{"version":3,"sources":["../src/parts.ts"],"sourcesContent":["import {\n  styles,\n  normStr,\n  tokens,\n  memoParts,\n  clockAgnostic,\n  clock24,\n  specDate,\n  clock12,\n  fractionalSeconds,\n} from \"./common\"\nimport type {\n  ParseOptions,\n  Format,\n  Part,\n  FormatStyle,\n  FormatStyleObj,\n  FormatPattern,\n  NamedFormats,\n  NamedFormatOption,\n} from \"./types\"\n/**\n * Given a format string, produce an array of matching \"parts\", each part\n * contains a regular expression and the corresponding\n * Intl.DateTimeFormatPartTypesRegistry key/value.\n * @param format - A format string like MM/DD/YYYY\n * @param locale - The locale to parse for.\n */\nexport function parts(format: Format, locale: string): Part[] {\n  if (styles.includes(format as FormatStyle) || typeof format === \"object\") {\n    return styleParts(format as FormatStyle | FormatStyleObj, locale)\n  }\n  let f = format\n  let match = 0\n  const testPattern = (pattern: FormatPattern) => {\n    if (!pattern[2]) pattern[2] = new RegExp(`(.)?(${pattern[0]})`, \"g\")\n    if (pattern[2].test(f)) {\n      let didAdd = 0\n      f = f.replace(pattern[2], (_, prefix, actualMatch) => {\n        if (prefix === \"\\\\\") return actualMatch\n        return `${typeof prefix === \"string\" ? prefix : \"\"}{!${\n          didAdd++ ? match : match++\n        }!}`\n      })\n      return !!didAdd\n    }\n    return false\n  }\n\n  function validate(patterns: Part[]): Part[] {\n    const parts = patterns.map((part) => part.partName)\n    const deduped = new Set(parts)\n    if (parts.length > deduped.size) {\n      throw new Error(`Cannot reuse format tokens.`)\n    }\n    return patterns\n  }\n\n  function createPart(\n    hour12: boolean,\n    [token, option, exp]: FormatPattern\n  ): Part {\n    const partName = Object.keys(option)[0] as Intl.DateTimeFormatPartTypes\n    const partValue = option[partName] as string\n    return {\n      option,\n      partName,\n      partValue,\n      token,\n      pattern: exp as RegExp,\n      hour12,\n    }\n  }\n\n  const found24Patterns = clockAgnostic\n    .filter(testPattern)\n    .concat(clock24.filter(testPattern))\n    .concat(fractionalSeconds.filter(testPattern))\n    .map(createPart.bind(null, false))\n\n  // Reset the format before re-checking\n  const parts = validate(\n    found24Patterns.concat(\n      clock12.filter(testPattern).map(createPart.bind(null, true))\n    )\n  )\n  const extractIndex = /^\\{!(\\d+)!\\}$/\n  return f\n    .split(/(\\{!\\d+!\\})/)\n    .map((match: string): Part => {\n      const hasIndex = match.match(extractIndex)\n      if (hasIndex) {\n        return parts[Number(hasIndex[1])]\n      }\n      return {\n        option: { literal: match },\n        partName: \"literal\",\n        partValue: match,\n        token: match,\n        pattern: new RegExp(\"\"),\n        hour12: false,\n      }\n    })\n    .filter((part) => !(part.partName === \"literal\" && part.partValue === \"\"))\n}\n\n/**\n * Determines the parts in a native date style, like \"full\".\n * @param format - A date style like \"full\" or \"short\"\n * @param locale - The locale string\n */\nfunction styleParts(\n  format: FormatStyle | FormatStyleObj,\n  locale: string\n): Part[] {\n  const options: Intl.DateTimeFormatOptions = {\n    timeZone: \"UTC\",\n  }\n  if (typeof format === \"string\") {\n    options.dateStyle = format\n  } else {\n    if (\"date\" in format) options.dateStyle = format.date\n    if (\"time\" in format) options.timeStyle = format.time\n  }\n\n  const formatter = new Intl.DateTimeFormat(locale, options)\n  const segments = formatter.formatToParts(new Date(specDate)).map(normStr)\n  const hourTypeSegments = formatter\n    .formatToParts(new Date(\"1999-04-05T23:05:01.000Z\"))\n    .map(normStr)\n  const hourPart = hourTypeSegments.find((segment) => segment.type === \"hour\")\n  const hourType = hourPart && hourPart.value === \"23\" ? 24 : 12\n  return segments\n    .map((part): Part | undefined => {\n      const partName = part.type\n      const formatPattern = guessPattern(\n        part.type,\n        part.value,\n        locale,\n        part.type === \"hour\" ? hourType : undefined,\n        options\n      )\n      if (formatPattern === undefined) return\n      const partValue = formatPattern[1][partName]\n      if (!partValue) return\n      if (!formatPattern[2])\n        formatPattern[2] = new RegExp(`${formatPattern[0]}`, \"g\")\n      return {\n        option: { [partName]: partValue },\n        partName,\n        partValue,\n        token: formatPattern[0],\n        pattern: formatPattern[2],\n        hour12: hourType === 12,\n      }\n    })\n    .filter((part): part is Part => !!part)\n}\n\n/**\n * Attempts to guess the correct part value type for a given dateStyle. For\n * example a month of 02 would be \"2-digit\".\n *\n * @param partName - The part name to guess for, like 'year' or 'month'\n * @param partValue - The current value, it is assumed this is the smallest denom.\n */\nfunction guessPattern<T extends Intl.DateTimeFormatPartTypes>(\n  partName: T,\n  partValue: string,\n  locale: string,\n  hour: T extends \"hour\" ? 12 | 24 : undefined,\n  options: Intl.DateTimeFormatOptions\n): FormatPattern | undefined {\n  const l = partValue.length\n  const n = !isNaN(Number(partValue))\n  let style: NamedFormatOption | undefined\n  /* eslint-disable @typescript-eslint/no-non-null-assertion */\n  switch (partName) {\n    case \"year\":\n      return l === 2 ? tokens.get(\"YY\") : tokens.get(\"YYYY\")\n    case \"month\":\n      if (n) return l === 1 ? tokens.get(\"M\") : tokens.get(\"MM\")\n      style = partStyle(locale, partName, partValue)\n      switch (style) {\n        case \"long\":\n          return tokens.get(\"MMMM\")\n        default:\n          return tokens.get(\"MMM\")\n      }\n    case \"day\":\n      return l === 1 ? tokens.get(\"D\") : tokens.get(\"DD\")\n    case \"weekday\":\n      style = partStyle(locale, partName, partValue)\n      switch (style) {\n        case \"narrow\":\n          return tokens.get(\"d\")\n        case \"short\":\n          return tokens.get(\"ddd\")\n        default:\n          return tokens.get(\"dddd\")\n      }\n    case \"hour\":\n      // Need to distinguish the locale’s default as 24 or 12 hour.\n      if (hour === 12) return l === 1 ? tokens.get(\"h\") : tokens.get(\"hh\")\n      return l === 1 ? tokens.get(\"H\") : tokens.get(\"HH\")\n    case \"minute\":\n      return l === 1 ? tokens.get(\"m\") : tokens.get(\"mm\")\n    case \"second\":\n      return l === 1 ? tokens.get(\"s\") : tokens.get(\"ss\")\n    case \"dayPeriod\":\n      return /^[A-Z]+$/u.test(partValue) ? tokens.get(\"A\") : tokens.get(\"a\")\n    case \"literal\":\n      return [partValue, { literal: partValue }, new RegExp(\"\")]\n    case \"timeZoneName\":\n      return options.timeStyle === \"full\" ? tokens.get(\"Z\") : tokens.get(\"ZZ\")\n    default:\n      return undefined\n  }\n  /* eslint-enable @typescript-eslint/no-non-null-assertion */\n}\n\n/**\n * Determines what \"style\" a given part is in. For example, if you provide:\n * ```js\n * partStyle('en', 'month', 'Jan')\n * // returns \"short\".\n * ```\n * Part styles are always expected to be \"genitive\" — for use in \"dateStyle\".\n * @param locale - Locale string\n * @param part - The part to attempt a lookup on\n * @param value - The value of a given part.\n */\nfunction partStyle(\n  locale: string,\n  part: keyof NamedFormats,\n  value: string\n): NamedFormatOption | undefined {\n  if (!memoParts.has(locale)) {\n    const date = new Date(specDate)\n    const weekdays = [3, 8, 9, 7, 6, 4, 3]\n    const parts = [\"weekday\", \"month\", \"dayPeriod\"]\n    const partStyles: NamedFormatOption[] = [\"long\", \"short\", \"narrow\"]\n    const formats: Partial<NamedFormats> = {}\n    for (let i = 0; i < 12; i++) {\n      date.setMonth(0 + i)\n      if (i in weekdays) date.setDate(weekdays[i])\n      date.setUTCHours(8 + i)\n      for (const style of partStyles) {\n        const segments = new Intl.DateTimeFormat(\n          locale,\n          parts.reduce(\n            (options, part) => Object.assign(options, { [part]: style }),\n            { hour12: true, timeZone: \"UTC\" }\n          )\n        )\n          .formatToParts(date)\n          .map(normStr)\n        if (style === \"long\" || style === \"short\") {\n          const genitiveFormattedParts = new Intl.DateTimeFormat(locale, {\n            dateStyle: style === \"short\" ? \"medium\" : \"long\",\n            timeZone: \"UTC\",\n          })\n            .formatToParts(date)\n            .map(normStr)\n          const genitiveMonth = genitiveFormattedParts.find(\n            (part) => part.type === \"month\"\n          )\n          const index = segments.findIndex((part) => part.type === \"month\")\n          if (index > -1 && genitiveMonth) segments[index] = genitiveMonth\n        }\n        segments.forEach((part) => {\n          if (part.type === \"literal\") return\n          const type = part.type as keyof NamedFormats\n          formats[type] = Object.assign(formats[type] || {}, {\n            [part.value]: style,\n          })\n        })\n      }\n    }\n    memoParts.set(locale, formats as NamedFormats)\n  }\n  const formats = memoParts.get(locale)\n  return formats ? formats[part][value] : undefined\n}\n"],"mappings":"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","names":["parts","match","formats","part"]}