@meng-xi/vite-plugin 0.0.2 → 0.0.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.
- package/README-en.md +37 -23
- package/README.md +64 -5
- package/dist/common/index.cjs +1 -0
- package/dist/common/index.d.cts +235 -0
- package/dist/common/index.d.mts +235 -0
- package/dist/common/index.d.ts +235 -0
- package/dist/common/index.mjs +1 -0
- package/dist/factory/index.cjs +1 -0
- package/dist/factory/index.d.cts +260 -0
- package/dist/factory/index.d.mts +260 -0
- package/dist/factory/index.d.ts +260 -0
- package/dist/factory/index.mjs +1 -0
- package/dist/index.cjs +1 -5
- package/dist/index.d.cts +7 -241
- package/dist/index.d.mts +7 -241
- package/dist/index.d.ts +7 -241
- package/dist/index.mjs +1 -5
- package/dist/logger/index.cjs +1 -0
- package/dist/logger/index.d.cts +1 -0
- package/dist/logger/index.d.mts +1 -0
- package/dist/logger/index.d.ts +1 -0
- package/dist/logger/index.mjs +1 -0
- package/dist/plugins/index.cjs +1 -0
- package/dist/plugins/index.d.cts +375 -0
- package/dist/plugins/index.d.mts +375 -0
- package/dist/plugins/index.d.ts +375 -0
- package/dist/plugins/index.mjs +1 -0
- package/dist/shared/vite-plugin.B3PARlU9.d.cts +119 -0
- package/dist/shared/vite-plugin.B3PARlU9.d.mts +119 -0
- package/dist/shared/vite-plugin.B3PARlU9.d.ts +119 -0
- package/dist/shared/vite-plugin.B88RyRN8.mjs +3 -0
- package/dist/shared/vite-plugin.C7isVPKg.mjs +1 -0
- package/dist/shared/vite-plugin.CiHfwMiN.d.cts +91 -0
- package/dist/shared/vite-plugin.CiHfwMiN.d.mts +91 -0
- package/dist/shared/vite-plugin.CiHfwMiN.d.ts +91 -0
- package/dist/shared/vite-plugin.D6NYITpX.cjs +1 -0
- package/dist/shared/vite-plugin.D8HTI0Ni.cjs +2 -0
- package/dist/shared/vite-plugin.Dd2ogbSe.mjs +2 -0
- package/dist/shared/vite-plugin.DqWt65U-.cjs +1 -0
- package/dist/shared/vite-plugin.HZb-1B5l.mjs +1 -0
- package/dist/shared/vite-plugin.IGZeStMa.cjs +3 -0
- package/dist/shared/vite-plugin.UkE7CdSe.d.cts +43 -0
- package/dist/shared/vite-plugin.UkE7CdSe.d.mts +43 -0
- package/dist/shared/vite-plugin.UkE7CdSe.d.ts +43 -0
- package/package.json +24 -5
|
@@ -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,3 @@
|
|
|
1
|
+
function s(i){return typeof i=="object"&&i!==null&&!Array.isArray(i)&&Object.prototype.toString.call(i)==="[object Object]"}function o(...i){const u={};for(const r of i)if(r)for(const t in r){if(!Object.prototype.hasOwnProperty.call(r,t))continue;const e=r[t],n=u[t];e!==void 0&&(s(e)&&s(n)?u[t]=o(n,e):u[t]=e)}return u}class l{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{l as V,o as d};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Logger as s}from"../logger/index.mjs";import"fs";import"path";import"crypto";import{V as g,d as a}from"./vite-plugin.B88RyRN8.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,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
|
+
"use strict";const o=require("fs"),u=require("path"),crypto=require("crypto");function _interopDefaultCompat(t){return t&&typeof t=="object"&&"default"in t?t.default:t}const o__default=_interopDefaultCompat(o),u__default=_interopDefaultCompat(u),h=10;async function checkSourceExists(t){try{await o__default.promises.access(t,o__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 o__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 o__default.promises.readdir(t,{withFileTypes:!0}),s=[];for(const i of r){const n=u__default.join(t,i.name),l=i.isFile(),F=i.isDirectory();if(s.push({path:n,isFile:l,isDirectory:F}),F&&e){const p=await readDirRecursive(n,e);s.push(...p)}}return s}async function shouldUpdateFile(t,e){try{const[r,s]=await Promise.all([o__default.promises.stat(t),o__default.promises.stat(e)]);return r.mtimeMs>s.mtimeMs||r.size!==s.size}catch{return!0}}async function C(t){try{return await o__default.promises.access(t,o__default.constants.F_OK),!0}catch{return!1}}async function D(t,e,r){const s=[];let i=0;async function n(){for(;i<t.length;){const F=i++,p=await e(t[F]);s[F]=p}}const l=Array(Math.min(r,t.length)).fill(null).map(()=>n());return await Promise.all(l),s}async function copySourceToTarget(t,e,r){const s=Date.now(),{recursive:i,overwrite:n,incremental:l=!1,parallelLimit:F=h}=r;let p=0,f=0,d=0;if((await o__default.promises.stat(t)).isDirectory()){await ensureTargetDir(e);const c=await readDirRecursive(t,i),g=c.filter(a=>a.isFile);d=c.filter(a=>a.isDirectory).length;const y=new Set;for(const a of g){const w=u__default.relative(t,a.path),E=u__default.dirname(u__default.join(e,w));y.add(E)}await Promise.all([...y].map(a=>ensureTargetDir(a)));const S=await D(g,async a=>{const w=u__default.relative(t,a.path),E=u__default.join(e,w);let m=n;return m||(m=!await C(E)),l&&m&&(m=await shouldUpdateFile(a.path,E)),m?(await o__default.promises.copyFile(a.path,E),{copied:!0,skipped:!1}):{copied:!1,skipped:!0}},F);for(const a of S)a.copied&&p++,a.skipped&&f++}else{await ensureTargetDir(u__default.dirname(e));let c=n;c||(c=!await C(e)),l&&c&&(c=await shouldUpdateFile(t,e)),c?(await o__default.promises.copyFile(t,e),p++):f++}const A=Date.now()-s;return{copiedFiles:p,skippedFiles:f,copiedDirs:d,executionTime:A}}async function writeFileContent(t,e){try{await o__default.promises.writeFile(t,e,"utf-8")}catch(r){const s=r;throw s.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${s.message}`)}}function readFileSync(t){try{return o__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}`)}}function padNumber(t,e=2){return t.toString().padStart(e,"0")}function generateRandomHash(t=8){const e=Math.max(1,Math.min(64,t));return crypto.randomBytes(Math.ceil(e/2)).toString("hex").slice(0,e)}function getDateFormatParams(t=new Date){return{YYYY:t.getFullYear().toString(),YY:t.getFullYear().toString().slice(-2),MM:padNumber(t.getMonth()+1),DD:padNumber(t.getDate()),HH:padNumber(t.getHours()),mm:padNumber(t.getMinutes()),ss:padNumber(t.getSeconds()),SSS:padNumber(t.getMilliseconds(),3),timestamp:t.getTime().toString()}}function formatDate(t,e){const r=getDateFormatParams(t);let s=e;for(const[i,n]of Object.entries(r))s=s.replace(new RegExp(`\\{${i}\\}`,"g"),n);return s}function parseTemplate(t,e){let r=t;for(const[s,i]of Object.entries(e))r=r.replace(new RegExp(`\\{${s}\\}`,"g"),i);return r}exports.checkSourceExists=checkSourceExists,exports.copySourceToTarget=copySourceToTarget,exports.ensureTargetDir=ensureTargetDir,exports.formatDate=formatDate,exports.generateRandomHash=generateRandomHash,exports.getDateFormatParams=getDateFormatParams,exports.padNumber=padNumber,exports.parseTemplate=parseTemplate,exports.readDirRecursive=readDirRecursive,exports.readFileSync=readFileSync,exports.shouldUpdateFile=shouldUpdateFile,exports.writeFileContent=writeFileContent;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const index=require("./vite-plugin.DqWt65U-.cjs"),format=require("./vite-plugin.D6NYITpX.cjs");require("crypto");const u$2=require("path"),validation=require("./vite-plugin.IGZeStMa.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:t,overwrite:i=!0,recursive:o=!0,incremental:r=!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 ${t}`);return}await format.checkSourceExists(e);const a=await format.copySourceToTarget(e,t,{recursive:o,overwrite:i,incremental:r});this.logger.success(`\u590D\u5236\u6587\u4EF6\u6210\u529F\uFF1A\u4ECE ${e} \u5230 ${t}`,`\u590D\u5236\u4E86 ${a.copiedFiles} \u4E2A\u6587\u4EF6\uFF0C\u8DF3\u8FC7\u4E86 ${a.skippedFiles} \u4E2A\u6587\u4EF6\uFF0C\u8017\u65F6 ${a.executionTime}ms`)}addPluginHooks(e){e.writeBundle=async()=>{await this.safeExecute(()=>this.copyFiles(),"\u590D\u5236\u6587\u4EF6")}}}const copyFile=index.createPluginFactory(p);let u$1=class extends index.BasePlugin{version="";buildTime=new Date;getDefaultOptions(){return{format:"timestamp",semverBase:"1.0.0",autoIncrement:!1,outputType:"file",outputFile:"version.json",defineName:"__APP_VERSION__",hashLength:8,prefix:"",suffix:""}}validateOptions(){if(this.validator.field("format").custom(e=>!e||["timestamp","date","datetime","semver","hash","custom"].includes(e),"format \u5FC5\u987B\u662F timestamp, date, datetime, semver, hash \u6216 custom").field("outputType").custom(e=>!e||["file","define","both"].includes(e),"outputType \u5FC5\u987B\u662F file, define \u6216 both").field("hashLength").number().custom(e=>!e||e>0&&e<=32,"hashLength \u5FC5\u987B\u5728 1-32 \u4E4B\u95F4").validate(),this.options.format==="custom"&&!this.options.customFormat)throw new Error("\u5F53 format \u4E3A custom \u65F6\uFF0C\u5FC5\u987B\u63D0\u4F9B customFormat")}getPluginName(){return"generate-version"}generateVersion(){const e=format.getDateFormatParams(this.buildTime),t=format.generateRandomHash(this.options.hashLength);let i;switch(this.options.format){case"timestamp":i=`${e.YYYY}${e.MM}${e.DD}${e.HH}${e.mm}${e.ss}`;break;case"date":i=`${e.YYYY}.${e.MM}.${e.DD}`;break;case"datetime":i=`${e.YYYY}.${e.MM}.${e.DD}.${e.HH}${e.mm}${e.ss}`;break;case"semver":i=this.options.semverBase||"1.0.0";break;case"hash":i=t;break;case"custom":i=this.parseCustomFormat({...e,hash:t});break;default:i=e.timestamp}const o=this.options.prefix||"",r=this.options.suffix||"";return`${o}${i}${r}`}parseCustomFormat(e){const t={...e};if(this.options.semverBase){const[i,o,r]=this.options.semverBase.split(".");t.major=i||"1",t.minor=o||"0",t.patch=r||"0"}return format.parseTemplate(this.options.customFormat||"",t)}generateVersionInfo(){return{version:this.version,buildTime:this.buildTime.toISOString(),timestamp:this.buildTime.getTime(),format:this.options.format,...this.options.extra}}async writeVersionFile(e){const t=u$2.join(e,this.options.outputFile||"version.json"),i=this.generateVersionInfo();await format.writeFileContent(t,JSON.stringify(i,null,2)),this.logger.success(`\u7248\u672C\u6587\u4EF6\u5DF2\u751F\u6210: ${t}`)}addPluginHooks(e){const t=e.configResolved;e.configResolved=i=>{this.options.enabled&&(this.buildTime=new Date,this.version=this.generateVersion(),this.logger.info(`\u751F\u6210\u7248\u672C\u53F7: ${this.version}`)),typeof t=="function"&&t(i)},(this.options.outputType==="define"||this.options.outputType==="both")&&(e.config=()=>{if(!this.options.enabled)return{};this.version||(this.buildTime=new Date,this.version=this.generateVersion());const i=this.options.defineName||"__APP_VERSION__";return this.logger.info(`\u6CE8\u5165\u5168\u5C40\u53D8\u91CF: ${i} = "${this.version}"`),{define:{[i]:JSON.stringify(this.version),[`${i}_INFO`]:JSON.stringify(this.generateVersionInfo())}}}),(this.options.outputType==="file"||this.options.outputType==="both")&&(e.writeBundle=async()=>{!this.options.enabled||!this.viteConfig||await this.safeExecute(async()=>{const i=this.viteConfig.build.outDir;await this.writeVersionFile(i)},"\u5199\u5165\u7248\u672C\u6587\u4EF6")})}};const generateVersion=index.createPluginFactory(u$1);function generateIconTagDescriptors(s){const e=[];if(s.link)return[];if(s.icons&&s.icons.length>0)for(const t of s.icons){const i={rel:t.rel,href:t.href};t.sizes&&(i.sizes=t.sizes),t.type&&(i.type=t.type),e.push({tag:"link",attrs:i,injectTo:"head"})}else if(s.url)e.push({tag:"link",attrs:{rel:"icon",href:s.url},injectTo:"head"});else{const t=s.base||"/",i=t.endsWith("/")?`${t}favicon.ico`:`${t}/favicon.ico`;e.push({tag:"link",attrs:{rel:"icon",href:i},injectTo:"head"})}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"}getIconTagDescriptors(){if(!this.options.enabled)return this.logger.info("\u63D2\u4EF6\u5DF2\u7981\u7528\uFF0C\u8DF3\u8FC7\u56FE\u6807\u6CE8\u5165"),[];const e=generateIconTagDescriptors(this.options);return e.length>0&&this.logger.success(`\u6210\u529F\u6CE8\u5165 ${e.length} \u4E2A\u56FE\u6807\u6807\u7B7E\u5230 HTML \u6587\u4EF6`),e}injectCustomLinkTag(e){if(!this.options.enabled||!this.options.link)return e;const t=this.options.link,i=/<\/head>/i,o=e.match(i);if(o&&o.index!==void 0){const r=e.slice(0,o.index)+t+`
|
|
2
|
+
`+e.slice(o.index);return this.logger.success("\u6210\u529F\u6CE8\u5165\u81EA\u5B9A\u4E49\u56FE\u6807\u6807\u7B7E\u5230 HTML \u6587\u4EF6"),this.logger.info(` - ${t}`),r}return this.logger.warn("\u672A\u627E\u5230 </head> \u6807\u7B7E\uFF0C\u8DF3\u8FC7\u56FE\u6807\u6CE8\u5165"),e}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:t,targetDir:i,overwrite:o=!0,recursive:r=!0}=e;await format.checkSourceExists(t);const n=await format.copySourceToTarget(t,i,{recursive:r,overwrite:o,incremental:!0});this.logger.success(`\u56FE\u6807\u6587\u4EF6\u590D\u5236\u6210\u529F\uFF1A\u4ECE ${t} \u5230 ${i}`,`\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={order:"pre",handler:t=>{if(this.options.link)return this.injectCustomLinkTag(t);const i=this.getIconTagDescriptors();return i.length>0?{html:t,tags:i}:t}},e.writeBundle=async()=>{await this.safeExecute(()=>this.copyFiles(),"\u56FE\u6807\u6587\u4EF6\u590D\u5236")}}}const injectIco=index.createPluginFactory(u,s=>typeof s=="string"?{base:s}:s||{});exports.copyFile=copyFile,exports.generateVersion=generateVersion,exports.injectIco=injectIco;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{c as a,B as c}from"./vite-plugin.C7isVPKg.mjs";import{c as l,a as h,b as p,g as F,d as m,w as f}from"./vite-plugin.HZb-1B5l.mjs";import"crypto";import{join as d}from"path";import{V as g}from"./vite-plugin.B88RyRN8.mjs";class E extends c{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:t,overwrite:i=!0,recursive:u=!0,incremental:o=!0,enabled:r=!0}=this.options;if(!r){this.logger.info(`\u63D2\u4EF6\u5DF2\u7981\u7528\uFF0C\u8DF3\u8FC7\u6267\u884C\uFF1A\u4ECE ${e} \u590D\u5236\u5230 ${t}`);return}await l(e);const n=await h(e,t,{recursive:u,overwrite:i,incremental:o});this.logger.success(`\u590D\u5236\u6587\u4EF6\u6210\u529F\uFF1A\u4ECE ${e} \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.writeBundle=async()=>{await this.safeExecute(()=>this.copyFiles(),"\u590D\u5236\u6587\u4EF6")}}}const D=a(E);let v=class extends c{version="";buildTime=new Date;getDefaultOptions(){return{format:"timestamp",semverBase:"1.0.0",autoIncrement:!1,outputType:"file",outputFile:"version.json",defineName:"__APP_VERSION__",hashLength:8,prefix:"",suffix:""}}validateOptions(){if(this.validator.field("format").custom(e=>!e||["timestamp","date","datetime","semver","hash","custom"].includes(e),"format \u5FC5\u987B\u662F timestamp, date, datetime, semver, hash \u6216 custom").field("outputType").custom(e=>!e||["file","define","both"].includes(e),"outputType \u5FC5\u987B\u662F file, define \u6216 both").field("hashLength").number().custom(e=>!e||e>0&&e<=32,"hashLength \u5FC5\u987B\u5728 1-32 \u4E4B\u95F4").validate(),this.options.format==="custom"&&!this.options.customFormat)throw new Error("\u5F53 format \u4E3A custom \u65F6\uFF0C\u5FC5\u987B\u63D0\u4F9B customFormat")}getPluginName(){return"generate-version"}generateVersion(){const e=p(this.buildTime),t=F(this.options.hashLength);let i;switch(this.options.format){case"timestamp":i=`${e.YYYY}${e.MM}${e.DD}${e.HH}${e.mm}${e.ss}`;break;case"date":i=`${e.YYYY}.${e.MM}.${e.DD}`;break;case"datetime":i=`${e.YYYY}.${e.MM}.${e.DD}.${e.HH}${e.mm}${e.ss}`;break;case"semver":i=this.options.semverBase||"1.0.0";break;case"hash":i=t;break;case"custom":i=this.parseCustomFormat({...e,hash:t});break;default:i=e.timestamp}const u=this.options.prefix||"",o=this.options.suffix||"";return`${u}${i}${o}`}parseCustomFormat(e){const t={...e};if(this.options.semverBase){const[i,u,o]=this.options.semverBase.split(".");t.major=i||"1",t.minor=u||"0",t.patch=o||"0"}return m(this.options.customFormat||"",t)}generateVersionInfo(){return{version:this.version,buildTime:this.buildTime.toISOString(),timestamp:this.buildTime.getTime(),format:this.options.format,...this.options.extra}}async writeVersionFile(e){const t=d(e,this.options.outputFile||"version.json"),i=this.generateVersionInfo();await f(t,JSON.stringify(i,null,2)),this.logger.success(`\u7248\u672C\u6587\u4EF6\u5DF2\u751F\u6210: ${t}`)}addPluginHooks(e){const t=e.configResolved;e.configResolved=i=>{this.options.enabled&&(this.buildTime=new Date,this.version=this.generateVersion(),this.logger.info(`\u751F\u6210\u7248\u672C\u53F7: ${this.version}`)),typeof t=="function"&&t(i)},(this.options.outputType==="define"||this.options.outputType==="both")&&(e.config=()=>{if(!this.options.enabled)return{};this.version||(this.buildTime=new Date,this.version=this.generateVersion());const i=this.options.defineName||"__APP_VERSION__";return this.logger.info(`\u6CE8\u5165\u5168\u5C40\u53D8\u91CF: ${i} = "${this.version}"`),{define:{[i]:JSON.stringify(this.version),[`${i}_INFO`]:JSON.stringify(this.generateVersionInfo())}}}),(this.options.outputType==="file"||this.options.outputType==="both")&&(e.writeBundle=async()=>{!this.options.enabled||!this.viteConfig||await this.safeExecute(async()=>{const i=this.viteConfig.build.outDir;await this.writeVersionFile(i)},"\u5199\u5165\u7248\u672C\u6587\u4EF6")})}};const C=a(v);function $(s){const e=[];if(s.link)return[];if(s.icons&&s.icons.length>0)for(const t of s.icons){const i={rel:t.rel,href:t.href};t.sizes&&(i.sizes=t.sizes),t.type&&(i.type=t.type),e.push({tag:"link",attrs:i,injectTo:"head"})}else if(s.url)e.push({tag:"link",attrs:{rel:"icon",href:s.url},injectTo:"head"});else{const t=s.base||"/",i=t.endsWith("/")?`${t}favicon.ico`:`${t}/favicon.ico`;e.push({tag:"link",attrs:{rel:"icon",href:i},injectTo:"head"})}return e}class b 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 g(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"}getIconTagDescriptors(){if(!this.options.enabled)return this.logger.info("\u63D2\u4EF6\u5DF2\u7981\u7528\uFF0C\u8DF3\u8FC7\u56FE\u6807\u6CE8\u5165"),[];const e=$(this.options);return e.length>0&&this.logger.success(`\u6210\u529F\u6CE8\u5165 ${e.length} \u4E2A\u56FE\u6807\u6807\u7B7E\u5230 HTML \u6587\u4EF6`),e}injectCustomLinkTag(e){if(!this.options.enabled||!this.options.link)return e;const t=this.options.link,i=/<\/head>/i,u=e.match(i);if(u&&u.index!==void 0){const o=e.slice(0,u.index)+t+`
|
|
2
|
+
`+e.slice(u.index);return this.logger.success("\u6210\u529F\u6CE8\u5165\u81EA\u5B9A\u4E49\u56FE\u6807\u6807\u7B7E\u5230 HTML \u6587\u4EF6"),this.logger.info(` - ${t}`),o}return this.logger.warn("\u672A\u627E\u5230 </head> \u6807\u7B7E\uFF0C\u8DF3\u8FC7\u56FE\u6807\u6CE8\u5165"),e}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:t,targetDir:i,overwrite:u=!0,recursive:o=!0}=e;await l(t);const r=await h(t,i,{recursive:o,overwrite:u,incremental:!0});this.logger.success(`\u56FE\u6807\u6587\u4EF6\u590D\u5236\u6210\u529F\uFF1A\u4ECE ${t} \u5230 ${i}`,`\u590D\u5236\u4E86 ${r.copiedFiles} \u4E2A\u6587\u4EF6\uFF0C\u8DF3\u8FC7\u4E86 ${r.skippedFiles} \u4E2A\u6587\u4EF6\uFF0C\u8017\u65F6 ${r.executionTime}ms`)}addPluginHooks(e){e.transformIndexHtml={order:"pre",handler:t=>{if(this.options.link)return this.injectCustomLinkTag(t);const i=this.getIconTagDescriptors();return i.length>0?{html:t,tags:i}:t}},e.writeBundle=async()=>{await this.safeExecute(()=>this.copyFiles(),"\u56FE\u6807\u6587\u4EF6\u590D\u5236")}}}const y=a(b,s=>typeof s=="string"?{base:s}:s||{});export{D as c,C as g,y as i};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const logger_index=require("../logger/index.cjs");require("fs"),require("path"),require("crypto");const validation=require("./vite-plugin.IGZeStMa.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 @@
|
|
|
1
|
+
import i from"fs";import l from"path";import{randomBytes as x}from"crypto";const T=10;async function Y(u){try{await i.promises.access(u,i.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 f(u){try{await i.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 i.promises.readdir(u,{withFileTypes:!0}),r=[];for(const s of e){const n=l.join(u,s.name),p=s.isFile(),c=s.isDirectory();if(r.push({path:n,isFile:p,isDirectory:c}),c&&t){const F=await h(n,t);r.push(...F)}}return r}async function g(u,t){try{const[e,r]=await Promise.all([i.promises.stat(u),i.promises.stat(t)]);return e.mtimeMs>r.mtimeMs||e.size!==r.size}catch{return!0}}async function C(u){try{return await i.promises.access(u,i.constants.F_OK),!0}catch{return!1}}async function k(u,t,e){const r=[];let s=0;async function n(){for(;s<u.length;){const c=s++,F=await t(u[c]);r[c]=F}}const p=Array(Math.min(e,u.length)).fill(null).map(()=>n());return await Promise.all(p),r}async function v(u,t,e){const r=Date.now(),{recursive:s,overwrite:n,incremental:p=!1,parallelLimit:c=T}=e;let F=0,D=0,y=0;if((await i.promises.stat(u)).isDirectory()){await f(t);const o=await h(u,s),A=o.filter(a=>a.isFile);y=o.filter(a=>a.isDirectory).length;const S=new Set;for(const a of A){const d=l.relative(u,a.path),m=l.dirname(l.join(t,d));S.add(m)}await Promise.all([...S].map(a=>f(a)));const M=await k(A,async a=>{const d=l.relative(u,a.path),m=l.join(t,d);let w=n;return w||(w=!await C(m)),p&&w&&(w=await g(a.path,m)),w?(await i.promises.copyFile(a.path,m),{copied:!0,skipped:!1}):{copied:!1,skipped:!0}},c);for(const a of M)a.copied&&F++,a.skipped&&D++}else{await f(l.dirname(t));let o=n;o||(o=!await C(t)),p&&o&&(o=await g(u,t)),o?(await i.promises.copyFile(u,t),F++):D++}const $=Date.now()-r;return{copiedFiles:F,skippedFiles:D,copiedDirs:y,executionTime:$}}async function j(u,t){try{await i.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}`)}}function O(u){try{return i.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}`)}}function E(u,t=2){return u.toString().padStart(t,"0")}function b(u=8){const t=Math.max(1,Math.min(64,u));return x(Math.ceil(t/2)).toString("hex").slice(0,t)}function B(u=new Date){return{YYYY:u.getFullYear().toString(),YY:u.getFullYear().toString().slice(-2),MM:E(u.getMonth()+1),DD:E(u.getDate()),HH:E(u.getHours()),mm:E(u.getMinutes()),ss:E(u.getSeconds()),SSS:E(u.getMilliseconds(),3),timestamp:u.getTime().toString()}}function H(u,t){const e=B(u);let r=t;for(const[s,n]of Object.entries(e))r=r.replace(new RegExp(`\\{${s}\\}`,"g"),n);return r}function P(u,t){let e=u;for(const[r,s]of Object.entries(t))e=e.replace(new RegExp(`\\{${r}\\}`,"g"),s);return e}export{v as a,B as b,Y as c,P as d,f as e,H as f,b as g,O as h,E as p,h as r,g as s,j as w};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";function i(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&Object.prototype.toString.call(e)==="[object Object]"}function deepMerge(...e){const u={};for(const r of e)if(r)for(const t in r){if(!Object.prototype.hasOwnProperty.call(r,t))continue;const n=r[t],s=u[t];n!==void 0&&(i(n)&&i(s)?u[t]=deepMerge(s,n):u[t]=n)}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,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 };
|