html-minifier-next 7.6.0 → 8.0.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/README.md +18 -21
- package/cli.js +152 -50
- package/dist/types/htmlminifier.d.ts +6 -4
- package/dist/types/htmlminifier.d.ts.map +1 -1
- package/dist/types/lib/attributes.d.ts +2 -2
- package/dist/types/lib/attributes.d.ts.map +1 -1
- package/dist/types/lib/constants.d.ts +2 -2
- package/dist/types/lib/constants.d.ts.map +1 -1
- package/dist/types/lib/fragments.d.ts +46 -0
- package/dist/types/lib/fragments.d.ts.map +1 -0
- package/dist/types/lib/option-definitions.d.ts +21 -198
- package/dist/types/lib/option-definitions.d.ts.map +1 -1
- package/dist/types/lib/options.d.ts +1 -1
- package/dist/types/lib/options.d.ts.map +1 -1
- package/dist/types/lib/unused-css.d.ts +5 -4
- package/dist/types/lib/unused-css.d.ts.map +1 -1
- package/dist/types/lib/utils.d.ts +18 -1
- package/dist/types/lib/utils.d.ts.map +1 -1
- package/dist/types/tokenchain.d.ts +2 -2
- package/dist/types/tokenchain.d.ts.map +1 -1
- package/html-minifier-next.schema.json +4 -5
- package/package.json +1 -1
- package/src/htmlminifier.js +49 -64
- package/src/htmlparser.js +4 -4
- package/src/lib/attributes.js +63 -6
- package/src/lib/constants.js +6 -8
- package/src/lib/fragments.js +274 -0
- package/src/lib/option-definitions.js +12 -4
- package/src/lib/options.js +25 -17
- package/src/lib/unused-css.js +5 -22
- package/src/lib/utils.js +308 -3
- package/src/tokenchain.js +37 -30
package/cli.js
CHANGED
|
@@ -36,7 +36,9 @@ import readline from 'readline';
|
|
|
36
36
|
import { Command, Option } from 'commander';
|
|
37
37
|
|
|
38
38
|
// Simple case conversion for CLI option names (ASCII-only, no Unicode needed)
|
|
39
|
+
/** @param {string} str */
|
|
39
40
|
const paramCase = (str) => str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
|
41
|
+
/** @param {string} str */
|
|
40
42
|
const camelCase = (str) => paramCase(str).replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
41
43
|
|
|
42
44
|
// Commander derives its internal option key by applying paramCase then camelCase to the flag name,
|
|
@@ -44,6 +46,7 @@ const camelCase = (str) => paramCase(str).replace(/-([a-z])/g, (_, c) => c.toUpp
|
|
|
44
46
|
// because option definition keys may differ from the result of that round-trip (e.g.,
|
|
45
47
|
// `minifyURLs` → Commander key `minifyUrls`, `noNewlinesBeforeTagClose` → `newlinesBeforeTagClose`),
|
|
46
48
|
// `commanderOptionKey` uses the same paramCase + camelCase path to compute the key Commander will use
|
|
49
|
+
/** @param {string} key */
|
|
47
50
|
const commanderOptionKey = (key) => {
|
|
48
51
|
const pc = paramCase(key);
|
|
49
52
|
return pc.startsWith('no-') ? camelCase(pc.slice(3)) : camelCase(pc);
|
|
@@ -67,13 +70,21 @@ const MARK_RESET = process.stderr.isTTY ? '\x1b[0m' : '';
|
|
|
67
70
|
const program = new Command();
|
|
68
71
|
program.name(pkg.name);
|
|
69
72
|
|
|
73
|
+
/**
|
|
74
|
+
* @param {string} message
|
|
75
|
+
* @returns {never}
|
|
76
|
+
*/
|
|
70
77
|
function fatal(message) {
|
|
71
78
|
console.error(`${MARK_ERROR}${message}${MARK_RESET}`);
|
|
72
79
|
process.exit(1);
|
|
73
80
|
}
|
|
74
81
|
|
|
82
|
+
// `catch` bindings are `unknown`, and throw values need not be `Error`s
|
|
83
|
+
/** @param {unknown} err */
|
|
84
|
+
const errorMessage = (err) => err instanceof Error ? err.message : String(err);
|
|
85
|
+
|
|
75
86
|
// Handle broken pipe (e.g., when piping to `head`)
|
|
76
|
-
process.stdout.on('error', (err) => {
|
|
87
|
+
process.stdout.on('error', (/** @type {NodeJS.ErrnoException} */ err) => {
|
|
77
88
|
if (err && err.code === 'EPIPE') {
|
|
78
89
|
process.exit(0);
|
|
79
90
|
}
|
|
@@ -99,6 +110,7 @@ process.stdout.on('error', (err) => {
|
|
|
99
110
|
* --customAttrSurround "[\"//matchString//\"]"
|
|
100
111
|
*/
|
|
101
112
|
|
|
113
|
+
/** @param {string} value */
|
|
102
114
|
function parseJSON(value) {
|
|
103
115
|
if (value) {
|
|
104
116
|
try {
|
|
@@ -112,21 +124,24 @@ function parseJSON(value) {
|
|
|
112
124
|
}
|
|
113
125
|
}
|
|
114
126
|
|
|
127
|
+
/** @param {string} value */
|
|
115
128
|
function parseJSONArray(value) {
|
|
116
|
-
if (value)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
129
|
+
if (!value) return undefined;
|
|
130
|
+
const parsed = parseJSON(value);
|
|
131
|
+
return Array.isArray(parsed) ? parsed : [parsed];
|
|
120
132
|
}
|
|
121
133
|
|
|
134
|
+
/** @param {string} value */
|
|
122
135
|
function parseJSONRegExpArray(value) {
|
|
123
|
-
|
|
124
|
-
return
|
|
136
|
+
const values = parseJSONArray(value);
|
|
137
|
+
return values && values.map(parseRegExp);
|
|
125
138
|
}
|
|
126
139
|
|
|
140
|
+
/** @param {string} value */
|
|
127
141
|
const parseString = value => value;
|
|
128
142
|
|
|
129
|
-
|
|
143
|
+
/** @param {string} optionName */
|
|
144
|
+
const parseValidInt = (optionName) => (/** @type {string} */ value) => {
|
|
130
145
|
const s = String(value).trim();
|
|
131
146
|
// Accept only non-negative whole integers
|
|
132
147
|
if (!/^\d+$/.test(s)) {
|
|
@@ -136,21 +151,34 @@ const parseValidInt = (optionName) => (value) => {
|
|
|
136
151
|
return num;
|
|
137
152
|
};
|
|
138
153
|
|
|
139
|
-
// Map option types to CLI parsers
|
|
154
|
+
// Map option types to CLI parsers—`int` is resolved by `getParser`, as its
|
|
155
|
+
// parser closes over the option name for error messages
|
|
156
|
+
/** @type {Record<string, (value: string) => any>} */
|
|
140
157
|
const typeParsers = {
|
|
141
158
|
regexp: parseRegExp,
|
|
142
159
|
regexpArray: parseJSONRegExpArray,
|
|
143
160
|
json: parseJSON,
|
|
144
161
|
jsonObject: parseJSON,
|
|
145
162
|
jsonArray: parseJSONArray,
|
|
146
|
-
string: parseString
|
|
147
|
-
int: (key) => parseValidInt(key)
|
|
163
|
+
string: parseString
|
|
148
164
|
};
|
|
149
165
|
|
|
166
|
+
/**
|
|
167
|
+
* @param {string} key Option definition key, for the `int` parser’s error messages
|
|
168
|
+
* @param {string} type Option definition type
|
|
169
|
+
* @returns {(value: string) => any}
|
|
170
|
+
*/
|
|
171
|
+
function getParser(key, type) {
|
|
172
|
+
const parser = type === 'int' ? parseValidInt(key) : typeParsers[type];
|
|
173
|
+
if (!parser) {
|
|
174
|
+
fatal(`No CLI parser for option \`${key}\` (type \`${type}\`)—add the type to \`typeParsers\` in cli.js`);
|
|
175
|
+
}
|
|
176
|
+
return parser;
|
|
177
|
+
}
|
|
178
|
+
|
|
150
179
|
// Configure command-line flags from shared option definitions
|
|
151
180
|
const mainOptionKeys = Object.keys(optionDefinitions);
|
|
152
|
-
|
|
153
|
-
const { description, descriptionAffirmative, type } = optionDefinitions[key];
|
|
181
|
+
Object.entries(optionDefinitions).forEach(function ([key, { description, descriptionAffirmative, type }]) {
|
|
154
182
|
const flag = paramCase(key);
|
|
155
183
|
if (type === 'invertedBoolean') {
|
|
156
184
|
// The positive form (to re-enable after a preset/config disables it) is hidden from
|
|
@@ -167,8 +195,7 @@ mainOptionKeys.forEach(function (key) {
|
|
|
167
195
|
}
|
|
168
196
|
} else {
|
|
169
197
|
const cliFlag = '--' + flag + (type === 'json' || type === 'jsonObject' ? ' [value]' : ' <value>');
|
|
170
|
-
|
|
171
|
-
program.option(cliFlag, description, parser);
|
|
198
|
+
program.option(cliFlag, description, getParser(key, type));
|
|
172
199
|
}
|
|
173
200
|
});
|
|
174
201
|
program.option('-i --input <file>', 'Specify input file (alternative to positional argument; pair with `--output` for output)');
|
|
@@ -178,6 +205,7 @@ program.option('-d --dry', 'Dry run: Process and report statistics without writi
|
|
|
178
205
|
program.addHelpText('after', '\nBoolean options support a `--no-<flag>` form to disable them, overriding a preset or config file (e.g., `--preset=comprehensive --no-collapse-whitespace`).');
|
|
179
206
|
|
|
180
207
|
// Lazy import wrapper for HMN
|
|
208
|
+
/** @type {Promise<typeof import('./src/htmlminifier.js').minify> | undefined} */
|
|
181
209
|
let minifyFnPromise;
|
|
182
210
|
async function getMinify() {
|
|
183
211
|
if (!minifyFnPromise) {
|
|
@@ -186,11 +214,12 @@ async function getMinify() {
|
|
|
186
214
|
return minifyFnPromise;
|
|
187
215
|
}
|
|
188
216
|
|
|
217
|
+
/** @param {string} file */
|
|
189
218
|
function readFile(file) {
|
|
190
219
|
try {
|
|
191
220
|
return fs.readFileSync(file, { encoding: 'utf8' });
|
|
192
221
|
} catch (err) {
|
|
193
|
-
fatal('Cannot read ' + file + '\n' + err
|
|
222
|
+
fatal('Cannot read ' + file + '\n' + errorMessage(err));
|
|
194
223
|
}
|
|
195
224
|
}
|
|
196
225
|
|
|
@@ -198,7 +227,7 @@ function readFile(file) {
|
|
|
198
227
|
* Load config from a file path. Extensions .json, .js, and .mjs are handled
|
|
199
228
|
* directly; for unknown extensions, JSON is tried first, then module import.
|
|
200
229
|
* @param {string} configPath - Path to config file
|
|
201
|
-
* @returns {Promise<
|
|
230
|
+
* @returns {Promise<Record<string, any>>} Loaded config object
|
|
202
231
|
*/
|
|
203
232
|
async function loadConfigFromPath(configPath) {
|
|
204
233
|
const abs = path.resolve(configPath);
|
|
@@ -206,24 +235,25 @@ async function loadConfigFromPath(configPath) {
|
|
|
206
235
|
|
|
207
236
|
if (ext === '.json') {
|
|
208
237
|
try { return JSON.parse(readFile(abs).replace(/^\uFEFF/, '')); }
|
|
209
|
-
catch (err) { fatal(`Cannot parse config file as JSON: ${err
|
|
238
|
+
catch (err) { fatal(`Cannot parse config file as JSON: ${errorMessage(err)}`); }
|
|
210
239
|
}
|
|
211
240
|
|
|
212
241
|
if (ext === '.js' || ext === '.mjs') {
|
|
213
242
|
// `import()` handles both ESM and CJS .js files—Node resolves the type via the
|
|
214
243
|
// nearest package.json `type` field, same as it does for regular module loading
|
|
215
244
|
try { const mod = await import(pathToFileURL(abs).href); return 'default' in mod ? mod.default : mod; }
|
|
216
|
-
catch (err) { fatal(`Cannot load config file: ${err
|
|
245
|
+
catch (err) { fatal(`Cannot load config file: ${errorMessage(err)}`); }
|
|
217
246
|
}
|
|
218
247
|
|
|
219
248
|
// Unknown extension: Try JSON, then module import
|
|
249
|
+
/** @type {unknown} */
|
|
220
250
|
let jsonErr;
|
|
221
251
|
try { return JSON.parse(readFile(abs).replace(/^\uFEFF/, '')); }
|
|
222
252
|
catch (err) { jsonErr = err; }
|
|
223
253
|
|
|
224
254
|
try { const mod = await import(pathToFileURL(abs).href); return 'default' in mod ? mod.default : mod; }
|
|
225
255
|
catch (esmErr) {
|
|
226
|
-
fatal(`Cannot read the specified config file.\nAs JSON: ${jsonErr
|
|
256
|
+
fatal(`Cannot read the specified config file.\nAs JSON: ${errorMessage(jsonErr)}\nAs module: ${errorMessage(esmErr)}`);
|
|
227
257
|
}
|
|
228
258
|
}
|
|
229
259
|
|
|
@@ -236,10 +266,11 @@ const CONFIG_FILES_DEFAULT = ['html-minifier-next.config.json', 'htmlminifier.co
|
|
|
236
266
|
|
|
237
267
|
/**
|
|
238
268
|
* Normalize and validate config object by applying parsers and transforming values.
|
|
239
|
-
* @param {
|
|
240
|
-
* @returns {
|
|
269
|
+
* @param {Record<string, any>} config - Raw config object
|
|
270
|
+
* @returns {Record<string, any>} Normalized config object
|
|
241
271
|
*/
|
|
242
272
|
function normalizeConfig(config) {
|
|
273
|
+
/** @type {Record<string, any>} */
|
|
243
274
|
const normalized = { ...config };
|
|
244
275
|
|
|
245
276
|
// Warn about unrecognized config keys—catches typos as well as options removed in earlier versions
|
|
@@ -250,13 +281,11 @@ function normalizeConfig(config) {
|
|
|
250
281
|
});
|
|
251
282
|
|
|
252
283
|
// Apply parsers to main options
|
|
253
|
-
|
|
284
|
+
Object.entries(optionDefinitions).forEach(function ([key, { type }]) {
|
|
254
285
|
if (key in normalized) {
|
|
255
|
-
const { type } = optionDefinitions[key];
|
|
256
286
|
if (type !== 'boolean' && type !== 'invertedBoolean') {
|
|
257
|
-
const parser = type === 'int' ? typeParsers.int(key) : typeParsers[type];
|
|
258
287
|
const value = normalized[key];
|
|
259
|
-
normalized[key] =
|
|
288
|
+
normalized[key] = getParser(key, type)(typeof value === 'string' ? value : JSON.stringify(value));
|
|
260
289
|
}
|
|
261
290
|
}
|
|
262
291
|
});
|
|
@@ -280,6 +309,7 @@ function normalizeConfig(config) {
|
|
|
280
309
|
return normalized;
|
|
281
310
|
}
|
|
282
311
|
|
|
312
|
+
/** @type {Record<string, any>} */
|
|
283
313
|
let config = {};
|
|
284
314
|
program.option('-z, --zero', 'Minify all HTML files in the current folder and its subfolders in place (except node_modules), using comprehensive settings (standalone—flag is ignored when combined with other options)');
|
|
285
315
|
program.option('-I --input-dir <dir>', 'Specify an input directory');
|
|
@@ -291,9 +321,17 @@ program.option('-c --config-file <file>', 'Use config file');
|
|
|
291
321
|
program.version(pkg.version, '-V, --version', 'Output the version number');
|
|
292
322
|
program.helpOption('-h, --help', 'Display help for command');
|
|
293
323
|
|
|
324
|
+
/**
|
|
325
|
+
* Progress state shared between the file walk and the indicator; `total` stays
|
|
326
|
+
* `null` until the background count finishes
|
|
327
|
+
* @typedef {{current: number, total: number | null}} Progress
|
|
328
|
+
*/
|
|
329
|
+
|
|
294
330
|
(async () => {
|
|
331
|
+
/** @type {string} */
|
|
295
332
|
let content;
|
|
296
333
|
let filesProvided = false;
|
|
334
|
+
/** @type {string[]} */
|
|
297
335
|
let capturedFiles = [];
|
|
298
336
|
await program.arguments('[files...]').action(function (files) {
|
|
299
337
|
capturedFiles = files;
|
|
@@ -329,11 +367,12 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
329
367
|
console.error('Note: `--zero` was ignored—it can only be used on its own, to minify the current folder at comprehensive settings.');
|
|
330
368
|
} else {
|
|
331
369
|
const cwd = process.cwd();
|
|
370
|
+
const [execPath = '', scriptPath = ''] = process.argv;
|
|
332
371
|
const commandName = process.env.npm_command === 'exec'
|
|
333
372
|
? 'npx html-minifier-next'
|
|
334
|
-
:
|
|
335
|
-
? `${path.basename(
|
|
336
|
-
: path.basename(
|
|
373
|
+
: scriptPath.endsWith('.js')
|
|
374
|
+
? `${path.basename(execPath)} ${scriptPath}`
|
|
375
|
+
: path.basename(scriptPath);
|
|
337
376
|
|
|
338
377
|
process.stderr.write(
|
|
339
378
|
`${MARK_WARNING}Zero-config mode minifies all HTML files in the current folder and its subfolders (${cwd}) in place, using comprehensive settings. If you want to compare results and be able to revert, do this under version control.${MARK_RESET}\n` +
|
|
@@ -342,7 +381,7 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
342
381
|
);
|
|
343
382
|
|
|
344
383
|
const answer = await new Promise((resolve) => {
|
|
345
|
-
const rl = readline.createInterface({ input: process.stdin
|
|
384
|
+
const rl = readline.createInterface({ input: process.stdin });
|
|
346
385
|
rl.once('line', (line) => {
|
|
347
386
|
resolve(line.trim().toLowerCase());
|
|
348
387
|
rl.close();
|
|
@@ -363,6 +402,7 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
363
402
|
const ignorePatterns = ['node_modules'];
|
|
364
403
|
|
|
365
404
|
const showProgress = process.stderr.isTTY;
|
|
405
|
+
/** @type {Progress | null} */
|
|
366
406
|
let progress = null;
|
|
367
407
|
if (showProgress) {
|
|
368
408
|
progress = { current: 0, total: null };
|
|
@@ -406,6 +446,7 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
406
446
|
}
|
|
407
447
|
|
|
408
448
|
function createOptions() {
|
|
449
|
+
/** @type {Record<string, any>} */
|
|
409
450
|
const options = {};
|
|
410
451
|
|
|
411
452
|
// Priority order: preset < config < CLI
|
|
@@ -427,8 +468,7 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
427
468
|
});
|
|
428
469
|
|
|
429
470
|
// 3. Apply CLI options (overrides config and preset)
|
|
430
|
-
|
|
431
|
-
const { type } = optionDefinitions[key];
|
|
471
|
+
Object.entries(optionDefinitions).forEach(function ([key, { type }]) {
|
|
432
472
|
const ck = commanderOptionKey(key);
|
|
433
473
|
if (program.getOptionValueSource(ck) === 'cli') {
|
|
434
474
|
const val = programOptions[ck];
|
|
@@ -441,7 +481,7 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
441
481
|
|
|
442
482
|
// 4. Surface minifier diagnostics when verbose
|
|
443
483
|
if (programOptions.verbose || programOptions.dry) {
|
|
444
|
-
options.log = message => {
|
|
484
|
+
options.log = (/** @type {unknown} */ message) => {
|
|
445
485
|
// The hook carries the minifier’s per-call timing as well, which the run's own
|
|
446
486
|
// per-file statistics already cover
|
|
447
487
|
if (typeof message === 'string' && message.startsWith('minified in: ')) {
|
|
@@ -462,6 +502,7 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
462
502
|
return options;
|
|
463
503
|
}
|
|
464
504
|
|
|
505
|
+
/** @param {Record<string, unknown>} minifierOptions */
|
|
465
506
|
function getActiveOptionsDisplay(minifierOptions) {
|
|
466
507
|
const presetName = programOptions.preset || config.preset;
|
|
467
508
|
if (presetName) {
|
|
@@ -475,6 +516,10 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
475
516
|
}
|
|
476
517
|
}
|
|
477
518
|
|
|
519
|
+
/**
|
|
520
|
+
* @param {string} original
|
|
521
|
+
* @param {string} minified
|
|
522
|
+
*/
|
|
478
523
|
function calculateStats(original, minified) {
|
|
479
524
|
const originalSize = Buffer.byteLength(original, 'utf8');
|
|
480
525
|
const minifiedSize = Buffer.byteLength(minified, 'utf8');
|
|
@@ -489,24 +534,31 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
489
534
|
async function printCacheStats() {
|
|
490
535
|
const { getCacheStats } = await import('./src/htmlminifier.js');
|
|
491
536
|
const cacheStats = getCacheStats();
|
|
537
|
+
/** @type {Record<string, string>} */
|
|
492
538
|
const labels = { css: 'CSS', js: 'JS', svg: 'SVG' };
|
|
493
539
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
540
|
+
/** @type {string[]} */
|
|
541
|
+
const lines = [];
|
|
542
|
+
for (const [key, { gets, hits, size, limit }] of Object.entries(cacheStats)) {
|
|
543
|
+
if (gets === 0) continue;
|
|
497
544
|
const misses = gets - hits;
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
}, []);
|
|
545
|
+
lines.push(` ${labels[key]} cache: ${hits.toLocaleString()} hit${hits === 1 ? '' : 's'}, ${misses.toLocaleString()} miss${misses === 1 ? '' : 'es'}, ${size.toLocaleString()}/${limit.toLocaleString()} entries`);
|
|
546
|
+
}
|
|
501
547
|
|
|
502
548
|
if (lines.length === 0) return;
|
|
503
549
|
console.error('Cache stats:');
|
|
504
550
|
lines.forEach(line => console.error(line));
|
|
505
551
|
}
|
|
506
552
|
|
|
553
|
+
/**
|
|
554
|
+
* @param {string} inputFile
|
|
555
|
+
* @param {string} outputFile
|
|
556
|
+
* @param {boolean} [isDryRun]
|
|
557
|
+
* @param {boolean} [isVerbose]
|
|
558
|
+
*/
|
|
507
559
|
async function processFile(inputFile, outputFile, isDryRun = false, isVerbose = false) {
|
|
508
560
|
const data = await fs.promises.readFile(inputFile, { encoding: 'utf8' }).catch(err => {
|
|
509
|
-
fatal('Cannot read ' + inputFile + '\n' + err
|
|
561
|
+
fatal('Cannot read ' + inputFile + '\n' + errorMessage(err));
|
|
510
562
|
});
|
|
511
563
|
|
|
512
564
|
let minified;
|
|
@@ -514,7 +566,7 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
514
566
|
const minify = await getMinify();
|
|
515
567
|
minified = await minify(data, createOptions());
|
|
516
568
|
} catch (err) {
|
|
517
|
-
fatal('Minification error on ' + inputFile + '\n' + err
|
|
569
|
+
fatal('Minification error on ' + inputFile + '\n' + errorMessage(err));
|
|
518
570
|
}
|
|
519
571
|
|
|
520
572
|
const stats = calculateStats(data, minified);
|
|
@@ -535,6 +587,10 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
535
587
|
return { originalSize: stats.originalSize, minifiedSize: stats.minifiedSize, saved: stats.saved };
|
|
536
588
|
}
|
|
537
589
|
|
|
590
|
+
/**
|
|
591
|
+
* @param {string} fileExt
|
|
592
|
+
* @returns {string[]}
|
|
593
|
+
*/
|
|
538
594
|
function parseFileExtensions(fileExt) {
|
|
539
595
|
if (!fileExt) return [];
|
|
540
596
|
if (fileExt.trim() === '*') return ['*'];
|
|
@@ -545,6 +601,10 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
545
601
|
return [...new Set(list)];
|
|
546
602
|
}
|
|
547
603
|
|
|
604
|
+
/**
|
|
605
|
+
* @param {string} filename
|
|
606
|
+
* @param {string[]} fileExtensions
|
|
607
|
+
*/
|
|
548
608
|
function shouldProcessFile(filename, fileExtensions) {
|
|
549
609
|
// Wildcard: process all files
|
|
550
610
|
if (fileExtensions.includes('*')) {
|
|
@@ -589,6 +649,14 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
589
649
|
});
|
|
590
650
|
}
|
|
591
651
|
|
|
652
|
+
/**
|
|
653
|
+
* @param {string} dir
|
|
654
|
+
* @param {string[]} extensions
|
|
655
|
+
* @param {string | undefined} skipRootAbs
|
|
656
|
+
* @param {string[]} ignorePatterns
|
|
657
|
+
* @param {string} baseDir
|
|
658
|
+
* @returns {Promise<number>}
|
|
659
|
+
*/
|
|
592
660
|
async function countFiles(dir, extensions, skipRootAbs, ignorePatterns, baseDir) {
|
|
593
661
|
let count = 0;
|
|
594
662
|
|
|
@@ -624,6 +692,10 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
624
692
|
return count;
|
|
625
693
|
}
|
|
626
694
|
|
|
695
|
+
/**
|
|
696
|
+
* @param {number} current
|
|
697
|
+
* @param {number | null} total
|
|
698
|
+
*/
|
|
627
699
|
function updateProgress(current, total) {
|
|
628
700
|
// Clear the line first, then write simple progress
|
|
629
701
|
process.stderr.write(`\r\x1b[K`);
|
|
@@ -642,7 +714,15 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
642
714
|
}
|
|
643
715
|
|
|
644
716
|
// Utility: concurrency runner
|
|
717
|
+
/**
|
|
718
|
+
* @template T, R
|
|
719
|
+
* @param {T[]} items
|
|
720
|
+
* @param {number} limit
|
|
721
|
+
* @param {(item: T, index: number) => Promise<R>} worker
|
|
722
|
+
* @returns {Promise<R[]>}
|
|
723
|
+
*/
|
|
645
724
|
async function runWithConcurrency(items, limit, worker) {
|
|
725
|
+
/** @type {R[]} */
|
|
646
726
|
const results = new Array(items.length);
|
|
647
727
|
let next = 0;
|
|
648
728
|
let active = 0;
|
|
@@ -650,8 +730,9 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
650
730
|
const launch = () => {
|
|
651
731
|
while (active < limit && next < items.length) {
|
|
652
732
|
const current = next++;
|
|
733
|
+
const item = /** @type {T} */ (items[current]);
|
|
653
734
|
active++;
|
|
654
|
-
Promise.resolve(worker(
|
|
735
|
+
Promise.resolve(worker(item, current))
|
|
655
736
|
.then((res) => {
|
|
656
737
|
results[current] = res;
|
|
657
738
|
active--;
|
|
@@ -667,7 +748,16 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
667
748
|
});
|
|
668
749
|
}
|
|
669
750
|
|
|
751
|
+
/**
|
|
752
|
+
* @param {string} dir
|
|
753
|
+
* @param {string[]} extensions
|
|
754
|
+
* @param {string | undefined} skipRootAbs
|
|
755
|
+
* @param {string[]} ignorePatterns
|
|
756
|
+
* @param {string} baseDir
|
|
757
|
+
* @returns {Promise<string[]>}
|
|
758
|
+
*/
|
|
670
759
|
async function collectFiles(dir, extensions, skipRootAbs, ignorePatterns, baseDir) {
|
|
760
|
+
/** @type {string[]} */
|
|
671
761
|
const out = [];
|
|
672
762
|
const entries = await fs.promises.readdir(dir).catch(() => []);
|
|
673
763
|
for (const name of entries) {
|
|
@@ -689,6 +779,17 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
689
779
|
return out;
|
|
690
780
|
}
|
|
691
781
|
|
|
782
|
+
/**
|
|
783
|
+
* @param {string} inputDir
|
|
784
|
+
* @param {string} outputDir
|
|
785
|
+
* @param {string | string[]} extensions
|
|
786
|
+
* @param {boolean} [isDryRun]
|
|
787
|
+
* @param {boolean} [isVerbose]
|
|
788
|
+
* @param {string} [skipRootAbs]
|
|
789
|
+
* @param {Progress | null} [progress]
|
|
790
|
+
* @param {string[]} [ignorePatterns]
|
|
791
|
+
* @param {string | null} [baseDir]
|
|
792
|
+
*/
|
|
692
793
|
async function processDirectory(inputDir, outputDir, extensions, isDryRun = false, isVerbose = false, skipRootAbs, progress = null, ignorePatterns = [], baseDir = null) {
|
|
693
794
|
// If first call provided a string, normalize once; otherwise assume pre-parsed array
|
|
694
795
|
if (typeof extensions === 'string') {
|
|
@@ -710,7 +811,7 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
710
811
|
const outDir = path.dirname(outFile);
|
|
711
812
|
if (!isDryRun) {
|
|
712
813
|
await fs.promises.mkdir(outDir, { recursive: true }).catch(err => {
|
|
713
|
-
fatal('Cannot create directory ' + outDir + '\n' + err
|
|
814
|
+
fatal('Cannot create directory ' + outDir + '\n' + errorMessage(err));
|
|
714
815
|
});
|
|
715
816
|
}
|
|
716
817
|
const stats = await processFile(inputFile, outFile, isDryRun, isVerbose);
|
|
@@ -737,7 +838,7 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
737
838
|
const minify = await getMinify();
|
|
738
839
|
minified = await minify(content, minifierOptions);
|
|
739
840
|
} catch (err) {
|
|
740
|
-
fatal('Minification error:\n' + err
|
|
841
|
+
fatal('Minification error:\n' + errorMessage(err));
|
|
741
842
|
}
|
|
742
843
|
|
|
743
844
|
const stats = calculateStats(content, minified);
|
|
@@ -766,7 +867,7 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
766
867
|
await fs.promises.mkdir(path.dirname(programOptions.output), { recursive: true });
|
|
767
868
|
await fs.promises.writeFile(programOptions.output, minified, { encoding: 'utf8' });
|
|
768
869
|
} catch (err) {
|
|
769
|
-
fatal('Cannot write ' + programOptions.output + '\n' + err
|
|
870
|
+
fatal('Cannot write ' + programOptions.output + '\n' + errorMessage(err));
|
|
770
871
|
}
|
|
771
872
|
return;
|
|
772
873
|
}
|
|
@@ -831,6 +932,7 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
831
932
|
|
|
832
933
|
// Set up progress indicator (only in TTY and when not verbose/dry)
|
|
833
934
|
const showProgress = process.stderr.isTTY && !isVerbose;
|
|
935
|
+
/** @type {Progress | null} */
|
|
834
936
|
let progress = null;
|
|
835
937
|
|
|
836
938
|
// Parse ignore patterns
|
|
@@ -843,7 +945,7 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
843
945
|
fatal(`${inputDir} is not a directory—to minify a single file, use \`--input\`/\`--output\`: html-minifier-next [options] -i ${inputDir} -o <output-file>`);
|
|
844
946
|
}
|
|
845
947
|
} catch (err) {
|
|
846
|
-
fatal('Cannot read directory ' + inputDir + '\n' + err
|
|
948
|
+
fatal('Cannot read directory ' + inputDir + '\n' + errorMessage(err));
|
|
847
949
|
}
|
|
848
950
|
|
|
849
951
|
// Resolve base directory for consistent path comparisons
|
|
@@ -914,13 +1016,13 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
914
1016
|
const outputs = new Array(inputs.length);
|
|
915
1017
|
|
|
916
1018
|
await runWithConcurrency(inputs, concurrency, async (file, idx) => {
|
|
917
|
-
const data = await fs.promises.readFile(file, 'utf8').catch(err => fatal('Cannot read ' + file + '\n' + err
|
|
1019
|
+
const data = await fs.promises.readFile(file, 'utf8').catch(err => fatal('Cannot read ' + file + '\n' + errorMessage(err)));
|
|
918
1020
|
const minify = await getMinify();
|
|
919
1021
|
let out;
|
|
920
1022
|
try {
|
|
921
1023
|
out = await minify(data, minifierOptions);
|
|
922
1024
|
} catch (err) {
|
|
923
|
-
fatal('Minification error on ' + file + '\n' + err
|
|
1025
|
+
fatal('Minification error on ' + file + '\n' + errorMessage(err));
|
|
924
1026
|
}
|
|
925
1027
|
originals[idx] = data;
|
|
926
1028
|
outputs[idx] = out;
|
|
@@ -953,7 +1055,7 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
953
1055
|
await fs.promises.mkdir(path.dirname(programOptions.output), { recursive: true });
|
|
954
1056
|
await fs.promises.writeFile(programOptions.output, minifiedCombined, 'utf8');
|
|
955
1057
|
} catch (err) {
|
|
956
|
-
fatal('Cannot write ' + programOptions.output + '\n' + err
|
|
1058
|
+
fatal('Cannot write ' + programOptions.output + '\n' + errorMessage(err));
|
|
957
1059
|
}
|
|
958
1060
|
} else {
|
|
959
1061
|
process.stdout.write(minifiedCombined);
|
|
@@ -962,7 +1064,7 @@ program.helpOption('-h, --help', 'Display help for command');
|
|
|
962
1064
|
} else { // Minifying input coming from STDIN
|
|
963
1065
|
content = '';
|
|
964
1066
|
process.stdin.setEncoding('utf8');
|
|
965
|
-
process.stdin.on('data', function (data) {
|
|
1067
|
+
process.stdin.on('data', function (/** @type {string} */ data) {
|
|
966
1068
|
content += data;
|
|
967
1069
|
}).on('end', async function() {
|
|
968
1070
|
await writeMinify();
|
|
@@ -144,12 +144,14 @@ export type MinifierOptions = {
|
|
|
144
144
|
*/
|
|
145
145
|
customEventAttributes?: RegExp[];
|
|
146
146
|
/**
|
|
147
|
-
*
|
|
148
|
-
*
|
|
147
|
+
* Rejects `ignoreCustomFragments` patterns that risk catastrophic backtracking,
|
|
148
|
+
* rather than warning about them: those that compound quantifiers or alternation
|
|
149
|
+
* (`(a+)+`, `(a|b)*`), those that repeat the same unbounded atom twice in a row
|
|
150
|
+
* (`.*.*`), and those too long or too deeply nested to analyze at all.
|
|
149
151
|
*
|
|
150
|
-
* Default: `
|
|
152
|
+
* Default: `false`
|
|
151
153
|
*/
|
|
152
|
-
|
|
154
|
+
strictCustomFragments?: boolean;
|
|
153
155
|
/**
|
|
154
156
|
* When true, decodes HTML entities in text and attributes before
|
|
155
157
|
* processing, and re-encodes ambiguous ampersands when outputting.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"htmlminifier.d.ts","sourceRoot":"","sources":["../../src/htmlminifier.js"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"htmlminifier.d.ts","sourceRoot":"","sources":["../../src/htmlminifier.js"],"names":[],"mappings":"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"}
|
|
@@ -119,7 +119,7 @@ declare function hasAttrName(name: string, attrs: HTMLAttribute[]): boolean;
|
|
|
119
119
|
* @param {HTMLAttribute[]} attrs
|
|
120
120
|
* @param {Function} minifyHTMLSelf
|
|
121
121
|
*/
|
|
122
|
-
declare function cleanAttributeValue(tag: string, attrName: string, attrValue: string, options: ProcessedOptions, attrs: HTMLAttribute[], minifyHTMLSelf: Function):
|
|
122
|
+
declare function cleanAttributeValue(tag: string, attrName: string, attrValue: string, options: ProcessedOptions, attrs: HTMLAttribute[], minifyHTMLSelf: Function): string | Promise<string>;
|
|
123
123
|
/**
|
|
124
124
|
* @param {HTMLAttribute} attr
|
|
125
125
|
* @param {HTMLAttribute[]} attrs
|
|
@@ -127,7 +127,7 @@ declare function cleanAttributeValue(tag: string, attrName: string, attrValue: s
|
|
|
127
127
|
* @param {ProcessedOptions} options
|
|
128
128
|
* @param {Function} minifyHTML
|
|
129
129
|
*/
|
|
130
|
-
declare function normalizeAttr(attr: HTMLAttribute, attrs: HTMLAttribute[], tag: string, options: ProcessedOptions, minifyHTML: Function):
|
|
130
|
+
declare function normalizeAttr(attr: HTMLAttribute, attrs: HTMLAttribute[], tag: string, options: ProcessedOptions, minifyHTML: Function): Promise<{
|
|
131
131
|
attr: HTMLAttribute;
|
|
132
132
|
name: string;
|
|
133
133
|
value: string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../../src/lib/attributes.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../../src/lib/attributes.js"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,7 @@ declare const RE_ATTR_WS_CHECK: RegExp;
|
|
|
15
15
|
declare const RE_ATTR_WS_COLLAPSE: RegExp;
|
|
16
16
|
declare const RE_ATTR_WS_TRIM: RegExp;
|
|
17
17
|
declare const RE_STYLE_ELEMENT: RegExp;
|
|
18
|
+
declare const RE_EMPTY_ATTRIBUTE: RegExp;
|
|
18
19
|
declare const inlineElementsToKeepWhitespaceAround: Set<string>;
|
|
19
20
|
declare const inlineElementsToKeepWhitespaceWithin: Set<string>;
|
|
20
21
|
declare const inlineElementsToKeepWhitespace: Set<string>;
|
|
@@ -93,7 +94,6 @@ declare const compactElements: Set<string>;
|
|
|
93
94
|
declare const looseElements: Set<string>;
|
|
94
95
|
declare const trailingElements: Set<string>;
|
|
95
96
|
declare const htmlElements: Set<string>;
|
|
96
|
-
declare const reEmptyAttribute: RegExp;
|
|
97
97
|
declare const specialContentElements: Set<string>;
|
|
98
|
-
export { RE_WS_START, RE_WS_END, RE_ALL_WS_NBSP, RE_NBSP_LEADING_GROUP, RE_NBSP_LEAD_GROUP, RE_NBSP_TRAILING_GROUP, RE_NBSP_TRAILING_STRIP, RE_EVENT_ATTR_DEFAULT, RE_CAN_REMOVE_ATTR_QUOTES, RE_TRAILING_SEMICOLON, RE_AMP_ENTITY, RE_LEGACY_ENTITIES, RE_ESCAPE_LT, RE_ATTR_WS_CHECK, RE_ATTR_WS_COLLAPSE, RE_ATTR_WS_TRIM, RE_STYLE_ELEMENT, inlineElementsToKeepWhitespaceAround, inlineElementsToKeepWhitespaceWithin, inlineElementsToKeepWhitespace, formControlElements, generalDefaults, tagDefaults, executableScriptsMimetypes, keepScriptsMimetypes, jsonScriptTypes, isSimpleBoolean, isBooleanValue, collapsibleValues, srcsetElements, optionalStartTags, optionalEndTags, headerElements, descriptionElements, pBlockElements, pInlineElements, rubyEndTagOmission, rubyRtcEndTagOmission, optionElements, tableContentElements, tableSectionElements, cellElements, topLevelElements, compactElements, looseElements, trailingElements, htmlElements,
|
|
98
|
+
export { RE_WS_START, RE_WS_END, RE_ALL_WS_NBSP, RE_NBSP_LEADING_GROUP, RE_NBSP_LEAD_GROUP, RE_NBSP_TRAILING_GROUP, RE_NBSP_TRAILING_STRIP, RE_EVENT_ATTR_DEFAULT, RE_CAN_REMOVE_ATTR_QUOTES, RE_TRAILING_SEMICOLON, RE_AMP_ENTITY, RE_LEGACY_ENTITIES, RE_ESCAPE_LT, RE_ATTR_WS_CHECK, RE_ATTR_WS_COLLAPSE, RE_ATTR_WS_TRIM, RE_STYLE_ELEMENT, RE_EMPTY_ATTRIBUTE, inlineElementsToKeepWhitespaceAround, inlineElementsToKeepWhitespaceWithin, inlineElementsToKeepWhitespace, formControlElements, generalDefaults, tagDefaults, executableScriptsMimetypes, keepScriptsMimetypes, jsonScriptTypes, isSimpleBoolean, isBooleanValue, collapsibleValues, srcsetElements, optionalStartTags, optionalEndTags, headerElements, descriptionElements, pBlockElements, pInlineElements, rubyEndTagOmission, rubyRtcEndTagOmission, optionElements, tableContentElements, tableSectionElements, cellElements, topLevelElements, compactElements, looseElements, trailingElements, htmlElements, specialContentElements };
|
|
99
99
|
//# sourceMappingURL=constants.d.ts.map
|