@nocobase/plugin-workflow 1.7.0-alpha.1 → 1.7.0-alpha.11
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/3d24e559cfbba5d8.js +10 -0
- package/dist/client/90a4f6d29bd453a7.js +10 -0
- package/dist/client/WorkflowTasks.d.ts +11 -11
- package/dist/client/a2fc280565d1c746.js +10 -0
- package/dist/client/f4370978c40502d7.js +10 -0
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.js +1 -1
- package/dist/client/locale/index.d.ts +2 -1
- package/dist/client/schemas/executions.d.ts +126 -125
- package/dist/client/triggers/schedule/RepeatField.d.ts +2 -1
- package/dist/common/collections/executions.d.ts +136 -0
- package/dist/common/collections/executions.js +125 -0
- package/dist/common/collections/flow_nodes.d.ts +44 -0
- package/dist/common/collections/flow_nodes.js +88 -0
- package/dist/common/collections/jobs.d.ts +37 -0
- package/dist/common/collections/jobs.js +74 -0
- package/dist/common/collections/workflowStats.d.ts +37 -0
- package/dist/common/collections/workflowStats.js +59 -0
- package/dist/common/collections/workflowTasks.d.ts +10 -0
- package/dist/common/collections/workflowTasks.js +64 -0
- package/dist/common/collections/workflowVersionStats.d.ts +37 -0
- package/dist/common/collections/workflowVersionStats.js +59 -0
- package/dist/common/collections/workflows.d.ts +250 -0
- package/dist/common/collections/workflows.js +225 -0
- package/dist/common/constants.d.ts +9 -0
- package/dist/common/constants.js +36 -0
- package/dist/externalVersion.js +13 -13
- package/dist/locale/de-DE.json +216 -0
- package/dist/locale/it-IT.json +123 -18
- package/dist/locale/nl-NL.json +100 -0
- package/dist/locale/zh-CN.json +4 -0
- package/dist/node_modules/cron-parser/package.json +1 -1
- package/dist/node_modules/lru-cache/package.json +1 -1
- package/dist/node_modules/nodejs-snowflake/LICENSE +201 -0
- package/dist/node_modules/nodejs-snowflake/nodejs_snowflake.d.ts +62 -0
- package/dist/node_modules/nodejs-snowflake/nodejs_snowflake.js +1 -0
- package/dist/node_modules/nodejs-snowflake/nodejs_snowflake_bg.wasm +0 -0
- package/dist/node_modules/nodejs-snowflake/package.json +1 -0
- package/dist/server/Dispatcher.d.ts +11 -0
- package/dist/server/Dispatcher.js +35 -0
- package/dist/server/Plugin.d.ts +8 -1
- package/dist/server/Plugin.js +118 -70
- package/dist/server/Processor.d.ts +4 -11
- package/dist/server/Processor.js +48 -45
- package/dist/server/actions/nodes.js +7 -5
- package/dist/server/actions/workflowTasks.js +4 -2
- package/dist/server/actions/workflows.js +5 -2
- package/dist/server/collections/executions.js +12 -44
- package/dist/server/collections/flow_nodes.js +12 -57
- package/dist/server/collections/jobs.js +12 -36
- package/dist/server/collections/workflowStats.d.ts +11 -0
- package/dist/server/collections/workflowStats.js +43 -0
- package/dist/server/collections/workflowTasks.d.ts +2 -1
- package/dist/server/collections/workflowTasks.js +12 -33
- package/dist/server/collections/workflowVersionStats.d.ts +11 -0
- package/dist/server/collections/workflowVersionStats.js +43 -0
- package/dist/server/collections/workflows.d.ts +2 -1
- package/dist/server/collections/workflows.js +12 -101
- package/dist/server/migrations/20250320223415-stats.d.ts +14 -0
- package/dist/server/migrations/20250320223415-stats.js +82 -0
- package/dist/server/migrations/20250409164913-remove-jobs-auto-increment.d.ts +14 -0
- package/dist/server/migrations/20250409164913-remove-jobs-auto-increment.js +57 -0
- package/dist/server/repositories/WorkflowRepository.js +1 -2
- package/dist/server/triggers/ScheduleTrigger/DateFieldScheduleTrigger.d.ts +5 -3
- package/dist/server/triggers/ScheduleTrigger/DateFieldScheduleTrigger.js +39 -36
- package/dist/server/triggers/ScheduleTrigger/StaticScheduleTrigger.d.ts +4 -2
- package/dist/server/triggers/ScheduleTrigger/StaticScheduleTrigger.js +26 -24
- package/dist/server/types/Workflow.d.ts +0 -2
- package/dist/swagger/index.d.ts +0 -14
- package/dist/swagger/index.js +0 -14
- package/package.json +4 -3
- package/dist/client/4d75ef32f02d7285.js +0 -10
- package/dist/client/56ce448358002e64.js +0 -10
- package/dist/client/58bb427e05b600de.js +0 -10
- package/dist/client/739d458621edf81f.js +0 -10
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
18
|
+
var __copyProps = (to, from, except, desc) => {
|
|
19
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
+
for (let key of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
+
}
|
|
24
|
+
return to;
|
|
25
|
+
};
|
|
26
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
+
var Dispatcher_exports = {};
|
|
28
|
+
__export(Dispatcher_exports, {
|
|
29
|
+
default: () => Dispatcher
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(Dispatcher_exports);
|
|
32
|
+
class Dispatcher {
|
|
33
|
+
constructor() {
|
|
34
|
+
}
|
|
35
|
+
}
|
package/dist/server/Plugin.d.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
|
+
import { Snowflake } from 'nodejs-snowflake';
|
|
9
10
|
import { Transactionable } from 'sequelize';
|
|
10
11
|
import { Plugin } from '@nocobase/server';
|
|
11
12
|
import { Registry } from '@nocobase/utils';
|
|
@@ -31,6 +32,7 @@ export default class PluginWorkflowServer extends Plugin {
|
|
|
31
32
|
triggers: Registry<Trigger>;
|
|
32
33
|
functions: Registry<CustomFunction>;
|
|
33
34
|
enabledCache: Map<number, WorkflowModel>;
|
|
35
|
+
snowflake: Snowflake;
|
|
34
36
|
private ready;
|
|
35
37
|
private executing;
|
|
36
38
|
private pending;
|
|
@@ -40,6 +42,11 @@ export default class PluginWorkflowServer extends Plugin {
|
|
|
40
42
|
private meter;
|
|
41
43
|
private checker;
|
|
42
44
|
private onBeforeSave;
|
|
45
|
+
private onAfterCreate;
|
|
46
|
+
private onAfterUpdate;
|
|
47
|
+
private onAfterDestroy;
|
|
48
|
+
private onAfterStart;
|
|
49
|
+
private onBeforeStop;
|
|
43
50
|
handleSyncMessage(message: any): Promise<void>;
|
|
44
51
|
/**
|
|
45
52
|
* @experimental
|
|
@@ -91,6 +98,6 @@ export default class PluginWorkflowServer extends Plugin {
|
|
|
91
98
|
/**
|
|
92
99
|
* @experimental
|
|
93
100
|
*/
|
|
94
|
-
toggleTaskStatus(task: WorkflowTaskModel,
|
|
101
|
+
toggleTaskStatus(task: WorkflowTaskModel, on: boolean, { transaction }: Transactionable): Promise<void>;
|
|
95
102
|
}
|
|
96
103
|
export {};
|
package/dist/server/Plugin.js
CHANGED
|
@@ -41,6 +41,7 @@ __export(Plugin_exports, {
|
|
|
41
41
|
module.exports = __toCommonJS(Plugin_exports);
|
|
42
42
|
var import_path = __toESM(require("path"));
|
|
43
43
|
var import_crypto = require("crypto");
|
|
44
|
+
var import_nodejs_snowflake = require("nodejs-snowflake");
|
|
44
45
|
var import_sequelize = require("sequelize");
|
|
45
46
|
var import_lru_cache = __toESM(require("lru-cache"));
|
|
46
47
|
var import_database = require("@nocobase/database");
|
|
@@ -66,6 +67,7 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
66
67
|
triggers = new import_utils.Registry();
|
|
67
68
|
functions = new import_utils.Registry();
|
|
68
69
|
enabledCache = /* @__PURE__ */ new Map();
|
|
70
|
+
snowflake;
|
|
69
71
|
ready = false;
|
|
70
72
|
executing = null;
|
|
71
73
|
pending = [];
|
|
@@ -76,6 +78,9 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
76
78
|
checker = null;
|
|
77
79
|
onBeforeSave = async (instance, { transaction }) => {
|
|
78
80
|
const Model = instance.constructor;
|
|
81
|
+
if (!instance.key) {
|
|
82
|
+
instance.set("key", (0, import_utils.uid)());
|
|
83
|
+
}
|
|
79
84
|
if (instance.enabled) {
|
|
80
85
|
instance.set("current", true);
|
|
81
86
|
}
|
|
@@ -103,6 +108,82 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
103
108
|
this.toggle(previous, false, { transaction });
|
|
104
109
|
}
|
|
105
110
|
};
|
|
111
|
+
onAfterCreate = async (model, { transaction }) => {
|
|
112
|
+
const WorkflowStatsModel = this.db.getModel("workflowStats");
|
|
113
|
+
let stats = await WorkflowStatsModel.findOne({
|
|
114
|
+
where: { key: model.key },
|
|
115
|
+
transaction
|
|
116
|
+
});
|
|
117
|
+
if (!stats) {
|
|
118
|
+
stats = await model.createStats({ executed: 0 }, { transaction });
|
|
119
|
+
}
|
|
120
|
+
model.stats = stats;
|
|
121
|
+
model.versionStats = await model.createVersionStats({ id: model.id }, { transaction });
|
|
122
|
+
if (model.enabled) {
|
|
123
|
+
this.toggle(model, true, { transaction });
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
onAfterUpdate = async (model, { transaction }) => {
|
|
127
|
+
model.stats = await model.getStats({ transaction });
|
|
128
|
+
model.versionStats = await model.getVersionStats({ transaction });
|
|
129
|
+
this.toggle(model, model.enabled, { transaction });
|
|
130
|
+
};
|
|
131
|
+
onAfterDestroy = async (model, { transaction }) => {
|
|
132
|
+
this.toggle(model, false, { transaction });
|
|
133
|
+
const TaskRepo = this.db.getRepository("workflowTasks");
|
|
134
|
+
await TaskRepo.destroy({
|
|
135
|
+
filter: {
|
|
136
|
+
workflowId: model.id
|
|
137
|
+
},
|
|
138
|
+
transaction
|
|
139
|
+
});
|
|
140
|
+
};
|
|
141
|
+
// [Life Cycle]:
|
|
142
|
+
// * load all workflows in db
|
|
143
|
+
// * add all hooks for enabled workflows
|
|
144
|
+
// * add hooks for create/update[enabled]/delete workflow to add/remove specific hooks
|
|
145
|
+
onAfterStart = async () => {
|
|
146
|
+
this.ready = true;
|
|
147
|
+
const collection = this.db.getCollection("workflows");
|
|
148
|
+
const workflows = await collection.repository.find({
|
|
149
|
+
filter: { enabled: true },
|
|
150
|
+
appends: ["stats", "versionStats"]
|
|
151
|
+
});
|
|
152
|
+
for (const workflow of workflows) {
|
|
153
|
+
if (!workflow.stats) {
|
|
154
|
+
workflow.stats = await workflow.createStats({ executed: 0 });
|
|
155
|
+
}
|
|
156
|
+
if (!workflow.versionStats) {
|
|
157
|
+
workflow.versionStats = await workflow.createVersionStats({ executed: 0 });
|
|
158
|
+
}
|
|
159
|
+
this.toggle(workflow, true, { silent: true });
|
|
160
|
+
}
|
|
161
|
+
this.checker = setInterval(() => {
|
|
162
|
+
this.getLogger("dispatcher").info(`(cycling) check for queueing executions`);
|
|
163
|
+
this.dispatch();
|
|
164
|
+
}, 3e5);
|
|
165
|
+
this.app.on("workflow:dispatch", () => {
|
|
166
|
+
this.app.logger.info("workflow:dispatch");
|
|
167
|
+
this.dispatch();
|
|
168
|
+
});
|
|
169
|
+
this.getLogger("dispatcher").info("(starting) check for queueing executions");
|
|
170
|
+
this.dispatch();
|
|
171
|
+
};
|
|
172
|
+
onBeforeStop = async () => {
|
|
173
|
+
for (const workflow of this.enabledCache.values()) {
|
|
174
|
+
this.toggle(workflow, false, { silent: true });
|
|
175
|
+
}
|
|
176
|
+
this.ready = false;
|
|
177
|
+
if (this.events.length) {
|
|
178
|
+
await this.prepare();
|
|
179
|
+
}
|
|
180
|
+
if (this.executing) {
|
|
181
|
+
await this.executing;
|
|
182
|
+
}
|
|
183
|
+
if (this.checker) {
|
|
184
|
+
clearInterval(this.checker);
|
|
185
|
+
}
|
|
186
|
+
};
|
|
106
187
|
async handleSyncMessage(message) {
|
|
107
188
|
if (message.type === "statusChange") {
|
|
108
189
|
if (message.enabled) {
|
|
@@ -196,6 +277,13 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
196
277
|
WorkflowRepository: import_WorkflowRepository.default,
|
|
197
278
|
WorkflowTasksRepository: import_WorkflowTasksRepository.default
|
|
198
279
|
});
|
|
280
|
+
const PluginRepo = this.db.getRepository("applicationPlugins");
|
|
281
|
+
const pluginRecord = await PluginRepo.findOne({
|
|
282
|
+
filter: { name: this.name }
|
|
283
|
+
});
|
|
284
|
+
this.snowflake = new import_nodejs_snowflake.Snowflake({
|
|
285
|
+
custom_epoch: pluginRecord == null ? void 0 : pluginRecord.createdAt.getTime()
|
|
286
|
+
});
|
|
199
287
|
}
|
|
200
288
|
/**
|
|
201
289
|
* @internal
|
|
@@ -247,54 +335,11 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
247
335
|
}
|
|
248
336
|
});
|
|
249
337
|
db.on("workflows.beforeSave", this.onBeforeSave);
|
|
250
|
-
db.on("workflows.afterCreate",
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
db.on(
|
|
256
|
-
"workflows.afterUpdate",
|
|
257
|
-
(model, { transaction }) => this.toggle(model, model.enabled, { transaction })
|
|
258
|
-
);
|
|
259
|
-
db.on(
|
|
260
|
-
"workflows.afterDestroy",
|
|
261
|
-
(model, { transaction }) => this.toggle(model, false, { transaction })
|
|
262
|
-
);
|
|
263
|
-
this.app.on("afterStart", async () => {
|
|
264
|
-
this.ready = true;
|
|
265
|
-
const collection = db.getCollection("workflows");
|
|
266
|
-
const workflows = await collection.repository.find({
|
|
267
|
-
filter: { enabled: true }
|
|
268
|
-
});
|
|
269
|
-
workflows.forEach((workflow) => {
|
|
270
|
-
this.toggle(workflow, true, { silent: true });
|
|
271
|
-
});
|
|
272
|
-
this.checker = setInterval(() => {
|
|
273
|
-
this.getLogger("dispatcher").info(`(cycling) check for queueing executions`);
|
|
274
|
-
this.dispatch();
|
|
275
|
-
}, 3e5);
|
|
276
|
-
this.app.on("workflow:dispatch", () => {
|
|
277
|
-
this.app.logger.info("workflow:dispatch");
|
|
278
|
-
this.dispatch();
|
|
279
|
-
});
|
|
280
|
-
this.getLogger("dispatcher").info("(starting) check for queueing executions");
|
|
281
|
-
this.dispatch();
|
|
282
|
-
});
|
|
283
|
-
this.app.on("beforeStop", async () => {
|
|
284
|
-
for (const workflow of this.enabledCache.values()) {
|
|
285
|
-
this.toggle(workflow, false, { silent: true });
|
|
286
|
-
}
|
|
287
|
-
this.ready = false;
|
|
288
|
-
if (this.events.length) {
|
|
289
|
-
await this.prepare();
|
|
290
|
-
}
|
|
291
|
-
if (this.executing) {
|
|
292
|
-
await this.executing;
|
|
293
|
-
}
|
|
294
|
-
if (this.checker) {
|
|
295
|
-
clearInterval(this.checker);
|
|
296
|
-
}
|
|
297
|
-
});
|
|
338
|
+
db.on("workflows.afterCreate", this.onAfterCreate);
|
|
339
|
+
db.on("workflows.afterUpdate", this.onAfterUpdate);
|
|
340
|
+
db.on("workflows.afterDestroy", this.onAfterDestroy);
|
|
341
|
+
this.app.on("afterStart", this.onAfterStart);
|
|
342
|
+
this.app.on("beforeStop", this.onBeforeStop);
|
|
298
343
|
}
|
|
299
344
|
toggle(workflow, enable, { silent, transaction } = {}) {
|
|
300
345
|
const type = workflow.get("type");
|
|
@@ -308,11 +353,14 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
308
353
|
const prev = workflow.previous();
|
|
309
354
|
if (prev.config) {
|
|
310
355
|
trigger.off({ ...workflow.get(), ...prev });
|
|
356
|
+
this.getLogger(workflow.id).info(`toggle OFF workflow ${workflow.id} based on configuration before updated`);
|
|
311
357
|
}
|
|
312
358
|
trigger.on(workflow);
|
|
359
|
+
this.getLogger(workflow.id).info(`toggle ON workflow ${workflow.id}`);
|
|
313
360
|
this.enabledCache.set(workflow.id, workflow);
|
|
314
361
|
} else {
|
|
315
362
|
trigger.off(workflow);
|
|
363
|
+
this.getLogger(workflow.id).info(`toggle OFF workflow ${workflow.id}`);
|
|
316
364
|
this.enabledCache.delete(workflow.id);
|
|
317
365
|
}
|
|
318
366
|
if (!silent) {
|
|
@@ -464,21 +512,20 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
464
512
|
throw err;
|
|
465
513
|
}
|
|
466
514
|
this.getLogger(workflow.id).info(`execution of workflow ${workflow.id} created as ${execution.id}`);
|
|
467
|
-
|
|
515
|
+
if (!workflow.stats) {
|
|
516
|
+
workflow.stats = await workflow.getStats({ transaction });
|
|
517
|
+
}
|
|
518
|
+
await workflow.stats.increment("executed", { transaction });
|
|
468
519
|
if (this.db.options.dialect !== "postgres") {
|
|
469
|
-
await workflow.reload({ transaction });
|
|
520
|
+
await workflow.stats.reload({ transaction });
|
|
521
|
+
}
|
|
522
|
+
if (!workflow.versionStats) {
|
|
523
|
+
workflow.versionStats = await workflow.getVersionStats({ transaction });
|
|
524
|
+
}
|
|
525
|
+
await workflow.versionStats.increment("executed", { transaction });
|
|
526
|
+
if (this.db.options.dialect !== "postgres") {
|
|
527
|
+
await workflow.versionStats.reload({ transaction });
|
|
470
528
|
}
|
|
471
|
-
await workflow.constructor.update(
|
|
472
|
-
{
|
|
473
|
-
allExecuted: workflow.allExecuted
|
|
474
|
-
},
|
|
475
|
-
{
|
|
476
|
-
where: {
|
|
477
|
-
key: workflow.key
|
|
478
|
-
},
|
|
479
|
-
transaction
|
|
480
|
-
}
|
|
481
|
-
);
|
|
482
529
|
if (!sameTransaction) {
|
|
483
530
|
await transaction.commit();
|
|
484
531
|
}
|
|
@@ -632,10 +679,16 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
632
679
|
/**
|
|
633
680
|
* @experimental
|
|
634
681
|
*/
|
|
635
|
-
async toggleTaskStatus(task,
|
|
682
|
+
async toggleTaskStatus(task, on, { transaction }) {
|
|
636
683
|
const { db } = this.app;
|
|
637
684
|
const repository = db.getRepository("workflowTasks");
|
|
638
|
-
if (
|
|
685
|
+
if (on) {
|
|
686
|
+
await repository.updateOrCreate({
|
|
687
|
+
filterKeys: ["key", "type"],
|
|
688
|
+
values: task,
|
|
689
|
+
transaction
|
|
690
|
+
});
|
|
691
|
+
} else {
|
|
639
692
|
await repository.destroy({
|
|
640
693
|
filter: {
|
|
641
694
|
type: task.type,
|
|
@@ -643,17 +696,12 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
643
696
|
},
|
|
644
697
|
transaction
|
|
645
698
|
});
|
|
646
|
-
} else {
|
|
647
|
-
await repository.updateOrCreate({
|
|
648
|
-
filterKeys: ["key", "type"],
|
|
649
|
-
values: task,
|
|
650
|
-
transaction
|
|
651
|
-
});
|
|
652
699
|
}
|
|
653
700
|
if (task.userId) {
|
|
654
701
|
const counts = await repository.countAll({
|
|
655
702
|
where: {
|
|
656
|
-
userId: task.userId
|
|
703
|
+
userId: task.userId,
|
|
704
|
+
workflowId: { [import_database.Op.ne]: null }
|
|
657
705
|
},
|
|
658
706
|
transaction
|
|
659
707
|
}) || [];
|
|
@@ -44,16 +44,9 @@ export default class Processor {
|
|
|
44
44
|
* @experimental
|
|
45
45
|
*/
|
|
46
46
|
nodesMap: Map<number, FlowNodeModel>;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
jobsMap: Map<number, JobModel>;
|
|
51
|
-
/**
|
|
52
|
-
* @experimental
|
|
53
|
-
*/
|
|
54
|
-
jobsMapByNodeKey: {
|
|
55
|
-
[key: string]: any;
|
|
56
|
-
};
|
|
47
|
+
private jobsMapByNodeKey;
|
|
48
|
+
private jobResultsMapByNodeKey;
|
|
49
|
+
private jobsToSave;
|
|
57
50
|
/**
|
|
58
51
|
* @experimental
|
|
59
52
|
*/
|
|
@@ -72,7 +65,7 @@ export default class Processor {
|
|
|
72
65
|
/**
|
|
73
66
|
* @experimental
|
|
74
67
|
*/
|
|
75
|
-
saveJob(payload: JobModel | Record<string, any>):
|
|
68
|
+
saveJob(payload: JobModel | Record<string, any>): JobModel;
|
|
76
69
|
/**
|
|
77
70
|
* @experimental
|
|
78
71
|
*/
|
package/dist/server/Processor.js
CHANGED
|
@@ -78,14 +78,9 @@ class Processor {
|
|
|
78
78
|
* @experimental
|
|
79
79
|
*/
|
|
80
80
|
nodesMap = /* @__PURE__ */ new Map();
|
|
81
|
-
/**
|
|
82
|
-
* @experimental
|
|
83
|
-
*/
|
|
84
|
-
jobsMap = /* @__PURE__ */ new Map();
|
|
85
|
-
/**
|
|
86
|
-
* @experimental
|
|
87
|
-
*/
|
|
88
81
|
jobsMapByNodeKey = {};
|
|
82
|
+
jobResultsMapByNodeKey = {};
|
|
83
|
+
jobsToSave = /* @__PURE__ */ new Map();
|
|
89
84
|
/**
|
|
90
85
|
* @experimental
|
|
91
86
|
*/
|
|
@@ -107,9 +102,9 @@ class Processor {
|
|
|
107
102
|
}
|
|
108
103
|
makeJobs(jobs) {
|
|
109
104
|
jobs.forEach((job) => {
|
|
110
|
-
this.jobsMap.set(job.id, job);
|
|
111
105
|
const node = this.nodesMap.get(job.nodeId);
|
|
112
|
-
this.jobsMapByNodeKey[node.key] = job
|
|
106
|
+
this.jobsMapByNodeKey[node.key] = job;
|
|
107
|
+
this.jobResultsMapByNodeKey[node.key] = job.result;
|
|
113
108
|
});
|
|
114
109
|
}
|
|
115
110
|
async prepare() {
|
|
@@ -179,11 +174,10 @@ class Processor {
|
|
|
179
174
|
}
|
|
180
175
|
}
|
|
181
176
|
if (!(job instanceof import_database.Model)) {
|
|
182
|
-
job.upstreamId = prevJob instanceof import_database.Model ? prevJob.get("id") : null;
|
|
183
177
|
job.nodeId = node.id;
|
|
184
178
|
job.nodeKey = node.key;
|
|
185
179
|
}
|
|
186
|
-
const savedJob =
|
|
180
|
+
const savedJob = this.saveJob(job);
|
|
187
181
|
this.logger.info(
|
|
188
182
|
`execution (${this.execution.id}) run instruction [${node.type}] for node (${node.id}) finished as status: ${savedJob.status}`
|
|
189
183
|
);
|
|
@@ -230,6 +224,30 @@ class Processor {
|
|
|
230
224
|
return this.exec(instruction.resume.bind(instruction), node, job);
|
|
231
225
|
}
|
|
232
226
|
async exit(s) {
|
|
227
|
+
if (this.jobsToSave.size) {
|
|
228
|
+
const newJobs = [];
|
|
229
|
+
for (const job of this.jobsToSave.values()) {
|
|
230
|
+
if (job.isNewRecord) {
|
|
231
|
+
newJobs.push(job);
|
|
232
|
+
} else {
|
|
233
|
+
await job.save({ transaction: this.mainTransaction });
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (newJobs.length) {
|
|
237
|
+
const JobsModel = this.options.plugin.db.getModel("jobs");
|
|
238
|
+
await JobsModel.bulkCreate(
|
|
239
|
+
newJobs.map((job) => job.toJSON()),
|
|
240
|
+
{
|
|
241
|
+
transaction: this.mainTransaction,
|
|
242
|
+
returning: false
|
|
243
|
+
}
|
|
244
|
+
);
|
|
245
|
+
for (const job of newJobs) {
|
|
246
|
+
job.isNewRecord = false;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
this.jobsToSave.clear();
|
|
250
|
+
}
|
|
233
251
|
if (typeof s === "number") {
|
|
234
252
|
const status = this.constructor.StatusMap[s] ?? Math.sign(s);
|
|
235
253
|
await this.execution.update({ status }, { transaction: this.mainTransaction });
|
|
@@ -240,32 +258,29 @@ class Processor {
|
|
|
240
258
|
this.logger.info(`execution (${this.execution.id}) exiting with status ${this.execution.status}`);
|
|
241
259
|
return null;
|
|
242
260
|
}
|
|
243
|
-
// TODO(optimize)
|
|
244
261
|
/**
|
|
245
262
|
* @experimental
|
|
246
263
|
*/
|
|
247
|
-
|
|
264
|
+
saveJob(payload) {
|
|
248
265
|
const { database } = this.execution.constructor;
|
|
249
|
-
const { mainTransaction: transaction } = this;
|
|
250
266
|
const { model } = database.getCollection("jobs");
|
|
251
267
|
let job;
|
|
252
268
|
if (payload instanceof model) {
|
|
253
|
-
job =
|
|
254
|
-
|
|
255
|
-
job = await model.findByPk(payload.id, { transaction });
|
|
256
|
-
await job.update(payload, { transaction });
|
|
269
|
+
job = payload;
|
|
270
|
+
job.set("updatedAt", /* @__PURE__ */ new Date());
|
|
257
271
|
} else {
|
|
258
|
-
job =
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
);
|
|
272
|
+
job = model.build({
|
|
273
|
+
...payload,
|
|
274
|
+
id: this.options.plugin.snowflake.getUniqueID().toString(),
|
|
275
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
276
|
+
updatedAt: /* @__PURE__ */ new Date(),
|
|
277
|
+
executionId: this.execution.id
|
|
278
|
+
});
|
|
265
279
|
}
|
|
266
|
-
this.
|
|
280
|
+
this.jobsToSave.set(job.id, job);
|
|
267
281
|
this.lastSavedJob = job;
|
|
268
|
-
this.jobsMapByNodeKey[job.nodeKey] = job
|
|
282
|
+
this.jobsMapByNodeKey[job.nodeKey] = job;
|
|
283
|
+
this.jobResultsMapByNodeKey[job.nodeKey] = job.result;
|
|
269
284
|
return job;
|
|
270
285
|
}
|
|
271
286
|
/**
|
|
@@ -319,31 +334,19 @@ class Processor {
|
|
|
319
334
|
* @experimental
|
|
320
335
|
*/
|
|
321
336
|
findBranchParentJob(job, node) {
|
|
322
|
-
|
|
323
|
-
if (j.nodeId === node.id) {
|
|
324
|
-
return j;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
return null;
|
|
337
|
+
return this.jobsMapByNodeKey[node.key];
|
|
328
338
|
}
|
|
329
339
|
/**
|
|
330
340
|
* @experimental
|
|
331
341
|
*/
|
|
332
342
|
findBranchLastJob(node, job) {
|
|
333
|
-
const allJobs =
|
|
343
|
+
const allJobs = Object.values(this.jobsMapByNodeKey);
|
|
334
344
|
const branchJobs = [];
|
|
335
345
|
for (let n = this.findBranchEndNode(node); n && n !== node.upstream; n = n.upstream) {
|
|
336
346
|
branchJobs.push(...allJobs.filter((item) => item.nodeId === n.id));
|
|
337
347
|
}
|
|
338
|
-
branchJobs.sort((a, b) => a.
|
|
339
|
-
|
|
340
|
-
for (let j = branchJobs[i]; j && j.id !== job.id; j = this.jobsMap.get(j.upstreamId)) {
|
|
341
|
-
if (j.upstreamId === job.id) {
|
|
342
|
-
return branchJobs[i];
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
return null;
|
|
348
|
+
branchJobs.sort((a, b) => a.updatedAt.getTime() - b.updatedAt.getTime());
|
|
349
|
+
return branchJobs[branchJobs.length - 1] || null;
|
|
347
350
|
}
|
|
348
351
|
/**
|
|
349
352
|
* @experimental
|
|
@@ -362,12 +365,12 @@ class Processor {
|
|
|
362
365
|
for (let n = includeSelfScope ? node : this.findBranchParentNode(node); n; n = this.findBranchParentNode(n)) {
|
|
363
366
|
const instruction = this.options.plugin.instructions.get(n.type);
|
|
364
367
|
if (typeof (instruction == null ? void 0 : instruction.getScope) === "function") {
|
|
365
|
-
$scopes[n.id] = $scopes[n.key] = instruction.getScope(n, this.
|
|
368
|
+
$scopes[n.id] = $scopes[n.key] = instruction.getScope(n, this.jobResultsMapByNodeKey[n.key], this);
|
|
366
369
|
}
|
|
367
370
|
}
|
|
368
371
|
return {
|
|
369
372
|
$context: this.execution.context,
|
|
370
|
-
$jobsMapByNodeKey: this.
|
|
373
|
+
$jobsMapByNodeKey: this.jobResultsMapByNodeKey,
|
|
371
374
|
$system: systemFns,
|
|
372
375
|
$scopes,
|
|
373
376
|
$env: this.options.plugin.app.environment.getVariables()
|
|
@@ -51,7 +51,9 @@ async function create(context, next) {
|
|
|
51
51
|
const { whitelist, blacklist, updateAssociationValues, values, associatedIndex: workflowId } = context.action.params;
|
|
52
52
|
context.body = await db.sequelize.transaction(async (transaction) => {
|
|
53
53
|
const workflow = await repository.getSourceModel(transaction);
|
|
54
|
-
|
|
54
|
+
workflow.versionStats = await workflow.getVersionStats({ transaction });
|
|
55
|
+
const { executed } = workflow.versionStats;
|
|
56
|
+
if (executed) {
|
|
55
57
|
context.throw(400, "Node could not be created in executed workflow");
|
|
56
58
|
}
|
|
57
59
|
const instance = await repository.create({
|
|
@@ -143,9 +145,9 @@ async function destroy(context, next) {
|
|
|
143
145
|
const instance = await repository.findOne({
|
|
144
146
|
filterByTk,
|
|
145
147
|
fields: [...fields, "workflowId"],
|
|
146
|
-
appends: ["upstream", "downstream", "workflow"]
|
|
148
|
+
appends: ["upstream", "downstream", "workflow.versionStats.executed"]
|
|
147
149
|
});
|
|
148
|
-
if (instance.workflow.executed) {
|
|
150
|
+
if (instance.workflow.versionStats.executed) {
|
|
149
151
|
context.throw(400, "Nodes in executed workflow could not be deleted");
|
|
150
152
|
}
|
|
151
153
|
await db.sequelize.transaction(async (transaction) => {
|
|
@@ -202,10 +204,10 @@ async function update(context, next) {
|
|
|
202
204
|
context.body = await db.sequelize.transaction(async (transaction) => {
|
|
203
205
|
const { workflow } = await repository.findOne({
|
|
204
206
|
filterByTk,
|
|
205
|
-
appends: ["workflow.executed"],
|
|
207
|
+
appends: ["workflow.versionStats.executed"],
|
|
206
208
|
transaction
|
|
207
209
|
});
|
|
208
|
-
if (workflow.executed) {
|
|
210
|
+
if (workflow.versionStats.executed) {
|
|
209
211
|
context.throw(400, "Nodes in executed workflow could not be reconfigured");
|
|
210
212
|
}
|
|
211
213
|
return repository.update({
|
|
@@ -29,15 +29,17 @@ __export(workflowTasks_exports, {
|
|
|
29
29
|
countMine: () => countMine
|
|
30
30
|
});
|
|
31
31
|
module.exports = __toCommonJS(workflowTasks_exports);
|
|
32
|
+
var import_sequelize = require("sequelize");
|
|
32
33
|
var import_actions = require("@nocobase/actions");
|
|
33
34
|
async function countMine(context, next) {
|
|
34
35
|
const repository = import_actions.utils.getRepositoryFromParams(context);
|
|
35
36
|
context.body = await repository.countAll({
|
|
36
37
|
where: {
|
|
37
|
-
userId: context.state.currentUser.id
|
|
38
|
+
userId: context.state.currentUser.id,
|
|
39
|
+
workflowId: { [import_sequelize.Op.ne]: null }
|
|
38
40
|
}
|
|
39
41
|
}) || [];
|
|
40
|
-
next();
|
|
42
|
+
await next();
|
|
41
43
|
}
|
|
42
44
|
// Annotate the CommonJS export names for ESM import in node:
|
|
43
45
|
0 && (module.exports = {
|
|
@@ -53,8 +53,11 @@ async function update(context, next) {
|
|
|
53
53
|
whitelist: ["title", "description", "enabled", "triggerTitle", "config", "options"]
|
|
54
54
|
});
|
|
55
55
|
if (Object.keys(values).includes("config")) {
|
|
56
|
-
const workflow = await repository.
|
|
57
|
-
|
|
56
|
+
const workflow = await repository.findOne({
|
|
57
|
+
filterByTk,
|
|
58
|
+
appends: ["versionStats"]
|
|
59
|
+
});
|
|
60
|
+
if (workflow.versionStats.executed) {
|
|
58
61
|
return context.throw(400, "config of executed workflow can not be updated");
|
|
59
62
|
}
|
|
60
63
|
}
|
|
@@ -7,9 +7,11 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
var __create = Object.create;
|
|
10
11
|
var __defProp = Object.defineProperty;
|
|
11
12
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
13
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
13
15
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
16
|
var __export = (target, all) => {
|
|
15
17
|
for (var name in all)
|
|
@@ -23,53 +25,19 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
23
25
|
}
|
|
24
26
|
return to;
|
|
25
27
|
};
|
|
28
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
29
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
30
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
31
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
32
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
33
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
34
|
+
mod
|
|
35
|
+
));
|
|
26
36
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
37
|
var executions_exports = {};
|
|
28
38
|
__export(executions_exports, {
|
|
29
39
|
default: () => executions_default
|
|
30
40
|
});
|
|
31
41
|
module.exports = __toCommonJS(executions_exports);
|
|
32
|
-
var
|
|
33
|
-
|
|
34
|
-
group: "log"
|
|
35
|
-
},
|
|
36
|
-
migrationRules: ["schema-only"],
|
|
37
|
-
name: "executions",
|
|
38
|
-
shared: true,
|
|
39
|
-
fields: [
|
|
40
|
-
{
|
|
41
|
-
type: "belongsTo",
|
|
42
|
-
name: "workflow"
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
type: "string",
|
|
46
|
-
name: "key"
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
type: "string",
|
|
50
|
-
name: "eventKey",
|
|
51
|
-
unique: true
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
type: "hasMany",
|
|
55
|
-
name: "jobs",
|
|
56
|
-
onDelete: "CASCADE"
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
type: "json",
|
|
60
|
-
name: "context"
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
type: "integer",
|
|
64
|
-
name: "status"
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
type: "json",
|
|
68
|
-
name: "stack"
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
type: "json",
|
|
72
|
-
name: "output"
|
|
73
|
-
}
|
|
74
|
-
]
|
|
75
|
-
};
|
|
42
|
+
var import_executions = __toESM(require("../../common/collections/executions"));
|
|
43
|
+
var executions_default = import_executions.default;
|