feat(web/m7-cover-sources): cover-providers API client + query
Adds CoverProvider type + capability union, getCoverProviders / updateCoverProvider / testCoverProvider against the three new admin endpoints, plus createCoverProvidersQuery (60s staleTime; refetches on focus + after mutations rather than polling — settings rarely change in operator time). New api.patch helper added to client.ts (the existing helpers were get/post/put/del; PATCH was missing). New qk.coverProviders() key follows the existing tuple pattern. api_key_set: bool replaces echoing the credential. UpdateCoverProviderPatch uses optional fields so the operator can change just enabled, just key, or both atomically. Vitest covers GET path, PATCH path with body, version_bumped response, POST /test path with empty body, ok=false error response. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -269,3 +269,63 @@ export function createCoverageQuery() {
|
||||
refetchInterval: 3_000
|
||||
});
|
||||
}
|
||||
|
||||
// Cover-art providers ------------------------------------------------------
|
||||
|
||||
export type CoverProviderCapability = 'album_cover' | 'artist_thumb' | 'artist_fanart';
|
||||
|
||||
export type CoverProvider = {
|
||||
id: string;
|
||||
display_name: string;
|
||||
requires_api_key: boolean;
|
||||
supports: CoverProviderCapability[];
|
||||
enabled: boolean;
|
||||
api_key_set: boolean;
|
||||
display_order: number;
|
||||
testable: boolean;
|
||||
};
|
||||
|
||||
export type CoverProvidersResponse = {
|
||||
providers: CoverProvider[];
|
||||
sources_version: number;
|
||||
};
|
||||
|
||||
export async function getCoverProviders(): Promise<CoverProvidersResponse> {
|
||||
return api.get<CoverProvidersResponse>('/api/admin/cover-sources');
|
||||
}
|
||||
|
||||
export type UpdateCoverProviderPatch = {
|
||||
enabled?: boolean;
|
||||
api_key?: string;
|
||||
};
|
||||
|
||||
export type UpdateCoverProviderResponse = CoverProvider & {
|
||||
version_bumped: boolean;
|
||||
};
|
||||
|
||||
export async function updateCoverProvider(
|
||||
id: string,
|
||||
patch: UpdateCoverProviderPatch
|
||||
): Promise<UpdateCoverProviderResponse> {
|
||||
return api.patch<UpdateCoverProviderResponse>(`/api/admin/cover-sources/${id}`, patch);
|
||||
}
|
||||
|
||||
export type TestCoverProviderResponse = {
|
||||
ok: boolean;
|
||||
duration_ms?: number;
|
||||
error?: string;
|
||||
};
|
||||
|
||||
export async function testCoverProvider(id: string): Promise<TestCoverProviderResponse> {
|
||||
return api.post<TestCoverProviderResponse>(`/api/admin/cover-sources/${id}/test`, {});
|
||||
}
|
||||
|
||||
// Settings rarely change in operator time. 60s staleTime; refetches
|
||||
// on window focus + after any mutation rather than polling.
|
||||
export function createCoverProvidersQuery() {
|
||||
return createQuery({
|
||||
queryKey: qk.coverProviders(),
|
||||
queryFn: getCoverProviders,
|
||||
staleTime: 60_000
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user