@nocobase/plugin-workflow 1.5.0-beta.2 → 1.5.0-beta.4

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.
Files changed (37) hide show
  1. package/dist/client/5ed8ff0f70ed5911.js +10 -0
  2. package/dist/client/739d458621edf81f.js +10 -0
  3. package/dist/client/92877729dbcede8f.js +10 -0
  4. package/dist/client/components/TriggerCollectionRecordSelect.d.ts +10 -0
  5. package/dist/client/components/index.d.ts +1 -0
  6. package/dist/client/constants.d.ts +1 -0
  7. package/dist/client/e7b9d67c6a964bec.js +10 -0
  8. package/dist/client/index.js +1 -566
  9. package/dist/client/triggers/collection.d.ts +14 -0
  10. package/dist/client/triggers/index.d.ts +3 -3
  11. package/dist/client/triggers/schedule/ScheduleModes.d.ts +167 -0
  12. package/dist/client/triggers/schedule/TriggerScheduleConfig.d.ts +10 -0
  13. package/dist/client/triggers/schedule/index.d.ts +11 -0
  14. package/dist/externalVersion.js +10 -10
  15. package/dist/locale/zh-CN.json +14 -0
  16. package/dist/node_modules/cron-parser/package.json +1 -1
  17. package/dist/node_modules/lru-cache/package.json +1 -1
  18. package/dist/server/Plugin.d.ts +6 -2
  19. package/dist/server/Plugin.js +65 -45
  20. package/dist/server/Processor.d.ts +4 -0
  21. package/dist/server/Processor.js +12 -4
  22. package/dist/server/actions/workflows.d.ts +5 -0
  23. package/dist/server/actions/workflows.js +56 -61
  24. package/dist/server/collections/workflows.js +2 -2
  25. package/dist/server/index.d.ts +1 -1
  26. package/dist/server/index.js +2 -0
  27. package/dist/server/repositories/WorkflowRepository.d.ts +12 -0
  28. package/dist/server/repositories/WorkflowRepository.js +112 -0
  29. package/dist/server/triggers/CollectionTrigger.d.ts +9 -1
  30. package/dist/server/triggers/CollectionTrigger.js +76 -57
  31. package/dist/server/triggers/ScheduleTrigger/DateFieldScheduleTrigger.d.ts +1 -1
  32. package/dist/server/triggers/ScheduleTrigger/DateFieldScheduleTrigger.js +7 -4
  33. package/dist/server/triggers/ScheduleTrigger/index.d.ts +2 -0
  34. package/dist/server/triggers/ScheduleTrigger/index.js +4 -0
  35. package/dist/server/triggers/index.d.ts +4 -2
  36. package/dist/server/triggers/index.js +4 -0
  37. package/package.json +3 -3
