metacoding
Version:
Guided Development Workflow for GitHub Copilot - Transform your coding experience with AI-guided standards, structured workflows, and quality practices
735 lines (671 loc) • 17.9 kB
Markdown
---
description: 'TypeScript/Node.js-specific documentation standards and JSDoc patterns'
applyTo: '**/*.{ts,js}'
language: 'typescript'
---
# TypeScript/Node.js Documentation Standards
## JSDoc Documentation Standards
### Function Documentation
````typescript
/**
* Retrieves user information by ID with caching support.
*
* This function first checks the cache for existing user data before
* making a database query. If the user is not found in cache, it queries
* the database and stores the result in cache for future requests.
*
* @param userId - The unique identifier for the user
* @param options - Configuration options for the retrieval
* @param options.useCache - Whether to use cached data if available (default: true)
* @param options.cacheTimeout - Cache timeout in milliseconds (default: 300000)
* @returns Promise that resolves to user data or null if not found
*
* @throws {ValidationError} When userId format is invalid
* @throws {DatabaseConnectionError} When database connection fails
*
* @example
* ```typescript
* // Basic usage
* const user = await getUserById('123');
*
* // With options
* const user = await getUserById('123', {
* useCache: false,
* cacheTimeout: 600000
* });
*
* // Error handling
* try {
* const user = await getUserById('invalid-id');
* } catch (error) {
* if (error instanceof ValidationError) {
* console.log('Invalid user ID format');
* }
* }
* ```
*
* @since 1.2.0
* @see {@link User} for user data structure
* @see {@link UserRepository.findById} for underlying database query
*/
async function getUserById(
userId: string,
options: GetUserOptions = {}
): Promise<User | null> {
// Implementation here
}
````
### Class Documentation
````typescript
/**
* Service for managing user data with caching and validation.
*
* The UserService provides a high-level interface for user operations,
* including automatic caching, input validation, and error handling.
* All operations are logged for debugging and monitoring purposes.
*
* @example
* ```typescript
* const userService = new UserService({
* repository: new UserRepository(database),
* cache: new RedisCache(),
* logger: new Logger('UserService')
* });
*
* // Create a new user
* const user = await userService.createUser({
* name: 'John Doe',
* email: 'john@example.com'
* });
*
* // Retrieve user with caching
* const foundUser = await userService.getUserById(user.id);
* ```
*
* @public
* @since 1.0.0
*/
export class UserService {
/**
* User repository for database operations.
* @private
*/
private readonly repository: UserRepository;
/**
* Cache instance for storing frequently accessed user data.
* @private
*/
private readonly cache: CacheService;
/**
* Logger instance for service operations.
* @private
*/
private readonly logger: Logger;
/**
* Creates a new UserService instance.
*
* @param dependencies - Service dependencies
* @param dependencies.repository - Repository for user data persistence
* @param dependencies.cache - Cache service for performance optimization
* @param dependencies.logger - Logger for operation tracking
*
* @throws {Error} When required dependencies are not provided
*/
constructor(dependencies: UserServiceDependencies) {
if (!dependencies.repository) {
throw new Error('UserRepository is required');
}
this.repository = dependencies.repository;
this.cache = dependencies.cache;
this.logger = dependencies.logger || new NullLogger();
}
/**
* Creates a new user with validation and duplicate checking.
*
* @param userData - Data for the new user
* @returns Promise resolving to the created user with generated ID
*
* @throws {ValidationError} When user data is invalid
* @throws {DuplicateEmailError} When email already exists
*
* @example
* ```typescript
* const newUser = await userService.createUser({
* name: 'Jane Doe',
* email: 'jane@example.com',
* preferences: { theme: 'dark' }
* });
* ```
*/
async createUser(userData: CreateUserData): Promise<User> {
// Implementation here
}
}
````
### Interface and Type Documentation
````typescript
/**
* Configuration options for user retrieval operations.
*
* @public
*/
export interface GetUserOptions {
/**
* Whether to use cached data if available.
* @defaultValue true
*/
useCache?: boolean;
/**
* Cache timeout in milliseconds.
* @defaultValue 300000 (5 minutes)
*/
cacheTimeout?: number;
/**
* Additional fields to include in the response.
* @defaultValue []
*/
includeFields?: Array<'preferences' | 'metadata' | 'lastLogin'>;
}
/**
* User data structure returned by the API.
*
* @example
* ```typescript
* const user: User = {
* id: '123e4567-e89b-12d3-a456-426614174000',
* name: 'John Doe',
* email: 'john@example.com',
* createdAt: new Date('2023-01-01T00:00:00Z'),
* updatedAt: new Date('2023-06-01T12:00:00Z'),
* isActive: true,
* preferences: {
* theme: 'dark',
* notifications: true
* }
* };
* ```
*
* @public
*/
export interface User {
/** Unique identifier for the user (UUID v4 format) */
id: string;
/** Full name of the user */
name: string;
/**
* Email address (unique across all users)
* @format email
*/
email: string;
/** Timestamp when the user was created */
createdAt: Date;
/** Timestamp when the user was last updated */
updatedAt: Date;
/**
* Whether the user account is active
* @defaultValue true
*/
isActive: boolean;
/**
* User preferences and settings
* @optional
*/
preferences?: UserPreferences;
}
/**
* Discriminated union type for different user roles.
*
* @example
* ```typescript
* function handleUser(user: UserRole) {
* switch (user.type) {
* case 'admin':
* // user.permissions is available here
* console.log('Admin permissions:', user.permissions);
* break;
* case 'member':
* // user.membershipLevel is available here
* console.log('Membership level:', user.membershipLevel);
* break;
* case 'guest':
* // user.expiresAt is available here
* console.log('Guest expires at:', user.expiresAt);
* break;
* }
* }
* ```
*/
export type UserRole =
| { type: 'admin'; permissions: string[] }
| { type: 'member'; membershipLevel: 'basic' | 'premium' }
| { type: 'guest'; expiresAt: Date };
````
### Error Class Documentation
````typescript
/**
* Error thrown when user validation fails.
*
* This error includes detailed information about which validation
* rules failed and can be used to provide specific feedback to users.
*
* @example
* ```typescript
* try {
* await userService.createUser(invalidData);
* } catch (error) {
* if (error instanceof ValidationError) {
* console.log('Validation failed:', error.details);
* error.details.forEach(detail => {
* console.log(`${detail.field}: ${detail.message}`);
* });
* }
* }
* ```
*
* @public
*/
export class ValidationError extends Error {
/**
* Detailed information about validation failures.
* Each entry contains the field name and specific error message.
*/
public readonly details: ValidationDetail[];
/**
* Error code for programmatic handling.
* @defaultValue 'VALIDATION_ERROR'
*/
public readonly code: string = 'VALIDATION_ERROR';
/**
* Creates a new ValidationError.
*
* @param message - High-level error message
* @param details - Specific validation failure details
*/
constructor(message: string, details: ValidationDetail[]) {
super(message);
this.name = 'ValidationError';
this.details = details;
}
/**
* Returns a formatted string of all validation errors.
*
* @returns Multi-line string with each validation error on a separate line
*/
getFormattedDetails(): string {
return this.details
.map((detail) => `${detail.field}: ${detail.message}`)
.join('\n');
}
}
````
### Module and Namespace Documentation
````typescript
/**
* @fileoverview User management utilities and services.
*
* This module provides a comprehensive set of tools for managing user data,
* including validation, caching, and database operations. It follows the
* repository pattern for data access and includes extensive error handling.
*
* @example
* ```typescript
* import { UserService, ValidationError } from './user-module';
*
* const userService = new UserService(dependencies);
*
* try {
* const user = await userService.createUser(userData);
* console.log('User created:', user.id);
* } catch (error) {
* if (error instanceof ValidationError) {
* console.error('Validation failed:', error.getFormattedDetails());
* }
* }
* ```
*
* @author Development Team <dev@example.com>
* @since 1.0.0
* @version 2.1.0
*/
/**
* Namespace containing user-related utility functions.
*
* @namespace UserUtils
*/
export namespace UserUtils {
/**
* Validates email format using RFC 5322 compliant regex.
*
* @param email - Email address to validate
* @returns True if email format is valid
*
* @example
* ```typescript
* if (UserUtils.isValidEmail('user@example.com')) {
* console.log('Valid email format');
* }
* ```
*/
export function isValidEmail(email: string): boolean {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
/**
* Generates a display name from user data.
*
* @param user - User object
* @returns Formatted display name
*
* @internal
*/
export function getDisplayName(user: Pick<User, 'name' | 'email'>): string {
return user.name || user.email.split('@')[0];
}
}
````
### API Route Documentation
````typescript
/**
* @fileoverview User API routes and handlers.
*
* This module defines REST API endpoints for user management operations.
* All endpoints require authentication except for user registration.
*
* @version 2.0.0
*/
import { Router, Request, Response } from 'express';
/**
* User-related API endpoints.
*
* @example
* ```typescript
* import express from 'express';
* import { userRoutes } from './routes/user-routes';
*
* const app = express();
* app.use('/api/users', userRoutes);
* ```
*/
export const userRoutes = Router();
/**
* GET /api/users/:id - Retrieve user by ID.
*
* @route GET /api/users/:id
* @param {string} id - User ID (UUID format)
* @returns {User} User object if found
* @returns {404} Not found if user doesn't exist
* @returns {400} Bad request if ID format is invalid
*
* @example
* ```bash
* curl -X GET /api/users/123e4567-e89b-12d3-a456-426614174000 \
* -H "Authorization: Bearer YOUR_TOKEN"
* ```
*
* @example Response
* ```json
* {
* "id": "123e4567-e89b-12d3-a456-426614174000",
* "name": "John Doe",
* "email": "john@example.com",
* "createdAt": "2023-01-01T00:00:00.000Z",
* "isActive": true
* }
* ```
*/
userRoutes.get('/:id', async (req: Request, res: Response) => {
// Implementation here
});
/**
* POST /api/users - Create a new user.
*
* @route POST /api/users
* @param {CreateUserData} body - User data for creation
* @returns {User} Created user object with generated ID
* @returns {400} Bad request if validation fails
* @returns {409} Conflict if email already exists
*
* @example Request Body
* ```json
* {
* "name": "Jane Doe",
* "email": "jane@example.com",
* "preferences": {
* "theme": "dark",
* "notifications": true
* }
* }
* ```
*/
userRoutes.post('/', async (req: Request, res: Response) => {
// Implementation here
});
````
### Configuration and Constants Documentation
````typescript
/**
* @fileoverview Application configuration and constants.
*
* This module contains all configuration values and constants used
* throughout the application. Values are loaded from environment
* variables with sensible defaults for development.
*/
/**
* Database configuration settings.
*
* @example
* ```typescript
* import { DatabaseConfig } from './config';
*
* const connection = new DatabaseConnection(DatabaseConfig);
* ```
*/
export const DatabaseConfig = {
/**
* Database connection URL.
* @env DATABASE_URL
* @defaultValue 'postgresql://localhost:5432/myapp_dev'
*/
url: process.env.DATABASE_URL || 'postgresql://localhost:5432/myapp_dev',
/**
* Maximum number of database connections in pool.
* @env DB_POOL_SIZE
* @defaultValue 10
*/
poolSize: parseInt(process.env.DB_POOL_SIZE || '10', 10),
/**
* Connection timeout in milliseconds.
* @env DB_TIMEOUT
* @defaultValue 30000
*/
timeout: parseInt(process.env.DB_TIMEOUT || '30000', 10),
} as const;
/**
* User validation constants.
*
* These constants define the validation rules for user data
* and are used throughout the application for consistency.
*/
export const UserValidation = {
/** Minimum length for user names */
NAME_MIN_LENGTH: 2,
/** Maximum length for user names */
NAME_MAX_LENGTH: 100,
/** Maximum length for email addresses */
EMAIL_MAX_LENGTH: 254,
/** Regex pattern for valid email format */
EMAIL_PATTERN: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
/** List of reserved usernames that cannot be used */
RESERVED_NAMES: ['admin', 'root', 'system', 'api'] as const,
} as const;
````
## Node.js Specific Documentation
### Process and Environment Documentation
````typescript
/**
* @fileoverview Process management and graceful shutdown handling.
*
* This module handles process lifecycle events and ensures graceful
* shutdown of the application with proper cleanup of resources.
*/
/**
* Graceful shutdown manager for Node.js applications.
*
* Handles SIGINT and SIGTERM signals to ensure clean shutdown
* with proper cleanup of database connections, file handles, and
* other resources.
*
* @example
* ```typescript
* const shutdownManager = new GracefulShutdown();
*
* shutdownManager.addHandler('database', async () => {
* await database.disconnect();
* });
*
* shutdownManager.addHandler('server', async () => {
* await server.close();
* });
*
* shutdownManager.start();
* ```
*/
export class GracefulShutdown {
/**
* Map of cleanup handlers by name.
* @private
*/
private handlers = new Map<string, () => Promise<void>>();
/**
* Whether shutdown process has started.
* @private
*/
private isShuttingDown = false;
/**
* Adds a cleanup handler for a named resource.
*
* @param name - Unique name for the handler
* @param handler - Async function to clean up the resource
*
* @throws {Error} If handler name already exists
*/
addHandler(name: string, handler: () => Promise<void>): void {
if (this.handlers.has(name)) {
throw new Error(`Handler '${name}' already exists`);
}
this.handlers.set(name, handler);
}
}
````
### Stream Documentation
````typescript
/**
* Custom transform stream for processing large datasets.
*
* This stream processes data in chunks to handle large files
* efficiently without loading everything into memory at once.
*
* @example
* ```typescript
* import fs from 'fs';
* import { DataProcessor } from './data-processor';
*
* const processor = new DataProcessor({
* batchSize: 1000,
* transform: (chunk) => chunk.toUpperCase()
* });
*
* fs.createReadStream('input.txt')
* .pipe(processor)
* .pipe(fs.createWriteStream('output.txt'));
* ```
*/
export class DataProcessor extends Transform {
/**
* Number of items to process in each batch.
* @private
*/
private readonly batchSize: number;
/**
* Function to transform each data chunk.
* @private
*/
private readonly transformFn: (chunk: string) => string;
/**
* Creates a new DataProcessor stream.
*
* @param options - Processor configuration
* @param options.batchSize - Number of items per batch
* @param options.transform - Function to transform each chunk
*/
constructor(options: DataProcessorOptions) {
super({ objectMode: true });
this.batchSize = options.batchSize || 100;
this.transformFn = options.transform || ((x) => x);
}
}
````
## README and Package Documentation
### Package.json Documentation Guidelines
```json
{
"name": "user-management-service",
"version": "2.1.0",
"description": "Comprehensive user management service with caching, validation, and REST API",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc",
"test": "jest",
"test:coverage": "jest --coverage",
"test:watch": "jest --watch",
"lint": "eslint src/**/*.ts",
"lint:fix": "eslint src/**/*.ts --fix",
"start": "node dist/index.js",
"dev": "ts-node src/index.ts",
"docs": "typedoc src --out docs"
},
"keywords": [
"user-management",
"authentication",
"rest-api",
"typescript",
"caching"
],
"author": "Your Name <your.email@example.com>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/username/user-management-service.git"
},
"bugs": {
"url": "https://github.com/username/user-management-service/issues"
},
"homepage": "https://github.com/username/user-management-service#readme"
}
```
### TypeDoc Configuration
```javascript
// typedoc.json
{
"entryPoints": ["src/index.ts"],
"out": "docs",
"excludePrivate": true,
"excludeProtected": false,
"excludeInternal": false,
"categorizeByGroup": true,
"sort": ["source-order"],
"kindSortOrder": [
"Module",
"Namespace",
"Enum",
"Class",
"Interface",
"Function",
"Variable"
],
"theme": "default",
"readme": "README.md",
"includeVersion": true
}
```