UNPKG

2.91 kBJavaScriptView Raw
1//-------------------------------------
2//-- Toolbox
3//-------------------------------------
4'use strict';
5
6const chalk = require('chalk');
7const deepKeys = require('deep-keys');
8const log = require('fancy-log');
9const plumber = require('gulp-plumber');
10const without = require('lodash.without');
11const merge = require('merge-stream');
12const emoji = require('node-emoji');
13const prettyBytes = require('pretty-bytes');
14const stream = require('stream');
15const Vinyl = require('vinyl');
16const fss = require('@absolunet/fss');
17const { terminal } = require('@absolunet/terminal');
18
19
20class Toolbox {
21
22 //-- Create a vinyl stream from a text
23 vinylStream(filename, string) {
24 const source = stream.Readable({ objectMode: true });
25
26 source._read = function() {
27 this.push(new Vinyl({
28 path: filename,
29 contents: Buffer.from(string)
30 }));
31 this.push(null);
32 };
33
34 return source;
35 }
36
37
38 //-- Return merged streams or self-closing stream
39 mergeStreams(streams) {
40 return streams.length !== 0 ? merge(...streams) : this.selfClosingStream();
41 }
42
43
44 //-- Fakes a stream waiting for a callback
45 fakeStream(callback) {
46 const fake = stream.Writable({ write: (chunk, encoding, callback2) => { callback2(); } });
47
48 callback(() => {
49 fake.end('End fake stream');
50 });
51
52 return fake;
53 }
54
55
56 //-- Get a self-closing stream
57 selfClosingStream() {
58 const selfClosing = stream.Writable({ write: (chunk, encoding, callback) => { callback(); } });
59 selfClosing.end('End self-closing stream');
60
61 return selfClosing;
62 }
63
64
65 //-- GraphicsMagick optimization
66 gmOptimization(gmfile, info) {
67 if (info.format === 'JPG') {
68 gmfile.noProfile().quality(95);
69 }
70
71 if (info.format === 'PNG' && info.depth === 8) {
72 gmfile.dither(false).colors(256);
73 }
74
75 return gmfile;
76 }
77
78
79 //-- Get human-readable filesize
80 filesize(file) {
81 return prettyBytes(fss.stat(file).size);
82 }
83
84
85 //-- Task logging
86 log(task, message, extra) {
87 log(`${task}: ${message} ${extra ? chalk.dim(`(${extra})`) : ''}`);
88 }
89
90
91 //-- Plumber
92 plumber() {
93 return plumber((error) => {
94 terminal.spacer(2);
95 terminal.echo(`${emoji.get('monkey')} ${error.toString()}`);
96 terminal.exit();
97 });
98 }
99
100
101 //-- Compare lists
102 compareLists(assertion, expectation) {
103 const superfluous = without(assertion, ...expectation);
104 const missing = without(expectation, ...assertion);
105
106 return {
107 pass: superfluous.length === 0 && missing.length === 0,
108 superfluous: superfluous,
109 missing: missing
110 };
111 }
112
113
114 //-- Flatten keys
115 flattenKeys(data, { depth = '' } = {}) {
116 return deepKeys(data, true).filter((key) => {
117 return new RegExp(`^[a-z0-9-]+(\\.[a-z0-9-]+){0,${depth}}$`, 'ui').test(key);
118 });
119 }
120
121
122 //-- Is kebab-case
123 isKebabCase(text) {
124 return (/^(?<kebab1>[a-z][a-z0-9]*)(?<kebab2>-[a-z0-9]+)*$/u).test(text);
125 }
126
127}
128
129
130module.exports = new Toolbox();