@@ -66,6 +66,10 @@ class Processor {
66
66
  * @experimental
67
67
  */
68
68
  transaction;
69
+ /**
70
+ * @experimental
71
+ */
72
+ mainTransaction;
69
73
  /**
70
74
  * @experimental
71
75
  */
@@ -111,12 +115,13 @@ class Processor {
111
115
  async prepare() {
112
116
  const {
113
117
  execution,
114
- transaction,
115
118
  options: { plugin }
116
119
  } = this;
117
120
  if (!execution.workflow) {
118
121
  execution.workflow = plugin.enabledCache.get(execution.workflowId);
119
122
  }
123
+ this.mainTransaction = plugin.useDataSourceTransaction("main", this.transaction);
124
+ const transaction = this.mainTransaction;
120
125
  const nodes = await execution.workflow.getNodes({ transaction });
121
126
  this.makeNodes(nodes);
122
127
  const jobs = await execution.getJobs({
@@ -154,7 +159,7 @@ class Processor {
154
159
  this.logger.debug(`config of node`, { data: node.config });
155
160
  job = await instruction(node, prevJob, this);
156
161
  if (!job) {
157
- return null;
162
+ return this.exit();
158
163
  }
159
164
  } catch (err) {
160
165
  this.logger.error(
@@ -227,7 +232,10 @@ class Processor {
227
232
  async exit(s) {
228
233
  if (typeof s === "number") {
229
234
  const status = this.constructor.StatusMap[s] ?? Math.sign(s);
230
- await this.execution.update({ status }, { transaction: this.transaction });
235
+ await this.execution.update({ status }, { transaction: this.mainTransaction });
236
+ }
237
+ if (this.mainTransaction && this.mainTransaction !== this.transaction) {
238
+ await this.mainTransaction.commit();
231
239
  }
232
240
  this.logger.info(`execution (${this.execution.id}) exiting with status ${this.execution.status}`);
233
241
  return null;
@@ -238,7 +246,7 @@ class Processor {
238
246
  */
239
247
  async saveJob(payload) {
240
248
  const { database } = this.execution.constructor;
241
- const { transaction } = this;
249
+ const { mainTransaction: transaction } = this;
242
250
  const { model } = database.getCollection("jobs");
243
251
  let job;
244
252
  if (payload instanceof model) {
@@ -11,4 +11,9 @@ export declare function update(context: Context, next: any): Promise<void>;
11
11
  export declare function destroy(context: Context, next: any): Promise<void>;
12
12
  export declare function revision(context: Context, next: any): Promise<void>;
13
13
  export declare function sync(context: Context, next: any): Promise<void>;
14
+ /**
15
+ * @deprecated
16
+ * Keep for action trigger compatibility
17
+ */
14
18
  export declare function trigger(context: Context, next: any): Promise<any>;
19
+ export declare function execute(context: Context, next: any): Promise<any>;
@@ -37,6 +37,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
37
37
  var workflows_exports = {};
38
38
  __export(workflows_exports, {
39
39
  destroy: () => destroy,
40
+ execute: () => execute,
40
41
  revision: () => revision,
41
42
  sync: () => sync,
42
43
  trigger: () => trigger,
@@ -90,69 +91,13 @@ async function destroy(context, next) {
90
91
  next();
91
92
  }
92
93
  async function revision(context, next) {
93
- const plugin = context.app.getPlugin(import_Plugin.default);
94
94
  const repository = import_actions.utils.getRepositoryFromParams(context);
95
95
  const { filterByTk, filter = {}, values = {} } = context.action.params;
96
- context.body = await context.db.sequelize.transaction(async (transaction) => {
97
- const origin = await repository.findOne({
98
- filterByTk,
99
- filter,
100
- appends: ["nodes"],
101
- context,
102
- transaction
103
- });
104
- const trigger2 = plugin.triggers.get(origin.type);
105
- const revisionData = filter.key ? {
106
- key: filter.key,
107
- title: origin.title,
108
- triggerTitle: origin.triggerTitle,
109
- allExecuted: origin.allExecuted
110
- } : values;
111
- const instance = await repository.create({
112
- values: {
113
- title: `${origin.title} copy`,
114
- description: origin.description,
115
- ...revisionData,
116
- sync: origin.sync,
117
- type: origin.type,
118
- config: typeof trigger2.duplicateConfig === "function" ? await trigger2.duplicateConfig(origin, { transaction }) : origin.config
119
- },
120
- transaction
121
- });
122
- const originalNodesMap = /* @__PURE__ */ new Map();
123
- origin.nodes.forEach((node) => {
124
- originalNodesMap.set(node.id, node);
125
- });
126
- const oldToNew = /* @__PURE__ */ new Map();
127
- const newToOld = /* @__PURE__ */ new Map();
128
- for await (const node of origin.nodes) {
129
- const instruction = plugin.instructions.get(node.type);
130
- const newNode = await instance.createNode(
131
- {
132
- type: node.type,
133
- key: node.key,
134
- config: typeof instruction.duplicateConfig === "function" ? await instruction.duplicateConfig(node, { transaction }) : node.config,
135
- title: node.title,
136
- branchIndex: node.branchIndex
137
- },
138
- { transaction }
139
- );
140
- oldToNew.set(node.id, newNode);
141
- newToOld.set(newNode.id, node);
142
- }
143
- for await (const [oldId, newNode] of oldToNew.entries()) {
144
- const oldNode = originalNodesMap.get(oldId);
145
- const newUpstream = oldNode.upstreamId ? oldToNew.get(oldNode.upstreamId) : null;
146
- const newDownstream = oldNode.downstreamId ? oldToNew.get(oldNode.downstreamId) : null;
147
- await newNode.update(
148
- {
149
- upstreamId: (newUpstream == null ? void 0 : newUpstream.id) ?? null,
150
- downstreamId: (newDownstream == null ? void 0 : newDownstream.id) ?? null
151
- },
152
- { transaction }
153
- );
154
- }
155
- return instance;
96
+ context.body = await repository.revision({
97
+ filterByTk,
98
+ filter,
99
+ values,
100
+ context
156
101
  });
157
102
  await next();
158
103
  }
@@ -174,9 +119,59 @@ async function sync(context, next) {
174
119
  async function trigger(context, next) {
175
120
  return next();
176
121
  }
122
+ async function execute(context, next) {
123
+ const plugin = context.app.pm.get(import_Plugin.default);
124
+ const { filterByTk, autoRevision } = context.action.params;
125
+ if (!filterByTk) {
126
+ return context.throw(400, "filterByTk is required");
127
+ }
128
+ const id = Number.parseInt(filterByTk, 10);
129
+ if (Number.isNaN(id)) {
130
+ return context.throw(400, "filterByTk is invalid");
131
+ }
132
+ const repository = import_actions.utils.getRepositoryFromParams(context);
133
+ const workflow = plugin.enabledCache.get(id) || await repository.findOne({ filterByTk });
134
+ if (!workflow) {
135
+ return context.throw(404, "workflow not found");
136
+ }
137
+ const { executed } = workflow;
138
+ let processor;
139
+ try {
140
+ processor = await plugin.execute(workflow, context, { manually: true });
141
+ if (!processor) {
142
+ return context.throw(400, "workflow not triggered");
143
+ }
144
+ } catch (ex) {
145
+ return context.throw(400, ex.message);
146
+ }
147
+ context.action.mergeParams({
148
+ filter: { key: workflow.key }
149
+ });
150
+ let newVersion;
151
+ if (!executed && autoRevision) {
152
+ newVersion = await repository.revision({
153
+ filterByTk: workflow.id,
154
+ filter: { key: workflow.key },
155
+ values: {
156
+ current: workflow.current,
157
+ enabled: workflow.enabled
158
+ },
159
+ context
160
+ });
161
+ }
162
+ context.body = {
163
+ execution: {
164
+ id: processor.execution.id,
165
+ status: processor.execution.status
166
+ },
167
+ newVersionId: newVersion == null ? void 0 : newVersion.id
168
+ };
169
+ return next();
170
+ }
177
171
  // Annotate the CommonJS export names for ESM import in node:
178
172
  0 && (module.exports = {
179
173
  destroy,
174
+ execute,
180
175
  revision,
181
176
  sync,
182
177
  trigger,
@@ -34,6 +34,7 @@ function workflows_default() {
34
34
  dumpRules: "required",
35
35
  name: "workflows",
36
36
  shared: true,
37
+ repository: "WorkflowRepository",
37
38
  fields: [
38
39
  {
39
40
  name: "key",
@@ -90,8 +91,7 @@ function workflows_default() {
90
91
  },
91
92
  {
92
93
  type: "boolean",
93
- name: "current",
94
- defaultValue: false
94
+ name: "current"
95
95
  },
96
96
  {
97
97
  type: "boolean",
@@ -13,5 +13,5 @@ export * from './functions';
13
13
  export * from './logicCalculate';
14
14
  export { Trigger } from './triggers';
15
15
  export { default as Processor } from './Processor';
16
- export { default } from './Plugin';
16
+ export { default, EventOptions } from './Plugin';
17
17
  export * from './types';
@@ -37,6 +37,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
37
37
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
38
38
  var server_exports = {};
39
39
  __export(server_exports, {
40
+ EventOptions: () => import_Plugin.EventOptions,
40
41
  Processor: () => import_Processor.default,
41
42
  Trigger: () => import_triggers.Trigger,
42
43
  default: () => import_Plugin.default
@@ -53,6 +54,7 @@ var import_Plugin = __toESM(require("./Plugin"));
53
54
  __reExport(server_exports, require("./types"), module.exports);
54
55
  // Annotate the CommonJS export names for ESM import in node:
55
56
  0 && (module.exports = {
57
+ EventOptions,
56
58
  Processor,
57
59
  Trigger,
58
60
  ...require("./utils"),
@@ -0,0 +1,12 @@
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 { Repository } from '@nocobase/database';
10
+ export default class WorkflowRepository extends Repository {
11
+ revision(options: any): Promise<any>;
12
+ }
@@ -0,0 +1,112 @@
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 __create = Object.create;
11
+ var __defProp = Object.defineProperty;
12
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
+ var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __getProtoOf = Object.getPrototypeOf;
15
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
16
+ var __export = (target, all) => {
17
+ for (var name in all)
18
+ __defProp(target, name, { get: all[name], enumerable: true });
19
+ };
20
+ var __copyProps = (to, from, except, desc) => {
21
+ if (from && typeof from === "object" || typeof from === "function") {
22
+ for (let key of __getOwnPropNames(from))
23
+ if (!__hasOwnProp.call(to, key) && key !== except)
24
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
25
+ }
26
+ return to;
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
+ ));
36
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
+ var WorkflowRepository_exports = {};
38
+ __export(WorkflowRepository_exports, {
39
+ default: () => WorkflowRepository
40
+ });
41
+ module.exports = __toCommonJS(WorkflowRepository_exports);
42
+ var import_database = require("@nocobase/database");
43
+ var import_Plugin = __toESM(require("../Plugin"));
44
+ class WorkflowRepository extends import_database.Repository {
45
+ async revision(options) {
46
+ const { filterByTk, filter, values, context } = options;
47
+ const plugin = context.app.pm.get(import_Plugin.default);
48
+ return this.database.sequelize.transaction(async (transaction) => {
49
+ const origin = await this.findOne({
50
+ filterByTk,
51
+ filter,
52
+ appends: ["nodes"],
53
+ context,
54
+ transaction
55
+ });
56
+ const trigger = plugin.triggers.get(origin.type);
57
+ const revisionData = filter.key ? {
58
+ key: filter.key,
59
+ title: origin.title,
60
+ triggerTitle: origin.triggerTitle,
61
+ allExecuted: origin.allExecuted,
62
+ current: null,
63
+ ...values
64
+ } : values;
65
+ const instance = await this.create({
66
+ values: {
67
+ title: `${origin.title} copy`,
68
+ description: origin.description,
69
+ ...revisionData,
70
+ sync: origin.sync,
71
+ type: origin.type,
72
+ config: typeof trigger.duplicateConfig === "function" ? await trigger.duplicateConfig(origin, { transaction }) : origin.config
73
+ },
74
+ transaction
75
+ });
76
+ const originalNodesMap = /* @__PURE__ */ new Map();
77
+ origin.nodes.forEach((node) => {
78
+ originalNodesMap.set(node.id, node);
79
+ });
80
+ const oldToNew = /* @__PURE__ */ new Map();
81
+ const newToOld = /* @__PURE__ */ new Map();
82
+ for await (const node of origin.nodes) {
83
+ const instruction = plugin.instructions.get(node.type);
84
+ const newNode = await instance.createNode(
85
+ {
86
+ type: node.type,
87
+ key: node.key,
88
+ config: typeof instruction.duplicateConfig === "function" ? await instruction.duplicateConfig(node, { transaction }) : node.config,
89
+ title: node.title,
90
+ branchIndex: node.branchIndex
91
+ },
92
+ { transaction }
93
+ );
94
+ oldToNew.set(node.id, newNode);
95
+ newToOld.set(newNode.id, node);
96
+ }
97
+ for await (const [oldId, newNode] of oldToNew.entries()) {
98
+ const oldNode = originalNodesMap.get(oldId);
99
+ const newUpstream = oldNode.upstreamId ? oldToNew.get(oldNode.upstreamId) : null;
100
+ const newDownstream = oldNode.downstreamId ? oldToNew.get(oldNode.downstreamId) : null;
101
+ await newNode.update(
102
+ {
103
+ upstreamId: (newUpstream == null ? void 0 : newUpstream.id) ?? null,
104
+ downstreamId: (newDownstream == null ? void 0 : newDownstream.id) ?? null
105
+ },
106
+ { transaction }
107
+ );
108
+ }
109
+ return instance;
110
+ });
111
+ }
112
+ }
@@ -6,9 +6,11 @@
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 { Transactionable } from '@nocobase/database';
9
+ import { Model, Transactionable } from '@nocobase/database';
10
10
  import Trigger from '.';
11
11
  import type { WorkflowModel } from '../types';
12
+ import type { EventOptions } from '../Plugin';
13
+ import { Context } from '@nocobase/actions';
12
14
  export interface CollectionChangeTriggerConfig {
13
15
  collection: string;
14
16
  mode: number;
@@ -16,7 +18,13 @@ export interface CollectionChangeTriggerConfig {
16
18
  }
17
19
  export default class CollectionTrigger extends Trigger {
18
20
  events: Map<any, any>;
21
+ private static handler;
22
+ prepare(workflow: WorkflowModel, data: Model | Record<string, any>, options: any): Promise<{
23
+ data: any;
24
+ stack: any;
25
+ }>;
19
26
  on(workflow: WorkflowModel): void;
20
27
  off(workflow: WorkflowModel): void;
21
28
  validateEvent(workflow: WorkflowModel, context: any, options: Transactionable): Promise<boolean>;
29
+ execute(workflow: WorkflowModel, context: Context, options: EventOptions): Promise<void | import("..").Processor>;
22
30
  }
@@ -39,11 +39,12 @@ __export(CollectionTrigger_exports, {
39
39
  default: () => CollectionTrigger
40
40
  });
41
41
  module.exports = __toCommonJS(CollectionTrigger_exports);
42
- var import__ = __toESM(require("."));
43
- var import_utils = require("../utils");
44
- var import_data_source_manager = require("@nocobase/data-source-manager");
45
- var import_utils2 = require("@nocobase/utils");
46
42
  var import_lodash = require("lodash");
43
+ var import_utils = require("@nocobase/utils");
44
+ var import_database = require("@nocobase/database");
45
+ var import_data_source_manager = require("@nocobase/data-source-manager");
46
+ var import__ = __toESM(require("."));
47
+ var import_utils2 = require("../utils");
47
48
  const MODE_BITMAP = {
48
49
  CREATE: 1,
49
50
  UPDATE: 2,
@@ -63,65 +64,73 @@ function getFieldRawName(collection, name) {
63
64
  }
64
65
  return name;
65
66
  }
66
- async function handler(workflow, data, options) {
67
- const { condition, changed, mode, appends } = workflow.config;
68
- const [dataSourceName, collectionName] = (0, import_data_source_manager.parseCollectionName)(workflow.config.collection);
69
- const { collectionManager } = this.workflow.app.dataSourceManager.dataSources.get(dataSourceName);
70
- const collection = collectionManager.getCollection(collectionName);
71
- const { transaction, context } = options;
72
- const { repository, filterTargetKey } = collection;
73
- if (changed && changed.length && changed.filter((name) => {
74
- const field = collection.getField(name);
75
- return field && !["linkTo", "hasOne", "hasMany", "belongsToMany"].includes(field.options.type);
76
- }).every((name) => !data.changedWithAssociations(getFieldRawName(collection, name)))) {
77
- return;
78
- }
79
- const filterByTk = Array.isArray(filterTargetKey) ? (0, import_lodash.pick)(data, filterTargetKey) : { [filterTargetKey]: data[filterTargetKey] };
80
- if ((0, import_utils2.isValidFilter)(condition) && !(mode & MODE_BITMAP.DESTROY)) {
81
- const count = await repository.count({
82
- filterByTk,
83
- filter: condition,
84
- context,
85
- transaction
86
- });
87
- if (!count) {
67
+ class CollectionTrigger extends import__.default {
68
+ events = /* @__PURE__ */ new Map();
69
+ // async function, should return promise
70
+ static async handler(workflow, data, options) {
71
+ const [dataSourceName] = (0, import_data_source_manager.parseCollectionName)(workflow.config.collection);
72
+ const transaction = this.workflow.useDataSourceTransaction(dataSourceName, options.transaction);
73
+ const ctx = await this.prepare(workflow, data, { ...options, transaction });
74
+ if (!ctx) {
88
75
  return;
89
76
  }
77
+ if (workflow.sync) {
78
+ await this.workflow.trigger(workflow, ctx, {
79
+ transaction
80
+ });
81
+ } else {
82
+ if (transaction) {
83
+ transaction.afterCommit(() => {
84
+ this.workflow.trigger(workflow, ctx);
85
+ });
86
+ } else {
87
+ this.workflow.trigger(workflow, ctx);
88
+ }
89
+ }
90
90
  }
91
- let result = data;
92
- if ((appends == null ? void 0 : appends.length) && !(mode & MODE_BITMAP.DESTROY)) {
93
- const includeFields = appends.reduce((set, field) => {
94
- set.add(field.split(".")[0]);
95
- set.add(field);
96
- return set;
97
- }, /* @__PURE__ */ new Set());
98
- result = await repository.findOne({
99
- filterByTk,
100
- appends: Array.from(includeFields),
101
- transaction
102
- });
103
- }
104
- const json = (0, import_utils.toJSON)(result);
105
- if (workflow.sync) {
106
- await this.workflow.trigger(
107
- workflow,
108
- { data: json, stack: context == null ? void 0 : context.stack },
109
- {
110
- transaction: this.workflow.useDataSourceTransaction(dataSourceName, transaction)
91
+ async prepare(workflow, data, options) {
92
+ const { condition, changed, mode, appends } = workflow.config;
93
+ const [dataSourceName, collectionName] = (0, import_data_source_manager.parseCollectionName)(workflow.config.collection);
94
+ const { collectionManager } = this.workflow.app.dataSourceManager.dataSources.get(dataSourceName);
95
+ const collection = collectionManager.getCollection(collectionName);
96
+ const { transaction, context } = options;
97
+ const { repository, filterTargetKey } = collection;
98
+ if (data instanceof import_database.Model && changed && changed.length && changed.filter((name) => {
99
+ const field = collection.getField(name);
100
+ return field && !["linkTo", "hasOne", "hasMany", "belongsToMany"].includes(field.options.type);
101
+ }).every((name) => !data.changedWithAssociations(getFieldRawName(collection, name)))) {
102
+ return null;
103
+ }
104
+ const filterByTk = Array.isArray(filterTargetKey) ? (0, import_lodash.pick)(data, filterTargetKey) : { [filterTargetKey]: data[filterTargetKey] };
105
+ if ((0, import_utils.isValidFilter)(condition) && !(mode & MODE_BITMAP.DESTROY)) {
106
+ const count = await repository.count({
107
+ filterByTk,
108
+ filter: condition,
109
+ context,
110
+ transaction
111
+ });
112
+ if (!count) {
113
+ return null;
111
114
  }
112
- );
113
- } else {
114
- if (transaction) {
115
- transaction.afterCommit(() => {
116
- this.workflow.trigger(workflow, { data: json, stack: context == null ? void 0 : context.stack });
115
+ }
116
+ let result = data;
117
+ if ((appends == null ? void 0 : appends.length) && !(mode & MODE_BITMAP.DESTROY)) {
118
+ const includeFields = appends.reduce((set, field) => {
119
+ set.add(field.split(".")[0]);
120
+ set.add(field);
121
+ return set;
122
+ }, /* @__PURE__ */ new Set());
123
+ result = await repository.findOne({
124
+ filterByTk,
125
+ appends: Array.from(includeFields),
126
+ transaction
117
127
  });
118
- } else {
119
- this.workflow.trigger(workflow, { data: json, stack: context == null ? void 0 : context.stack });
120
128
  }
129
+ return {
130
+ data: (0, import_utils2.toJSON)(result),
131
+ stack: context == null ? void 0 : context.stack
132
+ };
121
133
  }
122
- }
123
- class CollectionTrigger extends import__.default {
124
- events = /* @__PURE__ */ new Map();
125
134
  on(workflow) {
126
135
  var _a, _b;
127
136
  const { collection, mode } = workflow.config;
@@ -138,7 +147,7 @@ class CollectionTrigger extends import__.default {
138
147
  const name = getHookId(workflow, `${collection}.${type}`);
139
148
  if (mode & key) {
140
149
  if (!this.events.has(name)) {
141
- const listener = handler.bind(this, workflow);
150
+ const listener = this.constructor.handler.bind(this, workflow);
142
151
  this.events.set(name, listener);
143
152
  db.on(event, listener);
144
153
  }
@@ -190,4 +199,14 @@ class CollectionTrigger extends import__.default {
190
199
  }
191
200
  return true;
192
201
  }
202
+ async execute(workflow, context, options) {
203
+ var _a;
204
+ const ctx = await this.prepare(workflow, (_a = context.action.params.values) == null ? void 0 : _a.data, options);
205
+ const [dataSourceName] = (0, import_data_source_manager.parseCollectionName)(workflow.config.collection);
206
+ const { transaction } = options;
207
+ return this.workflow.trigger(workflow, ctx, {
208
+ ...options,
209
+ transaction: this.workflow.useDataSourceTransaction(dataSourceName, transaction)
210
+ });
211
+ }
193
212
  }
@@ -21,7 +21,7 @@ export interface ScheduleTriggerConfig {
21
21
  startsOn?: ScheduleOnField;
22
22
  endsOn?: string | ScheduleOnField;
23
23
  }
24
- export default class ScheduleTrigger {
24
+ export default class DateFieldScheduleTrigger {
25
25
  workflow: Plugin;
26
26
  events: Map<any, any>;
27
27
  private timer;
@@ -36,7 +36,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
36
36
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
37
  var DateFieldScheduleTrigger_exports = {};
38
38
  __export(DateFieldScheduleTrigger_exports, {
39
- default: () => ScheduleTrigger
39
+ default: () => DateFieldScheduleTrigger
40
40
  });
41
41
  module.exports = __toCommonJS(DateFieldScheduleTrigger_exports);
42
42
  var import_database = require("@nocobase/database");
@@ -95,7 +95,7 @@ function matchCronNextTime(cron, currentDate, range) {
95
95
  function getHookId(workflow, type) {
96
96
  return `${type}#${workflow.id}`;
97
97
  }
98
- class ScheduleTrigger {
98
+ class DateFieldScheduleTrigger {
99
99
  constructor(workflow) {
100
100
  this.workflow = workflow;
101
101
  workflow.app.on("afterStart", async () => {
@@ -340,7 +340,9 @@ class ScheduleTrigger {
340
340
  return this.schedule(workflow, data, nextTime, Boolean(nextTime), { transaction });
341
341
  };
342
342
  this.events.set(name, listener);
343
- this.workflow.app.dataSourceManager.dataSources.get(dataSourceName).collectionManager.db.on(event, listener);
343
+ const dataSource = this.workflow.app.dataSourceManager.dataSources.get(dataSourceName);
344
+ const { db } = dataSource.collectionManager;
345
+ db.on(event, listener);
344
346
  }
345
347
  off(workflow) {
346
348
  for (const [key, timer] of this.cache.entries()) {
@@ -355,7 +357,8 @@ class ScheduleTrigger {
355
357
  const name = getHookId(workflow, event);
356
358
  const listener = this.events.get(name);
357
359
  if (listener) {
358
- const { db } = this.workflow.app.dataSourceManager.dataSources.get(dataSourceName).collectionManager;
360
+ const dataSource = this.workflow.app.dataSourceManager.dataSources.get(dataSourceName);
361
+ const { db } = dataSource.collectionManager;
359
362
  db.off(event, listener);
360
363
  this.events.delete(name);
361
364
  }
@@ -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 { Context } from '@nocobase/actions';
9
10
  import Trigger from '..';
10
11
  import type Plugin from '../../Plugin';
11
12
  export default class ScheduleTrigger extends Trigger {
@@ -15,4 +16,5 @@ export default class ScheduleTrigger extends Trigger {
15
16
  private getTrigger;
16
17
  on(workflow: any): void;
17
18
  off(workflow: any): void;
19
+ execute(workflow: any, context: Context, options: any): Promise<void | import("../..").Processor>;
18
20
  }
@@ -68,6 +68,10 @@ class ScheduleTrigger extends import__.default {
68
68
  trigger.off(workflow);
69
69
  }
70
70
  }
71
+ async execute(workflow, context, options) {
72
+ const { values } = context.action.params;
73
+ return this.workflow.trigger(workflow, { ...values, date: (values == null ? void 0 : values.date) ?? /* @__PURE__ */ new Date() }, options);
74
+ }
71
75
  // async validateEvent(workflow: WorkflowModel, context: any, options: Transactionable): Promise<boolean> {
72
76
  // if (!context.date) {
73
77
  // return false;
@@ -9,13 +9,15 @@
9
9
  import { Transactionable } from '@nocobase/database';
10
10
  import type Plugin from '../Plugin';
11
11
  import type { WorkflowModel } from '../types';
12
+ import Processor from '../Processor';
12
13
  export declare abstract class Trigger {
13
14
  readonly workflow: Plugin;
14
15
  constructor(workflow: Plugin);
15
- abstract on(workflow: WorkflowModel): void;
16
- abstract off(workflow: WorkflowModel): void;
16
+ on(workflow: WorkflowModel): void;
17
+ off(workflow: WorkflowModel): void;
17
18
  validateEvent(workflow: WorkflowModel, context: any, options: Transactionable): boolean | Promise<boolean>;
18
19
  duplicateConfig?(workflow: WorkflowModel, options: Transactionable): object | Promise<object>;
19
20
  sync?: boolean;
21
+ execute?(workflow: WorkflowModel, context: any, options: Transactionable): void | Processor | Promise<void | Processor>;
20
22
  }
21
23
  export default Trigger;