//#region src/index.ts
var I18nConfigError = class extends Error {
	offending;
	constructor(message, offending) {
		super(message);
		this.offending = offending;
		this.name = "I18nConfigError";
	}
};
function createI18n(config) {
	if (!config.locales.includes(config.defaultLocale)) throw new I18nConfigError(`createI18n: defaultLocale "${config.defaultLocale}" not in locales [${config.locales.join(", ")}]`, {
		defaultLocale: config.defaultLocale,
		locales: config.locales
	});
	for (const locale of config.locales) if (!Object.hasOwn(config.messages, locale)) throw new I18nConfigError(`createI18n: messages missing entry for locale "${locale}"`, {
		missingLocale: locale,
		locales: config.locales
	});
	return Object.freeze({ ...config });
}
const TOKEN = /\{(\w+)\}/g;
function resolveMessage(table, key) {
	if (!table) return void 0;
	const direct = table[key];
	if (typeof direct === "string") return direct;
	if (!key.includes(".")) return void 0;
	let cur = table;
	for (const part of key.split(".")) {
		if (cur == null || typeof cur !== "object") return void 0;
		cur = cur[part];
	}
	return typeof cur === "string" ? cur : void 0;
}
function t(i18n, locale, key, vars) {
	let str = resolveMessage(i18n.messages[locale] ?? i18n.messages[i18n.defaultLocale], key) ?? resolveMessage(i18n.messages[i18n.defaultLocale], key) ?? key;
	if (vars) str = str.replace(TOKEN, (_m, k) => Object.hasOwn(vars, k) ? String(vars[k]) : `{${k}}`);
	return str;
}
function resolveLocale(i18n, request) {
	const seg = new URL(request.url).pathname.split("/")[1];
	if (seg && i18n.locales.includes(seg)) return seg;
	const m = (request.headers.get("cookie") ?? "").match(/(?:^|;\s*)locale=([^;]+)/);
	if (m && i18n.locales.includes(m[1])) return m[1];
	const al = request.headers.get("accept-language") ?? "";
	for (const part of al.split(",")) {
		const code = part.trim().split(/[-;]/)[0];
		if (code && i18n.locales.includes(code)) return code;
	}
	return i18n.defaultLocale;
}
//#endregion
export { I18nConfigError, createI18n, resolveLocale, t };
