From eaf480b60886b3b7d86c6d0b39ffd1a42d7d51b8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=97=8D+85CD?= <50108258+kwaa@users.noreply.github.com>
Date: Tue, 24 Dec 2024 23:55:11 +0800
Subject: [PATCH] feat(docs): og image

---
 docs/package.json                             |  1 +
 docs/src/pages/characters-og/[...slug].ts     | 33 +++++++++++++++++++
 .../[pkg]/[category]/[character].astro        |  8 ++---
 pnpm-lock.yaml                                | 28 ++++++++++++++++
 4 files changed, 66 insertions(+), 4 deletions(-)
 create mode 100644 docs/src/pages/characters-og/[...slug].ts

diff --git a/docs/package.json b/docs/package.json
index 0f44703..0a633f9 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -24,6 +24,7 @@
     "@moeru-ai/characters-derivative": "workspace:^",
     "@moeru-ai/characters-existing": "workspace:^",
     "@moeru-ai/characters-original": "workspace:^",
+    "astro-og-canvas": "^0.5.5",
     "daisyui": "^4.12.14",
     "starlight-sidebar-topics-dropdown": "^0.2.1",
     "starlight-theme-catppuccin": "^1.0.3",
diff --git a/docs/src/pages/characters-og/[...slug].ts b/docs/src/pages/characters-og/[...slug].ts
new file mode 100644
index 0000000..494f151
--- /dev/null
+++ b/docs/src/pages/characters-og/[...slug].ts
@@ -0,0 +1,33 @@
+import type { Card } from '@moeru-ai/ccc'
+
+import * as derivative from '@moeru-ai/characters-derivative'
+import * as existing from '@moeru-ai/characters-existing'
+import * as original from '@moeru-ai/characters-original'
+import { OGImageRoute } from 'astro-og-canvas'
+
+const generateOGImagePages = (json: typeof derivative | typeof existing | typeof original, pkg: string) =>
+  Object.fromEntries(
+    Object.entries(json)
+      .flatMap(([category, characters]) => Object.entries(characters)
+        .map(([character, json]) => [
+          // characters-og/[...slug].png
+          `${pkg}/${category}/${character}`,
+          json as Card,
+        ]),
+      ),
+  )
+
+export const { GET, getStaticPaths } = OGImageRoute({
+  getImageOptions: (_path, page: Card) => ({
+    description: page.notes,
+    title: page.name,
+  }),
+
+  pages: {
+    ...generateOGImagePages(derivative, 'derivative'),
+    ...generateOGImagePages(existing, 'existing'),
+    ...generateOGImagePages(original, 'original'),
+  },
+
+  param: 'slug',
+})
diff --git a/docs/src/pages/characters/[pkg]/[category]/[character].astro b/docs/src/pages/characters/[pkg]/[category]/[character].astro
index 929fce7..653eecd 100644
--- a/docs/src/pages/characters/[pkg]/[category]/[character].astro
+++ b/docs/src/pages/characters/[pkg]/[category]/[character].astro
@@ -17,10 +17,10 @@ export const getStaticPaths = () => {
     })))
 
   return [
-  ...generateStaticPaths(derivative, 'derivative'),
-  ...generateStaticPaths(existing, 'existing'),
-  ...generateStaticPaths(original, 'original'),
-]
+    ...generateStaticPaths(derivative, 'derivative'),
+    ...generateStaticPaths(existing, 'existing'),
+    ...generateStaticPaths(original, 'original'),
+  ]
 }
 
 const { category, character, pkg } = Astro.params
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index fb48dc8..e631810 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -78,6 +78,9 @@ importers:
       '@moeru-ai/characters-original':
         specifier: workspace:^
         version: link:../packages/characters-original
+      astro-og-canvas:
+        specifier: ^0.5.5
+        version: 0.5.5(astro@4.16.13(@types/node@22.9.0)(less@4.2.0)(rollup@4.24.3)(typescript@5.6.3))
       daisyui:
         specifier: ^4.12.14
         version: 4.12.14(postcss@8.4.49)
@@ -1376,6 +1379,9 @@ packages:
   '@vue/shared@3.5.13':
     resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==}
 
+  '@webgpu/types@0.1.21':
+    resolution: {integrity: sha512-pUrWq3V5PiSGFLeLxoGqReTZmiiXwY3jRkIG5sLLKjyqNxrwm/04b4nw7LSmGWJcKk59XOM/YRTUwOzo4MMlow==}
+
   acorn-jsx@5.3.2:
     resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
     peerDependencies:
@@ -1459,6 +1465,12 @@ packages:
     peerDependencies:
       astro: ^4.0.0-beta || ^5.0.0-beta || ^3.3.0
 
+  astro-og-canvas@0.5.5:
+    resolution: {integrity: sha512-dbZ7voJAmvy8Zyv5zFsgENs9G4uhcCJ4nVuUPb7ymu8+Vp/jr/fdQDKPrLYUG2TSi/1HejYRnzkXcSv6ntlDTA==}
+    engines: {node: '>=18.14.1'}
+    peerDependencies:
+      astro: ^3.0.0 || ^4.0.0 || ^5.0.0
+
   astro@4.16.13:
     resolution: {integrity: sha512-Mtd76+BC0zLWqoXpf9xc731AhdH4MNh5JFHYdLRvSH0Nqn48hA64dPGh/cWsJvh/DZFmC0NTZusM1Qq2gyNaVg==}
     engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'}
@@ -1545,6 +1557,9 @@ packages:
   caniuse-lite@1.0.30001676:
     resolution: {integrity: sha512-Qz6zwGCiPghQXGJvgQAem79esjitvJ+CxSbSQkW9H/UX5hg8XM88d4lp2W+MEQ81j+Hip58Il+jGVdazk1z9cw==}
 
+  canvaskit-wasm@0.39.1:
+    resolution: {integrity: sha512-Gy3lCmhUdKq+8bvDrs9t8+qf7RvcjuQn+we7vTVVyqgOVO1UVfHpsnBxkTZw+R4ApEJ3D5fKySl9TU11hmjl/A==}
+
   ccount@2.0.1:
     resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
 
@@ -5266,6 +5281,8 @@ snapshots:
 
   '@vue/shared@3.5.13': {}
 
+  '@webgpu/types@0.1.21': {}
+
   acorn-jsx@5.3.2(acorn@8.14.0):
     dependencies:
       acorn: 8.14.0
@@ -5351,6 +5368,13 @@ snapshots:
       astro: 4.16.13(@types/node@22.9.0)(less@4.2.0)(rollup@4.24.3)(typescript@5.6.3)
       rehype-expressive-code: 0.38.3
 
+  astro-og-canvas@0.5.5(astro@4.16.13(@types/node@22.9.0)(less@4.2.0)(rollup@4.24.3)(typescript@5.6.3)):
+    dependencies:
+      astro: 4.16.13(@types/node@22.9.0)(less@4.2.0)(rollup@4.24.3)(typescript@5.6.3)
+      canvaskit-wasm: 0.39.1
+      deterministic-object-hash: 2.0.2
+      entities: 4.5.0
+
   astro@4.16.13(@types/node@22.9.0)(less@4.2.0)(rollup@4.24.3)(typescript@5.6.3):
     dependencies:
       '@astrojs/compiler': 2.10.3
@@ -5508,6 +5532,10 @@ snapshots:
 
   caniuse-lite@1.0.30001676: {}
 
+  canvaskit-wasm@0.39.1:
+    dependencies:
+      '@webgpu/types': 0.1.21
+
   ccount@2.0.1: {}
 
   chai@5.1.2: