@i18n-micro/vitepress 1.0.1 → 1.1.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 (49) hide show
  1. package/README.md +73 -39
  2. package/client.d.ts +1 -0
  3. package/dist/adapter-BJ-0ltIc.cjs +2 -0
  4. package/dist/adapter-BJ-0ltIc.cjs.map +1 -0
  5. package/dist/adapter-BnsyIKhp.js +128 -0
  6. package/dist/adapter-BnsyIKhp.js.map +1 -0
  7. package/dist/config.cjs +64 -1
  8. package/dist/config.cjs.map +1 -1
  9. package/dist/config.d.cts +113 -111
  10. package/dist/config.d.ts +113 -111
  11. package/dist/config.mjs +393 -9
  12. package/dist/config.mjs.map +1 -1
  13. package/dist/create-BgMbe0w1.cjs +2 -0
  14. package/dist/create-BgMbe0w1.cjs.map +1 -0
  15. package/dist/create-Dev8Q66O.js +80 -0
  16. package/dist/create-Dev8Q66O.js.map +1 -0
  17. package/dist/index.cjs +1 -1
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +87 -141
  20. package/dist/index.d.ts +87 -141
  21. package/dist/index.mjs +28 -249
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/node.cjs +1 -1
  24. package/dist/node.cjs.map +1 -1
  25. package/dist/node.d.cts +56 -116
  26. package/dist/node.d.ts +56 -116
  27. package/dist/node.mjs +23 -7
  28. package/dist/node.mjs.map +1 -1
  29. package/dist/{virtual-stubs → plugin/virtual-stubs}/config.d.cts +2 -1
  30. package/dist/runtime/define-theme.d.cts +39 -0
  31. package/dist/theme.cjs +2 -0
  32. package/dist/theme.cjs.map +1 -0
  33. package/dist/theme.d.cts +58 -0
  34. package/dist/theme.d.ts +58 -0
  35. package/dist/theme.mjs +35 -0
  36. package/dist/theme.mjs.map +1 -0
  37. package/dist/vitepress-locales-6msv22Sn.js +27 -0
  38. package/dist/vitepress-locales-6msv22Sn.js.map +1 -0
  39. package/dist/vitepress-locales-Cz4AutfI.cjs +2 -0
  40. package/dist/vitepress-locales-Cz4AutfI.cjs.map +1 -0
  41. package/package.json +18 -6
  42. package/dist/i18n-routing-CcppCuuS.js +0 -64
  43. package/dist/i18n-routing-CcppCuuS.js.map +0 -1
  44. package/dist/i18n-routing-D9iYAKDq.cjs +0 -46
  45. package/dist/i18n-routing-D9iYAKDq.cjs.map +0 -1
  46. package/dist/with-i18n-micro-01q-vPO9.cjs +0 -15
  47. package/dist/with-i18n-micro-01q-vPO9.cjs.map +0 -1
  48. package/dist/with-i18n-micro-DIAoqY71.js +0 -216
  49. package/dist/with-i18n-micro-DIAoqY71.js.map +0 -1
