From 5abaf984559de5c8cd27cadb90d6ed2688bd3404 Mon Sep 17 00:00:00 2001 From: Princesseuh <3019731+Princesseuh@users.noreply.github.com> Date: Wed, 8 Nov 2023 23:08:04 +0100 Subject: [PATCH 1/4] fix(assets): Use uint8arrays instead of Buffer in code that can run outside of Node --- packages/astro/src/assets/build/generate.ts | 2 +- packages/astro/src/assets/endpoint/generic.ts | 10 +++++++--- packages/astro/src/assets/services/service.ts | 4 ++-- packages/astro/src/assets/services/squoosh.ts | 2 +- .../src/assets/services/vendor/squoosh/image-pool.ts | 4 ++-- packages/astro/src/assets/utils/metadata.ts | 3 ++- 6 files changed, 15 insertions(+), 10 deletions(-) diff --git a/packages/astro/src/assets/build/generate.ts b/packages/astro/src/assets/build/generate.ts index c34e136ddd52..be637c26da7a 100644 --- a/packages/astro/src/assets/build/generate.ts +++ b/packages/astro/src/assets/build/generate.ts @@ -41,7 +41,7 @@ type AssetEnv = { assetsFolder: AstroConfig['build']['assets']; }; -type ImageData = { data: Buffer; expires: number }; +type ImageData = { data: Uint8Array; expires: number }; export async function prepareAssetsGenerationEnv( pipeline: BuildPipeline, diff --git a/packages/astro/src/assets/endpoint/generic.ts b/packages/astro/src/assets/endpoint/generic.ts index 140189fe088c..a158448edbcf 100644 --- a/packages/astro/src/assets/endpoint/generic.ts +++ b/packages/astro/src/assets/endpoint/generic.ts @@ -14,7 +14,7 @@ async function loadRemoteImage(src: URL) { return undefined; } - return Buffer.from(await res.arrayBuffer()); + return await res.arrayBuffer(); } catch (err: unknown) { return undefined; } @@ -38,7 +38,7 @@ export const GET: APIRoute = async ({ request }) => { throw new Error('Incorrect transform returned by `parseURL`'); } - let inputBuffer: Buffer | undefined = undefined; + let inputBuffer: ArrayBuffer | undefined = undefined; const sourceUrl = isRemotePath(transform.src) ? new URL(transform.src) @@ -54,7 +54,11 @@ export const GET: APIRoute = async ({ request }) => { return new Response('Not Found', { status: 404 }); } - const { data, format } = await imageService.transform(inputBuffer, transform, imageConfig); + const { data, format } = await imageService.transform( + new Uint8Array(inputBuffer), + transform, + imageConfig + ); return new Response(data, { status: 200, diff --git a/packages/astro/src/assets/services/service.ts b/packages/astro/src/assets/services/service.ts index 5a063d4670ae..ab647b7107a0 100644 --- a/packages/astro/src/assets/services/service.ts +++ b/packages/astro/src/assets/services/service.ts @@ -96,10 +96,10 @@ export interface LocalImageService = Record - ) => Promise<{ data: Buffer; format: ImageOutputFormat }>; + ) => Promise<{ data: Uint8Array; format: ImageOutputFormat }>; /** * A list of properties that should be used to generate the hash for the image. diff --git a/packages/astro/src/assets/services/squoosh.ts b/packages/astro/src/assets/services/squoosh.ts index 5be5d40770c6..c9586af10d6c 100644 --- a/packages/astro/src/assets/services/squoosh.ts +++ b/packages/astro/src/assets/services/squoosh.ts @@ -30,7 +30,7 @@ const qualityTable: Record< }; async function getRotationForEXIF( - inputBuffer: Buffer, + inputBuffer: Uint8Array, src?: string ): Promise { const meta = await imageMetadata(inputBuffer, src); diff --git a/packages/astro/src/assets/services/vendor/squoosh/image-pool.ts b/packages/astro/src/assets/services/vendor/squoosh/image-pool.ts index 839708f03b41..cc2df9c96ffe 100644 --- a/packages/astro/src/assets/services/vendor/squoosh/image-pool.ts +++ b/packages/astro/src/assets/services/vendor/squoosh/image-pool.ts @@ -19,7 +19,7 @@ const getWorker = execOnce(() => { type DecodeParams = { operation: 'decode'; - buffer: Buffer; + buffer: Uint8Array; }; type ResizeParams = { operation: 'resize'; @@ -86,7 +86,7 @@ function handleJob(params: JobMessage) { } export async function processBuffer( - buffer: Buffer, + buffer: Uint8Array, operations: Operation[], encoding: ImageOutputFormat, quality?: number diff --git a/packages/astro/src/assets/utils/metadata.ts b/packages/astro/src/assets/utils/metadata.ts index 2ee96a7aca28..c2adc32b3fb4 100644 --- a/packages/astro/src/assets/utils/metadata.ts +++ b/packages/astro/src/assets/utils/metadata.ts @@ -3,9 +3,10 @@ import { AstroError, AstroErrorData } from '../../core/errors/index.js'; import type { ImageInputFormat, ImageMetadata } from '../types.js'; export async function imageMetadata( - data: Buffer, + data: Uint8Array, src?: string ): Promise> { + // @ts-expect-error probe-image-size types are wrong, it does accept Uint8Array. From the README: "Sync version can eat arrays, typed arrays and buffers."" const result = probe.sync(data); if (result === null) { From 10268879dec2b0c9efc18f891a2a4c7b1a1d4c3e Mon Sep 17 00:00:00 2001 From: Princesseuh <3019731+Princesseuh@users.noreply.github.com> Date: Wed, 8 Nov 2023 23:24:01 +0100 Subject: [PATCH 2/4] chore: changeset --- .changeset/ten-sloths-invent.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/ten-sloths-invent.md diff --git a/.changeset/ten-sloths-invent.md b/.changeset/ten-sloths-invent.md new file mode 100644 index 000000000000..1032d4691e6d --- /dev/null +++ b/.changeset/ten-sloths-invent.md @@ -0,0 +1,5 @@ +--- +'astro': minor +--- + +Use UInt8Array instead of Buffer in Image Services to ensure compatibility with non-Node runtimes. From d21544b8300c1d7d6f47071155af6bbca2854c31 Mon Sep 17 00:00:00 2001 From: Princesseuh <3019731+Princesseuh@users.noreply.github.com> Date: Thu, 9 Nov 2023 14:04:04 +0100 Subject: [PATCH 3/4] docs: update changeset with more information on what to do if a Buffer is important --- .changeset/ten-sloths-invent.md | 4 +++- packages/astro/src/assets/utils/metadata.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.changeset/ten-sloths-invent.md b/.changeset/ten-sloths-invent.md index 1032d4691e6d..d8b6b199bda8 100644 --- a/.changeset/ten-sloths-invent.md +++ b/.changeset/ten-sloths-invent.md @@ -2,4 +2,6 @@ 'astro': minor --- -Use UInt8Array instead of Buffer in Image Services to ensure compatibility with non-Node runtimes. +Use UInt8Array instead of Buffer for both the input and return values of the `transform()` hook of the Image Service API to ensure compatibility with non-Node runtimes. + +This change is unlikely to affect you, but if you were previously relying on the return value being a Buffer, you may convert an `UInt8Array` to a `Buffer` using `Buffer.from(your_array)`. diff --git a/packages/astro/src/assets/utils/metadata.ts b/packages/astro/src/assets/utils/metadata.ts index c2adc32b3fb4..175bacc050e7 100644 --- a/packages/astro/src/assets/utils/metadata.ts +++ b/packages/astro/src/assets/utils/metadata.ts @@ -6,7 +6,7 @@ export async function imageMetadata( data: Uint8Array, src?: string ): Promise> { - // @ts-expect-error probe-image-size types are wrong, it does accept Uint8Array. From the README: "Sync version can eat arrays, typed arrays and buffers."" + // @ts-expect-error probe-image-size types are wrong, it does accept Uint8Array. From the README: "Sync version can eat arrays, typed arrays and buffers." const result = probe.sync(data); if (result === null) { From c0b310f95f997079dcda9ed93c3994d7ac445a53 Mon Sep 17 00:00:00 2001 From: Princesseuh <3019731+Princesseuh@users.noreply.github.com> Date: Thu, 9 Nov 2023 14:05:03 +0100 Subject: [PATCH 4/4] nit: do a patch instead --- .changeset/ten-sloths-invent.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/ten-sloths-invent.md b/.changeset/ten-sloths-invent.md index d8b6b199bda8..12c5bdf5fe2e 100644 --- a/.changeset/ten-sloths-invent.md +++ b/.changeset/ten-sloths-invent.md @@ -1,5 +1,5 @@ --- -'astro': minor +'astro': patch --- Use UInt8Array instead of Buffer for both the input and return values of the `transform()` hook of the Image Service API to ensure compatibility with non-Node runtimes.