@i18n-micro/vitepress 1.1.13 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +13 -91
  3. package/dist/adapter-BbqZKi2F.cjs +2 -0
  4. package/dist/adapter-BbqZKi2F.cjs.map +1 -0
  5. package/dist/adapter-DTS0CTC7.js +131 -0
  6. package/dist/adapter-DTS0CTC7.js.map +1 -0
  7. package/dist/config.cjs +6 -6
  8. package/dist/config.cjs.map +1 -1
  9. package/dist/config.d.cts +7 -0
  10. package/dist/config.d.ts +7 -0
  11. package/dist/config.mjs +129 -220
  12. package/dist/config.mjs.map +1 -1
  13. package/dist/create-Bo6VND8l.js +87 -0
  14. package/dist/create-Bo6VND8l.js.map +1 -0
  15. package/dist/create-Dn1m6fyc.cjs +2 -0
  16. package/dist/create-Dn1m6fyc.cjs.map +1 -0
  17. package/dist/index.cjs +1 -1
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +8 -0
  20. package/dist/index.d.ts +8 -0
  21. package/dist/index.mjs +6 -7
  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.mjs +3 -4
  26. package/dist/theme.cjs +1 -1
  27. package/dist/theme.cjs.map +1 -1
  28. package/dist/theme.d.cts +42 -1
  29. package/dist/theme.d.ts +42 -1
  30. package/dist/theme.mjs +9 -7
  31. package/dist/theme.mjs.map +1 -1
  32. package/dist/vitepress-locales-CwOlvAa0.cjs.map +1 -1
  33. package/dist/{vitepress-locales-DOhKs3q5.js → vitepress-locales-DYuP6i_x.js} +2 -3
  34. package/dist/{vitepress-locales-DOhKs3q5.js.map → vitepress-locales-DYuP6i_x.js.map} +1 -1
  35. package/package.json +24 -13
  36. package/dist/adapter-CAJNI6Sw.js +0 -127
  37. package/dist/adapter-CAJNI6Sw.js.map +0 -1
  38. package/dist/adapter-eYZZOC9d.cjs +0 -2
  39. package/dist/adapter-eYZZOC9d.cjs.map +0 -1
  40. package/dist/create-C_dXg23X.js +0 -81
  41. package/dist/create-C_dXg23X.js.map +0 -1
  42. package/dist/create-Cwu2djcO.cjs +0 -2
  43. package/dist/create-Cwu2djcO.cjs.map +0 -1
  44. package/dist/plugin/virtual-stubs/config.d.cts +0 -14
  45. package/dist/runtime/define-theme.d.cts +0 -39
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2016
3
+ Copyright (c) 2024 s00d
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,107 +1,29 @@
1
- # `@i18n-micro/vitepress`
1
+ # @i18n-micro/vitepress
2
2
 
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.
3
+ VitePress bindings for Nuxt I18n Micro: runtime dictionaries, `$t` and `<I18nT>` in markdown, locale sync with VitePress path locales, path helpers and SEO tags. Built on `@i18n-micro/vue`.
4
4
 
5
- ## Entries
6
-
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) |
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`.
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 })
36
- ```
37
-
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
68
-
69
- ```ts
70
- import { defineConfig } from 'vitepress'
71
- import { withI18n, buildVitePressLocales } from '@i18n-micro/vitepress/config'
72
-
73
- const locales = [
74
- { code: 'en', iso: 'en-US', displayName: 'English', og: 'en_US' },
75
- { code: 'fr', iso: 'fr-FR', displayName: 'Français', og: 'fr_FR' },
76
- ]
77
- const defaultLocale = 'en'
78
-
79
- export default defineConfig(
80
- withI18n(
81
- { locales: buildVitePressLocales(locales, defaultLocale) },
82
- {
83
- locale: defaultLocale,
84
- defaultLocale,
85
- locales,
86
- translationDir: 'locales',
87
- metaBaseUrl: 'https://example.com',
88
- },
89
- ),
90
- )
5
+ ```bash
6
+ pnpm add @i18n-micro/vitepress
91
7
  ```
92
8
 
93
- `withI18n` injects `themeConfig.i18nRouting` automatically.
9
+ Peers: `vitepress` `>=1.0.0 || >=2.0.0-alpha.0`, `vue` `^3.3.0`. `check:oldest` runs VitePress 1.0.0, which brings its own Vue (`^3.4.21`), so Vue 3.3 itself is not tested here. The published types need Vue 3.5.5 or later with `skipLibCheck: false`; with `skipLibCheck: true`, the usual template setting, older versions compile too.
94
10
 
95
- ### Theme
11
+ | Import | Role |
12
+ | ------------------------------ | --------------------------------------------- |
13
+ | `@i18n-micro/vitepress/config` | `withI18n`, `buildVitePressLocales`, SEO head |
14
+ | `@i18n-micro/vitepress/theme` | `defineI18nTheme(DefaultTheme)` |
15
+ | `@i18n-micro/vitepress` | client `createI18n`, `useI18n`, components |
16
+ | `@i18n-micro/vitepress/node` | Node `createI18n` with path methods |
96
17
 
97
18
  ```ts
19
+ // .vitepress/theme/index.ts
98
20
  import DefaultTheme from 'vitepress/theme'
99
21
  import { defineI18nTheme } from '@i18n-micro/vitepress/theme'
100
22
 
101
23
  export default defineI18nTheme(DefaultTheme)
