diff --git a/.changeset/tame-poems-walk.md b/.changeset/tame-poems-walk.md new file mode 100644 index 000000000000..579f6c1bb44c --- /dev/null +++ b/.changeset/tame-poems-walk.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Allow binary data to be returned from api routes in SSG diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts index f5f72dc5ab93..3b163611ae75 100644 --- a/packages/astro/src/core/build/generate.ts +++ b/packages/astro/src/core/build/generate.ts @@ -382,7 +382,7 @@ async function generatePath( route: pageData.route, }); - let body: string; + let body: string | Uint8Array; let encoding: BufferEncoding | undefined; if (pageData.route.type === 'endpoint') { const endpointHandler = mod as unknown as EndpointHandler; @@ -392,7 +392,8 @@ async function generatePath( throwIfRedirectNotAllowed(result.response, opts.settings.config); // If there's no body, do nothing if (!result.response.body) return; - body = await result.response.text(); + const ab = await result.response.arrayBuffer(); + body = new Uint8Array(ab); } else { body = result.body; encoding = result.encoding; diff --git a/packages/astro/test/api-routes.test.js b/packages/astro/test/api-routes.test.js index ba229c095abf..2536ad18f843 100644 --- a/packages/astro/test/api-routes.test.js +++ b/packages/astro/test/api-routes.test.js @@ -41,4 +41,12 @@ describe('API routes', () => { }); }); }); + + describe('Binary data', () => { + it('can be returned from a response', async () => { + const dat = await fixture.readFile('/binary.dat', null); + expect(dat.length).to.equal(1); + expect(dat[0]).to.equal(0xff); + }); + }); }); diff --git a/packages/astro/test/fixtures/api-routes/src/pages/binary.dat.ts b/packages/astro/test/fixtures/api-routes/src/pages/binary.dat.ts new file mode 100644 index 000000000000..c735896335de --- /dev/null +++ b/packages/astro/test/fixtures/api-routes/src/pages/binary.dat.ts @@ -0,0 +1,5 @@ +import type { APIRoute } from 'astro'; + +export const get: APIRoute = async function () { + return new Response(new Uint8Array([0xff])); +}; diff --git a/packages/astro/test/test-utils.js b/packages/astro/test/test-utils.js index 27e4caa5ea9c..13d3aa00a87e 100644 --- a/packages/astro/test/test-utils.js +++ b/packages/astro/test/test-utils.js @@ -167,7 +167,7 @@ export async function loadFixture(inlineConfig) { }, pathExists: (p) => fs.existsSync(new URL(p.replace(/^\//, ''), config.outDir)), readFile: (filePath, encoding) => - fs.promises.readFile(new URL(filePath.replace(/^\//, ''), config.outDir), encoding ?? 'utf8'), + fs.promises.readFile(new URL(filePath.replace(/^\//, ''), config.outDir), encoding === undefined ? 'utf8' : encoding), readdir: (fp) => fs.promises.readdir(new URL(fp.replace(/^\//, ''), config.outDir)), glob: (p) => fastGlob(p, {