website

#astro#js#html#css

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

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


bb6d7b5pyrossh 2026-07-07T11:56:41+05:30
feat: add blog list and detail workers
packages/workers/posts/detail/package.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "@pyrossh/posts-detail",
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/config": "workspace:*",
10
+ "@pyrossh/core": "workspace:*",
11
+ "@pyrossh/types": "workspace:*",
12
+ "@pyrossh/ui": "workspace:*"
13
+ }
14
+ }
packages/workers/posts/detail/src/index.tsx ADDED
@@ -0,0 +1,30 @@
1
+ import { Layout } from "@pyrossh/ui";
2
+ import { getPost } from "@pyrossh/core";
3
+ import type { Env } from "@pyrossh/types";
4
+
5
+ export default {
6
+ async fetch(request: Request, env: Env): Promise<Response> {
7
+ const url = new URL(request.url);
8
+ const postId = url.pathname.replace("/posts/", "").replace(/\/$/, "");
9
+ const post = await getPost(env.REPOS, postId);
10
+ if (!post) {
11
+ return Response.redirect(`${url.origin}/404`, 302);
12
+ }
13
+ return new Response(
14
+ <Layout title={post.data.title} description={post.data.description} request={request}>
15
+ <article>
16
+ <h1 style="text-align:left;font-size:1.8rem;font-weight:bold;line-height:1;margin-top:0.5rem;margin-bottom:0.1rem">
17
+ {post.data.title}
18
+ </h1>
19
+ <h2 style="font-size:1.1rem;font-weight:500">{post.data.description}</h2>
20
+ <time style="font-size:1.1rem;color:light-dark(hsl(from var(--color-text) h s 40%), hsl(from var(--color-text) h s 80%))">
21
+ {post.data.pubDate.toLocaleDateString()}
22
+ </time>
23
+ <hr style="margin:0.5rem 0;border-color:var(--color-text)" />
24
+ <div dangerouslySetInnerHTML={{ __html: post.html }} />
25
+ </article>
26
+ </Layout>,
27
+ { headers: { "content-type": "text/html" } },
28
+ );
29
+ },
30
+ };
packages/workers/posts/detail/tsconfig.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "../../../../tsconfig.base.json",
3
+ "include": ["src"]
4
+ }
packages/workers/posts/detail/wrangler.jsonc ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "pyrossh-posts-detail",
3
+ "main": "src/index.tsx",
4
+ "compatibility_date": "2026-07-07",
5
+ "compatibility_flags": ["nodejs_compat"],
6
+ "workers_dev": false,
7
+ "routes": [{ "pattern": "pyrossh.dev/posts/*", "custom_domain": true }],
8
+ "r2_buckets": [{ "binding": "REPOS", "bucket_name": "pyrossh-repos-prd" }],
9
+ }
packages/workers/posts/index/package.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "@pyrossh/posts",
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/config": "workspace:*",
10
+ "@pyrossh/core": "workspace:*",
11
+ "@pyrossh/types": "workspace:*",
12
+ "@pyrossh/ui": "workspace:*"
13
+ }
14
+ }
packages/workers/posts/index/src/index.tsx ADDED
@@ -0,0 +1,31 @@
1
+ import { Layout } from "@pyrossh/ui";
2
+ import { getPosts } from "@pyrossh/core";
3
+ import type { Env } from "@pyrossh/types";
4
+
5
+ export default {
6
+ async fetch(request: Request, env: Env): Promise<Response> {
7
+ const posts = await getPosts(env.REPOS);
8
+ return new Response(
9
+ <Layout title="Posts" description="Posts" request={request}>
10
+ <h1 style="font-weight:800;font-size:2rem">Posts</h1>
11
+ <ul style="display:flex;flex-direction:column;list-style:none;padding:0">
12
+ {posts.map((post) => (
13
+ <li style="display:grid;grid-template-columns:1fr;gap:0.4rem;margin-top:1.25rem;line-height:1.5rem">
14
+ <div>
15
+ <a
16
+ href={`/posts/${post.id}`}
17
+ style="font-size:1.1rem;color:var(--color-post-link);text-underline-offset:4px"
18
+ >
19
+ {post.data.title}
20
+ </a>
21
+ <span style="font-size:13pt;display:block">{post.data.description}</span>
22
+ </div>
23
+ <time style="font-size:1.1rem">{post.data.pubDate.toLocaleDateString()}</time>
24
+ </li>
25
+ ))}
26
+ </ul>
27
+ </Layout>,
28
+ { headers: { "content-type": "text/html" } },
29
+ );
30
+ },
31
+ };
packages/workers/posts/index/tsconfig.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "../../../../tsconfig.base.json",
3
+ "include": ["src"]
4
+ }
packages/workers/posts/index/wrangler.jsonc ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "pyrossh-posts",
3
+ "main": "src/index.tsx",
4
+ "compatibility_date": "2026-07-07",
5
+ "compatibility_flags": ["nodejs_compat"],
6
+ "workers_dev": false,
7
+ "routes": [{ "pattern": "pyrossh.dev/posts", "custom_domain": true }],
8
+ "r2_buckets": [{ "binding": "REPOS", "bucket_name": "pyrossh-repos-prd" }],
9
+ }