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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | 29x 32x 32x 18x 13x 13x 37x 37x 9x 28x 7x 21x 25x 25x | // Validation utilities for forms and API requests
import { parseIndianPhone } from "@interioring/utils/validation/phone";
import {
validateCustomerName as sharedValidateCustomerName,
customerNameErrorMessage,
} from "@interioring/utils/validation/customer-name";
// Type for incoming inquiry request body (before validation)
export interface InquiryRequestBody {
proId?: string;
projectId?: string;
customerName?: string;
customerPhone?: string;
customerEmail?: string;
requirement?: string;
budget?: string;
type?: string;
requirementType?: string;
requirementDescription?: string;
sourceType?: string;
sourcePage?: string;
}
// Type for validated inquiry request
export interface ValidatedInquiryRequest {
proId: string;
customerName: string;
customerPhone: string;
projectId?: string;
customerEmail?: string;
requirement?: string;
budget?: string;
}
// Re-export the canonical name pattern for any consumer that imports it
// directly (tests, debug tooling). Sourced from the shared validator.
export const CUSTOMER_NAME_ALLOWED_PATTERN = /^[\p{L}][\p{L}\p{M}\s.'-]*$/u;
/**
* Validates a customer name. Thin wrapper over `@interioring/utils` that
* preserves the existing string-or-null return contract for marketplace
* form callers that show `result.message` directly in error UI.
*/
export function validateCustomerName(name: string): string | null {
const error = sharedValidateCustomerName(name);
return error ? customerNameErrorMessage(error) : null;
}
/**
* Type guard to validate required inquiry fields
*/
export function isValidInquiryRequest(
body: unknown,
): body is InquiryRequestBody & {
proId: string;
customerName: string;
customerPhone: string;
} {
if (typeof body !== "object" || body === null) return false;
const b = body as Record<string, unknown>;
return (
typeof b.proId === "string" &&
b.proId.length > 0 &&
typeof b.customerName === "string" &&
b.customerName.length > 0 &&
typeof b.customerPhone === "string" &&
b.customerPhone.length > 0
);
}
/**
* Validate Indian phone number format. Returns an error message if invalid,
* or null if valid. Backed by libphonenumber-js (via @interioring/phone) so it
* accepts any Indian mobile format the user might type — with or without
* country code, with or without spaces/dashes — and rejects landlines for
* the marketplace inquiry flow (WhatsApp/SMS only deliver to mobiles).
*/
export function validateIndianPhoneNumber(phone: string): string | null {
const parsed = parseIndianPhone(phone);
if (!parsed) {
return "Enter a valid 10-digit Indian mobile number.";
}
if (parsed.type !== "mobile") {
return "Phone number must be a mobile (we use WhatsApp/SMS to confirm inquiries).";
}
return null;
}
/**
* Extract digits from phone number string. Strips +91, spaces, and other
* formatting via the canonical parser so callers always see consistent input.
*/
export function extractPhoneDigits(phone: string): string {
const parsed = parseIndianPhone(phone);
return parsed ? parsed.e164.slice(3) : phone.replace(/\D/g, "");
}
|