@@ -0,0 +1,58 @@
1
+ import { Locale } from '@i18n-micro/types';
2
+ import { PluralFunc } from '@i18n-micro/types';
3
+ import { Theme } from 'vitepress';
4
+ import { Translations } from '@i18n-micro/types';
5
+
6
+ /**
7
+ * Zero-boilerplate theme wiring. Requires `withI18n(...)` in `.vitepress/config`
8
+ * so virtual config + messages modules exist.
9
+ *
10
+ * Uses **static** `virtual:i18n-micro/*` imports so VitePress SSG can rewrite them.
11
+ * Import this helper from `@i18n-micro/vitepress/theme` (not the root entry) so Node
12
+ * config evaluation never loads virtual modules.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import DefaultTheme from 'vitepress/theme'
17
+ * import { defineI18nTheme } from '@i18n-micro/vitepress/theme'
18
+ *
19
+ * export default defineI18nTheme(DefaultTheme)
20
+ * ```
21
+ */
22
+ export declare function defineI18nTheme<T extends Theme>(base: T, options?: DefineI18nThemeOptions): T;
23
+
24
+ export declare interface DefineI18nThemeOptions {
25
+ /**
26
+ * Extra `enhanceApp` run after i18n is installed.
27
+ */
28
+ enhanceApp?: NonNullable<Theme['enhanceApp']>;
29
+ /**
30
+ * Overrides not serializable into `virtual:i18n-micro/config`.
31
+ */
32
+ plural?: PluralFunc;
33
+ missingHandler?: (locale: string, key: string, routeName: string) => void;
34
+ localeKeyToCode?: Record<string, string>;
35
+ /**
36
+ * Optional overrides (tests / advanced). Defaults come from `virtual:i18n-micro/*`
37
+ * registered by `withI18n`.
38
+ */
39
+ config?: VirtualI18nConfig;
40
+ messages?: Record<string, Translations>;
41
+ routeMessages?: Record<string, Record<string, Translations>>;
42
+ }
43
+
44
+ declare interface VirtualI18nConfig {
45
+ defaultLocale: string;
46
+ fallbackLocale: string;
47
+ locales: Locale[];
48
+ localeCodes: string[];
49
+ missingWarn: boolean;
50
+ syncWithVitePress: boolean;
51
+ translationDir: string;
52
+ disablePageLocales: boolean;
53
+ localeKeyToCode: Record<string, string>;
54
+ /** VitePress `site.base` (normalized, trailing slash preserved from config). */
55
+ base?: string;
56
+ }
57
+
58
+ export { }
@@ -0,0 +1,58 @@
1
+ import { Locale } from '@i18n-micro/types';
2
+ import { PluralFunc } from '@i18n-micro/types';
3
+ import { Theme } from 'vitepress';
4
+ import { Translations } from '@i18n-micro/types';
5
+
6
+ /**
7
+ * Zero-boilerplate theme wiring. Requires `withI18n(...)` in `.vitepress/config`
8
+ * so virtual config + messages modules exist.
9
+ *
10
+ * Uses **static** `virtual:i18n-micro/*` imports so VitePress SSG can rewrite them.
11
+ * Import this helper from `@i18n-micro/vitepress/theme` (not the root entry) so Node
12
+ * config evaluation never loads virtual modules.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import DefaultTheme from 'vitepress/theme'
17
+ * import { defineI18nTheme } from '@i18n-micro/vitepress/theme'
18
+ *
19
+ * export default defineI18nTheme(DefaultTheme)
20
+ * ```
21
+ */
22
+ export declare function defineI18nTheme<T extends Theme>(base: T, options?: DefineI18nThemeOptions): T;
23
+
24
+ export declare interface DefineI18nThemeOptions {
25
+ /**
26
+ * Extra `enhanceApp` run after i18n is installed.
27
+ */
28
+ enhanceApp?: NonNullable<Theme['enhanceApp']>;
29
+ /**
30
+ * Overrides not serializable into `virtual:i18n-micro/config`.
31
+ */
32
+ plural?: PluralFunc;
33
+ missingHandler?: (locale: string, key: string, routeName: string) => void;
34
+ localeKeyToCode?: Record<string, string>;
35
+ /**
36
+ * Optional overrides (tests / advanced). Defaults come from `virtual:i18n-micro/*`
37
+ * registered by `withI18n`.
38
+ */
39
+ config?: VirtualI18nConfig;
40
+ messages?: Record<string, Translations>;
41
+ routeMessages?: Record<string, Record<string, Translations>>;
42
+ }
43
+
44
+ declare interface VirtualI18nConfig {
45
+ defaultLocale: string;
46
+ fallbackLocale: string;
47
+ locales: Locale[];
48
+ localeCodes: string[];
49
+ missingWarn: boolean;
50
+ syncWithVitePress: boolean;
51
+ translationDir: string;
52
+ disablePageLocales: boolean;
53
+ localeKeyToCode: Record<string, string>;
54
+ /** VitePress `site.base` (normalized, trailing slash preserved from config). */
55
+ base?: string;
56
+ }
57
+
58
+ export { }
package/dist/theme.mjs ADDED
@@ -0,0 +1,35 @@
1
+ import { config as d } from "virtual:i18n-micro/config";
2
+ import { messages as u, routeMessages as h } from "virtual:i18n-micro/messages";
3
+ import { c as y } from "./create-Dev8Q66O.js";
4
+ import { g as L } from "./adapter-BnsyIKhp.js";
5
+ function W(o, a = {}) {
6
+ const n = a.enhanceApp, c = o.enhanceApp, r = /* @__PURE__ */ new WeakMap();
7
+ return {
8
+ ...o,
9
+ async enhanceApp(s) {
10
+ let l = r.get(s.app);
11
+ if (!l) {
12
+ const e = a.config ?? d, i = a.messages ?? u, p = a.routeMessages ?? h, g = e.localeCodes.length ? e.localeCodes : e.locales.map((f) => f.code), t = a.localeKeyToCode ?? e.localeKeyToCode, m = L(s.router.route.path, g, e.defaultLocale, t, e.base);
13
+ l = y({
14
+ locale: m,
15
+ defaultLocale: e.defaultLocale,
16
+ fallbackLocale: e.fallbackLocale,
17
+ locales: e.locales,
18
+ messages: i,
19
+ routeMessages: p,
20
+ missingWarn: e.missingWarn ?? void 0,
21
+ syncWithVitePress: e.syncWithVitePress,
22
+ localeKeyToCode: t,
23
+ base: e.base,
24
+ plural: a.plural,
25
+ missingHandler: a.missingHandler
26
+ }), r.set(s.app, l);
27
+ }
28
+ l.enhanceApp(s), c && await c(s), n && await n(s), l.enhanceApp(s);
29
+ }
30
+ };
31
+ }
32
+ export {
33
+ W as defineI18nTheme
34
+ };
35
+ //# sourceMappingURL=theme.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.mjs","sources":["../src/runtime/define-theme.ts"],"sourcesContent":["import type { PluralFunc, Translations } from '@i18n-micro/types'\nimport type { Theme } from 'vitepress'\nimport { config as virtualConfig } from 'virtual:i18n-micro/config'\nimport { messages as virtualMessages, routeMessages as virtualRouteMessages } from 'virtual:i18n-micro/messages'\nimport { createI18n, type CreateI18nResult } from './create'\nimport { getLocaleFromPath } from '../router/adapter'\nimport type { VirtualI18nConfig } from '../plugin/with-i18n'\n\ntype EnhanceAppContext = Parameters<NonNullable<Theme['enhanceApp']>>[0]\n\nexport interface DefineI18nThemeOptions {\n /**\n * Extra `enhanceApp` run after i18n is installed.\n */\n enhanceApp?: NonNullable<Theme['enhanceApp']>\n /**\n * Overrides not serializable into `virtual:i18n-micro/config`.\n */\n plural?: PluralFunc\n missingHandler?: (locale: string, key: string, routeName: string) => void\n localeKeyToCode?: Record<string, string>\n /**\n * Optional overrides (tests / advanced). Defaults come from `virtual:i18n-micro/*`\n * registered by `withI18n`.\n */\n config?: VirtualI18nConfig\n messages?: Record<string, Translations>\n routeMessages?: Record<string, Record<string, Translations>>\n}\n\n/**\n * Zero-boilerplate theme wiring. Requires `withI18n(...)` in `.vitepress/config`\n * so virtual config + messages modules exist.\n *\n * Uses **static** `virtual:i18n-micro/*` imports so VitePress SSG can rewrite them.\n * Import this helper from `@i18n-micro/vitepress/theme` (not the root entry) so Node\n * config evaluation never loads virtual modules.\n *\n * @example\n * ```ts\n * import DefaultTheme from 'vitepress/theme'\n * import { defineI18nTheme } from '@i18n-micro/vitepress/theme'\n *\n * export default defineI18nTheme(DefaultTheme)\n * ```\n */\nexport function defineI18nTheme<T extends Theme>(base: T, options: DefineI18nThemeOptions = {}): T {\n const userEnhance = options.enhanceApp\n const baseEnhance = base.enhanceApp\n\n // Per app instance (SSR-safe: WeakMap by app).\n const byApp = new WeakMap<object, CreateI18nResult>()\n\n return {\n ...base,\n async enhanceApp(ctx: EnhanceAppContext) {\n let installed = byApp.get(ctx.app)\n if (!installed) {\n // Cast via `unknown`: root typecheck also sees Astro's ambient `virtual:i18n-micro/config`.\n const config = (options.config ?? virtualConfig) as unknown as VirtualI18nConfig\n const messages = options.messages ?? (virtualMessages as Record<string, Translations>)\n const routeMessages = options.routeMessages ?? (virtualRouteMessages as Record<string, Record<string, Translations>>)\n\n const localeCodes = config.localeCodes.length ? config.localeCodes : config.locales.map((l) => l.code)\n const localeKeyToCode = options.localeKeyToCode ?? config.localeKeyToCode\n const initialLocale = getLocaleFromPath(ctx.router.route.path, localeCodes, config.defaultLocale, localeKeyToCode, config.base)\n\n installed = createI18n({\n locale: initialLocale,\n defaultLocale: config.defaultLocale,\n fallbackLocale: config.fallbackLocale,\n locales: config.locales,\n messages,\n routeMessages,\n missingWarn: config.missingWarn ?? undefined,\n syncWithVitePress: config.syncWithVitePress,\n localeKeyToCode,\n base: config.base,\n plural: options.plural,\n missingHandler: options.missingHandler,\n })\n byApp.set(ctx.app, installed)\n }\n\n // Install plugin first so base/user enhanceApp can use $t / components.\n installed.enhanceApp(ctx as unknown as Parameters<typeof installed.enhanceApp>[0])\n if (baseEnhance) await baseEnhance(ctx)\n if (userEnhance) await userEnhance(ctx)\n // Re-run so route sync wraps any onAfterRouteChange set by base/user.\n installed.enhanceApp(ctx as unknown as Parameters<typeof installed.enhanceApp>[0])\n },\n }\n}\n"],"names":["defineI18nTheme","base","options","userEnhance","baseEnhance","byApp","ctx","installed","config","virtualConfig","messages","virtualMessages","routeMessages","virtualRouteMessages","localeCodes","l","localeKeyToCode","initialLocale","getLocaleFromPath","createI18n"],"mappings":";;;;AA8CO,SAASA,EAAiCC,GAASC,IAAkC,IAAO;AACjG,QAAMC,IAAcD,EAAQ,YACtBE,IAAcH,EAAK,YAGnBI,wBAAY,QAAA;AAElB,SAAO;AAAA,IACL,GAAGJ;AAAA,IACH,MAAM,WAAWK,GAAwB;AACvC,UAAIC,IAAYF,EAAM,IAAIC,EAAI,GAAG;AACjC,UAAI,CAACC,GAAW;AAEd,cAAMC,IAAUN,EAAQ,UAAUO,GAC5BC,IAAWR,EAAQ,YAAaS,GAChCC,IAAgBV,EAAQ,iBAAkBW,GAE1CC,IAAcN,EAAO,YAAY,SAASA,EAAO,cAAcA,EAAO,QAAQ,IAAI,CAACO,MAAMA,EAAE,IAAI,GAC/FC,IAAkBd,EAAQ,mBAAmBM,EAAO,iBACpDS,IAAgBC,EAAkBZ,EAAI,OAAO,MAAM,MAAMQ,GAAaN,EAAO,eAAeQ,GAAiBR,EAAO,IAAI;AAE9H,QAAAD,IAAYY,EAAW;AAAA,UACrB,QAAQF;AAAA,UACR,eAAeT,EAAO;AAAA,UACtB,gBAAgBA,EAAO;AAAA,UACvB,SAASA,EAAO;AAAA,UAAA,UAChBE;AAAAA,UAAA,eACAE;AAAAA,UACA,aAAaJ,EAAO,eAAe;AAAA,UACnC,mBAAmBA,EAAO;AAAA,UAC1B,iBAAAQ;AAAA,UACA,MAAMR,EAAO;AAAA,UACb,QAAQN,EAAQ;AAAA,UAChB,gBAAgBA,EAAQ;AAAA,QAAA,CACzB,GACDG,EAAM,IAAIC,EAAI,KAAKC,CAAS;AAAA,MAC9B;AAGA,MAAAA,EAAU,WAAWD,CAA4D,GAC7EF,KAAa,MAAMA,EAAYE,CAAG,GAClCH,KAAa,MAAMA,EAAYG,CAAG,GAEtCC,EAAU,WAAWD,CAA4D;AAAA,IACnF;AAAA,EAAA;AAEJ;"}
@@ -0,0 +1,27 @@
1
+ function a(e, n, c) {
2
+ for (const [s, t] of Object.entries(c))
3
+ if (t === e) return s;
4
+ return e === n ? "root" : e;
5
+ }
6
+ function d(e, n, c = {}) {
7
+ const s = c.localeKeyToCode ?? {}, t = {};
8
+ for (const o of e) {
9
+ const r = a(o.code, n, s), l = r === "root" ? o.code : r, i = {
10
+ label: o.displayName || o.code.toUpperCase(),
11
+ lang: o.iso || o.code
12
+ };
13
+ r !== "root" && (i.link = `/${l}/`), t[r] = i;
14
+ }
15
+ if (!t.root) {
16
+ const o = e.find((r) => r.code === n) ?? e[0];
17
+ o && (t.root = {
18
+ label: o.displayName || o.code.toUpperCase(),
19
+ lang: o.iso || o.code
20
+ });
21
+ }
22
+ return t;
23
+ }
24
+ export {
25
+ d as b
26
+ };
27
+ //# sourceMappingURL=vitepress-locales-6msv22Sn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vitepress-locales-6msv22Sn.js","sources":["../src/plugin/vitepress-locales.ts"],"sourcesContent":["import type { Locale } from '@i18n-micro/types'\n\n/**\n * Minimal VitePress `locales` entry used by the default theme language menu.\n */\nexport interface VitePressLocaleEntry {\n label: string\n lang: string\n link?: string\n}\n\nexport interface BuildVitePressLocalesOptions {\n /**\n * Map VitePress locale keys → i18n codes (`root` → default).\n * When a non-default code maps to a short VP key (`fr` → `fr-FR`), the URL\n * prefix / config key uses the VP key.\n */\n localeKeyToCode?: Record<string, string>\n}\n\nfunction localeKeyFromCode(code: string, defaultLocale: string, localeKeyToCode: Record<string, string>): string {\n for (const [key, mapped] of Object.entries(localeKeyToCode)) {\n if (mapped === code) return key\n }\n if (code === defaultLocale) return 'root'\n return code\n}\n\n/**\n * Build VitePress `config.locales` from i18n-micro `Locale[]`.\n * Default locale becomes `root` (no URL prefix); others get `/{key}/`.\n */\nexport function buildVitePressLocales(\n locales: Locale[],\n defaultLocale: string,\n options: BuildVitePressLocalesOptions = {},\n): Record<string, VitePressLocaleEntry> {\n const localeKeyToCode = options.localeKeyToCode ?? {}\n const result: Record<string, VitePressLocaleEntry> = {}\n\n for (const loc of locales) {\n const key = localeKeyFromCode(loc.code, defaultLocale, localeKeyToCode)\n const urlKey = key === 'root' ? loc.code : key\n const entry: VitePressLocaleEntry = {\n label: loc.displayName || loc.code.toUpperCase(),\n lang: loc.iso || loc.code,\n }\n if (key !== 'root') {\n entry.link = `/${urlKey}/`\n }\n result[key] = entry\n }\n\n if (!result.root) {\n const fallback = locales.find((l) => l.code === defaultLocale) ?? locales[0]\n if (fallback) {\n result.root = {\n label: fallback.displayName || fallback.code.toUpperCase(),\n lang: fallback.iso || fallback.code,\n }\n }\n }\n\n return result\n}\n"],"names":["localeKeyFromCode","code","defaultLocale","localeKeyToCode","key","mapped","buildVitePressLocales","locales","options","result","loc","urlKey","entry","fallback","l"],"mappings":"AAoBA,SAASA,EAAkBC,GAAcC,GAAuBC,GAAiD;AAC/G,aAAW,CAACC,GAAKC,CAAM,KAAK,OAAO,QAAQF,CAAe;AACxD,QAAIE,MAAWJ,EAAM,QAAOG;AAE9B,SAAIH,MAASC,IAAsB,SAC5BD;AACT;AAMO,SAASK,EACdC,GACAL,GACAM,IAAwC,CAAA,GACF;AACtC,QAAML,IAAkBK,EAAQ,mBAAmB,CAAA,GAC7CC,IAA+C,CAAA;AAErD,aAAWC,KAAOH,GAAS;AACzB,UAAMH,IAAMJ,EAAkBU,EAAI,MAAMR,GAAeC,CAAe,GAChEQ,IAASP,MAAQ,SAASM,EAAI,OAAON,GACrCQ,IAA8B;AAAA,MAClC,OAAOF,EAAI,eAAeA,EAAI,KAAK,YAAA;AAAA,MACnC,MAAMA,EAAI,OAAOA,EAAI;AAAA,IAAA;AAEvB,IAAIN,MAAQ,WACVQ,EAAM,OAAO,IAAID,CAAM,MAEzBF,EAAOL,CAAG,IAAIQ;AAAA,EAChB;AAEA,MAAI,CAACH,EAAO,MAAM;AAChB,UAAMI,IAAWN,EAAQ,KAAK,CAACO,MAAMA,EAAE,SAASZ,CAAa,KAAKK,EAAQ,CAAC;AAC3E,IAAIM,MACFJ,EAAO,OAAO;AAAA,MACZ,OAAOI,EAAS,eAAeA,EAAS,KAAK,YAAA;AAAA,MAC7C,MAAMA,EAAS,OAAOA,EAAS;AAAA,IAAA;AAAA,EAGrC;AAEA,SAAOJ;AACT;"}
@@ -0,0 +1,2 @@
1
+ "use strict";function a(e,n,s){for(const[c,t]of Object.entries(s))if(t===e)return c;return e===n?"root":e}function d(e,n,s={}){const c=s.localeKeyToCode??{},t={};for(const o of e){const r=a(o.code,n,c),l=r==="root"?o.code:r,i={label:o.displayName||o.code.toUpperCase(),lang:o.iso||o.code};r!=="root"&&(i.link=`/${l}/`),t[r]=i}if(!t.root){const o=e.find(r=>r.code===n)??e[0];o&&(t.root={label:o.displayName||o.code.toUpperCase(),lang:o.iso||o.code})}return t}exports.buildVitePressLocales=d;
2
+ //# sourceMappingURL=vitepress-locales-Cz4AutfI.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vitepress-locales-Cz4AutfI.cjs","sources":["../src/plugin/vitepress-locales.ts"],"sourcesContent":["import type { Locale } from '@i18n-micro/types'\n\n/**\n * Minimal VitePress `locales` entry used by the default theme language menu.\n */\nexport interface VitePressLocaleEntry {\n label: string\n lang: string\n link?: string\n}\n\nexport interface BuildVitePressLocalesOptions {\n /**\n * Map VitePress locale keys → i18n codes (`root` → default).\n * When a non-default code maps to a short VP key (`fr` → `fr-FR`), the URL\n * prefix / config key uses the VP key.\n */\n localeKeyToCode?: Record<string, string>\n}\n\nfunction localeKeyFromCode(code: string, defaultLocale: string, localeKeyToCode: Record<string, string>): string {\n for (const [key, mapped] of Object.entries(localeKeyToCode)) {\n if (mapped === code) return key\n }\n if (code === defaultLocale) return 'root'\n return code\n}\n\n/**\n * Build VitePress `config.locales` from i18n-micro `Locale[]`.\n * Default locale becomes `root` (no URL prefix); others get `/{key}/`.\n */\nexport function buildVitePressLocales(\n locales: Locale[],\n defaultLocale: string,\n options: BuildVitePressLocalesOptions = {},\n): Record<string, VitePressLocaleEntry> {\n const localeKeyToCode = options.localeKeyToCode ?? {}\n const result: Record<string, VitePressLocaleEntry> = {}\n\n for (const loc of locales) {\n const key = localeKeyFromCode(loc.code, defaultLocale, localeKeyToCode)\n const urlKey = key === 'root' ? loc.code : key\n const entry: VitePressLocaleEntry = {\n label: loc.displayName || loc.code.toUpperCase(),\n lang: loc.iso || loc.code,\n }\n if (key !== 'root') {\n entry.link = `/${urlKey}/`\n }\n result[key] = entry\n }\n\n if (!result.root) {\n const fallback = locales.find((l) => l.code === defaultLocale) ?? locales[0]\n if (fallback) {\n result.root = {\n label: fallback.displayName || fallback.code.toUpperCase(),\n lang: fallback.iso || fallback.code,\n }\n }\n }\n\n return result\n}\n"],"names":["localeKeyFromCode","code","defaultLocale","localeKeyToCode","key","mapped","buildVitePressLocales","locales","options","result","loc","urlKey","entry","fallback","l"],"mappings":"aAoBA,SAASA,EAAkBC,EAAcC,EAAuBC,EAAiD,CAC/G,SAAW,CAACC,EAAKC,CAAM,IAAK,OAAO,QAAQF,CAAe,EACxD,GAAIE,IAAWJ,EAAM,OAAOG,EAE9B,OAAIH,IAASC,EAAsB,OAC5BD,CACT,CAMO,SAASK,EACdC,EACAL,EACAM,EAAwC,CAAA,EACF,CACtC,MAAML,EAAkBK,EAAQ,iBAAmB,CAAA,EAC7CC,EAA+C,CAAA,EAErD,UAAWC,KAAOH,EAAS,CACzB,MAAMH,EAAMJ,EAAkBU,EAAI,KAAMR,EAAeC,CAAe,EAChEQ,EAASP,IAAQ,OAASM,EAAI,KAAON,EACrCQ,EAA8B,CAClC,MAAOF,EAAI,aAAeA,EAAI,KAAK,YAAA,EACnC,KAAMA,EAAI,KAAOA,EAAI,IAAA,EAEnBN,IAAQ,SACVQ,EAAM,KAAO,IAAID,CAAM,KAEzBF,EAAOL,CAAG,EAAIQ,CAChB,CAEA,GAAI,CAACH,EAAO,KAAM,CAChB,MAAMI,EAAWN,EAAQ,KAAMO,GAAMA,EAAE,OAASZ,CAAa,GAAKK,EAAQ,CAAC,EACvEM,IACFJ,EAAO,KAAO,CACZ,MAAOI,EAAS,aAAeA,EAAS,KAAK,YAAA,EAC7C,KAAMA,EAAS,KAAOA,EAAS,IAAA,EAGrC,CAEA,OAAOJ,CACT"}
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@i18n-micro/vitepress",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "VitePress bindings for i18n-micro — runtime dictionaries, MD components, and locale switcher.",
5
5
  "keywords": [
6
+ "documentation",
6
7
  "i18n",
7
8
  "internationalization",
8
9
  "translations",
9
10
  "vitepress",
10
- "vue",
11
- "documentation"
11
+ "vue"
12
12
  ],
