diff --git a/app/components/Diff/ViewerPanel.vue b/app/components/Diff/ViewerPanel.vue index 2051036fec..811599c3c9 100644 --- a/app/components/Diff/ViewerPanel.vue +++ b/app/components/Diff/ViewerPanel.vue @@ -33,10 +33,17 @@ const isLargeFile = computed(() => { ) }) -const apiUrl = computed( - () => - `/api/registry/compare-file/${props.packageName}/v/${props.fromVersion}...${props.toVersion}/${props.file.path}`, -) +function encodePathSegments(value: string): string { + return value.split('/').map(encodeURIComponent).join('/') +} + +const apiUrl = computed(() => { + const packagePath = encodePathSegments(props.packageName) + const versionRange = `${encodeURIComponent(props.fromVersion)}...${encodeURIComponent(props.toVersion)}` + const filePath = encodePathSegments(props.file.path) + return `/api/registry/compare-file/${packagePath}/v/${versionRange}/${filePath}` +}) +const rawDiffUrl = computed(() => `${apiUrl.value}?format=diff`) const apiQuery = computed(() => { if (isLargeFile.value) return {} @@ -94,6 +101,32 @@ function getCodeUrl(version: string): string { } const { announce } = useCommandPalette() +const { + copy: copyRawDiffToClipboard, + copied: rawDiffCopied, + isSupported: rawDiffCopySupported, +} = useClipboardItems({ copiedDuring: 2000 }) +const mounted = useMounted() +const copyingRawDiff = ref(false) + +async function copyRawDiff() { + if (copyingRawDiff.value || !rawDiffCopySupported.value) return + + copyingRawDiff.value = true + try { + // Hand the browser a pending blob before awaiting the network request. + // Safari requires clipboard.write() to begin during the click activation. + const rawDiff = $fetch(rawDiffUrl.value, { responseType: 'text' }).then( + value => new Blob([value], { type: 'text/plain' }), + ) + await copyRawDiffToClipboard([new ClipboardItem({ 'text/plain': rawDiff })]) + announce($t('command_palette.announcements.copied_to_clipboard')) + } catch { + // useClipboardItems keeps the copied state false when the write fails. + } finally { + copyingRawDiff.value = false + } +} useCommandPaletteContextCommands( computed((): CommandPaletteContextCommandInput[] => { @@ -193,7 +226,30 @@ useCommandPaletteContextCommands( -
+
+ + + + {{ $t('compare.view_diff') }} + +
diff --git a/i18n/locales/ar-EG.json b/i18n/locales/ar-EG.json index 18682843b5..8f3ecfd37e 100644 --- a/i18n/locales/ar-EG.json +++ b/i18n/locales/ar-EG.json @@ -327,7 +327,7 @@ "merge_modified_lines": "دمج الأسطر المعدّلة", "no_content_changes": "لا توجد تغييرات في المحتوى", "options": "الخيارات", - "view_file": "عرض الملف", + "view_diff": "عرض الاختلافات", "view_in_code_browser": "عرض في متصفح الكود", "word_wrap": "التفاف الكلمات" }, diff --git a/i18n/locales/bn-IN.json b/i18n/locales/bn-IN.json index af5c83bcd3..b079267945 100644 --- a/i18n/locales/bn-IN.json +++ b/i18n/locales/bn-IN.json @@ -319,6 +319,7 @@ "slate": "স্লেট", "black": "কালো" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "কীবোর্ড শর্টকাট সক্রিয় করুন", "keyboard_shortcuts_enabled_description": "কীবোর্ড শর্টকাট নিষ্ক্রিয় করা যেতে পারে যদি তারা অন্যান্য ব্রাউজার বা সিস্টেম শর্টকাটের সঙ্গে দুইপাশের সমস্যা তৈরি করে", "enable_code_ligatures": "কোডে লিগচারস সক্রিয় করুন", @@ -1588,7 +1589,6 @@ "merge_modified_lines": "পরিবর্তিত লাইন একত্রিত করুন", "no_content_changes": "কোনো বিষয়বস্তুর পরিবর্তন পাওয়া যায়নি", "options": "বিকল্পসমূহ", - "view_file": "ফাইল দেখুন", "view_in_code_browser": "কোড ব্রাউজারে দেখুন", "word_wrap": "লাইন মোড়ানো" }, diff --git a/i18n/locales/cs-CZ.json b/i18n/locales/cs-CZ.json index 52e946ae33..c7aaa267e7 100644 --- a/i18n/locales/cs-CZ.json +++ b/i18n/locales/cs-CZ.json @@ -316,6 +316,7 @@ "slate": "Břidlice", "black": "Černá" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "Povolit klávesové zkratky", "keyboard_shortcuts_enabled_description": "Klávesové zkratky lze zakázat, pokud se střetávají s jinými zkratkami prohlížeče nebo systému", "enable_code_ligatures": "Zapnout ligatury v kódu", @@ -1265,6 +1266,25 @@ } } }, + "sponsors_page": { + "what_we_do": {}, + "what_support_means": {}, + "what_this_means_for_you": { + "cards": { + "people": {}, + "visitors": {}, + "stars": {}, + "community": {}, + "adoption": {}, + "default_source": {} + } + }, + "tiers": { + "silver": {}, + "gold": {}, + "platinum": {} + } + }, "account_menu": { "connect": "připojit", "account": "Účet", @@ -1518,7 +1538,6 @@ "merge_modified_lines": "Sloučit upravené řádky", "no_content_changes": "Nebyly zjištěny žádné změny obsahu", "options": "Možnosti", - "view_file": "Zobrazit soubor", "view_in_code_browser": "Zobrazit v prohlížeči kódu", "word_wrap": "Zalomení slov" }, diff --git a/i18n/locales/de.json b/i18n/locales/de.json index 69f128ff87..23fb11bdeb 100644 --- a/i18n/locales/de.json +++ b/i18n/locales/de.json @@ -98,6 +98,7 @@ "current": "aktuell", "here": "du bist hier", "connected": "verbunden", + "keyboard_shortcuts": {}, "state": { "on": "an", "off": "aus" @@ -229,6 +230,9 @@ "more_replies": "noch {count} Antwort… | noch {count} Antworten…" } }, + "noodles": { + "missing": {} + }, "settings": { "title": "einstellungen", "tagline": "Passe npmx an deine Vorlieben an", @@ -284,6 +288,7 @@ "slate": "Schiefer", "black": "Schwarz" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "Tastenkombinationen aktivieren", "keyboard_shortcuts_enabled_description": "Tastenkombinationen können deaktiviert werden, wenn sie mit anderen Browser- oder Systemkürzeln in Konflikt stehen", "enable_code_ligatures": "Ligaturen im Code aktivieren", @@ -709,7 +714,8 @@ "general_description": "Die Y-Achse stellt die Anzahl der Downloads dar. Die X-Achse stellt den Datumsbereich dar, von {start_date} bis {end_date}, mit einem {granularity}en Zeitraum.{estimation_notice} {packages_analysis}. {watermark}.", "facet_bar_general_description": "Horizontales Balkendiagramm für: {packages}, Vergleich von {facet} ({description}). {facet_analysis} {watermark}.", "facet_bar_analysis": "{package_name} hat einen Wert von {value}." - } + }, + "embedding": {} }, "downloads": { "title": "Wöchentliche Downloads", @@ -1221,6 +1227,25 @@ } } }, + "sponsors_page": { + "what_we_do": {}, + "what_support_means": {}, + "what_this_means_for_you": { + "cards": { + "people": {}, + "visitors": {}, + "stars": {}, + "community": {}, + "adoption": {}, + "default_source": {} + } + }, + "tiers": { + "silver": {}, + "gold": {}, + "platinum": {} + } + }, "account_menu": { "connect": "Verbinden", "account": "Konto", @@ -1395,6 +1420,7 @@ "label": "GitHub-Sterne", "description": "Anzahl der Sterne im GitHub-Repository" }, + "githubForks": {}, "githubIssues": { "label": "GitHub-Issues", "description": "Anzahl der Issues im GitHub-Repository" @@ -1467,7 +1493,6 @@ "merge_modified_lines": "Geänderte Zeilen zusammenführen", "no_content_changes": "Keine Inhaltsänderungen erkannt", "options": "Optionen", - "view_file": "Datei anzeigen", "view_in_code_browser": "Im Code-Browser anzeigen", "word_wrap": "Zeilenumbruch" }, diff --git a/i18n/locales/en.json b/i18n/locales/en.json index c6881a08ae..2f0a1947da 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -1553,6 +1553,7 @@ "lines_hidden": "{count} line hidden | {count} lines hidden", "compare_versions": "diff", "compare_versions_title": "Compare with latest version", + "copy_diff": "Copy .diff", "comparing_versions_label": "Comparing versions...", "version_back_to_package": "Back to package", "version_error_message": "Failed to compare versions.", @@ -1599,7 +1600,7 @@ "merge_modified_lines": "Merge modified lines", "no_content_changes": "No content changes detected", "options": "Options", - "view_file": "View file", + "view_diff": "View .diff", "view_in_code_browser": "View in code browser", "word_wrap": "Word wrap" }, diff --git a/i18n/locales/es.json b/i18n/locales/es.json index b6b545404e..407a68b671 100644 --- a/i18n/locales/es.json +++ b/i18n/locales/es.json @@ -319,6 +319,7 @@ "slate": "Pizarra", "black": "Negro" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "Activar atajos de teclado", "keyboard_shortcuts_enabled_description": "Los atajos de teclado pueden desactivarse si entran en conflicto con otros atajos del navegador o del sistema", "enable_code_ligatures": "Activar ligaduras en código", @@ -1589,7 +1590,6 @@ "merge_modified_lines": "Combinar líneas modificadas", "no_content_changes": "No se detectaron cambios en el contenido", "options": "Opciones", - "view_file": "Ver archivo", "view_in_code_browser": "Ver en el navegador de código", "word_wrap": "Ajuste de línea" }, diff --git a/i18n/locales/fr-FR.json b/i18n/locales/fr-FR.json index 12ea672f09..5dddc10b44 100644 --- a/i18n/locales/fr-FR.json +++ b/i18n/locales/fr-FR.json @@ -98,6 +98,7 @@ "current": "actuel", "here": "vous êtes ici", "connected": "connecté", + "keyboard_shortcuts": {}, "state": { "on": "activé", "off": "désactivé" @@ -229,6 +230,9 @@ "more_replies": "{count} réponse supplémentaire... | {count} réponses supplémentaires..." } }, + "noodles": { + "missing": {} + }, "settings": { "title": "paramètres", "tagline": "personnalisez votre expérience npmx", @@ -284,6 +288,7 @@ "slate": "Ardoise", "black": "Noir" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "Activer les raccourcis clavier", "keyboard_shortcuts_enabled_description": "Les raccourcis clavier peuvent être désactivés s'ils entrent en conflit avec d'autres raccourcis du navigateur ou du système", "enable_code_ligatures": "Activer les ligatures de code", @@ -1227,6 +1232,25 @@ } } }, + "sponsors_page": { + "what_we_do": {}, + "what_support_means": {}, + "what_this_means_for_you": { + "cards": { + "people": {}, + "visitors": {}, + "stars": {}, + "community": {}, + "adoption": {}, + "default_source": {} + } + }, + "tiers": { + "silver": {}, + "gold": {}, + "platinum": {} + } + }, "account_menu": { "connect": "connexion", "account": "Compte", @@ -1401,6 +1425,7 @@ "label": "Étoiles GitHub", "description": "Nombre d’étoiles du dépôt GitHub" }, + "githubForks": {}, "githubIssues": { "label": "Issues GitHub", "description": "Nombre d’issues ouvertes sur GitHub" @@ -1473,7 +1498,6 @@ "merge_modified_lines": "Fusionner les lignes modifiées", "no_content_changes": "Aucun changement de contenu détecté", "options": "Options", - "view_file": "Voir le fichier", "view_in_code_browser": "Voir dans le navigateur de code", "word_wrap": "Retour à la ligne" }, diff --git a/i18n/locales/hi-IN.json b/i18n/locales/hi-IN.json index 77ccae8a94..61f4ea43c8 100644 --- a/i18n/locales/hi-IN.json +++ b/i18n/locales/hi-IN.json @@ -77,6 +77,7 @@ "instant_search_advisory": "{label} {state} — {action}" }, "command_palette": { + "keyboard_shortcuts": {}, "state": {}, "groups": {}, "actions": {}, @@ -131,6 +132,9 @@ "more_replies": "{count} और जवाब... | {count} और जवाब..." } }, + "noodles": { + "missing": {} + }, "settings": { "title": "सेटिंग्स", "tagline": "अपने npmx अनुभव को अनुकूलित करें", @@ -185,6 +189,7 @@ "slate": "स्लेट", "black": "काला" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "कीबोर्ड शॉर्टकट सक्षम करें", "keyboard_shortcuts_enabled_description": "यदि कीबोर्ड शॉर्टकट अन्य ब्राउज़र या सिस्टम शॉर्टकट से टकराते हैं, तो उन्हें बंद किया जा सकता है" }, @@ -544,7 +549,8 @@ "general_description": "Y अक्ष डाउनलोड की संख्या दर्शाता है। X अक्ष {start_date} से {end_date} तक की तारीख सीमा दर्शाता है, जिसमें {granularity} समय अवधि है।{estimation_notice} {packages_analysis}. {watermark}.", "facet_bar_general_description": "इनके लिए क्षैतिज बार चार्ट: {packages}, {facet} की तुलना करते हुए ({description})। {facet_analysis} {watermark}.", "facet_bar_analysis": "{package_name} का मान {value} है।" - } + }, + "embedding": {} }, "downloads": { "title": "साप्ताहिक डाउनलोड्स", @@ -1041,6 +1047,25 @@ } } }, + "sponsors_page": { + "what_we_do": {}, + "what_support_means": {}, + "what_this_means_for_you": { + "cards": { + "people": {}, + "visitors": {}, + "stars": {}, + "community": {}, + "adoption": {}, + "default_source": {} + } + }, + "tiers": { + "silver": {}, + "gold": {}, + "platinum": {} + } + }, "account_menu": { "connect": "कनेक्ट करें", "account": "खाता", @@ -1199,6 +1224,7 @@ "description": "ज्ञात सुरक्षा कमजोरियाँ" }, "githubStars": {}, + "githubForks": {}, "githubIssues": {}, "createdAt": {} }, @@ -1265,7 +1291,6 @@ "merge_modified_lines": "संशोधित पंक्तियाँ मर्ज करें", "no_content_changes": "कोई सामग्री परिवर्तन नहीं मिला", "options": "विकल्प", - "view_file": "फ़ाइल देखें", "view_in_code_browser": "कोड ब्राउज़र में देखें", "word_wrap": "वर्ड रैप" }, diff --git a/i18n/locales/id-ID.json b/i18n/locales/id-ID.json index b21589bd24..fac27d12af 100644 --- a/i18n/locales/id-ID.json +++ b/i18n/locales/id-ID.json @@ -77,6 +77,7 @@ "instant_search_advisory": "{label} {state} — {action}" }, "command_palette": { + "keyboard_shortcuts": {}, "state": {}, "groups": {}, "actions": {}, @@ -131,6 +132,9 @@ "more_replies": "{count} balasan lagi... | {count} balasan lagi..." } }, + "noodles": { + "missing": {} + }, "settings": { "title": "pengaturan", "tagline": "Sesuaikan npmx dengan preferensi anda", @@ -185,6 +189,7 @@ "slate": "Slate", "black": "Hitam" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "Aktifkan pintasan papan ketik", "keyboard_shortcuts_enabled_description": "Pintasan papan ketik dapat dinonaktifkan jika bertentangan dengan pintasan peramban atau sistem lainnya." }, @@ -561,7 +566,8 @@ "general_description": "Sumbu Y melambangkan jumlah unduhan. Sumbu X melambangkan jangka waktu, mulai dari {start_date} hingga {end_date}, dalam kurun waktu {granularity}. {estimation_notice} {packages_analysis}. {watermark}.", "facet_bar_general_description": "Grafik batang horizontal untuk: {packages}, membandingkan {facet} ({description}). {facet_analysis} {watermark}.", "facet_bar_analysis": "{package_name} memiliki nilai {value}." - } + }, + "embedding": {} }, "downloads": { "title": "Unduhan Mingguan", @@ -1058,6 +1064,25 @@ } } }, + "sponsors_page": { + "what_we_do": {}, + "what_support_means": {}, + "what_this_means_for_you": { + "cards": { + "people": {}, + "visitors": {}, + "stars": {}, + "community": {}, + "adoption": {}, + "default_source": {} + } + }, + "tiers": { + "silver": {}, + "gold": {}, + "platinum": {} + } + }, "account_menu": { "connect": "hubungkan", "account": "Akun", @@ -1221,6 +1246,7 @@ "description": "Kerentanan keamanan yang diketahui" }, "githubStars": {}, + "githubForks": {}, "githubIssues": {}, "createdAt": {} }, @@ -1287,7 +1313,6 @@ "merge_modified_lines": "Gabungkan baris yang dimodifikasi", "no_content_changes": "Tidak ada perubahan konten yang terdeteksi", "options": "Pengaturan", - "view_file": "Lihat file", "view_in_code_browser": "Lihat di code browser", "word_wrap": "Bungkus kata" }, diff --git a/i18n/locales/it-IT.json b/i18n/locales/it-IT.json index 24f00a8039..3ebd3cf5d7 100644 --- a/i18n/locales/it-IT.json +++ b/i18n/locales/it-IT.json @@ -99,6 +99,7 @@ "current": "corrente", "here": "sei qui", "connected": "connesso", + "keyboard_shortcuts": {}, "state": { "on": "attivo", "off": "disattivo" @@ -311,6 +312,7 @@ "slate": "Ardesia", "black": "Nero" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "Abilita scorciatoie da tastiera", "keyboard_shortcuts_enabled_description": "Le scorciatoie da tastiera possono essere disabilitate se entrano in conflitto con altre scorciatoie del browser o del sistema", "enable_code_ligatures": "Abilita legature nel codice", @@ -1260,6 +1262,25 @@ } } }, + "sponsors_page": { + "what_we_do": {}, + "what_support_means": {}, + "what_this_means_for_you": { + "cards": { + "people": {}, + "visitors": {}, + "stars": {}, + "community": {}, + "adoption": {}, + "default_source": {} + } + }, + "tiers": { + "silver": {}, + "gold": {}, + "platinum": {} + } + }, "account_menu": { "connect": "connetti", "account": "Account", @@ -1513,7 +1534,6 @@ "merge_modified_lines": "Unisci righe modificate", "no_content_changes": "Nessuna modifica al contenuto rilevata", "options": "Opzioni", - "view_file": "Visualizza file", "view_in_code_browser": "Visualizza nel browser del codice", "word_wrap": "A capo automatico" }, @@ -1545,6 +1565,20 @@ "new_accounts": "...più altri {count} che sono nuovi sull'atmosphere" } }, + "privacy_policy": { + "cookies": { + "what_are": {}, + "types": {}, + "local_storage": {}, + "management": {} + }, + "analytics": {}, + "authenticated": {}, + "data_retention": {}, + "your_rights": {}, + "contact": {}, + "changes": {} + }, "a11y": { "title": "accessibilità", "footer_title": "a11y", diff --git a/i18n/locales/ja-JP.json b/i18n/locales/ja-JP.json index 34f7688d64..649774a9a8 100644 --- a/i18n/locales/ja-JP.json +++ b/i18n/locales/ja-JP.json @@ -319,6 +319,7 @@ "slate": "スレート", "black": "ブラック" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "キーボードショートカットを有効化", "keyboard_shortcuts_enabled_description": "ブラウザやシステムのショートカットと競合する場合、キーボードショートカットを無効化できます", "enable_code_ligatures": "コードのリガチャを有効化", @@ -1581,7 +1582,6 @@ "merge_modified_lines": "変更行をマージ", "no_content_changes": "コンテンツの変更は検出されませんでした", "options": "オプション", - "view_file": "ファイルを表示", "view_in_code_browser": "コードブラウザで表示", "word_wrap": "右端で折り返す" }, diff --git a/i18n/locales/mr-IN.json b/i18n/locales/mr-IN.json index 09e258f33a..f758543b25 100644 --- a/i18n/locales/mr-IN.json +++ b/i18n/locales/mr-IN.json @@ -60,6 +60,7 @@ "instant_search_advisory": "{label} {state} — {action}" }, "command_palette": { + "keyboard_shortcuts": {}, "state": {}, "groups": {}, "actions": {}, @@ -114,6 +115,9 @@ "more_replies": "{count} आणखी उत्तर... | {count} आणखी उत्तरे..." } }, + "noodles": { + "missing": {} + }, "settings": { "title": "सेटिंग्ज", "tagline": "तुमचा npmx अनुभव सानुकूलित करा", @@ -168,6 +172,7 @@ "slate": "स्लेट", "black": "काळा" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "कीबोर्ड शॉर्टकट सक्षम करा", "keyboard_shortcuts_enabled_description": "जर कीबोर्ड शॉर्टकट इतर ब्राउझर किंवा सिस्टम शॉर्टकटशी संघर्ष करत असतील तर ते अक्षम करता येतात" }, @@ -522,7 +527,8 @@ "general_description": "Y अक्ष डाउनलोड्सची संख्या दर्शवतो. X अक्ष {start_date} ते {end_date} पर्यंतची दिनांक श्रेणी दर्शवतो, ज्यात {granularity} कालावधी आहे.{estimation_notice} {packages_analysis}. {watermark}.", "facet_bar_general_description": "या पॅकेजांसाठी आडवा बार चार्ट: {packages}, {facet} ची तुलना ({description}). {facet_analysis} {watermark}.", "facet_bar_analysis": "{package_name} ची किंमत {value} आहे." - } + }, + "embedding": {} }, "downloads": { "title": "साप्ताहिक डाउनलोड्स", @@ -1018,6 +1024,25 @@ } } }, + "sponsors_page": { + "what_we_do": {}, + "what_support_means": {}, + "what_this_means_for_you": { + "cards": { + "people": {}, + "visitors": {}, + "stars": {}, + "community": {}, + "adoption": {}, + "default_source": {} + } + }, + "tiers": { + "silver": {}, + "gold": {}, + "platinum": {} + } + }, "account_menu": { "connect": "जोडा", "account": "खाते", @@ -1174,6 +1199,7 @@ "description": "ज्ञात सुरक्षा असुरक्षितता" }, "githubStars": {}, + "githubForks": {}, "githubIssues": {}, "createdAt": {} }, @@ -1240,7 +1266,6 @@ "merge_modified_lines": "बदललेल्या ओळी एकत्र करा", "no_content_changes": "मजकुरात कोणतेही बदल आढळले नाहीत", "options": "पर्याय", - "view_file": "फाइल पहा", "view_in_code_browser": "कोड ब्राउझरमध्ये पहा", "word_wrap": "शब्द ओघ" }, diff --git a/i18n/locales/nb-NO.json b/i18n/locales/nb-NO.json index 2caa3e1c74..4eb23c623e 100644 --- a/i18n/locales/nb-NO.json +++ b/i18n/locales/nb-NO.json @@ -316,6 +316,7 @@ "slate": "Skifer", "black": "Svart" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "Aktiver tastatursnarveier", "keyboard_shortcuts_enabled_description": "Tastatursnarveier kan deaktiveres hvis de er i konflikt med andre nettleser- eller systemsnarveier", "enable_code_ligatures": "Aktiver ligaturer i kode", @@ -1265,6 +1266,25 @@ } } }, + "sponsors_page": { + "what_we_do": {}, + "what_support_means": {}, + "what_this_means_for_you": { + "cards": { + "people": {}, + "visitors": {}, + "stars": {}, + "community": {}, + "adoption": {}, + "default_source": {} + } + }, + "tiers": { + "silver": {}, + "gold": {}, + "platinum": {} + } + }, "account_menu": { "connect": "koble til", "account": "Konto", @@ -1518,7 +1538,6 @@ "merge_modified_lines": "Slå sammen endrede linjer", "no_content_changes": "Ingen innholdsendringer oppdaget", "options": "Alternativer", - "view_file": "Vis fil", "view_in_code_browser": "Vis i kodenettleser", "word_wrap": "Tekstbryting" }, diff --git a/i18n/locales/ne-NP.json b/i18n/locales/ne-NP.json index 4fea8c0f9a..cd544db2a9 100644 --- a/i18n/locales/ne-NP.json +++ b/i18n/locales/ne-NP.json @@ -319,6 +319,7 @@ "slate": "स्लेट", "black": "कालो" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "किबोर्ड सर्टकटहरू सक्षम गर्नुहोस्", "keyboard_shortcuts_enabled_description": "अन्य ब्राउजर वा सिस्टम सर्टकटहरूसँग बाझिएमा किबोर्ड सर्टकटहरू निष्क्रिय गर्न सकिन्छ", "enable_code_ligatures": "कोडमा लिगेचरहरू सक्षम गर्नुहोस्", @@ -1589,7 +1590,6 @@ "merge_modified_lines": "परिवर्तित लाइनहरू मर्ज गर्नुहोस्", "no_content_changes": "सामग्रीमा कुनै परिवर्तन भेटिएन", "options": "विकल्पहरू", - "view_file": "फाइल हेर्नुहोस्", "view_in_code_browser": "कोड ब्राउजरमा हेर्नुहोस्", "word_wrap": "वर्ड र्‍याप" }, diff --git a/i18n/locales/nl.json b/i18n/locales/nl.json index bf41518c21..91f2f9dd85 100644 --- a/i18n/locales/nl.json +++ b/i18n/locales/nl.json @@ -1599,7 +1599,6 @@ "merge_modified_lines": "Gewijzigde regels samenvoegen", "no_content_changes": "Geen inhoudelijke wijzigingen gedetecteerd", "options": "Opties", - "view_file": "Bekijk bestand", "view_in_code_browser": "Bekijk in code browser", "word_wrap": "Tekstomloop" }, diff --git a/i18n/locales/pt-BR.json b/i18n/locales/pt-BR.json index 8be735de9f..7f2c98c7b1 100644 --- a/i18n/locales/pt-BR.json +++ b/i18n/locales/pt-BR.json @@ -98,6 +98,7 @@ "current": "atual", "here": "você está aqui", "connected": "conectado", + "keyboard_shortcuts": {}, "state": { "on": "ativado", "off": "desativado" @@ -228,6 +229,9 @@ "more_replies": "{count} mais resposta... | {count} mais respostas..." } }, + "noodles": { + "missing": {} + }, "settings": { "title": "configurações", "tagline": "personalize sua experiência npmx", @@ -283,6 +287,7 @@ "slate": "Ardósia", "black": "Preto" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "Habilitar atalhos de teclado", "keyboard_shortcuts_enabled_description": "Os atalhos de teclado podem ser desativados se entrarem em conflito com outros atalhos do navegador ou do sistema", "enable_code_ligatures": "Habilitar ligaturas no código" @@ -688,7 +693,8 @@ "general_description": "O eixo Y representa o número de downloads. O eixo X representa o intervalo de datas, de {start_date} a {end_date}, com um período de {granularity}.{estimation_notice} {packages_analysis}. {watermark}.", "facet_bar_general_description": "Gráfico de barras horizontais para: {packages}, comparando {facet} ({description}). {facet_analysis} {watermark}.", "facet_bar_analysis": "{package_name} tem um valor de {value}." - } + }, + "embedding": {} }, "downloads": { "title": "Downloads Semanais", @@ -1189,6 +1195,25 @@ } } }, + "sponsors_page": { + "what_we_do": {}, + "what_support_means": {}, + "what_this_means_for_you": { + "cards": { + "people": {}, + "visitors": {}, + "stars": {}, + "community": {}, + "adoption": {}, + "default_source": {} + } + }, + "tiers": { + "silver": {}, + "gold": {}, + "platinum": {} + } + }, "account_menu": { "connect": "conectar", "account": "Conta", @@ -1363,6 +1388,7 @@ "label": "Estrelas no Github", "description": "Número de estrelas no repositório GitHub" }, + "githubForks": {}, "githubIssues": { "label": "Issues no Github", "description": "Número de issues no repositório GitHub" @@ -1435,7 +1461,6 @@ "merge_modified_lines": "Mesclar linhas modificadas", "no_content_changes": "Nenhuma alteração de conteúdo detectada", "options": "Opções", - "view_file": "Visualizar arquivo", "view_in_code_browser": "Visualizar código no navegador", "word_wrap": "Quebra de linha" }, diff --git a/i18n/locales/pt-PT.json b/i18n/locales/pt-PT.json index 8589219401..d94da4c2f5 100644 --- a/i18n/locales/pt-PT.json +++ b/i18n/locales/pt-PT.json @@ -98,6 +98,7 @@ "current": "atual", "here": "estás aqui", "connected": "ligado", + "keyboard_shortcuts": {}, "state": { "on": "ativado", "off": "desativado" @@ -228,6 +229,9 @@ "more_replies": "mais {count} resposta... | mais {count} respostas..." } }, + "noodles": { + "missing": {} + }, "settings": { "title": "definições", "tagline": "personaliza a tua experiência npmx", @@ -283,6 +287,7 @@ "slate": "Ardósia", "black": "Preto" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "Ativar atalhos de teclado", "keyboard_shortcuts_enabled_description": "Os atalhos de teclado podem ser desativados se entrarem em conflito com outros atalhos do navegador ou do sistema", "enable_code_ligatures": "Ativar ligaturas no código" @@ -692,7 +697,8 @@ "general_description": "O eixo Y representa o número de transferências. O eixo X representa o intervalo de datas, de {start_date} a {end_date}, com periodicidade {granularity}.{estimation_notice} {packages_analysis}. {watermark}.", "facet_bar_general_description": "Gráfico de barras horizontais para: {packages}, comparando {facet} ({description}). {facet_analysis} {watermark}.", "facet_bar_analysis": "{package_name} tem um valor de {value}." - } + }, + "embedding": {} }, "downloads": { "title": "Transferências Semanais", @@ -1200,6 +1206,25 @@ } } }, + "sponsors_page": { + "what_we_do": {}, + "what_support_means": {}, + "what_this_means_for_you": { + "cards": { + "people": {}, + "visitors": {}, + "stars": {}, + "community": {}, + "adoption": {}, + "default_source": {} + } + }, + "tiers": { + "silver": {}, + "gold": {}, + "platinum": {} + } + }, "account_menu": { "connect": "ligar", "account": "Conta", @@ -1374,6 +1399,7 @@ "label": "Estrelas no GitHub", "description": "Número de estrelas no repositório GitHub" }, + "githubForks": {}, "githubIssues": { "label": "Issues no GitHub", "description": "Número de issues no repositório GitHub" @@ -1446,7 +1472,6 @@ "merge_modified_lines": "Fundir linhas modificadas", "no_content_changes": "Nenhuma alteração de conteúdo detetada", "options": "Opções", - "view_file": "Ver ficheiro", "view_in_code_browser": "Ver código no navegador", "word_wrap": "Quebra de linha" }, diff --git a/i18n/locales/ro-RO.json b/i18n/locales/ro-RO.json index 6667f08eaf..947c9515c9 100644 --- a/i18n/locales/ro-RO.json +++ b/i18n/locales/ro-RO.json @@ -98,6 +98,7 @@ "current": "actual", "here": "ești aici", "connected": "conectat", + "keyboard_shortcuts": {}, "state": { "on": "activată", "off": "dezactivată" @@ -228,6 +229,9 @@ "more_replies": "{count} repostare în plus... | {count} repostări în plus..." } }, + "noodles": { + "missing": {} + }, "settings": { "title": "setări", "tagline": "personalizează-ți experiența cu npmx", @@ -283,6 +287,7 @@ "slate": "Ardezie", "black": "Negru" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "Activează comenzile rapide de la tastatură", "keyboard_shortcuts_enabled_description": "Comenzile rapide de la tastatură pot fi dezactivate dacă intră în conflict cu alte comenzi rapide ale browserului sau ale sistemului", "enable_code_ligatures": "Activează litere ligaturate în cod" @@ -700,7 +705,8 @@ "general_description": "Axa Y reprezintă numărul de descărcări. Axa X reprezintă intervalul de date, de la {start_date} până la {end_date}, cu o perioadă de timp de {granularity}.{estimation_notice} {packages_analysis}. {watermark}.", "facet_bar_general_description": "Diagramă cu bare orizontale pentru: {packages}, comparând {facet} ({description}). {facet_analysis} {watermark}.", "facet_bar_analysis": "{package_name} are valoarea {value}." - } + }, + "embedding": {} }, "downloads": { "title": "Descărcări Săptămânale", @@ -1208,6 +1214,25 @@ } } }, + "sponsors_page": { + "what_we_do": {}, + "what_support_means": {}, + "what_this_means_for_you": { + "cards": { + "people": {}, + "visitors": {}, + "stars": {}, + "community": {}, + "adoption": {}, + "default_source": {} + } + }, + "tiers": { + "silver": {}, + "gold": {}, + "platinum": {} + } + }, "account_menu": { "connect": "conectează", "account": "Cont", @@ -1382,6 +1407,7 @@ "label": "Stele GitHub", "description": "Numărul de stele din repository-ul GitHub" }, + "githubForks": {}, "githubIssues": { "label": "Probleme GitHub", "description": "Numărul de probleme din repository-ul GitHub" @@ -1454,7 +1480,6 @@ "merge_modified_lines": "Îmbină linii modificate", "no_content_changes": "Nu există modificări de conținut detectate", "options": "Opțiuni", - "view_file": "Vezi fișier", "view_in_code_browser": "Vezi în browser de cod", "word_wrap": "Aliniere automată" }, diff --git a/i18n/locales/ru-RU.json b/i18n/locales/ru-RU.json index 4770fe640d..55150a4108 100644 --- a/i18n/locales/ru-RU.json +++ b/i18n/locales/ru-RU.json @@ -1598,7 +1598,6 @@ "merge_modified_lines": "Объединить изменённые строки", "no_content_changes": "Изменений содержимого не обнаружено", "options": "Параметры", - "view_file": "Открыть файл", "view_in_code_browser": "В браузере кода", "word_wrap": "Перенос строк" }, diff --git a/i18n/locales/sr-Latn-RS.json b/i18n/locales/sr-Latn-RS.json index 2c76fa50b9..ce5a0dc270 100644 --- a/i18n/locales/sr-Latn-RS.json +++ b/i18n/locales/sr-Latn-RS.json @@ -77,6 +77,7 @@ "instant_search_advisory": "{label} {state} — {action}" }, "command_palette": { + "keyboard_shortcuts": {}, "state": {}, "groups": {}, "actions": {}, @@ -131,6 +132,9 @@ "more_replies": "{count} još odgovor... | {count} još odgovora... | {count} još odgovora..." } }, + "noodles": { + "missing": {} + }, "settings": { "title": "podešavanja", "tagline": "prilagodite svoje npmx iskustvo", @@ -185,6 +189,7 @@ "slate": "Škriljac", "black": "Crna" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "Omogućite prečice na tastaturi", "keyboard_shortcuts_enabled_description": "Prečice na tastaturi mogu biti isključene ako su u sukobu sa drugim prečicama pregledača ili sistema" }, @@ -558,7 +563,8 @@ "general_description": "Y osa predstavlja broj preuzimanja. X osa predstavlja opseg datuma, od {start_date} do {end_date}, sa vremenskim periodom {granularity}.{estimation_notice} {packages_analysis}. {watermark}.", "facet_bar_general_description": "Horizontalni stubičasti grafikon za: {packages}, poređenje {facet} ({description}). {facet_analysis} {watermark}.", "facet_bar_analysis": "{package_name} ima vrednost {value}." - } + }, + "embedding": {} }, "downloads": { "title": "Nedeljna preuzimanja", @@ -1055,6 +1061,25 @@ } } }, + "sponsors_page": { + "what_we_do": {}, + "what_support_means": {}, + "what_this_means_for_you": { + "cards": { + "people": {}, + "visitors": {}, + "stars": {}, + "community": {}, + "adoption": {}, + "default_source": {} + } + }, + "tiers": { + "silver": {}, + "gold": {}, + "platinum": {} + } + }, "account_menu": { "connect": "povežite se", "account": "Nalog", @@ -1217,6 +1242,7 @@ "description": "Poznate bezbednosne ranjivosti" }, "githubStars": {}, + "githubForks": {}, "githubIssues": {}, "createdAt": {} }, @@ -1283,7 +1309,6 @@ "merge_modified_lines": "Spojite izmenjene linije", "no_content_changes": "Nema otkrivenih promena u sadržaju", "options": "Opcije", - "view_file": "Pogledajte datoteku", "view_in_code_browser": "Pogledajte u pregledaču koda", "word_wrap": "Prelamanje reči" }, diff --git a/i18n/locales/tr-TR.json b/i18n/locales/tr-TR.json index 911af52729..b69219540a 100644 --- a/i18n/locales/tr-TR.json +++ b/i18n/locales/tr-TR.json @@ -98,6 +98,7 @@ "current": "mevcut", "here": "buradasınız", "connected": "bağlı", + "keyboard_shortcuts": {}, "state": { "on": "açık", "off": "kapalı" @@ -229,6 +230,9 @@ "more_replies": "{count} yanıt daha... | {count} yanıt daha..." } }, + "noodles": { + "missing": {} + }, "settings": { "title": "ayarlar", "tagline": "npmx deneyiminizi kişiselleştirin", @@ -284,6 +288,7 @@ "slate": "Arduvaz", "black": "Siyah" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "Klavye kısayolları etkin", "keyboard_shortcuts_enabled_description": "Hızlı navigasyon için klavye kısayollarını etkinleştir", "enable_code_ligatures": "Kodda ligature'ları etkinleştir", @@ -708,7 +713,8 @@ "general_description": "Y ekseni indirme sayısını temsil eder. X ekseni tarih aralığını temsil eder, {start_date}'den {end_date}'e, {granularity} zaman dönemi ile.{estimation_notice} {packages_analysis}. {watermark}.", "facet_bar_general_description": "{packages} paketleri için yatay çubuk grafiği, {facet} karşılaştırması ({description}). {facet_analysis} {watermark}.", "facet_bar_analysis": "{package_name} paketi {value} değerine sahip." - } + }, + "embedding": {} }, "downloads": { "title": "Haftalık İndirmeler", @@ -1216,6 +1222,25 @@ } } }, + "sponsors_page": { + "what_we_do": {}, + "what_support_means": {}, + "what_this_means_for_you": { + "cards": { + "people": {}, + "visitors": {}, + "stars": {}, + "community": {}, + "adoption": {}, + "default_source": {} + } + }, + "tiers": { + "silver": {}, + "gold": {}, + "platinum": {} + } + }, "account_menu": { "connect": "Bağlan", "account": "Hesap", @@ -1390,6 +1415,7 @@ "label": "GitHub Yıldızları", "description": "GitHub deposundaki yıldız sayısı" }, + "githubForks": {}, "githubIssues": { "label": "GitHub Sorunları", "description": "GitHub deposundaki sorun sayısı" @@ -1462,7 +1488,6 @@ "merge_modified_lines": "Değiştirilen satırları birleştir", "no_content_changes": "İçerik değişikliği tespit edilmedi", "options": "Seçenekler", - "view_file": "Dosyayı görüntüle", "view_in_code_browser": "Kod tarayıcısında aç", "word_wrap": "Kelime kaydırma" }, diff --git a/i18n/locales/uk-UA.json b/i18n/locales/uk-UA.json index af398342f5..6dfb371e09 100644 --- a/i18n/locales/uk-UA.json +++ b/i18n/locales/uk-UA.json @@ -98,6 +98,7 @@ "current": "поточна", "here": "ви тут", "connected": "підключено", + "keyboard_shortcuts": {}, "state": { "on": "увімкнено", "off": "вимкнено" @@ -228,6 +229,9 @@ "more_replies": "ще {count} відповідь... | ще {count} відповіді... | ще {count} відповідей..." } }, + "noodles": { + "missing": {} + }, "settings": { "title": "налаштування", "tagline": "налаштуйте ваше середовище npmx", @@ -283,6 +287,7 @@ "slate": "Сланцевий", "black": "Чорний" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "Увімкнути гарячі клавіші", "keyboard_shortcuts_enabled_description": "Гарячі клавіші можна вимкнути, якщо вони конфліктують з налаштуваннями браузера або системи", "enable_code_ligatures": "Увімкнути лігатури в коді" @@ -703,7 +708,8 @@ "general_description": "Вісь Y відображає кількість завантажень. Вісь X відображає діапазон дат, від {start_date} до {end_date}, з часовим інтервалом {granularity}.{estimation_notice} {packages_analysis}. {watermark}.", "facet_bar_general_description": "Горизонтальна стовпчаста діаграма для {packages}, порівнюється {facet} ({description}). {facet_analysis} {watermark}.", "facet_bar_analysis": "{package_name} має значення {value}." - } + }, + "embedding": {} }, "downloads": { "title": "Завантажень на тиждень", @@ -1211,6 +1217,25 @@ } } }, + "sponsors_page": { + "what_we_do": {}, + "what_support_means": {}, + "what_this_means_for_you": { + "cards": { + "people": {}, + "visitors": {}, + "stars": {}, + "community": {}, + "adoption": {}, + "default_source": {} + } + }, + "tiers": { + "silver": {}, + "gold": {}, + "platinum": {} + } + }, "account_menu": { "connect": "підключити", "account": "Обліковий запис", @@ -1385,6 +1410,7 @@ "label": "Зірки GitHub", "description": "Кількість зірок у репозиторії GitHub" }, + "githubForks": {}, "githubIssues": { "label": "Issues GitHub", "description": "Кількість issues у репозиторії GitHub" @@ -1457,7 +1483,6 @@ "merge_modified_lines": "Об'єднати змінені рядки", "no_content_changes": "Змін вмісту не виявлено", "options": "Параметри", - "view_file": "Переглянути файл", "view_in_code_browser": "Переглянути в браузері коду", "word_wrap": "Перенесення рядків" }, diff --git a/i18n/locales/vi-VN.json b/i18n/locales/vi-VN.json index 1301de2d17..5fe432dd7e 100644 --- a/i18n/locales/vi-VN.json +++ b/i18n/locales/vi-VN.json @@ -77,6 +77,7 @@ "instant_search_advisory": "{label} {state} — {action}" }, "command_palette": { + "keyboard_shortcuts": {}, "state": {}, "groups": {}, "actions": {}, @@ -131,6 +132,9 @@ "more_replies": "Thêm {count} phản hồi... | Thêm {count} phản hồi..." } }, + "noodles": { + "missing": {} + }, "settings": { "title": "cài đặt", "tagline": "tùy chỉnh trải nghiệm npmx của riêng bạn", @@ -185,6 +189,7 @@ "slate": "Slate", "black": "Black" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "Phím tắt", "keyboard_shortcuts_enabled_description": "Bạn có thể vô hiệu hóa phím tắt nếu gặp xung đột với trình duyệt hoặc các phím tắt hệ thống khác." }, @@ -558,7 +563,8 @@ "general_description": "Trục Y biểu thị số lượt tải. Trục X biểu thị khoảng ngày, từ {start_date} đến {end_date}, với độ chi tiết {granularity}.{estimation_notice} {packages_analysis}. {watermark}.", "facet_bar_general_description": "Biểu đồ cột ngang cho: {packages}, so sánh {facet} ({description}). {facet_analysis} {watermark}.", "facet_bar_analysis": "{package_name} có giá trị {value}." - } + }, + "embedding": {} }, "downloads": { "title": "Lượt tải hàng tuần", @@ -1055,6 +1061,25 @@ } } }, + "sponsors_page": { + "what_we_do": {}, + "what_support_means": {}, + "what_this_means_for_you": { + "cards": { + "people": {}, + "visitors": {}, + "stars": {}, + "community": {}, + "adoption": {}, + "default_source": {} + } + }, + "tiers": { + "silver": {}, + "gold": {}, + "platinum": {} + } + }, "account_menu": { "connect": "kết nối", "account": "Tài khoản", @@ -1217,6 +1242,7 @@ "description": "Các lỗ hổng bảo mật phổ biến" }, "githubStars": {}, + "githubForks": {}, "githubIssues": {}, "createdAt": {} }, @@ -1283,7 +1309,6 @@ "merge_modified_lines": "Gộp các dòng đã sửa", "no_content_changes": "Không phát hiện thay đổi về nội dung", "options": "Tùy chọn", - "view_file": "Xem tệp", "view_in_code_browser": "Xem trong trình duyệt mã nguồn", "word_wrap": "Ngắt dòng" }, diff --git a/i18n/locales/zh-CN.json b/i18n/locales/zh-CN.json index 99d9019d6a..7f64fd6c3e 100644 --- a/i18n/locales/zh-CN.json +++ b/i18n/locales/zh-CN.json @@ -98,6 +98,7 @@ "current": "当前", "here": "你在这里", "connected": "已连接", + "keyboard_shortcuts": {}, "state": { "on": "开启", "off": "关闭" @@ -228,6 +229,9 @@ "more_replies": "还有 {count} 条回复..." } }, + "noodles": { + "missing": {} + }, "settings": { "title": "设置", "tagline": "定制你的 npmx 体验", @@ -283,6 +287,7 @@ "slate": "板岩灰", "black": "黑色" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "启用快捷键", "keyboard_shortcuts_enabled_description": "如果某些快捷键与其他浏览器或系统快捷键冲突,可以选择将其禁用。", "enable_code_ligatures": "在代码中启用连字" @@ -703,7 +708,8 @@ "general_description": "Y 轴表示下载量,X 轴表示日期范围({start_date} 至 {end_date}),统计周期为{granularity}。{estimation_notice} {packages_analysis}。{watermark}。", "facet_bar_general_description": "水平条形图:{packages} 的 {facet} 对比({description})。{facet_analysis} {watermark}", "facet_bar_analysis": "{package_name}:{value}" - } + }, + "embedding": {} }, "downloads": { "title": "每周下载量", @@ -1212,6 +1218,25 @@ } } }, + "sponsors_page": { + "what_we_do": {}, + "what_support_means": {}, + "what_this_means_for_you": { + "cards": { + "people": {}, + "visitors": {}, + "stars": {}, + "community": {}, + "adoption": {}, + "default_source": {} + } + }, + "tiers": { + "silver": {}, + "gold": {}, + "platinum": {} + } + }, "account_menu": { "connect": "连接", "account": "账户", @@ -1386,6 +1411,7 @@ "label": "GitHub 星标", "description": "GitHub 仓库的星标数量" }, + "githubForks": {}, "githubIssues": { "label": "GitHub 问题数", "description": "GitHub 仓库的问题数量" @@ -1458,7 +1484,6 @@ "merge_modified_lines": "合并修改的行", "no_content_changes": "没有内容更改检测到", "options": "选项", - "view_file": "查看文件", "view_in_code_browser": "在代码浏览器中查看", "word_wrap": "自动换行" }, diff --git a/i18n/locales/zh-TW.json b/i18n/locales/zh-TW.json index e2b15eefb7..9237326ec2 100644 --- a/i18n/locales/zh-TW.json +++ b/i18n/locales/zh-TW.json @@ -94,6 +94,7 @@ "current": "目前", "here": "你所在的位置", "connected": "已連線", + "keyboard_shortcuts": {}, "state": { "on": "開", "off": "關" @@ -224,6 +225,9 @@ "more_replies": "還有 {count} 則回覆⋯⋯ | 還有 {count} 則回覆⋯⋯" } }, + "noodles": { + "missing": {} + }, "settings": { "title": "設定", "tagline": "自訂你的 npmx 體驗", @@ -279,6 +283,7 @@ "slate": "板岩灰", "black": "黑色" }, + "foreground_themes": {}, "keyboard_shortcuts_enabled": "啟用鍵盤快速鍵", "keyboard_shortcuts_enabled_description": "若與其他瀏覽器或系統快捷鍵衝突,可停用鍵盤快速鍵" }, @@ -657,7 +662,8 @@ "general_description": "Y 軸代表下載次數。X 軸代表日期範圍,從 {start_date} 至 {end_date},以 {granularity} 為時間單位。 {estimation_notice} {packages_analysis}. {watermark}.", "facet_bar_general_description": "水平長條圖: {package} 的 {facet} 對比({description}). {facet_analysis} {watermark}.", "facet_bar_analysis": "{package_name} 值為 {value}." - } + }, + "embedding": {} }, "downloads": { "title": "每週下載量", @@ -1159,6 +1165,25 @@ } } }, + "sponsors_page": { + "what_we_do": {}, + "what_support_means": {}, + "what_this_means_for_you": { + "cards": { + "people": {}, + "visitors": {}, + "stars": {}, + "community": {}, + "adoption": {}, + "default_source": {} + } + }, + "tiers": { + "silver": {}, + "gold": {}, + "platinum": {} + } + }, "account_menu": { "connect": "連線", "account": "帳戶", @@ -1330,6 +1355,7 @@ "description": "已知安全漏洞" }, "githubStars": {}, + "githubForks": {}, "githubIssues": {}, "createdAt": {} }, @@ -1396,7 +1422,6 @@ "merge_modified_lines": "合併修改過的行", "no_content_changes": "未偵測到內容變更", "options": "選項", - "view_file": "檢視檔案", "view_in_code_browser": "在程式碼瀏覽器中檢視", "word_wrap": "自動換行" }, diff --git a/i18n/schema.json b/i18n/schema.json index a955b9da4e..86d377ae0c 100644 --- a/i18n/schema.json +++ b/i18n/schema.json @@ -4663,6 +4663,9 @@ "compare_versions_title": { "type": "string" }, + "copy_diff": { + "type": "string" + }, "comparing_versions_label": { "type": "string" }, @@ -4801,7 +4804,7 @@ "options": { "type": "string" }, - "view_file": { + "view_diff": { "type": "string" }, "view_in_code_browser": { diff --git a/server/api/registry/compare-file/[...pkg].get.ts b/server/api/registry/compare-file/[...pkg].get.ts index 5f5504e01d..50b306a1f8 100644 --- a/server/api/registry/compare-file/[...pkg].get.ts +++ b/server/api/registry/compare-file/[...pkg].get.ts @@ -1,6 +1,12 @@ import * as v from 'valibot' import { PackageFileDiffQuerySchema } from '#shared/schemas/package' -import { countDiffStats, createDiff, insertSkipBlocks, truncateDiffHunks } from '#shared/utils/diff' +import { + countDiffStats, + createDiff, + createUnifiedDiff, + insertSkipBlocks, + truncateDiffHunks, +} from '#shared/utils/diff' import type { DiffHunk, DiffSkipBlock } from '#shared/types/compare' const CACHE_VERSION = 3 @@ -172,6 +178,7 @@ export default defineCachedEventHandler( try { // Get diff options from query params const query = getQuery(event) + const rawDiffRequested = query.format === 'diff' const diffOptions = { mergeModifiedLines: query.mergeModifiedLines !== 'false', maxChangeRatio: parseFloat(query.maxChangeRatio as string) || 0.45, @@ -233,6 +240,12 @@ export default defineCachedEventHandler( } : diffOptions + if (rawDiffRequested) { + setResponseHeader(event, 'content-type', 'text/x-diff; charset=utf-8') + setResponseHeader(event, 'x-content-type-options', 'nosniff') + return createUnifiedDiff(fromContent ?? '', toContent ?? '', filePath, type) + } + // Create diff with options const diff = createDiff(fromContent ?? '', toContent ?? '', filePath, effectiveDiffOptions) @@ -329,6 +342,11 @@ export default defineCachedEventHandler( getKey: event => { const pkg = getRouterParam(event, 'pkg') ?? '' const query = getQuery(event) + const format = query.format === 'diff' ? 'diff' : 'json' + const normalizedPkg = pkg.replace(/\/+$/, '').trim() + if (format === 'diff') { + return `compare-file:v${CACHE_VERSION}:${normalizedPkg}:diff` + } // Normalize option values to prevent cache pollution from arbitrary floats. // These match the parsing logic used in the handler body. const merge = query.mergeModifiedLines !== 'false' @@ -336,7 +354,7 @@ export default defineCachedEventHandler( const distance = parseInt(query.maxDiffDistance as string, 10) || 30 const charEdits = parseInt(query.inlineMaxCharEdits as string, 10) || 2 const optionsKey = `${merge}:${ratio}:${distance}:${charEdits}` - return `compare-file:v${CACHE_VERSION}:${pkg.replace(/\/+$/, '').trim()}:${optionsKey}` + return `compare-file:v${CACHE_VERSION}:${normalizedPkg}:${format}:${optionsKey}` }, }, ) diff --git a/shared/utils/diff.ts b/shared/utils/diff.ts index a9a4c68627..0329268226 100644 --- a/shared/utils/diff.ts +++ b/shared/utils/diff.ts @@ -381,18 +381,27 @@ export function createDiff( filePath: string, options: Partial = {}, ): FileDiff | null { - const diffText = createTwoFilesPatch( - `a/${filePath}`, - `b/${filePath}`, + const diffText = createUnifiedDiff(oldContent, newContent, filePath) + + const files = parseUnifiedDiff(diffText, options) + return files[0] ?? null +} + +export function createUnifiedDiff( + oldContent: string, + newContent: string, + filePath: string, + type: 'add' | 'delete' | 'modify' = 'modify', +): string { + return createTwoFilesPatch( + type === 'add' ? '/dev/null' : `a/${filePath}`, + type === 'delete' ? '/dev/null' : `b/${filePath}`, oldContent, newContent, '', '', { context: 3 }, ) - - const files = parseUnifiedDiff(diffText, options) - return files[0] ?? null } export function countDiffStats(hunks: (DiffHunk | DiffSkipBlock)[]): { diff --git a/test/nuxt/components/diff/ViewerPanel.spec.ts b/test/nuxt/components/diff/ViewerPanel.spec.ts new file mode 100644 index 0000000000..82ef73d38f --- /dev/null +++ b/test/nuxt/components/diff/ViewerPanel.spec.ts @@ -0,0 +1,114 @@ +import { mountSuspended } from '@nuxt/test-utils/runtime' +import { beforeEach, describe, expect, it, vi } from 'vitest' + +const { mockFetch, mockClipboardWrite } = vi.hoisted(() => ({ + mockFetch: vi.fn(), + mockClipboardWrite: vi.fn(), +})) + +const props = { + packageName: '@scope/package', + fromVersion: '1.0.0', + toVersion: '2.0.0', + file: { + path: 'src/file #1.ts', + type: 'modified' as const, + oldSize: 100, + newSize: 120, + }, +} + +const fileDiffResponse = { + package: props.packageName, + from: props.fromVersion, + to: props.toVersion, + path: props.file.path, + type: 'modify', + hunks: [], + stats: { additions: 0, deletions: 0 }, + meta: { large: false, truncated: false, computeTime: 1 }, +} + +describe('DiffViewerPanel raw diff actions', () => { + beforeEach(() => { + mockFetch.mockReset() + mockClipboardWrite.mockReset() + mockFetch.mockImplementation((url: string) => + Promise.resolve( + url.includes('?format=diff') + ? '--- a/src/index.ts\n+++ b/src/index.ts\n' + : fileDiffResponse, + ), + ) + mockClipboardWrite.mockResolvedValue(undefined) + Object.defineProperty(navigator, 'clipboard', { + configurable: true, + value: { write: mockClipboardWrite }, + }) + }) + + it('links to and copies the selected file as a raw diff', async () => { + const { default: DiffViewerPanel } = await import('~/components/Diff/ViewerPanel.vue') + vi.stubGlobal('$fetch', mockFetch) + const wrapper = await mountSuspended(DiffViewerPanel, { props }) + const rawDiffUrl = + '/api/registry/compare-file/%40scope/package/v/1.0.0...2.0.0/src/file%20%231.ts?format=diff' + + const viewLink = wrapper.get(`a[href="${rawDiffUrl}"]`) + expect(viewLink.text()).toBe('View .diff') + + const copyButton = wrapper + .findAll('button') + .find(button => button.text().trim() === 'Copy .diff') + expect(copyButton).toBeDefined() + + await copyButton!.trigger('click') + + await vi.waitFor(() => { + expect(mockFetch).toHaveBeenCalledWith(rawDiffUrl, { responseType: 'text' }) + expect(mockClipboardWrite).toHaveBeenCalledOnce() + }) + + wrapper.unmount() + }) + + it('starts the clipboard write before a slow raw diff request resolves', async () => { + let resolveRawDiff!: (value: string) => void + mockFetch.mockImplementation((url: string) => + url.includes('?format=diff') + ? new Promise(resolve => (resolveRawDiff = resolve)) + : Promise.resolve(fileDiffResponse), + ) + vi.stubGlobal('$fetch', mockFetch) + const { default: DiffViewerPanel } = await import('~/components/Diff/ViewerPanel.vue') + const wrapper = await mountSuspended(DiffViewerPanel, { props }) + + const copyButton = wrapper + .findAll('button') + .find(button => button.text().trim() === 'Copy .diff') + await copyButton!.trigger('click') + + expect(mockClipboardWrite).toHaveBeenCalledOnce() + resolveRawDiff('--- a/src/index.ts\n+++ b/src/index.ts\n') + await vi.waitFor(() => expect(copyButton!.attributes('disabled')).toBeUndefined()) + + wrapper.unmount() + }) + + it('does not report a failed clipboard write as copied', async () => { + mockClipboardWrite.mockRejectedValueOnce(new Error('clipboard denied')) + vi.stubGlobal('$fetch', mockFetch) + const { default: DiffViewerPanel } = await import('~/components/Diff/ViewerPanel.vue') + const wrapper = await mountSuspended(DiffViewerPanel, { props }) + + const copyButton = wrapper + .findAll('button') + .find(button => button.text().trim() === 'Copy .diff') + await copyButton!.trigger('click') + await vi.waitFor(() => expect(copyButton!.attributes('disabled')).toBeUndefined()) + + expect(copyButton!.text()).toContain('Copy .diff') + expect(copyButton!.text()).not.toContain('Copied') + wrapper.unmount() + }) +}) diff --git a/test/unit/shared/utils/diff.spec.ts b/test/unit/shared/utils/diff.spec.ts index bdeecb2318..4fcc782389 100644 --- a/test/unit/shared/utils/diff.spec.ts +++ b/test/unit/shared/utils/diff.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { truncateDiffHunks } from '#shared/utils/diff' +import { createUnifiedDiff, truncateDiffHunks } from '#shared/utils/diff' import type { DiffHunk, DiffSkipBlock } from '#shared/types/compare' function createHunk(lineCount: number): DiffHunk { @@ -19,6 +19,27 @@ function createHunk(lineCount: number): DiffHunk { } } +describe('createUnifiedDiff', () => { + it('creates a unified patch for a modified file', () => { + const result = createUnifiedDiff('old\n', 'new\n', 'src/index.ts') + + expect(result).toContain('--- a/src/index.ts') + expect(result).toContain('+++ b/src/index.ts') + expect(result).toContain('-old') + expect(result).toContain('+new') + }) + + it('uses /dev/null for added and deleted files', () => { + const added = createUnifiedDiff('', 'new\n', 'added.ts', 'add') + const deleted = createUnifiedDiff('old\n', '', 'deleted.ts', 'delete') + + expect(added).toContain('--- /dev/null') + expect(added).toContain('+++ b/added.ts') + expect(deleted).toContain('--- a/deleted.ts') + expect(deleted).toContain('+++ /dev/null') + }) +}) + describe('truncateDiffHunks', () => { it('leaves hunks untouched when they fit within the line budget', () => { const hunk = createHunk(2)