UNPKG

@gohcltech/bitbucket-mcp

Version:

Bitbucket integration for Claude via Model Context Protocol

396 lines 14.9 kB
/** * @fileoverview Zod validation schemas for Bitbucket branch operations. * * This module provides comprehensive validation schemas for branch-related * operations using Zod for runtime type checking and validation. These schemas * ensure that data conforms to Bitbucket API v2.0 specifications and provide * type-safe validation for MCP tool inputs and API responses. * * Key features: * - Runtime validation of branch API responses * - Branching model and Git Flow configuration validation * - Branch protection and permissions schema validation * - Default reviewer assignment rule validation * - Input parameter validation for branch management tools * - Type-safe schema definitions matching TypeScript interfaces */ import { z } from 'zod'; import { RepositoryBaseSchema } from '../common.js'; // ============================================================================= // RESPONSE SCHEMAS // ============================================================================= /** * Zod schema for validating Bitbucket branch API responses. * * This schema validates the structure of branch objects returned by * Bitbucket's REST API v2.0. It ensures that all required fields are present * and correctly typed, including commit metadata and navigation links. * * The schema uses `satisfies z.ZodType<Branch>` to guarantee that the * validation schema matches the TypeScript interface exactly. * * @example * ```typescript * const apiResponse = await fetch('/2.0/repositories/gohcl/bitbucket-mcp/refs/branches/feature/auth'); * const rawData = await apiResponse.json(); * const branch = BranchSchema.parse(rawData); * ``` */ export const BranchSchema = z.object({ /** * Branch name following git naming conventions. * Must be a non-empty string with valid git branch name format. */ name: z.string().min(1, 'Branch name is required') .max(100, 'Branch name too long') .regex(/^[a-zA-Z0-9][a-zA-Z0-9._/-]*[a-zA-Z0-9]$|^[a-zA-Z0-9]$/, 'Invalid branch name format'), /** * Target commit information that this branch points to. * Contains comprehensive metadata about the HEAD commit. */ target: z.object({ /** * SHA-1 hash of the target commit. * Must be a 40-character hexadecimal string. */ hash: z.string().length(40, 'Commit hash must be 40 characters') .regex(/^[a-f0-9]{40}$/, 'Invalid commit hash format'), /** * ISO 8601 timestamp when the commit was created. * Must be a valid datetime string with timezone information. */ date: z.string().datetime('Invalid commit date format'), /** * Commit author information. * May contain user details if author is a registered Bitbucket user. */ author: z.object({ /** * Optional Bitbucket user information for the commit author. * Present only if author email matches a registered user. */ user: z.object({ /** Display name of the commit author */ display_name: z.string().min(1, 'Author display name is required'), /** Unique UUID for the author's user account */ uuid: z.string().min(1, 'Author UUID is required'), }).optional(), }), /** * Commit message describing the changes. * Contains the full commit message including title and body. */ message: z.string(), }), /** * Collection of related URLs for the branch. * Provides navigation links to commits and web interface. */ links: z.object({ /** * API endpoint for commits on this branch. * Links to the filtered commits API for this branch. */ commits: z.object({ /** Full URL to the branch's commits API endpoint */ href: z.string().url('Invalid commits link'), }), /** * Web interface link to the branch page. * Opens the branch view in Bitbucket's web interface. */ html: z.object({ /** Full URL to the branch page in Bitbucket */ href: z.string().url('Invalid branch HTML link'), }), }), }); /** * Zod schema for validating Bitbucket branching model API responses. * * This schema validates the structure of branching model configurations that * define Git Flow, GitHub Flow, or custom branching strategies. It includes * validation for development/production branch settings and branch type * configurations with their naming prefixes. * * The schema accommodates the flexible nature of branching models where * most fields are optional depending on the strategy type. * * @example * ```typescript * const apiResponse = await fetch('/2.0/repositories/gohcl/bitbucket-mcp/branching-model'); * const rawData = await apiResponse.json(); * const model = BranchingModelSchema.parse(rawData); * ``` */ export const BranchingModelSchema = z.object({ /** * Type of branching workflow strategy. * Defines the overall branching strategy used by the repository. */ type: z.enum(['git_flow', 'github_flow', 'custom'], { errorMap: () => ({ message: 'Must be git_flow, github_flow, or custom' }) }).optional(), /** * Development branch configuration. * Defines the primary development branch for ongoing work. */ development: z.object({ /** * Name of the development branch. * Must be a valid git branch name. */ name: z.string().min(1, 'Development branch name is required') .regex(/^[a-zA-Z0-9][a-zA-Z0-9._/-]*[a-zA-Z0-9]$|^[a-zA-Z0-9]$/, 'Invalid branch name format'), /** * Whether this branch is the repository's main branch. * Determines if development happens on the main branch. */ use_mainbranch: z.boolean(), }).optional(), /** * Production/stable branch configuration. * Defines the branch containing production-ready code. */ production: z.object({ /** * Name of the production branch. * Must be a valid git branch name. */ name: z.string().min(1, 'Production branch name is required') .regex(/^[a-zA-Z0-9][a-zA-Z0-9._/-]*[a-zA-Z0-9]$|^[a-zA-Z0-9]$/, 'Invalid branch name format'), /** * Whether this branch is the repository's main branch. * Usually true for production branches. */ use_mainbranch: z.boolean(), }).optional(), /** * Array of branch type configurations. * Defines naming patterns and behavior for different branch categories. */ branch_types: z.array(z.object({ /** * Category of branch defining its purpose. * Must be one of the predefined branch types. */ kind: z.enum(['feature', 'bugfix', 'release', 'hotfix', 'custom'], { errorMap: () => ({ message: 'Must be feature, bugfix, release, hotfix, or custom' }) }), /** * Naming prefix for branches of this type. * Should end with a separator like '/' or '-'. */ prefix: z.string().min(1, 'Branch prefix is required') .max(50, 'Branch prefix too long'), /** * Whether branches of this type are currently enabled. * Controls whether new branches of this type can be created. */ enabled: z.boolean(), })).optional(), /** * Collection of related URLs for the branching model. * Provides API endpoints for managing branching model settings. */ links: z.object({ /** * Self-referential link to this branching model configuration. */ self: z.object({ /** API endpoint URL for this branching model */ href: z.string().url('Invalid branching model link'), }), }).optional(), }); /** * Zod schema for validating Bitbucket branch permissions API responses. * * This schema validates the structure of branch protection rules and restrictions * that control access to specific branches. It includes validation for various * restriction types, user/group exemptions, and pagination metadata. * * @example * ```typescript * const apiResponse = await fetch('/2.0/repositories/gohcl/bitbucket-mcp/branch-restrictions'); * const rawData = await apiResponse.json(); * const permissions = BranchPermissionsSchema.parse(rawData); * ``` */ export const BranchPermissionsSchema = z.object({ /** Array of branch restrictions */ values: z.array(z.object({ /** Unique restriction ID */ id: z.number(), /** Restriction type */ kind: z.enum(['push', 'force', 'delete', 'restrict_merges', 'enforce_merge_checks']), /** Branch name pattern this restriction applies to */ pattern: z.string(), /** Users affected by this restriction */ users: z.array(z.object({ display_name: z.string(), uuid: z.string(), })).optional(), /** Groups affected by this restriction */ groups: z.array(z.object({ name: z.string(), slug: z.string(), })).optional(), /** Restriction value/configuration */ value: z.union([z.string(), z.number(), z.boolean()]).optional(), /** Related links */ links: z.object({ self: z.object({ href: z.string(), }), }).optional(), })), /** Pagination information */ page: z.number().optional(), pagelen: z.number().optional(), size: z.number().optional(), next: z.string().optional(), }); /** * Zod schema for validating Bitbucket default reviewers API responses. * * This schema validates the structure of automatic reviewer assignment rules * that determine which users should be added as reviewers for pull requests * based on branch patterns. It includes comprehensive user information and * repository context. * * @example * ```typescript * const apiResponse = await fetch('/2.0/repositories/gohcl/bitbucket-mcp/default-reviewers'); * const rawData = await apiResponse.json(); * const reviewers = DefaultReviewersSchema.parse(rawData); * ``` */ export const DefaultReviewersSchema = z.object({ /** Array of default reviewer configurations */ values: z.array(z.object({ /** Default reviewer user information */ user: z.object({ display_name: z.string(), uuid: z.string(), account_id: z.string(), links: z.object({ avatar: z.object({ href: z.string(), }), html: z.object({ href: z.string(), }), }), }), /** Branch name pattern this reviewer applies to */ pattern: z.string().optional(), /** Repository information */ repository: z.object({ name: z.string(), full_name: z.string(), uuid: z.string(), }).optional(), })), /** Pagination information */ page: z.number().optional(), pagelen: z.number().optional(), size: z.number().optional(), next: z.string().optional(), }); // ============================================================================= // INPUT VALIDATION SCHEMAS // ============================================================================= /** * Input validation schema for branch-related MCP tool parameters. * * This schema validates the basic parameters required by branch-related tools, * extending the repository base schema with branch-specific validation. * It ensures proper formatting of workspace, repository, and branch identifiers. * * Used by tools that operate on existing branches like get_branch, delete_branch. * * @example * ```typescript * const input = { * workspace: 'gohcl', * repo_slug: 'bitbucket-mcp', * branch_name: 'feature/authentication' * }; * const validatedInput = BranchInputSchema.parse(input); * ``` */ export const BranchInputSchema = RepositoryBaseSchema.extend({ /** * Branch name following git naming conventions. * Must be a valid git branch name without path separators. */ branch_name: z.string().min(1, 'Branch name is required') .max(100, 'Branch name too long') .regex(/^[a-zA-Z0-9][a-zA-Z0-9._/-]*[a-zA-Z0-9]$|^[a-zA-Z0-9]$/, 'Invalid branch name format'), }); /** * Input validation schema for the create_branch MCP tool. * * This schema validates parameters for creating new branches, including * the branch name and target commit hash. It ensures that branch names * follow git conventions and target commits are properly specified. * * @example * ```typescript * const input = { * workspace: 'gohcl', * repo_slug: 'bitbucket-mcp', * name: 'feature/oauth-integration', * target: { * hash: 'a1b2c3d4e5f6789012345678901234567890abcd' * } * }; * const validatedInput = CreateBranchInputSchema.parse(input); * ``` */ export const CreateBranchInputSchema = RepositoryBaseSchema.extend({ /** * Name for the new branch. * Must follow git branch naming conventions and be unique within the repository. */ name: z.string().min(1, 'Branch name is required') .max(100, 'Branch name too long') .regex(/^[a-zA-Z0-9][a-zA-Z0-9._/-]*[a-zA-Z0-9]$|^[a-zA-Z0-9]$/, 'Invalid branch name format'), /** * Target commit information for the new branch. * Specifies which commit the new branch should point to. */ target: z.object({ /** * SHA-1 hash of the target commit. * Must be a valid 40-character hexadecimal commit hash. */ hash: z.string().length(40, 'Target hash must be 40 characters') .regex(/^[a-f0-9]{40}$/, 'Invalid commit hash format'), }), }); // ============================================================================= // TYPE GUARDS // ============================================================================= /** * Type guard function for branch input validation. * * Checks if the provided input matches the branch input schema structure, * providing runtime type safety for branch-related operations. * * @param input - Unknown input to validate * @returns True if input matches BranchInputSchema, false otherwise * * @example * ```typescript * if (isBranchInput(userInput)) { * // userInput is now typed as { workspace: string; repo_slug: string; branch_name: string } * console.log(`Branch: ${userInput.branch_name}`); * } * ``` */ export function isBranchInput(input) { return BranchInputSchema.safeParse(input).success; } //# sourceMappingURL=schemas.js.map