@jjlmoya/utils-social 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/package.json +59 -58
  2. package/src/category/i18n/de.ts +23 -0
  3. package/src/category/i18n/id.ts +23 -0
  4. package/src/category/i18n/it.ts +23 -0
  5. package/src/category/i18n/ja.ts +23 -0
  6. package/src/category/i18n/ko.ts +23 -0
  7. package/src/category/i18n/nl.ts +23 -0
  8. package/src/category/i18n/pl.ts +23 -0
  9. package/src/category/i18n/pt.ts +23 -0
  10. package/src/category/i18n/ru.ts +23 -0
  11. package/src/category/i18n/sv.ts +23 -0
  12. package/src/category/i18n/tr.ts +23 -0
  13. package/src/category/i18n/zh.ts +23 -0
  14. package/src/category/index.ts +12 -0
  15. package/src/index.ts +8 -0
  16. package/src/tests/i18n_coverage.test.ts +36 -0
  17. package/src/tests/locale_completeness.test.ts +1 -1
  18. package/src/tests/schemas_fulfillment.test.ts +23 -0
  19. package/src/tests/slug_uniqueness.test.ts +81 -0
  20. package/src/tests/title_quality.test.ts +55 -0
  21. package/src/tool/redditFormatter/i18n/de.ts +193 -0
  22. package/src/tool/redditFormatter/i18n/en.ts +1 -1
  23. package/src/tool/redditFormatter/i18n/es.ts +1 -1
  24. package/src/tool/redditFormatter/i18n/fr.ts +1 -1
  25. package/src/tool/redditFormatter/i18n/id.ts +193 -0
  26. package/src/tool/redditFormatter/i18n/it.ts +193 -0
  27. package/src/tool/redditFormatter/i18n/ja.ts +193 -0
  28. package/src/tool/redditFormatter/i18n/ko.ts +193 -0
  29. package/src/tool/redditFormatter/i18n/nl.ts +193 -0
  30. package/src/tool/redditFormatter/i18n/pl.ts +193 -0
  31. package/src/tool/redditFormatter/i18n/pt.ts +193 -0
  32. package/src/tool/redditFormatter/i18n/ru.ts +193 -0
  33. package/src/tool/redditFormatter/i18n/sv.ts +193 -0
  34. package/src/tool/redditFormatter/i18n/tr.ts +193 -0
  35. package/src/tool/redditFormatter/i18n/zh.ts +193 -0
  36. package/src/tool/redditFormatter/index.ts +15 -7
  37. package/src/tool/safeZones/i18n/de.ts +244 -0
  38. package/src/tool/safeZones/i18n/id.ts +244 -0
  39. package/src/tool/safeZones/i18n/it.ts +244 -0
  40. package/src/tool/safeZones/i18n/ja.ts +244 -0
  41. package/src/tool/safeZones/i18n/ko.ts +244 -0
  42. package/src/tool/safeZones/i18n/nl.ts +244 -0
  43. package/src/tool/safeZones/i18n/pl.ts +244 -0
  44. package/src/tool/safeZones/i18n/pt.ts +244 -0
  45. package/src/tool/safeZones/i18n/ru.ts +244 -0
  46. package/src/tool/safeZones/i18n/sv.ts +244 -0
  47. package/src/tool/safeZones/i18n/tr.ts +244 -0
  48. package/src/tool/safeZones/i18n/zh.ts +244 -0
  49. package/src/tool/safeZones/index.ts +17 -9
  50. package/src/tool/socialImageResizer/i18n/de.ts +211 -0
  51. package/src/tool/socialImageResizer/i18n/en.ts +1 -1
  52. package/src/tool/socialImageResizer/i18n/id.ts +211 -0
  53. package/src/tool/socialImageResizer/i18n/it.ts +211 -0
  54. package/src/tool/socialImageResizer/i18n/ja.ts +211 -0
  55. package/src/tool/socialImageResizer/i18n/ko.ts +211 -0
  56. package/src/tool/socialImageResizer/i18n/nl.ts +211 -0
  57. package/src/tool/socialImageResizer/i18n/pl.ts +211 -0
  58. package/src/tool/socialImageResizer/i18n/pt.ts +211 -0
  59. package/src/tool/socialImageResizer/i18n/ru.ts +211 -0
  60. package/src/tool/socialImageResizer/i18n/sv.ts +211 -0
  61. package/src/tool/socialImageResizer/i18n/tr.ts +211 -0
  62. package/src/tool/socialImageResizer/i18n/zh.ts +211 -0
  63. package/src/tool/socialImageResizer/index.ts +16 -8
  64. package/src/tool/socialValueCalculator/i18n/de.ts +306 -0
  65. package/src/tool/socialValueCalculator/i18n/es.ts +1 -1
  66. package/src/tool/socialValueCalculator/i18n/fr.ts +1 -1
  67. package/src/tool/socialValueCalculator/i18n/id.ts +306 -0
  68. package/src/tool/socialValueCalculator/i18n/it.ts +306 -0
  69. package/src/tool/socialValueCalculator/i18n/ja.ts +306 -0
  70. package/src/tool/socialValueCalculator/i18n/ko.ts +306 -0
  71. package/src/tool/socialValueCalculator/i18n/nl.ts +306 -0
  72. package/src/tool/socialValueCalculator/i18n/pl.ts +306 -0
  73. package/src/tool/socialValueCalculator/i18n/pt.ts +306 -0
  74. package/src/tool/socialValueCalculator/i18n/ru.ts +306 -0
  75. package/src/tool/socialValueCalculator/i18n/sv.ts +306 -0
  76. package/src/tool/socialValueCalculator/i18n/tr.ts +306 -0
  77. package/src/tool/socialValueCalculator/i18n/zh.ts +306 -0
  78. package/src/tool/socialValueCalculator/index.ts +17 -9
  79. package/src/tool/tinderPhotoOptimizer/i18n/de.ts +272 -0
  80. package/src/tool/tinderPhotoOptimizer/i18n/id.ts +272 -0
  81. package/src/tool/tinderPhotoOptimizer/i18n/it.ts +272 -0
  82. package/src/tool/tinderPhotoOptimizer/i18n/ja.ts +272 -0
  83. package/src/tool/tinderPhotoOptimizer/i18n/ko.ts +272 -0
  84. package/src/tool/tinderPhotoOptimizer/i18n/nl.ts +272 -0
  85. package/src/tool/tinderPhotoOptimizer/i18n/pl.ts +272 -0
  86. package/src/tool/tinderPhotoOptimizer/i18n/pt.ts +272 -0
  87. package/src/tool/tinderPhotoOptimizer/i18n/ru.ts +272 -0
  88. package/src/tool/tinderPhotoOptimizer/i18n/sv.ts +272 -0
  89. package/src/tool/tinderPhotoOptimizer/i18n/tr.ts +272 -0
  90. package/src/tool/tinderPhotoOptimizer/i18n/zh.ts +272 -0
  91. package/src/tool/tinderPhotoOptimizer/index.ts +17 -9
  92. package/src/tool/youtubeThumbnail/i18n/de.ts +207 -0
  93. package/src/tool/youtubeThumbnail/i18n/id.ts +207 -0
  94. package/src/tool/youtubeThumbnail/i18n/it.ts +207 -0
  95. package/src/tool/youtubeThumbnail/i18n/ja.ts +207 -0
  96. package/src/tool/youtubeThumbnail/i18n/ko.ts +207 -0
  97. package/src/tool/youtubeThumbnail/i18n/nl.ts +207 -0
  98. package/src/tool/youtubeThumbnail/i18n/pl.ts +207 -0
  99. package/src/tool/youtubeThumbnail/i18n/pt.ts +207 -0
  100. package/src/tool/youtubeThumbnail/i18n/ru.ts +207 -0
  101. package/src/tool/youtubeThumbnail/i18n/sv.ts +207 -0
  102. package/src/tool/youtubeThumbnail/i18n/tr.ts +207 -0
  103. package/src/tool/youtubeThumbnail/i18n/zh.ts +207 -0
  104. package/src/tool/youtubeThumbnail/index.ts +17 -9
  105. package/src/tool/youtubeThumbnailPreviewer/i18n/de.ts +321 -0
  106. package/src/tool/youtubeThumbnailPreviewer/i18n/en.ts +1 -1
  107. package/src/tool/youtubeThumbnailPreviewer/i18n/es.ts +1 -1
  108. package/src/tool/youtubeThumbnailPreviewer/i18n/fr.ts +2 -2
  109. package/src/tool/youtubeThumbnailPreviewer/i18n/id.ts +321 -0
  110. package/src/tool/youtubeThumbnailPreviewer/i18n/it.ts +321 -0
  111. package/src/tool/youtubeThumbnailPreviewer/i18n/ja.ts +321 -0
  112. package/src/tool/youtubeThumbnailPreviewer/i18n/ko.ts +321 -0
  113. package/src/tool/youtubeThumbnailPreviewer/i18n/nl.ts +321 -0
  114. package/src/tool/youtubeThumbnailPreviewer/i18n/pl.ts +321 -0
  115. package/src/tool/youtubeThumbnailPreviewer/i18n/pt.ts +321 -0
  116. package/src/tool/youtubeThumbnailPreviewer/i18n/ru.ts +321 -0
  117. package/src/tool/youtubeThumbnailPreviewer/i18n/sv.ts +321 -0
  118. package/src/tool/youtubeThumbnailPreviewer/i18n/tr.ts +321 -0
  119. package/src/tool/youtubeThumbnailPreviewer/i18n/zh.ts +321 -0
  120. package/src/tool/youtubeThumbnailPreviewer/index.ts +24 -0
