Files
Claude-Code-Workflow/ccw/frontend/src/lib/unsplash.ts
catlog22 b9b2932f50 Add tests and implement functionality for staged cascade search and LSP expansion
- Introduced a new JSON file for verbose output of the Codex Lens search results.
- Added unit tests for binary search functionality in `test_stage1_binary_search_uses_chunk_lines.py`.
- Implemented regression tests for staged cascade Stage 2 expansion depth in `test_staged_cascade_lsp_depth.py`.
- Created unit tests for staged cascade Stage 2 realtime LSP graph expansion in `test_staged_cascade_realtime_lsp.py`.
- Enhanced the ChainSearchEngine to respect configuration settings for staged LSP depth and improve search accuracy.
2026-02-08 21:54:42 +08:00

103 lines
2.4 KiB
TypeScript

/**
* Unsplash API Client
* Frontend functions to search Unsplash via the backend proxy.
*/
export interface UnsplashPhoto {
id: string;
thumbUrl: string;
smallUrl: string;
regularUrl: string;
photographer: string;
photographerUrl: string;
photoUrl: string;
blurHash: string | null;
downloadLocation: string;
}
export interface UnsplashSearchResult {
photos: UnsplashPhoto[];
total: number;
totalPages: number;
}
function getCsrfToken(): string | null {
const match = document.cookie.match(/XSRF-TOKEN=([^;]+)/);
return match ? decodeURIComponent(match[1]) : null;
}
/**
* Search Unsplash photos via backend proxy.
*/
export async function searchUnsplash(
query: string,
page = 1,
perPage = 20
): Promise<UnsplashSearchResult> {
const params = new URLSearchParams({
query,
page: String(page),
per_page: String(perPage),
});
const response = await fetch(`/api/unsplash/search?${params}`, {
credentials: 'same-origin',
});
if (!response.ok) {
const body = await response.json().catch(() => ({}));
throw new Error(body.error || `Unsplash search failed: ${response.status}`);
}
return response.json();
}
/**
* Upload a local image as background.
* Sends raw binary to avoid base64 overhead.
*/
export async function uploadBackgroundImage(file: File): Promise<{ url: string; filename: string }> {
const headers: Record<string, string> = {
'Content-Type': file.type,
'X-Filename': encodeURIComponent(file.name),
};
const csrfToken = getCsrfToken();
if (csrfToken) {
headers['X-CSRF-Token'] = csrfToken;
}
const response = await fetch('/api/background/upload', {
method: 'POST',
headers,
credentials: 'same-origin',
body: file,
});
if (!response.ok) {
const body = await response.json().catch(() => ({}));
throw new Error(body.error || `Upload failed: ${response.status}`);
}
return response.json();
}
/**
* Trigger Unsplash download event (required by API guidelines).
*/
export async function triggerUnsplashDownload(downloadLocation: string): Promise<void> {
const headers: Record<string, string> = {
'Content-Type': 'application/json',
};
const csrfToken = getCsrfToken();
if (csrfToken) {
headers['X-CSRF-Token'] = csrfToken;
}
await fetch('/api/unsplash/download', {
method: 'POST',
headers,
credentials: 'same-origin',
body: JSON.stringify({ downloadLocation }),
});
}