A TypeScript CLI tool that maintains API guidelines as a single source of truth and generates multiple output formats including full documentation, reference guides, and Spectral rulesets.
Managing API guidelines across multiple formats leads to synchronization issues:
- Full Documentation: Detailed markdown with examples and explanations
- Reference Guide: Quick-reference list of rules by severity
- Spectral Ruleset: Automated validation rules for OpenAPI specs
This tool solves the single source of truth problem by maintaining guidelines in structured YAML files and generating all outputs automatically.
- ✅ Single Source of Truth: Define guidelines once in YAML format
- ✅ Multiple Output Formats: Generate docs, reference guides, and Spectral rulesets
- ✅ Flexible Spectral Rules: Support both inline and external rule definitions
- ✅ Content Separation: Keep detailed explanations in separate markdown files
- ✅ Type-Safe: Full TypeScript implementation with Zod validation
- ✅ Extensible: Easy to add new output formats
# Install dependencies (use npm or pnpm)
npm install
# Build the project (optional - tsx runs TypeScript directly)
npm run buildapi-guidelines/
├── src/
│ ├── guidelines/ # Source of truth - YAML files
│ │ ├── naming.yaml
│ │ └── versioning.yaml
│ ├── content/ # Detailed markdown content
│ │ ├── naming-conventions.md
│ │ └── versioning.md
│ ├── spectral-rules/ # Optional external Spectral rules
│ │ └── versioning.yaml
│ ├── types/ # TypeScript types and schemas
│ ├── generators/ # Output generators
│ ├── utils/ # Loader and validator utilities
│ └── cli.ts # CLI entry point
├── dist/ # Generated outputs (gitignored)
└── package.json
npm run generateThis generates:
dist/api-guidelines.md- Full documentation with examplesdist/api-reference.md- Quick reference by severitydist/.spectral.yaml- Spectral ruleset
npm run generate:docs # Full documentation only
npm run generate:reference # Reference guide only
npm run generate:spectral # Spectral ruleset onlynpm run validateValidates all guideline YAML files without generating outputs.
# Human-readable list
npx tsx src/cli.ts list
# JSON output
npx tsx src/cli.ts list --jsonGuidelines are defined in YAML files in the src/guidelines/ directory.
guidelines:
- id: pzu:rest5:2025-general-naming-conventions
title: Ogólne Zasady Nazewnictwa
category: naming
content: ../content/naming-conventions.md
rules:
- level: must
text: Identyfikator MUSI być zapisany małymi literami
- level: must
text: Identyfikator MUSI używać konwencji camelCase dla złożonych słów
- level: should-not
text: Identyfikator NIE POWINIEN zawierać akronimów biznesowych
spectral:
# ... spectral rule definitionFollowing RFC 2119:
must- Required (Spectral: error)must-not- Prohibited (Spectral: error)should- Recommended (Spectral: warn)should-not- Not recommended (Spectral: warn)may- Optional (Spectral: info)
Define Spectral rules directly in the guideline file:
spectral:
description: "Each JSON property identifier SHOULD be written in camelCase"
message: "Property identifier '{{property}}' SHOULD be in camelCase"
severity: warn
given:
- $.components..properties[*]~
- $.paths[*][*].responses[*].content[*].schema..properties[*]~
then:
function: pattern
functionOptions:
match: "^(_link|_?[a-z]+([A-Z][a-z]+)*)$"Reference an external Spectral rule file:
spectral:
external: ../spectral-rules/versioning.yaml#pzu:rest5:2025-api-versioningThe external file should contain standard Spectral rule format:
# src/spectral-rules/versioning.yaml
pzu:rest5:2025-api-versioning:
description: "API paths MUST include version number"
message: "API path '{{path}}' MUST include version (e.g., /v1/)"
severity: error
given:
- $.paths[*]~
then:
function: pattern
functionOptions:
match: "^/v[0-9]+/"Detailed explanations, examples, and rationale are stored in separate markdown files in src/content/. These files are referenced from guideline YAML files.
Example structure:
#### Detailed Explanation
Proper naming conventions ensure consistency...
#### Examples
**Good Examples:**
\`\`\`json
{
"userId": "12345",
"firstName": "Jan"
}
\`\`\`
#### Rationale
- Consistency: Uniform naming makes APIs easier to learn
- Developer Experience: camelCase is widely adoptedtsx src/cli.ts generate [options]
Options:
-t, --type <type> Type: docs, reference, spectral, or all (default: "all")
-s, --source <dir> Source directory (default: "src/guidelines")
-o, --output <dir> Output directory (default: "dist")tsx src/cli.ts validate [options]
Options:
-s, --source <dir> Source directory (default: "src/guidelines")tsx src/cli.ts list [options]
Options:
-s, --source <dir> Source directory (default: "src/guidelines")
--json Output as JSONnpm run devRuns the CLI in watch mode, automatically reloading on file changes.
- Create a YAML file in
src/guidelines/(or use existing) - Define the guideline with id, title, category, rules
- Create corresponding content file in
src/content/ - Optionally add Spectral rule (inline or external)
- Run
npm run validateto check for errors - Run
npm run generateto create outputs
- Create a new generator in
src/generators/ - Implement the generation logic
- Add command option in
src/cli.ts - Update package.json scripts
The architecture supports future enhancements:
- New output formats: Add generators (HTML, JSON, Docusaurus, etc.)
- API documentation sites: Generate static site configs
- IDE plugins: Export as JSON for tooling integration
- Custom validation: Add business-specific validators
- Interactive docs: Generate searchable web interfaces
All types are defined in src/types/guideline.ts with Zod schemas for runtime validation:
Guideline- Main guideline structureGuidelineRule- Individual ruleSpectralRuleInline- Inline Spectral definitionSpectralRuleExternal- External Spectral referenceSeverity- RFC 2119 severity levels
MIT
- Create guideline files following the schema
- Validate with
pnpm validate - Generate outputs with
pnpm generate - Test the generated files
- Commit source files only (dist/ is gitignored)