@nocobase/plugin-workflow 1.6.0-alpha.3 → 1.6.0-alpha.31
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/4d75ef32f02d7285.js +10 -0
- package/dist/client/56ce448358002e64.js +10 -0
- package/dist/client/58bb427e05b600de.js +10 -0
- package/dist/client/FlowContext.d.ts +2 -0
- package/dist/client/WorkflowTasks.d.ts +18 -0
- package/dist/client/{settings/customizeSubmitToWorkflowActionSettings.d.ts → components/WorkflowTitle.d.ts} +1 -2
- package/dist/client/components/index.d.ts +1 -0
- package/dist/client/index.d.ts +20 -7
- package/dist/client/index.js +1 -1
- package/dist/client/nodes/calculation.d.ts +3 -2
- package/dist/client/nodes/condition.d.ts +1 -0
- package/dist/client/nodes/create.d.ts +3 -2
- package/dist/client/nodes/destroy.d.ts +2 -0
- package/dist/client/nodes/end.d.ts +2 -0
- package/dist/client/nodes/index.d.ts +1 -0
- package/dist/client/nodes/output.d.ts +31 -0
- package/dist/client/nodes/query.d.ts +5 -4
- package/dist/client/nodes/update.d.ts +3 -2
- package/dist/client/settings/BindWorkflowConfig.d.ts +10 -0
- package/dist/client/triggers/schedule/ScheduleModes.d.ts +5 -2
- package/dist/client/triggers/schedule/index.d.ts +2 -0
- package/dist/client/variable.d.ts +17 -6
- package/dist/externalVersion.js +14 -14
- package/dist/locale/en-US.json +3 -1
- package/dist/locale/it-IT.json +100 -0
- package/dist/locale/zh-CN.json +14 -7
- 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 +14 -7
- package/dist/server/Plugin.js +155 -46
- package/dist/server/Processor.d.ts +1 -0
- package/dist/server/Processor.js +6 -5
- package/dist/server/actions/index.js +3 -1
- package/dist/server/actions/workflowTasks.d.ts +10 -0
- package/dist/server/actions/workflowTasks.js +45 -0
- package/dist/server/actions/workflows.d.ts +0 -1
- package/dist/server/actions/workflows.js +5 -7
- package/dist/server/collections/executions.js +9 -0
- package/dist/server/collections/flow_nodes.js +1 -0
- package/dist/server/collections/jobs.js +1 -0
- package/dist/server/collections/workflowTasks.d.ts +10 -0
- package/dist/server/collections/workflowTasks.js +64 -0
- package/dist/server/collections/workflows.js +8 -1
- package/dist/server/instructions/CreateInstruction.js +1 -1
- package/dist/server/instructions/DestroyInstruction.js +1 -1
- package/dist/server/instructions/UpdateInstruction.js +1 -1
- package/dist/server/repositories/WorkflowTasksRepository.d.ts +12 -0
- package/dist/server/repositories/WorkflowTasksRepository.js +42 -0
- package/dist/server/triggers/CollectionTrigger.d.ts +6 -6
- package/dist/server/triggers/CollectionTrigger.js +54 -31
- package/dist/server/triggers/ScheduleTrigger/DateFieldScheduleTrigger.d.ts +5 -1
- package/dist/server/triggers/ScheduleTrigger/DateFieldScheduleTrigger.js +53 -14
- package/dist/server/triggers/ScheduleTrigger/StaticScheduleTrigger.d.ts +1 -0
- package/dist/server/triggers/ScheduleTrigger/StaticScheduleTrigger.js +3 -0
- package/dist/server/triggers/ScheduleTrigger/index.d.ts +2 -2
- package/dist/server/triggers/ScheduleTrigger/index.js +21 -3
- package/dist/server/triggers/index.d.ts +4 -1
- package/dist/server/types/WorkflowTask.d.ts +14 -0
- package/dist/server/types/WorkflowTask.js +24 -0
- package/dist/server/types/index.d.ts +1 -0
- package/dist/swagger/index.d.ts +3 -3
- package/dist/swagger/index.js +6 -6
- package/package.json +3 -3
- package/dist/client/5ed8ff0f70ed5911.js +0 -10
- package/dist/client/92877729dbcede8f.js +0 -10
- package/dist/client/e7b9d67c6a964bec.js +0 -10
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_sequelize = require("sequelize");
|
|
44
45
|
var import_lru_cache = __toESM(require("lru-cache"));
|
|
45
46
|
var import_database = require("@nocobase/database");
|
|
46
47
|
var import_server = require("@nocobase/server");
|
|
@@ -59,6 +60,7 @@ var import_DestroyInstruction = __toESM(require("./instructions/DestroyInstructi
|
|
|
59
60
|
var import_QueryInstruction = __toESM(require("./instructions/QueryInstruction"));
|
|
60
61
|
var import_UpdateInstruction = __toESM(require("./instructions/UpdateInstruction"));
|
|
61
62
|
var import_WorkflowRepository = __toESM(require("./repositories/WorkflowRepository"));
|
|
63
|
+
var import_WorkflowTasksRepository = __toESM(require("./repositories/WorkflowTasksRepository"));
|
|
62
64
|
class PluginWorkflowServer extends import_server.Plugin {
|
|
63
65
|
instructions = new import_utils.Registry();
|
|
64
66
|
triggers = new import_utils.Registry();
|
|
@@ -126,7 +128,7 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
126
128
|
/**
|
|
127
129
|
* @experimental
|
|
128
130
|
*/
|
|
129
|
-
getLogger(workflowId) {
|
|
131
|
+
getLogger(workflowId = "dispatcher") {
|
|
130
132
|
const now = /* @__PURE__ */ new Date();
|
|
131
133
|
const date = `${now.getFullYear()}-${`0${now.getMonth() + 1}`.slice(-2)}-${`0${now.getDate()}`.slice(-2)}`;
|
|
132
134
|
const key = `${date}-${workflowId}}`;
|
|
@@ -191,7 +193,8 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
191
193
|
}
|
|
192
194
|
async beforeLoad() {
|
|
193
195
|
this.db.registerRepositories({
|
|
194
|
-
WorkflowRepository: import_WorkflowRepository.default
|
|
196
|
+
WorkflowRepository: import_WorkflowRepository.default,
|
|
197
|
+
WorkflowTasksRepository: import_WorkflowTasksRepository.default
|
|
195
198
|
});
|
|
196
199
|
}
|
|
197
200
|
/**
|
|
@@ -226,13 +229,15 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
226
229
|
"executions:destroy",
|
|
227
230
|
"flow_nodes:update",
|
|
228
231
|
"flow_nodes:destroy",
|
|
229
|
-
"flow_nodes:test"
|
|
232
|
+
"flow_nodes:test",
|
|
233
|
+
"jobs:get"
|
|
230
234
|
]
|
|
231
235
|
});
|
|
232
236
|
this.app.acl.registerSnippet({
|
|
233
237
|
name: "ui.workflows",
|
|
234
238
|
actions: ["workflows:list"]
|
|
235
239
|
});
|
|
240
|
+
this.app.acl.allow("workflowTasks", "countMine", "loggedIn");
|
|
236
241
|
this.app.acl.allow("*", ["trigger"], "loggedIn");
|
|
237
242
|
this.db.addMigrations({
|
|
238
243
|
namespace: this.name,
|
|
@@ -256,7 +261,6 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
256
261
|
(model, { transaction }) => this.toggle(model, false, { transaction })
|
|
257
262
|
);
|
|
258
263
|
this.app.on("afterStart", async () => {
|
|
259
|
-
this.app.setMaintainingMessage("check for not started executions");
|
|
260
264
|
this.ready = true;
|
|
261
265
|
const collection = db.getCollection("workflows");
|
|
262
266
|
const workflows = await collection.repository.find({
|
|
@@ -266,8 +270,14 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
266
270
|
this.toggle(workflow, true, { silent: true });
|
|
267
271
|
});
|
|
268
272
|
this.checker = setInterval(() => {
|
|
273
|
+
this.getLogger("dispatcher").info(`(cycling) check for queueing executions`);
|
|
269
274
|
this.dispatch();
|
|
270
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");
|
|
271
281
|
this.dispatch();
|
|
272
282
|
});
|
|
273
283
|
this.app.on("beforeStop", async () => {
|
|
@@ -323,10 +333,19 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
323
333
|
logger.debug(`ignored event data:`, context);
|
|
324
334
|
return;
|
|
325
335
|
}
|
|
326
|
-
if (!options.manually && !workflow.enabled) {
|
|
336
|
+
if (!options.force && !options.manually && !workflow.enabled) {
|
|
327
337
|
logger.warn(`workflow ${workflow.id} is not enabled, event will be ignored`);
|
|
328
338
|
return;
|
|
329
339
|
}
|
|
340
|
+
const duplicated = this.events.find(([w, c, { eventKey }]) => {
|
|
341
|
+
if (eventKey && options.eventKey) {
|
|
342
|
+
return eventKey === options.eventKey;
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
if (duplicated) {
|
|
346
|
+
logger.warn(`event of workflow ${workflow.id} is duplicated (${options.eventKey}), event will be ignored`);
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
330
349
|
if (context == null) {
|
|
331
350
|
logger.warn(`workflow ${workflow.id} event data context is null, event will be ignored`);
|
|
332
351
|
return;
|
|
@@ -340,9 +359,10 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
340
359
|
logger.info(`new event triggered, now events: ${this.events.length}`);
|
|
341
360
|
logger.debug(`event data:`, { context });
|
|
342
361
|
if (this.events.length > 1) {
|
|
362
|
+
logger.info(`new event is pending to be prepared after previous preparation is finished`);
|
|
343
363
|
return;
|
|
344
364
|
}
|
|
345
|
-
|
|
365
|
+
setImmediate(this.prepare);
|
|
346
366
|
}
|
|
347
367
|
async triggerSync(workflow, context, { deferred, ...options } = {}) {
|
|
348
368
|
let execution;
|
|
@@ -367,33 +387,63 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
367
387
|
`execution (${job.execution.id}) resuming from job (${job.id}) added to pending list`
|
|
368
388
|
);
|
|
369
389
|
this.pending.push([job.execution, job]);
|
|
390
|
+
if (this.executing) {
|
|
391
|
+
await this.executing;
|
|
392
|
+
}
|
|
370
393
|
this.dispatch();
|
|
371
394
|
}
|
|
372
395
|
/**
|
|
373
396
|
* Start a deferred execution
|
|
374
397
|
* @experimental
|
|
375
398
|
*/
|
|
376
|
-
start(execution) {
|
|
399
|
+
async start(execution) {
|
|
377
400
|
if (execution.status !== import_constants.EXECUTION_STATUS.STARTED) {
|
|
378
401
|
return;
|
|
379
402
|
}
|
|
403
|
+
this.getLogger(execution.workflowId).info(`starting deferred execution (${execution.id})`);
|
|
380
404
|
this.pending.push([execution]);
|
|
405
|
+
if (this.executing) {
|
|
406
|
+
await this.executing;
|
|
407
|
+
}
|
|
381
408
|
this.dispatch();
|
|
382
409
|
}
|
|
383
|
-
|
|
384
|
-
|
|
410
|
+
async validateEvent(workflow, context, options) {
|
|
411
|
+
const trigger = this.triggers.get(workflow.type);
|
|
412
|
+
const triggerValid = await trigger.validateEvent(workflow, context, options);
|
|
413
|
+
if (!triggerValid) {
|
|
414
|
+
return false;
|
|
415
|
+
}
|
|
416
|
+
const { stack } = options;
|
|
417
|
+
let valid = true;
|
|
418
|
+
if ((stack == null ? void 0 : stack.length) > 0) {
|
|
419
|
+
const existed = await workflow.countExecutions({
|
|
420
|
+
where: {
|
|
421
|
+
id: stack
|
|
422
|
+
},
|
|
423
|
+
transaction: options.transaction
|
|
424
|
+
});
|
|
425
|
+
const limitCount = workflow.options.stackLimit || 1;
|
|
426
|
+
if (existed >= limitCount) {
|
|
427
|
+
this.getLogger(workflow.id).warn(
|
|
428
|
+
`workflow ${workflow.id} has already been triggered in stacks executions (${stack}), and max call coont is ${limitCount}, newly triggering will be skipped.`
|
|
429
|
+
);
|
|
430
|
+
valid = false;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return valid;
|
|
385
434
|
}
|
|
386
435
|
async createExecution(workflow, context, options) {
|
|
436
|
+
var _a;
|
|
387
437
|
const { deferred } = options;
|
|
388
438
|
const transaction = await this.useDataSourceTransaction("main", options.transaction, true);
|
|
389
439
|
const sameTransaction = options.transaction === transaction;
|
|
390
|
-
const
|
|
391
|
-
const valid = await trigger.validateEvent(workflow, context, { ...options, transaction });
|
|
440
|
+
const valid = await this.validateEvent(workflow, context, { ...options, transaction });
|
|
392
441
|
if (!valid) {
|
|
393
442
|
if (!sameTransaction) {
|
|
394
443
|
await transaction.commit();
|
|
395
444
|
}
|
|
396
|
-
|
|
445
|
+
(_a = options.onTriggerFail) == null ? void 0 : _a.call(options, workflow, context, options);
|
|
446
|
+
return Promise.reject(new Error("event is not valid"));
|
|
397
447
|
}
|
|
398
448
|
let execution;
|
|
399
449
|
try {
|
|
@@ -402,6 +452,7 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
402
452
|
context,
|
|
403
453
|
key: workflow.key,
|
|
404
454
|
eventKey: options.eventKey ?? (0, import_crypto.randomUUID)(),
|
|
455
|
+
stack: options.stack,
|
|
405
456
|
status: deferred ? import_constants.EXECUTION_STATUS.STARTED : import_constants.EXECUTION_STATUS.QUEUEING
|
|
406
457
|
},
|
|
407
458
|
{ transaction }
|
|
@@ -441,7 +492,7 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
441
492
|
const event = this.events.shift();
|
|
442
493
|
this.eventsCount = this.events.length;
|
|
443
494
|
if (!event) {
|
|
444
|
-
this.getLogger("dispatcher").
|
|
495
|
+
this.getLogger("dispatcher").info(`events queue is empty, no need to prepare`);
|
|
445
496
|
return;
|
|
446
497
|
}
|
|
447
498
|
const logger = this.getLogger(event[0].id);
|
|
@@ -451,12 +502,16 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
451
502
|
if ((execution == null ? void 0 : execution.status) === import_constants.EXECUTION_STATUS.QUEUEING && !this.executing && !this.pending.length) {
|
|
452
503
|
this.pending.push([execution]);
|
|
453
504
|
}
|
|
454
|
-
} catch (
|
|
455
|
-
logger.error(`failed to create execution
|
|
505
|
+
} catch (error) {
|
|
506
|
+
logger.error(`failed to create execution:`, { error });
|
|
456
507
|
}
|
|
457
508
|
if (this.events.length) {
|
|
458
509
|
await this.prepare();
|
|
459
510
|
} else {
|
|
511
|
+
this.getLogger("dispatcher").info("no more events need to be prepared, dispatching...");
|
|
512
|
+
if (this.executing) {
|
|
513
|
+
await this.executing;
|
|
514
|
+
}
|
|
460
515
|
this.dispatch();
|
|
461
516
|
}
|
|
462
517
|
};
|
|
@@ -474,59 +529,78 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
474
529
|
}
|
|
475
530
|
this.executing = (async () => {
|
|
476
531
|
let next = null;
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
"workflow.enabled": true,
|
|
486
|
-
"workflow.id": {
|
|
487
|
-
[import_database.Op.not]: null
|
|
488
|
-
}
|
|
532
|
+
if (this.pending.length) {
|
|
533
|
+
next = this.pending.shift();
|
|
534
|
+
this.getLogger(next[0].workflowId).info(`pending execution (${next[0].id}) ready to process`);
|
|
535
|
+
} else {
|
|
536
|
+
try {
|
|
537
|
+
await this.db.sequelize.transaction(
|
|
538
|
+
{
|
|
539
|
+
isolationLevel: this.db.options.dialect === "sqlite" ? [][0] : import_sequelize.Transaction.ISOLATION_LEVELS.REPEATABLE_READ
|
|
489
540
|
},
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
541
|
+
async (transaction) => {
|
|
542
|
+
const execution = await this.db.getRepository("executions").findOne({
|
|
543
|
+
filter: {
|
|
544
|
+
status: import_constants.EXECUTION_STATUS.QUEUEING,
|
|
545
|
+
"workflow.enabled": true
|
|
546
|
+
},
|
|
547
|
+
sort: "id",
|
|
548
|
+
transaction
|
|
549
|
+
});
|
|
550
|
+
if (execution) {
|
|
551
|
+
this.getLogger(execution.workflowId).info(`execution (${execution.id}) fetched from db`);
|
|
552
|
+
await execution.update(
|
|
553
|
+
{
|
|
554
|
+
status: import_constants.EXECUTION_STATUS.STARTED
|
|
555
|
+
},
|
|
556
|
+
{ transaction }
|
|
557
|
+
);
|
|
558
|
+
execution.workflow = this.enabledCache.get(execution.workflowId);
|
|
559
|
+
next = [execution];
|
|
560
|
+
} else {
|
|
561
|
+
this.getLogger("dispatcher").info(`no execution in db queued to process`);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
);
|
|
565
|
+
} catch (error) {
|
|
566
|
+
this.getLogger("dispatcher").error(`fetching execution from db failed: ${error.message}`, { error });
|
|
505
567
|
}
|
|
506
568
|
}
|
|
569
|
+
if (next) {
|
|
570
|
+
await this.process(...next);
|
|
571
|
+
}
|
|
572
|
+
this.executing = null;
|
|
573
|
+
if (next || this.pending.length) {
|
|
574
|
+
this.getLogger("dispatcher").info(`last process finished, will do another dispatch`);
|
|
575
|
+
this.dispatch();
|
|
576
|
+
}
|
|
507
577
|
})();
|
|
508
578
|
}
|
|
579
|
+
createProcessor(execution, options = {}) {
|
|
580
|
+
return new import_Processor.default(execution, { ...options, plugin: this });
|
|
581
|
+
}
|
|
509
582
|
async process(execution, job, options = {}) {
|
|
510
583
|
var _a, _b;
|
|
584
|
+
const logger = this.getLogger(execution.workflowId);
|
|
511
585
|
if (execution.status === import_constants.EXECUTION_STATUS.QUEUEING) {
|
|
512
586
|
const transaction = await this.useDataSourceTransaction("main", options.transaction);
|
|
513
587
|
await execution.update({ status: import_constants.EXECUTION_STATUS.STARTED }, { transaction });
|
|
588
|
+
logger.info(`queueing execution (${execution.id}) from pending list updated to started`);
|
|
514
589
|
}
|
|
515
|
-
const logger = this.getLogger(execution.workflowId);
|
|
516
590
|
const processor = this.createProcessor(execution, options);
|
|
517
591
|
logger.info(`execution (${execution.id}) ${job ? "resuming" : "starting"}...`);
|
|
518
592
|
try {
|
|
519
593
|
await (job ? processor.resume(job) : processor.start());
|
|
520
594
|
logger.info(`execution (${execution.id}) finished with status: ${execution.status}`, { execution });
|
|
521
595
|
if (execution.status && ((_b = (_a = execution.workflow.options) == null ? void 0 : _a.deleteExecutionOnStatus) == null ? void 0 : _b.includes(execution.status))) {
|
|
522
|
-
await execution.destroy();
|
|
596
|
+
await execution.destroy({ transaction: processor.mainTransaction });
|
|
523
597
|
}
|
|
524
598
|
} catch (err) {
|
|
525
599
|
logger.error(`execution (${execution.id}) error: ${err.message}`, err);
|
|
526
600
|
}
|
|
527
601
|
return processor;
|
|
528
602
|
}
|
|
529
|
-
async execute(workflow,
|
|
603
|
+
async execute(workflow, values, options = {}) {
|
|
530
604
|
const trigger = this.triggers.get(workflow.type);
|
|
531
605
|
if (!trigger) {
|
|
532
606
|
throw new Error(`trigger type "${workflow.type}" of workflow ${workflow.id} is not registered`);
|
|
@@ -534,7 +608,7 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
534
608
|
if (!trigger.execute) {
|
|
535
609
|
throw new Error(`"execute" method of trigger ${workflow.type} is not implemented`);
|
|
536
610
|
}
|
|
537
|
-
return trigger.execute(workflow,
|
|
611
|
+
return trigger.execute(workflow, values, options);
|
|
538
612
|
}
|
|
539
613
|
/**
|
|
540
614
|
* @experimental
|
|
@@ -555,4 +629,39 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
555
629
|
return db.sequelize.transaction();
|
|
556
630
|
}
|
|
557
631
|
}
|
|
632
|
+
/**
|
|
633
|
+
* @experimental
|
|
634
|
+
*/
|
|
635
|
+
async toggleTaskStatus(task, done, { transaction }) {
|
|
636
|
+
const { db } = this.app;
|
|
637
|
+
const repository = db.getRepository("workflowTasks");
|
|
638
|
+
if (done) {
|
|
639
|
+
await repository.destroy({
|
|
640
|
+
filter: {
|
|
641
|
+
type: task.type,
|
|
642
|
+
key: `${task.key}`
|
|
643
|
+
},
|
|
644
|
+
transaction
|
|
645
|
+
});
|
|
646
|
+
} else {
|
|
647
|
+
await repository.updateOrCreate({
|
|
648
|
+
filterKeys: ["key", "type"],
|
|
649
|
+
values: task,
|
|
650
|
+
transaction
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
if (task.userId) {
|
|
654
|
+
const counts = await repository.countAll({
|
|
655
|
+
where: {
|
|
656
|
+
userId: task.userId
|
|
657
|
+
},
|
|
658
|
+
transaction
|
|
659
|
+
}) || [];
|
|
660
|
+
this.app.emit("ws:sendToTag", {
|
|
661
|
+
tagKey: "userId",
|
|
662
|
+
tagValue: `${task.userId}`,
|
|
663
|
+
message: { type: "workflow:tasks:updated", payload: counts }
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
}
|
|
558
667
|
}
|
package/dist/server/Processor.js
CHANGED
|
@@ -117,11 +117,11 @@ class Processor {
|
|
|
117
117
|
execution,
|
|
118
118
|
options: { plugin }
|
|
119
119
|
} = this;
|
|
120
|
-
if (!execution.workflow) {
|
|
121
|
-
execution.workflow = plugin.enabledCache.get(execution.workflowId);
|
|
122
|
-
}
|
|
123
120
|
this.mainTransaction = plugin.useDataSourceTransaction("main", this.transaction);
|
|
124
121
|
const transaction = this.mainTransaction;
|
|
122
|
+
if (!execution.workflow) {
|
|
123
|
+
execution.workflow = plugin.enabledCache.get(execution.workflowId) || await execution.getWorkflow({ transaction });
|
|
124
|
+
}
|
|
125
125
|
const nodes = await execution.workflow.getNodes({ transaction });
|
|
126
126
|
this.makeNodes(nodes);
|
|
127
127
|
const jobs = await execution.getJobs({
|
|
@@ -212,7 +212,7 @@ class Processor {
|
|
|
212
212
|
if (parentNode) {
|
|
213
213
|
this.logger.debug(`not on main, recall to parent entry node (${node.id})})`);
|
|
214
214
|
await this.recall(parentNode, job);
|
|
215
|
-
return
|
|
215
|
+
return null;
|
|
216
216
|
}
|
|
217
217
|
return this.exit(job.status);
|
|
218
218
|
}
|
|
@@ -369,7 +369,8 @@ class Processor {
|
|
|
369
369
|
$context: this.execution.context,
|
|
370
370
|
$jobsMapByNodeKey: this.jobsMapByNodeKey,
|
|
371
371
|
$system: systemFns,
|
|
372
|
-
$scopes
|
|
372
|
+
$scopes,
|
|
373
|
+
$env: this.options.plugin.app.environment.getVariables()
|
|
373
374
|
};
|
|
374
375
|
}
|
|
375
376
|
/**
|
|
@@ -42,6 +42,7 @@ module.exports = __toCommonJS(actions_exports);
|
|
|
42
42
|
var workflows = __toESM(require("./workflows"));
|
|
43
43
|
var nodes = __toESM(require("./nodes"));
|
|
44
44
|
var executions = __toESM(require("./executions"));
|
|
45
|
+
var workflowTasks = __toESM(require("./workflowTasks"));
|
|
45
46
|
function make(name, mod) {
|
|
46
47
|
return Object.keys(mod).reduce(
|
|
47
48
|
(result, key) => ({
|
|
@@ -62,6 +63,7 @@ function actions_default({ app }) {
|
|
|
62
63
|
destroy: nodes.destroy,
|
|
63
64
|
test: nodes.test
|
|
64
65
|
}),
|
|
65
|
-
...make("executions", executions)
|
|
66
|
+
...make("executions", executions),
|
|
67
|
+
...make("workflowTasks", workflowTasks)
|
|
66
68
|
});
|
|
67
69
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
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
|
+
import { Context } from '@nocobase/actions';
|
|
10
|
+
export declare function countMine(context: Context, next: any): Promise<void>;
|
|
@@ -0,0 +1,45 @@
|
|
|
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 workflowTasks_exports = {};
|
|
28
|
+
__export(workflowTasks_exports, {
|
|
29
|
+
countMine: () => countMine
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(workflowTasks_exports);
|
|
32
|
+
var import_actions = require("@nocobase/actions");
|
|
33
|
+
async function countMine(context, next) {
|
|
34
|
+
const repository = import_actions.utils.getRepositoryFromParams(context);
|
|
35
|
+
context.body = await repository.countAll({
|
|
36
|
+
where: {
|
|
37
|
+
userId: context.state.currentUser.id
|
|
38
|
+
}
|
|
39
|
+
}) || [];
|
|
40
|
+
next();
|
|
41
|
+
}
|
|
42
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
43
|
+
0 && (module.exports = {
|
|
44
|
+
countMine
|
|
45
|
+
});
|
|
@@ -15,5 +15,4 @@ export declare function sync(context: Context, next: any): Promise<void>;
|
|
|
15
15
|
* @deprecated
|
|
16
16
|
* Keep for action trigger compatibility
|
|
17
17
|
*/
|
|
18
|
-
export declare function trigger(context: Context, next: any): Promise<any>;
|
|
19
18
|
export declare function execute(context: Context, next: any): Promise<any>;
|
|
@@ -40,7 +40,6 @@ __export(workflows_exports, {
|
|
|
40
40
|
execute: () => execute,
|
|
41
41
|
revision: () => revision,
|
|
42
42
|
sync: () => sync,
|
|
43
|
-
trigger: () => trigger,
|
|
44
43
|
update: () => update
|
|
45
44
|
});
|
|
46
45
|
module.exports = __toCommonJS(workflows_exports);
|
|
@@ -116,12 +115,12 @@ async function sync(context, next) {
|
|
|
116
115
|
context.status = 204;
|
|
117
116
|
await next();
|
|
118
117
|
}
|
|
119
|
-
async function trigger(context, next) {
|
|
120
|
-
return next();
|
|
121
|
-
}
|
|
122
118
|
async function execute(context, next) {
|
|
123
119
|
const plugin = context.app.pm.get(import_Plugin.default);
|
|
124
|
-
const { filterByTk, autoRevision } = context.action.params;
|
|
120
|
+
const { filterByTk, values, autoRevision } = context.action.params;
|
|
121
|
+
if (!values) {
|
|
122
|
+
return context.throw(400, "values is required");
|
|
123
|
+
}
|
|
125
124
|
if (!filterByTk) {
|
|
126
125
|
return context.throw(400, "filterByTk is required");
|
|
127
126
|
}
|
|
@@ -137,7 +136,7 @@ async function execute(context, next) {
|
|
|
137
136
|
const { executed } = workflow;
|
|
138
137
|
let processor;
|
|
139
138
|
try {
|
|
140
|
-
processor = await plugin.execute(workflow,
|
|
139
|
+
processor = await plugin.execute(workflow, values, { manually: true });
|
|
141
140
|
if (!processor) {
|
|
142
141
|
return context.throw(400, "workflow not triggered");
|
|
143
142
|
}
|
|
@@ -174,6 +173,5 @@ async function execute(context, next) {
|
|
|
174
173
|
execute,
|
|
175
174
|
revision,
|
|
176
175
|
sync,
|
|
177
|
-
trigger,
|
|
178
176
|
update
|
|
179
177
|
});
|
|
@@ -33,6 +33,7 @@ var executions_default = {
|
|
|
33
33
|
dumpRules: {
|
|
34
34
|
group: "log"
|
|
35
35
|
},
|
|
36
|
+
migrationRules: ["schema-only"],
|
|
36
37
|
name: "executions",
|
|
37
38
|
shared: true,
|
|
38
39
|
fields: [
|
|
@@ -61,6 +62,14 @@ var executions_default = {
|
|
|
61
62
|
{
|
|
62
63
|
type: "integer",
|
|
63
64
|
name: "status"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
type: "json",
|
|
68
|
+
name: "stack"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
type: "json",
|
|
72
|
+
name: "output"
|
|
64
73
|
}
|
|
65
74
|
]
|
|
66
75
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
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
|
+
import { CollectionOptions } from '@nocobase/database';
|
|
10
|
+
export default function (): CollectionOptions;
|
|
@@ -0,0 +1,64 @@
|
|
|
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 workflowTasks_exports = {};
|
|
28
|
+
__export(workflowTasks_exports, {
|
|
29
|
+
default: () => workflowTasks_default
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(workflowTasks_exports);
|
|
32
|
+
function workflowTasks_default() {
|
|
33
|
+
return {
|
|
34
|
+
dumpRules: "required",
|
|
35
|
+
migrationRules: ["overwrite", "schema-only"],
|
|
36
|
+
name: "workflowTasks",
|
|
37
|
+
shared: true,
|
|
38
|
+
repository: "WorkflowTasksRepository",
|
|
39
|
+
fields: [
|
|
40
|
+
{
|
|
41
|
+
name: "user",
|
|
42
|
+
type: "belongsTo"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: "workflow",
|
|
46
|
+
type: "belongsTo"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
type: "string",
|
|
50
|
+
name: "type"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
type: "string",
|
|
54
|
+
name: "key"
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
indexes: [
|
|
58
|
+
{
|
|
59
|
+
unique: true,
|
|
60
|
+
fields: ["type", "key"]
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
};
|
|
64
|
+
}
|
|
@@ -32,6 +32,7 @@ module.exports = __toCommonJS(workflows_exports);
|
|
|
32
32
|
function workflows_default() {
|
|
33
33
|
return {
|
|
34
34
|
dumpRules: "required",
|
|
35
|
+
migrationRules: ["overwrite", "schema-only"],
|
|
35
36
|
name: "workflows",
|
|
36
37
|
shared: true,
|
|
37
38
|
repository: "WorkflowRepository",
|
|
@@ -43,7 +44,13 @@ function workflows_default() {
|
|
|
43
44
|
{
|
|
44
45
|
type: "string",
|
|
45
46
|
name: "title",
|
|
46
|
-
|
|
47
|
+
interface: "input",
|
|
48
|
+
uiSchema: {
|
|
49
|
+
title: '{{t("Name")}}',
|
|
50
|
+
type: "string",
|
|
51
|
+
"x-component": "Input",
|
|
52
|
+
required: true
|
|
53
|
+
}
|
|
47
54
|
},
|
|
48
55
|
{
|
|
49
56
|
type: "boolean",
|