diff --git a/.changeset/odd-swans-walk.md b/.changeset/odd-swans-walk.md new file mode 100644 index 0000000000..0c406d7e06 --- /dev/null +++ b/.changeset/odd-swans-walk.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes non-GET API routes in dev with Node 14 diff --git a/packages/astro/src/vite-plugin-astro-server/index.ts b/packages/astro/src/vite-plugin-astro-server/index.ts index 4a5b1a5fc2..3294b4948a 100644 --- a/packages/astro/src/vite-plugin-astro-server/index.ts +++ b/packages/astro/src/vite-plugin-astro-server/index.ts @@ -15,6 +15,7 @@ import serverErrorTemplate from '../template/5xx.js'; import { RouteCache } from '../core/render/route-cache.js'; import { fixViteErrorMessage } from '../core/errors.js'; import { createRequest } from '../core/request.js'; +import { Readable } from 'stream'; interface AstroPluginOptions { config: AstroConfig; @@ -44,12 +45,17 @@ async function writeWebResponse(res: http.ServerResponse, webResponse: Response) const { status, headers, body } = webResponse; res.writeHead(status, Object.fromEntries(headers.entries())); if (body) { - const reader = body.getReader(); - while (true) { - const { done, value } = await reader.read(); - if (done) break; - if (value) { - res.write(value); + if(body instanceof Readable) { + body.pipe(res); + return; + } else { + const reader = body.getReader(); + while (true) { + const { done, value } = await reader.read(); + if (done) break; + if (value) { + res.write(value); + } } } } @@ -134,7 +140,7 @@ async function handleRequest( await new Promise((resolve) => { req.setEncoding('utf-8'); req.on('data', (bts) => bytes.push(bts)); - req.on('close', resolve); + req.on('end', resolve); }); body = new TextEncoder().encode(bytes.join('')).buffer; } diff --git a/packages/astro/test/fixtures/ssr-api-route/src/pages/food.json.js b/packages/astro/test/fixtures/ssr-api-route/src/pages/food.json.js index 0003f2ad4b..fecf830514 100644 --- a/packages/astro/test/fixtures/ssr-api-route/src/pages/food.json.js +++ b/packages/astro/test/fixtures/ssr-api-route/src/pages/food.json.js @@ -8,3 +8,13 @@ export function get() { ]) }; } + +export async function post(params, request) { + const body = await request.text(); + return new Response(body === `some data` ? `ok` : `not ok`, { + status: 200, + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + } + }); +} diff --git a/packages/astro/test/ssr-api-route.test.js b/packages/astro/test/ssr-api-route.test.js index 2131c2b6f4..cf053a8db8 100644 --- a/packages/astro/test/ssr-api-route.test.js +++ b/packages/astro/test/ssr-api-route.test.js @@ -36,4 +36,25 @@ describe('API routes in SSR', () => { const body = await response.json(); expect(body.length).to.equal(3); }); + + describe('Dev', () => { + let devServer; + before(async () => { + devServer = await fixture.startDevServer(); + }); + + after(async () => { + await devServer.stop(); + }); + + it('Can POST to API routes', async () => { + const response = await fixture.fetch('/food.json', { + method: 'POST', + body: `some data` + }) + expect(response.status).to.equal(200); + const text = await response.text(); + expect(text).to.equal(`ok`); + }); + }); });