@i18n-micro/utils 1.0.8 → 1.0.13
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/dist/auto-detect-path.cjs +1 -0
- package/dist/auto-detect-path.d.cts +16 -0
- package/dist/auto-detect-path.d.ts +16 -0
- package/dist/auto-detect-path.mjs +13 -0
- package/dist/build.cjs +1 -1
- package/dist/build.d.cts +1 -1
- package/dist/build.d.ts +1 -1
- package/dist/build.mjs +57 -54
- package/dist/merge-source.cjs +1 -1
- package/dist/merge-source.d.cts +8 -0
- package/dist/merge-source.d.ts +8 -0
- package/dist/merge-source.mjs +24 -19
- package/dist/normalize.d.cts +1 -0
- package/dist/normalize.d.ts +1 -0
- package/dist/payload-config.cjs +1 -1
- package/dist/payload-config.d.cts +15 -1
- package/dist/payload-config.d.ts +15 -1
- package/dist/payload-config.mjs +52 -37
- package/dist/resolve-hreflang.cjs +1 -0
- package/dist/resolve-hreflang.d.cts +22 -0
- package/dist/resolve-hreflang.d.ts +22 -0
- package/dist/resolve-hreflang.mjs +29 -0
- package/dist/split-locale-routes.cjs +1 -0
- package/dist/split-locale-routes.d.cts +36 -0
- package/dist/split-locale-routes.d.ts +36 -0
- package/dist/split-locale-routes.mjs +19 -0
- package/package.json +48 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function i(e,o={}){const t=o.autoDetectPath??"/",r=!e||e===""?"/":e;if(t==="*")return!0;if(t==="no_prefix")return!o.hasLocalePrefix;if(t==="/"||t==="")return r==="/";const c=t.startsWith("/")?t:`/${t}`;return r===c||r===`${c}/`}exports.shouldAttemptLocaleRedirect=i;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether cookie / Accept-Language preference may steer locale redirects (#242).
|
|
3
|
+
*
|
|
4
|
+
* Modes (`ModuleOptions.autoDetectPath`):
|
|
5
|
+
* - `'/'` (default) — only `/`
|
|
6
|
+
* - `'no_prefix'` — any path without a locale prefix
|
|
7
|
+
* - `'*'` — every path (also enables aggressive prefixed-URL rewrites in the plugin)
|
|
8
|
+
* - any other string — exact path match
|
|
9
|
+
*
|
|
10
|
+
* Does not gate strategy / `localeRoutes` canonicalization: when preference is denied on an
|
|
11
|
+
* unprefixed path, the plugin still runs `getClientRedirect` with the default locale.
|
|
12
|
+
*/
|
|
13
|
+
export declare function shouldAttemptLocaleRedirect(path: string, options?: {
|
|
14
|
+
autoDetectPath?: string;
|
|
15
|
+
hasLocalePrefix?: boolean;
|
|
16
|
+
}): boolean;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether cookie / Accept-Language preference may steer locale redirects (#242).
|
|
3
|
+
*
|
|
4
|
+
* Modes (`ModuleOptions.autoDetectPath`):
|
|
5
|
+
* - `'/'` (default) — only `/`
|
|
6
|
+
* - `'no_prefix'` — any path without a locale prefix
|
|
7
|
+
* - `'*'` — every path (also enables aggressive prefixed-URL rewrites in the plugin)
|
|
8
|
+
* - any other string — exact path match
|
|
9
|
+
*
|
|
10
|
+
* Does not gate strategy / `localeRoutes` canonicalization: when preference is denied on an
|
|
11
|
+
* unprefixed path, the plugin still runs `getClientRedirect` with the default locale.
|
|
12
|
+
*/
|
|
13
|
+
export declare function shouldAttemptLocaleRedirect(path: string, options?: {
|
|
14
|
+
autoDetectPath?: string;
|
|
15
|
+
hasLocalePrefix?: boolean;
|
|
16
|
+
}): boolean;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
function c(e, n = {}) {
|
|
2
|
+
const t = n.autoDetectPath ?? "/", r = !e || e === "" ? "/" : e;
|
|
3
|
+
if (t === "*") return !0;
|
|
4
|
+
if (t === "no_prefix")
|
|
5
|
+
return !n.hasLocalePrefix;
|
|
6
|
+
if (t === "/" || t === "")
|
|
7
|
+
return r === "/";
|
|
8
|
+
const o = t.startsWith("/") ? t : `/${t}`;
|
|
9
|
+
return r === o || r === `${o}/`;
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
c as shouldAttemptLocaleRedirect
|
|
13
|
+
};
|
package/dist/build.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("node:fs"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("node:fs"),r=require("node:path"),j=require("globby"),M=require("./deep-merge.cjs");async function P(m,h,a,p,S,w){n.existsSync(a)&&n.rmSync(a,{recursive:!0,force:!0}),n.mkdirSync(a,{recursive:!0});const c=m.map(e=>r.join(e,h)),i=new Set,g=await Promise.all(c.filter(e=>n.existsSync(e)).map(e=>j.globby("**/*.json",{cwd:e})));for(const e of g)e.forEach(o=>i.add(o));const u=new Map;for(const e of i){let o={};for(const t of c){const s=r.join(t,e);if(n.existsSync(s))try{o=M.deepMergeTranslationsRecursive(o,JSON.parse(n.readFileSync(s,"utf-8")))}catch{}}u.set(e,o)}const d=new Map,l=new Map;for(const[e,o]of u){const t=r.dirname(e),s=e.slice(e.lastIndexOf("/")+1).replace(".json","");t==="."?d.set(s,o):(l.has(t)||l.set(t,new Map),l.get(t).set(s,o))}const b=new Set(p.map(e=>e.code)),x=e=>{for(const o of p){const t=[S,o.fallbackLocale,o.code].filter(f=>!!f&&b.has(f)).filter((f,y,v)=>v.indexOf(f)===y);if(t.length<=1)continue;let s={};for(const f of t){const y=e.get(f);y&&(s=M.deepMergeTranslationsRecursive(s,y))}e.set(o.code,s)}};x(d);for(const e of l.values())x(e);if(w||l.size===0){const e=new Map;for(const[o,t]of d)e.set(o,{...t});l.set("pages/index",e)}else for(const[,e]of l)for(const[o,t]of d){const s=e.get(o);e.set(o,s?M.deepMergeTranslations(t,s):{...t})}for(const[e,o]of l){const t=e.replace(/^pages\/?/,"")||"index";for(const[s,f]of o){if(!b.has(s))continue;const y=r.join(a,t,s,"data.json");n.mkdirSync(r.dirname(y),{recursive:!0}),n.writeFileSync(y,JSON.stringify(f))}}}async function k(m,h,a){n.existsSync(a)&&n.rmSync(a,{recursive:!0,force:!0}),n.mkdirSync(a,{recursive:!0});const p=m.map(c=>r.join(c,h)),S=new Set,w=await Promise.all(p.filter(c=>n.existsSync(c)).map(c=>j.globby("**/*.json",{cwd:c})));for(const c of w)c.forEach(i=>S.add(i));for(const c of S){let i={};for(const u of p){const d=r.join(u,c);if(n.existsSync(d))try{i=M.deepMergeTranslationsRecursive(i,JSON.parse(n.readFileSync(d,"utf-8")))}catch{}}const g=r.join(a,c);n.mkdirSync(r.dirname(g),{recursive:!0}),n.writeFileSync(g,JSON.stringify(i))}}exports.buildTranslationSourceLayers=k;exports.preMergeLocales=P;
|
package/dist/build.d.cts
CHANGED
|
@@ -5,7 +5,7 @@ export interface PreMergeLocaleInfo {
|
|
|
5
5
|
/**
|
|
6
6
|
* Pre-merge all translation files at build time.
|
|
7
7
|
*
|
|
8
|
-
* Output:
|
|
8
|
+
* Output: `{page}/{locale}/data.json` (same relative path the client fetches under `apiBaseUrl`).
|
|
9
9
|
*/
|
|
10
10
|
export declare function preMergeLocales(rootDirs: string[], translationDirName: string, outputDir: string, locales: PreMergeLocaleInfo[], globalFallbackLocale?: string, disablePageLocales?: boolean): Promise<void>;
|
|
11
11
|
/**
|
package/dist/build.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export interface PreMergeLocaleInfo {
|
|
|
5
5
|
/**
|
|
6
6
|
* Pre-merge all translation files at build time.
|
|
7
7
|
*
|
|
8
|
-
* Output:
|
|
8
|
+
* Output: `{page}/{locale}/data.json` (same relative path the client fetches under `apiBaseUrl`).
|
|
9
9
|
*/
|
|
10
10
|
export declare function preMergeLocales(rootDirs: string[], translationDirName: string, outputDir: string, locales: PreMergeLocaleInfo[], globalFallbackLocale?: string, disablePageLocales?: boolean): Promise<void>;
|
|
11
11
|
/**
|
package/dist/build.mjs
CHANGED
|
@@ -1,81 +1,84 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { join as
|
|
3
|
-
import { globby as
|
|
4
|
-
import { deepMergeTranslationsRecursive as
|
|
5
|
-
async function z(M, S,
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
for (const e of
|
|
9
|
-
e.forEach((o) =>
|
|
10
|
-
const
|
|
11
|
-
for (const e of
|
|
1
|
+
import b, { existsSync as p, mkdirSync as w, readFileSync as j, writeFileSync as F } from "node:fs";
|
|
2
|
+
import { join as d, dirname as v } from "node:path";
|
|
3
|
+
import { globby as L } from "globby";
|
|
4
|
+
import { deepMergeTranslationsRecursive as x, deepMergeTranslations as J } from "./deep-merge.mjs";
|
|
5
|
+
async function z(M, S, n, y, m, u) {
|
|
6
|
+
p(n) && b.rmSync(n, { recursive: !0, force: !0 }), w(n, { recursive: !0 });
|
|
7
|
+
const s = M.map((e) => d(e, S)), c = /* @__PURE__ */ new Set(), g = await Promise.all(s.filter((e) => p(e)).map((e) => L("**/*.json", { cwd: e })));
|
|
8
|
+
for (const e of g)
|
|
9
|
+
e.forEach((o) => c.add(o));
|
|
10
|
+
const h = /* @__PURE__ */ new Map();
|
|
11
|
+
for (const e of c) {
|
|
12
12
|
let o = {};
|
|
13
|
-
for (const t of
|
|
14
|
-
const
|
|
15
|
-
if (
|
|
13
|
+
for (const t of s) {
|
|
14
|
+
const a = d(t, e);
|
|
15
|
+
if (p(a))
|
|
16
16
|
try {
|
|
17
|
-
o =
|
|
17
|
+
o = x(o, JSON.parse(j(a, "utf-8")));
|
|
18
18
|
} catch {
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
h.set(e, o);
|
|
22
22
|
}
|
|
23
|
-
const l = /* @__PURE__ */ new Map(),
|
|
24
|
-
for (const [e, o] of
|
|
25
|
-
const t = v(e),
|
|
26
|
-
t === "." ? l.set(
|
|
23
|
+
const l = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map();
|
|
24
|
+
for (const [e, o] of h) {
|
|
25
|
+
const t = v(e), a = e.slice(e.lastIndexOf("/") + 1).replace(".json", "");
|
|
26
|
+
t === "." ? l.set(a, o) : (r.has(t) || r.set(t, /* @__PURE__ */ new Map()), r.get(t).set(a, o));
|
|
27
27
|
}
|
|
28
|
-
const
|
|
29
|
-
for (const o of
|
|
30
|
-
const t = [
|
|
28
|
+
const P = new Set(y.map((e) => e.code)), O = (e) => {
|
|
29
|
+
for (const o of y) {
|
|
30
|
+
const t = [m, o.fallbackLocale, o.code].filter((f) => !!f && P.has(f)).filter((f, i, k) => k.indexOf(f) === i);
|
|
31
31
|
if (t.length <= 1) continue;
|
|
32
|
-
let
|
|
33
|
-
for (const
|
|
34
|
-
const
|
|
35
|
-
|
|
32
|
+
let a = {};
|
|
33
|
+
for (const f of t) {
|
|
34
|
+
const i = e.get(f);
|
|
35
|
+
i && (a = x(a, i));
|
|
36
36
|
}
|
|
37
|
-
e.set(o.code,
|
|
37
|
+
e.set(o.code, a);
|
|
38
38
|
}
|
|
39
39
|
};
|
|
40
|
-
|
|
41
|
-
for (const e of
|
|
42
|
-
|
|
43
|
-
if (u ||
|
|
40
|
+
O(l);
|
|
41
|
+
for (const e of r.values())
|
|
42
|
+
O(e);
|
|
43
|
+
if (u || r.size === 0) {
|
|
44
44
|
const e = /* @__PURE__ */ new Map();
|
|
45
45
|
for (const [o, t] of l)
|
|
46
46
|
e.set(o, { ...t });
|
|
47
|
-
|
|
47
|
+
r.set("pages/index", e);
|
|
48
48
|
} else
|
|
49
|
-
for (const [, e] of
|
|
49
|
+
for (const [, e] of r)
|
|
50
50
|
for (const [o, t] of l) {
|
|
51
|
-
const
|
|
52
|
-
e.set(o,
|
|
51
|
+
const a = e.get(o);
|
|
52
|
+
e.set(o, a ? J(t, a) : { ...t });
|
|
53
53
|
}
|
|
54
|
-
for (const [e, o] of
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
for (const [e, o] of r) {
|
|
55
|
+
const t = e.replace(/^pages\/?/, "") || "index";
|
|
56
|
+
for (const [a, f] of o) {
|
|
57
|
+
if (!P.has(a)) continue;
|
|
58
|
+
const i = d(n, t, a, "data.json");
|
|
59
|
+
w(v(i), { recursive: !0 }), F(i, JSON.stringify(f));
|
|
58
60
|
}
|
|
61
|
+
}
|
|
59
62
|
}
|
|
60
|
-
async function C(M, S,
|
|
61
|
-
|
|
62
|
-
const
|
|
63
|
-
|
|
63
|
+
async function C(M, S, n) {
|
|
64
|
+
p(n) && b.rmSync(n, { recursive: !0, force: !0 }), w(n, { recursive: !0 });
|
|
65
|
+
const y = M.map((s) => d(s, S)), m = /* @__PURE__ */ new Set(), u = await Promise.all(
|
|
66
|
+
y.filter((s) => p(s)).map((s) => L("**/*.json", { cwd: s }))
|
|
64
67
|
);
|
|
65
|
-
for (const
|
|
66
|
-
|
|
67
|
-
for (const
|
|
68
|
-
let
|
|
69
|
-
for (const
|
|
70
|
-
const l =
|
|
71
|
-
if (
|
|
68
|
+
for (const s of u)
|
|
69
|
+
s.forEach((c) => m.add(c));
|
|
70
|
+
for (const s of m) {
|
|
71
|
+
let c = {};
|
|
72
|
+
for (const h of y) {
|
|
73
|
+
const l = d(h, s);
|
|
74
|
+
if (p(l))
|
|
72
75
|
try {
|
|
73
|
-
|
|
76
|
+
c = x(c, JSON.parse(j(l, "utf-8")));
|
|
74
77
|
} catch {
|
|
75
78
|
}
|
|
76
79
|
}
|
|
77
|
-
const
|
|
78
|
-
w(v(
|
|
80
|
+
const g = d(n, s);
|
|
81
|
+
w(v(g), { recursive: !0 }), F(g, JSON.stringify(c));
|
|
79
82
|
}
|
|
80
83
|
}
|
|
81
84
|
export {
|
package/dist/merge-source.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("./deep-merge.cjs");function s(e,a,r){const c=new Set(a.map(o=>o.code)),n=a.find(o=>o.code===e);return[r,n?.fallbackLocale,e].filter(o=>!!o&&c.has(o)).filter((o,f,m)=>m.indexOf(o)===f)}function b(e,a,r){let c={};for(const n of e)c=l.deepMergeTranslations(c,a(r(n)));return c}async function t(e,a,r){return(await Promise.all(e.map(n=>a(r(n))))).reduce((n,o)=>l.deepMergeTranslations(n,o),{})}function i(e,a){return a?"index":e||"index"}function u(e){return`${e}.json`}function g(e,a){return`pages/${i(e)}/${a}.json`}function d(e){return e.replace(/^\/+/,"").replace(/\\/g,"/")}function S(e,a){const r=e.replace(/^\/+|\/+$/g,"")||"index";return d(`${r}/${a}/data.json`)}async function h(e){const a=i(e.pageName,e.disablePageLocales),r=s(e.locale,e.locales,e.globalFallbackLocale),c=await t(r,e.readLocaleFile,u),n=await t(r,e.readLocaleFile,o=>g(a,o));return l.deepMergeTranslations(c,n)}function k(e){return(e??[]).map(a=>typeof a=="string"?{code:a}:{code:a.code,fallbackLocale:a.fallbackLocale})}exports.buildFallbackLocaleChain=s;exports.buildSourcePagePath=g;exports.buildSourceRootPath=u;exports.mergeSourceTranslations=h;exports.mergeTranslationsFromFallbackChain=b;exports.mergeTranslationsFromFallbackChainAsync=t;exports.normalizeConfiguredLocales=k;exports.resolveSourcePageName=i;exports.toPremergedStorageKey=S;exports.toSourceStorageKey=d;
|
package/dist/merge-source.d.cts
CHANGED
|
@@ -17,6 +17,14 @@ export declare function mergeTranslationsFromFallbackChainAsync(chain: string[],
|
|
|
17
17
|
export declare function resolveSourcePageName(pageName: string, disablePageLocales?: boolean): string;
|
|
18
18
|
export declare function buildSourceRootPath(localeCode: string): string;
|
|
19
19
|
export declare function buildSourcePagePath(pageName: string, localeCode: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Storage key relative to the Nitro unstorage mount (fs-friendly `/` paths).
|
|
22
|
+
*/
|
|
20
23
|
export declare function toSourceStorageKey(relativePath: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Premerged page/locale payload key — matches the client URL path under `apiBaseUrl`
|
|
26
|
+
* (`{page}/{locale}/data.json`, e.g. `index/en/data.json` → `/_locales/index/en/data.json`).
|
|
27
|
+
*/
|
|
28
|
+
export declare function toPremergedStorageKey(pageName: string, locale: string): string;
|
|
21
29
|
export declare function mergeSourceTranslations(input: MergeSourceTranslationsInput): Promise<Record<string, unknown>>;
|
|
22
30
|
export declare function normalizeConfiguredLocales(locales: Array<string | Locale> | undefined): SourceLocaleInfo[];
|
package/dist/merge-source.d.ts
CHANGED
|
@@ -17,6 +17,14 @@ export declare function mergeTranslationsFromFallbackChainAsync(chain: string[],
|
|
|
17
17
|
export declare function resolveSourcePageName(pageName: string, disablePageLocales?: boolean): string;
|
|
18
18
|
export declare function buildSourceRootPath(localeCode: string): string;
|
|
19
19
|
export declare function buildSourcePagePath(pageName: string, localeCode: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Storage key relative to the Nitro unstorage mount (fs-friendly `/` paths).
|
|
22
|
+
*/
|
|
20
23
|
export declare function toSourceStorageKey(relativePath: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Premerged page/locale payload key — matches the client URL path under `apiBaseUrl`
|
|
26
|
+
* (`{page}/{locale}/data.json`, e.g. `index/en/data.json` → `/_locales/index/en/data.json`).
|
|
27
|
+
*/
|
|
28
|
+
export declare function toPremergedStorageKey(pageName: string, locale: string): string;
|
|
21
29
|
export declare function mergeSourceTranslations(input: MergeSourceTranslationsInput): Promise<Record<string, unknown>>;
|
|
22
30
|
export declare function normalizeConfiguredLocales(locales: Array<string | Locale> | undefined): SourceLocaleInfo[];
|
package/dist/merge-source.mjs
CHANGED
|
@@ -1,32 +1,36 @@
|
|
|
1
1
|
import { deepMergeTranslations as t } from "./deep-merge.mjs";
|
|
2
|
-
function f(e, a,
|
|
3
|
-
const c = new Set(a.map((o) => o.code)),
|
|
4
|
-
return [
|
|
2
|
+
function f(e, a, n) {
|
|
3
|
+
const c = new Set(a.map((o) => o.code)), r = a.find((o) => o.code === e);
|
|
4
|
+
return [n, r?.fallbackLocale, e].filter((o) => !!o && c.has(o)).filter((o, s, u) => u.indexOf(o) === s);
|
|
5
5
|
}
|
|
6
|
-
function
|
|
6
|
+
function k(e, a, n) {
|
|
7
7
|
let c = {};
|
|
8
|
-
for (const
|
|
9
|
-
c = t(c, a(r
|
|
8
|
+
for (const r of e)
|
|
9
|
+
c = t(c, a(n(r)));
|
|
10
10
|
return c;
|
|
11
11
|
}
|
|
12
|
-
async function l(e, a,
|
|
13
|
-
return (await Promise.all(e.map((
|
|
12
|
+
async function l(e, a, n) {
|
|
13
|
+
return (await Promise.all(e.map((r) => a(n(r))))).reduce((r, o) => t(r, o), {});
|
|
14
14
|
}
|
|
15
|
-
function
|
|
15
|
+
function i(e, a) {
|
|
16
16
|
return a ? "index" : e || "index";
|
|
17
17
|
}
|
|
18
18
|
function d(e) {
|
|
19
19
|
return `${e}.json`;
|
|
20
20
|
}
|
|
21
21
|
function g(e, a) {
|
|
22
|
-
return `pages/${
|
|
22
|
+
return `pages/${i(e)}/${a}.json`;
|
|
23
23
|
}
|
|
24
|
-
function
|
|
25
|
-
return
|
|
24
|
+
function m(e) {
|
|
25
|
+
return e.replace(/^\/+/, "").replace(/\\/g, "/");
|
|
26
26
|
}
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
return
|
|
27
|
+
function h(e, a) {
|
|
28
|
+
const n = e.replace(/^\/+|\/+$/g, "") || "index";
|
|
29
|
+
return m(`${n}/${a}/data.json`);
|
|
30
|
+
}
|
|
31
|
+
async function p(e) {
|
|
32
|
+
const a = i(e.pageName, e.disablePageLocales), n = f(e.locale, e.locales, e.globalFallbackLocale), c = await l(n, e.readLocaleFile, d), r = await l(n, e.readLocaleFile, (o) => g(a, o));
|
|
33
|
+
return t(c, r);
|
|
30
34
|
}
|
|
31
35
|
function L(e) {
|
|
32
36
|
return (e ?? []).map(
|
|
@@ -37,10 +41,11 @@ export {
|
|
|
37
41
|
f as buildFallbackLocaleChain,
|
|
38
42
|
g as buildSourcePagePath,
|
|
39
43
|
d as buildSourceRootPath,
|
|
40
|
-
|
|
41
|
-
|
|
44
|
+
p as mergeSourceTranslations,
|
|
45
|
+
k as mergeTranslationsFromFallbackChain,
|
|
42
46
|
l as mergeTranslationsFromFallbackChainAsync,
|
|
43
47
|
L as normalizeConfiguredLocales,
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
i as resolveSourcePageName,
|
|
49
|
+
h as toPremergedStorageKey,
|
|
50
|
+
m as toSourceStorageKey
|
|
46
51
|
};
|
package/dist/normalize.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Translations } from '@i18n-micro/types';
|
|
2
2
|
/**
|
|
3
3
|
* Normalize unknown fetch/storage payloads into a plain translation object.
|
|
4
|
+
* Unstorage already runs `destr` on JSON files — strings are not expected here.
|
|
4
5
|
*/
|
|
5
6
|
export declare function toTranslations(data: unknown): Translations;
|
|
6
7
|
/**
|
package/dist/normalize.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Translations } from '@i18n-micro/types';
|
|
2
2
|
/**
|
|
3
3
|
* Normalize unknown fetch/storage payloads into a plain translation object.
|
|
4
|
+
* Unstorage already runs `destr` on JSON files — strings are not expected here.
|
|
4
5
|
*/
|
|
5
6
|
export declare function toTranslations(data: unknown): Translations;
|
|
6
7
|
/**
|
package/dist/payload-config.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("node:path"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("node:path"),s=500,n=10*1024*1024;function l(e){return e.translationPayloads?.mode==="source"?"source":"premerged"}function c(e){const a=l(e),r=a==="source";return{mode:a,serverAssets:e.translationPayloads?.serverAssets!==!1,serverHandler:e.translationPayloads?.serverHandler!==!1,publicAssets:r?e.translationPayloads?.publicAssets===!0:e.translationPayloads?.publicAssets!==!1,prerenderRoutes:e.translationPayloads?.prerenderRoutes===!0,publicDir:e.translationPayloads?.publicDir,warnFileCount:e.translationPayloads?.warnFileCount,warnSizeBytes:e.translationPayloads?.warnSizeBytes}}function o(e,a){const r=e.translationPayloads?.publicDir;return r!=null&&String(r).length>0?String(r).replace(/^\/+|\/+$/g,"").replace(/\/{2,}/g,"/")||"_locales":(a??e.apiBaseUrl??"_locales").replace(/^\/+|\/+$/g,"").replace(/\/{2,}/g,"/")||"_locales"}function y(e,a,r){return d.join(e??"./dist",o(a,r))}function P(e,a){return e.publicAssets?!0:a&&e.serverAssets}function p(e,a){return!a&&e.serverAssets}function A(e){return{warnFileCount:e?.warnFileCount??s,warnSizeBytes:e?.warnSizeBytes??n}}function i(e){return e.serverAssets||e.serverHandler||e.publicAssets||e.prerenderRoutes}function T(e){const a=[];return!e.translationPayloads.serverAssets&&!e.translationPayloads.publicAssets&&!e.apiBaseServerHost&&a.push("[nuxt-i18n-micro] translationPayloads.serverAssets and publicAssets are false and apiBaseServerHost is not set. SSR will load empty translations unless you provide an external server payload host."),i(e.translationPayloads)||(e.apiBaseServerHost||a.push("[nuxt-i18n-micro] translationPayloads disabled all local outputs but apiBaseServerHost is not set. SSR will load empty translations unless you provide an external server payload host."),e.apiBaseClientHost||a.push("[nuxt-i18n-micro] translationPayloads disabled all local outputs but apiBaseClientHost is not set. Client-side navigation may load empty translations unless you provide an external client payload host.")),a}function u(e){return e>=1024*1024?`${(e/(1024*1024)).toFixed(1)} MB`:e>=1024?`${(e/1024).toFixed(1)} KB`:`${e} B`}function v(e,a){const r=a?.warnFileCount??s,t=a?.warnSizeBytes??n;return e.fileCount<r&&e.totalBytes<t?null:`[nuxt-i18n-micro] Generated translation payloads are large (${e.fileCount} files, ${u(e.totalBytes)}). Consider translationPayloads.mode: 'source' for public output, hosting payloads externally, or disabling unused public/prerender outputs.`}exports.DEFAULT_TRANSLATION_PAYLOAD_WARN_FILE_COUNT=s;exports.DEFAULT_TRANSLATION_PAYLOAD_WARN_SIZE_BYTES=n;exports.formatBytes=u;exports.getTranslationPayloadMisconfigurationWarnings=T;exports.getTranslationPayloadSizeWarning=v;exports.hasLocalTranslationPayloadOutput=i;exports.resolveTranslationPayloadMode=l;exports.resolveTranslationPayloadOptions=c;exports.resolveTranslationPayloadPublicDir=y;exports.resolveTranslationPayloadPublicRel=o;exports.resolveTranslationPayloadWarningThresholds=A;exports.shouldCopyTranslationPayloadsToPublic=P;exports.shouldRegisterNitroServerAssets=p;
|
|
@@ -27,7 +27,21 @@ export declare const DEFAULT_TRANSLATION_PAYLOAD_WARN_FILE_COUNT = 500;
|
|
|
27
27
|
export declare const DEFAULT_TRANSLATION_PAYLOAD_WARN_SIZE_BYTES: number;
|
|
28
28
|
export declare function resolveTranslationPayloadMode(options: ModuleOptions): TranslationPayloadMode;
|
|
29
29
|
export declare function resolveTranslationPayloadOptions(options: ModuleOptions): ResolvedTranslationPayloadOptions;
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Public payload directory relative to Nitro's public root.
|
|
32
|
+
* Defaults to `apiBaseUrl` (`_locales`) so static files match client fetch URLs.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolveTranslationPayloadPublicRel(options: ModuleOptions, apiBaseUrl?: string): string;
|
|
35
|
+
export declare function resolveTranslationPayloadPublicDir(outputPublicDir: string | undefined, options: ModuleOptions, apiBaseUrl?: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* Whether production builds should copy the payload tree into Nitro public output.
|
|
38
|
+
* - `publicAssets: true` always copies (CDN / static clients).
|
|
39
|
+
* - On Node, `serverAssets: true` also forces a copy — SSR reads `public/` via fs (no Rollup `raw:`).
|
|
40
|
+
* - On Edge, `serverAssets` means Nitro `serverAssets` embed only — do not force a public tree.
|
|
41
|
+
*/
|
|
42
|
+
export declare function shouldCopyTranslationPayloadsToPublic(translationPayloads: ResolvedTranslationPayloadOptions, isNode: boolean): boolean;
|
|
43
|
+
/** Edge-only: register Nitro `serverAssets` (`assets:i18n`) when local SSR payloads are enabled. */
|
|
44
|
+
export declare function shouldRegisterNitroServerAssets(translationPayloads: ResolvedTranslationPayloadOptions, isNode: boolean): boolean;
|
|
31
45
|
export declare function resolveTranslationPayloadWarningThresholds(options?: TranslationPayloadOptions): Required<TranslationPayloadSizeThresholds>;
|
|
32
46
|
export declare function hasLocalTranslationPayloadOutput(translationPayloads: ResolvedTranslationPayloadOptions): boolean;
|
|
33
47
|
export declare function getTranslationPayloadMisconfigurationWarnings(input: TranslationPayloadMisconfigurationInput): string[];
|
package/dist/payload-config.d.ts
CHANGED
|
@@ -27,7 +27,21 @@ export declare const DEFAULT_TRANSLATION_PAYLOAD_WARN_FILE_COUNT = 500;
|
|
|
27
27
|
export declare const DEFAULT_TRANSLATION_PAYLOAD_WARN_SIZE_BYTES: number;
|
|
28
28
|
export declare function resolveTranslationPayloadMode(options: ModuleOptions): TranslationPayloadMode;
|
|
29
29
|
export declare function resolveTranslationPayloadOptions(options: ModuleOptions): ResolvedTranslationPayloadOptions;
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Public payload directory relative to Nitro's public root.
|
|
32
|
+
* Defaults to `apiBaseUrl` (`_locales`) so static files match client fetch URLs.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolveTranslationPayloadPublicRel(options: ModuleOptions, apiBaseUrl?: string): string;
|
|
35
|
+
export declare function resolveTranslationPayloadPublicDir(outputPublicDir: string | undefined, options: ModuleOptions, apiBaseUrl?: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* Whether production builds should copy the payload tree into Nitro public output.
|
|
38
|
+
* - `publicAssets: true` always copies (CDN / static clients).
|
|
39
|
+
* - On Node, `serverAssets: true` also forces a copy — SSR reads `public/` via fs (no Rollup `raw:`).
|
|
40
|
+
* - On Edge, `serverAssets` means Nitro `serverAssets` embed only — do not force a public tree.
|
|
41
|
+
*/
|
|
42
|
+
export declare function shouldCopyTranslationPayloadsToPublic(translationPayloads: ResolvedTranslationPayloadOptions, isNode: boolean): boolean;
|
|
43
|
+
/** Edge-only: register Nitro `serverAssets` (`assets:i18n`) when local SSR payloads are enabled. */
|
|
44
|
+
export declare function shouldRegisterNitroServerAssets(translationPayloads: ResolvedTranslationPayloadOptions, isNode: boolean): boolean;
|
|
31
45
|
export declare function resolveTranslationPayloadWarningThresholds(options?: TranslationPayloadOptions): Required<TranslationPayloadSizeThresholds>;
|
|
32
46
|
export declare function hasLocalTranslationPayloadOutput(translationPayloads: ResolvedTranslationPayloadOptions): boolean;
|
|
33
47
|
export declare function getTranslationPayloadMisconfigurationWarnings(input: TranslationPayloadMisconfigurationInput): string[];
|
package/dist/payload-config.mjs
CHANGED
|
@@ -1,59 +1,74 @@
|
|
|
1
1
|
import { join as l } from "node:path";
|
|
2
|
-
const
|
|
3
|
-
function o(
|
|
4
|
-
return
|
|
2
|
+
const n = 500, t = 10 * 1024 * 1024;
|
|
3
|
+
function o(e) {
|
|
4
|
+
return e.translationPayloads?.mode === "source" ? "source" : "premerged";
|
|
5
5
|
}
|
|
6
|
-
function
|
|
7
|
-
const
|
|
6
|
+
function y(e) {
|
|
7
|
+
const a = o(e), r = a === "source";
|
|
8
8
|
return {
|
|
9
|
-
mode:
|
|
10
|
-
serverAssets:
|
|
11
|
-
serverHandler:
|
|
12
|
-
publicAssets:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
mode: a,
|
|
10
|
+
serverAssets: e.translationPayloads?.serverAssets !== !1,
|
|
11
|
+
serverHandler: e.translationPayloads?.serverHandler !== !1,
|
|
12
|
+
publicAssets: r ? e.translationPayloads?.publicAssets === !0 : e.translationPayloads?.publicAssets !== !1,
|
|
13
|
+
// Off by default: prerendering `/_locales` without a live handler writes empty public stubs.
|
|
14
|
+
// Opt in when you need static `/{apiBaseUrl}/.../data.json` and payloads are already available.
|
|
15
|
+
prerenderRoutes: e.translationPayloads?.prerenderRoutes === !0,
|
|
16
|
+
publicDir: e.translationPayloads?.publicDir,
|
|
17
|
+
warnFileCount: e.translationPayloads?.warnFileCount,
|
|
18
|
+
warnSizeBytes: e.translationPayloads?.warnSizeBytes
|
|
17
19
|
};
|
|
18
20
|
}
|
|
19
|
-
function
|
|
20
|
-
const
|
|
21
|
-
return
|
|
21
|
+
function i(e, a) {
|
|
22
|
+
const r = e.translationPayloads?.publicDir;
|
|
23
|
+
return r != null && String(r).length > 0 ? String(r).replace(/^\/+|\/+$/g, "").replace(/\/{2,}/g, "/") || "_locales" : (a ?? e.apiBaseUrl ?? "_locales").replace(/^\/+|\/+$/g, "").replace(/\/{2,}/g, "/") || "_locales";
|
|
22
24
|
}
|
|
23
|
-
function
|
|
25
|
+
function p(e, a, r) {
|
|
26
|
+
return l(e ?? "./dist", i(a, r));
|
|
27
|
+
}
|
|
28
|
+
function f(e, a) {
|
|
29
|
+
return e.publicAssets ? !0 : a && e.serverAssets;
|
|
30
|
+
}
|
|
31
|
+
function v(e, a) {
|
|
32
|
+
return !a && e.serverAssets;
|
|
33
|
+
}
|
|
34
|
+
function A(e) {
|
|
24
35
|
return {
|
|
25
|
-
warnFileCount:
|
|
26
|
-
warnSizeBytes:
|
|
36
|
+
warnFileCount: e?.warnFileCount ?? n,
|
|
37
|
+
warnSizeBytes: e?.warnSizeBytes ?? t
|
|
27
38
|
};
|
|
28
39
|
}
|
|
29
|
-
function u(
|
|
30
|
-
return
|
|
40
|
+
function u(e) {
|
|
41
|
+
return e.serverAssets || e.serverHandler || e.publicAssets || e.prerenderRoutes;
|
|
31
42
|
}
|
|
32
|
-
function P(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
43
|
+
function P(e) {
|
|
44
|
+
const a = [];
|
|
45
|
+
return !e.translationPayloads.serverAssets && !e.translationPayloads.publicAssets && !e.apiBaseServerHost && a.push(
|
|
46
|
+
"[nuxt-i18n-micro] translationPayloads.serverAssets and publicAssets are false and apiBaseServerHost is not set. SSR will load empty translations unless you provide an external server payload host."
|
|
47
|
+
), u(e.translationPayloads) || (e.apiBaseServerHost || a.push(
|
|
36
48
|
"[nuxt-i18n-micro] translationPayloads disabled all local outputs but apiBaseServerHost is not set. SSR will load empty translations unless you provide an external server payload host."
|
|
37
|
-
),
|
|
49
|
+
), e.apiBaseClientHost || a.push(
|
|
38
50
|
"[nuxt-i18n-micro] translationPayloads disabled all local outputs but apiBaseClientHost is not set. Client-side navigation may load empty translations unless you provide an external client payload host."
|
|
39
|
-
),
|
|
51
|
+
)), a;
|
|
40
52
|
}
|
|
41
|
-
function d(
|
|
42
|
-
return
|
|
53
|
+
function d(e) {
|
|
54
|
+
return e >= 1024 * 1024 ? `${(e / (1024 * 1024)).toFixed(1)} MB` : e >= 1024 ? `${(e / 1024).toFixed(1)} KB` : `${e} B`;
|
|
43
55
|
}
|
|
44
|
-
function
|
|
45
|
-
const
|
|
46
|
-
return
|
|
56
|
+
function S(e, a) {
|
|
57
|
+
const r = a?.warnFileCount ?? n, s = a?.warnSizeBytes ?? t;
|
|
58
|
+
return e.fileCount < r && e.totalBytes < s ? null : `[nuxt-i18n-micro] Generated translation payloads are large (${e.fileCount} files, ${d(e.totalBytes)}). Consider translationPayloads.mode: 'source' for public output, hosting payloads externally, or disabling unused public/prerender outputs.`;
|
|
47
59
|
}
|
|
48
60
|
export {
|
|
49
|
-
|
|
61
|
+
n as DEFAULT_TRANSLATION_PAYLOAD_WARN_FILE_COUNT,
|
|
50
62
|
t as DEFAULT_TRANSLATION_PAYLOAD_WARN_SIZE_BYTES,
|
|
51
63
|
d as formatBytes,
|
|
52
64
|
P as getTranslationPayloadMisconfigurationWarnings,
|
|
53
|
-
|
|
65
|
+
S as getTranslationPayloadSizeWarning,
|
|
54
66
|
u as hasLocalTranslationPayloadOutput,
|
|
55
67
|
o as resolveTranslationPayloadMode,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
68
|
+
y as resolveTranslationPayloadOptions,
|
|
69
|
+
p as resolveTranslationPayloadPublicDir,
|
|
70
|
+
i as resolveTranslationPayloadPublicRel,
|
|
71
|
+
A as resolveTranslationPayloadWarningThresholds,
|
|
72
|
+
f as shouldCopyTranslationPayloadsToPublic,
|
|
73
|
+
v as shouldRegisterNitroServerAssets
|
|
59
74
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function l(e){return e.iso?.trim()||String(e.code)}function u(e){const r=e.match(/^([A-Za-z]{2,3})(?:[-_](.+))?$/);return r?{language:r[1],region:r[2]}:{language:e}}function d(e,r={}){const{hreflangBaseLanguage:f=!1}=r;if(!f)return e.map(t=>{const o=String(t.code);return{hreflang:l(t),localeCode:o}});const s=new Map;for(const t of e){const o=String(t.code),a=l(t),{language:n,region:i}=u(a);n&&i&&!s.has(n)&&s.set(n,o),s.set(a,o)}const g=new Set,c=[];for(const t of e){const o=String(t.code),a=l(t),{language:n,region:i}=u(a);n&&i&&s.get(n)===o&&!g.has(n)&&(g.add(n),c.push({hreflang:n,localeCode:o})),g.has(a)||(g.add(a),c.push({hreflang:a,localeCode:o}))}return c}exports.resolveHreflangAlternates=d;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Locale } from '@i18n-micro/types';
|
|
2
|
+
export type HreflangLocaleInput = Pick<Locale, 'code' | 'iso'>;
|
|
3
|
+
export interface ResolveHreflangAlternatesOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Also emit a bare-language `hreflang` derived from `iso` (e.g. `es-ES` → `es`),
|
|
6
|
+
* claimed by the first regional locale in the list for that language.
|
|
7
|
+
* Never derived from routing `code`.
|
|
8
|
+
* @default false
|
|
9
|
+
*/
|
|
10
|
+
hreflangBaseLanguage?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface HreflangAlternate {
|
|
13
|
+
/** Value for the `hreflang` attribute (BCP-47 / `iso || code`). */
|
|
14
|
+
hreflang: string;
|
|
15
|
+
/** Locale `code` whose localized URL should back this tag. */
|
|
16
|
+
localeCode: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Resolve `hreflang` values for SEO alternate links.
|
|
20
|
+
* Uses `iso || code` — never emits routing `code` when `iso` is set (#243).
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveHreflangAlternates(locales: HreflangLocaleInput[], options?: ResolveHreflangAlternatesOptions): HreflangAlternate[];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Locale } from '@i18n-micro/types';
|
|
2
|
+
export type HreflangLocaleInput = Pick<Locale, 'code' | 'iso'>;
|
|
3
|
+
export interface ResolveHreflangAlternatesOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Also emit a bare-language `hreflang` derived from `iso` (e.g. `es-ES` → `es`),
|
|
6
|
+
* claimed by the first regional locale in the list for that language.
|
|
7
|
+
* Never derived from routing `code`.
|
|
8
|
+
* @default false
|
|
9
|
+
*/
|
|
10
|
+
hreflangBaseLanguage?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface HreflangAlternate {
|
|
13
|
+
/** Value for the `hreflang` attribute (BCP-47 / `iso || code`). */
|
|
14
|
+
hreflang: string;
|
|
15
|
+
/** Locale `code` whose localized URL should back this tag. */
|
|
16
|
+
localeCode: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Resolve `hreflang` values for SEO alternate links.
|
|
20
|
+
* Uses `iso || code` — never emits routing `code` when `iso` is set (#243).
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveHreflangAlternates(locales: HreflangLocaleInput[], options?: ResolveHreflangAlternatesOptions): HreflangAlternate[];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
function u(n) {
|
|
2
|
+
return n.iso?.trim() || String(n.code);
|
|
3
|
+
}
|
|
4
|
+
function f(n) {
|
|
5
|
+
const r = n.match(/^([A-Za-z]{2,3})(?:[-_](.+))?$/);
|
|
6
|
+
return r ? { language: r[1], region: r[2] } : { language: n };
|
|
7
|
+
}
|
|
8
|
+
function d(n, r = {}) {
|
|
9
|
+
const { hreflangBaseLanguage: l = !1 } = r;
|
|
10
|
+
if (!l)
|
|
11
|
+
return n.map((o) => {
|
|
12
|
+
const t = String(o.code);
|
|
13
|
+
return { hreflang: u(o), localeCode: t };
|
|
14
|
+
});
|
|
15
|
+
const g = /* @__PURE__ */ new Map();
|
|
16
|
+
for (const o of n) {
|
|
17
|
+
const t = String(o.code), a = u(o), { language: e, region: i } = f(a);
|
|
18
|
+
e && i && !g.has(e) && g.set(e, t), g.set(a, t);
|
|
19
|
+
}
|
|
20
|
+
const s = /* @__PURE__ */ new Set(), c = [];
|
|
21
|
+
for (const o of n) {
|
|
22
|
+
const t = String(o.code), a = u(o), { language: e, region: i } = f(a);
|
|
23
|
+
e && i && g.get(e) === t && !s.has(e) && (s.add(e), c.push({ hreflang: e, localeCode: t })), s.has(a) || (s.add(a), c.push({ hreflang: a, localeCode: t }));
|
|
24
|
+
}
|
|
25
|
+
return c;
|
|
26
|
+
}
|
|
27
|
+
export {
|
|
28
|
+
d as resolveHreflangAlternates
|
|
29
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function a(s){const o=[],n={},r=new Set;for(const t of s){const e=t.name?.trim();if(!e)throw new Error("[splitLocaleRoutes] each entry needs a non-empty `name`");if(!t.path)throw new Error(`[splitLocaleRoutes] entry "${e}" needs a \`path\``);if(!t.file)throw new Error(`[splitLocaleRoutes] entry "${e}" needs a \`file\``);if(r.has(e))throw new Error(`[splitLocaleRoutes] duplicate route name "${e}"`);r.add(e),o.push({name:e,path:t.path,file:t.file}),t.paths!==void 0&&(n[e]=t.paths)}return{pages:o,globalLocaleRoutes:n}}exports.splitLocaleRoutes=a;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { GlobalLocaleRoutes, LocaleCode } from '@i18n-micro/types';
|
|
2
|
+
/**
|
|
3
|
+
* One programmatic route entry for {@link splitLocaleRoutes} (#244).
|
|
4
|
+
* Prefer route `name` as the `globalLocaleRoutes` key so shared wrapper SFCs do not collapse.
|
|
5
|
+
*/
|
|
6
|
+
export interface SplitLocaleRouteEntry {
|
|
7
|
+
/** Route name — also the key in `globalLocaleRoutes`. */
|
|
8
|
+
name: string;
|
|
9
|
+
/** Default (unlocalized) path pushed into `pages:extend`. */
|
|
10
|
+
path: string;
|
|
11
|
+
/** Page component / wrapper SFC (Nuxt `file`). */
|
|
12
|
+
file: string;
|
|
13
|
+
/**
|
|
14
|
+
* Custom per-locale paths, or `false` to disable localization for this route.
|
|
15
|
+
* Omitted → route is still pushed to `pages`, but no `globalLocaleRoutes` entry.
|
|
16
|
+
*/
|
|
17
|
+
paths?: Record<LocaleCode, string> | false;
|
|
18
|
+
}
|
|
19
|
+
export interface SplitLocaleRoutePage {
|
|
20
|
+
name: string;
|
|
21
|
+
path: string;
|
|
22
|
+
file: string;
|
|
23
|
+
}
|
|
24
|
+
export interface SplitLocaleRoutesResult {
|
|
25
|
+
/** Pass into `pages:extend`: `pages.push(...pages)`. */
|
|
26
|
+
pages: SplitLocaleRoutePage[];
|
|
27
|
+
/** Merge into `i18n.globalLocaleRoutes` (keyed by route name). */
|
|
28
|
+
globalLocaleRoutes: NonNullable<GlobalLocaleRoutes>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Split one programmatic route registry into Nuxt pages + `globalLocaleRoutes` (#244).
|
|
32
|
+
*
|
|
33
|
+
* Keeps both halves in sync and keys locale paths by route **name** (not file path),
|
|
34
|
+
* so N routes sharing one wrapper SFC do not overwrite each other.
|
|
35
|
+
*/
|
|
36
|
+
export declare function splitLocaleRoutes(entries: readonly SplitLocaleRouteEntry[]): SplitLocaleRoutesResult;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { GlobalLocaleRoutes, LocaleCode } from '@i18n-micro/types';
|
|
2
|
+
/**
|
|
3
|
+
* One programmatic route entry for {@link splitLocaleRoutes} (#244).
|
|
4
|
+
* Prefer route `name` as the `globalLocaleRoutes` key so shared wrapper SFCs do not collapse.
|
|
5
|
+
*/
|
|
6
|
+
export interface SplitLocaleRouteEntry {
|
|
7
|
+
/** Route name — also the key in `globalLocaleRoutes`. */
|
|
8
|
+
name: string;
|
|
9
|
+
/** Default (unlocalized) path pushed into `pages:extend`. */
|
|
10
|
+
path: string;
|
|
11
|
+
/** Page component / wrapper SFC (Nuxt `file`). */
|
|
12
|
+
file: string;
|
|
13
|
+
/**
|
|
14
|
+
* Custom per-locale paths, or `false` to disable localization for this route.
|
|
15
|
+
* Omitted → route is still pushed to `pages`, but no `globalLocaleRoutes` entry.
|
|
16
|
+
*/
|
|
17
|
+
paths?: Record<LocaleCode, string> | false;
|
|
18
|
+
}
|
|
19
|
+
export interface SplitLocaleRoutePage {
|
|
20
|
+
name: string;
|
|
21
|
+
path: string;
|
|
22
|
+
file: string;
|
|
23
|
+
}
|
|
24
|
+
export interface SplitLocaleRoutesResult {
|
|
25
|
+
/** Pass into `pages:extend`: `pages.push(...pages)`. */
|
|
26
|
+
pages: SplitLocaleRoutePage[];
|
|
27
|
+
/** Merge into `i18n.globalLocaleRoutes` (keyed by route name). */
|
|
28
|
+
globalLocaleRoutes: NonNullable<GlobalLocaleRoutes>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Split one programmatic route registry into Nuxt pages + `globalLocaleRoutes` (#244).
|
|
32
|
+
*
|
|
33
|
+
* Keeps both halves in sync and keys locale paths by route **name** (not file path),
|
|
34
|
+
* so N routes sharing one wrapper SFC do not overwrite each other.
|
|
35
|
+
*/
|
|
36
|
+
export declare function splitLocaleRoutes(entries: readonly SplitLocaleRouteEntry[]): SplitLocaleRoutesResult;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function s(a) {
|
|
2
|
+
const o = [], n = {}, r = /* @__PURE__ */ new Set();
|
|
3
|
+
for (const t of a) {
|
|
4
|
+
const e = t.name?.trim();
|
|
5
|
+
if (!e)
|
|
6
|
+
throw new Error("[splitLocaleRoutes] each entry needs a non-empty `name`");
|
|
7
|
+
if (!t.path)
|
|
8
|
+
throw new Error(`[splitLocaleRoutes] entry "${e}" needs a \`path\``);
|
|
9
|
+
if (!t.file)
|
|
10
|
+
throw new Error(`[splitLocaleRoutes] entry "${e}" needs a \`file\``);
|
|
11
|
+
if (r.has(e))
|
|
12
|
+
throw new Error(`[splitLocaleRoutes] duplicate route name "${e}"`);
|
|
13
|
+
r.add(e), o.push({ name: e, path: t.path, file: t.file }), t.paths !== void 0 && (n[e] = t.paths);
|
|
14
|
+
}
|
|
15
|
+
return { pages: o, globalLocaleRoutes: n };
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
s as splitLocaleRoutes
|
|
19
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@i18n-micro/utils",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "Framework-agnostic utilities for Nuxt I18n Micro (granular subpath imports).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"i18n",
|
|
@@ -165,6 +165,36 @@
|
|
|
165
165
|
},
|
|
166
166
|
"default": "./dist/resolve-locale.mjs"
|
|
167
167
|
},
|
|
168
|
+
"./auto-detect-path": {
|
|
169
|
+
"production": {
|
|
170
|
+
"types": "./dist/auto-detect-path.d.ts",
|
|
171
|
+
"default": "./dist/auto-detect-path.mjs"
|
|
172
|
+
},
|
|
173
|
+
"import": {
|
|
174
|
+
"types": "./dist/auto-detect-path.d.ts",
|
|
175
|
+
"default": "./dist/auto-detect-path.mjs"
|
|
176
|
+
},
|
|
177
|
+
"require": {
|
|
178
|
+
"types": "./dist/auto-detect-path.d.cts",
|
|
179
|
+
"default": "./dist/auto-detect-path.cjs"
|
|
180
|
+
},
|
|
181
|
+
"default": "./dist/auto-detect-path.mjs"
|
|
182
|
+
},
|
|
183
|
+
"./split-locale-routes": {
|
|
184
|
+
"production": {
|
|
185
|
+
"types": "./dist/split-locale-routes.d.ts",
|
|
186
|
+
"default": "./dist/split-locale-routes.mjs"
|
|
187
|
+
},
|
|
188
|
+
"import": {
|
|
189
|
+
"types": "./dist/split-locale-routes.d.ts",
|
|
190
|
+
"default": "./dist/split-locale-routes.mjs"
|
|
191
|
+
},
|
|
192
|
+
"require": {
|
|
193
|
+
"types": "./dist/split-locale-routes.d.cts",
|
|
194
|
+
"default": "./dist/split-locale-routes.cjs"
|
|
195
|
+
},
|
|
196
|
+
"default": "./dist/split-locale-routes.mjs"
|
|
197
|
+
},
|
|
168
198
|
"./resolve-og-locale": {
|
|
169
199
|
"production": {
|
|
170
200
|
"types": "./dist/resolve-og-locale.d.ts",
|
|
@@ -180,6 +210,21 @@
|
|
|
180
210
|
},
|
|
181
211
|
"default": "./dist/resolve-og-locale.mjs"
|
|
182
212
|
},
|
|
213
|
+
"./resolve-hreflang": {
|
|
214
|
+
"production": {
|
|
215
|
+
"types": "./dist/resolve-hreflang.d.ts",
|
|
216
|
+
"default": "./dist/resolve-hreflang.mjs"
|
|
217
|
+
},
|
|
218
|
+
"import": {
|
|
219
|
+
"types": "./dist/resolve-hreflang.d.ts",
|
|
220
|
+
"default": "./dist/resolve-hreflang.mjs"
|
|
221
|
+
},
|
|
222
|
+
"require": {
|
|
223
|
+
"types": "./dist/resolve-hreflang.d.cts",
|
|
224
|
+
"default": "./dist/resolve-hreflang.cjs"
|
|
225
|
+
},
|
|
226
|
+
"default": "./dist/resolve-hreflang.mjs"
|
|
227
|
+
},
|
|
183
228
|
"./merge-i18n-head": {
|
|
184
229
|
"production": {
|
|
185
230
|
"types": "./dist/merge-i18n-head.d.ts",
|
|
@@ -353,14 +398,14 @@
|
|
|
353
398
|
},
|
|
354
399
|
"dependencies": {
|
|
355
400
|
"globby": "^14.1.0",
|
|
356
|
-
"@i18n-micro/types": "1.2.
|
|
401
|
+
"@i18n-micro/types": "^1.2.10"
|
|
357
402
|
},
|
|
358
403
|
"devDependencies": {
|
|
359
404
|
"publint": "^0.3.17",
|
|
360
405
|
"vite": "^7.3.6",
|
|
361
406
|
"vite-plugin-dts": "^4.5.4",
|
|
362
407
|
"vitest": "^4.1.10",
|
|
363
|
-
"@i18n-micro/test-utils": "1.2.
|
|
408
|
+
"@i18n-micro/test-utils": "^1.2.8"
|
|
364
409
|
},
|
|
365
410
|
"engines": {
|
|
366
411
|
"node": ">=18"
|