@bymbly/api-tools 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 ADDED
@@ -0,0 +1,566 @@
1
+ # @bymbly/api-tools
2
+
3
+ Unified, opinionated CLI wrapper for API specification tooling.
4
+
5
+ Standardizes common workflows across projects with sensible defaults while allowing full
6
+ customization through CLI options and passthrough arguments.
7
+
8
+ **Supports:** OpenAPI, AsyncAPI, Arazzo
9
+
10
+ **Wraps:** [Redocly](https://github.com/Redocly/redocly-cli) | [Spectral](https://github.com/stoplightio/spectral)
11
+
12
+ ## Features
13
+
14
+ - **Single unified CLI** - One tool for all API spec operations
15
+ - **Opinionated defaults** - Sensible conventions for file locations and configurations
16
+ - **Consistent interface** - Same flags and patterns across all commands
17
+ - **Flexible overrides** - CLI options for common cases, passthrough for advanced use
18
+ - **Bundled configs** - Default Spectral and Redocly configuration included
19
+ - **Auto-detection** - Finds OpenAPI, AsyncAPI, and Arazzo specs automatically
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ npm install -D @bymbly/api-tools@latest
25
+ ```
26
+
27
+ ## Quick Start
28
+
29
+ Add scripts to your `package.json`:
30
+
31
+ ```json
32
+ {
33
+ "scripts": {
34
+ "lint": "npm run lint:spectral && npm run lint:redocly",
35
+ "lint:spectral": "api-tools spectral lint",
36
+ "lint:redocly": "api-tools redocly lint",
37
+ "bundle": "api-tools redocly bundle",
38
+ "join": "api-tools redocly join",
39
+ "docs": "api-tools redocly build-docs",
40
+ "arazzo:gen": "api-tools redocly generate-arazzo",
41
+ "test:api": "api-tools redocly respect"
42
+ }
43
+ }
44
+ ```
45
+
46
+ Run:
47
+
48
+ ```bash
49
+ npm run lint # Lint with both Spectral and Redocly
50
+ npm run bundle # Bundle OpenAPI documents
51
+ npm run join # Join OpenAPI documents
52
+ npm run docs # Generate HTML documentation
53
+ npm run arazzo:gen # Generate Arazzo workflow starter
54
+ npm run test:api # Execute Arazzo workflow tests
55
+ ```
56
+
57
+ ## Command Structure
58
+
59
+ ```bash
60
+ api-tools [global-options] <command> <subcommand> [options] [-- passthrough-args]
61
+ ```
62
+
63
+ ### Global Options
64
+
65
+ Available for all commands:
66
+
67
+ - `--quiet` - Disable wrapper logging (still shows tool output)
68
+ - `--silent` - Disable all output (wrapper + tool)
69
+ - `--cwd <path>` - Run as if started in this directory
70
+
71
+ ## Commands
72
+
73
+ ### Spectral Commands
74
+
75
+ #### `spectral lint`
76
+
77
+ Validate and lint OpenAPI, AsyncAPI, and Arazzo documents.
78
+
79
+ **Usage:**
80
+
81
+ ```bash
82
+ api-tools spectral lint [input] [options]
83
+ ```
84
+
85
+ **Options:**
86
+
87
+ - `[input]` - Document path (default: auto-detect)
88
+ - `--openapi` - Lint only OpenAPI at `openapi/openapi.yaml`
89
+ - `--asyncapi` - Lint only AsyncAPI at `asyncapi/asyncapi.yaml`
90
+ - `--arazzo` - Lint only Arazzo at `arazzo/arazzo.yaml`
91
+ - `--format <format>` - Output format (default: `stylish`)
92
+ - Choices: `json`, `stylish`, `junit`, `html`, `text`, `teamcity`, `pretty`, `github-actions`, `sarif`, `markdown`, `gitlab`
93
+ - `--output <file>` - Write output to file
94
+ - `--ruleset <file>` - Custom ruleset (overrides auto/bundled)
95
+ - `--fail-severity <level>` - Fail threshold (default: `warn`)
96
+ - Choices: `error`, `warn`, `info`, `hint`
97
+ - `--display-only-failures` - Show only failing results
98
+ - `--verbose` - Enable verbose output
99
+
100
+ **Examples:**
101
+
102
+ ```bash
103
+ # Auto-detect and lint all specs
104
+ api-tools spectral lint
105
+
106
+ # Lint specific spec types
107
+ api-tools spectral lint --openapi
108
+ api-tools spectral lint --asyncapi --arazzo
109
+
110
+ # Lint specific file
111
+ api-tools spectral lint custom/spec.yaml
112
+
113
+ # JSON output
114
+ api-tools spectral lint --format json --output results.json
115
+
116
+ # Custom ruleset
117
+ api-tools spectral lint --ruleset .spectral.yaml
118
+
119
+ # Passthrough advanced options
120
+ api-tools spectral lint -- --ignore-unknown-format
121
+ ```
122
+
123
+ #### `spectral init`
124
+
125
+ Create a default `spectral.yaml` config file.
126
+
127
+ ```bash
128
+ api-tools spectral init [--force]
129
+ ```
130
+
131
+ ### Redocly Commands
132
+
133
+ #### `redocly lint`
134
+
135
+ Validate and lint OpenAPI, AsyncAPI, and Arazzo documents using Redocly.
136
+
137
+ **Usage:**
138
+
139
+ ```bash
140
+ api-tools redocly lint [input] [options]
141
+ ```
142
+
143
+ **Options:**
144
+
145
+ - `[input]` - Document path (default: auto-detect)
146
+ - `--openapi` - Lint only OpenAPI at `openapi/openapi.yaml`
147
+ - `--asyncapi` - Lint only AsyncAPI at `asyncapi/asyncapi.yaml`
148
+ - `--arazzo` - Lint only Arazzo at `arazzo/arazzo.yaml`
149
+ - `--format <format>` - Output format (default: `codeframe`)
150
+ - Choices: `codeframe`, `stylish`, `json`, `checkstyle`, `codeclimate`, `github-actions`, `markdown`, `summary`
151
+ - `--config <file>` - Config file path (overrides auto/bundled)
152
+
153
+ **Examples:**
154
+
155
+ ```bash
156
+ # Auto-detect and lint all specs
157
+ api-tools redocly lint
158
+
159
+ # Lint only OpenAPI
160
+ api-tools redocly lint --openapi
161
+
162
+ # JSON output
163
+ api-tools redocly lint --format json
164
+
165
+ # Custom config
166
+ api-tools redocly lint --config custom-redocly.yaml
167
+ ```
168
+
169
+ #### `redocly build-docs`
170
+
171
+ Build HTML documentation from OpenAPI documents.
172
+
173
+ **Usage:**
174
+
175
+ ```bash
176
+ api-tools redocly build-docs [input] [options]
177
+ ```
178
+
179
+ **Options:**
180
+
181
+ - `[input]` - OpenAPI document path (default: `openapi/openapi.yaml`)
182
+ - `--output <file>` - Output HTML file (default: `dist/docs/openapi.html`)
183
+ - `--config <file>` - Config file path (overrides auto/bundled)
184
+
185
+ **Examples:**
186
+
187
+ ```bash
188
+ # Generate docs with defaults
189
+ api-tools redocly build-docs
190
+
191
+ # Custom output location
192
+ api-tools redocly build-docs --output public/api-docs.html
193
+
194
+ # Custom title via passthrough
195
+ api-tools redocly build-docs -- --title "My API Documentation"
196
+ ```
197
+
198
+ #### `redocly bundle`
199
+
200
+ Bundle API descriptions into a single file.
201
+
202
+ > **Note:** The `bundle` command differs from the `join` command.
203
+ > The `bundle` command takes a root OpenAPI file as input and follows the `$ref` mentions to include
204
+ > all the referenced components into a single output file. The `join` command can combine multiple
205
+ > OpenAPI files into a single unified API description file.
206
+
207
+ **Usage:**
208
+
209
+ ```bash
210
+ api-tools redocly bundle [input] [options]
211
+ ```
212
+
213
+ **Options:**
214
+
215
+ - `[input]` - Document path (default: `openapi/openapi.yaml`)
216
+ - `--output <path>` - Output file path (default: `dist/bundle/openapi.yaml`)
217
+ - `--ext <extension>` - Output extension (overrides `--output` extension)
218
+ - Choices: `json`, `yaml`, `yml`
219
+ - `--dereferenced` - Generate fully dereferenced bundle (no `$ref`)
220
+ - `--config <file>` - Config file path (overrides auto/bundled)
221
+
222
+ **Examples:**
223
+
224
+ ```bash
225
+ # Bundle with defaults
226
+ api-tools redocly bundle
227
+
228
+ # Bundle to JSON
229
+ api-tools redocly bundle --ext json
230
+
231
+ # Fully dereferenced bundle
232
+ api-tools redocly bundle --dereferenced
233
+
234
+ # Custom output
235
+ api-tools redocly bundle --output dist/api-bundle.yaml
236
+
237
+ # Remove unused components via passthrough
238
+ api-tools redocly bundle -- --remove-unused-components
239
+ ```
240
+
241
+ #### `redocly join`
242
+
243
+ Join multiple OpenAPI 3.x documents into a single file.
244
+
245
+ > **Note:** The `join` command differs from the `bundle` command.
246
+ > The `bundle` command takes a root OpenAPI file as input and follows the `$ref` mentions to include
247
+ > all the referenced components into a single output file. The `join` command can combine multiple
248
+ > OpenAPI files into a single unified API description file.
249
+ > Unlike the `bundle` command, `join` does not execute preprocessors or decorators and combines the
250
+ > API description files as-is without modifying the original source files.
251
+
252
+ **Usage:**
253
+
254
+ ```bash
255
+ api-tools redocly join <inputs...> [options]
256
+ ```
257
+
258
+ **Options:**
259
+
260
+ - `<inputs...>` - **REQUIRED.** At least 2 document paths to join
261
+ - `--output <file>` - Output file path (default: `dist/join/openapi.yaml`)
262
+ - `--prefix-components-with-info-prop <property>` - Prefix component names with info property to
263
+ resolve conflicts (e.g., `version`, `title`)
264
+ - `--prefix-tags-with-info-prop <property>` - Prefix tag names with info property (e.g., `title`, `version`)
265
+ - `--prefix-tags-with-filename` - Prefix tag names with filename to resolve conflicts
266
+ - `--without-x-tag-groups` - Skip automated `x-tagGroups` creation (avoids tag duplication)
267
+ - `--config <file>` - Config file path (overrides auto/bundled)
268
+
269
+ > **Note:** The options `--prefix-tags-with-info-prop`, `--prefix-tags-with-filename`, and
270
+ > `--without-x-tag-groups` are mutually exclusive.
271
+
272
+ **Examples:**
273
+
274
+ ```bash
275
+ # Join two documents
276
+ api-tools redocly join api-1.yaml api-2.yaml
277
+
278
+ # Join with custom output
279
+ api-tools redocly join users-api.yaml orders-api.yaml --output dist/combined-api.yaml
280
+
281
+ # Resolve component naming conflicts using version
282
+ api-tools redocly join museum-v1.yaml museum-v2.yaml \
283
+ --prefix-components-with-info-prop version
284
+
285
+ # Prefix tags with title to avoid conflicts
286
+ api-tools redocly join first-api.yaml second-api.yaml \
287
+ --prefix-tags-with-info-prop title
288
+
289
+ # Prefix tags with filename
290
+ api-tools redocly join api1/openapi.yaml api2/openapi.yaml \
291
+ --prefix-tags-with-filename
292
+
293
+ # Skip x-tagGroups for duplicate tags
294
+ api-tools redocly join api-a.yaml api-b.yaml --without-x-tag-groups
295
+
296
+ # Advanced passthrough options
297
+ api-tools redocly join *.yaml -- --lint-config error
298
+ ```
299
+
300
+ #### `redocly generate-arazzo`
301
+
302
+ Generate Arazzo workflow description from OpenAPI document.
303
+
304
+ **Usage:**
305
+
306
+ ```bash
307
+ api-tools redocly generate-arazzo [input] [options]
308
+ ```
309
+
310
+ **Options:**
311
+
312
+ - `[input]` - OpenAPI document path (default: `openapi/openapi.yaml`)
313
+ - `--output <file>` - Output file path (default: `arazzo/auto-generated.arazzo.yaml`)
314
+
315
+ **Note:** Generated Arazzo files require manual editing to be functional.
316
+
317
+ **Examples:**
318
+
319
+ ```bash
320
+ # Generate from default OpenAPI
321
+ api-tools redocly generate-arazzo
322
+
323
+ # Custom output
324
+ api-tools redocly generate-arazzo --output arazzo/workflows.arazzo.yaml
325
+ ```
326
+
327
+ #### `redocly respect`
328
+
329
+ Execute Arazzo workflow tests.
330
+
331
+ **Usage:**
332
+
333
+ ```bash
334
+ api-tools redocly respect [input] [options]
335
+ ```
336
+
337
+ **Options:**
338
+
339
+ - `[input]` - Arazzo document path (default: `arazzo/arazzo.yaml`)
340
+ - `--workflow <names...>` - Run only specified workflows
341
+ - `--skip <names...>` - Skip specified workflows (conflicts with `--workflow`)
342
+ - `--verbose` - Enable verbose output
343
+ - `--input <params...>` - Workflow input parameters (`key=value` or JSON)
344
+ - `--server <overrides...>` - Server overrides (`name=url`)
345
+ - `--json-output <file>` - Save results to JSON file
346
+ - `--har-output <file>` - Save HTTP interactions to HAR file
347
+
348
+ **Examples:**
349
+
350
+ ```bash
351
+ # Execute default workflows
352
+ api-tools redocly respect
353
+
354
+ # Run specific workflow
355
+ api-tools redocly respect --workflow login-flow
356
+
357
+ # Test against staging
358
+ api-tools redocly respect --server api=https://staging.example.com
359
+
360
+ # Provide inputs
361
+ api-tools redocly respect --input email=test@example.com --input password=secret
362
+
363
+ # CI/CD with JSON output
364
+ api-tools redocly respect --json-output results.json --verbose
365
+
366
+ # Advanced options via passthrough
367
+ api-tools redocly respect -- --max-steps 100 --severity '{"STATUS_CODE_CHECK":"warn"}'
368
+ ```
369
+
370
+ #### `redocly init`
371
+
372
+ Create a default `redocly.yaml` config file.
373
+
374
+ ```bash
375
+ api-tools redocly init [--force]
376
+ ```
377
+
378
+ ## Default File Locations
379
+
380
+ The tool expects the following directory structure:
381
+
382
+ ```bash
383
+ project/
384
+ ├── openapi/
385
+ │ └── openapi.yaml # Main OpenAPI spec
386
+ ├── asyncapi/
387
+ │ └── asyncapi.yaml # Main AsyncAPI spec
388
+ ├── arazzo/
389
+ │ ├── arazzo.yaml # Production Arazzo workflows
390
+ │ └── auto-generated.arazzo.yaml # Generated starter
391
+ └── dist/
392
+ ├── bundle/
393
+ │ └── openapi.yaml # Bundled output
394
+ ├── join/
395
+ │ └── openapi.yaml # Joined output
396
+ └── docs/
397
+ └── openapi.html # Generated docs
398
+ ```
399
+
400
+ ## Configuration Files
401
+
402
+ ### Auto-Discovery
403
+
404
+ The tool automatically discovers local config files:
405
+
406
+ - `.spectral.yaml`, `.spectral.yml`, `.spectral.json`, `.spectral.js`, `.spectral.mjs`,
407
+ `spectral.yaml`, `spectral.yml`, `spectral.json`, `spectral.js`, `spectral.mjs`
408
+ - `.redocly.yaml`, `.redocly.yml`, `redocly.yaml`, `redocly.yml`
409
+
410
+ ### Bundled Defaults
411
+
412
+ If no local config exists, opinionated bundled configs are used with stricter-than-default rules:
413
+
414
+ - **Spectral**: `defaults/spectral.yaml` - Comprehensive OpenAPI/AsyncAPI/Arazzo validation
415
+ - **Redocly**: `defaults/redocly.yaml` - Strict API design standards
416
+
417
+ These bundled configs enforce best practices and may be more restrictive than upstream tool defaults.
418
+ Create a local config file to customize rules for your project.
419
+
420
+ ### Custom Configs
421
+
422
+ Override with CLI options:
423
+
424
+ ```bash
425
+ api-tools spectral lint --ruleset custom/.spectral.yaml
426
+ api-tools redocly lint --config custom/redocly.yaml
427
+ ```
428
+
429
+ ## Passthrough Arguments
430
+
431
+ For advanced options not exposed by the wrapper, use `--` to pass arguments directly to the underlying tool:
432
+
433
+ ```bash
434
+ # Spectral advanced options
435
+ api-tools spectral lint -- --ignore-unknown-format
436
+
437
+ # Redocly advanced options
438
+ api-tools redocly bundle -- --remove-unused-components
439
+ api-tools redocly respect -- --max-steps 100 --execution-timeout 1800000
440
+ ```
441
+
442
+ ## CI/CD Integration
443
+
444
+ ### GitHub Actions Example
445
+
446
+ ```yaml
447
+ name: API Validation
448
+
449
+ on: [push, pull_request]
450
+
451
+ jobs:
452
+ validate:
453
+ runs-on: ubuntu-latest
454
+ steps:
455
+ - uses: actions/checkout@v6
456
+
457
+ - uses: actions/setup-node@v6
458
+ with:
459
+ node-version: "24"
460
+
461
+ - name: Install dependencies
462
+ run: npm ci
463
+ env:
464
+ GITHUB_PACKAGES_TOKEN: ${{ secrets.GITHUB_PACKAGES_TOKEN }}
465
+
466
+ - name: Lint with Spectral
467
+ run: npm run lint:spectral -- --format github-actions
468
+
469
+ - name: Lint with Redocly
470
+ run: npm run lint:redocly -- --format github-actions
471
+
472
+ - name: Bundle spec
473
+ run: npm run bundle
474
+
475
+ - name: Generate docs
476
+ run: npm run docs
477
+
478
+ - name: Test workflows
479
+ run: npm run test:api -- --verbose
480
+
481
+ # Alternative: Call CLI directly (useful for matrix builds or custom workflows)
482
+ # - name: Lint OpenAPI with Spectral
483
+ # run: npx api-tools spectral lint --openapi --format github-actions
484
+
485
+ # Optional: Save results as artifacts
486
+ - name: Generate test report
487
+ if: always()
488
+ run: npm run test:api -- --json-output results.json
489
+
490
+ - name: Upload test results
491
+ if: always()
492
+ uses: actions/upload-artifact@v6
493
+ with:
494
+ name: api-test-results
495
+ path: results.json
496
+ ```
497
+
498
+ ## Common Workflows
499
+
500
+ ### Development
501
+
502
+ ```bash
503
+ # Lint using Spectral during development
504
+ api-tools spectral lint --openapi
505
+
506
+ # Lint using Redocly during development
507
+ api-tools redocly lint --openapi
508
+
509
+ # Generate docs for local preview
510
+ api-tools redocly build-docs
511
+ ```
512
+
513
+ ### Pre-commit
514
+
515
+ ```bash
516
+ # Fast validation
517
+ api-tools spectral lint --fail-severity error
518
+ api-tools redocly lint
519
+ ```
520
+
521
+ ### CI Pipeline
522
+
523
+ ```bash
524
+ # Full validation with outputs
525
+ api-tools spectral lint --format github-actions
526
+ api-tools redocly lint --format github-actions
527
+ api-tools redocly bundle --output dist/openapi.yaml
528
+ api-tools redocly build-docs --output dist/api-docs.html
529
+ ```
530
+
531
+ ### API Testing
532
+
533
+ ```bash
534
+ # Run Arazzo workflows against staging
535
+ api-tools redocly respect \
536
+ --server api=https://staging.example.com \
537
+ --input apiKey=${STAGING_API_KEY} \
538
+ --json-output test-results.json \
539
+ --verbose
540
+ ```
541
+
542
+ ## Troubleshooting
543
+
544
+ ### Command not found
545
+
546
+ Ensure the package is installed and npm scripts are configured:
547
+
548
+ ```bash
549
+ npm install -D @bymbly/api-tools@latest
550
+ ```
551
+
552
+ ### Config not found
553
+
554
+ Check config file names and locations. Use `--config` or `--ruleset` to specify custom paths.
555
+
556
+ ### Bundled config issues
557
+
558
+ To use your own config instead of bundled defaults, create a local config file that will be auto-discovered.
559
+
560
+ ## Contributing
561
+
562
+ Issues and pull requests welcome at [github.com/bymbly/api-tools](https://github.com/bymbly/api-tools)!
563
+
564
+ ## License
565
+
566
+ [Apache License, Version 2.0](LICENSE)
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import { errorMessage } from "../lib/cli/helpers.js";
3
+ import { buildProgram } from "../lib/cli/program.js";
4
+ buildProgram()
5
+ .parseAsync(process.argv)
6
+ .catch((error) => {
7
+ process.exitCode = 1;
8
+ const message = errorMessage(error);
9
+ console.error(`❌ Error: ${message}`);
10
+ });
11
+ //# sourceMappingURL=api-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-tools.js","sourceRoot":"","sources":["../../src/bin/api-tools.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,YAAY,EAAE;KACX,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC;KACxB,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IACxB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IAErB,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAEpC,OAAO,CAAC,KAAK,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;AACvC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ extends:
2
+ - recommended-strict
3
+
4
+ telemetry: off
@@ -0,0 +1 @@
1
+ extends: [[spectral:oas, all], [spectral:asyncapi, all], [spectral:arazzo, all]]