@nocobase/plugin-workflow 0.18.0-alpha.9 → 0.19.0-alpha.10
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/dist/client/components/CheckboxGroupWithTooltip.d.ts +7 -0
- package/dist/client/components/DrawerForm.d.ts +5 -0
- package/dist/client/components/{ExecutionStatusSelect.d.ts → ExecutionStatus.d.ts} +1 -0
- package/dist/client/components/index.d.ts +1 -0
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.js +35 -30
- package/dist/client/nodes/end.d.ts +22 -0
- package/dist/client/nodes/index.d.ts +3 -0
- package/dist/client/schemas/executions.d.ts +14 -1
- package/dist/client/triggers/index.d.ts +2 -1
- package/dist/client/triggers/schedule/constants.d.ts +1 -1
- package/dist/client/triggers/schedule/index.d.ts +1 -0
- package/dist/externalVersion.js +11 -11
- package/dist/locale/ko_KR.json +168 -0
- package/dist/locale/zh-CN.json +22 -6
- package/dist/node_modules/cron-parser/package.json +1 -1
- package/dist/node_modules/lru-cache/package.json +1 -1
- package/dist/server/Plugin.d.ts +6 -3
- package/dist/server/Plugin.js +84 -55
- package/dist/server/Processor.d.ts +4 -1
- package/dist/server/Processor.js +27 -15
- package/dist/server/actions/executions.d.ts +1 -0
- package/dist/server/actions/executions.js +38 -0
- package/dist/server/actions/workflows.js +4 -2
- package/dist/server/collections/executions.js +4 -2
- package/dist/server/collections/flow_nodes.js +2 -2
- package/dist/server/collections/jobs.js +8 -2
- package/dist/server/collections/workflows.js +12 -3
- package/dist/server/instructions/ConditionInstruction.d.ts +1 -0
- package/dist/server/instructions/ConditionInstruction.js +1 -0
- package/dist/server/instructions/CreateInstruction.js +5 -5
- package/dist/server/instructions/DestroyInstruction.js +3 -3
- package/dist/server/instructions/EndInstruction.d.ts +6 -0
- package/dist/server/instructions/EndInstruction.js +46 -0
- package/dist/server/instructions/QueryInstruction.js +2 -2
- package/dist/server/instructions/UpdateInstruction.js +3 -3
- package/dist/server/migrations/20221129153547-calculation-variables.d.ts +1 -0
- package/dist/server/migrations/20221129153547-calculation-variables.js +1 -0
- package/dist/server/migrations/20230221032941-change-request-body-type.d.ts +1 -0
- package/dist/server/migrations/20230221032941-change-request-body-type.js +1 -0
- package/dist/server/migrations/20230221071831-calculation-expression.d.ts +1 -0
- package/dist/server/migrations/20230221071831-calculation-expression.js +1 -0
- package/dist/server/migrations/20230221121203-condition-calculation.d.ts +1 -0
- package/dist/server/migrations/20230221121203-condition-calculation.js +1 -0
- package/dist/server/migrations/20230221162902-jsonb-to-json.d.ts +1 -0
- package/dist/server/migrations/20230221162902-jsonb-to-json.js +1 -0
- package/dist/server/migrations/20230411034722-manual-multi-form.d.ts +1 -0
- package/dist/server/migrations/20230411034722-manual-multi-form.js +1 -0
- package/dist/server/migrations/20230612021134-manual-collection-block.d.ts +1 -0
- package/dist/server/migrations/20230612021134-manual-collection-block.js +1 -0
- package/dist/server/migrations/20230710115902-manual-action-values.d.ts +1 -0
- package/dist/server/migrations/20230710115902-manual-action-values.js +1 -0
- package/dist/server/migrations/20230809113132-workflow-options.d.ts +1 -0
- package/dist/server/migrations/20230809113132-workflow-options.js +1 -0
- package/dist/server/migrations/20231024172342-add-node-key.d.ts +1 -0
- package/dist/server/migrations/20231024172342-add-node-key.js +2 -1
- package/dist/server/migrations/20231122143143-split-to-plugins.d.ts +1 -0
- package/dist/server/migrations/20231122143143-split-to-plugins.js +1 -0
- package/dist/server/migrations/20240115220721-add-node-key-to-job.d.ts +6 -0
- package/dist/server/migrations/20240115220721-add-node-key-to-job.js +54 -0
- package/dist/server/triggers/CollectionTrigger.d.ts +2 -0
- package/dist/server/triggers/CollectionTrigger.js +28 -7
- package/dist/server/triggers/ScheduleTrigger/DateFieldScheduleTrigger.d.ts +31 -0
- package/dist/server/triggers/ScheduleTrigger/DateFieldScheduleTrigger.js +334 -0
- package/dist/server/triggers/ScheduleTrigger/StaticScheduleTrigger.d.ts +15 -0
- package/dist/server/triggers/ScheduleTrigger/StaticScheduleTrigger.js +143 -0
- package/dist/server/triggers/ScheduleTrigger/index.d.ts +13 -0
- package/dist/server/triggers/ScheduleTrigger/index.js +74 -0
- package/dist/server/triggers/ScheduleTrigger/utils.d.ts +5 -0
- package/dist/server/triggers/ScheduleTrigger/utils.js +35 -0
- package/dist/server/triggers/index.d.ts +2 -0
- package/dist/server/triggers/index.js +4 -0
- package/dist/server/types/Workflow.d.ts +5 -2
- package/package.json +10 -5
- package/dist/server/triggers/ScheduleTrigger.d.ts +0 -41
- package/dist/server/triggers/ScheduleTrigger.js +0 -480
package/dist/server/Plugin.js
CHANGED
|
@@ -27,7 +27,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
27
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
28
|
var Plugin_exports = {};
|
|
29
29
|
__export(Plugin_exports, {
|
|
30
|
-
default: () =>
|
|
30
|
+
default: () => PluginWorkflowServer
|
|
31
31
|
});
|
|
32
32
|
module.exports = __toCommonJS(Plugin_exports);
|
|
33
33
|
var import_path = __toESM(require("path"));
|
|
@@ -43,11 +43,12 @@ var import_CollectionTrigger = __toESM(require("./triggers/CollectionTrigger"));
|
|
|
43
43
|
var import_ScheduleTrigger = __toESM(require("./triggers/ScheduleTrigger"));
|
|
44
44
|
var import_CalculationInstruction = __toESM(require("./instructions/CalculationInstruction"));
|
|
45
45
|
var import_ConditionInstruction = __toESM(require("./instructions/ConditionInstruction"));
|
|
46
|
+
var import_EndInstruction = __toESM(require("./instructions/EndInstruction"));
|
|
46
47
|
var import_CreateInstruction = __toESM(require("./instructions/CreateInstruction"));
|
|
47
48
|
var import_DestroyInstruction = __toESM(require("./instructions/DestroyInstruction"));
|
|
48
49
|
var import_QueryInstruction = __toESM(require("./instructions/QueryInstruction"));
|
|
49
50
|
var import_UpdateInstruction = __toESM(require("./instructions/UpdateInstruction"));
|
|
50
|
-
class
|
|
51
|
+
class PluginWorkflowServer extends import_server.Plugin {
|
|
51
52
|
instructions = new import_utils.Registry();
|
|
52
53
|
triggers = new import_utils.Registry();
|
|
53
54
|
functions = new import_utils.Registry();
|
|
@@ -73,6 +74,13 @@ class WorkflowPlugin extends import_server.Plugin {
|
|
|
73
74
|
this.loggerCache.set(key, logger);
|
|
74
75
|
return logger;
|
|
75
76
|
}
|
|
77
|
+
isWorkflowSync(workflow) {
|
|
78
|
+
const trigger = this.triggers.get(workflow.type);
|
|
79
|
+
if (!trigger) {
|
|
80
|
+
throw new Error(`invalid trigger type ${workflow.type} of workflow ${workflow.id}`);
|
|
81
|
+
}
|
|
82
|
+
return trigger.sync ?? workflow.sync;
|
|
83
|
+
}
|
|
76
84
|
onBeforeSave = async (instance, options) => {
|
|
77
85
|
const Model = instance.constructor;
|
|
78
86
|
if (instance.enabled) {
|
|
@@ -140,6 +148,7 @@ class WorkflowPlugin extends import_server.Plugin {
|
|
|
140
148
|
initInstructions(more = {}) {
|
|
141
149
|
this.registerInstruction("calculation", import_CalculationInstruction.default);
|
|
142
150
|
this.registerInstruction("condition", import_ConditionInstruction.default);
|
|
151
|
+
this.registerInstruction("end", import_EndInstruction.default);
|
|
143
152
|
this.registerInstruction("create", import_CreateInstruction.default);
|
|
144
153
|
this.registerInstruction("destroy", import_DestroyInstruction.default);
|
|
145
154
|
this.registerInstruction("query", import_QueryInstruction.default);
|
|
@@ -173,6 +182,7 @@ class WorkflowPlugin extends import_server.Plugin {
|
|
|
173
182
|
"workflows.nodes:*",
|
|
174
183
|
"executions:list",
|
|
175
184
|
"executions:get",
|
|
185
|
+
"executions:cancel",
|
|
176
186
|
"flow_nodes:update",
|
|
177
187
|
"flow_nodes:destroy"
|
|
178
188
|
]
|
|
@@ -182,9 +192,7 @@ class WorkflowPlugin extends import_server.Plugin {
|
|
|
182
192
|
actions: ["workflows:list"]
|
|
183
193
|
});
|
|
184
194
|
this.app.acl.allow("workflows", ["trigger"], "loggedIn");
|
|
185
|
-
await
|
|
186
|
-
directory: import_path.default.resolve(__dirname, "collections")
|
|
187
|
-
});
|
|
195
|
+
await this.importCollections(import_path.default.resolve(__dirname, "collections"));
|
|
188
196
|
this.db.addMigrations({
|
|
189
197
|
namespace: this.name,
|
|
190
198
|
directory: import_path.default.resolve(__dirname, "migrations"),
|
|
@@ -210,8 +218,8 @@ class WorkflowPlugin extends import_server.Plugin {
|
|
|
210
218
|
this.dispatch();
|
|
211
219
|
});
|
|
212
220
|
this.app.on("beforeStop", async () => {
|
|
213
|
-
const
|
|
214
|
-
const workflows = await
|
|
221
|
+
const repository = db.getRepository("workflows");
|
|
222
|
+
const workflows = await repository.find({
|
|
215
223
|
filter: { enabled: true }
|
|
216
224
|
});
|
|
217
225
|
workflows.forEach((workflow) => {
|
|
@@ -233,7 +241,7 @@ class WorkflowPlugin extends import_server.Plugin {
|
|
|
233
241
|
this.getLogger(workflow.id).error(`trigger type ${workflow.type} of workflow ${workflow.id} is not implemented`);
|
|
234
242
|
return;
|
|
235
243
|
}
|
|
236
|
-
if (
|
|
244
|
+
if (enable ?? workflow.get("enabled")) {
|
|
237
245
|
const prev = workflow.previous();
|
|
238
246
|
if (prev.config) {
|
|
239
247
|
trigger.off({ ...workflow.get(), ...prev });
|
|
@@ -247,14 +255,18 @@ class WorkflowPlugin extends import_server.Plugin {
|
|
|
247
255
|
const logger = this.getLogger(workflow.id);
|
|
248
256
|
if (!this.ready) {
|
|
249
257
|
logger.warn(`app is not ready, event of workflow ${workflow.id} will be ignored`);
|
|
250
|
-
logger.debug(`ignored event data:`,
|
|
258
|
+
logger.debug(`ignored event data:`, context);
|
|
251
259
|
return;
|
|
252
260
|
}
|
|
253
261
|
if (context == null) {
|
|
254
262
|
logger.warn(`workflow ${workflow.id} event data context is null, event will be ignored`);
|
|
255
263
|
return;
|
|
256
264
|
}
|
|
257
|
-
this.
|
|
265
|
+
if (this.isWorkflowSync(workflow)) {
|
|
266
|
+
return this.triggerSync(workflow, context, options);
|
|
267
|
+
}
|
|
268
|
+
const { transaction, ...rest } = options;
|
|
269
|
+
this.events.push([workflow, context, rest]);
|
|
258
270
|
this.eventsCount = this.events.length;
|
|
259
271
|
logger.info(`new event triggered, now events: ${this.events.length}`);
|
|
260
272
|
logger.debug(`event data:`, {
|
|
@@ -265,6 +277,21 @@ class WorkflowPlugin extends import_server.Plugin {
|
|
|
265
277
|
}
|
|
266
278
|
setTimeout(this.prepare);
|
|
267
279
|
}
|
|
280
|
+
async triggerSync(workflow, context, options = {}) {
|
|
281
|
+
let execution;
|
|
282
|
+
try {
|
|
283
|
+
execution = await this.createExecution(workflow, context, options);
|
|
284
|
+
} catch (err) {
|
|
285
|
+
this.getLogger(workflow.id).error(`creating execution failed: ${err.message}`, err);
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
try {
|
|
289
|
+
return this.process(execution, null, options);
|
|
290
|
+
} catch (err) {
|
|
291
|
+
this.getLogger(execution.workflowId).error(`execution (${execution.id}) error: ${err.message}`, err);
|
|
292
|
+
}
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
268
295
|
async resume(job) {
|
|
269
296
|
if (!job.execution) {
|
|
270
297
|
job.execution = await job.getExecution();
|
|
@@ -278,52 +305,50 @@ class WorkflowPlugin extends import_server.Plugin {
|
|
|
278
305
|
createProcessor(execution, options = {}) {
|
|
279
306
|
return new import_Processor.default(execution, { ...options, plugin: this });
|
|
280
307
|
}
|
|
281
|
-
async createExecution(
|
|
282
|
-
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
}
|
|
289
|
-
});
|
|
290
|
-
if (existed) {
|
|
291
|
-
this.getLogger(workflow.id).warn(
|
|
292
|
-
`workflow ${workflow.id} has already been triggered in same execution (${options.context.executionId}), and newly triggering will be skipped.`
|
|
293
|
-
);
|
|
294
|
-
return null;
|
|
308
|
+
async createExecution(workflow, context, options) {
|
|
309
|
+
const { transaction = await this.db.sequelize.transaction() } = options;
|
|
310
|
+
const trigger = this.triggers.get(workflow.type);
|
|
311
|
+
const valid = await trigger.validateEvent(workflow, context, { ...options, transaction });
|
|
312
|
+
if (!valid) {
|
|
313
|
+
if (!options.transaction) {
|
|
314
|
+
await transaction.commit();
|
|
295
315
|
}
|
|
316
|
+
return null;
|
|
296
317
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
318
|
+
const execution = await workflow.createExecution(
|
|
319
|
+
{
|
|
320
|
+
context,
|
|
321
|
+
key: workflow.key,
|
|
322
|
+
status: import_constants.EXECUTION_STATUS.QUEUEING
|
|
323
|
+
},
|
|
324
|
+
{ transaction }
|
|
325
|
+
);
|
|
326
|
+
this.getLogger(workflow.id).info(`execution of workflow ${workflow.id} created as ${execution.id}`);
|
|
327
|
+
await workflow.increment(["executed", "allExecuted"], { transaction });
|
|
328
|
+
if (this.db.options.dialect !== "postgres") {
|
|
329
|
+
await workflow.reload({ transaction });
|
|
330
|
+
}
|
|
331
|
+
await workflow.constructor.update(
|
|
332
|
+
{
|
|
333
|
+
allExecuted: workflow.allExecuted
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
where: {
|
|
337
|
+
key: workflow.key
|
|
303
338
|
},
|
|
304
|
-
|
|
305
|
-
);
|
|
306
|
-
this.getLogger(workflow.id).info(`execution of workflow ${workflow.id} created as ${execution.id}`);
|
|
307
|
-
await workflow.increment(["executed", "allExecuted"], { transaction });
|
|
308
|
-
if (this.db.options.dialect !== "postgres") {
|
|
309
|
-
await workflow.reload({ transaction });
|
|
339
|
+
transaction
|
|
310
340
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
key: workflow.key
|
|
318
|
-
},
|
|
319
|
-
transaction
|
|
320
|
-
}
|
|
321
|
-
);
|
|
322
|
-
execution.workflow = workflow;
|
|
323
|
-
return execution;
|
|
324
|
-
});
|
|
341
|
+
);
|
|
342
|
+
if (!options.transaction) {
|
|
343
|
+
await transaction.commit();
|
|
344
|
+
}
|
|
345
|
+
execution.workflow = workflow;
|
|
346
|
+
return execution;
|
|
325
347
|
}
|
|
326
348
|
prepare = async () => {
|
|
349
|
+
if (this.executing && this.db.options.dialect === "sqlite") {
|
|
350
|
+
await this.executing;
|
|
351
|
+
}
|
|
327
352
|
const event = this.events.shift();
|
|
328
353
|
this.eventsCount = this.events.length;
|
|
329
354
|
if (!event) {
|
|
@@ -333,8 +358,8 @@ class WorkflowPlugin extends import_server.Plugin {
|
|
|
333
358
|
const logger = this.getLogger(event[0].id);
|
|
334
359
|
logger.info(`preparing execution for event`);
|
|
335
360
|
try {
|
|
336
|
-
const execution = await this.createExecution(event);
|
|
337
|
-
if (!this.executing && !this.pending.length) {
|
|
361
|
+
const execution = await this.createExecution(...event);
|
|
362
|
+
if (execution && !this.executing && !this.pending.length) {
|
|
338
363
|
this.pending.push([execution]);
|
|
339
364
|
}
|
|
340
365
|
} catch (err) {
|
|
@@ -355,6 +380,9 @@ class WorkflowPlugin extends import_server.Plugin {
|
|
|
355
380
|
this.getLogger("dispatcher").warn(`workflow executing is not finished, new dispatching will be ignored`);
|
|
356
381
|
return;
|
|
357
382
|
}
|
|
383
|
+
if (this.events.length) {
|
|
384
|
+
return this.prepare();
|
|
385
|
+
}
|
|
358
386
|
this.executing = (async () => {
|
|
359
387
|
let next = null;
|
|
360
388
|
if (this.pending.length) {
|
|
@@ -386,12 +414,12 @@ class WorkflowPlugin extends import_server.Plugin {
|
|
|
386
414
|
}
|
|
387
415
|
})();
|
|
388
416
|
}
|
|
389
|
-
async process(execution, job) {
|
|
417
|
+
async process(execution, job, options = {}) {
|
|
390
418
|
var _a, _b;
|
|
391
419
|
if (execution.status === import_constants.EXECUTION_STATUS.QUEUEING) {
|
|
392
|
-
await execution.update({ status: import_constants.EXECUTION_STATUS.STARTED });
|
|
420
|
+
await execution.update({ status: import_constants.EXECUTION_STATUS.STARTED }, { transaction: options.transaction });
|
|
393
421
|
}
|
|
394
|
-
const processor = this.createProcessor(execution);
|
|
422
|
+
const processor = this.createProcessor(execution, options);
|
|
395
423
|
this.getLogger(execution.workflowId).info(`execution (${execution.id}) ${job ? "resuming" : "starting"}...`);
|
|
396
424
|
try {
|
|
397
425
|
await (job ? processor.resume(job) : processor.start());
|
|
@@ -404,5 +432,6 @@ class WorkflowPlugin extends import_server.Plugin {
|
|
|
404
432
|
} catch (err) {
|
|
405
433
|
this.getLogger(execution.workflowId).error(`execution (${execution.id}) error: ${err.message}`, err);
|
|
406
434
|
}
|
|
435
|
+
return processor;
|
|
407
436
|
}
|
|
408
437
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { Transactionable } from '@nocobase/database';
|
|
1
|
+
import { Transaction, Transactionable } from '@nocobase/database';
|
|
2
2
|
import { Logger } from '@nocobase/logger';
|
|
3
3
|
import type Plugin from './Plugin';
|
|
4
4
|
import type { ExecutionModel, FlowNodeModel, JobModel } from './types';
|
|
5
5
|
export interface ProcessorOptions extends Transactionable {
|
|
6
6
|
plugin: Plugin;
|
|
7
|
+
[key: string]: any;
|
|
7
8
|
}
|
|
8
9
|
export default class Processor {
|
|
9
10
|
execution: ExecutionModel;
|
|
@@ -19,12 +20,14 @@ export default class Processor {
|
|
|
19
20
|
[-6]: -6;
|
|
20
21
|
};
|
|
21
22
|
logger: Logger;
|
|
23
|
+
transaction: Transaction;
|
|
22
24
|
nodes: FlowNodeModel[];
|
|
23
25
|
nodesMap: Map<number, FlowNodeModel>;
|
|
24
26
|
jobsMap: Map<number, JobModel>;
|
|
25
27
|
jobsMapByNodeKey: {
|
|
26
28
|
[key: string]: any;
|
|
27
29
|
};
|
|
30
|
+
lastSavedJob: JobModel | null;
|
|
28
31
|
constructor(execution: ExecutionModel, options: ProcessorOptions);
|
|
29
32
|
private makeNodes;
|
|
30
33
|
private makeJobs;
|
package/dist/server/Processor.js
CHANGED
|
@@ -29,6 +29,7 @@ class Processor {
|
|
|
29
29
|
this.execution = execution;
|
|
30
30
|
this.options = options;
|
|
31
31
|
this.logger = options.plugin.getLogger(execution.workflowId);
|
|
32
|
+
this.transaction = options.transaction;
|
|
32
33
|
}
|
|
33
34
|
static StatusMap = {
|
|
34
35
|
[import_constants.JOB_STATUS.PENDING]: import_constants.EXECUTION_STATUS.STARTED,
|
|
@@ -41,10 +42,12 @@ class Processor {
|
|
|
41
42
|
[import_constants.JOB_STATUS.RETRY_NEEDED]: import_constants.EXECUTION_STATUS.RETRY_NEEDED
|
|
42
43
|
};
|
|
43
44
|
logger;
|
|
45
|
+
transaction;
|
|
44
46
|
nodes = [];
|
|
45
47
|
nodesMap = /* @__PURE__ */ new Map();
|
|
46
48
|
jobsMap = /* @__PURE__ */ new Map();
|
|
47
49
|
jobsMapByNodeKey = {};
|
|
50
|
+
lastSavedJob = null;
|
|
48
51
|
// make dual linked nodes list then cache
|
|
49
52
|
makeNodes(nodes = []) {
|
|
50
53
|
this.nodes = nodes;
|
|
@@ -68,14 +71,15 @@ class Processor {
|
|
|
68
71
|
});
|
|
69
72
|
}
|
|
70
73
|
async prepare() {
|
|
71
|
-
const { execution } = this;
|
|
74
|
+
const { execution, transaction } = this;
|
|
72
75
|
if (!execution.workflow) {
|
|
73
|
-
execution.workflow = await execution.getWorkflow();
|
|
76
|
+
execution.workflow = await execution.getWorkflow({ transaction });
|
|
74
77
|
}
|
|
75
|
-
const nodes = await execution.workflow.getNodes();
|
|
78
|
+
const nodes = await execution.workflow.getNodes({ transaction });
|
|
76
79
|
this.makeNodes(nodes);
|
|
77
80
|
const jobs = await execution.getJobs({
|
|
78
|
-
order: [["id", "ASC"]]
|
|
81
|
+
order: [["id", "ASC"]],
|
|
82
|
+
transaction
|
|
79
83
|
});
|
|
80
84
|
this.makeJobs(jobs);
|
|
81
85
|
}
|
|
@@ -116,7 +120,10 @@ class Processor {
|
|
|
116
120
|
{ error: err }
|
|
117
121
|
);
|
|
118
122
|
job = {
|
|
119
|
-
result: err instanceof Error ? {
|
|
123
|
+
result: err instanceof Error ? {
|
|
124
|
+
message: err.message,
|
|
125
|
+
stack: process.env.NODE_ENV === "production" ? 'Error stack will not be shown under "production" environment, please check logs.' : err.stack
|
|
126
|
+
} : err,
|
|
120
127
|
status: import_constants.JOB_STATUS.ERROR
|
|
121
128
|
};
|
|
122
129
|
if (prevJob && prevJob.nodeId === node.id) {
|
|
@@ -127,6 +134,7 @@ class Processor {
|
|
|
127
134
|
if (!(job instanceof import_database.Model)) {
|
|
128
135
|
job.upstreamId = prevJob instanceof import_database.Model ? prevJob.get("id") : null;
|
|
129
136
|
job.nodeId = node.id;
|
|
137
|
+
job.nodeKey = node.key;
|
|
130
138
|
}
|
|
131
139
|
const savedJob = await this.saveJob(job);
|
|
132
140
|
this.logger.info(
|
|
@@ -171,7 +179,7 @@ class Processor {
|
|
|
171
179
|
async exit(s) {
|
|
172
180
|
if (typeof s === "number") {
|
|
173
181
|
const status = this.constructor.StatusMap[s] ?? Math.sign(s);
|
|
174
|
-
await this.execution.update({ status });
|
|
182
|
+
await this.execution.update({ status }, { transaction: this.transaction });
|
|
175
183
|
}
|
|
176
184
|
this.logger.info(`execution (${this.execution.id}) exiting with status ${this.execution.status}`);
|
|
177
185
|
return null;
|
|
@@ -179,22 +187,26 @@ class Processor {
|
|
|
179
187
|
// TODO(optimize)
|
|
180
188
|
async saveJob(payload) {
|
|
181
189
|
const { database } = this.execution.constructor;
|
|
190
|
+
const { transaction } = this;
|
|
182
191
|
const { model } = database.getCollection("jobs");
|
|
183
192
|
let job;
|
|
184
193
|
if (payload instanceof model) {
|
|
185
|
-
job = await payload.save();
|
|
194
|
+
job = await payload.save({ transaction });
|
|
186
195
|
} else if (payload.id) {
|
|
187
|
-
job = await model.findByPk(payload.id);
|
|
188
|
-
await job.update(payload);
|
|
196
|
+
job = await model.findByPk(payload.id, { transaction });
|
|
197
|
+
await job.update(payload, { transaction });
|
|
189
198
|
} else {
|
|
190
|
-
job = await model.create(
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
199
|
+
job = await model.create(
|
|
200
|
+
{
|
|
201
|
+
...payload,
|
|
202
|
+
executionId: this.execution.id
|
|
203
|
+
},
|
|
204
|
+
{ transaction }
|
|
205
|
+
);
|
|
194
206
|
}
|
|
195
207
|
this.jobsMap.set(job.id, job);
|
|
196
|
-
|
|
197
|
-
this.jobsMapByNodeKey[
|
|
208
|
+
this.lastSavedJob = job;
|
|
209
|
+
this.jobsMapByNodeKey[job.nodeKey] = job.result;
|
|
198
210
|
return job;
|
|
199
211
|
}
|
|
200
212
|
getBranches(node) {
|
|
@@ -27,6 +27,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
27
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
28
|
var executions_exports = {};
|
|
29
29
|
__export(executions_exports, {
|
|
30
|
+
cancel: () => cancel,
|
|
30
31
|
destroy: () => destroy
|
|
31
32
|
});
|
|
32
33
|
module.exports = __toCommonJS(executions_exports);
|
|
@@ -43,7 +44,44 @@ async function destroy(context, next) {
|
|
|
43
44
|
});
|
|
44
45
|
await import_actions.default.destroy(context, next);
|
|
45
46
|
}
|
|
47
|
+
async function cancel(context, next) {
|
|
48
|
+
const { filterByTk } = context.action.params;
|
|
49
|
+
const ExecutionRepo = context.db.getRepository("executions");
|
|
50
|
+
const JobRepo = context.db.getRepository("jobs");
|
|
51
|
+
const execution = await ExecutionRepo.findOne({
|
|
52
|
+
filterByTk,
|
|
53
|
+
appends: ["jobs"]
|
|
54
|
+
});
|
|
55
|
+
if (!execution) {
|
|
56
|
+
return context.throw(404);
|
|
57
|
+
}
|
|
58
|
+
if (execution.status) {
|
|
59
|
+
return context.throw(400);
|
|
60
|
+
}
|
|
61
|
+
await context.db.sequelize.transaction(async (transaction) => {
|
|
62
|
+
await execution.update(
|
|
63
|
+
{
|
|
64
|
+
status: import_constants.EXECUTION_STATUS.CANCELED
|
|
65
|
+
},
|
|
66
|
+
{ transaction }
|
|
67
|
+
);
|
|
68
|
+
const pendingJobs = execution.jobs.filter((job) => job.status === import_constants.JOB_STATUS.PENDING);
|
|
69
|
+
await JobRepo.update({
|
|
70
|
+
values: {
|
|
71
|
+
status: import_constants.JOB_STATUS.CANCELED
|
|
72
|
+
},
|
|
73
|
+
filter: {
|
|
74
|
+
id: pendingJobs.map((job) => job.id)
|
|
75
|
+
},
|
|
76
|
+
individualHooks: false,
|
|
77
|
+
transaction
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
context.body = execution;
|
|
81
|
+
await next();
|
|
82
|
+
}
|
|
46
83
|
// Annotate the CommonJS export names for ESM import in node:
|
|
47
84
|
0 && (module.exports = {
|
|
85
|
+
cancel,
|
|
48
86
|
destroy
|
|
49
87
|
});
|
|
@@ -41,7 +41,7 @@ async function update(context, next) {
|
|
|
41
41
|
const repository = import_actions.utils.getRepositoryFromParams(context);
|
|
42
42
|
const { filterByTk, values } = context.action.params;
|
|
43
43
|
context.action.mergeParams({
|
|
44
|
-
whitelist: ["title", "description", "enabled", "config", "options"]
|
|
44
|
+
whitelist: ["title", "description", "enabled", "triggerTitle", "config", "options"]
|
|
45
45
|
});
|
|
46
46
|
if (Object.keys(values).includes("config")) {
|
|
47
47
|
const workflow = await repository.findById(filterByTk);
|
|
@@ -96,7 +96,9 @@ async function revision(context, next) {
|
|
|
96
96
|
const revisionData = filter.key ? {
|
|
97
97
|
key: filter.key,
|
|
98
98
|
title: origin.title,
|
|
99
|
-
|
|
99
|
+
triggerTitle: origin.triggerTitle,
|
|
100
|
+
allExecuted: origin.allExecuted,
|
|
101
|
+
sync: origin.sync
|
|
100
102
|
} : values;
|
|
101
103
|
const instance = await repository.create({
|
|
102
104
|
values: {
|
|
@@ -21,9 +21,11 @@ __export(executions_exports, {
|
|
|
21
21
|
});
|
|
22
22
|
module.exports = __toCommonJS(executions_exports);
|
|
23
23
|
var executions_default = {
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
dumpRules: {
|
|
25
|
+
group: "log"
|
|
26
|
+
},
|
|
26
27
|
name: "executions",
|
|
28
|
+
shared: true,
|
|
27
29
|
fields: [
|
|
28
30
|
{
|
|
29
31
|
type: "belongsTo",
|
|
@@ -21,9 +21,9 @@ __export(flow_nodes_exports, {
|
|
|
21
21
|
});
|
|
22
22
|
module.exports = __toCommonJS(flow_nodes_exports);
|
|
23
23
|
var flow_nodes_default = {
|
|
24
|
-
|
|
25
|
-
duplicator: "required",
|
|
24
|
+
dumpRules: "required",
|
|
26
25
|
name: "flow_nodes",
|
|
26
|
+
shared: true,
|
|
27
27
|
fields: [
|
|
28
28
|
{
|
|
29
29
|
type: "uid",
|
|
@@ -21,9 +21,11 @@ __export(jobs_exports, {
|
|
|
21
21
|
});
|
|
22
22
|
module.exports = __toCommonJS(jobs_exports);
|
|
23
23
|
var jobs_default = {
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
dumpRules: {
|
|
25
|
+
group: "log"
|
|
26
|
+
},
|
|
26
27
|
name: "jobs",
|
|
28
|
+
shared: true,
|
|
27
29
|
fields: [
|
|
28
30
|
{
|
|
29
31
|
type: "belongsTo",
|
|
@@ -34,6 +36,10 @@ var jobs_default = {
|
|
|
34
36
|
name: "node",
|
|
35
37
|
target: "flow_nodes"
|
|
36
38
|
},
|
|
39
|
+
{
|
|
40
|
+
type: "string",
|
|
41
|
+
name: "nodeKey"
|
|
42
|
+
},
|
|
37
43
|
{
|
|
38
44
|
type: "belongsTo",
|
|
39
45
|
name: "upstream",
|
|
@@ -22,9 +22,9 @@ __export(workflows_exports, {
|
|
|
22
22
|
module.exports = __toCommonJS(workflows_exports);
|
|
23
23
|
function workflows_default() {
|
|
24
24
|
return {
|
|
25
|
-
|
|
26
|
-
duplicator: "required",
|
|
25
|
+
dumpRules: "required",
|
|
27
26
|
name: "workflows",
|
|
27
|
+
shared: true,
|
|
28
28
|
fields: [
|
|
29
29
|
{
|
|
30
30
|
name: "key",
|
|
@@ -50,7 +50,11 @@ function workflows_default() {
|
|
|
50
50
|
required: true
|
|
51
51
|
},
|
|
52
52
|
{
|
|
53
|
-
type: "
|
|
53
|
+
type: "string",
|
|
54
|
+
name: "triggerTitle"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
type: "jsonb",
|
|
54
58
|
name: "config",
|
|
55
59
|
required: true,
|
|
56
60
|
defaultValue: {}
|
|
@@ -81,6 +85,11 @@ function workflows_default() {
|
|
|
81
85
|
name: "current",
|
|
82
86
|
defaultValue: false
|
|
83
87
|
},
|
|
88
|
+
{
|
|
89
|
+
type: "boolean",
|
|
90
|
+
name: "sync",
|
|
91
|
+
defaultValue: false
|
|
92
|
+
},
|
|
84
93
|
{
|
|
85
94
|
type: "hasMany",
|
|
86
95
|
name: "revisions",
|
|
@@ -128,6 +128,7 @@ class ConditionInstruction extends import__.Instruction {
|
|
|
128
128
|
result,
|
|
129
129
|
// TODO(optimize): try unify the building of job
|
|
130
130
|
nodeId: node.id,
|
|
131
|
+
nodeKey: node.key,
|
|
131
132
|
upstreamId: prevJob && prevJob.id || null
|
|
132
133
|
};
|
|
133
134
|
const branchNode = processor.nodes.find(
|
|
@@ -32,9 +32,9 @@ class CreateInstruction extends import__.Instruction {
|
|
|
32
32
|
const created = await repository.create({
|
|
33
33
|
...options,
|
|
34
34
|
context: {
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
35
|
+
stack: Array.from(new Set((processor.execution.context.stack ?? []).concat(processor.execution.id)))
|
|
36
|
+
},
|
|
37
|
+
transaction: processor.transaction
|
|
38
38
|
});
|
|
39
39
|
let result = created;
|
|
40
40
|
if (created && appends.length) {
|
|
@@ -45,8 +45,8 @@ class CreateInstruction extends import__.Instruction {
|
|
|
45
45
|
}, /* @__PURE__ */ new Set());
|
|
46
46
|
result = await repository.findOne({
|
|
47
47
|
filterByTk: created[model.primaryKeyAttribute],
|
|
48
|
-
appends: Array.from(includeFields)
|
|
49
|
-
|
|
48
|
+
appends: Array.from(includeFields),
|
|
49
|
+
transaction: processor.transaction
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
52
|
return {
|
|
@@ -31,9 +31,9 @@ class DestroyInstruction extends import__.Instruction {
|
|
|
31
31
|
const result = await repo.destroy({
|
|
32
32
|
...options,
|
|
33
33
|
context: {
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
34
|
+
stack: Array.from(new Set((processor.execution.context.stack ?? []).concat(processor.execution.id)))
|
|
35
|
+
},
|
|
36
|
+
transaction: processor.transaction
|
|
37
37
|
});
|
|
38
38
|
return {
|
|
39
39
|
result,
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var EndInstruction_exports = {};
|
|
29
|
+
__export(EndInstruction_exports, {
|
|
30
|
+
default: () => EndInstruction_default
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(EndInstruction_exports);
|
|
33
|
+
var import__ = __toESM(require("."));
|
|
34
|
+
var import_constants = require("../constants");
|
|
35
|
+
class EndInstruction_default extends import__.default {
|
|
36
|
+
async run(node, prevJob, processor) {
|
|
37
|
+
const { endStatus = import_constants.JOB_STATUS.RESOLVED } = node.config;
|
|
38
|
+
await processor.saveJob({
|
|
39
|
+
status: endStatus,
|
|
40
|
+
nodeId: node.id,
|
|
41
|
+
nodeKey: node.key,
|
|
42
|
+
upstreamId: (prevJob == null ? void 0 : prevJob.id) ?? null
|
|
43
|
+
});
|
|
44
|
+
return processor.exit(endStatus);
|
|
45
|
+
}
|
|
46
|
+
}
|