@ubean/i18n 0.2.2 → 0.3.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.
@@ -0,0 +1,330 @@
1
+ import { a as extractLocaleFromPath, n as parseLocaleCookie, r as serializeLocaleCookie, s as localizePath, t as detectLocaleFromAcceptLanguage } from "./detect-BIURd4aL.js";
2
+ import { AsyncLocalStorage } from "node:async_hooks";
3
+ import { compile, createCoreContext, datetime, number, registerMessageCompiler, translate } from "@intlify/core";
4
+ //#region src/context.ts
5
+ /**
6
+ * Request-scoped i18n engine (@intlify/core).
7
+ *
8
+ * `t()` / `d()` / `n()` 必须在 `runWithI18n()`(由 createI18nMiddleware 包住)
9
+ * 内调用。没有 ALS store 时抛错,禁止回落进程全局 locale。
10
+ *
11
+ * Cloudflare Workers:依赖 `nodejs_compat` 的 `AsyncLocalStorage`。不可用时
12
+ * 同样抛错;handler 应改读 `c.get('locale')` 再 `translate(createRequestContext(...))`。
13
+ *
14
+ * Dev 下 CLI 从 Node 加载 `@ubean/app`(进而 `@ubean/i18n`),路由经 Vite
15
+ * `ssrLoadModule` 再打一份 `@ubean/i18n`。ALS / catalogs / locale loader
16
+ * 挂在 `globalThis` 上,保证两份模块读写同一份状态;`t()` 委托 scope 上
17
+ * 绑定的 translate(与创建 ctx 的那份 `@intlify/core` 一致)。
18
+ */
19
+ registerMessageCompiler(compile);
20
+ function createI18nCoreContext(locale, fallback, messages) {
21
+ return createCoreContext({
22
+ locale,
23
+ fallbackLocale: fallback,
24
+ messages,
25
+ missingWarn: false,
26
+ fallbackWarn: false,
27
+ messageCompiler: compile
28
+ });
29
+ }
30
+ const ENGINE_KEY = "__UBEAN_I18N_ENGINE__";
31
+ function getState() {
32
+ const g = globalThis;
33
+ if (!g[ENGINE_KEY]) g[ENGINE_KEY] = {
34
+ storage: new AsyncLocalStorage(),
35
+ catalogs: /* @__PURE__ */ new Map(),
36
+ catalogMeta: /* @__PURE__ */ new Map(),
37
+ fallbackLocaleCode: "en",
38
+ compiled: /* @__PURE__ */ new Map()
39
+ };
40
+ if (!g[ENGINE_KEY].compiled) g[ENGINE_KEY].compiled = /* @__PURE__ */ new Map();
41
+ return g[ENGINE_KEY];
42
+ }
43
+ function setFallbackLocale(code) {
44
+ getState().fallbackLocaleCode = code;
45
+ }
46
+ function getFallbackLocale() {
47
+ return getState().fallbackLocaleCode;
48
+ }
49
+ function setLocaleMessages(code, messages) {
50
+ const state = getState();
51
+ state.catalogs.set(code, messages);
52
+ state.compiled.delete(code);
53
+ }
54
+ function getLocaleMessages(code) {
55
+ return getState().catalogs.get(code);
56
+ }
57
+ function mergeLocaleMessages(code, messages) {
58
+ const state = getState();
59
+ const catalogs = state.catalogs;
60
+ const merged = deepMerge(catalogs.get(code) || {}, messages);
61
+ catalogs.set(code, merged);
62
+ state.compiled.delete(code);
63
+ return merged;
64
+ }
65
+ function setLocaleMeta(code, meta) {
66
+ const catalogMeta = getState().catalogMeta;
67
+ const prev = catalogMeta.get(code);
68
+ catalogMeta.set(code, {
69
+ name: meta.name ?? prev?.name,
70
+ dir: meta.dir ?? prev?.dir ?? "ltr",
71
+ language: meta.language ?? prev?.language,
72
+ isDefault: meta.isDefault ?? prev?.isDefault
73
+ });
74
+ }
75
+ function getLocaleMeta(code) {
76
+ return getState().catalogMeta.get(code);
77
+ }
78
+ function listLocaleCodes() {
79
+ const { catalogs, catalogMeta } = getState();
80
+ return Array.from(/* @__PURE__ */ new Set([...catalogs.keys(), ...catalogMeta.keys()]));
81
+ }
82
+ function getRegisteredLocalesMeta() {
83
+ const { catalogMeta } = getState();
84
+ return listLocaleCodes().map((code) => {
85
+ const meta = catalogMeta.get(code);
86
+ return {
87
+ code,
88
+ name: meta?.name,
89
+ dir: meta?.dir || "ltr",
90
+ language: meta?.language,
91
+ isDefault: meta?.isDefault
92
+ };
93
+ });
94
+ }
95
+ function getLocaleDir(locale) {
96
+ const { storage, catalogMeta } = getState();
97
+ const code = locale || storage.getStore()?.locale;
98
+ if (!code) return "ltr";
99
+ return catalogMeta.get(code)?.dir || "ltr";
100
+ }
101
+ function getLocaleName(locale) {
102
+ const { storage, catalogMeta } = getState();
103
+ const code = locale || storage.getStore()?.locale;
104
+ if (!code) return void 0;
105
+ return catalogMeta.get(code)?.name;
106
+ }
107
+ /**
108
+ * Vite 图里的 `ubean:locales` 在求值时注册;Node 侧中间件通过
109
+ * `ensureLocaleMessages` 调用,避免 `import('ubean:locales')` 在 CLI 进程里 404。
110
+ */
111
+ function registerLocaleLoader(loader) {
112
+ getState().loadLocale = loader;
113
+ }
114
+ async function ensureLocaleMessages(locale, fallback) {
115
+ const loader = getState().loadLocale;
116
+ if (loader) {
117
+ await loader(locale);
118
+ if (fallback && fallback !== locale) await loader(fallback);
119
+ return;
120
+ }
121
+ try {
122
+ const mod = await import("ubean:locales");
123
+ if (mod.loadLocale) {
124
+ getState().loadLocale = mod.loadLocale;
125
+ await mod.loadLocale(locale);
126
+ if (fallback && fallback !== locale) await mod.loadLocale(fallback);
127
+ }
128
+ } catch {}
129
+ }
130
+ function catalogFingerprint(locale, fallback, catalogs) {
131
+ const loc = catalogs.get(locale);
132
+ const fb = locale === fallback ? void 0 : catalogs.get(fallback);
133
+ return `${locale}:${fallback}:${loc ? Object.keys(loc).join(",") : ""}:${fb ? Object.keys(fb).join(",") : ""}`;
134
+ }
135
+ function createRequestContext(locale, fallback) {
136
+ const { catalogs, fallbackLocaleCode, compiled } = getState();
137
+ const fb = fallback ?? fallbackLocaleCode;
138
+ const fingerprint = catalogFingerprint(locale, fb, catalogs);
139
+ const cached = compiled.get(locale);
140
+ if (cached && cached.key === fingerprint) return cached.ctx;
141
+ const messages = {};
142
+ const locMsgs = catalogs.get(locale);
143
+ if (locMsgs) messages[locale] = locMsgs;
144
+ if (fb !== locale) {
145
+ const fbMsgs = catalogs.get(fb);
146
+ if (fbMsgs) messages[fb] = fbMsgs;
147
+ }
148
+ const ctx = createI18nCoreContext(locale, fb, messages);
149
+ compiled.set(locale, {
150
+ key: fingerprint,
151
+ ctx
152
+ });
153
+ return ctx;
154
+ }
155
+ function bindScope(scope) {
156
+ if (scope.t && scope.d && scope.n) return scope;
157
+ const { ctx } = scope;
158
+ return {
159
+ ...scope,
160
+ t: (key, ...args) => {
161
+ try {
162
+ const result = translate(ctx, key, ...args);
163
+ return typeof result === "string" ? result : key;
164
+ } catch {
165
+ return key;
166
+ }
167
+ },
168
+ d: (value, ...args) => String(datetime(ctx, value, ...args)),
169
+ n: (value, ...args) => String(number(ctx, value, ...args))
170
+ };
171
+ }
172
+ function runWithI18n(scope, fn) {
173
+ return getState().storage.run(bindScope(scope), fn);
174
+ }
175
+ function getI18nScope() {
176
+ return getState().storage.getStore();
177
+ }
178
+ function getRequestLocale$1() {
179
+ const scope = getState().storage.getStore();
180
+ if (!scope) throw new Error("[ubean/i18n] t()/getRequestLocale() called outside request scope (no AsyncLocalStorage store)");
181
+ return scope.locale;
182
+ }
183
+ function t(key, ...args) {
184
+ const scope = getState().storage.getStore();
185
+ if (!scope) throw new Error("[ubean/i18n] t() called outside request scope. Use createI18nMiddleware or runWithI18n().");
186
+ return (scope.t ?? bindScope(scope).t)(key, ...args);
187
+ }
188
+ function d(value, ...args) {
189
+ const scope = getState().storage.getStore();
190
+ if (!scope) throw new Error("[ubean/i18n] d() called outside request scope");
191
+ return (scope.d ?? bindScope(scope).d)(value, ...args);
192
+ }
193
+ function n(value, ...args) {
194
+ const scope = getState().storage.getStore();
195
+ if (!scope) throw new Error("[ubean/i18n] n() called outside request scope");
196
+ return (scope.n ?? bindScope(scope).n)(value, ...args);
197
+ }
198
+ function isMessageDict(value) {
199
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
200
+ }
201
+ function deepMerge(target, source) {
202
+ const result = { ...target };
203
+ for (const key of Object.keys(source)) {
204
+ const srcVal = source[key];
205
+ const tgtVal = result[key];
206
+ if (isMessageDict(srcVal) && isMessageDict(tgtVal)) result[key] = deepMerge(tgtVal, srcVal);
207
+ else result[key] = srcVal;
208
+ }
209
+ return result;
210
+ }
211
+ //#endregion
212
+ //#region src/routing.ts
213
+ const DETECT_DEFAULTS = {
214
+ cookieName: "ubean_locale",
215
+ redirectOn: "root",
216
+ alwaysRedirect: false
217
+ };
218
+ function routingFrom(options) {
219
+ return {
220
+ defaultLocale: options.defaultLocale,
221
+ locales: options.locales,
222
+ strategy: options.strategy
223
+ };
224
+ }
225
+ function isRootPath(path) {
226
+ return path === "/" || path === "";
227
+ }
228
+ function shouldSkipDetect(path) {
229
+ return path.startsWith("/api/") || path.startsWith("/_") || path.startsWith("/__");
230
+ }
231
+ function resolvePreferredFromRequest(c, detect, cookieName, locales, defaultLocale) {
232
+ if (!detect) return defaultLocale;
233
+ const cookieLocale = parseLocaleCookie(c.req.header("cookie"), cookieName);
234
+ if (cookieLocale && locales.includes(cookieLocale)) return cookieLocale;
235
+ return detectLocaleFromAcceptLanguage(c.req.header("accept-language"), locales, defaultLocale);
236
+ }
237
+ function createI18nMiddleware(options) {
238
+ const { strategy, defaultLocale, locales } = options;
239
+ const detect = options.detectBrowserLanguage === false ? false : {
240
+ ...DETECT_DEFAULTS,
241
+ ...options.detectBrowserLanguage
242
+ };
243
+ const cookieName = detect ? detect.cookieName : DETECT_DEFAULTS.cookieName;
244
+ const routing = routingFrom(options);
245
+ setFallbackLocale(defaultLocale);
246
+ return async function i18nMiddleware(c, next) {
247
+ const url = new URL(c.req.url);
248
+ const path = url.pathname;
249
+ if (shouldSkipDetect(path)) {
250
+ const preferred = resolvePreferredFromRequest(c, detect, cookieName, locales, defaultLocale);
251
+ c.set("locale", preferred);
252
+ const fallback = getFallbackLocale();
253
+ if (options.loadMessages) await options.loadMessages(preferred, fallback);
254
+ else await ensureLocaleMessages(preferred, fallback);
255
+ await runWithI18n({
256
+ locale: preferred,
257
+ fallbackLocale: fallback,
258
+ ctx: createRequestContext(preferred, fallback)
259
+ }, () => next());
260
+ return;
261
+ }
262
+ const extracted = extractLocaleFromPath(path, locales);
263
+ let detectedLocale = defaultLocale;
264
+ if (extracted.locale && locales.includes(extracted.locale)) {
265
+ if (strategy === "prefix_except_default" && extracted.locale === defaultLocale) {
266
+ writeCookie(c, defaultLocale);
267
+ return c.redirect(extracted.pathWithoutLocale + url.search, 302);
268
+ }
269
+ detectedLocale = extracted.locale;
270
+ c.set("pathWithoutLocale", extracted.pathWithoutLocale);
271
+ } else if (strategy === "prefix") {
272
+ const preferred = resolvePreferred();
273
+ const redirectUrl = localizePath(path, preferred, routing);
274
+ if (redirectUrl !== path) {
275
+ writeCookie(c, preferred);
276
+ return c.redirect(redirectUrl + url.search, 302);
277
+ }
278
+ detectedLocale = preferred;
279
+ } else if (strategy === "prefix_and_default") {
280
+ detectedLocale = defaultLocale;
281
+ c.set("pathWithoutLocale", path);
282
+ } else if (strategy === "prefix_except_default") {
283
+ if (detect && (detect.redirectOn === "all" || detect.redirectOn === "root" && isRootPath(path))) {
284
+ const preferred = resolvePreferred();
285
+ if (preferred !== defaultLocale) {
286
+ const redirectUrl = localizePath(path, preferred, routing);
287
+ writeCookie(c, preferred);
288
+ return c.redirect(redirectUrl + url.search, 302);
289
+ }
290
+ }
291
+ detectedLocale = defaultLocale;
292
+ c.set("pathWithoutLocale", path);
293
+ } else if (strategy === "no_prefix") {
294
+ detectedLocale = resolvePreferred();
295
+ c.set("pathWithoutLocale", path);
296
+ }
297
+ function resolvePreferred() {
298
+ if (detect) {
299
+ const cookieLocale = parseLocaleCookie(c.req.header("cookie"), cookieName);
300
+ if (cookieLocale && locales.includes(cookieLocale)) return cookieLocale;
301
+ const header = c.req.header("accept-language");
302
+ return detectLocaleFromAcceptLanguage(header, locales, defaultLocale);
303
+ }
304
+ return defaultLocale;
305
+ }
306
+ writeCookie(c, detectedLocale);
307
+ c.set("locale", detectedLocale);
308
+ c.header("Content-Language", detectedLocale);
309
+ const fallback = getFallbackLocale();
310
+ if (options.loadMessages) await options.loadMessages(detectedLocale, fallback);
311
+ else await ensureLocaleMessages(detectedLocale, fallback);
312
+ const ctx = createRequestContext(detectedLocale, fallback);
313
+ await runWithI18n({
314
+ locale: detectedLocale,
315
+ fallbackLocale: fallback,
316
+ ctx
317
+ }, () => next());
318
+ };
319
+ function writeCookie(c, locale) {
320
+ c.header("Set-Cookie", serializeLocaleCookie(cookieName, locale), { append: true });
321
+ }
322
+ }
323
+ function getRequestLocale(c) {
324
+ return c.get("locale") || "en";
325
+ }
326
+ function getPathWithoutLocale(c) {
327
+ return c.get("pathWithoutLocale") || new URL(c.req.url).pathname;
328
+ }
329
+ //#endregion
330
+ export { t as C, setLocaleMeta as S, n as _, d as a, setFallbackLocale as b, getI18nScope as c, getLocaleMeta as d, getLocaleName as f, mergeLocaleMessages as g, listLocaleCodes as h, createRequestContext as i, getLocaleDir as l, getRequestLocale$1 as m, getPathWithoutLocale as n, ensureLocaleMessages as o, getRegisteredLocalesMeta as p, getRequestLocale as r, getFallbackLocale as s, createI18nMiddleware as t, getLocaleMessages as u, registerLocaleLoader as v, setLocaleMessages as x, runWithI18n as y };
package/dist/routing.d.ts CHANGED
@@ -1,27 +1,9 @@
1
- import { I18nRoutingStrategy } from "./index.js";
1
+ import { a as switchLocalePath, d as I18nRoutingStrategy, i as localizePath, n as extractLocaleFromPath, t as compileLocalePaths, u as I18nMiddlewareOptions } from "./paths-CJVBLGJS.js";
2
2
  import { Context, MiddlewareHandler } from "hono";
