mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-10 16:05:32 -04:00

the #shared alias used by Nuxt cannot be easily disabled and to prevent breackage with jiti, we make use of it
58 lines
1.8 KiB
TypeScript
58 lines
1.8 KiB
TypeScript
import { loadImage, createCanvas } from 'canvas';
|
|
|
|
import { newDate, sha256 } from '#shared/helpers.ts';
|
|
import { s3, s3BucketParams } from '~~/server/cloudServices.ts';
|
|
|
|
const convertToPng = async (original: Buffer): Promise<Buffer> => {
|
|
const image = await loadImage(original);
|
|
const canvas = createCanvas(image.width, image.height);
|
|
canvas.getContext('2d').drawImage(image, 0, 0);
|
|
|
|
return canvas.toBuffer('image/png');
|
|
};
|
|
|
|
export default async (prefix: string, url: string, ttlDays: number | null = null): Promise<string | null> => {
|
|
if (!url) {
|
|
return null;
|
|
}
|
|
|
|
const isSvg = url.toLowerCase().replace(/\?.*$/, '').endsWith('.svg') || url.startsWith('data:image/svg+xml');
|
|
|
|
const key = `${prefix}/${await sha256(url)}.${isSvg ? 'svg' : 'png'}`;
|
|
|
|
try {
|
|
const metadata = await s3.headObject({ Key: key, ...s3BucketParams });
|
|
|
|
if (
|
|
ttlDays !== null &&
|
|
metadata.LastModified! < new Date(
|
|
newDate().setDate(newDate().getDate() - ttlDays),
|
|
)
|
|
) {
|
|
throw 'force refresh';
|
|
}
|
|
|
|
return `${process.env.NUXT_PUBLIC_CLOUDFRONT}/${key}`;
|
|
} catch {
|
|
try {
|
|
const originalBuffer = Buffer.from(await (await fetch(url)).arrayBuffer());
|
|
|
|
await s3.putObject({
|
|
Key: key,
|
|
Body: isSvg
|
|
? originalBuffer
|
|
: await convertToPng(originalBuffer),
|
|
ContentType: isSvg
|
|
? 'image/svg+xml'
|
|
: 'image/png',
|
|
ACL: 'public-read',
|
|
...s3BucketParams,
|
|
});
|
|
|
|
return `${process.env.NUXT_PUBLIC_CLOUDFRONT}/${key}`;
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
};
|