diff --git a/CHANGES.md b/CHANGES.md
index 60589cb8e..467d624d2 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -8,6 +8,15 @@ Version 2.1.7
To be released.
+### @fedify/init
+
+ - Fixed `fedify init` generating Astro projects for Bun with the Node.js
+ adapter and `astro preview`, which could fail to run correctly on Bun.
+ Astro + Bun projects now use *@nurodev/astro-bun* and run the built
+ Bun server entry point instead. [[#707]]
+
+[#707]: https://github.com/fedify-dev/fedify/pull/707
+
Version 2.1.6
-------------
diff --git a/deno.lock b/deno.lock
index 9beed102c..f9bfdca01 100644
--- a/deno.lock
+++ b/deno.lock
@@ -83,6 +83,7 @@
"npm:@mjackson/node-fetch-server@0.7": "0.7.0",
"npm:@multiformats/base-x@^4.0.1": "4.0.1",
"npm:@nestjs/common@^11.0.1": "11.1.13_reflect-metadata@0.2.2_rxjs@7.8.2",
+ "npm:@nurodev/astro-bun@^2.1.2": "2.1.2_astro@5.17.3__@types+node@24.10.12",
"npm:@opentelemetry/api@^1.9.0": "1.9.0",
"npm:@opentelemetry/context-async-hooks@^2.5.0": "2.5.0_@opentelemetry+api@1.9.0",
"npm:@opentelemetry/core@^2.5.0": "2.5.0_@opentelemetry+api@1.9.0",
@@ -2339,6 +2340,14 @@
"@noble/hashes@1.4.0": {
"integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg=="
},
+ "@nurodev/astro-bun@2.1.2_astro@5.17.3__@types+node@24.10.12": {
+ "integrity": "sha512-CXzh0q+jOodmqtZ/YMyS7DTqmFC2zafv4C7GQMBDoBDRcx7CONzxCk/rK2uaKHoh3+AvSPo3hXnTp6oLfIpl5g==",
+ "dependencies": [
+ "astro",
+ "astro-integration-kit",
+ "zod@4.3.6"
+ ]
+ },
"@opentelemetry/api@1.9.0": {
"integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="
},
@@ -3053,7 +3062,7 @@
"integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==",
"dependencies": [
"@vitest/utils",
- "pathe",
+ "pathe@2.0.3",
"strip-literal"
]
},
@@ -3062,7 +3071,7 @@
"dependencies": [
"@vitest/pretty-format",
"magic-string",
- "pathe"
+ "pathe@2.0.3"
]
},
"@vitest/spy@3.2.4": {
@@ -3220,7 +3229,21 @@
"dependencies": [
"@babel/parser@8.0.0-rc.3",
"estree-walker@3.0.3",
- "pathe"
+ "pathe@2.0.3"
+ ]
+ },
+ "ast-types@0.16.1": {
+ "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==",
+ "dependencies": [
+ "tslib"
+ ]
+ },
+ "astro-integration-kit@0.18.0_astro@5.17.3__@types+node@24.10.12": {
+ "integrity": "sha512-Z0QW5IQjosuKQDEGYYkvUX6EhEtrmE4/oViqWz23QveV8U7AuyFsTdg00WRNPevWZl/5a4lLUeDpv4bCRynRRg==",
+ "dependencies": [
+ "astro",
+ "pathe@1.1.2",
+ "recast"
]
},
"astro@5.17.3_@types+node@24.10.12": {
@@ -4092,6 +4115,10 @@
"eslint-visitor-keys@4.2.1"
]
},
+ "esprima@4.0.1": {
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "bin": true
+ },
"esquery@1.7.0": {
"integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==",
"dependencies": [
@@ -5819,6 +5846,9 @@
"path-to-regexp@6.3.0": {
"integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ=="
},
+ "pathe@1.1.2": {
+ "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="
+ },
"pathe@2.0.3": {
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="
},
@@ -6034,6 +6064,16 @@
"real-require@0.2.0": {
"integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg=="
},
+ "recast@0.23.11": {
+ "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==",
+ "dependencies": [
+ "ast-types",
+ "esprima",
+ "source-map",
+ "tiny-invariant",
+ "tslib"
+ ]
+ },
"redis-errors@1.2.0": {
"integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w=="
},
@@ -6590,6 +6630,9 @@
"source-map-js@1.2.1": {
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="
},
+ "source-map@0.6.1": {
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+ },
"space-separated-tokens@2.0.2": {
"integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="
},
@@ -6760,6 +6803,9 @@
"tiny-inflate@1.0.3": {
"integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="
},
+ "tiny-invariant@1.3.3": {
+ "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="
+ },
"tinybench@2.9.0": {
"integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="
},
@@ -6946,7 +6992,7 @@
"defu",
"exsolve",
"ohash",
- "pathe",
+ "pathe@2.0.3",
"ufo"
]
},
@@ -7127,7 +7173,7 @@
"cac@6.7.14",
"debug@4.4.3",
"es-module-lexer",
- "pathe",
+ "pathe@2.0.3",
"vite@7.3.1_@types+node@24.10.12_tsx@4.21.0_yaml@2.8.2"
],
"bin": true
@@ -7206,7 +7252,7 @@
"debug@4.4.3",
"expect-type",
"magic-string",
- "pathe",
+ "pathe@2.0.3",
"picomatch@4.0.4",
"std-env",
"tinybench",
@@ -7436,6 +7482,9 @@
"zod@3.25.76": {
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="
},
+ "zod@4.3.6": {
+ "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="
+ },
"zwitch@2.0.4": {
"integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="
}
@@ -7488,7 +7537,8 @@
"packageJson": {
"dependencies": [
"npm:@astrojs/node@^9.5.4",
- "npm:@deno/astro-adapter@~0.3.2"
+ "npm:@deno/astro-adapter@~0.3.2",
+ "npm:@nurodev/astro-bun@^2.1.2"
]
}
},
diff --git a/examples/astro/README.md b/examples/astro/README.md
index 9ee3e2c61..cf06d45d6 100644
--- a/examples/astro/README.md
+++ b/examples/astro/README.md
@@ -7,14 +7,15 @@ A comprehensive example of building a federated server application using
[Fedify] with [Astro] via the [`@fedify/astro`] package. This sample
demonstrates how to create an ActivityPub-compatible federated social media
server that can interact with other federated platforms like Mastodon, Pleroma,
-and other ActivityPub implementations. It supports both [Deno] and [Node.js]
-runtimes.
+and other ActivityPub implementations. It supports [Deno], [Node.js], and
+[Bun] runtimes.
[Fedify]: https://fedify.dev
[Astro]: https://astro.build/
[`@fedify/astro`]: https://jsr.io/@fedify/astro
[Deno]: https://deno.com/
[Node.js]: https://nodejs.org/
+[Bun]: https://bun.sh/
Features
@@ -30,7 +31,8 @@ Features
- **Inbox Processing**: Real-time activity processing from federated instances
- **Content Negotiation**: Same routes serve HTML for browsers and ActivityPub
JSON for federated clients
- - **Dual Runtime**: Supports both Deno and Node.js via separate Astro configs
+ - **Three Runtimes**: Supports Deno, Node.js, and Bun via separate Astro
+ configs
- **TypeScript**: Full type safety throughout the application
@@ -40,8 +42,10 @@ How it works
- *astro.config.deno.ts* registers `fedifyIntegration()` to configure Vite's
SSR settings for Fedify compatibility, and uses `@deno/astro-adapter` to
run on Deno.
- - *astro.config.node.ts* registers `fedifyIntegration()` without any adapter
- for Node.js.
+ - *astro.config.node.ts* registers `fedifyIntegration()` and uses
+ `@astrojs/node` for Node.js.
+ - *astro.config.bun.ts* registers `fedifyIntegration()` and uses
+ `@nurodev/astro-bun` for Bun.
- *src/lib/store.ts* defines in-memory stores for key pairs, follower
relationships, and posts.
- *src/lib/federation.ts* sets up the full `Federation` instance with:
@@ -111,6 +115,23 @@ pnpm dev
This uses *astro.config.node.ts* as the configuration file.
+### Bun
+
+To run the dev server with Bun:
+
+~~~~ command
+bun run dev:bun
+~~~~
+
+This uses *astro.config.bun.ts* as the configuration file.
+
+To build and run the Bun server bundle:
+
+~~~~ command
+bun run build:bun
+bun run preview:bun
+~~~~
+
### Testing
The application will be available at .
@@ -139,6 +160,8 @@ Example usage scenarios
deno task dev
# or for Node.js
pnpm dev
+ # or for Bun
+ bun run dev:bun
~~~~
2. Visit the home page at to see the demo account
@@ -216,13 +239,13 @@ Using as a template
-------------------
If you are creating a new project based on this example, you only need the
-configuration file for your target runtime. Delete the unused one and rename
+configuration file for your target runtime. Delete the unused ones and rename
the one you keep to *astro.config.ts*:
### For Deno
~~~~ command
-rm astro.config.node.ts
+rm astro.config.node.ts astro.config.bun.ts
mv astro.config.deno.ts astro.config.ts
~~~~
@@ -241,7 +264,7 @@ Then remove the `--config` flags from *deno.json* tasks:
### For Node.js
~~~~ command
-rm astro.config.deno.ts
+rm astro.config.deno.ts astro.config.bun.ts
mv astro.config.node.ts astro.config.ts
~~~~
@@ -257,6 +280,25 @@ Then remove the `--config` flags from *package.json* scripts:
}
~~~~
+### For Bun
+
+~~~~ command
+rm astro.config.deno.ts astro.config.node.ts
+mv astro.config.bun.ts astro.config.ts
+~~~~
+
+Then update *package.json* scripts to use Bun's SSR entry point after build:
+
+~~~~ json
+{
+ "scripts": {
+ "dev": "bunx astro dev",
+ "build": "bunx astro build",
+ "preview": "bun ./dist/server/entry.mjs"
+ }
+}
+~~~~
+
Links
-----
diff --git a/examples/astro/astro.config.bun.ts b/examples/astro/astro.config.bun.ts
new file mode 100644
index 000000000..9eff6dc09
--- /dev/null
+++ b/examples/astro/astro.config.bun.ts
@@ -0,0 +1,12 @@
+import bun from "@nurodev/astro-bun";
+import { fedifyIntegration } from "@fedify/astro";
+import { defineConfig } from "astro/config";
+
+// https://astro.build/config
+export default defineConfig({
+ integrations: [fedifyIntegration()],
+ output: "server",
+ adapter: bun(),
+ server: { host: true, allowedHosts: true },
+ security: { allowedDomains: [{}] },
+});
diff --git a/examples/astro/package.json b/examples/astro/package.json
index cb91380a1..3f8c22d80 100644
--- a/examples/astro/package.json
+++ b/examples/astro/package.json
@@ -6,7 +6,10 @@
"scripts": {
"dev": "astro dev --config astro.config.node.ts",
"build": "astro build --config astro.config.node.ts",
- "preview": "astro preview --config astro.config.node.ts"
+ "preview": "astro preview --config astro.config.node.ts",
+ "dev:bun": "bunx astro dev --config astro.config.bun.ts",
+ "build:bun": "bunx astro build --config astro.config.bun.ts",
+ "preview:bun": "bun ./dist/server/entry.mjs"
},
"dependencies": {
"@astrojs/node": "^9.5.4",
@@ -14,6 +17,7 @@
"@fedify/astro": "workspace:^",
"@fedify/fedify": "workspace:^",
"@fedify/vocab": "workspace:^",
+ "@nurodev/astro-bun": "^2.1.2",
"astro": "catalog:"
}
}
diff --git a/packages/astro/README.md b/packages/astro/README.md
index 20430e89a..e8ee8b9d6 100644
--- a/packages/astro/README.md
+++ b/packages/astro/README.md
@@ -52,13 +52,12 @@ export const onRequest = fedifyMiddleware(
For Deno users
--------------
-If you are using Deno, you should import `@deno/vite-adapter` in
+If you are using Deno, you should import `@deno/astro-adapter` in
*astro.config.mjs* and use it as the adapter:
~~~~ typescript
import { defineConfig } from "astro/config";
import { fedifyIntegration } from "@fedify/astro";
-import deno from "@deno/vite-adapter";
import deno from "@deno/astro-adapter";
export default defineConfig({
@@ -82,6 +81,38 @@ instead of `astro`:
~~~~
+For Bun users
+-------------
+
+If you are using Bun, install `@nurodev/astro-bun` and configure it as the
+Astro adapter:
+
+~~~~ typescript
+import { defineConfig } from "astro/config";
+import { fedifyIntegration } from "@fedify/astro";
+import bun from "@nurodev/astro-bun";
+
+export default defineConfig({
+ integrations: [fedifyIntegration()],
+ output: "server",
+ adapter: bun(),
+});
+~~~~
+
+Then use Bun to start Astro in development, and run the generated server entry
+point after building for preview or production:
+
+~~~~ json
+{
+ "scripts": {
+ "dev": "bunx astro dev",
+ "build": "bunx astro build",
+ "preview": "bun ./dist/server/entry.mjs"
+ }
+}
+~~~~
+
+
How it works
------------
diff --git a/packages/init/src/package.test.ts b/packages/init/src/package.test.ts
index 5ad588210..bfef1cf0c 100644
--- a/packages/init/src/package.test.ts
+++ b/packages/init/src/package.test.ts
@@ -1,8 +1,9 @@
-import { strictEqual } from "node:assert/strict";
+import { match, ok, strictEqual } from "node:assert/strict";
import { access, readFile } from "node:fs/promises";
import { dirname, resolve } from "node:path";
import test from "node:test";
import { fileURLToPath } from "node:url";
+import astroDescription from "./webframeworks/astro.ts";
const packageDir = resolve(dirname(fileURLToPath(import.meta.url)), "..");
@@ -33,3 +34,41 @@ test(
}
},
);
+
+test(
+ "Astro init uses the Bun adapter for Bun projects",
+ async () => {
+ const packageJson = JSON.parse(
+ await readFile(resolve(packageDir, "package.json"), "utf8"),
+ );
+ const result = await astroDescription.init({
+ command: "init",
+ dir: packageDir,
+ dryRun: true,
+ kvStore: "in-memory",
+ messageQueue: "in-process",
+ packageManager: "bun",
+ projectName: "fedify-test",
+ testMode: true,
+ webFramework: "astro",
+ });
+
+ ok(result.dependencies != null);
+ ok(result.tasks != null);
+ ok(result.files != null);
+ const dependencies = result.dependencies as Record;
+ const tasks = result.tasks as Record;
+ const files = result.files as Record;
+
+ strictEqual(dependencies["@nurodev/astro-bun"], "^2.1.2");
+ strictEqual(dependencies["@fedify/astro"], packageJson.version);
+ strictEqual(tasks.dev, "bunx astro dev");
+ strictEqual(tasks.build, "bunx astro build");
+ strictEqual(tasks.preview, "bun ./dist/server/entry.mjs");
+ match(
+ files["astro.config.ts"],
+ /import bun from "@nurodev\/astro-bun";/,
+ );
+ match(files["astro.config.ts"], /adapter: bun\(\),/);
+ },
+);
diff --git a/packages/init/src/templates/astro/astro.config.bun.ts.tpl b/packages/init/src/templates/astro/astro.config.bun.ts.tpl
new file mode 100644
index 000000000..7f5e0e028
--- /dev/null
+++ b/packages/init/src/templates/astro/astro.config.bun.ts.tpl
@@ -0,0 +1,10 @@
+import bun from "@nurodev/astro-bun";
+import { fedifyIntegration } from "@fedify/astro";
+import { defineConfig } from "astro/config";
+
+// https://astro.build/config
+export default defineConfig({
+ integrations: [fedifyIntegration()],
+ output: "server",
+ adapter: bun(),
+});
diff --git a/packages/init/src/webframeworks/astro.ts b/packages/init/src/webframeworks/astro.ts
index dc5c0021b..31051cf0d 100644
--- a/packages/init/src/webframeworks/astro.ts
+++ b/packages/init/src/webframeworks/astro.ts
@@ -2,66 +2,75 @@ import { PACKAGE_MANAGER } from "../const.ts";
import { PACKAGE_VERSION, readTemplate } from "../lib.ts";
import type { PackageManager, WebFrameworkDescription } from "../types.ts";
import { defaultDenoDependencies, defaultDevDependencies } from "./const.ts";
-import { getInstruction } from "./utils.ts";
+import { getInstruction, packageManagerToRuntime } from "./utils.ts";
const astroDescription: WebFrameworkDescription = {
label: "Astro",
packageManagers: PACKAGE_MANAGER,
defaultPort: 4321,
- init: async ({ packageManager: pm }) => ({
- command: Array.from(getAstroInitCommand(pm)),
- dependencies: pm === "deno"
- ? {
- ...defaultDenoDependencies,
- "@deno/astro-adapter": "npm:@deno/astro-adapter@^0.3.2",
- "@fedify/astro": PACKAGE_VERSION,
- }
- : {
- "@astrojs/node": "^9.5.4",
- "@fedify/astro": PACKAGE_VERSION,
- },
- devDependencies: {
- ...defaultDevDependencies,
- ...(pm !== "deno"
- ? { typescript: "^5.9.3", "@types/node": "^22.17.0" }
- : {}),
- },
- federationFile: "src/federation.ts",
- loggingFile: "src/logging.ts",
- files: {
- [`astro.config.ts`]: await readTemplate(
- `astro/astro.config.${pm === "deno" ? "deno" : "node"}.ts`,
- ),
- "src/middleware.ts": await readTemplate("astro/src/middleware.ts"),
- ...(pm !== "deno"
- ? {
- "eslint.config.ts": await readTemplate("defaults/eslint.config.ts"),
- }
- : {}),
- },
- compilerOptions: undefined,
- tasks: {
- ...(pm === "deno"
+ init: async ({ packageManager: pm }) => {
+ const runtime = packageManagerToRuntime(pm);
+
+ return ({
+ command: Array.from(getAstroInitCommand(pm)),
+ dependencies: pm === "deno"
? {
- dev: "deno run -A npm:astro dev",
- build: "deno run -A npm:astro build",
- preview: "deno run -A npm:astro preview",
+ ...defaultDenoDependencies,
+ "@deno/astro-adapter": "npm:@deno/astro-adapter@^0.3.2",
+ "@fedify/astro": PACKAGE_VERSION,
}
: pm === "bun"
? {
- dev: "bunx astro dev",
- build: "bunx astro build",
- preview: "bunx astro preview",
+ "@fedify/astro": PACKAGE_VERSION,
+ "@nurodev/astro-bun": "^2.1.2",
}
: {
- dev: "astro dev",
- build: "astro build",
- preview: "astro preview",
- }),
- ...(pm !== "deno" ? { lint: "eslint ." } : {}),
- },
- instruction: getInstruction(pm, 4321),
- }),
+ "@astrojs/node": "^9.5.4",
+ "@fedify/astro": PACKAGE_VERSION,
+ },
+ devDependencies: {
+ ...defaultDevDependencies,
+ ...(pm !== "deno"
+ ? { typescript: "^5.9.3", "@types/node": "^22.17.0" }
+ : {}),
+ },
+ federationFile: "src/federation.ts",
+ loggingFile: "src/logging.ts",
+ files: {
+ [`astro.config.ts`]: await readTemplate(
+ `astro/astro.config.${runtime}.ts`,
+ ),
+ "src/middleware.ts": await readTemplate("astro/src/middleware.ts"),
+ ...(pm !== "deno"
+ ? {
+ "eslint.config.ts": await readTemplate("defaults/eslint.config.ts"),
+ }
+ : {}),
+ },
+ compilerOptions: undefined,
+ tasks: {
+ ...(pm === "deno"
+ ? {
+ dev: "deno run -A npm:astro dev",
+ build: "deno run -A npm:astro build",
+ preview: "deno run -A npm:astro preview",
+ }
+ : pm === "bun"
+ ? {
+ dev: "bunx astro dev",
+ build: "bunx astro build",
+ preview: "bun ./dist/server/entry.mjs",
+ }
+ : {
+ dev: "astro dev",
+ build: "astro build",
+ preview: "astro preview",
+ }),
+ ...(pm !== "deno" ? { lint: "eslint ." } : {}),
+ },
+ instruction: getInstruction(pm, 4321),
+ });
+ },
};
export default astroDescription;
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 07669b84d..19f3f3de1 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -373,6 +373,9 @@ importers:
'@fedify/vocab':
specifier: workspace:^
version: link:../../packages/vocab
+ '@nurodev/astro-bun':
+ specifier: ^2.1.2
+ version: 2.1.2(astro@5.17.3(@types/node@24.3.0)(ioredis@5.8.2)(jiti@2.5.1)(lightningcss@1.30.1)(rollup@4.44.1)(tsx@4.20.3)(typescript@5.9.3)(yaml@2.8.1))
astro:
specifier: 'catalog:'
version: 5.17.3(@types/node@24.3.0)(ioredis@5.8.2)(jiti@2.5.1)(lightningcss@1.30.1)(rollup@4.44.1)(tsx@4.20.3)(typescript@5.9.3)(yaml@2.8.1)
@@ -3583,6 +3586,11 @@ packages:
resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==}
engines: {node: '>=12.4.0'}
+ '@nurodev/astro-bun@2.1.2':
+ resolution: {integrity: sha512-CXzh0q+jOodmqtZ/YMyS7DTqmFC2zafv4C7GQMBDoBDRcx7CONzxCk/rK2uaKHoh3+AvSPo3hXnTp6oLfIpl5g==}
+ peerDependencies:
+ astro: ^5.1.1
+
'@opentelemetry/api-logs@0.211.0':
resolution: {integrity: sha512-swFdZq8MCdmdR22jTVGQDhwqDzcI4M10nhjXkLr1EsIzXgZBqm4ZlmmcWsg3TSNf+3mzgOiqveXmBLZuDi2Lgg==}
engines: {node: '>=8.0.0'}
@@ -5509,6 +5517,15 @@ packages:
ast-types-flow@0.0.8:
resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==}
+ ast-types@0.16.1:
+ resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==}
+ engines: {node: '>=4'}
+
+ astro-integration-kit@0.18.0:
+ resolution: {integrity: sha512-Z0QW5IQjosuKQDEGYYkvUX6EhEtrmE4/oViqWz23QveV8U7AuyFsTdg00WRNPevWZl/5a4lLUeDpv4bCRynRRg==}
+ peerDependencies:
+ astro: ^4.12.0 || ^5.0.0
+
astro@5.17.3:
resolution: {integrity: sha512-69dcfPe8LsHzklwj+hl+vunWUbpMB6pmg35mACjetxbJeUNNys90JaBM8ZiwsPK689SAj/4Zqb1ayaANls9/MA==}
engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'}
@@ -8247,6 +8264,9 @@ packages:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
+ pathe@1.1.2:
+ resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
+
pathe@2.0.3:
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
@@ -8663,6 +8683,10 @@ packages:
resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==}
engines: {node: '>= 12.13.0'}
+ recast@0.23.11:
+ resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==}
+ engines: {node: '>= 4'}
+
redis-errors@1.2.0:
resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==}
engines: {node: '>=4'}
@@ -9297,6 +9321,9 @@ packages:
tiny-inflate@1.0.3:
resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
+ tiny-invariant@1.3.3:
+ resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
+
tinybench@2.9.0:
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
@@ -10194,6 +10221,9 @@ packages:
zod@3.25.76:
resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
+ zod@4.3.6:
+ resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==}
+
zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
@@ -11848,6 +11878,12 @@ snapshots:
'@nolyfill/is-core-module@1.0.39': {}
+ '@nurodev/astro-bun@2.1.2(astro@5.17.3(@types/node@24.3.0)(ioredis@5.8.2)(jiti@2.5.1)(lightningcss@1.30.1)(rollup@4.44.1)(tsx@4.20.3)(typescript@5.9.3)(yaml@2.8.1))':
+ dependencies:
+ astro: 5.17.3(@types/node@24.3.0)(ioredis@5.8.2)(jiti@2.5.1)(lightningcss@1.30.1)(rollup@4.44.1)(tsx@4.20.3)(typescript@5.9.3)(yaml@2.8.1)
+ astro-integration-kit: 0.18.0(astro@5.17.3(@types/node@24.3.0)(ioredis@5.8.2)(jiti@2.5.1)(lightningcss@1.30.1)(rollup@4.44.1)(tsx@4.20.3)(typescript@5.9.3)(yaml@2.8.1))
+ zod: 4.3.6
+
'@opentelemetry/api-logs@0.211.0':
dependencies:
'@opentelemetry/api': 1.9.0
@@ -14203,6 +14239,16 @@ snapshots:
ast-types-flow@0.0.8: {}
+ ast-types@0.16.1:
+ dependencies:
+ tslib: 2.8.1
+
+ astro-integration-kit@0.18.0(astro@5.17.3(@types/node@24.3.0)(ioredis@5.8.2)(jiti@2.5.1)(lightningcss@1.30.1)(rollup@4.44.1)(tsx@4.20.3)(typescript@5.9.3)(yaml@2.8.1)):
+ dependencies:
+ astro: 5.17.3(@types/node@24.3.0)(ioredis@5.8.2)(jiti@2.5.1)(lightningcss@1.30.1)(rollup@4.44.1)(tsx@4.20.3)(typescript@5.9.3)(yaml@2.8.1)
+ pathe: 1.1.2
+ recast: 0.23.11
+
astro@5.17.3(@types/node@24.3.0)(ioredis@5.8.2)(jiti@2.5.1)(lightningcss@1.30.1)(rollup@4.44.1)(tsx@4.20.3)(typescript@5.9.3)(yaml@2.8.1):
dependencies:
'@astrojs/compiler': 2.13.1
@@ -17813,6 +17859,8 @@ snapshots:
path-type@4.0.0: {}
+ pathe@1.1.2: {}
+
pathe@2.0.3: {}
pathval@2.0.1: {}
@@ -18146,6 +18194,14 @@ snapshots:
real-require@0.2.0: {}
+ recast@0.23.11:
+ dependencies:
+ ast-types: 0.16.1
+ esprima: 4.0.1
+ source-map: 0.6.1
+ tiny-invariant: 1.3.3
+ tslib: 2.8.1
+
redis-errors@1.2.0: {}
redis-parser@3.0.0:
@@ -19024,6 +19080,8 @@ snapshots:
tiny-inflate@1.0.3: {}
+ tiny-invariant@1.3.3: {}
+
tinybench@2.9.0: {}
tinycolor2@1.6.0: {}
@@ -19951,4 +20009,6 @@ snapshots:
zod@3.25.76: {}
+ zod@4.3.6: {}
+
zwitch@2.0.4: {}