All files / src/lib validation.ts

88% Statements 22/25
100% Branches 2/2
81.25% Functions 13/16
94.44% Lines 17/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41        512x 23x 55x 23x 8x 8x 8x   3x     23x                 23x 39x 36x 36x 35x 35x 35x               132x    
import { isValidEmail as sharedIsValidEmail } from "@interioring/utils/validation/email";
import { isValidIndianMobile } from "@interioring/utils/validation/phone";
import { validateCustomerName } from "@interioring/utils/validation/customer-name";
 
export const isValidEmail = (v: string) => sharedIsValidEmail(v);
export const isValidPhone = (v: string) => isValidIndianMobile(v);
export const isValidName = (v: string) => validateCustomerName(v) === null;
export const isValidUrl = (v: string) => {
	try {
		const url = new URL(v);
		return url.protocol === "http:" || url.protocol === "https:";
	} catch {
		return false;
	}
};
export const maxLength = (v: string, max: number) => v.length <= max;
 
// ── Password strength ───────────────────────────────────────────────────
 
export type PasswordRule = {
	label: string;
	test: (password: string) => boolean;
};
 
export const PASSWORD_RULES: PasswordRule[] = [
	{ label: "At least 8 characters", test: (p) => p.length >= 8 },
	{ label: "Maximum 128 characters", test: (p) => p.length <= 128 },
	{ label: "One uppercase letter", test: (p) => /[A-Z]/.test(p) },
	{ label: "One lowercase letter", test: (p) => /[a-z]/.test(p) },
	{ label: "One number", test: (p) => /\d/.test(p) },
	{ label: "One special character (!@#$%...)", test: (p) => /[^A-Za-z0-9]/.test(p) },
];
 
export function getPasswordErrors(password: string): string[] {
	return PASSWORD_RULES.filter((r) => !r.test(password)).map((r) => r.label);
}
 
export function isStrongPassword(password: string): boolean {
	return PASSWORD_RULES.every((r) => r.test(password));
}