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
58
59
60
|
import type { ExternalImageService } from 'astro';
import { baseService } from 'astro/assets';
import { isESMImportedImage } from 'astro/assets/utils';
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 };
function removeLeadingForwardSlash(path: string) {
return path.startsWith('/') ? path.substring(1) : path;
}
const service: ExternalImageService = {
getURL(options) {
// For SVG files, return the original source path
if (isESMImportedImage(options.src) && options.src.format === 'svg') {
return options.src.src;
}
// For non-SVG files, continue with the Netlify's image processing
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;
|