bru2openapi
v0.0.1
Published
Generate OpenAPI specs from Bruno API collections
Maintainers
Readme
bru2openapi
Generate OpenAPI 3.0 specs from Bruno API collections.
bru2openapi takes a Bruno collection directory, runs every request through a capture proxy, and converts the recorded traffic into an OpenAPI specification using mitmproxy2swagger.
How it works
flowchart LR
A[Bruno Collection] -->|bru run| B[mitmdump proxy]
B -->|captures traffic| C[flows.mitm]
C -->|mitmproxy2swagger| D[openapi.yaml]- Reads the base URL from your Bruno environment file
- Starts
mitmdumpas a capture proxy - Runs all collection requests through the proxy via the
bruCLI - Converts captured traffic to HAR format
- Generates an OpenAPI spec with
mitmproxy2swagger
Installation
Requires Node.js 22+.
npm install -g bru2openapiQuick start
# Docker mode (default) -- only requires Docker
bru2openapi ./my-collection --env Development --base-url-var BaseUrl
# Local mode -- requires mitmproxy, mitmproxy2swagger, and bru CLI
bru2openapi ./my-collection --env Development --base-url-var BaseUrl --localIf you omit required flags, the CLI will prompt you interactively.
Usage
bru2openapi <collection-dir> [flags]
ARGUMENTS
collection-dir Path to Bruno collection directory
FLAGS
-e, --env <name> Bruno environment name
-b, --base-url-var <name> Name of the env variable holding the base URL
--format json|xml Expected API response format (default: json)
--[no-]get-only Only run GET requests (default: true)
--include <folders> Comma-separated folders to include, or ALL (default: ALL)
--exclude <folders> Comma-separated folders to exclude
--out <dir> Output directory (default: .)
--local Run locally instead of Docker
-y, --yes Skip confirmation promptsExecution modes
Docker mode (default)
Only requires Docker. The CLI builds and caches a Docker image (bru2openapi:<version>) containing mitmproxy, mitmproxy2swagger, and the Bruno CLI. The image is rebuilt automatically when the CLI version changes.
bru2openapi ./collection -e Production -b ApiBaseUrlLocal mode (--local)
Runs the pipeline directly on your machine. You need to install the dependencies yourself:
pip install mitmproxy mitmproxy2swagger
npm i -g @usebruno/cliThen:
bru2openapi ./collection -e Production -b ApiBaseUrl --localThe CLI checks for all three dependencies at startup and tells you what to install if anything is missing.
Config file
Place a .bru2openapi.yml in your collection root to save per-collection settings:
env: Development
baseUrlVar: BaseUrl
format: xml
getOnly: true
include:
- Stores
- Products
forceArrayJPaths:
- Stores
- Order.Payments
- PersonsResolution order
CLI flags take precedence over the config file, which takes precedence over interactive prompts, which fall back to built-in defaults:
CLI flags > .bru2openapi.yml > interactive prompts > defaultsforceArrayJPaths (XML only)
When format: xml, XML responses are converted to JSON before schema generation. XML-to-JSON conversion can lose array semantics when a collection contains only one element. The forceArrayJPaths list tells the converter which jPaths are always arrays, using dot-separated paths from the document root (e.g. Order.Payments).
Array jPaths are also auto-discovered via two heuristics:
- Parent element has
@Type="Array"attribute - Multiple same-name sibling elements exist in the raw XML
Folder filtering
--include
Limit which collection folders are run. Accepts a comma-separated list or the keyword ALL:
# Only run Stores and Products folders
bru2openapi ./collection -e Dev -b BaseUrl --include Stores,Products
# Run all folders (override a restrictive config file)
bru2openapi ./collection -e Dev -b BaseUrl --include ALLALL cannot be combined with specific folder names (e.g. --include ALL,Stores is an error).
--exclude
Skip specific folders:
bru2openapi ./collection -e Dev -b BaseUrl --exclude Returns,Coupons--include and --exclude are mutually exclusive.
Interactive prompts
When run in a terminal without all required flags, the CLI prompts for missing values with defaults pre-filled from the config file:
? Bruno environment (Development):
? Base URL variable (BaseUrl):
? Response format (json):
? GET requests only (Y/n):
? Include folders (ALL):
? Output directory (.):
? Run locally (no Docker) (y/N):Press Enter to accept the default or type a new value.
Use --yes / -y to skip all prompts (for CI/scripts). If required values are still missing, the CLI exits with an error.
Output
The CLI produces these files in the output directory:
| File | Description |
|---|---|
| <collection-name>-openapi.yml | The generated OpenAPI spec |
| flows.mitm | Raw mitmproxy capture file |
| flows.har | HAR file (converted from flows) |
| requests-report.json | Execution log with failures and array jPath info |
Post-generation
The generated spec is a starting point. Consider these improvements:
- Add descriptions to paths and parameters
- Add tags to group endpoints
- Add security schemes (e.g. Basic Auth)
- Parameterise path variables (replace hardcoded IDs with
{paramName}) - Add error responses (400, 401, 404, 500)
- Validate:
npx @redocly/cli lint <spec-file>
Development
pnpm install
pnpm testLicense
ISC