13
13
  "homepage": "https://github.com/s00d/nuxt-i18n-micro/tree/main/packages/vitepress#readme",
14
14
  "bugs": {
@@ -53,6 +53,17 @@
53
53
  },
54
54
  "default": "./dist/config.mjs"
55
55
  },
56
+ "./theme": {
57
+ "import": {
58
+ "types": "./dist/theme.d.ts",
59
+ "default": "./dist/theme.mjs"
60
+ },
61
+ "require": {
62
+ "types": "./dist/theme.d.cts",
63
+ "default": "./dist/theme.cjs"
64
+ },
65
+ "default": "./dist/theme.mjs"
66
+ },
56
67
  "./client": {
57
68
  "types": "./client.d.ts"
58
69
  },
@@ -73,10 +84,11 @@
73
84
  "access": "public"
74
85
  },
75
86
  "dependencies": {
76
- "@i18n-micro/core": "^1.3.13",
77
- "@i18n-micro/types": "^1.2.11",
78
87
  "@i18n-micro/utils": "^1.0.14",
79
- "@i18n-micro/vue": "^1.3.11"
88
+ "@i18n-micro/node": "^1.2.8",
89
+ "@i18n-micro/vue": "^1.3.12",
90
+ "@i18n-micro/core": "^1.3.14",
91
+ "@i18n-micro/types": "^1.2.11"
80
92
  },
