@nocobase/plugin-workflow-request 2.1.0-beta.37 → 2.1.0-beta.38

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.
@@ -14,12 +14,12 @@ module.exports = {
14
14
  "@formily/react": "2.3.7",
15
15
  "@formily/antd-v5": "1.2.3",
16
16
  "@ant-design/icons": "5.6.1",
17
- "@nocobase/client": "2.1.0-beta.37",
18
- "@nocobase/plugin-workflow": "2.1.0-beta.37",
17
+ "@nocobase/client": "2.1.0-beta.38",
18
+ "@nocobase/plugin-workflow": "2.1.0-beta.38",
19
19
  "react-i18next": "11.18.6",
20
- "@nocobase/server": "2.1.0-beta.37",
20
+ "@nocobase/server": "2.1.0-beta.38",
21
21
  "axios": "1.7.7",
22
22
  "lodash": "4.18.1",
23
- "@nocobase/plugin-file-manager": "2.1.0-beta.37",
24
- "@nocobase/utils": "2.1.0-beta.37"
23
+ "@nocobase/plugin-file-manager": "2.1.0-beta.38",
24
+ "@nocobase/utils": "2.1.0-beta.38"
25
25
  };
@@ -1 +1 @@
1
- {"name":"joi","description":"Object schema validation","version":"17.13.3","repository":"git://github.com/hapijs/joi","main":"lib/index.js","types":"lib/index.d.ts","browser":"dist/joi-browser.min.js","files":["lib/**/*","dist/*"],"keywords":["schema","validation"],"dependencies":{"@hapi/hoek":"^9.3.0","@hapi/topo":"^5.1.0","@sideway/address":"^4.1.5","@sideway/formula":"^3.0.1","@sideway/pinpoint":"^2.0.0"},"devDependencies":{"@hapi/bourne":"2.x.x","@hapi/code":"8.x.x","@hapi/joi-legacy-test":"npm:@hapi/joi@15.x.x","@hapi/lab":"^25.1.3","@types/node":"^14.18.63","typescript":"4.3.x"},"scripts":{"prepublishOnly":"cd browser && npm install && npm run build","test":"lab -t 100 -a @hapi/code -L -Y","test-cov-html":"lab -r html -o coverage.html -a @hapi/code"},"license":"BSD-3-Clause","_lastModified":"2026-05-26T00:46:22.707Z"}
1
+ {"name":"joi","description":"Object schema validation","version":"17.13.3","repository":"git://github.com/hapijs/joi","main":"lib/index.js","types":"lib/index.d.ts","browser":"dist/joi-browser.min.js","files":["lib/**/*","dist/*"],"keywords":["schema","validation"],"dependencies":{"@hapi/hoek":"^9.3.0","@hapi/topo":"^5.1.0","@sideway/address":"^4.1.5","@sideway/formula":"^3.0.1","@sideway/pinpoint":"^2.0.0"},"devDependencies":{"@hapi/bourne":"2.x.x","@hapi/code":"8.x.x","@hapi/joi-legacy-test":"npm:@hapi/joi@15.x.x","@hapi/lab":"^25.1.3","@types/node":"^14.18.63","typescript":"4.3.x"},"scripts":{"prepublishOnly":"cd browser && npm install && npm run build","test":"lab -t 100 -a @hapi/code -L -Y","test-cov-html":"lab -r html -o coverage.html -a @hapi/code"},"license":"BSD-3-Clause","_lastModified":"2026-05-29T02:54:09.920Z"}
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import Joi from 'joi';
10
10
  import { AxiosRequestConfig } from 'axios';
11
- import { Processor, Instruction, FlowNodeModel } from '@nocobase/plugin-workflow';
11
+ import { Processor, Instruction, FlowNodeModel, JobModel } from '@nocobase/plugin-workflow';
12
12
  export interface Header {
13
13
  name: string;
14
14
  value: string;
@@ -21,19 +21,21 @@ export type RequestInstructionConfig = Pick<AxiosRequestConfig, 'url' | 'method'
21
21
  };
