Files
2026-07-13 12:30:28 +08:00

64 lines
1.6 KiB
TypeScript

export interface DomainValidationResult {
valid: boolean;
message?: string;
}
export function normalizeDomain(domain: string): string {
return domain.replace(/^https?:\/\//, '').replace(/\/$/, '');
}
export function isDnsDomain(domain: string): boolean {
return normalizeDomain(domain).includes('.');
}
export function validateDnsDomain(domain: string): DomainValidationResult {
const cleanDomain = normalizeDomain(domain);
const domainRegex =
/^[a-zA-Z0-9][a-zA-Z0-9-]*(\.[a-zA-Z0-9][a-zA-Z0-9-]*)*\.[a-zA-Z]{2,}$/;
const parts = cleanDomain.split('.');
if (parts.length < 2) {
return {
valid: false,
message:
'Invalid domain format. Please enter a complete domain (e.g., example.com)',
};
}
for (const part of parts) {
if (part.length === 0) {
return {
valid: false,
message: 'Invalid domain format. Consecutive dots are not allowed',
};
}
if (part.length > 63) {
return {
valid: false,
message:
'Invalid domain format. Each label must be 63 characters or less',
};
}
if (!/^[a-zA-Z0-9-]+$/.test(part)) {
return {
valid: false,
message:
'Invalid domain format. Domains can only contain letters, numbers, and hyphens',
};
}
if (/^-|-$/.test(part)) {
return {
valid: false,
message:
'Invalid domain format. Labels cannot start or end with hyphens',
};
}
}
if (!domainRegex.test(cleanDomain)) {
return { valid: false, message: 'Invalid domain format' };
}
return { valid: true };
}