package/package.json CHANGED
@@ -1,60 +1,61 @@
1
1
  {
2
- "name": "@jjlmoya/utils-social",
3
- "version": "1.2.0",
4
- "type": "module",
5
- "main": "./src/index.ts",
6
- "types": "./src/index.ts",
7
- "exports": {
8
- ".": "./src/index.ts",
9
- "./data": "./src/data.ts"
10
- },
11
- "files": [
12
- "src"
13
- ],
14
- "publishConfig": {
15
- "access": "public"
16
- },
17
- "scripts": {
18
- "dev": "astro dev",
19
- "start": "astro dev",
20
- "build": "astro build",
21
- "preview": "astro preview",
22
- "astro": "astro",
23
- "lint": "eslint src/ --max-warnings 0 && stylelint \"src/**/*.{css,astro}\"",
24
- "check": "astro check",
25
- "type-check": "astro check",
26
- "test": "vitest run",
27
- "preversion": "npm run lint && npm run test",
28
- "postversion": "git push && git push --tags",
29
- "patch": "npm version patch",
30
- "minor": "npm version minor",
31
- "major": "npm version major"
32
- },
33
- "lint-staged": {
34
- "*.{ts,tsx,astro}": [
35
- "eslint --fix"
36
- ]
37
- },
38
- "dependencies": {
39
- "@iconify-json/mdi": "^1.2.3",
40
- "@jjlmoya/utils-shared": "^1.1.0",
41
- "astro": "^6.1.2",
42
- "astro-icon": "^1.1.0"
43
- },
44
- "devDependencies": {
45
- "@astrojs/check": "^0.9.8",
46
- "eslint": "^9.39.4",
47
- "eslint-plugin-astro": "^1.6.0",
48
- "eslint-plugin-no-comments": "^1.1.10",
49
- "husky": "^9.1.7",
50
- "lint-staged": "^16.4.0",
51
- "postcss-html": "^1.8.1",
52
- "schema-dts": "^1.1.2",
53
- "stylelint": "^17.6.0",
54
- "stylelint-config-standard": "^40.0.0",
55
- "stylelint-declaration-strict-value": "^1.11.1",
56
- "typescript": "^5.4.0",
57
- "typescript-eslint": "^8.58.0",
58
- "vitest": "^4.1.2"
59
- }
2
+ "name": "@jjlmoya/utils-social",
3
+ "version": "1.4.0",
4
+ "type": "module",
5
+ "main": "./src/index.ts",
6
+ "types": "./src/index.ts",
7
+ "exports": {
8
+ ".": "./src/index.ts",
9
+ "./data": "./src/data.ts"
10
+ },
11
+ "files": [
12
+ "src"
13
+ ],
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "scripts": {
18
+ "dev": "astro dev",
19
+ "start": "astro dev",
20
+ "build": "astro build",
21
+ "preview": "astro preview",
22
+ "astro": "astro",
23
+ "lint": "eslint src/ --max-warnings 0 && stylelint \"src/**/*.{css,astro}\"",
24
+ "check": "astro check",
25
+ "type-check": "astro check",
26
+ "test": "vitest run",
27
+ "preversion": "npm run lint && npm run test",
28
+ "postversion": "git push && git push --tags",
29
+ "patch": "npm version patch",
30
+ "minor": "npm version minor",
31
+ "major": "npm version major"
32
+ },
33
+ "lint-staged": {
34
+ "*.{ts,tsx,astro}": [
35
+ "eslint --fix"
36
+ ]
37
+ },
38
+ "dependencies": {
39
+ "@iconify-json/mdi": "^1.2.3",
40
+ "@jjlmoya/prompagate": "^1.1.0",
41
+ "@jjlmoya/utils-shared": "1.2.0",
42
+ "astro": "^6.1.2",
43
+ "astro-icon": "^1.1.0"
44
+ },
45
+ "devDependencies": {
46
+ "@astrojs/check": "^0.9.8",
47
+ "eslint": "^9.39.4",
48
+ "eslint-plugin-astro": "^1.6.0",
49
+ "eslint-plugin-no-comments": "^1.1.10",
50
+ "husky": "^9.1.7",
51
+ "lint-staged": "^16.4.0",
52
+ "postcss-html": "^1.8.1",
53
+ "schema-dts": "^1.1.2",
54
+ "stylelint": "^17.6.0",
55
+ "stylelint-config-standard": "^40.0.0",
56
+ "stylelint-declaration-strict-value": "^1.11.1",
57
+ "typescript": "^5.4.0",
58
+ "typescript-eslint": "^8.58.0",
59
+ "vitest": "^4.1.2"
60
+ }
60
61
  }
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'social-media',
5
+ title: 'Social Media Tools',
6
+ description:
7
+ 'Kostenlose Tools für Content-Ersteller: Schnittstellensimulatoren, Analysetools und Designwerkzeuge für TikTok, Instagram und YouTube.',
8
+ seo: [
9
+ {
10
+ type: 'title',
11
+ text: 'Professionelle Tools für Ersteller von vertikalem Content',
12
+ level: 2,
13
+ },
14
+ {
15
+ type: 'paragraph',
16
+ html: 'Vertikaler Content hat den digitalen Konsum revolutioniert. TikTok, Instagram Reels und YouTube Shorts konkurrieren um dieselben Sekunden an Aufmerksamkeit, und jedes Pixel zählt. Diese Sammlung von Tools entstand aus der Notwendigkeit, Inhalte vor der Veröffentlichung zu optimieren und zu überprüfen, um sicherzustellen, dass jede Kreation genau so aussieht, wie sie geplant war.',
17
+ },
18
+ {
19
+ type: 'paragraph',
20
+ html: 'Von nativen Schnittstellensimulatoren bis hin zu Validatoren für sichere Zonen sind alle Tools in dieser Kategorie <strong>100 % lokal</strong>: Ihre Inhalte verlassen niemals Ihr Gerät. Arbeiten Sie in aller Ruhe mit Videos, Bildern und vertraulichen Kundendaten.',
21
+ },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'media-sosial',
5
+ title: 'Alat Media Sosial',
6
+ description:
7
+ 'Utilitas gratis untuk pembuat konten: simulator antarmuka, penganalisis, dan alat desain untuk TikTok, Instagram, dan YouTube.',
8
+ seo: [
9
+ {
10
+ type: 'title',
11
+ text: 'Alat profesional untuk pembuat konten vertikal',
12
+ level: 2,
13
+ },
14
+ {
15
+ type: 'paragraph',
16
+ html: 'Konten vertikal telah merevolusi konsumsi digital. TikTok, Instagram Reels, dan YouTube Shorts bersaing untuk detik perhatian yang sama dan setiap piksel sangat berarti. Koleksi utilitas ini lahir dari kebutuhan untuk mengoptimalkan dan memverifikasi konten sebelum dipublikasikan, memastikan setiap kreasi terlihat persis seperti yang dirancang.',
17
+ },
18
+ {
19
+ type: 'paragraph',
20
+ html: 'Dari simulator antarmuka asli hingga validator zona aman, semua alat dalam kategori ini adalah <strong>100% lokal</strong>: konten Anda tidak pernah meninggalkan perangkat Anda. Bekerja dengan video, gambar, dan data klien rahasia dengan ketenangan pikiran sepenuhnya.',
21
+ },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'social-media',
5
+ title: 'Strumenti per i Social Media',
6
+ description:
7
+ 'Utility gratuite per i creatori di contenuti: simulatori di interfaccia, analizzatori e strumenti di progettazione per TikTok, Instagram e YouTube.',
8
+ seo: [
9
+ {
10
+ type: 'title',
11
+ text: 'Strumenti professionali per i creatori di contenuti verticali',
12
+ level: 2,
13
+ },
14
+ {
15
+ type: 'paragraph',
16
+ html: 'I contenuti verticali hanno rivoluzionato il consumo digitale. TikTok, Instagram Reels e YouTube Shorts competono per gli stessi secondi di attenzione e ogni pixel conta. Questa raccolta di utility nasce dalla necessità di ottimizzare e verificare i contenuti prima della pubblicazione, assicurando che ogni creazione appaia esattamente come è stata progettata.',
17
+ },
18
+ {
19
+ type: 'paragraph',
20
+ html: 'Dai simulatori di interfaccia nativi ai validatori delle zone sicure, tutti gli strumenti di questa categoria sono <strong>locali al 100%</strong>: i vostri contenuti non lasciano mai il vostro dispositivo. Lavorate con video, immagini e dati riservati dei clienti in totale tranquillità.',
21
+ },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'social-media',
5
+ title: 'ソーシャルメディアツール',
6
+ description:
7
+ 'コンテンツクリエイター向けの無料ユーティリティ:TikTok、Instagram、YouTube用のインターフェースシミュレーター、アナライザー、デザインツール。',
8
+ seo: [
9
+ {
10
+ type: 'title',
11
+ text: '縦型コンテンツクリエイター向けプロフェッショナルツール',
12
+ level: 2,
13
+ },
14
+ {
15
+ type: 'paragraph',
16
+ html: '縦型コンテンツはデジタル消費に革命をもたらしました。TikTok、Instagramリール、YouTubeショートは同じ数秒間の注目を競い合っており、すべてのピクセルが重要です。このユーティリティコレクションは、公開前にコンテンツを最適化し、検証する必要性から生まれ、すべての制作物が設計通りに表示されることを保証します。',
17
+ },
18
+ {
19
+ type: 'paragraph',
20
+ html: 'ネイティブインターフェースシミュレーターからセーフゾーンバリデーターまで、このカテゴリのすべてのツールは<strong>100%ローカル</strong>です。コンテンツがデバイスから離れることはありません。ビデオ、画像、機密性の高いクライアントデータを安心して処理できます。',
21
+ },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'social-media',
5
+ title: '소셜 미디어 도구',
6
+ description:
7
+ '콘텐츠 제작자를 위한 무료 유틸리티: TikTok, Instagram 및 YouTube용 인터페이스 시뮬레이터, 분석기 및 디자인 도구.',
8
+ seo: [
9
+ {
10
+ type: 'title',
11
+ text: '세로형 콘텐츠 제작자를 위한 전문 도구',
12
+ level: 2,
13
+ },
14
+ {
15
+ type: 'paragraph',
16
+ html: '세로형 콘텐츠는 디지털 소비의 혁명을 일으켰습니다. TikTok, Instagram 릴스 및 YouTube 쇼츠는 동일한 몇 초의 주의력을 끌기 위해 경쟁하며 모든 픽셀이 중요합니다. 이 유틸리티 컬렉션은 게시 전에 콘텐츠를 최적화하고 검증하여 모든 창작물이 설계된 대로 정확하게 보이도록 하기 위해 탄생했습니다.',
17
+ },
18
+ {
19
+ type: 'paragraph',
20
+ html: '네이티브 인터페이스 시뮬레이터부터 세이프 존 검증기까지, 이 카테고리의 모든 도구는 <strong>100% 로컬</strong>에서 작동합니다. 귀하의 콘텐츠는 장치를 절대 떠나지 않습니다. 동영상, 이미지 및 기밀 고객 데이터를 완벽하게 안심하고 작업하세요.',
21
+ },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'sociale-media',
5
+ title: 'Social Media Tools',
6
+ description:
7
+ 'Gratis hulpmiddelen voor contentmakers: interfacesimulators, analysers en ontwerptools voor TikTok, Instagram en YouTube.',
8
+ seo: [
9
+ {
10
+ type: 'title',
11
+ text: 'Professionele tools voor makers van verticale content',
12
+ level: 2,
13
+ },
14
+ {
15
+ type: 'paragraph',
16
+ html: 'Verticale content heeft de digitale consumptie gerevolutioneerd. TikTok, Instagram Reels en YouTube Shorts strijden om dezelfde seconden aandacht en elke pixel telt. Deze verzameling hulpmiddelen is ontstaan uit de behoefte om content te optimaliseren en te verifiëren vóór publicatie, zodat elke creatie er precies zo uitziet als ontworpen.',
17
+ },
18
+ {
19
+ type: 'paragraph',
20
+ html: 'Van native interfacesimulators tot safe zone validators, alle tools in deze categorie zijn <strong>100% lokaal</strong>: uw content verlaat nooit uw apparaat. Werk met een gerust hart aan video\'s, afbeeldingen en vertrouwelijke klantgegevens.',
21
+ },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'media-spolecznosciowe',
5
+ title: 'Narzędzia do mediów społecznościowych',
6
+ description:
7
+ 'Bezpłatne narzędzia dla twórców treści: symulatory interfejsu, analizatory i narzędzia projektowe dla TikTok, Instagrama i YouTube.',
8
+ seo: [
9
+ {
10
+ type: 'title',
11
+ text: 'Profesjonalne narzędzia dla twórców treści pionowych',
12
+ level: 2,
13
+ },
14
+ {
15
+ type: 'paragraph',
16
+ html: 'Treści pionowe zrewolucjonizowały konsumpcję cyfrową. TikTok, Instagram Reels i YouTube Shorts walczą o te same sekundy uwagi, a każdy piksel ma znaczenie. Kolekcja tych narzędzi zrodziła się z potrzeby optymalizacji i weryfikacji treści przed publikacją, zapewniając, że każda kreacja wygląda dokładnie tak, jak została zaprojektowana.',
17
+ },
18
+ {
19
+ type: 'paragraph',
20
+ html: 'Od natywnych symulatorów interfejsu po walidatory stref bezpiecznych, wszystkie narzędzia w tej kategorii są w <strong>100% lokalne</strong>: Twoje treści nigdy nie opuszczają Twojego urządzenia. Pracuj z filmami, zdjęciami i poufnymi danymi klientów z pełnym spokojem ducha.',
21
+ },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'redes-sociais',
5
+ title: 'Ferramentas para Redes Sociais',
6
+ description:
7
+ 'Utilitários gratuitos para criadores de conteúdo: simuladores de interface, analisadores e ferramentas de design para TikTok, Instagram e YouTube.',
8
+ seo: [
9
+ {
10
+ type: 'title',
11
+ text: 'Ferramentas profissionais para criadores de conteúdo vertical',
12
+ level: 2,
13
+ },
14
+ {
15
+ type: 'paragraph',
16
+ html: 'O conteúdo vertical revolucionou o consumo digital. O TikTok, o Instagram Reels e o YouTube Shorts competem pelos mesmos segundos de atenção e cada pixel conta. Esta coleção de utilitários nasceu da necessidade de otimizar e verificar o conteúdo antes da publicação, garantindo que cada criação tenha exatamente o aspeto planeado.',
17
+ },
18
+ {
19
+ type: 'paragraph',
20
+ html: 'Desde simuladores de interface nativos a validadores de zonas seguras, todas as ferramentas nesta categoria são <strong>100% locais</strong>: o seu conteúdo nunca sai do seu dispositivo. Trabalhe com vídeos, imagens e dados confidenciais de clientes com total tranquilidade.',
21
+ },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'socialnyje-seti',
5
+ title: 'Инструменты для социальных сетей',
6
+ description:
7
+ 'Бесплатные утилиты для создателей контента: симуляторы интерфейса, анализаторы и инструменты дизайна для TikTok, Instagram и YouTube.',
8
+ seo: [
9
+ {
10
+ type: 'title',
11
+ text: 'Профессиональные инструменты для создателей вертикального контента',
12
+ level: 2,
13
+ },
14
+ {
15
+ type: 'paragraph',
16
+ html: 'Вертикальный контент совершил революцию в цифровом потреблении. TikTok, Instagram Reels и YouTube Shorts борются за одни и те же секунды внимания, и каждый пиксель имеет значение. Эта коллекция утилит родилась из необходимости оптимизировать и проверять контент перед публикацией, гарантируя, что каждое творение выглядит именно так, как было задумано.',
17
+ },
18
+ {
19
+ type: 'paragraph',
20
+ html: 'От нативных симуляторов интерфейса до валидаторов безопасных зон — все инструменты в этой категории являются <strong>на 100 % локальными</strong>: ваш контент никогда не покидает ваше устройство. Работайте с видео, изображениями и конфиденциальными данными клиентов с полным спокойствием.',
21
+ },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'sociala-medier',
5
+ title: 'Verktyg för sociala medier',
6
+ description:
7
+ 'Gratis verktyg för innehållsskapare: gränssnittssimulatorer, analysatorer och designverktyg för TikTok, Instagram och YouTube.',
8
+ seo: [
9
+ {
10
+ type: 'title',
11
+ text: 'Professionella verktyg för skapare av vertikalt innehåll',
12
+ level: 2,
13
+ },
14
+ {
15
+ type: 'paragraph',
16
+ html: 'Vertikalt innehåll har revolutionerat digital konsumtion. TikTok, Instagram Reels och YouTube Shorts tävlar om samma sekunder av uppmärksamhet och varje pixel räknas. Denna samling verktyg föddes ur behovet att optimera och verifiera innehåll före publicering, för att säkerställa att varje skapelse ser ut exakt som planerat.',
17
+ },
18
+ {
19
+ type: 'paragraph',
20
+ html: 'Från inbyggda gränssnittssimulatorer till validerare av säkra zoner är alla verktyg i denna kategori <strong>100 % lokala</strong>: ditt innehåll lämnar aldrig din enhet. Arbeta med videor, bilder och konfidentiell kunddata med fullständig sinnesro.',
21
+ },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'sosyal-medya',
5
+ title: 'Sosyal Medya Araçları',
6
+ description:
7
+ 'İçerik üreticileri için ücretsiz araçlar: TikTok, Instagram ve YouTube için arayüz simülatörleri, analizörler ve tasarım araçları.',
8
+ seo: [
9
+ {
10
+ type: 'title',
11
+ text: 'Dikey içerik üreticileri için profesyonel araçlar',
12
+ level: 2,
13
+ },
14
+ {
15
+ type: 'paragraph',
16
+ html: 'Dikey içerik, dijital tüketimde devrim yarattı. TikTok, Instagram Reels ve YouTube Shorts aynı saniyelik dikkat için yarışıyor ve her pikselin önemi var. Bu araç koleksiyonu, içeriği yayınlamadan önce optimize etme ve doğrulama ihtiyacından doğdu; her tasarımın tam olarak planlandığı gibi görünmesini sağlıyor.',
17
+ },
18
+ {
19
+ type: 'paragraph',
20
+ html: 'Yerel arayüz simülatörlerinden güvenli bölge doğrulayıcılarına kadar, bu kategorideki tüm araçlar <strong>%100 yerel</strong> çalışır: içeriğiniz asla cihazınızdan çıkmaz. Videolarınız, görselleriniz ve gizli müşteri verilerinizle tam bir huzur içinde çalışın.',
21
+ },
22
+ ],
23
+ };
@@ -0,0 +1,23 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'social-media',
5
+ title: '社交媒体工具',
6
+ description:
7
+ '面向内容创作者的免费实用程序:TikTok、Instagram 和 YouTube 的界面模拟器、分析器和设计工具。',
8
+ seo: [
9
+ {
10
+ type: 'title',
11
+ text: '垂直内容创作者的专业工具',
12
+ level: 2,
13
+ },
14
+ {
15
+ type: 'paragraph',
16
+ html: '垂直内容彻底改变了数字消费。TikTok、Instagram Reels 和 YouTube Shorts 都在争夺同样的几秒钟注意力,每一个像素都至关重要。这套工具集源于在发布前优化和验证内容的需求,确保每一件作品都呈现出设计时的精确效果。',
17
+ },
18
+ {
19
+ type: 'paragraph',
20
+ html: '从原生界面模拟器到安全区域验证器,此类别中的所有工具都是 <strong>100% 本地运行</strong>:您的内容永远不会离开您的设备。您可以完全放心地处理视频、图像和机密的客户数据。',
21
+ },
22
+ ],
23
+ };
@@ -8,6 +8,18 @@ export const socialCategory: SocialCategoryEntry = {
8
8
  es: () => import('./i18n/es').then((m) => m.content),
9
9
  en: () => import('./i18n/en').then((m) => m.content),
10
10
  fr: () => import('./i18n/fr').then((m) => m.content),
11
+ de: () => import('./i18n/de').then((m) => m.content),
12
+ id: () => import('./i18n/id').then((m) => m.content),
13
+ it: () => import('./i18n/it').then((m) => m.content),
14
+ ja: () => import('./i18n/ja').then((m) => m.content),
15
+ ko: () => import('./i18n/ko').then((m) => m.content),
16
+ nl: () => import('./i18n/nl').then((m) => m.content),
17
+ pl: () => import('./i18n/pl').then((m) => m.content),
18
+ pt: () => import('./i18n/pt').then((m) => m.content),
19
+ ru: () => import('./i18n/ru').then((m) => m.content),
20
+ sv: () => import('./i18n/sv').then((m) => m.content),
21
+ tr: () => import('./i18n/tr').then((m) => m.content),
22
+ zh: () => import('./i18n/zh').then((m) => m.content),
11
23
  },
12
24
  };
13
25
 
package/src/index.ts CHANGED
@@ -25,3 +25,11 @@ export { SocialImageResizerComponent, SocialImageResizerSEO, SocialImageResizerB
25
25
  export { TinderPhotoOptimizerComponent, TinderPhotoOptimizerSEO, TinderPhotoOptimizerBibliography } from './tool/tinderPhotoOptimizer';
26
26
  export { YoutubeThumbnailPreviewerComponent, YoutubeThumbnailPreviewerSEO, YoutubeThumbnailPreviewerBibliography } from './tool/youtubeThumbnailPreviewer';
27
27
 
28
+ export { SAFE_ZONES_TOOL } from './tool/safeZones/index';
29
+ export { YOUTUBE_THUMBNAIL_TOOL } from './tool/youtubeThumbnail/index';
30
+ export { SOCIAL_VALUE_CALCULATOR_TOOL } from './tool/socialValueCalculator/index';
31
+ export { REDDIT_FORMATTER_TOOL } from './tool/redditFormatter/index';
32
+ export { SOCIAL_IMAGE_RESIZER_TOOL } from './tool/socialImageResizer/index';
33
+ export { TINDER_PHOTO_OPTIMIZER_TOOL } from './tool/tinderPhotoOptimizer/index';
34
+ export { YOUTUBE_THUMBNAIL_PREVIEWER_TOOL } from './tool/youtubeThumbnailPreviewer/index';
35
+
@@ -0,0 +1,36 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { ALL_TOOLS } from '../tools';
3
+
4
+ const EXPECTED_LOCALES = [
5
+ 'de', 'en', 'es', 'fr', 'id', 'it', 'ja', 'ko', 'nl', 'pl', 'pt', 'ru', 'sv', 'tr', 'zh'
6
+ ];
7
+
8
+ describe('I18n Coverage Validation', () => {
9
+ it('all tools should be registered', () => {
10
+ expect(ALL_TOOLS.length).toBeGreaterThan(0);
11
+ });
12
+
13
+ ALL_TOOLS.forEach(({ entry }: { entry: any }) => {
14
+ describe(`Tool: ${entry.id}`, () => {
15
+ it('should have all 15 required locales', () => {
16
+ const registeredLocales = Object.keys(entry.i18n);
17
+ EXPECTED_LOCALES.forEach((locale) => {
18
+ expect(
19
+ registeredLocales,
20
+ `Tool "${entry.id}" is missing locale "${locale}"`,
21
+ ).toContain(locale);
22
+ });
23
+ });
24
+
25
+ it('all locale loaders should be functions', () => {
26
+ EXPECTED_LOCALES.forEach((locale) => {
27
+ const loader = entry.i18n[locale as keyof typeof entry.i18n];
28
+ expect(
29
+ typeof loader,
30
+ `Tool "${entry.id}" locale "${locale}" loader is not a function`,
31
+ ).toBe('function');
32
+ });
33
+ });
34
+ });
35
+ });
36
+ });
@@ -35,7 +35,7 @@ describe('Locale Completeness Validation', () => {
35
35
  });
36
36
  });
37
37
 
38
- it('should have 7 tools registered', () => {
38
+ it('all 7 tools registered', () => {
39
39
  expect(ALL_TOOLS.length).toBe(7);
40
40
  });
41
41
  });
@@ -0,0 +1,23 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { ALL_TOOLS } from '../tools';
3
+ import type { ToolLocaleContent } from '../types';
4
+
5
+ describe('Schemas Fulfillment Validation', () => {
6
+ ALL_TOOLS.forEach((tool) => {
7
+ describe(`Tool: ${tool.entry.id}`, () => {
8
+ Object.keys(tool.entry.i18n).forEach((locale) => {
9
+ it(`Locale: ${locale} should have faqSchema, appSchema and howToSchema`, async () => {
10
+ const loader = tool.entry.i18n[locale as keyof typeof tool.entry.i18n];
11
+ if (!loader) return;
12
+ const content = (await loader()) as ToolLocaleContent;
13
+
14
+ const schemaTypes = content.schemas.map((s: any) => s['@type']);
15
+
16
+ expect(schemaTypes, `Tool "${tool.entry.id}" locale "${locale}" is missing FAQPage schema`).toContain('FAQPage');
17
+ expect(schemaTypes, `Tool "${tool.entry.id}" locale "${locale}" is missing SoftwareApplication schema`).toContain('SoftwareApplication');
18
+ expect(schemaTypes, `Tool "${tool.entry.id}" locale "${locale}" is missing HowTo schema`).toContain('HowTo');
19
+ });
20
+ });
21
+ });
22
+ });
23
+ });
@@ -0,0 +1,81 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { ALL_TOOLS } from '../tools';
3
+ import type { ToolLocaleContent } from '../types';
4
+
5
+ const sharingLocales = ['ja', 'ko', 'zh'];
6
+
7
+ interface ValidateParams {
8
+ toolId: string;
9
+ locale: string;
10
+ content: ToolLocaleContent;
11
+ enSlug: string;
12
+ slugs: Map<string, string>;
13
+ }
14
+
15
+ const validateLocaleSlug = ({
16
+ toolId,
17
+ locale,
18
+ content,
19
+ enSlug,
20
+ slugs,
21
+ }: ValidateParams) => {
22
+ expect(
23
+ content.slug,
24
+ `Tool "${toolId}" locale "${locale}" has an invalid slug ("${content.slug}"). Slugs must be transliterated (only a-z, 0-9, and -).`,
25
+ ).toMatch(/^[a-z0-9-]+$/);
26
+
27
+ if (locale === 'en') {
28
+ return;
29
+ }
30
+
31
+ if (sharingLocales.includes(locale)) {
32
+ expect(
33
+ content.slug,
34
+ `Tool "${toolId}" locale "${locale}" must use the same slug as "en" ("${enSlug}").`,
35
+ ).toBe(enSlug);
36
+ } else {
37
+ expect(
38
+ content.slug,
39
+ `Tool "${toolId}" locale "${locale}" has the same slug as "en" ("${enSlug}"). Cada slug tiene que estar en su propia idioma`,
40
+ ).not.toBe(enSlug);
41
+
42
+ if (slugs.has(content.slug)) {
43
+ const previousLocale = slugs.get(content.slug);
44
+ expect(
45
+ false,
46
+ `Tool "${toolId}" locales "${locale}" and "${previousLocale}" share the same slug ("${content.slug}"). Cada slug tiene que estar en su propia idioma`,
47
+ ).toBe(true);
48
+ }
49
+ slugs.set(content.slug, locale);
50
+ }
51
+ };
52
+
53
+ describe('Slug Localization and Uniqueness Validation', () => {
54
+ ALL_TOOLS.forEach((tool) => {
55
+ describe(`Tool: ${tool.entry.id}`, () => {
56
+ it('every locale should have a unique, translated slug', async () => {
57
+ const slugs = new Map<string, string>();
58
+ const locales = Object.keys(tool.entry.i18n);
59
+
60
+ let enSlug = '';
61
+ if (locales.includes('en')) {
62
+ const enLoader = tool.entry.i18n['en' as keyof typeof tool.entry.i18n];
63
+ const enContent = (await enLoader?.()) as ToolLocaleContent;
64
+ enSlug = enContent.slug;
65
+ }
66
+
67
+ for (const locale of locales) {
68
+ const loader = tool.entry.i18n[locale as keyof typeof tool.entry.i18n];
69
+ const content = (await loader?.()) as ToolLocaleContent;
70
+ validateLocaleSlug({
71
+ toolId: tool.entry.id,
72
+ locale,
73
+ content,
74
+ enSlug,
75
+ slugs,
76
+ });
77
+ }
78
+ });
79
+ });
80
+ });
81
+ });