@meng-xi/vite-plugin 0.1.2 → 0.1.4

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 (106) hide show
  1. package/README-en.md +86 -510
  2. package/README.md +83 -506
  3. package/dist/common/compress/index.cjs +1 -0
  4. package/dist/common/compress/index.d.cts +23 -0
  5. package/dist/common/compress/index.d.mts +23 -0
  6. package/dist/common/compress/index.d.ts +23 -0
  7. package/dist/common/compress/index.mjs +1 -0
  8. package/dist/common/format/index.cjs +1 -1
  9. package/dist/common/format/index.d.cts +33 -1
  10. package/dist/common/format/index.d.mts +33 -1
  11. package/dist/common/format/index.d.ts +33 -1
  12. package/dist/common/format/index.mjs +1 -1
  13. package/dist/common/fs/index.cjs +1 -1
  14. package/dist/common/fs/index.d.cts +70 -2
  15. package/dist/common/fs/index.d.mts +70 -2
  16. package/dist/common/fs/index.d.ts +70 -2
  17. package/dist/common/fs/index.mjs +1 -1
  18. package/dist/common/html/index.cjs +2 -2
  19. package/dist/common/html/index.d.cts +268 -19
  20. package/dist/common/html/index.d.mts +268 -19
  21. package/dist/common/html/index.d.ts +268 -19
  22. package/dist/common/html/index.mjs +2 -2
  23. package/dist/common/index.cjs +1 -1
  24. package/dist/common/index.d.cts +8 -3
  25. package/dist/common/index.d.mts +8 -3
  26. package/dist/common/index.d.ts +8 -3
  27. package/dist/common/index.mjs +1 -1
  28. package/dist/common/path/index.cjs +1 -0
  29. package/dist/common/path/index.d.cts +22 -0
  30. package/dist/common/path/index.d.mts +22 -0
  31. package/dist/common/path/index.d.ts +22 -0
  32. package/dist/common/path/index.mjs +1 -0
  33. package/dist/common/ui/index.cjs +1 -0
  34. package/dist/common/ui/index.d.cts +132 -0
  35. package/dist/common/ui/index.d.mts +132 -0
  36. package/dist/common/ui/index.d.ts +132 -0
  37. package/dist/common/ui/index.mjs +1 -0
  38. package/dist/common/validation/index.cjs +1 -1
  39. package/dist/common/validation/index.d.cts +1 -0
  40. package/dist/common/validation/index.d.mts +1 -0
  41. package/dist/common/validation/index.d.ts +1 -0
  42. package/dist/common/validation/index.mjs +1 -1
  43. package/dist/index.cjs +1 -1
  44. package/dist/index.d.cts +11 -4
  45. package/dist/index.d.mts +11 -4
  46. package/dist/index.d.ts +11 -4
  47. package/dist/index.mjs +1 -1
  48. package/dist/plugins/buildProgress/index.cjs +2 -2
  49. package/dist/plugins/buildProgress/index.mjs +2 -2
  50. package/dist/plugins/bundleAnalyzer/index.cjs +235 -0
  51. package/dist/plugins/bundleAnalyzer/index.d.cts +215 -0
  52. package/dist/plugins/bundleAnalyzer/index.d.mts +215 -0
  53. package/dist/plugins/bundleAnalyzer/index.d.ts +215 -0
  54. package/dist/plugins/bundleAnalyzer/index.mjs +235 -0
  55. package/dist/plugins/compressAssets/index.cjs +1 -1
  56. package/dist/plugins/compressAssets/index.mjs +1 -1
  57. package/dist/plugins/copyFile/index.d.cts +20 -2
  58. package/dist/plugins/copyFile/index.d.mts +20 -2
  59. package/dist/plugins/copyFile/index.d.ts +20 -2
  60. package/dist/plugins/envGuard/index.cjs +67 -0
  61. package/dist/plugins/envGuard/index.d.cts +156 -0
  62. package/dist/plugins/envGuard/index.d.mts +156 -0
  63. package/dist/plugins/envGuard/index.d.ts +156 -0
  64. package/dist/plugins/envGuard/index.mjs +67 -0
  65. package/dist/plugins/faviconManager/index.cjs +1 -1
  66. package/dist/plugins/faviconManager/index.d.cts +43 -5
  67. package/dist/plugins/faviconManager/index.d.mts +43 -5
  68. package/dist/plugins/faviconManager/index.d.ts +43 -5
  69. package/dist/plugins/faviconManager/index.mjs +1 -1
  70. package/dist/plugins/generateRouter/index.cjs +4 -4
  71. package/dist/plugins/generateRouter/index.d.cts +61 -14
  72. package/dist/plugins/generateRouter/index.d.mts +61 -14
  73. package/dist/plugins/generateRouter/index.d.ts +61 -14
  74. package/dist/plugins/generateRouter/index.mjs +1 -1
  75. package/dist/plugins/generateVersion/index.cjs +1 -1
  76. package/dist/plugins/generateVersion/index.d.cts +12 -0
  77. package/dist/plugins/generateVersion/index.d.mts +12 -0
  78. package/dist/plugins/generateVersion/index.d.ts +12 -0
  79. package/dist/plugins/generateVersion/index.mjs +1 -1
  80. package/dist/plugins/htmlInject/index.cjs +1 -7
  81. package/dist/plugins/htmlInject/index.d.cts +49 -194
  82. package/dist/plugins/htmlInject/index.d.mts +49 -194
  83. package/dist/plugins/htmlInject/index.d.ts +49 -194
  84. package/dist/plugins/htmlInject/index.mjs +1 -7
  85. package/dist/plugins/index.cjs +1 -1
  86. package/dist/plugins/index.d.cts +5 -1
  87. package/dist/plugins/index.d.mts +5 -1
  88. package/dist/plugins/index.d.ts +5 -1
  89. package/dist/plugins/index.mjs +1 -1
  90. package/dist/plugins/loadingManager/index.cjs +2 -2
  91. package/dist/plugins/loadingManager/index.mjs +1 -1
  92. package/dist/plugins/versionUpdateChecker/index.cjs +2 -2
  93. package/dist/plugins/versionUpdateChecker/index.mjs +3 -3
  94. package/dist/shared/vite-plugin.BCuhU1au.mjs +7 -0
  95. package/dist/shared/vite-plugin.BrI73DHA.cjs +7 -0
  96. package/dist/shared/vite-plugin.CmtcnItg.d.cts +261 -0
  97. package/dist/shared/vite-plugin.CmtcnItg.d.mts +261 -0
  98. package/dist/shared/vite-plugin.CmtcnItg.d.ts +261 -0
  99. package/dist/shared/vite-plugin.DnFDPjNf.mjs +1 -0
  100. package/dist/shared/vite-plugin.Dumot0up.mjs +1 -0
  101. package/dist/shared/vite-plugin.FfJ-Wwfu.d.cts +143 -0
  102. package/dist/shared/vite-plugin.FfJ-Wwfu.d.mts +143 -0
  103. package/dist/shared/vite-plugin.FfJ-Wwfu.d.ts +143 -0
  104. package/dist/shared/vite-plugin.soT9a-KD.cjs +1 -0
  105. package/dist/shared/vite-plugin.vwox4bU0.cjs +1 -0
  106. package/package.json +26 -1
