-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
90 lines (70 loc) · 2.57 KB
/
index.js
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
const
{blue, red} = require('chalk'),
sharp = require('sharp'),
accepts = require('accepts'),
fs = require('fs');
let imageRoot;
module.exports = (root) => {
// Is root folder available?
if (!fs.existsSync(root)) {
console.error(`[${blue('images')}]`, red(`Cannot find root folder: ${root}`));
throw new Error('Cannot find root folder');
}
imageRoot = root;
return (request, response, next) => {
let match = decodeURI(request.url).match(/^\/(?<rules>[^/]*)\/(?<image>.*?.(?<ext>jpe?g|png))$/);
if (match) {
// Is image available?
if (!fs.existsSync(`${imageRoot}/${match.groups.image}`)) {
console.error(`[${blue('images')}]`, red(`${match.groups.image} does not exist in ${imageRoot}`));
return;
}
// Collect rules: key=value[,key=value]...
let rules = {};
match.groups.rules.split(',').forEach(rule => {
const [key, value] = rule.split('=');
rules[key] = value;
});
// ... and 'interpret' them.
let options = {};
// Width, Height & DPR
options.dpr = rules.dpr ? parseInt(rules.dpr) : 1;
options.width = rules.w ? parseInt(rules.w) * options.dpr : null;
options.height = rules.h ? parseInt(rules.h) * options.dpr : null;
// Fit or Smartcrop (default)
if ((options.width * options.height > 0) && (rules.s === 'fit')) {
options.fit = sharp.fit.inside;
} else {
options.fit = sharp.fit.cover;
options.position = sharp.strategy.entropy;
}
let transformer = sharp()
.resize(options);
// Better or forced type: avif, webp or stays jpg/png
if (rules.f === 'auto') {
switch (accepts(request).type(['avif', 'webp'])) {
case 'avif':
transformer = transformer.avif();
break;
case 'webp':
transformer = transformer.webp();
break;
}
}
else if (rules.f === 'avif') transformer = transformer.avif();
else if (rules.f === 'webp') transformer = transformer.webp();
transformer = transformer
.on('info', info => {
response.setHeader('Content-Type', `image/${info.format}`);
response.setHeader('Content-Length', info.size);
response.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
});
fs.createReadStream(`${imageRoot}/${match.groups.image}`)
.on('error', (e) => {
console.error(`[${blue('images')}]`, red(e.message));
})
.pipe(transformer)
.pipe(response);
} else next();
};
};