site: hero auto-discovery, pick.json hero selection, amazonLink + shortlist fields
- src/lib/hero.ts: review heroes are now auto-discovered via import.meta.glob over reviews/*/hero.<ext>; only legacy non-hero-named assets remain as explicit overrides. New reviews need zero registration. - Pick of the day moves from a hardcoded HERO_SLUG in index.astro to src/data/pick.json (content edit, not code edit); dev set-pick API and the review-page button now write pick.json. Fallback: latest review. - Schemas: finds gain shortlist (bool) + amazonLink; reviews gain amazonLink. - Review + find pages render an 'Also on Amazon' affiliate link when amazonLink is set, with shared disclosure handling. - Both hero globs now include .avif (two June finds ship avif heroes).
This commit is contained in:
+2
-6
@@ -12,7 +12,7 @@ const EXCLUDED_PATHS = new Set([
|
||||
|
||||
const FIND_ROOT = path.resolve('src/content/find');
|
||||
const REVIEW_ROOT = path.resolve('src/content/reviews');
|
||||
const HOME_PAGE = path.resolve('src/pages/index.astro');
|
||||
const PICK_FILE = path.resolve('src/data/pick.json');
|
||||
const VALID_SLUG = /^[a-z0-9][a-z0-9-]*$/;
|
||||
const VALID_TAG = /^[a-z0-9][a-z0-9-]{0,40}$/i;
|
||||
|
||||
@@ -118,11 +118,7 @@ const setPickApi = {
|
||||
if (!reviewPath.startsWith(REVIEW_ROOT + path.sep)) return send(res, 400, { error: 'path escape' });
|
||||
try { await stat(reviewPath); } catch { return send(res, 404, { error: 'review not found' }); }
|
||||
|
||||
const text = await readFile(HOME_PAGE, 'utf8');
|
||||
const re = /^(const HERO_SLUG = ')([^']+)(';)/m;
|
||||
if (!re.test(text)) return send(res, 422, { error: 'HERO_SLUG line not found in src/pages/index.astro' });
|
||||
const out = text.replace(re, (_, a, _b, c) => `${a}${slug}${c}`);
|
||||
await writeFile(HOME_PAGE, out, 'utf8');
|
||||
await writeFile(PICK_FILE, JSON.stringify({ hero: slug }, null, 2) + '\n', 'utf8');
|
||||
|
||||
return send(res, 200, { slug });
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user