The bruno-api-typescript project is an automation tool designed to streamline API synchronization between backend development (using Bruno .bru files) and frontend development. It automatically transforms Bruno request definitions into OpenAPI specifications and typed API clients (along with optional Mock Service Worker (MSW) handlers). This entire process is integrated with GitHub Apps and GitHub Actions, enabling automated generation of client code and Pull Requests in frontend repositories whenever backend API definitions in Bruno files change.
Core Goal: To minimize manual effort in maintaining API client code and documentation by automating the generation process directly from Bruno API definitions.
- OpenAPI Specification Generation: Converts Bruno
.brucollection files into a comprehensive OpenAPI 3.0.0 specification (openapi.json). This includes API paths, methods, request bodies, and inferred response schemas based on JSON examples provided in the Brunodocsblocks. - Typed API Client Generation: Generates TypeScript API factory functions from Bruno API definitions. These clients are type-safe, leveraging inferred schemas for request and response types.
- API Definitions Generation: Creates typed metadata files (
apiDefinitions.ts) that provide type information for each API endpoint including method, path, parameters, body, and response types. - Mock Service Worker (MSW) Handlers Generation (Optional): Can generate MSW handlers to mock API responses during frontend development and testing, based on the same Bruno definitions.
- Change Detection and Changelog Generation: Detects breaking changes between different versions of the OpenAPI specification and can generate detailed changelogs (Markdown, JSON, HTML) to inform frontend teams about API modifications.
- GitHub Apps Integration: Designed to run within GitHub Actions workflows, leveraging GitHub Apps for programmatic access to repositories (reading Bruno files, creating PRs in frontend repos).
- Incremental Generation: Utilizes a hash-based caching mechanism (
BrunoHashCache) to intelligently regenerate only the changed API clients, optimizing performance for large projects.
The project follows a CLI-driven, pipeline-like architecture with a clear separation of concerns.
- CLI (
src/cli/index.ts):- Role: The primary entry point for the tool. It parses command-line arguments (
generatefor OpenAPI,generate-hooksfor API clients/MSW). - Interaction: Orchestrates the entire process by invoking the appropriate internal modules based on the command and options provided.
- Role: The primary entry point for the tool. It parses command-line arguments (
- Parser (
src/parser/bruParser.ts):- Role: Responsible for reading and parsing individual Bruno
.brufiles. It extracts structured data such as request metadata (meta), HTTP details (method, URL), headers, request body, and the crucialdocsblock content. - Interaction: Provides the raw, structured representation of Bruno API definitions to the Converter and Generator modules.
- Role: Responsible for reading and parsing individual Bruno
- Converter (
src/converter/openapiConverter.ts,src/converter/schemaBuilder.ts):openapiConverter.tsRole: Takes the parsed Bruno data and constructs the OpenAPI Specification. It iterates through Bruno files, extracts domains for tagging, normalizes URLs, and builds operation objects for each API endpoint.schemaBuilder.tsRole: Infers JSON schemas (used in OpenAPI for request/response bodies) from example JSON data extracted from the Brunodocsblocks. It handles primitive types, arrays, and objects, marking properties asrequiredif present in the example.- Interaction:
bruParserfeeds data toopenapiConverter, which in turn usesschemaBuilderto infer schemas for the OpenAPI spec.
- Generator (
src/generator/index.ts,src/generator/*Generator.ts):index.tsRole: The main orchestrator for generating frontend-specific code. It manages theBrunoHashCachefor incremental updates, collects Bruno files, and then dispatches to specialized generators.apiClientGenerator.ts(implied fromextractApiFunction) Role: Extracts API function metadata from parsed Bruno files.apiFactoryGenerator.tsRole: Generates API factory files, grouping related API functions by domain with full type safety.apiDefinitionGenerator.tsRole: Generates typed API metadata files with method, path, parameter, body, and response type information.mswGenerator.tsRole: Generates Mock Service Worker (MSW) request handlers from Bruno API definitions anddocsexamples.typeGenerator.tsRole: Infers TypeScript types from JSON examples in Brunodocsblocks.- Interaction:
bruParserfeeds data toindex.ts, which then uses various*Generator.tsmodules to produce the final client-side code.BrunoHashCacheis used throughout to manage regeneration efficiently.
- Diffing (
src/diff/changeDetector.ts,src/diff/changelogGenerator.ts):changeDetector.tsRole: Compares two OpenAPI specifications to identify differences, categorizing them (e.g., breaking changes, non-breaking changes).changelogGenerator.tsRole: Formats the detected changes into a human-readable changelog.- Interaction: Used by the CLI
generatecommand when the--diffoption is enabled, operating on generated OpenAPI specs.
This project does not define its own external API endpoints. Instead, it processes API definitions provided in Bruno .bru files.
- Bruno
.bruFiles: Serve as the source of truth for API definitions. Each.brufile typically represents a single API request and includes:metablock: Defines request name, type, etc.- HTTP method and URL (e.g.,
get /users/profile). headersblock: HTTP headers.body:jsonblock: JSON request body content.docsblock: Crucially, this block can contain Markdown, including ````json` code blocks that provide example JSON responses. These examples are used for schema inference.
- Generated OpenAPI Spec: Conforms to the OpenAPI 3.0.0 standard, providing a machine-readable API contract. Paths are normalized (e.g.,
/users/:idbecomes/users/{id}). - Generated API Clients: Domain-based API factories and typed API definitions for each endpoint.
- Generated MSW Handlers: Designed to integrate seamlessly with the Mock Service Worker library.
- Input: Bruno
.brufiles (containing API request definitions and JSON examples indocsblocks). - Parsing:
bruParserreads.brufiles into structuredParsedBrunoFileobjects. - Schema Inference:
schemaBuilderinfers JSON schemas fromdocsJSON examples within the parsed Bruno files. - OpenAPI Generation:
openapiConverteruses parsed Bruno data and inferred schemas to buildOpenAPISpec. - Client Code Generation:
generator/index.tsuses parsed Bruno data and inferred schemas (implicitly via other generator modules) to produce:- API factory functions (
apiFactoryGenerator) - API definitions (
apiDefinitionGenerator) - MSW handlers (
mswGenerator)
- API factory functions (
- Output:
openapi.json, TypeScript files for API factories, API definitions, and MSW handlers. - Automation Flow (via GitHub Actions):
- Backend developer pushes changes to Bruno files.
- GitHub Action triggers
bruno-api-typescriptCLI. - The tool generates updated OpenAPI spec and frontend client code.
- A Pull Request is automatically created against the frontend repository with the generated code.
- TypeScript: Primary development language.
- Node.js: Runtime environment.
- Commander.js: CLI framework.
- Bruno: API client for defining requests.
- OpenAPI (Swagger): Standard for API documentation and client generation.
- Mock Service Worker (MSW): API mocking library.
- Mock Service Worker (MSW): API mocking library.
- GitHub Apps / GitHub Actions: For automation and integration with repositories.
- YAML: For parsing Bruno files.
- Clone the repository.
- Install dependencies:
npm install. - Build the project:
npm run build. - Refer to
README.mdfor detailed GitHub App and workflow configuration.