@jjlmoya/utils-shared 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -2
- package/src/i18n.translations.ts +30 -0
- package/src/i18n.ts +7 -66
- package/src/seo/SEODiagnostic.astro +9 -6
- package/src/seo/SEOProsCons.astro +6 -3
- package/src/seo/SEORenderer.astro +1 -1
- package/src/types/index.ts +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jjlmoya/utils-shared",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Shared SEO primitives and UI components for jjlmoya ecosystem",
|
|
5
5
|
"author": "jjlmoya",
|
|
6
6
|
"license": "MIT",
|
|
@@ -32,7 +32,12 @@
|
|
|
32
32
|
"lint": "eslint src --ext .ts,.astro",
|
|
33
33
|
"lint:css": "stylelint \"src/**/*.{astro,css}\"",
|
|
34
34
|
"lint:all": "npm run check && npm run lint && npm run lint:css",
|
|
35
|
-
"prepublishOnly": "npm run lint:all"
|
|
35
|
+
"prepublishOnly": "npm run lint:all",
|
|
36
|
+
"preversion": "npm run lint:all",
|
|
37
|
+
"postversion": "git push && git push --tags",
|
|
38
|
+
"patch": "npm version patch",
|
|
39
|
+
"minor": "npm version minor",
|
|
40
|
+
"major": "npm version major"
|
|
36
41
|
},
|
|
37
42
|
"peerDependencies": {
|
|
38
43
|
"@iconify-json/mdi": "^1.0.0",
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Language } from "./i18n";
|
|
2
|
+
|
|
3
|
+
export type TranslationKeys = {
|
|
4
|
+
bibliographicReferences: string;
|
|
5
|
+
faq: string;
|
|
6
|
+
pros: string;
|
|
7
|
+
cons: string;
|
|
8
|
+
diagWarning: string;
|
|
9
|
+
diagError: string;
|
|
10
|
+
diagInfo: string;
|
|
11
|
+
diagSuccess: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const translations: Record<Language, TranslationKeys> = {
|
|
15
|
+
es: { bibliographicReferences: "Referencias Bibliográficas", faq: "Preguntas Frecuentes", pros: "Ventajas", cons: "Desventajas", diagWarning: "Advertencia", diagError: "Problema crítico", diagInfo: "A tener en cuenta", diagSuccess: "Buena práctica" },
|
|
16
|
+
en: { bibliographicReferences: "Bibliographic References", faq: "Frequently Asked Questions", pros: "Advantages", cons: "Disadvantages", diagWarning: "Warning", diagError: "Critical issue", diagInfo: "Worth noting", diagSuccess: "Best practice" },
|
|
17
|
+
fr: { bibliographicReferences: "Références Bibliographiques", faq: "Questions Fréquemment Posées", pros: "Avantages", cons: "Inconvénients", diagWarning: "Avertissement", diagError: "Problème critique", diagInfo: "À noter", diagSuccess: "Bonne pratique" },
|
|
18
|
+
nl: { bibliographicReferences: "Bibliografische Referenties", faq: "Veelgestelde Vragen", pros: "Voordelen", cons: "Nadelen", diagWarning: "Waarschuwing", diagError: "Kritiek probleem", diagInfo: "Let op", diagSuccess: "Best practice" },
|
|
19
|
+
de: { bibliographicReferences: "Bibliographische Referenzen", faq: "Häufig Gestellte Fragen", pros: "Vorteile", cons: "Nachteile", diagWarning: "Warnung", diagError: "Kritisches Problem", diagInfo: "Zu beachten", diagSuccess: "Bewährte Methode" },
|
|
20
|
+
it: { bibliographicReferences: "Riferimenti Bibliografici", faq: "Domande Frequenti", pros: "Vantaggi", cons: "Svantaggi", diagWarning: "Avviso", diagError: "Problema critico", diagInfo: "Da tenere a mente", diagSuccess: "Buona pratica" },
|
|
21
|
+
pt: { bibliographicReferences: "Referências Bibliográficas", faq: "Perguntas Frequentes", pros: "Vantagens", cons: "Desvantagens", diagWarning: "Aviso", diagError: "Problema crítico", diagInfo: "A ter em conta", diagSuccess: "Boa prática" },
|
|
22
|
+
ja: { bibliographicReferences: "参考文献", faq: "よくある質問", pros: "メリット", cons: "デメリット", diagWarning: "警告", diagError: "重大な問題", diagInfo: "注意事項", diagSuccess: "ベストプラクティス" },
|
|
23
|
+
zh: { bibliographicReferences: "参考文献", faq: "常见问题", pros: "优点", cons: "缺点", diagWarning: "警告", diagError: "严重问题", diagInfo: "注意事项", diagSuccess: "最佳实践" },
|
|
24
|
+
ko: { bibliographicReferences: "참고 문헌", faq: "자주 묻는 질문", pros: "장점", cons: "단점", diagWarning: "경고", diagError: "심각한 문제", diagInfo: "참고 사항", diagSuccess: "모범 사례" },
|
|
25
|
+
ru: { bibliographicReferences: "Библиографические ссылки", faq: "Часто задаваемые вопросы", pros: "Преимущества", cons: "Недостатки", diagWarning: "Предупреждение", diagError: "Критическая проблема", diagInfo: "Важно учесть", diagSuccess: "Хорошая практика" },
|
|
26
|
+
pl: { bibliographicReferences: "Referencje Bibliograficzne", faq: "Najczęściej Zadawane Pytania", pros: "Zalety", cons: "Wady", diagWarning: "Ostrzeżenie", diagError: "Krytyczny problem", diagInfo: "Warto wiedzieć", diagSuccess: "Dobra praktyka" },
|
|
27
|
+
tr: { bibliographicReferences: "Bibliyografik Referanslar", faq: "Sıkça Sorulan Sorular", pros: "Avantajlar", cons: "Dezavantajlar", diagWarning: "Uyarı", diagError: "Kritik sorun", diagInfo: "Dikkat edilmesi gereken", diagSuccess: "En iyi uygulama" },
|
|
28
|
+
sv: { bibliographicReferences: "Bibliografiska Referenser", faq: "Vanliga Frågor", pros: "Fördelar", cons: "Nackdelar", diagWarning: "Varning", diagError: "Kritiskt problem", diagInfo: "Värt att notera", diagSuccess: "Bästa praxis" },
|
|
29
|
+
hi: { bibliographicReferences: "ग्रंथ सूची संदर्भ", faq: "अक्सर पूछे जाने वाले प्रश्न", pros: "फायदे", cons: "नुकसान", diagWarning: "चेतावनी", diagError: "गंभीर समस्या", diagInfo: "ध्यान देने योग्य", diagSuccess: "सर्वोत्तम अभ्यास" },
|
|
30
|
+
};
|
package/src/i18n.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import { translations } from "./i18n.translations";
|
|
2
|
+
|
|
3
|
+
export { translations };
|
|
4
|
+
export type { TranslationKeys } from "./i18n.translations";
|
|
5
|
+
|
|
1
6
|
export const languages = {
|
|
2
7
|
es: "Español",
|
|
3
8
|
en: "English",
|
|
@@ -20,75 +25,11 @@ export type Language = keyof typeof languages;
|
|
|
20
25
|
|
|
21
26
|
export const defaultLanguage: Language = "es";
|
|
22
27
|
|
|
23
|
-
export const translations: Record<Language, { bibliographicReferences: string; faq: string }> = {
|
|
24
|
-
es: {
|
|
25
|
-
bibliographicReferences: "Referencias Bibliográficas",
|
|
26
|
-
faq: "Preguntas Frecuentes",
|
|
27
|
-
},
|
|
28
|
-
en: {
|
|
29
|
-
bibliographicReferences: "Bibliographic References",
|
|
30
|
-
faq: "Frequently Asked Questions",
|
|
31
|
-
},
|
|
32
|
-
fr: {
|
|
33
|
-
bibliographicReferences: "Références Bibliographiques",
|
|
34
|
-
faq: "Questions Fréquemment Posées",
|
|
35
|
-
},
|
|
36
|
-
nl: {
|
|
37
|
-
bibliographicReferences: "Bibliografische Referenties",
|
|
38
|
-
faq: "Veelgestelde Vragen",
|
|
39
|
-
},
|
|
40
|
-
de: {
|
|
41
|
-
bibliographicReferences: "Bibliographische Referenzen",
|
|
42
|
-
faq: "Häufig Gestellte Fragen",
|
|
43
|
-
},
|
|
44
|
-
it: {
|
|
45
|
-
bibliographicReferences: "Riferimenti Bibliografici",
|
|
46
|
-
faq: "Domande Frequenti",
|
|
47
|
-
},
|
|
48
|
-
pt: {
|
|
49
|
-
bibliographicReferences: "Referências Bibliográficas",
|
|
50
|
-
faq: "Perguntas Frequentes",
|
|
51
|
-
},
|
|
52
|
-
ja: {
|
|
53
|
-
bibliographicReferences: "参考文献",
|
|
54
|
-
faq: "よくある質問",
|
|
55
|
-
},
|
|
56
|
-
zh: {
|
|
57
|
-
bibliographicReferences: "参考文献",
|
|
58
|
-
faq: "常见问题",
|
|
59
|
-
},
|
|
60
|
-
ko: {
|
|
61
|
-
bibliographicReferences: "참고 문헌",
|
|
62
|
-
faq: "자주 묻는 질문",
|
|
63
|
-
},
|
|
64
|
-
ru: {
|
|
65
|
-
bibliographicReferences: "Библиографические ссылки",
|
|
66
|
-
faq: "Часто задаваемые вопросы",
|
|
67
|
-
},
|
|
68
|
-
pl: {
|
|
69
|
-
bibliographicReferences: "Referencje Bibliograficzne",
|
|
70
|
-
faq: "Najczęściej Zadawane Pytania",
|
|
71
|
-
},
|
|
72
|
-
tr: {
|
|
73
|
-
bibliographicReferences: "Bibliyografik Referanslar",
|
|
74
|
-
faq: "Sıkça Sorulan Sorular",
|
|
75
|
-
},
|
|
76
|
-
sv: {
|
|
77
|
-
bibliographicReferences: "Bibliografiska Referenser",
|
|
78
|
-
faq: "Vanliga Frågor",
|
|
79
|
-
},
|
|
80
|
-
hi: {
|
|
81
|
-
bibliographicReferences: "ग्रंथ सूची संदर्भ",
|
|
82
|
-
faq: "अक्सर पूछे जाने वाले प्रश्न",
|
|
83
|
-
},
|
|
84
|
-
};
|
|
85
|
-
|
|
86
28
|
export const getLanguageFromUrl = (url: URL | string): Language => {
|
|
87
29
|
const pathname = typeof url === "string" ? url : url.pathname;
|
|
88
|
-
const
|
|
89
|
-
const firstSegment = segments[0];
|
|
30
|
+
const firstSegment = pathname.split("/").filter(Boolean)[0];
|
|
90
31
|
|
|
91
|
-
if (firstSegment && firstSegment in
|
|
32
|
+
if (firstSegment && firstSegment in languages) {
|
|
92
33
|
return firstSegment as Language;
|
|
93
34
|
}
|
|
94
35
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { Icon } from "astro-icon/components";
|
|
3
|
+
import { getLanguageFromUrl, getTranslation } from "../i18n";
|
|
3
4
|
|
|
4
5
|
interface Props {
|
|
5
6
|
title: string;
|
|
@@ -10,14 +11,16 @@ interface Props {
|
|
|
10
11
|
|
|
11
12
|
const { title, icon, type = "info", badge } = Astro.props;
|
|
12
13
|
|
|
14
|
+
const language = getLanguageFromUrl(Astro.url);
|
|
15
|
+
|
|
13
16
|
const typeConfig = {
|
|
14
|
-
warning: { color: "var(--color-warning)", badgeText: badge ?? "
|
|
15
|
-
error: { color: "var(--color-error)",
|
|
16
|
-
info: { color: "var(--color-info)",
|
|
17
|
-
success: { color: "var(--color-success)",
|
|
18
|
-
}
|
|
17
|
+
warning: { color: "var(--color-warning)", badgeText: badge ?? getTranslation(language, "diagWarning") },
|
|
18
|
+
error: { color: "var(--color-error)", badgeText: badge ?? getTranslation(language, "diagError") },
|
|
19
|
+
info: { color: "var(--color-info)", badgeText: badge ?? getTranslation(language, "diagInfo") },
|
|
20
|
+
success: { color: "var(--color-success)", badgeText: badge ?? getTranslation(language, "diagSuccess") },
|
|
21
|
+
};
|
|
19
22
|
|
|
20
|
-
const cfg = typeConfig[type
|
|
23
|
+
const cfg = typeConfig[type];
|
|
21
24
|
---
|
|
22
25
|
|
|
23
26
|
<div class={`seo-diagnostic is-${type}`}>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { Icon } from "astro-icon/components";
|
|
3
|
+
import { getLanguageFromUrl, getTranslation } from "../i18n";
|
|
3
4
|
|
|
4
5
|
interface ProsConsItem {
|
|
5
6
|
pro: string;
|
|
@@ -9,11 +10,13 @@ interface ProsConsItem {
|
|
|
9
10
|
interface Props {
|
|
10
11
|
title?: string | undefined;
|
|
11
12
|
items: ProsConsItem[];
|
|
12
|
-
proTitle?: string | undefined;
|
|
13
|
-
conTitle?: string | undefined;
|
|
14
13
|
}
|
|
15
14
|
|
|
16
|
-
const { title, items
|
|
15
|
+
const { title, items } = Astro.props;
|
|
16
|
+
|
|
17
|
+
const language = getLanguageFromUrl(Astro.url);
|
|
18
|
+
const proTitle = getTranslation(language, "pros");
|
|
19
|
+
const conTitle = getTranslation(language, "cons");
|
|
17
20
|
---
|
|
18
21
|
|
|
19
22
|
<div class="seo-proscons-box">
|
|
@@ -71,7 +71,7 @@ const { content } = Astro.props;
|
|
|
71
71
|
);
|
|
72
72
|
}
|
|
73
73
|
if (section.type === "proscons") {
|
|
74
|
-
return <SEOProsCons title={section.title} items={section.items}
|
|
74
|
+
return <SEOProsCons title={section.title} items={section.items} />;
|
|
75
75
|
}
|
|
76
76
|
if (section.type === "summary") {
|
|
77
77
|
return <SEOSummary title={section.title} items={section.items} />;
|
package/src/types/index.ts
CHANGED
|
@@ -34,7 +34,7 @@ export type SEOSection =
|
|
|
34
34
|
| { type: "table"; headers: string[]; rows: string[][] }
|
|
35
35
|
| { type: "tip"; title?: string; html: string }
|
|
36
36
|
| { type: "card"; icon?: string; title?: string; html: string }
|
|
37
|
-
| { type: "stats"; items: { value: string; label: string; icon?: string }[]; columns?: 2 | 3 | 4 }
|
|
37
|
+
| { type: "stats"; items: { value: string; label: string; icon?: string; trend?: { value: string; positive: boolean } }[]; columns?: 2 | 3 | 4 }
|
|
38
38
|
| { type: "glossary"; items: { term: string; definition: string }[] }
|
|
39
39
|
| { type: "code"; code: string; ariaLabel?: string }
|
|
40
40
|
| {
|
|
@@ -50,7 +50,7 @@ export type SEOSection =
|
|
|
50
50
|
columns?: 2 | 3;
|
|
51
51
|
}
|
|
52
52
|
| { type: "diagnostic"; variant: "warning" | "error" | "info" | "success"; title: string; icon?: string; badge?: string; html: string }
|
|
53
|
-
| { type: "proscons"; title?: string; items: { pro: string; con: string }[]
|
|
53
|
+
| { type: "proscons"; title?: string; items: { pro: string; con: string }[] }
|
|
54
54
|
| { type: "summary"; title: string; items: string[] }
|
|
55
55
|
| { type: "grid"; columns?: 1 | 2 | 3 | 4 }
|
|
56
56
|
| { type: "message"; title?: string; ariaLabel?: string; html: string };
|