3
3
  import { UbeanEnv } from "@ubean/shared";
4
4
  //#region src/routing.d.ts
5
- interface I18nRoutingOptions {
6
- strategy?: I18nRoutingStrategy;
7
- defaultLocale?: string;
8
- locales?: string[];
9
- detectFromHeader?: boolean;
10
- detectFromCookie?: boolean | string;
11
- redirectOnLocaleMismatch?: boolean;
12
- cookieName?: string;
13
- }
14
- declare function createI18nMiddleware(options?: I18nRoutingOptions): MiddlewareHandler<UbeanEnv>;
15
- declare function switchLocalePath(c: Context, locale: string, strategy?: I18nRoutingStrategy, defaultLocale?: string): string;
16
- declare function getLocalePath(c: Context): string;
5
+ declare function createI18nMiddleware(options: I18nMiddlewareOptions): MiddlewareHandler<UbeanEnv>;
6
+ declare function getRequestLocale(c: Context): string;
17
7
  declare function getPathWithoutLocale(c: Context): string;
18
- declare function localeRoutes(locales: string[], defaultLocale: string, strategy?: I18nRoutingStrategy): {
19
- localizePath: (path: string, locale?: string) => string;
20
- getLocaleFromUrl: (url: string) => string | null;
21
- getLocalizedPaths: (path: string) => Array<{
22
- locale: string;
23
- path: string;
24
- }>;
25
- };
26
8
  //#endregion
