{"version":3,"file":"config-C3EBstHi.mjs","names":[],"sources":["../src/i18n/config.ts"],"sourcesContent":["/**\n * EmDash i18n Configuration\n *\n * Reads locale configuration from the virtual module (sourced from Astro config).\n * Initialized during runtime startup, then available via getI18nConfig().\n */\n\nexport interface I18nConfig {\n\tdefaultLocale: string;\n\tlocales: string[];\n\tfallback?: Record<string, string>;\n\tprefixDefaultLocale?: boolean;\n}\n\nexport const LOCALE_CODE_PATTERN = /^[a-z]{2,3}(-[a-z0-9]{2,8})*$/i;\n\nconst I18N_CONFIG_KEY = Symbol.for(\"emdash:i18n-config\");\n\nfunction configStore(): Record<symbol, I18nConfig | null | undefined> {\n\treturn globalThis;\n}\n\n/**\n * Initialize i18n config from virtual module data.\n * Called during runtime initialization.\n */\nexport function setI18nConfig(config: I18nConfig | null): void {\n\tconfigStore()[I18N_CONFIG_KEY] = config;\n}\n\n/**\n * Get the current i18n config.\n * Returns null if i18n is not configured.\n */\nexport function getI18nConfig(): I18nConfig | null {\n\treturn configStore()[I18N_CONFIG_KEY] ?? null;\n}\n\n/** Match a locale to the exact casing used by the site configuration. */\nexport function resolveConfiguredLocale(locale: string): string {\n\tconst config = getI18nConfig();\n\treturn (\n\t\tconfig?.locales.find((configured) => configured.toLowerCase() === locale.toLowerCase()) ??\n\t\tlocale\n\t);\n}\n\n/** Whether a string matches the locale-code subset accepted by EmDash. */\nexport function isValidLocaleCode(locale: string): boolean {\n\treturn LOCALE_CODE_PATTERN.test(locale);\n}\n\n/** Resolve the locale for a new content row. */\nexport function resolveContentCreateLocale(\n\tlocale: unknown,\n\tconfig: I18nConfig | null = getI18nConfig(),\n): string {\n\tif (locale !== undefined) {\n\t\tif (typeof locale !== \"string\") {\n\t\t\tthrow new Error(\"Invalid locale code: expected a string\");\n\t\t}\n\t\tif (!isValidLocaleCode(locale)) {\n\t\t\tthrow new Error(`Invalid locale code: \"${locale}\"`);\n\t\t}\n\n\t\tconst configured = config?.locales.find(\n\t\t\t(candidate) => candidate.toLowerCase() === locale.toLowerCase(),\n\t\t);\n\t\tif (config && !configured) {\n\t\t\tthrow new Error(`Locale \"${locale}\" is not configured for this site`);\n\t\t}\n\t\treturn configured ?? locale;\n\t}\n\n\treturn config?.defaultLocale ?? \"en\";\n}\n\n/**\n * Check if i18n is enabled.\n * Returns true when multiple locales are configured.\n */\nexport function isI18nEnabled(): boolean {\n\tconst config = getI18nConfig();\n\treturn config != null && config.locales.length > 1;\n}\n\n/**\n * Resolve fallback locale chain for a given locale.\n * Returns array of locales to try, from most preferred to least.\n * Always ends with defaultLocale.\n */\nexport function getFallbackChain(locale: string): string[] {\n\tconst config = getI18nConfig();\n\tif (!config) return [locale];\n\n\tconst chain: string[] = [locale];\n\tlet current = locale;\n\tconst visited = new Set<string>([locale]);\n\n\twhile (config.fallback?.[current]) {\n\t\t// eslint-disable-next-line typescript/no-unnecessary-type-assertion -- noUncheckedIndexedAccess\n\t\tconst next = config.fallback[current]!;\n\t\tif (visited.has(next)) break; // prevent cycles\n\t\tchain.push(next);\n\t\tvisited.add(next);\n\t\tcurrent = next;\n\t}\n\n\t// Always end with defaultLocale if not already in chain\n\tif (!visited.has(config.defaultLocale)) {\n\t\tchain.push(config.defaultLocale);\n\t}\n\n\treturn chain;\n}\n"],"mappings":";AAcA,MAAa,sBAAsB;AAEnC,MAAM,kBAAkB,OAAO,IAAI,qBAAqB;AAExD,SAAS,cAA6D;AACrE,QAAO;;;;;;AAOR,SAAgB,cAAc,QAAiC;AAC9D,cAAa,CAAC,mBAAmB;;;;;;AAOlC,SAAgB,gBAAmC;AAClD,QAAO,aAAa,CAAC,oBAAoB;;;AAI1C,SAAgB,wBAAwB,QAAwB;AAE/D,QADe,eAAe,EAErB,QAAQ,MAAM,eAAe,WAAW,aAAa,KAAK,OAAO,aAAa,CAAC,IACvF;;;AAKF,SAAgB,kBAAkB,QAAyB;AAC1D,QAAO,oBAAoB,KAAK,OAAO;;;AAIxC,SAAgB,2BACf,QACA,SAA4B,eAAe,EAClC;AACT,KAAI,WAAW,QAAW;AACzB,MAAI,OAAO,WAAW,SACrB,OAAM,IAAI,MAAM,yCAAyC;AAE1D,MAAI,CAAC,kBAAkB,OAAO,CAC7B,OAAM,IAAI,MAAM,yBAAyB,OAAO,GAAG;EAGpD,MAAM,aAAa,QAAQ,QAAQ,MACjC,cAAc,UAAU,aAAa,KAAK,OAAO,aAAa,CAC/D;AACD,MAAI,UAAU,CAAC,WACd,OAAM,IAAI,MAAM,WAAW,OAAO,mCAAmC;AAEtE,SAAO,cAAc;;AAGtB,QAAO,QAAQ,iBAAiB;;;;;;AAOjC,SAAgB,gBAAyB;CACxC,MAAM,SAAS,eAAe;AAC9B,QAAO,UAAU,QAAQ,OAAO,QAAQ,SAAS;;;;;;;AAQlD,SAAgB,iBAAiB,QAA0B;CAC1D,MAAM,SAAS,eAAe;AAC9B,KAAI,CAAC,OAAQ,QAAO,CAAC,OAAO;CAE5B,MAAM,QAAkB,CAAC,OAAO;CAChC,IAAI,UAAU;CACd,MAAM,UAAU,IAAI,IAAY,CAAC,OAAO,CAAC;AAEzC,QAAO,OAAO,WAAW,UAAU;EAElC,MAAM,OAAO,OAAO,SAAS;AAC7B,MAAI,QAAQ,IAAI,KAAK,CAAE;AACvB,QAAM,KAAK,KAAK;AAChB,UAAQ,IAAI,KAAK;AACjB,YAAU;;AAIX,KAAI,CAAC,QAAQ,IAAI,OAAO,cAAc,CACrC,OAAM,KAAK,OAAO,cAAc;AAGjC,QAAO"}