Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 123 additions & 68 deletions markdown/docs/tools/cli/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,95 +3,150 @@ title: 'CLI Architecture'
weight: 40
---

The AsyncAPI CLI uses oclif (Open CLI Framework) as its core framework, which enables developers to build powerful and scalable command-line applications.
# CLI Architecture

**Structure of the AsyncAPI CLI**: The CLI is primarily divided into two components: commands and the core part.
## Overview

1. **Command Component**: The commands include all the necessary functionalities that help developers interact with features like creating new AsyncAPI projects, validating AsyncAPI files, formatting AsyncAPI files, and more.
2. **Core Component**: The core part of the CLI contains various utilities that facilitate the efficient creation of new commands.
The AsyncAPI CLI is built with [oclif](https://oclif.io/) and provides both command-line operations and a REST API server for working with AsyncAPI specifications.

---

### Detailed Explanation of Key Directories in the CLI

#### `src/commands/`
- **Purpose:** Implements the CLI commands available to the user.
- **Subdirectories:**
- `config/`: Stores configuration-related files for commands.
- `generate/`: Generates typed models or other artifacts like clients, applications, or documentation using AsyncAPI Generator templates.
- **Files:**
- `fromTemplate.ts`: Contains logic for generating files using templates.
- `models.ts`: Defines the models used during generation.
- `new/`: Create a new AsyncAPI project, specification files, or templates for clients and applications.
- **Files:**
- `file.ts`: Handles file creation logic.
- `template.ts`: Manages templates for new projects.
- `start/`: Implements starting functionalities like launching a local server or studio.
- **Files:**
- `studio.ts`: Integrates with the AsyncAPI Studio.

- **Standalone Files:**
- `bundle.ts`: Bundles one or multiple AsyncAPI documents and their references together.
- `convert.ts`: Converts AsyncAPI documents from older to newer versions or transforms OpenAPI/Postman-collection documents into AsyncAPI.
- `diff.ts`: Compares two AsyncAPI documents.
- `format.ts`: Converts AsyncAPI documents from any format to YAML, YML, or JSON.
- `optimize.ts`: Optimizes AsyncAPI documents for performance.
- `pretty.ts`: Beautifies the AsyncAPI spec file (indentation, styling) in place or outputs the formatted spec to a new file.
- `validate.ts`: Validates AsyncAPI documents for correctness.
## Architecture Diagram

```
┌─────────────────────────────────────────────────┐
│ Entry Points │
│ ┌──────────┐ ┌──────────┐ │
│ │ CLI │ │ API │ │
│ │ (oclif) │ │ (Express)│ │
│ └────┬─────┘ └────┬─────┘ │
└───────┼─────────────────────────┼───────────────┘
└───────────┬─────────────┘
┌───────────────────────┐
│ Domain Services │
│ Validation, Generator│
│ Convert, Config │
└───────────┬───────────┘
┌───────────────────────┐
│ Domain Models │
│ Specification,Context│
└───────────┬───────────┘
┌───────────────────────┐
│ Utilities │
│ Logger, Helpers │
└───────────────────────┘
```

---

#### `src/core/`
- **Purpose:** Provides foundational components and utilities for the CLI.
- **Subdirectories:**
- `errors/`: Centralized error definitions.
- `flags/`: Defines CLI flags and their behavior.
- `hooks/`: Event hooks used for customization.
- `models/`: Core data models used across the application.
- `utils/`: Utility functions for common operations.

- **Standalone Files:**
- `base.ts`: Base class or logic for CLI commands.
- `global.d.ts`: Global TypeScript definitions.
- `globals.ts`: Stores global variables and configurations.
- `parser.ts`: Parses AsyncAPI documents.
## Directory Structure

```
src/
├── apps/
│ ├── cli/ # CLI commands & internals
│ └── api/ # REST API (Express)
├── domains/
│ ├── models/ # Specification, Context
│ └── services/ # Business logic
├── errors/ # Custom errors
├── interfaces/ # TypeScript types
└── utils/ # Utilities
```

---

#### `test/`
- **Purpose:** Implements the test suite for the CLI.
- **Subdirectories:**
- `fixtures/`: Contains mock data or files for testing.
- `hooks/`: Tests related to hooks.
- `integration/`: Integration tests to verify end-to-end functionality.
- `system/`: System-level tests.
- `unit/`: Unit tests for individual modules or functions.
## Core Components

### CLI Application

| Component | Description |
|-----------|-------------|
| **Entry Points** | `bin/run` (dev), `bin/run_bin` (prod) |
| **Base Command** | Metrics, parser integration, error handling |

**Commands:**
- **Core:** `validate`, `convert`, `format`, `optimize`, `diff`, `bundle`
- **Generation:** `generate client`, `generate models`, `generate fromTemplate`
- **Config:** `config context`, `config analytics`, `config versions`
- **Utility:** `new file`, `new template`, `start api|studio|preview`, `pretty`

### API Server

**Endpoints:** `/v1/validate`, `/v1/parse`, `/v1/generate`, `/v1/convert`, `/v1/bundle`, `/v1/diff`, `/v1/docs`, `/v1/help`, `/v1/version`

**Features:** Express with Helmet security, CORS, compression, RFC 7807 error responses

### Domain Services

All services extend `BaseService` and return `ServiceResult<T>`:

| Service | Purpose |
|---------|---------|
| `ValidationService` | Validates specs with Spectral, calculates scores |
| `GeneratorService` | Generates code/models |
| `ConvertService` | Converts between AsyncAPI/OpenAPI formats |
| `ConfigService` | Manages CLI config and contexts |
| `ArchiverService` | Creates ZIP archives |

### Domain Models

| Model | Purpose |
|-------|---------|
| **Specification** | Loads from file, URL, or context; auto-detects `asyncapi.json\|yml\|yaml` |
| **Context** | Manages multiple AsyncAPI contexts; stored in `~/.asyncapi/` |

### Error Classes

`ContextError`, `SpecificationFileError`, `ValidationError`, `GeneratorError`, `DiffError`

---

### Use Cases
## Execution Flow

1. **Generate AsyncAPI Artifacts:**
- Use the `generate` command to create client/server code, documentation, or other artifacts based on AsyncAPI templates.
**CLI Command:**
```
User Command → oclif → Base Command → Domain Service → ServiceResult
```

2. **Create New Projects:**
- The `new` command helps users scaffold new AsyncAPI projects with predefined templates.
**API Request:**
```
HTTP Request → Express → Controller → Domain Service → HTTP Response
```

3. **Validate AsyncAPI Documents:**
- The `validate` command ensures AsyncAPI documents conform to the specification.
---

4. **Optimize and Format Documents:**
- The `optimize` and `pretty` commands provide tools for improving document readability and performance.
## Extension Points

5. **Compare Documents:**
- The `diff` command enables comparison between two AsyncAPI documents to track changes.
| Add | Steps |
|-----|-------|
| **New Command** | Create in `src/apps/cli/commands/`, extend `Command`, implement `run()` |
| **New API Endpoint** | Create controller in `src/apps/api/controllers/`, register in `index.ts` |
| **New Service** | Create in `src/domains/services/`, extend `BaseService`, return `ServiceResult<T>` |

6. **Integration with AsyncAPI Studio:**
- The `start` command integrates with the AsyncAPI Studio for editing and visualizing documents.
---

## Configuration

7. **Convert Between Formats:**
- The `convert` command supports converting AsyncAPI documents between formats like YAML and JSON.
| Config | Location |
|--------|----------|
| CLI Context | `~/.asyncapi/contexts.json`, `~/.asyncapi/.current` |
| Analytics | `~/.asyncapi-analytics` |

**Environment Variables:**
- `NODE_ENV` — `development` | `production` | `test`
- `PORT` — API server port (default: 3000)
- `ASYNCAPI_METRICS_*` — Metrics configuration

---

This structure ensures the CLI is modular, scalable, and easy to maintain. Let me know if you need further clarification or additional details!
## Technology Stack

| Category | Technologies |
|----------|--------------|
| **Core** | oclif, TypeScript, Express |
| **AsyncAPI** | @asyncapi/parser, generator, converter, bundler, diff, optimizer |
| **Supporting** | winston, ajv, chalk, @clack/prompts |
114 changes: 114 additions & 0 deletions markdown/docs/tools/cli/contributing-prs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
---
title: 'Contributing via Pull Requests'
weight: 50
---

# Contributing via Pull Requests

## Getting Started

1. **Open an issue first** (unless it's a trivial fix)
2. **Set up environment** — Follow [DEVELOPMENT.md](../DEVELOPMENT.md)
3. **Create a branch** — Use prefixes: `feat/`, `fix/`, `docs/`, `refactor/`, `test/`, `chore/`

---

## PR Title Format

Follow [Conventional Commits](https://www.conventionalcommits.org/):

| Type | Description | Release |
|------|-------------|---------|
| `feat:` | New feature | MINOR |
| `fix:` | Bug fix | PATCH |
| `docs:` | Documentation | None |
| `chore:` | Maintenance | None |
| `test:` | Tests only | None |
| `refactor:` | Code refactoring | None |

**Breaking changes:** Add `!` → `feat!:`, `fix!:`

**Examples:**
- ✅ `feat: add AsyncAPI 3.0 validation support`
- ✅ `fix: resolve context loading with special characters`
- ❌ `Added new feature`
- ❌ `fix bug`

---

## PR Checklist

**Before submitting:**
- [ ] Branch synced with `main`
- [ ] `npm run build` passes
- [ ] `npm run cli:test` passes
- [ ] `npm run lint` passes (max 5 warnings)
- [ ] Documentation updated (if needed)

**Code quality:**
- [ ] Follows existing code patterns
- [ ] TypeScript types used (avoid `any`)
- [ ] Error handling implemented
- [ ] Tests added for new functionality
- [ ] No `console.log` or commented code

---

## Code Standards

| Area | Guideline |
|------|-----------|
| **TypeScript** | Explicit types, interfaces for objects, prefer `const` |
| **Organization** | Follow existing structure, use path aliases (`@/`, `@cli/`, `@domains/`) |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify TypeScript path alias configuration and actual directory structure

echo "=== Checking for tsconfig.json ==="
if [ -f "tsconfig.json" ]; then
  echo "Found tsconfig.json"
  echo ""
  echo "=== TypeScript paths configuration ==="
  jq '.compilerOptions.paths' tsconfig.json 2>/dev/null || cat tsconfig.json | grep -A 50 '"paths"'
else
  echo "tsconfig.json not found in root"
  # Search for tsconfig files in the repository
  find . -name "tsconfig*.json" -type f | head -20
fi

echo ""
echo "=== Checking directory structure for potential path mappings ==="
if [ -d "src" ]; then
  echo "Found src directory:"
  ls -la src/ | head -20
fi

if [ -d "src/apps/cli" ]; then
  echo "Found src/apps/cli directory"
fi

Repository: asyncapi/website

Length of output: 249


🏁 Script executed:

#!/bin/bash
# Check the actual documented content and search for alias usage

echo "=== Checking line 62 of contributing-prs.md ==="
if [ -f "markdown/docs/tools/cli/contributing-prs.md" ]; then
  sed -n '60,65p' markdown/docs/tools/cli/contributing-prs.md
else
  echo "File not found, searching for it..."
  find . -name "contributing-prs.md" -type f
fi

echo ""
echo "=== Searching for @cli/ usage in codebase ==="
rg "@cli/" --type-list 2>/dev/null | head -5 || rg "@cli/" | head -20

echo ""
echo "=== Searching for @domains/ usage in codebase ==="
rg "@domains/" | head -20

echo ""
echo "=== Checking for additional tsconfig files ==="
find . -name "tsconfig*.json" -type f

echo ""
echo "=== Full tsconfig.json content ==="
cat tsconfig.json

Repository: asyncapi/website

Length of output: 1423


Remove or configure the documented path aliases (@cli/, @domains/).

The tsconfig.json only defines a single path alias: @/* -> ./*. The documentation on line 62 lists @/, @cli/, and @domains/, but @cli/ and @domains/ do not exist in the TypeScript configuration and have no usage in the codebase. Either remove the non-existent aliases from the documentation or add them to tsconfig.json if they're intended for future use.

🤖 Prompt for AI Agents
In markdown/docs/tools/cli/contributing-prs.md around line 62, the docs list
path aliases @/, @cli/, and @domains/ but tsconfig.json only defines @/* -> ./*;
remove the non-existent @cli/ and @domains/ entries from the documentation OR
add corresponding path mappings to tsconfig.json (e.g., map @cli/* and
@domains/* to the actual source folders) and ensure the mapped folders exist and
are used; update either the docs or tsconfig so they stay consistent.

| **Errors** | Use custom errors from `src/errors/`, return `ServiceResult<T>` from services |
| **Commands** | Extend base `Command`, use domain services for business logic |

---

## Testing

**Add tests for:**
- New commands or API endpoints
- Bug fixes (regression tests)
- New domain services
- Complex business logic

```bash
npm run cli:test # All tests
npm run unit:test # Unit tests only
```

---

## Best Practices

| ❌ Avoid | ✅ Do |
|----------|-------|
| Large PRs (>500 lines) | Small, focused PRs |
| Multiple concerns in one PR | One issue per PR |
| Skipping tests | Comprehensive tests |
| Hardcoded values | Externalize configuration |
| Force push to main | Rebase instead of merge |

---

## Review Process

1. CI runs automated checks
2. Maintainers review code
3. Address feedback promptly
4. PR merged when approved

---

## Quick Reference

```bash
# Setup
npm install && npx lefthook install

# Before PR
npm run build && npm run lint && npm run cli:test
```

**Quality over speed** — Write good code, tests, and documentation.
Loading