html-minifier-next 7.1.0 → 7.3.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.
Files changed (35) hide show
  1. package/README.md +59 -22
  2. package/cli.js +29 -4
  3. package/dist/types/htmlminifier.d.ts +77 -20
  4. package/dist/types/htmlminifier.d.ts.map +1 -1
  5. package/dist/types/htmlparser.d.ts +11 -11
  6. package/dist/types/htmlparser.d.ts.map +1 -1
  7. package/dist/types/lib/attributes.d.ts +36 -38
  8. package/dist/types/lib/attributes.d.ts.map +1 -1
  9. package/dist/types/lib/constants.d.ts +97 -100
  10. package/dist/types/lib/constants.d.ts.map +1 -1
  11. package/dist/types/lib/content.d.ts +7 -6
  12. package/dist/types/lib/content.d.ts.map +1 -1
  13. package/dist/types/lib/elements.d.ts +13 -18
  14. package/dist/types/lib/elements.d.ts.map +1 -1
  15. package/dist/types/lib/option-definitions.d.ts +202 -281
  16. package/dist/types/lib/option-definitions.d.ts.map +1 -1
  17. package/dist/types/lib/options.d.ts +7 -14
  18. package/dist/types/lib/options.d.ts.map +1 -1
  19. package/dist/types/lib/urls.d.ts +10 -2
  20. package/dist/types/lib/urls.d.ts.map +1 -1
  21. package/dist/types/lib/utils.d.ts +30 -10
  22. package/dist/types/lib/utils.d.ts.map +1 -1
  23. package/dist/types/lib/whitespace.d.ts +7 -6
  24. package/dist/types/lib/whitespace.d.ts.map +1 -1
  25. package/dist/types/presets.d.ts +39 -37
  26. package/dist/types/presets.d.ts.map +1 -1
  27. package/dist/types/tokenchain.d.ts +13 -11
  28. package/dist/types/tokenchain.d.ts.map +1 -1
  29. package/html-minifier-next.schema.json +303 -0
  30. package/package.json +8 -6
  31. package/src/htmlminifier.js +34 -1
  32. package/src/lib/option-definitions.js +12 -0
  33. package/src/lib/options.js +44 -32
  34. package/src/lib/urls.js +1 -1
  35. package/src/lib/utils.js +14 -0
@@ -1,7 +1,7 @@
1
1
  /** @param {string} str */
2
- export function trimWhitespace(str: string): string;
2
+ declare const trimWhitespace: (str: string) => string;
3
3
  /** @param {string} str */
4
- export function collapseWhitespaceAll(str: string): string;
4
+ declare function collapseWhitespaceAll(str: string): string;
5
5
  /**
6
6
  * @param {string} str
7
7
  * @param {{preserveLineBreaks?: boolean | undefined, conservativeCollapse?: boolean | undefined}} options
@@ -9,7 +9,7 @@ export function collapseWhitespaceAll(str: string): string;
9
9
  * @param {boolean} trimRight
10
10
  * @param {boolean} [collapseAll]
11
11
  */
