@e-mc/compress 0.8.7 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +10 -10
- package/README.md +98 -11
- package/index.d.ts +4 -4
- package/index.js +81 -86
- package/package.json +3 -3
package/LICENSE
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
Copyright 2024 An Pham
|
|
2
|
-
|
|
3
|
-
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
4
|
-
|
|
5
|
-
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
6
|
-
|
|
7
|
-
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
8
|
-
|
|
9
|
-
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
10
|
-
|
|
1
|
+
Copyright 2024 An Pham
|
|
2
|
+
|
|
3
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
4
|
+
|
|
5
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
6
|
+
|
|
7
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
8
|
+
|
|
9
|
+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
10
|
+
|
|
11
11
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @e-mc/compress
|
|
2
2
|
|
|
3
|
-
* NodeJS 14
|
|
3
|
+
* NodeJS 14/16
|
|
4
4
|
* ES2020
|
|
5
5
|
|
|
6
6
|
## General Usage
|
|
@@ -9,16 +9,16 @@
|
|
|
9
9
|
|
|
10
10
|
## Interface
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
* [View Source](https://www.unpkg.com/@e-mc/types@0.9.0/lib/index.d.ts)
|
|
13
13
|
|
|
14
14
|
```typescript
|
|
15
15
|
import type { CompressLevel } from "./squared";
|
|
16
16
|
|
|
17
17
|
import type { IModule, ModuleConstructor } from "./index";
|
|
18
|
-
import type { BufferResult, CompressFormat, TryFileCompressor
|
|
18
|
+
import type { BufferResult, CompressFormat, TryFileCompressor } from "./compress";
|
|
19
19
|
import type { CompressModule, CompressSettings } from "./settings";
|
|
20
20
|
|
|
21
|
-
import type { WriteStream } from
|
|
21
|
+
import type { WriteStream } from "fs";
|
|
22
22
|
import type { Readable } from "stream";
|
|
23
23
|
import type { BrotliCompress, Gzip } from "zlib";
|
|
24
24
|
|
|
@@ -35,10 +35,12 @@ interface ICompress extends IModule {
|
|
|
35
35
|
createBrotliCompress(file: string | Buffer, options?: CompressLevel): BrotliCompress;
|
|
36
36
|
createWriteStreamAsGzip(file: string | Buffer, output: string, options?: CompressLevel): WriteStream;
|
|
37
37
|
createWriteStreamAsBrotli(file: string | Buffer, output: string, options?: CompressLevel): WriteStream;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
writeGzip(file: string | Buffer, output: string, options?: CompressLevel): Promise<void>;
|
|
39
|
+
writeBrotli(file: string | Buffer, output: string, options?: CompressLevel): Promise<void>;
|
|
40
|
+
tryFile(file: string | Buffer, options: CompressFormat): Promise<BufferResult>;
|
|
41
|
+
tryFile(file: string | Buffer, output: string, options?: CompressFormat): Promise<BufferResult>;
|
|
42
|
+
tryImage(file: string, options: CompressFormat): Promise<BufferResult>;
|
|
43
|
+
tryImage(file: string | Buffer, output: string, options?: CompressFormat): Promise<BufferResult>;
|
|
42
44
|
get settings(): CompressSettings;
|
|
43
45
|
}
|
|
44
46
|
|
|
@@ -49,11 +51,96 @@ interface CompressConstructor extends ModuleConstructor {
|
|
|
49
51
|
}
|
|
50
52
|
```
|
|
51
53
|
|
|
54
|
+
## Settings
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import type { BrotliOptions, ZlibOptions } from "zlib";
|
|
58
|
+
import type { Options as ZopfliOptions } from "node-zopfli";
|
|
59
|
+
|
|
60
|
+
interface CompressModule {
|
|
61
|
+
gzip?: ZlibOptions;
|
|
62
|
+
brotli?: BrotliOptions;
|
|
63
|
+
zopfli?: ZopfliOptions;
|
|
64
|
+
tinify?: {
|
|
65
|
+
api_key?: string;
|
|
66
|
+
proxy?: string;
|
|
67
|
+
};
|
|
68
|
+
settings?: {
|
|
69
|
+
broadcast_id?: string | string[];
|
|
70
|
+
cache?: boolean;
|
|
71
|
+
cache_expires?: number | string;
|
|
72
|
+
gzip_level?: number;
|
|
73
|
+
brotli_quality?: number;
|
|
74
|
+
zopfli_iterations?: number;
|
|
75
|
+
chunk_size?: number | string;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Example usage
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
const Compress = require("@e-mc/compress");
|
|
84
|
+
|
|
85
|
+
const instance = new Compress({
|
|
86
|
+
gzip: {
|
|
87
|
+
memLevel: 1,
|
|
88
|
+
windowBits: 16
|
|
89
|
+
},
|
|
90
|
+
tinify: {
|
|
91
|
+
api_key: "**********"
|
|
92
|
+
},
|
|
93
|
+
settings: {
|
|
94
|
+
gzip_level: 9, // Lowest priority
|
|
95
|
+
brotli_quality: 11,
|
|
96
|
+
chunk_size: "16kb" // All compression types
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
instance.init();
|
|
100
|
+
|
|
101
|
+
const stream = instance.createWriteStreamAsGzip("/tmp/archive.tar", "/path/output/archive.tar.gz", { level: 5, chunkSize: 4 * 1024 }); // Override settings
|
|
102
|
+
stream
|
|
103
|
+
.on("finish", () => console.log("finish"))
|
|
104
|
+
.on("error", err => console.error(err));
|
|
105
|
+
|
|
106
|
+
const options = {
|
|
107
|
+
plugin: "tinify",
|
|
108
|
+
format: "png", // Optional with extension
|
|
109
|
+
timeout: 60 * 1000, // 1m
|
|
110
|
+
options: {
|
|
111
|
+
apiKey: "**********" // Override settings
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
instance.tryImage("/tmp/image.png", "/path/output/compressed.png", options)
|
|
115
|
+
.then(data => {
|
|
116
|
+
console.log(Buffer.byteLength(data));
|
|
117
|
+
})
|
|
118
|
+
.catch(err => console.error(err));
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## NodeJS 14 LTS
|
|
122
|
+
|
|
123
|
+
Any optional fail safe dependencies were removed as of `E-mc 0.9`. The code itself will still be *ES2020* and will continue to work equivalently when self-installing these dependencies:
|
|
124
|
+
|
|
125
|
+
### Under 15.4 + 16.0
|
|
126
|
+
|
|
127
|
+
```sh
|
|
128
|
+
npm i abort-controller event-target-shim
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Under 14.17 + 15.6
|
|
132
|
+
|
|
133
|
+
```sh
|
|
134
|
+
npm i uuid
|
|
135
|
+
```
|
|
136
|
+
|
|
52
137
|
## References
|
|
53
138
|
|
|
54
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
55
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
56
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
139
|
+
- https://www.unpkg.com/@e-mc/types@0.9.0/lib/squared.d.ts
|
|
140
|
+
- https://www.unpkg.com/@e-mc/types@0.9.0/lib/compress.d.ts
|
|
141
|
+
- https://www.unpkg.com/@e-mc/types@0.9.0/lib/settings.d.ts
|
|
142
|
+
|
|
143
|
+
* https://www.npmjs.com/package/@types/node
|
|
57
144
|
|
|
58
145
|
## LICENSE
|
|
59
146
|
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { CompressConstructor } from '../types/lib';
|
|
2
|
-
|
|
3
|
-
declare const Compress: CompressConstructor;
|
|
4
|
-
|
|
1
|
+
import type { CompressConstructor } from '../types/lib';
|
|
2
|
+
|
|
3
|
+
declare const Compress: CompressConstructor;
|
|
4
|
+
|
|
5
5
|
export = Compress;
|
package/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
2
|
const path = require("path");
|
|
4
3
|
const fs = require("fs");
|
|
5
4
|
const stream = require("stream");
|
|
@@ -7,7 +6,6 @@ const zlib = require("zlib");
|
|
|
7
6
|
const wawoff2 = require("wawoff2");
|
|
8
7
|
const { toSfnt, toWoff } = require('woff2sfnt-sfnt2woff');
|
|
9
8
|
const types_1 = require("@e-mc/types");
|
|
10
|
-
const lib_v4_1 = require("@e-mc/module/lib-v4");
|
|
11
9
|
const module_1 = require("@e-mc/module");
|
|
12
10
|
const CACHE_IMAGE = {};
|
|
13
11
|
const CACHE_FONT = {};
|
|
@@ -35,7 +33,7 @@ function setCacheData(index) {
|
|
|
35
33
|
if (TEMP_DIR) {
|
|
36
34
|
if (expires === 0) {
|
|
37
35
|
if (CACHE_INIT.every(value => !value)) {
|
|
38
|
-
module_1.
|
|
36
|
+
module_1.removeDir(TEMP_DIR, true);
|
|
39
37
|
}
|
|
40
38
|
settings.cache_expires = 0;
|
|
41
39
|
}
|
|
@@ -83,7 +81,7 @@ function setCacheData(index) {
|
|
|
83
81
|
}
|
|
84
82
|
const removeFile = (pathname) => fs.unlink(pathname, () => { });
|
|
85
83
|
const checkChunkSize = (value) => typeof value === 'number' && value > 0 && value % 1024 === 0;
|
|
86
|
-
class Compress extends module_1
|
|
84
|
+
class Compress extends module_1 {
|
|
87
85
|
static singleton() {
|
|
88
86
|
if (!SINGLETON_INSTANCE) {
|
|
89
87
|
SINGLETON_INSTANCE = new Compress();
|
|
@@ -115,7 +113,7 @@ class Compress extends module_1.default {
|
|
|
115
113
|
if (zopfli_iterations && (zopfli_iterations = Math.floor(+zopfli_iterations)) > 0) {
|
|
116
114
|
this.level.zopfli = zopfli_iterations;
|
|
117
115
|
}
|
|
118
|
-
if (chunk_size && checkChunkSize(chunk_size = +chunk_size)) {
|
|
116
|
+
if (chunk_size && ((0, types_1.isString)(chunk_size) && checkChunkSize(chunk_size = (0, types_1.formatSize)(chunk_size)) || checkChunkSize(chunk_size = +chunk_size))) {
|
|
119
117
|
this.chunkSize = chunk_size;
|
|
120
118
|
}
|
|
121
119
|
return this;
|
|
@@ -192,7 +190,11 @@ class Compress extends module_1.default {
|
|
|
192
190
|
brotli = { params };
|
|
193
191
|
}
|
|
194
192
|
params[zlib.constants.BROTLI_PARAM_MODE] = (mimeType || (mimeType = '')).includes('text/') ? zlib.constants.BROTLI_MODE_TEXT : mimeType.includes('font/') ? zlib.constants.BROTLI_MODE_FONT : zlib.constants.BROTLI_MODE_GENERIC;
|
|
195
|
-
|
|
193
|
+
try {
|
|
194
|
+
params[zlib.constants.BROTLI_PARAM_SIZE_HINT] = typeof file === 'string' ? fs.statSync(file).size : Buffer.byteLength(file);
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
}
|
|
196
198
|
if (checkChunkSize(chunkSize)) {
|
|
197
199
|
brotli.chunkSize = chunkSize;
|
|
198
200
|
}
|
|
@@ -207,26 +209,36 @@ class Compress extends module_1.default {
|
|
|
207
209
|
createWriteStreamAsBrotli(file, output, options) {
|
|
208
210
|
return this.createBrotliCompress(file, options).pipe(fs.createWriteStream(output));
|
|
209
211
|
}
|
|
210
|
-
async
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
212
|
+
async writeGzip(file, output, options) {
|
|
213
|
+
return new Promise((resolve, reject) => {
|
|
214
|
+
this.createWriteStreamAsGzip(file, output, options)
|
|
215
|
+
.on('finish', resolve)
|
|
216
|
+
.on('error', reject);
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
async writeBrotli(file, output, options) {
|
|
220
|
+
return new Promise((resolve, reject) => {
|
|
221
|
+
this.createWriteStreamAsBrotli(file, output, options)
|
|
222
|
+
.on('finish', resolve)
|
|
223
|
+
.on('error', reject);
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
async tryFile(file, output, options) {
|
|
215
227
|
if ((0, types_1.isObject)(output)) {
|
|
216
|
-
|
|
228
|
+
options = output;
|
|
217
229
|
output = '';
|
|
218
230
|
}
|
|
219
231
|
if (!(0, types_1.isString)(output)) {
|
|
220
232
|
output = typeof file === 'string' ? file : '';
|
|
221
233
|
}
|
|
222
|
-
|
|
223
|
-
const { filename, startTime = process.hrtime(), timeout = 0, sessionId, broadcastId } =
|
|
224
|
-
let format =
|
|
225
|
-
if (!
|
|
226
|
-
return Promise.reject((0, types_1.errorValue)(
|
|
234
|
+
options || (options = {});
|
|
235
|
+
const { filename, startTime = process.hrtime(), timeout = 0, sessionId, broadcastId } = options;
|
|
236
|
+
let format = options.format;
|
|
237
|
+
if (!format) {
|
|
238
|
+
return Promise.reject((0, types_1.errorValue)("Missing option \"format\"", output || filename));
|
|
227
239
|
}
|
|
228
|
-
let hash =
|
|
229
|
-
const cache = this.settings.cache ? !!(hash && (hash = module_1.
|
|
240
|
+
let hash = options.etag;
|
|
241
|
+
const cache = this.settings.cache ? !!(hash && (hash = module_1.asHash(hash)) || Buffer.isBuffer(file) && (hash = module_1.asHash(file))) : false;
|
|
230
242
|
return new Promise((resolve, reject) => {
|
|
231
243
|
let timer = null, aborted;
|
|
232
244
|
const endProcess = (err, data = null, ext, result, fromCache) => {
|
|
@@ -234,23 +246,19 @@ class Compress extends module_1.default {
|
|
|
234
246
|
clearTimeout(timer);
|
|
235
247
|
}
|
|
236
248
|
if (err) {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
resolve(null);
|
|
240
|
-
}
|
|
241
|
-
else {
|
|
242
|
-
reject(err);
|
|
243
|
-
}
|
|
249
|
+
reject(err);
|
|
250
|
+
return;
|
|
244
251
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
callback(null, result || data, ext);
|
|
251
|
-
}
|
|
252
|
-
resolve(data);
|
|
252
|
+
if (!fromCache) {
|
|
253
|
+
this.writeTimeProcess(ext || format, (0, types_1.isString)(result) ? path.basename(result) : filename || "Completed", startTime, { type: 8, sessionId, broadcastId });
|
|
254
|
+
}
|
|
255
|
+
if (result) {
|
|
256
|
+
options.outFile = result;
|
|
253
257
|
}
|
|
258
|
+
if (ext) {
|
|
259
|
+
options.outExt = ext;
|
|
260
|
+
}
|
|
261
|
+
resolve(data);
|
|
254
262
|
};
|
|
255
263
|
const startProcess = (compressing) => {
|
|
256
264
|
if (timeout > 0) {
|
|
@@ -280,7 +288,7 @@ class Compress extends module_1.default {
|
|
|
280
288
|
if (cache) {
|
|
281
289
|
const pathname = path.join(from, ext);
|
|
282
290
|
let tempFont;
|
|
283
|
-
if (TEMP_DIR && module_1.
|
|
291
|
+
if (TEMP_DIR && module_1.createDir(tempFont = path.join(TEMP_DIR, pathname))) {
|
|
284
292
|
tempFont = path.join(tempFont, hash);
|
|
285
293
|
}
|
|
286
294
|
else {
|
|
@@ -300,7 +308,7 @@ class Compress extends module_1.default {
|
|
|
300
308
|
const cacheKey = from + `_${to}_` + hash;
|
|
301
309
|
const tempFont = CACHE_FONT[cacheKey];
|
|
302
310
|
if (tempFont) {
|
|
303
|
-
if (module_1.
|
|
311
|
+
if (module_1.isPath(tempFont[0])) {
|
|
304
312
|
try {
|
|
305
313
|
const data = fs.readFileSync(tempFont[0]);
|
|
306
314
|
let pathname;
|
|
@@ -311,7 +319,7 @@ class Compress extends module_1.default {
|
|
|
311
319
|
else {
|
|
312
320
|
endProcess(null, data, to, '', true);
|
|
313
321
|
}
|
|
314
|
-
this.formatMessage(8, from, [pathname ? path.basename(pathname) : "Completed" + ` -> font/${to}`, 'cache'], tempFont[1].toLocaleString(), { ...module_1.
|
|
322
|
+
this.formatMessage(8, from, [pathname ? path.basename(pathname) : "Completed" + ` -> font/${to}`, 'cache'], tempFont[1].toLocaleString(), { ...module_1.LOG_STYLE_NOTICE, hintBold: true, sessionId, broadcastId });
|
|
315
323
|
return true;
|
|
316
324
|
}
|
|
317
325
|
catch {
|
|
@@ -322,7 +330,7 @@ class Compress extends module_1.default {
|
|
|
322
330
|
return false;
|
|
323
331
|
}
|
|
324
332
|
};
|
|
325
|
-
const errorResponse = (font) => endProcess((0, types_1.errorValue)(
|
|
333
|
+
const errorResponse = (font) => endProcess((0, types_1.errorValue)("Unsupported MIME", (font ? font.mime : "Unknown") + ': ' + (output || filename || "Unknown")));
|
|
326
334
|
const data = Buffer.isBuffer(file) ? file : fs.readFileSync(file);
|
|
327
335
|
switch (format = format.toLowerCase()) {
|
|
328
336
|
case 'gz':
|
|
@@ -330,11 +338,11 @@ class Compress extends module_1.default {
|
|
|
330
338
|
startProcess(true);
|
|
331
339
|
let transform, chunks;
|
|
332
340
|
if (output) {
|
|
333
|
-
transform = this[format === 'gz' ? 'createWriteStreamAsGzip' : 'createWriteStreamAsBrotli'](data, output,
|
|
341
|
+
transform = this[format === 'gz' ? 'createWriteStreamAsGzip' : 'createWriteStreamAsBrotli'](data, output, options);
|
|
334
342
|
}
|
|
335
343
|
else {
|
|
336
344
|
chunks = [];
|
|
337
|
-
transform = this[format === 'gz' ? 'createGzip' : 'createBrotliCompress'](data,
|
|
345
|
+
transform = this[format === 'gz' ? 'createGzip' : 'createBrotliCompress'](data, options).on('data', chunk => chunks.push(chunk));
|
|
338
346
|
}
|
|
339
347
|
transform
|
|
340
348
|
.on('finish', () => {
|
|
@@ -355,7 +363,7 @@ class Compress extends module_1.default {
|
|
|
355
363
|
}
|
|
356
364
|
startProcess(false);
|
|
357
365
|
const checkResult = (result, from) => {
|
|
358
|
-
module_1.
|
|
366
|
+
module_1.resolveMime(result).then(font => {
|
|
359
367
|
switch (font?.mime) {
|
|
360
368
|
case "font/ttf":
|
|
361
369
|
case "font/otf":
|
|
@@ -367,7 +375,7 @@ class Compress extends module_1.default {
|
|
|
367
375
|
}
|
|
368
376
|
});
|
|
369
377
|
};
|
|
370
|
-
module_1.
|
|
378
|
+
module_1.resolveMime(data).then(font => {
|
|
371
379
|
try {
|
|
372
380
|
switch (font?.mime) {
|
|
373
381
|
case "font/woff":
|
|
@@ -399,7 +407,7 @@ class Compress extends module_1.default {
|
|
|
399
407
|
return;
|
|
400
408
|
}
|
|
401
409
|
const checkResult = (result, mimeType, from) => {
|
|
402
|
-
module_1.
|
|
410
|
+
module_1.resolveMime(result).then(font => {
|
|
403
411
|
if (font?.mime === mimeType) {
|
|
404
412
|
writeFont(result, font.ext, from);
|
|
405
413
|
}
|
|
@@ -409,7 +417,7 @@ class Compress extends module_1.default {
|
|
|
409
417
|
});
|
|
410
418
|
};
|
|
411
419
|
startProcess(true);
|
|
412
|
-
module_1.
|
|
420
|
+
module_1.resolveMime(data).then(font => {
|
|
413
421
|
try {
|
|
414
422
|
switch (font?.mime) {
|
|
415
423
|
case "font/ttf":
|
|
@@ -440,7 +448,7 @@ class Compress extends module_1.default {
|
|
|
440
448
|
if (typeof compressor === 'function') {
|
|
441
449
|
startProcess(true);
|
|
442
450
|
if (compressor.toString().startsWith('async')) {
|
|
443
|
-
compressor.call(this, file, output,
|
|
451
|
+
compressor.call(this, file, output, options)
|
|
444
452
|
.then(result => {
|
|
445
453
|
if (typeof result === 'string') {
|
|
446
454
|
endProcess(null, null, format, result);
|
|
@@ -449,14 +457,14 @@ class Compress extends module_1.default {
|
|
|
449
457
|
endProcess(null, result, format);
|
|
450
458
|
}
|
|
451
459
|
})
|
|
452
|
-
.catch(err => endProcess(err));
|
|
460
|
+
.catch((err) => endProcess(err));
|
|
453
461
|
}
|
|
454
462
|
else {
|
|
455
|
-
compressor.call(this, file, output,
|
|
463
|
+
compressor.call(this, file, output, options, endProcess);
|
|
456
464
|
}
|
|
457
465
|
}
|
|
458
466
|
else {
|
|
459
|
-
throw (0, types_1.errorValue)(
|
|
467
|
+
throw (0, types_1.errorValue)("Missing compression plugin", format);
|
|
460
468
|
}
|
|
461
469
|
break;
|
|
462
470
|
}
|
|
@@ -467,24 +475,20 @@ class Compress extends module_1.default {
|
|
|
467
475
|
}
|
|
468
476
|
});
|
|
469
477
|
}
|
|
470
|
-
async tryImage(file, output,
|
|
471
|
-
if (typeof config === 'function') {
|
|
472
|
-
callback = config;
|
|
473
|
-
config = undefined;
|
|
474
|
-
}
|
|
478
|
+
async tryImage(file, output, options) {
|
|
475
479
|
if ((0, types_1.isObject)(output)) {
|
|
476
|
-
|
|
480
|
+
options = output;
|
|
477
481
|
output = '';
|
|
478
482
|
}
|
|
479
483
|
else {
|
|
480
|
-
|
|
484
|
+
options || (options = {});
|
|
481
485
|
}
|
|
482
|
-
const { plugin =
|
|
486
|
+
const { plugin = "tinify", filename, startTime = process.hrtime(), timeout = 0, proxyUrl, sessionId, broadcastId } = options;
|
|
483
487
|
if (!(0, types_1.isString)(output)) {
|
|
484
488
|
output = typeof file === 'string' ? file : '';
|
|
485
489
|
}
|
|
486
|
-
const ext = output ? path.extname(output).substring(1) :
|
|
487
|
-
const format =
|
|
490
|
+
const ext = output ? path.extname(output).substring(1) : options.format || "Unknown";
|
|
491
|
+
const format = options.format || ext;
|
|
488
492
|
return new Promise((resolve, reject) => {
|
|
489
493
|
let timer = null, hash, cacheKey, aborted, apiKey;
|
|
490
494
|
const failed = (err) => {
|
|
@@ -492,13 +496,7 @@ class Compress extends module_1.default {
|
|
|
492
496
|
if (timer) {
|
|
493
497
|
clearTimeout(timer);
|
|
494
498
|
}
|
|
495
|
-
|
|
496
|
-
callback(err, null);
|
|
497
|
-
resolve(null);
|
|
498
|
-
}
|
|
499
|
-
else {
|
|
500
|
-
reject(err);
|
|
501
|
-
}
|
|
499
|
+
reject(err);
|
|
502
500
|
};
|
|
503
501
|
const success = (result, ctime) => {
|
|
504
502
|
if (aborted) {
|
|
@@ -508,21 +506,22 @@ class Compress extends module_1.default {
|
|
|
508
506
|
clearTimeout(timer);
|
|
509
507
|
}
|
|
510
508
|
const complete = (err) => {
|
|
509
|
+
if (err) {
|
|
510
|
+
reject(err);
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
511
513
|
const value = output ? path.basename(output) : filename || (0, types_1.isString)(file) && path.basename(file);
|
|
512
514
|
const status = value ? plugin + ' -> ' + value : "Completed";
|
|
513
515
|
if (ctime) {
|
|
514
|
-
this.formatMessage(8, value ? path.extname(value).substring(1) : '', [status, 'cache'], ctime.toLocaleString(), { ...module_1.
|
|
516
|
+
this.formatMessage(8, value ? path.extname(value).substring(1) : '', [status, 'cache'], ctime.toLocaleString(), { ...module_1.LOG_STYLE_NOTICE, hintBold: true, sessionId, broadcastId });
|
|
515
517
|
}
|
|
516
518
|
else {
|
|
517
519
|
this.writeTimeProcess(ext, status, startTime, { type: 8, sessionId, broadcastId });
|
|
518
520
|
}
|
|
519
|
-
if (callback) {
|
|
520
|
-
callback(err, result);
|
|
521
|
-
}
|
|
522
521
|
resolve(result);
|
|
523
522
|
if (!ctime && hash && cacheKey && TEMP_DIR) {
|
|
524
523
|
const pathname = path.join(TEMP_DIR, plugin, hash);
|
|
525
|
-
if (module_1.
|
|
524
|
+
if (module_1.createDir(pathname)) {
|
|
526
525
|
fs.writeFile(path.join(pathname, cacheKey), result, error => {
|
|
527
526
|
var _a, _b;
|
|
528
527
|
if (!error) {
|
|
@@ -540,29 +539,29 @@ class Compress extends module_1.default {
|
|
|
540
539
|
}
|
|
541
540
|
};
|
|
542
541
|
const getFormat = () => output ? path.basename(output) : ext;
|
|
543
|
-
if (plugin ===
|
|
542
|
+
if (plugin === "tinify") {
|
|
544
543
|
switch (format) {
|
|
545
544
|
case 'png':
|
|
546
545
|
case 'jpg':
|
|
547
546
|
case 'jpeg':
|
|
548
547
|
case 'webp':
|
|
549
|
-
apiKey =
|
|
548
|
+
apiKey = options.options?.apiKey || (module_1.enabled("process.env.apply") ? process.env.TINIFY_KEY : '');
|
|
550
549
|
break;
|
|
551
550
|
default:
|
|
552
|
-
failed((0, types_1.errorMessage)(plugin,
|
|
551
|
+
failed((0, types_1.errorMessage)(plugin, "Unsupported MIME", format));
|
|
553
552
|
return;
|
|
554
553
|
}
|
|
555
|
-
if (!
|
|
554
|
+
if (!apiKey) {
|
|
556
555
|
failed((0, types_1.errorMessage)(plugin, 'Missing API key'));
|
|
557
556
|
return;
|
|
558
557
|
}
|
|
559
|
-
switch (module_1.
|
|
558
|
+
switch (module_1.lookupMime(ext)) {
|
|
560
559
|
case "image/jpeg":
|
|
561
560
|
case "image/png":
|
|
562
561
|
case "image/webp":
|
|
563
562
|
break;
|
|
564
563
|
default:
|
|
565
|
-
failed((0, types_1.errorMessage)(plugin,
|
|
564
|
+
failed((0, types_1.errorMessage)(plugin, "Unsupported MIME", getFormat()));
|
|
566
565
|
return;
|
|
567
566
|
}
|
|
568
567
|
}
|
|
@@ -577,8 +576,8 @@ class Compress extends module_1.default {
|
|
|
577
576
|
if (this.settings.cache && setCacheData.call(this, 1)) {
|
|
578
577
|
let stored;
|
|
579
578
|
try {
|
|
580
|
-
stored = (CACHE_IMAGE[plugin] || (CACHE_IMAGE[plugin] = {}))[hash = module_1.
|
|
581
|
-
cacheKey = module_1.
|
|
579
|
+
stored = (CACHE_IMAGE[plugin] || (CACHE_IMAGE[plugin] = {}))[hash = module_1.asHash(data)];
|
|
580
|
+
cacheKey = module_1.asHash(plugin + ':' + (apiKey ? format + apiKey : module_1.asString(options) || 'unknown'), 'md5');
|
|
582
581
|
const ctime = stored?.[cacheKey];
|
|
583
582
|
if (ctime) {
|
|
584
583
|
success(fs.readFileSync(path.join(TEMP_DIR, plugin, hash, cacheKey)), ctime);
|
|
@@ -596,7 +595,7 @@ class Compress extends module_1.default {
|
|
|
596
595
|
timer = setTimeout(() => failed((0, types_1.errorMessage)(plugin, "Timeout was exceeded")), timeout);
|
|
597
596
|
}
|
|
598
597
|
if (apiKey) {
|
|
599
|
-
const apiProxy = proxyUrl && (typeof proxyUrl === 'function' ? proxyUrl("https://api.tinify.com") : proxyUrl) || this.module.tinify?.proxy || module_1.
|
|
598
|
+
const apiProxy = proxyUrl && (typeof proxyUrl === 'function' ? proxyUrl("https://api.tinify.com") : proxyUrl) || this.module.tinify?.proxy || module_1.enabled("process.env.apply") && process.env.TINIFY_PROXY || '';
|
|
600
599
|
const key = apiKey + apiProxy;
|
|
601
600
|
let tinypng = CACHE_TINIFY[key];
|
|
602
601
|
const validate = () => {
|
|
@@ -642,12 +641,12 @@ class Compress extends module_1.default {
|
|
|
642
641
|
else {
|
|
643
642
|
try {
|
|
644
643
|
const transform = require(plugin);
|
|
645
|
-
transform(options)(data).then(result => {
|
|
644
|
+
transform(options.options)(data).then(result => {
|
|
646
645
|
if (result !== data) {
|
|
647
646
|
success(result);
|
|
648
647
|
}
|
|
649
648
|
else {
|
|
650
|
-
failed((0, types_1.errorMessage)(plugin,
|
|
649
|
+
failed((0, types_1.errorMessage)(plugin, "Unsupported MIME", getFormat()));
|
|
651
650
|
}
|
|
652
651
|
});
|
|
653
652
|
}
|
|
@@ -662,9 +661,5 @@ class Compress extends module_1.default {
|
|
|
662
661
|
return (_a = this.module).settings || (_a.settings = {});
|
|
663
662
|
}
|
|
664
663
|
}
|
|
665
|
-
exports.default = Compress;
|
|
666
664
|
|
|
667
|
-
|
|
668
|
-
module.exports = exports.default;
|
|
669
|
-
module.exports.default = exports.default;
|
|
670
|
-
}
|
|
665
|
+
module.exports = Compress;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@e-mc/compress",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Compress constructor for E-mc.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"license": "BSD 3-Clause",
|
|
24
24
|
"homepage": "https://github.com/anpham6/e-mc#readme",
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@e-mc/module": "0.
|
|
27
|
-
"@e-mc/types": "0.
|
|
26
|
+
"@e-mc/module": "0.9.0",
|
|
27
|
+
"@e-mc/types": "0.9.0",
|
|
28
28
|
"tinify": "^1.7.1",
|
|
29
29
|
"wawoff2": "^2.0.1",
|
|
30
30
|
"woff2sfnt-sfnt2woff": "^1.0.0"
|