mpx-api 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.
@@ -0,0 +1,71 @@
1
+ # Contributing to mpx-api
2
+
3
+ Thanks for your interest in contributing to mpx-api! We welcome contributions from the community.
4
+
5
+ ## Development Setup
6
+
7
+ ```bash
8
+ # Clone the repository
9
+ git clone https://github.com/mesaplex/mpx-api.git
10
+ cd mpx-api
11
+
12
+ # Install dependencies
13
+ npm install
14
+
15
+ # Link for local development
16
+ npm link
17
+
18
+ # Run tests
19
+ npm test
20
+ ```
21
+
22
+ ## Testing
23
+
24
+ All pull requests must include tests. We use Node.js built-in test runner.
25
+
26
+ Run tests:
27
+ ```bash
28
+ npm test
29
+ ```
30
+
31
+ Add tests in the `test/` directory with the `.test.js` extension.
32
+
33
+ ## Code Style
34
+
35
+ - Use ES modules (import/export)
36
+ - 2-space indentation
37
+ - Semicolons required
38
+ - Descriptive variable names
39
+ - Comment complex logic
40
+
41
+ ## Pull Request Process
42
+
43
+ 1. Fork the repository
44
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
45
+ 3. Make your changes
46
+ 4. Add tests for new functionality
47
+ 5. Ensure all tests pass (`npm test`)
48
+ 6. Commit your changes (`git commit -m 'Add amazing feature'`)
49
+ 7. Push to your fork (`git push origin feature/amazing-feature`)
50
+ 8. Open a Pull Request
51
+
52
+ ## Feature Requests
53
+
54
+ Open an issue with the "enhancement" label. Please include:
55
+ - Use case / problem you're trying to solve
56
+ - Proposed solution
57
+ - Alternative solutions considered
58
+
59
+ ## Bug Reports
60
+
61
+ Open an issue with the "bug" label. Please include:
62
+ - Steps to reproduce
63
+ - Expected behavior
64
+ - Actual behavior
65
+ - mpx-api version (`mpx-api --version`)
66
+ - Node.js version (`node --version`)
67
+ - Operating system
68
+
69
+ ## License
70
+
71
+ By contributing, you agree that your contributions will be licensed under the MIT License.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mesaplex
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,345 @@
1
+ # mpx-api 🚀
2
+
3
+ **Developer-first API testing, mocking, and documentation CLI.**
4
+
5
+ No GUI. No proprietary formats. Just powerful, git-friendly API testing from your terminal.
6
+
7
+ [![npm version](https://img.shields.io/npm/v/mpx-api.svg)](https://www.npmjs.com/package/mpx-api)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
9
+
10
+ ## Why mpx-api?
11
+
12
+ - **Git-friendly**: Collections are YAML files, not proprietary blobs
13
+ - **CI/CD ready**: Exit codes, JSON output, no GUI dependency
14
+ - **Developer experience**: Beautiful terminal output, syntax highlighting
15
+ - **Request chaining**: Use response from one request in another (`{{request.response.body.id}}`)
16
+ - **Built-in mock server**: Test against OpenAPI specs without deploying
17
+ - **Assertions in collections**: No separate test code needed
18
+ - **Fast**: Pure Node.js, minimal dependencies, < 200ms startup
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ npm install -g mpx-api
24
+ ```
25
+
26
+ Or use with `npx`:
27
+
28
+ ```bash
29
+ npx mpx-api get https://api.github.com/users/octocat
30
+ ```
31
+
32
+ ## Quick Start
33
+
34
+ ### Make HTTP Requests
35
+
36
+ ```bash
37
+ # Simple GET request
38
+ mpx-api get https://jsonplaceholder.typicode.com/users
39
+
40
+ # POST with JSON
41
+ mpx-api post https://api.example.com/users --json '{"name":"Alice","email":"alice@example.com"}'
42
+
43
+ # Custom headers
44
+ mpx-api get https://api.example.com/protected \
45
+ -H "Authorization: Bearer $TOKEN" \
46
+ -H "Accept: application/json"
47
+
48
+ # Verbose output (show headers)
49
+ mpx-api get https://httpbin.org/get -v
50
+
51
+ # Quiet mode (only response body)
52
+ mpx-api get https://api.example.com/data -q
53
+ ```
54
+
55
+ ### Create a Collection
56
+
57
+ ```bash
58
+ # Initialize collection in your project
59
+ mpx-api collection init
60
+
61
+ # Add requests
62
+ mpx-api collection add get-users GET /users
63
+ mpx-api collection add create-user POST /users --json '{"name":"Bob"}'
64
+
65
+ # Run the collection
66
+ mpx-api collection run
67
+ ```
68
+
69
+ ### Collection File Format
70
+
71
+ Collections are simple YAML files (`.mpx-api/collection.yaml`):
72
+
73
+ ```yaml
74
+ name: My API Tests
75
+ baseUrl: https://api.example.com
76
+
77
+ requests:
78
+ - name: get-users
79
+ method: GET
80
+ url: /users
81
+ headers:
82
+ Authorization: Bearer {{env.API_TOKEN}}
83
+ assert:
84
+ status: 200
85
+ body.length: { gt: 0 }
86
+ responseTime: { lt: 500 }
87
+
88
+ - name: get-specific-user
89
+ method: GET
90
+ url: /users/{{get-users.response.body[0].id}}
91
+ assert:
92
+ status: 200
93
+ body.email: { exists: true }
94
+
95
+ - name: create-post
96
+ method: POST
97
+ url: /posts
98
+ json:
99
+ title: New Post
100
+ userId: {{get-users.response.body[0].id}}
101
+ assert:
102
+ status: 201
103
+ body.title: New Post
104
+ ```
105
+
106
+ **Key features:**
107
+
108
+ - **Request chaining**: `{{get-users.response.body[0].id}}` uses the response from a previous request
109
+ - **Environment variables**: `{{env.API_TOKEN}}` pulls from environment files
110
+ - **Assertions**: Test status codes, response times, body fields, headers
111
+ - **Operators**: `gt`, `lt`, `gte`, `lte`, `eq`, `ne`, `contains`, `exists`
112
+
113
+ ### Environments
114
+
115
+ ```bash
116
+ # Initialize environments (creates dev, staging, production)
117
+ mpx-api env init
118
+
119
+ # Set variables
120
+ mpx-api env set staging API_URL=https://staging.example.com
121
+ mpx-api env set staging API_TOKEN=abc123
122
+
123
+ # List environments
124
+ mpx-api env list
125
+
126
+ # List variables in environment
127
+ mpx-api env list staging
128
+
129
+ # Run collection with environment
130
+ mpx-api collection run --env staging
131
+ ```
132
+
133
+ Environment files (`.mpx-api/environments/staging.yaml`):
134
+
135
+ ```yaml
136
+ name: staging
137
+ variables:
138
+ API_URL: https://staging.example.com
139
+ API_TOKEN: secret-token-here
140
+ ```
141
+
142
+ ### Testing & Assertions
143
+
144
+ ```bash
145
+ # Run tests from collection
146
+ mpx-api test ./collection.yaml
147
+
148
+ # With environment
149
+ mpx-api test ./collection.yaml --env production
150
+
151
+ # JSON output for CI/CD
152
+ mpx-api test ./collection.yaml --json
153
+ ```
154
+
155
+ Assertions support:
156
+
157
+ - **Status codes**: `status: 200`
158
+ - **Response time**: `responseTime: { lt: 500 }`
159
+ - **Headers**: `headers.content-type: application/json`
160
+ - **Body fields**: `body.users[0].name: Alice`
161
+ - **Operators**:
162
+ - `{ gt: 10 }` - greater than
163
+ - `{ lt: 100 }` - less than
164
+ - `{ gte: 5 }` - greater than or equal
165
+ - `{ lte: 50 }` - less than or equal
166
+ - `{ eq: "value" }` - equals
167
+ - `{ ne: "value" }` - not equals
168
+ - `{ contains: "text" }` - contains substring
169
+ - `{ exists: true }` - field exists
170
+
171
+ ### Request History
172
+
173
+ ```bash
174
+ # View recent requests
175
+ mpx-api history
176
+
177
+ # Limit to last 50
178
+ mpx-api history -n 50
179
+ ```
180
+
181
+ ### Cookie Management
182
+
183
+ Cookies are automatically saved and sent with subsequent requests. Cookie jar is stored at `~/.mpx-api/cookies.json`.
184
+
185
+ ## Pro Features 💎
186
+
187
+ Upgrade to **mpx-api Pro** ($12/mo) for advanced features:
188
+
189
+ ### Mock Server
190
+
191
+ Start a mock API server from an OpenAPI spec:
192
+
193
+ ```bash
194
+ mpx-api mock ./openapi.yaml --port 4000
195
+ ```
196
+
197
+ Supports:
198
+ - OpenAPI 3.0 specs (YAML or JSON)
199
+ - Automatic response generation from schemas
200
+ - Configurable response delay: `--delay 200`
201
+ - CORS support: `--cors`
202
+
203
+ ### Load Testing
204
+
205
+ ```bash
206
+ mpx-api load https://api.example.com/health --rps 100 --duration 30s
207
+ ```
208
+
209
+ Features:
210
+ - Requests per second (RPS) control
211
+ - Response time percentiles (P50, P95, P99)
212
+ - Status code distribution
213
+ - Error tracking
214
+
215
+ ### Documentation Generation
216
+
217
+ Generate beautiful API docs from your collections:
218
+
219
+ ```bash
220
+ mpx-api docs ./collection.yaml --output API.md
221
+ ```
222
+
223
+ Creates Markdown documentation with:
224
+ - Table of contents
225
+ - Request/response examples
226
+ - Expected responses from assertions
227
+ - Auto-generated from your test collections
228
+
229
+ ### Request Chaining
230
+
231
+ Already included in free tier! Use response data from previous requests:
232
+
233
+ ```yaml
234
+ requests:
235
+ - name: login
236
+ method: POST
237
+ url: /auth/login
238
+ json:
239
+ username: test
240
+ password: secret
241
+
242
+ - name: get-profile
243
+ method: GET
244
+ url: /users/me
245
+ headers:
246
+ Authorization: Bearer {{login.response.body.token}}
247
+ ```
248
+
249
+ ## Examples
250
+
251
+ See the `examples/` directory for real-world collections:
252
+
253
+ - `jsonplaceholder.yaml` - CRUD operations with JSONPlaceholder API
254
+ - `github-api.yaml` - GitHub API with request chaining
255
+ - `openapi-petstore.yaml` - OpenAPI spec for mock server testing
256
+
257
+ Run examples:
258
+
259
+ ```bash
260
+ mpx-api test examples/jsonplaceholder.yaml
261
+ mpx-api collection run examples/github-api.yaml
262
+ ```
263
+
264
+ ## CI/CD Integration
265
+
266
+ Use exit codes for CI/CD pipelines:
267
+
268
+ ```bash
269
+ # In your CI script
270
+ mpx-api test ./api-tests.yaml --env production
271
+
272
+ # Exit code 0 = all tests passed
273
+ # Exit code 1 = tests failed
274
+ ```
275
+
276
+ GitHub Actions example:
277
+
278
+ ```yaml
279
+ - name: Run API Tests
280
+ run: npx mpx-api test ./tests/api-collection.yaml --env staging
281
+ ```
282
+
283
+ ## Error Handling
284
+
285
+ mpx-api gracefully handles:
286
+
287
+ - **DNS failures**: Clear error messages
288
+ - **Timeouts**: Configurable with `--timeout <ms>`
289
+ - **SSL errors**: Skip verification with `--no-verify`
290
+ - **Invalid JSON**: Parse errors with helpful messages
291
+ - **Large responses**: Automatic truncation in terminal (full body still accessible)
292
+
293
+ ## Configuration
294
+
295
+ Global config: `~/.mpx-api/config.json`
296
+ Project config: `.mpx-api/config.json`
297
+ Cookie jar: `~/.mpx-api/cookies.json`
298
+ History: `~/.mpx-api/history.jsonl`
299
+
300
+ ## Comparison
301
+
302
+ | Feature | mpx-api | Postman | HTTPie Pro | curl |
303
+ |---------|---------|---------|------------|------|
304
+ | **Price** | Free / $12 Pro | $49/user | $9/mo | Free |
305
+ | **Collections** | ✅ YAML files | ✅ Proprietary | ❌ | ❌ |
306
+ | **Request chaining** | ✅ | ✅ | ❌ | ❌ |
307
+ | **Assertions** | ✅ Built-in | ✅ Scripts | ❌ | ❌ |
308
+ | **Mock server** | ✅ Pro | ✅ Pro | ❌ | ❌ |
309
+ | **Load testing** | ✅ Pro | ✅ Pro | ❌ | ❌ |
310
+ | **Git-friendly** | ✅ | ⚠️ Export needed | N/A | N/A |
311
+ | **No GUI needed** | ✅ | ❌ | ✅ | ✅ |
312
+ | **Syntax highlighting** | ✅ | ✅ | ✅ | ❌ |
313
+
314
+ ## Development
315
+
316
+ ```bash
317
+ # Clone and install
318
+ git clone https://github.com/mesaplex/mpx-api.git
319
+ cd mpx-api
320
+ npm install
321
+
322
+ # Run tests
323
+ npm test
324
+
325
+ # Link for local development
326
+ npm link
327
+ ```
328
+
329
+ ## Contributing
330
+
331
+ Contributions welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) first.
332
+
333
+ ## License
334
+
335
+ MIT © Mesaplex
336
+
337
+ ## Support
338
+
339
+ - **Issues**: [GitHub Issues](https://github.com/mesaplex/mpx-api/issues)
340
+ - **Discussions**: [GitHub Discussions](https://github.com/mesaplex/mpx-api/discussions)
341
+ - **Email**: support@mpx-api.dev
342
+
343
+ ---
344
+
345
+ **Built with ❤️ by developers, for developers.**
package/bin/mpx-api.js ADDED
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { program } from 'commander';
4
+ import { fileURLToPath } from 'url';
5
+ import { dirname, join } from 'path';
6
+ import { readFileSync } from 'fs';
7
+
8
+ // Command imports
9
+ import { registerRequestCommands } from '../src/commands/request.js';
10
+ import { registerCollectionCommands } from '../src/commands/collection.js';
11
+ import { registerEnvCommands } from '../src/commands/env.js';
12
+ import { registerMockCommands } from '../src/commands/mock.js';
13
+ import { registerTestCommand } from '../src/commands/test.js';
14
+ import { registerHistoryCommand } from '../src/commands/history.js';
15
+ import { registerLoadCommand } from '../src/commands/load.js';
16
+ import { registerDocsCommand } from '../src/commands/docs.js';
17
+
18
+ const __filename = fileURLToPath(import.meta.url);
19
+ const __dirname = dirname(__filename);
20
+
21
+ const pkg = JSON.parse(
22
+ readFileSync(join(__dirname, '../package.json'), 'utf8')
23
+ );
24
+
25
+ program
26
+ .name('mpx-api')
27
+ .description('Developer-first API testing, mocking, and documentation CLI')
28
+ .version(pkg.version);
29
+
30
+ // Register HTTP method commands (get, post, put, patch, delete, head, options)
31
+ registerRequestCommands(program);
32
+
33
+ // Register collection commands
34
+ registerCollectionCommands(program);
35
+
36
+ // Register environment commands
37
+ registerEnvCommands(program);
38
+
39
+ // Register mock server commands
40
+ registerMockCommands(program);
41
+
42
+ // Register test command
43
+ registerTestCommand(program);
44
+
45
+ // Register history command
46
+ registerHistoryCommand(program);
47
+
48
+ // Register Pro commands (gracefully handle unlicensed)
49
+ registerLoadCommand(program);
50
+ registerDocsCommand(program);
51
+
52
+ program.parse();
@@ -0,0 +1,35 @@
1
+ name: GitHub API Collection
2
+ description: Example collection for GitHub API with request chaining
3
+ baseUrl: https://api.github.com
4
+
5
+ requests:
6
+ - name: get-user
7
+ method: GET
8
+ url: /users/octocat
9
+ headers:
10
+ Accept: application/vnd.github+json
11
+ User-Agent: mpx-api
12
+ assert:
13
+ status: 200
14
+ body.login: octocat
15
+ body.type: User
16
+
17
+ - name: get-repos
18
+ method: GET
19
+ url: /users/{{get-user.response.body.login}}/repos
20
+ headers:
21
+ Accept: application/vnd.github+json
22
+ User-Agent: mpx-api
23
+ assert:
24
+ status: 200
25
+ body.length: { gt: 0 }
26
+
27
+ - name: get-first-repo
28
+ method: GET
29
+ url: "{{get-repos.response.body[0].url}}"
30
+ headers:
31
+ Accept: application/vnd.github+json
32
+ User-Agent: mpx-api
33
+ assert:
34
+ status: 200
35
+ body.owner.login: octocat
@@ -0,0 +1,52 @@
1
+ name: JSONPlaceholder API Tests
2
+ description: Example collection testing JSONPlaceholder API
3
+ baseUrl: https://jsonplaceholder.typicode.com
4
+
5
+ requests:
6
+ - name: Get all users
7
+ method: GET
8
+ url: /users
9
+ assert:
10
+ status: 200
11
+ body.length: { gt: 0 }
12
+ headers.content-type: application/json
13
+ responseTime: { lt: 2000 }
14
+
15
+ - name: Get specific user
16
+ method: GET
17
+ url: /users/1
18
+ assert:
19
+ status: 200
20
+ body.id: 1
21
+ body.name: { exists: true }
22
+ body.email: { exists: true }
23
+
24
+ - name: Create new post
25
+ method: POST
26
+ url: /posts
27
+ json:
28
+ title: Test Post
29
+ body: This is a test post created by mpx-api
30
+ userId: 1
31
+ assert:
32
+ status: 201
33
+ body.title: Test Post
34
+ body.userId: 1
35
+
36
+ - name: Update post
37
+ method: PUT
38
+ url: /posts/1
39
+ json:
40
+ id: 1
41
+ title: Updated Title
42
+ body: Updated content
43
+ userId: 1
44
+ assert:
45
+ status: 200
46
+ body.title: Updated Title
47
+
48
+ - name: Delete post
49
+ method: DELETE
50
+ url: /posts/1
51
+ assert:
52
+ status: 200
@@ -0,0 +1,88 @@
1
+ openapi: 3.0.0
2
+ info:
3
+ title: Pet Store API
4
+ version: 1.0.0
5
+ description: A simple pet store API for testing mpx-api mock server
6
+
7
+ paths:
8
+ /pets:
9
+ get:
10
+ summary: List all pets
11
+ responses:
12
+ '200':
13
+ description: A list of pets
14
+ content:
15
+ application/json:
16
+ schema:
17
+ type: array
18
+ items:
19
+ type: object
20
+ properties:
21
+ id:
22
+ type: integer
23
+ example: 1
24
+ name:
25
+ type: string
26
+ example: "Fluffy"
27
+ species:
28
+ type: string
29
+ example: "cat"
30
+
31
+ post:
32
+ summary: Create a pet
33
+ requestBody:
34
+ content:
35
+ application/json:
36
+ schema:
37
+ type: object
38
+ properties:
39
+ name:
40
+ type: string
41
+ species:
42
+ type: string
43
+ responses:
44
+ '201':
45
+ description: Pet created
46
+ content:
47
+ application/json:
48
+ schema:
49
+ type: object
50
+ properties:
51
+ id:
52
+ type: integer
53
+ example: 2
54
+ name:
55
+ type: string
56
+ example: "Buddy"
57
+ species:
58
+ type: string
59
+ example: "dog"
60
+
61
+ /pets/{id}:
62
+ get:
63
+ summary: Get a pet by ID
64
+ parameters:
65
+ - name: id
66
+ in: path
67
+ required: true
68
+ schema:
69
+ type: integer
70
+ responses:
71
+ '200':
72
+ description: A single pet
73
+ content:
74
+ application/json:
75
+ schema:
76
+ type: object
77
+ properties:
78
+ id:
79
+ type: integer
80
+ example: 1
81
+ name:
82
+ type: string
83
+ example: "Fluffy"
84
+ species:
85
+ type: string
86
+ example: "cat"
87
+ '404':
88
+ description: Pet not found