Openstatus www.openstatus.dev

๐Ÿ”ฅ rss feed (#719)

* ๐Ÿ”ฅ rss feed

* ๐Ÿ”ฅ rss feed

* ๐Ÿ”ฅ rss feed sort

authored by

Thibault Le Ouay and committed by
GitHub
2d8f2f10 e57bd4f4

+111
+2
apps/web/package.json
··· 69 69 "remark-parse": "10.0.2", 70 70 "remark-rehype": "10.1.0", 71 71 "resend": "1.1.0", 72 + "rss": "^1.2.2", 72 73 "shiki": "0.14.4", 73 74 "sonner": "1.3.1", 74 75 "stripe": "13.8.0", ··· 85 86 "@types/node": "20.8.0", 86 87 "@types/react": "18.2.64", 87 88 "@types/react-dom": "18.2.21", 89 + "@types/rss": "^0.0.32", 88 90 "autoprefixer": "10.4.16", 89 91 "postcss": "8.4.31", 90 92 "rehype-autolink-headings": "7.1.0",
+38
apps/web/src/app/(content)/blog/feed.xml/route.ts
··· 1 + import { allPosts } from "contentlayer/generated"; 2 + import RSS from "rss"; 3 + 4 + export async function GET() { 5 + const feed = new RSS({ 6 + title: "OpenStatus", 7 + description: "OpenStatus blog feed", 8 + generator: "RSS for Node and Next.js", 9 + feed_url: "https://www.openstatus.dev/blog/feed.xml", 10 + site_url: "https://www.openstatus.dev", 11 + managingEditor: "ping@openstatus.dev (OpenStatus Team)", 12 + webMaster: "ping@openstatus.dev (OpenStatus Team)", 13 + copyright: `Copyright ${new Date().getFullYear().toString()}, OpenStatus`, 14 + language: "en-US", 15 + pubDate: new Date().toUTCString(), 16 + ttl: 60, 17 + }); 18 + 19 + allPosts 20 + .sort( 21 + (a, b) => 22 + new Date(b.publishedAt).getTime() - new Date(a.publishedAt).getTime(), 23 + ) 24 + .map((post) => { 25 + feed.item({ 26 + title: post.title, 27 + description: post.description, 28 + url: `https://www.openstatus.dev/blog/${post.slug}`, 29 + author: post.author.name, 30 + date: post.publishedAt, 31 + }); 32 + }); 33 + return new Response(feed.xml({ indent: true }), { 34 + headers: { 35 + "Content-Type": "application/xml; charset=utf-8", 36 + }, 37 + }); 38 + }
+38
apps/web/src/app/(content)/changelog/feed.xml/route.ts
··· 1 + import { allChangelogs } from "contentlayer/generated"; 2 + import RSS from "rss"; 3 + 4 + export async function GET() { 5 + const feed = new RSS({ 6 + title: "OpenStatus", 7 + description: "OpenStatus changelog feed", 8 + generator: "RSS for Node and Next.js", 9 + feed_url: "https://www.openstatus.dev/blog/feed.xml", 10 + site_url: "https://www.openstatus.dev", 11 + managingEditor: "ping@openstatus.dev (OpenStatus Team)", 12 + webMaster: "ping@openstatus.dev (OpenStatus Team)", 13 + copyright: `Copyright ${new Date().getFullYear().toString()}, OpenStatus`, 14 + language: "en-US", 15 + pubDate: new Date().toUTCString(), 16 + ttl: 60, 17 + }); 18 + 19 + allChangelogs 20 + .sort( 21 + (a, b) => 22 + new Date(b.publishedAt).getTime() - new Date(a.publishedAt).getTime(), 23 + ) 24 + .map((post) => { 25 + feed.item({ 26 + title: post.title, 27 + description: post.description, 28 + url: `https://www.openstatus.dev/changelog/${post.slug}`, 29 + author: "OpenStatus Team", 30 + date: post.publishedAt, 31 + }); 32 + }); 33 + return new Response(feed.xml({ indent: true }), { 34 + headers: { 35 + "Content-Type": "application/xml; charset=utf-8", 36 + }, 37 + }); 38 + }
+33
pnpm-lock.yaml
··· 290 290 resend: 291 291 specifier: 1.1.0 292 292 version: 1.1.0 293 + rss: 294 + specifier: ^1.2.2 295 + version: 1.2.2 293 296 shiki: 294 297 specifier: 0.14.4 295 298 version: 0.14.4 ··· 333 336 '@types/react-dom': 334 337 specifier: 18.2.21 335 338 version: 18.2.21 339 + '@types/rss': 340 + specifier: ^0.0.32 341 + version: 0.0.32 336 342 autoprefixer: 337 343 specifier: 10.4.16 338 344 version: 10.4.16(postcss@8.4.31) ··· 5366 5372 resolution: {integrity: sha512-BKGK0T1VgB1zD+PwQR4RRf0ais3NyvH1qjLUrHI5SEiccYaJrhLstLuoXFWJ+2Op9whGizSPUMGPJY/Qtb/A2w==} 5367 5373 dev: false 5368 5374 5375 + /@types/rss@0.0.32: 5376 + resolution: {integrity: sha512-2oKNqKyUY4RSdvl5eZR1n2Q9yvw3XTe3mQHsFPn9alaNBxfPnbXBtGP8R0SV8pK1PrVnLul0zx7izbm5/gF5Qw==} 5377 + dev: true 5378 + 5369 5379 /@types/scheduler@0.16.5: 5370 5380 resolution: {integrity: sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw==} 5371 5381 ··· 10202 10212 braces: 3.0.2 10203 10213 picomatch: 2.3.1 10204 10214 10215 + /mime-db@1.25.0: 10216 + resolution: {integrity: sha512-5k547tI4Cy+Lddr/hdjNbBEWBwSl8EBc5aSdKvedav8DReADgWJzcYiktaRIw3GtGC1jjwldXtTzvqJZmtvC7w==} 10217 + engines: {node: '>= 0.6'} 10218 + dev: false 10219 + 10205 10220 /mime-db@1.52.0: 10206 10221 resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} 10207 10222 engines: {node: '>= 0.6'} 10208 10223 dev: false 10209 10224 10225 + /mime-types@2.1.13: 10226 + resolution: {integrity: sha512-ryBDp1Z/6X90UvjUK3RksH0IBPM137T7cmg4OgD5wQBojlAiUwuok0QeELkim/72EtcYuNlmbkrcGuxj3Kl0YQ==} 10227 + engines: {node: '>= 0.6'} 10228 + dependencies: 10229 + mime-db: 1.25.0 10230 + dev: false 10231 + 10210 10232 /mime-types@2.1.35: 10211 10233 resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} 10212 10234 engines: {node: '>= 0.6'} ··· 11805 11827 optionalDependencies: 11806 11828 fsevents: 2.3.3 11807 11829 dev: true 11830 + 11831 + /rss@1.2.2: 11832 + resolution: {integrity: sha512-xUhRTgslHeCBeHAqaWSbOYTydN2f0tAzNXvzh3stjz7QDhQMzdgHf3pfgNIngeytQflrFPfy6axHilTETr6gDg==} 11833 + dependencies: 11834 + mime-types: 2.1.13 11835 + xml: 1.0.1 11836 + dev: false 11808 11837 11809 11838 /run-async@2.4.1: 11810 11839 resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} ··· 13529 13558 /xml-name-validator@4.0.0: 13530 13559 resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} 13531 13560 engines: {node: '>=12'} 13561 + dev: false 13562 + 13563 + /xml@1.0.1: 13564 + resolution: {integrity: sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==} 13532 13565 dev: false 13533 13566 13534 13567 /xmlchars@2.2.0: