const FILENAME_VARIANT_RULES: Array<{ pattern: RegExp; variant: string }> = [ { pattern: /arm64[-_]?v8a/i, variant: 'arm64-v8a' }, { pattern: /armeabi[-_]?v7a/i, variant: 'armeabi-v7a' }, { pattern: /x86[-_]?64/i, variant: 'x86_64' }, { pattern: /(? = { universal: 'Universal', 'arm64-v8a': 'ARM64 (arm64-v8a)', 'armeabi-v7a': 'ARMv7 (armeabi-v7a)', x86_64: 'x86_64', x86: 'x86' }; export function detectVariantFromFileName(fileName: string) { const baseName = fileName.trim().replace(/\.apk$/i, ''); for (const rule of FILENAME_VARIANT_RULES) { if (rule.pattern.test(baseName)) { return rule.variant; } } const normalized = baseName .toLowerCase() .replace(/[^a-z0-9]+/g, '-') .replace(/^-+|-+$/g, '') .slice(0, 64); return normalized || 'universal'; } export function formatReleaseVariantLabel(variant: string) { return VARIANT_LABELS[variant] ?? variant; } export function groupReleasesByVersion(releases: T[]) { const groups = new Map(); for (const release of releases) { const key = `${release.versionCode}:${release.version}`; const list = groups.get(key) ?? []; list.push(release); groups.set(key, list); } return [...groups.entries()] .sort((left, right) => Number(right[0].split(':')[0]) - Number(left[0].split(':')[0])) .map(([key, items]) => ({ key, version: items[0]?.version ?? '', versionCode: items[0]?.versionCode ?? 0, variants: [...items].sort((a, b) => { const left = 'variant' in a ? String((a as { variant?: string }).variant ?? '') : ''; const right = 'variant' in b ? String((b as { variant?: string }).variant ?? '') : ''; return left.localeCompare(right, 'ru'); }) })); }