@kamod-ch/otok-i18n 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +163 -0
  3. package/dist/catalog.d.ts +17 -0
  4. package/dist/catalog.d.ts.map +1 -0
  5. package/dist/catalog.js +38 -0
  6. package/dist/catalog.js.map +1 -0
  7. package/dist/client.d.ts +41 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +67 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/format.d.ts +5 -0
  12. package/dist/format.d.ts.map +1 -0
  13. package/dist/format.js +39 -0
  14. package/dist/format.js.map +1 -0
  15. package/dist/head.d.ts +18 -0
  16. package/dist/head.d.ts.map +1 -0
  17. package/dist/head.js +33 -0
  18. package/dist/head.js.map +1 -0
  19. package/dist/i18n.d.ts +24 -0
  20. package/dist/i18n.d.ts.map +1 -0
  21. package/dist/i18n.js +74 -0
  22. package/dist/i18n.js.map +1 -0
  23. package/dist/index.d.ts +18 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +16 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/interpolate.d.ts +7 -0
  28. package/dist/interpolate.d.ts.map +1 -0
  29. package/dist/interpolate.js +28 -0
  30. package/dist/interpolate.js.map +1 -0
  31. package/dist/loader.d.ts +23 -0
  32. package/dist/loader.d.ts.map +1 -0
  33. package/dist/loader.js +31 -0
  34. package/dist/loader.js.map +1 -0
  35. package/dist/locale-core.d.ts +19 -0
  36. package/dist/locale-core.d.ts.map +1 -0
  37. package/dist/locale-core.js +55 -0
  38. package/dist/locale-core.js.map +1 -0
  39. package/dist/locale.d.ts +33 -0
  40. package/dist/locale.d.ts.map +1 -0
  41. package/dist/locale.js +110 -0
  42. package/dist/locale.js.map +1 -0
  43. package/dist/messages.d.ts +9 -0
  44. package/dist/messages.d.ts.map +1 -0
  45. package/dist/messages.js +52 -0
  46. package/dist/messages.js.map +1 -0
  47. package/dist/middleware.d.ts +17 -0
  48. package/dist/middleware.d.ts.map +1 -0
  49. package/dist/middleware.js +121 -0
  50. package/dist/middleware.js.map +1 -0
  51. package/dist/plugin.d.ts +16 -0
  52. package/dist/plugin.d.ts.map +1 -0
  53. package/dist/plugin.js +55 -0
  54. package/dist/plugin.js.map +1 -0
  55. package/dist/plural.d.ts +5 -0
  56. package/dist/plural.d.ts.map +1 -0
  57. package/dist/plural.js +42 -0
  58. package/dist/plural.js.map +1 -0
  59. package/dist/registry.d.ts +27 -0
  60. package/dist/registry.d.ts.map +1 -0
  61. package/dist/registry.js +34 -0
  62. package/dist/registry.js.map +1 -0
  63. package/dist/routes.d.ts +26 -0
  64. package/dist/routes.d.ts.map +1 -0
  65. package/dist/routes.js +69 -0
  66. package/dist/routes.js.map +1 -0
  67. package/dist/sitemap.d.ts +25 -0
  68. package/dist/sitemap.d.ts.map +1 -0
  69. package/dist/sitemap.js +55 -0
  70. package/dist/sitemap.js.map +1 -0
  71. package/dist/switcher.d.ts +12 -0
  72. package/dist/switcher.d.ts.map +1 -0
  73. package/dist/switcher.js +17 -0
  74. package/dist/switcher.js.map +1 -0
  75. package/dist/types.d.ts +96 -0
  76. package/dist/types.d.ts.map +1 -0
  77. package/dist/types.js +2 -0
  78. package/dist/types.js.map +1 -0
  79. package/package.json +81 -0
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ export { createTranslator } from "./catalog.js";
2
+ export { i18nHead } from "./head.js";
3
+ export { buildI18nContext, createI18n, createI18nAsync } from "./i18n.js";
4
+ export { interpolate } from "./interpolate.js";
5
+ export { defineLoader, defineAction, serializeI18n } from "./loader.js";
6
+ export { DEFAULT_COOKIE_NAME, DEFAULT_PARAM_KEY, looksLikeLocaleSegment, matchLocale, normalizeLocale, parseAcceptLanguage, resolveLocale, resolveLocaleFromDomain, resolveLocaleFull, stripLocaleFromPath, } from "./locale.js";
7
+ export { clearMessageCache, getCachedMessages, loadLocaleMessages } from "./messages.js";
8
+ export { extractCount, pickPluralMessage, resolvePluralKey } from "./plural.js";
9
+ export { createI18nMiddleware, createI18nPluginMiddleware, configureI18nApp, readI18n, toRouteMiddleware, clearMessageCache as clearI18nMessageCache, } from "./middleware.js";
10
+ export { createFormatters, localeDirection } from "./format.js";
11
+ export { default } from "./plugin.js";
12
+ export { configureI18nApp as configureI18nPluginApp } from "./plugin.js";
13
+ export { createLinkHelper, localizePath, localizeRouteSegment, stripLocaleParam, switchLocalePath, withLocaleParam, } from "./routes.js";
14
+ export { clearI18nRuntime, getI18nRuntime, normalizePluginOptions, registerI18nRuntime, tryGetI18nRuntime, } from "./registry.js";
15
+ export { createLocalizedSitemapEntries, renderSitemapXml, } from "./sitemap.js";
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAA8D,MAAM,cAAc,CAAC;AAE5G,OAAO,EAAE,QAAQ,EAAwB,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,eAAe,EAAqC,MAAM,WAAW,CAAC;AAC7G,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,WAAW,EACX,eAAe,EACf,mBAAmB,EACnB,aAAa,EACb,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,GAIpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACzF,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,gBAAgB,EAChB,QAAQ,EACR,iBAAiB,EACjB,iBAAiB,IAAI,qBAAqB,GAC3C,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,gBAAgB,IAAI,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,GAEhB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,GAGlB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,6BAA6B,EAC7B,gBAAgB,GAIjB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { TranslateValues } from "./types.js";
2
+ /**
3
+ * Replace `{name}` placeholders safely (HTML-escaped values).
4
+ * Does not interpret HTML in the template — output is safe for text nodes.
5
+ */
6
+ export declare function interpolate(template: string, values?: TranslateValues): string;
7
+ //# sourceMappingURL=interpolate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interpolate.d.ts","sourceRoot":"","sources":["../src/interpolate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAkBlD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAE,eAAoB,GAAG,MAAM,CAKlF"}
@@ -0,0 +1,28 @@
1
+ function escapeHtml(value) {
2
+ return value
3
+ .replaceAll("&", "&")
4
+ .replaceAll("<", "&lt;")
5
+ .replaceAll(">", "&gt;")
6
+ .replaceAll('"', "&quot;")
7
+ .replaceAll("'", "&#39;");
8
+ }
9
+ function formatValue(value) {
10
+ if (value == null)
11
+ return "";
12
+ if (typeof value === "boolean")
13
+ return value ? "true" : "false";
14
+ const str = String(value);
15
+ return escapeHtml(str);
16
+ }
17
+ /**
18
+ * Replace `{name}` placeholders safely (HTML-escaped values).
19
+ * Does not interpret HTML in the template — output is safe for text nodes.
20
+ */
21
+ export function interpolate(template, values = {}) {
22
+ return template.replace(/\{(\w+)\}/g, (_match, key) => {
23
+ if (!(key in values))
24
+ return `{${key}}`;
25
+ return formatValue(values[key]);
26
+ });
27
+ }
28
+ //# sourceMappingURL=interpolate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interpolate.js","sourceRoot":"","sources":["../src/interpolate.ts"],"names":[],"mappings":"AAEA,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK;SACT,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC;SACxB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;SACvB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;SACvB,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC;SACzB,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,WAAW,CAAC,KAAmD;IACtE,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,EAAE,CAAC;IAC7B,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IAChE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1B,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB,EAAE,SAA0B,EAAE;IACxE,OAAO,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,GAAW,EAAE,EAAE;QAC5D,IAAI,CAAC,CAAC,GAAG,IAAI,MAAM,CAAC;YAAE,OAAO,IAAI,GAAG,GAAG,CAAC;QACxC,OAAO,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { LoaderResult, OtokActionContext, OtokContext, OtokLoader } from "@kamod-ch/otok/server";
2
+ import type { I18nContext } from "./types.js";
3
+ type LoaderI18nContext = {
4
+ i18n: I18nContext;
5
+ };
6
+ type ActionI18nContext = LoaderI18nContext;
7
+ /**
8
+ * Wrap a loader with typed `i18n` from the Hono context.
9
+ *
10
+ * ```ts
11
+ * export const loader = defineLoader(async ({ i18n }) => ({
12
+ * locale: i18n.locale,
13
+ * title: i18n.t("dashboard.welcome"),
14
+ * i18n: i18n.toClientPayload(),
15
+ * }));
16
+ * ```
17
+ */
18
+ export declare function defineLoader<Data extends LoaderResult>(handler: (ctx: OtokContext & LoaderI18nContext) => Data | Promise<Data>): OtokLoader<Data>;
19
+ export declare function defineAction<Result>(handler: (ctx: OtokActionContext & ActionI18nContext) => Result | Promise<Result>): (context: OtokActionContext) => Result | Promise<Result>;
20
+ /** Serialize i18n for client islands — call from loaders. */
21
+ export declare function serializeI18n(hono: OtokContext["hono"], contextKey?: string): import("./types.js").I18nClientPayload;
22
+ export {};
23
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEtG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,KAAK,iBAAiB,GAAG;IACvB,IAAI,EAAE,WAAW,CAAC;CACnB,CAAC;AAEF,KAAK,iBAAiB,GAAG,iBAAiB,CAAC;AAa3C;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,IAAI,SAAS,YAAY,EACpD,OAAO,EAAE,CAAC,GAAG,EAAE,WAAW,GAAG,iBAAiB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACtE,UAAU,CAAC,IAAI,CAAC,CAElB;AAED,wBAAgB,YAAY,CAAC,MAAM,EACjC,OAAO,EAAE,CAAC,GAAG,EAAE,iBAAiB,GAAG,iBAAiB,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAChF,CAAC,OAAO,EAAE,iBAAiB,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE1D;AAED,6DAA6D;AAC7D,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,UAAU,SAAS,0CAE3E"}
package/dist/loader.js ADDED
@@ -0,0 +1,31 @@
1
+ import { readI18n } from "./middleware.js";
2
+ function resolveI18n(hono, contextKey = "i18n") {
3
+ const ctx = readI18n(hono, contextKey);
4
+ if (!ctx) {
5
+ throw new Error("otok-i18n: defineLoader requires i18n() plugin or createI18nMiddleware(). " +
6
+ "Use loader: ({ hono }) => readI18n(hono) for manual wiring.");
7
+ }
8
+ return ctx;
9
+ }
10
+ /**
11
+ * Wrap a loader with typed `i18n` from the Hono context.
12
+ *
13
+ * ```ts
14
+ * export const loader = defineLoader(async ({ i18n }) => ({
15
+ * locale: i18n.locale,
16
+ * title: i18n.t("dashboard.welcome"),
17
+ * i18n: i18n.toClientPayload(),
18
+ * }));
19
+ * ```
20
+ */
21
+ export function defineLoader(handler) {
22
+ return (context) => handler({ ...context, i18n: resolveI18n(context.hono) });
23
+ }
24
+ export function defineAction(handler) {
25
+ return (context) => handler({ ...context, i18n: resolveI18n(context.hono) });
26
+ }
27
+ /** Serialize i18n for client islands — call from loaders. */
28
+ export function serializeI18n(hono, contextKey = "i18n") {
29
+ return resolveI18n(hono, contextKey).toClientPayload();
30
+ }
31
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAS3C,SAAS,WAAW,CAAC,IAAyB,EAAE,UAAU,GAAG,MAAM;IACjE,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACvC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,4EAA4E;YAC1E,6DAA6D,CAChE,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAuE;IAEvE,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,OAAiF;IAEjF,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC/E,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,aAAa,CAAC,IAAyB,EAAE,UAAU,GAAG,MAAM;IAC1E,OAAO,WAAW,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,eAAe,EAAE,CAAC;AACzD,CAAC"}
@@ -0,0 +1,19 @@
1
+ export type LocaleSource = "url" | "domain" | "cookie" | "header" | "default";
2
+ export interface ResolveLocaleOptions {
3
+ param?: string | undefined;
4
+ cookie?: string | undefined;
5
+ acceptLanguage?: string | undefined;
6
+ locales: readonly string[];
7
+ defaultLocale: string;
8
+ }
9
+ export interface ResolvedLocale {
10
+ locale: string;
11
+ source: LocaleSource;
12
+ }
13
+ export declare const DEFAULT_PARAM_KEY = "lang";
14
+ export declare const DEFAULT_COOKIE_NAME = "locale";
15
+ export declare function normalizeLocale(value: string | undefined | null): string | undefined;
16
+ export declare function matchLocale(candidate: string | undefined, locales: readonly string[]): string | undefined;
17
+ export declare function parseAcceptLanguage(header: string | undefined, locales: readonly string[]): string | undefined;
18
+ export declare function resolveLocale(options: ResolveLocaleOptions): ResolvedLocale;
19
+ //# sourceMappingURL=locale-core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale-core.d.ts","sourceRoot":"","sources":["../src/locale-core.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE9E,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,eAAO,MAAM,iBAAiB,SAAS,CAAC;AACxC,eAAO,MAAM,mBAAmB,WAAW,CAAC;AAE5C,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAIpF;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAUzG;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAmB9G;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,cAAc,CAc3E"}
@@ -0,0 +1,55 @@
1
+ export const DEFAULT_PARAM_KEY = "lang";
2
+ export const DEFAULT_COOKIE_NAME = "locale";
3
+ export function normalizeLocale(value) {
4
+ if (value == null)
5
+ return undefined;
6
+ const trimmed = value.trim().toLowerCase();
7
+ return trimmed.length > 0 ? trimmed : undefined;
8
+ }
9
+ export function matchLocale(candidate, locales) {
10
+ const normalized = normalizeLocale(candidate);
11
+ if (!normalized)
12
+ return undefined;
13
+ const exact = locales.find((locale) => normalizeLocale(locale) === normalized);
14
+ if (exact)
15
+ return exact;
16
+ const primary = normalized.split("-")[0];
17
+ if (!primary || primary === normalized)
18
+ return undefined;
19
+ return locales.find((locale) => normalizeLocale(locale) === primary);
20
+ }
21
+ export function parseAcceptLanguage(header, locales) {
22
+ if (!header)
23
+ return undefined;
24
+ const tags = header
25
+ .split(",")
26
+ .map((part) => {
27
+ const [tag, ...params] = part.trim().split(";");
28
+ const qParam = params.find((p) => p.trim().startsWith("q="));
29
+ const q = qParam ? Number.parseFloat(qParam.trim().slice(2)) : 1;
30
+ return { tag: tag?.trim() ?? "", q: Number.isFinite(q) ? q : 0 };
31
+ })
32
+ .filter((entry) => entry.tag.length > 0 && entry.q > 0)
33
+ .sort((a, b) => b.q - a.q);
34
+ for (const { tag } of tags) {
35
+ const matched = matchLocale(tag, locales);
36
+ if (matched)
37
+ return matched;
38
+ }
39
+ return undefined;
40
+ }
41
+ export function resolveLocale(options) {
42
+ const { locales, defaultLocale } = options;
43
+ const fromParam = matchLocale(options.param, locales);
44
+ if (fromParam)
45
+ return { locale: fromParam, source: "url" };
46
+ const fromCookie = matchLocale(options.cookie, locales);
47
+ if (fromCookie)
48
+ return { locale: fromCookie, source: "cookie" };
49
+ const fromHeader = parseAcceptLanguage(options.acceptLanguage, locales);
50
+ if (fromHeader)
51
+ return { locale: fromHeader, source: "header" };
52
+ const fallback = matchLocale(defaultLocale, locales) ?? defaultLocale;
53
+ return { locale: fallback, source: "default" };
54
+ }
55
+ //# sourceMappingURL=locale-core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale-core.js","sourceRoot":"","sources":["../src/locale-core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type { ResolveLocaleInput, ResolvedLocaleResult, RoutingMode } from "./types.js";
2
+ export { matchLocale, normalizeLocale, parseAcceptLanguage } from "./locale-core.js";
3
+ export type LocaleSource = import("./types.js").LocaleSource;
4
+ export interface ResolveLocaleOptions {
5
+ param?: string | undefined;
6
+ domain?: string | undefined;
7
+ cookie?: string | undefined;
8
+ acceptLanguage?: string | undefined;
9
+ locales: readonly string[];
10
+ defaultLocale: string;
11
+ }
12
+ export interface ResolvedLocale {
13
+ locale: string;
14
+ source: LocaleSource;
15
+ }
16
+ export declare function looksLikeLocaleSegment(segment: string): boolean;
17
+ export declare function resolveLocaleFromDomain(hostname: string, domains: Record<string, string> | undefined, locales: readonly string[]): string | undefined;
18
+ export declare function stripLocaleFromPath(pathname: string, locales: readonly string[], routing: RoutingMode): {
19
+ pathname: string;
20
+ locale?: string;
21
+ unknownLocale?: string;
22
+ };
23
+ /**
24
+ * Full locale resolution with routing-mode awareness.
25
+ *
26
+ * Priority: URL/domain → cookie → Accept-Language → defaultLocale
27
+ */
28
+ export declare function resolveLocaleFull(input: ResolveLocaleInput): ResolvedLocaleResult;
29
+ /** Legacy simple resolver (param → cookie → header → default). */
30
+ export declare function resolveLocale(options: ResolveLocaleOptions): ResolvedLocale;
31
+ export declare const DEFAULT_PARAM_KEY = "lang";
32
+ export declare const DEFAULT_COOKIE_NAME = "locale";
33
+ //# sourceMappingURL=locale.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../src/locale.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAExF,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAErF,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,EAAE,YAAY,CAAC;AAE7D,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,YAAY,CAAC;CACtB;AAID,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC3C,OAAO,EAAE,SAAS,MAAM,EAAE,GACzB,MAAM,GAAG,SAAS,CAMpB;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,EAAE,WAAW,GACnB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,CA6B/D;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,kBAAkB,GAAG,oBAAoB,CAkDjF;AAED,kEAAkE;AAClE,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,cAAc,CAiB3E;AAED,eAAO,MAAM,iBAAiB,SAAS,CAAC;AACxC,eAAO,MAAM,mBAAmB,WAAW,CAAC"}
package/dist/locale.js ADDED
@@ -0,0 +1,110 @@
1
+ import { matchLocale, parseAcceptLanguage } from "./locale-core.js";
2
+ export { matchLocale, normalizeLocale, parseAcceptLanguage } from "./locale-core.js";
3
+ const LOCALE_SEGMENT_RE = /^[a-z]{2}(?:-[a-z]{2})?$/i;
4
+ export function looksLikeLocaleSegment(segment) {
5
+ return LOCALE_SEGMENT_RE.test(segment);
6
+ }
7
+ export function resolveLocaleFromDomain(hostname, domains, locales) {
8
+ if (!domains)
9
+ return undefined;
10
+ const host = hostname.toLowerCase().split(":")[0] ?? hostname;
11
+ const mapped = domains[host];
12
+ if (mapped)
13
+ return matchLocale(mapped, locales);
14
+ return undefined;
15
+ }
16
+ export function stripLocaleFromPath(pathname, locales, routing) {
17
+ const normalized = pathname.startsWith("/") ? pathname : `/${pathname}`;
18
+ if (normalized === "/" || routing === "none" || routing === "domain") {
19
+ return { pathname: normalized };
20
+ }
21
+ const segments = normalized.split("/").filter(Boolean);
22
+ if (segments.length === 0)
23
+ return { pathname: "/" };
24
+ const first = segments[0] ?? "";
25
+ const matched = matchLocale(first, locales);
26
+ if (matched) {
27
+ const rest = segments.slice(1).join("/");
28
+ return {
29
+ pathname: rest ? `/${rest}` : "/",
30
+ locale: matched,
31
+ };
32
+ }
33
+ if (looksLikeLocaleSegment(first)) {
34
+ const rest = segments.slice(1).join("/");
35
+ return {
36
+ pathname: rest ? `/${rest}` : "/",
37
+ unknownLocale: first,
38
+ };
39
+ }
40
+ return { pathname: normalized };
41
+ }
42
+ /**
43
+ * Full locale resolution with routing-mode awareness.
44
+ *
45
+ * Priority: URL/domain → cookie → Accept-Language → defaultLocale
46
+ */
47
+ export function resolveLocaleFull(input) {
48
+ const { locales, defaultLocale, routing, domains } = input;
49
+ let pathLocale;
50
+ let unknownPathLocale;
51
+ let canonicalPathname = input.pathname;
52
+ if (routing === "domain") {
53
+ const fromDomain = resolveLocaleFromDomain(input.hostname, domains, locales);
54
+ if (fromDomain) {
55
+ const stripped = stripLocaleFromPath(input.pathname, locales, "none");
56
+ return {
57
+ locale: fromDomain,
58
+ source: "domain",
59
+ canonicalPathname: stripped.pathname,
60
+ };
61
+ }
62
+ }
63
+ const stripped = stripLocaleFromPath(input.pathname, locales, routing);
64
+ canonicalPathname = stripped.pathname;
65
+ pathLocale = stripped.locale;
66
+ unknownPathLocale = stripped.unknownLocale;
67
+ if (pathLocale) {
68
+ return { locale: pathLocale, source: "url", pathLocale, canonicalPathname };
69
+ }
70
+ if (unknownPathLocale) {
71
+ const fallback = matchLocale(defaultLocale, locales) ?? defaultLocale;
72
+ return {
73
+ locale: fallback,
74
+ source: "default",
75
+ unknownPathLocale,
76
+ canonicalPathname,
77
+ };
78
+ }
79
+ const fromCookie = matchLocale(input.cookie, locales);
80
+ if (fromCookie) {
81
+ return { locale: fromCookie, source: "cookie", canonicalPathname };
82
+ }
83
+ const fromHeader = parseAcceptLanguage(input.acceptLanguage, locales);
84
+ if (fromHeader) {
85
+ return { locale: fromHeader, source: "header", canonicalPathname };
86
+ }
87
+ const fallback = matchLocale(defaultLocale, locales) ?? defaultLocale;
88
+ return { locale: fallback, source: "default", canonicalPathname };
89
+ }
90
+ /** Legacy simple resolver (param → cookie → header → default). */
91
+ export function resolveLocale(options) {
92
+ const { locales, defaultLocale } = options;
93
+ const fromParam = matchLocale(options.param, locales);
94
+ if (fromParam)
95
+ return { locale: fromParam, source: "url" };
96
+ const fromDomain = matchLocale(options.domain, locales);
97
+ if (fromDomain)
98
+ return { locale: fromDomain, source: "domain" };
99
+ const fromCookie = matchLocale(options.cookie, locales);
100
+ if (fromCookie)
101
+ return { locale: fromCookie, source: "cookie" };
102
+ const fromHeader = parseAcceptLanguage(options.acceptLanguage, locales);
103
+ if (fromHeader)
104
+ return { locale: fromHeader, source: "header" };
105
+ const fallback = matchLocale(defaultLocale, locales) ?? defaultLocale;
106
+ return { locale: fallback, source: "default" };
107
+ }
108
+ export const DEFAULT_PARAM_KEY = "lang";
109
+ export const DEFAULT_COOKIE_NAME = "locale";
110
+ //# sourceMappingURL=locale.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale.js","sourceRoot":"","sources":["../src/locale.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { FlatMessages, MessageLoader, NamespaceLoader } from "./types.js";
2
+ export type { MessageLoader, NamespaceLoader } from "./types.js";
3
+ /** Flatten nested namespace loaders into a single message map. */
4
+ export declare function loadLocaleMessages(loader: MessageLoader | NamespaceLoader, namespaces?: string[]): Promise<FlatMessages>;
5
+ export declare function cacheKey(locale: string, namespaces?: string[]): string;
6
+ export declare function getCachedMessages(locale: string, loader: MessageLoader | NamespaceLoader, namespaces?: string[]): Promise<FlatMessages>;
7
+ /** Clear message cache (for tests). */
8
+ export declare function clearMessageCache(): void;
9
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE/E,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAiBjE,kEAAkE;AAClE,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,aAAa,GAAG,eAAe,EACvC,UAAU,CAAC,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC,YAAY,CAAC,CAmBvB;AAID,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAEtE;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,aAAa,GAAG,eAAe,EACvC,UAAU,CAAC,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC,YAAY,CAAC,CAOvB;AAED,uCAAuC;AACvC,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}
@@ -0,0 +1,52 @@
1
+ function isNamespaceLoader(loader) {
2
+ return typeof loader === "object" && !("then" in loader) && typeof loader !== "function";
3
+ }
4
+ async function resolveLoader(loader) {
5
+ const result = await loader();
6
+ if (typeof result === "string")
7
+ return {};
8
+ if (result && typeof result === "object" && "default" in result) {
9
+ const value = result.default;
10
+ if (value && typeof value === "object")
11
+ return value;
12
+ return {};
13
+ }
14
+ return result;
15
+ }
16
+ /** Flatten nested namespace loaders into a single message map. */
17
+ export async function loadLocaleMessages(loader, namespaces) {
18
+ if (!isNamespaceLoader(loader)) {
19
+ return resolveLoader(loader);
20
+ }
21
+ const keys = namespaces ?? Object.keys(loader);
22
+ const merged = {};
23
+ for (const ns of keys) {
24
+ const nsLoader = loader[ns];
25
+ if (!nsLoader)
26
+ continue;
27
+ const messages = await resolveLoader(nsLoader);
28
+ for (const [key, value] of Object.entries(messages)) {
29
+ merged[`${ns}.${key}`] = value;
30
+ merged[key] = value;
31
+ }
32
+ }
33
+ return merged;
34
+ }
35
+ const messageCache = new Map();
36
+ export function cacheKey(locale, namespaces) {
37
+ return namespaces?.length ? `${locale}:${namespaces.sort().join(",")}` : locale;
38
+ }
39
+ export async function getCachedMessages(locale, loader, namespaces) {
40
+ const key = cacheKey(locale, namespaces);
41
+ const cached = messageCache.get(key);
42
+ if (cached)
43
+ return cached;
44
+ const messages = await loadLocaleMessages(loader, namespaces);
45
+ messageCache.set(key, messages);
46
+ return messages;
47
+ }
48
+ /** Clear message cache (for tests). */
49
+ export function clearMessageCache() {
50
+ messageCache.clear();
51
+ }
52
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAIA,SAAS,iBAAiB,CAAC,MAAuC;IAChE,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,OAAO,MAAM,KAAK,UAAU,CAAC;AAC3F,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,MAAqB;IAChD,MAAM,MAAM,GAAG,MAAM,MAAM,EAAE,CAAC;IAC9B,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IAC1C,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,SAAS,IAAI,MAAM,EAAE,CAAC;QAChE,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC;QAC7B,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QACrD,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,MAAsB,CAAC;AAChC,CAAC;AAED,kEAAkE;AAClE,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAAuC,EACvC,UAAqB;IAErB,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,IAAI,GAAG,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAiB,EAAE,CAAC;IAEhC,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;QACtB,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5B,IAAI,CAAC,QAAQ;YAAE,SAAS;QACxB,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC/C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpD,MAAM,CAAC,GAAG,EAAE,IAAI,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC;YAC/B,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,YAAY,GAAG,IAAI,GAAG,EAAwB,CAAC;AAErD,MAAM,UAAU,QAAQ,CAAC,MAAc,EAAE,UAAqB;IAC5D,OAAO,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AAClF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAc,EACd,MAAuC,EACvC,UAAqB;IAErB,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC9D,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAChC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,iBAAiB;IAC/B,YAAY,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { Context } from "hono";
2
+ import { type MiddlewareModule, type OtokMiddleware } from "@kamod-ch/otok/server";
3
+ import type { MessageCatalog } from "./catalog.js";
4
+ import type { I18nConfig, I18nContext, I18nPluginOptions } from "./types.js";
5
+ import { type NormalizedI18nOptions } from "./registry.js";
6
+ import { clearMessageCache } from "./messages.js";
7
+ /** Wrap middleware for Otok route `middleware` arrays (requires `{ default }` export shape). */
8
+ export declare function toRouteMiddleware(middleware: OtokMiddleware): MiddlewareModule;
9
+ /** App-level middleware used by the i18n() plugin. */
10
+ export declare function createI18nPluginMiddleware(options: NormalizedI18nOptions): OtokMiddleware;
11
+ /** Route-level middleware for legacy flat-catalog config. */
12
+ export declare function createI18nMiddleware<_Catalog extends MessageCatalog>(config: I18nConfig<_Catalog>): OtokMiddleware;
13
+ export declare function readI18n<_Catalog extends MessageCatalog = MessageCatalog>(c: Context, contextKey?: string): I18nContext | undefined;
14
+ /** Configure i18n on a Hono app (used by plugin and manual setup). */
15
+ export declare function configureI18nApp(app: import("hono").Hono, pluginOptions: I18nPluginOptions): NormalizedI18nOptions;
16
+ export { clearMessageCache };
17
+ //# sourceMappingURL=middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,EAAoB,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACrG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAInD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAA+C,KAAK,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACxG,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAwDlD,gGAAgG;AAChG,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,cAAc,GAAG,gBAAgB,CAE9E;AAED,sDAAsD;AACtD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,qBAAqB,GAAG,cAAc,CAezF;AAED,6DAA6D;AAC7D,wBAAgB,oBAAoB,CAAC,QAAQ,SAAS,cAAc,EAAE,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,cAAc,CAuClH;AAED,wBAAgB,QAAQ,CAAC,QAAQ,SAAS,cAAc,GAAG,cAAc,EACvE,CAAC,EAAE,OAAO,EACV,UAAU,SAAS,GAClB,WAAW,GAAG,SAAS,CAEzB;AAED,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,iBAAiB,GAAG,qBAAqB,CAKlH;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
@@ -0,0 +1,121 @@
1
+ import { getCookie, setCookie } from "hono/cookie";
2
+ import { defineMiddleware } from "@kamod-ch/otok/server";
3
+ import { buildI18nContext, createI18nAsync } from "./i18n.js";
4
+ import { DEFAULT_COOKIE_NAME, resolveLocaleFull } from "./locale.js";
5
+ import { localizePath } from "./routes.js";
6
+ import { normalizePluginOptions, registerI18nRuntime } from "./registry.js";
7
+ import { clearMessageCache } from "./messages.js";
8
+ async function buildPluginContext(c, options) {
9
+ const url = new URL(c.req.url);
10
+ const resolved = resolveLocaleFull({
11
+ pathname: url.pathname,
12
+ hostname: url.hostname,
13
+ cookie: getCookie(c, options.cookieName),
14
+ acceptLanguage: c.req.header("accept-language") ?? undefined,
15
+ locales: options.locales,
16
+ defaultLocale: options.defaultLocale,
17
+ routing: options.routing,
18
+ domains: options.domains,
19
+ });
20
+ if (options.redirectUnknownLocale && resolved.unknownPathLocale) {
21
+ const target = localizePath(resolved.canonicalPathname, resolved.locale, {
22
+ defaultLocale: options.defaultLocale,
23
+ routing: options.routing,
24
+ });
25
+ const location = `${target}${url.search}`;
26
+ if (location !== `${url.pathname}${url.search}`) {
27
+ return { i18n: {}, redirect: c.redirect(location, 307) };
28
+ }
29
+ }
30
+ const i18n = await createI18nAsync(options, {
31
+ pathname: url.pathname,
32
+ hostname: url.hostname,
33
+ cookie: getCookie(c, options.cookieName),
34
+ acceptLanguage: c.req.header("accept-language") ?? undefined,
35
+ locales: options.locales,
36
+ defaultLocale: options.defaultLocale,
37
+ routing: options.routing,
38
+ domains: options.domains,
39
+ });
40
+ return { i18n };
41
+ }
42
+ function persistLocaleCookie(c, options, locale) {
43
+ if (!options.persistLocale)
44
+ return;
45
+ const current = getCookie(c, options.cookieName);
46
+ if (current === locale)
47
+ return;
48
+ setCookie(c, options.cookieName, locale, {
49
+ path: "/",
50
+ maxAge: options.cookieMaxAge,
51
+ sameSite: "Lax",
52
+ httpOnly: false,
53
+ });
54
+ }
55
+ /** Wrap middleware for Otok route `middleware` arrays (requires `{ default }` export shape). */
56
+ export function toRouteMiddleware(middleware) {
57
+ return { default: middleware };
58
+ }
59
+ /** App-level middleware used by the i18n() plugin. */
60
+ export function createI18nPluginMiddleware(options) {
61
+ return defineMiddleware(async (c, next) => {
62
+ const { i18n, redirect } = await buildPluginContext(c, options);
63
+ if (redirect)
64
+ return redirect;
65
+ c.set(options.contextKey, i18n);
66
+ persistLocaleCookie(c, options, i18n.locale);
67
+ registerI18nRuntime({
68
+ options,
69
+ getContext: () => i18n,
70
+ });
71
+ await next();
72
+ });
73
+ }
74
+ /** Route-level middleware for legacy flat-catalog config. */
75
+ export function createI18nMiddleware(config) {
76
+ const cookieName = config.cookieName ?? DEFAULT_COOKIE_NAME;
77
+ const contextKey = config.contextKey ?? "i18n";
78
+ const routing = config.routing ?? "prefix-except-default";
79
+ const fallbackLocale = (config.fallbackLocale ?? config.defaultLocale);
80
+ return defineMiddleware(async (c, next) => {
81
+ const url = new URL(c.req.url);
82
+ const resolved = resolveLocaleFull({
83
+ pathname: url.pathname,
84
+ hostname: url.hostname,
85
+ cookie: getCookie(c, cookieName),
86
+ acceptLanguage: c.req.header("accept-language") ?? undefined,
87
+ locales: config.locales,
88
+ defaultLocale: config.defaultLocale,
89
+ routing,
90
+ domains: config.domains,
91
+ });
92
+ const locale = config.locales.includes(resolved.locale)
93
+ ? resolved.locale
94
+ : config.defaultLocale;
95
+ const messages = config.catalog[locale] ?? {};
96
+ const fallbackMessages = config.catalog[fallbackLocale] ?? {};
97
+ const i18n = buildI18nContext({
98
+ locale: locale,
99
+ source: resolved.source,
100
+ routing,
101
+ defaultLocale: config.defaultLocale,
102
+ fallbackLocale,
103
+ messages,
104
+ fallbackMessages,
105
+ });
106
+ c.set(contextKey, i18n);
107
+ await next();
108
+ });
109
+ }
110
+ export function readI18n(c, contextKey = "i18n") {
111
+ return c.get(contextKey);
112
+ }
113
+ /** Configure i18n on a Hono app (used by plugin and manual setup). */
114
+ export function configureI18nApp(app, pluginOptions) {
115
+ clearMessageCache();
116
+ const options = normalizePluginOptions(pluginOptions);
117
+ app.use("*", createI18nPluginMiddleware(options));
118
+ return options;
119
+ }
120
+ export { clearMessageCache };
121
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { configureI18nApp } from "./middleware.js";
2
+ import type { I18nPluginOptions } from "./types.js";
3
+ /**
4
+ * Otok i18n plugin factory.
5
+ *
6
+ * ```ts
7
+ * import i18n from "@kamod-ch/otok-i18n";
8
+ *
9
+ * export default defineConfig({
10
+ * plugins: [i18n({ locales: ["de", "en"], defaultLocale: "de", messages: { ... } })],
11
+ * });
12
+ * ```
13
+ */
14
+ export default function i18n(options: I18nPluginOptions): import("@kamod-ch/otok-config").OtokPlugin<unknown>;
15
+ export { configureI18nApp };
16
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAoCpD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,OAAO,EAAE,iBAAiB,uDAMtD;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}