{"version":3,"sources":["../src/core.ts","../src/metadata.ts","../src/reachability.ts","../src/format.ts","../src/asYouType.ts"],"sourcesContent":["import { getMetadata, type CountryMetadata, type TypePattern } from './metadata.js';\nimport { getProvider } from './reachability.js';\nimport { ParseErrorCode, type AsyncParseResult, type ParseResult, type PhoneNumber } from './types.js';\n\nexport { format, type FormatStyle } from './format.js';\nexport { asYouType } from './asYouType.js';\nexport { getCountries, getCountryCallingCode, isSupportedCountry } from './metadata.js';\n\nconst MIN_DIGIT_LENGTH = 4;\nconst MAX_DIGIT_LENGTH = 15; // E.164 maximum\nconst MAX_CALLING_CODE_LENGTH = 3;\n\nconst SANITIZE_PATTERN = /[\\s\\-().]/g;\n\ninterface CallingCodeGroup {\n  callingCode: string;\n  regions: CountryMetadata[];\n}\n\n// E.164 calling codes are a prefix-free code by design, so trying\n// shortest-to-longest and taking the first match is correct, not just\n// convenient - no valid calling code is a prefix of another. A calling\n// code can be shared by several regions (e.g. NANP's \"1\"), so this\n// returns every region sharing the matched code, not just one.\nconst findCallingCodeGroup = (digits: string): CallingCodeGroup | undefined => {\n  const regions = Object.values(getMetadata());\n  for (let length = 1; length <= MAX_CALLING_CODE_LENGTH; length++) {\n    const candidate = digits.slice(0, length);\n    const matches = regions.filter((region) => region.callingCode === candidate);\n    if (matches.length > 0) {\n      return { callingCode: candidate, regions: matches };\n    }\n  }\n  return undefined;\n};\n\n// Checked in this order, first match wins - these types are specific\n// enough that a real number shouldn't match more than one.\nconst TYPE_PRIORITY = [\n  'PREMIUM_RATE',\n  'TOLL_FREE',\n  'SHARED_COST',\n  'VOIP',\n  'PERSONAL_NUMBER',\n  'PAGER',\n  'UAN',\n  'VOICEMAIL',\n] as const satisfies ReadonlyArray<keyof NonNullable<CountryMetadata['types']>>;\n\nconst patternMatches = (nationalNumber: string, pattern: TypePattern): boolean =>\n  pattern.possibleLengths.includes(nationalNumber.length) && new RegExp(pattern.nationalNumberPattern).test(nationalNumber);\n\n// MOBILE/FIXED are checked last, and separately from TYPE_PRIORITY, because\n// upstream data sometimes makes them identical (e.g. the US) - in that case\n// this reports 'FIXED_LINE_OR_MOBILE' rather than arbitrarily picking one.\nconst classifyType = (nationalNumber: string, region: CountryMetadata): PhoneNumber['type'] | undefined => {\n  const types = region.types;\n  if (!types) {\n    return undefined;\n  }\n\n  for (const key of TYPE_PRIORITY) {\n    const pattern = types[key];\n    if (pattern && patternMatches(nationalNumber, pattern)) {\n      return key;\n    }\n  }\n\n  const isMobile = types.MOBILE && patternMatches(nationalNumber, types.MOBILE);\n  const isFixed = types.FIXED && patternMatches(nationalNumber, types.FIXED);\n  if (isMobile && isFixed) {\n    return 'FIXED_LINE_OR_MOBILE';\n  }\n  if (isMobile) {\n    return 'MOBILE';\n  }\n  if (isFixed) {\n    return 'FIXED';\n  }\n\n  return undefined;\n};\n\ninterface ResolvedRegion {\n  region: CountryMetadata;\n  type: PhoneNumber['type'];\n}\n\n// Of the regions sharing a calling code, find the one whose length and\n// pattern actually validate this national number. Real area codes don't\n// collide across regions sharing a calling code, so at most one matches.\n// A region counts as a match if ANY of its type-specific patterns match\n// (not just the general one) - this is what correctly accepts numbers\n// like US toll-free, which don't share fixed-line's area-code structure.\nconst matchRegion = (nationalNumber: string, regions: CountryMetadata[]): ResolvedRegion | undefined => {\n  for (const region of regions) {\n    const type = classifyType(nationalNumber, region);\n    if (type) {\n      return { region, type };\n    }\n    // No type-specific data (or none matched): fall back to the general\n    // pattern, same as before per-type data existed.\n    if (\n      region.possibleLengths.includes(nationalNumber.length) &&\n      new RegExp(region.nationalNumberPattern).test(nationalNumber)\n    ) {\n      return { region, type: 'UNKNOWN' };\n    }\n  }\n  return undefined;\n};\n\nexport const parse = (input: string, defaultCountry?: string): ParseResult => {\n  const sanitized = input.replace(SANITIZE_PATTERN, '');\n\n  // TODO: use `defaultCountry` to resolve national-format numbers (no\n  // leading '+') into a calling code via metadata.\n  if (!sanitized.startsWith('+')) {\n    return {\n      success: false,\n      error: ParseErrorCode.NOT_A_NUMBER,\n      message: 'Number must be in E.164 format (leading \"+\") until metadata support lands',\n    };\n  }\n\n  const digits = sanitized.slice(1);\n\n  if (!/^\\d+$/.test(digits)) {\n    return {\n      success: false,\n      error: ParseErrorCode.NOT_A_NUMBER,\n      message: 'Number must contain only digits after the leading \"+\"',\n    };\n  }\n\n  if (digits.length < MIN_DIGIT_LENGTH) {\n    return {\n      success: false,\n      error: ParseErrorCode.TOO_SHORT,\n      message: `Number must have at least ${MIN_DIGIT_LENGTH} digits`,\n    };\n  }\n\n  if (digits.length > MAX_DIGIT_LENGTH) {\n    return {\n      success: false,\n      error: ParseErrorCode.TOO_LONG,\n      message: `Number must have at most ${MAX_DIGIT_LENGTH} digits`,\n    };\n  }\n\n  const group = findCallingCodeGroup(digits);\n\n  // No metadata injected, or this calling code isn't covered by whatever\n  // was injected: fall back to format-only validation. Metadata is a\n  // plugin - not having it for a given number isn't an error.\n  if (!group) {\n    return {\n      success: true,\n      data: {\n        e164: sanitized,\n        countryCode: 0,\n        region: null,\n        nationalNumber: digits,\n        type: 'UNKNOWN',\n      },\n    };\n  }\n\n  const nationalNumber = digits.slice(group.callingCode.length);\n\n  // Aggregate across every region sharing this calling code, and every\n  // type-specific pattern within each region, so a length that's out of\n  // range for *all* of them is still reported as TOO_SHORT/TOO_LONG\n  // rather than a generic \"not a number\".\n  const allLengths = group.regions.flatMap((region) => [\n    ...region.possibleLengths,\n    ...Object.values(region.types ?? {}).flatMap((pattern) => pattern.possibleLengths),\n  ]);\n  const minLength = Math.min(...allLengths);\n  const maxLength = Math.max(...allLengths);\n\n  if (nationalNumber.length < minLength) {\n    return {\n      success: false,\n      error: ParseErrorCode.TOO_SHORT,\n      message: `National number must have at least ${minLength} digits for calling code +${group.callingCode}`,\n    };\n  }\n\n  if (nationalNumber.length > maxLength) {\n    return {\n      success: false,\n      error: ParseErrorCode.TOO_LONG,\n      message: `National number must have at most ${maxLength} digits for calling code +${group.callingCode}`,\n    };\n  }\n\n  const resolved = matchRegion(nationalNumber, group.regions);\n\n  if (!resolved) {\n    return {\n      success: false,\n      error: ParseErrorCode.NOT_A_NUMBER,\n      message: `National number is not valid for calling code +${group.callingCode}`,\n    };\n  }\n\n  return {\n    success: true,\n    data: {\n      e164: sanitized,\n      countryCode: Number(group.callingCode),\n      region: resolved.region.region,\n      nationalNumber,\n      type: resolved.type,\n    },\n  };\n};\n\nexport const isValid = (input: string, country?: string): boolean => {\n  return parse(input, country).success;\n};\n\n// Validates first, then optionally enriches with a live lookup - never\n// spends a network call on a number that's already known to be invalid.\n// Never throws: a provider error is indistinguishable from no provider\n// being configured at all (both surface as `reachability: null`), which\n// keeps this consistent with the rest of the library's no-try/catch\n// contract.\nexport const asyncParse = async (input: string, defaultCountry?: string): Promise<AsyncParseResult> => {\n  const result = parse(input, defaultCountry);\n  if (!result.success) {\n    return result;\n  }\n\n  const provider = getProvider();\n  if (!provider) {\n    return { ...result, reachability: null };\n  }\n\n  try {\n    const reachability = await provider.lookup(result.data);\n    return { ...result, reachability };\n  } catch {\n    return { ...result, reachability: null };\n  }\n};","export interface TypePattern {\n  nationalNumberPattern: string;\n  possibleLengths: number[];\n}\n\nexport interface FormatRule {\n  // Full-match regex with capture groups, e.g. \"(\\d{3})(\\d{4})\".\n  pattern: string;\n  // Template using $1/$2/... for the capture groups, e.g. \"$1 $2\".\n  format: string;\n  // How the national prefix combines with the first group in NATIONAL\n  // format specifically, e.g. \"$NP$FG\" ($NP = nationalPrefix, $FG = the\n  // raw first group) - omitted means NATIONAL format has no prefix at all.\n  // Never applies to INTERNATIONAL format.\n  nationalPrefixFormattingRule?: string;\n  // Overrides `format` for INTERNATIONAL style specifically. The literal\n  // value \"NA\" means this rule should be skipped entirely for\n  // INTERNATIONAL (try the next matching rule) - e.g. local-only formats\n  // that omit the area code aren't valid once you need to dial\n  // internationally. Omitted (not \"NA\") means reuse `format` as-is.\n  intlFormat?: string;\n  // Upstream declaration order, least to most specific - each is a\n  // stricter refinement of the one before it, not an independent\n  // alternative. Only used by asYouType() to pick a candidate rule before\n  // enough digits exist for `pattern` to fully match; `format()` doesn't\n  // need this since it only ever formats complete numbers.\n  leadingDigits?: string[];\n}\n\nexport interface CountryMetadata {\n  // ISO 3166-1 alpha-2, e.g. \"US\". Kept on the value itself (not just as\n  // the object key) because callers group entries by calling code - once\n  // grouped, the original object key is gone.\n  region: string;\n  callingCode: string;\n  // General/fallback pattern - used directly when a type-specific match\n  // isn't available (e.g. a region without per-type data yet).\n  nationalNumberPattern: string;\n  possibleLengths: number[];\n  // Per-type patterns, each optional since not every region's upstream\n  // data distinguishes all of these (e.g. many small territories have no\n  // separate pager/uan/voicemail block at all).\n  types?: {\n    MOBILE?: TypePattern;\n    FIXED?: TypePattern;\n    TOLL_FREE?: TypePattern;\n    PREMIUM_RATE?: TypePattern;\n    SHARED_COST?: TypePattern;\n    PERSONAL_NUMBER?: TypePattern;\n    VOIP?: TypePattern;\n    PAGER?: TypePattern;\n    UAN?: TypePattern;\n    VOICEMAIL?: TypePattern;\n  };\n  // e.g. \"0\" for GB, \"1\" for NANP. Absent for regions with no national\n  // dialing prefix.\n  nationalPrefix?: string;\n  // In upstream declaration order - first full match against the national\n  // number wins, same resolution order as Google's own algorithm.\n  formats?: FormatRule[];\n}\n\nexport interface Metadata {\n  // Keyed by region, not calling code: a calling code can map to several\n  // regions (e.g. NANP's \"1\" covers US, Canada, and ~19 Caribbean\n  // territories), so calling code can't be a unique key.\n  [region: string]: CountryMetadata;\n}\n\n// Global state for injected metadata, initialized empty\nlet _metadata: Metadata = {};\n\nexport const setup = (config: { metadata: Metadata }) => {\n  _metadata = config.metadata;\n};\n\nexport const getMetadata = (): Metadata => _metadata;\n\n// These three all read whatever's currently injected via setup() - not\n// the full set of countries DialSense ships in data/, which this module\n// has no knowledge of at runtime. A country is only \"supported\" once its\n// metadata has actually been passed to setup().\nexport const getCountries = (): string[] => Object.keys(_metadata);\n\nexport const getCountryCallingCode = (country: string): number | undefined => {\n  const region = _metadata[country];\n  return region ? Number(region.callingCode) : undefined;\n};\n\nexport const isSupportedCountry = (country: string): boolean => country in _metadata;","import type { PhoneNumber } from './types.js';\n\n// Live-lookup counterpart to metadata.ts's static country data: this is\n// the plugin point for real-time telephony intelligence (HLR-style\n// reachability, carrier/porting/roaming status, CNAM, fraud/risk scoring)\n// that static regex patterns fundamentally can't provide - e.g. `parse()`\n// can never resolve `PhoneNumber.type` past 'UNKNOWN' for countries where\n// mobile and fixed-line share the same numbering pattern, but a live\n// lookup can. DialSense ships the interface, not an implementation -\n// consumers plug in their own provider.\nexport interface ReachabilityResult {\n  reachable: boolean | null;\n  lineType: 'MOBILE' | 'FIXED' | 'VOIP' | 'UNKNOWN';\n  carrierName: string | null;\n  ported: boolean | null;\n  roaming: boolean | null;\n  callerName: string | null;\n  riskScore: number | null;\n}\n\nexport interface IReachabilityProvider {\n  lookup(phoneNumber: PhoneNumber): Promise<ReachabilityResult>;\n}\n\nlet _provider: IReachabilityProvider | null = null;\n\nexport const configure = (config: { provider: IReachabilityProvider | null }) => {\n  _provider = config.provider;\n};\n\nexport const getProvider = (): IReachabilityProvider | null => _provider;\n","import { getMetadata, type CountryMetadata, type FormatRule } from './metadata.js';\nimport type { PhoneNumber } from './types.js';\n\nexport type FormatStyle = 'NATIONAL' | 'INTERNATIONAL' | 'E164';\n\nconst applyTemplate = (template: string, groups: string[]): string =>\n  template.replace(/\\$(\\d)/g, (_match, index: string) => groups[Number(index) - 1] ?? '');\n\ninterface RuleMatch {\n  rule: FormatRule;\n  groups: string[];\n}\n\n// `skipNA` is only relevant for INTERNATIONAL - a rule's `intlFormat` of\n// exactly \"NA\" means \"don't use this rule internationally, try the next\n// matching one\" (e.g. a local-only format that omits the area code).\nconst findMatchingRule = (nationalNumber: string, rules: FormatRule[], skipNA: boolean): RuleMatch | undefined => {\n  for (const rule of rules) {\n    if (skipNA && rule.intlFormat === 'NA') {\n      continue;\n    }\n    const match = nationalNumber.match(new RegExp(`^(?:${rule.pattern})$`));\n    if (match) {\n      return { rule, groups: match.slice(1) };\n    }\n  }\n  return undefined;\n};\n\nconst formatNational = (nationalNumber: string, region: CountryMetadata): string => {\n  const found = findMatchingRule(nationalNumber, region.formats ?? [], false);\n  if (!found) {\n    return nationalNumber;\n  }\n  const { rule, groups } = found;\n\n  if (!rule.nationalPrefixFormattingRule) {\n    return applyTemplate(rule.format, groups);\n  }\n\n  // Only the first group gets prefix-wrapped - e.g. rule \"$NP$FG\" with\n  // nationalPrefix \"0\" and first group \"10\" produces \"010\", which then\n  // substitutes wherever `format` uses \"$1\".\n  const prefixedFirstGroup = rule.nationalPrefixFormattingRule\n    .replace('$NP', region.nationalPrefix ?? '')\n    .replace('$FG', groups[0] ?? '');\n  return applyTemplate(rule.format, [prefixedFirstGroup, ...groups.slice(1)]);\n};\n\nconst formatInternational = (nationalNumber: string, region: CountryMetadata): string => {\n  const found = findMatchingRule(nationalNumber, region.formats ?? [], true);\n  const grouped = found ? applyTemplate(found.rule.intlFormat ?? found.rule.format, found.groups) : nationalNumber;\n  return `+${region.callingCode} ${grouped}`;\n};\n\n// Falls back to the unformatted national number (NATIONAL) or plain\n// e164 (INTERNATIONAL/E164 with no region resolved) rather than\n// throwing - consistent with the rest of this library treating missing\n// metadata as \"can't do better,\" not an error.\nexport const format = (phoneNumber: PhoneNumber, style: FormatStyle): string => {\n  if (style === 'E164') {\n    return phoneNumber.e164;\n  }\n\n  const region = phoneNumber.region ? getMetadata()[phoneNumber.region] : undefined;\n  if (!region) {\n    return phoneNumber.e164;\n  }\n\n  if (style === 'NATIONAL') {\n    return formatNational(phoneNumber.nationalNumber, region);\n  }\n\n  return formatInternational(phoneNumber.nationalNumber, region);\n};\n","import { getMetadata, type FormatRule } from './metadata.js';\n\nconst SANITIZE_PATTERN = /[^\\d]/g;\n\n// Long enough that any real leadingDigits pattern can complete a full\n// match attempt against typed digits, however few there are.\nconst PREFIX_TEST_PADDING = '0'.repeat(20);\n\n// Tests whether `typed` (a prefix of an eventual number) is consistent\n// with `leadingDigitsPattern` - not the same as a normal regex test,\n// since `typed` may be too short for the pattern to match on its own yet.\n// Padding lets the pattern attempt a full match; because the regex is\n// anchored at the start and the padded string's first `typed.length`\n// characters are exactly what was typed, any successful match proves the\n// real typed digits are consistent with the pattern - whether it matched\n// entirely within them already, or needed padding to finish. A failed\n// match means the real digits already contradict the pattern.\nconst isPrefixCompatible = (typed: string, leadingDigitsPattern: string): boolean =>\n  new RegExp(`^(?:${leadingDigitsPattern})`).test(typed + PREFIX_TEST_PADDING);\n\n// Parses \"(\\d{3})(\\d{4})\" into fixed group lengths [3, 4]. Returns\n// undefined for patterns that don't decompose into simple fixed-length\n// digit groups - rather than guess, those rules just aren't used for\n// live formatting (falls back to plain digits if nothing else matches).\nconst parseGroupLengths = (pattern: string): number[] | undefined => {\n  const groups = [...pattern.matchAll(/\\(\\\\d\\{(\\d+)\\}\\)/g)];\n  return groups.length > 0 ? groups.map((g) => Number(g[1])) : undefined;\n};\n\n// Among rules consistent with the digits typed so far, prefers the one\n// with the LARGEST total capacity - not simply the first declared. e.g.\n// US has both a 7-digit local-only rule and the standard 10-digit rule;\n// a number starting with digits compatible with both should format\n// progressively as the 10-digit one (confirmed against a documented real\n// example: formatting \"2133734\" produces \"(213) 373-4\", the partial\n// 10-digit grouping, not the 7-digit dash format) - only falling back to\n// a shorter/more specific rule once it's the only one still compatible\n// (e.g. once more than 7 digits have been typed).\nconst findCandidateRule = (typedDigits: string, rules: FormatRule[]): FormatRule | undefined => {\n  let best: { rule: FormatRule; capacity: number } | undefined;\n\n  for (const rule of rules) {\n    const groupLengths = parseGroupLengths(rule.pattern);\n    if (!groupLengths) {\n      continue;\n    }\n\n    // Reject rules that can't hold what's already been typed -\n    // leadingDigits compatibility alone isn't enough, since a short\n    // leadingDigits pattern (e.g. \"310\") can be satisfied well before the\n    // digit count exceeds that rule's total capacity.\n    const capacity = groupLengths.reduce((sum, n) => sum + n, 0);\n    if (typedDigits.length > capacity) {\n      continue;\n    }\n\n    // A rule with no leadingDigits at all is always compatible (some\n    // rules don't have any). Otherwise, only the *last* entry is tested -\n    // upstream documents each as a stricter refinement of the one\n    // before it, not an independent alternative.\n    const leadingDigits = rule.leadingDigits;\n    const compatible =\n      !leadingDigits || leadingDigits.length === 0 || isPrefixCompatible(typedDigits, leadingDigits.at(-1) ?? '');\n    if (!compatible) {\n      continue;\n    }\n\n    if (!best || capacity > best.capacity) {\n      best = { rule, capacity };\n    }\n  }\n\n  return best?.rule;\n};\n\n// Splits a format template like \"($1) $2-$3\" into the literal text\n// around each placeholder: [\"(\", \") \", \"-\"] - index 0 is whatever\n// precedes $1, each following entry is what comes between that group and\n// the next.\nconst parseSeparators = (format: string): string[] => format.split(/\\$\\d/);\n\nconst buildLiveFormat = (typedDigits: string, rule: FormatRule, nationalPrefix: string | undefined): string => {\n  const groupLengths = parseGroupLengths(rule.pattern) ?? [];\n  const separators = parseSeparators(rule.format);\n\n  let result = separators[0] ?? '';\n  let remaining = typedDigits;\n\n  for (let i = 0; i < groupLengths.length && remaining.length > 0; i++) {\n    let chunk = remaining.slice(0, groupLengths[i]);\n    remaining = remaining.slice(groupLengths[i]);\n\n    if (i === 0 && rule.nationalPrefixFormattingRule) {\n      chunk = rule.nationalPrefixFormattingRule.replace('$NP', nationalPrefix ?? '').replace('$FG', chunk);\n    }\n\n    result += chunk;\n    if (remaining.length > 0) {\n      result += separators[i + 1] ?? '';\n    }\n  }\n\n  return result;\n};\n\n// A pure function, not a stateful class: called fresh with the full\n// accumulated input each time (like a controlled input's current value),\n// not incrementally fed one digit at a time with hidden state to manage.\n// Deletion needs no special handling as a result - calling this with a\n// shorter string just recomputes correctly, since there's nothing to\n// reset.\nexport const asYouType = (inputSoFar: string, region: string): string => {\n  const typedDigits = inputSoFar.replace(SANITIZE_PATTERN, '');\n  const metadata = getMetadata()[region];\n  const rules = metadata?.formats ?? [];\n\n  const rule = findCandidateRule(typedDigits, rules);\n  if (!rule) {\n    return typedDigits;\n  }\n\n  return buildLiveFormat(typedDigits, rule, metadata?.nationalPrefix);\n};\n"],"mappings":"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","names":["format","SANITIZE_PATTERN"]}