f4b404's picture
Upload folder using huggingface_hub
f55c62a verified
Raw
History Blame Contribute Delete
3.53 kB
import { UserData } from '@aiostreams/core';
import { getObjectDiff, sortKeys, DiffItem } from './diff';
/** Strip volatile / identity fields that should never appear in a diff. */
export function filterForDiff(d: UserData | null): UserData | null {
if (!d) return d;
const filtered: any = { ...d };
delete filtered.ip;
delete filtered.uuid;
delete filtered.accessToken;
delete filtered.trusted;
delete filtered.encryptedPassword;
delete filtered.showChanges;
if (filtered.parentConfig?.password) {
filtered.parentConfig = { ...filtered.parentConfig, password: '[hidden]' };
}
return sortKeys(filtered) as UserData;
}
/**
* Replace raw addon instance IDs inside groupings with their human-readable
* names, so the diff shows "Torrentio" instead of "abc123".
*/
export function resolveNamesInConfig(
conf: UserData | null,
presetsSource: UserData['presets']
): UserData | null {
if (!conf || !conf.groups) return conf;
const newConf = { ...conf, groups: { ...conf.groups } };
if (newConf.groups.groupings) {
newConf.groups.groupings = newConf.groups.groupings.map((g: any) => {
if (Array.isArray(g.addons)) {
return {
...g,
addons: g.addons.map((id: string) => {
const find = (list?: any[]) =>
list?.find((p) => p.instanceId === id || p.options?.id === id);
const item = find(presetsSource);
return item?.options?.name || id;
}),
};
}
return g;
});
}
return newConf;
}
function resolveId(v: string, allPresets: UserData['presets']): string {
const addon = allPresets?.find((p) => {
if (p.instanceId === v) return true;
const opts = p.options as Record<string, any>;
return opts?.id === v;
});
if (addon) {
const opts = addon.options as Record<string, any>;
if (opts?.name && typeof opts.name === 'string') return opts.name;
}
return v;
}
/**
* Returns a formatter function that recursively replaces addon IDs with names
* and JSON-serialises objects for display in the diff viewer.
*/
export function createValueFormatter(
allPresets: UserData['presets']
): (val: any) => string {
const resolveDeep = (v: any): any => {
if (typeof v === 'string') return resolveId(v, allPresets);
if (Array.isArray(v)) return v.map(resolveDeep);
if (v && typeof v === 'object') {
return Object.fromEntries(
Object.entries(v).map(([k, value]) => [k, resolveDeep(value)])
);
}
return v;
};
return (val: any): string => {
const resolved = resolveDeep(val);
if (typeof resolved === 'object' && resolved !== null) {
try {
return JSON.stringify(resolved, null, 2);
} catch {
return '[Circular Reference]';
}
}
return String(resolved);
};
}
export interface UserDataDiffResult {
diffs: DiffItem[];
processedOld: UserData | null;
processedNew: UserData | null;
}
export function computeUserDataDiff(
oldConfig: UserData | null,
newConfig: UserData | null
): UserDataDiffResult {
const allPresets: UserData['presets'] = [
...(oldConfig?.presets ?? []),
...(newConfig?.presets ?? []),
];
const filteredOld = filterForDiff(oldConfig);
const filteredNew = filterForDiff(newConfig);
const processedOld = resolveNamesInConfig(filteredOld, allPresets);
const processedNew = resolveNamesInConfig(filteredNew, allPresets);
const diffs = getObjectDiff(processedOld, processedNew);
return { diffs, processedOld, processedNew };
}