@oberoncms/plugin-uploadthing
Version:
An Puck component and OberonCMS plugin for embeding uploadthing images
42 lines (39 loc) • 1.33 kB
text/typescript
import { imageSize } from "image-size"
type ImageSize = { width: number; height: number }
// TODO change to iterable stream when supported https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams#consuming_a_fetch_using_asynchronous_iteration
export async function getImageSize(
url: string,
defaultSize: ImageSize = { width: 100, height: 100 },
): Promise<ImageSize> {
const MAX_HEADER_BYTES = 128 * 1024 // 128KB
let totalBytes = 0
const chunks: Uint8Array[] = []
const response = await fetch(url)
if (!response.body) {
throw new Error("Image not found for size processing")
}
const reader = response.body.getReader()
while (true) {
const { done, value } = await reader.read()
if (done) {
return defaultSize
}
if (totalBytes + value.length > MAX_HEADER_BYTES) {
reader.cancel()
return defaultSize
}
totalBytes += value.length
chunks.push(value)
try {
// This throws if it cannot determine the size
const { width, height } = imageSize(Buffer.concat(chunks))
if (width && height) {
return { width, height }
}
// If the width or height are (probably incorrectly) zero, return the default
return defaultSize
} catch (error) {
// Cannot determine the size yet
}
}
}