@node-minify/utils 10.2.0 → 10.4.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 (86) hide show
  1. package/LICENSE +1 -1
  2. package/dist/buildArgs.js +2 -2
  3. package/dist/buildArgs.js.map +1 -1
  4. package/dist/compressSingleFile.d.ts +1 -1
  5. package/dist/compressSingleFile.d.ts.map +1 -1
  6. package/dist/compressSingleFile.js +6 -32
  7. package/dist/compressSingleFile.js.map +1 -1
  8. package/dist/compressor-resolver.d.ts +76 -0
  9. package/dist/compressor-resolver.d.ts.map +1 -0
  10. package/dist/compressor-resolver.js +183 -0
  11. package/dist/compressor-resolver.js.map +1 -0
  12. package/dist/deleteFile.d.ts +1 -1
  13. package/dist/deleteFile.js +2 -2
  14. package/dist/deleteFile.js.map +1 -1
  15. package/dist/deprecation.d.ts +1 -1
  16. package/dist/deprecation.js +1 -1
  17. package/dist/deprecation.js.map +1 -1
  18. package/dist/ensureStringContent.d.ts +1 -1
  19. package/dist/ensureStringContent.js +1 -1
  20. package/dist/ensureStringContent.js.map +1 -1
  21. package/dist/{error-Ck87RwDD.js → error-CUgKxOvI.js} +5 -3
  22. package/dist/error-CUgKxOvI.js.map +1 -0
  23. package/dist/error.d.ts +2 -1
  24. package/dist/error.d.ts.map +1 -1
  25. package/dist/error.js +1 -1
  26. package/dist/errors.d.ts +27 -0
  27. package/dist/errors.d.ts.map +1 -0
  28. package/dist/errors.js +32 -0
  29. package/dist/errors.js.map +1 -0
  30. package/dist/getContentFromFiles.d.ts +1 -1
  31. package/dist/getContentFromFiles.js +4 -4
  32. package/dist/getContentFromFiles.js.map +1 -1
  33. package/dist/getFilesizeBrotliInBytes.d.ts +26 -0
  34. package/dist/getFilesizeBrotliInBytes.d.ts.map +1 -0
  35. package/dist/getFilesizeBrotliInBytes.js +63 -0
  36. package/dist/getFilesizeBrotliInBytes.js.map +1 -0
  37. package/dist/getFilesizeGzippedInBytes.d.ts +14 -8
  38. package/dist/getFilesizeGzippedInBytes.d.ts.map +1 -1
  39. package/dist/getFilesizeGzippedInBytes.js +41 -18
  40. package/dist/getFilesizeGzippedInBytes.js.map +1 -1
  41. package/dist/getFilesizeInBytes.d.ts +1 -1
  42. package/dist/getFilesizeInBytes.js +1 -1
  43. package/dist/getFilesizeInBytes.js.map +1 -1
  44. package/dist/index.d.ts +8 -4
  45. package/dist/index.js +9 -5
  46. package/dist/isImageFile.d.ts +16 -0
  47. package/dist/isImageFile.d.ts.map +1 -0
  48. package/dist/isImageFile.js +35 -0
  49. package/dist/isImageFile.js.map +1 -0
  50. package/dist/{isValidFile-DnWJtlKA.js → isValidFile-COstpeyW.js} +4 -4
  51. package/dist/isValidFile-COstpeyW.js.map +1 -0
  52. package/dist/isValidFile.d.ts +1 -1
  53. package/dist/isValidFile.js +1 -1
  54. package/dist/prettyBytes.d.ts +1 -1
  55. package/dist/prettyBytes.js +2 -2
  56. package/dist/prettyBytes.js.map +1 -1
  57. package/dist/readFile.d.ts +13 -2
  58. package/dist/readFile.d.ts.map +1 -1
  59. package/dist/readFile.js +19 -3
  60. package/dist/readFile.js.map +1 -1
  61. package/dist/run.d.ts +4 -4
  62. package/dist/run.js +48 -37
  63. package/dist/run.js.map +1 -1
  64. package/dist/setFileNameMin.d.ts +1 -1
  65. package/dist/setFileNameMin.js +2 -2
  66. package/dist/setFileNameMin.js.map +1 -1
  67. package/dist/setPublicFolder.d.ts +1 -1
  68. package/dist/setPublicFolder.js +1 -1
  69. package/dist/setPublicFolder.js.map +1 -1
  70. package/dist/{types-BUlX1Zbb.d.ts → types-CWBFD3au.d.ts} +16 -2
  71. package/dist/types-CWBFD3au.d.ts.map +1 -0
  72. package/dist/types.d.ts +1 -1
  73. package/dist/wildcards.d.ts +1 -1
  74. package/dist/wildcards.js +1 -1
  75. package/dist/wildcards.js.map +1 -1
  76. package/dist/writeFile-mfUS3rMz.js +96 -0
  77. package/dist/writeFile-mfUS3rMz.js.map +1 -0
  78. package/dist/writeFile.d.ts +20 -2
  79. package/dist/writeFile.d.ts.map +1 -1
  80. package/dist/writeFile.js +2 -2
  81. package/package.json +2 -2
  82. package/dist/error-Ck87RwDD.js.map +0 -1
  83. package/dist/isValidFile-DnWJtlKA.js.map +0 -1
  84. package/dist/types-BUlX1Zbb.d.ts.map +0 -1
  85. package/dist/writeFile-BRfs9FqY.js +0 -39
  86. package/dist/writeFile-BRfs9FqY.js.map +0 -1
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Rodolphe Stoclin
3
+ Copyright (c) 2011-2026 Rodolphe Stoclin
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/dist/buildArgs.js CHANGED
@@ -1,9 +1,9 @@
1
- import { n as ValidationError } from "./error-Ck87RwDD.js";
1
+ import { n as ValidationError } from "./error-CUgKxOvI.js";
2
2
 
3
3
  //#region src/buildArgs.ts
4
4
  /*!
5
5
  * node-minify
6
- * Copyright(c) 2011-2025 Rodolphe Stoclin
6
+ * Copyright (c) 2011-2026 Rodolphe Stoclin
7
7
  * MIT Licensed
8
8
  */
