@gohcltech/bitbucket-mcp
Version:
Bitbucket integration for Claude via Model Context Protocol
278 lines • 8.78 kB
JavaScript
/**
* @fileoverview Parameter validation utilities for consolidated tools.
*
* Provides reusable validation functions for action-specific parameters,
* including required field checks, enum validation, and Zod schema validation.
*/
/**
* Validates that required parameters are present in the arguments object.
*
* Checks if all specified fields are present and are not null or undefined.
* Throws an error with field names if validation fails.
*
* @param args - The arguments object to validate
* @param fields - Array of required field names
* @param operation - Name of the operation (used in error message)
* @throws {Error} If any required fields are missing
*
* @example
* ```typescript
* validateRequired(
* args,
* ['workspaceSlug', 'repoSlug', 'issueId'],
* 'get_issue'
* );
* // Throws: "Missing required parameter(s) for get_issue: issueId"
* ```
*/
export function validateRequired(args, fields, operation) {
const missing = fields.filter(f => args[f] === undefined || args[f] === null);
if (missing.length > 0) {
throw new Error(`Missing required parameter(s) for ${operation}: ${missing.join(', ')}`);
}
}
/**
* Validates that a value is one of the allowed enum values.
*
* Throws an error if the value is not in the enumValues array.
* The error message lists all valid values.
*
* @template T - Type of the enum values (inferred from enumValues)
* @param value - The value to validate
* @param enumValues - Array or readonly array of allowed values
* @param paramName - Name of the parameter (for error messages)
* @throws {Error} If value is not in enumValues
*
* @example
* ```typescript
* validateEnum(
* args.state,
* ['OPEN', 'MERGED', 'DECLINED'] as const,
* 'state'
* );
* // Throws: "Invalid value for state: UNKNOWN. Must be one of: OPEN, MERGED, DECLINED"
* ```
*/
export function validateEnum(value, enumValues, paramName) {
if (!enumValues.includes(value)) {
throw new Error(`Invalid value for ${paramName}: ${value}. Must be one of: ${enumValues.join(', ')}`);
}
}
/**
* Validates that a value is a positive integer.
*
* Useful for validating IDs and counts that must be positive integers.
*
* @param value - The value to validate
* @param paramName - Name of the parameter (for error messages)
* @throws {Error} If value is not a positive integer
*
* @example
* ```typescript
* validatePositiveInteger(args.issueId, 'issueId');
* // Throws: "issueId must be a positive integer"
* ```
*/
export function validatePositiveInteger(value, paramName) {
if (typeof value !== 'number' || !Number.isInteger(value) || value <= 0) {
throw new Error(`${paramName} must be a positive integer`);
}
}
/**
* Validates that a value is a non-negative integer.
*
* Useful for validating indices, limits, and counts that can be zero.
*
* @param value - The value to validate
* @param paramName - Name of the parameter (for error messages)
* @throws {Error} If value is not a non-negative integer
*
* @example
* ```typescript
* validateNonNegativeInteger(args.limit, 'limit');
* ```
*/
export function validateNonNegativeInteger(value, paramName) {
if (typeof value !== 'number' || !Number.isInteger(value) || value < 0) {
throw new Error(`${paramName} must be a non-negative integer`);
}
}
/**
* Validates that a value is a non-empty string.
*
* @param value - The value to validate
* @param paramName - Name of the parameter (for error messages)
* @throws {Error} If value is not a non-empty string
*
* @example
* ```typescript
* validateNonEmptyString(args.title, 'title');
* // Throws: "title must be a non-empty string"
* ```
*/
export function validateNonEmptyString(value, paramName) {
if (typeof value !== 'string' || value.length === 0) {
throw new Error(`${paramName} must be a non-empty string`);
}
}
/**
* Validates that a value is a valid commit hash (40-character hex string).
*
* Git commit hashes are 40 hexadecimal characters (SHA-1).
*
* @param value - The value to validate
* @param paramName - Name of the parameter (for error messages)
* @throws {Error} If value is not a valid commit hash
*
* @example
* ```typescript
* validateCommitHash(args.commitHash, 'commitHash');
* ```
*/
export function validateCommitHash(value, paramName) {
if (typeof value !== 'string' || !/^[a-f0-9]{40}$/.test(value)) {
throw new Error(`${paramName} must be a valid commit hash (40 hexadecimal characters)`);
}
}
/**
* Validates input data against a Zod schema.
*
* Safe validation that returns success/error result rather than throwing.
* Useful for detailed error reporting.
*
* @template T - The expected type after validation
* @param schema - Zod schema to validate against
* @param data - Data to validate
* @returns Object with success boolean and either data or error details
*
* @example
* ```typescript
* const result = validateWithSchema(ManageWorkspacesArgsSchema, args);
* if (!result.success) {
* return createErrorResponse(new Error(result.error), 'manage_workspaces');
* }
* const validatedArgs: ManageWorkspacesArgs = result.data;
* ```
*/
export function validateWithSchema(schema, data) {
const result = schema.safeParse(data);
if (result.success) {
return { success: true, data: result.data };
}
return {
success: false,
error: result.error.message,
};
}
/**
* Validates input data against a Zod schema, throwing on failure.
*
* Stricter version that throws an error if validation fails.
* Useful for early validation in handler functions.
*
* @template T - The expected type after validation
* @param schema - Zod schema to validate against
* @param data - Data to validate
* @param context - Optional context for error message
* @returns Validated data (type-safe)
* @throws {Error} If validation fails
*
* @example
* ```typescript
* const args = validateWithSchemaOrThrow(
* ManageWorkspacesArgsSchema,
* input,
* 'manage_workspaces'
* );
* // args is now type-safe: ManageWorkspacesArgs
* ```
*/
export function validateWithSchemaOrThrow(schema, data, context) {
const result = schema.safeParse(data);
if (!result.success) {
const contextMsg = context ? ` (${context})` : '';
throw new Error(`Validation failed${contextMsg}: ${result.error.message}`);
}
return result.data;
}
/**
* Extracts and validates specific parameters from arguments.
*
* Type-safe parameter extraction for a subset of parameters.
* Validates that all required fields are present and correctly typed.
*
* @template T - Type of the extracted parameters
* @param args - The arguments object
* @param schema - Zod schema for the parameters
* @returns Extracted and validated parameters
* @throws {Error} If validation fails
*
* @example
* ```typescript
* const params = extractAndValidateParams(
* args,
* z.object({
* workspaceSlug: z.string(),
* repoSlug: z.string(),
* })
* );
* // params: { workspaceSlug: string, repoSlug: string }
* ```
*/
export function extractAndValidateParams(args, schema) {
return validateWithSchemaOrThrow(schema, args);
}
/**
* Conditionally validates parameters based on a condition.
*
* Useful for action-specific validation where different actions
* require different parameters.
*
* @param condition - Boolean condition to check
* @param args - The arguments object
* @param fields - Array of required field names
* @param operation - Name of the operation (for error messages)
* @throws {Error} If condition is true and required fields are missing
*
* @example
* ```typescript
* conditionalValidateRequired(
* action === 'get',
* args,
* ['issueId'],
* 'get_issue'
* );
* ```
*/
export function conditionalValidateRequired(condition, args, fields, operation) {
if (condition) {
validateRequired(args, fields, operation);
}
}
/**
* Creates a validator function for a specific set of required parameters.
*
* Returns a reusable validator function for consistent validation
* of the same parameters across multiple handlers.
*
* @param fields - Array of required field names
* @param operation - Name of the operation (for error messages)
* @returns Validator function that takes args and validates them
*
* @example
* ```typescript
* const validateGetParams = createValidator(
* ['workspaceSlug', 'repoSlug', 'issueId'],
* 'get_issue'
* );
*
* // Use in multiple handlers:
* validateGetParams(args);
* ```
*/
export function createValidator(fields, operation) {
return (args) => {
validateRequired(args, fields, operation);
};
}
//# sourceMappingURL=parameter-validator.js.map