server for refapp and refbot and other stuff
0

Configure Feed

Select the types of activity you want to include in your feed.

fix: omit unset diff filters from SpinShare search (all-false empties results)

alpine (Jul 19, 2026, 1:03 AM +0200) 7e5c230e 57999963

+16 -23
+16 -23
src/external/spinshare.ts
··· 158 158 159 159 // Fetch basic chart metadata from the SpinShare API. 160 160 export async function fetchChartFromAPI(songId: number, fetchFn: FetchFn = fetch): Promise<SpinshareChartApiData> { 161 - try { 162 - const res = await fetchFn(`${config.spinshare.apiBaseUrl}/song/${songId}`, { headers: SPINSHARE_HEADERS }); 163 - if (!res.ok) throw new Error(`SpinShare API returned ${res.status} for song ${songId}`); 164 - const json = await res.json() as { status: number; data: SpinshareChartApiData }; 165 - if (json.status !== 200) throw new Error(`SpinShare API error for song ${songId}: ${json.status}`); 166 - return json.data; 167 - } 168 - catch (err) { 169 - logger.warn({ err: String(err), songId, url: `${config.spinshare.apiBaseUrl}/song/${songId}` }, 'DEBUG fetchChartFromAPI failed'); 170 - throw err; 171 - } 161 + const res = await fetchFn(`${config.spinshare.apiBaseUrl}/song/${songId}`, { headers: SPINSHARE_HEADERS }); 162 + if (!res.ok) throw new Error(`SpinShare API returned ${res.status} for song ${songId}`); 163 + const json = await res.json() as { status: number; data: SpinshareChartApiData }; 164 + if (json.status !== 200) throw new Error(`SpinShare API error for song ${songId}: ${json.status}`); 165 + return json.data; 172 166 } 173 167 174 168 export interface MaxScoreResult { ··· 290 284 ): Promise<SpinshareChartApiData[]> { 291 285 if (!query || !query.trim()) return []; 292 286 try { 293 - // SpinShare's /searchCharts treats diffRatingFrom/To as a literal rating 294 - // RANGE, so sending 0/0 filters everything out. Only include the range 295 - // when the caller actually sets a bound. 296 - const from = opts.diffRatingFrom; 297 - const to = opts.diffRatingTo; 287 + // SpinShare's /searchCharts treats the diff* booleans and diffRating* 288 + // range as FILTERS. Sending all-false / 0-0 filters everything out. 289 + // Only include each field when the caller explicitly sets it, so the 290 + // default request means "any chart". 298 291 const body: Record<string, unknown> = { 299 292 searchQuery: query.trim(), 300 - diffEasy: opts.diffEasy ?? false, 301 - diffNormal: opts.diffNormal ?? false, 302 - diffHard: opts.diffHard ?? false, 303 - diffExpert: opts.diffExpert ?? false, 304 - diffXD: opts.diffXD ?? false, 305 293 showExplicit: opts.showExplicit ?? true, 306 294 }; 307 - if (from != null) body.diffRatingFrom = from; 308 - if (to != null) body.diffRatingTo = to; 295 + if (opts.diffEasy != null) body.diffEasy = opts.diffEasy; 296 + if (opts.diffNormal != null) body.diffNormal = opts.diffNormal; 297 + if (opts.diffHard != null) body.diffHard = opts.diffHard; 298 + if (opts.diffExpert != null) body.diffExpert = opts.diffExpert; 299 + if (opts.diffXD != null) body.diffXD = opts.diffXD; 300 + if (opts.diffRatingFrom != null) body.diffRatingFrom = opts.diffRatingFrom; 301 + if (opts.diffRatingTo != null) body.diffRatingTo = opts.diffRatingTo; 309 302 const res = await fetchFn(`${config.spinshare.apiBaseUrl}/searchCharts`, { 310 303 method: 'POST', 311 304 headers: SPINSHARE_HEADERS,