bruno-swagger-sync
v1.0.1
Published
Sync OpenAPI/Swagger specs to Bruno API client collections with hot-reload
Maintainers
Readme
bruno-swagger-sync
Sync OpenAPI/Swagger specs to Bruno API client collections — with hot-reload.
Features
- Converts OpenAPI 3.x and Swagger 2.0 specs (JSON or YAML) to Bruno collections
- Reads from local files or remote URLs
- Hot-reload watch mode: re-syncs whenever the spec changes
- Smart diffing via a manifest file — only writes changed requests
- Groups requests by tags or path segments
- Generates Bruno environment files from OpenAPI
servers - Cleans up orphaned
.brufiles when operations are removed
Installation
npm install -g bruno-swagger-syncOr use without installing via npx:
npx bruno-swagger-sync -i openapi.yaml -o ./my-collectionCLI Usage
bruno-swagger-sync [options]
Options:
-i, --input <path|url> Path or URL to OpenAPI/Swagger spec (required)
-o, --output <dir> Output directory for Bruno collection (required)
-w, --watch Enable hot-reload (default: false)
--debounce <ms> Debounce delay for file watch (default: 300)
--poll-interval <ms> Poll interval for URL watch mode (default: 2000)
--group-by <tags|path> Folder grouping strategy (default: tags)
--no-env Skip environment file generation
--no-clean-orphans Keep .bru files for removed operations
--collection-name <name> Override collection name from spec title
-V, --version Print version
-h, --help Show helpOne-shot sync
# From a local file
bruno-swagger-sync -i ./openapi.yaml -o ./bruno-collection
# From a remote URL
bruno-swagger-sync -i https://petstore3.swagger.io/api/v3/openapi.json -o ./petstore
# Group by URL path instead of tags
bruno-swagger-sync -i ./openapi.yaml -o ./bruno-collection --group-by path
# Custom collection name, skip environment generation
bruno-swagger-sync -i ./openapi.yaml -o ./bruno-collection --collection-name "My API" --no-envWatch mode
# Watch a local file — re-syncs on every save
bruno-swagger-sync -i ./openapi.yaml -o ./bruno-collection --watch
# Watch a remote URL — polls every 5 seconds
bruno-swagger-sync -i https://api.example.com/openapi.json -o ./bruno-collection --watch --poll-interval 5000Programmatic API
import { sync, watch } from 'bruno-swagger-sync';
// One-shot sync
const result = await sync({
input: './openapi.yaml',
output: './bruno-collection',
groupBy: 'tags', // 'tags' | 'path'
envFromServers: true, // generate environment files from servers block
cleanOrphans: true, // delete .bru files for removed operations
collectionName: 'My API', // optional override
});
console.log(`Added: ${result.added.length}`);
console.log(`Updated: ${result.updated.length}`);
console.log(`Deleted: ${result.deleted.length}`);
console.log(`Skipped: ${result.skipped.length}`);
// Watch mode
const handle = await watch({
input: './openapi.yaml',
output: './bruno-collection',
debounce: 300,
pollInterval: 2000,
});
handle.on('ready', () => console.log('Watching for changes...'));
handle.on('synced', (result) => console.log('Synced:', result));
handle.on('error', (err) => console.error('Error:', err));
// Stop watching
await handle.close();SyncOptions
| Option | Type | Default | Description |
|---|---|---|---|
| input | string | — | Path or URL to OpenAPI/Swagger spec |
| output | string | — | Output directory for Bruno collection |
| groupBy | 'tags' \| 'path' | 'tags' | Folder grouping strategy |
| envFromServers | boolean | true | Generate Bruno env files from servers |
| cleanOrphans | boolean | true | Delete .bru files for removed operations |
| collectionName | string | spec title | Override the collection name |
| debounce | number | 300 | Debounce delay in ms (watch mode, file inputs) |
| pollInterval | number | 2000 | Poll interval in ms (watch mode, URL inputs) |
SyncResult
interface SyncResult {
added: string[]; // file paths written for new operations
updated: string[]; // file paths rewritten for changed operations
deleted: string[]; // file paths removed for dropped operations
skipped: string[]; // operation keys skipped (no changes)
errors: Array<{ operation: string; message: string }>;
}Output structure
Given a spec with tags Pets and Store, the output directory looks like:
bruno-collection/
collection.bru # Collection-level settings
environments/
production.bru # Generated from spec servers
Pets/
List pets.bru
Create pet.bru
Get pet by ID.bru
Store/
Get inventory.bru
.bruno-sync-manifest.json # Internal diff tracker (commit this)The .bruno-sync-manifest.json file tracks which operations have been written and their content hashes. Commit it alongside your Bruno collection so future syncs only write what changed.
Requirements
- Node.js 18+
- Bruno desktop app to open the generated collection
License
MIT
