1 | import fs from 'fs'
|
2 | import path from 'path'
|
3 | import crypto from 'crypto'
|
4 | import { makeRe } from 'minimatch'
|
5 | import imagemin from 'imagemin'
|
6 | import mkdirp from 'mkdirp'
|
7 | import promisify from 'util.promisify'
|
8 |
|
9 | export const readFile = promisify(fs.readFile)
|
10 | const writeFileAsync = promisify(fs.writeFile)
|
11 | const mkdirpAsync = promisify(mkdirp)
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 | export async function optimizeImage (imageData, imageminOptions) {
|
20 |
|
21 | const imageBuffer = (Buffer.isBuffer(imageData) ? imageData : Buffer.from(imageData, 'utf8'))
|
22 |
|
23 | const originalSize = imageBuffer.length
|
24 |
|
25 |
|
26 | const optimizedImageBuffer = await imagemin.buffer(imageBuffer, imageminOptions)
|
27 |
|
28 |
|
29 | if (optimizedImageBuffer.length < originalSize) {
|
30 | return optimizedImageBuffer
|
31 | } else {
|
32 |
|
33 | return imageBuffer
|
34 | }
|
35 | }
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 | export function buildTestFunction (rawTestValue, minFileSize, maxFileSize) {
|
47 | const testFunctions = compileRegex(rawTestValue)
|
48 | |
49 |
|
50 |
|
51 |
|
52 |
|
53 | return (filename, assetSource) => {
|
54 | for (let func of testFunctions) {
|
55 | if (func(filename) === true) {
|
56 | return assetSource.length > minFileSize && assetSource.length <= maxFileSize
|
57 | }
|
58 | }
|
59 | return false
|
60 | }
|
61 | }
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 | export function hashContent (content) {
|
69 | return crypto.createHash('sha1').update(content).digest('hex')
|
70 | }
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 | export function invokeIfFunction (func) {
|
78 | if (typeof func === 'function') {
|
79 | return func()
|
80 | } else {
|
81 | return func
|
82 | }
|
83 | }
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 | export async function getFromCacheIfPossible (cacheFolder, content, elseFunc) {
|
95 | let cacheFilePath
|
96 | if (cacheFolder !== null) {
|
97 | cacheFilePath = path.resolve(cacheFolder, hashContent(content))
|
98 | if (await exists(cacheFilePath)) {
|
99 | return readFile(cacheFilePath)
|
100 | }
|
101 | }
|
102 |
|
103 | const fileBuffer = await elseFunc()
|
104 | if (cacheFolder !== null) {
|
105 | await writeFile(cacheFilePath, fileBuffer)
|
106 | }
|
107 | return fileBuffer
|
108 | }
|
109 |
|
110 |
|
111 |
|
112 |
|
113 |
|
114 |
|
115 | export async function exists (directory) {
|
116 | return new Promise((resolve, reject) => {
|
117 | fs.access(directory, fs.constants.R_OK | fs.constants.W_OK, (err) => {
|
118 | if (err) {
|
119 | resolve(false)
|
120 | } else {
|
121 | resolve(true)
|
122 | }
|
123 | })
|
124 | })
|
125 | }
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
133 | export async function writeFile (filename, buffer) {
|
134 | const directory = path.dirname(filename)
|
135 |
|
136 | if (!(await exists(directory))) {
|
137 | await mkdirpAsync(directory)
|
138 | }
|
139 |
|
140 | return writeFileAsync(filename, buffer)
|
141 | }
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 | function compileRegex (rawTestValue) {
|
149 | const tests = Array.isArray(rawTestValue) ? rawTestValue : [rawTestValue]
|
150 |
|
151 | return tests.map((test) => {
|
152 | if (typeof test === 'function') {
|
153 |
|
154 | return test
|
155 | } else if (test instanceof RegExp) {
|
156 |
|
157 | return (filename) => test.test(filename)
|
158 | } else if (typeof test === 'string') {
|
159 |
|
160 | const regex = makeRe(test)
|
161 | return (filename) => regex.test(filename)
|
162 | } else {
|
163 | throw new Error('test parameter must be a regex, glob string, function, or an array of any of them')
|
164 | }
|
165 | })
|
166 | }
|