diff --git a/src/platform/assets/composables/media/assetMappers.test.ts b/src/platform/assets/composables/media/assetMappers.test.ts new file mode 100644 index 0000000000..a4667a234e --- /dev/null +++ b/src/platform/assets/composables/media/assetMappers.test.ts @@ -0,0 +1,52 @@ +import { describe, expect, it, vi } from 'vitest' + +import { mapInputFileToAssetItem } from './assetMappers' + +vi.mock('@/scripts/api', () => ({ + api: { + apiURL: (path: string) => `/api${path}` + } +})) + +vi.mock('@/platform/distribution/cloudPreviewUtil', () => ({ + appendCloudResParam: vi.fn() +})) + +describe('mapInputFileToAssetItem', () => { + it('preserves a clean filename', () => { + const asset = mapInputFileToAssetItem('photo.png', 0, 'input') + + expect(asset.name).toBe('photo.png') + expect(asset.id).toBe('input-0-photo.png') + expect(asset.preview_url).toBe('/api/view?filename=photo.png&type=input') + }) + + it.each([ + ['photo.png [input]', 'photo.png'], + ['photo.png [output]', 'photo.png'], + ['photo.png [temp]', 'photo.png'], + ['clip.mp4[input]', 'clip.mp4'], + ['MyFile.WEBP [Input]', 'MyFile.WEBP'] + ])('strips ComfyUI directory annotation: %s -> %s', (input, expectedName) => { + const asset = mapInputFileToAssetItem(input, 1, 'input') + + expect(asset.name).toBe(expectedName) + expect(asset.id).toBe(`input-1-${expectedName}`) + expect(asset.preview_url).toBe( + `/api/view?filename=${encodeURIComponent(expectedName)}&type=input` + ) + }) + + it('leaves non-annotation brackets in the filename intact', () => { + const asset = mapInputFileToAssetItem('my [draft] image.png', 0, 'input') + + expect(asset.name).toBe('my [draft] image.png') + }) + + it('uses the directory passed in for the type query param', () => { + const asset = mapInputFileToAssetItem('clip.mp4 [output]', 0, 'output') + + expect(asset.preview_url).toBe('/api/view?filename=clip.mp4&type=output') + expect(asset.tags).toEqual(['output']) + }) +}) diff --git a/src/platform/assets/composables/media/assetMappers.ts b/src/platform/assets/composables/media/assetMappers.ts index da468ca9b3..67544a0e87 100644 --- a/src/platform/assets/composables/media/assetMappers.ts +++ b/src/platform/assets/composables/media/assetMappers.ts @@ -51,6 +51,17 @@ export function mapTaskOutputToAssetItem( } } +/** + * Strips ComfyUI's trailing directory-type annotation (e.g. ` [input]`, + * ` [output]`, `[temp]`) from a filename returned by the OSS internal + * `/internal/files/{type}` endpoint. The annotation is part of the wire + * format LoadImage-style widgets expect, but for the assets sidebar we + * want the canonical on-disk filename so type detection / titles work. + */ +function stripDirectoryAnnotation(filename: string): string { + return filename.replace(/\s*\[(?:input|output|temp)\]\s*$/i, '') +} + /** * Maps input directory file to AssetItem format * @param filename The filename @@ -63,13 +74,14 @@ export function mapInputFileToAssetItem( index: number, directory: 'input' | 'output' = 'input' ): AssetItem { - const params = new URLSearchParams({ filename, type: directory }) + const cleanName = stripDirectoryAnnotation(filename) + const params = new URLSearchParams({ filename: cleanName, type: directory }) const preview_url = api.apiURL(`/view?${params}`) - appendCloudResParam(params, filename) + appendCloudResParam(params, cleanName) return { - id: `${directory}-${index}-${filename}`, - name: filename, + id: `${directory}-${index}-${cleanName}`, + name: cleanName, size: 0, created_at: new Date().toISOString(), tags: [directory],