27
- export { I18nRoutingOptions, type I18nRoutingStrategy, createI18nMiddleware, getLocalePath, getPathWithoutLocale, localeRoutes, switchLocalePath };
9
+ export { type I18nMiddlewareOptions, type I18nRoutingStrategy, compileLocalePaths, createI18nMiddleware, extractLocaleFromPath, getPathWithoutLocale, getRequestLocale, localizePath, switchLocalePath };
package/dist/routing.js CHANGED
@@ -1,129 +1,3 @@
1
- import { useI18n } from "./index.js";
2
- //#region src/routing.ts
3
- function getLocaleFromPath(path, locales) {
4
- const segments = path.split("/");
5
- if (segments.length >= 2 && locales.includes(segments[1])) {
6
- const remainingPath = segments.slice(2).join("/");
7
- return {
8
- locale: segments[1],
9
- pathWithoutLocale: remainingPath ? `/${remainingPath}` : "/"
10
- };
11
- }
12
- return {
13
- locale: null,
14
- pathWithoutLocale: path
15
- };
16
- }
17
- function createI18nMiddleware(options = {}) {
18
- const { strategy = "prefix_except_default", defaultLocale: explicitDefault, locales: explicitLocales, detectFromHeader = true, detectFromCookie = true, redirectOnLocaleMismatch = true, cookieName = "ubean_locale" } = options;
19
- return async function i18nMiddleware(c, next) {
20
- const i18n = useI18n();
21
- const resolvedDefaultLocale = explicitDefault || i18n.fallbackLocale;
22
- const resolvedLocales = explicitLocales || i18n.availableLocales;
23
- const path = new URL(c.req.url).pathname;
24
- let detectedLocale = resolvedDefaultLocale;
25
- if (strategy === "prefix" || strategy === "prefix_except_default" || strategy === "prefix_and_default") {
26
- const { locale: pathLocale, pathWithoutLocale } = getLocaleFromPath(path, resolvedLocales);
27
- if (pathLocale) {
28
- detectedLocale = pathLocale;
29
- c.set("locale", pathLocale);
30
- c.set("pathWithoutLocale", pathWithoutLocale);
31
- } else if (strategy === "prefix_and_default") {
32
- detectedLocale = resolvedDefaultLocale;
33
- c.set("pathWithoutLocale", path);
34
- } else if (strategy === "prefix") {
35
- const preferredLocale = resolvePreferredLocale();
36
- if (redirectOnLocaleMismatch && preferredLocale !== resolvedDefaultLocale) {
37
- const redirectUrl = `/${preferredLocale}${path === "/" ? "" : path}`;
38
- return c.redirect(redirectUrl, 302);
39
- }
40
- if (redirectOnLocaleMismatch) return c.redirect(`/${resolvedDefaultLocale}${path === "/" ? "" : path}`, 302);
41
- } else if (strategy === "prefix_except_default") {
42
- const preferredLocale = resolvePreferredLocale();
43
- if (preferredLocale !== resolvedDefaultLocale && redirectOnLocaleMismatch) return c.redirect(`/${preferredLocale}${path === "/" ? "" : path}`, 302);
44
- detectedLocale = resolvedDefaultLocale;
45
- }
46
- } else if (strategy === "no_prefix") detectedLocale = resolvePreferredLocale();
47
- function resolvePreferredLocale() {
48
- if (detectFromCookie) {
49
- const cookieLocale = c.req.header("cookie");
50
- if (cookieLocale) {
51
- const match = cookieLocale.match(new RegExp(`${cookieName}=([^;]+)`));
52
- if (match && resolvedLocales.includes(match[1])) return match[1];
53
- }
54
- }
55
- if (detectFromHeader) {
56
- const acceptLang = c.req.header("accept-language");
57
- if (acceptLang) {
58
- const detected = i18n.detectLocale(acceptLang);
59
- if (resolvedLocales.includes(detected)) return detected;
60
- }
61
- }
62
- return resolvedDefaultLocale;
63
- }
64
- if (resolvedLocales.includes(detectedLocale)) i18n.setLocale(detectedLocale);
65
- c.set("locale", detectedLocale);
66
- c.header("Content-Language", detectedLocale);
67
- await next();
68
- };
69
- }
70
- function switchLocalePath(c, locale, strategy = "prefix_except_default", defaultLocale) {
71
- const path = new URL(c.req.url).pathname;
72
- const i18n = useI18n();
73
- const resolvedDefault = defaultLocale || i18n.fallbackLocale;
74
- const resolvedLocales = i18n.availableLocales;
75
- const { pathWithoutLocale } = getLocaleFromPath(path, resolvedLocales);
76
- const cleanPath = pathWithoutLocale === "/" ? "" : pathWithoutLocale;
77
- switch (strategy) {
78
- case "no_prefix": return path;
79
- case "prefix": return `/${locale}${cleanPath}`;
80
- case "prefix_except_default":
81
- case "prefix_and_default":
82
- if (locale === resolvedDefault) return cleanPath || "/";
83
- return `/${locale}${cleanPath}`;
84
- default: return path;
85
- }
86
- }
87
- function getLocalePath(c) {
88
- return c.get("locale") || "en";
89
- }
90
- function getPathWithoutLocale(c) {
91
- return c.get("pathWithoutLocale") || new URL(c.req.url).pathname;
92
- }
93
- function localeRoutes(locales, defaultLocale, strategy = "prefix_except_default") {
94
- function localizePath(path, locale) {
95
- const targetLocale = locale || defaultLocale;
96
- const cleanPath = path.startsWith("/") ? path : `/${path}`;
97
- switch (strategy) {
98
- case "no_prefix": return cleanPath;
99
- case "prefix": return `/${targetLocale}${cleanPath === "/" ? "" : cleanPath}`;
100
- case "prefix_except_default":
101
- case "prefix_and_default":
102
- if (targetLocale === defaultLocale) return cleanPath;
103
- return `/${targetLocale}${cleanPath === "/" ? "" : cleanPath}`;
104
- }
105
- }
106
- function getLocaleFromUrl(url) {
107
- try {
108
- const pathname = new URL(url).pathname;
109
- const { locale } = getLocaleFromPath(pathname, locales);
110
- return locale;
111
- } catch {
112
- const { locale } = getLocaleFromPath(url, locales);
113
- return locale;
114
- }
115
- }
116
- function getLocalizedPaths(path) {
117
- return locales.map((locale) => ({
118
- locale,
119
- path: localizePath(path, locale)
120
- }));
121
- }
122
- return {
123
- localizePath,
124
- getLocaleFromUrl,
125
- getLocalizedPaths
126
- };
127
- }
128
- //#endregion
129
- export { createI18nMiddleware, getLocalePath, getPathWithoutLocale, localeRoutes, switchLocalePath };
1
+ import { a as extractLocaleFromPath, c as switchLocalePath, i as compileLocalePaths, s as localizePath } from "./detect-BIURd4aL.js";
2
+ import { n as getPathWithoutLocale, r as getRequestLocale, t as createI18nMiddleware } from "./routing-D4Y0l8jV.js";
3
+ export { compileLocalePaths, createI18nMiddleware, extractLocaleFromPath, getPathWithoutLocale, getRequestLocale, localizePath, switchLocalePath };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ubean/i18n",
3
- "version": "0.2.2",
4
- "description": "Zero-dependency i18n for ubean (defineLocale, t, formatDate, routing)",
3
+ "version": "0.3.0",
4
+ "description": "i18n for ubean (vue-i18n / @intlify/core, compact locale routing, ALS)",
5
5
  "files": [
6
6
  "dist"
7
7
  ],
@@ -17,17 +17,25 @@
17
17
  "./routing": {
18
18
  "types": "./dist/routing.d.ts",
19
19
  "import": "./dist/routing.js"
20
+ },
21
+ "./browser": {
22
+ "types": "./dist/browser.d.ts",
23
+ "import": "./dist/browser.js"
20
24
  }
21
25
  },
22
26
  "dependencies": {
27
+ "@intlify/core": "11.4.8",
23
28
  "hono": "4.13.3",
24
- "@ubean/shared": "0.2.2"
29
+ "@ubean/shared": "0.3.0"
25
30
  },
26
31
  "devDependencies": {
27
32
  "@types/node": "^26.2.0",
28
33
  "typescript": "7.0.2",
29
34
  "vite-plus": "0.2.9"
30
35
  },
36
+ "engines": {
37
+ "node": ">=22"
38
+ },
31
39
  "scripts": {
32
40
  "build": "vp pack",
33
41
  "dev": "vp pack --watch",