Files
DemonGatanjieu-Anomalous_Mo…/web/modules/model_source_data.js
T

68 lines
2.7 KiB
JavaScript

import { isPhysicalRenameProtectedType } from './model_policies.js';
export function usableSourceUrl(value) {
const url = typeof value === 'string' ? value.trim() : '';
if (!url) return '';
const civitaiModel = url.match(/^https?:\/\/(?:www\.)?civitai\.(?:com|red)\/models\/(-?\d+)(?:[/?#]|$)/i);
if (civitaiModel && Number(civitaiModel[1]) <= 0) return '';
return url;
}
export function foundationModelType(model) {
const candidates = Array.isArray(model?.folderTypes) ? [...model.folderTypes] : [];
if (model?.type) candidates.push(model.type);
return candidates.find(isPhysicalRenameProtectedType) || '';
}
export function shapeLibrarySourceModels(rawList, detectPlatform) {
return (Array.isArray(rawList) ? rawList : []).map(m => {
const meta = m.metadata || {};
const sourceUrl = usableSourceUrl(meta.source_url);
const civitaiUrl = usableSourceUrl(meta.civitai_url);
const url = sourceUrl || civitaiUrl;
const relPath = m.subfolder ? `${m.subfolder}/${m.filename}` : m.filename;
return {
key: `lib_${m.type}_${m.path_idx}_${relPath}`,
type: m.type,
path_idx: m.path_idx,
subfolder: m.subfolder || '',
filename: m.filename,
basename: m.filename,
relPath,
size_mb: m.size_mb || 0,
hash: meta.hash || '',
civitai_url: civitaiUrl,
source_url: sourceUrl,
url,
initialUrl: url,
platform: detectPlatform(url),
hasResolved: Boolean(url.trim()),
};
});
}
function matchesSearch(model, keyword) {
if (!keyword) return true;
const haystack = `${model.nodeTitle || ''} ${model.nodeType || ''} ${model.type || ''} ${model.filename || ''} ${model.basename || ''}`.toLowerCase();
return haystack.includes(keyword);
}
export function partitionSourceModels(models, filter = 'all', searchKeyword = '') {
const allModels = Array.isArray(models) ? models : [];
const allComponents = allModels.filter(model => Boolean(foundationModelType(model)));
const allMain = allModels.filter(model => !foundationModelType(model));
const matchesFilter = model => {
if (filter === 'resolved' && !model.url) return false;
if (filter === 'unresolved' && model.url) return false;
return matchesSearch(model, searchKeyword);
};
const mainModels = allMain.filter(matchesFilter);
const componentModels = allComponents.filter(matchesFilter);
return {
mainModels,
componentModels,
allComponentCount: componentModels.length,
componentMissingCount: componentModels.filter(model => model.isMissing === true).length,
};
}