9
9
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"buildArgs.js","names":["result: BuildArgsOptions","args: string[]"],"sources":["../src/buildArgs.ts"],"sourcesContent":["/*!\n * node-minify\n * Copyright(c) 2011-2025 Rodolphe Stoclin\n * MIT Licensed\n */\n\nimport { ValidationError } from \"./error.ts\";\nimport type { BuildArgsOptions } from \"./types.ts\";\n\n/**\n * Converts a generic options object to BuildArgsOptions by filtering out non-primitive values.\n * Only keeps string, number, boolean, and undefined values.\n * @param options - Generic options object\n * @returns Filtered options compatible with buildArgs\n */\nexport function toBuildArgsOptions(\n options: Record<string, unknown>\n): BuildArgsOptions {\n const result: BuildArgsOptions = {};\n for (const [key, value] of Object.entries(options)) {\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\" ||\n value === undefined\n ) {\n result[key] = value;\n }\n }\n return result;\n}\n\n/**\n * Builds arguments array based on an object.\n * @param options Object containing command line arguments\n * @returns Array of command line arguments\n * @throws {ValidationError} If options is null or undefined\n * @example\n * buildArgs({ compress: true, output: 'file.min.js' })\n * // returns ['--compress', '--output', 'file.min.js']\n */\nexport function buildArgs(options: BuildArgsOptions): string[] {\n if (!options || typeof options !== \"object\") {\n throw new ValidationError(\"Options must be a valid object\");\n }\n\n const args: string[] = [];\n Object.entries(options).forEach(([key, value]) => {\n if (value !== undefined && value !== false) {\n args.push(`--${key}`);\n if (value !== true) {\n args.push(String(value));\n }\n }\n });\n\n return args;\n}\n"],"mappings":";;;;;;;;;;;;;;AAeA,SAAgB,mBACZ,SACgB;CAChB,MAAMA,SAA2B,EAAE;AACnC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,CAC9C,KACI,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU,aACjB,UAAU,OAEV,QAAO,OAAO;AAGtB,QAAO;;;;;;;;;;;AAYX,SAAgB,UAAU,SAAqC;AAC3D,KAAI,CAAC,WAAW,OAAO,YAAY,SAC/B,OAAM,IAAI,gBAAgB,iCAAiC;CAG/D,MAAMC,OAAiB,EAAE;AACzB,QAAO,QAAQ,QAAQ,CAAC,SAAS,CAAC,KAAK,WAAW;AAC9C,MAAI,UAAU,UAAa,UAAU,OAAO;AACxC,QAAK,KAAK,KAAK,MAAM;AACrB,OAAI,UAAU,KACV,MAAK,KAAK,OAAO,MAAM,CAAC;;GAGlC;AAEF,QAAO"}
1
+ {"version":3,"file":"buildArgs.js","names":[],"sources":["../src/buildArgs.ts"],"sourcesContent":["/*!\n * node-minify\n * Copyright (c) 2011-2026 Rodolphe Stoclin\n * MIT Licensed\n */\n\nimport { ValidationError } from \"./error.ts\";\nimport type { BuildArgsOptions } from \"./types.ts\";\n\n/**\n * Converts a generic options object to BuildArgsOptions by filtering out non-primitive values.\n * Only keeps string, number, boolean, and undefined values.\n * @param options - Generic options object\n * @returns Filtered options compatible with buildArgs\n */\nexport function toBuildArgsOptions(\n options: Record<string, unknown>\n): BuildArgsOptions {\n const result: BuildArgsOptions = {};\n for (const [key, value] of Object.entries(options)) {\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\" ||\n value === undefined\n ) {\n result[key] = value;\n }\n }\n return result;\n}\n\n/**\n * Builds arguments array based on an object.\n * @param options Object containing command line arguments\n * @returns Array of command line arguments\n * @throws {ValidationError} If options is null or undefined\n * @example\n * buildArgs({ compress: true, output: 'file.min.js' })\n * // returns ['--compress', '--output', 'file.min.js']\n */\nexport function buildArgs(options: BuildArgsOptions): string[] {\n if (!options || typeof options !== \"object\") {\n throw new ValidationError(\"Options must be a valid object\");\n }\n\n const args: string[] = [];\n Object.entries(options).forEach(([key, value]) => {\n if (value !== undefined && value !== false) {\n args.push(`--${key}`);\n if (value !== true) {\n args.push(String(value));\n }\n }\n });\n\n return args;\n}\n"],"mappings":";;;;;;;;;;;;;;AAeA,SAAgB,mBACZ,SACgB;CAChB,MAAM,SAA2B,EAAE;AACnC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,CAC9C,KACI,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU,aACjB,UAAU,OAEV,QAAO,OAAO;AAGtB,QAAO;;;;;;;;;;;AAYX,SAAgB,UAAU,SAAqC;AAC3D,KAAI,CAAC,WAAW,OAAO,YAAY,SAC/B,OAAM,IAAI,gBAAgB,iCAAiC;CAG/D,MAAM,OAAiB,EAAE;AACzB,QAAO,QAAQ,QAAQ,CAAC,SAAS,CAAC,KAAK,WAAW;AAC9C,MAAI,UAAU,UAAa,UAAU,OAAO;AACxC,QAAK,KAAK,KAAK,MAAM;AACrB,OAAI,UAAU,KACV,MAAK,KAAK,OAAO,MAAM,CAAC;;GAGlC;AAEF,QAAO"}
@@ -1,4 +1,4 @@
1
- import { r as Settings, t as CompressorOptions } from "./types-BUlX1Zbb.js";
1
+ import { i as Settings, n as CompressorOptions } from "./types-CWBFD3au.js";
2
2
 
3
3
  //#region src/compressSingleFile.d.ts
4
4
 
