Compare commits
3 Commits
85420872ab
...
97983aff87
| Author | SHA1 | Date | |
|---|---|---|---|
|
97983aff87
|
|||
|
c000517fd1
|
|||
|
8fe3a87ee2
|
+4
-2
@@ -9,9 +9,11 @@ isHelp() {
|
||||
return 1
|
||||
}
|
||||
echoReadmeInfo() {
|
||||
local -r script="bs/${0##*/}"
|
||||
local -r script="bs/${0##*bs/}"
|
||||
local info
|
||||
info="$(grep -A1 "## $script" "$readme" | tail -n1)"
|
||||
if ! info="$(grep -A1 "## $script" "$readme" | tail -n1)"; then
|
||||
info="No info found in $readme for $script"
|
||||
fi
|
||||
cat <<-EOF
|
||||
$info
|
||||
Usage: $script [options]
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# Basic Episodes Fetch
|
||||
|
||||
## Overview
|
||||
This plan focuses on adding a minimal **episodes‑fetch** feature that pulls podcast episodes from the CommaFeed backend
|
||||
using environment variables for configuration.
|
||||
|
||||
The plan is derived from:
|
||||
- `docs/dev/README.md` (API endpoints, authentication)
|
||||
- `src/` structure and existing route system
|
||||
- Build scripts in `bs/` – only linting is required at this stage.
|
||||
|
||||
## Tasks
|
||||
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/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. **Page update** (TODO)
|
||||
- Add fetching all episodes
|
||||
- Update `<app-episodes>` to reflect loading state(s).
|
||||
- Add episode list item component.
|
||||
- Update `<app-episodes>` to render the episode list received from the route context.
|
||||
1. **Testing** (TODO)
|
||||
- Add unit tests for `api/*.ts` using project test setup.
|
||||
- Add unit test for created component(s)
|
||||
1. **Linting** (TODO)
|
||||
- Ensure all new files satisfy the lint rule defined in `bs/dev/lint`.
|
||||
|
||||
## Expected Output
|
||||
- Visiting `/episodes/` will display a list of episodes fetched from CommaFeed.
|
||||
- Episodes are identified by their `id` and displayed with title, publish date, and an audio link if available.
|
||||
- Authentication uses the env variables; no credentials are hard‑coded in source.
|
||||
|
||||
---
|
||||
|
||||
> **Note**: This plan intentionally keeps external dependencies minimal. It can be extended later for pagination, caching, or offline support.
|
||||
@@ -2,3 +2,4 @@
|
||||
|
||||
- [x] initial setup (`bs`, app structure, …)
|
||||
- [x] adds routing support
|
||||
- [ ] [episodes basic fetch](./plans/plan-basic-episodes.md)
|
||||
|
||||
@@ -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<Episode[]> {
|
||||
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<Episode> {
|
||||
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;
|
||||
}
|
||||
@@ -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<Response> {
|
||||
|
||||
const url = `${url_base}/${endpoint}`;
|
||||
const auth = authHeader();
|
||||
|
||||
const headers = new Headers(options.headers);
|
||||
headers.set('Authorization', auth);
|
||||
|
||||
return fetch(url, {
|
||||
...options,
|
||||
headers,
|
||||
});
|
||||
}
|
||||
+2
-1
@@ -34,7 +34,8 @@
|
||||
"types": ["mocha"],
|
||||
"lib": ["es2021", "dom", "DOM.Iterable"],
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
"@/*": ["./src/*"],
|
||||
"ENV": ["./.env.js"]
|
||||
}
|
||||
},
|
||||
"include": ["**/*.ts"]
|
||||
|
||||
Reference in New Issue
Block a user