@flow-conductor/adapter-axios 1.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.
- package/README.md +527 -0
- package/build/index.d.ts +39 -0
- package/build/index.js +35 -0
- package/build/index.js.map +1 -0
- package/package.json +71 -0
package/README.md
ADDED
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
# @flow-conductor/adapter-axios
|
|
2
|
+
|
|
3
|
+
Axios adapter for flow-conductor. This adapter uses Axios for making HTTP requests, providing features like request/response interceptors, automatic JSON parsing, and better error handling.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @flow-conductor/adapter-axios @flow-conductor/core axios
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Note**: Both `@flow-conductor/core` and `axios` are peer dependencies and must be installed alongside this package.
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { begin } from "@flow-conductor/core";
|
|
17
|
+
import { AxiosRequestAdapter } from "@flow-conductor/adapter-axios";
|
|
18
|
+
|
|
19
|
+
const adapter = new AxiosRequestAdapter();
|
|
20
|
+
|
|
21
|
+
const result = await begin(
|
|
22
|
+
{
|
|
23
|
+
config: {
|
|
24
|
+
url: "https://api.example.com/users",
|
|
25
|
+
method: "GET",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
adapter
|
|
29
|
+
).execute();
|
|
30
|
+
|
|
31
|
+
console.log(result.data); // Axios automatically parses JSON
|
|
32
|
+
console.log(result.status); // HTTP status code
|
|
33
|
+
console.log(result.headers); // Response headers
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
### Basic GET Request
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { begin } from "@flow-conductor/core";
|
|
42
|
+
import { AxiosRequestAdapter } from "@flow-conductor/adapter-axios";
|
|
43
|
+
|
|
44
|
+
const adapter = new AxiosRequestAdapter();
|
|
45
|
+
|
|
46
|
+
const result = await begin(
|
|
47
|
+
{
|
|
48
|
+
config: {
|
|
49
|
+
url: "https://api.example.com/users/1",
|
|
50
|
+
method: "GET",
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
adapter
|
|
54
|
+
).execute();
|
|
55
|
+
|
|
56
|
+
const user = result.data; // Already parsed JSON
|
|
57
|
+
console.log(user);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### POST Request with Data
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { begin } from "@flow-conductor/core";
|
|
64
|
+
import { AxiosRequestAdapter } from "@flow-conductor/adapter-axios";
|
|
65
|
+
|
|
66
|
+
const adapter = new AxiosRequestAdapter();
|
|
67
|
+
|
|
68
|
+
const result = await begin(
|
|
69
|
+
{
|
|
70
|
+
config: {
|
|
71
|
+
url: "https://api.example.com/users",
|
|
72
|
+
method: "POST",
|
|
73
|
+
data: {
|
|
74
|
+
name: "John Doe",
|
|
75
|
+
email: "john@example.com",
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
adapter
|
|
80
|
+
).execute();
|
|
81
|
+
|
|
82
|
+
const newUser = result.data;
|
|
83
|
+
console.log(newUser);
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Request with Custom Headers
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { begin } from "@flow-conductor/core";
|
|
90
|
+
import { AxiosRequestAdapter } from "@flow-conductor/adapter-axios";
|
|
91
|
+
|
|
92
|
+
const adapter = new AxiosRequestAdapter();
|
|
93
|
+
|
|
94
|
+
const result = await begin(
|
|
95
|
+
{
|
|
96
|
+
config: {
|
|
97
|
+
url: "https://api.example.com/users",
|
|
98
|
+
method: "GET",
|
|
99
|
+
headers: {
|
|
100
|
+
Authorization: "Bearer your-token-here",
|
|
101
|
+
"X-Custom-Header": "value",
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
adapter
|
|
106
|
+
).execute();
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Chained Requests
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { begin } from "@flow-conductor/core";
|
|
113
|
+
import { AxiosRequestAdapter } from "@flow-conductor/adapter-axios";
|
|
114
|
+
|
|
115
|
+
const adapter = new AxiosRequestAdapter();
|
|
116
|
+
|
|
117
|
+
const result = await begin(
|
|
118
|
+
{
|
|
119
|
+
config: {
|
|
120
|
+
url: "https://api.example.com/users/1",
|
|
121
|
+
method: "GET",
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
adapter
|
|
125
|
+
)
|
|
126
|
+
.next({
|
|
127
|
+
config: (previousResult) => {
|
|
128
|
+
const user = previousResult.data;
|
|
129
|
+
return {
|
|
130
|
+
url: `https://api.example.com/users/${user.id}/posts`,
|
|
131
|
+
method: "GET",
|
|
132
|
+
};
|
|
133
|
+
},
|
|
134
|
+
})
|
|
135
|
+
.execute();
|
|
136
|
+
|
|
137
|
+
const posts = result.data;
|
|
138
|
+
console.log(posts);
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Configuration
|
|
142
|
+
|
|
143
|
+
The `AxiosRequestAdapter` accepts `IRequestConfig` objects and extends them with Axios-specific options. The adapter automatically:
|
|
144
|
+
|
|
145
|
+
- Parses JSON responses (available in `result.data`)
|
|
146
|
+
- Handles request data serialization
|
|
147
|
+
- Supports all Axios configuration options
|
|
148
|
+
|
|
149
|
+
### Request Config Interface
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
interface AxiosRequestConfigType extends IRequestConfig {
|
|
153
|
+
url: string;
|
|
154
|
+
method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS";
|
|
155
|
+
data?: any; // Automatically serialized by Axios
|
|
156
|
+
headers?: Record<string, string>;
|
|
157
|
+
// ... other Axios options (params, timeout, auth, etc.)
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Supported Axios Options
|
|
162
|
+
|
|
163
|
+
All standard Axios configuration options are supported:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
const result = await begin(
|
|
167
|
+
{
|
|
168
|
+
config: {
|
|
169
|
+
url: "https://api.example.com/users",
|
|
170
|
+
method: "GET",
|
|
171
|
+
headers: {
|
|
172
|
+
Authorization: "Bearer token",
|
|
173
|
+
},
|
|
174
|
+
params: {
|
|
175
|
+
page: 1,
|
|
176
|
+
limit: 10,
|
|
177
|
+
},
|
|
178
|
+
timeout: 5000,
|
|
179
|
+
auth: {
|
|
180
|
+
username: "user",
|
|
181
|
+
password: "pass",
|
|
182
|
+
},
|
|
183
|
+
// ... any other AxiosRequestConfig options
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
adapter
|
|
187
|
+
).execute();
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Query Parameters
|
|
191
|
+
|
|
192
|
+
Axios handles query parameters separately from the URL:
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
const result = await begin(
|
|
196
|
+
{
|
|
197
|
+
config: {
|
|
198
|
+
url: "https://api.example.com/users",
|
|
199
|
+
method: "GET",
|
|
200
|
+
params: {
|
|
201
|
+
page: 1,
|
|
202
|
+
limit: 10,
|
|
203
|
+
sort: "name",
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
adapter
|
|
208
|
+
).execute();
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Data Handling
|
|
212
|
+
|
|
213
|
+
Axios automatically handles data serialization:
|
|
214
|
+
|
|
215
|
+
- **Objects**: Automatically JSON stringified
|
|
216
|
+
- **FormData**: Sent as multipart/form-data
|
|
217
|
+
- **URLSearchParams**: Sent as application/x-www-form-urlencoded
|
|
218
|
+
- **Strings**: Sent as-is
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
// POST with JSON data
|
|
222
|
+
const result = await begin(
|
|
223
|
+
{
|
|
224
|
+
config: {
|
|
225
|
+
url: "https://api.example.com/users",
|
|
226
|
+
method: "POST",
|
|
227
|
+
data: { name: "John", email: "john@example.com" },
|
|
228
|
+
// Content-Type: application/json is automatically set
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
adapter
|
|
232
|
+
).execute();
|
|
233
|
+
|
|
234
|
+
// POST with FormData
|
|
235
|
+
const formData = new FormData();
|
|
236
|
+
formData.append("file", fileBlob);
|
|
237
|
+
|
|
238
|
+
const uploadResult = await begin(
|
|
239
|
+
{
|
|
240
|
+
config: {
|
|
241
|
+
url: "https://api.example.com/upload",
|
|
242
|
+
method: "POST",
|
|
243
|
+
data: formData,
|
|
244
|
+
// Content-Type: multipart/form-data is automatically set
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
adapter
|
|
248
|
+
).execute();
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Custom Axios Instance
|
|
252
|
+
|
|
253
|
+
You can create a custom Axios instance with default configuration:
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
import axios from "axios";
|
|
257
|
+
import { AxiosRequestAdapter } from "@flow-conductor/adapter-axios";
|
|
258
|
+
|
|
259
|
+
// Create a custom axios instance
|
|
260
|
+
const axiosInstance = axios.create({
|
|
261
|
+
baseURL: "https://api.example.com",
|
|
262
|
+
timeout: 5000,
|
|
263
|
+
headers: {
|
|
264
|
+
"X-Custom-Header": "value",
|
|
265
|
+
},
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
// Note: The adapter uses the default axios instance
|
|
269
|
+
// For custom instances, you may need to extend the adapter
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Response Handling
|
|
273
|
+
|
|
274
|
+
The adapter returns an `AxiosResponse` object with the following properties:
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
const result = await begin(
|
|
278
|
+
{
|
|
279
|
+
config: {
|
|
280
|
+
url: "https://api.example.com/users",
|
|
281
|
+
method: "GET",
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
adapter
|
|
285
|
+
).execute();
|
|
286
|
+
|
|
287
|
+
// Response properties
|
|
288
|
+
console.log(result.data); // Response data (automatically parsed JSON)
|
|
289
|
+
console.log(result.status); // HTTP status code
|
|
290
|
+
console.log(result.statusText); // HTTP status text
|
|
291
|
+
console.log(result.headers); // Response headers
|
|
292
|
+
console.log(result.config); // Request configuration
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Automatic JSON Parsing
|
|
296
|
+
|
|
297
|
+
Unlike the Fetch API, Axios automatically parses JSON responses:
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
const result = await begin(
|
|
301
|
+
{
|
|
302
|
+
config: {
|
|
303
|
+
url: "https://api.example.com/users/1",
|
|
304
|
+
method: "GET",
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
adapter
|
|
308
|
+
).execute();
|
|
309
|
+
|
|
310
|
+
// No need to call .json() - data is already parsed
|
|
311
|
+
const user = result.data; // Already a JavaScript object
|
|
312
|
+
console.log(user.name);
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
## Error Handling
|
|
316
|
+
|
|
317
|
+
Axios throws errors for HTTP error statuses (4xx, 5xx), making error handling more straightforward:
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
import { begin } from "@flow-conductor/core";
|
|
321
|
+
import { AxiosRequestAdapter } from "@flow-conductor/adapter-axios";
|
|
322
|
+
import { AxiosError } from "axios";
|
|
323
|
+
|
|
324
|
+
const adapter = new AxiosRequestAdapter();
|
|
325
|
+
|
|
326
|
+
try {
|
|
327
|
+
const result = await begin(
|
|
328
|
+
{
|
|
329
|
+
config: {
|
|
330
|
+
url: "https://api.example.com/users",
|
|
331
|
+
method: "GET",
|
|
332
|
+
},
|
|
333
|
+
},
|
|
334
|
+
adapter
|
|
335
|
+
)
|
|
336
|
+
.withErrorHandler((error) => {
|
|
337
|
+
if (error instanceof AxiosError) {
|
|
338
|
+
console.error("Request failed:", error.message);
|
|
339
|
+
console.error("Status:", error.response?.status);
|
|
340
|
+
console.error("Data:", error.response?.data);
|
|
341
|
+
}
|
|
342
|
+
})
|
|
343
|
+
.execute();
|
|
344
|
+
|
|
345
|
+
const data = result.data;
|
|
346
|
+
console.log(data);
|
|
347
|
+
} catch (error) {
|
|
348
|
+
if (error instanceof AxiosError) {
|
|
349
|
+
// Handle Axios-specific errors
|
|
350
|
+
console.error("Axios error:", error.response?.data);
|
|
351
|
+
} else {
|
|
352
|
+
console.error("Error:", error);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### Error Response Access
|
|
358
|
+
|
|
359
|
+
Axios provides detailed error information:
|
|
360
|
+
|
|
361
|
+
```typescript
|
|
362
|
+
try {
|
|
363
|
+
await begin(
|
|
364
|
+
{
|
|
365
|
+
config: {
|
|
366
|
+
url: "https://api.example.com/users",
|
|
367
|
+
method: "GET",
|
|
368
|
+
},
|
|
369
|
+
},
|
|
370
|
+
adapter
|
|
371
|
+
).execute();
|
|
372
|
+
} catch (error) {
|
|
373
|
+
if (error instanceof AxiosError) {
|
|
374
|
+
if (error.response) {
|
|
375
|
+
// Server responded with error status
|
|
376
|
+
console.error("Status:", error.response.status);
|
|
377
|
+
console.error("Data:", error.response.data);
|
|
378
|
+
console.error("Headers:", error.response.headers);
|
|
379
|
+
} else if (error.request) {
|
|
380
|
+
// Request made but no response received
|
|
381
|
+
console.error("No response:", error.request);
|
|
382
|
+
} else {
|
|
383
|
+
// Error setting up request
|
|
384
|
+
console.error("Error:", error.message);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
## Examples
|
|
391
|
+
|
|
392
|
+
### Authentication Flow
|
|
393
|
+
|
|
394
|
+
```typescript
|
|
395
|
+
import { begin } from "@flow-conductor/core";
|
|
396
|
+
import { AxiosRequestAdapter } from "@flow-conductor/adapter-axios";
|
|
397
|
+
|
|
398
|
+
const adapter = new AxiosRequestAdapter();
|
|
399
|
+
|
|
400
|
+
// Login and use token
|
|
401
|
+
const userData = await begin(
|
|
402
|
+
{
|
|
403
|
+
config: {
|
|
404
|
+
url: "https://api.example.com/auth/login",
|
|
405
|
+
method: "POST",
|
|
406
|
+
data: { username: "user", password: "pass" },
|
|
407
|
+
},
|
|
408
|
+
},
|
|
409
|
+
adapter
|
|
410
|
+
)
|
|
411
|
+
.next({
|
|
412
|
+
config: (previousResult) => {
|
|
413
|
+
const auth = previousResult.data;
|
|
414
|
+
return {
|
|
415
|
+
url: "https://api.example.com/user/profile",
|
|
416
|
+
method: "GET",
|
|
417
|
+
headers: { Authorization: `Bearer ${auth.token}` },
|
|
418
|
+
};
|
|
419
|
+
},
|
|
420
|
+
})
|
|
421
|
+
.execute();
|
|
422
|
+
|
|
423
|
+
const profile = userData.data;
|
|
424
|
+
console.log(profile);
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
### File Upload
|
|
428
|
+
|
|
429
|
+
```typescript
|
|
430
|
+
import { begin } from "@flow-conductor/core";
|
|
431
|
+
import { AxiosRequestAdapter } from "@flow-conductor/adapter-axios";
|
|
432
|
+
|
|
433
|
+
const adapter = new AxiosRequestAdapter();
|
|
434
|
+
|
|
435
|
+
const formData = new FormData();
|
|
436
|
+
formData.append("file", fileBlob);
|
|
437
|
+
formData.append("name", "document.pdf");
|
|
438
|
+
|
|
439
|
+
const result = await begin(
|
|
440
|
+
{
|
|
441
|
+
config: {
|
|
442
|
+
url: "https://api.example.com/upload",
|
|
443
|
+
method: "POST",
|
|
444
|
+
data: formData,
|
|
445
|
+
headers: {
|
|
446
|
+
"Content-Type": "multipart/form-data",
|
|
447
|
+
},
|
|
448
|
+
},
|
|
449
|
+
},
|
|
450
|
+
adapter
|
|
451
|
+
).execute();
|
|
452
|
+
|
|
453
|
+
console.log(result.data);
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
### Request with Timeout
|
|
457
|
+
|
|
458
|
+
```typescript
|
|
459
|
+
const result = await begin(
|
|
460
|
+
{
|
|
461
|
+
config: {
|
|
462
|
+
url: "https://api.example.com/users",
|
|
463
|
+
method: "GET",
|
|
464
|
+
timeout: 5000, // 5 seconds
|
|
465
|
+
},
|
|
466
|
+
},
|
|
467
|
+
adapter
|
|
468
|
+
).execute();
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### Request with Authentication
|
|
472
|
+
|
|
473
|
+
```typescript
|
|
474
|
+
const result = await begin(
|
|
475
|
+
{
|
|
476
|
+
config: {
|
|
477
|
+
url: "https://api.example.com/users",
|
|
478
|
+
method: "GET",
|
|
479
|
+
auth: {
|
|
480
|
+
username: "user",
|
|
481
|
+
password: "pass",
|
|
482
|
+
},
|
|
483
|
+
},
|
|
484
|
+
},
|
|
485
|
+
adapter
|
|
486
|
+
).execute();
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
## API Reference
|
|
490
|
+
|
|
491
|
+
### AxiosRequestAdapter
|
|
492
|
+
|
|
493
|
+
```typescript
|
|
494
|
+
class AxiosRequestAdapter extends RequestAdapter<AxiosResponse, AxiosRequestConfigType> {
|
|
495
|
+
createRequest(requestConfig: AxiosRequestConfigType): Promise<AxiosResponse>;
|
|
496
|
+
}
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
### AxiosRequestConfigType
|
|
500
|
+
|
|
501
|
+
```typescript
|
|
502
|
+
type AxiosRequestConfigType = IRequestConfig & Partial<AxiosRequestConfig>;
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
Extends `IRequestConfig` with all Axios configuration options.
|
|
506
|
+
|
|
507
|
+
## Advantages over Fetch Adapter
|
|
508
|
+
|
|
509
|
+
- **Automatic JSON parsing**: No need to call `.json()` on responses
|
|
510
|
+
- **Better error handling**: Throws errors for HTTP error statuses
|
|
511
|
+
- **Request/Response interceptors**: Can be configured globally
|
|
512
|
+
- **Request cancellation**: Built-in support for canceling requests
|
|
513
|
+
- **Automatic request body serialization**: Handles FormData, URLSearchParams, etc.
|
|
514
|
+
- **Request/Response transformation**: Built-in support for transforming data
|
|
515
|
+
- **Progress tracking**: Support for upload/download progress
|
|
516
|
+
|
|
517
|
+
## Requirements
|
|
518
|
+
|
|
519
|
+
- `@flow-conductor/core` (peer dependency)
|
|
520
|
+
- `axios` ^1.0.0 (peer dependency)
|
|
521
|
+
- Node.js 18+
|
|
522
|
+
- TypeScript 5.0+
|
|
523
|
+
|
|
524
|
+
## License
|
|
525
|
+
|
|
526
|
+
MIT
|
|
527
|
+
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { RequestAdapter, IRequestConfig, UrlValidationOptions } from '@flow-conductor/core';
|
|
2
|
+
import { AxiosResponse, AxiosRequestConfig } from 'axios';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Extended request configuration type that combines IRequestConfig with Axios-specific options.
|
|
6
|
+
* Allows using all Axios configuration options while maintaining compatibility with flow-conductor.
|
|
7
|
+
*/
|
|
8
|
+
type AxiosRequestConfigType = IRequestConfig & Partial<AxiosRequestConfig>;
|
|
9
|
+
/**
|
|
10
|
+
* Request adapter implementation using Axios as the underlying HTTP client.
|
|
11
|
+
* Provides seamless integration between flow-conductor and Axios.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const adapter = new AxiosRequestAdapter();
|
|
16
|
+
* const chain = begin(
|
|
17
|
+
* { config: { url: 'https://api.example.com/users', method: 'GET' } },
|
|
18
|
+
* adapter
|
|
19
|
+
* );
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
declare class AxiosRequestAdapter extends RequestAdapter<AxiosResponse, AxiosRequestConfigType> {
|
|
23
|
+
/**
|
|
24
|
+
* Creates a new AxiosRequestAdapter instance.
|
|
25
|
+
*
|
|
26
|
+
* @param urlValidationOptions - Optional URL validation options to prevent SSRF attacks
|
|
27
|
+
*/
|
|
28
|
+
constructor(urlValidationOptions?: UrlValidationOptions);
|
|
29
|
+
/**
|
|
30
|
+
* Creates and executes an HTTP request using Axios.
|
|
31
|
+
* Converts flow-conductor request configuration to Axios format.
|
|
32
|
+
*
|
|
33
|
+
* @param requestConfig - The request configuration object
|
|
34
|
+
* @returns A promise that resolves to an AxiosResponse
|
|
35
|
+
*/
|
|
36
|
+
createRequest(requestConfig: AxiosRequestConfigType): Promise<AxiosResponse>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { type AxiosRequestConfigType, AxiosRequestAdapter as default };
|
package/build/index.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { RequestAdapter } from '@flow-conductor/core';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
|
|
4
|
+
// src/axios-request-adapter.ts
|
|
5
|
+
var AxiosRequestAdapter = class extends RequestAdapter {
|
|
6
|
+
/**
|
|
7
|
+
* Creates a new AxiosRequestAdapter instance.
|
|
8
|
+
*
|
|
9
|
+
* @param urlValidationOptions - Optional URL validation options to prevent SSRF attacks
|
|
10
|
+
*/
|
|
11
|
+
constructor(urlValidationOptions) {
|
|
12
|
+
super(urlValidationOptions);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Creates and executes an HTTP request using Axios.
|
|
16
|
+
* Converts flow-conductor request configuration to Axios format.
|
|
17
|
+
*
|
|
18
|
+
* @param requestConfig - The request configuration object
|
|
19
|
+
* @returns A promise that resolves to an AxiosResponse
|
|
20
|
+
*/
|
|
21
|
+
async createRequest(requestConfig) {
|
|
22
|
+
const { url, method, data, ...rest } = requestConfig;
|
|
23
|
+
const axiosConfig = {
|
|
24
|
+
url,
|
|
25
|
+
method: method.toLowerCase(),
|
|
26
|
+
data,
|
|
27
|
+
...rest
|
|
28
|
+
};
|
|
29
|
+
return axios(axiosConfig);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export { AxiosRequestAdapter as default };
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
35
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/axios-request-adapter.ts"],"names":[],"mappings":";;;;AA2BA,IAAqB,mBAAA,GAArB,cAAiD,cAAA,CAG/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAY,oBAAA,EAA6C;AACvD,IAAA,KAAA,CAAM,oBAAoB,CAAA;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAa,cACX,aAAA,EACwB;AACxB,IAAA,MAAM,EAAE,GAAA,EAAK,MAAA,EAAQ,IAAA,EAAM,GAAG,MAAK,GAAI,aAAA;AAEvC,IAAA,MAAM,WAAA,GAAkC;AAAA,MACtC,GAAA;AAAA,MACA,MAAA,EAAQ,OAAO,WAAA,EAAY;AAAA,MAC3B,IAAA;AAAA,MACA,GAAG;AAAA,KACL;AAEA,IAAA,OAAO,MAAM,WAAW,CAAA;AAAA,EAC1B;AACF","file":"index.js","sourcesContent":["import { RequestAdapter } from \"@flow-conductor/core\";\nimport type {\n IRequestConfig,\n UrlValidationOptions,\n} from \"@flow-conductor/core\";\nimport axios, { type AxiosRequestConfig, type AxiosResponse } from \"axios\";\n\n/**\n * Extended request configuration type that combines IRequestConfig with Axios-specific options.\n * Allows using all Axios configuration options while maintaining compatibility with flow-conductor.\n */\nexport type AxiosRequestConfigType = IRequestConfig &\n Partial<AxiosRequestConfig>;\n\n/**\n * Request adapter implementation using Axios as the underlying HTTP client.\n * Provides seamless integration between flow-conductor and Axios.\n *\n * @example\n * ```typescript\n * const adapter = new AxiosRequestAdapter();\n * const chain = begin(\n * { config: { url: 'https://api.example.com/users', method: 'GET' } },\n * adapter\n * );\n * ```\n */\nexport default class AxiosRequestAdapter extends RequestAdapter<\n AxiosResponse,\n AxiosRequestConfigType\n> {\n /**\n * Creates a new AxiosRequestAdapter instance.\n *\n * @param urlValidationOptions - Optional URL validation options to prevent SSRF attacks\n */\n constructor(urlValidationOptions?: UrlValidationOptions) {\n super(urlValidationOptions);\n }\n\n /**\n * Creates and executes an HTTP request using Axios.\n * Converts flow-conductor request configuration to Axios format.\n *\n * @param requestConfig - The request configuration object\n * @returns A promise that resolves to an AxiosResponse\n */\n public async createRequest(\n requestConfig: AxiosRequestConfigType\n ): Promise<AxiosResponse> {\n const { url, method, data, ...rest } = requestConfig;\n\n const axiosConfig: AxiosRequestConfig = {\n url,\n method: method.toLowerCase() as AxiosRequestConfig[\"method\"],\n data,\n ...rest,\n };\n\n return axios(axiosConfig);\n }\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flow-conductor/adapter-axios",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Axios adapter for flow-conductor",
|
|
6
|
+
"main": "./build/index.js",
|
|
7
|
+
"types": "./build/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./build/index.d.ts",
|
|
11
|
+
"import": "./build/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"build/**/*.js",
|
|
16
|
+
"build/**/*.d.ts",
|
|
17
|
+
"build/**/*.js.map",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"keywords": [
|
|
22
|
+
"flow-conductor",
|
|
23
|
+
"request",
|
|
24
|
+
"adapter",
|
|
25
|
+
"axios",
|
|
26
|
+
"http",
|
|
27
|
+
"typescript"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"test": "node --test --import tsx/esm 'src/__test__/**/*.test.ts'",
|
|
31
|
+
"test:watch": "node --test --import tsx/esm --watch 'src/__test__/**/*.test.ts'",
|
|
32
|
+
"build": "tsup",
|
|
33
|
+
"clean": "rm -rf build",
|
|
34
|
+
"lint": "eslint src --ext .ts",
|
|
35
|
+
"lint:fix": "eslint src --ext .ts --fix",
|
|
36
|
+
"type-check": "tsc --noEmit",
|
|
37
|
+
"prepublishOnly": "npm run clean && npm run lint && npm run type-check && npm run build"
|
|
38
|
+
},
|
|
39
|
+
"author": "Dawid Hermann",
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "https://github.com/dawidhermann/flow-conductor.git",
|
|
44
|
+
"directory": "packages/adapter-axios"
|
|
45
|
+
},
|
|
46
|
+
"sideEffects": false,
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=18.0.0"
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"@flow-conductor/core": "^1.0.0",
|
|
55
|
+
"axios": "^1.0.0"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@eslint/js": "^9.39.2",
|
|
59
|
+
"@flow-conductor/core": "*",
|
|
60
|
+
"@typescript-eslint/eslint-plugin": "^8.50.1",
|
|
61
|
+
"@typescript-eslint/parser": "^8.50.1",
|
|
62
|
+
"axios": "^1.7.9",
|
|
63
|
+
"eslint": "^9.39.2",
|
|
64
|
+
"eslint-config-prettier": "^10.1.8",
|
|
65
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
66
|
+
"prettier": "^3.7.4",
|
|
67
|
+
"tsx": "^4.7.0",
|
|
68
|
+
"typescript": "^5.9.3",
|
|
69
|
+
"typescript-eslint": "^8.50.1"
|
|
70
|
+
}
|
|
71
|
+
}
|