@@ -1 +1 @@
1
- {"version":3,"file":"compressSingleFile.d.ts","names":[],"sources":["../src/compressSingleFile.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;iBA+CsB,6BACR,oBAAoB,6BACtB,SAAS,KAAK"}
1
+ {"version":3,"file":"compressSingleFile.d.ts","names":[],"sources":["../src/compressSingleFile.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;iBAsBsB,6BACR,oBAAoB,6BACtB,SAAS,KAAK"}
@@ -1,37 +1,9 @@
1
1
  import { getContentFromFilesAsync } from "./getContentFromFiles.js";
2
+ import { isImageFile } from "./isImageFile.js";
3
+ import { readFileAsync } from "./readFile.js";
2
4
  import { run } from "./run.js";
3
- import { readFile } from "node:fs/promises";
4
5
 
5
6
  //#region src/compressSingleFile.ts
6
- /*!
7
- * node-minify
8
- * Copyright(c) 2011-2025 Rodolphe Stoclin
9
- * MIT Licensed
10
- */
11
- const IMAGE_EXTENSIONS = new Set([
12
- ".png",
13
- ".jpg",
14
- ".jpeg",
15
- ".gif",
16
- ".webp",
17
- ".avif",
18
- ".tiff",
19
- ".tif",
20
- ".heif",
21
- ".heic"
22
- ]);
23
- /**
24
- * Determines whether a file path refers to a supported image file by its extension.
25
- *
26
- * @param filePath - The file name or path to check; may include directories.
27
- * @returns `true` if the path ends with a recognized image extension, `false` otherwise.
28
- */
29
- function isImageFile(filePath) {
30
- const lastDot = filePath.lastIndexOf(".");
31
- if (lastDot === -1) return false;
32
- const ext = filePath.slice(lastDot).toLowerCase();
33
- return IMAGE_EXTENSIONS.has(ext);
34
- }
35
7
  /**
36
8
  * Compress a single file using the provided settings.
37
9
  *
@@ -57,11 +29,13 @@ async function determineContent(settings) {
57
29
  const imageFilesCount = settings.input.filter((file) => isImageFile(file)).length;
58
30
  if (imageFilesCount > 0) {
59
31
  if (imageFilesCount !== settings.input.length) throw new Error("Cannot mix image and text files in the same input array");
60
- return await Promise.all(settings.input.map((file) => readFile(file)));
32
+ const firstInput = settings.input[0];
33
+ if (settings.input.length === 1 && firstInput) return await readFileAsync(firstInput, true);
34
+ return await Promise.all(settings.input.map((file) => readFileAsync(file, true)));
61
35
  }
62
36
  }
63
37
  if (settings.input && typeof settings.input === "string") {
64
- if (isImageFile(settings.input)) return await readFile(settings.input);
38
+ if (isImageFile(settings.input)) return await readFileAsync(settings.input, true);
65
39
  }
66
40
  if (settings.input) return await getContentFromFilesAsync(settings.input);
67
41
  return "";
@@ -1 +1 @@
1
- {"version":3,"file":"compressSingleFile.js","names":[],"sources":["../src/compressSingleFile.ts"],"sourcesContent":["/*!\n * node-minify\n * Copyright(c) 2011-2025 Rodolphe Stoclin\n * MIT Licensed\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport type {\n CompressorOptions,\n MinifierOptions,\n Settings,\n} from \"@node-minify/types\";\nimport { getContentFromFilesAsync } from \"./getContentFromFiles.ts\";\nimport { run } from \"./run.ts\";\n\nconst IMAGE_EXTENSIONS = new Set([\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".webp\",\n \".avif\",\n \".tiff\",\n \".tif\",\n \".heif\",\n \".heic\",\n]);\n\n/**\n * Determines whether a file path refers to a supported image file by its extension.\n *\n * @param filePath - The file name or path to check; may include directories.\n * @returns `true` if the path ends with a recognized image extension, `false` otherwise.\n */\nfunction isImageFile(filePath: string): boolean {\n const lastDot = filePath.lastIndexOf(\".\");\n if (lastDot === -1) return false;\n const ext = filePath.slice(lastDot).toLowerCase();\n return IMAGE_EXTENSIONS.has(ext);\n}\n\n/**\n * Compress a single file using the provided settings.\n *\n * @param settings - Configuration that specifies input content or input path(s) and compressor options\n * @returns The compressed output as a string\n */\nexport async function compressSingleFile<\n T extends CompressorOptions = CompressorOptions,\n>(settings: Settings<T>): Promise<string> {\n const content = await determineContent(settings);\n return run({ settings, content } as MinifierOptions<T>);\n}\n\n/**\n * Resolve the content to be minified from the provided settings.\n *\n * @param settings - Settings that may contain `content` or `input` (string or string[]); `content` is used preferentially.\n * @returns The resolved content: a `string` for text input, a `Buffer` for a single image file, or a `Buffer[]` for multiple image files.\n * @throws Error - If `settings.input` is an array that mixes image and non-image file paths.\n */\nasync function determineContent<\n T extends CompressorOptions = CompressorOptions,\n>(settings: Settings<T>): Promise<string | Buffer | Buffer[]> {\n if (settings.content) {\n return settings.content;\n }\n\n if (settings.input && Array.isArray(settings.input)) {\n const imageFilesCount = settings.input.filter((file) =>\n isImageFile(file)\n ).length;\n if (imageFilesCount > 0) {\n if (imageFilesCount !== settings.input.length) {\n throw new Error(\n \"Cannot mix image and text files in the same input array\"\n );\n }\n return await Promise.all(\n settings.input.map((file) => readFile(file))\n );\n }\n }\n\n if (settings.input && typeof settings.input === \"string\") {\n if (isImageFile(settings.input)) {\n return await readFile(settings.input);\n }\n }\n\n if (settings.input) {\n return await getContentFromFilesAsync(settings.input);\n }\n\n return \"\";\n}\n"],"mappings":";;;;;;;;;;AAeA,MAAM,mBAAmB,IAAI,IAAI;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACH,CAAC;;;;;;;AAQF,SAAS,YAAY,UAA2B;CAC5C,MAAM,UAAU,SAAS,YAAY,IAAI;AACzC,KAAI,YAAY,GAAI,QAAO;CAC3B,MAAM,MAAM,SAAS,MAAM,QAAQ,CAAC,aAAa;AACjD,QAAO,iBAAiB,IAAI,IAAI;;;;;;;;AASpC,eAAsB,mBAEpB,UAAwC;AAEtC,QAAO,IAAI;EAAE;EAAU,SADP,MAAM,iBAAiB,SAAS;EAChB,CAAuB;;;;;;;;;AAU3D,eAAe,iBAEb,UAA4D;AAC1D,KAAI,SAAS,QACT,QAAO,SAAS;AAGpB,KAAI,SAAS,SAAS,MAAM,QAAQ,SAAS,MAAM,EAAE;EACjD,MAAM,kBAAkB,SAAS,MAAM,QAAQ,SAC3C,YAAY,KAAK,CACpB,CAAC;AACF,MAAI,kBAAkB,GAAG;AACrB,OAAI,oBAAoB,SAAS,MAAM,OACnC,OAAM,IAAI,MACN,0DACH;AAEL,UAAO,MAAM,QAAQ,IACjB,SAAS,MAAM,KAAK,SAAS,SAAS,KAAK,CAAC,CAC/C;;;AAIT,KAAI,SAAS,SAAS,OAAO,SAAS,UAAU,UAC5C;MAAI,YAAY,SAAS,MAAM,CAC3B,QAAO,MAAM,SAAS,SAAS,MAAM;;AAI7C,KAAI,SAAS,MACT,QAAO,MAAM,yBAAyB,SAAS,MAAM;AAGzD,QAAO"}
1
+ {"version":3,"file":"compressSingleFile.js","names":[],"sources":["../src/compressSingleFile.ts"],"sourcesContent":["/*!\n * node-minify\n * Copyright (c) 2011-2026 Rodolphe Stoclin\n * MIT Licensed\n */\n\nimport type {\n CompressorOptions,\n MinifierOptions,\n Settings,\n} from \"@node-minify/types\";\nimport { getContentFromFilesAsync } from \"./getContentFromFiles.ts\";\nimport { isImageFile } from \"./isImageFile.ts\";\nimport { readFileAsync } from \"./readFile.ts\";\nimport { run } from \"./run.ts\";\n\n/**\n * Compress a single file using the provided settings.\n *\n * @param settings - Configuration that specifies input content or input path(s) and compressor options\n * @returns The compressed output as a string\n */\nexport async function compressSingleFile<\n T extends CompressorOptions = CompressorOptions,\n>(settings: Settings<T>): Promise<string> {\n const content = await determineContent(settings);\n return run({ settings, content } as MinifierOptions<T>);\n}\n\n/**\n * Resolve the content to be minified from the provided settings.\n *\n * @param settings - Settings that may contain `content` or `input` (string or string[]); `content` is used preferentially.\n * @returns The resolved content: a `string` for text input, a `Buffer` for a single image file, or a `Buffer[]` for multiple image files.\n * @throws Error - If `settings.input` is an array that mixes image and non-image file paths.\n */\nasync function determineContent<\n T extends CompressorOptions = CompressorOptions,\n>(settings: Settings<T>): Promise<string | Buffer | Buffer[]> {\n if (settings.content) {\n return settings.content;\n }\n\n if (settings.input && Array.isArray(settings.input)) {\n const imageFilesCount = settings.input.filter((file) =>\n isImageFile(file)\n ).length;\n if (imageFilesCount > 0) {\n if (imageFilesCount !== settings.input.length) {\n throw new Error(\n \"Cannot mix image and text files in the same input array\"\n );\n }\n const firstInput = settings.input[0];\n if (settings.input.length === 1 && firstInput) {\n return await readFileAsync(firstInput, true);\n }\n return await Promise.all(\n settings.input.map((file) => readFileAsync(file, true))\n );\n }\n }\n\n if (settings.input && typeof settings.input === \"string\") {\n if (isImageFile(settings.input)) {\n return await readFileAsync(settings.input, true);\n }\n }\n\n if (settings.input) {\n return await getContentFromFilesAsync(settings.input);\n }\n\n return \"\";\n}\n"],"mappings":";;;;;;;;;;;;AAsBA,eAAsB,mBAEpB,UAAwC;AAEtC,QAAO,IAAI;EAAE;EAAU,SADP,MAAM,iBAAiB,SAAS;EAChB,CAAuB;;;;;;;;;AAU3D,eAAe,iBAEb,UAA4D;AAC1D,KAAI,SAAS,QACT,QAAO,SAAS;AAGpB,KAAI,SAAS,SAAS,MAAM,QAAQ,SAAS,MAAM,EAAE;EACjD,MAAM,kBAAkB,SAAS,MAAM,QAAQ,SAC3C,YAAY,KAAK,CACpB,CAAC;AACF,MAAI,kBAAkB,GAAG;AACrB,OAAI,oBAAoB,SAAS,MAAM,OACnC,OAAM,IAAI,MACN,0DACH;GAEL,MAAM,aAAa,SAAS,MAAM;AAClC,OAAI,SAAS,MAAM,WAAW,KAAK,WAC/B,QAAO,MAAM,cAAc,YAAY,KAAK;AAEhD,UAAO,MAAM,QAAQ,IACjB,SAAS,MAAM,KAAK,SAAS,cAAc,MAAM,KAAK,CAAC,CAC1D;;;AAIT,KAAI,SAAS,SAAS,OAAO,SAAS,UAAU,UAC5C;MAAI,YAAY,SAAS,MAAM,CAC3B,QAAO,MAAM,cAAc,SAAS,OAAO,KAAK;;AAIxD,KAAI,SAAS,MACT,QAAO,MAAM,yBAAyB,SAAS,MAAM;AAGzD,QAAO"}
@@ -0,0 +1,76 @@
1
+ import { t as Compressor } from "./types-CWBFD3au.js";
2
+
3
+ //#region src/compressor-resolver.d.ts
4
+
5
+ /**
6
+ * Result from resolving a compressor.
7
+ */
8
+ type CompressorResolution = {
9
+ /**
10
+ * The resolved compressor function.
11
+ */
12
+ compressor: Compressor;
13
+ /**
14
+ * Label for the compressor (used in logs/reports).
15
+ */
16
+ label: string;
17
+ /**
18
+ * Whether this is a built-in @node-minify compressor.
19
+ */
20
+ isBuiltIn: boolean;
21
+ };
22
+ /**
23
+ * Determines whether a string represents a local file path.
24
+ *
25
+ * @param name - The path string to test
26
+ * @returns `true` if `name` appears to be a local file path, `false` otherwise
27
+ */
28
+ declare function isLocalPath(name: string): boolean;
29
+ /**
30
+ * Try to resolve a compressor from a built-in @node-minify package.
31
+ *
32
+ * @param name - The compressor name (e.g., "terser", "esbuild")
33
+ * @returns The resolved CompressorResolution if found, or `null` if not installed/available
34
+ */
35
+ declare function tryResolveBuiltIn(name: string): Promise<CompressorResolution | null>;
36
+ /**
37
+ * Try to resolve a compressor from an npm package.
38
+ *
39
+ * @param name - The npm package name
40
+ * @returns The resolved CompressorResolution if found, or `null` if not resolvable
41
+ * @throws Error if the package is found but doesn't export a valid compressor
42
+ */
43
+ declare function tryResolveNpmPackage(name: string): Promise<CompressorResolution | null>;
44
+ /**
45
+ * Try to resolve a compressor from a local file path.
46
+ *
47
+ * @param name - The local file path (e.g., "./my-compressor.js")
48
+ * @returns The resolved CompressorResolution if found, or `null` if not a local path
49
+ * @throws Error if the file is found but doesn't export a valid compressor
50
+ */
51
+ declare function tryResolveLocalFile(name: string): Promise<CompressorResolution | null>;
52
+ /**
53
+ * Resolve a compressor by name from a built-in @node-minify package, an installed npm package, or a local file path.
54
+ *
55
+ * @param name - Compressor identifier: a built-in name (e.g., "terser"), an npm package name, or a local path (e.g., "./compressor.js")
56
+ * @returns The resolved CompressorResolution containing the compressor function, a display `label`, and `isBuiltIn` flag
57
+ * @throws Error if the compressor cannot be found or the module does not export a valid compressor function
58
+ */
59
+ declare function resolveCompressor(name: string): Promise<CompressorResolution>;
60
+ /**
61
+ * Determines whether a compressor name corresponds to a known built-in compressor.
62
+ *
63
+ * @param name - The compressor identifier (e.g., built-in package name or alias)
64
+ * @returns `true` if the name corresponds to a known built-in compressor, `false` otherwise.
65
+ */
66
+ declare function isBuiltInCompressor(name: string): boolean;
67
+ /**
68
+ * Return the known exported symbol name for a built-in compressor package.
69
+ *
70
+ * @param name - The compressor package name (for example, `"esbuild"`, `"terser"`)
71
+ * @returns The export name used by the built-in package, or `undefined` if the compressor is not a known built-in
72
+ */
73
+ declare function getKnownExportName(name: string): string | undefined;
74
+ //#endregion
75
+ export { CompressorResolution, getKnownExportName, isBuiltInCompressor, isLocalPath, resolveCompressor, tryResolveBuiltIn, tryResolveLocalFile, tryResolveNpmPackage };
76
+ //# sourceMappingURL=compressor-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compressor-resolver.d.ts","names":[],"sources":["../src/compressor-resolver.ts"],"sourcesContent":[],"mappings":";;;;AAmLA;AAsCA;AA8CA;AAsCgB,KAnQJ,oBAAA,GAmQuB;EAUnB;;;cAzQA;;;;;;;;;;;;;;;;iBAmBA,WAAA;;;;;;;iBA+EM,iBAAA,gBAEnB,QAAQ;;;;;;;;iBAiCW,oBAAA,gBAEnB,QAAQ;;;;;;;;iBAoCW,mBAAA,gBAEnB,QAAQ;;;;;;;;iBA4CW,iBAAA,gBAEnB,QAAQ;;;;;;;iBAoCK,mBAAA;;;;;;;iBAUA,kBAAA"}
@@ -0,0 +1,183 @@
1
+ import path from "node:path";
2
+ import { pathToFileURL } from "node:url";
3
+
4
+ //#region src/compressor-resolver.ts
5
+ /*!
6
+ * node-minify
7
+ * Copyright (c) 2011-2026 Rodolphe Stoclin
8
+ * MIT Licensed
9
+ */
10
+ /**
11
+ * Known compressor exports for built-in @node-minify packages.
12
+ * Maps package name to the exported function name.
13
+ */
14
+ const KNOWN_COMPRESSOR_EXPORTS = {
15
+ esbuild: "esbuild",
16
+ "google-closure-compiler": "gcc",
17
+ oxc: "oxc",
18
+ swc: "swc",
19
+ terser: "terser",
20
+ "uglify-js": "uglifyJs",
21
+ "babel-minify": "babelMinify",
22
+ "uglify-es": "uglifyEs",
23
+ yui: "yui",
24
+ "clean-css": "cleanCss",
25
+ cssnano: "cssnano",
26
+ csso: "csso",
27
+ lightningcss: "lightningCss",
28
+ crass: "crass",
29
+ sqwish: "sqwish",
30
+ "html-minifier": "htmlMinifier",
31
+ "minify-html": "minifyHtml",
32
+ jsonminify: "jsonMinify",
33
+ imagemin: "imagemin",
34
+ sharp: "sharp",
35
+ svgo: "svgo",
36
+ "no-compress": "noCompress"
37
+ };
38
+ /**
39
+ * Determines whether a string represents a local file path.
40
+ *
41
+ * @param name - The path string to test
42
+ * @returns `true` if `name` appears to be a local file path, `false` otherwise
43
+ */
44
+ function isLocalPath(name) {
45
+ return name.startsWith("./") || name.startsWith("../") || name.startsWith("/") || /^[a-zA-Z]:[/\\]/.test(name);
46
+ }
47
+ /**
48
+ * Converts a package name to camelCase for export lookup.
49
+ *
50
+ * @param name - The package or file name to convert
51
+ * @returns The input `name` converted to camelCase
52
+ */
53
+ function toCamelCase(name) {
54
+ return name.replace(/[-_](.)/g, (_, char) => char.toUpperCase());
55
+ }
56
+ /**
57
+ * Resolve a compressor function exported by a loaded module.
58
+ *
59
+ * @param mod - The imported module object to inspect for exports
60
+ * @param name - The package or file name used to derive known and camelCase export names
61
+ * @returns The resolved `Compressor` function if found, or `null` if no suitable function export exists
62
+ */
63
+ function extractCompressor(mod, name) {
64
+ const knownExport = KNOWN_COMPRESSOR_EXPORTS[name];
65
+ if (knownExport && typeof mod[knownExport] === "function") return mod[knownExport];
66
+ const camelName = toCamelCase(name.includes("/") ? name.split("/").pop() ?? name : name);
67
+ if (typeof mod[camelName] === "function") return mod[camelName];
68
+ if (typeof mod.compressor === "function") return mod.compressor;
69
+ if (typeof mod.default === "function") return mod.default;
70
+ for (const value of Object.values(mod)) if (typeof value === "function") return value;
71
+ return null;
72
+ }
73
+ /**
74
+ * Create a display label from a compressor package name or a local file path.
75
+ *
76
+ * @param name - Compressor npm package name or a local file path
77
+ * @returns The package name for npm compressors, or the local file's basename without extension
78
+ */
79
+ function generateLabel(name) {
80
+ if (isLocalPath(name)) return path.basename(name).replace(/\.(js|ts|mjs|cjs)$/, "");
81
+ return name;
82
+ }
83
+ /**
84
+ * Try to resolve a compressor from a built-in @node-minify package.
85
+ *
86
+ * @param name - The compressor name (e.g., "terser", "esbuild")
87
+ * @returns The resolved CompressorResolution if found, or `null` if not installed/available
88
+ */
89
+ async function tryResolveBuiltIn(name) {
90
+ if (!(name in KNOWN_COMPRESSOR_EXPORTS)) return null;
91
+ try {
92
+ const compressor = extractCompressor(await import(`@node-minify/${name}`), name);
93
+ if (compressor) return {
94
+ compressor,
95
+ label: name,
96
+ isBuiltIn: true
97
+ };
98
+ } catch {}
99
+ return null;
100
+ }
101
+ /**
102
+ * Try to resolve a compressor from an npm package.
103
+ *
104
+ * @param name - The npm package name
105
+ * @returns The resolved CompressorResolution if found, or `null` if not resolvable
106
+ * @throws Error if the package is found but doesn't export a valid compressor
107
+ */
108
+ async function tryResolveNpmPackage(name) {
109
+ try {
110
+ const compressor = extractCompressor(await import(name), name);
111
+ if (compressor) return {
112
+ compressor,
113
+ label: generateLabel(name),
114
+ isBuiltIn: false
115
+ };
116
+ throw new Error(`Package '${name}' doesn't export a valid compressor function. Expected a function as default export, named export 'compressor', or named export '${toCamelCase(name)}'.`);
117
+ } catch (error) {
118
+ if (error instanceof Error && error.message.includes("doesn't export a valid compressor")) throw error;
119
+ return null;
120
+ }
121
+ }
122
+ /**
123
+ * Try to resolve a compressor from a local file path.
124
+ *
125
+ * @param name - The local file path (e.g., "./my-compressor.js")
126
+ * @returns The resolved CompressorResolution if found, or `null` if not a local path
127
+ * @throws Error if the file is found but doesn't export a valid compressor
128
+ */
129
+ async function tryResolveLocalFile(name) {
130
+ if (!isLocalPath(name)) return null;
131
+ try {
132
+ const compressor = extractCompressor(await import(pathToFileURL(path.resolve(process.cwd(), name)).href), name);
133
+ if (compressor) return {
134
+ compressor,
135
+ label: generateLabel(name),
136
+ isBuiltIn: false
137
+ };
138
+ throw new Error(`Local file '${name}' doesn't export a valid compressor function. Expected a function as default export or named export 'compressor'.`);
139
+ } catch (error) {
140
+ if (error instanceof Error && error.message.includes("doesn't export a valid compressor")) throw error;
141
+ throw new Error(`Could not load local compressor '${name}'. File not found or failed to import: ${error instanceof Error ? error.message : String(error)}`);
142
+ }
143
+ }
144
+ /**
145
+ * Resolve a compressor by name from a built-in @node-minify package, an installed npm package, or a local file path.
146
+ *
147
+ * @param name - Compressor identifier: a built-in name (e.g., "terser"), an npm package name, or a local path (e.g., "./compressor.js")
148
+ * @returns The resolved CompressorResolution containing the compressor function, a display `label`, and `isBuiltIn` flag
149
+ * @throws Error if the compressor cannot be found or the module does not export a valid compressor function
150
+ */
151
+ async function resolveCompressor(name) {
152
+ const builtIn = await tryResolveBuiltIn(name);
153
+ if (builtIn) return builtIn;
154
+ const npmPackage = await tryResolveNpmPackage(name);
155
+ if (npmPackage) return npmPackage;
156
+ if (isLocalPath(name)) {
157
+ const localFile = await tryResolveLocalFile(name);
158
+ if (localFile) return localFile;
159
+ }
160
+ throw new Error(`Could not resolve compressor '${name}'. Is it installed? For local files, use a path starting with './' or '/'.`);
161
+ }
162
+ /**
163
+ * Determines whether a compressor name corresponds to a known built-in compressor.
164
+ *
165
+ * @param name - The compressor identifier (e.g., built-in package name or alias)
166
+ * @returns `true` if the name corresponds to a known built-in compressor, `false` otherwise.
167
+ */
168
+ function isBuiltInCompressor(name) {
169
+ return name in KNOWN_COMPRESSOR_EXPORTS;
170
+ }
171
+ /**
172
+ * Return the known exported symbol name for a built-in compressor package.
173
+ *
174
+ * @param name - The compressor package name (for example, `"esbuild"`, `"terser"`)
175
+ * @returns The export name used by the built-in package, or `undefined` if the compressor is not a known built-in
176
+ */
177
+ function getKnownExportName(name) {
178
+ return KNOWN_COMPRESSOR_EXPORTS[name];
179
+ }
180
+
181
+ //#endregion
182
+ export { getKnownExportName, isBuiltInCompressor, isLocalPath, resolveCompressor, tryResolveBuiltIn, tryResolveLocalFile, tryResolveNpmPackage };
183
+ //# sourceMappingURL=compressor-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compressor-resolver.js","names":[],"sources":["../src/compressor-resolver.ts"],"sourcesContent":["/*!\n * node-minify\n * Copyright (c) 2011-2026 Rodolphe Stoclin\n * MIT Licensed\n */\n\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { Compressor } from \"@node-minify/types\";\n\n/**\n * Known compressor exports for built-in @node-minify packages.\n * Maps package name to the exported function name.\n */\nconst KNOWN_COMPRESSOR_EXPORTS: Record<string, string> = {\n esbuild: \"esbuild\",\n \"google-closure-compiler\": \"gcc\",\n oxc: \"oxc\",\n swc: \"swc\",\n terser: \"terser\",\n \"uglify-js\": \"uglifyJs\",\n \"babel-minify\": \"babelMinify\",\n \"uglify-es\": \"uglifyEs\",\n yui: \"yui\",\n \"clean-css\": \"cleanCss\",\n cssnano: \"cssnano\",\n csso: \"csso\",\n lightningcss: \"lightningCss\",\n crass: \"crass\",\n sqwish: \"sqwish\",\n \"html-minifier\": \"htmlMinifier\",\n \"minify-html\": \"minifyHtml\",\n jsonminify: \"jsonMinify\",\n imagemin: \"imagemin\",\n sharp: \"sharp\",\n svgo: \"svgo\",\n \"no-compress\": \"noCompress\",\n};\n\n/**\n * Result from resolving a compressor.\n */\nexport type CompressorResolution = {\n /**\n * The resolved compressor function.\n */\n compressor: Compressor;\n\n /**\n * Label for the compressor (used in logs/reports).\n */\n label: string;\n\n /**\n * Whether this is a built-in @node-minify compressor.\n */\n isBuiltIn: boolean;\n};\n\n/**\n * Determines whether a string represents a local file path.\n *\n * @param name - The path string to test\n * @returns `true` if `name` appears to be a local file path, `false` otherwise\n */\nexport function isLocalPath(name: string): boolean {\n return (\n name.startsWith(\"./\") ||\n name.startsWith(\"../\") ||\n name.startsWith(\"/\") ||\n /^[a-zA-Z]:[/\\\\]/.test(name)\n );\n}\n\n/**\n * Converts a package name to camelCase for export lookup.\n *\n * @param name - The package or file name to convert\n * @returns The input `name` converted to camelCase\n */\nfunction toCamelCase(name: string): string {\n return name.replace(/[-_](.)/g, (_, char) => char.toUpperCase());\n}\n\n/**\n * Resolve a compressor function exported by a loaded module.\n *\n * @param mod - The imported module object to inspect for exports\n * @param name - The package or file name used to derive known and camelCase export names\n * @returns The resolved `Compressor` function if found, or `null` if no suitable function export exists\n */\nfunction extractCompressor(\n mod: Record<string, unknown>,\n name: string\n): Compressor | null {\n const knownExport = KNOWN_COMPRESSOR_EXPORTS[name];\n if (knownExport && typeof mod[knownExport] === \"function\") {\n return mod[knownExport] as Compressor;\n }\n\n const baseName = name.includes(\"/\")\n ? (name.split(\"/\").pop() ?? name)\n : name;\n const camelName = toCamelCase(baseName);\n if (typeof mod[camelName] === \"function\") {\n return mod[camelName] as Compressor;\n }\n\n if (typeof mod.compressor === \"function\") {\n return mod.compressor as Compressor;\n }\n\n if (typeof mod.default === \"function\") {\n return mod.default as Compressor;\n }\n\n for (const value of Object.values(mod)) {\n if (typeof value === \"function\") {\n return value as Compressor;\n }\n }\n\n return null;\n}\n\n/**\n * Create a display label from a compressor package name or a local file path.\n *\n * @param name - Compressor npm package name or a local file path\n * @returns The package name for npm compressors, or the local file's basename without extension\n */\nfunction generateLabel(name: string): string {\n if (isLocalPath(name)) {\n return path.basename(name).replace(/\\.(js|ts|mjs|cjs)$/, \"\");\n }\n return name;\n}\n\n/**\n * Try to resolve a compressor from a built-in @node-minify package.\n *\n * @param name - The compressor name (e.g., \"terser\", \"esbuild\")\n * @returns The resolved CompressorResolution if found, or `null` if not installed/available\n */\nexport async function tryResolveBuiltIn(\n name: string\n): Promise<CompressorResolution | null> {\n if (!(name in KNOWN_COMPRESSOR_EXPORTS)) {\n return null;\n }\n\n try {\n const mod = (await import(`@node-minify/${name}`)) as Record<\n string,\n unknown\n >;\n const compressor = extractCompressor(mod, name);\n\n if (compressor) {\n return {\n compressor,\n label: name,\n isBuiltIn: true,\n };\n }\n } catch {\n // Built-in package not installed\n }\n\n return null;\n}\n\n/**\n * Try to resolve a compressor from an npm package.\n *\n * @param name - The npm package name\n * @returns The resolved CompressorResolution if found, or `null` if not resolvable\n * @throws Error if the package is found but doesn't export a valid compressor\n */\nexport async function tryResolveNpmPackage(\n name: string\n): Promise<CompressorResolution | null> {\n try {\n const mod = (await import(name)) as Record<string, unknown>;\n const compressor = extractCompressor(mod, name);\n\n if (compressor) {\n return {\n compressor,\n label: generateLabel(name),\n isBuiltIn: false,\n };\n }\n\n throw new Error(\n `Package '${name}' doesn't export a valid compressor function. ` +\n `Expected a function as default export, named export 'compressor', or ` +\n `named export '${toCamelCase(name)}'.`\n );\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(\"doesn't export a valid compressor\")\n ) {\n throw error;\n }\n return null;\n }\n}\n\n/**\n * Try to resolve a compressor from a local file path.\n *\n * @param name - The local file path (e.g., \"./my-compressor.js\")\n * @returns The resolved CompressorResolution if found, or `null` if not a local path\n * @throws Error if the file is found but doesn't export a valid compressor\n */\nexport async function tryResolveLocalFile(\n name: string\n): Promise<CompressorResolution | null> {\n if (!isLocalPath(name)) {\n return null;\n }\n\n try {\n const absolutePath = path.resolve(process.cwd(), name);\n const fileUrl = pathToFileURL(absolutePath).href;\n const mod = (await import(fileUrl)) as Record<string, unknown>;\n const compressor = extractCompressor(mod, name);\n\n if (compressor) {\n return {\n compressor,\n label: generateLabel(name),\n isBuiltIn: false,\n };\n }\n\n throw new Error(\n `Local file '${name}' doesn't export a valid compressor function. ` +\n `Expected a function as default export or named export 'compressor'.`\n );\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(\"doesn't export a valid compressor\")\n ) {\n throw error;\n }\n throw new Error(\n `Could not load local compressor '${name}'. ` +\n `File not found or failed to import: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\n/**\n * Resolve a compressor by name from a built-in @node-minify package, an installed npm package, or a local file path.\n *\n * @param name - Compressor identifier: a built-in name (e.g., \"terser\"), an npm package name, or a local path (e.g., \"./compressor.js\")\n * @returns The resolved CompressorResolution containing the compressor function, a display `label`, and `isBuiltIn` flag\n * @throws Error if the compressor cannot be found or the module does not export a valid compressor function\n */\nexport async function resolveCompressor(\n name: string\n): Promise<CompressorResolution> {\n // 1. Try built-in @node-minify package\n const builtIn = await tryResolveBuiltIn(name);\n if (builtIn) {\n return builtIn;\n }\n\n // 2. Try as npm package\n const npmPackage = await tryResolveNpmPackage(name);\n if (npmPackage) {\n return npmPackage;\n }\n\n // 3. Try as local file path (throws if file exists but has invalid exports)\n if (isLocalPath(name)) {\n const localFile = await tryResolveLocalFile(name);\n if (localFile) {\n return localFile;\n }\n // tryResolveLocalFile throws for local paths that can't be loaded,\n // so reaching here means it returned null (which shouldn't happen\n // after the isLocalPath guard, but we handle it defensively)\n }\n\n throw new Error(\n `Could not resolve compressor '${name}'. ` +\n `Is it installed? For local files, use a path starting with './' or '/'.`\n );\n}\n\n/**\n * Determines whether a compressor name corresponds to a known built-in compressor.\n *\n * @param name - The compressor identifier (e.g., built-in package name or alias)\n * @returns `true` if the name corresponds to a known built-in compressor, `false` otherwise.\n */\nexport function isBuiltInCompressor(name: string): boolean {\n return name in KNOWN_COMPRESSOR_EXPORTS;\n}\n\n/**\n * Return the known exported symbol name for a built-in compressor package.\n *\n * @param name - The compressor package name (for example, `\"esbuild\"`, `\"terser\"`)\n * @returns The export name used by the built-in package, or `undefined` if the compressor is not a known built-in\n */\nexport function getKnownExportName(name: string): string | undefined {\n return KNOWN_COMPRESSOR_EXPORTS[name];\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,MAAM,2BAAmD;CACrD,SAAS;CACT,2BAA2B;CAC3B,KAAK;CACL,KAAK;CACL,QAAQ;CACR,aAAa;CACb,gBAAgB;CAChB,aAAa;CACb,KAAK;CACL,aAAa;CACb,SAAS;CACT,MAAM;CACN,cAAc;CACd,OAAO;CACP,QAAQ;CACR,iBAAiB;CACjB,eAAe;CACf,YAAY;CACZ,UAAU;CACV,OAAO;CACP,MAAM;CACN,eAAe;CAClB;;;;;;;AA4BD,SAAgB,YAAY,MAAuB;AAC/C,QACI,KAAK,WAAW,KAAK,IACrB,KAAK,WAAW,MAAM,IACtB,KAAK,WAAW,IAAI,IACpB,kBAAkB,KAAK,KAAK;;;;;;;;AAUpC,SAAS,YAAY,MAAsB;AACvC,QAAO,KAAK,QAAQ,aAAa,GAAG,SAAS,KAAK,aAAa,CAAC;;;;;;;;;AAUpE,SAAS,kBACL,KACA,MACiB;CACjB,MAAM,cAAc,yBAAyB;AAC7C,KAAI,eAAe,OAAO,IAAI,iBAAiB,WAC3C,QAAO,IAAI;CAMf,MAAM,YAAY,YAHD,KAAK,SAAS,IAAI,GAC5B,KAAK,MAAM,IAAI,CAAC,KAAK,IAAI,OAC1B,KACiC;AACvC,KAAI,OAAO,IAAI,eAAe,WAC1B,QAAO,IAAI;AAGf,KAAI,OAAO,IAAI,eAAe,WAC1B,QAAO,IAAI;AAGf,KAAI,OAAO,IAAI,YAAY,WACvB,QAAO,IAAI;AAGf,MAAK,MAAM,SAAS,OAAO,OAAO,IAAI,CAClC,KAAI,OAAO,UAAU,WACjB,QAAO;AAIf,QAAO;;;;;;;;AASX,SAAS,cAAc,MAAsB;AACzC,KAAI,YAAY,KAAK,CACjB,QAAO,KAAK,SAAS,KAAK,CAAC,QAAQ,sBAAsB,GAAG;AAEhE,QAAO;;;;;;;;AASX,eAAsB,kBAClB,MACoC;AACpC,KAAI,EAAE,QAAQ,0BACV,QAAO;AAGX,KAAI;EAKA,MAAM,aAAa,kBAJN,MAAM,OAAO,gBAAgB,SAIA,KAAK;AAE/C,MAAI,WACA,QAAO;GACH;GACA,OAAO;GACP,WAAW;GACd;SAED;AAIR,QAAO;;;;;;;;;AAUX,eAAsB,qBAClB,MACoC;AACpC,KAAI;EAEA,MAAM,aAAa,kBADN,MAAM,OAAO,OACgB,KAAK;AAE/C,MAAI,WACA,QAAO;GACH;GACA,OAAO,cAAc,KAAK;GAC1B,WAAW;GACd;AAGL,QAAM,IAAI,MACN,YAAY,KAAK,mIAEI,YAAY,KAAK,CAAC,IAC1C;UACI,OAAO;AACZ,MACI,iBAAiB,SACjB,MAAM,QAAQ,SAAS,oCAAoC,CAE3D,OAAM;AAEV,SAAO;;;;;;;;;;AAWf,eAAsB,oBAClB,MACoC;AACpC,KAAI,CAAC,YAAY,KAAK,CAClB,QAAO;AAGX,KAAI;EAIA,MAAM,aAAa,kBADN,MAAM,OADH,cADK,KAAK,QAAQ,QAAQ,KAAK,EAAE,KAAK,CACX,CAAC,OAEF,KAAK;AAE/C,MAAI,WACA,QAAO;GACH;GACA,OAAO,cAAc,KAAK;GAC1B,WAAW;GACd;AAGL,QAAM,IAAI,MACN,eAAe,KAAK,mHAEvB;UACI,OAAO;AACZ,MACI,iBAAiB,SACjB,MAAM,QAAQ,SAAS,oCAAoC,CAE3D,OAAM;AAEV,QAAM,IAAI,MACN,oCAAoC,KAAK,yCACE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,GACpG;;;;;;;;;;AAWT,eAAsB,kBAClB,MAC6B;CAE7B,MAAM,UAAU,MAAM,kBAAkB,KAAK;AAC7C,KAAI,QACA,QAAO;CAIX,MAAM,aAAa,MAAM,qBAAqB,KAAK;AACnD,KAAI,WACA,QAAO;AAIX,KAAI,YAAY,KAAK,EAAE;EACnB,MAAM,YAAY,MAAM,oBAAoB,KAAK;AACjD,MAAI,UACA,QAAO;;AAOf,OAAM,IAAI,MACN,iCAAiC,KAAK,4EAEzC;;;;;;;;AASL,SAAgB,oBAAoB,MAAuB;AACvD,QAAO,QAAQ;;;;;;;;AASnB,SAAgB,mBAAmB,MAAkC;AACjE,QAAO,yBAAyB"}
@@ -1,7 +1,7 @@
1
1
  //#region src/deleteFile.d.ts
2
2
  /*!
3
3
  * node-minify
4
- * Copyright(c) 2011-2025 Rodolphe Stoclin
4
+ * Copyright (c) 2011-2026 Rodolphe Stoclin
5
5
  * MIT Licensed
6
6
  */
7
7
  /**
@@ -1,10 +1,10 @@
1
- import { t as FileOperationError } from "./error-Ck87RwDD.js";
1
+ import { t as FileOperationError } from "./error-CUgKxOvI.js";
2
2
  import { existsSync, unlinkSync } from "node:fs";
3
3
 
4
4
  //#region src/deleteFile.ts
5
5
  /*!
6
6
  * node-minify
7
- * Copyright(c) 2011-2025 Rodolphe Stoclin
7
+ * Copyright (c) 2011-2026 Rodolphe Stoclin
8
8
  * MIT Licensed
9
9
  */
10
10
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"deleteFile.js","names":[],"sources":["../src/deleteFile.ts"],"sourcesContent":["/*!\n * node-minify\n * Copyright(c) 2011-2025 Rodolphe Stoclin\n * MIT Licensed\n */\n\nimport { existsSync, unlinkSync } from \"node:fs\";\nimport { FileOperationError } from \"./error.ts\";\n\n/**\n * Delete file from the filesystem.\n * @param file Path to the file to delete\n * @throws {FileOperationError} If file doesn't exist or deletion fails\n * @example\n * deleteFile('path/to/file.js')\n */\nexport function deleteFile(file: string): void {\n try {\n if (!existsSync(file)) {\n throw new Error(\"File does not exist\");\n }\n unlinkSync(file);\n } catch (error) {\n throw new FileOperationError(\"delete\", file, error as Error);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,SAAgB,WAAW,MAAoB;AAC3C,KAAI;AACA,MAAI,CAAC,WAAW,KAAK,CACjB,OAAM,IAAI,MAAM,sBAAsB;AAE1C,aAAW,KAAK;UACX,OAAO;AACZ,QAAM,IAAI,mBAAmB,UAAU,MAAM,MAAe"}
1
+ {"version":3,"file":"deleteFile.js","names":[],"sources":["../src/deleteFile.ts"],"sourcesContent":["/*!\n * node-minify\n * Copyright (c) 2011-2026 Rodolphe Stoclin\n * MIT Licensed\n */\n\nimport { existsSync, unlinkSync } from \"node:fs\";\nimport { FileOperationError } from \"./error.ts\";\n\n/**\n * Delete file from the filesystem.\n * @param file Path to the file to delete\n * @throws {FileOperationError} If file doesn't exist or deletion fails\n * @example\n * deleteFile('path/to/file.js')\n */\nexport function deleteFile(file: string): void {\n try {\n if (!existsSync(file)) {\n throw new Error(\"File does not exist\");\n }\n unlinkSync(file);\n } catch (error) {\n throw new FileOperationError(\"delete\", file, error as Error);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,SAAgB,WAAW,MAAoB;AAC3C,KAAI;AACA,MAAI,CAAC,WAAW,KAAK,CACjB,OAAM,IAAI,MAAM,sBAAsB;AAE1C,aAAW,KAAK;UACX,OAAO;AACZ,QAAM,IAAI,mBAAmB,UAAU,MAAM,MAAe"}
@@ -1,7 +1,7 @@
1
1
  //#region src/deprecation.d.ts
2
2
  /*!
3
3
  * node-minify
4
- * Copyright(c) 2011-2025 Rodolphe Stoclin
4
+ * Copyright (c) 2011-2026 Rodolphe Stoclin
5
5
  * MIT Licensed
6
6
  */
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  //#region src/deprecation.ts
2
2
  /*!
3
3
  * node-minify
4
- * Copyright(c) 2011-2025 Rodolphe Stoclin
4
+ * Copyright (c) 2011-2026 Rodolphe Stoclin
5
5
  * MIT Licensed
6
6
  */
7
7
  const warnedPackages = /* @__PURE__ */ new Set();
@@ -1 +1 @@
1
- {"version":3,"file":"deprecation.js","names":[],"sources":["../src/deprecation.ts"],"sourcesContent":["/*!\n * node-minify\n * Copyright(c) 2011-2025 Rodolphe Stoclin\n * MIT Licensed\n */\n\nconst warnedPackages = new Set<string>();\n\n/**\n * Show a deprecation warning for a package, but only once per process.\n * Subsequent calls with the same package name will be ignored.\n *\n * @param packageName - The package name (e.g., \"babel-minify\", \"uglify-es\")\n * @param message - The deprecation message explaining why and what to use instead\n *\n * @example\n * ```ts\n * warnDeprecation(\n * \"babel-minify\",\n * \"babel-minify uses Babel 6 which is no longer maintained. \" +\n * \"Please migrate to @node-minify/terser for continued support.\"\n * );\n * ```\n */\nexport function warnDeprecation(packageName: string, message: string): void {\n if (warnedPackages.has(packageName)) {\n return;\n }\n\n warnedPackages.add(packageName);\n console.warn(`[@node-minify/${packageName}] DEPRECATED: ${message}`);\n}\n\n/**\n * Reset the deprecation warning state.\n * Only intended for testing purposes.\n */\nexport function resetDeprecationWarnings(): void {\n warnedPackages.clear();\n}\n"],"mappings":";;;;;;AAMA,MAAM,iCAAiB,IAAI,KAAa;;;;;;;;;;;;;;;;;AAkBxC,SAAgB,gBAAgB,aAAqB,SAAuB;AACxE,KAAI,eAAe,IAAI,YAAY,CAC/B;AAGJ,gBAAe,IAAI,YAAY;AAC/B,SAAQ,KAAK,iBAAiB,YAAY,gBAAgB,UAAU;;;;;;AAOxE,SAAgB,2BAAiC;AAC7C,gBAAe,OAAO"}
1
+ {"version":3,"file":"deprecation.js","names":[],"sources":["../src/deprecation.ts"],"sourcesContent":["/*!\n * node-minify\n * Copyright (c) 2011-2026 Rodolphe Stoclin\n * MIT Licensed\n */\n\nconst warnedPackages = new Set<string>();\n\n/**\n * Show a deprecation warning for a package, but only once per process.\n * Subsequent calls with the same package name will be ignored.\n *\n * @param packageName - The package name (e.g., \"babel-minify\", \"uglify-es\")\n * @param message - The deprecation message explaining why and what to use instead\n *\n * @example\n * ```ts\n * warnDeprecation(\n * \"babel-minify\",\n * \"babel-minify uses Babel 6 which is no longer maintained. \" +\n * \"Please migrate to @node-minify/terser for continued support.\"\n * );\n * ```\n */\nexport function warnDeprecation(packageName: string, message: string): void {\n if (warnedPackages.has(packageName)) {\n return;\n }\n\n warnedPackages.add(packageName);\n console.warn(`[@node-minify/${packageName}] DEPRECATED: ${message}`);\n}\n\n/**\n * Reset the deprecation warning state.\n * Only intended for testing purposes.\n */\nexport function resetDeprecationWarnings(): void {\n warnedPackages.clear();\n}\n"],"mappings":";;;;;;AAMA,MAAM,iCAAiB,IAAI,KAAa;;;;;;;;;;;;;;;;;AAkBxC,SAAgB,gBAAgB,aAAqB,SAAuB;AACxE,KAAI,eAAe,IAAI,YAAY,CAC/B;AAGJ,gBAAe,IAAI,YAAY;AAC/B,SAAQ,KAAK,iBAAiB,YAAY,gBAAgB,UAAU;;;;;;AAOxE,SAAgB,2BAAiC;AAC7C,gBAAe,OAAO"}
@@ -1,7 +1,7 @@
1
1
  //#region src/ensureStringContent.d.ts
2
2
  /*!
3
3
  * node-minify
4
- * Copyright(c) 2011-2025 Rodolphe Stoclin
4
+ * Copyright (c) 2011-2026 Rodolphe Stoclin
5
5
  * MIT Licensed
6
6
  */
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  //#region src/ensureStringContent.ts
2
2
  /*!
3
3
  * node-minify
4
- * Copyright(c) 2011-2025 Rodolphe Stoclin
4
+ * Copyright (c) 2011-2026 Rodolphe Stoclin
5
5
  * MIT Licensed
6
6
  */
7
7
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ensureStringContent.js","names":[],"sources":["../src/ensureStringContent.ts"],"sourcesContent":["/*!\n * node-minify\n * Copyright(c) 2011-2025 Rodolphe Stoclin\n * MIT Licensed\n */\n\n/**\n * Convert provided content to a string suitable for text-based compressors.\n *\n * @param content - The input content; a `Buffer` is converted to a string, `undefined` becomes an empty string, and a `Buffer[]` is rejected.\n * @param compressorName - Name used in the error message when array content is not supported.\n * @returns The content as a string; returns an empty string when `content` is `undefined`.\n * @throws Error if `content` is an array with message \"`<compressorName> compressor does not support array content`\".\n */\nexport function ensureStringContent(\n content: string | Buffer | Buffer[] | undefined,\n compressorName: string\n): string {\n if (Array.isArray(content)) {\n throw new Error(\n `${compressorName} compressor does not support array content`\n );\n }\n\n if (Buffer.isBuffer(content)) {\n return content.toString();\n }\n\n return content ?? \"\";\n}\n"],"mappings":";;;;;;;;;;;;;;AAcA,SAAgB,oBACZ,SACA,gBACM;AACN,KAAI,MAAM,QAAQ,QAAQ,CACtB,OAAM,IAAI,MACN,GAAG,eAAe,4CACrB;AAGL,KAAI,OAAO,SAAS,QAAQ,CACxB,QAAO,QAAQ,UAAU;AAG7B,QAAO,WAAW"}
1
+ {"version":3,"file":"ensureStringContent.js","names":[],"sources":["../src/ensureStringContent.ts"],"sourcesContent":["/*!\n * node-minify\n * Copyright (c) 2011-2026 Rodolphe Stoclin\n * MIT Licensed\n */\n\n/**\n * Convert provided content to a string suitable for text-based compressors.\n *\n * @param content - The input content; a `Buffer` is converted to a string, `undefined` becomes an empty string, and a `Buffer[]` is rejected.\n * @param compressorName - Name used in the error message when array content is not supported.\n * @returns The content as a string; returns an empty string when `content` is `undefined`.\n * @throws Error if `content` is an array with message \"`<compressorName> compressor does not support array content`\".\n */\nexport function ensureStringContent(\n content: string | Buffer | Buffer[] | undefined,\n compressorName: string\n): string {\n if (Array.isArray(content)) {\n throw new Error(\n `${compressorName} compressor does not support array content`\n );\n }\n\n if (Buffer.isBuffer(content)) {\n return content.toString();\n }\n\n return content ?? \"\";\n}\n"],"mappings":";;;;;;;;;;;;;;AAcA,SAAgB,oBACZ,SACA,gBACM;AACN,KAAI,MAAM,QAAQ,QAAQ,CACtB,OAAM,IAAI,MACN,GAAG,eAAe,4CACrB;AAGL,KAAI,OAAO,SAAS,QAAQ,CACxB,QAAO,QAAQ,UAAU;AAG7B,QAAO,WAAW"}
@@ -1,7 +1,7 @@
1
1
  //#region src/error.ts
2
2
  /*!
3
3
  * node-minify
4
- * Copyright(c) 2011-2025 Rodolphe Stoclin
4
+ * Copyright (c) 2011-2026 Rodolphe Stoclin
5
5
  * MIT Licensed
6
6
  */
7
7
  /**
@@ -9,9 +9,11 @@
9
9
  * @extends Error
10
10
  */
11
11
  var FileOperationError = class extends Error {
12
+ cause;
12
13
  constructor(operation, path, originalError) {
13
- super(`Failed to ${operation} file ${path}: ${originalError?.message || ""}`);
14
+ super(`Failed to ${operation} file ${path}: ${originalError?.message || ""}`, originalError ? { cause: originalError } : void 0);
14
15
  this.name = "FileOperationError";
16
+ if (originalError && !this.cause) this.cause = originalError;
15
17
  }
16
18
  };
17
19
  /**
@@ -27,4 +29,4 @@ var ValidationError = class extends Error {
27
29
 
28
30
  //#endregion
29
31
  export { ValidationError as n, FileOperationError as t };
30
- //# sourceMappingURL=error-Ck87RwDD.js.map
32
+ //# sourceMappingURL=error-CUgKxOvI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-CUgKxOvI.js","names":[],"sources":["../src/error.ts"],"sourcesContent":["/*!\n * node-minify\n * Copyright (c) 2011-2026 Rodolphe Stoclin\n * MIT Licensed\n */\n\n/**\n * Error class for file operation failures.\n * @extends Error\n */\nexport class FileOperationError extends Error {\n override cause?: Error;\n\n constructor(operation: string, path: string, originalError?: Error) {\n super(\n `Failed to ${operation} file ${path}: ${originalError?.message || \"\"}`,\n originalError ? { cause: originalError } : undefined\n );\n this.name = \"FileOperationError\";\n // For older runtimes that don't support the cause option\n if (originalError && !this.cause) {\n this.cause = originalError;\n }\n }\n}\n\n/**\n * Error class for validation failures.\n * @extends Error\n */\nexport class ValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ValidationError\";\n }\n}\n"],"mappings":";;;;;;;;;;AAUA,IAAa,qBAAb,cAAwC,MAAM;CAC1C,AAAS;CAET,YAAY,WAAmB,MAAc,eAAuB;AAChE,QACI,aAAa,UAAU,QAAQ,KAAK,IAAI,eAAe,WAAW,MAClE,gBAAgB,EAAE,OAAO,eAAe,GAAG,OAC9C;AACD,OAAK,OAAO;AAEZ,MAAI,iBAAiB,CAAC,KAAK,MACvB,MAAK,QAAQ;;;;;;;AASzB,IAAa,kBAAb,cAAqC,MAAM;CACvC,YAAY,SAAiB;AACzB,QAAM,QAAQ;AACd,OAAK,OAAO"}
package/dist/error.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  //#region src/error.d.ts
2
2
  /*!
3
3
  * node-minify
4
- * Copyright(c) 2011-2025 Rodolphe Stoclin
4
+ * Copyright (c) 2011-2026 Rodolphe Stoclin
5
5
  * MIT Licensed
6
6
  */
7
7
  /**
@@ -9,6 +9,7 @@
9
9
  * @extends Error
10
10
  */
11
11
  declare class FileOperationError extends Error {
12
+ cause?: Error;
12
13
  constructor(operation: string, path: string, originalError?: Error);
13
14
  }
14
15
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"error.d.ts","names":[],"sources":["../src/error.ts"],"sourcesContent":[],"mappings":";;AAUA;AAaA;;;;;;;cAba,kBAAA,SAA2B,KAAA;+DACyB;;;;;;cAYpD,eAAA,SAAwB,KAAA"}
1
+ {"version":3,"file":"error.d.ts","names":[],"sources":["../src/error.ts"],"sourcesContent":[],"mappings":";;AAUA;;;;;AAoBA;;;cApBa,kBAAA,SAA2B,KAAA;UACnB;+DAE4C;;;;;;cAiBpD,eAAA,SAAwB,KAAA"}
package/dist/error.js CHANGED
@@ -1,3 +1,3 @@
1
- import { n as ValidationError, t as FileOperationError } from "./error-Ck87RwDD.js";
1
+ import { n as ValidationError, t as FileOperationError } from "./error-CUgKxOvI.js";
2
2
 
3
3
  export { FileOperationError, ValidationError };
@@ -0,0 +1,27 @@
1
+ //#region src/errors.d.ts
2
+ /*!
3
+ * node-minify
4
+ * Copyright (c) 2011-2026 Rodolphe Stoclin
5
+ * MIT Licensed
6
+ */
7
+ /**
8
+ * Wraps an error thrown during minification with a consistent, descriptive message.
9
+ *
10
+ * @param compressorName - The name of the compressor that failed
11
+ * @param error - The original error (unknown type for proper catch handling)
12
+ * @returns A new Error with a standardized message format
13
+ */
14
+ declare function wrapMinificationError(compressorName: string, error: unknown): Error;
15
+ /**
16
+ * Validates that a minification result contains valid output.
17
+ *
18
+ * @param result - The result object to validate
19
+ * @param compressorName - The name of the compressor (for error messages)
20
+ * @throws Error if result is falsy or result.code is not a string
21
+ */
22
+ declare function validateMinifyResult(result: unknown, compressorName: string): asserts result is {
23
+ code: string;
24
+ };
25
+ //#endregion
26
+ export { validateMinifyResult, wrapMinificationError };
27
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","names":[],"sources":["../src/errors.ts"],"sourcesContent":[],"mappings":";;AAaA;AAkBA;;;;;;;;;;iBAlBgB,qBAAA,0CAGb;;;;;;;;iBAea,oBAAA"}
package/dist/errors.js ADDED
@@ -0,0 +1,32 @@
1
+ //#region src/errors.ts
2
+ /*!
3
+ * node-minify
4
+ * Copyright (c) 2011-2026 Rodolphe Stoclin
5
+ * MIT Licensed
6
+ */
7
+ /**
8
+ * Wraps an error thrown during minification with a consistent, descriptive message.
9
+ *
10
+ * @param compressorName - The name of the compressor that failed
11
+ * @param error - The original error (unknown type for proper catch handling)
12
+ * @returns A new Error with a standardized message format
13
+ */
14
+ function wrapMinificationError(compressorName, error) {
15
+ const message = error instanceof Error ? error.message : String(error);
16
+ const cause = error instanceof Error ? error : void 0;
17
+ return new Error(`${compressorName} minification failed: ${message}`, { cause });
18
+ }
19
+ /**
20
+ * Validates that a minification result contains valid output.
21
+ *
22
+ * @param result - The result object to validate
23
+ * @param compressorName - The name of the compressor (for error messages)
24
+ * @throws Error if result is falsy or result.code is not a string
25
+ */
26
+ function validateMinifyResult(result, compressorName) {
27
+ if (!result || typeof result !== "object" || !("code" in result) || typeof result.code !== "string") throw new Error(`${compressorName} failed: empty or invalid result`);
28
+ }
29
+
30
+ //#endregion
31
+ export { validateMinifyResult, wrapMinificationError };
32
+ //# sourceMappingURL=errors.js.map