@nocobase/plugin-workflow-cc 2.0.0-beta.9 → 2.0.0

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.
@@ -0,0 +1,304 @@
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 tempAssociationFields_exports = {};
28
+ __export(tempAssociationFields_exports, {
29
+ appendTempAssociationFields: () => appendTempAssociationFields
30
+ });
31
+ module.exports = __toCommonJS(tempAssociationFields_exports);
32
+ var import_data_source_manager = require("@nocobase/data-source-manager");
33
+ var import_tempAssociation = require("../common/tempAssociation");
34
+ const TEMP_ASSOCIATION_FIELDS_LIMIT = 50;
35
+ const toPlainObject = (record) => {
36
+ if (!record || typeof record !== "object") return record;
37
+ if (typeof record.get === "function") return record.get();
38
+ if (typeof record.toJSON === "function") return record.toJSON();
39
+ return record;
40
+ };
41
+ const normalizeTempAssociationConfigs = (configs) => {
42
+ if (!Array.isArray(configs)) return [];
43
+ return configs.filter((config) => !!config && typeof config === "object").map((config) => ({
44
+ nodeId: config.nodeId,
45
+ nodeKey: config.nodeKey,
46
+ nodeType: config.nodeType
47
+ })).filter(
48
+ (config) => config.nodeId !== void 0 && typeof config.nodeKey === "string" && config.nodeKey.length > 0 && (config.nodeType === "workflow" || config.nodeType === "node")
49
+ ).slice(0, TEMP_ASSOCIATION_FIELDS_LIMIT);
50
+ };
51
+ const pickRecordData = (value) => {
52
+ if (!value) return null;
53
+ if (Array.isArray(value)) return value[0] ?? null;
54
+ if ((value == null ? void 0 : value.data) && typeof value.data === "object" && !Array.isArray(value.data)) return value.data;
55
+ return value;
56
+ };
57
+ const getRecordKey = (record, primaryKey) => {
58
+ if (!record || typeof record !== "object") return void 0;
59
+ if (primaryKey && record[primaryKey] != null) return record[primaryKey];
60
+ if (record.id != null) return record.id;
61
+ return void 0;
62
+ };
63
+ const setTaskFieldValue = (task, fieldName, value) => {
64
+ if (task && typeof task.setDataValue === "function") {
65
+ task.setDataValue(fieldName, value);
66
+ return;
67
+ }
68
+ task[fieldName] = value;
69
+ };
70
+ const normalizeNodeConfig = (config) => {
71
+ if (!config) return void 0;
72
+ if (typeof config === "string") {
73
+ try {
74
+ return JSON.parse(config);
75
+ } catch (error) {
76
+ return void 0;
77
+ }
78
+ }
79
+ return config;
80
+ };
81
+ const normalizeAppends = (appends) => {
82
+ if (!Array.isArray(appends)) return [];
83
+ const set = /* @__PURE__ */ new Set();
84
+ appends.forEach((field) => {
85
+ if (typeof field !== "string" || !field) return;
86
+ set.add(field.split(".")[0]);
87
+ set.add(field);
88
+ });
89
+ return Array.from(set);
90
+ };
91
+ const getConfigAppends = (config) => {
92
+ var _a;
93
+ return normalizeAppends(((_a = config == null ? void 0 : config.params) == null ? void 0 : _a.appends) ?? (config == null ? void 0 : config.appends));
94
+ };
95
+ async function appendTempAssociationFields(context) {
96
+ var _a, _b;
97
+ const body = context.body;
98
+ const bodyData = Array.isArray(body) ? body : body == null ? void 0 : body.rows;
99
+ if (!Array.isArray(bodyData) || bodyData.length === 0) {
100
+ return;
101
+ }
102
+ const tasksWithConfig = /* @__PURE__ */ new Map();
103
+ const executionIds = /* @__PURE__ */ new Set();
104
+ const tasksByNodeId = /* @__PURE__ */ new Map();
105
+ const ccNodeConfigMap = /* @__PURE__ */ new Map();
106
+ const ccNodeIdsToFetch = /* @__PURE__ */ new Set();
107
+ const workflowIds = /* @__PURE__ */ new Set();
108
+ bodyData.forEach((task) => {
109
+ var _a2, _b2, _c;
110
+ const nodeId = ((_a2 = task == null ? void 0 : task.node) == null ? void 0 : _a2.id) ?? (task == null ? void 0 : task.nodeId);
111
+ if (nodeId == null) return;
112
+ const tasks = tasksByNodeId.get(nodeId) || [];
113
+ tasks.push(task);
114
+ tasksByNodeId.set(nodeId, tasks);
115
+ if ((_b2 = task == null ? void 0 : task.node) == null ? void 0 : _b2.config) {
116
+ ccNodeConfigMap.set(nodeId, normalizeNodeConfig(task.node.config));
117
+ } else {
118
+ ccNodeIdsToFetch.add(nodeId);
119
+ }
120
+ if (task.executionId) {
121
+ executionIds.add(task.executionId);
122
+ }
123
+ const workflowId = task.workflowId ?? ((_c = task.workflow) == null ? void 0 : _c.id);
124
+ if (workflowId) {
125
+ workflowIds.add(workflowId);
126
+ }
127
+ });
128
+ if (ccNodeIdsToFetch.size) {
129
+ const nodeRepo = context.app.db.getRepository("flow_nodes");
130
+ const nodes = await nodeRepo.find({
131
+ filter: { id: Array.from(ccNodeIdsToFetch) }
132
+ });
133
+ nodes.forEach((node) => {
134
+ ccNodeConfigMap.set(node.id, normalizeNodeConfig(node.config) || {});
135
+ });
136
+ }
137
+ const referencedNodeIds = /* @__PURE__ */ new Set();
138
+ tasksByNodeId.forEach((tasks, nodeId) => {
139
+ const config = normalizeNodeConfig(ccNodeConfigMap.get(nodeId));
140
+ const configs = normalizeTempAssociationConfigs(config == null ? void 0 : config.tempAssociationFields);
141
+ if (!configs.length) return;
142
+ configs.forEach((item) => {
143
+ if (item.nodeType === "node") {
144
+ referencedNodeIds.add(item.nodeId);
145
+ }
146
+ });
147
+ tasks.forEach((task) => {
148
+ tasksWithConfig.set(task, configs);
149
+ });
150
+ });
151
+ if (!tasksWithConfig.size) return;
152
+ const workflowIdsNeedingConfig = /* @__PURE__ */ new Set();
153
+ for (const [task, configs] of tasksWithConfig.entries()) {
154
+ if (!configs.some((config) => config.nodeType === "workflow")) continue;
155
+ const workflow = task.workflow;
156
+ if ((_a = workflow == null ? void 0 : workflow.config) == null ? void 0 : _a.collection) continue;
157
+ const workflowId = task.workflowId ?? (workflow == null ? void 0 : workflow.id);
158
+ if (workflowId) {
159
+ workflowIdsNeedingConfig.add(workflowId);
160
+ }
161
+ }
162
+ if (workflowIdsNeedingConfig.size) {
163
+ const workflowRepo = context.app.db.getRepository("workflows");
164
+ const workflows = await workflowRepo.find({
165
+ filter: { id: Array.from(workflowIdsNeedingConfig) }
166
+ });
167
+ const workflowMap = new Map(workflows.map((workflow) => [workflow.id, workflow]));
168
+ for (const task of tasksWithConfig.keys()) {
169
+ const workflowId = task.workflowId ?? ((_b = task.workflow) == null ? void 0 : _b.id);
170
+ if (!workflowId) continue;
171
+ const stored = workflowMap.get(workflowId);
172
+ if (!stored) continue;
173
+ if (!task.workflow) {
174
+ task.workflow = toPlainObject(stored);
175
+ continue;
176
+ }
177
+ task.workflow.config = stored.config;
178
+ }
179
+ }
180
+ const executionRepo = context.app.db.getRepository("executions");
181
+ const executions = executionIds.size ? await executionRepo.find({
182
+ filter: { id: Array.from(executionIds) },
183
+ appends: ["jobs"]
184
+ }) : [];
185
+ const executionMap = new Map(executions.map((execution) => [execution.id, execution]));
186
+ const workflowNodeMap = /* @__PURE__ */ new Map();
187
+ const collectionCache = /* @__PURE__ */ new Map();
188
+ const pendingGroups = /* @__PURE__ */ new Map();
189
+ if (referencedNodeIds.size) {
190
+ const nodeRepo = context.app.db.getRepository("flow_nodes");
191
+ const nodes = await nodeRepo.find({
192
+ filter: { id: Array.from(referencedNodeIds) }
193
+ });
194
+ nodes.forEach((node) => {
195
+ workflowNodeMap.set(String(node.id), {
196
+ ...node,
197
+ config: normalizeNodeConfig(node.config)
198
+ });
199
+ });
200
+ }
201
+ const getRepository = (dataSourceName, collectionName) => {
202
+ var _a2;
203
+ const cacheKey = `${dataSourceName}:${collectionName}`;
204
+ if (collectionCache.has(cacheKey)) return collectionCache.get(cacheKey);
205
+ const dataSource = context.app.dataSourceManager.dataSources.get(dataSourceName);
206
+ if (!dataSource) return null;
207
+ const collection = dataSource.collectionManager.getCollection(collectionName);
208
+ if (!collection) return null;
209
+ const entry = {
210
+ repository: collection.repository,
211
+ collection,
212
+ filterTargetKey: collection.filterTargetKey || ((_a2 = collection.model) == null ? void 0 : _a2.primaryKeyAttribute)
213
+ };
214
+ collectionCache.set(cacheKey, entry);
215
+ return entry;
216
+ };
217
+ for (const [task, configs] of tasksWithConfig.entries()) {
218
+ const execution = executionMap.get(task.executionId);
219
+ const workflow = task.workflow;
220
+ configs.forEach((config) => {
221
+ var _a2, _b2, _c, _d, _e, _f;
222
+ const fieldName = (0, import_tempAssociation.buildTempAssociationFieldName)(config.nodeType, config.nodeKey);
223
+ let collectionConfig;
224
+ let recordData;
225
+ let appends = [];
226
+ if (config.nodeType === "workflow") {
227
+ collectionConfig = (_a2 = workflow == null ? void 0 : workflow.config) == null ? void 0 : _a2.collection;
228
+ recordData = pickRecordData((_b2 = execution == null ? void 0 : execution.context) == null ? void 0 : _b2.data);
229
+ appends = getConfigAppends(workflow == null ? void 0 : workflow.config);
230
+ } else {
231
+ const node = workflowNodeMap.get(String(config.nodeId));
232
+ collectionConfig = (_c = node == null ? void 0 : node.config) == null ? void 0 : _c.collection;
233
+ const job = (_d = execution == null ? void 0 : execution.jobs) == null ? void 0 : _d.find((item) => String(item.nodeId) === String(config.nodeId));
234
+ recordData = pickRecordData(job == null ? void 0 : job.result);
235
+ appends = getConfigAppends(node == null ? void 0 : node.config);
236
+ }
237
+ if (!collectionConfig) {
238
+ setTaskFieldValue(task, fieldName, null);
239
+ return;
240
+ }
241
+ const [dataSourceName, collectionName] = (0, import_data_source_manager.parseCollectionName)(collectionConfig);
242
+ if (!dataSourceName || !collectionName) {
243
+ setTaskFieldValue(task, fieldName, null);
244
+ return;
245
+ }
246
+ const repoEntry = getRepository(dataSourceName, collectionName);
247
+ if (!repoEntry) {
248
+ setTaskFieldValue(task, fieldName, null);
249
+ return;
250
+ }
251
+ const recordKey = getRecordKey(recordData, (_f = (_e = repoEntry.collection) == null ? void 0 : _e.model) == null ? void 0 : _f.primaryKeyAttribute);
252
+ if (recordKey == null) {
253
+ setTaskFieldValue(task, fieldName, recordData ? toPlainObject(recordData) : null);
254
+ return;
255
+ }
256
+ if (Array.isArray(repoEntry.filterTargetKey)) {
257
+ setTaskFieldValue(task, fieldName, recordData ? toPlainObject(recordData) : null);
258
+ return;
259
+ }
260
+ const groupKey = `${dataSourceName}:${collectionName}`;
261
+ const group = pendingGroups.get(groupKey) || {
262
+ dataSourceName,
263
+ collectionName,
264
+ recordKeys: /* @__PURE__ */ new Set(),
265
+ appends: /* @__PURE__ */ new Set(),
266
+ references: []
267
+ };
268
+ group.recordKeys.add(recordKey);
269
+ appends.forEach((append) => group.appends.add(append));
270
+ group.references.push({ task, fieldName, recordKey });
271
+ pendingGroups.set(groupKey, group);
272
+ });
273
+ }
274
+ for (const group of pendingGroups.values()) {
275
+ const repoEntry = getRepository(group.dataSourceName, group.collectionName);
276
+ if (!repoEntry) {
277
+ group.references.forEach(({ task, fieldName }) => {
278
+ setTaskFieldValue(task, fieldName, null);
279
+ });
280
+ continue;
281
+ }
282
+ const filterTargetKey = repoEntry.filterTargetKey;
283
+ if (!filterTargetKey) {
284
+ group.references.forEach(({ task, fieldName }) => {
285
+ setTaskFieldValue(task, fieldName, null);
286
+ });
287
+ continue;
288
+ }
289
+ const records = await repoEntry.repository.find({
290
+ filter: {
291
+ [filterTargetKey]: Array.from(group.recordKeys)
292
+ },
293
+ appends: group.appends.size ? Array.from(group.appends) : void 0
294
+ });
295
+ const recordMap = new Map(records.map((record) => [toPlainObject(record)[filterTargetKey], toPlainObject(record)]));
296
+ group.references.forEach(({ task, fieldName, recordKey }) => {
297
+ setTaskFieldValue(task, fieldName, recordMap.get(recordKey) ?? null);
298
+ });
299
+ }
300
+ }
301
+ // Annotate the CommonJS export names for ESM import in node:
302
+ 0 && (module.exports = {
303
+ appendTempAssociationFields
304
+ });
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "homepage.ru-RU": "https://docs-ru.nocobase.com/handbook/workflow-cc",
11
11
  "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/workflow-cc",
12
12
  "license": "AGPL-3.0",
13
- "version": "2.0.0-beta.9",
13
+ "version": "2.0.0",
14
14
  "main": "dist/server/index.js",
15
15
  "peerDependencies": {
16
16
  "@nocobase/actions": "2.x",
@@ -25,5 +25,5 @@
25
25
  "keywords": [
26
26
  "Workflow"
27
27
  ],
28
- "gitHead": "36ef50291e22fe1024c819b8748d51a59a5ea4f8"
28
+ "gitHead": "3590c0087a56f0f285a5357f43a80bdc62b11bec"
29
29
  }