review: resolve extension via display filename + path-aware suffix

- Use getAssetDisplayFilename so Cloud assets (asset.name = content hash,
  filename on display_name) still produce a sensible extension label.
- Use getPathDetails so path-like filename metadata resolves the basename
  before extracting the suffix.
- Add regression tests for the Cloud hash case and path-prefixed names.
This commit is contained in:
Glary-Bot
2026-05-15 15:35:49 +00:00
parent 97d09c471d
commit 55855112ce
2 changed files with 24 additions and 10 deletions

View File

@@ -404,6 +404,23 @@ describe('assetMetadataUtils', () => {
expect(getAssetExtensionLabel(asset)).toBe('PNG')
})
it('falls back to display_name when asset.name is a content hash (Cloud case)', () => {
const asset = {
...mockAsset,
name: 'blake3:abcdef',
display_name: 'ComfyUI_00001_.png'
}
expect(getAssetExtensionLabel(asset)).toBe('PNG')
})
it('strips path prefixes before resolving the extension', () => {
const asset = {
...mockAsset,
name: 'subdir.v2/cover.jpg'
}
expect(getAssetExtensionLabel(asset)).toBe('JPG')
})
it('returns an empty string when no filename source has an extension', () => {
expect(
getAssetExtensionLabel({ ...mockAsset, name: 'no-extension' })

View File

@@ -1,5 +1,5 @@
import type { AssetItem } from '@/platform/assets/schemas/assetSchema'
import { getFilenameDetails, isCivitaiUrl } from '@/utils/formatUtil'
import { getPathDetails, isCivitaiUrl } from '@/utils/formatUtil'
/**
* Type-safe utilities for extracting metadata from assets.
@@ -201,17 +201,14 @@ export function getAssetCardTitle(asset: AssetItem): string {
/**
* Returns the asset's file extension formatted for display in metadata lines,
* e.g. `PNG`, `MP4`, `GLB`. Uses the canonical filename (with the
* user/metadata filename as a fallback) so that user-edited display names
* without an extension still produce a sensible label.
* e.g. `PNG`, `MP4`, `GLB`. Resolves the filename via
* {@link getAssetDisplayFilename} (covering the Cloud hash case where the
* extension lives on `display_name`) and uses {@link getPathDetails} so
* path-like values still resolve to the basename's suffix.
*
* Returns an empty string when no extension can be determined.
*/
export function getAssetExtensionLabel(asset: AssetItem): string {
const candidates = [asset.name, getAssetFilename(asset)]
for (const candidate of candidates) {
const suffix = getFilenameDetails(candidate).suffix
if (suffix) return suffix.toUpperCase()
}
return ''
const suffix = getPathDetails(getAssetDisplayFilename(asset)).suffix
return suffix ? suffix.toUpperCase() : ''
}