@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.
- package/README.md +73 -39
- package/client.d.ts +1 -0
- package/dist/adapter-BJ-0ltIc.cjs +2 -0
- package/dist/adapter-BJ-0ltIc.cjs.map +1 -0
- package/dist/adapter-BnsyIKhp.js +128 -0
- package/dist/adapter-BnsyIKhp.js.map +1 -0
- package/dist/config.cjs +64 -1
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.cts +113 -111
- package/dist/config.d.ts +113 -111
- package/dist/config.mjs +393 -9
- package/dist/config.mjs.map +1 -1
- package/dist/create-BgMbe0w1.cjs +2 -0
- package/dist/create-BgMbe0w1.cjs.map +1 -0
- package/dist/create-Dev8Q66O.js +80 -0
- package/dist/create-Dev8Q66O.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +87 -141
- package/dist/index.d.ts +87 -141
- package/dist/index.mjs +28 -249
- package/dist/index.mjs.map +1 -1
- package/dist/node.cjs +1 -1
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +56 -116
- package/dist/node.d.ts +56 -116
- package/dist/node.mjs +23 -7
- package/dist/node.mjs.map +1 -1
- package/dist/{virtual-stubs → plugin/virtual-stubs}/config.d.cts +2 -1
- package/dist/runtime/define-theme.d.cts +39 -0
- package/dist/theme.cjs +2 -0
- package/dist/theme.cjs.map +1 -0
- package/dist/theme.d.cts +58 -0
- package/dist/theme.d.ts +58 -0
- package/dist/theme.mjs +35 -0
- package/dist/theme.mjs.map +1 -0
- package/dist/vitepress-locales-6msv22Sn.js +27 -0
- package/dist/vitepress-locales-6msv22Sn.js.map +1 -0
- package/dist/vitepress-locales-Cz4AutfI.cjs +2 -0
- package/dist/vitepress-locales-Cz4AutfI.cjs.map +1 -0
- package/package.json +18 -6
- package/dist/i18n-routing-CcppCuuS.js +0 -64
- package/dist/i18n-routing-CcppCuuS.js.map +0 -1
- package/dist/i18n-routing-D9iYAKDq.cjs +0 -46
- package/dist/i18n-routing-D9iYAKDq.cjs.map +0 -1
- package/dist/with-i18n-micro-01q-vPO9.cjs +0 -15
- package/dist/with-i18n-micro-01q-vPO9.cjs.map +0 -1
- package/dist/with-i18n-micro-DIAoqY71.js +0 -216
- package/dist/with-i18n-micro-DIAoqY71.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,73 +1,107 @@
|
|
|
1
1
|
# `@i18n-micro/vitepress`
|
|
2
2
|
|
|
3
|
-
VitePress bindings for [i18n-micro](https://github.com/s00d/nuxt-i18n-micro)
|
|
3
|
+
VitePress bindings for [i18n-micro](https://github.com/s00d/nuxt-i18n-micro). One runtime API: **`createI18n`** — translations, path helpers, and (in the theme) Vue plugin + route sync.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Entries
|
|
6
6
|
|
|
7
|
-
|
|
|
8
|
-
|
|
9
|
-
|
|
|
10
|
-
|
|
|
11
|
-
|
|
|
7
|
+
| Import | Role |
|
|
8
|
+
| ------------------------------ | ----------------------------------------------------- |
|
|
9
|
+
| `@i18n-micro/vitepress` | Client `createI18n` + `useI18n` / `getLocaleFromPath` |
|
|
10
|
+
| `@i18n-micro/vitepress/theme` | `defineI18nTheme` (uses virtual modules from config) |
|
|
11
|
+
| `@i18n-micro/vitepress/config` | `withI18n`, `buildVitePressLocales`, SEO head |
|
|
12
|
+
| `@i18n-micro/vitepress/node` | Node `createI18n` (`@i18n-micro/node` + path methods) |
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
OpenAPI-style locks: `tests/integration-openapi.test.ts`.
|
|
15
|
+
Playground SSG smoke (en/fr/de, page-scoped, SEO / disableMeta): `tests/playground-ssg.test.ts`.
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
There is **no** separate `createVitePressRouterAdapter` / path-helpers package surface — path methods hang on the `createI18n` instance via `BaseI18n.extend`.
|
|
18
|
+
|
|
19
|
+
## `createI18n`
|
|
20
|
+
|
|
21
|
+
### Theme / client
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { createI18n } from '@i18n-micro/vitepress'
|
|
25
|
+
|
|
26
|
+
const i18n = createI18n({
|
|
27
|
+
locale: 'en',
|
|
28
|
+
defaultLocale: 'en',
|
|
29
|
+
locales: [{ code: 'en' }, { code: 'fr' }],
|
|
30
|
+
messages: { en: { hi: 'Hi' }, fr: { hi: 'Salut' } },
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
i18n.localizePath('/guide', 'fr') // '/fr/guide'
|
|
34
|
+
i18n.t // via i18n.global / after enhanceApp
|
|
35
|
+
// app.use(i18n) happens inside i18n.enhanceApp({ app, router })
|
|
17
36
|
```
|
|
18
37
|
|
|
19
|
-
|
|
38
|
+
Prefer `defineI18nTheme` for zero-boilerplate sites.
|
|
39
|
+
|
|
40
|
+
### Node / generators
|
|
41
|
+
|
|
42
|
+
Built on **`@i18n-micro/node`** (same `createI18n` / `loadTranslations` as Astro & CLI), plus VitePress path methods on the same object:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { createI18n } from '@i18n-micro/vitepress/node'
|
|
46
|
+
|
|
47
|
+
const i18n = createI18n({
|
|
48
|
+
locale: 'en',
|
|
49
|
+
fallbackLocale: 'en',
|
|
50
|
+
translationDir: './locales',
|
|
51
|
+
locales: ['en', 'fr'],
|
|
52
|
+
defaultLocale: 'en',
|
|
53
|
+
})
|
|
54
|
+
await i18n.loadTranslations()
|
|
55
|
+
i18n.t('cta.readMore')
|
|
56
|
+
i18n.localizePath('/guide', 'fr')
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
You can also import `createI18n` from `@i18n-micro/node` directly when you do not need path helpers.
|
|
60
|
+
|
|
61
|
+
Custom methods anywhere BaseI18n is used:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
i18n.extend({ shout: (key) => String(i18n.t(key)).toUpperCase() })
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Config
|
|
20
68
|
|
|
21
69
|
```ts
|
|
22
70
|
import { defineConfig } from 'vitepress'
|
|
23
|
-
import {
|
|
71
|
+
import { withI18n, buildVitePressLocales } from '@i18n-micro/vitepress/config'
|
|
24
72
|
|
|
25
73
|
const locales = [
|
|
26
|
-
{ code: 'en', iso: 'en-US', displayName: 'English' },
|
|
27
|
-
{ code: 'fr', iso: 'fr-FR', displayName: 'Français' },
|
|
74
|
+
{ code: 'en', iso: 'en-US', displayName: 'English', og: 'en_US' },
|
|
75
|
+
{ code: 'fr', iso: 'fr-FR', displayName: 'Français', og: 'fr_FR' },
|
|
28
76
|
]
|
|
77
|
+
const defaultLocale = 'en'
|
|
29
78
|
|
|
30
79
|
export default defineConfig(
|
|
31
|
-
|
|
32
|
-
{
|
|
33
|
-
locales: {
|
|
34
|
-
root: { label: 'English', lang: 'en' },
|
|
35
|
-
fr: { label: 'Français', lang: 'fr', link: '/fr/' },
|
|
36
|
-
},
|
|
37
|
-
themeConfig: {
|
|
38
|
-
i18nRouting: createI18nRoutingFromAdapter({
|
|
39
|
-
defaultLocale: 'en',
|
|
40
|
-
localeCodes: locales.map((l) => l.code),
|
|
41
|
-
}),
|
|
42
|
-
},
|
|
43
|
-
},
|
|
80
|
+
withI18n(
|
|
81
|
+
{ locales: buildVitePressLocales(locales, defaultLocale) },
|
|
44
82
|
{
|
|
45
|
-
locale:
|
|
46
|
-
defaultLocale
|
|
83
|
+
locale: defaultLocale,
|
|
84
|
+
defaultLocale,
|
|
47
85
|
locales,
|
|
48
|
-
translationDir: 'locales',
|
|
86
|
+
translationDir: 'locales',
|
|
87
|
+
metaBaseUrl: 'https://example.com',
|
|
49
88
|
},
|
|
50
89
|
),
|
|
51
90
|
)
|
|
52
91
|
```
|
|
53
92
|
|
|
93
|
+
`withI18n` injects `themeConfig.i18nRouting` automatically.
|
|
94
|
+
|
|
54
95
|
### Theme
|
|
55
96
|
|
|
56
97
|
```ts
|
|
57
98
|
import DefaultTheme from 'vitepress/theme'
|
|
58
|
-
import { defineI18nTheme } from '@i18n-micro/vitepress'
|
|
99
|
+
import { defineI18nTheme } from '@i18n-micro/vitepress/theme'
|
|
59
100
|
|
|
60
101
|
export default defineI18nTheme(DefaultTheme)
|
|
61
102
|
```
|
|
62
103
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
```md
|
|
66
|
-
{{ $t('cta.readMore') }}
|
|
67
|
-
|
|
68
|
-
<I18nT keypath="greeting" :params="{ name: 'VitePress' }" />
|
|
69
|
-
<I18nLink to="/guide/demo">Demo</I18nLink>
|
|
70
|
-
```
|
|
104
|
+
In pages: `useI18n().localePath` / `switchLocale`, or `$t` / `<I18nT>`.
|
|
71
105
|
|
|
72
106
|
## License
|
|
73
107
|
|
package/client.d.ts
CHANGED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const j=require("vue");function g(i){const o=i.indexOf("#"),e=i.indexOf("?");let n=i.length;return o>=0&&(n=Math.min(n,o)),e>=0&&(n=Math.min(n,e)),{pathname:i.slice(0,n)||"/",extras:i.slice(n)}}function p(i,o){if(!o||o==="/")return i;const e=o.endsWith("/")?o.slice(0,-1):o;if(!e)return i;const{pathname:n,extras:c}=g(i);return n===e?`/${c}`:n.startsWith(`${e}/`)?`${n.slice(e.length)||"/"}${c}`:i}function x(i,o,e={}){const n=s=>{for(const[a,f]of Object.entries(e))if(f===s)return a;return s===o?"root":s},c=new Map;for(const s of i){if(s===o)continue;const a=n(s),f=a==="root"?s:a;c.set(f,s),f!==s&&c.set(s,s)}return c}function K(i,o,e,n={},c){const{pathname:s}=g(p(i,c)),a=s.split("/").filter(Boolean)[0];return a===void 0?e:x(o,e,n).get(a)??e}function L(i,o,e,n={},c){const{pathname:s}=g(p(i,c)),a=s.split("/").filter(Boolean),f=a[0];return f!==void 0&&(e!==void 0?x(o,e,n).has(f)&&a.shift():o.includes(f)&&a.shift()),a.length===0?"index":a.join("-").replace(/\.html$/,"")}function V(i){return j.defineComponent({name:"VitePressI18nLink",props:{to:{type:String,required:!0},style:{type:Object,default:void 0}},setup(o,{slots:e}){return()=>j.h("a",{href:o.to,style:o.style,onClick:n=>{n.defaultPrevented||n.button===0&&(n.metaKey||n.altKey||n.ctrlKey||n.shiftKey||(n.preventDefault(),i?i(o.to):typeof window<"u"&&window.location.assign(o.to)))}},e.default?.())}})}function z(i){const{locales:o,defaultLocale:e,localeKeyToCode:n={},base:c,getPath:s,go:a}=i,f=o.map(t=>t.code),l={...n},C=x(f,e,l),S=[...C.keys()],d=c&&c!=="/"?c:void 0,B=t=>l[t]?l[t]:t==="root"?e:t,v=t=>{for(const[r,u]of Object.entries(l))if(u===t)return r;return t===e?"root":t},O=t=>{if(t===e)return null;const r=v(t);return r==="root"?t:r},T=t=>{const r=t==="/"||t.endsWith("/"),u=t.split("/").filter(Boolean),h=u[0];return h!==void 0&&C.has(h)&&u.shift(),{segments:u,hadTrailingSlash:r}},R=t=>{const{pathname:r,extras:u}=g(p(t,d)),{segments:h,hadTrailingSlash:m}=T(r);let w=h.length===0?"/":`/${h.join("/")}`;return w!=="/"&&m&&(w+="/"),`${w}${u}`},y=(t,r)=>{const{pathname:u,extras:h}=g(p(t,d)),{segments:m,hadTrailingSlash:w}=T(u),k=O(r);k&&m.unshift(k);let P=m.length===0?"/":`/${m.join("/")}`;return P!=="/"&&w&&(P+="/"),`${P}${h}`},b=(t,r)=>y(t,r),q=(t,r)=>{const u=typeof t=="string"?t:t.path||"/";return y(u,r)},F=(t,r=!1)=>{if(a){a(t,{replace:r});return}typeof window<"u"&&(r?window.location.replace(t):window.location.assign(t))},$=()=>s?s():typeof window<"u"?window.location.pathname+window.location.search+window.location.hash:"/";return{localeCodes:f,defaultLocale:e,localeKeyToCode:l,urlPrefixes:S,base:d,codeFromLocaleKey:B,localeKeyFromCode:v,getLocaleFromPath:t=>K(t,f,e,l,d),switchLocalePath:b,localizePath:y,removeLocaleFromPath:R,routeNameFromPath:t=>L(t,f,e,l,d),linkComponent:V(a),getCurrentPath:()=>p($(),d),push:t=>{F(t.path,!1)},replace:t=>{F(t.path,!0)},resolvePath:q,getRoute:()=>{const t=p($(),d),r=typeof window<"u"?new URL(t,window.location.origin):new URL(t,"http://localhost");return{fullPath:r.pathname+r.search+r.hash,query:Object.fromEntries(r.searchParams)}}}}exports.createVitePressRouterAdapter=z;exports.getLocaleFromPath=K;exports.routeNameFromPath=L;exports.stripSiteBase=p;
|
|
2
|
+
//# sourceMappingURL=adapter-BJ-0ltIc.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-BJ-0ltIc.cjs","sources":["../src/router/adapter.ts"],"sourcesContent":["import type { Locale } from '@i18n-micro/types'\nimport type { I18nRoutingStrategy } from '@i18n-micro/vue'\nimport { defineComponent, h, type Component, type PropType } from 'vue'\n\nexport interface VitePressRouterLike {\n route: {\n path: string\n hash?: string\n query?: string\n }\n go: (to: string, options?: { initialLoad?: boolean; replace?: boolean }) => void | Promise<void>\n onAfterRouteChange?: (to: string) => unknown\n}\n\nexport type VitePressGo = (href: string, options?: { replace?: boolean }) => void | Promise<void>\n\nexport interface VitePressRouterAdapterOptions {\n locales: Locale[]\n defaultLocale: string\n /**\n * Map VitePress locale keys (`root`, `fr`) to i18n locale codes.\n * Defaults: `root` → `defaultLocale`, other keys → same string as the key.\n * URL prefixes always use VitePress keys; i18n uses codes.\n */\n localeKeyToCode?: Record<string, string>\n /**\n * VitePress `site.base` (e.g. `/openapi_docs/`). Stripped from paths before\n * locale / route-name detection. Returned localize paths are base-relative\n * (VitePress / `withBase` re-applies the base).\n */\n base?: string\n getPath?: () => string\n go?: VitePressGo\n}\n\nexport interface VitePressRouterAdapter extends I18nRoutingStrategy {\n getLocaleFromPath: (path: string) => string\n switchLocalePath: (path: string, newLocale: string) => string\n localizePath: (path: string, locale: string) => string\n removeLocaleFromPath: (path: string) => string\n /** Page dictionary route name (`/fr/guide/demo` → `guide-demo`). */\n routeNameFromPath: (path: string) => string\n /** Resolve VitePress locale key (`root` / `fr`) to i18n code. */\n codeFromLocaleKey: (localeKey: string) => string\n /** Resolve i18n code to VitePress locale key. */\n localeKeyFromCode: (code: string) => string\n localeCodes: string[]\n defaultLocale: string\n /** Snapshot of mapping used when building the adapter (for `i18nRouting` serialization). */\n localeKeyToCode: Record<string, string>\n /** URL path prefixes (VitePress locale keys except `root`). */\n urlPrefixes: string[]\n /** VitePress `site.base` used when constructing this adapter (may be undefined). */\n base?: string\n}\n\n/** Path helpers exposed on `createI18n` instances (slice of the router adapter). */\nexport type PathMethods = Pick<\n VitePressRouterAdapter,\n 'localizePath' | 'switchLocalePath' | 'getLocaleFromPath' | 'removeLocaleFromPath' | 'routeNameFromPath'\n>\n\nfunction splitPathAndExtras(path: string): { pathname: string; extras: string } {\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 return {\n pathname: path.slice(0, cut) || '/',\n extras: path.slice(cut),\n }\n}\n\n/**\n * Strip VitePress `site.base` from a path. Leaves query/hash intact.\n * No-op when `base` is missing or `/`.\n */\nexport function stripSiteBase(path: string, base?: string): string {\n if (!base || base === '/') return path\n const normalized = base.endsWith('/') ? base.slice(0, -1) : base\n if (!normalized) return path\n const { pathname, extras } = splitPathAndExtras(path)\n if (pathname === normalized) return `/${extras}`\n if (pathname.startsWith(`${normalized}/`)) {\n return `${pathname.slice(normalized.length) || '/'}${extras}`\n }\n return path\n}\n\n/**\n * Build URL prefix → i18n code map.\n * Prefixes are VitePress locale keys (and codes when they differ), never `root`.\n */\nexport function buildUrlPrefixToCode(\n localeCodes: string[],\n defaultLocale: string,\n localeKeyToCode: Record<string, string> = {},\n): Map<string, string> {\n const keyFromCode = (code: 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 const prefixToCode = new Map<string, string>()\n for (const code of localeCodes) {\n if (code === defaultLocale) continue\n const key = keyFromCode(code)\n const urlKey = key === 'root' ? code : key\n prefixToCode.set(urlKey, code)\n if (urlKey !== code) prefixToCode.set(code, code)\n }\n return prefixToCode\n}\n\n/**\n * Detect i18n locale code from a URL path (prefix_except_default).\n * Path prefixes are VitePress locale keys; return value is the i18n code.\n * Pass `base` when the path may include VitePress `site.base` (SSG).\n */\nexport function getLocaleFromPath(\n path: string,\n localeCodes: string[],\n defaultLocale: string,\n localeKeyToCode: Record<string, string> = {},\n base?: string,\n): string {\n const { pathname } = splitPathAndExtras(stripSiteBase(path, base))\n const first = pathname.split('/').filter(Boolean)[0]\n if (first === undefined) return defaultLocale\n const prefixToCode = buildUrlPrefixToCode(localeCodes, defaultLocale, localeKeyToCode)\n return prefixToCode.get(first) ?? defaultLocale\n}\n\n/**\n * Route name for page-scoped dictionaries (`/guide/demo` → `guide-demo`).\n * Strips VitePress URL prefixes (keys), not only raw i18n codes.\n *\n * When `defaultLocale` is omitted (legacy 2-arg call), any segment that matches a\n * listed locale code is stripped — callers must not rely on `localeCodes[0]` as default.\n */\nexport function routeNameFromPath(\n path: string,\n localeCodes: string[],\n defaultLocale?: string,\n localeKeyToCode: Record<string, string> = {},\n base?: string,\n): string {\n const { pathname } = splitPathAndExtras(stripSiteBase(path, base))\n const segments = pathname.split('/').filter(Boolean)\n const first = segments[0]\n if (first !== undefined) {\n if (defaultLocale !== undefined) {\n const prefixToCode = buildUrlPrefixToCode(localeCodes, defaultLocale, localeKeyToCode)\n if (prefixToCode.has(first)) segments.shift()\n } else if (localeCodes.includes(first)) {\n segments.shift()\n }\n }\n if (segments.length === 0) return 'index'\n return segments.join('-').replace(/\\.html$/, '')\n}\n\nfunction createVitePressLinkComponent(go?: VitePressGo): Component {\n return defineComponent({\n name: 'VitePressI18nLink',\n props: {\n to: { type: String, required: true },\n style: { type: Object as PropType<Record<string, string>>, default: undefined },\n },\n setup(props, { slots }) {\n return () =>\n h(\n 'a',\n {\n href: props.to,\n style: props.style,\n onClick: (e: MouseEvent) => {\n if (e.defaultPrevented) return\n if (e.button !== 0) return\n if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) return\n e.preventDefault()\n if (go) {\n void go(props.to)\n } else if (typeof window !== 'undefined') {\n window.location.assign(props.to)\n }\n },\n },\n slots.default?.(),\n )\n },\n })\n}\n\n/**\n * VitePress path adapter (prefix_except_default semantics):\n * default locale has no URL prefix; other locales use `/{vitepressKey}/…`.\n * i18n locale values remain `locale.code` (via `localeKeyToCode`).\n */\nexport function createVitePressRouterAdapter(options: VitePressRouterAdapterOptions): VitePressRouterAdapter {\n const { locales, defaultLocale, localeKeyToCode = {}, base, getPath, go } = options\n const localeCodes = locales.map((loc) => loc.code)\n const localeKeyToCodeSnapshot = { ...localeKeyToCode }\n const prefixToCode = buildUrlPrefixToCode(localeCodes, defaultLocale, localeKeyToCodeSnapshot)\n const urlPrefixes = [...prefixToCode.keys()]\n const siteBase = base && base !== '/' ? base : undefined\n\n const codeFromLocaleKey = (localeKey: string): string => {\n if (localeKeyToCodeSnapshot[localeKey]) return localeKeyToCodeSnapshot[localeKey]!\n if (localeKey === 'root') return defaultLocale\n return localeKey\n }\n\n const localeKeyFromCode = (code: string): string => {\n for (const [key, mapped] of Object.entries(localeKeyToCodeSnapshot)) {\n if (mapped === code) return key\n }\n if (code === defaultLocale) return 'root'\n return code\n }\n\n const urlPrefixForCode = (code: string): string | null => {\n if (code === defaultLocale) return null\n const key = localeKeyFromCode(code)\n return key === 'root' ? code : key\n }\n\n const stripPrefix = (pathname: string): { segments: string[]; hadTrailingSlash: boolean } => {\n const hadTrailingSlash = pathname === '/' || pathname.endsWith('/')\n const segments = pathname.split('/').filter(Boolean)\n const first = segments[0]\n if (first !== undefined && prefixToCode.has(first)) {\n segments.shift()\n }\n return { segments, hadTrailingSlash }\n }\n\n const removeLocaleFromPath = (path: string): string => {\n const { pathname, extras } = splitPathAndExtras(stripSiteBase(path, siteBase))\n const { segments, hadTrailingSlash } = stripPrefix(pathname)\n let clean = segments.length === 0 ? '/' : `/${segments.join('/')}`\n if (clean !== '/' && hadTrailingSlash) clean += '/'\n return `${clean}${extras}`\n }\n\n const localizePath = (path: string, locale: string): string => {\n const { pathname, extras } = splitPathAndExtras(stripSiteBase(path, siteBase))\n const { segments, hadTrailingSlash } = stripPrefix(pathname)\n const prefix = urlPrefixForCode(locale)\n if (prefix) segments.unshift(prefix)\n let localized = segments.length === 0 ? '/' : `/${segments.join('/')}`\n if (localized !== '/' && hadTrailingSlash) localized += '/'\n return `${localized}${extras}`\n }\n\n const switchLocalePath = (path: string, newLocale: string): string => {\n return localizePath(path, newLocale)\n }\n\n const resolvePath = (to: string | { path?: string }, locale: string): string => {\n const path = typeof to === 'string' ? to : to.path || '/'\n return localizePath(path, locale)\n }\n\n const navigate = (href: string, replace = false) => {\n if (go) {\n void go(href, { replace })\n return\n }\n if (typeof window !== 'undefined') {\n if (replace) {\n window.location.replace(href)\n } else {\n window.location.assign(href)\n }\n }\n }\n\n const currentFullPath = (): string => {\n if (getPath) return getPath()\n if (typeof window !== 'undefined') {\n return window.location.pathname + window.location.search + window.location.hash\n }\n return '/'\n }\n\n return {\n localeCodes,\n defaultLocale,\n localeKeyToCode: localeKeyToCodeSnapshot,\n urlPrefixes,\n base: siteBase,\n codeFromLocaleKey,\n localeKeyFromCode,\n getLocaleFromPath: (path: string) => getLocaleFromPath(path, localeCodes, defaultLocale, localeKeyToCodeSnapshot, siteBase),\n switchLocalePath,\n localizePath,\n removeLocaleFromPath,\n routeNameFromPath: (path: string) => routeNameFromPath(path, localeCodes, defaultLocale, localeKeyToCodeSnapshot, siteBase),\n linkComponent: createVitePressLinkComponent(go),\n getCurrentPath: () => stripSiteBase(currentFullPath(), siteBase),\n push: (target: { path: string }) => {\n navigate(target.path, false)\n },\n replace: (target: { path: string }) => {\n navigate(target.path, true)\n },\n resolvePath,\n getRoute: () => {\n const path = stripSiteBase(currentFullPath(), siteBase)\n const url = typeof window !== 'undefined' ? new URL(path, window.location.origin) : new URL(path, 'http://localhost')\n return {\n fullPath: url.pathname + url.search + url.hash,\n query: Object.fromEntries(url.searchParams),\n }\n },\n }\n}\n"],"names":["splitPathAndExtras","path","hashIndex","queryIndex","cut","stripSiteBase","base","normalized","pathname","extras","buildUrlPrefixToCode","localeCodes","defaultLocale","localeKeyToCode","keyFromCode","code","key","mapped","prefixToCode","urlKey","getLocaleFromPath","first","routeNameFromPath","segments","createVitePressLinkComponent","go","defineComponent","props","slots","h","e","createVitePressRouterAdapter","options","locales","getPath","loc","localeKeyToCodeSnapshot","urlPrefixes","siteBase","codeFromLocaleKey","localeKey","localeKeyFromCode","urlPrefixForCode","stripPrefix","hadTrailingSlash","removeLocaleFromPath","clean","localizePath","locale","prefix","localized","switchLocalePath","newLocale","resolvePath","to","navigate","href","replace","currentFullPath","target","url"],"mappings":"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"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { defineComponent as b, h as R } from "vue";
|
|
2
|
+
function g(i) {
|
|
3
|
+
const o = i.indexOf("#"), e = i.indexOf("?");
|
|
4
|
+
let n = i.length;
|
|
5
|
+
return o >= 0 && (n = Math.min(n, o)), e >= 0 && (n = Math.min(n, e)), {
|
|
6
|
+
pathname: i.slice(0, n) || "/",
|
|
7
|
+
extras: i.slice(n)
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function p(i, o) {
|
|
11
|
+
if (!o || o === "/") return i;
|
|
12
|
+
const e = o.endsWith("/") ? o.slice(0, -1) : o;
|
|
13
|
+
if (!e) return i;
|
|
14
|
+
const { pathname: n, extras: c } = g(i);
|
|
15
|
+
return n === e ? `/${c}` : n.startsWith(`${e}/`) ? `${n.slice(e.length) || "/"}${c}` : i;
|
|
16
|
+
}
|
|
17
|
+
function P(i, o, e = {}) {
|
|
18
|
+
const n = (s) => {
|
|
19
|
+
for (const [a, f] of Object.entries(e))
|
|
20
|
+
if (f === s) return a;
|
|
21
|
+
return s === o ? "root" : s;
|
|
22
|
+
}, c = /* @__PURE__ */ new Map();
|
|
23
|
+
for (const s of i) {
|
|
24
|
+
if (s === o) continue;
|
|
25
|
+
const a = n(s), f = a === "root" ? s : a;
|
|
26
|
+
c.set(f, s), f !== s && c.set(s, s);
|
|
27
|
+
}
|
|
28
|
+
return c;
|
|
29
|
+
}
|
|
30
|
+
function q(i, o, e, n = {}, c) {
|
|
31
|
+
const { pathname: s } = g(p(i, c)), a = s.split("/").filter(Boolean)[0];
|
|
32
|
+
return a === void 0 ? e : P(o, e, n).get(a) ?? e;
|
|
33
|
+
}
|
|
34
|
+
function z(i, o, e, n = {}, c) {
|
|
35
|
+
const { pathname: s } = g(p(i, c)), a = s.split("/").filter(Boolean), f = a[0];
|
|
36
|
+
return f !== void 0 && (e !== void 0 ? P(o, e, n).has(f) && a.shift() : o.includes(f) && a.shift()), a.length === 0 ? "index" : a.join("-").replace(/\.html$/, "");
|
|
37
|
+
}
|
|
38
|
+
function I(i) {
|
|
39
|
+
return b({
|
|
40
|
+
name: "VitePressI18nLink",
|
|
41
|
+
props: {
|
|
42
|
+
to: { type: String, required: !0 },
|
|
43
|
+
style: { type: Object, default: void 0 }
|
|
44
|
+
},
|
|
45
|
+
setup(o, { slots: e }) {
|
|
46
|
+
return () => R(
|
|
47
|
+
"a",
|
|
48
|
+
{
|
|
49
|
+
href: o.to,
|
|
50
|
+
style: o.style,
|
|
51
|
+
onClick: (n) => {
|
|
52
|
+
n.defaultPrevented || n.button === 0 && (n.metaKey || n.altKey || n.ctrlKey || n.shiftKey || (n.preventDefault(), i ? i(o.to) : typeof window < "u" && window.location.assign(o.to)));
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
e.default?.()
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function U(i) {
|
|
61
|
+
const { locales: o, defaultLocale: e, localeKeyToCode: n = {}, base: c, getPath: s, go: a } = i, f = o.map((t) => t.code), u = { ...n }, C = P(f, e, u), j = [...C.keys()], d = c && c !== "/" ? c : void 0, K = (t) => u[t] ? u[t] : t === "root" ? e : t, v = (t) => {
|
|
62
|
+
for (const [r, l] of Object.entries(u))
|
|
63
|
+
if (l === t) return r;
|
|
64
|
+
return t === e ? "root" : t;
|
|
65
|
+
}, L = (t) => {
|
|
66
|
+
if (t === e) return null;
|
|
67
|
+
const r = v(t);
|
|
68
|
+
return r === "root" ? t : r;
|
|
69
|
+
}, T = (t) => {
|
|
70
|
+
const r = t === "/" || t.endsWith("/"), l = t.split("/").filter(Boolean), h = l[0];
|
|
71
|
+
return h !== void 0 && C.has(h) && l.shift(), { segments: l, hadTrailingSlash: r };
|
|
72
|
+
}, O = (t) => {
|
|
73
|
+
const { pathname: r, extras: l } = g(p(t, d)), { segments: h, hadTrailingSlash: m } = T(r);
|
|
74
|
+
let w = h.length === 0 ? "/" : `/${h.join("/")}`;
|
|
75
|
+
return w !== "/" && m && (w += "/"), `${w}${l}`;
|
|
76
|
+
}, y = (t, r) => {
|
|
77
|
+
const { pathname: l, extras: h } = g(p(t, d)), { segments: m, hadTrailingSlash: w } = T(l), F = L(r);
|
|
78
|
+
F && m.unshift(F);
|
|
79
|
+
let x = m.length === 0 ? "/" : `/${m.join("/")}`;
|
|
80
|
+
return x !== "/" && w && (x += "/"), `${x}${h}`;
|
|
81
|
+
}, S = (t, r) => y(t, r), B = (t, r) => {
|
|
82
|
+
const l = typeof t == "string" ? t : t.path || "/";
|
|
83
|
+
return y(l, r);
|
|
84
|
+
}, $ = (t, r = !1) => {
|
|
85
|
+
if (a) {
|
|
86
|
+
a(t, { replace: r });
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
typeof window < "u" && (r ? window.location.replace(t) : window.location.assign(t));
|
|
90
|
+
}, k = () => s ? s() : typeof window < "u" ? window.location.pathname + window.location.search + window.location.hash : "/";
|
|
91
|
+
return {
|
|
92
|
+
localeCodes: f,
|
|
93
|
+
defaultLocale: e,
|
|
94
|
+
localeKeyToCode: u,
|
|
95
|
+
urlPrefixes: j,
|
|
96
|
+
base: d,
|
|
97
|
+
codeFromLocaleKey: K,
|
|
98
|
+
localeKeyFromCode: v,
|
|
99
|
+
getLocaleFromPath: (t) => q(t, f, e, u, d),
|
|
100
|
+
switchLocalePath: S,
|
|
101
|
+
localizePath: y,
|
|
102
|
+
removeLocaleFromPath: O,
|
|
103
|
+
routeNameFromPath: (t) => z(t, f, e, u, d),
|
|
104
|
+
linkComponent: I(a),
|
|
105
|
+
getCurrentPath: () => p(k(), d),
|
|
106
|
+
push: (t) => {
|
|
107
|
+
$(t.path, !1);
|
|
108
|
+
},
|
|
109
|
+
replace: (t) => {
|
|
110
|
+
$(t.path, !0);
|
|
111
|
+
},
|
|
112
|
+
resolvePath: B,
|
|
113
|
+
getRoute: () => {
|
|
114
|
+
const t = p(k(), d), r = typeof window < "u" ? new URL(t, window.location.origin) : new URL(t, "http://localhost");
|
|
115
|
+
return {
|
|
116
|
+
fullPath: r.pathname + r.search + r.hash,
|
|
117
|
+
query: Object.fromEntries(r.searchParams)
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
export {
|
|
123
|
+
U as c,
|
|
124
|
+
q as g,
|
|
125
|
+
z as r,
|
|
126
|
+
p as s
|
|
127
|
+
};
|
|
128
|
+
//# sourceMappingURL=adapter-BnsyIKhp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-BnsyIKhp.js","sources":["../src/router/adapter.ts"],"sourcesContent":["import type { Locale } from '@i18n-micro/types'\nimport type { I18nRoutingStrategy } from '@i18n-micro/vue'\nimport { defineComponent, h, type Component, type PropType } from 'vue'\n\nexport interface VitePressRouterLike {\n route: {\n path: string\n hash?: string\n query?: string\n }\n go: (to: string, options?: { initialLoad?: boolean; replace?: boolean }) => void | Promise<void>\n onAfterRouteChange?: (to: string) => unknown\n}\n\nexport type VitePressGo = (href: string, options?: { replace?: boolean }) => void | Promise<void>\n\nexport interface VitePressRouterAdapterOptions {\n locales: Locale[]\n defaultLocale: string\n /**\n * Map VitePress locale keys (`root`, `fr`) to i18n locale codes.\n * Defaults: `root` → `defaultLocale`, other keys → same string as the key.\n * URL prefixes always use VitePress keys; i18n uses codes.\n */\n localeKeyToCode?: Record<string, string>\n /**\n * VitePress `site.base` (e.g. `/openapi_docs/`). Stripped from paths before\n * locale / route-name detection. Returned localize paths are base-relative\n * (VitePress / `withBase` re-applies the base).\n */\n base?: string\n getPath?: () => string\n go?: VitePressGo\n}\n\nexport interface VitePressRouterAdapter extends I18nRoutingStrategy {\n getLocaleFromPath: (path: string) => string\n switchLocalePath: (path: string, newLocale: string) => string\n localizePath: (path: string, locale: string) => string\n removeLocaleFromPath: (path: string) => string\n /** Page dictionary route name (`/fr/guide/demo` → `guide-demo`). */\n routeNameFromPath: (path: string) => string\n /** Resolve VitePress locale key (`root` / `fr`) to i18n code. */\n codeFromLocaleKey: (localeKey: string) => string\n /** Resolve i18n code to VitePress locale key. */\n localeKeyFromCode: (code: string) => string\n localeCodes: string[]\n defaultLocale: string\n /** Snapshot of mapping used when building the adapter (for `i18nRouting` serialization). */\n localeKeyToCode: Record<string, string>\n /** URL path prefixes (VitePress locale keys except `root`). */\n urlPrefixes: string[]\n /** VitePress `site.base` used when constructing this adapter (may be undefined). */\n base?: string\n}\n\n/** Path helpers exposed on `createI18n` instances (slice of the router adapter). */\nexport type PathMethods = Pick<\n VitePressRouterAdapter,\n 'localizePath' | 'switchLocalePath' | 'getLocaleFromPath' | 'removeLocaleFromPath' | 'routeNameFromPath'\n>\n\nfunction splitPathAndExtras(path: string): { pathname: string; extras: string } {\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 return {\n pathname: path.slice(0, cut) || '/',\n extras: path.slice(cut),\n }\n}\n\n/**\n * Strip VitePress `site.base` from a path. Leaves query/hash intact.\n * No-op when `base` is missing or `/`.\n */\nexport function stripSiteBase(path: string, base?: string): string {\n if (!base || base === '/') return path\n const normalized = base.endsWith('/') ? base.slice(0, -1) : base\n if (!normalized) return path\n const { pathname, extras } = splitPathAndExtras(path)\n if (pathname === normalized) return `/${extras}`\n if (pathname.startsWith(`${normalized}/`)) {\n return `${pathname.slice(normalized.length) || '/'}${extras}`\n }\n return path\n}\n\n/**\n * Build URL prefix → i18n code map.\n * Prefixes are VitePress locale keys (and codes when they differ), never `root`.\n */\nexport function buildUrlPrefixToCode(\n localeCodes: string[],\n defaultLocale: string,\n localeKeyToCode: Record<string, string> = {},\n): Map<string, string> {\n const keyFromCode = (code: 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 const prefixToCode = new Map<string, string>()\n for (const code of localeCodes) {\n if (code === defaultLocale) continue\n const key = keyFromCode(code)\n const urlKey = key === 'root' ? code : key\n prefixToCode.set(urlKey, code)\n if (urlKey !== code) prefixToCode.set(code, code)\n }\n return prefixToCode\n}\n\n/**\n * Detect i18n locale code from a URL path (prefix_except_default).\n * Path prefixes are VitePress locale keys; return value is the i18n code.\n * Pass `base` when the path may include VitePress `site.base` (SSG).\n */\nexport function getLocaleFromPath(\n path: string,\n localeCodes: string[],\n defaultLocale: string,\n localeKeyToCode: Record<string, string> = {},\n base?: string,\n): string {\n const { pathname } = splitPathAndExtras(stripSiteBase(path, base))\n const first = pathname.split('/').filter(Boolean)[0]\n if (first === undefined) return defaultLocale\n const prefixToCode = buildUrlPrefixToCode(localeCodes, defaultLocale, localeKeyToCode)\n return prefixToCode.get(first) ?? defaultLocale\n}\n\n/**\n * Route name for page-scoped dictionaries (`/guide/demo` → `guide-demo`).\n * Strips VitePress URL prefixes (keys), not only raw i18n codes.\n *\n * When `defaultLocale` is omitted (legacy 2-arg call), any segment that matches a\n * listed locale code is stripped — callers must not rely on `localeCodes[0]` as default.\n */\nexport function routeNameFromPath(\n path: string,\n localeCodes: string[],\n defaultLocale?: string,\n localeKeyToCode: Record<string, string> = {},\n base?: string,\n): string {\n const { pathname } = splitPathAndExtras(stripSiteBase(path, base))\n const segments = pathname.split('/').filter(Boolean)\n const first = segments[0]\n if (first !== undefined) {\n if (defaultLocale !== undefined) {\n const prefixToCode = buildUrlPrefixToCode(localeCodes, defaultLocale, localeKeyToCode)\n if (prefixToCode.has(first)) segments.shift()\n } else if (localeCodes.includes(first)) {\n segments.shift()\n }\n }\n if (segments.length === 0) return 'index'\n return segments.join('-').replace(/\\.html$/, '')\n}\n\nfunction createVitePressLinkComponent(go?: VitePressGo): Component {\n return defineComponent({\n name: 'VitePressI18nLink',\n props: {\n to: { type: String, required: true },\n style: { type: Object as PropType<Record<string, string>>, default: undefined },\n },\n setup(props, { slots }) {\n return () =>\n h(\n 'a',\n {\n href: props.to,\n style: props.style,\n onClick: (e: MouseEvent) => {\n if (e.defaultPrevented) return\n if (e.button !== 0) return\n if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) return\n e.preventDefault()\n if (go) {\n void go(props.to)\n } else if (typeof window !== 'undefined') {\n window.location.assign(props.to)\n }\n },\n },\n slots.default?.(),\n )\n },\n })\n}\n\n/**\n * VitePress path adapter (prefix_except_default semantics):\n * default locale has no URL prefix; other locales use `/{vitepressKey}/…`.\n * i18n locale values remain `locale.code` (via `localeKeyToCode`).\n */\nexport function createVitePressRouterAdapter(options: VitePressRouterAdapterOptions): VitePressRouterAdapter {\n const { locales, defaultLocale, localeKeyToCode = {}, base, getPath, go } = options\n const localeCodes = locales.map((loc) => loc.code)\n const localeKeyToCodeSnapshot = { ...localeKeyToCode }\n const prefixToCode = buildUrlPrefixToCode(localeCodes, defaultLocale, localeKeyToCodeSnapshot)\n const urlPrefixes = [...prefixToCode.keys()]\n const siteBase = base && base !== '/' ? base : undefined\n\n const codeFromLocaleKey = (localeKey: string): string => {\n if (localeKeyToCodeSnapshot[localeKey]) return localeKeyToCodeSnapshot[localeKey]!\n if (localeKey === 'root') return defaultLocale\n return localeKey\n }\n\n const localeKeyFromCode = (code: string): string => {\n for (const [key, mapped] of Object.entries(localeKeyToCodeSnapshot)) {\n if (mapped === code) return key\n }\n if (code === defaultLocale) return 'root'\n return code\n }\n\n const urlPrefixForCode = (code: string): string | null => {\n if (code === defaultLocale) return null\n const key = localeKeyFromCode(code)\n return key === 'root' ? code : key\n }\n\n const stripPrefix = (pathname: string): { segments: string[]; hadTrailingSlash: boolean } => {\n const hadTrailingSlash = pathname === '/' || pathname.endsWith('/')\n const segments = pathname.split('/').filter(Boolean)\n const first = segments[0]\n if (first !== undefined && prefixToCode.has(first)) {\n segments.shift()\n }\n return { segments, hadTrailingSlash }\n }\n\n const removeLocaleFromPath = (path: string): string => {\n const { pathname, extras } = splitPathAndExtras(stripSiteBase(path, siteBase))\n const { segments, hadTrailingSlash } = stripPrefix(pathname)\n let clean = segments.length === 0 ? '/' : `/${segments.join('/')}`\n if (clean !== '/' && hadTrailingSlash) clean += '/'\n return `${clean}${extras}`\n }\n\n const localizePath = (path: string, locale: string): string => {\n const { pathname, extras } = splitPathAndExtras(stripSiteBase(path, siteBase))\n const { segments, hadTrailingSlash } = stripPrefix(pathname)\n const prefix = urlPrefixForCode(locale)\n if (prefix) segments.unshift(prefix)\n let localized = segments.length === 0 ? '/' : `/${segments.join('/')}`\n if (localized !== '/' && hadTrailingSlash) localized += '/'\n return `${localized}${extras}`\n }\n\n const switchLocalePath = (path: string, newLocale: string): string => {\n return localizePath(path, newLocale)\n }\n\n const resolvePath = (to: string | { path?: string }, locale: string): string => {\n const path = typeof to === 'string' ? to : to.path || '/'\n return localizePath(path, locale)\n }\n\n const navigate = (href: string, replace = false) => {\n if (go) {\n void go(href, { replace })\n return\n }\n if (typeof window !== 'undefined') {\n if (replace) {\n window.location.replace(href)\n } else {\n window.location.assign(href)\n }\n }\n }\n\n const currentFullPath = (): string => {\n if (getPath) return getPath()\n if (typeof window !== 'undefined') {\n return window.location.pathname + window.location.search + window.location.hash\n }\n return '/'\n }\n\n return {\n localeCodes,\n defaultLocale,\n localeKeyToCode: localeKeyToCodeSnapshot,\n urlPrefixes,\n base: siteBase,\n codeFromLocaleKey,\n localeKeyFromCode,\n getLocaleFromPath: (path: string) => getLocaleFromPath(path, localeCodes, defaultLocale, localeKeyToCodeSnapshot, siteBase),\n switchLocalePath,\n localizePath,\n removeLocaleFromPath,\n routeNameFromPath: (path: string) => routeNameFromPath(path, localeCodes, defaultLocale, localeKeyToCodeSnapshot, siteBase),\n linkComponent: createVitePressLinkComponent(go),\n getCurrentPath: () => stripSiteBase(currentFullPath(), siteBase),\n push: (target: { path: string }) => {\n navigate(target.path, false)\n },\n replace: (target: { path: string }) => {\n navigate(target.path, true)\n },\n resolvePath,\n getRoute: () => {\n const path = stripSiteBase(currentFullPath(), siteBase)\n const url = typeof window !== 'undefined' ? new URL(path, window.location.origin) : new URL(path, 'http://localhost')\n return {\n fullPath: url.pathname + url.search + url.hash,\n query: Object.fromEntries(url.searchParams),\n }\n },\n }\n}\n"],"names":["splitPathAndExtras","path","hashIndex","queryIndex","cut","stripSiteBase","base","normalized","pathname","extras","buildUrlPrefixToCode","localeCodes","defaultLocale","localeKeyToCode","keyFromCode","code","key","mapped","prefixToCode","urlKey","getLocaleFromPath","first","routeNameFromPath","segments","createVitePressLinkComponent","go","defineComponent","props","slots","h","e","createVitePressRouterAdapter","options","locales","getPath","loc","localeKeyToCodeSnapshot","urlPrefixes","siteBase","codeFromLocaleKey","localeKey","localeKeyFromCode","urlPrefixForCode","stripPrefix","hadTrailingSlash","removeLocaleFromPath","clean","localizePath","locale","prefix","localized","switchLocalePath","newLocale","resolvePath","to","navigate","href","replace","currentFullPath","target","url"],"mappings":"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"}
|
package/dist/config.cjs
CHANGED
|
@@ -1,2 +1,65 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const C=require("node:fs"),v=require("node:path"),V=require("@i18n-micro/utils/parse-path"),G=require("@i18n-micro/utils/resolve-hreflang"),k=require("@i18n-micro/utils/resolve-og-locale"),q=require("./adapter-BJ-0ltIc.cjs"),Q=require("./vitepress-locales-Cz4AutfI.cjs");function z(e){return"switchLocalePath"in e&&typeof e.switchLocalePath=="function"}function U(e){const t=z(e)?{defaultLocale:e.defaultLocale,localeCodes:e.localeCodes,localeKeyToCode:e.localeKeyToCode??{},base:e.base}:e,a=t.defaultLocale,s=t.localeCodes,o=t.localeKeyToCode??{},c=t.base&&t.base!=="/"?t.base:"";return new Function("data","route","targetLocale",`
|
|
2
|
+
const defaultLocale = ${JSON.stringify(a)};
|
|
3
|
+
const localeCodes = ${JSON.stringify(s)};
|
|
4
|
+
const localeKeyToCode = ${JSON.stringify(o)};
|
|
5
|
+
const siteBase = ${JSON.stringify(c)};
|
|
6
|
+
const keyFromCode = (code) => {
|
|
7
|
+
for (const key of Object.keys(localeKeyToCode)) {
|
|
8
|
+
if (localeKeyToCode[key] === code) return key;
|
|
9
|
+
}
|
|
10
|
+
return code === defaultLocale ? 'root' : code;
|
|
11
|
+
};
|
|
12
|
+
const prefixes = [];
|
|
13
|
+
for (let i = 0; i < localeCodes.length; i++) {
|
|
14
|
+
const code = localeCodes[i];
|
|
15
|
+
if (code === defaultLocale) continue;
|
|
16
|
+
const key = keyFromCode(code);
|
|
17
|
+
const urlKey = key === 'root' ? code : key;
|
|
18
|
+
prefixes.push(urlKey);
|
|
19
|
+
if (urlKey !== code) prefixes.push(code);
|
|
20
|
+
}
|
|
21
|
+
// VitePress passes locale *keys* (root / fr). URL prefix is the key, not the i18n code.
|
|
22
|
+
const urlPrefix = targetLocale === 'root' ? null : targetLocale;
|
|
23
|
+
let path = (route && route.path) || '/';
|
|
24
|
+
const hash = (route && route.hash) || '';
|
|
25
|
+
const query = (route && route.query) || '';
|
|
26
|
+
const hashIndex = path.indexOf('#');
|
|
27
|
+
const queryIndex = path.indexOf('?');
|
|
28
|
+
let cut = path.length;
|
|
29
|
+
if (hashIndex >= 0) cut = Math.min(cut, hashIndex);
|
|
30
|
+
if (queryIndex >= 0) cut = Math.min(cut, queryIndex);
|
|
31
|
+
let pathname = path.slice(0, cut) || '/';
|
|
32
|
+
const extras = path.slice(cut);
|
|
33
|
+
if (siteBase) {
|
|
34
|
+
const b = siteBase.endsWith('/') ? siteBase.slice(0, -1) : siteBase;
|
|
35
|
+
if (pathname === b) pathname = '/';
|
|
36
|
+
else if (pathname.indexOf(b + '/') === 0) pathname = pathname.slice(b.length) || '/';
|
|
37
|
+
}
|
|
38
|
+
const hadTrailingSlash = pathname === '/' || pathname.endsWith('/');
|
|
39
|
+
const segments = pathname.split('/').filter(Boolean);
|
|
40
|
+
if (segments[0] && prefixes.indexOf(segments[0]) >= 0) segments.shift();
|
|
41
|
+
if (urlPrefix) segments.unshift(urlPrefix);
|
|
42
|
+
let localized = segments.length === 0 ? '/' : '/' + segments.join('/');
|
|
43
|
+
if (localized !== '/' && hadTrailingSlash) localized += '/';
|
|
44
|
+
const q = extras.indexOf('?') >= 0
|
|
45
|
+
? ''
|
|
46
|
+
: (query ? (query.charAt(0) === '?' ? query : '?' + query) : '');
|
|
47
|
+
const h = hash
|
|
48
|
+
? (hash.charAt(0) === '#' ? hash : '#' + hash)
|
|
49
|
+
: '';
|
|
50
|
+
return localized + extras + q + h;
|
|
51
|
+
`)}function X(e,t){const a=e.indexOf("#"),s=e.indexOf("?");let o=e.length;a>=0&&(o=Math.min(o,a)),s>=0&&(o=Math.min(o,s));const c=e.slice(0,o)||"/";if(s<0||t.length===0)return c;const n=new URLSearchParams(e.slice(s,a>=0?a:void 0)),i=new URLSearchParams;for(const f of t)n.has(f)&&i.set(f,n.get(f));const h=i.toString();return h?`${c}?${h}`:c}function R(e,t,a){const s=e.replace(/\/$/,""),o=!t||t==="/"?"":t.replace(/\/$/,""),c=a.startsWith("/")?a:`/${a}`;return`${s}${o}${c}`}function j(e){let t=e.replace(/\\/g,"/");return t=t.replace(/(^|\/)index\.md$/,"$1").replace(/\.md$/,""),t.startsWith("/")||(t=`/${t}`),t.length>1&&t.endsWith("/")&&(t=t.slice(0,-1)),t||"/"}function K(e){const{locales:t,defaultLocale:a,localeKeyToCode:s={},base:o,metaBaseUrl:c,hreflangBaseLanguage:n=!1,canonicalQueryWhitelist:i=[],addDirAttribute:h=!0,addSeoAttributes:f=!0,identifierAttribute:u="id",missingWarn:m=!0}=e,g=q.stripSiteBase(e.path,o),r=q.getLocaleFromPath(g,t.map(l=>l.code),a,s,void 0),y=t.find(l=>l.code===r);if(!y)return{htmlAttrs:{},head:[]};const b=y.iso||r,p=y.dir||"auto",M={lang:b,...h?{dir:p}:{}};if(!f||!c)return{htmlAttrs:M,head:[]};const d=U({defaultLocale:a,localeCodes:t.map(l=>l.code),localeKeyToCode:s,base:o}),x=X(g,i),S=r===a?"root":(()=>{for(const[l,L]of Object.entries(s))if(L===r)return l==="root"?"root":l;return r})(),A=d({},{path:x},S),w=R(c,o,A),$=t.filter(l=>!l.disabled&&l.seo!==!1),I=k.resolveOgLocale(y);I||k.warnUnresolvedOgLocale(y,{missingWarn:m,tag:"og:locale"});const P=[];P.push(["link",{[u]:"i18n-can",rel:"canonical",href:w}]),I&&P.push(["meta",{[u]:"i18n-og",property:"og:locale",content:I}]),P.push(["meta",{[u]:"i18n-og-url",property:"og:url",content:w}]);for(const l of $){if(l.code===r)continue;const L=k.resolveOgLocale(l);if(!L){k.warnUnresolvedOgLocale(l,{missingWarn:m,tag:"og:locale:alternate"});continue}P.push(["meta",{[u]:`i18n-og-alt-${L}`,property:"og:locale:alternate",content:L}])}const O=new Map;for(const l of $){const L=l.code===a?"root":(()=>{for(const[N,H]of Object.entries(s))if(H===l.code)return N==="root"?l.code:N;return l.code})(),T=d({},{path:x},L);T&&O.set(String(l.code),R(c,o,T))}for(const{hreflang:l,localeCode:L}of G.resolveHreflangAlternates($,{hreflangBaseLanguage:n})){const T=O.get(L);T&&P.push(["link",{[u]:`i18n-alternate-${l}`,rel:"alternate",href:T,hreflang:l}])}const D=t.find(l=>l.code===a);if(D&&D.seo!==!1){const l=O.get(a);l&&P.push(["link",{[u]:"i18n-xd",rel:"alternate",href:l,hreflang:"x-default"}])}return{htmlAttrs:M,head:P}}function B(e,t){if(C.existsSync(e))for(const a of C.readdirSync(e)){const s=v.join(e,a);if(C.statSync(s).isDirectory()){B(s,t);continue}a.endsWith(".json")&&t(s)}}function Y(e){const t=e.rootDir??process.cwd(),a=v.resolve(t,e.translationDir),s=[];return B(a,o=>{s.push({absolutePath:o,relativePath:v.relative(a,o).split(v.sep).join("/")})}),s.sort((o,c)=>o.relativePath.localeCompare(c.relativePath))}function Z(e){const t=e.rootDir??process.cwd(),a=v.resolve(t,e.translationDir),s={root:{},routes:{}},o=e.disablePageLocales===!0;return C.existsSync(a)&&B(a,c=>{const n=v.relative(a,c).split(v.sep).join("/");try{const i=JSON.parse(C.readFileSync(c,"utf-8"));if(i===null||typeof i!="object"||Array.isArray(i)){console.error(`[i18n-micro/vitepress] Skipping ${n}: expected a JSON object, got ${Array.isArray(i)?"array":typeof i}`);return}V.storeLoadedTranslationFile(s,n,i,o)}catch(i){console.error(`[i18n-micro/vitepress] Failed to load ${n}:`,i)}}),s}const F="virtual:i18n-micro/config",E=`\0${F}`,J="virtual:i18n-micro/messages",W=`\0${J}`;function ee(e){return e.replace(/\\/g,"/")}function te(e,t,a){const s=Y({rootDir:e,translationDir:t});if(s.length===0)return`export const messages = {}
|
|
52
|
+
export const routeMessages = {}
|
|
53
|
+
`;const o=[],c=[],n=new Map;let i=0;for(const f of s){const u=V.classifyTranslationRelativePath(f.relativePath,a);if(u.type==="ignore")continue;const m=`__i18n_${i++}`;if(o.push(`import ${m} from ${JSON.stringify(ee(f.absolutePath))}`),u.type==="root"){c.push(` ${JSON.stringify(u.locale)}: ${m}`);continue}let g=n.get(u.pageName);g||(g=new Map,n.set(u.pageName,g)),g.set(u.locale,m)}const h=[];for(const[f,u]of n){const m=[...u.entries()].map(([g,r])=>` ${JSON.stringify(g)}: ${r}`).join(`,
|
|
54
|
+
`);h.push(` ${JSON.stringify(f)}: {
|
|
55
|
+
${m}
|
|
56
|
+
}`)}return[...o,`export const messages = {
|
|
57
|
+
${c.join(`,
|
|
58
|
+
`)}
|
|
59
|
+
}`,`export const routeMessages = {
|
|
60
|
+
${h.join(`,
|
|
61
|
+
`)}
|
|
62
|
+
}`,""].join(`
|
|
63
|
+
`)}function ae(e,t){return[`export const messages = ${JSON.stringify(e)}`,`export const routeMessages = ${JSON.stringify(t)}`,""].join(`
|
|
64
|
+
`)}function se(e,t){const a=e.defaultLocale||e.locale,s=e.translationDir??"locales",o=e.disablePageLocales===!0,c={defaultLocale:a,fallbackLocale:e.fallbackLocale||a,locales:e.locales||[],localeCodes:(e.locales||[]).map(r=>r.code),missingWarn:e.missingWarn??!0,syncWithVitePress:e.syncWithVitePress!==!1,translationDir:s,disablePageLocales:o,localeKeyToCode:e.localeKeyToCode??{},base:t&&t!=="/"?t:void 0};let n=process.cwd(),i=!!(e.messages||e.routeMessages),h=e.messages??{},f=e.routeMessages??{},u;const m=()=>!e.messages||!e.routeMessages,g=()=>{if(!m())return;const r=Z({rootDir:n,translationDir:s,disablePageLocales:o});e.messages||(h=r.root),e.routeMessages||(f=r.routes)};return{name:"vite-plugin-i18n-vitepress",configResolved(r){n=r.root,i=!!(e.messages||e.routeMessages),i&&(e.messages&&(h=e.messages),e.routeMessages&&(f=e.routeMessages),m()&&g(),e.messages&&(h=e.messages),e.routeMessages&&(f=e.routeMessages))},configureServer(r){if(i&&!m())return;const y=v.resolve(n,s);if(!C.existsSync(y))return;r.watcher.add(y);const b=()=>{u&&clearTimeout(u),u=setTimeout(()=>{i&&g();const p=r.moduleGraph.getModuleById(W);p&&(r.moduleGraph.invalidateModule(p),r.ws.send({type:"full-reload"}))},50)};r.watcher.on("add",p=>{p.startsWith(y)&&p.endsWith(".json")&&b()}),r.watcher.on("unlink",p=>{p.startsWith(y)&&p.endsWith(".json")&&b()}),i&&m()&&r.watcher.on("change",p=>{p.startsWith(y)&&p.endsWith(".json")&&b()})},resolveId(r){if(r===F)return E;if(r===J)return W},load(r){if(r===E)return`export const config = ${JSON.stringify(c)}`;if(r===W)return i?ae(h,f):te(n,s,o)}}}function _(e,t){if(t.warnOnLocaleMismatch===!1)return;const a=e.locales;if(!a||!t.locales?.length)return;const s=t.defaultLocale||t.locale,o=Object.keys(a),c=new Set(t.locales.map(n=>n.code));for(const n of o){const i=n==="root"?s:t.localeKeyToCode?.[n]??n;c.has(i)||console.warn(`[i18n-micro/vitepress] VitePress locale key "${n}" maps to "${i}", which is not in i18n locales (${[...c].join(", ")}).`)}}function oe(e,t){_(e,t);const a=typeof e.base=="string"?e.base:void 0,s=e.vite?.plugins,o=[...Array.isArray(s)?s.flat():[],se(t,a)],c=e.vite?.ssr,n=c?.noExternal,i=["@i18n-micro/vitepress",...Array.isArray(n)?n:n&&n!==!0?[n]:[]],h=t.defaultLocale||t.locale,f=(t.locales||[]).map(d=>d.code),u=e.themeConfig&&typeof e.themeConfig=="object"?e.themeConfig:{},m=t.i18nRouting!==!1&&u.i18nRouting===void 0&&f.length>0,g=t.meta??!!t.metaBaseUrl,r=t.locales||[],y=e.transformHead,b=e.transformPageData,p=g?async d=>{const x=typeof y=="function"?await y(d):[],S=Array.isArray(x)?x:[];if(d.pageData?.frontmatter?.i18n?.disableMeta===!0)return S;const A=d.pageData?.relativePath||"index.md",w=(typeof e.base=="string"?e.base:void 0)??d.siteData?.base??d.siteConfig?.site?.base,$=K({path:j(A),locales:r,defaultLocale:h,localeKeyToCode:t.localeKeyToCode,base:w,metaBaseUrl:t.metaBaseUrl,hreflangBaseLanguage:t.hreflangBaseLanguage,canonicalQueryWhitelist:t.canonicalQueryWhitelist,missingWarn:t.missingWarn});return[...S,...$.head]}:y,M=g?async(d,x)=>{if(typeof b=="function"&&await b(d,x),d.frontmatter?.i18n?.disableMeta===!0)return;const S=K({path:j(d.relativePath||"index.md"),locales:r,defaultLocale:h,localeKeyToCode:t.localeKeyToCode,base:typeof e.base=="string"?e.base:void 0,metaBaseUrl:t.metaBaseUrl,hreflangBaseLanguage:t.hreflangBaseLanguage,canonicalQueryWhitelist:t.canonicalQueryWhitelist,missingWarn:t.missingWarn,addSeoAttributes:!1});S.htmlAttrs.lang&&(d.frontmatter??={},d.frontmatter.lang||(d.frontmatter.lang=S.htmlAttrs.lang))}:b;return{...e,...m?{themeConfig:{...u,i18nRouting:U({defaultLocale:h,localeCodes:f,localeKeyToCode:t.localeKeyToCode,base:a})}}:{},...g?{transformHead:p,transformPageData:M}:{},vite:{...e.vite,plugins:o,ssr:{...c,noExternal:n===!0?!0:i}}}}exports.buildVitePressLocales=Q.buildVitePressLocales;exports.buildVitePressLocaleHead=K;exports.relativePathToRoutePath=j;exports.warnLocaleMismatch=_;exports.withI18n=oe;
|
|
2
65
|
//# sourceMappingURL=config.cjs.map
|
package/dist/config.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"config.cjs","sources":["../src/router/i18n-routing.ts","../src/seo/locale-head.ts","../src/plugin/load-messages.ts","../src/plugin/with-i18n.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 = (data: VitePressI18nRoutingData, route: VitePressI18nRoutingRoute, targetLocale: string) => string\n\nexport interface I18nRoutingFromAdapterOptions {\n defaultLocale: string\n localeCodes: string[]\n localeKeyToCode?: Record<string, string>\n /**\n * VitePress `site.base`. Stripped from `route.path` before rewriting locale;\n * result is base-relative (VitePress applies `withBase`).\n */\n base?: 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(adapterOrOptions: VitePressRouterAdapter | I18nRoutingFromAdapterOptions): VitePressI18nRoutingFn {\n const options: I18nRoutingFromAdapterOptions = isAdapter(adapterOrOptions)\n ? {\n defaultLocale: adapterOrOptions.defaultLocale,\n localeCodes: adapterOrOptions.localeCodes,\n localeKeyToCode: adapterOrOptions.localeKeyToCode ?? {},\n base: adapterOrOptions.base,\n }\n : adapterOrOptions\n\n const defaultLocale = options.defaultLocale\n const localeCodes = options.localeCodes\n const localeKeyToCode = options.localeKeyToCode ?? {}\n const base = options.base && options.base !== '/' ? options.base : ''\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 siteBase = ${JSON.stringify(base)};\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 let pathname = path.slice(0, cut) || '/';\n const extras = path.slice(cut);\n if (siteBase) {\n const b = siteBase.endsWith('/') ? siteBase.slice(0, -1) : siteBase;\n if (pathname === b) pathname = '/';\n else if (pathname.indexOf(b + '/') === 0) pathname = pathname.slice(b.length) || '/';\n }\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","import type { Locale } from '@i18n-micro/types'\nimport { resolveHreflangAlternates } from '@i18n-micro/utils/resolve-hreflang'\nimport { resolveOgLocale, warnUnresolvedOgLocale } from '@i18n-micro/utils/resolve-og-locale'\nimport { createI18nRoutingFromAdapter } from '../router/i18n-routing'\nimport { getLocaleFromPath, stripSiteBase } from '../router/adapter'\n\n/** VitePress `HeadConfig` tuple (tag + attrs). */\nexport type VitePressHeadTuple = [string, Record<string, string>]\n\nexport interface VitePressLocaleHeadObject {\n htmlAttrs: {\n lang?: string\n dir?: 'ltr' | 'rtl' | 'auto'\n }\n /** Ready for `transformHead` / `frontmatter.head`. */\n head: VitePressHeadTuple[]\n}\n\nexport interface BuildVitePressLocaleHeadOptions {\n /**\n * Current page path (with or without `site.base`). Query/hash optional.\n * Example: `/docs/fr/guide/` or `/fr/guide`.\n */\n path: string\n locales: Locale[]\n defaultLocale: string\n localeKeyToCode?: Record<string, string>\n /** VitePress `site.base` (e.g. `/docs/`). */\n base?: string\n /**\n * Public site origin **without** trailing slash (e.g. `https://example.com`).\n * Required for absolute `canonical` / `hreflang` / `og:url`.\n * When omitted, only `htmlAttrs` are produced.\n */\n metaBaseUrl?: string\n /** @default false — same as Nuxt / Vue `useLocaleHead`. */\n hreflangBaseLanguage?: boolean\n /** Query keys kept on canonical / alternate URLs. @default [] */\n canonicalQueryWhitelist?: string[]\n /** @default true */\n addDirAttribute?: boolean\n /** @default true */\n addSeoAttributes?: boolean\n /** @default 'id' */\n identifierAttribute?: string\n missingWarn?: boolean\n}\n\nfunction filterQuery(fullPath: string, whitelist: string[]): string {\n const hashIndex = fullPath.indexOf('#')\n const queryIndex = fullPath.indexOf('?')\n let cut = fullPath.length\n if (hashIndex >= 0) cut = Math.min(cut, hashIndex)\n if (queryIndex >= 0) cut = Math.min(cut, queryIndex)\n const pathname = fullPath.slice(0, cut) || '/'\n if (queryIndex < 0 || whitelist.length === 0) return pathname\n\n const params = new URLSearchParams(fullPath.slice(queryIndex, hashIndex >= 0 ? hashIndex : undefined))\n const filtered = new URLSearchParams()\n for (const key of whitelist) {\n if (params.has(key)) filtered.set(key, params.get(key)!)\n }\n const q = filtered.toString()\n return q ? `${pathname}?${q}` : pathname\n}\n\nfunction joinAbsolute(metaBaseUrl: string, siteBase: string | undefined, path: string): string {\n const origin = metaBaseUrl.replace(/\\/$/, '')\n const base = !siteBase || siteBase === '/' ? '' : siteBase.replace(/\\/$/, '')\n const p = path.startsWith('/') ? path : `/${path}`\n return `${origin}${base}${p}`\n}\n\n/**\n * Convert VitePress `pageData.relativePath` to a route path (cleanUrls-style).\n */\nexport function relativePathToRoutePath(relativePath: string): string {\n let path = relativePath.replace(/\\\\/g, '/')\n path = path.replace(/(^|\\/)index\\.md$/, '$1').replace(/\\.md$/, '')\n if (!path.startsWith('/')) path = `/${path}`\n if (path.length > 1 && path.endsWith('/')) path = path.slice(0, -1)\n return path || '/'\n}\n\n/**\n * Build i18n SEO head for VitePress — same tags as Nuxt `useLocaleHead` /\n * plugin `02.meta` (canonical, hreflang, x-default, og:locale / og:url / alternates).\n *\n * Framework-agnostic pure function; wired automatically by `withI18n` when `meta` is on.\n */\nexport function buildVitePressLocaleHead(options: BuildVitePressLocaleHeadOptions): VitePressLocaleHeadObject {\n const {\n locales,\n defaultLocale,\n localeKeyToCode = {},\n base,\n metaBaseUrl,\n hreflangBaseLanguage = false,\n canonicalQueryWhitelist = [],\n addDirAttribute = true,\n addSeoAttributes = true,\n identifierAttribute = 'id',\n missingWarn = true,\n } = options\n\n const path = stripSiteBase(options.path, base)\n const locale = getLocaleFromPath(\n path,\n locales.map((l) => l.code),\n defaultLocale,\n localeKeyToCode,\n undefined,\n )\n const currentLocale = locales.find((l) => l.code === locale)\n if (!currentLocale) {\n return { htmlAttrs: {}, head: [] }\n }\n\n const currentIso = currentLocale.iso || locale\n const currentDir = (currentLocale.dir || 'auto') as 'ltr' | 'rtl' | 'auto'\n const htmlAttrs: VitePressLocaleHeadObject['htmlAttrs'] = {\n lang: currentIso,\n ...(addDirAttribute ? { dir: currentDir } : {}),\n }\n\n if (!addSeoAttributes || !metaBaseUrl) {\n return { htmlAttrs, head: [] }\n }\n\n const switchLocalePath = createI18nRoutingFromAdapter({\n defaultLocale,\n localeCodes: locales.map((l) => l.code),\n localeKeyToCode,\n base,\n })\n\n const filteredPath = filterQuery(path, canonicalQueryWhitelist)\n // VitePress locale keys for i18nRouting: root vs code\n const currentVpKey =\n locale === defaultLocale\n ? 'root'\n : (() => {\n for (const [key, code] of Object.entries(localeKeyToCode)) {\n if (code === locale) return key === 'root' ? 'root' : key\n }\n return locale\n })()\n const canonicalPath = switchLocalePath({}, { path: filteredPath }, currentVpKey)\n const ogUrl = joinAbsolute(metaBaseUrl, base, canonicalPath)\n\n const localesForSeo = locales.filter((loc) => !loc.disabled && loc.seo !== false)\n const currentOg = resolveOgLocale(currentLocale)\n if (!currentOg) {\n warnUnresolvedOgLocale(currentLocale, { missingWarn, tag: 'og:locale' })\n }\n\n const head: VitePressHeadTuple[] = []\n\n head.push(['link', { [identifierAttribute]: 'i18n-can', rel: 'canonical', href: ogUrl }])\n\n if (currentOg) {\n head.push(['meta', { [identifierAttribute]: 'i18n-og', property: 'og:locale', content: currentOg }])\n }\n head.push(['meta', { [identifierAttribute]: 'i18n-og-url', property: 'og:url', content: ogUrl }])\n\n for (const loc of localesForSeo) {\n if (loc.code === locale) continue\n const ogAlt = resolveOgLocale(loc)\n if (!ogAlt) {\n warnUnresolvedOgLocale(loc, { missingWarn, tag: 'og:locale:alternate' })\n continue\n }\n head.push(['meta', { [identifierAttribute]: `i18n-og-alt-${ogAlt}`, property: 'og:locale:alternate', content: ogAlt }])\n }\n\n const hrefByCode = new Map<string, string>()\n for (const loc of localesForSeo) {\n const vpKey =\n loc.code === defaultLocale\n ? 'root'\n : (() => {\n for (const [key, code] of Object.entries(localeKeyToCode)) {\n if (code === loc.code) return key === 'root' ? loc.code : key\n }\n return loc.code\n })()\n const switched = switchLocalePath({}, { path: filteredPath }, vpKey)\n if (!switched) continue\n hrefByCode.set(String(loc.code), joinAbsolute(metaBaseUrl, base, switched))\n }\n\n for (const { hreflang, localeCode } of resolveHreflangAlternates(localesForSeo, { hreflangBaseLanguage })) {\n const href = hrefByCode.get(localeCode)\n if (!href) continue\n head.push(['link', { [identifierAttribute]: `i18n-alternate-${hreflang}`, rel: 'alternate', href, hreflang }])\n }\n\n const defaultLocaleObj = locales.find((l) => l.code === defaultLocale)\n if (defaultLocaleObj && defaultLocaleObj.seo !== false) {\n const xHref = hrefByCode.get(defaultLocale)\n if (xHref) {\n head.push(['link', { [identifierAttribute]: 'i18n-xd', rel: 'alternate', href: xHref, hreflang: 'x-default' }])\n }\n }\n\n return { htmlAttrs, head }\n}\n","import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs'\nimport { join, relative, resolve, sep } from 'node:path'\nimport type { Translations } from '@i18n-micro/types'\nimport { storeLoadedTranslationFile, type TranslationFileBuckets } from '@i18n-micro/utils/parse-path'\n\n/** Sync FS walk for the Vite plugin — prefer `@i18n-micro/node` in scripts. */\nexport interface LoadMessagesOptions {\n translationDir: string\n rootDir?: string\n disablePageLocales?: boolean\n}\n\nexport type LoadedTranslations = TranslationFileBuckets<Translations>\n\nexport interface TranslationFileRef {\n relativePath: string\n absolutePath: string\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')) onFile(fullPath)\n }\n}\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\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)) return buckets\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 (parsed === null || typeof parsed !== 'object' || Array.isArray(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 storeLoadedTranslationFile(buckets, relativePath, parsed as Translations, disablePageLocales)\n } catch (error) {\n console.error(`[i18n-micro/vitepress] Failed to load ${relativePath}:`, error)\n }\n })\n\n return buckets\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 { CreateI18nOptions } from '../runtime/create'\nimport { buildVitePressLocaleHead, relativePathToRoutePath } from '../seo/locale-head'\nimport { listTranslationFiles, loadTranslationBuckets } from './load-messages'\nimport { createI18nRoutingFromAdapter } from '../router/i18n-routing'\n\nexport interface WithI18nOptions extends CreateI18nOptions {\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 * Inject `themeConfig.i18nRouting` from adapter options + `config.base`.\n * Set `false` to skip. Skipped automatically when `themeConfig.i18nRouting` is already set.\n * @default true\n */\n i18nRouting?: boolean\n /**\n * Emit i18n SEO tags via `transformHead` (canonical, hreflang, og:locale…) —\n * Nuxt `meta` / plugin `02.meta` analogue.\n * Absolute link tags require `metaBaseUrl`.\n * @default true when `metaBaseUrl` is set, otherwise false\n */\n meta?: boolean\n /**\n * Public origin without trailing slash (`https://example.com`).\n * Same role as Nuxt `metaBaseUrl`.\n */\n metaBaseUrl?: string\n /** Also emit bare-language hreflang from `iso` (Nuxt `hreflangBaseLanguage`). @default false */\n hreflangBaseLanguage?: boolean\n /** Query keys kept on canonical / alternate URLs. @default [] */\n canonicalQueryWhitelist?: string[]\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 base?: string\n locales?: Record<string, unknown>\n themeConfig?: Record<string, unknown> | null\n transformHead?: (...args: any[]) => any\n transformPageData?: (...args: any[]) => any\n vite?: {\n plugins?: Plugin[] | Plugin[][]\n ssr?: {\n noExternal?: string | true | Array<string | RegExp>\n [key: string]: unknown\n }\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 /** VitePress `site.base` (normalized, trailing slash preserved from config). */\n base?: 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(rootDir: string, translationDir: string, disablePageLocales: boolean): 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()].map(([locale, varName]) => ` ${JSON.stringify(locale)}: ${varName}`).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(messages: Record<string, Translations>, routeMessages: Record<string, Record<string, Translations>>): string {\n return [`export const messages = ${JSON.stringify(messages)}`, `export const routeMessages = ${JSON.stringify(routeMessages)}`, ''].join('\\n')\n}\n\nfunction createI18nVitePlugin(options: WithI18nOptions, siteBase?: string): 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 base: siteBase && siteBase !== '/' ? siteBase : undefined,\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-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: WithI18nOptions): 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 * VitePress config helper: virtual modules + optional `i18nRouting` / SEO head.\n *\n * Registers:\n * - `virtual:i18n-micro/config`\n * - `virtual:i18n-micro/messages` (from `translationDir`, default `locales/`)\n *\n * By default also sets `themeConfig.i18nRouting` (pass `i18nRouting: false` to skip).\n * Pair with `defineI18nTheme(DefaultTheme)` from `@i18n-micro/vitepress/theme`.\n * Import from `@i18n-micro/vitepress/config` (Node / config files only).\n */\nexport function withI18n<T extends VitePressUserConfigLike>(config: T, options: WithI18nOptions): T {\n warnLocaleMismatch(config, options)\n\n const siteBase = typeof config.base === 'string' ? config.base : undefined\n const existingPlugins = config.vite?.plugins\n const plugins = [...(Array.isArray(existingPlugins) ? existingPlugins.flat() : []), createI18nVitePlugin(options, siteBase)]\n\n const prevSsr = config.vite?.ssr\n const prevNoExternal = prevSsr?.noExternal\n const noExternalList = [\n '@i18n-micro/vitepress',\n ...(Array.isArray(prevNoExternal) ? prevNoExternal : prevNoExternal && prevNoExternal !== true ? [prevNoExternal] : []),\n ]\n\n const defaultLocale = options.defaultLocale || options.locale\n const localeCodes = (options.locales || []).map((l) => l.code)\n const prevTheme = (config.themeConfig && typeof config.themeConfig === 'object' ? config.themeConfig : {}) as Record<string, unknown>\n const shouldInjectRouting = options.i18nRouting !== false && prevTheme.i18nRouting === undefined && localeCodes.length > 0\n\n const metaEnabled = options.meta ?? Boolean(options.metaBaseUrl)\n const locales = options.locales || []\n const prevTransformHead = config.transformHead\n const prevTransformPageData = config.transformPageData\n\n const transformHead = metaEnabled\n ? async (ctx: {\n pageData?: { relativePath?: string; frontmatter?: { i18n?: { disableMeta?: boolean } } }\n siteConfig?: { site?: { base?: string } }\n siteData?: { base?: string }\n }) => {\n const prev = typeof prevTransformHead === 'function' ? await prevTransformHead(ctx) : []\n const prevHead = Array.isArray(prev) ? prev : []\n if (ctx.pageData?.frontmatter?.i18n?.disableMeta === true) return prevHead\n\n const relativePath = ctx.pageData?.relativePath || 'index.md'\n const siteBase = (typeof config.base === 'string' ? config.base : undefined) ?? ctx.siteData?.base ?? ctx.siteConfig?.site?.base\n const built = buildVitePressLocaleHead({\n path: relativePathToRoutePath(relativePath),\n locales,\n defaultLocale,\n localeKeyToCode: options.localeKeyToCode,\n base: siteBase,\n metaBaseUrl: options.metaBaseUrl,\n hreflangBaseLanguage: options.hreflangBaseLanguage,\n canonicalQueryWhitelist: options.canonicalQueryWhitelist,\n missingWarn: options.missingWarn,\n })\n return [...prevHead, ...built.head]\n }\n : prevTransformHead\n\n const transformPageData = metaEnabled\n ? async (\n pageData: {\n relativePath?: string\n frontmatter?: Record<string, unknown> & { i18n?: { disableMeta?: boolean } }\n },\n ctx?: unknown,\n ) => {\n if (typeof prevTransformPageData === 'function') {\n await prevTransformPageData(pageData, ctx)\n }\n if (pageData.frontmatter?.i18n?.disableMeta === true) return\n\n const built = buildVitePressLocaleHead({\n path: relativePathToRoutePath(pageData.relativePath || 'index.md'),\n locales,\n defaultLocale,\n localeKeyToCode: options.localeKeyToCode,\n base: typeof config.base === 'string' ? config.base : undefined,\n metaBaseUrl: options.metaBaseUrl,\n hreflangBaseLanguage: options.hreflangBaseLanguage,\n canonicalQueryWhitelist: options.canonicalQueryWhitelist,\n missingWarn: options.missingWarn,\n addSeoAttributes: false,\n })\n if (built.htmlAttrs.lang) {\n pageData.frontmatter ??= {}\n // VitePress uses frontmatter for per-page lang when set\n if (!pageData.frontmatter.lang) {\n pageData.frontmatter.lang = built.htmlAttrs.lang\n }\n }\n }\n : prevTransformPageData\n\n return {\n ...config,\n ...(shouldInjectRouting\n ? {\n themeConfig: {\n ...prevTheme,\n i18nRouting: createI18nRoutingFromAdapter({\n defaultLocale,\n localeCodes,\n localeKeyToCode: options.localeKeyToCode,\n base: siteBase,\n }),\n },\n }\n : {}),\n ...(metaEnabled\n ? {\n transformHead,\n transformPageData,\n }\n : {}),\n vite: {\n ...config.vite,\n plugins,\n // Theme entry statically imports `virtual:i18n-micro/*`; Vite must bundle\n // the package during SSG so those IDs resolve (not left as bare Node imports).\n ssr: {\n ...prevSsr,\n noExternal: prevNoExternal === true ? true : noExternalList,\n },\n },\n }\n}\n"],"names":["isAdapter","value","createI18nRoutingFromAdapter","adapterOrOptions","options","defaultLocale","localeCodes","localeKeyToCode","base","filterQuery","fullPath","whitelist","hashIndex","queryIndex","cut","pathname","params","filtered","key","q","joinAbsolute","metaBaseUrl","siteBase","path","origin","p","relativePathToRoutePath","relativePath","buildVitePressLocaleHead","locales","hreflangBaseLanguage","canonicalQueryWhitelist","addDirAttribute","addSeoAttributes","identifierAttribute","missingWarn","stripSiteBase","locale","getLocaleFromPath","currentLocale","currentIso","currentDir","htmlAttrs","switchLocalePath","filteredPath","currentVpKey","code","canonicalPath","ogUrl","localesForSeo","loc","currentOg","resolveOgLocale","warnUnresolvedOgLocale","head","ogAlt","hrefByCode","vpKey","switched","hreflang","localeCode","resolveHreflangAlternates","href","defaultLocaleObj","xHref","walkTranslationFiles","dir","onFile","existsSync","entry","readdirSync","join","statSync","listTranslationFiles","rootDir","resolve","files","relative","sep","a","b","loadTranslationBuckets","buckets","disablePageLocales","parsed","readFileSync","storeLoadedTranslationFile","error","VIRTUAL_CONFIG_ID","RESOLVED_CONFIG_ID","VIRTUAL_MESSAGES_ID","RESOLVED_MESSAGES_ID","toPosix","generateImportMessagesModule","translationDir","imports","rootEntries","routeVarNames","file","classifyTranslationRelativePath","varName","byLocale","routeEntries","routeName","localeEntries","generateInlineMessagesModule","messages","routeMessages","createI18nVitePlugin","configData","l","useInline","inlineRoot","inlineRoutes","debounceTimer","needsDiskReload","reloadInlineFromDisk","loaded","config","server","invalidate","mod","id","warnLocaleMismatch","vpLocales","vpKeys","codes","expectedCode","withI18n","existingPlugins","plugins","prevSsr","prevNoExternal","noExternalList","prevTheme","shouldInjectRouting","metaEnabled","prevTransformHead","prevTransformPageData","transformHead","ctx","prev","prevHead","built","transformPageData","pageData"],"mappings":"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"}
|