eleventy-plugin-podcaster 2.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CLAUDE.md ADDED
@@ -0,0 +1,54 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Commands
6
+
7
+ ```bash
8
+ npm test # run all tests (AVA)
9
+ npx ava test/someTestFile.js # run a single test file
10
+ npx eslint src/ # lint source files
11
+ ```
12
+
13
+ There is no build step — the plugin is used directly from source.
14
+
15
+ ## Architecture
16
+
17
+ `eleventy.config.js` is the plugin entry point. It registers 8 sub-plugins and 3 optional features:
18
+
19
+ **Core sub-plugins (always active):**
20
+
21
+ - `podcastFeed.js` — RSS feed generation; creates `episodePost` and `episodePostWithChapters` collections via virtual templates
22
+ - `podcastData.js` — Computes podcast-level `eleventyComputed` fields: `feedPath`, `imagePath`, `episodeUrlBase`, `copyrightNotice`
23
+ - `episodeData.js` — Parses `seasonNumber`/`episodeNumber` from filenames; constructs episode `url` and `permalink`
24
+ - `calculateEpisodeSizeAndDuration.js` — Reads audio metadata from local files or S3; caches results; uses `music-metadata`
25
+ - `calculateEpisodeFilename.js` — Matches episode posts to audio files by season/episode number
26
+ - `readableFilters.js` — Adds `readableDate`, `readableDuration`, `readableSize` filters
27
+ - `chapters.js` — Filter for normalizing chapter data to JSON-LD; template in `src/chapters.njk`
28
+
29
+ **Optional features (opt-in via plugin options):**
30
+
31
+ - `drafts.js` — Filters draft posts; controlled by `INCLUDE_DRAFTS` env var or `ELEVENTY_RUN_MODE`
32
+ - `excerpts.js` — Auto-generates episode excerpts from front matter, HTML comments, or first paragraph
33
+ - `pageTitle.js` — Computes `pageTitle` with configurable separator
34
+
35
+ **Options:** `handleDrafts`, `handleExcerpts`, `handlePageTitles` (individual flags), or `optionalFeatures: true` (enables all three). `episodePostsDirectory` and `episodeFilesDirectory` override the default directory names.
36
+
37
+ ## Tests
38
+
39
+ Tests use AVA and are configured in `ava.config.js`. Each test file typically builds a fixture site using Eleventy's programmatic API and asserts on the output.
40
+
41
+ Fixture sites live in `fixtures/` — each is a minimal Eleventy site with `eleventy.config.js`, `_data/podcast.json`, episode markdown files in `episode-posts/`, and audio files in `episode-files/`.
42
+
43
+ Key environment variables used in tests:
44
+
45
+ - `SKIP_EPISODE_CALCULATIONS` — skip audio metadata calculation (speeds up tests that don't need it)
46
+ - `INCLUDE_DRAFTS` — controls draft inclusion
47
+ - `ELEVENTY_RUN_MODE` — `'build'` or `'serve'`
48
+
49
+ ## Conventions
50
+
51
+ - All source files are ES modules (`"type": "module"` in package.json)
52
+ - Computed episode/podcast fields are set via Eleventy's `eleventyComputed` pattern
53
+ - No Luxon — duration logic uses native `Intl` / `Date`; see `src/readableDuration.js`
54
+ - Commit messages: short past-tense verb phrases, no body, no co-author lines (e.g. `Removed Luxon dependency`)
package/jsconfig.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "compilerOptions": {
3
+ "checkJs": false
4
+ }
5
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eleventy-plugin-podcaster",
3
- "version": "2.0.2",
3
+ "version": "2.1.0",
4
4
  "description": "An Eleventy plugin that allows you to create a podcast and its accompanying website",
5
5
  "main": "eleventy.config.js",
6
6
  "exports": {
@@ -29,7 +29,7 @@
29
29
  "license": "ISC",
30
30
  "dependencies": {
31
31
  "@11ty/eleventy": "^3.0.0",
32
- "@11ty/eleventy-plugin-rss": "^2.0.1",
32
+ "@11ty/eleventy-plugin-rss": "^3.0.0",
33
33
  "@aws-sdk/client-s3": "^3.862.0",
34
34
  "@tsmx/human-readable": "^2.0.3",
35
35
  "dom-serializer": "^2.0.0",
@@ -40,8 +40,8 @@
40
40
  "devDependencies": {
41
41
  "ava": "^6.1.3",
42
42
  "dotenv": "^17.2.1",
43
- "fast-xml-parser": "^4.4.0",
44
- "mock-aws-s3-v3": "^6.0.5",
43
+ "fast-xml-parser": "^5.5.9",
44
+ "mock-aws-s3-v3": "^6.1.12",
45
45
  "neostandard": "^0.11.4"
46
46
  }
47
47
  }
@@ -13,7 +13,9 @@ export default function (eleventyConfig, options = {}) {
13
13
  eleventyExcludeFromCollections: true,
14
14
  eleventyImport: {
15
15
  collections: ['episodePost']
16
- }
16
+ },
17
+ script: options?.feedScript,
18
+ stylesheet: options?.feedStylesheet
17
19
  })
18
20
 
19
21
  const chaptersPath = path.join(import.meta.dirname, './chapters.njk')
@@ -5,12 +5,14 @@ eleventyAllowMissingExtension: true
5
5
  ---
6
6
  {%- set siteUrl %}{{ podcast.siteUrl or site.url }}{% endset -%}
7
7
  <?xml version="1.0" encoding="utf-8"?>
8
+ {% if stylesheet %}<?xml-stylesheet type="text/xsl" href="{{ stylesheet }}" ?>{% endif %}
8
9
  <rss version="2.0"
9
10
  xmlns:atom="http://www.w3.org/2005/Atom"
10
11
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
11
12
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
12
13
  xmlns:podcast="https://podcastindex.org/namespace/1.0">
13
14
  <channel>
15
+ {% if script %}<script src="{{ script }}" xmlns="http://www.w3.org/1999/xhtml"></script>{% endif %}
14
16
  <title>{{ podcast.title }}</title>
15
17
  <link>{{ siteUrl }}</link>
16
18
  <atom:link href="{{ permalink | htmlBaseUrl(siteUrl) }}" rel="self" type="application/rss+xml" />