### Install, Build, and Test Commands Source: https://github.com/jpmonette/feed/blob/master/CLAUDE.md Use these pnpm commands for dependency installation, TypeScript compilation, running tests, and code formatting checks. ```bash pnpm install # Install dependencies pnpm build # Compile TypeScript (uses tsdown) pnpm test # Run Jest tests pnpm pretty:check # Check Prettier formatting pnpm pretty:fix # Fix formatting issues ``` -------------------------------- ### Install the feed Library Source: https://github.com/jpmonette/feed/blob/master/_autodocs/quick-start.md Install the feed library using npm, yarn, or pnpm. Node.js 20 or higher is required. ```bash npm install feed # or yarn add feed # or pnpm add feed ``` -------------------------------- ### Install Feed Package Source: https://github.com/jpmonette/feed/blob/master/README.md Install the feed package using Yarn. ```bash $ yarn add feed ``` -------------------------------- ### Complete Feed Generation Example Source: https://github.com/jpmonette/feed/blob/master/_autodocs/api-reference/feed.md This example demonstrates how to create a new feed instance, add categories and items, and generate the feed in Atom 1.0, RSS 2.0, and JSON Feed 1.0 formats. ```typescript import { Feed } from "feed"; // Create feed instance const feed = new Feed({ title: "Tech Blog", description: "Latest in technology", id: "https://techblog.example.com", link: "https://techblog.example.com", language: "en", copyright: "2024 Tech Blog", image: "https://techblog.example.com/logo.png", favicon: "https://techblog.example.com/favicon.ico", author: { name: "Sarah Chen", email: "sarah@techblog.example.com", link: "https://techblog.example.com/about" }, feedLinks: { rss: "https://techblog.example.com/feed.xml", atom: "https://techblog.example.com/feed.atom", json: "https://techblog.example.com/feed.json" } }); // Add categories feed.addCategory("JavaScript"); feed.addCategory("Web Development"); // Add items feed.addItem({ title: "React 19 Released", link: "https://techblog.example.com/react-19", date: new Date(), id: "react-19-release", description: "New features in React 19", content: "
React 19 introduces...
", author: [ { name: "Sarah Chen", email: "sarah@techblog.example.com" } ], published: new Date("2024-06-20") }); // Generate in different formats const atom = feed.atom1(); // Atom 1.0 XML const rss = feed.rss2(); // RSS 2.0 XML const json = feed.json1(); // JSON Feed 1.0 ``` -------------------------------- ### JSON Feed 1.0 Example Document Source: https://github.com/jpmonette/feed/blob/master/_autodocs/format-specifications.md This is a complete example of a JSON Feed 1.0 document, demonstrating all common properties for both the feed and its items. ```json { "version": "https://jsonfeed.org/version/1", "title": "Tech Blog", "home_page_url": "https://example.com", "feed_url": "https://example.com/feed.json", "description": "Latest articles", "icon": "https://example.com/logo.png", "author": { "name": "John Doe", "url": "https://example.com", "avatar": "https://example.com/avatar.jpg" }, "items": [ { "id": "article-1", "url": "https://example.com/article1", "title": "Getting Started", "content_html": "Full HTML content
", "summary": "A beginner's guide", "image": "https://example.com/image.jpg", "date_published": "2024-06-20T08:00:00.000Z", "date_modified": "2024-06-20T10:00:00.000Z", "author": { "name": "Jane Smith", "url": "https://example.com/jane" }, "tags": ["JavaScript", "Web Development"] } ] } ``` -------------------------------- ### Example JSON Feed 1.0 Output Source: https://github.com/jpmonette/feed/blob/master/_autodocs/api-reference/renderers.md A complete example demonstrating the structure and content of a JSON Feed 1.0 document generated by the renderer. ```json { "version": "https://jsonfeed.org/version/1", "title": "Tech Blog", "home_page_url": "https://example.com", "feed_url": "https://example.com/feed.json", "description": "Latest in technology", "icon": "https://example.com/logo.png", "author": { "name": "John Doe", "url": "https://example.com", "avatar": "https://example.com/avatar.png" }, "items": [ { "id": "article-1", "url": "https://example.com/article", "title": "Article Title", "content_html": "Full HTML content
", "summary": "Summary text", "image": "https://example.com/image.jpg", "date_published": "2024-06-20T12:00:00.000Z", "date_modified": "2024-06-20T12:00:00.000Z", "author": { "name": "Jane Smith", "url": "https://example.com/jane", "avatar": "https://example.com/jane.jpg" }, "tags": ["JavaScript", "Web Development"] } ] } ``` -------------------------------- ### Example Podcast Feed Configuration Source: https://github.com/jpmonette/feed/blob/master/_autodocs/types.md Illustrates the configuration for a podcast feed using FeedOptions. Highlights the 'podcast' and 'category' fields for podcast-specific extensions. ```typescript const podcastOptions: FeedOptions = { id: "https://techpodcast.example.com", title: "The Tech Podcast", description: "A weekly podcast about technology trends", link: "https://techpodcast.example.com", image: "https://techpodcast.example.com/artwork.jpg", author: { name: "Alex Johnson", email: "alex@techpodcast.example.com", link: "https://techpodcast.example.com" }, podcast: true, // Enable podcast extensions category: "Technology", feedLinks: { rss: "https://techpodcast.example.com/feed.xml" } }; const podcastFeed = new Feed(podcastOptions); ``` -------------------------------- ### Example Blog Feed Configuration Source: https://github.com/jpmonette/feed/blob/master/_autodocs/types.md Demonstrates how to configure FeedOptions for a blog feed. Includes essential fields like id, title, description, links, and author details. ```typescript const feedOptions: FeedOptions = { id: "https://techblog.example.com", title: "Tech Blog", description: "Latest articles in web development and JavaScript", link: "https://techblog.example.com", language: "en", copyright: "2024 Tech Blog", ttl: 60, // Cache for 1 hour author: { name: "Sarah Chen", email: "sarah@techblog.example.com", link: "https://techblog.example.com/about" }, image: "https://techblog.example.com/logo.png", favicon: "https://techblog.example.com/favicon.ico", feedLinks: { rss: "https://techblog.example.com/feed.xml", atom: "https://techblog.example.com/feed.atom", json: "https://techblog.example.com/feed.json" }, generator: "Tech Blog v2.0" }; const feed = new Feed(feedOptions); ``` -------------------------------- ### Category Examples Source: https://github.com/jpmonette/feed/blob/master/_autodocs/types.md Illustrates creating Category objects for different feed formats. Provide at least 'name' for compatibility. ```typescript // Simple category with name only const simpleCategory: Category = { name: "JavaScript" }; // RSS-style with domain const rssCategory: Category = { name: "Technology", domain: "http://www.dmoz.org/Computers/Programming/" }; // Atom-style with scheme and term const atomCategory: Category = { name: "Web Development", scheme: "http://example.com/taxonomy", term: "web-dev" }; feed.addItem({ title: "Article", link: "https://example.com/article", date: new Date(), category: [ simpleCategory, rssCategory, atomCategory ] }); ``` -------------------------------- ### Enclosure Usage Examples Source: https://github.com/jpmonette/feed/blob/master/_autodocs/types.md Demonstrates how to use the Enclosure type, from a simple URL string to a fully defined Enclosure object for podcast audio and image attachments. Shows how to add an item with audio and image enclosures to a feed. ```typescript // Simple string URL (MIME type auto-detected) const simpleImage: string = "https://example.com/photo.jpg"; ``` ```typescript // Full Enclosure object const podcastAudio: Enclosure = { url: "https://example.com/episodes/ep001.mp3", type: "audio/mpeg", length: 5242880, title: "Episode 1: Getting Started", duration: 1800 // 30 minutes }; ``` ```typescript // Image Enclosure const imageEnclosure: Enclosure = { url: "https://example.com/article-image.png", type: "image/png", length: 245000, title: "Article Banner" }; ``` ```typescript feed.addItem({ title: "My Podcast Episode", link: "https://example.com/episodes/1", date: new Date(), audio: podcastAudio, image: imageEnclosure }); ``` -------------------------------- ### Initialize Feed with Essential Options Source: https://github.com/jpmonette/feed/blob/master/_autodocs/INDEX.md Configure the basic settings for your feed, including title, ID, link, description, and author information. This is a required setup for any feed. ```typescript const feed = new Feed({ // Required title: "Feed Title", // Recommended id: "https://example.com", // Unique feed ID link: "https://example.com", // Website URL description: "Feed description", // Author info author: { name: "Author Name", email: "author@example.com" } }); ``` -------------------------------- ### RSS 2.0 Feed Example Source: https://github.com/jpmonette/feed/blob/master/_autodocs/format-specifications.md This is a complete example of an RSS 2.0 feed, including channel and item elements. It demonstrates standard tags and Atom extensions. ```xmlTypeScript is a typed superset of JavaScript...
", published: new Date("2024-06-15"), author: [ { name: "Jane Smith", email: "jane@example.com", link: "https://example.com/jane" } ], category: [ { name: "TypeScript" }, { name: "Web Development" } ], image: "https://example.com/articles/ts-intro.jpg", copyright: "2024 Example Blog" }; feed.addItem(item); ``` -------------------------------- ### Feed Class Constructor Source: https://github.com/jpmonette/feed/blob/master/_autodocs/INDEX.md Instantiate the Feed class with optional configuration options. This is the starting point for creating a new feed object. ```typescript new Feed(options: FeedOptions): Feed ``` -------------------------------- ### Sanitize Example: URL with Query Parameters Source: https://github.com/jpmonette/feed/blob/master/_autodocs/api-reference/utilities.md Demonstrates the sanitization of a URL containing query parameters. The output is safe for embedding within XML structures. Also shows handling of undefined input. ```typescript // Input URL with query parameters const url = "https://example.com/page?foo=1&bar=2&baz=3"; // After sanitization const sanitized = sanitize(url); // Result: "https://example.com/page?foo=1&bar=2&baz=3" // Now safe to embed in XML: // https://example.com/page?foo=1&bar=2&baz=3 // Undefined handling const result = sanitize(undefined); // Result: undefined ``` -------------------------------- ### Atom 1.0 Enclosure Links Examples Source: https://github.com/jpmonette/feed/blob/master/_autodocs/format-specifications.md Illustrates how to represent media attachments using elements with the 'enclosure' relation type, including optional attributes like type, title, and length. ```xml ``` -------------------------------- ### Serve a Feed from an Express Server Source: https://github.com/jpmonette/feed/blob/master/_autodocs/quick-start.md Integrate feed generation into an Express.js application to serve RSS feeds. This example sets up a route to generate and send an RSS 2.0 feed. ```typescript import express from "express"; import { Feed } from "feed"; const app = express(); app.get("/feed.rss", (req, res) => { const feed = new Feed({ title: "My Site", id: "https://example.com", link: "https://example.com" }); // Add items from database items.forEach(item => { feed.addItem({ title: item.title, link: item.url, date: item.date, id: item.id, description: item.description }); }); res.type("application/rss+xml"); res.send(feed.rss2()); }); app.listen(3000); ``` -------------------------------- ### URL Sanitization Example Source: https://github.com/jpmonette/feed/blob/master/_autodocs/quick-start.md The library automatically sanitizes URLs, including query parameters, for safe inclusion in feeds. ```typescript feed.addItem({ link: "https://example.com/page?foo=1&bar=2" // Automatically escaped in XML as: ...&bar=2 }); ``` -------------------------------- ### Express Server Integration with Environment Variables Source: https://github.com/jpmonette/feed/blob/master/_autodocs/configuration.md Shows an example of integrating the feed library into an Express.js server, using environment variables for feed configuration. Fallback values are provided if environment variables are not set. ```typescript import express from "express"; import { Feed } from "feed"; const app = express(); app.get("/feed.xml", (req, res) => { const feed = new Feed({ title: process.env.FEED_TITLE || "My Feed", link: process.env.FEED_LINK || "https://example.com", description: process.env.FEED_DESCRIPTION || "My feed description" }); // Add items... res.type("application/rss+xml"); res.send(feed.rss2()); }); ``` -------------------------------- ### Complete Atom Feed Example Source: https://github.com/jpmonette/feed/blob/master/_autodocs/format-specifications.md This XML document demonstrates the structure of a valid Atom feed, including essential elements like id, title, updated, author, link, and entry. It also shows optional elements such as subtitle, logo, icon, rights, category, and contributor. ```xmlFull HTML content
" }); // Generate output console.log(feed.rss2()); // RSS 2.0 XML console.log(feed.atom1()); // Atom 1.0 XML console.log(feed.json1()); // JSON Feed 1.0 ``` -------------------------------- ### Initialize Feed with Options Source: https://github.com/jpmonette/feed/blob/master/_autodocs/configuration.md Instantiate the Feed class with a FeedOptions object. The 'title' property is mandatory. ```typescript import { Feed } from "feed"; const feed = new Feed({ title: "My Feed", // ... other options }); ``` -------------------------------- ### Run a Single Test File Source: https://github.com/jpmonette/feed/blob/master/CLAUDE.md Execute a specific test file using pnpm and Jest. ```bash pnpm test src/__tests__/rss2.spec.ts ``` -------------------------------- ### Blog Feed Configuration Source: https://github.com/jpmonette/feed/blob/master/_autodocs/configuration.md Configure a standard blog feed with detailed metadata including author, image, and multiple feed link types. ```typescript const feed = new Feed({ title: "My Blog", id: "https://myblog.example.com", link: "https://myblog.example.com", description: "Articles about web development", language: "en", copyright: "© 2024 My Blog", author: { name: "John Smith", email: "john@myblog.example.com", link: "https://myblog.example.com/about" }, image: "https://myblog.example.com/logo.png", favicon: "https://myblog.example.com/favicon.ico", feedLinks: { rss: "https://myblog.example.com/feed.xml", atom: "https://myblog.example.com/feed.atom", json: "https://myblog.example.com/feed.json" }, updated: new Date(), generator: "My Blog v1.0", ttl: 60 // Suggest 1 hour cache }); ``` -------------------------------- ### Podcast Specific Options Source: https://github.com/jpmonette/feed/blob/master/_autodocs/INDEX.md Enable podcast extensions, specify the iTunes category, and set the artwork image for podcast feeds. These options are for podcast-specific configurations. ```typescript // Podcasts { podcast: true, // Enable podcast extensions category: "Technology", // iTunes category image: "artwork.jpg" // 1400x600px for podcasts } ``` -------------------------------- ### Enclosure Options Interface Source: https://github.com/jpmonette/feed/blob/master/README.md Defines the structure for media enclosure properties, used for audio, video, or generic attachments. ```typescript interface Enclosure { url: string; type?: string; // MIME type (e.g., "audio/mpeg") length?: number; // File size in bytes title?: string; duration?: number; // Duration in seconds (for podcasts) } ``` -------------------------------- ### Initialize Feed with Type Definitions Source: https://github.com/jpmonette/feed/blob/master/_autodocs/quick-start.md Use type definitions for type-safe configuration when initializing the Feed library. Import necessary types from the 'feed' package. ```typescript import type { Feed, FeedOptions, Item, Author, Category, Enclosure, Extension } from "feed"; // Use for type-safe configuration const options: FeedOptions = { title: "My Feed", id: "https://example.com" }; const feed = new Feed(options); const item: Item = { title: "Article", link: "https://example.com/article", date: new Date() }; feed.addItem(item); ``` -------------------------------- ### Create New Feed Instance Source: https://github.com/jpmonette/feed/blob/master/_autodocs/quick-start.md Instantiate a new feed object. The `FeedOptions` must include a `title` property. ```typescript new Feed(options: FeedOptions) ``` -------------------------------- ### Feed Library Architecture Overview Source: https://github.com/jpmonette/feed/blob/master/_autodocs/INDEX.md Illustrates the main components of the feed library, including the Feed class, its options, data structures, and the renderer functions for different feed formats. ```plaintext Feed (main class) ├── FeedOptions (constructor parameter) ├── items: Item[] ├── categories: string[] ├── contributors: Author[] ├── extensions: Extension[] └── Renderer Functions ├── rss2() → RSS 2.0 XML ├── atom1() → Atom 1.0 XML └── json1() → JSON Feed 1.0 ``` -------------------------------- ### Add Item-Level Extensions Source: https://github.com/jpmonette/feed/blob/master/_autodocs/types.md Demonstrates adding multiple item-level extensions, including podcast chapters and custom metadata. Each extension has a 'name' and 'objects' field, allowing for structured custom data per item. ```typescript // Item-level custom extension feed.addItem({ title: "Episode 1", link: "https://example.com/ep1", date: new Date(), extensions: [ { name: "podcast:chapters", objects: { "podcast:chapter": [ { start: "00:00:00", title: "Intro" }, { start: "00:05:00", title: "Main Topic" } ] } }, { name: "custom:metadata", objects: { "custom:rating": 5, "custom:featured": true } } ] }); ``` -------------------------------- ### Importing Feed Class (v3+) Source: https://github.com/jpmonette/feed/blob/master/_autodocs/INDEX.md Demonstrates how to import the Feed class using ES6 named imports, which is required from v3 onwards. Shows both CommonJS and ES module syntax. ```typescript // Old (v2.x and earlier) const Feed = require('feed'); // New (v3.x+) const { Feed } = require('feed'); // or import { Feed } from "feed"; ``` -------------------------------- ### Optional Field Handling in TypeScript Source: https://github.com/jpmonette/feed/blob/master/_autodocs/types.md Demonstrates safe checking for optional fields like language and description before including them in output. Fields set to undefined are omitted. ```typescript // These are equivalent in usage if (options.language) { // Language is included in RSS } if (item.description) { // Description is included in output } ``` -------------------------------- ### Enable WebSub/PubSubHubbub for Real-time Updates Source: https://github.com/jpmonette/feed/blob/master/_autodocs/INDEX.md Configure a Feed object to support WebSub (PubSubHubbub) for real-time feed updates. Provide the 'hub' URL to enable this functionality. The library automatically adds the necessary hub link to generated RSS and Atom feeds. ```typescript const feed = new Feed({ link: "https://example.com", hub: "https://pubsubhubbub.example.com/hub" }); // Automatically adds hub link to RSS and Atom feeds ``` -------------------------------- ### Import Feed Library Types Source: https://github.com/jpmonette/feed/blob/master/_autodocs/types.md Import all necessary types from the main feed library entry point. These types define the structure for feed elements. ```typescript import type { Item, FeedOptions, Author, Category, Enclosure, Extension } from "feed"; ``` -------------------------------- ### Serve RSS Feed Source: https://github.com/jpmonette/feed/blob/master/_autodocs/quick-start.md Set the content type to 'application/rss+xml' and send the generated RSS feed using `feed.rss2()`. ```typescript res.type("application/rss+xml"); res.send(feed.rss2()); ``` -------------------------------- ### Serve Atom Feed Source: https://github.com/jpmonette/feed/blob/master/_autodocs/quick-start.md Set the content type to 'application/atom+xml' and send the generated Atom feed using `feed.atom1()`. ```typescript res.type("application/atom+xml"); res.send(feed.atom1()); ``` -------------------------------- ### Add Content (HTML Body) to Item Source: https://github.com/jpmonette/feed/blob/master/_autodocs/quick-start.md Provide the main content for an item using HTML. A short `description` can also be included. ```typescript feed.addItem({ title: "Article", link: "https://example.com/article", date: new Date(), description: "Short summary", content: "Full HTML content here
Can be multiple paragraphs
" }); ``` -------------------------------- ### Serve JSON Feed Source: https://github.com/jpmonette/feed/blob/master/_autodocs/quick-start.md Set the content type to 'application/feed+json' and send the generated JSON feed using `feed.json1()`. ```typescript res.type("application/feed+json"); res.send(feed.json1()); ```