{"version":3,"sources":["../src/normalization.ts","../src/detection.ts"],"names":["safeIntlSupported","isNode","isBrowser"],"mappings":"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","file":"detection.cjs","sourcesContent":["import { safeIntlSupported } from \"@multisystemsuite/timezone-engine-utils\";\n\nconst DISPLAY_SUFFIX_PATTERN = /\\s*\\(.*\\)\\s*$/;\n\n/**\n * Strip any display suffix from a timezone string and return a bare IANA id.\n *\n * @example\n * normalizeTimezone(\"America/New_York (GMT-5:00)\") // \"America/New_York\"\n * normalizeTimezone(\"Asia/Kolkata (GMT+5:30)\")     // \"Asia/Kolkata\"\n * normalizeTimezone(\"\")                            // \"UTC\"\n */\nexport function normalizeTimezone(timeZone: string | null | undefined): string {\n  if (!timeZone) return \"UTC\";\n  const stripped = timeZone.replace(DISPLAY_SUFFIX_PATTERN, \"\").trim();\n  return stripped || \"UTC\";\n}\n\n/** Validate a bare IANA timezone id using the runtime Intl implementation */\nexport function isValidIanaTimezone(timeZone: string): boolean {\n  if (!safeIntlSupported()) return true;\n  try {\n    Intl.DateTimeFormat(undefined, { timeZone });\n    return true;\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Normalise and validate in one step. Returns the IANA id if valid,\n * otherwise returns the fallback and logs a warning.\n */\nexport function safeTimezone(timeZone: string | null | undefined, fallback = \"UTC\"): string {\n  const tz = normalizeTimezone(timeZone);\n  if (isValidIanaTimezone(tz)) return tz;\n  console.warn(\n    `[timezone-engine] Invalid timezone \"${String(timeZone)}\" (normalised: \"${tz}\"), falling back to ${fallback}`,\n  );\n  return fallback;\n}\n\n/**\n * Sanitise a timezone value before saving it to the database.\n * Strips any display suffix so only the bare IANA id is persisted.\n *\n * @example\n * site.TimeZone = sanitizeTimezoneForDB(req.body.TimeZone);\n */\nexport function sanitizeTimezoneForDB(timeZone: string | null | undefined): string {\n  return safeTimezone(timeZone);\n}\n","import type {\n  DetectTimezoneResult,\n  Environment,\n} from \"@multisystemsuite/timezone-engine-shared-types\";\nimport { isBrowser, isNode, safeIntlSupported } from \"@multisystemsuite/timezone-engine-utils\";\nimport { isValidIanaTimezone, normalizeTimezone } from \"./normalization.js\";\n\nconst DEFAULT_TIMEZONE = \"UTC\";\n\nfunction detectViaIntl(): string | undefined {\n  if (!safeIntlSupported()) return undefined;\n  try {\n    return Intl.DateTimeFormat().resolvedOptions().timeZone;\n  } catch {\n    return undefined;\n  }\n}\n\nfunction detectViaEnv(): string | undefined {\n  if (isNode()) {\n    return process.env[\"TZ\"] ?? process.env[\"DEFAULT_TIMEZONE\"];\n  }\n  return undefined;\n}\n\nfunction getEnvironment(): Environment {\n  if (isBrowser()) return \"browser\";\n  if (isNode()) return \"node\";\n  return \"ssr\";\n}\n\n/** Detect timezone in browser environment */\nexport function detectBrowserTimezone(): DetectTimezoneResult {\n  const timezone = detectViaIntl() ?? DEFAULT_TIMEZONE;\n  return { timezone, source: \"intl\", environment: \"browser\" };\n}\n\n/** Detect timezone in Node.js environment */\nexport function detectNodeTimezone(): DetectTimezoneResult {\n  const envTz = detectViaEnv();\n  const timezone = envTz ?? detectViaIntl() ?? DEFAULT_TIMEZONE;\n  return {\n    timezone,\n    source: envTz ? \"env\" : \"intl\",\n    environment: \"node\",\n  };\n}\n\n/** Detect server timezone */\nexport function detectServerTimezone(defaultTimezone = DEFAULT_TIMEZONE): DetectTimezoneResult {\n  const envTz = detectViaEnv();\n  const timezone = envTz ?? defaultTimezone;\n  return {\n    timezone,\n    source: envTz ? \"env\" : \"config\",\n    environment: isNode() ? \"node\" : \"ssr\",\n  };\n}\n\n/** Universal timezone detection — SSR-safe */\nexport function detectTimezone(fallback = DEFAULT_TIMEZONE): DetectTimezoneResult {\n  const intlTz = detectViaIntl();\n  const envTz = detectViaEnv();\n\n  if (intlTz) {\n    return { timezone: intlTz, source: \"intl\", environment: getEnvironment() };\n  }\n  if (envTz) {\n    return { timezone: envTz, source: \"env\", environment: getEnvironment() };\n  }\n  return { timezone: fallback, source: \"config\", environment: getEnvironment() };\n}\n\n/** Get user's current timezone */\nexport function getUserTimezone(fallback = DEFAULT_TIMEZONE): string {\n  return detectTimezone(fallback).timezone;\n}\n\n/** Resolve timezone from header, cookie, or query param value */\nexport function resolveTimezoneFromValue(\n  value: string | undefined,\n  fallback = DEFAULT_TIMEZONE,\n): DetectTimezoneResult {\n  const normalized = normalizeTimezone(value);\n  if (value && isValidTimezone(normalized)) {\n    return { timezone: normalized, source: \"header\", environment: getEnvironment() };\n  }\n  return detectTimezone(fallback);\n}\n\n/**\n * Validate that a timezone string (after normalisation) is a valid IANA id\n * recognised by the runtime Intl implementation.\n */\nexport function isValidTimezone(timeZone: string | null | undefined): boolean {\n  const tz = normalizeTimezone(timeZone);\n  return isValidIanaTimezone(tz);\n}\n\n/** List all supported IANA timezones via Intl */\nexport function listSupportedTimezones(): string[] {\n  if (typeof Intl.supportedValuesOf === \"function\") {\n    return Intl.supportedValuesOf(\"timeZone\");\n  }\n  return [];\n}\n"]}