12
- export function collapseWhitespace(str: string, options: {
12
+ declare function collapseWhitespace(str: string, options: {
13
13
  preserveLineBreaks?: boolean | undefined;
14
14
  conservativeCollapse?: boolean | undefined;
15
15
  }, trimLeft: boolean, trimRight: boolean, collapseAll?: boolean): string;
@@ -23,7 +23,7 @@ export function collapseWhitespace(str: string, options: {
23
23
  * @param {Set<string>} inlineElements
24
24
  * @param {Set<string>} inlineTextSet
25
25
  */
26
- export function collapseWhitespaceSmart(str: string, prevTag: string, nextTag: string, prevAttrs: Array<{
26
+ declare function collapseWhitespaceSmart(str: string, prevTag: string, nextTag: string, prevAttrs: Array<{
27
27
  name: string;
28
28
  value?: string;
29
29
  }>, nextAttrs: Array<{
@@ -35,7 +35,8 @@ export function collapseWhitespaceSmart(str: string, prevTag: string, nextTag: s
35
35
  collapseInlineTagWhitespace?: boolean;
36
36
  }, inlineElements: Set<string>, inlineTextSet: Set<string>): string;
37
37
  /** @param {string} tag */
38
- export function canCollapseWhitespace(tag: string): boolean;
38
+ declare function canCollapseWhitespace(tag: string): boolean;
39
39
  /** @param {string} tag */
40
- export function canTrimWhitespace(tag: string): boolean;
40
+ declare function canTrimWhitespace(tag: string): boolean;
41
+ export { trimWhitespace, collapseWhitespaceAll, collapseWhitespace, collapseWhitespaceSmart, canCollapseWhitespace, canTrimWhitespace };
41
42
  //# sourceMappingURL=whitespace.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"whitespace.d.ts","sourceRoot":"","sources":["../../../src/lib/whitespace.js"],"names":[],"mappings":"AAeA,0BAA0B;AAC1B,oCADY,MAAM,UAQjB;AAID,0BAA0B;AAC1B,2CADY,MAAM,UAiBjB;AAID;;;;;;GAMG;AACH,wCANW,MAAM,WACN;IAAC,kBAAkB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAAC,YACtF,OAAO,aACP,OAAO,gBACP,OAAO,UAuFjB;AAID;;;;;;;;;GASG;AACH,6CATW,MAAM,WACN,MAAM,WACN,MAAM,aACN,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC,aACrC,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC,WACrC;IAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAAC,2BAA2B,CAAC,EAAE,OAAO,CAAA;CAAC,kBACrG,GAAG,CAAC,MAAM,CAAC,iBACX,GAAG,CAAC,MAAM,CAAC,UA0ErB;AAOD,0BAA0B;AAC1B,2CADY,MAAM,WAGjB;AAED,0BAA0B;AAC1B,uCADY,MAAM,WAGjB"}
1
+ {"version":3,"file":"whitespace.d.ts","sourceRoot":"","sources":["../../../src/lib/whitespace.js"],"names":[],"mappings":"AAeA,0BAA0B;AAC1B,QAAA,MAAM,cAAc,QADR,MAAM,WAQjB,CAAC;AAIF,0BAA0B;AAC1B,iBAAS,qBAAqB,CAAC,GAAG,EADtB,MACsB,UAgBjC;AAID;;;;;;GAMG;AACH,iBAAS,kBAAkB,CAAC,GAAG,EANpB,MAMoB,EAAE,OAAO,EAL7B;IAAC,kBAAkB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAKxD,EAAE,QAAQ,EAJvC,OAIuC,EAAE,SAAS,EAHlD,OAGkD,EAAE,WAAW,AAFvE,CAA8B,EAAtB,OAEuE,UAqFjF;AAID;;;;;;;;;GASG;AACH,iBAAS,uBAAuB,CAAC,GAAG,EATzB,MASyB,EAAE,OAAO,EARlC,MAQkC,EAAE,OAAO,EAP3C,MAO2C,EAAE,SAAS,EANtD,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,CAMkB,EAAE,SAAS,EALjE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,CAK6B,EAAE,OAAO,EAJ1E;IAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAAC,2BAA2B,CAAC,EAAE,OAAO,CAAA;CAI1B,EAAE,cAAc,EAH1F,GAAG,CAAC,MAAM,CAGgF,EAAE,aAAa,EAFzG,GAAG,CAAC,MAAM,CAE+F,UAwEnH;AAOD,0BAA0B;AAC1B,iBAAS,qBAAqB,CAAC,GAAG,EADtB,MACsB,WAEjC;AAED,0BAA0B;AAC1B,iBAAS,iBAAiB,CAAC,GAAG,EADlB,MACkB,WAE7B;AAID,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EAClB,uBAAuB,EACvB,qBAAqB,EACrB,iBAAiB,EAClB,CAAC"}
@@ -1,47 +1,49 @@
1
+ /**
2
+ * Preset configurations
3
+ *
4
+ * Presets provide curated option sets for common use cases:
5
+ * - `conservative`: Safe minification suitable for most projects
6
+ * - `comprehensive`: Aggressive minification for maximum file size reduction
7
+ */
8
+ export declare const presets: {
9
+ conservative: {
10
+ caseSensitive: boolean;
11
+ collapseBooleanAttributes: boolean;
12
+ collapseWhitespace: boolean;
13
+ conservativeCollapse: boolean;
14
+ preserveLineBreaks: boolean;
15
+ removeComments: boolean;
16
+ removeDefaultTypeAttributes: boolean;
17
+ useShortDoctype: boolean;
18
+ };
19
+ comprehensive: {
20
+ collapseAttributeWhitespace: boolean;
21
+ collapseBooleanAttributes: boolean;
22
+ collapseWhitespace: boolean;
23
+ decodeEntities: boolean;
24
+ mergeScripts: boolean;
25
+ minifyCSS: boolean;
26
+ minifyJS: boolean;
27
+ minifySVG: boolean;
28
+ minifyURLs: boolean;
29
+ removeAttributeQuotes: boolean;
30
+ removeComments: boolean;
31
+ removeDefaultTypeAttributes: boolean;
32
+ removeEmptyAttributes: boolean;
33
+ removeOptionalTags: boolean;
34
+ removeRedundantAttributes: boolean;
35
+ useShortDoctype: boolean;
36
+ };
37
+ };
1
38
  /**
2
39
  * Get preset configuration by name
3
40
  * @param {string} name - Preset name (“conservative” or “comprehensive”)
4
41
  * @returns {object|null} Preset options object or null if not found
5
42
  */
6
- export function getPreset(name: string): object | null;
43
+ export declare function getPreset(name: string): object | null;
7
44
  /**
8
45
  * Get list of available preset names
9
46
  * @returns {string[]} Array of preset names
10
47
  */
11
- export function getPresetNames(): string[];
12
- export namespace presets {
13
- namespace conservative {
14
- let caseSensitive: boolean;
15
- let collapseBooleanAttributes: boolean;
16
- let collapseWhitespace: boolean;
17
- let conservativeCollapse: boolean;
18
- let preserveLineBreaks: boolean;
19
- let removeComments: boolean;
20
- let removeDefaultTypeAttributes: boolean;
21
- let useShortDoctype: boolean;
22
- }
23
- namespace comprehensive {
24
- export let collapseAttributeWhitespace: boolean;
25
- let collapseBooleanAttributes_1: boolean;
26
- export { collapseBooleanAttributes_1 as collapseBooleanAttributes };
27
- let collapseWhitespace_1: boolean;
28
- export { collapseWhitespace_1 as collapseWhitespace };
29
- export let decodeEntities: boolean;
30
- export let mergeScripts: boolean;
31
- export let minifyCSS: boolean;
32
- export let minifyJS: boolean;
33
- export let minifySVG: boolean;
34
- export let minifyURLs: boolean;
35
- export let removeAttributeQuotes: boolean;
36
- let removeComments_1: boolean;
37
- export { removeComments_1 as removeComments };
38
- let removeDefaultTypeAttributes_1: boolean;
39
- export { removeDefaultTypeAttributes_1 as removeDefaultTypeAttributes };
40
- export let removeEmptyAttributes: boolean;
41
- export let removeOptionalTags: boolean;
42
- export let removeRedundantAttributes: boolean;
43
- let useShortDoctype_1: boolean;
44
- export { useShortDoctype_1 as useShortDoctype };
45
- }
46
- }
48
+ export declare function getPresetNames(): string[];
47
49
  //# sourceMappingURL=presets.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/presets.js"],"names":[],"mappings":"AAuCA;;;;GAIG;AACH,gCAHW,MAAM,GACJ,MAAM,GAAC,IAAI,CAMvB;AAED;;;GAGG;AACH,kCAFa,MAAM,EAAE,CAIpB"}
1
+ {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/presets.js"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,OAAO;IAClB,YAAY;QACV,aAAa;QACb,yBAAyB;QACzB,kBAAkB;QAClB,oBAAoB;QACpB,kBAAkB;QAClB,cAAc;QACd,2BAA2B;QAC3B,eAAe;;IAEjB,aAAa;QACX,2BAA2B;QAC3B,yBAAyB;QACzB,kBAAkB;QAClB,cAAc;QACd,YAAY;QACZ,SAAS;QACT,QAAQ;QACR,SAAS;QACT,UAAU;QACV,qBAAqB;QACrB,cAAc;QACd,2BAA2B;QAC3B,qBAAqB;QACrB,kBAAkB;QAClB,yBAAyB;QACzB,eAAe;;CAElB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAHnB,MAGmB,GAFjB,MAAM,GAAC,IAAI,CAMvB;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAFjB,MAAM,EAAE,CAIpB"}
@@ -1,19 +1,9 @@
1
- export default TokenChain;
2
- declare class TokenChain {
3
- /** @type {Map<string, {arrays: string[][], processed: number}>} */
4
- map: Map<string, {
5
- arrays: string[][];
6
- processed: number;
7
- }>;
8
- /** @param {string[]} tokens */
9
- add(tokens: string[]): void;
10
- createSorter(): Sorter;
11
- }
12
1
  declare class Sorter {
13
2
  /** @type {string[]} */
14
3
  keys: string[];
15
4
  /** @type {Map<string, Sorter>} */
16
5
  sorterMap: Map<string, Sorter>;
6
+ constructor();
17
7
  /**
18
8
  * @param {string[]} tokens
19
9
  * @param {number} fromIndex
@@ -21,4 +11,16 @@ declare class Sorter {
21
11
  */
22
12
  sort(tokens: string[], fromIndex?: number): string[];
23
13
  }
14
+ declare class TokenChain {
15
+ /** @type {Map<string, {arrays: string[][], processed: number}>} */
16
+ map: Map<string, {
17
+ arrays: string[][];
18
+ processed: number;
19
+ }>;
20
+ constructor();
21
+ /** @param {string[]} tokens */
22
+ add(tokens: string[]): void;
23
+ createSorter(): Sorter;
24
+ }
25
+ export default TokenChain;
24
26
  //# sourceMappingURL=tokenchain.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tokenchain.d.ts","sourceRoot":"","sources":["../../src/tokenchain.js"],"names":[],"mappings":";AA+CA;IAEI,mEAAmE;IACnE,KADW,GAAG,CAAC,MAAM,EAAE;QAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAC,CAAC,CAC3C;IAGtB,+BAA+B;IAC/B,YADY,MAAM,EAAE,QAUnB;IAED,uBA+CC;CACF;AAjHD;IAEI,uBAAuB;IACvB,MADW,MAAM,EAAE,CACL;IACd,kCAAkC;IAClC,WADW,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CACJ;IAG5B;;;;OAIG;IACH,aAJW,MAAM,EAAE,cACR,MAAM,GACJ,MAAM,EAAE,CAiCpB;CACF"}
1
+ {"version":3,"file":"tokenchain.d.ts","sourceRoot":"","sources":["../../src/tokenchain.js"],"names":[],"mappings":"AAAA,cAAM,MAAM;IAER,uBAAuB;IAClB,IAAI,EADE,MAAM,EAAE;IAEnB,kCAAkC;IAC7B,SAAS,EADH,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAHhC,cAKC;IAED;;;;OAIG;IACH,IAAI,CAAC,MAAM,EAJA,MAAM,EAIN,EAAE,SAAS,GAHX,MAGe,GAFb,MAAM,EAAE,CAiCpB;CACF;AAED,cAAM,UAAU;IAEZ,mEAAmE;IAC9D,GAAG,EADG,GAAG,CAAC,MAAM,EAAE;QAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAC,CAAC;IADjE,cAGC;IAED,+BAA+B;IAC/B,GAAG,CAAC,MAAM,EADE,MAAM,EACR,QAST;IAED,YAAY,WA+CX;CACF;eAEc,UAAU"}
@@ -0,0 +1,303 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://raw.githubusercontent.com/j9t/html-minifier-next/main/html-minifier-next.schema.json",
4
+ "title": "HTML Minifier Next configuration",
5
+ "description": "Configuration file for HTML Minifier Next (HMN), used via `--config-file`",
6
+ "type": "object",
7
+ "properties": {
8
+ "$schema": {
9
+ "description": "JSON Schema reference for this configuration file (enables editor validation and autocomplete)",
10
+ "type": "string"
11
+ },
12
+ "preset": {
13
+ "description": "Preset configuration to start from—config file options override preset options",
14
+ "enum": [
15
+ "conservative",
16
+ "comprehensive"
17
+ ]
18
+ },
19
+ "fileExt": {
20
+ "description": "File extension(s) to process, as comma-separated string or array (default: `html,htm,shtml,shtm`; use `*` for all files)",
21
+ "type": [
22
+ "string",
23
+ "array"
24
+ ],
25
+ "items": {
26
+ "type": "string"
27
+ }
28
+ },
29
+ "ignoreDir": {
30
+ "description": "Directories—relative to the input directory—to exclude from processing, as comma-separated string or array",
31
+ "type": [
32
+ "string",
33
+ "array"
34
+ ],
35
+ "items": {
36
+ "type": "string"
37
+ }
38
+ },
39
+ "cacheCSS": {
40
+ "description": "Set CSS minification cache size (number of entries, default: 500)",
41
+ "type": "integer",
42
+ "minimum": 0
43
+ },
44
+ "cacheJS": {
45
+ "description": "Set JavaScript minification cache size (number of entries, default: 500)",
46
+ "type": "integer",
47
+ "minimum": 0
48
+ },
49
+ "cacheSVG": {
50
+ "description": "Set SVG minification cache size (number of entries, default: 500)",
51
+ "type": "integer",
52
+ "minimum": 0
53
+ },
54
+ "caseSensitive": {
55
+ "description": "Treat attributes in case-sensitive manner (useful for custom HTML elements)",
56
+ "type": "boolean"
57
+ },
58
+ "collapseAttributeWhitespace": {
59
+ "description": "Trim and collapse whitespace characters within attribute values",
60
+ "type": "boolean"
61
+ },
62
+ "collapseBooleanAttributes": {
63
+ "description": "Omit attribute values from boolean attributes",
64
+ "type": "boolean"
65
+ },
66
+ "collapseInlineTagWhitespace": {
67
+ "description": "Collapse whitespace more aggressively between inline elements—use with `--collapse-whitespace`",
68
+ "type": "boolean"
69
+ },
70
+ "collapseWhitespace": {
71
+ "description": "Collapse whitespace that contributes to text nodes in a document tree",
72
+ "type": "boolean"
73
+ },
74
+ "conservativeCollapse": {
75
+ "description": "Always collapse to one space (never remove it entirely)—use with `--collapse-whitespace`",
76
+ "type": "boolean"
77
+ },
78
+ "continueOnMinifyError": {
79
+ "description": "Continue on minification errors",
80
+ "type": "boolean"
81
+ },
82
+ "continueOnParseError": {
83
+ "description": "Handle parse errors instead of aborting",
84
+ "type": "boolean"
85
+ },
86
+ "customAttrAssign": {
87
+ "description": "Array of regexes that allow to support custom attribute assign expressions (e.g., `<div flex?=\"{{mode != cover}}\"></div>`)",
88
+ "type": [
89
+ "string",
90
+ "array"
91
+ ],
92
+ "items": {
93
+ "type": "string"
94
+ }
95
+ },
96
+ "customAttrCollapse": {
97
+ "description": "Regex that specifies custom attribute to strip newlines from (e.g., `/ng-class/`)",
98
+ "type": "string"
99
+ },
100
+ "customAttrSurround": {
101
+ "description": "Array of regexes that allow to support custom attribute surround expressions (e.g., `<input {{#if value}}checked=\"checked\"{{/if}}>`)",
102
+ "type": [
103
+ "string",
104
+ "array"
105
+ ],
106
+ "items": {
107
+ "type": "string"
108
+ }
109
+ },
110
+ "customEventAttributes": {
111
+ "description": "Array of regexes that allow to support custom event attributes for minifyJS (e.g., `ng-click`)",
112
+ "type": [
113
+ "string",
114
+ "array"
115
+ ],
116
+ "items": {
117
+ "type": "string"
118
+ }
119
+ },
120
+ "customFragmentQuantifierLimit": {
121
+ "description": "Set maximum quantifier limit for custom fragments to prevent ReDoS attacks (default: 200)",
122
+ "type": "integer",
123
+ "minimum": 0
124
+ },
125
+ "decodeEntities": {
126
+ "description": "Use direct Unicode characters whenever possible",
127
+ "type": "boolean"
128
+ },
129
+ "ignoreCustomComments": {
130
+ "description": "Array of regexes that allow to ignore matching comments",
131
+ "type": [
132
+ "string",
133
+ "array"
134
+ ],
135
+ "items": {
136
+ "type": "string"
137
+ }
138
+ },
139
+ "ignoreCustomFragments": {
140
+ "description": "Array of regexes that allow to ignore certain fragments, when matched (e.g., `<?php … ?>`, `{{ … }}`)",
141
+ "type": [
142
+ "string",
143
+ "array"
144
+ ],
145
+ "items": {
146
+ "type": "string"
147
+ }
148
+ },
149
+ "includeAutoGeneratedTags": {
150
+ "description": "Insert elements generated by HTML parser",
151
+ "type": "boolean"
152
+ },
153
+ "inlineCustomElements": {
154
+ "description": "Array of names of custom elements which are inline, for whitespace handling",
155
+ "type": [
156
+ "string",
157
+ "array"
158
+ ],
159
+ "items": {
160
+ "type": "string"
161
+ }
162
+ },
163
+ "keepClosingSlash": {
164
+ "description": "Keep the trailing slash on void elements",
165
+ "type": "boolean"
166
+ },
167
+ "maxInputLength": {
168
+ "description": "Maximum input length to prevent ReDoS attacks",
169
+ "type": "integer",
170
+ "minimum": 0
171
+ },
172
+ "maxLineLength": {
173
+ "description": "Specify a maximum line length; compressed output will be split by newlines at valid HTML split-points",
174
+ "type": "integer",
175
+ "minimum": 0
176
+ },
177
+ "mergeScripts": {
178
+ "description": "Merge consecutive inline `script` elements into one",
179
+ "type": "boolean"
180
+ },
181
+ "minifyCSS": {
182
+ "description": "Minify CSS in `style` elements and attributes (uses Lightning CSS)",
183
+ "type": [
184
+ "boolean",
185
+ "string",
186
+ "object"
187
+ ]
188
+ },
189
+ "minifyJS": {
190
+ "description": "Minify JavaScript in `script` elements and event attributes (uses Terser or SWC; pass `{\"engine\": \"swc\"}` for SWC)",
191
+ "type": [
192
+ "boolean",
193
+ "string",
194
+ "object"
195
+ ]
196
+ },
197
+ "minifySVG": {
198
+ "description": "Minify SVG elements (uses SVGO)",
199
+ "type": [
200
+ "boolean",
201
+ "string",
202
+ "object"
203
+ ]
204
+ },
205
+ "minifyURLs": {
206
+ "description": "Minify URLs in various attributes",
207
+ "type": [
208
+ "boolean",
209
+ "string",
210
+ "object"
211
+ ]
212
+ },
213
+ "noNewlinesBeforeTagClose": {
214
+ "description": "Never add a newline before a tag that closes an element",
215
+ "type": "boolean"
216
+ },
217
+ "partialMarkup": {
218
+ "description": "Treat input as a partial HTML fragment, preserving stray end tags and unclosed tags",
219
+ "type": "boolean"
220
+ },
221
+ "preserveLineBreaks": {
222
+ "description": "Always collapse to one line break (never remove it entirely) when whitespace between tags includes a line break—use with `--collapse-whitespace`",
223
+ "type": "boolean"
224
+ },
225
+ "preventAttributesEscaping": {
226
+ "description": "Prevents the escaping of the values of attributes",
227
+ "type": "boolean"
228
+ },
229
+ "processScripts": {
230
+ "description": "Array of strings corresponding to types of `script` elements to process through minifier (e.g., `text/ng-template`, `text/x-handlebars-template`, etc.)",
231
+ "type": [
232
+ "string",
233
+ "array"
234
+ ],
235
+ "items": {
236
+ "type": "string"
237
+ }
238
+ },
239
+ "quoteCharacter": {
240
+ "description": "Type of quote to use for attribute values (`'` or `\"`)",
241
+ "type": "string"
242
+ },
243
+ "removeAttributeQuotes": {
244
+ "description": "Remove quotes around attributes when possible",
245
+ "type": "boolean"
246
+ },
247
+ "removeComments": {
248
+ "description": "Strip HTML comments",
249
+ "type": "boolean"
250
+ },
251
+ "removeDefaultTypeAttributes": {
252
+ "description": "Remove default `type` attributes from `style`/`link` (e.g., `type=\"text/css\"`) and `script` (e.g., `type=\"text/javascript\"`) elements; other `type` attribute values are left intact",
253
+ "type": "boolean"
254
+ },
255
+ "removeEmptyAttributes": {
256
+ "description": "Remove all attributes with whitespace-only values",
257
+ "type": "boolean"
258
+ },
259
+ "removeEmptyElements": {
260
+ "description": "Remove all elements with empty contents",
261
+ "type": "boolean"
262
+ },
263
+ "removeEmptyElementsExcept": {
264
+ "description": "Array of elements to preserve when `--remove-empty-elements` is enabled (e.g., `td`, `<span aria-hidden=\"true\">`)",
265
+ "type": [
266
+ "string",
267
+ "array"
268
+ ],
269
+ "items": {
270
+ "type": "string"
271
+ }
272
+ },
273
+ "removeOptionalTags": {
274
+ "description": "Remove optional tags",
275
+ "type": "boolean"
276
+ },
277
+ "removeRedundantAttributes": {
278
+ "description": "Remove attributes when value matches default",
279
+ "type": "boolean"
280
+ },
281
+ "removeTagWhitespace": {
282
+ "description": "Remove space between attributes whenever possible; note that this will result in invalid HTML",
283
+ "type": "boolean"
284
+ },
285
+ "sortAttributes": {
286
+ "description": "Sort attributes by frequency",
287
+ "type": "boolean"
288
+ },
289
+ "sortClassNames": {
290
+ "description": "Sort style classes by frequency",
291
+ "type": "boolean"
292
+ },
293
+ "trimCustomFragments": {
294
+ "description": "Trim whitespace around custom fragments (`--ignore-custom-fragments`)",
295
+ "type": "boolean"
296
+ },
297
+ "useShortDoctype": {
298
+ "description": "Replaces the doctype with the short HTML doctype",
299
+ "type": "boolean"
300
+ }
301
+ },
302
+ "additionalProperties": false
303
+ }
package/package.json CHANGED
@@ -17,9 +17,9 @@
17
17
  "@commitlint/cli": "^21.2.0",
18
18
  "@eslint/js": "^10.0.1",
19
19
  "@swc/core": "^1.15.41",
20
- "@types/node": "^26.1.0",
20
+ "@types/node": "^26.1.1",
21
21
  "eslint": "^10.6.0",
22
- "typescript": "^6.0.3",
22
+ "typescript": "^7.0.2",
23
23
  "vite": "^8.0.16"
24
24
  },
25
25
  "engines": {
@@ -34,8 +34,9 @@
34
34
  },
35
35
  "files": [
36
36
  "cli.js",
37
- "dist/types/",
38
- "src/"
37
+ "dist/types",
38
+ "html-minifier-next.schema.json",
39
+ "src"
39
40
  ],
40
41
  "funding": "https://github.com/j9t/html-minifier-next?sponsor=1",
41
42
  "homepage": "https://j9t.github.io/html-minifier-next/",
@@ -78,8 +79,9 @@
78
79
  "url": "git+https://github.com/j9t/html-minifier-next.git"
79
80
  },
80
81
  "scripts": {
81
- "build": "tsc",
82
+ "build": "tsc && npm run build:schema",
82
83
  "build:docs": "vite build --base /html-minifier-next/",
84
+ "build:schema": "node scripts/build-schema.js",
83
85
  "deploy": "npm run build && npm run build:docs",
84
86
  "lint": "eslint .",
85
87
  "prebuild": "node --input-type=module --eval \"import {rmSync} from 'fs';rmSync('dist',{recursive:true,force:true})\"",
@@ -91,5 +93,5 @@
91
93
  "test:watch": "node --test --watch tests/*.spec.js"
92
94
  },
93
95
  "type": "module",
94
- "version": "7.1.0"
96
+ "version": "7.3.0"
95
97
  }
@@ -529,6 +529,22 @@ let jsMinifyCache = null;
529
529
  /** @type {LRU | null} */
530
530
  let svgMinifyCache = null;
531
531
 
532
+ /**
533
+ * @typedef {Object} CacheStats
534
+ * Hit/miss statistics and current occupancy for a single minification cache.
535
+ *
536
+ * @prop {number} gets Number of lookups attempted against the cache.
537
+ * @prop {number} hits Number of lookups that found a cached entry.
538
+ * @prop {number} size Number of entries currently held in the cache.
539
+ * @prop {number} limit Maximum number of entries the cache can hold.
540
+ */
541
+
542
+ /**
543
+ * @param {LRU | null} cache
544
+ * @returns {CacheStats}
545
+ */
546
+ const cacheStatsOrEmpty = (cache) => cache ? cache.stats() : { gets: 0, hits: 0, size: 0, limit: 0 };
547
+
532
548
  // Pre-compiled patterns for script merging (avoid repeated allocation in hot path)
533
549
  const RE_SCRIPT_ATTRS = /([^\s=]+)(?:=(?:"([^"]*)"|'([^']*)'|([^\s>]+)))?/g;
534
550
  const RE_SCRIPT_OPEN = /<script(?=[\s>])/gi; // Finds tag start; use `findTagEnd()` for the actual closing `>`
@@ -1893,6 +1909,23 @@ function initCaches(options) {
1893
1909
  return { cssMinifyCache, jsMinifyCache, svgMinifyCache };
1894
1910
  }
1895
1911
 
1912
+ /**
1913
+ * Get hit/miss statistics for the CSS, JavaScript, and SVG minification caches.
1914
+ *
1915
+ * Each cache is created lazily on the first `minify()` call (see `initCaches`); before
1916
+ * that first call, or for a cache never exercised (e.g., `minifyCSS` disabled), its
1917
+ * entry reports all-zero stats.
1918
+ *
1919
+ * @returns {{ css: CacheStats, js: CacheStats, svg: CacheStats }}
1920
+ */
1921
+ export function getCacheStats() {
1922
+ return {
1923
+ css: cacheStatsOrEmpty(cssMinifyCache),
1924
+ js: cacheStatsOrEmpty(jsMinifyCache),
1925
+ svg: cacheStatsOrEmpty(svgMinifyCache)
1926
+ };
1927
+ }
1928
+
1896
1929
  /**
1897
1930
  * @param {string} value
1898
1931
  * @param {MinifierOptions} [options]
@@ -1926,4 +1959,4 @@ export const minify = async function (value, options) {
1926
1959
 
1927
1960
  export { presets, getPreset, getPresetNames };
1928
1961
 
1929
- export default { minify, presets, getPreset, getPresetNames };
1962
+ export default { minify, presets, getPreset, getPresetNames, getCacheStats };
@@ -1,6 +1,18 @@
1
1
  // Single source of truth for minifier option names, descriptions, types, and shared defaults
2
2
 
3
3
  const optionDefinitions = {
4
+ cacheCSS: {
5
+ description: 'Set CSS minification cache size (number of entries, default: 500)',
6
+ type: 'int'
7
+ },
8
+ cacheJS: {
9
+ description: 'Set JavaScript minification cache size (number of entries, default: 500)',
10
+ type: 'int'
11
+ },
12
+ cacheSVG: {
13
+ description: 'Set SVG minification cache size (number of entries, default: 500)',
14
+ type: 'int'
15
+ },
4
16
  caseSensitive: {
5
17
  description: 'Treat attributes in case-sensitive manner (useful for custom HTML elements)',
6
18
  type: 'boolean'