website

#astro#js#html#css

git clone https://git.pyrossh.dev/website

木 Personal website of pyrossh. Built with astrojs, shiki, vite.


f2e6a46pyrossh 2026-07-07T11:41:15+05:30
feat: add simple workers — robots, rss, 404, 500
packages/workers/not-found/package.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "@pyrossh/not-found",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "main": "src/index.tsx",
7
+ "types": "src/index.tsx",
8
+ "dependencies": {
9
+ "@pyrossh/ui": "workspace:*"
10
+ }
11
+ }
packages/workers/not-found/src/index.tsx ADDED
@@ -0,0 +1,13 @@
1
+ import { Layout } from "@pyrossh/ui";
2
+
3
+ export default {
4
+ async fetch(request: Request): Promise<Response> {
5
+ return new Response(
6
+ <Layout title="404 — Not Found" request={request}>
7
+ <h1>404</h1>
8
+ <p>Page not found.</p>
9
+ </Layout>,
10
+ { headers: { "content-type": "text/html" }, status: 404 },
11
+ );
12
+ },
13
+ };
packages/workers/not-found/tsconfig.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "../../../tsconfig.base.json",
3
+ "include": ["src"]
4
+ }
packages/workers/not-found/wrangler.jsonc ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "pyrossh-not-found",
3
+ "main": "src/index.tsx",
4
+ "compatibility_date": "2026-07-07",
5
+ "compatibility_flags": ["nodejs_compat"],
6
+ "workers_dev": false,
7
+ }
packages/workers/robots/package.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "@pyrossh/robots",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "main": "src/index.ts",
7
+ "types": "src/index.ts"
8
+ }
packages/workers/robots/src/index.ts ADDED
@@ -0,0 +1,10 @@
1
+ export default {
2
+ async fetch(request: Request): Promise<Response> {
3
+ const url = new URL(request.url);
4
+ const sitemapURL = new URL("sitemap-index.xml", url.origin);
5
+ const robots = `User-agent: *\nAllow: /\n\nSitemap: ${sitemapURL.href}\n`;
6
+ return new Response(robots, {
7
+ headers: { "content-type": "text/plain" },
8
+ });
9
+ },
10
+ };
packages/workers/robots/tsconfig.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "../../../tsconfig.base.json",
3
+ "include": ["src"]
4
+ }
packages/workers/robots/wrangler.jsonc ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "pyrossh-robots",
3
+ "main": "src/index.ts",
4
+ "compatibility_date": "2026-07-07",
5
+ "compatibility_flags": ["nodejs_compat"],
6
+ "workers_dev": false,
7
+ "routes": [{ "pattern": "pyrossh.dev/robots.txt", "custom_domain": true }],
8
+ }
packages/workers/rss/package.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "@pyrossh/rss",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "main": "src/index.ts",
7
+ "types": "src/index.ts",
8
+ "dependencies": {
9
+ "@pyrossh/config": "workspace:*",
10
+ "@pyrossh/core": "workspace:*",
11
+ "@pyrossh/types": "workspace:*"
12
+ }
13
+ }
packages/workers/rss/src/index.ts ADDED
@@ -0,0 +1,37 @@
1
+ import { getPosts } from "@pyrossh/core";
2
+ import type { Env } from "@pyrossh/types";
3
+ import { SITE_TITLE, SITE_DESCRIPTION, SITE_URL } from "@pyrossh/config";
4
+
5
+ export default {
6
+ async fetch(request: Request, env: Env): Promise<Response> {
7
+ const posts = await getPosts(env.REPOS);
8
+ const items = posts
9
+ .map(
10
+ (post) => `
11
+ <item>
12
+ <title><![CDATA[${post.data.title}]]></title>
13
+ <description><![CDATA[${post.data.description}]]></description>
14
+ <link>${SITE_URL}/posts/${post.id}/</link>
15
+ <guid>${SITE_URL}/posts/${post.id}/</guid>
16
+ <pubDate>${post.data.pubDate.toUTCString()}</pubDate>
17
+ </item>
18
+ `,
19
+ )
20
+ .join("\n");
21
+
22
+ const rss = `<?xml version="1.0" encoding="UTF-8"?>
23
+ <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
24
+ <channel>
25
+ <title>${SITE_TITLE}</title>
26
+ <description>${SITE_DESCRIPTION}</description>
27
+ <link>${SITE_URL}</link>
28
+ <atom:link href="${SITE_URL}/rss.xml" rel="self" type="application/rss+xml"/>
29
+ ${items}
30
+ </channel>
31
+ </rss>`;
32
+
33
+ return new Response(rss, {
34
+ headers: { "content-type": "application/rss+xml; charset=utf-8" },
35
+ });
36
+ },
37
+ };
packages/workers/rss/tsconfig.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "../../../tsconfig.base.json",
3
+ "include": ["src"]
4
+ }
packages/workers/rss/wrangler.jsonc ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "pyrossh-rss",
3
+ "main": "src/index.ts",
4
+ "compatibility_date": "2026-07-07",
5
+ "compatibility_flags": ["nodejs_compat"],
6
+ "workers_dev": false,
7
+ "routes": [{ "pattern": "pyrossh.dev/rss.xml", "custom_domain": true }],
8
+ "r2_buckets": [{ "binding": "REPOS", "bucket_name": "pyrossh-repos-prd" }],
9
+ }
packages/workers/server-error/package.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "@pyrossh/server-error",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "main": "src/index.tsx",
7
+ "types": "src/index.tsx",
8
+ "dependencies": {
9
+ "@pyrossh/ui": "workspace:*"
10
+ }
11
+ }
packages/workers/server-error/src/index.tsx ADDED
@@ -0,0 +1,13 @@
1
+ import { Layout } from "@pyrossh/ui";
2
+
3
+ export default {
4
+ async fetch(request: Request): Promise<Response> {
5
+ return new Response(
6
+ <Layout title="500 — Server Error" request={request}>
7
+ <h1>500</h1>
8
+ <p>Something went wrong.</p>
9
+ </Layout>,
10
+ { headers: { "content-type": "text/html" }, status: 500 },
11
+ );
12
+ },
13
+ };
packages/workers/server-error/tsconfig.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "../../../tsconfig.base.json",
3
+ "include": ["src"]
4
+ }
packages/workers/server-error/wrangler.jsonc ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "pyrossh-server-error",
3
+ "main": "src/index.tsx",
4
+ "compatibility_date": "2026-07-07",
5
+ "compatibility_flags": ["nodejs_compat"],
6
+ "workers_dev": false,
7
+ }