From d897191065f81e6e484bc4c4c25028d8c7e183ae Mon Sep 17 00:00:00 2001 From: ShroXd Date: Fri, 6 Mar 2026 18:23:41 +0800 Subject: [PATCH 1/6] feat: add placeholder for binary file --- .../v/[version]/[...filePath].vue | 32 +++++++++ app/utils/file-types.ts | 70 +++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 app/utils/file-types.ts diff --git a/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue b/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue index 0f3cbac2c2..7ee0376f7d 100644 --- a/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue +++ b/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue @@ -4,6 +4,7 @@ import type { PackageFileTreeResponse, PackageFileContentResponse, } from '#shared/types' +import { isBinaryFilePath } from '~/utils/file-types' definePageMeta({ name: 'code', @@ -105,6 +106,14 @@ const isViewingFile = computed(() => currentNode.value?.type === 'file') // Maximum file size we'll try to load (500KB) - must match server const MAX_FILE_SIZE = 500 * 1024 + +const isBinaryFile = computed(() => !!filePath.value && isBinaryFilePath(filePath.value)) +const showBinaryContent = shallowRef(false) + +watch(filePath, () => { + showBinaryContent.value = false +}) + const isFileTooLarge = computed(() => { const size = currentNode.value?.size return size !== undefined && size > MAX_FILE_SIZE @@ -116,6 +125,10 @@ const fileContentUrl = computed(() => { if (!filePath.value || !fileTree.value || isFileTooLarge.value || !isViewingFile.value) { return null } + // Don't fetch binary files until user explicitly requests rendering + if (isBinaryFile.value && !showBinaryContent.value) { + return null + } return `/api/registry/file/${packageName.value}/v/${version.value}/${filePath.value}` }) @@ -519,6 +532,25 @@ defineOgImageComponent('Default', { /> + +
+
+

Binary file

+

Rendering may produce garbled output.

+
+ Render anyway + + View raw file + +
+
+
diff --git a/app/utils/file-types.ts b/app/utils/file-types.ts new file mode 100644 index 0000000000..33e74324f1 --- /dev/null +++ b/app/utils/file-types.ts @@ -0,0 +1,70 @@ +// Extensions that are binary and cannot be meaningfully displayed as text +const BINARY_EXTENSIONS = new Set([ + // Images + 'png', + 'jpg', + 'jpeg', + 'gif', + 'webp', + 'ico', + 'bmp', + 'tiff', + 'tif', + 'avif', + 'heic', + 'heif', + // Fonts + 'woff', + 'woff2', + 'ttf', + 'otf', + 'eot', + // Archives + 'zip', + 'tar', + 'gz', + 'tgz', + 'bz2', + 'xz', + '7z', + 'rar', + // Executables / compiled + 'exe', + 'dll', + 'so', + 'dylib', + 'node', + 'wasm', + 'pyc', + 'class', + // Media + 'mp3', + 'mp4', + 'ogg', + 'wav', + 'avi', + 'mov', + 'webm', + 'flac', + 'aac', + 'mkv', + // Documents + 'pdf', + 'doc', + 'docx', + 'xls', + 'xlsx', + 'ppt', + 'pptx', + // Data + 'bin', + 'dat', + 'db', + 'sqlite', + 'sqlite3', +]) + +export function isBinaryFilePath(filePath: string): boolean { + const ext = filePath.split('.').pop()?.toLowerCase() ?? '' + return BINARY_EXTENSIONS.has(ext) +} From b23cd49efe7f6c6f8f0b74ac5c92d9fe18a83dfa Mon Sep 17 00:00:00 2001 From: ShroXd Date: Fri, 6 Mar 2026 18:42:39 +0800 Subject: [PATCH 2/6] feat: add en for binary file placeholder related text --- .../[packageName]/v/[version]/[...filePath].vue | 10 ++++++---- i18n/locales/en.json | 5 ++++- i18n/schema.json | 9 +++++++++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue b/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue index 7ee0376f7d..624eb2ffb6 100644 --- a/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue +++ b/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue @@ -538,15 +538,17 @@ defineOgImageComponent('Default', { class="py-20 text-center" >
-

Binary file

-

Rendering may produce garbled output.

+

{{ $t('code.binary_file') }}

+

{{ $t('code.binary_rendering_warning') }}

- Render anyway + {{ + $t('code.render_anyway') + }} - View raw file + {{ $t('code.view_raw') }}
diff --git a/i18n/locales/en.json b/i18n/locales/en.json index 5bc57ea17e..1c8f4c5c46 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -777,7 +777,10 @@ "code": "code" }, "file_path": "File path", - "scroll_to_top": "Scroll to top" + "scroll_to_top": "Scroll to top", + "binary_file": "Binary file", + "binary_rendering_warning": "File type not supported for preview.", + "render_anyway": "Render anyway" }, "badges": { "provenance": { diff --git a/i18n/schema.json b/i18n/schema.json index 4ed08a60b2..eb3ada1f9e 100644 --- a/i18n/schema.json +++ b/i18n/schema.json @@ -2337,6 +2337,15 @@ }, "scroll_to_top": { "type": "string" + }, + "binary_file": { + "type": "string" + }, + "binary_rendering_warning": { + "type": "string" + }, + "render_anyway": { + "type": "string" } }, "additionalProperties": false From 3339d4264d1bddf798fc3cd2afb673f4c4c417cc Mon Sep 17 00:00:00 2001 From: ShroXd Date: Fri, 6 Mar 2026 19:08:04 +0800 Subject: [PATCH 3/6] fix: follow existing pattern of naming --- .../[[org]]/[packageName]/v/[version]/[...filePath].vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue b/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue index 624eb2ffb6..fbf6f00cba 100644 --- a/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue +++ b/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue @@ -532,7 +532,7 @@ defineOgImageComponent('Default', { /> - +
Date: Sat, 7 Mar 2026 08:34:46 +0800 Subject: [PATCH 4/6] fix: remove render anyway button --- .../v/[version]/[...filePath].vue | 39 +++++++------------ i18n/locales/en.json | 3 +- i18n/schema.json | 3 -- 3 files changed, 15 insertions(+), 30 deletions(-) diff --git a/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue b/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue index fbf6f00cba..4fbb7846c9 100644 --- a/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue +++ b/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue @@ -108,11 +108,6 @@ const isViewingFile = computed(() => currentNode.value?.type === 'file') const MAX_FILE_SIZE = 500 * 1024 const isBinaryFile = computed(() => !!filePath.value && isBinaryFilePath(filePath.value)) -const showBinaryContent = shallowRef(false) - -watch(filePath, () => { - showBinaryContent.value = false -}) const isFileTooLarge = computed(() => { const size = currentNode.value?.size @@ -122,11 +117,13 @@ const isFileTooLarge = computed(() => { // Fetch file content when a file is selected (and not too large) const fileContentUrl = computed(() => { // Don't fetch if no file path, file tree not loaded, file is too large, or it's a directory - if (!filePath.value || !fileTree.value || isFileTooLarge.value || !isViewingFile.value) { - return null - } - // Don't fetch binary files until user explicitly requests rendering - if (isBinaryFile.value && !showBinaryContent.value) { + if ( + !filePath.value || + !fileTree.value || + isFileTooLarge.value || + !isViewingFile.value || + isBinaryFile.value + ) { return null } return `/api/registry/file/${packageName.value}/v/${version.value}/${filePath.value}` @@ -533,24 +530,16 @@ defineOgImageComponent('Default', { -
+

{{ $t('code.binary_file') }}

{{ $t('code.binary_rendering_warning') }}

-
- {{ - $t('code.render_anyway') - }} - - {{ $t('code.view_raw') }} - -
+ + {{ $t('code.view_raw') }} +
diff --git a/i18n/locales/en.json b/i18n/locales/en.json index 1c8f4c5c46..e485ba8eae 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -779,8 +779,7 @@ "file_path": "File path", "scroll_to_top": "Scroll to top", "binary_file": "Binary file", - "binary_rendering_warning": "File type not supported for preview.", - "render_anyway": "Render anyway" + "binary_rendering_warning": "File type not supported for preview." }, "badges": { "provenance": { diff --git a/i18n/schema.json b/i18n/schema.json index eb3ada1f9e..dfc2c339df 100644 --- a/i18n/schema.json +++ b/i18n/schema.json @@ -2343,9 +2343,6 @@ }, "binary_rendering_warning": { "type": "string" - }, - "render_anyway": { - "type": "string" } }, "additionalProperties": false From d81687ae9e6bde7edeb57bb04786e3a1e7cfb686 Mon Sep 17 00:00:00 2001 From: ShroXd Date: Sat, 7 Mar 2026 08:48:52 +0800 Subject: [PATCH 5/6] fix: fix render condition of file viewer --- .../[[org]]/[packageName]/v/[version]/[...filePath].vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue b/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue index 4fbb7846c9..cb1d3955d1 100644 --- a/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue +++ b/app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue @@ -436,7 +436,7 @@ defineOgImageComponent('Default', { ref="contentContainer" > -