@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.
- package/LICENSE +21 -0
- package/README.md +163 -0
- package/dist/catalog.d.ts +17 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +38 -0
- package/dist/catalog.js.map +1 -0
- package/dist/client.d.ts +41 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +67 -0
- package/dist/client.js.map +1 -0
- package/dist/format.d.ts +5 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +39 -0
- package/dist/format.js.map +1 -0
- package/dist/head.d.ts +18 -0
- package/dist/head.d.ts.map +1 -0
- package/dist/head.js +33 -0
- package/dist/head.js.map +1 -0
- package/dist/i18n.d.ts +24 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +74 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/interpolate.d.ts +7 -0
- package/dist/interpolate.d.ts.map +1 -0
- package/dist/interpolate.js +28 -0
- package/dist/interpolate.js.map +1 -0
- package/dist/loader.d.ts +23 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +31 -0
- package/dist/loader.js.map +1 -0
- package/dist/locale-core.d.ts +19 -0
- package/dist/locale-core.d.ts.map +1 -0
- package/dist/locale-core.js +55 -0
- package/dist/locale-core.js.map +1 -0
- package/dist/locale.d.ts +33 -0
- package/dist/locale.d.ts.map +1 -0
- package/dist/locale.js +110 -0
- package/dist/locale.js.map +1 -0
- package/dist/messages.d.ts +9 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +52 -0
- package/dist/messages.js.map +1 -0
- package/dist/middleware.d.ts +17 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +121 -0
- package/dist/middleware.js.map +1 -0
- package/dist/plugin.d.ts +16 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +55 -0
- package/dist/plugin.js.map +1 -0
- package/dist/plural.d.ts +5 -0
- package/dist/plural.d.ts.map +1 -0
- package/dist/plural.js +42 -0
- package/dist/plural.js.map +1 -0
- package/dist/registry.d.ts +27 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +34 -0
- package/dist/registry.js.map +1 -0
- package/dist/routes.d.ts +26 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +69 -0
- package/dist/routes.js.map +1 -0
- package/dist/sitemap.d.ts +25 -0
- package/dist/sitemap.d.ts.map +1 -0
- package/dist/sitemap.js +55 -0
- package/dist/sitemap.js.map +1 -0
- package/dist/switcher.d.ts +12 -0
- package/dist/switcher.d.ts.map +1 -0
- package/dist/switcher.js +17 -0
- package/dist/switcher.js.map +1 -0
- package/dist/types.d.ts +96 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +81 -0
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { definePlugin } from "@kamod-ch/otok";
|
|
2
|
+
import { configureI18nApp } from "./middleware.js";
|
|
3
|
+
const i18nPluginFactory = definePlugin({
|
|
4
|
+
name: "@kamod-ch/otok-i18n",
|
|
5
|
+
version: "2.0.0",
|
|
6
|
+
schema: {
|
|
7
|
+
parse(input) {
|
|
8
|
+
if (!input || typeof input !== "object") {
|
|
9
|
+
throw new Error("i18n() options must be an object");
|
|
10
|
+
}
|
|
11
|
+
const record = input;
|
|
12
|
+
if (!Array.isArray(record.locales) || record.locales.length === 0) {
|
|
13
|
+
throw new Error("i18n() requires locales: string[]");
|
|
14
|
+
}
|
|
15
|
+
if (typeof record.defaultLocale !== "string") {
|
|
16
|
+
throw new Error("i18n() requires defaultLocale: string");
|
|
17
|
+
}
|
|
18
|
+
if (!record.messages || typeof record.messages !== "object") {
|
|
19
|
+
throw new Error("i18n() requires messages: Record<locale, loader>");
|
|
20
|
+
}
|
|
21
|
+
const locales = record.locales;
|
|
22
|
+
if (!locales.includes(record.defaultLocale)) {
|
|
23
|
+
throw new Error("i18n() defaultLocale must be in locales");
|
|
24
|
+
}
|
|
25
|
+
if (record.fallbackLocale != null && !locales.includes(record.fallbackLocale)) {
|
|
26
|
+
throw new Error("i18n() fallbackLocale must be in locales");
|
|
27
|
+
}
|
|
28
|
+
const routing = record.routing;
|
|
29
|
+
if (routing != null && !["prefix", "prefix-except-default", "domain", "none"].includes(routing)) {
|
|
30
|
+
throw new Error(`i18n() invalid routing mode: ${routing}`);
|
|
31
|
+
}
|
|
32
|
+
return input;
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
/**
|
|
37
|
+
* Otok i18n plugin factory.
|
|
38
|
+
*
|
|
39
|
+
* ```ts
|
|
40
|
+
* import i18n from "@kamod-ch/otok-i18n";
|
|
41
|
+
*
|
|
42
|
+
* export default defineConfig({
|
|
43
|
+
* plugins: [i18n({ locales: ["de", "en"], defaultLocale: "de", messages: { ... } })],
|
|
44
|
+
* });
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export default function i18n(options) {
|
|
48
|
+
const plugin = i18nPluginFactory(options);
|
|
49
|
+
plugin.configureApp = ({ app }) => {
|
|
50
|
+
configureI18nApp(app, options);
|
|
51
|
+
};
|
|
52
|
+
return plugin;
|
|
53
|
+
}
|
|
54
|
+
export { configureI18nApp };
|
|
55
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnD,MAAM,iBAAiB,GAAG,YAAY,CAAoB;IACxD,IAAI,EAAE,qBAAqB;IAC3B,OAAO,EAAE,OAAO;IAChB,MAAM,EAAE;QACN,KAAK,CAAC,KAAK;YACT,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACxC,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;YACtD,CAAC;YACD,MAAM,MAAM,GAAG,KAAgC,CAAC;YAChD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAClE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;YACvD,CAAC;YACD,IAAI,OAAO,MAAM,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;gBAC7C,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;YAC3D,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC5D,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;YACtE,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAmB,CAAC;YAC3C,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAuB,CAAC,EAAE,CAAC;gBACtD,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;YAC7D,CAAC;YACD,IAAI,MAAM,CAAC,cAAc,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,cAAwB,CAAC,EAAE,CAAC;gBACxF,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;YAC9D,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,CAAC,OAA6B,CAAC;YACrD,IAAI,OAAO,IAAI,IAAI,IAAI,CAAC,CAAC,QAAQ,EAAE,uBAAuB,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBAChG,MAAM,IAAI,KAAK,CAAC,gCAAgC,OAAO,EAAE,CAAC,CAAC;YAC7D,CAAC;YACD,OAAO,KAA0B,CAAC;QACpC,CAAC;KACF;CACF,CAAC,CAAC;AAEH;;;;;;;;;;GAUG;AACH,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,OAA0B;IACrD,MAAM,MAAM,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,CAAC,YAAY,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;QAChC,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|
package/dist/plural.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { TranslateValues } from "./types.js";
|
|
2
|
+
export declare function resolvePluralKey(baseKey: string, locale: string, count: number): string;
|
|
3
|
+
export declare function pickPluralMessage(messages: Record<string, string>, baseKey: string, locale: string, count: number): string | undefined;
|
|
4
|
+
export declare function extractCount(values?: TranslateValues): number | undefined;
|
|
5
|
+
//# sourceMappingURL=plural.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plural.d.ts","sourceRoot":"","sources":["../src/plural.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAclD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAIvF;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,MAAM,GAAG,SAAS,CAUpB;AAED,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,GAAG,SAAS,CASzE"}
|
package/dist/plural.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const PLURAL_SUFFIXES = ["zero", "one", "two", "few", "many", "other"];
|
|
2
|
+
const pluralRulesCache = new Map();
|
|
3
|
+
function getPluralRules(locale) {
|
|
4
|
+
const cached = pluralRulesCache.get(locale);
|
|
5
|
+
if (cached)
|
|
6
|
+
return cached;
|
|
7
|
+
const rules = new Intl.PluralRules(locale);
|
|
8
|
+
pluralRulesCache.set(locale, rules);
|
|
9
|
+
return rules;
|
|
10
|
+
}
|
|
11
|
+
export function resolvePluralKey(baseKey, locale, count) {
|
|
12
|
+
const category = getPluralRules(locale).select(count);
|
|
13
|
+
const specific = `${baseKey}.${category}`;
|
|
14
|
+
return specific;
|
|
15
|
+
}
|
|
16
|
+
export function pickPluralMessage(messages, baseKey, locale, count) {
|
|
17
|
+
const category = getPluralRules(locale).select(count);
|
|
18
|
+
const candidates = [`${baseKey}.${category}`, ...PLURAL_SUFFIXES.map((s) => `${baseKey}.${s}`)];
|
|
19
|
+
for (const key of candidates) {
|
|
20
|
+
const value = messages[key];
|
|
21
|
+
if (value != null && value !== "")
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
const direct = messages[baseKey];
|
|
25
|
+
if (direct != null && direct !== "")
|
|
26
|
+
return direct;
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
export function extractCount(values) {
|
|
30
|
+
if (values == null || !("count" in values))
|
|
31
|
+
return undefined;
|
|
32
|
+
const count = values.count;
|
|
33
|
+
if (typeof count === "number" && Number.isFinite(count))
|
|
34
|
+
return count;
|
|
35
|
+
if (typeof count === "string") {
|
|
36
|
+
const parsed = Number.parseFloat(count);
|
|
37
|
+
if (Number.isFinite(parsed))
|
|
38
|
+
return parsed;
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=plural.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plural.js","sourceRoot":"","sources":["../src/plural.ts"],"names":[],"mappings":"AAEA,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAEhF,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAA4B,CAAC;AAE7D,SAAS,cAAc,CAAC,MAAc;IACpC,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3C,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACpC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,MAAc,EAAE,KAAa;IAC7E,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,GAAG,OAAO,IAAI,QAAQ,EAAE,CAAC;IAC1C,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,QAAgC,EAChC,OAAe,EACf,MAAc,EACd,KAAa;IAEb,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,UAAU,GAAG,CAAC,GAAG,OAAO,IAAI,QAAQ,EAAE,EAAE,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAChG,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,EAAE;YAAE,OAAO,KAAK,CAAC;IAClD,CAAC;IACD,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IACjC,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,KAAK,EAAE;QAAE,OAAO,MAAM,CAAC;IACnD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAwB;IACnD,IAAI,MAAM,IAAI,IAAI,IAAI,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACtE,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACxC,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,OAAO,MAAM,CAAC;IAC7C,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { I18nPluginOptions, I18nContext, RoutingMode } from "./types.js";
|
|
2
|
+
import type { MessageLoader, NamespaceLoader } from "./types.js";
|
|
3
|
+
export interface I18nRuntime {
|
|
4
|
+
options: NormalizedI18nOptions;
|
|
5
|
+
getContext: () => I18nContext | undefined;
|
|
6
|
+
}
|
|
7
|
+
export interface NormalizedI18nOptions {
|
|
8
|
+
locales: readonly string[];
|
|
9
|
+
defaultLocale: string;
|
|
10
|
+
fallbackLocale: string;
|
|
11
|
+
routing: RoutingMode;
|
|
12
|
+
domains: Record<string, string>;
|
|
13
|
+
messages: Record<string, MessageLoader | NamespaceLoader>;
|
|
14
|
+
paramKey: string;
|
|
15
|
+
cookieName: string;
|
|
16
|
+
contextKey: string;
|
|
17
|
+
persistLocale: boolean;
|
|
18
|
+
warnMissingKeys: boolean;
|
|
19
|
+
redirectUnknownLocale: boolean;
|
|
20
|
+
cookieMaxAge: number;
|
|
21
|
+
}
|
|
22
|
+
export declare function normalizePluginOptions<Locales extends readonly string[]>(options: I18nPluginOptions<Locales>): NormalizedI18nOptions;
|
|
23
|
+
export declare function registerI18nRuntime(next: I18nRuntime): void;
|
|
24
|
+
export declare function getI18nRuntime(): I18nRuntime;
|
|
25
|
+
export declare function tryGetI18nRuntime(): I18nRuntime | undefined;
|
|
26
|
+
export declare function clearI18nRuntime(): void;
|
|
27
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9E,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,qBAAqB,CAAC;IAC/B,UAAU,EAAE,MAAM,WAAW,GAAG,SAAS,CAAC;CAC3C;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,WAAW,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,eAAe,CAAC,CAAC;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;CACtB;AAID,wBAAgB,sBAAsB,CAAC,OAAO,SAAS,SAAS,MAAM,EAAE,EACtE,OAAO,EAAE,iBAAiB,CAAC,OAAO,CAAC,GAClC,qBAAqB,CAgBvB;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAE3D;AAED,wBAAgB,cAAc,IAAI,WAAW,CAK5C;AAED,wBAAgB,iBAAiB,IAAI,WAAW,GAAG,SAAS,CAE3D;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC"}
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
let runtime;
|
|
2
|
+
export function normalizePluginOptions(options) {
|
|
3
|
+
return {
|
|
4
|
+
locales: options.locales,
|
|
5
|
+
defaultLocale: options.defaultLocale,
|
|
6
|
+
fallbackLocale: options.fallbackLocale ?? options.defaultLocale,
|
|
7
|
+
routing: options.routing ?? "prefix-except-default",
|
|
8
|
+
domains: (options.domains ?? {}),
|
|
9
|
+
messages: options.messages,
|
|
10
|
+
paramKey: options.paramKey ?? "lang",
|
|
11
|
+
cookieName: options.cookieName ?? "locale",
|
|
12
|
+
contextKey: options.contextKey ?? "i18n",
|
|
13
|
+
persistLocale: options.persistLocale ?? true,
|
|
14
|
+
warnMissingKeys: options.warnMissingKeys ?? process.env.NODE_ENV !== "production",
|
|
15
|
+
redirectUnknownLocale: options.redirectUnknownLocale ?? true,
|
|
16
|
+
cookieMaxAge: options.cookieMaxAge ?? 60 * 60 * 24 * 365,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function registerI18nRuntime(next) {
|
|
20
|
+
runtime = next;
|
|
21
|
+
}
|
|
22
|
+
export function getI18nRuntime() {
|
|
23
|
+
if (!runtime) {
|
|
24
|
+
throw new Error("otok-i18n: i18n() plugin not registered. Add i18n() to otok.config.ts plugins.");
|
|
25
|
+
}
|
|
26
|
+
return runtime;
|
|
27
|
+
}
|
|
28
|
+
export function tryGetI18nRuntime() {
|
|
29
|
+
return runtime;
|
|
30
|
+
}
|
|
31
|
+
export function clearI18nRuntime() {
|
|
32
|
+
runtime = undefined;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAwBA,IAAI,OAAgC,CAAC;AAErC,MAAM,UAAU,sBAAsB,CACpC,OAAmC;IAEnC,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,aAAa;QAC/D,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,uBAAuB;QACnD,OAAO,EAAE,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAA2B;QAC1D,QAAQ,EAAE,OAAO,CAAC,QAA2D;QAC7E,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,MAAM;QACpC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,QAAQ;QAC1C,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,MAAM;QACxC,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,IAAI;QAC5C,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;QACjF,qBAAqB,EAAE,OAAO,CAAC,qBAAqB,IAAI,IAAI;QAC5D,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG;KACzD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAiB;IACnD,OAAO,GAAG,IAAI,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC,CAAC;IACpG,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,GAAG,SAAS,CAAC;AACtB,CAAC"}
|
package/dist/routes.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { LocalizedRouteNames, RoutingMode } from "./types.js";
|
|
2
|
+
export declare const DEFAULT_PARAM_KEY = "lang";
|
|
3
|
+
export interface LocalizePathOptions {
|
|
4
|
+
defaultLocale?: string;
|
|
5
|
+
routing?: RoutingMode;
|
|
6
|
+
}
|
|
7
|
+
export declare function withLocaleParam(params: Record<string, string | undefined>, locale: string, paramKey?: string): Record<string, string | undefined>;
|
|
8
|
+
export declare function stripLocaleParam(pathname: string, locales: readonly string[], _paramKey?: string): {
|
|
9
|
+
pathname: string;
|
|
10
|
+
locale?: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Build a localized pathname according to the routing mode.
|
|
14
|
+
*/
|
|
15
|
+
export declare function localizePath(pathname: string, locale: string, options?: LocalizePathOptions): string;
|
|
16
|
+
/**
|
|
17
|
+
* Switch locale while preserving the current canonical path.
|
|
18
|
+
*/
|
|
19
|
+
export declare function switchLocalePath(currentPathname: string, targetLocale: string, locales: readonly string[], options?: LocalizePathOptions): string;
|
|
20
|
+
export declare function localizeRouteSegment(routeKey: string, locale: string, routeNames: LocalizedRouteNames, fallbackLocale: string): string;
|
|
21
|
+
export declare function createLinkHelper(locales: readonly string[], defaultLocale: string, routing: RoutingMode, routeNames?: LocalizedRouteNames): {
|
|
22
|
+
href(pathname: string, locale: string): string;
|
|
23
|
+
switchLocale(currentPathname: string, targetLocale: string): string;
|
|
24
|
+
route(routeKey: string, locale: string): string;
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEnE,eAAO,MAAM,iBAAiB,SAAS,CAAC;AAExC,MAAM,WAAW,mBAAmB;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAC1C,MAAM,EAAE,MAAM,EACd,QAAQ,SAAoB,GAC3B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAEpC;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,SAAS,SAAoB,GAC5B;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAgBvC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,MAAM,CAgBxG;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,eAAe,EAAE,MAAM,EACvB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,GAAE,mBAAwB,GAChC,MAAM,CAGR;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,mBAAmB,EAC/B,cAAc,EAAE,MAAM,GACrB,MAAM,CAIR;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,WAAW,EACpB,UAAU,GAAE,mBAAwB;mBAGnB,MAAM,UAAU,MAAM,GAAG,MAAM;kCAGhB,MAAM,gBAAgB,MAAM,GAAG,MAAM;oBAGnD,MAAM,UAAU,MAAM,GAAG,MAAM;EAKlD"}
|
package/dist/routes.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { matchLocale, normalizeLocale } from "./locale-core.js";
|
|
2
|
+
export const DEFAULT_PARAM_KEY = "lang";
|
|
3
|
+
export function withLocaleParam(params, locale, paramKey = DEFAULT_PARAM_KEY) {
|
|
4
|
+
return { ...params, [paramKey]: locale };
|
|
5
|
+
}
|
|
6
|
+
export function stripLocaleParam(pathname, locales, _paramKey = DEFAULT_PARAM_KEY) {
|
|
7
|
+
const normalized = pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
8
|
+
if (normalized === "/")
|
|
9
|
+
return { pathname: "/" };
|
|
10
|
+
const segments = normalized.split("/").filter(Boolean);
|
|
11
|
+
if (segments.length === 0)
|
|
12
|
+
return { pathname: "/" };
|
|
13
|
+
const first = segments[0] ?? "";
|
|
14
|
+
const matched = matchLocale(first, locales);
|
|
15
|
+
if (!matched)
|
|
16
|
+
return { pathname: normalized };
|
|
17
|
+
const rest = segments.slice(1).join("/");
|
|
18
|
+
return {
|
|
19
|
+
pathname: rest ? `/${rest}` : "/",
|
|
20
|
+
locale: matched,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Build a localized pathname according to the routing mode.
|
|
25
|
+
*/
|
|
26
|
+
export function localizePath(pathname, locale, options = {}) {
|
|
27
|
+
const { defaultLocale, routing = "prefix-except-default" } = options;
|
|
28
|
+
const normalized = pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
29
|
+
const localeNorm = normalizeLocale(locale) ?? locale;
|
|
30
|
+
if (routing === "none" || routing === "domain") {
|
|
31
|
+
return normalized === "" ? "/" : normalized;
|
|
32
|
+
}
|
|
33
|
+
if (routing === "prefix-except-default" && defaultLocale != null) {
|
|
34
|
+
const defaultNorm = normalizeLocale(defaultLocale) ?? defaultLocale;
|
|
35
|
+
if (localeNorm === defaultNorm)
|
|
36
|
+
return normalized === "" ? "/" : normalized;
|
|
37
|
+
}
|
|
38
|
+
if (normalized === "/")
|
|
39
|
+
return `/${localeNorm}`;
|
|
40
|
+
return `/${localeNorm}${normalized}`;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Switch locale while preserving the current canonical path.
|
|
44
|
+
*/
|
|
45
|
+
export function switchLocalePath(currentPathname, targetLocale, locales, options = {}) {
|
|
46
|
+
const { pathname } = stripLocaleParam(currentPathname, locales);
|
|
47
|
+
return localizePath(pathname, targetLocale, options);
|
|
48
|
+
}
|
|
49
|
+
export function localizeRouteSegment(routeKey, locale, routeNames, fallbackLocale) {
|
|
50
|
+
const names = routeNames[routeKey];
|
|
51
|
+
if (!names)
|
|
52
|
+
return routeKey;
|
|
53
|
+
return names[locale] ?? names[fallbackLocale] ?? routeKey;
|
|
54
|
+
}
|
|
55
|
+
export function createLinkHelper(locales, defaultLocale, routing, routeNames = {}) {
|
|
56
|
+
return {
|
|
57
|
+
href(pathname, locale) {
|
|
58
|
+
return localizePath(pathname, locale, { defaultLocale, routing });
|
|
59
|
+
},
|
|
60
|
+
switchLocale(currentPathname, targetLocale) {
|
|
61
|
+
return switchLocalePath(currentPathname, targetLocale, locales, { defaultLocale, routing });
|
|
62
|
+
},
|
|
63
|
+
route(routeKey, locale) {
|
|
64
|
+
const segment = localizeRouteSegment(routeKey, locale, routeNames, defaultLocale);
|
|
65
|
+
return localizePath(`/${segment}`, locale, { defaultLocale, routing });
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { RoutingMode } from "./types.js";
|
|
2
|
+
export interface SitemapAlternate {
|
|
3
|
+
hreflang: string;
|
|
4
|
+
href: string;
|
|
5
|
+
}
|
|
6
|
+
export interface LocalizedSitemapEntry {
|
|
7
|
+
loc: string;
|
|
8
|
+
alternates: SitemapAlternate[];
|
|
9
|
+
lastmod?: string;
|
|
10
|
+
changefreq?: "always" | "hourly" | "daily" | "weekly" | "monthly" | "yearly" | "never";
|
|
11
|
+
priority?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface CreateSitemapOptions {
|
|
14
|
+
origin: string;
|
|
15
|
+
locales: readonly string[];
|
|
16
|
+
defaultLocale: string;
|
|
17
|
+
routing?: RoutingMode;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Build localized sitemap entries with hreflang alternates for each path.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createLocalizedSitemapEntries(paths: readonly string[], options: CreateSitemapOptions): LocalizedSitemapEntry[];
|
|
23
|
+
/** Render sitemap XML with xhtml:link alternates. */
|
|
24
|
+
export declare function renderSitemapXml(entries: LocalizedSitemapEntry[]): string;
|
|
25
|
+
//# sourceMappingURL=sitemap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sitemap.d.ts","sourceRoot":"","sources":["../src/sitemap.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;IACvF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,EAAE,oBAAoB,GAC5B,qBAAqB,EAAE,CAqBzB;AAED,qDAAqD;AACrD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,EAAE,GAAG,MAAM,CA2BzE"}
|
package/dist/sitemap.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { localizePath } from "./routes.js";
|
|
2
|
+
/**
|
|
3
|
+
* Build localized sitemap entries with hreflang alternates for each path.
|
|
4
|
+
*/
|
|
5
|
+
export function createLocalizedSitemapEntries(paths, options) {
|
|
6
|
+
const { origin, locales, defaultLocale, routing = "prefix-except-default" } = options;
|
|
7
|
+
const base = origin.replace(/\/$/, "");
|
|
8
|
+
return paths.map((pathname) => {
|
|
9
|
+
const normalized = pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
10
|
+
const alternates = locales.map((locale) => ({
|
|
11
|
+
hreflang: locale,
|
|
12
|
+
href: `${base}${localizePath(normalized, locale, { defaultLocale, routing })}`,
|
|
13
|
+
}));
|
|
14
|
+
alternates.push({
|
|
15
|
+
hreflang: "x-default",
|
|
16
|
+
href: `${base}${localizePath(normalized, defaultLocale, { defaultLocale, routing })}`,
|
|
17
|
+
});
|
|
18
|
+
return {
|
|
19
|
+
loc: `${base}${localizePath(normalized, defaultLocale, { defaultLocale, routing })}`,
|
|
20
|
+
alternates,
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/** Render sitemap XML with xhtml:link alternates. */
|
|
25
|
+
export function renderSitemapXml(entries) {
|
|
26
|
+
const xmlns = 'xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"';
|
|
27
|
+
const xhtml = 'xmlns:xhtml="http://www.w3.org/1999/xhtml"';
|
|
28
|
+
const urls = entries
|
|
29
|
+
.map((entry) => {
|
|
30
|
+
const altLinks = entry.alternates
|
|
31
|
+
.map((alt) => ` <xhtml:link rel="alternate" hreflang="${escapeXml(alt.hreflang)}" href="${escapeXml(alt.href)}" />`)
|
|
32
|
+
.join("\n");
|
|
33
|
+
const lastmod = entry.lastmod ? `\n <lastmod>${escapeXml(entry.lastmod)}</lastmod>` : "";
|
|
34
|
+
const changefreq = entry.changefreq ? `\n <changefreq>${entry.changefreq}</changefreq>` : "";
|
|
35
|
+
const priority = entry.priority != null ? `\n <priority>${entry.priority.toFixed(1)}</priority>` : "";
|
|
36
|
+
return ` <url>
|
|
37
|
+
<loc>${escapeXml(entry.loc)}</loc>${lastmod}${changefreq}${priority}
|
|
38
|
+
${altLinks}
|
|
39
|
+
</url>`;
|
|
40
|
+
})
|
|
41
|
+
.join("\n");
|
|
42
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
43
|
+
<urlset ${xmlns} ${xhtml}>
|
|
44
|
+
${urls}
|
|
45
|
+
</urlset>`;
|
|
46
|
+
}
|
|
47
|
+
function escapeXml(value) {
|
|
48
|
+
return value
|
|
49
|
+
.replaceAll("&", "&")
|
|
50
|
+
.replaceAll("<", "<")
|
|
51
|
+
.replaceAll(">", ">")
|
|
52
|
+
.replaceAll('"', """)
|
|
53
|
+
.replaceAll("'", "'");
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=sitemap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sitemap.js","sourceRoot":"","sources":["../src/sitemap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface LocaleSwitcherProps {
|
|
2
|
+
locales: readonly string[];
|
|
3
|
+
currentPath: string;
|
|
4
|
+
labels?: Record<string, string>;
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Locale switcher that preserves the current route.
|
|
9
|
+
* Uses plain anchors for progressive enhancement and soft-nav compatibility.
|
|
10
|
+
*/
|
|
11
|
+
export declare function LocaleSwitcher({ locales, currentPath, labels, className }: LocaleSwitcherProps): import("preact").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=switcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"switcher.d.ts","sourceRoot":"","sources":["../src/switcher.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,MAAW,EAAE,SAAS,EAAE,EAAE,mBAAmB,gCA4BnG"}
|
package/dist/switcher.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx } from "preact/jsx-runtime";
|
|
2
|
+
import { useI18n } from "./client.js";
|
|
3
|
+
import { switchLocalePath } from "./routes.js";
|
|
4
|
+
/**
|
|
5
|
+
* Locale switcher that preserves the current route.
|
|
6
|
+
* Uses plain anchors for progressive enhancement and soft-nav compatibility.
|
|
7
|
+
*/
|
|
8
|
+
export function LocaleSwitcher({ locales, currentPath, labels = {}, className }) {
|
|
9
|
+
const { locale: activeLocale, defaultLocale, routing } = useI18n();
|
|
10
|
+
return (_jsx("nav", { "aria-label": "Language", className: className, "data-otok-locale-switcher": "", children: _jsx("ul", { style: { display: "flex", gap: "0.5rem", listStyle: "none", padding: 0, margin: 0 }, children: locales.map((locale) => {
|
|
11
|
+
const href = switchLocalePath(currentPath, locale, locales, { defaultLocale, routing });
|
|
12
|
+
const label = labels[locale] ?? locale.toUpperCase();
|
|
13
|
+
const isActive = locale === activeLocale;
|
|
14
|
+
return (_jsx("li", { children: isActive ? (_jsx("span", { "aria-current": "true", "data-active-locale": "", children: label })) : (_jsx("a", { href: href, hrefLang: locale, lang: locale, "data-locale": locale, children: label })) }, locale));
|
|
15
|
+
}) }) }));
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=switcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"switcher.js","sourceRoot":"","sources":["../src/switcher.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAS/C;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,EAAE,EAAE,SAAS,EAAuB;IAClG,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;IAEnE,OAAO,CACL,4BAAgB,UAAU,EAAC,SAAS,EAAE,SAAS,+BAA4B,EAAE,YAC3E,aAAI,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,YACpF,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;gBACtB,MAAM,IAAI,GAAG,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC,CAAC;gBACxF,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBACrD,MAAM,QAAQ,GAAG,MAAM,KAAK,YAAY,CAAC;gBAEzC,OAAO,CACL,uBACG,QAAQ,CAAC,CAAC,CAAC,CACV,+BAAmB,MAAM,wBAAoB,EAAE,YAC5C,KAAK,GACD,CACR,CAAC,CAAC,CAAC,CACF,YAAG,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,iBAAe,MAAM,YAC/D,KAAK,GACJ,CACL,IATM,MAAM,CAUV,CACN,CAAC;YACJ,CAAC,CAAC,GACC,GACD,CACP,CAAC;AACJ,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/** Supported URL routing strategies for locale detection. */
|
|
2
|
+
export type RoutingMode = "prefix" | "prefix-except-default" | "domain" | "none";
|
|
3
|
+
export type LocaleSource = "url" | "domain" | "cookie" | "header" | "default";
|
|
4
|
+
export type MessageValue = string | Record<string, string>;
|
|
5
|
+
export type FlatMessages = Record<string, string>;
|
|
6
|
+
export type MessageLoader = (() => Promise<{
|
|
7
|
+
default?: FlatMessages;
|
|
8
|
+
} | FlatMessages>) | (() => FlatMessages);
|
|
9
|
+
export type NamespaceLoader = Record<string, MessageLoader>;
|
|
10
|
+
export interface I18nPluginOptions<Locales extends readonly string[] = readonly string[]> {
|
|
11
|
+
locales: Locales;
|
|
12
|
+
defaultLocale: Locales[number];
|
|
13
|
+
/** Secondary locale for missing keys. Defaults to `defaultLocale`. */
|
|
14
|
+
fallbackLocale?: Locales[number];
|
|
15
|
+
routing?: RoutingMode;
|
|
16
|
+
/** Hostname → locale for `routing: "domain"`. */
|
|
17
|
+
domains?: Record<string, Locales[number]>;
|
|
18
|
+
/** Per-locale message loaders (lazy). Optional namespace loaders via `messages[locale][namespace]`. */
|
|
19
|
+
messages: Record<Locales[number], MessageLoader | NamespaceLoader>;
|
|
20
|
+
paramKey?: string;
|
|
21
|
+
cookieName?: string;
|
|
22
|
+
contextKey?: string;
|
|
23
|
+
/** Write resolved locale to cookie. Default: true. */
|
|
24
|
+
persistLocale?: boolean;
|
|
25
|
+
/** Log missing translation keys in development. Default: true in dev. */
|
|
26
|
+
warnMissingKeys?: boolean;
|
|
27
|
+
/** Redirect invalid locale URL prefixes to canonical paths. Default: true. */
|
|
28
|
+
redirectUnknownLocale?: boolean;
|
|
29
|
+
/** Cookie max-age in seconds. Default: 1 year. */
|
|
30
|
+
cookieMaxAge?: number;
|
|
31
|
+
}
|
|
32
|
+
/** Legacy flat-catalog config (still supported). */
|
|
33
|
+
export interface I18nConfig<Catalog extends Record<string, FlatMessages> = Record<string, FlatMessages>> {
|
|
34
|
+
catalog: Catalog;
|
|
35
|
+
locales: readonly (keyof Catalog & string)[];
|
|
36
|
+
defaultLocale: keyof Catalog & string;
|
|
37
|
+
fallbackLocale?: keyof Catalog & string;
|
|
38
|
+
routing?: RoutingMode;
|
|
39
|
+
domains?: Record<string, keyof Catalog & string>;
|
|
40
|
+
paramKey?: string;
|
|
41
|
+
cookieName?: string;
|
|
42
|
+
contextKey?: string;
|
|
43
|
+
}
|
|
44
|
+
export interface Formatters {
|
|
45
|
+
formatDate: (value: Date | number, options?: Intl.DateTimeFormatOptions) => string;
|
|
46
|
+
formatTime: (value: Date | number, options?: Intl.DateTimeFormatOptions) => string;
|
|
47
|
+
formatNumber: (value: number, options?: Intl.NumberFormatOptions) => string;
|
|
48
|
+
formatPercent: (value: number, options?: Intl.NumberFormatOptions) => string;
|
|
49
|
+
formatCurrency: (value: number, currency: string, options?: Intl.NumberFormatOptions) => string;
|
|
50
|
+
}
|
|
51
|
+
export type TranslateValues = Record<string, string | number | boolean | null | undefined>;
|
|
52
|
+
export interface Translator {
|
|
53
|
+
(key: string, values?: TranslateValues, fallback?: string): string;
|
|
54
|
+
}
|
|
55
|
+
export interface I18nContext {
|
|
56
|
+
locale: string;
|
|
57
|
+
defaultLocale: string;
|
|
58
|
+
fallbackLocale: string;
|
|
59
|
+
source: LocaleSource;
|
|
60
|
+
routing: RoutingMode;
|
|
61
|
+
t: Translator;
|
|
62
|
+
formatters: Formatters;
|
|
63
|
+
/** Serializable payload for client hydration — only active locale messages. */
|
|
64
|
+
toClientPayload: () => I18nClientPayload;
|
|
65
|
+
}
|
|
66
|
+
export interface I18nClientPayload {
|
|
67
|
+
locale: string;
|
|
68
|
+
defaultLocale: string;
|
|
69
|
+
fallbackLocale: string;
|
|
70
|
+
messages: FlatMessages;
|
|
71
|
+
routing: RoutingMode;
|
|
72
|
+
}
|
|
73
|
+
export interface LocalizedRouteNames {
|
|
74
|
+
readonly [routeKey: string]: Readonly<Record<string, string>>;
|
|
75
|
+
}
|
|
76
|
+
export interface ResolveLocaleInput {
|
|
77
|
+
pathname: string;
|
|
78
|
+
hostname: string;
|
|
79
|
+
cookie?: string | undefined;
|
|
80
|
+
acceptLanguage?: string | undefined;
|
|
81
|
+
locales: readonly string[];
|
|
82
|
+
defaultLocale: string;
|
|
83
|
+
routing: RoutingMode;
|
|
84
|
+
domains?: Record<string, string> | undefined;
|
|
85
|
+
}
|
|
86
|
+
export interface ResolvedLocaleResult {
|
|
87
|
+
locale: string;
|
|
88
|
+
source: LocaleSource;
|
|
89
|
+
/** Locale segment stripped from pathname, if any. */
|
|
90
|
+
pathLocale?: string | undefined;
|
|
91
|
+
/** Whether the first path segment looks like a locale but is unsupported. */
|
|
92
|
+
unknownPathLocale?: string | undefined;
|
|
93
|
+
/** Canonical pathname without locale prefix. */
|
|
94
|
+
canonicalPathname: string;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kamod-ch/otok-i18n",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Locale resolution, message catalogs, and i18n helpers for Otok apps.",
|
|
5
|
+
"homepage": "https://github.com/kamod-ch/otok/tree/main/packages/otok-i18n#readme",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/kamod-ch/otok/issues"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/kamod-ch/otok.git",
|
|
13
|
+
"directory": "packages/otok-i18n"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"type": "module",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"default": "./dist/index.js"
|
|
24
|
+
},
|
|
25
|
+
"./middleware": {
|
|
26
|
+
"types": "./dist/middleware.d.ts",
|
|
27
|
+
"default": "./dist/middleware.js"
|
|
28
|
+
},
|
|
29
|
+
"./client": {
|
|
30
|
+
"types": "./dist/client.d.ts",
|
|
31
|
+
"default": "./dist/client.js"
|
|
32
|
+
},
|
|
33
|
+
"./routes": {
|
|
34
|
+
"types": "./dist/routes.d.ts",
|
|
35
|
+
"default": "./dist/routes.js"
|
|
36
|
+
},
|
|
37
|
+
"./loader": {
|
|
38
|
+
"types": "./dist/loader.d.ts",
|
|
39
|
+
"default": "./dist/loader.js"
|
|
40
|
+
},
|
|
41
|
+
"./sitemap": {
|
|
42
|
+
"types": "./dist/sitemap.d.ts",
|
|
43
|
+
"default": "./dist/sitemap.js"
|
|
44
|
+
},
|
|
45
|
+
"./switcher": {
|
|
46
|
+
"types": "./dist/switcher.d.ts",
|
|
47
|
+
"default": "./dist/switcher.js"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@kamod-ch/otok": "1.0.0",
|
|
55
|
+
"@kamod-ch/otok-test": "1.0.0",
|
|
56
|
+
"@types/node": "^24.12.2",
|
|
57
|
+
"hono": "^4.13.8",
|
|
58
|
+
"preact": "^10.28.2",
|
|
59
|
+
"preact-render-to-string": "^6.7.0",
|
|
60
|
+
"typescript": "~6.0.2",
|
|
61
|
+
"vitest": "^4.1.2"
|
|
62
|
+
},
|
|
63
|
+
"peerDependencies": {
|
|
64
|
+
"@kamod-ch/otok": ">=0.6.1",
|
|
65
|
+
"hono": ">=4",
|
|
66
|
+
"preact": ">=10"
|
|
67
|
+
},
|
|
68
|
+
"peerDependenciesMeta": {
|
|
69
|
+
"preact": {
|
|
70
|
+
"optional": true
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"engines": {
|
|
74
|
+
"node": ">=20"
|
|
75
|
+
},
|
|
76
|
+
"scripts": {
|
|
77
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json",
|
|
78
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
79
|
+
"test": "vitest run"
|
|
80
|
+
}
|
|
81
|
+
}
|