0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-16 21:46:22 -05:00

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
This commit is contained in:
Erika 2023-11-09 14:05:32 +01:00 committed by GitHub
parent 78b8b76eae
commit 29b83e9e4b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 22 additions and 10 deletions

View file

@ -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)`.

View file

@ -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,

View file

@ -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,

View file

@ -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.

View file

@ -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);

View file

@ -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

View file

@ -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) {