@ironclads/namecheap-mcp
Version:
MCP server for Namecheap API integration - domain management, DNS, and domain suggestions
87 lines • 3.85 kB
JavaScript
import { z } from 'zod';
// Domain name validation
export const DomainNameSchema = z.string()
.min(1, 'Domain name is required')
.max(253, 'Domain name too long')
.regex(/^[^\s]+$/, 'Domain cannot contain spaces')
.regex(/^[^@]+$/, 'Domain cannot contain @ symbol')
.regex(/\.[a-zA-Z]{2,}$/, 'Domain must have valid TLD (at least 2 characters)')
.regex(/^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/, 'Invalid domain name format');
// Bulk domains validation
export const BulkDomainsSchema = z.array(DomainNameSchema)
.min(1, 'At least one domain required')
.max(50, 'Maximum 50 domains allowed');
// Years validation
export const YearsSchema = z.number()
.int('Years must be an integer')
.min(1, 'Minimum 1 year')
.max(10, 'Maximum 10 years');
// IP address validation
export const IPAddressSchema = z.string()
.regex(/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/, 'Invalid IP address format');
// IPv6 address validation (basic)
export const IPv6AddressSchema = z.string()
.regex(/^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^::1$|^::$/, 'Invalid IPv6 address format');
// Hostname validation
export const HostnameSchema = z.string()
.min(1, 'Hostname is required')
.max(253, 'Hostname too long')
.regex(/^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)*[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/, 'Invalid hostname format');
// DNS record name validation
export const DNSRecordNameSchema = z.string()
.min(1, 'Record name is required')
.max(63, 'Record name too long')
.regex(/^(?:[a-zA-Z0-9_-]+|\*|@)$/, 'Invalid DNS record name. Use alphanumeric characters, hyphens, underscores, @ for root, or * for wildcard');
// TTL validation
export const TTLSchema = z.number()
.int('TTL must be an integer')
.min(60, 'Minimum TTL is 60 seconds')
.max(86400, 'Maximum TTL is 86400 seconds (24 hours)');
// MX preference validation
export const MXPreferenceSchema = z.number()
.int('MX preference must be an integer')
.min(0, 'Minimum MX preference is 0')
.max(65535, 'Maximum MX preference is 65535');
// Nameserver validation
export const NameserverSchema = z.string()
.min(1, 'Nameserver is required')
.max(253, 'Nameserver name too long')
.regex(/^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/, 'Invalid nameserver format');
// Validation helper functions
export function validateDNSRecordValue(type, value) {
switch (type.toUpperCase()) {
case 'A':
return IPAddressSchema.safeParse(value).success;
case 'AAAA':
return IPv6AddressSchema.safeParse(value).success;
case 'CNAME':
case 'NS':
return HostnameSchema.safeParse(value).success;
case 'TXT':
return value.length <= 255;
case 'MX':
return HostnameSchema.safeParse(value).success;
case 'SRV':
// SRV format: priority weight port target
const srvParts = value.split(' ');
return srvParts.length === 4 &&
!isNaN(Number(srvParts[0])) &&
!isNaN(Number(srvParts[1])) &&
!isNaN(Number(srvParts[2])) &&
HostnameSchema.safeParse(srvParts[3]).success;
default:
return true; // Allow unknown record types
}
}
export function validateDomainOwnership() {
// In a real implementation, you would check if the API user owns the domain
// This is a placeholder that always returns true
return true;
}
export function sanitizeDomainName(domain) {
return domain.toLowerCase().trim();
}
export function sanitizeRecordName(name) {
return name.toLowerCase().trim();
}
//# sourceMappingURL=validation.js.map