@i18n-micro/utils 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/merge-i18n-head.cjs +1 -0
- package/dist/merge-i18n-head.d.cts +12 -0
- package/dist/merge-i18n-head.d.ts +12 -0
- package/dist/merge-i18n-head.mjs +97 -0
- package/package.json +13 -2
package/README.md
CHANGED
|
@@ -9,6 +9,9 @@ import { findAllowedLocalesForRoute } from '@i18n-micro/utils/route'
|
|
|
9
9
|
import { extractBaseRoutePattern } from '@i18n-micro/utils/route-pattern'
|
|
10
10
|
import { resolveI18nConfigWithRuntimeOverrides } from '@i18n-micro/utils/runtime-config'
|
|
11
11
|
import { preMergeLocales } from '@i18n-micro/utils/build'
|
|
12
|
+
import { mergeI18nHead } from '@i18n-micro/utils/merge-i18n-head'
|
|
12
13
|
```
|
|
13
14
|
|
|
15
|
+
`mergeI18nHead` merges `useLocaleHead` output with page-level overrides (`I18nHeadInput`). Used by the `02.meta` plugin; import it directly for custom tooling or unit tests that need the same merge rules (replace hreflang/canonical/og, disable groups, append meta/link).
|
|
16
|
+
|
|
14
17
|
No Vue, Nuxt, or Nitro dependencies. `sideEffects: false` for tree-shaking friendly bundlers.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("./resolve-og-locale.cjs");function u(e){return e.rel==="alternate"}function s(e){return e.rel==="alternate"&&e.hreflang==="x-default"}function m(e){return e.rel==="alternate"&&e.hreflang!=="x-default"}function g(e,t){const n=e[t];return n?`id:${n}`:e.property?`property:${e.property}`:e.name?`name:${e.name}`:`meta:${JSON.stringify(e)}`}function A(e,t){const n=e[t];return n?`id:${n}`:`link:${e.rel}:${e.hreflang??""}`}function p(e,t){const n=new Set([A(e,t)]);return e.rel==="alternate"&&e.hreflang&&n.add(`link:${e.rel}:${e.hreflang}`),e.rel==="canonical"&&n.add("link:canonical:"),[...n]}function $(e,t,n){if(g(e,n)===g(t,n)||t.property&&e.property===t.property||t.name&&e.name===t.name)return!0;const o=t[n];return!!(o&&e[n]===o)}function L(e,t,n){const o=e.filter(i=>!$(i,t,n));return o.push(t),o}function k(e,t,n){const o=new Set(p(t,n)),i=e.filter(c=>!p(c,n).some(l=>o.has(l)));return i.push(t),i}function x(e,t,n){let o=!1;const i=e.map(c=>c.rel!=="canonical"?c:(o=!0,{...c,href:t}));return o||i.unshift({[n]:"i18n-can",rel:"canonical",href:t}),i}function h(e,t,n,o,i){const c=e.filter(l=>l.property!==t);return c.push({[o]:t==="og:locale"?"i18n-og":t==="og:url"?"i18n-og-url":`i18n-page-${t}`,property:t,content:n}),c}function S(e,t,n,o){const i=[];for(const c of e){if(n&&c===n)continue;const l=t.find(f=>f.code===c);if(!l)continue;const a=d.resolveOgLocale(l);a&&i.push({[o]:`i18n-og-alt-${a}`,property:"og:locale:alternate",content:a})}return i}function M(e,t,n={}){if(!t)return{htmlAttrs:{...e.htmlAttrs},meta:[...e.meta],link:[...e.link]};const o=n.identifierAttribute??"id",i=new Set(t.disable??[]);let c={...e.htmlAttrs},l=[...e.meta],a=[...e.link];i.has("html")&&(c={}),i.has("hreflang")&&(a=a.filter(r=>!m(r))),i.has("x-default")&&(a=a.filter(r=>!s(r))),i.has("canonical")&&(a=a.filter(r=>r.rel!=="canonical")),i.has("og")&&(l=l.filter(r=>r.property!=="og:locale"&&r.property!=="og:url")),i.has("og-alternates")&&(l=l.filter(r=>r.property!=="og:locale:alternate"));const f=t.replace;if(f){if(f.canonical===!1?a=a.filter(r=>r.rel!=="canonical"):typeof f.canonical=="string"&&(a=x(a,f.canonical,o)),f.hreflang===!1?a=a.filter(r=>!u(r)):Array.isArray(f.hreflang)&&(a=a.filter(r=>!u(r)),a.push(...f.hreflang)),f.xDefault===!1?a=a.filter(r=>!s(r)):f.xDefault&&(a=a.filter(r=>!s(r)),a.push(f.xDefault)),f.ogLocale===!1?l=l.filter(r=>r.property!=="og:locale"):typeof f.ogLocale=="string"&&(l=h(l,"og:locale",f.ogLocale,o)),f.ogUrl===!1?l=l.filter(r=>r.property!=="og:url"):typeof f.ogUrl=="string"&&(l=h(l,"og:url",f.ogUrl,o)),f.ogAlternates===!1)l=l.filter(r=>r.property!=="og:locale:alternate");else if(Array.isArray(f.ogAlternates)){l=l.filter(y=>y.property!=="og:locale:alternate");const r=n.locales??[];l.push(...S(f.ogAlternates,r,n.currentLocale,o))}}t.htmlAttrs&&(c={...c,...t.htmlAttrs});for(const r of t.meta??[])l=L(l,r,o);for(const r of t.link??[])a=k(a,r,o);return{htmlAttrs:c,meta:l,link:a}}exports.mergeI18nHead=M;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { I18nHeadInput, I18nHeadLink, I18nHeadMeta, Locale } from '@i18n-micro/types';
|
|
2
|
+
export interface I18nHeadObject {
|
|
3
|
+
htmlAttrs: Record<string, string | undefined>;
|
|
4
|
+
meta: I18nHeadMeta[];
|
|
5
|
+
link: I18nHeadLink[];
|
|
6
|
+
}
|
|
7
|
+
export interface MergeI18nHeadOptions {
|
|
8
|
+
identifierAttribute?: string;
|
|
9
|
+
locales?: Locale[];
|
|
10
|
+
currentLocale?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function mergeI18nHead(base: I18nHeadObject, override: I18nHeadInput | null | undefined, options?: MergeI18nHeadOptions): I18nHeadObject;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { I18nHeadInput, I18nHeadLink, I18nHeadMeta, Locale } from '@i18n-micro/types';
|
|
2
|
+
export interface I18nHeadObject {
|
|
3
|
+
htmlAttrs: Record<string, string | undefined>;
|
|
4
|
+
meta: I18nHeadMeta[];
|
|
5
|
+
link: I18nHeadLink[];
|
|
6
|
+
}
|
|
7
|
+
export interface MergeI18nHeadOptions {
|
|
8
|
+
identifierAttribute?: string;
|
|
9
|
+
locales?: Locale[];
|
|
10
|
+
currentLocale?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function mergeI18nHead(base: I18nHeadObject, override: I18nHeadInput | null | undefined, options?: MergeI18nHeadOptions): I18nHeadObject;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { resolveOgLocale as d } from "./resolve-og-locale.mjs";
|
|
2
|
+
function u(e) {
|
|
3
|
+
return e.rel === "alternate";
|
|
4
|
+
}
|
|
5
|
+
function s(e) {
|
|
6
|
+
return e.rel === "alternate" && e.hreflang === "x-default";
|
|
7
|
+
}
|
|
8
|
+
function m(e) {
|
|
9
|
+
return e.rel === "alternate" && e.hreflang !== "x-default";
|
|
10
|
+
}
|
|
11
|
+
function p(e, t) {
|
|
12
|
+
const n = e[t];
|
|
13
|
+
return n ? `id:${n}` : e.property ? `property:${e.property}` : e.name ? `name:${e.name}` : `meta:${JSON.stringify(e)}`;
|
|
14
|
+
}
|
|
15
|
+
function A(e, t) {
|
|
16
|
+
const n = e[t];
|
|
17
|
+
return n ? `id:${n}` : `link:${e.rel}:${e.hreflang ?? ""}`;
|
|
18
|
+
}
|
|
19
|
+
function g(e, t) {
|
|
20
|
+
const n = /* @__PURE__ */ new Set([A(e, t)]);
|
|
21
|
+
return e.rel === "alternate" && e.hreflang && n.add(`link:${e.rel}:${e.hreflang}`), e.rel === "canonical" && n.add("link:canonical:"), [...n];
|
|
22
|
+
}
|
|
23
|
+
function $(e, t, n) {
|
|
24
|
+
if (p(e, n) === p(t, n) || t.property && e.property === t.property || t.name && e.name === t.name) return !0;
|
|
25
|
+
const o = t[n];
|
|
26
|
+
return !!(o && e[n] === o);
|
|
27
|
+
}
|
|
28
|
+
function L(e, t, n) {
|
|
29
|
+
const o = e.filter((i) => !$(i, t, n));
|
|
30
|
+
return o.push(t), o;
|
|
31
|
+
}
|
|
32
|
+
function x(e, t, n) {
|
|
33
|
+
const o = new Set(g(t, n)), i = e.filter((c) => !g(c, n).some((l) => o.has(l)));
|
|
34
|
+
return i.push(t), i;
|
|
35
|
+
}
|
|
36
|
+
function k(e, t, n) {
|
|
37
|
+
let o = !1;
|
|
38
|
+
const i = e.map((c) => c.rel !== "canonical" ? c : (o = !0, { ...c, href: t }));
|
|
39
|
+
return o || i.unshift({
|
|
40
|
+
[n]: "i18n-can",
|
|
41
|
+
rel: "canonical",
|
|
42
|
+
href: t
|
|
43
|
+
}), i;
|
|
44
|
+
}
|
|
45
|
+
function h(e, t, n, o, i) {
|
|
46
|
+
const c = e.filter((l) => l.property !== t);
|
|
47
|
+
return c.push({
|
|
48
|
+
[o]: t === "og:locale" ? "i18n-og" : t === "og:url" ? "i18n-og-url" : `i18n-page-${t}`,
|
|
49
|
+
property: t,
|
|
50
|
+
content: n
|
|
51
|
+
}), c;
|
|
52
|
+
}
|
|
53
|
+
function D(e, t, n, o) {
|
|
54
|
+
const i = [];
|
|
55
|
+
for (const c of e) {
|
|
56
|
+
if (n && c === n) continue;
|
|
57
|
+
const l = t.find((f) => f.code === c);
|
|
58
|
+
if (!l) continue;
|
|
59
|
+
const a = d(l);
|
|
60
|
+
a && i.push({
|
|
61
|
+
[o]: `i18n-og-alt-${a}`,
|
|
62
|
+
property: "og:locale:alternate",
|
|
63
|
+
content: a
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return i;
|
|
67
|
+
}
|
|
68
|
+
function S(e, t, n = {}) {
|
|
69
|
+
if (!t)
|
|
70
|
+
return {
|
|
71
|
+
htmlAttrs: { ...e.htmlAttrs },
|
|
72
|
+
meta: [...e.meta],
|
|
73
|
+
link: [...e.link]
|
|
74
|
+
};
|
|
75
|
+
const o = n.identifierAttribute ?? "id", i = new Set(t.disable ?? []);
|
|
76
|
+
let c = { ...e.htmlAttrs }, l = [...e.meta], a = [...e.link];
|
|
77
|
+
i.has("html") && (c = {}), i.has("hreflang") && (a = a.filter((r) => !m(r))), i.has("x-default") && (a = a.filter((r) => !s(r))), i.has("canonical") && (a = a.filter((r) => r.rel !== "canonical")), i.has("og") && (l = l.filter((r) => r.property !== "og:locale" && r.property !== "og:url")), i.has("og-alternates") && (l = l.filter((r) => r.property !== "og:locale:alternate"));
|
|
78
|
+
const f = t.replace;
|
|
79
|
+
if (f) {
|
|
80
|
+
if (f.canonical === !1 ? a = a.filter((r) => r.rel !== "canonical") : typeof f.canonical == "string" && (a = k(a, f.canonical, o)), f.hreflang === !1 ? a = a.filter((r) => !u(r)) : Array.isArray(f.hreflang) && (a = a.filter((r) => !u(r)), a.push(...f.hreflang)), f.xDefault === !1 ? a = a.filter((r) => !s(r)) : f.xDefault && (a = a.filter((r) => !s(r)), a.push(f.xDefault)), f.ogLocale === !1 ? l = l.filter((r) => r.property !== "og:locale") : typeof f.ogLocale == "string" && (l = h(l, "og:locale", f.ogLocale, o)), f.ogUrl === !1 ? l = l.filter((r) => r.property !== "og:url") : typeof f.ogUrl == "string" && (l = h(l, "og:url", f.ogUrl, o)), f.ogAlternates === !1)
|
|
81
|
+
l = l.filter((r) => r.property !== "og:locale:alternate");
|
|
82
|
+
else if (Array.isArray(f.ogAlternates)) {
|
|
83
|
+
l = l.filter((y) => y.property !== "og:locale:alternate");
|
|
84
|
+
const r = n.locales ?? [];
|
|
85
|
+
l.push(...D(f.ogAlternates, r, n.currentLocale, o));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
t.htmlAttrs && (c = { ...c, ...t.htmlAttrs });
|
|
89
|
+
for (const r of t.meta ?? [])
|
|
90
|
+
l = L(l, r, o);
|
|
91
|
+
for (const r of t.link ?? [])
|
|
92
|
+
a = x(a, r, o);
|
|
93
|
+
return { htmlAttrs: c, meta: l, link: a };
|
|
94
|
+
}
|
|
95
|
+
export {
|
|
96
|
+
S as mergeI18nHead
|
|
97
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@i18n-micro/utils",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Framework-agnostic utilities for Nuxt I18n Micro (granular subpath imports).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"i18n",
|
|
@@ -140,6 +140,17 @@
|
|
|
140
140
|
},
|
|
141
141
|
"default": "./dist/resolve-og-locale.mjs"
|
|
142
142
|
},
|
|
143
|
+
"./merge-i18n-head": {
|
|
144
|
+
"import": {
|
|
145
|
+
"types": "./dist/merge-i18n-head.d.ts",
|
|
146
|
+
"default": "./dist/merge-i18n-head.mjs"
|
|
147
|
+
},
|
|
148
|
+
"require": {
|
|
149
|
+
"types": "./dist/merge-i18n-head.d.cts",
|
|
150
|
+
"default": "./dist/merge-i18n-head.cjs"
|
|
151
|
+
},
|
|
152
|
+
"default": "./dist/merge-i18n-head.mjs"
|
|
153
|
+
},
|
|
143
154
|
"./active-locales": {
|
|
144
155
|
"import": {
|
|
145
156
|
"types": "./dist/active-locales.d.ts",
|
|
@@ -247,7 +258,7 @@
|
|
|
247
258
|
},
|
|
248
259
|
"dependencies": {
|
|
249
260
|
"globby": "^14.1.0",
|
|
250
|
-
"@i18n-micro/types": "1.2.
|
|
261
|
+
"@i18n-micro/types": "1.2.6"
|
|
251
262
|
},
|
|
252
263
|
"devDependencies": {
|
|
253
264
|
"publint": "^0.3.17",
|