-
Notifications
You must be signed in to change notification settings - Fork 10.3k
/
cache-image.js
68 lines (57 loc) · 1.76 KB
/
cache-image.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
const crypto = require(`crypto`)
const { resolve, parse } = require(`path`)
const axios = require(`axios`)
const { pathExists, createWriteStream } = require(`fs-extra`)
module.exports = async function cacheImage(store, image, options) {
const program = store.getState().program
const CACHE_DIR = resolve(`${program.directory}/.cache/contentful/assets/`)
const {
file: { url, fileName, details },
} = image
const {
width,
height,
maxWidth,
maxHeight,
resizingBehavior,
cropFocus,
background,
} = options
const userWidth = maxWidth || width
const userHeight = maxHeight || height
const aspectRatio = details.image.height / details.image.width
const resultingWidth = Math.round(userWidth || 800)
const resultingHeight = Math.round(userHeight || resultingWidth * aspectRatio)
const params = [`w=${resultingWidth}`, `h=${resultingHeight}`]
if (resizingBehavior) {
params.push(`fit=${resizingBehavior}`)
}
if (cropFocus) {
params.push(`crop=${cropFocus}`)
}
if (background) {
params.push(`bg=${background}`)
}
const optionsHash = crypto
.createHash(`md5`)
.update(JSON.stringify([url, ...params]))
.digest(`hex`)
const { name, ext } = parse(fileName)
const absolutePath = resolve(CACHE_DIR, `${name}-${optionsHash}${ext}`)
const alreadyExists = await pathExists(absolutePath)
if (!alreadyExists) {
const previewUrl = `http:${url}?${params.join(`&`)}`
const response = await axios({
method: `get`,
url: previewUrl,
responseType: `stream`,
})
await new Promise((resolve, reject) => {
const file = createWriteStream(absolutePath)
response.data.pipe(file)
file.on(`finish`, resolve)
file.on(`error`, reject)
})
}
return absolutePath
}