@emailcheck/email-validator-js 3.4.4 → 4.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"vercel.esm.js","sources":["../../../src/serverless/_shared/cors.ts","../../../node_modules/string-similarity-js/dist/string-similarity.js","../../../src/serverless/verifier.ts","../../../src/serverless/_shared/dispatch.ts","../../../src/serverless/_shared/validation.ts","../../../src/serverless/adapters/vercel.ts"],"sourcesContent":["/**\n * Standard CORS header set used by every adapter. `methods` lets each platform\n * advertise the verbs it actually supports without re-declaring the rest.\n */\nexport function corsHeaders(methods: string = 'GET, POST, OPTIONS'): Record<string, string> {\n return {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': methods,\n 'Access-Control-Allow-Headers': 'Content-Type',\n };\n}\n\nexport function jsonHeaders(extra?: Record<string, string>): Record<string, string> {\n return { 'Content-Type': 'application/json', ...extra };\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.stringSimilarity = void 0;\n/* global exports, Map */\n/**\n * Calculate similarity between two strings\n * @param {string} str1 First string to match\n * @param {string} str2 Second string to match\n * @param {number} [substringLength=2] Optional. Length of substring to be used in calculating similarity. Default 2.\n * @param {boolean} [caseSensitive=false] Optional. Whether you want to consider case in string matching. Default false;\n * @returns Number between 0 and 1, with 0 being a low match score.\n */\nvar stringSimilarity = function (str1, str2, substringLength, caseSensitive) {\n if (substringLength === void 0) { substringLength = 2; }\n if (caseSensitive === void 0) { caseSensitive = false; }\n if (!caseSensitive) {\n str1 = str1.toLowerCase();\n str2 = str2.toLowerCase();\n }\n if (str1.length < substringLength || str2.length < substringLength)\n return 0;\n var map = new Map();\n for (var i = 0; i < str1.length - (substringLength - 1); i++) {\n var substr1 = str1.substr(i, substringLength);\n map.set(substr1, map.has(substr1) ? map.get(substr1) + 1 : 1);\n }\n var match = 0;\n for (var j = 0; j < str2.length - (substringLength - 1); j++) {\n var substr2 = str2.substr(j, substringLength);\n var count = map.has(substr2) ? map.get(substr2) : 0;\n if (count > 0) {\n map.set(substr2, count - 1);\n match++;\n }\n }\n return (match * 2) / (str1.length + str2.length - ((substringLength - 1) * 2));\n};\nexports.stringSimilarity = stringSimilarity;\nexports.default = exports.stringSimilarity;\n//# sourceMappingURL=string-similarity.js.map","/**\n * Edge-runtime / serverless email validator.\n *\n * No Node.js APIs (no `node:net`, no `node:dns`) — DNS is delegated to a\n * caller-supplied `DNSResolver`, so the same code runs on Cloudflare Workers,\n * Vercel Edge, Lambda@Edge, and Deno Deploy.\n *\n * Shares data with the main validator: `commonEmailDomains` and the typo map\n * are imported from `src/data/`, so we never drift between the two surfaces.\n */\n\nimport { stringSimilarity } from 'string-similarity-js';\nimport commonEmailDomainsJson from '../data/common-email-domains.json';\nimport typoPatternsJson from '../data/typo-patterns.json';\nimport disposableProviders from '../disposable-email-providers.json';\nimport freeProviders from '../free-email-providers.json';\nimport type { DomainSuggesterOptions, EmailValidationResult, ValidateEmailOptions } from '../types';\n\n/** Compact LRU/TTL cache. One Map, expiry stamp per entry, batched eviction. */\nexport class EdgeCache<T> {\n private readonly cache = new Map<string, { value: T; expires: number }>();\n\n constructor(\n private readonly maxSize = 1000,\n private readonly ttl = 3_600_000\n ) {}\n\n get(key: string): T | undefined {\n const item = this.cache.get(key);\n if (!item) return undefined;\n if (Date.now() > item.expires) {\n this.cache.delete(key);\n return undefined;\n }\n return item.value;\n }\n\n set(key: string, value: T): void {\n if (this.cache.size >= this.maxSize) this.evict();\n this.cache.set(key, { value, expires: Date.now() + this.ttl });\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n size(): number {\n return this.cache.size;\n }\n\n private evict(): void {\n // Drop the oldest 10% in one pass — Map preserves insertion order so\n // `keys()` walks oldest-first.\n const drop = Math.max(1, Math.floor(this.maxSize * 0.1));\n let n = 0;\n for (const key of this.cache.keys()) {\n if (n++ >= drop) break;\n this.cache.delete(key);\n }\n }\n}\n\n// Module-level per-isolate caches. Edge runtimes get cold-start fresh; warm\n// invocations benefit from the in-memory hits.\nexport const validationCache = new EdgeCache<EmailValidationResult>(1000);\nexport const mxCache = new EdgeCache<string[]>(500);\n\n/** Same regex the main validator uses — kept inline because edge runtimes don't auto-resolve psl. */\nconst VALID_EMAIL_REGEX =\n /^(([a-zA-Z0-9_+'-]+(\\.[a-zA-Z0-9_+'-]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}))$/;\n\n/**\n * Common email domains — re-exported so callers (Vercel Edge, etc.) can pass a\n * custom subset via `DomainSuggesterOptions.customDomains`.\n */\nexport const COMMON_DOMAINS: readonly string[] = commonEmailDomainsJson as string[];\n\nconst TYPO_PATTERNS = typoPatternsJson as Record<string, string[]>;\n/** Reverse index for O(1) typo → canonical lookup. */\nconst TYPO_LOOKUP = new Map<string, string>();\nfor (const [canonical, typos] of Object.entries(TYPO_PATTERNS)) {\n for (const typo of typos) TYPO_LOOKUP.set(typo, canonical);\n}\n\n/** DNS resolver contract — caller-supplied so we don't import `node:dns`. */\nexport interface DNSResolver {\n resolveMx(domain: string): Promise<Array<{ exchange: string; priority: number }>>;\n resolveTxt(domain: string): Promise<string[]>;\n}\n\n/** No-op resolver for environments where DNS isn't available. */\nexport class StubDNSResolver implements DNSResolver {\n async resolveMx(): Promise<Array<{ exchange: string; priority: number }>> {\n return [];\n }\n async resolveTxt(): Promise<string[]> {\n return [];\n }\n}\n\n/**\n * DNS-over-HTTPS resolver — works in any runtime with `fetch` (Cloudflare\n * Workers, Vercel Edge, Deno, browsers, Node 18+). Defaults to Cloudflare's\n * 1.1.1.1 endpoint; pass `endpoint` to use Google (8.8.8.8), NextDNS, or\n * a self-hosted resolver.\n *\n * Compatible with [`cf-doh`](https://www.npmjs.com/package/cf-doh) — if you\n * already use that, drop it in directly. This built-in keeps the package\n * zero-dep so the same code works on every edge runtime without an extra\n * install step.\n */\nexport interface DoHResolverOptions {\n /** DoH endpoint URL. Default: https://cloudflare-dns.com/dns-query */\n endpoint?: string;\n /** Per-query request timeout, ms. Default: 5000 */\n timeoutMs?: number;\n /** Custom fetch (e.g. to add headers / proxy). Default: globalThis.fetch */\n fetch?: typeof fetch;\n}\n\ninterface DoHAnswer {\n name: string;\n type: number;\n TTL: number;\n data: string;\n}\n\ninterface DoHResponse {\n Status: number;\n Answer?: DoHAnswer[];\n}\n\nconst DOH_RECORD_TYPE = { MX: 15, TXT: 16 } as const;\n\nexport class DoHResolver implements DNSResolver {\n private readonly endpoint: string;\n private readonly timeoutMs: number;\n private readonly fetchFn: typeof fetch;\n\n constructor(options: DoHResolverOptions = {}) {\n this.endpoint = options.endpoint ?? 'https://cloudflare-dns.com/dns-query';\n this.timeoutMs = options.timeoutMs ?? 5000;\n this.fetchFn = options.fetch ?? globalThis.fetch;\n }\n\n async resolveMx(domain: string): Promise<Array<{ exchange: string; priority: number }>> {\n const records = await this.query(domain, DOH_RECORD_TYPE.MX);\n if (!records) return [];\n return records\n .map((answer) => {\n // MX answer data: \"<priority> <exchange>\" (with optional trailing dot).\n const match = answer.data.match(/^(\\d+)\\s+(.+?)\\.?$/);\n if (!match) return null;\n return { priority: Number(match[1]), exchange: match[2] as string };\n })\n .filter((r): r is { exchange: string; priority: number } => r !== null)\n .sort((a, b) => a.priority - b.priority);\n }\n\n async resolveTxt(domain: string): Promise<string[]> {\n const records = await this.query(domain, DOH_RECORD_TYPE.TXT);\n if (!records) return [];\n // TXT answers come back as quoted strings — strip the surrounding quotes.\n return records.map((answer) => answer.data.replace(/^\"(.*)\"$/, '$1'));\n }\n\n private async query(domain: string, type: number): Promise<DoHAnswer[] | null> {\n const url = `${this.endpoint}?name=${encodeURIComponent(domain)}&type=${type}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n try {\n const response = await this.fetchFn(url, {\n headers: { Accept: 'application/dns-json' },\n signal: controller.signal,\n });\n if (!response.ok) return null;\n const json = (await response.json()) as DoHResponse;\n // Status 0 = NOERROR. Anything else (NXDOMAIN, SERVFAIL, etc.) → no answers.\n if (json.Status !== 0) return [];\n return json.Answer ?? [];\n } catch {\n return null;\n } finally {\n clearTimeout(timer);\n }\n }\n}\n\n/**\n * Suggest a corrected domain. Returns the canonical for a known typo,\n * otherwise the closest match within the threshold, otherwise null.\n */\nexport function suggestDomain(domain: string, options?: DomainSuggesterOptions): string | null {\n const lower = domain.toLowerCase();\n\n // Hand-curated typo map first — beats similarity for common cases.\n const known = TYPO_LOOKUP.get(lower);\n if (known) return known;\n\n const domains = options?.customDomains ?? COMMON_DOMAINS;\n if (domains.includes(lower)) return null;\n\n const threshold = options?.threshold ?? 2;\n let minDistance = Infinity;\n let suggestion: string | null = null;\n\n for (const candidate of domains) {\n const candidateLower = candidate.toLowerCase();\n if (lower === candidateLower) return null;\n const similarity = stringSimilarity(lower, candidateLower);\n const distance = Math.round((1 - similarity) * Math.max(domain.length, candidate.length));\n if (distance > 0 && distance <= threshold && distance < minDistance) {\n minDistance = distance;\n suggestion = candidate;\n }\n }\n return suggestion;\n}\n\n/**\n * Validate one email — syntax / typo / disposable / free / MX (if a resolver\n * is supplied). Each step is independently flag-gated so callers pay only for\n * what they use.\n */\nexport async function validateEmailCore(\n email: string,\n options?: ValidateEmailOptions & { dnsResolver?: DNSResolver }\n): Promise<EmailValidationResult> {\n const normalized = email.toLowerCase().trim();\n\n if (!options?.skipCache) {\n const cached = validationCache.get(normalized);\n if (cached) return cached;\n }\n\n const result: EmailValidationResult = { valid: false, email: normalized, validators: {} };\n\n if (options?.validateSyntax !== false) {\n const syntaxValid = VALID_EMAIL_REGEX.test(normalized);\n result.validators.syntax = { valid: syntaxValid };\n if (!syntaxValid) {\n validationCache.set(normalized, result);\n return result;\n }\n }\n\n const [local, domain] = normalized.split('@');\n result.local = local;\n result.domain = domain;\n\n if (options?.validateTypo !== false) {\n const suggestion = suggestDomain(domain, options?.domainSuggesterOptions);\n result.validators.typo = { valid: !suggestion, suggestion: suggestion ?? undefined };\n }\n\n if (options?.validateDisposable !== false) {\n result.validators.disposable = { valid: !disposableProviders.includes(domain) };\n }\n\n if (options?.validateFree !== false) {\n result.validators.free = { valid: !freeProviders.includes(domain) };\n }\n\n if (options?.validateMx && options.dnsResolver) {\n try {\n const records = await options.dnsResolver.resolveMx(domain);\n const hasMx = records.length > 0;\n result.validators.mx = {\n valid: hasMx,\n records: hasMx ? records.map((r) => r.exchange) : undefined,\n };\n } catch (error) {\n result.validators.mx = {\n valid: false,\n error: error instanceof Error ? error.message : 'MX validation failed',\n };\n }\n }\n\n // Free-provider detection is informational; only the hard validators gate validity.\n result.valid = (['syntax', 'typo', 'disposable', 'mx'] as const).every((key) => {\n const validator = result.validators[key];\n return !validator || validator.valid !== false;\n });\n\n if (!options?.skipCache) validationCache.set(normalized, result);\n return result;\n}\n\nexport async function validateEmailBatch(\n emails: string[],\n options?: ValidateEmailOptions & { dnsResolver?: DNSResolver }\n): Promise<EmailValidationResult[]> {\n const chunkSize = options?.batchSize ?? 10;\n const results: EmailValidationResult[] = [];\n for (let i = 0; i < emails.length; i += chunkSize) {\n const chunk = emails.slice(i, i + chunkSize);\n const chunkResults = await Promise.all(chunk.map((email) => validateEmailCore(email, options)));\n results.push(...chunkResults);\n }\n return results;\n}\n\nexport function clearCache(): void {\n validationCache.clear();\n mxCache.clear();\n}\n\nexport type { DomainSuggesterOptions, EmailValidationResult, ValidateEmailOptions } from '../types';\n","import type { EmailValidationResult } from '../../types';\nimport { validateEmailBatch, validateEmailCore } from '../verifier';\nimport type { ValidationDispatch } from './validation';\n\n/**\n * Execute a classified request against the core validator. Single-email\n * requests yield one result; batch requests yield an array.\n */\nexport async function executeValidation(\n dispatch: ValidationDispatch\n): Promise<EmailValidationResult | EmailValidationResult[]> {\n if (dispatch.kind === 'single') {\n return validateEmailCore(dispatch.email, dispatch.options);\n }\n return validateEmailBatch(dispatch.emails, dispatch.options);\n}\n","import type { ValidateEmailOptions } from '../../types';\n\n/** Hard limit on batch size enforced by every adapter. */\nexport const MAX_BATCH_SIZE = 100;\n\n/** Shape of POST bodies and Lambda invocations across all serverless adapters. */\nexport interface ValidationRequestBody {\n email?: string;\n emails?: string[];\n options?: ValidateEmailOptions;\n}\n\nexport type ValidationDispatch =\n | { kind: 'single'; email: string; options?: ValidateEmailOptions }\n | { kind: 'batch'; emails: string[]; options?: ValidateEmailOptions };\n\nexport interface ValidationFailure {\n kind: 'invalid';\n status: 400;\n message: string;\n}\n\n/**\n * Validation for endpoints that accept ONLY a batch (`emails`). Returns\n * a 400 failure if emails is missing/empty/oversized, or null when valid.\n * Routed `/validate/batch` paths use this so error messages stay batch-specific.\n */\nexport type BatchValidation = { ok: true; emails: string[] } | { ok: false; status: 400; message: string };\n\nexport function validateBatchEmailsField(emails: unknown): BatchValidation {\n if (!Array.isArray(emails) || emails.length === 0) {\n return { ok: false, status: 400, message: 'Emails array is required' };\n }\n if (emails.length > MAX_BATCH_SIZE) {\n return { ok: false, status: 400, message: `Maximum ${MAX_BATCH_SIZE} emails allowed per batch` };\n }\n return { ok: true, emails: emails as string[] };\n}\n\n/**\n * Apply the rules every serverless adapter shares:\n * 1. body must request either `email` or `emails`\n * 2. `emails` must be a non-empty array of ≤ MAX_BATCH_SIZE entries\n *\n * Centralising this means a future rule change (say, raising the cap) lands\n * in one place instead of three.\n */\nexport function classifyRequest(\n body: ValidationRequestBody | null | undefined\n): ValidationDispatch | ValidationFailure {\n if (!body || (!body.email && !body.emails)) {\n return { kind: 'invalid', status: 400, message: 'Email or emails array is required' };\n }\n if (body.emails) {\n if (!Array.isArray(body.emails) || body.emails.length === 0) {\n return { kind: 'invalid', status: 400, message: 'Emails array is required' };\n }\n if (body.emails.length > MAX_BATCH_SIZE) {\n return { kind: 'invalid', status: 400, message: `Maximum ${MAX_BATCH_SIZE} emails allowed per batch` };\n }\n return { kind: 'batch', emails: body.emails, options: body.options };\n }\n // body.email must be set per the first guard (which checks both fields).\n if (!body.email) {\n return { kind: 'invalid', status: 400, message: 'Email or emails array is required' };\n }\n return { kind: 'single', email: body.email, options: body.options };\n}\n","/**\n * Vercel Edge Function adapter for email validation.\n *\n * Three handler shapes are exported for backward compatibility:\n * - `edgeHandler`: Web-API style, no path routing.\n * - `nodeHandler`: Express-style req/res for the Node.js runtime.\n * - `handler`: routed Web-API handler with `/api/health`, `/api/validate`,\n * `/api/validate/batch`.\n *\n * Shared validation/CORS logic comes from `../_shared/`.\n */\nimport type { ValidateEmailOptions } from '../../types';\nimport { corsHeaders, jsonHeaders } from '../_shared/cors';\nimport { executeValidation } from '../_shared/dispatch';\nimport { classifyRequest, type ValidationRequestBody, validateBatchEmailsField } from '../_shared/validation';\nimport { validateEmailBatch, validateEmailCore } from '../verifier';\n\nexport interface VercelRequest {\n method: string;\n url: string;\n headers: Headers;\n body?: unknown;\n query?: { [key: string]: string | string[] };\n}\n\nexport interface VercelResponse {\n status: (code: number) => VercelResponse;\n json: (data: unknown) => void;\n send: (data: unknown) => void;\n}\n\nconst POST_HEADERS = jsonHeaders(corsHeaders('POST, GET, OPTIONS'));\nconst ROUTED_HEADERS = jsonHeaders({\n 'Access-Control-Allow-Origin': '*',\n 'Cache-Control': 'no-store, max-age=0',\n 'X-Powered-By': 'Vercel Edge Functions',\n});\n\nfunction jsonResponse(status: number, body: unknown, headers: Record<string, string> = POST_HEADERS): Response {\n return new Response(JSON.stringify(body), { status, headers });\n}\n\nfunction parseGetParams(url: URL): ValidationRequestBody {\n const email = url.searchParams.get('email');\n const emails = url.searchParams.get('emails');\n return {\n email: email || undefined,\n emails: emails ? emails.split(',') : undefined,\n options: {\n validateMx: url.searchParams.get('validateMx') === 'true',\n validateSMTP: url.searchParams.get('validateSMTP') === 'true',\n validateTypo: url.searchParams.get('validateTypo') !== 'false',\n validateDisposable: url.searchParams.get('validateDisposable') !== 'false',\n validateFree: url.searchParams.get('validateFree') !== 'false',\n },\n };\n}\n\n// Edge Runtime handler — no path routing, `email`/`emails` from body or query.\nexport async function edgeHandler(request: Request): Promise<Response> {\n if (request.method === 'OPTIONS') {\n return new Response(null, { status: 200, headers: corsHeaders('POST, GET, OPTIONS') });\n }\n\n try {\n let body: ValidationRequestBody;\n if (request.method === 'GET') {\n body = parseGetParams(new URL(request.url));\n } else if (request.method === 'POST') {\n body = await request.json();\n } else {\n return jsonResponse(405, { success: false, error: 'Method not allowed' });\n }\n\n const classified = classifyRequest(body);\n if (classified.kind === 'invalid') {\n return jsonResponse(classified.status, { success: false, error: classified.message });\n }\n\n const data = await executeValidation(classified);\n return jsonResponse(\n 200,\n { success: true, data },\n jsonHeaders({ ...corsHeaders('POST, GET, OPTIONS'), 'Cache-Control': 'public, max-age=3600' })\n );\n } catch (error) {\n console.error('Vercel Edge error:', error);\n const message = error instanceof Error ? error.message : 'Internal server error';\n return jsonResponse(500, { success: false, error: message });\n }\n}\n\n// Node.js runtime handler (Express-style).\nexport async function nodeHandler(req: VercelRequest, res: VercelResponse): Promise<void> {\n if (req.method === 'OPTIONS') {\n res.status(200).send('');\n return;\n }\n\n try {\n let body: ValidationRequestBody;\n if (req.method === 'GET') {\n const fakeUrl = new URL(req.url, 'http://localhost');\n body = parseGetParams(fakeUrl);\n // Fall back to the parsed query map if the URL was relative without params.\n if (!body.email && !body.emails && req.query) {\n body.email = req.query.email as string | undefined;\n body.emails = req.query.emails ? (req.query.emails as string).split(',') : undefined;\n }\n } else if (req.method === 'POST') {\n body = req.body as ValidationRequestBody;\n } else {\n res.status(405).json({ success: false, error: 'Method not allowed' });\n return;\n }\n\n const classified = classifyRequest(body);\n if (classified.kind === 'invalid') {\n res.status(classified.status).json({ success: false, error: classified.message });\n return;\n }\n const data = await executeValidation(classified);\n res.status(200).json({ success: true, data });\n } catch (error) {\n console.error('Vercel Node error:', error);\n res.status(500).json({ success: false, error: error instanceof Error ? error.message : 'Internal server error' });\n }\n}\n\nexport const config = {\n runtime: 'edge',\n regions: ['iad1'],\n};\n\nfunction requireJsonContentType(request: Request): Response | null {\n const contentType = request.headers.get('content-type');\n if (!contentType?.includes('application/json')) {\n return jsonResponse(400, { error: 'Content-Type must be application/json' }, ROUTED_HEADERS);\n }\n return null;\n}\n\nasync function readJsonBody(request: Request): Promise<{ body: unknown } | { error: Response }> {\n try {\n return { body: await request.json() };\n } catch {\n return { error: jsonResponse(400, { error: 'Invalid request body' }, ROUTED_HEADERS) };\n }\n}\n\n// Routed handler used by the test suite — `/api/health`, `/api/validate`,\n// `/api/validate/batch`.\nexport async function handler(request: Request): Promise<Response> {\n const url = new URL(request.url);\n const { pathname } = url;\n\n if (request.method === 'OPTIONS') {\n return new Response(null, { status: 204, headers: corsHeaders() });\n }\n\n try {\n if (pathname === '/api/health' && request.method === 'GET') {\n return jsonResponse(\n 200,\n { status: 'healthy', platform: 'vercel', timestamp: new Date().toISOString() },\n ROUTED_HEADERS\n );\n }\n\n const isValidatePath = pathname === '/api/validate' || pathname === '/api/validate/batch';\n if (isValidatePath && request.method !== 'POST') {\n return jsonResponse(405, { error: 'Method not allowed' }, ROUTED_HEADERS);\n }\n\n if (pathname === '/api/validate' && request.method === 'POST') {\n const ct = requireJsonContentType(request);\n if (ct) return ct;\n const parsed = await readJsonBody(request);\n if ('error' in parsed) return parsed.error;\n const body = parsed.body as { email?: string };\n if (!body.email) return jsonResponse(400, { error: 'Email is required' }, ROUTED_HEADERS);\n\n const options: Partial<ValidateEmailOptions> = {};\n if (url.searchParams.has('skipCache')) options.skipCache = url.searchParams.get('skipCache') === 'true';\n if (url.searchParams.has('validateTypo')) options.validateTypo = url.searchParams.get('validateTypo') === 'true';\n\n const result = await validateEmailCore(body.email, options);\n return jsonResponse(200, result, ROUTED_HEADERS);\n }\n\n if (pathname === '/api/validate/batch' && request.method === 'POST') {\n const ct = requireJsonContentType(request);\n if (ct) return ct;\n const parsed = await readJsonBody(request);\n if ('error' in parsed) return parsed.error;\n const body = parsed.body as ValidationRequestBody;\n const validated = validateBatchEmailsField(body.emails);\n if (!validated.ok) return jsonResponse(validated.status, { error: validated.message }, ROUTED_HEADERS);\n\n const options: { batchSize?: number } = {};\n const batchSizeParam = url.searchParams.get('batchSize');\n if (batchSizeParam) options.batchSize = parseInt(batchSizeParam, 10);\n\n const results = await validateEmailBatch(validated.emails, options);\n return jsonResponse(200, { results }, ROUTED_HEADERS);\n }\n\n return jsonResponse(404, { error: 'Not found' }, ROUTED_HEADERS);\n } catch (error) {\n console.error('Handler error:', error);\n return jsonResponse(500, { error: 'Internal server error' }, ROUTED_HEADERS);\n }\n}\n\nexport default {\n edgeHandler,\n nodeHandler,\n handler,\n};\n"],"names":["__spreadValues","exports","stringSimilarity","__async"],"mappings":"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","x_google_ignoreList":[1]}
1
+ {"version":3,"file":"vercel.esm.js","sources":["../../../src/serverless/_shared/cors.ts","../../../node_modules/string-similarity-js/dist/string-similarity.js","../../../src/serverless/verifier.ts","../../../src/serverless/_shared/dispatch.ts","../../../src/serverless/_shared/validation.ts","../../../src/serverless/adapters/vercel.ts"],"sourcesContent":["/**\n * Standard CORS header set used by every adapter. `methods` lets each platform\n * advertise the verbs it actually supports without re-declaring the rest.\n */\nexport function corsHeaders(methods: string = 'GET, POST, OPTIONS'): Record<string, string> {\n return {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': methods,\n 'Access-Control-Allow-Headers': 'Content-Type',\n };\n}\n\nexport function jsonHeaders(extra?: Record<string, string>): Record<string, string> {\n return { 'Content-Type': 'application/json', ...extra };\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.stringSimilarity = void 0;\n/* global exports, Map */\n/**\n * Calculate similarity between two strings\n * @param {string} str1 First string to match\n * @param {string} str2 Second string to match\n * @param {number} [substringLength=2] Optional. Length of substring to be used in calculating similarity. Default 2.\n * @param {boolean} [caseSensitive=false] Optional. Whether you want to consider case in string matching. Default false;\n * @returns Number between 0 and 1, with 0 being a low match score.\n */\nvar stringSimilarity = function (str1, str2, substringLength, caseSensitive) {\n if (substringLength === void 0) { substringLength = 2; }\n if (caseSensitive === void 0) { caseSensitive = false; }\n if (!caseSensitive) {\n str1 = str1.toLowerCase();\n str2 = str2.toLowerCase();\n }\n if (str1.length < substringLength || str2.length < substringLength)\n return 0;\n var map = new Map();\n for (var i = 0; i < str1.length - (substringLength - 1); i++) {\n var substr1 = str1.substr(i, substringLength);\n map.set(substr1, map.has(substr1) ? map.get(substr1) + 1 : 1);\n }\n var match = 0;\n for (var j = 0; j < str2.length - (substringLength - 1); j++) {\n var substr2 = str2.substr(j, substringLength);\n var count = map.has(substr2) ? map.get(substr2) : 0;\n if (count > 0) {\n map.set(substr2, count - 1);\n match++;\n }\n }\n return (match * 2) / (str1.length + str2.length - ((substringLength - 1) * 2));\n};\nexports.stringSimilarity = stringSimilarity;\nexports.default = exports.stringSimilarity;\n//# sourceMappingURL=string-similarity.js.map","/**\n * Edge-runtime / serverless email validator.\n *\n * No Node.js APIs (no `node:net`, no `node:dns`) — DNS is delegated to a\n * caller-supplied `DNSResolver`, so the same code runs on Cloudflare Workers,\n * Vercel Edge, Lambda@Edge, and Deno Deploy.\n *\n * Shares data with the main validator: `commonEmailDomains` and the typo map\n * are imported from `src/data/`, so we never drift between the two surfaces.\n */\n\nimport { stringSimilarity } from 'string-similarity-js';\nimport commonEmailDomainsJson from '../data/common-email-domains.json';\nimport typoPatternsJson from '../data/typo-patterns.json';\nimport disposableProviders from '../disposable-email-providers.json';\nimport freeProviders from '../free-email-providers.json';\nimport type { DomainSuggesterOptions, EmailValidationResult, ValidateEmailOptions } from '../types';\n\n/** Compact LRU/TTL cache. One Map, expiry stamp per entry, batched eviction. */\nexport class EdgeCache<T> {\n private readonly cache = new Map<string, { value: T; expires: number }>();\n\n constructor(\n private readonly maxSize = 1000,\n private readonly ttl = 3_600_000\n ) {}\n\n get(key: string): T | undefined {\n const item = this.cache.get(key);\n if (!item) return undefined;\n if (Date.now() > item.expires) {\n this.cache.delete(key);\n return undefined;\n }\n return item.value;\n }\n\n set(key: string, value: T): void {\n if (this.cache.size >= this.maxSize) this.evict();\n this.cache.set(key, { value, expires: Date.now() + this.ttl });\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n size(): number {\n return this.cache.size;\n }\n\n private evict(): void {\n // Drop the oldest 10% in one pass — Map preserves insertion order so\n // `keys()` walks oldest-first.\n const drop = Math.max(1, Math.floor(this.maxSize * 0.1));\n let n = 0;\n for (const key of this.cache.keys()) {\n if (n++ >= drop) break;\n this.cache.delete(key);\n }\n }\n}\n\n// Module-level per-isolate caches. Edge runtimes get cold-start fresh; warm\n// invocations benefit from the in-memory hits.\nexport const validationCache = new EdgeCache<EmailValidationResult>(1000);\nexport const mxCache = new EdgeCache<string[]>(500);\n\n/** Same regex the main validator uses — kept inline because edge runtimes don't auto-resolve psl. */\nconst VALID_EMAIL_REGEX =\n /^(([a-zA-Z0-9_+'-]+(\\.[a-zA-Z0-9_+'-]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}))$/;\n\n/**\n * Common email domains — re-exported so callers (Vercel Edge, etc.) can pass a\n * custom subset via `DomainSuggesterOptions.customDomains`.\n */\nexport const COMMON_DOMAINS: readonly string[] = commonEmailDomainsJson as string[];\n\nconst TYPO_PATTERNS = typoPatternsJson as Record<string, string[]>;\n/** Reverse index for O(1) typo → canonical lookup. */\nconst TYPO_LOOKUP = new Map<string, string>();\nfor (const [canonical, typos] of Object.entries(TYPO_PATTERNS)) {\n for (const typo of typos) TYPO_LOOKUP.set(typo, canonical);\n}\n\n/** DNS resolver contract — caller-supplied so we don't import `node:dns`. */\nexport interface DNSResolver {\n resolveMx(domain: string): Promise<Array<{ exchange: string; priority: number }>>;\n resolveTxt(domain: string): Promise<string[]>;\n}\n\n/** No-op resolver for environments where DNS isn't available. */\nexport class StubDNSResolver implements DNSResolver {\n async resolveMx(): Promise<Array<{ exchange: string; priority: number }>> {\n return [];\n }\n async resolveTxt(): Promise<string[]> {\n return [];\n }\n}\n\n/**\n * DNS-over-HTTPS resolver — works in any runtime with `fetch` (Cloudflare\n * Workers, Vercel Edge, Deno, browsers, Node 18+). Defaults to Cloudflare's\n * 1.1.1.1 endpoint; pass `endpoint` to use Google (8.8.8.8), NextDNS, or\n * a self-hosted resolver.\n *\n * Compatible with [`cf-doh`](https://www.npmjs.com/package/cf-doh) — if you\n * already use that, drop it in directly. This built-in keeps the package\n * zero-dep so the same code works on every edge runtime without an extra\n * install step.\n */\nexport interface DoHResolverOptions {\n /** DoH endpoint URL. Default: https://cloudflare-dns.com/dns-query */\n endpoint?: string;\n /** Per-query request timeout, ms. Default: 5000 */\n timeoutMs?: number;\n /** Custom fetch (e.g. to add headers / proxy). Default: globalThis.fetch */\n fetch?: typeof fetch;\n}\n\ninterface DoHAnswer {\n name: string;\n type: number;\n TTL: number;\n data: string;\n}\n\ninterface DoHResponse {\n Status: number;\n Answer?: DoHAnswer[];\n}\n\nconst DOH_RECORD_TYPE = { MX: 15, TXT: 16 } as const;\n\nexport class DoHResolver implements DNSResolver {\n private readonly endpoint: string;\n private readonly timeoutMs: number;\n private readonly fetchFn: typeof fetch;\n\n constructor(options: DoHResolverOptions = {}) {\n this.endpoint = options.endpoint ?? 'https://cloudflare-dns.com/dns-query';\n this.timeoutMs = options.timeoutMs ?? 5000;\n this.fetchFn = options.fetch ?? globalThis.fetch;\n }\n\n async resolveMx(domain: string): Promise<Array<{ exchange: string; priority: number }>> {\n const records = await this.query(domain, DOH_RECORD_TYPE.MX);\n if (!records) return [];\n return records\n .map((answer) => {\n // MX answer data: \"<priority> <exchange>\" (with optional trailing dot).\n const match = answer.data.match(/^(\\d+)\\s+(.+?)\\.?$/);\n if (!match) return null;\n return { priority: Number(match[1]), exchange: match[2] as string };\n })\n .filter((r): r is { exchange: string; priority: number } => r !== null)\n .sort((a, b) => a.priority - b.priority);\n }\n\n async resolveTxt(domain: string): Promise<string[]> {\n const records = await this.query(domain, DOH_RECORD_TYPE.TXT);\n if (!records) return [];\n // TXT answers come back as quoted strings — strip the surrounding quotes.\n return records.map((answer) => answer.data.replace(/^\"(.*)\"$/, '$1'));\n }\n\n private async query(domain: string, type: number): Promise<DoHAnswer[] | null> {\n const url = `${this.endpoint}?name=${encodeURIComponent(domain)}&type=${type}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n try {\n const response = await this.fetchFn(url, {\n headers: { Accept: 'application/dns-json' },\n signal: controller.signal,\n });\n if (!response.ok) return null;\n const json = (await response.json()) as DoHResponse;\n // Status 0 = NOERROR. Anything else (NXDOMAIN, SERVFAIL, etc.) → no answers.\n if (json.Status !== 0) return [];\n return json.Answer ?? [];\n } catch {\n return null;\n } finally {\n clearTimeout(timer);\n }\n }\n}\n\n/**\n * Suggest a corrected domain. Returns the canonical for a known typo,\n * otherwise the closest match within the threshold, otherwise null.\n */\nexport function suggestDomain(domain: string, options?: DomainSuggesterOptions): string | null {\n const lower = domain.toLowerCase();\n\n // Hand-curated typo map first — beats similarity for common cases.\n const known = TYPO_LOOKUP.get(lower);\n if (known) return known;\n\n const domains = options?.customDomains ?? COMMON_DOMAINS;\n if (domains.includes(lower)) return null;\n\n const threshold = options?.threshold ?? 2;\n let minDistance = Infinity;\n let suggestion: string | null = null;\n\n for (const candidate of domains) {\n const candidateLower = candidate.toLowerCase();\n if (lower === candidateLower) return null;\n const similarity = stringSimilarity(lower, candidateLower);\n const distance = Math.round((1 - similarity) * Math.max(domain.length, candidate.length));\n if (distance > 0 && distance <= threshold && distance < minDistance) {\n minDistance = distance;\n suggestion = candidate;\n }\n }\n return suggestion;\n}\n\n/**\n * Validate one email — syntax / typo / disposable / free / MX (if a resolver\n * is supplied). Each step is independently flag-gated so callers pay only for\n * what they use.\n */\nexport async function validateEmailCore(\n email: string,\n options?: ValidateEmailOptions & { dnsResolver?: DNSResolver }\n): Promise<EmailValidationResult> {\n const normalized = email.toLowerCase().trim();\n\n if (!options?.skipCache) {\n const cached = validationCache.get(normalized);\n if (cached) return cached;\n }\n\n const result: EmailValidationResult = { valid: false, email: normalized, validators: {} };\n\n if (options?.validateSyntax !== false) {\n const syntaxValid = VALID_EMAIL_REGEX.test(normalized);\n result.validators.syntax = { valid: syntaxValid };\n if (!syntaxValid) {\n validationCache.set(normalized, result);\n return result;\n }\n }\n\n const [local, domain] = normalized.split('@');\n result.local = local;\n result.domain = domain;\n\n if (options?.validateTypo !== false) {\n const suggestion = suggestDomain(domain, options?.domainSuggesterOptions);\n result.validators.typo = { valid: !suggestion, suggestion: suggestion ?? undefined };\n }\n\n if (options?.validateDisposable !== false) {\n result.validators.disposable = { valid: !disposableProviders.includes(domain) };\n }\n\n if (options?.validateFree !== false) {\n result.validators.free = { valid: !freeProviders.includes(domain) };\n }\n\n if (options?.validateMx && options.dnsResolver) {\n try {\n const records = await options.dnsResolver.resolveMx(domain);\n const hasMx = records.length > 0;\n result.validators.mx = {\n valid: hasMx,\n records: hasMx ? records.map((r) => r.exchange) : undefined,\n };\n } catch (error) {\n result.validators.mx = {\n valid: false,\n error: error instanceof Error ? error.message : 'MX validation failed',\n };\n }\n }\n\n // Free-provider detection is informational; only the hard validators gate validity.\n result.valid = (['syntax', 'typo', 'disposable', 'mx'] as const).every((key) => {\n const validator = result.validators[key];\n return !validator || validator.valid !== false;\n });\n\n if (!options?.skipCache) validationCache.set(normalized, result);\n return result;\n}\n\nexport async function validateEmailBatch(\n emails: string[],\n options?: ValidateEmailOptions & { dnsResolver?: DNSResolver }\n): Promise<EmailValidationResult[]> {\n const chunkSize = options?.batchSize ?? 10;\n const results: EmailValidationResult[] = [];\n for (let i = 0; i < emails.length; i += chunkSize) {\n const chunk = emails.slice(i, i + chunkSize);\n const chunkResults = await Promise.all(chunk.map((email) => validateEmailCore(email, options)));\n results.push(...chunkResults);\n }\n return results;\n}\n\nexport function clearCache(): void {\n validationCache.clear();\n mxCache.clear();\n}\n\nexport type { DomainSuggesterOptions, EmailValidationResult, ValidateEmailOptions } from '../types';\n","import type { EmailValidationResult } from '../../types';\nimport { validateEmailBatch, validateEmailCore } from '../verifier';\nimport type { ValidationDispatch } from './validation';\n\n/**\n * Execute a classified request against the core validator. Single-email\n * requests yield one result; batch requests yield an array.\n */\nexport async function executeValidation(\n dispatch: ValidationDispatch\n): Promise<EmailValidationResult | EmailValidationResult[]> {\n if (dispatch.kind === 'single') {\n return validateEmailCore(dispatch.email, dispatch.options);\n }\n return validateEmailBatch(dispatch.emails, dispatch.options);\n}\n","import type { ValidateEmailOptions } from '../../types';\n\n/** Hard limit on batch size enforced by every adapter. */\nexport const MAX_BATCH_SIZE = 100;\n\n/** Shape of POST bodies and Lambda invocations across all serverless adapters. */\nexport interface ValidationRequestBody {\n email?: string;\n emails?: string[];\n options?: ValidateEmailOptions;\n}\n\nexport type ValidationDispatch =\n | { kind: 'single'; email: string; options?: ValidateEmailOptions }\n | { kind: 'batch'; emails: string[]; options?: ValidateEmailOptions };\n\nexport interface ValidationFailure {\n kind: 'invalid';\n status: 400;\n message: string;\n}\n\n/**\n * Validation for endpoints that accept ONLY a batch (`emails`). Returns\n * a 400 failure if emails is missing/empty/oversized, or null when valid.\n * Routed `/validate/batch` paths use this so error messages stay batch-specific.\n */\nexport type BatchValidation = { ok: true; emails: string[] } | { ok: false; status: 400; message: string };\n\nexport function validateBatchEmailsField(emails: unknown): BatchValidation {\n if (!Array.isArray(emails) || emails.length === 0) {\n return { ok: false, status: 400, message: 'Emails array is required' };\n }\n if (emails.length > MAX_BATCH_SIZE) {\n return { ok: false, status: 400, message: `Maximum ${MAX_BATCH_SIZE} emails allowed per batch` };\n }\n return { ok: true, emails: emails as string[] };\n}\n\n/**\n * Apply the rules every serverless adapter shares:\n * 1. body must request either `email` or `emails`\n * 2. `emails` must be a non-empty array of ≤ MAX_BATCH_SIZE entries\n *\n * Centralising this means a future rule change (say, raising the cap) lands\n * in one place instead of three.\n */\nexport function classifyRequest(\n body: ValidationRequestBody | null | undefined\n): ValidationDispatch | ValidationFailure {\n if (!body || (!body.email && !body.emails)) {\n return { kind: 'invalid', status: 400, message: 'Email or emails array is required' };\n }\n if (body.emails) {\n if (!Array.isArray(body.emails) || body.emails.length === 0) {\n return { kind: 'invalid', status: 400, message: 'Emails array is required' };\n }\n if (body.emails.length > MAX_BATCH_SIZE) {\n return { kind: 'invalid', status: 400, message: `Maximum ${MAX_BATCH_SIZE} emails allowed per batch` };\n }\n return { kind: 'batch', emails: body.emails, options: body.options };\n }\n // body.email must be set per the first guard (which checks both fields).\n if (!body.email) {\n return { kind: 'invalid', status: 400, message: 'Email or emails array is required' };\n }\n return { kind: 'single', email: body.email, options: body.options };\n}\n","/**\n * Vercel adapter — three handler shapes for three runtime / routing combos:\n *\n * - `handler` — routed Web handler — `/api/health`, `/api/validate`,\n * `/api/validate/batch`. Wire as `app/api/[...path]/route.ts`.\n * - `edgeHandler` — single-route Edge handler. Pick this when each URL\n * maps to its own Edge Function (no internal routing).\n * - `nodeHandler` — Express-style `(req, res)` for the Node.js runtime.\n * Pick this when you're on the Node runtime and your\n * framework hands you `VercelRequest` / `VercelResponse`.\n *\n * Shared validation/CORS logic comes from `../_shared/`.\n */\nimport type { ValidateEmailOptions } from '../../types';\nimport { corsHeaders, jsonHeaders } from '../_shared/cors';\nimport { executeValidation } from '../_shared/dispatch';\nimport { classifyRequest, type ValidationRequestBody, validateBatchEmailsField } from '../_shared/validation';\nimport { validateEmailBatch, validateEmailCore } from '../verifier';\n\nexport interface VercelRequest {\n method: string;\n url: string;\n headers: Headers;\n body?: unknown;\n query?: { [key: string]: string | string[] };\n}\n\nexport interface VercelResponse {\n status: (code: number) => VercelResponse;\n json: (data: unknown) => void;\n send: (data: unknown) => void;\n}\n\nconst POST_HEADERS = jsonHeaders(corsHeaders('POST, GET, OPTIONS'));\nconst ROUTED_HEADERS = jsonHeaders({\n 'Access-Control-Allow-Origin': '*',\n 'Cache-Control': 'no-store, max-age=0',\n 'X-Powered-By': 'Vercel Edge Functions',\n});\n\nfunction jsonResponse(status: number, body: unknown, headers: Record<string, string> = POST_HEADERS): Response {\n return new Response(JSON.stringify(body), { status, headers });\n}\n\nfunction parseGetParams(url: URL): ValidationRequestBody {\n const email = url.searchParams.get('email');\n const emails = url.searchParams.get('emails');\n return {\n email: email || undefined,\n emails: emails ? emails.split(',') : undefined,\n options: {\n validateMx: url.searchParams.get('validateMx') === 'true',\n validateSMTP: url.searchParams.get('validateSMTP') === 'true',\n validateTypo: url.searchParams.get('validateTypo') !== 'false',\n validateDisposable: url.searchParams.get('validateDisposable') !== 'false',\n validateFree: url.searchParams.get('validateFree') !== 'false',\n },\n };\n}\n\n// Edge Runtime handler — no path routing, `email`/`emails` from body or query.\nexport async function edgeHandler(request: Request): Promise<Response> {\n if (request.method === 'OPTIONS') {\n return new Response(null, { status: 200, headers: corsHeaders('POST, GET, OPTIONS') });\n }\n\n try {\n let body: ValidationRequestBody;\n if (request.method === 'GET') {\n body = parseGetParams(new URL(request.url));\n } else if (request.method === 'POST') {\n body = await request.json();\n } else {\n return jsonResponse(405, { success: false, error: 'Method not allowed' });\n }\n\n const classified = classifyRequest(body);\n if (classified.kind === 'invalid') {\n return jsonResponse(classified.status, { success: false, error: classified.message });\n }\n\n const data = await executeValidation(classified);\n return jsonResponse(\n 200,\n { success: true, data },\n jsonHeaders({ ...corsHeaders('POST, GET, OPTIONS'), 'Cache-Control': 'public, max-age=3600' })\n );\n } catch (error) {\n console.error('Vercel Edge error:', error);\n const message = error instanceof Error ? error.message : 'Internal server error';\n return jsonResponse(500, { success: false, error: message });\n }\n}\n\n// Node.js runtime handler (Express-style).\nexport async function nodeHandler(req: VercelRequest, res: VercelResponse): Promise<void> {\n if (req.method === 'OPTIONS') {\n res.status(200).send('');\n return;\n }\n\n try {\n let body: ValidationRequestBody;\n if (req.method === 'GET') {\n const fakeUrl = new URL(req.url, 'http://localhost');\n body = parseGetParams(fakeUrl);\n // Fall back to the parsed query map if the URL was relative without params.\n if (!body.email && !body.emails && req.query) {\n body.email = req.query.email as string | undefined;\n body.emails = req.query.emails ? (req.query.emails as string).split(',') : undefined;\n }\n } else if (req.method === 'POST') {\n body = req.body as ValidationRequestBody;\n } else {\n res.status(405).json({ success: false, error: 'Method not allowed' });\n return;\n }\n\n const classified = classifyRequest(body);\n if (classified.kind === 'invalid') {\n res.status(classified.status).json({ success: false, error: classified.message });\n return;\n }\n const data = await executeValidation(classified);\n res.status(200).json({ success: true, data });\n } catch (error) {\n console.error('Vercel Node error:', error);\n res.status(500).json({ success: false, error: error instanceof Error ? error.message : 'Internal server error' });\n }\n}\n\nexport const config = {\n runtime: 'edge',\n regions: ['iad1'],\n};\n\nfunction requireJsonContentType(request: Request): Response | null {\n const contentType = request.headers.get('content-type');\n if (!contentType?.includes('application/json')) {\n return jsonResponse(400, { error: 'Content-Type must be application/json' }, ROUTED_HEADERS);\n }\n return null;\n}\n\nasync function readJsonBody(request: Request): Promise<{ body: unknown } | { error: Response }> {\n try {\n return { body: await request.json() };\n } catch {\n return { error: jsonResponse(400, { error: 'Invalid request body' }, ROUTED_HEADERS) };\n }\n}\n\n// Routed handler used by the test suite — `/api/health`, `/api/validate`,\n// `/api/validate/batch`.\nexport async function handler(request: Request): Promise<Response> {\n const url = new URL(request.url);\n const { pathname } = url;\n\n if (request.method === 'OPTIONS') {\n return new Response(null, { status: 204, headers: corsHeaders() });\n }\n\n try {\n if (pathname === '/api/health' && request.method === 'GET') {\n return jsonResponse(\n 200,\n { status: 'healthy', platform: 'vercel', timestamp: new Date().toISOString() },\n ROUTED_HEADERS\n );\n }\n\n const isValidatePath = pathname === '/api/validate' || pathname === '/api/validate/batch';\n if (isValidatePath && request.method !== 'POST') {\n return jsonResponse(405, { error: 'Method not allowed' }, ROUTED_HEADERS);\n }\n\n if (pathname === '/api/validate' && request.method === 'POST') {\n const ct = requireJsonContentType(request);\n if (ct) return ct;\n const parsed = await readJsonBody(request);\n if ('error' in parsed) return parsed.error;\n const body = parsed.body as { email?: string };\n if (!body.email) return jsonResponse(400, { error: 'Email is required' }, ROUTED_HEADERS);\n\n const options: Partial<ValidateEmailOptions> = {};\n if (url.searchParams.has('skipCache')) options.skipCache = url.searchParams.get('skipCache') === 'true';\n if (url.searchParams.has('validateTypo')) options.validateTypo = url.searchParams.get('validateTypo') === 'true';\n\n const result = await validateEmailCore(body.email, options);\n return jsonResponse(200, result, ROUTED_HEADERS);\n }\n\n if (pathname === '/api/validate/batch' && request.method === 'POST') {\n const ct = requireJsonContentType(request);\n if (ct) return ct;\n const parsed = await readJsonBody(request);\n if ('error' in parsed) return parsed.error;\n const body = parsed.body as ValidationRequestBody;\n const validated = validateBatchEmailsField(body.emails);\n if (!validated.ok) return jsonResponse(validated.status, { error: validated.message }, ROUTED_HEADERS);\n\n const options: { batchSize?: number } = {};\n const batchSizeParam = url.searchParams.get('batchSize');\n if (batchSizeParam) options.batchSize = parseInt(batchSizeParam, 10);\n\n const results = await validateEmailBatch(validated.emails, options);\n return jsonResponse(200, { results }, ROUTED_HEADERS);\n }\n\n return jsonResponse(404, { error: 'Not found' }, ROUTED_HEADERS);\n } catch (error) {\n console.error('Handler error:', error);\n return jsonResponse(500, { error: 'Internal server error' }, ROUTED_HEADERS);\n }\n}\n\nexport default {\n edgeHandler,\n nodeHandler,\n handler,\n};\n"],"names":["__spreadValues","exports","stringSimilarity","__async"],"mappings":"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","x_google_ignoreList":[1]}