22
22
  export default class extends Instruction {
23
23
  configSchema: Joi.ObjectSchema<any>;
24
- run(node: FlowNodeModel, prevJob: any, processor: Processor): Promise<{
24
+ run(node: FlowNodeModel, prevJob: JobModel, processor: Processor, options?: {
25
+ signal?: AbortSignal;
26
+ }): Promise<{
25
27
  status: 1;
26
28
  result: any;
27
29
  } | {
28
- status: 1 | -1;
30
+ status: 1 | -3 | -1;
29
31
  result: Record<string, any>;
30
32
  }>;
31
- resume(node: FlowNodeModel, job: any, processor: Processor): Promise<any>;
33
+ resume(node: FlowNodeModel, job: JobModel, processor: Processor): Promise<JobModel>;
32
34
  test(config: RequestInstructionConfig): Promise<{
33
35
  status: 1;
34
36
  result: any;
35
37
  } | {
36
- status: 1 | -1;
38
+ status: 1 | -3 | -1;
37
39
  result: Record<string, any>;
38
40
  }>;
39
41
  }
@@ -95,6 +95,9 @@ function createInvalidUrlError(cause) {
95
95
  return error;
96
96
  }
97
97
  function validateUrl(url) {
98
+ if (!url) {
99
+ throw createInvalidUrlError();
100
+ }
98
101
  try {
99
102
  const parsed = new URL(url);
100
103
  if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
@@ -104,7 +107,7 @@ function validateUrl(url) {
104
107
  throw createInvalidUrlError(error);
105
108
  }
106
109
  }
107
- async function request(config, app) {
110
+ async function request(config, app, signal) {
108
111
  const { url, method = "POST", contentType = "application/json", data, timeout = 5e3 } = config;
109
112
  validateUrl(url);
110
113
  const headers = (config.headers ?? []).reduce((result, header) => {
@@ -128,6 +131,7 @@ async function request(config, app) {
128
131
  headers,
129
132
  params,
130
133
  timeout,
134
+ signal,
131
135
  ...method.toLowerCase() !== "get" && data != null ? {
132
136
  data: transformer ? await transformer(data) : data
133
137
  } : {}
@@ -157,6 +161,12 @@ function responseFailure(error) {
157
161
  }
158
162
  return result;
159
163
  }
164
+ function failureStatus(config, error) {
165
+ if (config.ignoreFail) {
166
+ return import_plugin_workflow.JOB_STATUS.RESOLVED;
167
+ }
168
+ return (error == null ? void 0 : error.code) === "ECONNABORTED" ? import_plugin_workflow.JOB_STATUS.ABORTED : import_plugin_workflow.JOB_STATUS.FAILED;
169
+ }
160
170
  const METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE"];
161
171
  const CONTENT_TYPES = [
162
172
  "application/json",
@@ -201,13 +211,13 @@ class RequestInstruction_default extends import_plugin_workflow.Instruction {
201
211
  ignoreFail: import_joi.default.boolean().default(false),
202
212
  onlyData: import_joi.default.boolean().default(false)
203
213
  });
204
- async run(node, prevJob, processor) {
214
+ async run(node, prevJob, processor, options) {
205
215
  const config = processor.getParsedValue(node.config, node.id);
206
216
  const { workflow } = processor.execution;
207
217
  const sync = this.workflow.isWorkflowSync(workflow);
208
218
  if (sync) {
209
219
  try {
210
- const response = await request(config, this.workflow.app);
220
+ const response = await request(config, this.workflow.app, options == null ? void 0 : options.signal);
211
221
  return {
212
222
  status: import_plugin_workflow.JOB_STATUS.RESOLVED,
213
223
  result: responseSuccess(response, config.onlyData)
@@ -215,7 +225,7 @@ class RequestInstruction_default extends import_plugin_workflow.Instruction {
215
225
  } catch (error) {
216
226
  logFailureDebug(this.workflow.app.logger, error);
217
227
  return {
218
- status: config.ignoreFail ? import_plugin_workflow.JOB_STATUS.RESOLVED : import_plugin_workflow.JOB_STATUS.FAILED,
228
+ status: failureStatus(config, error),
219
229
  result: responseFailure(error)
220
230
  };
221
231
  }
@@ -230,7 +240,7 @@ class RequestInstruction_default extends import_plugin_workflow.Instruction {
230
240
  const jobDone = { status: import_plugin_workflow.JOB_STATUS.PENDING };
231
241
  try {
232
242
  processor.logger.info(`request (#${node.id}) sent to "${config.url}", waiting for response...`);
233
- const response = await request(config, this.workflow.app);
243
+ const response = await request(config, this.workflow.app, options == null ? void 0 : options.signal);
234
244
  processor.logger.info(`request (#${node.id}) response success, status: ${response.status}`);
235
245
  jobDone.status = import_plugin_workflow.JOB_STATUS.RESOLVED;
236
246
  jobDone.result = responseSuccess(response, config.onlyData);
@@ -247,14 +257,20 @@ class RequestInstruction_default extends import_plugin_workflow.Instruction {
247
257
  processor.logger.error(`request (#${node.id}) failed unexpectedly: ${error.message}`);
248
258
  }
249
259
  logFailureDebug(processor.logger, error);
250
- jobDone.status = config.ignoreFail ? import_plugin_workflow.JOB_STATUS.RESOLVED : import_plugin_workflow.JOB_STATUS.FAILED;
260
+ jobDone.status = failureStatus(config, error);
251
261
  jobDone.result = responseFailure(error);
252
262
  } finally {
253
263
  const job = await this.workflow.app.db.getRepository("jobs").findOne({
254
264
  filterByTk: id
255
265
  });
256
- job.set(jobDone);
257
- this.workflow.resume(job);
266
+ const execution = await job.getExecution();
267
+ if (!execution.status) {
268
+ job.set(jobDone);
269
+ job.execution = execution;
270
+ this.workflow.resume(job);
271
+ } else {
272
+ processor.logger.warn(`request (#${node.id}) result discarded because execution (${execution.id}) is ended`);
273
+ }
258
274
  }
259
275
  }
260
276
  async resume(node, job, processor) {
@@ -274,7 +290,7 @@ class RequestInstruction_default extends import_plugin_workflow.Instruction {
274
290
  } catch (error) {
275
291
  logFailureDebug(this.workflow.app.logger, error);
276
292
  return {
277
- status: config.ignoreFail ? import_plugin_workflow.JOB_STATUS.RESOLVED : import_plugin_workflow.JOB_STATUS.FAILED,
293
+ status: failureStatus(config, error),
278
294
  result: responseFailure(error)
279
295
  };
280
296
  }
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "description": "Send HTTP requests to any HTTP service for data interaction in workflow.",
7
7
  "description.ru-RU": "Отправляет HTTP-запросы к любому HTTP-сервису для взаимодействия с данными в рабочем процессе.",
8
8
  "description.zh-CN": "可用于在工作流中向任意 HTTP 服务发送请求,进行数据交互。",
9
- "version": "2.1.0-beta.37",
9
+ "version": "2.1.0-beta.38",
10
10
  "license": "Apache-2.0",
11
11
  "main": "./dist/server/index.js",
12
12
  "homepage": "https://docs.nocobase.com/handbook/workflow-request",
@@ -27,7 +27,7 @@
27
27
  "@nocobase/server": "2.x",
28
28
  "@nocobase/test": "2.x"
29
29
  },
30
- "gitHead": "7132e5b83ecc0e42b54715eaf1429c72bcef34ae",
30
+ "gitHead": "d1c585108ff6e51c17b0b52bacb1a2d621d9c119",
31
31
  "keywords": [
32
32
  "Workflow"
33
33
  ]