81
93
  "devDependencies": {
82
94
  "@types/node": "^20.19.26",
@@ -1,64 +0,0 @@
1
- function l(e) {
2
- return "switchLocalePath" in e && typeof e.switchLocalePath == "function";
3
- }
4
- function a(e) {
5
- const o = l(e) ? {
6
- defaultLocale: e.defaultLocale,
7
- localeCodes: e.localeCodes,
8
- localeKeyToCode: e.localeKeyToCode ?? {}
9
- } : e, t = o.defaultLocale, c = o.localeCodes, s = o.localeKeyToCode ?? {};
10
- return new Function(
11
- "data",
12
- "route",
13
- "targetLocale",
14
- `
15
- const defaultLocale = ${JSON.stringify(t)};
16
- const localeCodes = ${JSON.stringify(c)};
17
- const localeKeyToCode = ${JSON.stringify(s)};
18
- const keyFromCode = (code) => {
19
- for (const key of Object.keys(localeKeyToCode)) {
20
- if (localeKeyToCode[key] === code) return key;
21
- }
22
- return code === defaultLocale ? 'root' : code;
23
- };
24
- const prefixes = [];
25
- for (let i = 0; i < localeCodes.length; i++) {
26
- const code = localeCodes[i];
27
- if (code === defaultLocale) continue;
28
- const key = keyFromCode(code);
29
- const urlKey = key === 'root' ? code : key;
30
- prefixes.push(urlKey);
31
- if (urlKey !== code) prefixes.push(code);
32
- }
33
- // VitePress passes locale *keys* (root / fr). URL prefix is the key, not the i18n code.
34
- const urlPrefix = targetLocale === 'root' ? null : targetLocale;
35
- let path = (route && route.path) || '/';
36
- const hash = (route && route.hash) || '';
37
- const query = (route && route.query) || '';
38
- const hashIndex = path.indexOf('#');
39
- const queryIndex = path.indexOf('?');
40
- let cut = path.length;
41
- if (hashIndex >= 0) cut = Math.min(cut, hashIndex);
42
- if (queryIndex >= 0) cut = Math.min(cut, queryIndex);
43
- const pathname = path.slice(0, cut) || '/';
44
- const extras = path.slice(cut);
45
- const hadTrailingSlash = pathname === '/' || pathname.endsWith('/');
46
- const segments = pathname.split('/').filter(Boolean);
47
- if (segments[0] && prefixes.indexOf(segments[0]) >= 0) segments.shift();
48
- if (urlPrefix) segments.unshift(urlPrefix);
49
- let localized = segments.length === 0 ? '/' : '/' + segments.join('/');
50
- if (localized !== '/' && hadTrailingSlash) localized += '/';
51
- const q = extras.indexOf('?') >= 0
52
- ? ''
53
- : (query ? (query.charAt(0) === '?' ? query : '?' + query) : '');
54
- const h = hash
55
- ? (hash.charAt(0) === '#' ? hash : '#' + hash)
56
- : '';
57
- return localized + extras + q + h;
58
- `
59
- );
60
- }
61
- export {
62
- a as c
63
- };
64
- //# sourceMappingURL=i18n-routing-CcppCuuS.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"i18n-routing-CcppCuuS.js","sources":["../src/router/i18n-routing.ts"],"sourcesContent":["import type { VitePressRouterAdapter } from './adapter'\n\n/**\n * Minimal shapes used by VitePress `themeConfig.i18nRouting`.\n * Kept loose so we do not hard-depend on VitePress internal DefaultTheme types at compile time.\n */\nexport interface VitePressI18nRoutingData {\n site?: {\n value?: {\n locales?: Record<string, { link?: string, lang?: string }>\n }\n }\n localeIndex?: { value?: string }\n}\n\nexport interface VitePressI18nRoutingRoute {\n path: string\n hash?: string\n query?: string\n data?: {\n relativePath?: string\n }\n}\n\nexport type VitePressI18nRoutingFn = (\n data: VitePressI18nRoutingData,\n route: VitePressI18nRoutingRoute,\n targetLocale: string,\n) => string\n\nexport interface I18nRoutingFromAdapterOptions {\n defaultLocale: string\n localeCodes: string[]\n localeKeyToCode?: Record<string, string>\n}\n\nfunction isAdapter(value: VitePressRouterAdapter | I18nRoutingFromAdapterOptions): value is VitePressRouterAdapter {\n return 'switchLocalePath' in value && typeof (value as VitePressRouterAdapter).switchLocalePath === 'function'\n}\n\n/**\n * Bridge so VitePress navbar language menu and `<I18nSwitcher>` share path logic.\n * Pass the result to `themeConfig.i18nRouting`.\n *\n * `targetLocale` is a **VitePress locale key** (`root` / `fr`). URL prefixes use that key;\n * `localeKeyToCode` is only for resolving the i18n code when callers need it elsewhere.\n *\n * Returns a **self-contained** function (no closures) so VitePress can serialize it\n * into site data via `Function#toString()` + `new Function`.\n */\nexport function createI18nRoutingFromAdapter(\n adapterOrOptions: VitePressRouterAdapter | I18nRoutingFromAdapterOptions,\n): VitePressI18nRoutingFn {\n const options: I18nRoutingFromAdapterOptions = isAdapter(adapterOrOptions)\n ? {\n defaultLocale: adapterOrOptions.defaultLocale,\n localeCodes: adapterOrOptions.localeCodes,\n localeKeyToCode: adapterOrOptions.localeKeyToCode ?? {},\n }\n : adapterOrOptions\n\n const defaultLocale = options.defaultLocale\n const localeCodes = options.localeCodes\n const localeKeyToCode = options.localeKeyToCode ?? {}\n\n // Inlined constants — required for VitePress themeConfig function serialization.\n // oxlint-disable-next-line typescript/no-implied-eval -- intentional for VP serializeFunctions\n return new Function(\n 'data',\n 'route',\n 'targetLocale',\n `\n const defaultLocale = ${JSON.stringify(defaultLocale)};\n const localeCodes = ${JSON.stringify(localeCodes)};\n const localeKeyToCode = ${JSON.stringify(localeKeyToCode)};\n const keyFromCode = (code) => {\n for (const key of Object.keys(localeKeyToCode)) {\n if (localeKeyToCode[key] === code) return key;\n }\n return code === defaultLocale ? 'root' : code;\n };\n const prefixes = [];\n for (let i = 0; i < localeCodes.length; i++) {\n const code = localeCodes[i];\n if (code === defaultLocale) continue;\n const key = keyFromCode(code);\n const urlKey = key === 'root' ? code : key;\n prefixes.push(urlKey);\n if (urlKey !== code) prefixes.push(code);\n }\n // VitePress passes locale *keys* (root / fr). URL prefix is the key, not the i18n code.\n const urlPrefix = targetLocale === 'root' ? null : targetLocale;\n let path = (route && route.path) || '/';\n const hash = (route && route.hash) || '';\n const query = (route && route.query) || '';\n const hashIndex = path.indexOf('#');\n const queryIndex = path.indexOf('?');\n let cut = path.length;\n if (hashIndex >= 0) cut = Math.min(cut, hashIndex);\n if (queryIndex >= 0) cut = Math.min(cut, queryIndex);\n const pathname = path.slice(0, cut) || '/';\n const extras = path.slice(cut);\n const hadTrailingSlash = pathname === '/' || pathname.endsWith('/');\n const segments = pathname.split('/').filter(Boolean);\n if (segments[0] && prefixes.indexOf(segments[0]) >= 0) segments.shift();\n if (urlPrefix) segments.unshift(urlPrefix);\n let localized = segments.length === 0 ? '/' : '/' + segments.join('/');\n if (localized !== '/' && hadTrailingSlash) localized += '/';\n const q = extras.indexOf('?') >= 0\n ? ''\n : (query ? (query.charAt(0) === '?' ? query : '?' + query) : '');\n const h = hash\n ? (hash.charAt(0) === '#' ? hash : '#' + hash)\n : '';\n return localized + extras + q + h;\n `,\n ) as VitePressI18nRoutingFn\n}\n"],"names":["isAdapter","value","createI18nRoutingFromAdapter","adapterOrOptions","options","defaultLocale","localeCodes","localeKeyToCode"],"mappings":"AAoCA,SAASA,EAAUC,GAAgG;AACjH,SAAO,sBAAsBA,KAAS,OAAQA,EAAiC,oBAAqB;AACtG;AAYO,SAASC,EACdC,GACwB;AACxB,QAAMC,IAAyCJ,EAAUG,CAAgB,IACrE;AAAA,IACE,eAAeA,EAAiB;AAAA,IAChC,aAAaA,EAAiB;AAAA,IAC9B,iBAAiBA,EAAiB,mBAAmB,CAAA;AAAA,EAAC,IAExDA,GAEEE,IAAgBD,EAAQ,eACxBE,IAAcF,EAAQ,aACtBG,IAAkBH,EAAQ,mBAAmB,CAAA;AAInD,SAAO,IAAI;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,8BAC0B,KAAK,UAAUC,CAAa,CAAC;AAAA,4BAC/B,KAAK,UAAUC,CAAW,CAAC;AAAA,gCACvB,KAAK,UAAUC,CAAe,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAAA;AA2C/D;"}
@@ -1,46 +0,0 @@
1
- "use strict";function a(e){return"switchLocalePath"in e&&typeof e.switchLocalePath=="function"}function l(e){const o=a(e)?{defaultLocale:e.defaultLocale,localeCodes:e.localeCodes,localeKeyToCode:e.localeKeyToCode??{}}:e,t=o.defaultLocale,c=o.localeCodes,s=o.localeKeyToCode??{};return new Function("data","route","targetLocale",`
2
- const defaultLocale = ${JSON.stringify(t)};
3
- const localeCodes = ${JSON.stringify(c)};
4
- const localeKeyToCode = ${JSON.stringify(s)};
5
- const keyFromCode = (code) => {
6
- for (const key of Object.keys(localeKeyToCode)) {
7
- if (localeKeyToCode[key] === code) return key;
8
- }
9
- return code === defaultLocale ? 'root' : code;
10
- };
11
- const prefixes = [];
12
- for (let i = 0; i < localeCodes.length; i++) {
13
- const code = localeCodes[i];
14
- if (code === defaultLocale) continue;
15
- const key = keyFromCode(code);
16
- const urlKey = key === 'root' ? code : key;
17
- prefixes.push(urlKey);
18
- if (urlKey !== code) prefixes.push(code);
19
- }
20
- // VitePress passes locale *keys* (root / fr). URL prefix is the key, not the i18n code.
21
- const urlPrefix = targetLocale === 'root' ? null : targetLocale;
22
- let path = (route && route.path) || '/';
23
- const hash = (route && route.hash) || '';
24
- const query = (route && route.query) || '';
25
- const hashIndex = path.indexOf('#');
26
- const queryIndex = path.indexOf('?');
27
- let cut = path.length;
28
- if (hashIndex >= 0) cut = Math.min(cut, hashIndex);
29
- if (queryIndex >= 0) cut = Math.min(cut, queryIndex);
30
- const pathname = path.slice(0, cut) || '/';
31
- const extras = path.slice(cut);
32
- const hadTrailingSlash = pathname === '/' || pathname.endsWith('/');
33
- const segments = pathname.split('/').filter(Boolean);
34
- if (segments[0] && prefixes.indexOf(segments[0]) >= 0) segments.shift();
35
- if (urlPrefix) segments.unshift(urlPrefix);
36
- let localized = segments.length === 0 ? '/' : '/' + segments.join('/');
37
- if (localized !== '/' && hadTrailingSlash) localized += '/';
38
- const q = extras.indexOf('?') >= 0
39
- ? ''
40
- : (query ? (query.charAt(0) === '?' ? query : '?' + query) : '');
41
- const h = hash
42
- ? (hash.charAt(0) === '#' ? hash : '#' + hash)
43
- : '';
44
- return localized + extras + q + h;
45
- `)}exports.createI18nRoutingFromAdapter=l;
46
- //# sourceMappingURL=i18n-routing-D9iYAKDq.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"i18n-routing-D9iYAKDq.cjs","sources":["../src/router/i18n-routing.ts"],"sourcesContent":["import type { VitePressRouterAdapter } from './adapter'\n\n/**\n * Minimal shapes used by VitePress `themeConfig.i18nRouting`.\n * Kept loose so we do not hard-depend on VitePress internal DefaultTheme types at compile time.\n */\nexport interface VitePressI18nRoutingData {\n site?: {\n value?: {\n locales?: Record<string, { link?: string, lang?: string }>\n }\n }\n localeIndex?: { value?: string }\n}\n\nexport interface VitePressI18nRoutingRoute {\n path: string\n hash?: string\n query?: string\n data?: {\n relativePath?: string\n }\n}\n\nexport type VitePressI18nRoutingFn = (\n data: VitePressI18nRoutingData,\n route: VitePressI18nRoutingRoute,\n targetLocale: string,\n) => string\n\nexport interface I18nRoutingFromAdapterOptions {\n defaultLocale: string\n localeCodes: string[]\n localeKeyToCode?: Record<string, string>\n}\n\nfunction isAdapter(value: VitePressRouterAdapter | I18nRoutingFromAdapterOptions): value is VitePressRouterAdapter {\n return 'switchLocalePath' in value && typeof (value as VitePressRouterAdapter).switchLocalePath === 'function'\n}\n\n/**\n * Bridge so VitePress navbar language menu and `<I18nSwitcher>` share path logic.\n * Pass the result to `themeConfig.i18nRouting`.\n *\n * `targetLocale` is a **VitePress locale key** (`root` / `fr`). URL prefixes use that key;\n * `localeKeyToCode` is only for resolving the i18n code when callers need it elsewhere.\n *\n * Returns a **self-contained** function (no closures) so VitePress can serialize it\n * into site data via `Function#toString()` + `new Function`.\n */\nexport function createI18nRoutingFromAdapter(\n adapterOrOptions: VitePressRouterAdapter | I18nRoutingFromAdapterOptions,\n): VitePressI18nRoutingFn {\n const options: I18nRoutingFromAdapterOptions = isAdapter(adapterOrOptions)\n ? {\n defaultLocale: adapterOrOptions.defaultLocale,\n localeCodes: adapterOrOptions.localeCodes,\n localeKeyToCode: adapterOrOptions.localeKeyToCode ?? {},\n }\n : adapterOrOptions\n\n const defaultLocale = options.defaultLocale\n const localeCodes = options.localeCodes\n const localeKeyToCode = options.localeKeyToCode ?? {}\n\n // Inlined constants — required for VitePress themeConfig function serialization.\n // oxlint-disable-next-line typescript/no-implied-eval -- intentional for VP serializeFunctions\n return new Function(\n 'data',\n 'route',\n 'targetLocale',\n `\n const defaultLocale = ${JSON.stringify(defaultLocale)};\n const localeCodes = ${JSON.stringify(localeCodes)};\n const localeKeyToCode = ${JSON.stringify(localeKeyToCode)};\n const keyFromCode = (code) => {\n for (const key of Object.keys(localeKeyToCode)) {\n if (localeKeyToCode[key] === code) return key;\n }\n return code === defaultLocale ? 'root' : code;\n };\n const prefixes = [];\n for (let i = 0; i < localeCodes.length; i++) {\n const code = localeCodes[i];\n if (code === defaultLocale) continue;\n const key = keyFromCode(code);\n const urlKey = key === 'root' ? code : key;\n prefixes.push(urlKey);\n if (urlKey !== code) prefixes.push(code);\n }\n // VitePress passes locale *keys* (root / fr). URL prefix is the key, not the i18n code.\n const urlPrefix = targetLocale === 'root' ? null : targetLocale;\n let path = (route && route.path) || '/';\n const hash = (route && route.hash) || '';\n const query = (route && route.query) || '';\n const hashIndex = path.indexOf('#');\n const queryIndex = path.indexOf('?');\n let cut = path.length;\n if (hashIndex >= 0) cut = Math.min(cut, hashIndex);\n if (queryIndex >= 0) cut = Math.min(cut, queryIndex);\n const pathname = path.slice(0, cut) || '/';\n const extras = path.slice(cut);\n const hadTrailingSlash = pathname === '/' || pathname.endsWith('/');\n const segments = pathname.split('/').filter(Boolean);\n if (segments[0] && prefixes.indexOf(segments[0]) >= 0) segments.shift();\n if (urlPrefix) segments.unshift(urlPrefix);\n let localized = segments.length === 0 ? '/' : '/' + segments.join('/');\n if (localized !== '/' && hadTrailingSlash) localized += '/';\n const q = extras.indexOf('?') >= 0\n ? ''\n : (query ? (query.charAt(0) === '?' ? query : '?' + query) : '');\n const h = hash\n ? (hash.charAt(0) === '#' ? hash : '#' + hash)\n : '';\n return localized + extras + q + h;\n `,\n ) as VitePressI18nRoutingFn\n}\n"],"names":["isAdapter","value","createI18nRoutingFromAdapter","adapterOrOptions","options","defaultLocale","localeCodes","localeKeyToCode"],"mappings":"aAoCA,SAASA,EAAUC,EAAgG,CACjH,MAAO,qBAAsBA,GAAS,OAAQA,EAAiC,kBAAqB,UACtG,CAYO,SAASC,EACdC,EACwB,CACxB,MAAMC,EAAyCJ,EAAUG,CAAgB,EACrE,CACE,cAAeA,EAAiB,cAChC,YAAaA,EAAiB,YAC9B,gBAAiBA,EAAiB,iBAAmB,CAAA,CAAC,EAExDA,EAEEE,EAAgBD,EAAQ,cACxBE,EAAcF,EAAQ,YACtBG,EAAkBH,EAAQ,iBAAmB,CAAA,EAInD,OAAO,IAAI,SACT,OACA,QACA,eACA;AAAA,8BAC0B,KAAK,UAAUC,CAAa,CAAC;AAAA,4BAC/B,KAAK,UAAUC,CAAW,CAAC;AAAA,gCACvB,KAAK,UAAUC,CAAe,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAAA,CA2C/D"}
@@ -1,15 +0,0 @@
1
- "use strict";const h=require("node:fs"),m=require("node:path"),S=require("@i18n-micro/utils/parse-path"),D=require("@i18n-micro/utils/deep-merge");function N(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function L(e,t){if(h.existsSync(e))for(const r of h.readdirSync(e)){const s=m.join(e,r);if(h.statSync(s).isDirectory()){L(s,t);continue}r.endsWith(".json")&&t(s)}}function $(e){const t=e.rootDir??process.cwd(),r=m.resolve(t,e.translationDir),s=[];return L(r,i=>{s.push({absolutePath:i,relativePath:m.relative(r,i).split(m.sep).join("/")})}),s.sort((i,c)=>i.relativePath.localeCompare(c.relativePath))}function v(e){const t=e.rootDir??process.cwd(),r=m.resolve(t,e.translationDir),s={root:{},routes:{}},i=e.disablePageLocales===!0;return h.existsSync(r)&&L(r,c=>{const a=m.relative(r,c).split(m.sep).join("/");try{const l=JSON.parse(h.readFileSync(c,"utf-8"));if(!N(l)){console.error(`[i18n-micro/vitepress] Skipping ${a}: expected a JSON object, got ${Array.isArray(l)?"array":typeof l}`);return}const f=l,u=S.classifyTranslationRelativePath(a,i);if(u.type==="page"){const n=s.routes[u.pageName]??(s.routes[u.pageName]={});n[u.locale]=f;return}if(u.type==="root"){const n=s.root[u.locale];s.root[u.locale]=n?D.deepMergeTranslations(n,f):f}}catch(l){console.error(`[i18n-micro/vitepress] Failed to load ${a}:`,l)}}),s}function O(e){return v(e).root}function P(e,t){for(const[r,s]of Object.entries(t.root))e.addTranslations(r,s,!1);for(const[r,s]of Object.entries(t.routes))for(const[i,c]of Object.entries(s))e.addRouteTranslations(i,r,S.mergeRouteTranslationsWithRoot(t.root[i],c),!1)}const b="virtual:i18n-micro/config",T=`\0${b}`,j="virtual:i18n-micro/messages",p=`\0${j}`;function I(e){return e.replace(/\\/g,"/")}function x(e,t,r){const s=$({rootDir:e,translationDir:t});if(s.length===0)return`export const messages = {}
2
- export const routeMessages = {}
3
- `;const i=[],c=[],a=new Map;let l=0;for(const u of s){const n=S.classifyTranslationRelativePath(u.relativePath,r);if(n.type==="ignore")continue;const d=`__i18n_${l++}`;if(i.push(`import ${d} from ${JSON.stringify(I(u.absolutePath))}`),n.type==="root"){c.push(` ${JSON.stringify(n.locale)}: ${d}`);continue}let o=a.get(n.pageName);o||(o=new Map,a.set(n.pageName,o)),o.set(n.locale,d)}const f=[];for(const[u,n]of a){const d=[...n.entries()].map(([o,y])=>` ${JSON.stringify(o)}: ${y}`).join(`,
4
- `);f.push(` ${JSON.stringify(u)}: {
5
- ${d}
6
- }`)}return[...i,`export const messages = {
7
- ${c.join(`,
8
- `)}
9
- }`,`export const routeMessages = {
10
- ${f.join(`,
11
- `)}
12
- }`,""].join(`
13
- `)}function k(e,t){return[`export const messages = ${JSON.stringify(e)}`,`export const routeMessages = ${JSON.stringify(t)}`,""].join(`
14
- `)}function R(e){const t=e.defaultLocale||e.locale,r=e.translationDir??"locales",s=e.disablePageLocales===!0,i={defaultLocale:t,fallbackLocale:e.fallbackLocale||t,locales:e.locales||[],localeCodes:(e.locales||[]).map(o=>o.code),missingWarn:e.missingWarn??!0,syncWithVitePress:e.syncWithVitePress!==!1,translationDir:r,disablePageLocales:s,localeKeyToCode:e.localeKeyToCode??{}};let c=process.cwd(),a=!!(e.messages||e.routeMessages),l=e.messages??{},f=e.routeMessages??{},u;const n=()=>!e.messages||!e.routeMessages,d=()=>{if(!n())return;const o=v({rootDir:c,translationDir:r,disablePageLocales:s});e.messages||(l=o.root),e.routeMessages||(f=o.routes)};return{name:"vite-plugin-i18n-micro-vitepress",configResolved(o){c=o.root,a=!!(e.messages||e.routeMessages),a&&(e.messages&&(l=e.messages),e.routeMessages&&(f=e.routeMessages),n()&&d(),e.messages&&(l=e.messages),e.routeMessages&&(f=e.routeMessages))},configureServer(o){if(a&&!n())return;const y=m.resolve(c,r);if(!h.existsSync(y))return;o.watcher.add(y);const M=()=>{u&&clearTimeout(u),u=setTimeout(()=>{a&&d();const g=o.moduleGraph.getModuleById(p);g&&(o.moduleGraph.invalidateModule(g),o.ws.send({type:"full-reload"}))},50)};o.watcher.on("add",g=>{g.startsWith(y)&&g.endsWith(".json")&&M()}),o.watcher.on("unlink",g=>{g.startsWith(y)&&g.endsWith(".json")&&M()}),a&&n()&&o.watcher.on("change",g=>{g.startsWith(y)&&g.endsWith(".json")&&M()})},resolveId(o){if(o===b)return T;if(o===j)return p},load(o){if(o===T)return`export const config = ${JSON.stringify(i)}`;if(o===p)return a?k(l,f):x(c,r,s)}}}function w(e,t){if(t.warnOnLocaleMismatch===!1)return;const r=e.locales;if(!r||!t.locales?.length)return;const s=t.defaultLocale||t.locale,i=Object.keys(r),c=new Set(t.locales.map(a=>a.code));for(const a of i){const l=a==="root"?s:t.localeKeyToCode?.[a]??a;c.has(l)||console.warn(`[i18n-micro/vitepress] VitePress locale key "${a}" maps to "${l}", which is not in i18n locales (${[...c].join(", ")}).`)}}function _(e,t){w(e,t);const r=e.vite?.plugins,s=[...Array.isArray(r)?r.flat():[],R(t)];return{...e,vite:{...e.vite,plugins:s}}}exports.applyLoadedTranslations=P;exports.listTranslationFiles=$;exports.loadMessages=O;exports.loadTranslationBuckets=v;exports.warnLocaleMismatch=w;exports.withI18nMicro=_;
15
- //# sourceMappingURL=with-i18n-micro-01q-vPO9.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"with-i18n-micro-01q-vPO9.cjs","sources":["../src/load-messages.ts","../src/with-i18n-micro.ts"],"sourcesContent":["import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs'\nimport { join, relative, resolve, sep } from 'node:path'\nimport type { Translations } from '@i18n-micro/types'\nimport { deepMergeTranslations } from '@i18n-micro/utils/deep-merge'\nimport {\n classifyTranslationRelativePath,\n mergeRouteTranslationsWithRoot,\n type TranslationFileBuckets,\n} from '@i18n-micro/utils/parse-path'\n\nexport interface LoadMessagesOptions {\n /** Directory with locale JSON (`en.json`, `pages/guide/demo/en.json`, …). */\n translationDir: string\n rootDir?: string\n /**\n * When true, treat `pages/**` files as root-level dictionaries.\n * @default false\n */\n disablePageLocales?: boolean\n}\n\nexport type LoadedTranslations = TranslationFileBuckets<Translations>\n\nexport interface TranslationFileRef {\n /** Path relative to `translationDir` using `/` separators. */\n relativePath: string\n absolutePath: string\n}\n\nfunction isTranslationsObject(value: unknown): value is Translations {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction walkTranslationFiles(dir: string, onFile: (fullPath: string) => void): void {\n if (!existsSync(dir)) return\n\n for (const entry of readdirSync(dir)) {\n const fullPath = join(dir, entry)\n const stat = statSync(fullPath)\n if (stat.isDirectory()) {\n walkTranslationFiles(fullPath, onFile)\n continue\n }\n if (entry.endsWith('.json')) {\n onFile(fullPath)\n }\n }\n}\n\n/**\n * List JSON translation files under `translationDir` (absolute + relative paths).\n */\nexport function listTranslationFiles(options: LoadMessagesOptions): TranslationFileRef[] {\n const rootDir = options.rootDir ?? process.cwd()\n const dir = resolve(rootDir, options.translationDir)\n const files: TranslationFileRef[] = []\n\n walkTranslationFiles(dir, (fullPath) => {\n files.push({\n absolutePath: fullPath,\n relativePath: relative(dir, fullPath).split(sep).join('/'),\n })\n })\n\n return files.sort((a, b) => a.relativePath.localeCompare(b.relativePath))\n}\n\n/**\n * Load root + page-scoped dictionaries (`pages/** /xx.json`).\n * Node.js-only (`node:fs`).\n */\nexport function loadTranslationBuckets(options: LoadMessagesOptions): LoadedTranslations {\n const rootDir = options.rootDir ?? process.cwd()\n const dir = resolve(rootDir, options.translationDir)\n const buckets: LoadedTranslations = { root: {}, routes: {} }\n const disablePageLocales = options.disablePageLocales === true\n\n if (!existsSync(dir)) {\n return buckets\n }\n\n walkTranslationFiles(dir, (fullPath) => {\n const relativePath = relative(dir, fullPath).split(sep).join('/')\n try {\n const parsed: unknown = JSON.parse(readFileSync(fullPath, 'utf-8'))\n if (!isTranslationsObject(parsed)) {\n console.error(\n `[i18n-micro/vitepress] Skipping ${relativePath}: expected a JSON object, got ${Array.isArray(parsed) ? 'array' : typeof parsed}`,\n )\n return\n }\n const translations = parsed\n const classified = classifyTranslationRelativePath(relativePath, disablePageLocales)\n\n if (classified.type === 'page') {\n const routeBucket = buckets.routes[classified.pageName]\n ?? (buckets.routes[classified.pageName] = {})\n routeBucket[classified.locale] = translations\n return\n }\n\n if (classified.type === 'root') {\n const existing = buckets.root[classified.locale]\n buckets.root[classified.locale] = existing\n ? deepMergeTranslations(existing as Record<string, unknown>, translations as Record<string, unknown>) as Translations\n : translations\n }\n }\n catch (error) {\n console.error(`[i18n-micro/vitepress] Failed to load ${relativePath}:`, error)\n }\n })\n\n return buckets\n}\n\n/**\n * Load root-level locale JSON only (`en.json`, `fr.json`, …).\n * Prefer `loadTranslationBuckets` when page locales are needed.\n *\n * Node.js-only (`node:fs`). For bundler-friendly loading prefer\n * `withI18nMicro` virtual modules or `messagesFromGlob` in the theme.\n */\nexport function loadMessages(options: LoadMessagesOptions): Record<string, Translations> {\n return loadTranslationBuckets(options).root\n}\n\n/**\n * Apply page dictionaries onto an i18n instance (merged with root).\n */\nexport function applyLoadedTranslations(\n i18n: {\n addTranslations: (locale: string, translations: Translations, merge?: boolean) => void\n addRouteTranslations: (locale: string, routeName: string, translations: Translations, merge?: boolean) => void\n },\n loaded: LoadedTranslations,\n): void {\n for (const [locale, translations] of Object.entries(loaded.root)) {\n i18n.addTranslations(locale, translations, false)\n }\n for (const [routeName, byLocale] of Object.entries(loaded.routes)) {\n for (const [locale, translations] of Object.entries(byLocale)) {\n i18n.addRouteTranslations(\n locale,\n routeName,\n mergeRouteTranslationsWithRoot(loaded.root[locale], translations),\n false,\n )\n }\n }\n}\n","import { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport type { Locale, Translations } from '@i18n-micro/types'\nimport { classifyTranslationRelativePath } from '@i18n-micro/utils/parse-path'\nimport type { Plugin } from 'vite'\nimport type { VitePressI18nOptions } from './create'\nimport { listTranslationFiles, loadTranslationBuckets } from './load-messages'\n\nexport interface WithI18nMicroOptions extends VitePressI18nOptions {\n /**\n * Directory with locale JSON (`en.json`, `pages/guide/demo/en.json`, …), relative to Vite root\n * (VitePress content / docs root). Used by `virtual:i18n-micro/messages`.\n * @default 'locales'\n */\n translationDir?: string\n /**\n * When true, treat `pages/**` as root-level dictionaries.\n * @default false\n */\n disablePageLocales?: boolean\n /**\n * When true, logs a warning if VitePress `locales` keys do not align with\n * configured i18n locale codes.\n * @default true\n */\n warnOnLocaleMismatch?: boolean\n}\n\n/**\n * Minimal VitePress / Vite user config shape we merge into.\n * Avoid importing `vitepress` types so the package stays usable as a pure library dep.\n */\nexport interface VitePressUserConfigLike {\n locales?: Record<string, unknown>\n vite?: {\n plugins?: Plugin[] | Plugin[][]\n [key: string]: unknown\n }\n [key: string]: unknown\n}\n\nexport interface VirtualI18nConfig {\n defaultLocale: string\n fallbackLocale: string\n locales: Locale[]\n localeCodes: string[]\n missingWarn: boolean\n syncWithVitePress: boolean\n translationDir: string\n disablePageLocales: boolean\n localeKeyToCode: Record<string, string>\n}\n\nconst VIRTUAL_CONFIG_ID = 'virtual:i18n-micro/config'\nconst RESOLVED_CONFIG_ID = `\\0${VIRTUAL_CONFIG_ID}`\nconst VIRTUAL_MESSAGES_ID = 'virtual:i18n-micro/messages'\nconst RESOLVED_MESSAGES_ID = `\\0${VIRTUAL_MESSAGES_ID}`\n\nfunction toPosix(path: string): string {\n return path.replace(/\\\\/g, '/')\n}\n\nfunction generateImportMessagesModule(\n rootDir: string,\n translationDir: string,\n disablePageLocales: boolean,\n): string {\n const files = listTranslationFiles({ rootDir, translationDir })\n if (files.length === 0) {\n return 'export const messages = {}\\nexport const routeMessages = {}\\n'\n }\n\n const imports: string[] = []\n const rootEntries: string[] = []\n const routeVarNames = new Map<string, Map<string, string>>()\n let i = 0\n\n for (const file of files) {\n const parsed = classifyTranslationRelativePath(file.relativePath, disablePageLocales)\n if (parsed.type === 'ignore') continue\n\n const varName = `__i18n_${i++}`\n imports.push(`import ${varName} from ${JSON.stringify(toPosix(file.absolutePath))}`)\n\n if (parsed.type === 'root') {\n rootEntries.push(` ${JSON.stringify(parsed.locale)}: ${varName}`)\n continue\n }\n\n let byLocale = routeVarNames.get(parsed.pageName)\n if (!byLocale) {\n byLocale = new Map()\n routeVarNames.set(parsed.pageName, byLocale)\n }\n byLocale.set(parsed.locale, varName)\n }\n\n const routeEntries: string[] = []\n for (const [routeName, byLocale] of routeVarNames) {\n const localeEntries = [...byLocale.entries()]\n .map(([locale, varName]) => ` ${JSON.stringify(locale)}: ${varName}`)\n .join(',\\n')\n routeEntries.push(` ${JSON.stringify(routeName)}: {\\n${localeEntries}\\n }`)\n }\n\n return [\n ...imports,\n `export const messages = {\\n${rootEntries.join(',\\n')}\\n}`,\n `export const routeMessages = {\\n${routeEntries.join(',\\n')}\\n}`,\n '',\n ].join('\\n')\n}\n\nfunction generateInlineMessagesModule(\n messages: Record<string, Translations>,\n routeMessages: Record<string, Record<string, Translations>>,\n): string {\n return [\n `export const messages = ${JSON.stringify(messages)}`,\n `export const routeMessages = ${JSON.stringify(routeMessages)}`,\n '',\n ].join('\\n')\n}\n\nfunction createI18nMicroVitePlugin(options: WithI18nMicroOptions): Plugin {\n const defaultLocale = options.defaultLocale || options.locale\n const translationDir = options.translationDir ?? 'locales'\n const disablePageLocales = options.disablePageLocales === true\n const configData: VirtualI18nConfig = {\n defaultLocale,\n fallbackLocale: options.fallbackLocale || defaultLocale,\n locales: options.locales || [],\n localeCodes: (options.locales || []).map((l) => l.code),\n missingWarn: options.missingWarn ?? true,\n syncWithVitePress: options.syncWithVitePress !== false,\n translationDir,\n disablePageLocales,\n localeKeyToCode: options.localeKeyToCode ?? {},\n }\n\n let rootDir = process.cwd()\n let useInline = Boolean(options.messages || options.routeMessages)\n let inlineRoot = options.messages ?? {}\n let inlineRoutes = options.routeMessages ?? {}\n let debounceTimer: ReturnType<typeof setTimeout> | undefined\n const needsDiskReload = () => !options.messages || !options.routeMessages\n\n const reloadInlineFromDisk = () => {\n // Fully inline config: skip disk I/O (and avoid spurious JSON parse errors).\n if (!needsDiskReload()) return\n const loaded = loadTranslationBuckets({\n rootDir,\n translationDir,\n disablePageLocales,\n })\n if (!options.messages) {\n inlineRoot = loaded.root\n }\n if (!options.routeMessages) {\n inlineRoutes = loaded.routes\n }\n }\n\n return {\n name: 'vite-plugin-i18n-micro-vitepress',\n configResolved(config) {\n rootDir = config.root\n // Inline when caller passed messages and/or routeMessages.\n // routeMessages alone still loads root dictionaries from translationDir.\n useInline = Boolean(options.messages || options.routeMessages)\n if (useInline) {\n if (options.messages) inlineRoot = options.messages\n if (options.routeMessages) inlineRoutes = options.routeMessages\n if (needsDiskReload()) {\n reloadInlineFromDisk()\n }\n if (options.messages) inlineRoot = options.messages\n if (options.routeMessages) inlineRoutes = options.routeMessages\n }\n },\n configureServer(server) {\n // Both maps provided inline — nothing to watch on disk.\n if (useInline && !needsDiskReload()) return\n\n const dir = resolve(rootDir, translationDir)\n if (!existsSync(dir)) return\n\n server.watcher.add(dir)\n\n const invalidate = () => {\n if (debounceTimer) clearTimeout(debounceTimer)\n debounceTimer = setTimeout(() => {\n if (useInline) reloadInlineFromDisk()\n const mod = server.moduleGraph.getModuleById(RESOLVED_MESSAGES_ID)\n if (mod) {\n server.moduleGraph.invalidateModule(mod)\n server.ws.send({ type: 'full-reload' })\n }\n }, 50)\n }\n\n // add/unlink need virtual module regen; change is usually handled by JSON import HMR,\n // but we still invalidate when using inline payload that still reads disk.\n server.watcher.on('add', (file) => {\n if (file.startsWith(dir) && file.endsWith('.json')) invalidate()\n })\n server.watcher.on('unlink', (file) => {\n if (file.startsWith(dir) && file.endsWith('.json')) invalidate()\n })\n if (useInline && needsDiskReload()) {\n server.watcher.on('change', (file) => {\n if (file.startsWith(dir) && file.endsWith('.json')) invalidate()\n })\n }\n },\n resolveId(id) {\n if (id === VIRTUAL_CONFIG_ID) return RESOLVED_CONFIG_ID\n if (id === VIRTUAL_MESSAGES_ID) return RESOLVED_MESSAGES_ID\n },\n load(id) {\n if (id === RESOLVED_CONFIG_ID) {\n return `export const config = ${JSON.stringify(configData)}`\n }\n if (id === RESOLVED_MESSAGES_ID) {\n if (useInline) {\n return generateInlineMessagesModule(inlineRoot, inlineRoutes)\n }\n return generateImportMessagesModule(rootDir, translationDir, disablePageLocales)\n }\n },\n }\n}\n\nexport function warnLocaleMismatch(config: VitePressUserConfigLike, options: WithI18nMicroOptions): void {\n if (options.warnOnLocaleMismatch === false) return\n const vpLocales = config.locales\n if (!vpLocales || !options.locales?.length) return\n\n const defaultLocale = options.defaultLocale || options.locale\n const vpKeys = Object.keys(vpLocales)\n const codes = new Set(options.locales.map((l) => l.code))\n\n for (const key of vpKeys) {\n const expectedCode = key === 'root' ? defaultLocale : (options.localeKeyToCode?.[key] ?? key)\n if (!codes.has(expectedCode)) {\n console.warn(\n `[i18n-micro/vitepress] VitePress locale key \"${key}\" maps to \"${expectedCode}\", `\n + `which is not in i18n locales (${[...codes].join(', ')}).`,\n )\n }\n }\n}\n\n/**\n * Config helper (like `withMermaid`). Name is `withI18nMicro` on purpose —\n * `withI18n` is already used by the unrelated `vitepress-i18n` package.\n *\n * Registers virtual modules:\n * - `virtual:i18n-micro/config`\n * - `virtual:i18n-micro/messages` (from `translationDir`, default `locales/`)\n *\n * Pair with `defineI18nTheme(DefaultTheme)` — no manual `import.meta.glob` in the theme.\n *\n * Import from `@i18n-micro/vitepress/config` (Node / config files only).\n */\nexport function withI18nMicro<T extends VitePressUserConfigLike>(\n config: T,\n options: WithI18nMicroOptions,\n): T {\n warnLocaleMismatch(config, options)\n\n const existingPlugins = config.vite?.plugins\n const plugins = [\n ...(Array.isArray(existingPlugins) ? existingPlugins.flat() : []),\n createI18nMicroVitePlugin(options),\n ]\n\n return {\n ...config,\n vite: {\n ...config.vite,\n plugins,\n },\n }\n}\n"],"names":["isTranslationsObject","value","walkTranslationFiles","dir","onFile","existsSync","entry","readdirSync","fullPath","join","statSync","listTranslationFiles","options","rootDir","resolve","files","relative","sep","a","b","loadTranslationBuckets","buckets","disablePageLocales","relativePath","parsed","readFileSync","translations","classified","classifyTranslationRelativePath","routeBucket","existing","deepMergeTranslations","error","loadMessages","applyLoadedTranslations","i18n","loaded","locale","routeName","byLocale","mergeRouteTranslationsWithRoot","VIRTUAL_CONFIG_ID","RESOLVED_CONFIG_ID","VIRTUAL_MESSAGES_ID","RESOLVED_MESSAGES_ID","toPosix","path","generateImportMessagesModule","translationDir","imports","rootEntries","routeVarNames","i","file","varName","routeEntries","localeEntries","generateInlineMessagesModule","messages","routeMessages","createI18nMicroVitePlugin","defaultLocale","configData","l","useInline","inlineRoot","inlineRoutes","debounceTimer","needsDiskReload","reloadInlineFromDisk","config","server","invalidate","mod","id","warnLocaleMismatch","vpLocales","vpKeys","codes","key","expectedCode","withI18nMicro","existingPlugins","plugins"],"mappings":"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"}