@i18n-micro/utils 1.0.7 → 1.0.11
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/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/cache-control.cjs +1 -1
- package/dist/cache-control.mjs +1 -1
- package/dist/deep-merge.cjs +1 -1
- package/dist/deep-merge.mjs +16 -16
- 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/payload-stats.cjs +1 -1
- package/dist/payload-stats.d.cts +30 -0
- package/dist/payload-stats.d.ts +30 -0
- package/dist/payload-stats.mjs +48 -13
- package/dist/payload-url.cjs +1 -1
- package/dist/payload-url.d.cts +12 -0
- package/dist/payload-url.d.ts +12 -0
- package/dist/payload-url.mjs +10 -5
- package/package.json +6 -6
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/cache-control.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class s{constructor(t){this.cache=new Map,this.expiry=new Map,this.maxSize=0,this.ttlMs=0,t&&this.configure(t)}configure(t){this.maxSize=t.maxSize??0,this.ttlMs=(t.ttl??0)*1e3,this.ttlMs===0&&this.expiry.clear()}get(t){const e=this.cache.get(t);if(e!==void 0){if(this.ttlMs>0){const i=this.expiry.get(t);if(i&&Date.now()>i){this.delete(t);return}this.expiry.set(t,Date.now()+this.ttlMs)}return this.cache.delete(t),this.cache.set(t,e),e}}has(t){if(!this.cache.has(t))return!1;if(this.ttlMs>0){const e=this.expiry.get(t);if(e&&Date.now()>e)return this.delete(t),!1}return!0}set(t,e){if(this.cache.has(t))this.cache.delete(t);else if(this.maxSize>0&&this.cache.size>=this.maxSize){const i=this.cache.keys().next().value;i!==void 0&&this.delete(i)}this.cache.set(t,e),this.ttlMs>0&&this.expiry.set(t,Date.now()+this.ttlMs)}delete(t){return this.expiry.delete(t),this.cache.delete(t)}clear(){this.cache.clear(),this.expiry.clear()}keys(){return this.cache.keys()}get size(){return this.cache.size}}exports.CacheControl=s;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class s{constructor(t){this.cache=new Map,this.expiry=new Map,this.maxSize=0,this.ttlMs=0,t&&this.configure(t)}configure(t){this.maxSize=t.maxSize??0,this.ttlMs=(t.ttl??0)*1e3,this.ttlMs===0&&this.expiry.clear()}get(t){const e=this.cache.get(t);if(e!==void 0){if(this.ttlMs>0){const i=this.expiry.get(t);if(i&&Date.now()>i){this.delete(t);return}this.expiry.set(t,Date.now()+this.ttlMs)}return this.maxSize>0&&(this.cache.delete(t),this.cache.set(t,e)),e}}has(t){if(!this.cache.has(t))return!1;if(this.ttlMs>0){const e=this.expiry.get(t);if(e&&Date.now()>e)return this.delete(t),!1}return!0}set(t,e){if(this.cache.has(t))this.cache.delete(t);else if(this.maxSize>0&&this.cache.size>=this.maxSize){const i=this.cache.keys().next().value;i!==void 0&&this.delete(i)}this.cache.set(t,e),this.ttlMs>0&&this.expiry.set(t,Date.now()+this.ttlMs)}delete(t){return this.expiry.delete(t),this.cache.delete(t)}clear(){this.cache.clear(),this.expiry.clear()}keys(){return this.cache.keys()}get size(){return this.cache.size}}exports.CacheControl=s;
|
package/dist/cache-control.mjs
CHANGED
package/dist/deep-merge.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function i(s,
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function i(s,n){const r={...s};for(const e of Object.keys(n)){if(e==="__proto__")continue;const t=n[e],o=r[e];t!==null&&typeof t=="object"&&!Array.isArray(t)&&o!==null&&typeof o=="object"&&!Array.isArray(o)?r[e]={...o,...t}:r[e]=t}return r}function c(s,n){if(!s||Object.keys(s).length===0)return{...n};const r={...s};for(const e of Object.keys(n)){if(e==="__proto__")continue;const t=n[e],o=r[e];t&&typeof t=="object"&&!Array.isArray(t)&&o&&typeof o=="object"&&!Array.isArray(o)?r[e]=c(o,t):r[e]=t}return r}exports.deepMergeTranslations=i;exports.deepMergeTranslationsRecursive=c;
|
package/dist/deep-merge.mjs
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
function
|
|
2
|
-
const
|
|
3
|
-
for (const
|
|
4
|
-
if (
|
|
5
|
-
const
|
|
6
|
-
|
|
1
|
+
function y(s, n) {
|
|
2
|
+
const r = { ...s };
|
|
3
|
+
for (const e of Object.keys(n)) {
|
|
4
|
+
if (e === "__proto__") continue;
|
|
5
|
+
const t = n[e], o = r[e];
|
|
6
|
+
t !== null && typeof t == "object" && !Array.isArray(t) && o !== null && typeof o == "object" && !Array.isArray(o) ? r[e] = { ...o, ...t } : r[e] = t;
|
|
7
7
|
}
|
|
8
|
-
return
|
|
8
|
+
return r;
|
|
9
9
|
}
|
|
10
|
-
function c(s,
|
|
11
|
-
if (!s || Object.keys(s).length === 0) return { ...
|
|
12
|
-
const
|
|
13
|
-
for (const
|
|
14
|
-
if (
|
|
15
|
-
const
|
|
16
|
-
|
|
10
|
+
function c(s, n) {
|
|
11
|
+
if (!s || Object.keys(s).length === 0) return { ...n };
|
|
12
|
+
const r = { ...s };
|
|
13
|
+
for (const e of Object.keys(n)) {
|
|
14
|
+
if (e === "__proto__") continue;
|
|
15
|
+
const t = n[e], o = r[e];
|
|
16
|
+
t && typeof t == "object" && !Array.isArray(t) && o && typeof o == "object" && !Array.isArray(o) ? r[e] = c(o, t) : r[e] = t;
|
|
17
17
|
}
|
|
18
|
-
return
|
|
18
|
+
return r;
|
|
19
19
|
}
|
|
20
20
|
export {
|
|
21
|
-
|
|
21
|
+
y as deepMergeTranslations,
|
|
22
22
|
c as deepMergeTranslationsRecursive
|
|
23
23
|
};
|
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
|
};
|
package/dist/payload-stats.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("node:fs"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=require("node:crypto"),o=require("node:fs"),l=require("node:zlib"),u=require("node:path");function f(n,t){for(const e of o.readdirSync(n,{withFileTypes:!0})){const s=u.join(n,e.name);e.isDirectory()?f(s,t):e.name.endsWith(".json")&&t.push(s)}}function S(n){const t={fileCount:0,totalBytes:0};if(!o.existsSync(n))return t;const e=[];f(n,e);for(const s of e)t.fileCount+=1,t.totalBytes+=o.statSync(s).size;return t}function d(n,t){const e=y.createHash("sha256");let s=0;for(const c of n){const a=u.join(c,t);if(!o.existsSync(a))continue;const r=[];f(a,r),r.sort();for(const i of r)e.update(u.relative(a,i)),e.update("\0"),e.update(o.readFileSync(i)),s+=1}return s>0?e.digest("hex").slice(0,16):null}const h=1024;function T(n,t){if(!t||!o.existsSync(n))return 0;const e=t===!0||t.gzip!==!1,s=t===!0||t.brotli!==!1;if(!e&&!s)return 0;const c=[];f(n,c);let a=0;for(const r of c){const i=o.readFileSync(r);i.length<h||(e&&o.writeFileSync(`${r}.gz`,l.gzipSync(i,{level:9})),s&&o.writeFileSync(`${r}.br`,l.brotliCompressSync(i,{params:{[l.constants.BROTLI_PARAM_QUALITY]:11,[l.constants.BROTLI_PARAM_SIZE_HINT]:i.length}})),a+=1)}return a}exports.compressTranslationPayloads=T;exports.hashTranslationSources=d;exports.scanTranslationPayloadDirectory=S;
|
package/dist/payload-stats.d.cts
CHANGED
|
@@ -1,2 +1,32 @@
|
|
|
1
1
|
import { TranslationPayloadStats } from './payload-config';
|
|
2
2
|
export declare function scanTranslationPayloadDirectory(dir: string): TranslationPayloadStats;
|
|
3
|
+
/**
|
|
4
|
+
* Fingerprint of the translation sources, used to cache-bust `_locales` requests.
|
|
5
|
+
*
|
|
6
|
+
* The alternative — a build timestamp — changes on every deploy, so browsers and CDNs
|
|
7
|
+
* throw away a dictionary that may not have changed at all. Hashing the sources means
|
|
8
|
+
* the URL only moves when the translations actually move.
|
|
9
|
+
*
|
|
10
|
+
* Layer order matters (later layers override earlier ones), so paths are hashed in the
|
|
11
|
+
* order given and relative to their own root: an identical tree checked out elsewhere
|
|
12
|
+
* must produce the same value.
|
|
13
|
+
*
|
|
14
|
+
* Returns `null` when there is nothing to hash, leaving the caller to fall back.
|
|
15
|
+
*/
|
|
16
|
+
export declare function hashTranslationSources(rootDirs: string[], translationDirName: string): string | null;
|
|
17
|
+
/** Nitro's `compressPublicAssets`: `true` means both encodings, an object selects them. */
|
|
18
|
+
export type PublicAssetCompression = boolean | {
|
|
19
|
+
gzip?: boolean;
|
|
20
|
+
brotli?: boolean;
|
|
21
|
+
} | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Gzip/brotli the translation payloads copied into the public directory.
|
|
24
|
+
*
|
|
25
|
+
* Nitro compresses public assets before the `nitro:build:public-assets` hook where the
|
|
26
|
+
* payloads are copied, so `compressPublicAssets` never reaches them — a static host
|
|
27
|
+
* would serve the single largest part of the output uncompressed. This applies the
|
|
28
|
+
* user's setting to those files; it does not turn compression on by itself.
|
|
29
|
+
*
|
|
30
|
+
* Returns the number of files actually compressed.
|
|
31
|
+
*/
|
|
32
|
+
export declare function compressTranslationPayloads(dir: string, compression: PublicAssetCompression): number;
|
package/dist/payload-stats.d.ts
CHANGED
|
@@ -1,2 +1,32 @@
|
|
|
1
1
|
import { TranslationPayloadStats } from './payload-config';
|
|
2
2
|
export declare function scanTranslationPayloadDirectory(dir: string): TranslationPayloadStats;
|
|
3
|
+
/**
|
|
4
|
+
* Fingerprint of the translation sources, used to cache-bust `_locales` requests.
|
|
5
|
+
*
|
|
6
|
+
* The alternative — a build timestamp — changes on every deploy, so browsers and CDNs
|
|
7
|
+
* throw away a dictionary that may not have changed at all. Hashing the sources means
|
|
8
|
+
* the URL only moves when the translations actually move.
|
|
9
|
+
*
|
|
10
|
+
* Layer order matters (later layers override earlier ones), so paths are hashed in the
|
|
11
|
+
* order given and relative to their own root: an identical tree checked out elsewhere
|
|
12
|
+
* must produce the same value.
|
|
13
|
+
*
|
|
14
|
+
* Returns `null` when there is nothing to hash, leaving the caller to fall back.
|
|
15
|
+
*/
|
|
16
|
+
export declare function hashTranslationSources(rootDirs: string[], translationDirName: string): string | null;
|
|
17
|
+
/** Nitro's `compressPublicAssets`: `true` means both encodings, an object selects them. */
|
|
18
|
+
export type PublicAssetCompression = boolean | {
|
|
19
|
+
gzip?: boolean;
|
|
20
|
+
brotli?: boolean;
|
|
21
|
+
} | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Gzip/brotli the translation payloads copied into the public directory.
|
|
24
|
+
*
|
|
25
|
+
* Nitro compresses public assets before the `nitro:build:public-assets` hook where the
|
|
26
|
+
* payloads are copied, so `compressPublicAssets` never reaches them — a static host
|
|
27
|
+
* would serve the single largest part of the output uncompressed. This applies the
|
|
28
|
+
* user's setting to those files; it does not turn compression on by itself.
|
|
29
|
+
*
|
|
30
|
+
* Returns the number of files actually compressed.
|
|
31
|
+
*/
|
|
32
|
+
export declare function compressTranslationPayloads(dir: string, compression: PublicAssetCompression): number;
|
package/dist/payload-stats.mjs
CHANGED
|
@@ -1,19 +1,54 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
o.name.endsWith(".json") && (t.fileCount += 1, t.totalBytes += c(e).size);
|
|
1
|
+
import { createHash as p } from "node:crypto";
|
|
2
|
+
import { existsSync as c, readFileSync as y, writeFileSync as a, statSync as S, readdirSync as m } from "node:fs";
|
|
3
|
+
import { gzipSync as T, brotliCompressSync as d, constants as u } from "node:zlib";
|
|
4
|
+
import { join as h, relative as _ } from "node:path";
|
|
5
|
+
function f(n, t) {
|
|
6
|
+
for (const e of m(n, { withFileTypes: !0 })) {
|
|
7
|
+
const o = h(n, e.name);
|
|
8
|
+
e.isDirectory() ? f(o, t) : e.name.endsWith(".json") && t.push(o);
|
|
11
9
|
}
|
|
12
10
|
}
|
|
13
|
-
function
|
|
11
|
+
function A(n) {
|
|
14
12
|
const t = { fileCount: 0, totalBytes: 0 };
|
|
15
|
-
|
|
13
|
+
if (!c(n)) return t;
|
|
14
|
+
const e = [];
|
|
15
|
+
f(n, e);
|
|
16
|
+
for (const o of e)
|
|
17
|
+
t.fileCount += 1, t.totalBytes += S(o).size;
|
|
18
|
+
return t;
|
|
19
|
+
}
|
|
20
|
+
function B(n, t) {
|
|
21
|
+
const e = p("sha256");
|
|
22
|
+
let o = 0;
|
|
23
|
+
for (const l of n) {
|
|
24
|
+
const i = h(l, t);
|
|
25
|
+
if (!c(i)) continue;
|
|
26
|
+
const s = [];
|
|
27
|
+
f(i, s), s.sort();
|
|
28
|
+
for (const r of s)
|
|
29
|
+
e.update(_(i, r)), e.update("\0"), e.update(y(r)), o += 1;
|
|
30
|
+
}
|
|
31
|
+
return o > 0 ? e.digest("hex").slice(0, 16) : null;
|
|
32
|
+
}
|
|
33
|
+
const g = 1024;
|
|
34
|
+
function b(n, t) {
|
|
35
|
+
if (!t || !c(n)) return 0;
|
|
36
|
+
const e = t === !0 || t.gzip !== !1, o = t === !0 || t.brotli !== !1;
|
|
37
|
+
if (!e && !o) return 0;
|
|
38
|
+
const l = [];
|
|
39
|
+
f(n, l);
|
|
40
|
+
let i = 0;
|
|
41
|
+
for (const s of l) {
|
|
42
|
+
const r = y(s);
|
|
43
|
+
r.length < g || (e && a(`${s}.gz`, T(r, { level: 9 })), o && a(
|
|
44
|
+
`${s}.br`,
|
|
45
|
+
d(r, { params: { [u.BROTLI_PARAM_QUALITY]: 11, [u.BROTLI_PARAM_SIZE_HINT]: r.length } })
|
|
46
|
+
), i += 1);
|
|
47
|
+
}
|
|
48
|
+
return i;
|
|
16
49
|
}
|
|
17
50
|
export {
|
|
18
|
-
|
|
51
|
+
b as compressTranslationPayloads,
|
|
52
|
+
B as hashTranslationSources,
|
|
53
|
+
A as scanTranslationPayloadDirectory
|
|
19
54
|
};
|
package/dist/payload-url.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function r(a,e){const l=a||"index";return e?.[l]??l}function
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function r(a,e){const l=a||"index";return e?.[l]??l}function t(a,e,l){return`/${a.replace(/^\/+|\/+$/g,"")}/${e}/${l}/data.json`.replace(/\/{2,}/g,"/")}function n(a){return(a.isServer?a.apiBaseServerHost:a.apiBaseClientHost)??a.baseURL}function o(a){const e=r(a.routeName,a.routesLocaleLinks);return{path:t(a.apiBaseUrl,e,a.locale),baseURL:n(a),params:a.dateBuild?{v:a.dateBuild}:void 0}}function s(a,e=!0){const l=Math.floor(a??0);return!Number.isSafeInteger(l)||l<=0?null:e?`public, max-age=${l}, immutable`:"public, max-age=0, must-revalidate"}exports.buildTranslationPayloadCacheControl=s;exports.buildTranslationPayloadFetchRequest=o;exports.buildTranslationPayloadPath=t;exports.resolveTranslationPayloadBaseURL=n;exports.resolveTranslationPayloadPage=r;
|
package/dist/payload-url.d.cts
CHANGED
|
@@ -22,3 +22,15 @@ export declare function buildTranslationPayloadFetchRequest(input: TranslationPa
|
|
|
22
22
|
baseURL: string;
|
|
23
23
|
params?: Record<string, string | number>;
|
|
24
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* Builds `Cache-Control` for `/{apiBaseUrl}/:page/:locale/data.json`.
|
|
27
|
+
*
|
|
28
|
+
* `immutable` is only emitted when a cache-buster is active (`hasCacheBuster`),
|
|
29
|
+
* i.e. requests carry `?v=<dateBuild>`. Without a cache-buster (`dateBuild` set
|
|
30
|
+
* to `0`/`''`) the URL is stable across deploys, so we intentionally avoid
|
|
31
|
+
* long-lived caching by returning a conservative `max-age=0` policy.
|
|
32
|
+
*
|
|
33
|
+
* Returns `null` when caching should be skipped — non-positive or non-finite
|
|
34
|
+
* `duration` (guards `NaN`/`Infinity` from producing a malformed header).
|
|
35
|
+
*/
|
|
36
|
+
export declare function buildTranslationPayloadCacheControl(durationSeconds: number | undefined, hasCacheBuster?: boolean): string | null;
|
package/dist/payload-url.d.ts
CHANGED
|
@@ -22,3 +22,15 @@ export declare function buildTranslationPayloadFetchRequest(input: TranslationPa
|
|
|
22
22
|
baseURL: string;
|
|
23
23
|
params?: Record<string, string | number>;
|
|
24
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* Builds `Cache-Control` for `/{apiBaseUrl}/:page/:locale/data.json`.
|
|
27
|
+
*
|
|
28
|
+
* `immutable` is only emitted when a cache-buster is active (`hasCacheBuster`),
|
|
29
|
+
* i.e. requests carry `?v=<dateBuild>`. Without a cache-buster (`dateBuild` set
|
|
30
|
+
* to `0`/`''`) the URL is stable across deploys, so we intentionally avoid
|
|
31
|
+
* long-lived caching by returning a conservative `max-age=0` policy.
|
|
32
|
+
*
|
|
33
|
+
* Returns `null` when caching should be skipped — non-positive or non-finite
|
|
34
|
+
* `duration` (guards `NaN`/`Infinity` from producing a malformed header).
|
|
35
|
+
*/
|
|
36
|
+
export declare function buildTranslationPayloadCacheControl(durationSeconds: number | undefined, hasCacheBuster?: boolean): string | null;
|
package/dist/payload-url.mjs
CHANGED
|
@@ -5,20 +5,25 @@ function l(a, e) {
|
|
|
5
5
|
function n(a, e, r) {
|
|
6
6
|
return `/${a.replace(/^\/+|\/+$/g, "")}/${e}/${r}/data.json`.replace(/\/{2,}/g, "/");
|
|
7
7
|
}
|
|
8
|
-
function
|
|
8
|
+
function t(a) {
|
|
9
9
|
return (a.isServer ? a.apiBaseServerHost : a.apiBaseClientHost) ?? a.baseURL;
|
|
10
10
|
}
|
|
11
|
-
function
|
|
11
|
+
function s(a) {
|
|
12
12
|
const e = l(a.routeName, a.routesLocaleLinks);
|
|
13
13
|
return {
|
|
14
14
|
path: n(a.apiBaseUrl, e, a.locale),
|
|
15
|
-
baseURL:
|
|
15
|
+
baseURL: t(a),
|
|
16
16
|
params: a.dateBuild ? { v: a.dateBuild } : void 0
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
|
+
function i(a, e = !0) {
|
|
20
|
+
const r = Math.floor(a ?? 0);
|
|
21
|
+
return !Number.isSafeInteger(r) || r <= 0 ? null : e ? `public, max-age=${r}, immutable` : "public, max-age=0, must-revalidate";
|
|
22
|
+
}
|
|
19
23
|
export {
|
|
20
|
-
|
|
24
|
+
i as buildTranslationPayloadCacheControl,
|
|
25
|
+
s as buildTranslationPayloadFetchRequest,
|
|
21
26
|
n as buildTranslationPayloadPath,
|
|
22
|
-
|
|
27
|
+
t as resolveTranslationPayloadBaseURL,
|
|
23
28
|
l as resolveTranslationPayloadPage
|
|
24
29
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@i18n-micro/utils",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
4
4
|
"description": "Framework-agnostic utilities for Nuxt I18n Micro (granular subpath imports).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"i18n",
|
|
@@ -353,14 +353,14 @@
|
|
|
353
353
|
},
|
|
354
354
|
"dependencies": {
|
|
355
355
|
"globby": "^14.1.0",
|
|
356
|
-
"@i18n-micro/types": "1.2.
|
|
356
|
+
"@i18n-micro/types": "1.2.8"
|
|
357
357
|
},
|
|
358
358
|
"devDependencies": {
|
|
359
359
|
"publint": "^0.3.17",
|
|
360
|
-
"vite": "^7.3.
|
|
360
|
+
"vite": "^7.3.6",
|
|
361
361
|
"vite-plugin-dts": "^4.5.4",
|
|
362
|
-
"vitest": "^
|
|
363
|
-
"@i18n-micro/test-utils": "1.2.
|
|
362
|
+
"vitest": "^4.1.10",
|
|
363
|
+
"@i18n-micro/test-utils": "1.2.6"
|
|
364
364
|
},
|
|
365
365
|
"engines": {
|
|
366
366
|
"node": ">=18"
|
|
@@ -368,7 +368,7 @@
|
|
|
368
368
|
"scripts": {
|
|
369
369
|
"build": "vite build",
|
|
370
370
|
"check:package": "publint",
|
|
371
|
-
"test": "
|
|
371
|
+
"test": "vitest run",
|
|
372
372
|
"test:dist": "vitest run --config vitest.dist.config.ts"
|
|
373
373
|
}
|
|
374
374
|
}
|