specshield 1.0.4 → 1.0.6
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 +205 -91
- package/package.json +1 -1
- package/src/commands/compare.js +1 -1
- package/src/commands/login.js +1 -1
package/README.md
CHANGED
|
@@ -1,153 +1,259 @@
|
|
|
1
|
-
#
|
|
1
|
+
# SpecShield CLI
|
|
2
2
|
|
|
3
|
-

|
|
4
|
-

|
|
5
|
-

|
|
6
|
-

|
|
3
|
+
[](https://www.npmjs.com/package/specshield)
|
|
4
|
+
[](https://www.npmjs.com/package/specshield)
|
|
5
|
+
[](#license)
|
|
6
|
+
[](https://nodejs.org)
|
|
7
7
|
|
|
8
8
|
Compare OpenAPI and Swagger specs, detect breaking changes, and fail CI before incompatible API changes reach production.
|
|
9
9
|
|
|
10
|
+
---
|
|
10
11
|
|
|
11
|
-
##
|
|
12
|
-
|
|
13
|
-
SpecShield is a CLI tool that compares two OpenAPI/Swagger specifications and detects:
|
|
14
|
-
|
|
15
|
-
- ❌ Breaking changes
|
|
16
|
-
- ➕ Additions
|
|
17
|
-
- 🔄 Modifications
|
|
12
|
+
## Table of Contents
|
|
18
13
|
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
14
|
+
- [What is SpecShield CLI?](#what-is-specshield-cli)
|
|
15
|
+
- [Installation](#installation)
|
|
16
|
+
- [Local Compare](#local-compare)
|
|
17
|
+
- [Authentication](#authentication)
|
|
18
|
+
- [Generate an API Token](#generate-an-api-token)
|
|
19
|
+
- [Remote Compare](#remote-compare)
|
|
20
|
+
- [Config File](#config-file)
|
|
21
|
+
- [All Options](#all-options)
|
|
22
|
+
- [Exit Codes](#exit-codes)
|
|
23
|
+
- [CI/CD — GitHub Actions](#cicd--github-actions)
|
|
24
|
+
- [Support](#support)
|
|
24
25
|
|
|
25
26
|
---
|
|
26
27
|
|
|
27
|
-
##
|
|
28
|
+
## What is SpecShield CLI?
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
- Mobile apps
|
|
31
|
-
- Frontend clients
|
|
32
|
-
- Partner integrations
|
|
33
|
-
- Internal microservices
|
|
30
|
+
SpecShield CLI is a command-line tool for comparing two OpenAPI/Swagger specifications and detecting what changed between them. It classifies changes into:
|
|
34
31
|
|
|
35
|
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
32
|
+
- **Breaking changes** — removed endpoints, changed required fields, incompatible type changes
|
|
33
|
+
- **Modifications** — changed behavior that may or may not break clients
|
|
34
|
+
- **Additions** — new endpoints or fields
|
|
35
|
+
- **Warnings** — low-severity notices
|
|
39
36
|
|
|
40
|
-
|
|
37
|
+
It works in two modes:
|
|
41
38
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
- 🚫 Prevent breaking API releases
|
|
47
|
-
- ⚙️ Enforce API contract checks in CI/CD
|
|
48
|
-
- 🔍 Compare OpenAPI specs automatically
|
|
49
|
-
- 📊 Generate machine-readable reports
|
|
50
|
-
- 🧩 Integrate easily with existing workflows
|
|
51
|
-
- 🛑 Fail builds when breaking changes are detected
|
|
39
|
+
| Mode | Description |
|
|
40
|
+
|---|---|
|
|
41
|
+
| **Local** | Compares two spec files on your machine. No account needed. |
|
|
42
|
+
| **Remote** | Sends specs to the SpecShield hosted API. Requires an API token. Results are stored in your dashboard. |
|
|
52
43
|
|
|
53
44
|
---
|
|
54
45
|
|
|
55
|
-
## ✨ Features
|
|
56
|
-
|
|
57
|
-
- Detect breaking changes, additions, and modifications
|
|
58
|
-
- Support YAML and JSON OpenAPI specs
|
|
59
|
-
- CI/CD-ready with exit codes
|
|
60
|
-
- JSON output for automation
|
|
61
|
-
- `.specshield.yml` config support
|
|
62
|
-
- Ignore list for known changes
|
|
63
|
-
- Future SaaS-ready remote mode
|
|
64
|
-
|
|
65
46
|
## Installation
|
|
66
47
|
|
|
67
48
|
```bash
|
|
68
49
|
npm install -g specshield
|
|
69
|
-
# or use locally:
|
|
70
|
-
npm install && npm link
|
|
71
50
|
```
|
|
72
51
|
|
|
73
|
-
|
|
52
|
+
Verify the installation:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
specshield --version
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Local Compare
|
|
61
|
+
|
|
62
|
+
No account or token required for local comparisons.
|
|
74
63
|
|
|
75
|
-
### Basic comparison
|
|
76
64
|
```bash
|
|
77
65
|
specshield compare base.yaml target.yaml
|
|
78
66
|
```
|
|
79
67
|
|
|
80
|
-
|
|
68
|
+
Fail CI if breaking changes are found:
|
|
69
|
+
|
|
81
70
|
```bash
|
|
82
71
|
specshield compare base.yaml target.yaml --fail-on-breaking
|
|
83
72
|
```
|
|
84
73
|
|
|
85
|
-
|
|
74
|
+
Output as JSON:
|
|
75
|
+
|
|
86
76
|
```bash
|
|
87
77
|
specshield compare base.yaml target.yaml --json
|
|
88
78
|
```
|
|
89
79
|
|
|
90
|
-
|
|
80
|
+
Save results to a file:
|
|
81
|
+
|
|
91
82
|
```bash
|
|
92
83
|
specshield compare base.yaml target.yaml --output result.json
|
|
93
84
|
```
|
|
94
85
|
|
|
95
|
-
|
|
86
|
+
Ignore specific changes:
|
|
87
|
+
|
|
96
88
|
```bash
|
|
97
89
|
specshield compare base.yaml target.yaml --ignore "DELETE /users removed" --fail-on-breaking
|
|
98
90
|
```
|
|
99
91
|
|
|
100
|
-
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Authentication
|
|
95
|
+
|
|
96
|
+
Remote compare requires a SpecShield account and an API token.
|
|
97
|
+
|
|
98
|
+
### Sign in to SpecShield
|
|
99
|
+
|
|
100
|
+
1. Go to [https://specshield.io](https://specshield.io)
|
|
101
|
+
2. Sign in with your email/password, GitHub, or Google account
|
|
102
|
+
3. You will land on your account dashboard
|
|
103
|
+
|
|
104
|
+
### Generate an API Token
|
|
105
|
+
|
|
106
|
+
1. From your dashboard, go to **Account → API Keys**
|
|
107
|
+
(direct link: [https://specshield.io/account/keys](https://specshield.io/account/keys))
|
|
108
|
+
2. Click **Generate API Key**
|
|
109
|
+
3. Copy the token — it starts with `ss_` and is shown only once
|
|
110
|
+
4. Store it securely (password manager, secrets vault, or CI/CD secret)
|
|
111
|
+
|
|
112
|
+
### Configure the CLI
|
|
113
|
+
|
|
114
|
+
Run the login command with your token:
|
|
115
|
+
|
|
101
116
|
```bash
|
|
102
|
-
specshield
|
|
117
|
+
specshield login --api-key ss_your_token_here
|
|
103
118
|
```
|
|
104
119
|
|
|
105
|
-
|
|
120
|
+
This validates the token against the SpecShield API and saves it to `~/.specshield/config.json`. You will not need to pass the token on every command after this.
|
|
106
121
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
122
|
+
**Example output:**
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
✔ Logged in successfully.
|
|
126
|
+
|
|
127
|
+
Customer: Jane Smith
|
|
128
|
+
Plan: FREE
|
|
129
|
+
Config: /Users/jane/.specshield/config.json
|
|
130
|
+
|
|
131
|
+
Run: specshield compare base.yaml target.yaml --remote
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Alternative: Environment Variable
|
|
135
|
+
|
|
136
|
+
If you prefer not to use the stored config (e.g. in CI/CD), set the token as an environment variable:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
export SPECSHIELD_API_KEY=ss_your_token_here
|
|
140
|
+
specshield compare base.yaml target.yaml --remote
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
The token resolution order is:
|
|
144
|
+
|
|
145
|
+
1. `--api-key` flag (highest priority)
|
|
146
|
+
2. `SPECSHIELD_API_KEY` environment variable
|
|
147
|
+
3. Stored config (`~/.specshield/config.json`)
|
|
148
|
+
4. `remote.apiKey` in `.specshield.yml`
|
|
149
|
+
|
|
150
|
+
### Log Out
|
|
151
|
+
|
|
152
|
+
To remove the stored token:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
specshield logout
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Remote Compare
|
|
161
|
+
|
|
162
|
+
Remote compare sends your spec files to the SpecShield hosted API at [https://specshield.io](https://specshield.io). Results are processed server-side and stored in your dashboard for review.
|
|
163
|
+
|
|
164
|
+
**When to use remote mode:**
|
|
165
|
+
- You want comparison history tracked in the SpecShield dashboard
|
|
166
|
+
- Your team shares a centralized view of API drift over time
|
|
167
|
+
- You are on a plan with advanced reporting features
|
|
168
|
+
|
|
169
|
+
### Basic remote compare
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
specshield compare base.yaml target.yaml --remote
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Remote compare with CI fail on breaking changes
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
specshield compare base.yaml target.yaml --remote --fail-on-breaking
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Remote compare with JSON output
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
specshield compare base.yaml target.yaml --remote --json --output result.json
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### How authentication works in remote mode
|
|
188
|
+
|
|
189
|
+
The CLI reads your API token (from flag, env var, or stored config) and sends it as an `X-Api-Key` header with each request. If no token is found, the command exits with an error:
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
Error: No API key found. Run: specshield login --api-key <KEY>
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
118
196
|
|
|
119
197
|
## Config File
|
|
120
198
|
|
|
121
|
-
Create `.specshield.yml` in your project root:
|
|
199
|
+
Create `.specshield.yml` in your project root to set default behavior:
|
|
122
200
|
|
|
123
201
|
```yaml
|
|
124
|
-
allowBreakingChanges: false
|
|
125
202
|
failOnBreaking: true
|
|
203
|
+
allowBreakingChanges: false
|
|
204
|
+
severity: error
|
|
126
205
|
|
|
127
206
|
ignore:
|
|
128
|
-
- "
|
|
129
|
-
- "
|
|
130
|
-
|
|
131
|
-
severity: error
|
|
207
|
+
- "DELETE /admin removed"
|
|
208
|
+
- "User.internal_id removed"
|
|
132
209
|
|
|
133
210
|
remote:
|
|
134
211
|
enabled: false
|
|
135
|
-
url: "https://
|
|
212
|
+
url: "https://specshield.io/compare"
|
|
136
213
|
timeout: 10000
|
|
214
|
+
apiKey: "" # prefer env var or specshield login instead
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
CLI flags always override config file values.
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## All Options
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
specshield compare <base> <target> [options]
|
|
137
225
|
```
|
|
138
226
|
|
|
139
|
-
|
|
227
|
+
| Option | Description |
|
|
228
|
+
|---|---|
|
|
229
|
+
| `--remote` | Use the SpecShield hosted compare API |
|
|
230
|
+
| `--api-key <key>` | API token for remote mode (overrides env and stored config) |
|
|
231
|
+
| `--remote-url <url>` | Override the hosted API base URL |
|
|
232
|
+
| `--fail-on-breaking` | Exit code 1 if breaking changes are found |
|
|
233
|
+
| `--allow-breaking` | Override fail-on-breaking |
|
|
234
|
+
| `--json` | Output machine-readable JSON |
|
|
235
|
+
| `--output <file>` | Save result to a file |
|
|
236
|
+
| `--ignore <change>` | Ignore a specific change string (repeatable) |
|
|
237
|
+
| `--severity <level>` | Minimum severity: `info` / `warning` / `error` |
|
|
238
|
+
| `--config <path>` | Path to `.specshield.yml` |
|
|
239
|
+
| `--timeout <ms>` | Request timeout for remote mode (default: 10000) |
|
|
240
|
+
|
|
241
|
+
---
|
|
140
242
|
|
|
141
243
|
## Exit Codes
|
|
142
244
|
|
|
143
245
|
| Code | Meaning |
|
|
144
246
|
|---|---|
|
|
145
247
|
| `0` | Success — no blocking issues |
|
|
146
|
-
| `1` | Breaking changes found and `--fail-on-breaking` active |
|
|
147
|
-
| `2` | Invalid input, config error, or runtime error |
|
|
248
|
+
| `1` | Breaking changes found and `--fail-on-breaking` is active |
|
|
249
|
+
| `2` | Invalid input, missing token, config error, or runtime error |
|
|
250
|
+
|
|
251
|
+
---
|
|
148
252
|
|
|
149
253
|
## CI/CD — GitHub Actions
|
|
150
254
|
|
|
255
|
+
### Local compare (no token required)
|
|
256
|
+
|
|
151
257
|
```yaml
|
|
152
258
|
name: API Contract Check
|
|
153
259
|
|
|
@@ -169,7 +275,6 @@ jobs:
|
|
|
169
275
|
|
|
170
276
|
- run: npm install -g specshield
|
|
171
277
|
|
|
172
|
-
# Option A: spec files are committed to the repo
|
|
173
278
|
- name: Get base spec from main branch
|
|
174
279
|
run: git show origin/main:api/openapi.yaml > /tmp/base-spec.yaml
|
|
175
280
|
|
|
@@ -187,22 +292,31 @@ jobs:
|
|
|
187
292
|
path: spec-diff.json
|
|
188
293
|
```
|
|
189
294
|
|
|
190
|
-
|
|
295
|
+
### Remote compare (with SpecShield hosted API)
|
|
191
296
|
|
|
192
|
-
|
|
297
|
+
Add your API token as a GitHub Actions secret named `SPECSHIELD_API_KEY`, then:
|
|
193
298
|
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
299
|
+
```yaml
|
|
300
|
+
- name: Compare specs (remote)
|
|
301
|
+
env:
|
|
302
|
+
SPECSHIELD_API_KEY: ${{ secrets.SPECSHIELD_API_KEY }}
|
|
303
|
+
run: |
|
|
304
|
+
specshield compare /tmp/base-spec.yaml api/openapi.yaml \
|
|
305
|
+
--remote \
|
|
306
|
+
--fail-on-breaking \
|
|
307
|
+
--output spec-diff.json
|
|
198
308
|
```
|
|
199
309
|
|
|
200
|
-
|
|
310
|
+
> **Note:** If your project generates its OpenAPI spec dynamically (e.g. Spring Boot, FastAPI), add a build step before the compare step to generate the spec from your code.
|
|
201
311
|
|
|
202
|
-
|
|
203
|
-
npm test
|
|
204
|
-
```
|
|
312
|
+
---
|
|
205
313
|
|
|
206
314
|
## License
|
|
207
315
|
|
|
208
316
|
MIT © Deepak Satyam
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## Support
|
|
321
|
+
|
|
322
|
+
Questions or issues? Reach out at [admin@specshield.io](mailto:admin@specshield.io) or open an issue on GitHub.
|
package/package.json
CHANGED
package/src/commands/compare.js
CHANGED
|
@@ -16,7 +16,7 @@ const logger = require('../utils/logger');
|
|
|
16
16
|
const fsExtra = require('fs-extra');
|
|
17
17
|
const { getStoredApiKey } = require('../config/localConfig');
|
|
18
18
|
|
|
19
|
-
const HOSTED_API_URL = '
|
|
19
|
+
const HOSTED_API_URL = 'https://specshield.io';
|
|
20
20
|
|
|
21
21
|
const compare = new Command('compare');
|
|
22
22
|
|
package/src/commands/login.js
CHANGED
|
@@ -6,7 +6,7 @@ const ora = require('ora');
|
|
|
6
6
|
const axios = require('axios');
|
|
7
7
|
const { setStoredApiKey, CONFIG_PATH } = require('../config/localConfig');
|
|
8
8
|
|
|
9
|
-
const HOSTED_API_URL = '
|
|
9
|
+
const HOSTED_API_URL = 'https://specshield.io';
|
|
10
10
|
|
|
11
11
|
const login = new Command('login');
|
|
12
12
|
|