@@ -0,0 +1 @@
1
+ "use strict";const node_zlib=require("node:zlib"),promises=require("node:stream/promises"),node_stream=require("node:stream");async function calculateGzipSize(e){const t=typeof e=="string"?Buffer.from(e,"utf-8"):e,r=[],n=node_zlib.createGzip({level:9}),o=new node_stream.Transform({transform(s,a,i){r.push(s),i()}});return await promises.pipeline(node_stream.Readable.from(t),n,o),Buffer.concat(r).length}exports.calculateGzipSize=calculateGzipSize;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * 计算给定数据的 gzip 压缩后大小
3
+ *
4
+ * @async
5
+ * @param {Buffer | string} data - 待计算的数据
6
+ * @returns {Promise<number>} gzip 压缩后的字节大小
7
+ *
8
+ * @description 将数据通过 gzip 流压缩后计算压缩体积,
9
+ * 用于估算网络传输时的实际体积。
10
+ * 使用最高压缩级别(level: 9)以获得最小的压缩体积。
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const gzipSize = await calculateGzipSize(Buffer.from('hello world'))
15
+ * console.log(`gzip 大小: ${gzipSize} 字节`)
16
+ *
17
+ * const stringData = 'some long string content...'
18
+ * const size = await calculateGzipSize(stringData)
19
+ * ```
20
+ */
21
+ declare function calculateGzipSize(data: Buffer | string): Promise<number>;
22
+
23
+ export { calculateGzipSize };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * 计算给定数据的 gzip 压缩后大小
3
+ *
4
+ * @async
5
+ * @param {Buffer | string} data - 待计算的数据
6
+ * @returns {Promise<number>} gzip 压缩后的字节大小
7
+ *
8
+ * @description 将数据通过 gzip 流压缩后计算压缩体积,
9
+ * 用于估算网络传输时的实际体积。
10
+ * 使用最高压缩级别(level: 9)以获得最小的压缩体积。
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const gzipSize = await calculateGzipSize(Buffer.from('hello world'))
15
+ * console.log(`gzip 大小: ${gzipSize} 字节`)
16
+ *
17
+ * const stringData = 'some long string content...'
18
+ * const size = await calculateGzipSize(stringData)
19
+ * ```
20
+ */
21
+ declare function calculateGzipSize(data: Buffer | string): Promise<number>;
22
+
23
+ export { calculateGzipSize };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * 计算给定数据的 gzip 压缩后大小
3
+ *
4
+ * @async
5
+ * @param {Buffer | string} data - 待计算的数据
6
+ * @returns {Promise<number>} gzip 压缩后的字节大小
7
+ *
8
+ * @description 将数据通过 gzip 流压缩后计算压缩体积,
9
+ * 用于估算网络传输时的实际体积。
10
+ * 使用最高压缩级别(level: 9)以获得最小的压缩体积。
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const gzipSize = await calculateGzipSize(Buffer.from('hello world'))
15
+ * console.log(`gzip 大小: ${gzipSize} 字节`)
16
+ *
17
+ * const stringData = 'some long string content...'
18
+ * const size = await calculateGzipSize(stringData)
19
+ * ```
20
+ */
21
+ declare function calculateGzipSize(data: Buffer | string): Promise<number>;
22
+
23
+ export { calculateGzipSize };
@@ -0,0 +1 @@
1
+ import{createGzip as i}from"node:zlib";import{pipeline as p}from"node:stream/promises";import{Transform as m,Readable as c}from"node:stream";async function l(e){const o=typeof e=="string"?Buffer.from(e,"utf-8"):e,r=[],t=i({level:9}),f=new m({transform(n,u,a){r.push(n),a()}});return await p(c.from(o),t,f),Buffer.concat(r).length}export{l as calculateGzipSize};
@@ -1 +1 @@
1
- "use strict";const crypto=require("crypto");function padNumber(e,t=2){return e.toString().padStart(t,"0")}function generateRandomHash(e=8){const t=Math.max(1,Math.min(64,e));return crypto.randomBytes(Math.ceil(t/2)).toString("hex").slice(0,t)}function getDateFormatParams(e=new Date){return{YYYY:e.getFullYear().toString(),YY:e.getFullYear().toString().slice(-2),MM:padNumber(e.getMonth()+1),DD:padNumber(e.getDate()),HH:padNumber(e.getHours()),mm:padNumber(e.getMinutes()),ss:padNumber(e.getSeconds()),SSS:padNumber(e.getMilliseconds(),3),timestamp:e.getTime().toString()}}function formatDate(e,t){const r=getDateFormatParams(e);let a=t;for(const[o,n]of Object.entries(r))a=a.replace(new RegExp(`\\{${o}\\}`,"g"),n);return a}function parseTemplate(e,t){let r=e;for(const[a,o]of Object.entries(t))r=r.replace(new RegExp(`\\{${a}\\}`,"g"),o);return r}function toCamelCase(e,t=/[/-]/){return e.replace(/^\/+/,"").split(t).filter(Boolean).map((r,a)=>a===0?r.toLowerCase():r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join("")}function toPascalCase(e,t=/[/-]/){return e.replace(/^\/+/,"").split(t).filter(Boolean).map(r=>r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join("")}function stripJsonComments(e){return e.replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,"")}function escapeHtmlAttr(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}exports.escapeHtmlAttr=escapeHtmlAttr,exports.formatDate=formatDate,exports.generateRandomHash=generateRandomHash,exports.getDateFormatParams=getDateFormatParams,exports.padNumber=padNumber,exports.parseTemplate=parseTemplate,exports.stripJsonComments=stripJsonComments,exports.toCamelCase=toCamelCase,exports.toPascalCase=toPascalCase;
1
+ "use strict";const crypto=require("crypto"),a=require("node:path");function _interopDefaultCompat(e){return e&&typeof e=="object"&&"default"in e?e.default:e}const a__default=_interopDefaultCompat(a);function padNumber(e,t=2){return e.toString().padStart(t,"0")}function generateRandomHash(e=8){const t=Math.max(1,Math.min(64,e));return crypto.randomBytes(Math.ceil(t/2)).toString("hex").slice(0,t)}function getDateFormatParams(e=new Date){return{YYYY:e.getFullYear().toString(),YY:e.getFullYear().toString().slice(-2),MM:padNumber(e.getMonth()+1),DD:padNumber(e.getDate()),HH:padNumber(e.getHours()),mm:padNumber(e.getMinutes()),ss:padNumber(e.getSeconds()),SSS:padNumber(e.getMilliseconds(),3),timestamp:e.getTime().toString()}}function formatDate(e,t){const r=getDateFormatParams(e);let o=t;for(const[n,s]of Object.entries(r))o=o.replace(new RegExp(`\\{${n}\\}`,"g"),s);return o}function parseTemplate(e,t){let r=e;for(const[o,n]of Object.entries(t))r=r.replace(new RegExp(`\\{${o}\\}`,"g"),n);return r}function toCamelCase(e,t=/[/-]/){return e.replace(/^\/+/,"").split(t).filter(Boolean).map((r,o)=>o===0?r.toLowerCase():r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join("")}function toPascalCase(e,t=/[/-]/){return e.replace(/^\/+/,"").split(t).filter(Boolean).map(r=>r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join("")}function stripJsonComments(e){return e.replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,"")}function escapeHtmlAttr(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function formatFileSize(e){return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/(1024*1024)).toFixed(2)}MB`}function getExtension(e){return a__default.extname(e).toLowerCase()}exports.escapeHtmlAttr=escapeHtmlAttr,exports.formatDate=formatDate,exports.formatFileSize=formatFileSize,exports.generateRandomHash=generateRandomHash,exports.getDateFormatParams=getDateFormatParams,exports.getExtension=getExtension,exports.padNumber=padNumber,exports.parseTemplate=parseTemplate,exports.stripJsonComments=stripJsonComments,exports.toCamelCase=toCamelCase,exports.toPascalCase=toPascalCase;
@@ -151,6 +151,38 @@ declare function stripJsonComments(jsonString: string): string;
151
151
  * ```
152
152
  */
153
153
  declare function escapeHtmlAttr(str: string): string;
154
+ /**
155
+ * 将字节数格式化为人类可读的文件大小字符串
156
+ *
157
+ * @param {number} bytes - 文件大小(字节)
158
+ * @returns {string} 格式化后的文件大小字符串
159
+ *
160
+ * @description 转换规则:
161
+ * - 小于 1KB:显示为 `xB`(如 `512B`)
162
+ * - 小于 1MB:显示为 `x.xKB`(如 `1.5KB`)
163
+ * - 大于等于 1MB:显示为 `x.xxMB`(如 `2.35MB`)
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * formatFileSize(512) // '512B'
168
+ * formatFileSize(1536) // '1.5KB'
169
+ * formatFileSize(2461726) // '2.35MB'
170
+ * ```
171
+ */
172
+ declare function formatFileSize(bytes: number): string;
173
+ /**
174
+ * 获取文件扩展名
175
+ *
176
+ * @param {string} filePath - 文件路径
177
+ * @returns {string} 小写的文件扩展名(如 '.js')
178
+ *
179
+ * @example
180
+ * ```typescript
181
+ * getExtension('dist/app.js') // '.js'
182
+ * getExtension('dist/style.CSS') // '.css'
183
+ * ```
184
+ */
185
+ declare function getExtension(filePath: string): string;
154
186
 
