From 50dd2a546ef99cd8e21d7b21d48228246ce87ee6 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Mon, 20 Apr 2026 22:37:08 +0900 Subject: [PATCH 1/5] Fix Astro Bun scaffolding in fedify init Switch Astro projects generated for Bun from the Node.js adapter to @nurodev/astro-bun and run the built Bun server entry point for preview. Update the Astro example and package documentation to cover the Bun setup, and record the bug fix in CHANGES.md. Assisted-by: OpenCode:gpt-5.4 --- CHANGES.md | 7 ++ deno.lock | 64 +++++++++++++++++-- examples/astro/README.md | 54 ++++++++++++++-- examples/astro/astro.config.bun.ts | 12 ++++ examples/astro/package.json | 6 +- packages/astro/README.md | 35 +++++++++- .../templates/astro/astro.config.bun.ts.tpl | 10 +++ packages/init/src/webframeworks/astro.ts | 11 +++- pnpm-lock.yaml | 60 +++++++++++++++++ 9 files changed, 241 insertions(+), 18 deletions(-) create mode 100644 examples/astro/astro.config.bun.ts create mode 100644 packages/init/src/templates/astro/astro.config.bun.ts.tpl diff --git a/CHANGES.md b/CHANGES.md index 60589cb8e..47b3e3d74 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,13 @@ 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. + 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..11f6e7844 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,7 +239,7 @@ 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 @@ -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/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..13c84c95c 100644 --- a/packages/init/src/webframeworks/astro.ts +++ b/packages/init/src/webframeworks/astro.ts @@ -16,6 +16,11 @@ const astroDescription: WebFrameworkDescription = { "@deno/astro-adapter": "npm:@deno/astro-adapter@^0.3.2", "@fedify/astro": PACKAGE_VERSION, } + : pm === "bun" + ? { + "@fedify/astro": PACKAGE_VERSION, + "@nurodev/astro-bun": "^2.1.2", + } : { "@astrojs/node": "^9.5.4", "@fedify/astro": PACKAGE_VERSION, @@ -30,7 +35,9 @@ const astroDescription: WebFrameworkDescription = { loggingFile: "src/logging.ts", files: { [`astro.config.ts`]: await readTemplate( - `astro/astro.config.${pm === "deno" ? "deno" : "node"}.ts`, + `astro/astro.config.${ + pm === "deno" ? "deno" : pm === "bun" ? "bun" : "node" + }.ts`, ), "src/middleware.ts": await readTemplate("astro/src/middleware.ts"), ...(pm !== "deno" @@ -51,7 +58,7 @@ const astroDescription: WebFrameworkDescription = { ? { dev: "bunx astro dev", build: "bunx astro build", - preview: "bunx astro preview", + preview: "bun ./dist/server/entry.mjs", } : { dev: "astro dev", 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: {} From 0bc9f9e5a335757874dffb81b64e4c5cb1997b8e Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Mon, 20 Apr 2026 23:05:50 +0900 Subject: [PATCH 2/5] Clarify Astro example template cleanup steps Adjust the Deno and Node.js template instructions in the Astro example so they also remove the Bun config file. This keeps the documented cleanup steps aligned with the new astro.config.bun.ts file added in the previous fix. Assisted-by: OpenCode:gpt-5.4 --- examples/astro/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/astro/README.md b/examples/astro/README.md index 11f6e7844..cf06d45d6 100644 --- a/examples/astro/README.md +++ b/examples/astro/README.md @@ -245,7 +245,7 @@ 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 ~~~~ @@ -264,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 ~~~~ From 5c863dfdf8199fbe94e535f39a3e62b4a4564da0 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Mon, 20 Apr 2026 23:12:12 +0900 Subject: [PATCH 3/5] Add a PR link to the changelog --- CHANGES.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 47b3e3d74..467d624d2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,7 +13,9 @@ To be released. - 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. + Bun server entry point instead. [[#707]] + +[#707]: https://github.com/fedify-dev/fedify/pull/707 Version 2.1.6 From 04550b6bfa8641508ad8337b2956995a564cd910 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Mon, 20 Apr 2026 23:15:41 +0900 Subject: [PATCH 4/5] Cover Astro + Bun init scaffolding in tests Add a regression test for the Astro initializer's Bun path so changes to its adapter dependency, generated config, or preview command stay covered by the init package test suite. Assisted-by: OpenCode:gpt-5.4 --- packages/init/src/package.test.ts | 41 ++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) 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\(\),/); + }, +); From 3364cf93565c55b484e5f75d07f5ec2287d71edb Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Tue, 21 Apr 2026 10:59:02 +0900 Subject: [PATCH 5/5] Reuse the runtime helper in Astro init Use the shared package-manager-to-runtime helper in the Astro initializer instead of duplicating the runtime mapping inline. This keeps the template selection logic aligned with the existing utility used elsewhere in the init package. Assisted-by: OpenCode:gpt-5.4 --- packages/init/src/webframeworks/astro.ts | 114 ++++++++++++----------- 1 file changed, 58 insertions(+), 56 deletions(-) diff --git a/packages/init/src/webframeworks/astro.ts b/packages/init/src/webframeworks/astro.ts index 13c84c95c..31051cf0d 100644 --- a/packages/init/src/webframeworks/astro.ts +++ b/packages/init/src/webframeworks/astro.ts @@ -2,73 +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, - } - : pm === "bun" - ? { - "@fedify/astro": PACKAGE_VERSION, - "@nurodev/astro-bun": "^2.1.2", - } - : { - "@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" : pm === "bun" ? "bun" : "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: "bun ./dist/server/entry.mjs", + "@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;