@nocobase/plugin-workflow-request 0.18.0-alpha.8 → 0.19.0-alpha.1
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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Instruction, WorkflowVariableInput, WorkflowVariableJSON } from '@nocobase/plugin-workflow/client';
|
|
1
|
+
import { Instruction, WorkflowVariableInput, WorkflowVariableJSON, WorkflowVariableTextArea } from '@nocobase/plugin-workflow/client';
|
|
2
2
|
export default class extends Instruction {
|
|
3
3
|
title: string;
|
|
4
4
|
type: string;
|
|
@@ -166,6 +166,7 @@ export default class extends Instruction {
|
|
|
166
166
|
}>;
|
|
167
167
|
};
|
|
168
168
|
WorkflowVariableInput: typeof WorkflowVariableInput;
|
|
169
|
+
WorkflowVariableTextArea: typeof WorkflowVariableTextArea;
|
|
169
170
|
WorkflowVariableJSON: typeof WorkflowVariableJSON;
|
|
170
171
|
};
|
|
171
172
|
useVariables({ key, title }: {
|
package/dist/client/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(t,o){typeof exports=="object"&&typeof module!="undefined"?o(exports,require("@nocobase/client"),require("@formily/antd-v5"),require("@nocobase/plugin-workflow/client"),require("react-i18next")):typeof define=="function"&&define.amd?define(["exports","@nocobase/client","@formily/antd-v5","@nocobase/plugin-workflow/client","react-i18next"],o):(t=typeof globalThis!="undefined"?globalThis:t||self,o(t["@nocobase/plugin-workflow-request"]={},t["@nocobase/client"],t["@formily/antd-v5"],t["@nocobase/plugin-workflow"]))})(this,function(t,o,r,
|
|
1
|
+
(function(t,o){typeof exports=="object"&&typeof module!="undefined"?o(exports,require("@nocobase/client"),require("@formily/antd-v5"),require("@nocobase/plugin-workflow/client"),require("react-i18next")):typeof define=="function"&&define.amd?define(["exports","@nocobase/client","@formily/antd-v5","@nocobase/plugin-workflow/client","react-i18next"],o):(t=typeof globalThis!="undefined"?globalThis:t||self,o(t["@nocobase/plugin-workflow-request"]={},t["@nocobase/client"],t["@formily/antd-v5"],t["@nocobase/plugin-workflow"]))})(this,function(t,o,r,a){"use strict";var x=Object.defineProperty;var y=(t,o,r)=>o in t?x(t,o,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[o]=r;var s=(t,o,r)=>(y(t,typeof o!="symbol"?o+"":o,r),r);var l=(t,o,r)=>new Promise((a,e)=>{var d=n=>{try{p(r.next(n))}catch(i){e(i)}},m=n=>{try{p(r.throw(n))}catch(i){e(i)}},p=n=>n.done?a(n.value):Promise.resolve(n.value).then(d,m);p((r=r.apply(t,o)).next())});const e="workflow-request";class d extends a.Instruction{constructor(){super(...arguments);s(this,"title",`{{t("HTTP request", { ns: "${e}" })}}`);s(this,"type","request");s(this,"group","extended");s(this,"description",`{{t("Send HTTP request to a URL. You can use the variables in the upstream nodes as request headers, parameters and request body.", { ns: "${e}" })}}`);s(this,"fieldset",{method:{type:"string",required:!0,title:`{{t("HTTP method", { ns: "${e}" })}}`,"x-decorator":"FormItem","x-component":"Select","x-component-props":{showSearch:!1,allowClear:!1,className:"auto-width"},enum:[{label:"GET",value:"GET"},{label:"POST",value:"POST"},{label:"PUT",value:"PUT"},{label:"PATCH",value:"PATCH"},{label:"DELETE",value:"DELETE"}],default:"POST"},url:{type:"string",required:!0,title:`{{t("URL", { ns: "${e}" })}}`,"x-decorator":"FormItem","x-decorator-props":{},"x-component":"WorkflowVariableTextArea","x-component-props":{placeholder:"https://www.nocobase.com"}},headers:{type:"array","x-component":"ArrayItems","x-decorator":"FormItem",title:`{{t("Headers", { ns: "${e}" })}}`,description:`{{t('"Content-Type" only support "application/json", and no need to specify', { ns: "${e}" })}}`,items:{type:"object",properties:{space:{type:"void","x-component":"Space",properties:{name:{type:"string","x-decorator":"FormItem","x-component":"Input","x-component-props":{placeholder:'{{t("Name")}}'}},value:{type:"string","x-decorator":"FormItem","x-component":"WorkflowVariableInput","x-component-props":{useTypedConstant:!0}},remove:{type:"void","x-decorator":"FormItem","x-component":"ArrayItems.Remove"}}}}},properties:{add:{type:"void",title:`{{t("Add request header", { ns: "${e}" })}}`,"x-component":"ArrayItems.Addition"}}},params:{type:"array","x-component":"ArrayItems","x-decorator":"FormItem",title:`{{t("Parameters", { ns: "${e}" })}}`,items:{type:"object",properties:{space:{type:"void","x-component":"Space",properties:{name:{type:"string","x-decorator":"FormItem","x-component":"Input","x-component-props":{placeholder:'{{t("Name")}}'}},value:{type:"string","x-decorator":"FormItem","x-component":"WorkflowVariableInput","x-component-props":{useTypedConstant:!0}},remove:{type:"void","x-decorator":"FormItem","x-component":"ArrayItems.Remove"}}}}},properties:{add:{type:"void",title:`{{t("Add parameter", { ns: "${e}" })}}`,"x-component":"ArrayItems.Addition"}}},data:{type:"string",title:`{{t("Body", { ns: "${e}" })}}`,"x-decorator":"FormItem","x-decorator-props":{},"x-component":"WorkflowVariableJSON","x-component-props":{changeOnSelect:!0,autoSize:{minRows:10},placeholder:`{{t("Input request data", { ns: "${e}" })}}`},description:`{{t("Only support standard JSON data", { ns: "${e}" })}}`},timeout:{type:"number",title:`{{t("Timeout config", { ns: "${e}" })}}`,"x-decorator":"FormItem","x-decorator-props":{},"x-component":"InputNumber","x-component-props":{addonAfter:`{{t("ms", { ns: "${e}" })}}`,min:1,step:1e3,defaultValue:5e3}},ignoreFail:{type:"boolean",title:`{{t("Ignore failed request and continue workflow", { ns: "${e}" })}}`,"x-decorator":"FormItem","x-component":"Checkbox"}});s(this,"components",{ArrayItems:r.ArrayItems,WorkflowVariableInput:a.WorkflowVariableInput,WorkflowVariableTextArea:a.WorkflowVariableTextArea,WorkflowVariableJSON:a.WorkflowVariableJSON})}useVariables({key:i,title:u},{types:f,fieldNames:c=a.defaultFieldNames}){return{[c.value]:i,[c.label]:u}}}class m extends o.Plugin{afterAdd(){return l(this,null,function*(){})}beforeLoad(){return l(this,null,function*(){})}load(){return l(this,null,function*(){this.app.pm.get("workflow").registerInstruction("request",d)})}}t.default=m,Object.defineProperties(t,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
package/dist/externalVersion.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
module.exports = {
|
|
2
2
|
"@formily/antd-v5": "1.1.9",
|
|
3
|
-
"@nocobase/plugin-workflow": "0.
|
|
4
|
-
"@nocobase/client": "0.
|
|
3
|
+
"@nocobase/plugin-workflow": "0.19.0-alpha.1",
|
|
4
|
+
"@nocobase/client": "0.19.0-alpha.1",
|
|
5
5
|
"react-i18next": "11.18.6",
|
|
6
|
-
"@nocobase/server": "0.
|
|
6
|
+
"@nocobase/server": "0.19.0-alpha.1",
|
|
7
7
|
"axios": "0.26.1"
|
|
8
8
|
};
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"displayName.zh-CN": "工作流:HTTP 请求节点",
|
|
5
5
|
"description": "Send HTTP requests to any HTTP service for data interaction in workflow.",
|
|
6
6
|
"description.zh-CN": "可用于在工作流中向任意 HTTP 服务发送请求,进行数据交互。",
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.19.0-alpha.1",
|
|
8
8
|
"license": "AGPL-3.0",
|
|
9
9
|
"main": "./dist/server/index.js",
|
|
10
10
|
"devDependencies": {
|
|
@@ -19,5 +19,5 @@
|
|
|
19
19
|
"@nocobase/server": "0.x",
|
|
20
20
|
"@nocobase/test": "0.x"
|
|
21
21
|
},
|
|
22
|
-
"gitHead": "
|
|
22
|
+
"gitHead": "64601944412fc4d2e2bd05f4b982118dd28247dc"
|
|
23
23
|
}
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
Instruction,
|
|
5
5
|
WorkflowVariableInput,
|
|
6
6
|
WorkflowVariableJSON,
|
|
7
|
+
WorkflowVariableTextArea,
|
|
7
8
|
defaultFieldNames,
|
|
8
9
|
} from '@nocobase/plugin-workflow/client';
|
|
9
10
|
|
|
@@ -41,7 +42,7 @@ export default class extends Instruction {
|
|
|
41
42
|
title: `{{t("URL", { ns: "${NAMESPACE}" })}}`,
|
|
42
43
|
'x-decorator': 'FormItem',
|
|
43
44
|
'x-decorator-props': {},
|
|
44
|
-
'x-component': '
|
|
45
|
+
'x-component': 'WorkflowVariableTextArea',
|
|
45
46
|
'x-component-props': {
|
|
46
47
|
placeholder: 'https://www.nocobase.com',
|
|
47
48
|
},
|
|
@@ -175,6 +176,7 @@ export default class extends Instruction {
|
|
|
175
176
|
components = {
|
|
176
177
|
ArrayItems,
|
|
177
178
|
WorkflowVariableInput,
|
|
179
|
+
WorkflowVariableTextArea,
|
|
178
180
|
WorkflowVariableJSON,
|
|
179
181
|
};
|
|
180
182
|
useVariables({ key, title }, { types, fieldNames = defaultFieldNames }) {
|
|
@@ -1,41 +1,42 @@
|
|
|
1
|
+
import { Server } from 'http';
|
|
1
2
|
import jwt from 'jsonwebtoken';
|
|
3
|
+
import Koa from 'koa';
|
|
4
|
+
import bodyParser from 'koa-bodyparser';
|
|
2
5
|
|
|
3
|
-
import { Gateway } from '@nocobase/server';
|
|
4
6
|
import Database from '@nocobase/database';
|
|
5
7
|
import { MockServer } from '@nocobase/test';
|
|
6
8
|
|
|
7
9
|
import { EXECUTION_STATUS, JOB_STATUS } from '@nocobase/plugin-workflow';
|
|
8
10
|
import { getApp, sleep } from '@nocobase/plugin-workflow-test';
|
|
9
11
|
|
|
10
|
-
import Plugin from '..';
|
|
11
12
|
import { RequestConfig } from '../RequestInstruction';
|
|
12
13
|
|
|
13
14
|
const HOST = 'localhost';
|
|
14
|
-
const PORT = 12345;
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
16
|
+
function getRandomPort() {
|
|
17
|
+
const minPort = 1024;
|
|
18
|
+
const maxPort = 49151;
|
|
19
|
+
return Math.floor(Math.random() * (maxPort - minPort + 1)) + minPort;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
class MockAPI {
|
|
23
|
+
app: Koa;
|
|
24
|
+
server: Server;
|
|
25
|
+
port: number;
|
|
26
|
+
get URL_DATA() {
|
|
27
|
+
return `http://${HOST}:${this.port}/api/data`;
|
|
28
|
+
}
|
|
29
|
+
get URL_400() {
|
|
30
|
+
return `http://${HOST}:${this.port}/api/400`;
|
|
31
|
+
}
|
|
32
|
+
get URL_TIMEOUT() {
|
|
33
|
+
return `http://${HOST}:${this.port}/api/timeout`;
|
|
34
|
+
}
|
|
35
|
+
constructor() {
|
|
36
|
+
this.app = new Koa();
|
|
37
|
+
this.app.use(bodyParser());
|
|
38
|
+
|
|
39
|
+
this.app.use(async (ctx, next) => {
|
|
39
40
|
if (ctx.path === '/api/400') {
|
|
40
41
|
return ctx.throw(400);
|
|
41
42
|
}
|
|
@@ -46,7 +47,6 @@ describe('workflow > instructions > request', () => {
|
|
|
46
47
|
}
|
|
47
48
|
if (ctx.path === '/api/data') {
|
|
48
49
|
await sleep(100);
|
|
49
|
-
ctx.withoutDataWrapping = true;
|
|
50
50
|
ctx.body = {
|
|
51
51
|
meta: { title: ctx.query.title },
|
|
52
52
|
data: { title: ctx.request.body['title'] },
|
|
@@ -54,13 +54,45 @@ describe('workflow > instructions > request', () => {
|
|
|
54
54
|
}
|
|
55
55
|
await next();
|
|
56
56
|
});
|
|
57
|
+
}
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
async start() {
|
|
60
|
+
return new Promise((resolve) => {
|
|
61
|
+
this.server = this.app.listen(0, () => {
|
|
62
|
+
this.port = this.server.address()['port'];
|
|
63
|
+
resolve(true);
|
|
64
|
+
});
|
|
61
65
|
});
|
|
66
|
+
}
|
|
62
67
|
|
|
63
|
-
|
|
68
|
+
async close() {
|
|
69
|
+
return new Promise((resolve) => {
|
|
70
|
+
this.server.close(() => {
|
|
71
|
+
resolve(true);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
describe('workflow > instructions > request', () => {
|
|
78
|
+
let app: MockServer;
|
|
79
|
+
let db: Database;
|
|
80
|
+
let PostRepo;
|
|
81
|
+
let PostCollection;
|
|
82
|
+
let ReplyRepo;
|
|
83
|
+
let WorkflowModel;
|
|
84
|
+
let workflow;
|
|
85
|
+
let api: MockAPI;
|
|
86
|
+
|
|
87
|
+
beforeEach(async () => {
|
|
88
|
+
api = new MockAPI();
|
|
89
|
+
api.start();
|
|
90
|
+
app = await getApp({
|
|
91
|
+
resourcer: {
|
|
92
|
+
prefix: '/api',
|
|
93
|
+
},
|
|
94
|
+
plugins: ['users', 'auth', 'workflow-request'],
|
|
95
|
+
});
|
|
64
96
|
|
|
65
97
|
db = app.db;
|
|
66
98
|
WorkflowModel = db.getCollection('workflows').model;
|
|
@@ -78,14 +110,17 @@ describe('workflow > instructions > request', () => {
|
|
|
78
110
|
});
|
|
79
111
|
});
|
|
80
112
|
|
|
81
|
-
afterEach(() =>
|
|
113
|
+
afterEach(async () => {
|
|
114
|
+
await api.close();
|
|
115
|
+
await app.destroy();
|
|
116
|
+
});
|
|
82
117
|
|
|
83
118
|
describe('request static app routes', () => {
|
|
84
119
|
it('get data', async () => {
|
|
85
120
|
await workflow.createNode({
|
|
86
121
|
type: 'request',
|
|
87
122
|
config: {
|
|
88
|
-
url: URL_DATA,
|
|
123
|
+
url: api.URL_DATA,
|
|
89
124
|
method: 'GET',
|
|
90
125
|
} as RequestConfig,
|
|
91
126
|
});
|
|
@@ -105,7 +140,7 @@ describe('workflow > instructions > request', () => {
|
|
|
105
140
|
await workflow.createNode({
|
|
106
141
|
type: 'request',
|
|
107
142
|
config: {
|
|
108
|
-
url: URL_TIMEOUT,
|
|
143
|
+
url: api.URL_TIMEOUT,
|
|
109
144
|
method: 'GET',
|
|
110
145
|
timeout: 250,
|
|
111
146
|
} as RequestConfig,
|
|
@@ -134,7 +169,7 @@ describe('workflow > instructions > request', () => {
|
|
|
134
169
|
await workflow.createNode({
|
|
135
170
|
type: 'request',
|
|
136
171
|
config: {
|
|
137
|
-
url: URL_TIMEOUT,
|
|
172
|
+
url: api.URL_TIMEOUT,
|
|
138
173
|
method: 'GET',
|
|
139
174
|
timeout: 250,
|
|
140
175
|
ignoreFail: true,
|
|
@@ -160,7 +195,7 @@ describe('workflow > instructions > request', () => {
|
|
|
160
195
|
await workflow.createNode({
|
|
161
196
|
type: 'request',
|
|
162
197
|
config: {
|
|
163
|
-
url: URL_400,
|
|
198
|
+
url: api.URL_400,
|
|
164
199
|
method: 'GET',
|
|
165
200
|
ignoreFail: false,
|
|
166
201
|
} as RequestConfig,
|
|
@@ -180,7 +215,7 @@ describe('workflow > instructions > request', () => {
|
|
|
180
215
|
await workflow.createNode({
|
|
181
216
|
type: 'request',
|
|
182
217
|
config: {
|
|
183
|
-
url: URL_400,
|
|
218
|
+
url: api.URL_400,
|
|
184
219
|
method: 'GET',
|
|
185
220
|
timeout: 1000,
|
|
186
221
|
ignoreFail: true,
|
|
@@ -201,7 +236,7 @@ describe('workflow > instructions > request', () => {
|
|
|
201
236
|
const n1 = await workflow.createNode({
|
|
202
237
|
type: 'request',
|
|
203
238
|
config: {
|
|
204
|
-
url: URL_DATA,
|
|
239
|
+
url: api.URL_DATA,
|
|
205
240
|
method: 'POST',
|
|
206
241
|
data: { title: '{{$context.data.title}}' },
|
|
207
242
|
} as RequestConfig,
|
|
@@ -222,7 +257,7 @@ describe('workflow > instructions > request', () => {
|
|
|
222
257
|
const n1 = await workflow.createNode({
|
|
223
258
|
type: 'request',
|
|
224
259
|
config: {
|
|
225
|
-
url: URL_DATA,
|
|
260
|
+
url: api.URL_DATA,
|
|
226
261
|
method: 'POST',
|
|
227
262
|
data: { title: '{{$context.data.title}}' },
|
|
228
263
|
} as RequestConfig,
|
|
@@ -254,7 +289,7 @@ describe('workflow > instructions > request', () => {
|
|
|
254
289
|
upstreamId: n1.id,
|
|
255
290
|
branchIndex: 0,
|
|
256
291
|
config: {
|
|
257
|
-
url: URL_DATA,
|
|
292
|
+
url: api.URL_DATA,
|
|
258
293
|
method: 'GET',
|
|
259
294
|
},
|
|
260
295
|
});
|
|
@@ -286,10 +321,14 @@ describe('workflow > instructions > request', () => {
|
|
|
286
321
|
},
|
|
287
322
|
);
|
|
288
323
|
|
|
324
|
+
const server = app.listen(12346, () => {});
|
|
325
|
+
|
|
326
|
+
await sleep(1000);
|
|
327
|
+
|
|
289
328
|
const n1 = await workflow.createNode({
|
|
290
329
|
type: 'request',
|
|
291
330
|
config: {
|
|
292
|
-
url: `http://localhost
|
|
331
|
+
url: `http://localhost:12346/api/categories`,
|
|
293
332
|
method: 'POST',
|
|
294
333
|
headers: [{ name: 'Authorization', value: `Bearer ${token}` }],
|
|
295
334
|
} as RequestConfig,
|
|
@@ -306,6 +345,8 @@ describe('workflow > instructions > request', () => {
|
|
|
306
345
|
const [job] = await execution.getJobs();
|
|
307
346
|
expect(job.status).toBe(JOB_STATUS.RESOLVED);
|
|
308
347
|
expect(job.result.data).toMatchObject({});
|
|
348
|
+
|
|
349
|
+
server.close();
|
|
309
350
|
});
|
|
310
351
|
});
|
|
311
352
|
});
|