{"version":3,"file":"datetime.cjs","sources":["../src/datetime.ts"],"sourcesContent":["import { NanointlPlugin } from './makeIntl';\nimport { ExternalParser } from './parse';\nimport { ExternalSerializer } from './serialize';\nimport type { TopLevelBracketsGroup, OptionalSpacingSymbolSequence } from './typings';\n\ntype SkeletonPart =\n  | 'G' //\tEra designator\n  | 'y' //\tyear\n  | 'M' //\tmonth in year\n  | 'd' //\tday in month\n  | 'E' //\tday of week\n  | 'j' //\tHour\n  | 'h' //\tHour [1-12]\n  | 'H' //\tHour [0-23]\n  | 'm' //\tMinute\n  | 's' //\tSecond\n  | 'z'; //\tTime Zone\nconst skeletonChartsMap: { [Char in SkeletonPart]: true } = {\n  G: true,\n  y: true,\n  M: true,\n  d: true,\n  E: true,\n  j: true,\n  h: true,\n  H: true,\n  m: true,\n  s: true,\n  z: true,\n};\ntype Display = 'short' | 'medium' | 'long' | 'full';\n\nexport type DateTimeSerializationParams = Intl.DateTimeFormatOptions;\n\nexport const parseDateTime: ExternalParser<DateTimeSerializationParams> = (template, variableName, verboseInput) => {\n  if (template.trim() === 'verbose') return verboseInput;\n  if (!template.trim().startsWith('::')) {\n    const display: Intl.DateTimeFormatOptions['timeStyle'] = ['short', 'medium', 'long', 'full'].includes(\n      template.trim().toLowerCase(),\n    )\n      ? (template.trim().toLowerCase() as Display)\n      : 'medium';\n\n    return {\n      dateStyle: display,\n      timeStyle: display,\n    };\n  } else {\n    const skeleton = template.split('::')[1].trim();\n    const parts: (\n      | string\n      | {\n          partName: SkeletonPart;\n          size: number;\n        }\n    )[] = [];\n    let lastChar: string | null = null;\n    let lastPart: typeof parts[0] | null = null;\n    for (let i = 0; i < skeleton.length; i++) {\n      const char = skeleton[i];\n      if (!(char in skeletonChartsMap)) {\n        if (typeof lastPart === 'string') {\n          lastPart += char;\n        } else if (lastPart === null) {\n          lastPart = char;\n        } else {\n          if (lastPart) parts.push(lastPart);\n          lastPart = char;\n        }\n      } else {\n        if (typeof lastPart === 'string') {\n          parts.push(lastPart);\n        }\n        if (typeof lastPart === 'string' || lastPart === null) {\n          lastPart = { partName: char as SkeletonPart, size: 1 };\n        } else if (lastChar === char) {\n          lastPart.size++;\n        } else if (lastChar !== char) {\n          parts.push(lastPart);\n          lastPart = { partName: char as SkeletonPart, size: 1 };\n        }\n      }\n      lastChar = char;\n    }\n    if (lastPart !== null) {\n      parts.push(lastPart);\n    }\n    const result: Intl.DateTimeFormatOptions = {};\n    for (const part of parts) {\n      if (typeof part === 'string') continue;\n      if (part.partName === 'G') {\n        result.era = (['narrow', 'short', 'long'] as const)[part.size - 1];\n      } else if (part.partName === 'y') {\n        result.year = ([undefined, '2-digit', undefined, 'numeric'] as const)[part.size - 1];\n      } else if (part.partName === 'M') {\n        result.month = (['numeric', '2-digit', 'short', 'long', 'narrow'] as const)[part.size - 1];\n      } else if (part.partName === 'd') {\n        result.day = (['numeric', '2-digit'] as const)[part.size - 1];\n      } else if (part.partName === 'E') {\n        result.weekday = (['narrow', 'short', 'long'] as const)[part.size - 1];\n      } else if (part.partName === 'h') {\n        result.hour = (['numeric', '2-digit'] as const)[part.size - 1];\n        result.hour12 = true;\n      } else if (part.partName === 'H') {\n        result.hour = (['numeric', '2-digit'] as const)[part.size - 1];\n        result.hour12 = false;\n      } else if (part.partName === 'j') {\n        result.hour = (['numeric', '2-digit'] as const)[part.size - 1];\n        result.hour12 = undefined;\n      } else if (part.partName === 'm') {\n        result.minute = (['numeric', '2-digit'] as const)[part.size - 1];\n      } else if (part.partName === 's') {\n        result.second = (['numeric', '2-digit'] as const)[part.size - 1];\n      } else if (part.partName === 'z') {\n        result.timeZoneName = (['short', 'shortGeneric', 'long', 'longGeneric'] as const)[part.size - 1];\n      } else {\n        throw new Error(\n          `Token \"${part.partName}\" is not supported for template \"${template}\" of variable \"${variableName}\" interpolation`,\n        );\n      }\n    }\n\n    return result;\n  }\n};\n\nconst normalizeDate = (providedDate: unknown) => {\n  if (typeof providedDate === 'number') return new Date(providedDate);\n  if (typeof providedDate === 'string') return new Date(providedDate);\n  if (typeof providedDate === 'object' && providedDate instanceof Date) return providedDate;\n\n  return new Date('Invalid date');\n};\n\nexport const serializeDate: ExternalSerializer<DateTimeSerializationParams> = (params, variableValue, intl) => {\n  const date = normalizeDate(variableValue);\n  const dateTimeFormat = intl.makeDateTimeFormat(params ?? { year: 'numeric', month: 'numeric', day: 'numeric' });\n\n  return dateTimeFormat.format(date);\n};\n\nexport const serializeTime: ExternalSerializer<DateTimeSerializationParams> = (params, variableValue, intl) => {\n  const date = normalizeDate(variableValue);\n  const dateTimeFormat = intl.makeDateTimeFormat(params ?? { timeStyle: 'medium' });\n\n  return dateTimeFormat.format(date);\n};\n\nexport const dateTimePlugin: NanointlPlugin<DateTimeSerializationParams> = {\n  name: 'dateTime-plugin',\n  init(options) {\n    options.addParser('date', parseDateTime);\n    options.addParser('time', parseDateTime);\n    options.addSerializer('date', serializeDate);\n    options.addSerializer('time', serializeTime);\n  },\n};\n\ntype DateOrTimeToken = 'date' | 'time';\ntype DateTimeParser<Template extends string> =\n  TopLevelBracketsGroup<Template> extends `{${infer SelectVariable},${OptionalSpacingSymbolSequence}${DateOrTimeToken}}`\n    ? SelectVariable extends `${string}{${string}`\n      ? { vars: [] }\n      : { vars: [{ name: SelectVariable; type: Date }] }\n    : // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    TopLevelBracketsGroup<Template> extends `{${infer SelectVariable},${OptionalSpacingSymbolSequence}${DateOrTimeToken},${infer DateTimeOptions}}`\n    ? { vars: [{ name: SelectVariable; type: Date }] }\n    : { vars: [] };\n\ndeclare global {\n  interface NanointlBracketsParsers<Template extends string> {\n    dateTime: DateTimeParser<Template>;\n  }\n}\n"],"names":["skeletonChartsMap","G","y","M","d","E","j","h","H","m","s","z","parseDateTime","template","variableName","verboseInput","trim","startsWith","skeleton","split","parts","lastChar","lastPart","i","length","char","push","partName","size","result","part","_parts","_i","era","year","undefined","month","day","weekday","hour","hour12","minute","second","Error","timeZoneName","display","includes","toLowerCase","dateStyle","timeStyle","providedDate","Date","serializeDate","params","variableValue","intl","normalizeDate","makeDateTimeFormat","format","date","serializeTime","name","init","options","addParser","addSerializer"],"mappings":"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"}