155
- export { escapeHtmlAttr, formatDate, generateRandomHash, getDateFormatParams, padNumber, parseTemplate, stripJsonComments, toCamelCase, toPascalCase };
187
+ export { escapeHtmlAttr, formatDate, formatFileSize, generateRandomHash, getDateFormatParams, getExtension, padNumber, parseTemplate, stripJsonComments, toCamelCase, toPascalCase };
156
188
  export type { DateFormatOptions };
@@ -151,6 +151,38 @@ declare function stripJsonComments(jsonString: string): string;
151
151
  * ```
152
152
  */
153
153
  declare function escapeHtmlAttr(str: string): string;
154
+ /**
155
+ * 将字节数格式化为人类可读的文件大小字符串
156
+ *
157
+ * @param {number} bytes - 文件大小(字节)
158
+ * @returns {string} 格式化后的文件大小字符串
159
+ *
160
+ * @description 转换规则:
161
+ * - 小于 1KB:显示为 `xB`(如 `512B`)
162
+ * - 小于 1MB:显示为 `x.xKB`(如 `1.5KB`)
163
+ * - 大于等于 1MB:显示为 `x.xxMB`(如 `2.35MB`)
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * formatFileSize(512) // '512B'
168
+ * formatFileSize(1536) // '1.5KB'
169
+ * formatFileSize(2461726) // '2.35MB'
170
+ * ```
171
+ */
172
+ declare function formatFileSize(bytes: number): string;
173
+ /**
174
+ * 获取文件扩展名
175
+ *
176
+ * @param {string} filePath - 文件路径
177
+ * @returns {string} 小写的文件扩展名(如 '.js')
178
+ *
179
+ * @example
180
+ * ```typescript
181
+ * getExtension('dist/app.js') // '.js'
182
+ * getExtension('dist/style.CSS') // '.css'
183
+ * ```
184
+ */
185
+ declare function getExtension(filePath: string): string;
154
186
 
155
- export { escapeHtmlAttr, formatDate, generateRandomHash, getDateFormatParams, padNumber, parseTemplate, stripJsonComments, toCamelCase, toPascalCase };
187
+ export { escapeHtmlAttr, formatDate, formatFileSize, generateRandomHash, getDateFormatParams, getExtension, padNumber, parseTemplate, stripJsonComments, toCamelCase, toPascalCase };
156
188
  export type { DateFormatOptions };
@@ -151,6 +151,38 @@ declare function stripJsonComments(jsonString: string): string;
151
151
  * ```
152
152
  */
153
153
  declare function escapeHtmlAttr(str: string): string;
154
+ /**
155
+ * 将字节数格式化为人类可读的文件大小字符串
156
+ *
157
+ * @param {number} bytes - 文件大小(字节)
158
+ * @returns {string} 格式化后的文件大小字符串
159
+ *
160
+ * @description 转换规则:
161
+ * - 小于 1KB:显示为 `xB`(如 `512B`)
162
+ * - 小于 1MB:显示为 `x.xKB`(如 `1.5KB`)
163
+ * - 大于等于 1MB:显示为 `x.xxMB`(如 `2.35MB`)
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * formatFileSize(512) // '512B'
168
+ * formatFileSize(1536) // '1.5KB'
169
+ * formatFileSize(2461726) // '2.35MB'
170
+ * ```
171
+ */
172
+ declare function formatFileSize(bytes: number): string;
173
+ /**
174
+ * 获取文件扩展名
175
+ *
176
+ * @param {string} filePath - 文件路径
177
+ * @returns {string} 小写的文件扩展名(如 '.js')
178
+ *
179
+ * @example
180
+ * ```typescript
181
+ * getExtension('dist/app.js') // '.js'
182
+ * getExtension('dist/style.CSS') // '.css'
183
+ * ```
184
+ */
185
+ declare function getExtension(filePath: string): string;
154
186
 
155
- export { escapeHtmlAttr, formatDate, generateRandomHash, getDateFormatParams, padNumber, parseTemplate, stripJsonComments, toCamelCase, toPascalCase };
187
+ export { escapeHtmlAttr, formatDate, formatFileSize, generateRandomHash, getDateFormatParams, getExtension, padNumber, parseTemplate, stripJsonComments, toCamelCase, toPascalCase };
156
188
  export type { DateFormatOptions };
