Compare commits

...

1 Commits

Author SHA1 Message Date
bymyself
9835e5379b refactor: deduplicate Civitai hostname logic in getSourceName by reusing formatUtil
Extract `isCivitaiHost` as a private helper in formatUtil.ts and add a new
exported `isCivitaiUrl` for hostname-only detection. Refactor `isCivitaiModelUrl`
to use the helper (DRY), and update `getSourceName` in assetMetadataUtils.ts to
import and use `isCivitaiUrl` instead of inlining the same hostname checks.

Fixes #11357

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 03:12:18 +00:00
3 changed files with 34 additions and 18 deletions

View File

@@ -8,6 +8,7 @@ import {
getPathDetails,
highlightQuery,
isCivitaiModelUrl,
isCivitaiUrl,
isPreviewableMediaType,
truncateFilename
} from './formatUtil'
@@ -381,6 +382,19 @@ describe('formatUtil', () => {
})
})
describe('isCivitaiUrl', () => {
it.for([
{ url: 'https://civitai.com/models/123', expected: true },
{ url: 'https://civitai.red/models/123', expected: true },
{ url: 'https://sub.civitai.com/models/123', expected: true },
{ url: 'https://sub.civitai.red/models/123', expected: true },
{ url: 'https://example.com/model', expected: false },
{ url: 'not-a-url', expected: false }
])('$url → $expected', ({ url, expected }) => {
expect(isCivitaiUrl(url)).toBe(expected)
})
})
describe('isCivitaiModelUrl', () => {
it('recognizes civitai.red model URLs', () => {
expect(

View File

@@ -355,6 +355,22 @@ export const generateUUID = (): string => {
})
}
const isCivitaiHost = (hostname: string): boolean =>
hostname === 'civitai.com' ||
hostname.endsWith('.civitai.com') ||
hostname === 'civitai.red' ||
hostname.endsWith('.civitai.red')
/**
* Checks if a URL belongs to any Civitai domain (civitai.com or civitai.red).
* Use this for source-name detection; use `isCivitaiModelUrl` when the URL
* must also match a specific model API path format.
*/
export const isCivitaiUrl = (url: string): boolean => {
if (!isValidUrl(url)) return false
return isCivitaiHost(new URL(url).hostname.toLowerCase())
}
/**
* Checks if a URL is a Civitai model URL
* @example
@@ -367,17 +383,9 @@ export const isCivitaiModelUrl = (url: string): boolean => {
if (!isValidUrl(url)) return false
const urlObj = new URL(url)
const hostname = urlObj.hostname.toLowerCase()
const isCivitaiHost =
hostname === 'civitai.com' ||
hostname.endsWith('.civitai.com') ||
hostname === 'civitai.red' ||
hostname.endsWith('.civitai.red')
if (!isCivitaiHost) {
return false
}
const pathname = urlObj.pathname
if (!isCivitaiHost(urlObj.hostname.toLowerCase())) return false
const pathname = urlObj.pathname
return (
/^\/api\/download\/models\/(\d+)$/.test(pathname) ||
/^\/api\/v1\/models\/(\d+)$/.test(pathname) ||

View File

@@ -1,4 +1,5 @@
import type { AssetItem } from '@/platform/assets/schemas/assetSchema'
import { isCivitaiUrl } from '@/utils/formatUtil'
/**
* Type-safe utilities for extracting metadata from assets.
@@ -126,16 +127,9 @@ export function getAssetAdditionalTags(asset: AssetItem): string[] {
* @returns Human-readable source name
*/
export function getSourceName(url: string): string {
if (isCivitaiUrl(url)) return 'Civitai'
try {
const hostname = new URL(url).hostname.toLowerCase()
if (
hostname === 'civitai.com' ||
hostname.endsWith('.civitai.com') ||
hostname === 'civitai.red' ||
hostname.endsWith('.civitai.red')
) {
return 'Civitai'
}
if (hostname === 'huggingface.co' || hostname.endsWith('.huggingface.co')) {
return 'Hugging Face'
}