https://github.com/bymbly/api-tools
Unified, opinionated CLI wrapper for API specification tooling.
https://github.com/bymbly/api-tools
api arazzo asyncapi cli openapi redocly spectral tools
Last synced: 4 days ago
JSON representation
Unified, opinionated CLI wrapper for API specification tooling.
- Host: GitHub
- URL: https://github.com/bymbly/api-tools
- Owner: bymbly
- License: apache-2.0
- Created: 2025-12-02T05:18:07.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-01-25T13:01:37.000Z (10 days ago)
- Last Synced: 2026-01-25T22:41:24.985Z (9 days ago)
- Topics: api, arazzo, asyncapi, cli, openapi, redocly, spectral, tools
- Language: TypeScript
- Homepage:
- Size: 251 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# @bymbly/api-tools
Unified, opinionated CLI wrapper for API specification tooling.
Standardizes common workflows across projects with sensible defaults while allowing full
customization through CLI options and passthrough arguments.
**Supports:** OpenAPI, AsyncAPI, Arazzo
**Wraps:** [Redocly](https://github.com/Redocly/redocly-cli) | [Spectral](https://github.com/stoplightio/spectral)
[](https://github.com/bymbly/api-tools/actions/workflows/workflow.yaml)


## Features
- **Single unified CLI** - One tool for all API spec operations
- **Opinionated defaults** - Sensible conventions for file locations and configurations
- **Consistent interface** - Same flags and patterns across all commands
- **Flexible overrides** - CLI options for common cases, passthrough for advanced use
- **Bundled configs** - Default Spectral and Redocly configuration included
- **Auto-detection** - Finds OpenAPI, AsyncAPI, and Arazzo specs automatically
## Table of Contents
- [@bymbly/api-tools](#bymblyapi-tools)
- [Features](#features)
- [Table of Contents](#table-of-contents)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Command Structure](#command-structure)
- [Global Options](#global-options)
- [Commands](#commands)
- [Spectral Commands](#spectral-commands)
- [`spectral lint`](#spectral-lint)
- [`spectral init`](#spectral-init)
- [Redocly Commands](#redocly-commands)
- [`redocly lint`](#redocly-lint)
- [`redocly build-docs`](#redocly-build-docs)
- [`redocly bundle`](#redocly-bundle)
- [`redocly join`](#redocly-join)
- [`redocly generate-arazzo`](#redocly-generate-arazzo)
- [`redocly respect`](#redocly-respect)
- [`redocly init`](#redocly-init)
- [Default File Locations](#default-file-locations)
- [Configuration Files](#configuration-files)
- [Auto-Discovery](#auto-discovery)
- [Bundled Defaults](#bundled-defaults)
- [Custom Configs](#custom-configs)
- [Passthrough Arguments](#passthrough-arguments)
- [CI/CD Integration](#cicd-integration)
- [GitHub Actions Example](#github-actions-example)
- [Common Workflows](#common-workflows)
- [Development](#development)
- [Pre-commit](#pre-commit)
- [CI Pipeline](#ci-pipeline)
- [API Testing](#api-testing)
- [Troubleshooting](#troubleshooting)
- [Command not found](#command-not-found)
- [Config not found](#config-not-found)
- [Bundled config issues](#bundled-config-issues)
- [Contributing](#contributing)
- [License](#license)
## Installation
```bash
npm install -D @bymbly/api-tools@latest
```
## Quick Start
Add scripts to your `package.json`:
```json
{
"scripts": {
"lint": "npm run lint:spectral && npm run lint:redocly",
"lint:spectral": "api-tools spectral lint",
"lint:redocly": "api-tools redocly lint",
"bundle": "api-tools redocly bundle",
"join": "api-tools redocly join",
"docs": "api-tools redocly build-docs",
"arazzo:gen": "api-tools redocly generate-arazzo",
"test:api": "api-tools redocly respect"
}
}
```
Run:
```bash
npm run lint # Lint with both Spectral and Redocly
npm run bundle # Bundle OpenAPI documents
npm run join # Join OpenAPI documents
npm run docs # Generate HTML documentation
npm run arazzo:gen # Generate Arazzo workflow starter
npm run test:api # Execute Arazzo workflow tests
```
## Command Structure
```bash
api-tools [global-options] [options] [-- passthrough-args]
```
### Global Options
Available for all commands:
- `--quiet` - Disable wrapper logging (still shows tool output)
- `--silent` - Disable all output (wrapper + tool)
- `--cwd ` - Run as if started in this directory
## Commands
### Spectral Commands
#### `spectral lint`
Validate and lint OpenAPI, AsyncAPI, and Arazzo documents.
**Usage:**
```bash
api-tools spectral lint [input] [options]
```
**Options:**
- `[input]` - Document path (default: auto-detect)
- `--openapi` - Lint only OpenAPI at `openapi/openapi.yaml`
- `--asyncapi` - Lint only AsyncAPI at `asyncapi/asyncapi.yaml`
- `--arazzo` - Lint only Arazzo at `arazzo/arazzo.yaml`
- `--format ` - Output format (default: `stylish`)
- Choices: `json`, `stylish`, `junit`, `html`, `text`, `teamcity`, `pretty`, `github-actions`, `sarif`, `markdown`, `gitlab`
- `--output ` - Write output to file
- `--ruleset ` - Custom ruleset (overrides auto/bundled)
- `--fail-severity ` - Fail threshold (default: `warn`)
- Choices: `error`, `warn`, `info`, `hint`
- `--display-only-failures` - Show only failing results
- `--verbose` - Enable verbose output
**Examples:**
```bash
# Auto-detect and lint all specs
api-tools spectral lint
# Lint specific spec types
api-tools spectral lint --openapi
api-tools spectral lint --asyncapi --arazzo
# Lint specific file
api-tools spectral lint custom/spec.yaml
# JSON output
api-tools spectral lint --format json --output results.json
# Custom ruleset
api-tools spectral lint --ruleset .spectral.yaml
# Passthrough advanced options
api-tools spectral lint -- --ignore-unknown-format
```
#### `spectral init`
Create a default `spectral.yaml` config file.
```bash
api-tools spectral init [--force]
```
### Redocly Commands
#### `redocly lint`
Validate and lint OpenAPI, AsyncAPI, and Arazzo documents using Redocly.
**Usage:**
```bash
api-tools redocly lint [input] [options]
```
**Options:**
- `[input]` - Document path (default: auto-detect)
- `--openapi` - Lint only OpenAPI at `openapi/openapi.yaml`
- `--asyncapi` - Lint only AsyncAPI at `asyncapi/asyncapi.yaml`
- `--arazzo` - Lint only Arazzo at `arazzo/arazzo.yaml`
- `--format ` - Output format (default: `codeframe`)
- Choices: `codeframe`, `stylish`, `json`, `checkstyle`, `codeclimate`, `github-actions`, `markdown`, `summary`
- `--config ` - Config file path (overrides auto/bundled)
**Examples:**
```bash
# Auto-detect and lint all specs
api-tools redocly lint
# Lint only OpenAPI
api-tools redocly lint --openapi
# JSON output
api-tools redocly lint --format json
# Custom config
api-tools redocly lint --config custom-redocly.yaml
```
#### `redocly build-docs`
Build HTML documentation from OpenAPI documents.
**Usage:**
```bash
api-tools redocly build-docs [input] [options]
```
**Options:**
- `[input]` - OpenAPI document path (default: `openapi/openapi.yaml`)
- `--output ` - Output HTML file (default: `dist/docs/openapi.html`)
- `--config ` - Config file path (overrides auto/bundled)
**Examples:**
```bash
# Generate docs with defaults
api-tools redocly build-docs
# Custom output location
api-tools redocly build-docs --output public/api-docs.html
# Custom title via passthrough
api-tools redocly build-docs -- --title "My API Documentation"
```
#### `redocly bundle`
Bundle API descriptions into a single file.
> **Note:** The `bundle` command differs from the `join` command.
> The `bundle` command takes a root OpenAPI file as input and follows the `$ref` mentions to include
> all the referenced components into a single output file. The `join` command can combine multiple
> OpenAPI files into a single unified API description file.
**Usage:**
```bash
api-tools redocly bundle [input] [options]
```
**Options:**
- `[input]` - Document path (default: `openapi/openapi.yaml`)
- `--output ` - Output file path (default: `dist/bundle/openapi.yaml`)
- `--ext ` - Output extension (overrides `--output` extension)
- Choices: `json`, `yaml`, `yml`
- `--dereferenced` - Generate fully dereferenced bundle (no `$ref`)
- `--config ` - Config file path (overrides auto/bundled)
**Examples:**
```bash
# Bundle with defaults
api-tools redocly bundle
# Bundle to JSON
api-tools redocly bundle --ext json
# Fully dereferenced bundle
api-tools redocly bundle --dereferenced
# Custom output
api-tools redocly bundle --output dist/api-bundle.yaml
# Remove unused components via passthrough
api-tools redocly bundle -- --remove-unused-components
```
#### `redocly join`
Join multiple OpenAPI 3.x documents into a single file.
> **Note:** The `join` command differs from the `bundle` command.
> The `bundle` command takes a root OpenAPI file as input and follows the `$ref` mentions to include
> all the referenced components into a single output file. The `join` command can combine multiple
> OpenAPI files into a single unified API description file.
> Unlike the `bundle` command, `join` does not execute preprocessors or decorators and combines the
> API description files as-is without modifying the original source files.
**Usage:**
```bash
api-tools redocly join [options]
```
**Options:**
- `` - **REQUIRED.** At least 2 document paths to join
- `--output ` - Output file path (default: `dist/join/openapi.yaml`)
- `--prefix-components-with-info-prop ` - Prefix component names with info property to
resolve conflicts (e.g., `version`, `title`)
- `--prefix-tags-with-info-prop ` - Prefix tag names with info property (e.g., `title`, `version`)
- `--prefix-tags-with-filename` - Prefix tag names with filename to resolve conflicts
- `--without-x-tag-groups` - Skip automated `x-tagGroups` creation (avoids tag duplication)
- `--config ` - Config file path (overrides auto/bundled)
> **Note:** The options `--prefix-tags-with-info-prop`, `--prefix-tags-with-filename`, and
> `--without-x-tag-groups` are mutually exclusive.
**Examples:**
```bash
# Join two documents
api-tools redocly join api-1.yaml api-2.yaml
# Join with custom output
api-tools redocly join users-api.yaml orders-api.yaml --output dist/combined-api.yaml
# Resolve component naming conflicts using version
api-tools redocly join museum-v1.yaml museum-v2.yaml \
--prefix-components-with-info-prop version
# Prefix tags with title to avoid conflicts
api-tools redocly join first-api.yaml second-api.yaml \
--prefix-tags-with-info-prop title
# Prefix tags with filename
api-tools redocly join api1/openapi.yaml api2/openapi.yaml \
--prefix-tags-with-filename
# Skip x-tagGroups for duplicate tags
api-tools redocly join api-a.yaml api-b.yaml --without-x-tag-groups
# Advanced passthrough options
api-tools redocly join *.yaml -- --lint-config error
```
#### `redocly generate-arazzo`
Generate Arazzo workflow description from OpenAPI document.
**Usage:**
```bash
api-tools redocly generate-arazzo [input] [options]
```
**Options:**
- `[input]` - OpenAPI document path (default: `openapi/openapi.yaml`)
- `--output ` - Output file path (default: `arazzo/auto-generated.arazzo.yaml`)
**Note:** Generated Arazzo files require manual editing to be functional.
**Examples:**
```bash
# Generate from default OpenAPI
api-tools redocly generate-arazzo
# Custom output
api-tools redocly generate-arazzo --output arazzo/workflows.arazzo.yaml
```
#### `redocly respect`
Execute Arazzo workflow tests.
**Usage:**
```bash
api-tools redocly respect [input] [options]
```
**Options:**
- `[input]` - Arazzo document path (default: `arazzo/arazzo.yaml`)
- `--workflow ` - Run only specified workflows
- `--skip ` - Skip specified workflows (conflicts with `--workflow`)
- `--verbose` - Enable verbose output
- `--input ` - Workflow input parameters (`key=value` or JSON)
- `--server ` - Server overrides (`name=url`)
- `--json-output ` - Save results to JSON file
- `--har-output ` - Save HTTP interactions to HAR file
**Examples:**
```bash
# Execute default workflows
api-tools redocly respect
# Run specific workflow
api-tools redocly respect --workflow login-flow
# Test against staging
api-tools redocly respect --server api=https://staging.example.com
# Provide inputs
api-tools redocly respect --input email=test@example.com --input password=secret
# CI/CD with JSON output
api-tools redocly respect --json-output results.json --verbose
# Advanced options via passthrough
api-tools redocly respect -- --max-steps 100 --severity '{"STATUS_CODE_CHECK":"warn"}'
```
#### `redocly init`
Create a default `redocly.yaml` config file.
```bash
api-tools redocly init [--force]
```
## Default File Locations
The tool expects the following directory structure:
```bash
project/
├── openapi/
│ └── openapi.yaml # Main OpenAPI spec
├── asyncapi/
│ └── asyncapi.yaml # Main AsyncAPI spec
├── arazzo/
│ ├── arazzo.yaml # Production Arazzo workflows
│ └── auto-generated.arazzo.yaml # Generated starter
└── dist/
├── bundle/
│ └── openapi.yaml # Bundled output
├── join/
│ └── openapi.yaml # Joined output
└── docs/
└── openapi.html # Generated docs
```
## Configuration Files
### Auto-Discovery
The tool automatically discovers local config files:
- `.spectral.yaml`, `.spectral.yml`, `.spectral.json`, `.spectral.js`, `.spectral.mjs`,
`spectral.yaml`, `spectral.yml`, `spectral.json`, `spectral.js`, `spectral.mjs`
- `.redocly.yaml`, `.redocly.yml`, `redocly.yaml`, `redocly.yml`
### Bundled Defaults
If no local config exists, opinionated bundled configs are used with stricter-than-default rules:
- **Spectral**: `defaults/spectral.yaml` - Comprehensive OpenAPI/AsyncAPI/Arazzo validation
- **Redocly**: `defaults/redocly.yaml` - Strict API design standards
These bundled configs enforce best practices and may be more restrictive than upstream tool defaults.
Create a local config file to customize rules for your project.
### Custom Configs
Override with CLI options:
```bash
api-tools spectral lint --ruleset custom/.spectral.yaml
api-tools redocly lint --config custom/redocly.yaml
```
## Passthrough Arguments
For advanced options not exposed by the wrapper, use `--` to pass arguments directly to the underlying tool:
```bash
# Spectral advanced options
api-tools spectral lint -- --ignore-unknown-format
# Redocly advanced options
api-tools redocly bundle -- --remove-unused-components
api-tools redocly respect -- --max-steps 100 --execution-timeout 1800000
```
## CI/CD Integration
### GitHub Actions Example
```yaml
name: API Validation
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: "24"
- name: Install dependencies
run: npm ci
env:
GITHUB_PACKAGES_TOKEN: ${{ secrets.GITHUB_PACKAGES_TOKEN }}
- name: Lint with Spectral
run: npm run lint:spectral -- --format github-actions
- name: Lint with Redocly
run: npm run lint:redocly -- --format github-actions
- name: Bundle spec
run: npm run bundle
- name: Generate docs
run: npm run docs
- name: Test workflows
run: npm run test:api -- --verbose
# Alternative: Call CLI directly (useful for matrix builds or custom workflows)
# - name: Lint OpenAPI with Spectral
# run: npx api-tools spectral lint --openapi --format github-actions
# Optional: Save results as artifacts
- name: Generate test report
if: always()
run: npm run test:api -- --json-output results.json
- name: Upload test results
if: always()
uses: actions/upload-artifact@v6
with:
name: api-test-results
path: results.json
```
## Common Workflows
### Development
```bash
# Lint using Spectral during development
api-tools spectral lint --openapi
# Lint using Redocly during development
api-tools redocly lint --openapi
# Generate docs for local preview
api-tools redocly build-docs
```
### Pre-commit
```bash
# Fast validation
api-tools spectral lint --fail-severity error
api-tools redocly lint
```
### CI Pipeline
```bash
# Full validation with outputs
api-tools spectral lint --format github-actions
api-tools redocly lint --format github-actions
api-tools redocly bundle --output dist/openapi.yaml
api-tools redocly build-docs --output dist/api-docs.html
```
### API Testing
```bash
# Run Arazzo workflows against staging
api-tools redocly respect \
--server api=https://staging.example.com \
--input apiKey=${STAGING_API_KEY} \
--json-output test-results.json \
--verbose
```
## Troubleshooting
### Command not found
Ensure the package is installed and npm scripts are configured:
```bash
npm install -D @bymbly/api-tools@latest
```
### Config not found
Check config file names and locations. Use `--config` or `--ruleset` to specify custom paths.
### Bundled config issues
To use your own config instead of bundled defaults, create a local config file that will be auto-discovered.
## Contributing
Issues and pull requests welcome at [github.com/bymbly/api-tools](https://github.com/bymbly/api-tools)!
## License
[Apache License, Version 2.0](LICENSE)