summaryrefslogtreecommitdiff
path: root/packages/integrations/netlify/src/image-service.ts
blob: 1e1f571f8d64d0620e0b48f7fc18256f92205aa8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import type { ExternalImageService, ImageMetadata } from 'astro';
import { baseService } from 'astro/assets';
import { AstroError } from 'astro/errors';

const SUPPORTED_FORMATS = ['avif', 'jpg', 'png', 'webp'];
const QUALITY_NAMES: Record<string, number> = { low: 25, mid: 50, high: 90, max: 100 };

export function isESMImportedImage(src: ImageMetadata | string): src is ImageMetadata {
	return typeof src === 'object';
}

function removeLeadingForwardSlash(path: string) {
	return path.startsWith('/') ? path.substring(1) : path;
}

const service: ExternalImageService = {
	getURL(options) {
		const query = new URLSearchParams();

		const fileSrc = isESMImportedImage(options.src)
			? removeLeadingForwardSlash(options.src.src)
			: options.src;

		query.set('url', fileSrc);

		if (options.format) query.set('fm', options.format);
		if (options.width) query.set('w', `${options.width}`);
		if (options.height) query.set('h', `${options.height}`);
		if (options.quality) query.set('q', `${options.quality}`);

		return `/.netlify/images?${query}`;
	},
	getHTMLAttributes: baseService.getHTMLAttributes,
	getSrcSet: baseService.getSrcSet,
	validateOptions(options) {
		if (options.format && !SUPPORTED_FORMATS.includes(options.format)) {
			throw new AstroError(
				`Unsupported image format "${options.format}"`,
				`Use one of ${SUPPORTED_FORMATS.join(', ')} instead.`,
			);
		}

		if (options.quality) {
			options.quality =
				typeof options.quality === 'string' ? QUALITY_NAMES[options.quality] : options.quality;
			if (options.quality < 1 || options.quality > 100) {
				throw new AstroError(
					`Invalid quality for picture "${options.src}"`,
					'Quality needs to be between 1 and 100.',
				);
			}
		}
		return options;
	},
};

export default service;