@powerduck/openapi-request 0.2.3 → 0.2.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.
- package/README.md +139 -294
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
# @powerduck/openapi-request
|
|
2
2
|
|
|
3
|
-
Execute OpenAPI operations with full parameter serialization, security resolution, and response parsing. Supports fetch, axios, and custom HTTP clients. Built for browsers, Node.js, and Edge Functions.
|
|
4
|
-
|
|
5
3
|
[](https://www.npmjs.com/package/@powerduck/openapi-request)
|
|
6
4
|
[](https://github.com/PowerDuckie/openapi-request/blob/main/LICENSE)
|
|
5
|
+
[](https://www.npmjs.com/package/@powerduck/openapi-request)
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
Execute OpenAPI operations with full parameter serialization, security resolution, and response parsing. Supports fetch, axios, and custom HTTP clients. Built for browsers, Node.js, and Edge Functions.
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
-
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
Powerduck is an open-source developer tooling platform for teams building modern API workflows.
|
|
12
|
+
|
|
13
|
+
- **Full Parameter Serialization** — Path, query, header, and cookie parameters with RFC 6570 URI templates
|
|
14
|
+
- **Security Resolution** — Bearer tokens, API keys, Basic auth, OAuth2, and custom schemes
|
|
15
|
+
- **3 HTTP Clients** — fetch (default), axios, and custom client adapters
|
|
16
|
+
- **Request Body Handling** — JSON, form-data, x-www-form-urlencoded, and raw payloads
|
|
17
|
+
- **Response Parsing** — Automatic JSON, text, blob, and stream parsing with content-type detection
|
|
18
|
+
- **Prepare & Send** — Two-phase API for request inspection before sending
|
|
19
|
+
- **Type-Safe Operations** — Full TypeScript types for parameters, request bodies, and responses
|
|
20
|
+
- **Error Handling** — Structured error objects with status, headers, and parsed body
|
|
21
|
+
- **Interceptors** — Request and response interceptors for logging, auth refresh, and retries
|
|
22
|
+
- **Browser & Node** — Works in browsers, Node.js, and Edge Functions with zero dependencies
|
|
15
23
|
|
|
16
24
|
---
|
|
17
25
|
|
|
@@ -39,9 +47,9 @@ const result = await client.send({
|
|
|
39
47
|
},
|
|
40
48
|
});
|
|
41
49
|
|
|
42
|
-
console.log(result.response.status);
|
|
43
|
-
console.log(result.response.body);
|
|
44
|
-
console.log(result.response.headers);
|
|
50
|
+
console.log(result.response.status); // e.g. 200
|
|
51
|
+
console.log(result.response.body); // parsed response body
|
|
52
|
+
console.log(result.response.headers); // response headers
|
|
45
53
|
```
|
|
46
54
|
|
|
47
55
|
### Prepare and send separately
|
|
@@ -60,368 +68,205 @@ const prepared = client.prepare({
|
|
|
60
68
|
},
|
|
61
69
|
});
|
|
62
70
|
|
|
63
|
-
console.log(prepared.url);
|
|
64
|
-
console.log(prepared.method);
|
|
65
|
-
console.log(prepared.headers);
|
|
71
|
+
console.log(prepared.url); // final URL with serialized params
|
|
72
|
+
console.log(prepared.method); // HTTP method
|
|
73
|
+
console.log(prepared.headers); // resolved headers
|
|
66
74
|
|
|
67
75
|
// Send the prepared request
|
|
68
|
-
const result = await client.
|
|
76
|
+
const result = await client.sendPrepared(prepared);
|
|
69
77
|
```
|
|
70
78
|
|
|
71
|
-
### With
|
|
79
|
+
### With authentication
|
|
72
80
|
|
|
73
81
|
```typescript
|
|
74
82
|
import { createClient } from "@powerduck/openapi-request";
|
|
75
83
|
|
|
76
84
|
const client = createClient({
|
|
77
85
|
securityValues: {
|
|
78
|
-
bearerAuth: "
|
|
79
|
-
apiKey: "
|
|
86
|
+
bearerAuth: "your-token-here",
|
|
87
|
+
apiKey: "your-api-key",
|
|
80
88
|
},
|
|
81
89
|
});
|
|
82
90
|
|
|
83
91
|
const result = await client.send({
|
|
84
92
|
spec: openApiDocument,
|
|
85
|
-
operationId: "
|
|
86
|
-
parameters: {
|
|
87
|
-
body: { name: "Ada", email: "ada@example.com" },
|
|
88
|
-
},
|
|
93
|
+
operationId: "getProfile",
|
|
89
94
|
});
|
|
90
95
|
```
|
|
91
96
|
|
|
92
|
-
|
|
97
|
+
---
|
|
93
98
|
|
|
94
|
-
|
|
95
|
-
import { createClient } from "@powerduck/openapi-request";
|
|
99
|
+
## Links
|
|
96
100
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
console.log("Response:", response.status);
|
|
102
|
-
return response;
|
|
103
|
-
},
|
|
104
|
-
});
|
|
105
|
-
```
|
|
101
|
+
- [Official Website](https://www.powerduck.com/opensource/openapi-request.html)
|
|
102
|
+
- [Documentation](https://www.powerduck.com/docs/openapi-request/introduction)
|
|
103
|
+
- [GitHub](https://github.com/PowerDuckie/openapi-request)
|
|
104
|
+
- [npm](https://www.npmjs.com/package/@powerduck/openapi-request)
|
|
106
105
|
|
|
107
106
|
---
|
|
108
107
|
|
|
109
108
|
## Features
|
|
110
109
|
|
|
111
|
-
- **Full
|
|
112
|
-
- **Security resolution** — Bearer
|
|
113
|
-
- **
|
|
114
|
-
- **
|
|
115
|
-
- **
|
|
116
|
-
- **
|
|
117
|
-
- **
|
|
118
|
-
- **
|
|
119
|
-
- **
|
|
120
|
-
- **
|
|
121
|
-
- **
|
|
122
|
-
- **
|
|
110
|
+
- **Full parameter serialization** — Path, query, header, and cookie parameters with RFC 6570 URI templates
|
|
111
|
+
- **Security resolution** — Bearer tokens, API keys, Basic auth, OAuth2, and custom schemes
|
|
112
|
+
- **3 HTTP clients** — fetch (default), axios, and custom client adapters
|
|
113
|
+
- **Request body handling** — JSON, form-data, x-www-form-urlencoded, and raw payloads
|
|
114
|
+
- **Response parsing** — Automatic JSON, text, blob, and stream parsing with content-type detection
|
|
115
|
+
- **Prepare & send** — Two-phase API for request inspection before sending
|
|
116
|
+
- **Type-safe operations** — Full TypeScript types for parameters, request bodies, and responses
|
|
117
|
+
- **Error handling** — Structured error objects with status, headers, and parsed body
|
|
118
|
+
- **Interceptors** — Request and response interceptors for logging, auth refresh, and retries
|
|
119
|
+
- **Browser & Node** — Works in browsers, Node.js, and Edge Functions with zero dependencies
|
|
120
|
+
- **Server selection** — Auto-select or manually specify server from OpenAPI servers
|
|
121
|
+
- **Content negotiation** — Automatic Accept header based on response content types
|
|
122
|
+
- **Upload progress** — Progress callbacks for file uploads with axios client
|
|
123
|
+
- **Abort support** — AbortController / AbortSignal for request cancellation
|
|
124
|
+
- **Dual ESM/CJS** — Works with `import` and `require`, with bundled TypeScript declarations
|
|
123
125
|
|
|
124
126
|
---
|
|
125
127
|
|
|
126
|
-
## API
|
|
127
|
-
|
|
128
|
-
### `createClient(options?: CreateClientOptions): OpenApiClient`
|
|
129
|
-
|
|
130
|
-
Creates a new client instance.
|
|
131
|
-
|
|
132
|
-
```typescript
|
|
133
|
-
interface CreateClientOptions {
|
|
134
|
-
fetchFn?: (url: string, init: RequestInit) => Promise<Response>;
|
|
135
|
-
securityValues?: Record<string, string>;
|
|
136
|
-
serverUrl?: string;
|
|
137
|
-
timeoutMs?: number;
|
|
138
|
-
validateResponse?: boolean;
|
|
139
|
-
}
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### `client.send(options: SendOptions): Promise<SendResult>`
|
|
143
|
-
|
|
144
|
-
Prepares and sends a request in one call.
|
|
145
|
-
|
|
146
|
-
### `client.prepare(options: SendOptions): PreparedRequest`
|
|
147
|
-
|
|
148
|
-
Builds the request without sending. Returns a `PreparedRequest` that can be inspected or passed to `send()`.
|
|
128
|
+
## API Reference
|
|
149
129
|
|
|
150
|
-
### `
|
|
130
|
+
### `createClient(options?)`
|
|
151
131
|
|
|
152
|
-
|
|
153
|
-
interface SendOptions {
|
|
154
|
-
spec: OpenApiDocument; // Parsed OpenAPI 3.2 document
|
|
155
|
-
operationId?: string; // Operation ID (alternative to path + method)
|
|
156
|
-
path?: string; // Path template, e.g. "/users/{id}"
|
|
157
|
-
method?: string; // HTTP method, e.g. "get"
|
|
158
|
-
parameters?: {
|
|
159
|
-
path?: Record<string, unknown>;
|
|
160
|
-
query?: Record<string, unknown>;
|
|
161
|
-
header?: Record<string, string>;
|
|
162
|
-
cookie?: Record<string, string>;
|
|
163
|
-
body?: unknown;
|
|
164
|
-
};
|
|
165
|
-
securityValues?: Record<string, string>;
|
|
166
|
-
serverUrl?: string;
|
|
167
|
-
timeoutMs?: number;
|
|
168
|
-
signal?: AbortSignal;
|
|
169
|
-
}
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
> Either `operationId` or `path` + `method` must be provided to identify the operation.
|
|
173
|
-
|
|
174
|
-
### `SendResult`
|
|
132
|
+
Create an OpenAPI request client.
|
|
175
133
|
|
|
176
134
|
```typescript
|
|
177
|
-
|
|
178
|
-
response: {
|
|
179
|
-
status: number; // HTTP status code
|
|
180
|
-
statusText: string; // HTTP status text
|
|
181
|
-
headers: Record<string, string>; // Response headers
|
|
182
|
-
body?: unknown; // Parsed JSON body (if content-type is JSON)
|
|
183
|
-
text?: string; // Raw response text
|
|
184
|
-
};
|
|
185
|
-
timings: {
|
|
186
|
-
durationMs: number; // Total request duration in milliseconds
|
|
187
|
-
};
|
|
188
|
-
sizeBytes: number; // Response body size in bytes
|
|
189
|
-
}
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
> **Important:** Response data is under `result.response`, not directly on `result`. Use `result.response.status`, `result.response.body`, and `result.response.headers`.
|
|
193
|
-
|
|
194
|
-
### `PreparedRequest`
|
|
135
|
+
import { createClient } from "@powerduck/openapi-request";
|
|
195
136
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
path: string; // Path template
|
|
204
|
-
parameters: ResolvedParameters;
|
|
205
|
-
}
|
|
137
|
+
const client = createClient({
|
|
138
|
+
client: "fetch", // "fetch" | "axios" | custom adapter
|
|
139
|
+
baseUrl: "https://api.example.com",
|
|
140
|
+
securityValues: { bearerAuth: "token" },
|
|
141
|
+
defaultHeaders: { "X-App": "my-app" },
|
|
142
|
+
timeout: 30000,
|
|
143
|
+
});
|
|
206
144
|
```
|
|
207
145
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
## Parameter Serialization
|
|
146
|
+
### `client.send(options)`
|
|
211
147
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
| Location | Style | `explode: true` | `explode: false` |
|
|
215
|
-
|---|---|---|---|
|
|
216
|
-
| `path` | `simple` (default) | `id=5,role=admin` | `id,role=5,admin` |
|
|
217
|
-
| `path` | `label` | `.id=5.role=admin` | `.id,role=5,admin` |
|
|
218
|
-
| `path` | `matrix` | `;id=5;role=admin` | `;id,role=5,admin` |
|
|
219
|
-
| `query` | `form` (default) | `id=5&role=admin` | `id=5,role=admin` |
|
|
220
|
-
| `query` | `spaceDelimited` | `id=5%20role=admin` | `id=5%20role=admin` |
|
|
221
|
-
| `query` | `pipeDelimited` | `id=5\|role=admin` | `id=5\|role=admin` |
|
|
222
|
-
| `query` | `deepObject` | `user[id]=5&user[role]=admin` | — |
|
|
223
|
-
| `header` | `simple` (default) | `id=5,role=admin` | `id,role=5,admin` |
|
|
224
|
-
| `cookie` | `form` (default) | `id=5; role=admin` | `id=5,role=admin` |
|
|
225
|
-
|
|
226
|
-
---
|
|
227
|
-
|
|
228
|
-
## Security Schemes
|
|
229
|
-
|
|
230
|
-
### Bearer token
|
|
148
|
+
Send an OpenAPI operation.
|
|
231
149
|
|
|
232
150
|
```typescript
|
|
233
151
|
const result = await client.send({
|
|
234
|
-
spec,
|
|
152
|
+
spec: openApiDocument,
|
|
235
153
|
operationId: "getUser",
|
|
236
|
-
|
|
154
|
+
parameters: {
|
|
155
|
+
path: { id: "123" },
|
|
156
|
+
query: { include: ["profile", "orders"] },
|
|
157
|
+
header: { "X-Request-ID": "abc" },
|
|
158
|
+
},
|
|
159
|
+
requestBody: { name: "Ada" },
|
|
160
|
+
securityValues: { bearerAuth: "token" },
|
|
161
|
+
serverIndex: 0,
|
|
162
|
+
signal: abortSignal,
|
|
237
163
|
});
|
|
238
|
-
// Sends: Authorization: Bearer YOUR_TOKEN
|
|
239
164
|
```
|
|
240
165
|
|
|
241
|
-
###
|
|
242
|
-
|
|
243
|
-
```typescript
|
|
244
|
-
const result = await client.send({
|
|
245
|
-
spec,
|
|
246
|
-
operationId: "getUser",
|
|
247
|
-
securityValues: { basicAuth: "username:password" },
|
|
248
|
-
});
|
|
249
|
-
// Sends: Authorization: Basic <base64(username:password)>
|
|
250
|
-
```
|
|
166
|
+
### `client.prepare(options)`
|
|
251
167
|
|
|
252
|
-
|
|
168
|
+
Prepare a request without sending.
|
|
253
169
|
|
|
254
170
|
```typescript
|
|
255
|
-
const
|
|
256
|
-
spec,
|
|
257
|
-
operationId: "
|
|
258
|
-
|
|
171
|
+
const prepared = client.prepare({
|
|
172
|
+
spec: openApiDocument,
|
|
173
|
+
operationId: "listUsers",
|
|
174
|
+
parameters: { query: { page: 1 } },
|
|
259
175
|
});
|
|
260
|
-
// Sends: X-API-Key: YOUR_KEY (header name from spec)
|
|
261
|
-
```
|
|
262
176
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
```typescript
|
|
266
|
-
const result = await client.send({
|
|
267
|
-
spec,
|
|
268
|
-
operationId: "getUser",
|
|
269
|
-
securityValues: { apiKeyQuery: "YOUR_KEY" },
|
|
270
|
-
});
|
|
271
|
-
// Appends: ?api_key=YOUR_KEY (param name from spec)
|
|
177
|
+
// prepared.url, prepared.method, prepared.headers, prepared.body
|
|
272
178
|
```
|
|
273
179
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
## Request Body Examples
|
|
180
|
+
### `client.sendPrepared(prepared)`
|
|
277
181
|
|
|
278
|
-
|
|
182
|
+
Send a previously prepared request.
|
|
279
183
|
|
|
280
184
|
```typescript
|
|
281
|
-
const result = await client.
|
|
282
|
-
spec,
|
|
283
|
-
operationId: "createUser",
|
|
284
|
-
parameters: {
|
|
285
|
-
body: { name: "Ada", email: "ada@example.com" },
|
|
286
|
-
},
|
|
287
|
-
});
|
|
185
|
+
const result = await client.sendPrepared(prepared);
|
|
288
186
|
```
|
|
289
187
|
|
|
290
|
-
###
|
|
188
|
+
### Result Type
|
|
291
189
|
|
|
292
190
|
```typescript
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
191
|
+
interface RequestResult<T = unknown> {
|
|
192
|
+
response: {
|
|
193
|
+
status: number;
|
|
194
|
+
statusText: string;
|
|
195
|
+
headers: Record<string, string>;
|
|
196
|
+
body: T;
|
|
197
|
+
raw: Response;
|
|
198
|
+
};
|
|
199
|
+
request: {
|
|
200
|
+
url: string;
|
|
201
|
+
method: string;
|
|
202
|
+
headers: Record<string, string>;
|
|
203
|
+
body?: unknown;
|
|
204
|
+
};
|
|
205
|
+
duration: number; // milliseconds
|
|
206
|
+
}
|
|
300
207
|
```
|
|
301
208
|
|
|
302
|
-
###
|
|
209
|
+
### Error Type
|
|
303
210
|
|
|
304
211
|
```typescript
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
},
|
|
313
|
-
},
|
|
314
|
-
});
|
|
212
|
+
class OpenApiRequestError extends Error {
|
|
213
|
+
status: number;
|
|
214
|
+
statusText: string;
|
|
215
|
+
headers: Record<string, string>;
|
|
216
|
+
body: unknown;
|
|
217
|
+
request: { url: string; method: string; headers: Record<string, string> };
|
|
218
|
+
}
|
|
315
219
|
```
|
|
316
220
|
|
|
317
221
|
---
|
|
318
222
|
|
|
319
|
-
##
|
|
223
|
+
## Interceptors
|
|
320
224
|
|
|
321
225
|
```typescript
|
|
322
226
|
import { createClient } from "@powerduck/openapi-request";
|
|
323
227
|
|
|
324
|
-
const client = createClient(
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
228
|
+
const client = createClient({
|
|
229
|
+
interceptors: {
|
|
230
|
+
request: async (request) => {
|
|
231
|
+
console.log("Request:", request.method, request.url);
|
|
232
|
+
request.headers["X-Request-ID"] = crypto.randomUUID();
|
|
233
|
+
return request;
|
|
234
|
+
},
|
|
235
|
+
response: async (response) => {
|
|
236
|
+
console.log("Response:", response.status);
|
|
237
|
+
return response;
|
|
238
|
+
},
|
|
239
|
+
error: async (error) => {
|
|
240
|
+
if (error.status === 401) {
|
|
241
|
+
// Refresh token and retry
|
|
242
|
+
return refreshToken().then(() => client.sendPrepared(error.request));
|
|
243
|
+
}
|
|
244
|
+
throw error;
|
|
245
|
+
},
|
|
246
|
+
},
|
|
338
247
|
});
|
|
339
248
|
```
|
|
340
249
|
|
|
341
250
|
---
|
|
342
251
|
|
|
343
|
-
##
|
|
344
|
-
|
|
345
|
-
Run Postman test scripts embedded in `x-postman-scripts`:
|
|
252
|
+
## TypeScript Types
|
|
346
253
|
|
|
347
254
|
```typescript
|
|
348
|
-
import {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
console.log("Passed:", testResults.passed);
|
|
360
|
-
console.log("Failed:", testResults.failed);
|
|
361
|
-
for (const test of testResults.tests) {
|
|
362
|
-
console.log(`${test.passed ? "✓" : "✗"} ${test.name}`);
|
|
363
|
-
}
|
|
255
|
+
import type {
|
|
256
|
+
OpenApiClient,
|
|
257
|
+
ClientOptions,
|
|
258
|
+
SendOptions,
|
|
259
|
+
PrepareOptions,
|
|
260
|
+
RequestResult,
|
|
261
|
+
OpenApiRequestError,
|
|
262
|
+
ParameterMap,
|
|
263
|
+
SecurityValues,
|
|
264
|
+
HttpMethod,
|
|
265
|
+
} from "@powerduck/openapi-request";
|
|
364
266
|
```
|
|
365
267
|
|
|
366
268
|
---
|
|
367
269
|
|
|
368
|
-
## Error Handling
|
|
369
|
-
|
|
370
|
-
```typescript
|
|
371
|
-
try {
|
|
372
|
-
const result = await client.send({
|
|
373
|
-
spec,
|
|
374
|
-
operationId: "getUser",
|
|
375
|
-
parameters: { path: { id: "123" } },
|
|
376
|
-
});
|
|
377
|
-
|
|
378
|
-
if (result.response.status >= 400) {
|
|
379
|
-
console.error("API error:", result.response.status, result.response.body);
|
|
380
|
-
}
|
|
381
|
-
} catch (error) {
|
|
382
|
-
if (error.name === "AbortError") {
|
|
383
|
-
console.error("Request timed out or was aborted");
|
|
384
|
-
} else if (error.name === "OpenApiRequestError") {
|
|
385
|
-
console.error("Request preparation failed:", error.message);
|
|
386
|
-
} else {
|
|
387
|
-
console.error("Network error:", error);
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
---
|
|
393
|
-
|
|
394
|
-
## Development
|
|
395
|
-
|
|
396
|
-
```bash
|
|
397
|
-
# Install dependencies
|
|
398
|
-
npm install
|
|
399
|
-
|
|
400
|
-
# Type check
|
|
401
|
-
npm run typecheck
|
|
402
|
-
|
|
403
|
-
# Build (ESM + CJS + type declarations)
|
|
404
|
-
npm run build
|
|
405
|
-
|
|
406
|
-
# Run tests
|
|
407
|
-
npm test
|
|
408
|
-
|
|
409
|
-
# Watch mode
|
|
410
|
-
npx vitest watch
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
---
|
|
414
|
-
|
|
415
|
-
## Related Packages
|
|
416
|
-
|
|
417
|
-
- [`@powerduck/openapi-parser`](https://www.npmjs.com/package/@powerduck/openapi-parser) — OpenAPI 3.2 parser, validator, and upgrader
|
|
418
|
-
- [`@powerduck/openapi-codegen`](https://www.npmjs.com/package/@powerduck/openapi-codegen) — Generate runnable request examples in 21 languages
|
|
419
|
-
- [`@powerduck/openapi-cli`](https://www.npmjs.com/package/@powerduck/openapi-cli) — CI-ready batch testing for OpenAPI documents
|
|
420
|
-
- [`@powerduck/openapi-mcp-server`](https://www.npmjs.com/package/@powerduck/openapi-mcp-server) — Turn OpenAPI docs into MCP servers
|
|
421
|
-
- [`@powerduck/x-to-openapi`](https://www.npmjs.com/package/@powerduck/x-to-openapi) — Convert curl commands and Postman Collections to OpenAPI 3.2
|
|
422
|
-
|
|
423
|
-
---
|
|
424
|
-
|
|
425
270
|
## License
|
|
426
271
|
|
|
427
|
-
MIT
|
|
272
|
+
MIT © [POWERDUCK LIMITED](https://www.powerduck.com)
|
package/package.json
CHANGED