@meng-xi/vite-plugin 0.0.2 → 0.0.3

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 (45) hide show
  1. package/README-en.md +150 -150
  2. package/README.md +84 -84
  3. package/dist/common/index.cjs +1 -0
  4. package/dist/common/index.d.cts +109 -0
  5. package/dist/common/index.d.mts +109 -0
  6. package/dist/common/index.d.ts +109 -0
  7. package/dist/common/index.mjs +1 -0
  8. package/dist/factory/index.cjs +1 -0
  9. package/dist/factory/index.d.cts +260 -0
  10. package/dist/factory/index.d.mts +260 -0
  11. package/dist/factory/index.d.ts +260 -0
  12. package/dist/factory/index.mjs +1 -0
  13. package/dist/index.cjs +1 -5
  14. package/dist/index.d.cts +7 -241
  15. package/dist/index.d.mts +7 -241
  16. package/dist/index.d.ts +7 -241
  17. package/dist/index.mjs +1 -5
  18. package/dist/logger/index.cjs +1 -0
  19. package/dist/logger/index.d.cts +1 -0
  20. package/dist/logger/index.d.mts +1 -0
  21. package/dist/logger/index.d.ts +1 -0
  22. package/dist/logger/index.mjs +1 -0
  23. package/dist/plugins/index.cjs +1 -0
  24. package/dist/plugins/index.d.cts +210 -0
  25. package/dist/plugins/index.d.mts +210 -0
  26. package/dist/plugins/index.d.ts +210 -0
  27. package/dist/plugins/index.mjs +1 -0
  28. package/dist/shared/vite-plugin.B3PARlU9.d.cts +119 -0
  29. package/dist/shared/vite-plugin.B3PARlU9.d.mts +119 -0
  30. package/dist/shared/vite-plugin.B3PARlU9.d.ts +119 -0
  31. package/dist/shared/vite-plugin.BT1oHRKK.cjs +1 -0
  32. package/dist/shared/vite-plugin.BTKhc7n7.cjs +3 -0
  33. package/dist/shared/vite-plugin.BZqhBDYR.mjs +1 -0
  34. package/dist/shared/vite-plugin.Bn8mcCzy.cjs +3 -0
  35. package/dist/shared/vite-plugin.CY2ydccp.mjs +3 -0
  36. package/dist/shared/vite-plugin.CiHfwMiN.d.cts +91 -0
  37. package/dist/shared/vite-plugin.CiHfwMiN.d.mts +91 -0
  38. package/dist/shared/vite-plugin.CiHfwMiN.d.ts +91 -0
  39. package/dist/shared/vite-plugin.ClHiVXD6.mjs +1 -0
  40. package/dist/shared/vite-plugin.DSRKYuae.mjs +3 -0
  41. package/dist/shared/vite-plugin.DrSzERYS.cjs +1 -0
  42. package/dist/shared/vite-plugin.UkE7CdSe.d.cts +43 -0
  43. package/dist/shared/vite-plugin.UkE7CdSe.d.mts +43 -0
  44. package/dist/shared/vite-plugin.UkE7CdSe.d.ts +43 -0
  45. package/package.json +72 -53
