import { apiClient } from '../api/api-client'; import { AppVersion, AppVersionFilter, UpdateAppVersionInput, UploadAppVersionInput, ParsedPackageInfo, } from '@/domain/entities/app-version'; /** Normalize version-service response: platform comes back as ANDROID/IOS, fileSize as bigint string */ function normalize(raw: Record): AppVersion { return { ...(raw as AppVersion), platform: (raw.platform as string).toLowerCase() as 'android' | 'ios', fileSize: raw.fileSize != null ? Number(raw.fileSize) : undefined, }; } export async function listVersions(filter?: AppVersionFilter): Promise { const params = new URLSearchParams(); if (filter?.platform) params.append('platform', filter.platform.toUpperCase()); if (filter?.includeDisabled) params.append('includeDisabled', 'true'); const qs = params.toString(); const result = await apiClient(`/api/v1/versions${qs ? '?' + qs : ''}`); return result.map((v) => normalize(v as Record)); } export async function getVersionById(id: string): Promise { const result = await apiClient(`/api/v1/versions/${id}`); return normalize(result as Record); } export async function updateVersion(id: string, input: UpdateAppVersionInput): Promise { const result = await apiClient(`/api/v1/versions/${id}`, { method: 'PUT', body: input }); return normalize(result as Record); } export async function deleteVersion(id: string): Promise { await apiClient(`/api/v1/versions/${id}`, { method: 'DELETE' }); } export async function toggleVersion(id: string, isEnabled: boolean): Promise { await apiClient(`/api/v1/versions/${id}/toggle`, { method: 'PATCH', body: { isEnabled }, }); } function getClientAuthHeaders(): Record { const headers: Record = {}; if (typeof window === 'undefined') return headers; const token = localStorage.getItem('access_token'); if (token) headers['Authorization'] = `Bearer ${token}`; const tenantData = localStorage.getItem('current_tenant'); if (tenantData) { try { const tenant = JSON.parse(tenantData) as { id: string }; headers['X-Tenant-Id'] = tenant.id; } catch { // ignore parse errors } } return headers; } export async function uploadVersion(input: UploadAppVersionInput): Promise { const formData = new FormData(); formData.append('file', input.file); formData.append('platform', input.platform.toUpperCase()); formData.append('versionName', input.versionName); formData.append('buildNumber', input.buildNumber); formData.append('isForceUpdate', String(input.isForceUpdate ?? false)); if (input.changelog) formData.append('changelog', input.changelog); if (input.minOsVersion) formData.append('minOsVersion', input.minOsVersion); const response = await fetch('/api/app-versions/upload', { method: 'POST', headers: getClientAuthHeaders(), body: formData, }); if (!response.ok) { const err = await response.json().catch(() => null) as { message?: string } | null; throw new Error(err?.message || `上传失败: ${response.status}`); } const result = await response.json() as Record; return normalize(result); } export async function parsePackage(file: File, platform: 'android' | 'ios'): Promise { const formData = new FormData(); formData.append('file', file); formData.append('platform', platform.toUpperCase()); const response = await fetch('/api/app-versions/parse', { method: 'POST', headers: getClientAuthHeaders(), body: formData, }); if (!response.ok) { throw new Error(`解析失败: ${response.status}`); } return response.json() as Promise; }