html-minifier-next 7.6.0 → 8.1.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/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
- value = parseJSON(value);
118
- return Array.isArray(value) ? value : [value];
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
- value = parseJSONArray(value);
124
- return value && value.map(parseRegExp);
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
- const parseValidInt = (optionName) => (value) => {
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
- mainOptionKeys.forEach(function (key) {
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
- const parser = type === 'int' ? typeParsers.int(key) : typeParsers[type];
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.message);
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<object>} Loaded config object
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.message}`); }
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.message}`); }
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.message}\nAs module: ${esmErr.message}`);
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 {object} config - Raw config object
240
- * @returns {object} Normalized config object
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
- mainOptionKeys.forEach(function (key) {
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] = parser(typeof value === 'string' ? value : JSON.stringify(value));
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
- : process.argv[1].endsWith('.js')
335
- ? `${path.basename(process.argv[0])} ${process.argv[1]}`
336
- : path.basename(process.argv[1]);
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, output: null });
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
- mainOptionKeys.forEach(function (key) {
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
- const lines = Object.keys(labels).reduce((acc, key) => {
495
- const { gets, hits, size, limit } = cacheStats[key];
496
- if (gets === 0) return acc;
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
- acc.push(` ${labels[key]} cache: ${hits.toLocaleString()} hit${hits === 1 ? '' : 's'}, ${misses.toLocaleString()} miss${misses === 1 ? '' : 'es'}, ${size.toLocaleString()}/${limit.toLocaleString()} entries`);
499
- return acc;
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.message);
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.message);
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(items[current], current))
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.message);
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.message);
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.message);
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.message);
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.message));
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.message);
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.message);
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
- * Limits the quantifier used when building a safe regex for custom
148
- * fragments to avoid ReDoS. See source use for details.
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: `200`
152
+ * Default: `false`
151
153
  */
152
- customFragmentQuantifierLimit?: number;
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":"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"}
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): any;
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): PromiseLike<{
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":"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"}
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, reEmptyAttribute, specialContentElements };
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