@@ -0,0 +1,119 @@
1
+ /**
2
+ * 构造函数参数接口
3
+ */
4
+ interface LoggerOptions {
5
+ /**
6
+ * 插件名称
7
+ */
8
+ name: string;
9
+ /**
10
+ * 是否启用日志
11
+ */
12
+ enabled?: boolean;
13
+ }
14
+
15
+ /**
16
+ * 日志工具类(单例模式)
17
+ * @description 全局单例日志管理器,统一管理所有插件的日志输出
18
+ */
19
+ declare class Logger {
20
+ /**
21
+ * 单例实例
22
+ */
23
+ private static instance;
24
+ /**
25
+ * 库名称
26
+ */
27
+ private readonly libName;
28
+ /**
29
+ * 插件日志配置映射表
30
+ * @description 存储每个插件的日志开关状态
31
+ */
32
+ private pluginConfigs;
33
+ /**
34
+ * 日志类型映射
35
+ */
36
+ private readonly logTypes;
37
+ /**
38
+ * 私有构造函数,防止外部实例化
39
+ */
40
+ private constructor();
41
+ /**
42
+ * 获取单例实例
43
+ * @returns Logger 单例实例
44
+ */
45
+ private static getInstance;
46
+ /**
47
+ * 创建日志记录器(工厂方法)
48
+ * @param options 配置选项
49
+ * @returns Logger 单例实例
50
+ * @description 为插件创建日志记录器,实际返回单例实例并注册插件配置
51
+ */
52
+ static create(options: LoggerOptions): Logger;
53
+ /**
54
+ * 注册插件日志配置
55
+ * @param pluginName 插件名称
56
+ * @param enabled 是否启用日志
57
+ */
58
+ private registerPlugin;
59
+ /**
60
+ * 生成日志前缀
61
+ * @param pluginName 插件名称
62
+ * @returns 格式化的日志前缀
63
+ */
64
+ private formatPrefix;
65
+ /**
66
+ * 检查插件日志是否启用
67
+ * @param pluginName 插件名称
68
+ * @returns 是否启用
69
+ */
70
+ private isPluginEnabled;
71
+ /**
72
+ * 统一日志输出方法
73
+ * @param pluginName 插件名称
74
+ * @param type 日志类型
75
+ * @param message 日志消息
76
+ * @param data 附加数据
77
+ */
78
+ private log;
79
+ /**
80
+ * 创建插件日志代理对象
81
+ * @param pluginName 插件名称
82
+ * @returns 插件日志代理对象
83
+ * @internal 供 BasePlugin 内部使用
84
+ */
85
+ createPluginLogger(pluginName: string): PluginLogger;
86
+ }
87
+ /**
88
+ * 插件日志代理接口
89
+ * @description 为每个插件提供独立的日志接口
90
+ */
91
+ interface PluginLogger {
92
+ /**
93
+ * 输出成功日志
94
+ * @param message 日志消息
95
+ * @param data 附加数据
96
+ */
97
+ success(message: string, data?: any): void;
98
+ /**
99
+ * 输出信息日志
100
+ * @param message 日志消息
101
+ * @param data 附加数据
102
+ */
103
+ info(message: string, data?: any): void;
104
+ /**
105
+ * 输出警告日志
106
+ * @param message 日志消息
107
+ * @param data 附加数据
108
+ */
109
+ warn(message: string, data?: any): void;
110
+ /**
111
+ * 输出错误日志
112
+ * @param message 日志消息
113
+ * @param data 附加数据
114
+ */
115
+ error(message: string, data?: any): void;
116
+ }
117
+
118
+ export { Logger as L };
119
+ export type { PluginLogger as P, LoggerOptions as a };
@@ -0,0 +1 @@
1
+ "use strict";const logger_index=require("../logger/index.cjs");require("fs"),require("path");const validation=require("./vite-plugin.BTKhc7n7.cjs");class BasePlugin{options;logger;validator;viteConfig=null;constructor(e,t){this.options=this.mergeOptions(e),this.logger=this.initLogger(t),this.validator=new validation.Validator(this.options),this.safeExecuteSync(()=>this.validateOptions(),"\u63D2\u4EF6\u914D\u7F6E\u9A8C\u8BC1")}mergeOptions(e){const t={enabled:!0,verbose:!0,errorStrategy:"throw"},r=this.getDefaultOptions();return validation.deepMerge(t,r,e)}initLogger(e){return logger_index.Logger.create({name:this.getPluginName(),enabled:this.options.verbose,...e}).createPluginLogger(this.getPluginName())}validateOptions(){}getEnforce(){}onConfigResolved(e){this.viteConfig=e,this.logger.info("\u914D\u7F6E\u89E3\u6790\u5B8C\u6210\uFF0C\u63D2\u4EF6\u5DF2\u521D\u59CB\u5316")}safeExecuteSync(e,t){try{return e()}catch(r){return this.handleError(r,t)}}async safeExecute(e,t){try{return await e()}catch(r){return this.handleError(r,t)}}handleError(e,t){let r=`${t}: `;switch(e instanceof Error?r+=e.message:typeof e=="string"?r+=e:r+=String(e),this.options.errorStrategy){case"throw":throw this.logger.error(r),e;case"log":case"ignore":this.logger.error(r);return;default:throw this.logger.error(r),e}}toPlugin(){const e={name:this.getPluginName(),enforce:this.getEnforce(),configResolved:t=>{this.options.enabled&&this.onConfigResolved(t)}};return this.addPluginHooks(e),e}}function createPluginFactory(o,e){return t=>{const r=e?e(t):t,i=new o(r),n=i.toPlugin();return n.pluginInstance=i,n}}exports.BasePlugin=BasePlugin,exports.createPluginFactory=createPluginFactory;
@@ -0,0 +1,3 @@
1
+ "use strict";function deepMerge(...n){const u={};for(const r of n)if(r)for(const t in r){const i=r[t],e=u[t];typeof i=="object"&&i!==null&&!Array.isArray(i)&&typeof e=="object"&&e!==null&&!Array.isArray(e)?u[t]=deepMerge(e,i):u[t]=i}return u}class Validator{options;currentField=null;errors=[];constructor(u){this.options=u}field(u){const r=this;return r.currentField=u,r}required(){if(this.currentField===null)throw new Error("\u5FC5\u987B\u5148\u8C03\u7528 field() \u65B9\u6CD5\u6307\u5B9A\u8981\u9A8C\u8BC1\u7684\u5B57\u6BB5");return this.options[this.currentField]==null&&this.errors.push(`${String(this.currentField)} \u662F\u5FC5\u586B\u5B57\u6BB5`),this}string(){if(this.currentField===null)throw new Error("\u5FC5\u987B\u5148\u8C03\u7528 field() \u65B9\u6CD5\u6307\u5B9A\u8981\u9A8C\u8BC1\u7684\u5B57\u6BB5");const u=this.options[this.currentField];return u!=null&&typeof u!="string"&&this.errors.push(`${String(this.currentField)} \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u7C7B\u578B`),this}boolean(){if(this.currentField===null)throw new Error("\u5FC5\u987B\u5148\u8C03\u7528 field() \u65B9\u6CD5\u6307\u5B9A\u8981\u9A8C\u8BC1\u7684\u5B57\u6BB5");const u=this.options[this.currentField];return u!=null&&typeof u!="boolean"&&this.errors.push(`${String(this.currentField)} \u5FC5\u987B\u662F\u5E03\u5C14\u7C7B\u578B`),this}number(){if(this.currentField===null)throw new Error("\u5FC5\u987B\u5148\u8C03\u7528 field() \u65B9\u6CD5\u6307\u5B9A\u8981\u9A8C\u8BC1\u7684\u5B57\u6BB5");const u=this.options[this.currentField];return u!=null&&typeof u!="number"&&this.errors.push(`${String(this.currentField)} \u5FC5\u987B\u662F\u6570\u5B57\u7C7B\u578B`),this}array(){if(this.currentField===null)throw new Error("\u5FC5\u987B\u5148\u8C03\u7528 field() \u65B9\u6CD5\u6307\u5B9A\u8981\u9A8C\u8BC1\u7684\u5B57\u6BB5");const u=this.options[this.currentField];return u!=null&&!Array.isArray(u)&&this.errors.push(`${String(this.currentField)} \u5FC5\u987B\u662F\u6570\u7EC4\u7C7B\u578B`),this}object(){if(this.currentField===null)throw new Error("\u5FC5\u987B\u5148\u8C03\u7528 field() \u65B9\u6CD5\u6307\u5B9A\u8981\u9A8C\u8BC1\u7684\u5B57\u6BB5");const u=this.options[this.currentField];return u!=null&&typeof u!="object"&&!Array.isArray(u)&&this.errors.push(`${String(this.currentField)} \u5FC5\u987B\u662F\u5BF9\u8C61\u7C7B\u578B`),this}default(u){if(this.currentField===null)throw new Error("\u5FC5\u987B\u5148\u8C03\u7528 field() \u65B9\u6CD5\u6307\u5B9A\u8981\u9A8C\u8BC1\u7684\u5B57\u6BB5");return this.options[this.currentField]==null&&(this.options[this.currentField]=u),this}custom(u,r){if(this.currentField===null)throw new Error("\u5FC5\u987B\u5148\u8C03\u7528 field() \u65B9\u6CD5\u6307\u5B9A\u8981\u9A8C\u8BC1\u7684\u5B57\u6BB5");const t=this.options[this.currentField];return t!=null&&!u(t)&&this.errors.push(r),this}validate(){if(this.errors.length>0)throw new Error(`\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25\uFF1A
2
+ ${this.errors.map(u=>`- ${u}`).join(`
3
+ `)}`);return this.options}}exports.Validator=Validator,exports.deepMerge=deepMerge;
@@ -0,0 +1 @@
1
+ import s from"fs";import n from"path";async function C(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 p(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 y(u,t){const r=await s.promises.readdir(u,{withFileTypes:!0});let a=[];for(const E of r){const o=n.join(u,E.name);if(E.isDirectory()){if(a.push(o),t){const w=await y(o,t);a=[...a,...w]}}else a.push(o)}return a}async function A(u,t){try{const r=await s.promises.stat(u),a=await s.promises.stat(t);return r.mtimeMs>a.mtimeMs||r.size!==a.size}catch{return!0}}async function B(u,t,r){const a=Date.now(),{recursive:E,overwrite:o,incremental:w=!1}=r;let l=0,D=0,f=0;if((await s.promises.stat(u)).isDirectory()){await p(t);const i=await y(u,E),d=(await Promise.all(i.map(async e=>{const c=await s.promises.stat(e);return{path:e,isFile:c.isFile()}}))).filter(e=>e.isFile).map(e=>e.path);for(const e of d){const c=n.relative(u,e),m=n.join(t,c);await p(n.dirname(m));let F=o;if(!F)try{await s.promises.access(m,s.constants.F_OK),F=!1}catch{F=!0}w&&F&&(F=await A(e,m)),F?(await s.promises.copyFile(e,m),l++):D++}f=(await Promise.all(i.map(async e=>{const c=await s.promises.stat(e);return{path:e,isDirectory:c.isDirectory()}}))).filter(e=>e.isDirectory).length}else{await p(n.dirname(t));let i=o;if(!i)try{await s.promises.access(t,s.constants.F_OK),i=!1}catch{i=!0}w&&i&&(i=await A(u,t)),i?(await s.promises.copyFile(u,t),l++):D++}const h=Date.now()-a;return{copiedFiles:l,skippedFiles:D,copiedDirs:f,executionTime:h}}async function $(u,t){try{await s.promises.writeFile(u,t,"utf-8")}catch(r){const a=r;throw a.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${a.message}`)}}function S(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{B as a,S as b,C as c,p as e,y as r,A as s,$ as w};
@@ -0,0 +1,3 @@
1
+ "use strict";const index=require("./vite-plugin.BT1oHRKK.cjs"),index$1=require("./vite-plugin.DrSzERYS.cjs"),validation=require("./vite-plugin.BTKhc7n7.cjs");class p extends index.BasePlugin{getDefaultOptions(){return{overwrite:!0,recursive:!0,incremental:!0}}validateOptions(){this.validator.field("sourceDir").required().string().custom(e=>e.trim()!=="","sourceDir \u4E0D\u80FD\u4E3A\u7A7A\u5B57\u7B26\u4E32").field("targetDir").required().string().custom(e=>e.trim()!=="","targetDir \u4E0D\u80FD\u4E3A\u7A7A\u5B57\u7B26\u4E32").field("overwrite").boolean().field("recursive").boolean().field("incremental").boolean().validate()}getPluginName(){return"copy-file"}getEnforce(){return"post"}async copyFiles(){const{sourceDir:e,targetDir:i,overwrite:t=!0,recursive:s=!0,incremental:o=!0,enabled:n=!0}=this.options;if(!n){this.logger.info(`\u63D2\u4EF6\u5DF2\u7981\u7528\uFF0C\u8DF3\u8FC7\u6267\u884C\uFF1A\u4ECE ${e} \u590D\u5236\u5230 ${i}`);return}await index$1.checkSourceExists(e);const c=await index$1.copySourceToTarget(e,i,{recursive:s,overwrite:t,incremental:o});this.logger.success(`\u590D\u5236\u6587\u4EF6\u6210\u529F\uFF1A\u4ECE ${e} \u5230 ${i}`,`\u590D\u5236\u4E86 ${c.copiedFiles} \u4E2A\u6587\u4EF6\uFF0C\u8DF3\u8FC7\u4E86 ${c.skippedFiles} \u4E2A\u6587\u4EF6\uFF0C\u8017\u65F6 ${c.executionTime}ms`)}addPluginHooks(e){e.writeBundle=async()=>{await this.safeExecute(()=>this.copyFiles(),"\u590D\u5236\u6587\u4EF6")}}}const copyFile=index.createPluginFactory(p);function generateIconTags(r){const e=[];if(r.link)return e.push(r.link),e;if(r.icons&&r.icons.length>0)e.push(...r.icons.map(i=>{let t=`<link rel="${i.rel}" href="${i.href}"`;return i.sizes&&(t+=` sizes="${i.sizes}"`),i.type&&(t+=` type="${i.type}"`),t+=" />",t}));else if(r.url)e.push(`<link rel="icon" href="${r.url}" />`);else{const i=r.base||"/",t=i.endsWith("/")?`${i}favicon.ico`:`${i}/favicon.ico`;e.push(`<link rel="icon" href="${t}" />`)}return e}class u extends index.BasePlugin{getDefaultOptions(){return{base:"/"}}validateOptions(){this.validator.field("base").string().field("url").string().field("link").string().field("icons").array(),this.options?.copyOptions&&(this.validator.field("copyOptions").object(),new validation.Validator(this.options.copyOptions).field("sourceDir").required().string().field("targetDir").required().string().field("overwrite").boolean().field("recursive").boolean().validate()),this.validator.validate()}getPluginName(){return"inject-ico"}injectIcoTags(e){if(!this.options.enabled)return this.logger.info("\u63D2\u4EF6\u5DF2\u7981\u7528\uFF0C\u8DF3\u8FC7\u56FE\u6807\u6CE8\u5165"),e;const i=generateIconTags(this.options);if(i.length===0)return this.logger.info("\u6CA1\u6709\u751F\u6210\u56FE\u6807\u6807\u7B7E\uFF0C\u8DF3\u8FC7\u6CE8\u5165"),e;let t=e;const s=t.indexOf("</head>");if(s!==-1){const o=i.join(`
2
+ `)+`
3
+ `;t=t.substring(0,s)+o+t.substring(s),this.logger.success(`\u6210\u529F\u6CE8\u5165 ${i.length} \u4E2A\u56FE\u6807\u6807\u7B7E\u5230 HTML \u6587\u4EF6`),i.forEach(n=>{this.logger.info(` - ${n}`)})}else this.logger.warn("\u672A\u627E\u5230 </head> \u6807\u7B7E\uFF0C\u8DF3\u8FC7\u56FE\u6807\u6CE8\u5165");return t}async copyFiles(){if(!this.options.enabled){this.logger.info("\u63D2\u4EF6\u5DF2\u7981\u7528\uFF0C\u8DF3\u8FC7\u6587\u4EF6\u590D\u5236");return}const{copyOptions:e}=this.options;if(!e)return;const{sourceDir:i,targetDir:t,overwrite:s=!0,recursive:o=!0}=e;await index$1.checkSourceExists(i);const n=await index$1.copySourceToTarget(i,t,{recursive:o,overwrite:s,incremental:!0});this.logger.success(`\u56FE\u6807\u6587\u4EF6\u590D\u5236\u6210\u529F\uFF1A\u4ECE ${i} \u5230 ${t}`,`\u590D\u5236\u4E86 ${n.copiedFiles} \u4E2A\u6587\u4EF6\uFF0C\u8DF3\u8FC7\u4E86 ${n.skippedFiles} \u4E2A\u6587\u4EF6\uFF0C\u8017\u65F6 ${n.executionTime}ms`)}addPluginHooks(e){e.transformIndexHtml=i=>this.injectIcoTags(i),e.writeBundle=async()=>{await this.safeExecute(()=>this.copyFiles(),"\u56FE\u6807\u6587\u4EF6\u590D\u5236")}}}const injectIco=index.createPluginFactory(u,r=>typeof r=="string"?{base:r}:r||{});exports.copyFile=copyFile,exports.injectIco=injectIco;
@@ -0,0 +1,3 @@
1
+ import{c as a,B as c}from"./vite-plugin.ClHiVXD6.mjs";import{c as l,a as F}from"./vite-plugin.BZqhBDYR.mjs";import{V as E}from"./vite-plugin.DSRKYuae.mjs";class g extends c{getDefaultOptions(){return{overwrite:!0,recursive:!0,incremental:!0}}validateOptions(){this.validator.field("sourceDir").required().string().custom(u=>u.trim()!=="","sourceDir \u4E0D\u80FD\u4E3A\u7A7A\u5B57\u7B26\u4E32").field("targetDir").required().string().custom(u=>u.trim()!=="","targetDir \u4E0D\u80FD\u4E3A\u7A7A\u5B57\u7B26\u4E32").field("overwrite").boolean().field("recursive").boolean().field("incremental").boolean().validate()}getPluginName(){return"copy-file"}getEnforce(){return"post"}async copyFiles(){const{sourceDir:u,targetDir:e,overwrite:i=!0,recursive:r=!0,incremental:o=!0,enabled:s=!0}=this.options;if(!s){this.logger.info(`\u63D2\u4EF6\u5DF2\u7981\u7528\uFF0C\u8DF3\u8FC7\u6267\u884C\uFF1A\u4ECE ${u} \u590D\u5236\u5230 ${e}`);return}await l(u);const n=await F(u,e,{recursive:r,overwrite:i,incremental:o});this.logger.success(`\u590D\u5236\u6587\u4EF6\u6210\u529F\uFF1A\u4ECE ${u} \u5230 ${e}`,`\u590D\u5236\u4E86 ${n.copiedFiles} \u4E2A\u6587\u4EF6\uFF0C\u8DF3\u8FC7\u4E86 ${n.skippedFiles} \u4E2A\u6587\u4EF6\uFF0C\u8017\u65F6 ${n.executionTime}ms`)}addPluginHooks(u){u.writeBundle=async()=>{await this.safeExecute(()=>this.copyFiles(),"\u590D\u5236\u6587\u4EF6")}}}const d=a(g);function f(t){const u=[];if(t.link)return u.push(t.link),u;if(t.icons&&t.icons.length>0)u.push(...t.icons.map(e=>{let i=`<link rel="${e.rel}" href="${e.href}"`;return e.sizes&&(i+=` sizes="${e.sizes}"`),e.type&&(i+=` type="${e.type}"`),i+=" />",i}));else if(t.url)u.push(`<link rel="icon" href="${t.url}" />`);else{const e=t.base||"/",i=e.endsWith("/")?`${e}favicon.ico`:`${e}/favicon.ico`;u.push(`<link rel="icon" href="${i}" />`)}return u}class p extends c{getDefaultOptions(){return{base:"/"}}validateOptions(){this.validator.field("base").string().field("url").string().field("link").string().field("icons").array(),this.options?.copyOptions&&(this.validator.field("copyOptions").object(),new E(this.options.copyOptions).field("sourceDir").required().string().field("targetDir").required().string().field("overwrite").boolean().field("recursive").boolean().validate()),this.validator.validate()}getPluginName(){return"inject-ico"}injectIcoTags(u){if(!this.options.enabled)return this.logger.info("\u63D2\u4EF6\u5DF2\u7981\u7528\uFF0C\u8DF3\u8FC7\u56FE\u6807\u6CE8\u5165"),u;const e=f(this.options);if(e.length===0)return this.logger.info("\u6CA1\u6709\u751F\u6210\u56FE\u6807\u6807\u7B7E\uFF0C\u8DF3\u8FC7\u6CE8\u5165"),u;let i=u;const r=i.indexOf("</head>");if(r!==-1){const o=e.join(`
2
+ `)+`
3
+ `;i=i.substring(0,r)+o+i.substring(r),this.logger.success(`\u6210\u529F\u6CE8\u5165 ${e.length} \u4E2A\u56FE\u6807\u6807\u7B7E\u5230 HTML \u6587\u4EF6`),e.forEach(s=>{this.logger.info(` - ${s}`)})}else this.logger.warn("\u672A\u627E\u5230 </head> \u6807\u7B7E\uFF0C\u8DF3\u8FC7\u56FE\u6807\u6CE8\u5165");return i}async copyFiles(){if(!this.options.enabled){this.logger.info("\u63D2\u4EF6\u5DF2\u7981\u7528\uFF0C\u8DF3\u8FC7\u6587\u4EF6\u590D\u5236");return}const{copyOptions:u}=this.options;if(!u)return;const{sourceDir:e,targetDir:i,overwrite:r=!0,recursive:o=!0}=u;await l(e);const s=await F(e,i,{recursive:o,overwrite:r,incremental:!0});this.logger.success(`\u56FE\u6807\u6587\u4EF6\u590D\u5236\u6210\u529F\uFF1A\u4ECE ${e} \u5230 ${i}`,`\u590D\u5236\u4E86 ${s.copiedFiles} \u4E2A\u6587\u4EF6\uFF0C\u8DF3\u8FC7\u4E86 ${s.skippedFiles} \u4E2A\u6587\u4EF6\uFF0C\u8017\u65F6 ${s.executionTime}ms`)}addPluginHooks(u){u.transformIndexHtml=e=>this.injectIcoTags(e),u.writeBundle=async()=>{await this.safeExecute(()=>this.copyFiles(),"\u56FE\u6807\u6587\u4EF6\u590D\u5236")}}}const h=a(p,t=>typeof t=="string"?{base:t}:t||{});export{d as c,h as i};
@@ -0,0 +1,91 @@
1
+ /**
2
+ * 参数验证器,提供流畅的 API 用于验证插件配置
3
+ *
4
+ * @class Validator
5
+ * @description 该类提供了流畅的 API 用于验证插件配置,支持必填字段、类型验证、自定义验证规则等
6
+ * @example
7
+ * ```typescript
8
+ * const validator = new Validator(options)
9
+ * validator
10
+ * .field('sourceDir').required().string()
11
+ * .field('targetDir').required().string()
12
+ * .field('overwrite').boolean().default(true)
13
+ * .validate()
14
+ * ```
15
+ */
16
+ declare class Validator<T extends Record<string, any>, K extends keyof T = any> {
17
+ /**
18
+ * 要验证的选项对象
19
+ */
20
+ private options;
21
+ /**
22
+ * 当前正在验证的字段名
23
+ */
24
+ private currentField;
25
+ /**
26
+ * 验证错误信息
27
+ */
28
+ private errors;
29
+ /**
30
+ * 构造函数
31
+ * @param options 要验证的选项对象
32
+ */
33
+ constructor(options: T);
34
+ /**
35
+ * 指定要验证的字段
36
+ * @param field 字段名
37
+ * @returns Validator 实例,用于链式调用
38
+ */
39
+ field<NextK extends keyof T>(field: NextK): Validator<T, NextK>;
40
+ /**
41
+ * 标记字段为必填
42
+ * @returns Validator 实例,用于链式调用
43
+ */
44
+ required(): this;
45
+ /**
46
+ * 验证字段值是否为字符串类型
47
+ * @returns Validator 实例,用于链式调用
48
+ */
49
+ string(): this;
50
+ /**
51
+ * 验证字段值是否为布尔类型
52
+ * @returns Validator 实例,用于链式调用
53
+ */
54
+ boolean(): this;
55
+ /**
56
+ * 验证字段值是否为数字类型
57
+ * @returns Validator 实例,用于链式调用
58
+ */
59
+ number(): this;
60
+ /**
61
+ * 验证字段值是否为数组类型
62
+ * @returns Validator 实例,用于链式调用
63
+ */
64
+ array(): this;
65
+ /**
66
+ * 验证字段值是否为对象类型
67
+ * @returns Validator 实例,用于链式调用
68
+ */
69
+ object(): this;
70
+ /**
71
+ * 为字段设置默认值(仅当字段值为 undefined 或 null 时生效)
72
+ * @param defaultValue 默认值
73
+ * @returns Validator 实例,用于链式调用
74
+ */
75
+ default(defaultValue: T[K]): this;
76
+ /**
77
+ * 使用自定义函数验证字段值
78
+ * @param validator 自定义验证函数,返回 true 表示验证通过,返回 false 表示验证失败
79
+ * @param message 验证失败时的错误信息
80
+ * @returns Validator 实例,用于链式调用
81
+ */
82
+ custom(validator: (value: T[K]) => boolean, message: string): this;
83
+ /**
84
+ * 执行验证,验证失败时抛出错误
85
+ * @returns 验证后的选项对象
86
+ * @throws {Error} 验证失败时抛出包含所有错误信息的异常
87
+ */
88
+ validate(): T;
89
+ }
90
+
91
+ export { Validator as V };
@@ -0,0 +1,91 @@
1
+ /**
2
+ * 参数验证器,提供流畅的 API 用于验证插件配置
3
+ *
4
+ * @class Validator
5
+ * @description 该类提供了流畅的 API 用于验证插件配置,支持必填字段、类型验证、自定义验证规则等
6
+ * @example
7
+ * ```typescript
8
+ * const validator = new Validator(options)
9
+ * validator
10
+ * .field('sourceDir').required().string()
11
+ * .field('targetDir').required().string()
12
+ * .field('overwrite').boolean().default(true)
13
+ * .validate()
14
+ * ```
15
+ */
16
+ declare class Validator<T extends Record<string, any>, K extends keyof T = any> {
17
+ /**
18
+ * 要验证的选项对象
19
+ */
20
+ private options;
21
+ /**
22
+ * 当前正在验证的字段名
23
+ */
24
+ private currentField;
25
+ /**
26
+ * 验证错误信息
27
+ */
28
+ private errors;
29
+ /**
30
+ * 构造函数
31
+ * @param options 要验证的选项对象
32
+ */
33
+ constructor(options: T);
34
+ /**
35
+ * 指定要验证的字段
36
+ * @param field 字段名
37
+ * @returns Validator 实例,用于链式调用
38
+ */
39
+ field<NextK extends keyof T>(field: NextK): Validator<T, NextK>;
40
+ /**
41
+ * 标记字段为必填
42
+ * @returns Validator 实例,用于链式调用
43
+ */
44
+ required(): this;
45
+ /**
46
+ * 验证字段值是否为字符串类型
47
+ * @returns Validator 实例,用于链式调用
48
+ */
49
+ string(): this;
50
+ /**
51
+ * 验证字段值是否为布尔类型
52
+ * @returns Validator 实例,用于链式调用
53
+ */
54
+ boolean(): this;
55
+ /**
56
+ * 验证字段值是否为数字类型
57
+ * @returns Validator 实例,用于链式调用
58
+ */
59
+ number(): this;
60
+ /**
61
+ * 验证字段值是否为数组类型
62
+ * @returns Validator 实例,用于链式调用
63
+ */
64
+ array(): this;
65
+ /**
66
+ * 验证字段值是否为对象类型
67
+ * @returns Validator 实例,用于链式调用
68
+ */
69
+ object(): this;
70
+ /**
71
+ * 为字段设置默认值(仅当字段值为 undefined 或 null 时生效)
72
+ * @param defaultValue 默认值
73
+ * @returns Validator 实例,用于链式调用
74
+ */
75
+ default(defaultValue: T[K]): this;
76
+ /**
77
+ * 使用自定义函数验证字段值
78
+ * @param validator 自定义验证函数,返回 true 表示验证通过,返回 false 表示验证失败
79
+ * @param message 验证失败时的错误信息
80
+ * @returns Validator 实例,用于链式调用
81
+ */
82
+ custom(validator: (value: T[K]) => boolean, message: string): this;
83
+ /**
84
+ * 执行验证,验证失败时抛出错误
85
+ * @returns 验证后的选项对象
86
+ * @throws {Error} 验证失败时抛出包含所有错误信息的异常
87
+ */
88
+ validate(): T;
89
+ }
90
+
91
+ export { Validator as V };
@@ -0,0 +1,91 @@
1
+ /**
2
+ * 参数验证器,提供流畅的 API 用于验证插件配置
3
+ *
4
+ * @class Validator
5
+ * @description 该类提供了流畅的 API 用于验证插件配置,支持必填字段、类型验证、自定义验证规则等
6
+ * @example
7
+ * ```typescript
8
+ * const validator = new Validator(options)
9
+ * validator
10
+ * .field('sourceDir').required().string()
11
+ * .field('targetDir').required().string()
12
+ * .field('overwrite').boolean().default(true)
13
+ * .validate()
14
+ * ```
15
+ */
16
+ declare class Validator<T extends Record<string, any>, K extends keyof T = any> {
17
+ /**
18
+ * 要验证的选项对象
19
+ */
20
+ private options;
21
+ /**
22
+ * 当前正在验证的字段名
23
+ */
24
+ private currentField;
25
+ /**
26
+ * 验证错误信息
27
+ */
28
+ private errors;
29
+ /**
30
+ * 构造函数
31
+ * @param options 要验证的选项对象
32
+ */
33
+ constructor(options: T);
34
+ /**
35
+ * 指定要验证的字段
36
+ * @param field 字段名
37
+ * @returns Validator 实例,用于链式调用
38
+ */
39
+ field<NextK extends keyof T>(field: NextK): Validator<T, NextK>;
40
+ /**
41
+ * 标记字段为必填
42
+ * @returns Validator 实例,用于链式调用
43
+ */
44
+ required(): this;
45
+ /**
46
+ * 验证字段值是否为字符串类型
47
+ * @returns Validator 实例,用于链式调用
48
+ */
49
+ string(): this;
50
+ /**
51
+ * 验证字段值是否为布尔类型
52
+ * @returns Validator 实例,用于链式调用
53
+ */
54
+ boolean(): this;
55
+ /**
56
+ * 验证字段值是否为数字类型
57
+ * @returns Validator 实例,用于链式调用
58
+ */
59
+ number(): this;
60
+ /**
61
+ * 验证字段值是否为数组类型
62
+ * @returns Validator 实例,用于链式调用
63
+ */
64
+ array(): this;
65
+ /**
66
+ * 验证字段值是否为对象类型
67
+ * @returns Validator 实例,用于链式调用
68
+ */
69
+ object(): this;
70
+ /**
71
+ * 为字段设置默认值(仅当字段值为 undefined 或 null 时生效)
72
+ * @param defaultValue 默认值
73
+ * @returns Validator 实例,用于链式调用
74
+ */
75
+ default(defaultValue: T[K]): this;
76
+ /**
77
+ * 使用自定义函数验证字段值
78
+ * @param validator 自定义验证函数,返回 true 表示验证通过,返回 false 表示验证失败
79
+ * @param message 验证失败时的错误信息
80
+ * @returns Validator 实例,用于链式调用
81
+ */
82
+ custom(validator: (value: T[K]) => boolean, message: string): this;
83
+ /**
84
+ * 执行验证,验证失败时抛出错误
85
+ * @returns 验证后的选项对象
86
+ * @throws {Error} 验证失败时抛出包含所有错误信息的异常
87
+ */
88
+ validate(): T;
89
+ }
90
+
91
+ export { Validator as V };
@@ -0,0 +1 @@
1
+ import{Logger as s}from"../logger/index.mjs";import"fs";import"path";import{V as g,d as a}from"./vite-plugin.DSRKYuae.mjs";class u{options;logger;validator;viteConfig=null;constructor(t,e){this.options=this.mergeOptions(t),this.logger=this.initLogger(e),this.validator=new g(this.options),this.safeExecuteSync(()=>this.validateOptions(),"\u63D2\u4EF6\u914D\u7F6E\u9A8C\u8BC1")}mergeOptions(t){const e={enabled:!0,verbose:!0,errorStrategy:"throw"},r=this.getDefaultOptions();return a(e,r,t)}initLogger(t){return s.create({name:this.getPluginName(),enabled:this.options.verbose,...t}).createPluginLogger(this.getPluginName())}validateOptions(){}getEnforce(){}onConfigResolved(t){this.viteConfig=t,this.logger.info("\u914D\u7F6E\u89E3\u6790\u5B8C\u6210\uFF0C\u63D2\u4EF6\u5DF2\u521D\u59CB\u5316")}safeExecuteSync(t,e){try{return t()}catch(r){return this.handleError(r,e)}}async safeExecute(t,e){try{return await t()}catch(r){return this.handleError(r,e)}}handleError(t,e){let r=`${e}: `;switch(t instanceof Error?r+=t.message:typeof t=="string"?r+=t:r+=String(t),this.options.errorStrategy){case"throw":throw this.logger.error(r),t;case"log":case"ignore":this.logger.error(r);return;default:throw this.logger.error(r),t}}toPlugin(){const t={name:this.getPluginName(),enforce:this.getEnforce(),configResolved:e=>{this.options.enabled&&this.onConfigResolved(e)}};return this.addPluginHooks(t),t}}function l(o,t){return e=>{const r=t?t(e):e,i=new o(r),n=i.toPlugin();return n.pluginInstance=i,n}}export{u as B,l as c};
@@ -0,0 +1,3 @@
1
+ function s(...n){const u={};for(const r of n)if(r)for(const t in r){const i=r[t],e=u[t];typeof i=="object"&&i!==null&&!Array.isArray(i)&&typeof e=="object"&&e!==null&&!Array.isArray(e)?u[t]=s(e,i):u[t]=i}return u}class o{options;currentField=null;errors=[];constructor(u){this.options=u}field(u){const r=this;return r.currentField=u,r}required(){if(this.currentField===null)throw new Error("\u5FC5\u987B\u5148\u8C03\u7528 field() \u65B9\u6CD5\u6307\u5B9A\u8981\u9A8C\u8BC1\u7684\u5B57\u6BB5");return this.options[this.currentField]==null&&this.errors.push(`${String(this.currentField)} \u662F\u5FC5\u586B\u5B57\u6BB5`),this}string(){if(this.currentField===null)throw new Error("\u5FC5\u987B\u5148\u8C03\u7528 field() \u65B9\u6CD5\u6307\u5B9A\u8981\u9A8C\u8BC1\u7684\u5B57\u6BB5");const u=this.options[this.currentField];return u!=null&&typeof u!="string"&&this.errors.push(`${String(this.currentField)} \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u7C7B\u578B`),this}boolean(){if(this.currentField===null)throw new Error("\u5FC5\u987B\u5148\u8C03\u7528 field() \u65B9\u6CD5\u6307\u5B9A\u8981\u9A8C\u8BC1\u7684\u5B57\u6BB5");const u=this.options[this.currentField];return u!=null&&typeof u!="boolean"&&this.errors.push(`${String(this.currentField)} \u5FC5\u987B\u662F\u5E03\u5C14\u7C7B\u578B`),this}number(){if(this.currentField===null)throw new Error("\u5FC5\u987B\u5148\u8C03\u7528 field() \u65B9\u6CD5\u6307\u5B9A\u8981\u9A8C\u8BC1\u7684\u5B57\u6BB5");const u=this.options[this.currentField];return u!=null&&typeof u!="number"&&this.errors.push(`${String(this.currentField)} \u5FC5\u987B\u662F\u6570\u5B57\u7C7B\u578B`),this}array(){if(this.currentField===null)throw new Error("\u5FC5\u987B\u5148\u8C03\u7528 field() \u65B9\u6CD5\u6307\u5B9A\u8981\u9A8C\u8BC1\u7684\u5B57\u6BB5");const u=this.options[this.currentField];return u!=null&&!Array.isArray(u)&&this.errors.push(`${String(this.currentField)} \u5FC5\u987B\u662F\u6570\u7EC4\u7C7B\u578B`),this}object(){if(this.currentField===null)throw new Error("\u5FC5\u987B\u5148\u8C03\u7528 field() \u65B9\u6CD5\u6307\u5B9A\u8981\u9A8C\u8BC1\u7684\u5B57\u6BB5");const u=this.options[this.currentField];return u!=null&&typeof u!="object"&&!Array.isArray(u)&&this.errors.push(`${String(this.currentField)} \u5FC5\u987B\u662F\u5BF9\u8C61\u7C7B\u578B`),this}default(u){if(this.currentField===null)throw new Error("\u5FC5\u987B\u5148\u8C03\u7528 field() \u65B9\u6CD5\u6307\u5B9A\u8981\u9A8C\u8BC1\u7684\u5B57\u6BB5");return this.options[this.currentField]==null&&(this.options[this.currentField]=u),this}custom(u,r){if(this.currentField===null)throw new Error("\u5FC5\u987B\u5148\u8C03\u7528 field() \u65B9\u6CD5\u6307\u5B9A\u8981\u9A8C\u8BC1\u7684\u5B57\u6BB5");const t=this.options[this.currentField];return t!=null&&!u(t)&&this.errors.push(r),this}validate(){if(this.errors.length>0)throw new Error(`\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25\uFF1A
2
+ ${this.errors.map(u=>`- ${u}`).join(`
3
+ `)}`);return this.options}}export{o as V,s as d};
@@ -0,0 +1 @@
1
+ "use strict";const s=require("fs"),l=require("path");function _interopDefaultCompat(u){return u&&typeof u=="object"&&"default"in u?u.default:u}const s__default=_interopDefaultCompat(s),l__default=_interopDefaultCompat(l);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});let i=[];for(const F of e){const o=l__default.join(u,F.name);if(F.isDirectory()){if(i.push(o),t){const E=await readDirRecursive(o,t);i=[...i,...E]}}else i.push(o)}return i}async function shouldUpdateFile(u,t){try{const e=await s__default.promises.stat(u),i=await s__default.promises.stat(t);return e.mtimeMs>i.mtimeMs||e.size!==i.size}catch{return!0}}async function copySourceToTarget(u,t,e){const i=Date.now(),{recursive:F,overwrite:o,incremental:E=!1}=e;let w=0,m=0,D=0;if((await s__default.promises.stat(u)).isDirectory()){await ensureTargetDir(t);const a=await readDirRecursive(u,F),y=(await Promise.all(a.map(async r=>{const n=await s__default.promises.stat(r);return{path:r,isFile:n.isFile()}}))).filter(r=>r.isFile).map(r=>r.path);for(const r of y){const n=l__default.relative(u,r),p=l__default.join(t,n);await ensureTargetDir(l__default.dirname(p));let c=o;if(!c)try{await s__default.promises.access(p,s__default.constants.F_OK),c=!1}catch{c=!0}E&&c&&(c=await shouldUpdateFile(r,p)),c?(await s__default.promises.copyFile(r,p),w++):m++}D=(await Promise.all(a.map(async r=>{const n=await s__default.promises.stat(r);return{path:r,isDirectory:n.isDirectory()}}))).filter(r=>r.isDirectory).length}else{await ensureTargetDir(l__default.dirname(t));let a=o;if(!a)try{await s__default.promises.access(t,s__default.constants.F_OK),a=!1}catch{a=!0}E&&a&&(a=await shouldUpdateFile(u,t)),a?(await s__default.promises.copyFile(u,t),w++):m++}const f=Date.now()-i;return{copiedFiles:w,skippedFiles:m,copiedDirs:D,executionTime:f}}async function writeFileContent(u,t){try{await s__default.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}`)}}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}`)}}exports.checkSourceExists=checkSourceExists,exports.copySourceToTarget=copySourceToTarget,exports.ensureTargetDir=ensureTargetDir,exports.readDirRecursive=readDirRecursive,exports.readFileSync=readFileSync,exports.shouldUpdateFile=shouldUpdateFile,exports.writeFileContent=writeFileContent;
@@ -0,0 +1,43 @@
1
+ import { Plugin } from 'vite';
2
+
3
+ /**
4
+ * 基础插件配置
5
+ *
6
+ * @interface BasePluginOptions
7
+ */
8
+ interface BasePluginOptions {
9
+ /**
10
+ * 是否启用插件
11
+ *
12
+ * @default true
13
+ */
14
+ enabled?: boolean;
15
+ /**
16
+ * 是否启用日志
17
+ *
18
+ * @default true
19
+ */
20
+ verbose?: boolean;
21
+ /**
22
+ * 错误处理策略
23
+ *
24
+ * @default 'throw'
25
+ */
26
+ errorStrategy?: 'throw' | 'log' | 'ignore';
27
+ }
28
+ /**
29
+ * 插件选项标准化器类型
30
+ *
31
+ * @template T 目标选项类型
32
+ * @template R 原始选项类型
33
+ */
34
+ type OptionsNormalizer<T, R = any> = (raw?: R) => T;
35
+ /**
36
+ * 插件工厂函数类型
37
+ *
38
+ * @template T 插件配置类型,默认继承自 BasePluginOptions
39
+ * @template R 原始配置类型,默认与 T 相同
40
+ */
41
+ type PluginFactory<T extends BasePluginOptions = BasePluginOptions, R = T> = (options?: R) => Plugin;
42
+
43
+ export type { BasePluginOptions as B, OptionsNormalizer as O, PluginFactory as P };
@@ -0,0 +1,43 @@
1
+ import { Plugin } from 'vite';
2
+
3
+ /**
4
+ * 基础插件配置
5
+ *
6
+ * @interface BasePluginOptions
7
+ */
8
+ interface BasePluginOptions {
9
+ /**
10
+ * 是否启用插件
11
+ *
12
+ * @default true
13
+ */
14
+ enabled?: boolean;
15
+ /**
16
+ * 是否启用日志
17
+ *
18
+ * @default true
19
+ */
20
+ verbose?: boolean;
21
+ /**
22
+ * 错误处理策略
23
+ *
24
+ * @default 'throw'
25
+ */
26
+ errorStrategy?: 'throw' | 'log' | 'ignore';
27
+ }
28
+ /**
29
+ * 插件选项标准化器类型
30
+ *
31
+ * @template T 目标选项类型
32
+ * @template R 原始选项类型
33
+ */
34
+ type OptionsNormalizer<T, R = any> = (raw?: R) => T;
35
+ /**
36
+ * 插件工厂函数类型
37
+ *
38
+ * @template T 插件配置类型,默认继承自 BasePluginOptions
39
+ * @template R 原始配置类型,默认与 T 相同
40
+ */
41
+ type PluginFactory<T extends BasePluginOptions = BasePluginOptions, R = T> = (options?: R) => Plugin;
42
+
43
+ export type { BasePluginOptions as B, OptionsNormalizer as O, PluginFactory as P };
@@ -0,0 +1,43 @@
1
+ import { Plugin } from 'vite';
2
+
3
+ /**
4
+ * 基础插件配置
5
+ *
6
+ * @interface BasePluginOptions
7
+ */
8
+ interface BasePluginOptions {
9
+ /**
10
+ * 是否启用插件
11
+ *
12
+ * @default true
13
+ */
14
+ enabled?: boolean;
15
+ /**
16
+ * 是否启用日志
17
+ *
18
+ * @default true
19
+ */
20
+ verbose?: boolean;
21
+ /**
22
+ * 错误处理策略
23
+ *
24
+ * @default 'throw'
25
+ */
26
+ errorStrategy?: 'throw' | 'log' | 'ignore';
27
+ }
28
+ /**
29
+ * 插件选项标准化器类型
30
+ *
31
+ * @template T 目标选项类型
32
+ * @template R 原始选项类型
33
+ */
34
+ type OptionsNormalizer<T, R = any> = (raw?: R) => T;
35
+ /**
36
+ * 插件工厂函数类型
37
+ *
38
+ * @template T 插件配置类型,默认继承自 BasePluginOptions
39
+ * @template R 原始配置类型,默认与 T 相同
40
+ */
41
+ type PluginFactory<T extends BasePluginOptions = BasePluginOptions, R = T> = (options?: R) => Plugin;
42
+
43
+ export type { BasePluginOptions as B, OptionsNormalizer as O, PluginFactory as P };