From 97983aff875a673dcb0342a62f7fec84c1a81621 Mon Sep 17 00:00:00 2001 From: Jan Andrle Date: Thu, 11 Jun 2026 15:03:28 +0200 Subject: [PATCH] :zap: Adds api --- changelog/plans/plan-basic-episodes.md | 15 ++++------- src/api/episodes.ts | 36 ++++++++++++++++++++++++++ src/api/fetchAPI.ts | 34 ++++++++++++++++++++++++ tsconfig.json | 3 ++- 4 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 src/api/episodes.ts create mode 100644 src/api/fetchAPI.ts diff --git a/changelog/plans/plan-basic-episodes.md b/changelog/plans/plan-basic-episodes.md index 673b40b..cc780e0 100644 --- a/changelog/plans/plan-basic-episodes.md +++ b/changelog/plans/plan-basic-episodes.md @@ -10,21 +10,16 @@ The plan is derived from: - Build scripts in `bs/` – only linting is required at this stage. ## Tasks -1. **Environment handling** (TODO) - - Create a small helper (`@core/env.ts`) that reads `.env.ts` (or falls back to process.env). - - Expose constants: `COMMAFEED_URL`, `USERNAME`, `PASSWORD`. -1. **API client** (TODO) +1. **API client** (DONE) - Adds `src/api` folder to the project structure (update also @src/README.md). - - Implement a lightweight wrapper around `fetch` in `src/api/index.ts`. - - Build `authHeader()` that returns the Basic‑Auth header using env vars. -1. **Episode service** (TODO) + - Implement a lightweight wrapper around `fetch` in `src/api/fetchAPI.ts`. + - Build `authHeader()` that returns the Basic‑Auth header using for now hardcoded vars. +1. **Episode service** (DONE) - Add `src/api/episodes.ts` with `getEpisodes(feedId)` and `getEpisode(id)`. - Add data types - Use `/rest/feed/entries?feed_id=${feedId}` endpoint. -1. **Route integration** (TODO) - - In `app-episodes/routes.ts`, call the service during `enter()` to pre‑fetch episodes. - - Pass fetched data via route context or set a global state (e.g., using Lit Labs signals). 1. **Page update** (TODO) + - Add fetching all episodes - Update `` to reflect loading state(s). - Add episode list item component. - Update `` to render the episode list received from the route context. diff --git a/src/api/episodes.ts b/src/api/episodes.ts new file mode 100644 index 0000000..e94f1f4 --- /dev/null +++ b/src/api/episodes.ts @@ -0,0 +1,36 @@ +import { fetchAPI } from "./fetchAPI.js"; + +export interface Episode { + id: string; + title: string; + published: string; // ISO string or similar + audio_url?: string; + description?: string; +} + +export interface FeedEntriesResponse { + entries: Episode[]; +} + +/** + * Fetches all entries for a given feed. + * @param feedId - The ID of the feed. + */ +export async function getEpisodes(feedId: string= "all"): Promise { + const response = await fetchAPI(`feed/entries?feed_id=${feedId}`); + if (!response.ok) + throw new Error(`Failed to fetch episodes: ${response.statusText}`); + const data = await response.json() as FeedEntriesResponse; + return data.entries || []; +} + +/** + * Fetches a single episode by its ID. + * @param id - The ID of the episode. + */ +export async function getEpisode(id: string): Promise { + const response = await fetchAPI(`feed/entry/${id}/`); + if (!response.ok) + throw new Error(`Failed to fetch episode: ${response.statusText}`); + return await response.json() as Episode; +} diff --git a/src/api/fetchAPI.ts b/src/api/fetchAPI.ts new file mode 100644 index 0000000..02673b4 --- /dev/null +++ b/src/api/fetchAPI.ts @@ -0,0 +1,34 @@ +const url_server = "https://rss.jaandrle.cz"; +const url_base = `${url_server}/rest`; +// @ts-expect-error S7016 +import { users } from "ENV"; +const [ username, password ] = users[0].split(':'); + +console.log(import.meta); + +/** + * Generates the Basic Authentication header. + */ +export function authHeader(): string { + const credentials = btoa(`${username}:${password}`); + return `Basic ${credentials}`; +} + +/** + * A lightweight wrapper around fetch for the CommaFeed API. + * @param endpoint - The API endpoint (e.g., '/rest/feed/') + * @param options - Fetch options + */ +export async function fetchAPI(endpoint: string, options: RequestInit = {}): Promise { + + const url = `${url_base}/${endpoint}`; + const auth = authHeader(); + + const headers = new Headers(options.headers); + headers.set('Authorization', auth); + + return fetch(url, { + ...options, + headers, + }); +} diff --git a/tsconfig.json b/tsconfig.json index 908063d..59655c1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -34,7 +34,8 @@ "types": ["mocha"], "lib": ["es2021", "dom", "DOM.Iterable"], "paths": { - "@/*": ["./src/*"] + "@/*": ["./src/*"], + "ENV": ["./.env.js"] } }, "include": ["**/*.ts"]