{"id":31725384,"url":"https://github.com/rumendamyanov/npm-feed","last_synced_at":"2025-10-09T05:42:56.524Z","repository":{"id":317039990,"uuid":"1065376101","full_name":"RumenDamyanov/npm-feed","owner":"RumenDamyanov","description":"A comprehensive TypeScript package for generating RSS and Atom feeds in Node.js applications with full caching support and customizable views","archived":false,"fork":false,"pushed_at":"2025-10-06T10:54:49.000Z","size":434,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-10-06T12:31:59.366Z","etag":null,"topics":["atom-generator","feed-generator","node-js","npm-package","rss-generator","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RumenDamyanov.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"RumenDamyanov","custom":["https://github.com/sponsors/RumenDamyanov"]}},"created_at":"2025-09-27T15:47:01.000Z","updated_at":"2025-10-06T10:54:46.000Z","dependencies_parsed_at":"2025-09-28T13:25:33.919Z","dependency_job_id":"a394052d-cc88-4e26-bbb7-35fcedb05c48","html_url":"https://github.com/RumenDamyanov/npm-feed","commit_stats":null,"previous_names":["rumendamyanov/npm-feed"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/RumenDamyanov/npm-feed","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RumenDamyanov%2Fnpm-feed","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RumenDamyanov%2Fnpm-feed/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RumenDamyanov%2Fnpm-feed/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RumenDamyanov%2Fnpm-feed/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RumenDamyanov","download_url":"https://codeload.github.com/RumenDamyanov/npm-feed/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RumenDamyanov%2Fnpm-feed/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000740,"owners_count":26082932,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["atom-generator","feed-generator","node-js","npm-package","rss-generator","typescript"],"created_at":"2025-10-09T05:42:53.609Z","updated_at":"2025-10-09T05:42:56.517Z","avatar_url":"https://github.com/RumenDamyanov.png","language":"TypeScript","funding_links":["https://github.com/sponsors/RumenDamyanov"],"categories":[],"sub_categories":[],"readme":"# @rumenx/feed\n\n[![npm version](https://badge.fury.io/js/@rumenx%2Ffeed.svg)](https://badge.fury.io/js/@rumenx%2Ffeed)\n[![Node.js CI](https://github.com/RumenDamyanov/npm-feed/actions/workflows/ci.yml/badge.svg)](https://github.com/RumenDamyanov/npm-feed/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/RumenDamyanov/npm-feed/branch/master/graph/badge.svg)](https://codecov.io/gh/RumenDamyanov/npm-feed)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.7-blue.svg)](https://www.typescriptlang.org/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Downloads](https://img.shields.io/npm/dm/@rumenx/feed.svg)](https://www.npmjs.com/package/@rumenx/feed)\n\nA comprehensive TypeScript package for generating RSS and Atom feeds in Node.js applications.\n\n**Framework-agnostic with built-in caching support, rich media features, and 100% type safety.**\n\n## 💡 Multi-Language Feed Family\n\nThis package is part of a comprehensive feed generation suite created by the same author:\n\n- 🐘 **PHP**: [RumenDamyanov/php-feed](https://github.com/RumenDamyanov/php-feed) - Composer package\n- 🐹 **Go**: [RumenDamyanov/go-feed](https://github.com/RumenDamyanov/go-feed) - Go module\n- 🟨 **Node.js**: This package - NPM package for JavaScript/TypeScript\n\nAll implementations share the same core philosophy and feature set with language-specific optimizations.\n\n## ✨ Features\n\n- 🎯 **Full TypeScript Support** - Complete type safety and IntelliSense\n- 🏗️ **Modern Architecture** - ESM/CJS dual package with tree-shaking support\n- 🚀 **Framework Agnostic** - Works with Express, Next.js, Fastify, or any Node.js project\n- 📡 **Multiple Formats** - RSS 2.0 and Atom 1.0 support\n- ⚡ **High Performance** - Optimized for large feeds with efficient memory usage\n- 🔍 **Advanced Validation** - Built-in URL validation and data sanitization\n- 📊 **Rich Media Support** - Images, videos, translations, and Google News\n- 🎨 **Custom Views** - Template-based feed generation with framework adapters\n- 🔧 **Dependency Injection** - Clean architecture with adapter pattern\n- 🌍 **Internationalization** - Full multi-language and translation support\n- 🧪 **Battle Tested** - Comprehensive test coverage with real-world validation\n- 📦 **Zero Dependencies** - Minimal runtime footprint\n\n## 📦 Installation\n\n```bash\n# npm\nnpm install @rumenx/feed\n\n# yarn\nyarn add @rumenx/feed\n\n# pnpm\npnpm add @rumenx/feed\n```\n\n## 🚀 Quick Start\n\n```typescript\nimport { Feed } from '@rumenx/feed';\n\n// Create a new feed\nconst feed = new Feed();\n\n// Configure the feed\nfeed\n  .setTitle('My Blog Feed')\n  .setDescription('Latest posts from my blog')\n  .setLink('https://example.com')\n  .setLanguage('en');\n\n// Add items\nfeed\n  .addItem({\n    title: 'First Post',\n    description: 'This is my first blog post',\n    link: 'https://example.com/posts/first-post',\n    author: 'Rumen Damyanov',\n    pubdate: new Date(),\n  })\n  .addItem({\n    title: 'Second Post',\n    description: 'Another interesting post',\n    link: 'https://example.com/posts/second-post',\n    author: 'Rumen Damyanov',\n    pubdate: new Date(),\n    images: [\n      {\n        url: 'https://example.com/images/post-image.jpg',\n        caption: 'Post featured image',\n      },\n    ],\n  });\n\n// Generate RSS feed\nconst rssXml = feed.toXML('rss');\nconsole.log(rssXml);\n\n// Generate Atom feed\nconst atomXml = feed.toXML('atom');\nconsole.log(atomXml);\n```\n\n## 📚 Advanced Usage\n\n### Framework Integration\n\n#### Express.js\n\n```typescript\nimport express from 'express';\nimport { FeedFactory } from '@rumenx/feed';\n\nconst app = express();\n\napp.get('/feed.xml', (req, res) =\u003e {\n  const feed = FeedFactory.createForExpress({\n    baseUrl: 'https://example.com',\n    validate: true,\n  });\n\n  feed.setTitle('My Blog').setDescription('Latest blog posts').setLink('https://example.com');\n\n  // Add your content\n  feed.addItem({\n    title: 'Hello World',\n    description: 'My first post',\n    link: 'https://example.com/hello',\n    pubdate: new Date(),\n  });\n\n  // Render and send response\n  const xml = feed.render('rss');\n  res.set('Content-Type', 'application/xml');\n  res.send(xml);\n});\n\napp.listen(3000);\n```\n\n#### Next.js\n\n```typescript\n// pages/api/feed.xml.ts\nimport type { NextApiRequest, NextApiResponse } from 'next';\nimport { FeedFactory } from '@rumenx/feed';\n\nexport default function handler(req: NextApiRequest, res: NextApiResponse) {\n  const feed = FeedFactory.createForNextjs({\n    baseUrl: 'https://yoursite.com',\n  });\n\n  feed.setTitle('My Next.js Blog').setDescription('Latest posts').setLink('https://yoursite.com');\n\n  // Add your posts\n  feed.addItem({\n    title: 'Next.js is Awesome',\n    description: 'Why I love Next.js',\n    link: 'https://yoursite.com/posts/nextjs-awesome',\n    pubdate: new Date(),\n  });\n\n  res.setHeader('Content-Type', 'application/xml');\n  res.status(200).send(feed.toXML('rss'));\n}\n```\n\n### Rich Media Feeds\n\n```typescript\nimport { Feed } from '@rumenx/feed';\n\nconst feed = new Feed({\n  baseUrl: 'https://example.com',\n  validate: true,\n  escapeContent: true,\n});\n\n// Add item with images and videos\nfeed.addItem({\n  title: 'Amazing Travel Guide',\n  description: 'Discover the best travel destinations',\n  link: 'https://example.com/travel-guide',\n  author: 'Travel Blogger',\n  pubdate: new Date(),\n  images: [\n    {\n      url: 'https://example.com/images/travel.jpg',\n      caption: 'Beautiful mountain landscape',\n      title: 'Mountain View',\n      license: 'https://creativecommons.org/licenses/by/4.0/',\n      geoLocation: 'Swiss Alps',\n    },\n  ],\n  videos: [\n    {\n      thumbnail_url: 'https://example.com/thumbnails/travel-video.jpg',\n      title: 'Travel Video Guide',\n      description: 'A comprehensive video guide to travel',\n      content_url: 'https://example.com/videos/travel.mp4',\n      duration: 300,\n      rating: 4.8,\n      view_count: 15000,\n      publication_date: '2023-12-01',\n      family_friendly: true,\n      tags: ['travel', 'guide', 'adventure'],\n    },\n  ],\n});\n```\n\n### Multilingual Feeds\n\n```typescript\n// Add multilingual content with translations\nfeed.addItem({\n  title: 'Global News Update',\n  description: 'Latest international news',\n  link: 'https://example.com/news/global-update',\n  translations: [\n    { language: 'en', url: 'https://example.com/en/news/global-update' },\n    { language: 'es', url: 'https://example.com/es/noticias/actualizacion-global' },\n    { language: 'fr', url: 'https://example.com/fr/nouvelles/mise-a-jour-mondiale' },\n    { language: 'de', url: 'https://example.com/de/nachrichten/globale-aktualisierung' },\n  ],\n});\n```\n\n### Google News Feeds\n\n```typescript\n// Add Google News compatible items\nfeed.addItem({\n  title: 'Breaking: Major Discovery in Science',\n  description: 'Scientists make groundbreaking discovery',\n  link: 'https://example.com/news/major-discovery',\n  pubdate: new Date(),\n  news: {\n    sitename: 'Science Daily',\n    language: 'en',\n    publication_date: new Date(),\n    title: 'Major Discovery in Quantum Physics',\n    keywords: 'science, quantum, physics, discovery',\n  },\n});\n```\n\n## 🛠️ Configuration Options\n\n```typescript\ninterface FeedConfig {\n  /** Base URL for resolving relative URLs */\n  baseUrl?: string;\n  /** Enable validation of URLs and data */\n  validate?: boolean;\n  /** Enable XML content escaping */\n  escapeContent?: boolean;\n  /** Pretty print XML output */\n  prettyPrint?: boolean;\n  /** Date format string */\n  dateFormat?: string;\n  /** Feed language */\n  language?: string;\n  /** Maximum items per feed */\n  maxItems?: number;\n  /** Maximum file size in bytes */\n  maxFileSize?: number;\n  /** Allowed domains for URL validation */\n  allowedDomains?: string[];\n}\n```\n\n## 📊 Statistics and Analysis\n\n```typescript\n// Get detailed feed statistics\nconst stats = feed.getStats();\nconsole.log(stats);\n// Output:\n// {\n//   totalItems: 25,\n//   totalImages: 12,\n//   totalVideos: 3,\n//   totalTranslations: 75,\n//   averagePriority: 0.8,\n//   lastModified: '2023-12-01T10:30:00.000Z',\n//   sizeEstimate: 145000\n// }\n\n// Check if feed should be split\nif (feed.shouldSplit()) {\n  console.log('Feed is too large and should be split into multiple feeds');\n}\n```\n\n## 🔍 Validation and Error Handling\n\n```typescript\nimport { ValidationError } from '@rumenx/feed';\n\n// Validate feed content\nconst errors = feed.validate();\nif (errors.length \u003e 0) {\n  console.error('Feed validation errors:', errors);\n}\n\n// Handle validation during configuration\nconst feed = new Feed({\n  validate: true, // Throws errors on invalid data\n});\n\ntry {\n  feed.addItem({\n    title: 'Invalid Item',\n    description: 'This item has invalid data',\n    link: 'not-a-valid-url', // Will throw validation error\n  });\n} catch (error) {\n  if (error instanceof ValidationError) {\n    console.error('Validation error:', {\n      field: error.field,\n      type: error.type,\n      message: error.message,\n      value: error.value,\n    });\n  }\n}\n```\n\n## 🧪 TypeScript Support\n\nThis package is written in TypeScript and provides complete type definitions:\n\n```typescript\nimport type {\n  Feed,\n  FeedConfig,\n  FeedItem,\n  FeedItemData,\n  FeedStats,\n  ValidationError,\n  ImageData,\n  VideoData,\n  NewsData,\n} from '@rumenx/feed';\n\n// Full IntelliSense support\nconst item: FeedItemData = {\n  title: 'My Post',\n  description: 'Post description',\n  link: 'https://example.com/post',\n  pubdate: new Date(),\n  images: [\n    /* Fully typed image objects */\n  ],\n  videos: [\n    /* Fully typed video objects */\n  ],\n};\n```\n\n## 📈 Performance\n\n- **Optimized for large feeds** - Efficiently handles 50,000+ items\n- **Memory efficient** - Stream-friendly architecture for large datasets\n- **Fast XML generation** - Optimized string building and concatenation\n- **Minimal dependencies** - Zero runtime dependencies for optimal bundle size\n- **Tree-shakable** - Import only what you need with modern bundlers\n\n## 📋 Requirements\n\n- **Node.js**: \u003e= 18.0.0\n- **TypeScript**: \u003e= 4.5.0 (for TypeScript projects)\n\n## 🤝 Contributing\n\nContributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.\n\n## 🔗 Links\n\n- [GitHub Repository](https://github.com/RumenDamyanov/npm-feed)\n- [npm Package](https://www.npmjs.com/package/@rumenx/feed)\n- [Issue Tracker](https://github.com/RumenDamyanov/npm-feed/issues)\n- [Changelog](CHANGELOG.md)\n\n## ⭐ Support\n\nIf you find this package helpful, please consider:\n\n- ⭐ Starring this repository\n- 🐛 Reporting bugs and suggesting improvements\n- 💻 Contributing code or documentation\n- 💖 [Sponsoring the project](https://github.com/sponsors/RumenDamyanov)\n\n---\n\n**Built with ❤️ by [Rumen Damyanov](https://github.com/RumenDamyanov)**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frumendamyanov%2Fnpm-feed","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frumendamyanov%2Fnpm-feed","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frumendamyanov%2Fnpm-feed/lists"}