summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Erika <3019731+Princesseuh@users.noreply.github.com> 2023-11-09 14:05:32 +0100
committerGravatar GitHub <noreply@github.com> 2023-11-09 14:05:32 +0100
commit29b83e9e4b906cc0b5d92fae854fb350fc2be7c8 (patch)
treed81d70e6e8ebb132be685e1badc1cb4ad2337cee
parent78b8b76eae8dd716467aa9e7f982bc690e870446 (diff)
downloadastro-29b83e9e4b906cc0b5d92fae854fb350fc2be7c8.tar.gz
astro-29b83e9e4b906cc0b5d92fae854fb350fc2be7c8.tar.zst
astro-29b83e9e4b906cc0b5d92fae854fb350fc2be7c8.zip
fix(assets): Use uint8arrays instead of Buffer in code that can run outside of Node (#9029)
* fix(assets): Use uint8arrays instead of Buffer in code that can run outside of Node * chore: changeset * docs: update changeset with more information on what to do if a Buffer is important * nit: do a patch instead
-rw-r--r--.changeset/ten-sloths-invent.md7
-rw-r--r--packages/astro/src/assets/build/generate.ts2
-rw-r--r--packages/astro/src/assets/endpoint/generic.ts10
-rw-r--r--packages/astro/src/assets/services/service.ts4
-rw-r--r--packages/astro/src/assets/services/squoosh.ts2
-rw-r--r--packages/astro/src/assets/services/vendor/squoosh/image-pool.ts4
-rw-r--r--packages/astro/src/assets/utils/metadata.ts3
7 files changed, 22 insertions, 10 deletions
diff --git a/.changeset/ten-sloths-invent.md b/.changeset/ten-sloths-invent.md
new file mode 100644
index 000000000..12c5bdf5f
--- /dev/null
+++ b/.changeset/ten-sloths-invent.md
@@ -0,0 +1,7 @@
+---
+'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.
+
+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/build/generate.ts b/packages/astro/src/assets/build/generate.ts
index c34e136dd..be637c26d 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 140189fe0..a158448ed 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 5a063d467..ab647b710 100644
--- a/packages/astro/src/assets/services/service.ts
+++ b/packages/astro/src/assets/services/service.ts
@@ -96,10 +96,10 @@ export interface LocalImageService<T extends Record<string, any> = Record<string
* final image format of the optimized image.
*/
transform: (
- inputBuffer: Buffer,
+ inputBuffer: Uint8Array,
transform: LocalImageTransform,
imageConfig: ImageConfig<T>
- ) => 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 5be5d4077..c9586af10 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<Operation | undefined> {
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 839708f03..cc2df9c96 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 2ee96a7ac..175bacc05 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<Omit<ImageMetadata, 'src' | 'fsPath'>> {
+ // @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) {