102
24
  ```
103
25
 
104
- In pages: `useI18n().localePath` / `switchLocale`, or `$t` / `<I18nT>`.
26
+ Docs: [https://s00d.github.io/nuxt-i18n-micro/integrations/vitepress-package](https://s00d.github.io/nuxt-i18n-micro/integrations/vitepress-package) · Repository: [github.com/s00d/nuxt-i18n-micro](https://github.com/s00d/nuxt-i18n-micro)
105
27
 
106
28
  ## License
107
29
 
@@ -0,0 +1,2 @@
1
+ let e=require("@i18n-micro/core"),t=require("@i18n-micro/utils/locale-head"),n=require("vue");function r(e){let t=e.indexOf(`#`),n=e.indexOf(`?`),r=e.length;return t>=0&&(r=Math.min(r,t)),n>=0&&(r=Math.min(r,n)),{pathname:e.slice(0,r)||`/`,extras:e.slice(r)}}function i(e,t){if(!t||t===`/`)return e;let n=t.endsWith(`/`)?t.slice(0,-1):t;if(!n)return e;let{pathname:i,extras:a}=r(e);return i===n?`/${a}`:i.startsWith(`${n}/`)?`${i.slice(n.length)||`/`}${a}`:e}function a(e,t,n={}){let r=e=>{for(let[t,r]of Object.entries(n))if(r===e)return t;return e===t?`root`:e},i=new Map;for(let n of e){if(n===t)continue;let e=r(n),a=e===`root`?n:e;i.set(a,n),a!==n&&i.set(n,n)}return i}function o(e,t,n,o={},s){let{pathname:c}=r(i(e,s)),l=c.split(`/`).filter(Boolean)[0];return l===void 0?n:a(t,n,o).get(l)??n}function s(e,t,n,o={},s){let{pathname:c}=r(i(e,s)),l=c.split(`/`).filter(Boolean),u=l[0];if(u!==void 0&&(n===void 0?t.includes(u)&&l.shift():a(t,n,o).has(u)&&l.shift()),l.length===0)return`index`;let d=l.join(`-`);return d.endsWith(`.html`)?d.slice(0,-5):d}function c(t,r){return(0,n.defineComponent)({name:`VitePressI18nLink`,props:{to:{type:String,required:!0},style:{type:Object,default:void 0}},setup(i,{slots:a}){return()=>{let o=t(i.to);return(0,n.h)(`a`,{href:o,style:i.style,onClick:t=>{(0,e.isPlainClick)(t)&&(t.preventDefault(),r?r(o):typeof window<`u`&&window.location.assign(o))}},a.default?.())}}})}function l(n){let{locales:l,defaultLocale:u,localeKeyToCode:d={},base:f,getPath:p,go:m}=n,h=l.map(e=>e.code),g={...d},_=a(h,u,g),v=[..._.keys()],y=f&&f!==`/`?f:void 0,b=e=>y?(0,t.joinBase)(y,e):e,x=e=>g[e]?g[e]:e===`root`?u:e,S=e=>{for(let[t,n]of Object.entries(g))if(n===e)return t;return e===u?`root`:e},C=e=>{if(e===u)return null;let t=S(e);return t===`root`?e:t},w=t=>{let n=t===`/`||t.endsWith(`/`),r=(0,e.pathSegments)(t),i=r[0];return i!==void 0&&_.has(i)&&r.shift(),{segments:r,hadTrailingSlash:n}},T=e=>{let{pathname:t,extras:n}=r(i(e,y)),{segments:a,hadTrailingSlash:o}=w(t),s=a.length===0?`/`:`/${a.join(`/`)}`;return s!==`/`&&o&&(s+=`/`),`${s}${n}`},E=(e,t)=>{let{pathname:n,extras:a}=r(i(e,y)),{segments:o,hadTrailingSlash:s}=w(n),c=C(t);c&&o.unshift(c);let l=o.length===0?`/`:`/${o.join(`/`)}`;return l!==`/`&&s&&(l+=`/`),`${l}${a}`},D=(e,t)=>E(e,t),O=(e,n)=>{let r=typeof e==`string`?e:`${e.path||`/`}${(0,t.queryString)(e.query)}${e.hash??``}`;return E(r,n)},k=(e,t=!1)=>{let n=b(e);m?m(n,{replace:t}):typeof window<`u`&&(t?window.location.replace(n):window.location.assign(n))},A=()=>p?p():typeof window<`u`?window.location.pathname+window.location.search+window.location.hash:`/`;return{localeCodes:h,defaultLocale:u,localeKeyToCode:g,urlPrefixes:v,base:y,codeFromLocaleKey:x,localeKeyFromCode:S,getLocaleFromPath:e=>o(e,h,u,g,y),switchLocalePath:D,localizePath:E,removeLocaleFromPath:T,routeNameFromPath:e=>s(e,h,u,g,y),linkComponent:c(b,m),toHref:b,getCurrentPath:()=>i(A(),y),push:e=>{k(e.path,!1)},replace:e=>{k(e.path,!0)},resolvePath:O,getRoute:()=>{let e=i(A(),y),t=typeof window<`u`?new URL(e,window.location.origin):new URL(e,`http://localhost`);return{fullPath:t.pathname+t.search+t.hash,query:Object.fromEntries(t.searchParams)}}}}Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return l}});
2
+ //# sourceMappingURL=adapter-BbqZKi2F.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-BbqZKi2F.cjs","names":["defineComponent","h","isPlainClick","joinBase","pathSegments","queryString","_i18n_micro_core","_i18n_micro_utils_locale_head","vue","splitPathAndExtras","hashIndex","path","queryIndex","cut","stripSiteBase","base","normalized","pathname","extras","buildUrlPrefixToCode","keyFromCode","key","mapped","localeKeyToCode","code","defaultLocale","prefixToCode","localeCodes","urlKey","getLocaleFromPath","first","routeNameFromPath","segments","name","createVitePressLinkComponent","href","toHref","props","e","go","slots","createVitePressRouterAdapter","options","locales","loc","localeKeyToCodeSnapshot","urlPrefixes","siteBase","codeFromLocaleKey","localeKey","localeKeyFromCode","urlPrefixForCode","stripPrefix","hadTrailingSlash","removeLocaleFromPath","clean","localizePath","prefix","locale","localized","switchLocalePath","newLocale","resolvePath","to","navigate","replace","currentFullPath","getPath","target","url"],"sources":["../src/router/adapter.ts"],"sourcesContent":["import { isPlainClick, pathSegments } from '@i18n-micro/core'\nimport type { Locale } from '@i18n-micro/types'\nimport type { I18nRoutingStrategy, I18nRouteTarget } from '@i18n-micro/vue'\nimport { joinBase, queryString } from '@i18n-micro/utils/locale-head'\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 /** The only name VitePress calls before 1.6. */\n onAfterRouteChanged?: (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 const name = segments.join('-')\n return name.endsWith('.html') ? name.slice(0, -5) : name\n}\n\nfunction createVitePressLinkComponent(toHref: (path: string) => string, 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 const href = toHref(props.to)\n return h(\n 'a',\n {\n href,\n style: props.style,\n onClick: (e: MouseEvent) => {\n if (!isPlainClick(e)) return\n e.preventDefault()\n if (go) {\n void go(href)\n } else if (typeof window !== 'undefined') {\n window.location.assign(href)\n }\n },\n },\n slots.default?.(),\n )\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 /** Our paths are relative to the site base; VitePress `go` and the address bar are not. */\n const toHref = (path: string): string => (siteBase ? joinBase(siteBase, path) : path)\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 = pathSegments(pathname)\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: I18nRouteTarget, locale: string): string => {\n const path = typeof to === 'string' ? to : `${to.path || '/'}${queryString(to.query)}${to.hash ?? ''}`\n return localizePath(path, locale)\n }\n\n const navigate = (path: string, replace = false) => {\n const href = toHref(path)\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(toHref, go),\n toHref,\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"],"mappings":"A,8FAkEA,SAASS,EAAmB,EAAoD,CAC9E,IAAMC,EAAYC,EAAK,QAAQ,GAAG,EAC5BC,EAAaD,EAAK,QAAQ,GAAG,EAC/BE,EAAMF,EAAK,OAGf,OAFID,GAAa,IAAG,EAAM,KAAK,IAAIG,EAAKH,CAAS,GAC7CE,GAAc,IAAG,EAAM,KAAK,IAAIC,EAAKD,CAAU,GAC5C,CACL,SAAUD,EAAK,MAAM,EAAGE,CAAG,GAAK,IAChC,OAAQF,EAAK,MAAME,CAAG,CACxB,CACF,CAMA,SAAgBC,EAAc,EAAc,EAAuB,CACjE,GAAI,CAACC,GAAQA,IAAS,IAAK,OAAOJ,EAClC,IAAMK,EAAaD,EAAK,SAAS,GAAG,EAAIA,EAAK,MAAM,EAAG,EAAE,EAAIA,EAC5D,GAAI,CAACC,EAAY,OAAOL,EACxB,GAAM,CAAE,WAAU,UAAWF,EAAmBE,CAAI,EAKpD,OAJIM,IAAaD,EAAmB,IAAIE,IACpCD,EAAS,WAAW,GAAGD,EAAW,EAAE,EAC/B,GAAGC,EAAS,MAAMD,EAAW,MAAM,GAAK,MAAME,IAEhDP,CACT,CAMA,SAAgBQ,EACd,EACA,EACA,EAA0C,CAAC,EACtB,CACrB,IAAMC,EAAe,GAAyB,CAC5C,IAAK,GAAM,CAACC,EAAKC,KAAW,OAAO,QAAQC,CAAe,EACxD,GAAID,IAAWE,EAAM,OAAOH,EAG9B,OADIG,IAASC,EAAsB,OAC5BD,CACT,EAEME,EAAe,IAAI,IACzB,IAAK,IAAMF,KAAQG,EAAa,CAC9B,GAAIH,IAASC,EAAe,SAC5B,IAAMJ,EAAMD,EAAYI,CAAI,EACtBI,EAASP,IAAQ,OAASG,EAAOH,EACvCK,EAAa,IAAIE,EAAQJ,CAAI,EACzBI,IAAWJ,GAAME,EAAa,IAAIF,EAAMA,CAAI,CAClD,CACA,OAAOE,CACT,CAOA,SAAgBG,EACd,EACA,EACA,EACA,EAA0C,CAAC,EAC3C,EACQ,CACR,GAAM,CAAE,YAAapB,EAAmBK,EAAcH,EAAMI,CAAI,CAAC,EAC3De,EAAQb,EAAS,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,GAGlD,OAFIa,IAAU,IAAA,GAAkBL,EACXN,EAAqBQ,EAAaF,EAAeF,CAC/D,CAAA,CAAa,IAAIO,CAAK,GAAKL,CACpC,CASA,SAAgBM,EACd,EACA,EACA,EACA,EAA0C,CAAC,EAC3C,EACQ,CACR,GAAM,CAAE,YAAatB,EAAmBK,EAAcH,EAAMI,CAAI,CAAC,EAC3DiB,EAAWf,EAAS,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO,EAC7Ca,EAAQE,EAAS,GASvB,GARIF,IAAU,IAAA,KACRL,IAAkB,IAAA,GAGXE,EAAY,SAASG,CAAK,GACnCE,EAAS,MAAM,EAHMb,EAAqBQ,EAAaF,EAAeF,CAClE,CAAA,CAAa,IAAIO,CAAK,GAAGE,EAAS,MAAM,GAK5CA,EAAS,SAAW,EAAG,MAAO,QAClC,IAAMC,EAAOD,EAAS,KAAK,GAAG,EAC9B,OAAOC,EAAK,SAAS,OAAO,EAAIA,EAAK,MAAM,EAAG,EAAE,EAAIA,CACtD,CAEA,SAASC,EAA6B,EAAkC,EAA6B,CACnG,OAAA,EAAOlC,EAAAA,gBAAAA,CAAgB,CACrB,KAAM,oBACN,MAAO,CACL,GAAI,CAAE,KAAM,OAAQ,SAAU,EAAK,EACnC,MAAO,CAAE,KAAM,OAA4C,QAAS,IAAA,EAAU,CAChF,EACA,MAAM,EAAO,CAAE,SAAS,CACtB,UAAa,CACX,IAAMmC,EAAOC,EAAOC,EAAM,EAAE,EAC5B,OAAA,EAAOpC,EAAAA,EAAAA,CACL,IACA,CACE,OACA,MAAOoC,EAAM,MACb,QAAU,GAAkB,EACtB,EAACnC,EAAAA,aAAAA,CAAaoC,CAAC,IACnBA,EAAE,eAAe,EACbC,EACFA,EAAQJ,CAAI,EACH,OAAO,OAAW,KAC3B,OAAO,SAAS,OAAOA,CAAI,EAE/B,CACF,EACAK,EAAM,UAAU,CAClB,CACF,CACF,CACF,CAAC,CACH,CAOA,SAAgBC,EAA6B,EAAgE,CAC3G,GAAM,CAAE,UAAS,gBAAe,kBAAkB,CAAC,EAAG,OAAM,UAAS,MAAOC,EACtEf,EAAcgB,EAAQ,IAAK,GAAQC,EAAI,IAAI,EAC3CC,EAA0B,CAAE,GAAGtB,CAAgB,EAC/CG,EAAeP,EAAqBQ,EAAaF,EAAeoB,CAAuB,EACvFC,EAAc,CAAC,GAAGpB,EAAa,KAAK,CAAC,EACrCqB,EAAWhC,GAAQA,IAAS,IAAMA,EAAO,IAAA,GAEzCqB,EAAU,GAA0BW,GAAA,EAAW5C,EAAAA,SAAAA,CAAS4C,EAAUpC,CAAI,EAAIA,EAE1EqC,EAAqB,GACrBH,EAAwBI,GAAmBJ,EAAwBI,GACnEA,IAAc,OAAexB,EAC1BwB,EAGHC,EAAqB,GAAyB,CAClD,IAAK,GAAM,CAAC7B,EAAKC,KAAW,OAAO,QAAQuB,CAAuB,EAChE,GAAIvB,IAAWE,EAAM,OAAOH,EAG9B,OADIG,IAASC,EAAsB,OAC5BD,CACT,EAEM2B,EAAoB,GAAgC,CACxD,GAAI3B,IAASC,EAAe,OAAO,KACnC,IAAMJ,EAAM6B,EAAkB1B,CAAI,EAClC,OAAOH,IAAQ,OAASG,EAAOH,CACjC,EAEM+B,EAAe,GAAwE,CAC3F,IAAMC,EAAmBpC,IAAa,KAAOA,EAAS,SAAS,GAAG,EAC5De,GAAA,EAAW5B,EAAAA,aAAAA,CAAaa,CAAQ,EAChCa,EAAQE,EAAS,GAIvB,OAHIF,IAAU,IAAA,IAAaJ,EAAa,IAAII,CAAK,GAC/CE,EAAS,MAAM,EAEV,CAAE,WAAU,kBAAiB,CACtC,EAEMsB,EAAwB,GAAyB,CACrD,GAAM,CAAE,WAAU,UAAW7C,EAAmBK,EAAcH,EAAMoC,CAAQ,CAAC,EACvE,CAAE,WAAU,oBAAqBK,EAAYnC,CAAQ,EACvDsC,EAAQvB,EAAS,SAAW,EAAI,IAAM,IAAIA,EAAS,KAAK,GAAG,IAE/D,OADIuB,IAAU,KAAOF,IAAkB,GAAS,KACzC,GAAGE,IAAQrC,GACpB,EAEMsC,GAAgB,EAAc,IAA2B,CAC7D,GAAM,CAAE,WAAU,UAAW/C,EAAmBK,EAAcH,EAAMoC,CAAQ,CAAC,EACvE,CAAE,WAAU,oBAAqBK,EAAYnC,CAAQ,EACrDwC,EAASN,EAAiBO,CAAM,EAClCD,GAAQzB,EAAS,QAAQyB,CAAM,EACnC,IAAIE,EAAY3B,EAAS,SAAW,EAAI,IAAM,IAAIA,EAAS,KAAK,GAAG,IAEnE,OADI2B,IAAc,KAAON,IAAkB,GAAa,KACjD,GAAGM,IAAYzC,GACxB,EAEM0C,GAAoB,EAAc,IAC/BJ,EAAa7C,EAAMkD,CAAS,EAG/BC,GAAe,EAAqB,IAA2B,CACnE,IAAMnD,EAAO,OAAOoD,GAAO,SAAWA,EAAK,GAAGA,EAAG,MAAQ,OAAA,EAAM1D,EAAAA,YAAAA,CAAY0D,EAAG,KAAK,IAAIA,EAAG,MAAQ,KAClG,OAAOP,EAAa7C,EAAM+C,CAAM,CAClC,EAEMM,GAAY,EAAc,EAAU,KAAU,CAClD,IAAM7B,EAAOC,EAAOzB,CAAI,EACpB4B,EACFA,EAAQJ,EAAM,CAAE,SAAQ,CAAC,EAGvB,OAAO,OAAW,MAChB8B,EACF,OAAO,SAAS,QAAQ9B,CAAI,EAE5B,OAAO,SAAS,OAAOA,CAAI,EAGjC,EAEM+B,MACAC,EAAgBA,EAAQ,EACxB,OAAO,OAAW,IACb,OAAO,SAAS,SAAW,OAAO,SAAS,OAAS,OAAO,SAAS,KAEtE,IAGT,MAAO,CACL,cACA,gBACA,gBAAiBtB,EACjB,cACA,KAAME,EACN,oBACA,oBACA,kBAAoB,GAAiBlB,EAAkBlB,EAAMgB,EAAaF,EAAeoB,EAAyBE,CAAQ,EAC1H,mBACA,eACA,uBACA,kBAAoB,GAAiBhB,EAAkBpB,EAAMgB,EAAaF,EAAeoB,EAAyBE,CAAQ,EAC1H,cAAeb,EAA6BE,EAAQG,CAAE,EACtD,SACA,mBAAsBzB,EAAcoD,EAAgB,EAAGnB,CAAQ,EAC/D,KAAO,GAA6B,CAClCiB,EAASI,EAAO,KAAM,EAAK,CAC7B,EACA,QAAU,GAA6B,CACrCJ,EAASI,EAAO,KAAM,EAAI,CAC5B,EACA,cACA,aAAgB,CACd,IAAMzD,EAAOG,EAAcoD,EAAgB,EAAGnB,CAAQ,EAChDsB,EAAM,OAAO,OAAW,IAAc,IAAI,IAAI1D,EAAM,OAAO,SAAS,MAAM,EAAI,IAAI,IAAIA,EAAM,kBAAkB,EACpH,MAAO,CACL,SAAU0D,EAAI,SAAWA,EAAI,OAASA,EAAI,KAC1C,MAAO,OAAO,YAAYA,EAAI,YAAY,CAC5C,CACF,CACF,CACF,C"}
@@ -0,0 +1,131 @@
1
+ import { isPlainClick as e, pathSegments as t } from "@i18n-micro/core";
2
+ import { joinBase as n, queryString as r } from "@i18n-micro/utils/locale-head";
3
+ import { defineComponent as i, h as a } from "vue";
4
+ // src/router/adapter.ts
5
+ function o(e) {
6
+ let t = e.indexOf("#"), n = e.indexOf("?"), r = e.length;
7
+ return t >= 0 && (r = Math.min(r, t)), n >= 0 && (r = Math.min(r, n)), {
8
+ pathname: e.slice(0, r) || "/",
9
+ extras: e.slice(r)
10
+ };
11
+ }
12
+ function s(e, t) {
13
+ if (!t || t === "/") return e;
14
+ let n = t.endsWith("/") ? t.slice(0, -1) : t;
15
+ if (!n) return e;
16
+ let { pathname: r, extras: i } = o(e);
17
+ return r === n ? `/${i}` : r.startsWith(`${n}/`) ? `${r.slice(n.length) || "/"}${i}` : e;
18
+ }
19
+ function c(e, t, n = {}) {
20
+ let r = (e) => {
21
+ for (let [t, r] of Object.entries(n)) if (r === e) return t;
22
+ return e === t ? "root" : e;
23
+ }, i = /* @__PURE__ */ new Map();
24
+ for (let n of e) {
25
+ if (n === t) continue;
26
+ let e = r(n), a = e === "root" ? n : e;
27
+ i.set(a, n), a !== n && i.set(n, n);
28
+ }
29
+ return i;
30
+ }
31
+ function l(e, t, n, r = {}, i) {
32
+ let { pathname: a } = o(s(e, i)), l = a.split("/").filter(Boolean)[0];
33
+ return l === void 0 ? n : c(t, n, r).get(l) ?? n;
34
+ }
35
+ function u(e, t, n, r = {}, i) {
36
+ let { pathname: a } = o(s(e, i)), l = a.split("/").filter(Boolean), u = l[0];
37
+ if (u !== void 0 && (n === void 0 ? t.includes(u) && l.shift() : c(t, n, r).has(u) && l.shift()), l.length === 0) return "index";
38
+ let d = l.join("-");
39
+ return d.endsWith(".html") ? d.slice(0, -5) : d;
40
+ }
41
+ function d(t, n) {
42
+ return i({
43
+ name: "VitePressI18nLink",
44
+ props: {
45
+ to: {
46
+ type: String,
47
+ required: !0
48
+ },
49
+ style: {
50
+ type: Object,
51
+ default: void 0
52
+ }
53
+ },
54
+ setup(r, { slots: i }) {
55
+ return () => {
56
+ let o = t(r.to);
57
+ return a("a", {
58
+ href: o,
59
+ style: r.style,
60
+ onClick: (t) => {
61
+ e(t) && (t.preventDefault(), n ? n(o) : typeof window < "u" && window.location.assign(o));
62
+ }
63
+ }, i.default?.());
64
+ };
65
+ }
66
+ });
67
+ }
68
+ function f(e) {
69
+ let { locales: i, defaultLocale: a, localeKeyToCode: f = {}, base: p, getPath: m, go: h } = e, g = i.map((e) => e.code), _ = { ...f }, v = c(g, a, _), y = [...v.keys()], b = p && p !== "/" ? p : void 0, x = (e) => b ? n(b, e) : e, S = (e) => _[e] ? _[e] : e === "root" ? a : e, C = (e) => {
70
+ for (let [t, n] of Object.entries(_)) if (n === e) return t;
71
+ return e === a ? "root" : e;
72
+ }, w = (e) => {
73
+ if (e === a) return null;
74
+ let t = C(e);
75
+ return t === "root" ? e : t;
76
+ }, T = (e) => {
77
+ let n = e === "/" || e.endsWith("/"), r = t(e), i = r[0];
78
+ return i !== void 0 && v.has(i) && r.shift(), {
79
+ segments: r,
80
+ hadTrailingSlash: n
81
+ };
82
+ }, E = (e) => {
83
+ let { pathname: t, extras: n } = o(s(e, b)), { segments: r, hadTrailingSlash: i } = T(t), a = r.length === 0 ? "/" : `/${r.join("/")}`;
84
+ return a !== "/" && i && (a += "/"), `${a}${n}`;
85
+ }, D = (e, t) => {
86
+ let { pathname: n, extras: r } = o(s(e, b)), { segments: i, hadTrailingSlash: a } = T(n), c = w(t);
87
+ c && i.unshift(c);
88
+ let l = i.length === 0 ? "/" : `/${i.join("/")}`;
89
+ return l !== "/" && a && (l += "/"), `${l}${r}`;
90
+ }, O = (e, t) => D(e, t), k = (e, t) => {
91
+ let n = typeof e == "string" ? e : `${e.path || "/"}${r(e.query)}${e.hash ?? ""}`;
92
+ return D(n, t);
93
+ }, A = (e, t = !1) => {
94
+ let n = x(e);
95
+ h ? h(n, { replace: t }) : typeof window < "u" && (t ? window.location.replace(n) : window.location.assign(n));
96
+ }, j = () => m ? m() : typeof window < "u" ? window.location.pathname + window.location.search + window.location.hash : "/";
97
+ return {
98
+ localeCodes: g,
99
+ defaultLocale: a,
100
+ localeKeyToCode: _,
101
+ urlPrefixes: y,
102
+ base: b,
103
+ codeFromLocaleKey: S,
104
+ localeKeyFromCode: C,
105
+ getLocaleFromPath: (e) => l(e, g, a, _, b),
106
+ switchLocalePath: O,
107
+ localizePath: D,
108
+ removeLocaleFromPath: E,
109
+ routeNameFromPath: (e) => u(e, g, a, _, b),
110
+ linkComponent: d(x, h),
111
+ toHref: x,
112
+ getCurrentPath: () => s(j(), b),
113
+ push: (e) => {
114
+ A(e.path, !1);
115
+ },
116
+ replace: (e) => {
117
+ A(e.path, !0);
118
+ },
119
+ resolvePath: k,
120
+ getRoute: () => {
121
+ let e = s(j(), b), t = typeof window < "u" ? new URL(e, window.location.origin) : new URL(e, "http://localhost");
122
+ return {
123
+ fullPath: t.pathname + t.search + t.hash,
124
+ query: Object.fromEntries(t.searchParams)
125
+ };
126
+ }
127
+ };
128
+ }
129
+ export { s as i, l as n, u as r, f as t };
130
+
131
+ //# sourceMappingURL=adapter-DTS0CTC7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-DTS0CTC7.js","names":["splitPathAndExtras","hashIndex","path","queryIndex","cut","stripSiteBase","base","normalized","pathname","extras","buildUrlPrefixToCode","keyFromCode","key","mapped","localeKeyToCode","code","defaultLocale","prefixToCode","localeCodes","urlKey","getLocaleFromPath","first","routeNameFromPath","segments","name","createVitePressLinkComponent","defineComponent","href","toHref","props","h","isPlainClick","e","go","slots","createVitePressRouterAdapter","options","locales","loc","localeKeyToCodeSnapshot","urlPrefixes","siteBase","joinBase","codeFromLocaleKey","localeKey","localeKeyFromCode","urlPrefixForCode","stripPrefix","hadTrailingSlash","pathSegments","removeLocaleFromPath","clean","localizePath","prefix","locale","localized","switchLocalePath","newLocale","resolvePath","to","queryString","navigate","replace","currentFullPath","getPath","target","url"],"sources":["../src/router/adapter.ts"],"sourcesContent":["import { isPlainClick, pathSegments } from '@i18n-micro/core'\nimport type { Locale } from '@i18n-micro/types'\nimport type { I18nRoutingStrategy, I18nRouteTarget } from '@i18n-micro/vue'\nimport { joinBase, queryString } from '@i18n-micro/utils/locale-head'\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 /** The only name VitePress calls before 1.6. */\n onAfterRouteChanged?: (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 const name = segments.join('-')\n return name.endsWith('.html') ? name.slice(0, -5) : name\n}\n\nfunction createVitePressLinkComponent(toHref: (path: string) => string, 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 const href = toHref(props.to)\n return h(\n 'a',\n {\n href,\n style: props.style,\n onClick: (e: MouseEvent) => {\n if (!isPlainClick(e)) return\n e.preventDefault()\n if (go) {\n void go(href)\n } else if (typeof window !== 'undefined') {\n window.location.assign(href)\n }\n },\n },\n slots.default?.(),\n )\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 /** Our paths are relative to the site base; VitePress `go` and the address bar are not. */\n const toHref = (path: string): string => (siteBase ? joinBase(siteBase, path) : path)\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 = pathSegments(pathname)\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: I18nRouteTarget, locale: string): string => {\n const path = typeof to === 'string' ? to : `${to.path || '/'}${queryString(to.query)}${to.hash ?? ''}`\n return localizePath(path, locale)\n }\n\n const navigate = (path: string, replace = false) => {\n const href = toHref(path)\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(toHref, go),\n toHref,\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"],"mappings":"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"}
package/dist/config.cjs CHANGED
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./adapter-eYZZOC9d.cjs"),t=require("./vitepress-locales-CwOlvAa0.cjs");let n=require("@i18n-micro/utils/parse-path"),r=require("node:fs"),i=require("node:path"),a=require("@i18n-micro/utils/resolve-hreflang"),o=require("@i18n-micro/utils/resolve-og-locale");function s(e){return`switchLocalePath`in e&&typeof e.switchLocalePath==`function`}function c(e){let t=s(e)?{defaultLocale:e.defaultLocale,localeCodes:e.localeCodes,localeKeyToCode:e.localeKeyToCode??{},base:e.base}:e,n=t.defaultLocale,r=t.localeCodes,i=t.localeKeyToCode??{},a=t.base&&t.base!==`/`?t.base:``;return Function(`data`,`route`,`targetLocale`,`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./adapter-BbqZKi2F.cjs"),t=require("./vitepress-locales-CwOlvAa0.cjs");let n=require("@i18n-micro/utils/locale-head"),r=require("node:fs"),i=require("node:path"),a=require("@i18n-micro/utils/parse-path"),o=require("@i18n-micro/utils/load-dir");new Set(`xml txt ico json js css png jpg jpeg gif svg webp avif pdf wasm map mp4 webm mp3 zip gz woff woff2 ttf eot`.split(` `));var s=e=>e.includes(`\\`)?e.split(`\\`).join(`/`):e;function c(e){return`switchLocalePath`in e&&typeof e.switchLocalePath==`function`}function l(e){let t=c(e)?{defaultLocale:e.defaultLocale,localeCodes:e.localeCodes,localeKeyToCode:e.localeKeyToCode??{},base:e.base}:e,n=t.defaultLocale,r=t.localeCodes,i=t.localeKeyToCode??{},a=t.base&&t.base!==`/`?t.base:``;return Function(`data`,`route`,`targetLocale`,`
2
2
  const defaultLocale = ${JSON.stringify(n)};
3
3
  const localeCodes = ${JSON.stringify(r)};
4
4
  const localeKeyToCode = ${JSON.stringify(i)};
@@ -48,12 +48,12 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
48
48
  ? (hash.charAt(0) === '#' ? hash : '#' + hash)
49
49
  : '';
50
50
  return localized + extras + q + h;
51
- `)}function l(e,t){let n=e.indexOf(`#`),r=e.indexOf(`?`),i=e.length;n>=0&&(i=Math.min(i,n)),r>=0&&(i=Math.min(i,r));let a=e.slice(0,i)||`/`;if(r<0||t.length===0)return a;let o=new URLSearchParams(e.slice(r,n>=0?n:void 0)),s=new URLSearchParams;for(let e of t)o.has(e)&&s.set(e,o.get(e));let c=s.toString();return c?`${a}?${c}`:a}function u(e,t,n){return`${e.replace(/\/$/,``)}${!t||t===`/`?``:t.replace(/\/$/,``)}${n.startsWith(`/`)?n:`/${n}`}`}function d(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 f(t){let{locales:n,defaultLocale:r,localeKeyToCode:i={},base:s,metaBaseUrl:d,hreflangBaseLanguage:f=!1,canonicalQueryWhitelist:p=[],addDirAttribute:m=!0,addSeoAttributes:h=!0,identifierAttribute:g=`id`,missingWarn:_=!0}=t,v=e.i(t.path,s),y=e.n(v,n.map(e=>e.code),r,i,void 0),b=n.find(e=>e.code===y);if(!b)return{htmlAttrs:{},head:[]};let x=b.iso||y,S=b.dir||`auto`,C={lang:x,...m?{dir:S}:{}};if(!h||!d)return{htmlAttrs:C,head:[]};let w=c({defaultLocale:r,localeCodes:n.map(e=>e.code),localeKeyToCode:i,base:s}),T=l(v,p),E=y===r?`root`:(()=>{for(let[e,t]of Object.entries(i))if(t===y)return e===`root`?`root`:e;return y})(),D=u(d,s,w({},{path:T},E)),O=n.filter(e=>!e.disabled&&e.seo!==!1),k=(0,o.resolveOgLocale)(b);k||(0,o.warnUnresolvedOgLocale)(b,{missingWarn:_,tag:`og:locale`});let A=[];A.push([`link`,{[g]:`i18n-can`,rel:`canonical`,href:D}]),k&&A.push([`meta`,{[g]:`i18n-og`,property:`og:locale`,content:k}]),A.push([`meta`,{[g]:`i18n-og-url`,property:`og:url`,content:D}]);for(let e of O){if(e.code===y)continue;let t=(0,o.resolveOgLocale)(e);if(!t){(0,o.warnUnresolvedOgLocale)(e,{missingWarn:_,tag:`og:locale:alternate`});continue}A.push([`meta`,{[g]:`i18n-og-alt-${t}`,property:`og:locale:alternate`,content:t}])}let j=new Map;for(let e of O){let t=e.code===r?`root`:(()=>{for(let[t,n]of Object.entries(i))if(n===e.code)return t===`root`?e.code:t;return e.code})(),n=w({},{path:T},t);n&&j.set(String(e.code),u(d,s,n))}for(let{hreflang:e,localeCode:t}of(0,a.resolveHreflangAlternates)(O,{hreflangBaseLanguage:f})){let n=j.get(t);n&&A.push([`link`,{[g]:`i18n-alternate-${e}`,rel:`alternate`,href:n,hreflang:e}])}let M=n.find(e=>e.code===r);if(M&&M.seo!==!1){let e=j.get(r);e&&A.push([`link`,{[g]:`i18n-xd`,rel:`alternate`,href:e,hreflang:`x-default`}])}return{htmlAttrs:C,head:A}}function p(e,t){if((0,r.existsSync)(e))for(let n of(0,r.readdirSync)(e)){let a=(0,i.join)(e,n);if((0,r.statSync)(a).isDirectory()){p(a,t);continue}n.endsWith(`.json`)&&t(a)}}function m(e){let t=e.rootDir??process.cwd(),n=(0,i.resolve)(t,e.translationDir),r=[];return p(n,e=>{r.push({absolutePath:e,relativePath:(0,i.relative)(n,e).split(i.sep).join(`/`)})}),r.sort((e,t)=>e.relativePath.localeCompare(t.relativePath))}function h(e){let t=e.rootDir??process.cwd(),a=(0,i.resolve)(t,e.translationDir),o={root:{},routes:{}},s=e.disablePageLocales===!0;return(0,r.existsSync)(a)&&p(a,e=>{let t=(0,i.relative)(a,e).split(i.sep).join(`/`);try{let i=JSON.parse((0,r.readFileSync)(e,`utf-8`));if(typeof i!=`object`||!i||Array.isArray(i)){console.error(`[i18n-micro/vitepress] Skipping ${t}: expected a JSON object, got ${Array.isArray(i)?`array`:typeof i}`);return}(0,n.storeLoadedTranslationFile)(o,t,i,s)}catch(e){console.error(`[i18n-micro/vitepress] Failed to load ${t}:`,e)}}),o}var g=`virtual:i18n-micro/config`,_=`\0${g}`,v=`virtual:i18n-micro/messages`,y=`\0${v}`;function b(e){return e.replace(/\\/g,`/`)}function x(e,t,r){let i=m({rootDir:e,translationDir:t});if(i.length===0)return`export const messages = {}
51
+ `)}var u=e=>e.endsWith(`/`)?e.slice(0,-1):e;function d(e,t,n){return`${u(e)}${!t||t===`/`?``:u(t)}${n.startsWith(`/`)?n:`/${n}`}`}function f(e){let t=s(e);return t===`index.md`||t.endsWith(`/index.md`)?t=t.slice(0,-8):t.endsWith(`.md`)&&(t=t.slice(0,-3)),t.startsWith(`/`)||(t=`/${t}`),t.length>1&&t.endsWith(`/`)&&(t=t.slice(0,-1)),t||`/`}function p(t){let{locales:r,defaultLocale:i,localeKeyToCode:a={},base:o,metaBaseUrl:s,hreflangBaseLanguage:c=!1,canonicalQueryWhitelist:u=[],addDirAttribute:f=!0,addSeoAttributes:p=!0,identifierAttribute:m=`id`,missingWarn:h=!0}=t,g=e.i(t.path,o),_=e.n(g,r.map(e=>e.code),i,a,void 0),v=r.find(e=>e.code===_);if(!v)return{htmlAttrs:{},head:[]};let y=l({defaultLocale:i,localeCodes:r.map(e=>e.code),localeKeyToCode:a,base:o}),b=(0,n.filterQuery)(g,u),x=e=>d(s??``,o,y({},{path:b},e)),S=(e,t)=>{if(e===i)return`root`;let n=Object.entries(a).find(([,t])=>t===e);return n?n[0]===`root`?t:n[0]:e},C=r.filter(e=>!e.disabled&&e.seo!==!1),{htmlAttrs:w,link:T,meta:E}=(0,n.buildLocaleHead)({locale:v,seoLocales:C,hrefOf:e=>x(S(e,e)),canonical:x(S(_,`root`)),xDefault:C.some(e=>e.code===i)?x(`root`):void 0,addDirAttribute:f,addSeoAttributes:p&&!!s,identifierAttribute:m,hreflangBaseLanguage:c,missingWarn:h});if(T.length===0)return{htmlAttrs:w,head:[]};let[D,...O]=T,k=(e,t)=>t.map(t=>[e,t]);return{htmlAttrs:w,head:[...k(`link`,[D]),...k(`meta`,E),...k(`link`,O)]}}var m=e=>(0,i.resolve)(e.rootDir??process.cwd(),e.translationDir);function h(e){return(0,o.listTranslationFiles)(m(e))}function g(e){return(0,o.loadTranslationDir)(m(e),e.disablePageLocales===!0)}var _=`virtual:i18n-micro/config`,v=`\0${_}`,y=`virtual:i18n-micro/messages`,b=`\0${y}`;function x(e){return s(e)}function S(e,t,n){let r=h({rootDir:e,translationDir:t});if(r.length===0)return`export const messages = {}
52
52
  export const routeMessages = {}
53
- `;let a=[],o=[],s=new Map,c=0;for(let e of i){let t=(0,n.classifyTranslationRelativePath)(e.relativePath,r);if(t.type===`ignore`)continue;let i=`__i18n_${c++}`;if(a.push(`import ${i} from ${JSON.stringify(b(e.absolutePath))}`),t.type===`root`){o.push(` ${JSON.stringify(t.locale)}: ${i}`);continue}let l=s.get(t.pageName);l||(l=new Map,s.set(t.pageName,l)),l.set(t.locale,i)}let l=[];for(let[e,t]of s){let n=[...t.entries()].map(([e,t])=>` ${JSON.stringify(e)}: ${t}`).join(`,
54
- `);l.push(` ${JSON.stringify(e)}: {\n${n}\n }`)}return[...a,`export const messages = {\n${o.join(`,
53
+ `;let i=[],o=[],s=new Map,c=0;for(let e of r){let t=(0,a.classifyTranslationRelativePath)(e.relativePath,n);if(t.type===`ignore`)continue;let r=`__i18n_${c++}`;if(i.push(`import ${r} from ${JSON.stringify(x(e.absolutePath))}`),t.type===`root`){o.push(` ${JSON.stringify(t.locale)}: ${r}`);continue}let l=s.get(t.pageName);l||(l=new Map,s.set(t.pageName,l)),l.set(t.locale,r)}let l=[];for(let[e,t]of s){let n=[...t.entries()].map(([e,t])=>` ${JSON.stringify(e)}: ${t}`).join(`,
54
+ `);l.push(` ${JSON.stringify(e)}: {\n${n}\n }`)}return[...i,`export const messages = {\n${o.join(`,
55
55
  `)}\n}`,`export const routeMessages = {\n${l.join(`,
56
56
  `)}\n}`,``].join(`
57
- `)}function S(e,t){return[`export const messages = ${JSON.stringify(e)}`,`export const routeMessages = ${JSON.stringify(t)}`,``].join(`
58
- `)}function C(e,t){let n=e.defaultLocale||e.locale,a=e.translationDir??`locales`,o=e.disablePageLocales===!0,s={defaultLocale:n,fallbackLocale:e.fallbackLocale||n,locales:e.locales||[],localeCodes:(e.locales||[]).map(e=>e.code),missingWarn:e.missingWarn??!0,syncWithVitePress:e.syncWithVitePress!==!1,translationDir:a,disablePageLocales:o,localeKeyToCode:e.localeKeyToCode??{},base:t&&t!==`/`?t:void 0},c=process.cwd(),l=!!(e.messages||e.routeMessages),u=e.messages??{},d=e.routeMessages??{},f,p=()=>!e.messages||!e.routeMessages,m=()=>{if(!p())return;let t=h({rootDir:c,translationDir:a,disablePageLocales:o});e.messages||(u=t.root),e.routeMessages||(d=t.routes)};return{name:`vite-plugin-i18n-vitepress`,configResolved(t){c=t.root,l=!!(e.messages||e.routeMessages),l&&(e.messages&&(u=e.messages),e.routeMessages&&(d=e.routeMessages),p()&&m(),e.messages&&(u=e.messages),e.routeMessages&&(d=e.routeMessages))},configureServer(e){if(l&&!p())return;let t=(0,i.resolve)(c,a);if(!(0,r.existsSync)(t))return;e.watcher.add(t);let n=()=>{f&&clearTimeout(f),f=setTimeout(()=>{l&&m();let t=e.moduleGraph.getModuleById(y);t&&(e.moduleGraph.invalidateModule(t),e.ws.send({type:`full-reload`}))},50)};e.watcher.on(`add`,e=>{e.startsWith(t)&&e.endsWith(`.json`)&&n()}),e.watcher.on(`unlink`,e=>{e.startsWith(t)&&e.endsWith(`.json`)&&n()}),l&&p()&&e.watcher.on(`change`,e=>{e.startsWith(t)&&e.endsWith(`.json`)&&n()})},resolveId(e){if(e===g)return _;if(e===v)return y},load(e){if(e===_)return`export const config = ${JSON.stringify(s)}`;if(e===y)return l?S(u,d):x(c,a,o)}}}function w(e,t){if(t.warnOnLocaleMismatch===!1)return;let n=e.locales;if(!n||!t.locales?.length)return;let r=t.defaultLocale||t.locale,i=Object.keys(n),a=new Set(t.locales.map(e=>e.code));for(let e of i){let n=e===`root`?r:t.localeKeyToCode?.[e]??e;a.has(n)||console.warn(`[i18n-micro/vitepress] VitePress locale key "${e}" maps to "${n}", which is not in i18n locales (${[...a].join(`, `)}).`)}}function T(e,t){w(e,t);let n=typeof e.base==`string`?e.base:void 0,r=e.vite?.plugins,i=[...Array.isArray(r)?r.flat():[],C(t,n)],a=e.vite?.ssr,o=a?.noExternal,s=[`@i18n-micro/vitepress`,...Array.isArray(o)?o:o&&o!==!0?[o]:[]],l=t.defaultLocale||t.locale,u=(t.locales||[]).map(e=>e.code),p=e.themeConfig&&typeof e.themeConfig==`object`?e.themeConfig:{},m=t.i18nRouting!==!1&&p.i18nRouting===void 0&&u.length>0,h=t.meta??!!t.metaBaseUrl,g=t.locales||[],_=e.transformHead,v=e.transformPageData,y=h?async n=>{let r=typeof _==`function`?await _(n):[],i=Array.isArray(r)?r:[];if(n.pageData?.frontmatter?.i18n?.disableMeta===!0)return i;let a=n.pageData?.relativePath||`index.md`,o=(typeof e.base==`string`?e.base:void 0)??n.siteData?.base??n.siteConfig?.site?.base,s=f({path:d(a),locales:g,defaultLocale:l,localeKeyToCode:t.localeKeyToCode,base:o,metaBaseUrl:t.metaBaseUrl,hreflangBaseLanguage:t.hreflangBaseLanguage,canonicalQueryWhitelist:t.canonicalQueryWhitelist,missingWarn:t.missingWarn});return[...i,...s.head]}:_,b=h?async(n,r)=>{if(typeof v==`function`&&await v(n,r),n.frontmatter?.i18n?.disableMeta===!0)return;let i=f({path:d(n.relativePath||`index.md`),locales:g,defaultLocale:l,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});i.htmlAttrs.lang&&(n.frontmatter??={},n.frontmatter.lang||(n.frontmatter.lang=i.htmlAttrs.lang))}:v;return{...e,...m?{themeConfig:{...p,i18nRouting:c({defaultLocale:l,localeCodes:u,localeKeyToCode:t.localeKeyToCode,base:n})}}:{},...h?{transformHead:y,transformPageData:b}:{},vite:{...e.vite,plugins:i,ssr:{...a,noExternal:o===!0||s}}}}exports.buildVitePressLocaleHead=f,exports.buildVitePressLocales=t.t,exports.relativePathToRoutePath=d,exports.warnLocaleMismatch=w,exports.withI18n=T;
57
+ `)}function C(e,t){return[`export const messages = ${JSON.stringify(e)}`,`export const routeMessages = ${JSON.stringify(t)}`,``].join(`
58
+ `)}function w(e,t){let n=e.defaultLocale||e.locale,a=e.translationDir??`locales`,o=e.disablePageLocales===!0,s={defaultLocale:n,fallbackLocale:e.fallbackLocale||n,locales:e.locales||[],localeCodes:(e.locales||[]).map(e=>e.code),missingWarn:e.missingWarn??!0,syncWithVitePress:e.syncWithVitePress!==!1,translationDir:a,disablePageLocales:o,localeKeyToCode:e.localeKeyToCode??{},base:t&&t!==`/`?t:void 0,numberFormats:e.numberFormats,datetimeFormats:e.datetimeFormats,timeZone:e.timeZone},c=process.cwd(),l=!!(e.messages||e.routeMessages),u=e.messages??{},d=e.routeMessages??{},f,p=()=>!e.messages||!e.routeMessages,m=()=>{if(!p())return;let t=g({rootDir:c,translationDir:a,disablePageLocales:o});e.messages||(u=t.root),e.routeMessages||(d=t.routes)};return{name:`vite-plugin-i18n-vitepress`,configResolved(e){c=e.root,l&&m()},configureServer(e){if(l&&!p())return;let t=(0,i.resolve)(c,a);if(!(0,r.existsSync)(t))return;e.watcher.add(t);let n=()=>{f&&clearTimeout(f),f=setTimeout(()=>{l&&m();let t=e.moduleGraph.getModuleById(b);t&&(e.moduleGraph.invalidateModule(t),e.ws.send({type:`full-reload`}))},50)};e.watcher.on(`add`,e=>{e.startsWith(t)&&e.endsWith(`.json`)&&n()}),e.watcher.on(`unlink`,e=>{e.startsWith(t)&&e.endsWith(`.json`)&&n()}),l&&p()&&e.watcher.on(`change`,e=>{e.startsWith(t)&&e.endsWith(`.json`)&&n()})},resolveId(e){if(e===_)return v;if(e===y)return b},load(e){if(e===v)return`export const config = ${JSON.stringify(s)}`;if(e===b)return l?C(u,d):S(c,a,o)}}}function T(e,t){if(t.warnOnLocaleMismatch===!1)return;let n=e.locales;if(!n||!t.locales?.length)return;let r=t.defaultLocale||t.locale,i=Object.keys(n),a=new Set(t.locales.map(e=>e.code));for(let e of i){let n=e===`root`?r:t.localeKeyToCode?.[e]??e;a.has(n)||console.warn(`[i18n-micro/vitepress] VitePress locale key "${e}" maps to "${n}", which is not in i18n locales (${[...a].join(`, `)}).`)}}function E(e,t){T(e,t);let n=typeof e.base==`string`?e.base:void 0,r=e.vite?.plugins,i=[...Array.isArray(r)?r.flat():[],w(t,n)],a=e.vite?.ssr,o=a?.noExternal,s=[`@i18n-micro/vitepress`,...Array.isArray(o)?o:o&&o!==!0?[o]:[]],c=t.defaultLocale||t.locale,u=(t.locales||[]).map(e=>e.code),d=e.themeConfig&&typeof e.themeConfig==`object`?e.themeConfig:{},m=t.i18nRouting!==!1&&d.i18nRouting===void 0&&u.length>0,h=t.meta??!!t.metaBaseUrl,g=t.locales||[],_=e.transformHead,v=e.transformPageData,y={locales:g,defaultLocale:c,localeKeyToCode:t.localeKeyToCode,metaBaseUrl:t.metaBaseUrl,hreflangBaseLanguage:t.hreflangBaseLanguage,canonicalQueryWhitelist:t.canonicalQueryWhitelist,missingWarn:t.missingWarn},b=h?async t=>{let n=typeof _==`function`?await _(t):[],r=Array.isArray(n)?n:[];if(t.pageData?.frontmatter?.i18n?.disableMeta===!0)return r;let i=t.pageData?.relativePath||`index.md`,a=(typeof e.base==`string`?e.base:void 0)??t.siteData?.base??t.siteConfig?.site?.base,o=p({...y,path:f(i),base:a});return[...r,...o.head]}:_,x=h?async(t,n)=>{if(typeof v==`function`&&await v(t,n),t.frontmatter?.i18n?.disableMeta===!0)return;let r=p({...y,path:f(t.relativePath||`index.md`),base:typeof e.base==`string`?e.base:void 0,addSeoAttributes:!1});r.htmlAttrs.lang&&(t.frontmatter??={},t.frontmatter.lang||(t.frontmatter.lang=r.htmlAttrs.lang))}:v;return{...e,...m?{themeConfig:{...d,i18nRouting:l({defaultLocale:c,localeCodes:u,localeKeyToCode:t.localeKeyToCode,base:n})}}:{},...h?{transformHead:b,transformPageData:x}:{},vite:{...e.vite,plugins:i,ssr:{...a,noExternal:o===!0||s}}}}exports.buildVitePressLocaleHead=p,exports.buildVitePressLocales=t.t,exports.relativePathToRoutePath=f,exports.warnLocaleMismatch=T,exports.withI18n=E;
59
59
  //# sourceMappingURL=config.cjs.map