@@ -1 +1 @@
1
- import{randomBytes as i}from"crypto";function o(e,t=2){return e.toString().padStart(t,"0")}function l(e=8){const t=Math.max(1,Math.min(64,e));return i(Math.ceil(t/2)).toString("hex").slice(0,t)}function s(e=new Date){return{YYYY:e.getFullYear().toString(),YY:e.getFullYear().toString().slice(-2),MM:o(e.getMonth()+1),DD:o(e.getDate()),HH:o(e.getHours()),mm:o(e.getMinutes()),ss:o(e.getSeconds()),SSS:o(e.getMilliseconds(),3),timestamp:e.getTime().toString()}}function p(e,t){const r=s(e);let n=t;for(const[a,c]of Object.entries(r))n=n.replace(new RegExp(`\\{${a}\\}`,"g"),c);return n}function g(e,t){let r=e;for(const[n,a]of Object.entries(t))r=r.replace(new RegExp(`\\{${n}\\}`,"g"),a);return r}function m(e,t=/[/-]/){return e.replace(/^\/+/,"").split(t).filter(Boolean).map((r,n)=>n===0?r.toLowerCase():r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join("")}function u(e,t=/[/-]/){return e.replace(/^\/+/,"").split(t).filter(Boolean).map(r=>r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join("")}function f(e){return e.replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,"")}function S(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}export{S as escapeHtmlAttr,p as formatDate,l as generateRandomHash,s as getDateFormatParams,o as padNumber,g as parseTemplate,f as stripJsonComments,m as toCamelCase,u as toPascalCase};
1
+ import{randomBytes as c}from"crypto";import l from"node:path";function o(e,t=2){return e.toString().padStart(t,"0")}function p(e=8){const t=Math.max(1,Math.min(64,e));return c(Math.ceil(t/2)).toString("hex").slice(0,t)}function i(e=new Date){return{YYYY:e.getFullYear().toString(),YY:e.getFullYear().toString().slice(-2),MM:o(e.getMonth()+1),DD:o(e.getDate()),HH:o(e.getHours()),mm:o(e.getMinutes()),ss:o(e.getSeconds()),SSS:o(e.getMilliseconds(),3),timestamp:e.getTime().toString()}}function g(e,t){const r=i(e);let n=t;for(const[a,s]of Object.entries(r))n=n.replace(new RegExp(`\\{${a}\\}`,"g"),s);return n}function m(e,t){let r=e;for(const[n,a]of Object.entries(t))r=r.replace(new RegExp(`\\{${n}\\}`,"g"),a);return r}function u(e,t=/[/-]/){return e.replace(/^\/+/,"").split(t).filter(Boolean).map((r,n)=>n===0?r.toLowerCase():r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join("")}function f(e,t=/[/-]/){return e.replace(/^\/+/,"").split(t).filter(Boolean).map(r=>r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join("")}function S(e){return e.replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,"")}function C(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function x(e){return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/(1024*1024)).toFixed(2)}MB`}function M(e){return l.extname(e).toLowerCase()}export{C as escapeHtmlAttr,g as formatDate,x as formatFileSize,p as generateRandomHash,i as getDateFormatParams,M as getExtension,o as padNumber,m as parseTemplate,S as stripJsonComments,u as toCamelCase,f as toPascalCase};
@@ -1 +1 @@
1
- "use strict";const s=require("fs"),u=require("path");function _interopDefaultCompat(t){return t&&typeof t=="object"&&"default"in t?t.default:t}const s__default=_interopDefaultCompat(s),u__default=_interopDefaultCompat(u),S=10;async function checkSourceExists(t){try{await s__default.promises.access(t,s__default.constants.F_OK)}catch(e){const r=e;throw r.code==="ENOENT"?new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u6E90\u6587\u4EF6\u4E0D\u5B58\u5728 - ${t}`):r.code==="EACCES"?new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u8BBF\u95EE\u6E90\u6587\u4EF6 - ${t}`):new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u68C0\u67E5\u6E90\u6587\u4EF6\u65F6\u51FA\u9519 - ${t}\uFF0C\u9519\u8BEF\uFF1A${r.message}`)}}async function ensureTargetDir(t){try{await s__default.promises.mkdir(t,{recursive:!0})}catch(e){const r=e;throw r.code==="EACCES"?new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u521B\u5EFA\u76EE\u6807\u76EE\u5F55 - ${t}`):new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u521B\u5EFA\u76EE\u6807\u76EE\u5F55\u65F6\u51FA\u9519 - ${t}\uFF0C\u9519\u8BEF\uFF1A${r.message}`)}}async function readDirRecursive(t,e){const r=await s__default.promises.readdir(t,{withFileTypes:!0}),i=[];for(const n of r){const c=u__default.join(t,n.name),l=n.isFile(),F=n.isDirectory();if(i.push({path:c,isFile:l,isDirectory:F}),F&&e){const E=await readDirRecursive(c,e);i.push(...E)}}return i}async function shouldUpdateFile(t,e){try{const[r,i]=await Promise.all([s__default.promises.stat(t),s__default.promises.stat(e)]);return r.mtimeMs>i.mtimeMs||r.size!==i.size}catch{return!0}}async function fileExists(t){try{return await s__default.promises.access(t,s__default.constants.F_OK),!0}catch{return!1}}async function runWithConcurrency(t,e,r){const i=[];let n=0;async function c(){for(;n<t.length;){const F=n++,E=await e(t[F]);i[F]=E}}const l=Array(Math.min(r,t.length)).fill(null).map(()=>c());return await Promise.all(l),i}async function copySourceToTarget(t,e,r){const i=Date.now(),{recursive:n,overwrite:c,incremental:l=!1,parallelLimit:F=S}=r;let E=0,f=0,m=0;if((await s__default.promises.stat(t)).isDirectory()){await ensureTargetDir(e);const a=await readDirRecursive(t,n),D=a.filter(o=>o.isFile);m=a.filter(o=>o.isDirectory).length;const y=new Set;for(const o of D){const d=u__default.relative(t,o.path),p=u__default.dirname(u__default.join(e,d));y.add(p)}await Promise.all([...y].map(o=>ensureTargetDir(o)));const h=await runWithConcurrency(D,async o=>{const d=u__default.relative(t,o.path),p=u__default.join(e,d);let w=c;return w||(w=!await fileExists(p)),l&&w&&(w=await shouldUpdateFile(o.path,p)),w?(await s__default.promises.copyFile(o.path,p),{copied:!0,skipped:!1}):{copied:!1,skipped:!0}},F);for(const o of h)o.copied&&E++,o.skipped&&f++}else{await ensureTargetDir(u__default.dirname(e));let a=c;a||(a=!await fileExists(e)),l&&a&&(a=await shouldUpdateFile(t,e)),a?(await s__default.promises.copyFile(t,e),E++):f++}const A=Date.now()-i;return{copiedFiles:E,skippedFiles:f,copiedDirs:m,executionTime:A}}async function writeFileContent(t,e){try{await s__default.promises.writeFile(t,e,"utf-8")}catch(r){const i=r;throw i.code==="EACCES"?new Error(`\u5199\u5165\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u5199\u5165\u6587\u4EF6 - ${t}`):new Error(`\u5199\u5165\u6587\u4EF6\u5931\u8D25\uFF1A\u5199\u5165\u6587\u4EF6\u65F6\u51FA\u9519 - ${t}\uFF0C\u9519\u8BEF\uFF1A${i.message}`)}}async function readFileContent(t){try{return await s__default.promises.readFile(t,"utf-8")}catch(e){const r=e;throw r.code==="EACCES"?new Error(`\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u8BFB\u53D6\u6587\u4EF6 - ${t}`):new Error(`\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25\uFF1A\u8BFB\u53D6\u6587\u4EF6\u65F6\u51FA\u9519 - ${t}\uFF0C\u9519\u8BEF\uFF1A${r.message}`)}}function readFileSync(t){try{return s__default.readFileSync(t,"utf-8")}catch(e){const r=e;throw r.code==="EACCES"?new Error(`\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u8BFB\u53D6\u6587\u4EF6 - ${t}`):new Error(`\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25\uFF1A\u8BFB\u53D6\u6587\u4EF6\u65F6\u51FA\u9519 - ${t}\uFF0C\u9519\u8BEF\uFF1A${r.message}`)}}exports.checkSourceExists=checkSourceExists,exports.copySourceToTarget=copySourceToTarget,exports.ensureTargetDir=ensureTargetDir,exports.fileExists=fileExists,exports.readDirRecursive=readDirRecursive,exports.readFileContent=readFileContent,exports.readFileSync=readFileSync,exports.runWithConcurrency=runWithConcurrency,exports.shouldUpdateFile=shouldUpdateFile,exports.writeFileContent=writeFileContent;
1
+ "use strict";const s=require("fs"),f=require("path");function _interopDefaultCompat(u){return u&&typeof u=="object"&&"default"in u?u.default:u}const s__default=_interopDefaultCompat(s),f__default=_interopDefaultCompat(f),S=10;async function checkSourceExists(u){try{await s__default.promises.access(u,s__default.constants.F_OK)}catch(t){const e=t;throw e.code==="ENOENT"?new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u6E90\u6587\u4EF6\u4E0D\u5B58\u5728 - ${u}`):e.code==="EACCES"?new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u8BBF\u95EE\u6E90\u6587\u4EF6 - ${u}`):new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u68C0\u67E5\u6E90\u6587\u4EF6\u65F6\u51FA\u9519 - ${u}\uFF0C\u9519\u8BEF\uFF1A${e.message}`)}}async function ensureTargetDir(u){try{await s__default.promises.mkdir(u,{recursive:!0})}catch(t){const e=t;throw e.code==="EACCES"?new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u521B\u5EFA\u76EE\u6807\u76EE\u5F55 - ${u}`):new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u521B\u5EFA\u76EE\u6807\u76EE\u5F55\u65F6\u51FA\u9519 - ${u}\uFF0C\u9519\u8BEF\uFF1A${e.message}`)}}async function readDirRecursive(u,t){const e=await s__default.promises.readdir(u,{withFileTypes:!0}),r=[];for(const n of e){const a=f__default.join(u,n.name),F=n.isFile(),c=n.isDirectory();if(r.push({path:a,isFile:F,isDirectory:c}),c&&t){const l=await readDirRecursive(a,t);r.push(...l)}}return r}async function shouldUpdateFile(u,t){try{const[e,r]=await Promise.all([s__default.promises.stat(u),s__default.promises.stat(t)]);return e.mtimeMs>r.mtimeMs||e.size!==r.size}catch{return!0}}async function fileExists(u){try{return await s__default.promises.access(u,s__default.constants.F_OK),!0}catch{return!1}}async function runWithConcurrency(u,t,e){const r=[];let n=0;async function a(){for(;n<u.length;){const c=n++,l=await t(u[c]);r[c]=l}}const F=Array(Math.min(e,u.length)).fill(null).map(()=>a());return await Promise.all(F),r}async function copySourceToTarget(u,t,e){const r=Date.now(),{recursive:n,overwrite:a,incremental:F=!1,parallelLimit:c=S}=e;let l=0,p=0,E=0;if((await s__default.promises.stat(u)).isDirectory()){await ensureTargetDir(t);const o=await readDirRecursive(u,n),w=o.filter(i=>i.isFile);E=o.filter(i=>i.isDirectory).length;const h=new Set;for(const i of w){const D=f__default.relative(u,i.path),y=f__default.dirname(f__default.join(t,D));h.add(y)}await Promise.all([...h].map(i=>ensureTargetDir(i)));const A=await runWithConcurrency(w,async i=>{const D=f__default.relative(u,i.path),y=f__default.join(t,D);let m=a;return m||(m=!await fileExists(y)),F&&m&&(m=await shouldUpdateFile(i.path,y)),m?(await s__default.promises.copyFile(i.path,y),{copied:!0,skipped:!1}):{copied:!1,skipped:!0}},c);for(const i of A)i.copied&&l++,i.skipped&&p++}else{await ensureTargetDir(f__default.dirname(t));let o=a;o||(o=!await fileExists(t)),F&&o&&(o=await shouldUpdateFile(u,t)),o?(await s__default.promises.copyFile(u,t),l++):p++}const d=Date.now()-r;return{copiedFiles:l,skippedFiles:p,copiedDirs:E,executionTime:d}}async function writeFileContent(u,t){try{await s__default.promises.writeFile(u,t,"utf-8")}catch(e){const r=e;throw r.code==="EACCES"?new Error(`\u5199\u5165\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u5199\u5165\u6587\u4EF6 - ${u}`):new Error(`\u5199\u5165\u6587\u4EF6\u5931\u8D25\uFF1A\u5199\u5165\u6587\u4EF6\u65F6\u51FA\u9519 - ${u}\uFF0C\u9519\u8BEF\uFF1A${r.message}`)}}async function readFileContent(u){try{return await s__default.promises.readFile(u,"utf-8")}catch(t){const e=t;throw e.code==="EACCES"?new Error(`\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u8BFB\u53D6\u6587\u4EF6 - ${u}`):new Error(`\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25\uFF1A\u8BFB\u53D6\u6587\u4EF6\u65F6\u51FA\u9519 - ${u}\uFF0C\u9519\u8BEF\uFF1A${e.message}`)}}function readFileSync(u){try{return s__default.readFileSync(u,"utf-8")}catch(t){const e=t;throw e.code==="EACCES"?new Error(`\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u8BFB\u53D6\u6587\u4EF6 - ${u}`):new Error(`\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25\uFF1A\u8BFB\u53D6\u6587\u4EF6\u65F6\u51FA\u9519 - ${u}\uFF0C\u9519\u8BEF\uFF1A${e.message}`)}}async function scanDirectory(u,t={}){const{includeExtensions:e=[],excludePatterns:r=[],filter:n}=t,a=[];async function F(c){const l=await s__default.promises.readdir(c,{withFileTypes:!0});for(const p of l){const E=f__default.join(c,p.name);if(p.isDirectory()){await F(E);continue}if(!p.isFile()||r.some(w=>w.startsWith("*")?E.endsWith(w.slice(1)):E.includes(w)))continue;const d=f__default.extname(p.name).toLowerCase();if(e.length>0&&!e.includes(d))continue;const o=await s__default.promises.stat(E);n&&!n(E,d,o.size)||a.push({filePath:E,size:o.size,extension:d})}}return await F(u),a}async function writeJsonReport(u,t,e=2){await writeFileContent(u,JSON.stringify(t,null,e))}exports.checkSourceExists=checkSourceExists,exports.copySourceToTarget=copySourceToTarget,exports.ensureTargetDir=ensureTargetDir,exports.fileExists=fileExists,exports.readDirRecursive=readDirRecursive,exports.readFileContent=readFileContent,exports.readFileSync=readFileSync,exports.runWithConcurrency=runWithConcurrency,exports.scanDirectory=scanDirectory,exports.shouldUpdateFile=shouldUpdateFile,exports.writeFileContent=writeFileContent,exports.writeJsonReport=writeJsonReport;
@@ -145,6 +145,74 @@ declare function readFileContent(filePath: string): Promise<string>;
145
145
  * @deprecated 请使用异步版本 readFileContent
146
146
  */
147
147
  declare function readFileSync(filePath: string): string;
148
+ /**
149
+ * 扫描目录中的文件信息
150
+ */
151
+ interface ScannedFile {
152
+ /** 文件绝对路径 */
153
+ filePath: string;
154
+ /** 文件大小(字节) */
155
+ size: number;
156
+ /** 文件扩展名(小写,含点号,如 '.js') */
157
+ extension: string;
158
+ }
159
+ /**
160
+ * 目录扫描选项
161
+ */
162
+ interface ScanDirectoryOptions {
163
+ /** 包含的文件扩展名列表,为空则包含所有 */
164
+ includeExtensions?: string[];
165
+ /** 排除的路径模式列表 */
166
+ excludePatterns?: string[];
167
+ /** 自定义文件过滤函数,返回 true 表示包含该文件 */
168
+ filter?: (filePath: string, extension: string, size: number) => boolean;
169
+ }
170
+ /**
171
+ * 递归扫描目录,收集所有文件信息
172
+ *
173
+ * @async
174
+ * @param {string} dirPath - 要扫描的目录路径
175
+ * @param {ScanDirectoryOptions} options - 扫描选项
176
+ * @returns {Promise<ScannedFile[]>} 文件信息列表
177
+ *
178
+ * @description 递归遍历指定目录下的所有文件,收集每个文件的大小和扩展名信息,
179
+ * 支持按扩展名、路径模式和自定义过滤函数进行过滤。
180
+ * 这是通用的目录扫描函数,可被不同插件复用。
181
+ *
182
+ * @example
183
+ * ```typescript
184
+ * // 扫描所有 .js 文件
185
+ * const jsFiles = await scanDirectory('dist', { includeExtensions: ['.js'] })
186
+ *
187
+ * // 排除 node_modules
188
+ * const files = await scanDirectory('dist', { excludePatterns: ['node_modules'] })
189
+ *
190
+ * // 使用自定义过滤
191
+ * const largeFiles = await scanDirectory('dist', {
192
+ * filter: (filePath, ext, size) => size > 1024
193
+ * })
194
+ * ```
195
+ */
196
+ declare function scanDirectory(dirPath: string, options?: ScanDirectoryOptions): Promise<ScannedFile[]>;
197
+ /**
198
+ * 将数据写入 JSON 文件
199
+ *
200
+ * @async
201
+ * @param {string} filePath - 输出文件路径
202
+ * @param {object} data - 要序列化的数据对象
203
+ * @param {number} [indent=2] - JSON 缩进空格数
204
+ * @returns {Promise<void>}
205
+ *
206
+ * @description 将任意数据对象序列化为 JSON 格式并写入文件。
207
+ * 内部使用 writeFileContent 确保统一的错误处理。
208
+ *
209
+ * @example
210
+ * ```typescript
211
+ * await writeJsonReport('dist/report.json', { timestamp: Date.now(), stats: [] })
212
+ * await writeJsonReport('dist/report.json', data, 4)
213
+ * ```
214
+ */
215
+ declare function writeJsonReport(filePath: string, data: object, indent?: number): Promise<void>;
148
216
 
149
- export { checkSourceExists, copySourceToTarget, ensureTargetDir, fileExists, readDirRecursive, readFileContent, readFileSync, runWithConcurrency, shouldUpdateFile, writeFileContent };
150
- export type { CopyOptions, CopyResult };
217
+ export { checkSourceExists, copySourceToTarget, ensureTargetDir, fileExists, readDirRecursive, readFileContent, readFileSync, runWithConcurrency, scanDirectory, shouldUpdateFile, writeFileContent, writeJsonReport };
218
+ export type { CopyOptions, CopyResult, ScanDirectoryOptions, ScannedFile };
@@ -145,6 +145,74 @@ declare function readFileContent(filePath: string): Promise<string>;
145
145
  * @deprecated 请使用异步版本 readFileContent
146
146
  */
147
147
  declare function readFileSync(filePath: string): string;
148
+ /**
149
+ * 扫描目录中的文件信息
150
+ */
151
+ interface ScannedFile {
152
+ /** 文件绝对路径 */
153
+ filePath: string;
154
+ /** 文件大小(字节) */
155
+ size: number;
156
+ /** 文件扩展名(小写,含点号,如 '.js') */
157
+ extension: string;
158
+ }
159
+ /**
160
+ * 目录扫描选项
161
+ */
162
+ interface ScanDirectoryOptions {
163
+ /** 包含的文件扩展名列表,为空则包含所有 */
164
+ includeExtensions?: string[];
165
+ /** 排除的路径模式列表 */
166
+ excludePatterns?: string[];
167
+ /** 自定义文件过滤函数,返回 true 表示包含该文件 */
168
+ filter?: (filePath: string, extension: string, size: number) => boolean;
169
+ }
170
+ /**
171
+ * 递归扫描目录,收集所有文件信息
172
+ *
173
+ * @async
174
+ * @param {string} dirPath - 要扫描的目录路径
175
+ * @param {ScanDirectoryOptions} options - 扫描选项
176
+ * @returns {Promise<ScannedFile[]>} 文件信息列表
177
+ *
178
+ * @description 递归遍历指定目录下的所有文件,收集每个文件的大小和扩展名信息,
179
+ * 支持按扩展名、路径模式和自定义过滤函数进行过滤。
180
+ * 这是通用的目录扫描函数,可被不同插件复用。
181
+ *
182
+ * @example
183
+ * ```typescript
184
+ * // 扫描所有 .js 文件
185
+ * const jsFiles = await scanDirectory('dist', { includeExtensions: ['.js'] })
186
+ *
187
+ * // 排除 node_modules
188
+ * const files = await scanDirectory('dist', { excludePatterns: ['node_modules'] })
189
+ *
190
+ * // 使用自定义过滤
191
+ * const largeFiles = await scanDirectory('dist', {
192
+ * filter: (filePath, ext, size) => size > 1024
193
+ * })
194
+ * ```
195
+ */
196
+ declare function scanDirectory(dirPath: string, options?: ScanDirectoryOptions): Promise<ScannedFile[]>;
197
+ /**
198
+ * 将数据写入 JSON 文件
199
+ *
200
+ * @async
201
+ * @param {string} filePath - 输出文件路径
202
+ * @param {object} data - 要序列化的数据对象
203
+ * @param {number} [indent=2] - JSON 缩进空格数
204
+ * @returns {Promise<void>}
205
+ *
206
+ * @description 将任意数据对象序列化为 JSON 格式并写入文件。
207
+ * 内部使用 writeFileContent 确保统一的错误处理。
208
+ *
209
+ * @example
210
+ * ```typescript
211
+ * await writeJsonReport('dist/report.json', { timestamp: Date.now(), stats: [] })
212
+ * await writeJsonReport('dist/report.json', data, 4)
213
+ * ```
214
+ */
215
+ declare function writeJsonReport(filePath: string, data: object, indent?: number): Promise<void>;
148
216
 
149
- export { checkSourceExists, copySourceToTarget, ensureTargetDir, fileExists, readDirRecursive, readFileContent, readFileSync, runWithConcurrency, shouldUpdateFile, writeFileContent };
150
- export type { CopyOptions, CopyResult };
217
+ export { checkSourceExists, copySourceToTarget, ensureTargetDir, fileExists, readDirRecursive, readFileContent, readFileSync, runWithConcurrency, scanDirectory, shouldUpdateFile, writeFileContent, writeJsonReport };
218
+ export type { CopyOptions, CopyResult, ScanDirectoryOptions, ScannedFile };
@@ -145,6 +145,74 @@ declare function readFileContent(filePath: string): Promise<string>;
145
145
  * @deprecated 请使用异步版本 readFileContent
146
146
  */
147
147
  declare function readFileSync(filePath: string): string;
148
+ /**
149
+ * 扫描目录中的文件信息
150
+ */
151
+ interface ScannedFile {
152
+ /** 文件绝对路径 */
153
+ filePath: string;
154
+ /** 文件大小(字节) */
155
+ size: number;
156
+ /** 文件扩展名(小写,含点号,如 '.js') */
157
+ extension: string;
158
+ }
159
+ /**
160
+ * 目录扫描选项
161
+ */
162
+ interface ScanDirectoryOptions {
163
+ /** 包含的文件扩展名列表,为空则包含所有 */
164
+ includeExtensions?: string[];
165
+ /** 排除的路径模式列表 */
166
+ excludePatterns?: string[];
167
+ /** 自定义文件过滤函数,返回 true 表示包含该文件 */
168
+ filter?: (filePath: string, extension: string, size: number) => boolean;
169
+ }
170
+ /**
171
+ * 递归扫描目录,收集所有文件信息
172
+ *
173
+ * @async
174
+ * @param {string} dirPath - 要扫描的目录路径
175
+ * @param {ScanDirectoryOptions} options - 扫描选项
176
+ * @returns {Promise<ScannedFile[]>} 文件信息列表
177
+ *
178
+ * @description 递归遍历指定目录下的所有文件,收集每个文件的大小和扩展名信息,
179
+ * 支持按扩展名、路径模式和自定义过滤函数进行过滤。
180
+ * 这是通用的目录扫描函数,可被不同插件复用。
181
+ *
182
+ * @example
183
+ * ```typescript
184
+ * // 扫描所有 .js 文件
185
+ * const jsFiles = await scanDirectory('dist', { includeExtensions: ['.js'] })
186
+ *
187
+ * // 排除 node_modules
188
+ * const files = await scanDirectory('dist', { excludePatterns: ['node_modules'] })
189
+ *
190
+ * // 使用自定义过滤
191
+ * const largeFiles = await scanDirectory('dist', {
192
+ * filter: (filePath, ext, size) => size > 1024
193
+ * })
194
+ * ```
195
+ */
196
+ declare function scanDirectory(dirPath: string, options?: ScanDirectoryOptions): Promise<ScannedFile[]>;
197
+ /**
198
+ * 将数据写入 JSON 文件
199
+ *
200
+ * @async
201
+ * @param {string} filePath - 输出文件路径
202
+ * @param {object} data - 要序列化的数据对象
203
+ * @param {number} [indent=2] - JSON 缩进空格数
204
+ * @returns {Promise<void>}
205
+ *
206
+ * @description 将任意数据对象序列化为 JSON 格式并写入文件。
207
+ * 内部使用 writeFileContent 确保统一的错误处理。
208
+ *
209
+ * @example
210
+ * ```typescript
211
+ * await writeJsonReport('dist/report.json', { timestamp: Date.now(), stats: [] })
212
+ * await writeJsonReport('dist/report.json', data, 4)
213
+ * ```
214
+ */
215
+ declare function writeJsonReport(filePath: string, data: object, indent?: number): Promise<void>;
148
216
 
149
- export { checkSourceExists, copySourceToTarget, ensureTargetDir, fileExists, readDirRecursive, readFileContent, readFileSync, runWithConcurrency, shouldUpdateFile, writeFileContent };
150
- export type { CopyOptions, CopyResult };
217
+ export { checkSourceExists, copySourceToTarget, ensureTargetDir, fileExists, readDirRecursive, readFileContent, readFileSync, runWithConcurrency, scanDirectory, shouldUpdateFile, writeFileContent, writeJsonReport };
218
+ export type { CopyOptions, CopyResult, ScanDirectoryOptions, ScannedFile };
@@ -1 +1 @@
1
- import s from"fs";import E from"path";const k=10;async function v(u){try{await s.promises.access(u,s.constants.F_OK)}catch(t){const r=t;throw r.code==="ENOENT"?new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u6E90\u6587\u4EF6\u4E0D\u5B58\u5728 - ${u}`):r.code==="EACCES"?new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u8BBF\u95EE\u6E90\u6587\u4EF6 - ${u}`):new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u68C0\u67E5\u6E90\u6587\u4EF6\u65F6\u51FA\u9519 - ${u}\uFF0C\u9519\u8BEF\uFF1A${r.message}`)}}async function m(u){try{await s.promises.mkdir(u,{recursive:!0})}catch(t){const r=t;throw r.code==="EACCES"?new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u521B\u5EFA\u76EE\u6807\u76EE\u5F55 - ${u}`):new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u521B\u5EFA\u76EE\u6807\u76EE\u5F55\u65F6\u51FA\u9519 - ${u}\uFF0C\u9519\u8BEF\uFF1A${r.message}`)}}async function D(u,t){const r=await s.promises.readdir(u,{withFileTypes:!0}),e=[];for(const a of r){const o=E.join(u,a.name),l=a.isFile(),F=a.isDirectory();if(e.push({path:o,isFile:l,isDirectory:F}),F&&t){const c=await D(o,t);e.push(...c)}}return e}async function y(u,t){try{const[r,e]=await Promise.all([s.promises.stat(u),s.promises.stat(t)]);return r.mtimeMs>e.mtimeMs||r.size!==e.size}catch{return!0}}async function d(u){try{return await s.promises.access(u,s.constants.F_OK),!0}catch{return!1}}async function $(u,t,r){const e=[];let a=0;async function o(){for(;a<u.length;){const F=a++,c=await t(u[F]);e[F]=c}}const l=Array(Math.min(r,u.length)).fill(null).map(()=>o());return await Promise.all(l),e}async function T(u,t,r){const e=Date.now(),{recursive:a,overwrite:o,incremental:l=!1,parallelLimit:F=k}=r;let c=0,f=0,h=0;if((await s.promises.stat(u)).isDirectory()){await m(t);const n=await D(u,a),B=n.filter(i=>i.isFile);h=n.filter(i=>i.isDirectory).length;const C=new Set;for(const i of B){const A=E.relative(u,i.path),w=E.dirname(E.join(t,A));C.add(w)}await Promise.all([...C].map(i=>m(i)));const S=await $(B,async i=>{const A=E.relative(u,i.path),w=E.join(t,A);let p=o;return p||(p=!await d(w)),l&&p&&(p=await y(i.path,w)),p?(await s.promises.copyFile(i.path,w),{copied:!0,skipped:!1}):{copied:!1,skipped:!0}},F);for(const i of S)i.copied&&c++,i.skipped&&f++}else{await m(E.dirname(t));let n=o;n||(n=!await d(t)),l&&n&&(n=await y(u,t)),n?(await s.promises.copyFile(u,t),c++):f++}const g=Date.now()-e;return{copiedFiles:c,skippedFiles:f,copiedDirs:h,executionTime:g}}async function x(u,t){try{await s.promises.writeFile(u,t,"utf-8")}catch(r){const e=r;throw e.code==="EACCES"?new Error(`\u5199\u5165\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u5199\u5165\u6587\u4EF6 - ${u}`):new Error(`\u5199\u5165\u6587\u4EF6\u5931\u8D25\uFF1A\u5199\u5165\u6587\u4EF6\u65F6\u51FA\u9519 - ${u}\uFF0C\u9519\u8BEF\uFF1A${e.message}`)}}async function j(u){try{return await s.promises.readFile(u,"utf-8")}catch(t){const r=t;throw r.code==="EACCES"?new Error(`\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u8BFB\u53D6\u6587\u4EF6 - ${u}`):new Error(`\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25\uFF1A\u8BFB\u53D6\u6587\u4EF6\u65F6\u51FA\u9519 - ${u}\uFF0C\u9519\u8BEF\uFF1A${r.message}`)}}function M(u){try{return s.readFileSync(u,"utf-8")}catch(t){const r=t;throw r.code==="EACCES"?new Error(`\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u8BFB\u53D6\u6587\u4EF6 - ${u}`):new Error(`\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25\uFF1A\u8BFB\u53D6\u6587\u4EF6\u65F6\u51FA\u9519 - ${u}\uFF0C\u9519\u8BEF\uFF1A${r.message}`)}}export{v as checkSourceExists,T as copySourceToTarget,m as ensureTargetDir,d as fileExists,D as readDirRecursive,j as readFileContent,M as readFileSync,$ as runWithConcurrency,y as shouldUpdateFile,x as writeFileContent};
1
+ import r from"fs";import w from"path";const T=10;async function k(u){try{await r.promises.access(u,r.constants.F_OK)}catch(t){const e=t;throw e.code==="ENOENT"?new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u6E90\u6587\u4EF6\u4E0D\u5B58\u5728 - ${u}`):e.code==="EACCES"?new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u8BBF\u95EE\u6E90\u6587\u4EF6 - ${u}`):new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u68C0\u67E5\u6E90\u6587\u4EF6\u65F6\u51FA\u9519 - ${u}\uFF0C\u9519\u8BEF\uFF1A${e.message}`)}}async function D(u){try{await r.promises.mkdir(u,{recursive:!0})}catch(t){const e=t;throw e.code==="EACCES"?new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u521B\u5EFA\u76EE\u6807\u76EE\u5F55 - ${u}`):new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u521B\u5EFA\u76EE\u6807\u76EE\u5F55\u65F6\u51FA\u9519 - ${u}\uFF0C\u9519\u8BEF\uFF1A${e.message}`)}}async function h(u,t){const e=await r.promises.readdir(u,{withFileTypes:!0}),i=[];for(const n of e){const a=w.join(u,n.name),F=n.isFile(),c=n.isDirectory();if(i.push({path:a,isFile:F,isDirectory:c}),c&&t){const E=await h(a,t);i.push(...E)}}return i}async function B(u,t){try{const[e,i]=await Promise.all([r.promises.stat(u),r.promises.stat(t)]);return e.mtimeMs>i.mtimeMs||e.size!==i.size}catch{return!0}}async function C(u){try{return await r.promises.access(u,r.constants.F_OK),!0}catch{return!1}}async function g(u,t,e){const i=[];let n=0;async function a(){for(;n<u.length;){const c=n++,E=await t(u[c]);i[c]=E}}const F=Array(Math.min(e,u.length)).fill(null).map(()=>a());return await Promise.all(F),i}async function v(u,t,e){const i=Date.now(),{recursive:n,overwrite:a,incremental:F=!1,parallelLimit:c=T}=e;let E=0,p=0,l=0;if((await r.promises.stat(u)).isDirectory()){await D(t);const o=await h(u,n),f=o.filter(s=>s.isFile);l=o.filter(s=>s.isDirectory).length;const $=new Set;for(const s of f){const A=w.relative(u,s.path),y=w.dirname(w.join(t,A));$.add(y)}await Promise.all([...$].map(s=>D(s)));const x=await g(f,async s=>{const A=w.relative(u,s.path),y=w.join(t,A);let d=a;return d||(d=!await C(y)),F&&d&&(d=await B(s.path,y)),d?(await r.promises.copyFile(s.path,y),{copied:!0,skipped:!1}):{copied:!1,skipped:!0}},c);for(const s of x)s.copied&&E++,s.skipped&&p++}else{await D(w.dirname(t));let o=a;o||(o=!await C(t)),F&&o&&(o=await B(u,t)),o?(await r.promises.copyFile(u,t),E++):p++}const m=Date.now()-i;return{copiedFiles:E,skippedFiles:p,copiedDirs:l,executionTime:m}}async function S(u,t){try{await r.promises.writeFile(u,t,"utf-8")}catch(e){const i=e;throw i.code==="EACCES"?new Error(`\u5199\u5165\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u5199\u5165\u6587\u4EF6 - ${u}`):new Error(`\u5199\u5165\u6587\u4EF6\u5931\u8D25\uFF1A\u5199\u5165\u6587\u4EF6\u65F6\u51FA\u9519 - ${u}\uFF0C\u9519\u8BEF\uFF1A${i.message}`)}}async function z(u){try{return await r.promises.readFile(u,"utf-8")}catch(t){const e=t;throw e.code==="EACCES"?new Error(`\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u8BFB\u53D6\u6587\u4EF6 - ${u}`):new Error(`\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25\uFF1A\u8BFB\u53D6\u6587\u4EF6\u65F6\u51FA\u9519 - ${u}\uFF0C\u9519\u8BEF\uFF1A${e.message}`)}}function P(u){try{return r.readFileSync(u,"utf-8")}catch(t){const e=t;throw e.code==="EACCES"?new Error(`\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u8BFB\u53D6\u6587\u4EF6 - ${u}`):new Error(`\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25\uFF1A\u8BFB\u53D6\u6587\u4EF6\u65F6\u51FA\u9519 - ${u}\uFF0C\u9519\u8BEF\uFF1A${e.message}`)}}async function j(u,t={}){const{includeExtensions:e=[],excludePatterns:i=[],filter:n}=t,a=[];async function F(c){const E=await r.promises.readdir(c,{withFileTypes:!0});for(const p of E){const l=w.join(c,p.name);if(p.isDirectory()){await F(l);continue}if(!p.isFile()||i.some(f=>f.startsWith("*")?l.endsWith(f.slice(1)):l.includes(f)))continue;const m=w.extname(p.name).toLowerCase();if(e.length>0&&!e.includes(m))continue;const o=await r.promises.stat(l);n&&!n(l,m,o.size)||a.push({filePath:l,size:o.size,extension:m})}}return await F(u),a}async function O(u,t,e=2){await S(u,JSON.stringify(t,null,e))}export{k as checkSourceExists,v as copySourceToTarget,D as ensureTargetDir,C as fileExists,h as readDirRecursive,z as readFileContent,P as readFileSync,g as runWithConcurrency,j as scanDirectory,B as shouldUpdateFile,S as writeFileContent,O as writeJsonReport};
@@ -1,2 +1,2 @@
1
- "use strict";function injectBeforeTag(e,t,l){const n=new RegExp(t,"i");return n.test(e)?{html:e.replace(n,`${l}
2
- ${t}`),injected:!0}:{html:e,injected:!1}}function injectHtmlByPriority(e,t,l=["</head>","</body>","</html>"]){for(const n of l){const c=injectBeforeTag(e,n,t);if(c.injected)return c}return{html:e+t,injected:!0}}function injectBeforeTagWithFallback(e,t,l){const n=injectBeforeTag(e,"</body>",t);if(n.injected)return{...n,usedFallback:!1};const c=injectBeforeTag(e,"</html>",t);return c.injected?{...c,usedFallback:!1}:{html:e+t,injected:!0,usedFallback:!0}}function injectHeadAndBody(e,t,l){let n=e,c=!1;if(t){const i=injectBeforeTag(n,"</head>",t);i.injected&&(n=i.html,c=!0)}const r=injectBeforeTagWithFallback(n,l);return{html:r.html,headInjected:c,bodyInjected:r.injected,usedFallback:r.usedFallback}}exports.injectBeforeTag=injectBeforeTag,exports.injectBeforeTagWithFallback=injectBeforeTagWithFallback,exports.injectHeadAndBody=injectHeadAndBody,exports.injectHtmlByPriority=injectHtmlByPriority;
1
+ "use strict";const security=require("../../shared/vite-plugin.BrI73DHA.cjs");require("../script/index.cjs");function injectBeforeTag(e,t,r){const i=new RegExp(t,"i");return i.test(e)?{html:e.replace(i,`${r}
2
+ ${t}`),injected:!0}:{html:e,injected:!1}}function injectHtmlByPriority(e,t,r=["</head>","</body>","</html>"]){for(const i of r){const n=injectBeforeTag(e,i,t);if(n.injected)return n}return{html:e+t,injected:!0}}function injectBeforeTagWithFallback(e,t,r){const i=injectBeforeTag(e,"</body>",t);if(i.injected)return{...i,usedFallback:!1};const n=injectBeforeTag(e,"</html>",t);return n.injected?{...n,usedFallback:!1}:{html:e+t,injected:!0,usedFallback:!0}}function injectHeadAndBody(e,t,r){let i=e,n=!1;if(t){const c=injectBeforeTag(i,"</head>",t);c.injected&&(i=c.html,n=!0)}const o=injectBeforeTagWithFallback(i,r);return{html:o.html,headInjected:n,bodyInjected:o.injected,usedFallback:o.usedFallback}}exports.DEFAULT_BLOCKED_ATTRIBUTES=security.DEFAULT_BLOCKED_ATTRIBUTES,exports.DEFAULT_BLOCKED_TAGS=security.DEFAULT_BLOCKED_TAGS,exports.applyTemplateVars=security.applyTemplateVars,exports.evaluateCondition=security.evaluateCondition,exports.findSelectorMatch=security.findSelectorMatch,exports.injectAtPosition=security.injectAtPosition,exports.sanitizeContent=security.sanitizeContent,exports.sortRulesByPriority=security.sortRulesByPriority,exports.validateSecurityConfig=security.validateSecurityConfig,exports.injectBeforeTag=injectBeforeTag,exports.injectBeforeTagWithFallback=injectBeforeTagWithFallback,exports.injectHeadAndBody=injectHeadAndBody,exports.injectHtmlByPriority=injectHtmlByPriority;