UNPKG

@gohcltech/bitbucket-mcp

Version:

Bitbucket integration for Claude via Model Context Protocol

239 lines 9.57 kB
/** * @fileoverview Common types and schemas shared across all domain modules. * * This module contains: * - Error classes for different failure scenarios * - Pagination interfaces used by all API responses * - Configuration schemas for server and OAuth settings * - Utility functions for validation and sanitization * - Common validation patterns used across domains * */ import { z } from 'zod'; // ============================================================================= // ERROR CLASSES // ============================================================================= /** * Error thrown when input validation fails. * Contains detailed information about validation failures for debugging. */ export class ValidationError extends Error { details; constructor(message, details) { super(message); this.details = details; this.name = 'ValidationError'; } } /** * Error thrown when authentication fails or tokens are invalid. * Indicates that the user needs to re-authenticate or refresh tokens. */ export class AuthenticationError extends Error { constructor(message) { super(message); this.name = 'AuthenticationError'; } } /** * Error thrown when API rate limits are exceeded. * Includes retry-after information when available from the API. */ export class RateLimitError extends Error { retryAfter; constructor(message, retryAfter) { super(message); this.retryAfter = retryAfter; this.name = 'RateLimitError'; } } /** * Error thrown when Bitbucket API requests fail. * Contains HTTP status code and response data for debugging. */ export class BitbucketApiError extends Error { statusCode; response; constructor(message, statusCode, response) { super(message); this.statusCode = statusCode; this.response = response; this.name = 'BitbucketApiError'; } } // ============================================================================= // CONFIGURATION SCHEMAS // ============================================================================= /** * Schema for logging configuration parameters. * Defines options for multiple output destinations and logging behavior. */ export const LoggingConfigSchema = z.object({ /** Enable real-time web log viewer */ enableLogViewer: z.boolean().default(true), /** Enable console logging output */ enableConsoleLogging: z.boolean().default(true), /** Enable file logging output */ enableFileLogging: z.boolean().default(false), /** Path for log file when file logging is enabled */ logFilePath: z.string().default('./logs/bitbucket-mcp.log'), /** Maximum number of log entries to keep in memory for web viewer */ logViewerMaxEntries: z.number().int().min(10).default(1000), /** Enable structured logging with additional metadata */ enableStructuredLogging: z.boolean().default(true), }); /** * Schema for server configuration parameters. * Defines valid ranges and defaults for server operation settings. */ export const ServerConfigSchema = z.object({ /** Application version (loaded dynamically from package.json) */ version: z.string().default('unknown'), /** Server port number (1-65535) */ port: z.number().int().min(1).max(65535).default(3000), /** Logging level for server operations */ logLevel: z.enum(['error', 'warn', 'info', 'debug']).default('info'), /** Logging configuration for multiple output destinations */ logging: LoggingConfigSchema.default({}), /** Rate limiting configuration to respect API quotas using token bucket algorithm */ rateLimit: z.object({ /** Maximum concurrent requests to prevent overwhelming the API */ maxConcurrent: z.number().int().min(1).default(10), /** Minimum time between requests in milliseconds to throttle request rate */ minTime: z.number().int().min(0).default(100), /** Request reservoir size - initial number of tokens available for burst requests */ reservoir: z.number().int().min(1).default(100), /** Amount to refill reservoir - tokens added during each refresh interval */ reservoirRefreshAmount: z.number().int().min(1).default(100), /** Reservoir refresh interval in milliseconds - how often tokens are replenished */ reservoirRefreshInterval: z.number().int().min(1000).default(60000), }).default({}), /** Optional encrypted token storage configuration */ tokenStorage: z.object({ /** Encryption key (minimum 32 characters for security) */ encryptionKey: z.string().min(32, 'Encryption key must be at least 32 characters'), /** File path for encrypted token storage */ filePath: z.string().default('./tokens.enc'), }).optional(), /** Pull request configuration options */ pullRequest: z.object({ /** Automatically close source branch when PR is merged (default: true) */ autoCloseBranchOnMerge: z.boolean().default(true), }).default({}), }); // ============================================================================= // TOKEN SCHEMAS // ============================================================================= /** * Schema for OAuth token data persistence. * Defines the structure for storing authentication tokens securely. */ export const TokenDataSchema = z.object({ /** OAuth 2.0 access token */ accessToken: z.string(), /** Optional refresh token for automatic renewal */ refreshToken: z.string().optional(), /** Token expiration timestamp (milliseconds since epoch) */ expiresAt: z.number().optional(), /** Token type (typically 'Bearer') */ tokenType: z.string().default('Bearer'), }); // ============================================================================= // OAUTH CONFIGURATION SCHEMAS // ============================================================================= // NOTE: OAuth configuration schemas have been removed as part of v2.0 // architecture simplification. Old schemas that were removed: // - BitbucketOAuthConfigSchema // - EnhancedBitbucketOAuthConfigSchema // // These have been replaced with token-based authentication in src/types.ts: // - AuthMethod enum // - ApiTokenAuth schema // - RepositoryTokenAuth schema // - AuthConfig discriminated union // // See src/types.ts for new authentication types. // ============================================================================= // COMMON VALIDATION PATTERNS // ============================================================================= /** * Common regex patterns for validating Bitbucket identifiers. */ export const ValidationPatterns = { /** Workspace slug validation (alphanumeric, hyphens, underscores) */ workspace: /^[a-zA-Z0-9_-]+$/, /** Repository slug validation (alphanumeric, hyphens, underscores, dots) */ repository: /^[a-zA-Z0-9_.-]+$/, /** Commit hash validation (40 character hexadecimal) */ commitHash: /^[a-f0-9]{40}$/, /** Branch name validation (general git branch naming rules) */ branchName: /^[a-zA-Z0-9][a-zA-Z0-9._/-]*[a-zA-Z0-9]$|^[a-zA-Z0-9]$/, }; /** * Base schema for workspace-related operations. */ export const WorkspaceBaseSchema = z.object({ workspace: z.string() .min(1, 'Workspace is required') .regex(ValidationPatterns.workspace, 'Invalid workspace format'), }); /** * Base schema for repository-related operations. */ export const RepositoryBaseSchema = WorkspaceBaseSchema.extend({ repo_slug: z.string() .min(1, 'Repository slug is required') .regex(ValidationPatterns.repository, 'Invalid repository slug format'), }); // ============================================================================= // UTILITY FUNCTIONS // ============================================================================= /** * Validates input against a Zod schema and throws detailed error on failure. * * @template T - The expected type after validation * @param schema - Zod schema to validate against * @param input - Input data to validate * @returns Validated and typed data * @throws {ValidationError} If validation fails with detailed error information */ export function validateInput(schema, input) { try { return schema.parse(input); } catch (error) { if (error instanceof z.ZodError) { const errorMessage = error.errors.map(err => `${err.path.join('.')}: ${err.message}`).join(', '); throw new ValidationError(`Validation failed: ${errorMessage}`, error.errors); } throw error; } } /** * Sanitizes string input to prevent injection attacks and limit length. * * @param input - String to sanitize * @returns Sanitized string safe for processing */ export function sanitizeString(input) { return input .replace(/[<>"'&]/g, '') // Remove HTML/script injection characters .trim() .substring(0, 1000); // Limit length } // ============================================================================= // TYPE GUARD FUNCTIONS // ============================================================================= /** * Type guard to check if input matches workspace input schema. */ export function isWorkspaceInput(input) { return WorkspaceBaseSchema.safeParse(input).success; } /** * Type guard to check if input matches repository input schema. */ export function isRepositoryInput(input) { return RepositoryBaseSchema.safeParse(input).success; } //# sourceMappingURL=common.js.map