Complete guide for setting up a local development environment for APIDoc, contributing to the project, and customizing functionality.
# Clone the repository
git clone https://github.com/hrefcl/apidoc.git
cd apidoc
# Install dependencies
npm install
# Verify installation
npm run typecheck
npm run test:lint
apidoc/
โโโ bin/ # CLI executable
โ โโโ apidoc # Main CLI script
โโโ lib/ # TypeScript source code
โ โโโ core/ # Core logic
โ โ โโโ parsers/ # Comment parsers
โ โ โโโ workers/ # Data processors
โ โ โโโ filters/ # Output filters
โ โ โโโ languages/ # Language support
โ โ โโโ errors/ # Error classes
โ โโโ index.ts # Main library entry
โ โโโ reader.ts # File reading logic
โ โโโ writer.ts # Output generation
โโโ template/ # HTML templates
โ โโโ src/ # TypeScript/CSS source
โ โ โโโ main.ts # Main JavaScript
โ โ โโโ css/ # CSS styles
โ โโโ index.html # Main template
โโโ example/ # Example API for testing
โโโ test/ # Test suite
โโโ md/ # Project documentation
โโโ dist/ # Compiled output
โโโ tmp/ # Temporary build files
โโโ package.json # npm configuration and scripts
โโโ tsconfig.json # TypeScript configuration
โโโ eslint.config.js # ESLint configuration
โโโ typedoc.json # TypeDoc configuration
โโโ .gitignore # Git ignored files
โโโ .github/ # GitHub Actions workflows
โโโ workflows/
โโโ test.yml # Automated tests
โโโ release.yml # Release pipeline
# TypeScript compilation
npm run build # Compile TypeScript + Stencil
npm run typecheck # Type checking only
npm run dev # Watch mode for development
# Documentation generation
npm run build:example # Generate example documentation
npm run docs # Generate TypeDoc documentation
npm run docs:serve # Serve docs at http://localhost:3001
# Template development
npm run dev:template # Build example + server on port 8080
npm run start # Serve generated documentation
# Quality Assurance
npm run test # Run test suite
npm run test:lint # ESLint + spell check
npm run test:fix # Auto-fix ESLint issues
npm run pre-commit # Complete validation (types + lint + tests)
# Container workflows
npm run serve # Build, containerize and serve with auto-open
npm run serve:stop # Stop container
# CSS and styles
npm run build:css # Compile CSS for production
npm run build:css:dev # CSS for local development
# Cleanup
npm run clean # Clean build directories
npm run clean:all # Complete cleanup + node_modules
# Release
npm run version:patch # Increment patch version
npm run version:minor # Increment minor version
npm run version:major # Increment major version
# Run all tests
npm run test
# Specific tests
npm test -- --grep "parser" # Only parser tests
npm test -- --grep "MQTT" # Only MQTT tests
npm test -- test/core/parser.test.js # Specific file
# Coverage
npm run test:coverage # Generate coverage report
test/
โโโ core/ # Core tests
โ โโโ parsers/ # Parser tests
โ โโโ workers/ # Worker tests
โ โโโ filters/ # Filter tests
โโโ integration/ # Integration tests
โโโ fixtures/ # Test data
โโโ helpers/ # Testing utilities
// test/core/parsers/api.test.js
import { describe, it } from 'mocha';
import { expect } from 'chai';
import { parseApi } from '../../../lib/core/parsers/api.js';
describe('API Parser', () => {
it('should parse basic API definition', () => {
const content = '{get} /users Get Users';
const result = parseApi(content);
expect(result).to.have.property('method', 'get');
expect(result).to.have.property('url', '/users');
expect(result).to.have.property('title', 'Get Users');
});
it('should handle complex URLs with parameters', () => {
const content = '{post} /users/:id/posts Create User Post';
const result = parseApi(content);
expect(result.url).to.equal('/users/:id/posts');
expect(result.method).to.equal('post');
});
});
// lib/core/parsers/my-new-parser.ts
export function parseMyNewTag(content: string): any {
// 1. Define regex for parsing
const regex = /^(.+?)\s+(.+)$/;
const match = content.match(regex);
if (!match) {
throw new Error('Invalid format for @myNewTag');
}
// 2. Extract data
const [, type, description] = match;
// 3. Return normalized object
return {
type: type.trim(),
description: description.trim()
};
}
// lib/core/parsers/index.ts
import { parseMyNewTag } from './my-new-parser.js';
export const parsers = {
// ... existing parsers
mynew: parseMyNewTag
};
// test/core/parsers/my-new-parser.test.js
describe('My New Parser', () => {
it('should parse custom tag correctly', () => {
const result = parseMyNewTag('string User description');
expect(result.type).to.equal('string');
expect(result.description).to.equal('User description');
});
});
template/
โโโ src/
โ โโโ main.ts # Main JavaScript
โ โโโ css/
โ โ โโโ tailwind.css # TailwindCSS styles
โ โ โโโ bootstrap.css # Bootstrap styles
โ โโโ components/ # Stencil components
โโโ assets/ # Static assets
โโโ index.html # Main template
โโโ stencil.config.ts # Stencil configuration
// template/src/components/api-endpoint.tsx
import { Component, Prop, h } from '@stencil/core';
@Component({
tag: 'api-endpoint',
styleUrl: 'api-endpoint.css',
shadow: true
})
export class ApiEndpoint {
@Prop() method: string;
@Prop() url: string;
@Prop() title: string;
render() {
return (
<div class={`endpoint endpoint-${this.method}`}>
<span class="method">{this.method.toUpperCase()}</span>
<span class="url">{this.url}</span>
<span class="title">{this.title}</span>
</div>
);
}
}
# Development with hot reload
npm run dev:template
# Production build
npm run build:template
# Fork the repository on GitHub
git clone https://github.com/your-username/apidoc.git
cd apidoc
# Configure upstream
git remote add upstream https://github.com/hrefcl/apidoc.git
# Install dependencies
npm install
# Verify everything works
npm run pre-commit
# Create and switch to new branch
git checkout -b feature/my-new-feature
# Or for bugfix
git checkout -b fix/fix-some-issue
# Iterative development
npm run dev # Watch mode
npm run build:example # Test changes
npm run test # Run tests
# Continuous validation
npm run typecheck # Check types
npm run test:lint # Linting
# Staging and commit
git add .
git commit -m "feat: add support for new parser"
# Push to your fork
git push origin feature/my-new-feature
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug APIDoc",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/bin/apidoc",
"args": [
"-i", "example/",
"-o", "tmp/debug/",
"--debug"
],
"env": {
"NODE_ENV": "development"
},
"console": "integratedTerminal",
"sourceMaps": true
}
]
}
// lib/utils/logger.ts
export const logger = {
debug: (message: string, data?: any) => {
if (process.env.NODE_ENV === 'development') {
console.log(`[DEBUG] ${message}`, data || '');
}
},
info: (message: string) => {
console.log(`[INFO] ${message}`);
},
error: (message: string, error?: Error) => {
console.error(`[ERROR] ${message}`, error || '');
}
};
# Complete build
npm run build
# Verify build
npm run test
npm run typecheck
# Local distribution test
npm pack
npm install -g ./apidoc-*.tgz
// package.json
{
"scripts": {
"release:patch": "npm version patch && npm publish",
"release:minor": "npm version minor && npm publish",
"release:major": "npm version major && npm publish"
}
}
The APIDoc development environment is designed to be accessible and productive, enabling effective contributions to the project.