@vlian/framework 1.2.19 → 1.2.37
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/dist/analytics.umd.js +208 -2395
- package/dist/analytics.umd.js.map +1 -1
- package/dist/core/error/ErrorHandler.cjs.map +1 -1
- package/dist/core/error/ErrorHandler.d.ts +1 -1
- package/dist/core/error/ErrorHandler.js.map +1 -1
- package/dist/core/index.cjs +0 -1
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.ts +1 -2
- package/dist/core/index.js +0 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/initialization/index.cjs.map +1 -1
- package/dist/core/initialization/index.d.ts +1 -1
- package/dist/core/initialization/index.js.map +1 -1
- package/dist/core/initialization/initialization.cjs +2 -147
- package/dist/core/initialization/initialization.cjs.map +1 -1
- package/dist/core/initialization/initialization.d.ts +0 -57
- package/dist/core/initialization/initialization.js +2 -148
- package/dist/core/initialization/initialization.js.map +1 -1
- package/dist/core/kernel/startKernel.cjs +1 -2
- package/dist/core/kernel/startKernel.cjs.map +1 -1
- package/dist/core/kernel/startKernel.js +1 -2
- package/dist/core/kernel/startKernel.js.map +1 -1
- package/dist/core/plugin.cjs +16 -16
- package/dist/core/plugin.cjs.map +1 -1
- package/dist/core/plugin.d.ts +5 -1
- package/dist/core/plugin.js +17 -17
- package/dist/core/plugin.js.map +1 -1
- package/dist/core/router/monitoring/RouterMonitoring.cjs +1 -1
- package/dist/core/router/monitoring/RouterMonitoring.cjs.map +1 -1
- package/dist/core/router/monitoring/RouterMonitoring.js +1 -1
- package/dist/core/router/monitoring/RouterMonitoring.js.map +1 -1
- package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.cjs +13 -8
- package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.cjs.map +1 -1
- package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.js +13 -8
- package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.js.map +1 -1
- package/dist/core/router/utils/adapters/react-router/transform.cjs +4 -0
- package/dist/core/router/utils/adapters/react-router/transform.cjs.map +1 -1
- package/dist/core/router/utils/adapters/react-router/transform.js +4 -0
- package/dist/core/router/utils/adapters/react-router/transform.js.map +1 -1
- package/dist/core/startup/initializeServices.cjs +1 -1
- package/dist/core/startup/initializeServices.cjs.map +1 -1
- package/dist/core/startup/initializeServices.d.ts +1 -1
- package/dist/core/startup/initializeServices.js +1 -1
- package/dist/core/startup/initializeServices.js.map +1 -1
- package/dist/core/startup/performanceTracker.cjs.map +1 -1
- package/dist/core/startup/performanceTracker.d.ts +1 -1
- package/dist/core/startup/performanceTracker.js.map +1 -1
- package/dist/core/startup/renderApp.cjs +1 -1
- package/dist/core/startup/renderApp.cjs.map +1 -1
- package/dist/core/startup/renderApp.d.ts +1 -1
- package/dist/core/startup/renderApp.js +1 -1
- package/dist/core/startup/renderApp.js.map +1 -1
- package/dist/core/startup/startApp.cjs +2 -4
- package/dist/core/startup/startApp.cjs.map +1 -1
- package/dist/core/startup/startApp.js +3 -5
- package/dist/core/startup/startApp.js.map +1 -1
- package/dist/core/types.d.ts +2 -6
- package/dist/core/types.js.map +1 -1
- package/dist/index.cjs +15 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +11758 -32895
- package/dist/index.umd.js.map +1 -1
- package/dist/kernel/constants.cjs +67 -0
- package/dist/kernel/constants.cjs.map +1 -0
- package/dist/kernel/constants.d.ts +5 -0
- package/dist/kernel/constants.js +43 -0
- package/dist/kernel/constants.js.map +1 -0
- package/dist/kernel/index.cjs +40 -0
- package/dist/kernel/index.cjs.map +1 -0
- package/dist/kernel/index.d.ts +3 -0
- package/dist/kernel/index.js +4 -0
- package/dist/kernel/index.js.map +1 -0
- package/dist/kernel/kernel.cjs +296 -0
- package/dist/kernel/kernel.cjs.map +1 -0
- package/dist/kernel/kernel.d.ts +40 -0
- package/dist/kernel/kernel.js +272 -0
- package/dist/kernel/kernel.js.map +1 -0
- package/dist/kernel/manager/cacheManager.cjs +46 -0
- package/dist/kernel/manager/cacheManager.cjs.map +1 -0
- package/dist/kernel/manager/cacheManager.d.ts +6 -0
- package/dist/kernel/manager/cacheManager.js +36 -0
- package/dist/kernel/manager/cacheManager.js.map +1 -0
- package/dist/kernel/manager/i18nManager.cjs +68 -0
- package/dist/kernel/manager/i18nManager.cjs.map +1 -0
- package/dist/kernel/manager/i18nManager.d.ts +8 -0
- package/dist/kernel/manager/i18nManager.js +58 -0
- package/dist/kernel/manager/i18nManager.js.map +1 -0
- package/dist/kernel/manager/index.cjs +30 -0
- package/dist/kernel/manager/index.cjs.map +1 -0
- package/dist/kernel/manager/index.d.ts +4 -0
- package/dist/kernel/manager/index.js +6 -0
- package/dist/kernel/manager/index.js.map +1 -0
- package/dist/kernel/manager/loggerManager.cjs +70 -0
- package/dist/kernel/manager/loggerManager.cjs.map +1 -0
- package/dist/kernel/manager/loggerManager.d.ts +14 -0
- package/dist/kernel/manager/loggerManager.js +60 -0
- package/dist/kernel/manager/loggerManager.js.map +1 -0
- package/dist/kernel/manager/persistence.cjs +93 -0
- package/dist/kernel/manager/persistence.cjs.map +1 -0
- package/dist/kernel/manager/persistence.d.ts +3 -0
- package/dist/kernel/manager/persistence.js +75 -0
- package/dist/kernel/manager/persistence.js.map +1 -0
- package/dist/kernel/manager/themeManager.cjs +85 -0
- package/dist/kernel/manager/themeManager.cjs.map +1 -0
- package/dist/kernel/manager/themeManager.d.ts +9 -0
- package/dist/kernel/manager/themeManager.js +75 -0
- package/dist/kernel/manager/themeManager.js.map +1 -0
- package/dist/kernel/types.cjs.map +1 -0
- package/dist/kernel/types.d.ts +72 -0
- package/dist/kernel/types.js.map +1 -0
- package/dist/library/storage/index.cjs +1 -1
- package/dist/library/storage/index.cjs.map +1 -1
- package/dist/library/storage/index.d.ts +1 -0
- package/dist/library/storage/index.js +1 -1
- package/dist/library/storage/index.js.map +1 -1
- package/dist/request/adapter.d.ts +1 -0
- package/dist/request/core.d.ts +1 -0
- package/dist/request/index.d.ts +1 -42
- package/dist/request/plugin/csrfPlugin.d.ts +2 -2
- package/dist/request/plugin/queue.d.ts +2 -2
- package/dist/request/plugin.d.ts +1 -0
- package/dist/request/runtime.d.ts +1 -0
- package/dist/request/types.d.ts +1 -394
- package/dist/request/utils.d.ts +1 -0
- package/dist/state.umd.js +1 -1
- package/dist/utils/csrf.cjs +13 -152
- package/dist/utils/csrf.cjs.map +1 -1
- package/dist/utils/csrf.d.ts +1 -72
- package/dist/utils/csrf.js +1 -142
- package/dist/utils/csrf.js.map +1 -1
- package/dist/utils/errors/ErrorCodes.cjs +6 -76
- package/dist/utils/errors/ErrorCodes.cjs.map +1 -1
- package/dist/utils/errors/ErrorCodes.d.ts +1 -45
- package/dist/utils/errors/ErrorCodes.js +1 -84
- package/dist/utils/errors/ErrorCodes.js.map +1 -1
- package/dist/utils/errors.cjs +15 -344
- package/dist/utils/errors.cjs.map +1 -1
- package/dist/utils/errors.d.ts +1 -183
- package/dist/utils/errors.js +1 -352
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/logger.cjs +5 -374
- package/dist/utils/logger.cjs.map +1 -1
- package/dist/utils/logger.d.ts +2 -189
- package/dist/utils/logger.js +1 -379
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/logger.types.cjs +3 -12
- package/dist/utils/logger.types.cjs.map +1 -1
- package/dist/utils/logger.types.d.ts +2 -57
- package/dist/utils/logger.types.js +1 -10
- package/dist/utils/logger.types.js.map +1 -1
- package/dist/utils/monitoring.cjs +11 -302
- package/dist/utils/monitoring.cjs.map +1 -1
- package/dist/utils/monitoring.d.ts +1 -163
- package/dist/utils/monitoring.js +1 -294
- package/dist/utils/monitoring.js.map +1 -1
- package/dist/utils/performance.cjs +5 -352
- package/dist/utils/performance.cjs.map +1 -1
- package/dist/utils/performance.d.ts +2 -246
- package/dist/utils/performance.js +1 -354
- package/dist/utils/performance.js.map +1 -1
- package/dist/utils/resourceLoader.cjs +5 -303
- package/dist/utils/resourceLoader.cjs.map +1 -1
- package/dist/utils/resourceLoader.d.ts +2 -130
- package/dist/utils/resourceLoader.js +1 -305
- package/dist/utils/resourceLoader.js.map +1 -1
- package/dist/utils/runtimeSecurity.cjs +2 -140
- package/dist/utils/runtimeSecurity.cjs.map +1 -1
- package/dist/utils/runtimeSecurity.d.ts +2 -104
- package/dist/utils/runtimeSecurity.js +1 -141
- package/dist/utils/runtimeSecurity.js.map +1 -1
- package/dist/utils/security.cjs +3 -314
- package/dist/utils/security.cjs.map +1 -1
- package/dist/utils/security.d.ts +2 -80
- package/dist/utils/security.js +1 -311
- package/dist/utils/security.js.map +1 -1
- package/dist/utils/traceId.cjs +10 -111
- package/dist/utils/traceId.cjs.map +1 -1
- package/dist/utils/traceId.d.ts +1 -63
- package/dist/utils/traceId.js +1 -116
- package/dist/utils/traceId.js.map +1 -1
- package/dist/utils/validation.cjs +3 -173
- package/dist/utils/validation.cjs.map +1 -1
- package/dist/utils/validation.d.ts +2 -110
- package/dist/utils/validation.js +1 -175
- package/dist/utils/validation.js.map +1 -1
- package/package.json +98 -13
- package/dist/core/ui-adapter/adapters.cjs +0 -45
- package/dist/core/ui-adapter/adapters.cjs.map +0 -1
- package/dist/core/ui-adapter/adapters.d.ts +0 -4
- package/dist/core/ui-adapter/adapters.js +0 -27
- package/dist/core/ui-adapter/adapters.js.map +0 -1
- package/dist/core/ui-adapter/index.cjs +0 -21
- package/dist/core/ui-adapter/index.cjs.map +0 -1
- package/dist/core/ui-adapter/index.d.ts +0 -2
- package/dist/core/ui-adapter/index.js +0 -3
- package/dist/core/ui-adapter/index.js.map +0 -1
- package/dist/core/ui-adapter/types.cjs.map +0 -1
- package/dist/core/ui-adapter/types.d.ts +0 -24
- package/dist/core/ui-adapter/types.js.map +0 -1
- package/dist/request/adapter/RequestAdapter.cjs +0 -78
- package/dist/request/adapter/RequestAdapter.cjs.map +0 -1
- package/dist/request/adapter/axiosAdapter.cjs +0 -164
- package/dist/request/adapter/axiosAdapter.cjs.map +0 -1
- package/dist/request/adapter/fetchAdapter.cjs +0 -134
- package/dist/request/adapter/fetchAdapter.cjs.map +0 -1
- package/dist/request/adapter/index.cjs +0 -80
- package/dist/request/adapter/index.cjs.map +0 -1
- package/dist/request/adapter/kyAdapter.cjs +0 -191
- package/dist/request/adapter/kyAdapter.cjs.map +0 -1
- package/dist/request/adapter/undiciAdapter.cjs +0 -213
- package/dist/request/adapter/undiciAdapter.cjs.map +0 -1
- package/dist/request/core/RequestClient.cjs +0 -558
- package/dist/request/core/RequestClient.cjs.map +0 -1
- package/dist/request/core/index.cjs +0 -15
- package/dist/request/core/index.cjs.map +0 -1
- package/dist/request/index.cjs +0 -149
- package/dist/request/index.cjs.map +0 -1
- package/dist/request/plugin/RequestPlugin.cjs +0 -218
- package/dist/request/plugin/RequestPlugin.cjs.map +0 -1
- package/dist/request/plugin/cache.cjs +0 -269
- package/dist/request/plugin/cache.cjs.map +0 -1
- package/dist/request/plugin/csrfPlugin.cjs +0 -40
- package/dist/request/plugin/csrfPlugin.cjs.map +0 -1
- package/dist/request/plugin/index.cjs +0 -53
- package/dist/request/plugin/index.cjs.map +0 -1
- package/dist/request/plugin/monitoring.cjs +0 -216
- package/dist/request/plugin/monitoring.cjs.map +0 -1
- package/dist/request/plugin/queue.cjs +0 -140
- package/dist/request/plugin/queue.cjs.map +0 -1
- package/dist/request/plugin/retry.cjs +0 -98
- package/dist/request/plugin/retry.cjs.map +0 -1
- package/dist/request/plugin/validation.cjs +0 -121
- package/dist/request/plugin/validation.cjs.map +0 -1
- package/dist/request/runtime/RequestContext.cjs +0 -77
- package/dist/request/runtime/RequestContext.cjs.map +0 -1
- package/dist/request/runtime/index.cjs +0 -32
- package/dist/request/runtime/index.cjs.map +0 -1
- package/dist/request/types.cjs +0 -112
- package/dist/request/types.cjs.map +0 -1
- package/dist/request/utils/RequestQueueManager.cjs +0 -168
- package/dist/request/utils/RequestQueueManager.cjs.map +0 -1
- package/dist/request/utils/dependencyCheck.cjs +0 -237
- package/dist/request/utils/dependencyCheck.cjs.map +0 -1
- package/dist/request/utils/index.cjs +0 -30
- package/dist/request/utils/index.cjs.map +0 -1
- package/dist/request.umd.js +0 -5392
- package/dist/request.umd.js.map +0 -1
- /package/dist/{core/ui-adapter → kernel}/types.cjs +0 -0
- /package/dist/{core/ui-adapter → kernel}/types.js +0 -0
package/dist/utils/security.js
CHANGED
|
@@ -1,313 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
import { SecurityError } from "./errors";
|
|
3
|
-
/**
|
|
4
|
-
* 敏感数据标识(扩展列表)
|
|
5
|
-
*/ export const SENSITIVE_FIELDS = [
|
|
6
|
-
'password',
|
|
7
|
-
'pwd',
|
|
8
|
-
'passwd',
|
|
9
|
-
'token',
|
|
10
|
-
'secret',
|
|
11
|
-
'key',
|
|
12
|
-
'apiKey',
|
|
13
|
-
'apikey',
|
|
14
|
-
'api_key',
|
|
15
|
-
'accessToken',
|
|
16
|
-
'access_token',
|
|
17
|
-
'refreshToken',
|
|
18
|
-
'refresh_token',
|
|
19
|
-
'authorization',
|
|
20
|
-
'auth',
|
|
21
|
-
'cookie',
|
|
22
|
-
'session',
|
|
23
|
-
'sessionId',
|
|
24
|
-
'session_id',
|
|
25
|
-
'creditCard',
|
|
26
|
-
'credit_card',
|
|
27
|
-
'cardNumber',
|
|
28
|
-
'card_number',
|
|
29
|
-
'cvv',
|
|
30
|
-
'cvc',
|
|
31
|
-
'ssn',
|
|
32
|
-
'socialSecurityNumber',
|
|
33
|
-
'social_security_number',
|
|
34
|
-
'phone',
|
|
35
|
-
'phoneNumber',
|
|
36
|
-
'phone_number',
|
|
37
|
-
'mobile',
|
|
38
|
-
'email',
|
|
39
|
-
'emailAddress',
|
|
40
|
-
'email_address',
|
|
41
|
-
'privateKey',
|
|
42
|
-
'private_key',
|
|
43
|
-
'secretKey',
|
|
44
|
-
'secret_key',
|
|
45
|
-
'apiSecret',
|
|
46
|
-
'api_secret'
|
|
47
|
-
];
|
|
48
|
-
/**
|
|
49
|
-
* 敏感信息检测模式(正则表达式)
|
|
50
|
-
*/ const SENSITIVE_PATTERNS = [
|
|
51
|
-
/\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b/,
|
|
52
|
-
/\b\d{3}-\d{2}-\d{4}\b/,
|
|
53
|
-
/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/,
|
|
54
|
-
/\b\d{10,}\b/
|
|
55
|
-
];
|
|
56
|
-
/**
|
|
57
|
-
* 安全工具类
|
|
58
|
-
*/ export class SecurityUtils {
|
|
59
|
-
/**
|
|
60
|
-
* 清理 HTML,防止 XSS 攻击
|
|
61
|
-
*/ static sanitizeHTML(html, config) {
|
|
62
|
-
if (typeof window === 'undefined') {
|
|
63
|
-
// Node.js 环境,返回原始字符串(需要服务端处理)
|
|
64
|
-
return html;
|
|
65
|
-
}
|
|
66
|
-
try {
|
|
67
|
-
if (config?.allowHTML) {
|
|
68
|
-
// 默认禁止所有标签,除非明确允许
|
|
69
|
-
const allowedTags = config.allowedTags && config.allowedTags.length > 0 ? config.allowedTags : [];
|
|
70
|
-
const allowedAttributes = config.allowedAttributes && config.allowedAttributes.length > 0 ? config.allowedAttributes : [];
|
|
71
|
-
return DOMPurify.sanitize(html, {
|
|
72
|
-
ALLOWED_TAGS: allowedTags,
|
|
73
|
-
ALLOWED_ATTR: allowedAttributes,
|
|
74
|
-
FORBID_TAGS: [
|
|
75
|
-
'script',
|
|
76
|
-
'iframe',
|
|
77
|
-
'object',
|
|
78
|
-
'embed',
|
|
79
|
-
'form',
|
|
80
|
-
'link',
|
|
81
|
-
'meta',
|
|
82
|
-
'style'
|
|
83
|
-
],
|
|
84
|
-
FORBID_ATTR: [
|
|
85
|
-
'onerror',
|
|
86
|
-
'onload',
|
|
87
|
-
'onclick',
|
|
88
|
-
'onmouseover',
|
|
89
|
-
'onfocus',
|
|
90
|
-
'onblur',
|
|
91
|
-
'onchange'
|
|
92
|
-
],
|
|
93
|
-
// 添加更多安全配置
|
|
94
|
-
KEEP_CONTENT: false,
|
|
95
|
-
RETURN_DOM: false,
|
|
96
|
-
RETURN_DOM_FRAGMENT: false,
|
|
97
|
-
RETURN_TRUSTED_TYPE: false
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
// 默认模式:完全清理,不允许任何 HTML
|
|
101
|
-
return DOMPurify.sanitize(html, {
|
|
102
|
-
ALLOWED_TAGS: [],
|
|
103
|
-
KEEP_CONTENT: false
|
|
104
|
-
});
|
|
105
|
-
} catch (error) {
|
|
106
|
-
// 错误处理:不泄露敏感信息,记录错误但不抛出详细错误
|
|
107
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
108
|
-
// 只记录错误类型,不记录具体内容
|
|
109
|
-
console.error('HTML 清理失败:', errorMessage.substring(0, 50));
|
|
110
|
-
// 返回安全的空字符串或清理后的文本
|
|
111
|
-
return this.sanitizeText(html);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* 清理文本内容(移除所有 HTML 标签)
|
|
116
|
-
*/ static sanitizeText(text) {
|
|
117
|
-
if (typeof window === 'undefined') {
|
|
118
|
-
return text.replace(/<[^>]*>/g, '');
|
|
119
|
-
}
|
|
120
|
-
try {
|
|
121
|
-
return DOMPurify.sanitize(text, {
|
|
122
|
-
ALLOWED_TAGS: []
|
|
123
|
-
});
|
|
124
|
-
} catch (error) {
|
|
125
|
-
throw new SecurityError('文本清理失败', error instanceof Error ? error : undefined);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* 检查字符串是否包含潜在的危险内容
|
|
130
|
-
*/ static containsDangerousContent(text) {
|
|
131
|
-
const dangerousPatterns = [
|
|
132
|
-
/<script[\s\S]*?>[\s\S]*?<\/script>/gi,
|
|
133
|
-
/javascript:/gi,
|
|
134
|
-
/on\w+\s*=/gi,
|
|
135
|
-
/<iframe[\s\S]*?>/gi,
|
|
136
|
-
/<object[\s\S]*?>/gi,
|
|
137
|
-
/<embed[\s\S]*?>/gi,
|
|
138
|
-
/<link[\s\S]*?>/gi,
|
|
139
|
-
/<meta[\s\S]*?>/gi,
|
|
140
|
-
/data:text\/html/gi,
|
|
141
|
-
/vbscript:/gi,
|
|
142
|
-
/expression\s*\(/gi,
|
|
143
|
-
/@import/gi,
|
|
144
|
-
/<style[\s\S]*?>[\s\S]*?<\/style>/gi
|
|
145
|
-
];
|
|
146
|
-
return dangerousPatterns.some((pattern)=>pattern.test(text));
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* 验证 URL 是否安全
|
|
150
|
-
*/ static isSafeUrl(url) {
|
|
151
|
-
try {
|
|
152
|
-
const urlObj = new URL(url);
|
|
153
|
-
// 检查协议
|
|
154
|
-
if (![
|
|
155
|
-
'http:',
|
|
156
|
-
'https:'
|
|
157
|
-
].includes(urlObj.protocol)) {
|
|
158
|
-
return false;
|
|
159
|
-
}
|
|
160
|
-
// 检查是否包含危险内容
|
|
161
|
-
return !this.containsDangerousContent(url);
|
|
162
|
-
} catch {
|
|
163
|
-
return false;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* 检查字段名是否为敏感字段
|
|
168
|
-
*/ static isSensitiveField(fieldName) {
|
|
169
|
-
const lowerFieldName = fieldName.toLowerCase();
|
|
170
|
-
return SENSITIVE_FIELDS.some((field)=>lowerFieldName.includes(field.toLowerCase()));
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* 检查值是否包含敏感信息(基于模式匹配)
|
|
174
|
-
*/ static containsSensitiveData(value) {
|
|
175
|
-
return SENSITIVE_PATTERNS.some((pattern)=>pattern.test(value));
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* 生成 CSP(Content Security Policy)头
|
|
179
|
-
*/ static generateCSP(config) {
|
|
180
|
-
const directives = [];
|
|
181
|
-
const allowUnsafeInline = config?.allowUnsafeInline ?? false;
|
|
182
|
-
const allowUnsafeEval = config?.allowUnsafeEval ?? false;
|
|
183
|
-
if (config?.defaultSrc) {
|
|
184
|
-
directives.push(`default-src ${config.defaultSrc.join(' ')}`);
|
|
185
|
-
} else {
|
|
186
|
-
directives.push("default-src 'self'");
|
|
187
|
-
}
|
|
188
|
-
if (config?.scriptSrc) {
|
|
189
|
-
directives.push(`script-src ${config.scriptSrc.join(' ')}`);
|
|
190
|
-
} else {
|
|
191
|
-
// 默认不允许 unsafe-inline 和 unsafe-eval,提高安全性
|
|
192
|
-
const scriptSrc = [
|
|
193
|
-
"'self'"
|
|
194
|
-
];
|
|
195
|
-
if (allowUnsafeInline) {
|
|
196
|
-
scriptSrc.push("'unsafe-inline'");
|
|
197
|
-
}
|
|
198
|
-
if (allowUnsafeEval) {
|
|
199
|
-
scriptSrc.push("'unsafe-eval'");
|
|
200
|
-
}
|
|
201
|
-
directives.push(`script-src ${scriptSrc.join(' ')}`);
|
|
202
|
-
}
|
|
203
|
-
if (config?.styleSrc) {
|
|
204
|
-
directives.push(`style-src ${config.styleSrc.join(' ')}`);
|
|
205
|
-
} else {
|
|
206
|
-
// 对于样式,可以使用 nonce 或 hash 替代 unsafe-inline
|
|
207
|
-
const styleSrc = [
|
|
208
|
-
"'self'"
|
|
209
|
-
];
|
|
210
|
-
if (allowUnsafeInline) {
|
|
211
|
-
styleSrc.push("'unsafe-inline'");
|
|
212
|
-
}
|
|
213
|
-
directives.push(`style-src ${styleSrc.join(' ')}`);
|
|
214
|
-
}
|
|
215
|
-
if (config?.imgSrc) {
|
|
216
|
-
directives.push(`img-src ${config.imgSrc.join(' ')}`);
|
|
217
|
-
} else {
|
|
218
|
-
directives.push("img-src 'self' data: https:");
|
|
219
|
-
}
|
|
220
|
-
if (config?.connectSrc) {
|
|
221
|
-
directives.push(`connect-src ${config.connectSrc.join(' ')}`);
|
|
222
|
-
} else {
|
|
223
|
-
directives.push("connect-src 'self'");
|
|
224
|
-
}
|
|
225
|
-
if (config?.fontSrc) {
|
|
226
|
-
directives.push(`font-src ${config.fontSrc.join(' ')}`);
|
|
227
|
-
} else {
|
|
228
|
-
directives.push("font-src 'self' data:");
|
|
229
|
-
}
|
|
230
|
-
if (config?.frameSrc) {
|
|
231
|
-
directives.push(`frame-src ${config.frameSrc.join(' ')}`);
|
|
232
|
-
} else {
|
|
233
|
-
directives.push("frame-src 'none'");
|
|
234
|
-
}
|
|
235
|
-
return directives.join('; ');
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* 转义 HTML 特殊字符
|
|
239
|
-
*/ static escapeHTML(text) {
|
|
240
|
-
const map = {
|
|
241
|
-
'&': '&',
|
|
242
|
-
'<': '<',
|
|
243
|
-
'>': '>',
|
|
244
|
-
'"': '"',
|
|
245
|
-
"'": '''
|
|
246
|
-
};
|
|
247
|
-
return text.replace(/[&<>"']/g, (char)=>map[char]);
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* 验证输入是否安全
|
|
251
|
-
*/ static validateInput(input) {
|
|
252
|
-
if (typeof input !== 'string') {
|
|
253
|
-
return {
|
|
254
|
-
safe: true
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
if (this.containsDangerousContent(input)) {
|
|
258
|
-
return {
|
|
259
|
-
safe: false,
|
|
260
|
-
sanitized: this.sanitizeText(input),
|
|
261
|
-
reason: '包含潜在的危险内容'
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
// 检查是否包含敏感数据模式
|
|
265
|
-
if (this.containsSensitiveData(input)) {
|
|
266
|
-
return {
|
|
267
|
-
safe: false,
|
|
268
|
-
sanitized: this.sanitizeText(input),
|
|
269
|
-
reason: '可能包含敏感信息'
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
return {
|
|
273
|
-
safe: true,
|
|
274
|
-
sanitized: input
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
/**
|
|
278
|
-
* 深度脱敏处理(递归处理嵌套对象)
|
|
279
|
-
*/ static deepSanitize(data, maxDepth = 10, currentDepth = 0) {
|
|
280
|
-
if (currentDepth >= maxDepth) {
|
|
281
|
-
return '***'; // 防止无限递归
|
|
282
|
-
}
|
|
283
|
-
if (data === null || data === undefined) {
|
|
284
|
-
return data;
|
|
285
|
-
}
|
|
286
|
-
if (typeof data === 'string') {
|
|
287
|
-
if (this.containsDangerousContent(data) || this.containsSensitiveData(data)) {
|
|
288
|
-
return this.sanitizeText(data);
|
|
289
|
-
}
|
|
290
|
-
return data;
|
|
291
|
-
}
|
|
292
|
-
if (typeof data === 'number' || typeof data === 'boolean') {
|
|
293
|
-
return data;
|
|
294
|
-
}
|
|
295
|
-
if (Array.isArray(data)) {
|
|
296
|
-
return data.map((item)=>this.deepSanitize(item, maxDepth, currentDepth + 1));
|
|
297
|
-
}
|
|
298
|
-
if (typeof data === 'object') {
|
|
299
|
-
const sanitized = {};
|
|
300
|
-
for (const [key, value] of Object.entries(data)){
|
|
301
|
-
if (this.isSensitiveField(key)) {
|
|
302
|
-
sanitized[key] = '***';
|
|
303
|
-
} else {
|
|
304
|
-
sanitized[key] = this.deepSanitize(value, maxDepth, currentDepth + 1);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
return sanitized;
|
|
308
|
-
}
|
|
309
|
-
return data;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
1
|
+
export { SecurityUtils, SENSITIVE_FIELDS } from "@vlian/utils";
|
|
312
2
|
|
|
313
3
|
//# sourceMappingURL=security.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/security.ts"],"sourcesContent":["import DOMPurify from 'dompurify';\nimport { SecurityError } from './errors';\n\n/**\n * XSS 防护配置\n */\nexport interface XSSConfig {\n /**\n * 是否允许 HTML 标签\n */\n allowHTML?: boolean;\n /**\n * 允许的 HTML 标签列表\n */\n allowedTags?: string[];\n /**\n * 允许的 HTML 属性列表\n */\n allowedAttributes?: string[];\n}\n\n/**\n * 敏感数据标识(扩展列表)\n */\nexport const SENSITIVE_FIELDS = [\n 'password',\n 'pwd',\n 'passwd',\n 'token',\n 'secret',\n 'key',\n 'apiKey',\n 'apikey',\n 'api_key',\n 'accessToken',\n 'access_token',\n 'refreshToken',\n 'refresh_token',\n 'authorization',\n 'auth',\n 'cookie',\n 'session',\n 'sessionId',\n 'session_id',\n 'creditCard',\n 'credit_card',\n 'cardNumber',\n 'card_number',\n 'cvv',\n 'cvc',\n 'ssn',\n 'socialSecurityNumber',\n 'social_security_number',\n 'phone',\n 'phoneNumber',\n 'phone_number',\n 'mobile',\n 'email',\n 'emailAddress',\n 'email_address',\n 'privateKey',\n 'private_key',\n 'secretKey',\n 'secret_key',\n 'apiSecret',\n 'api_secret',\n] as const;\n\n/**\n * 敏感信息检测模式(正则表达式)\n */\nconst SENSITIVE_PATTERNS = [\n /\\b\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}\\b/, // 信用卡号\n /\\b\\d{3}-\\d{2}-\\d{4}\\b/, // SSN\n /\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b/, // 邮箱(可选,根据需求决定是否脱敏)\n /\\b\\d{10,}\\b/, // 长数字(可能是敏感信息)\n] as const;\n\n/**\n * 安全工具类\n */\nexport class SecurityUtils {\n /**\n * 清理 HTML,防止 XSS 攻击\n */\n static sanitizeHTML(html: string, config?: XSSConfig): string {\n if (typeof window === 'undefined') {\n // Node.js 环境,返回原始字符串(需要服务端处理)\n return html;\n }\n\n try {\n if (config?.allowHTML) {\n // 默认禁止所有标签,除非明确允许\n const allowedTags = config.allowedTags && config.allowedTags.length > 0 \n ? config.allowedTags \n : [];\n const allowedAttributes = config.allowedAttributes && config.allowedAttributes.length > 0\n ? config.allowedAttributes\n : [];\n \n return DOMPurify.sanitize(html, {\n ALLOWED_TAGS: allowedTags,\n ALLOWED_ATTR: allowedAttributes,\n FORBID_TAGS: ['script', 'iframe', 'object', 'embed', 'form', 'link', 'meta', 'style'],\n FORBID_ATTR: ['onerror', 'onload', 'onclick', 'onmouseover', 'onfocus', 'onblur', 'onchange'],\n // 添加更多安全配置\n KEEP_CONTENT: false,\n RETURN_DOM: false,\n RETURN_DOM_FRAGMENT: false,\n RETURN_TRUSTED_TYPE: false,\n });\n }\n // 默认模式:完全清理,不允许任何 HTML\n return DOMPurify.sanitize(html, { \n ALLOWED_TAGS: [],\n KEEP_CONTENT: false,\n });\n } catch (error) {\n // 错误处理:不泄露敏感信息,记录错误但不抛出详细错误\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n // 只记录错误类型,不记录具体内容\n console.error('HTML 清理失败:', errorMessage.substring(0, 50));\n // 返回安全的空字符串或清理后的文本\n return this.sanitizeText(html);\n }\n }\n\n /**\n * 清理文本内容(移除所有 HTML 标签)\n */\n static sanitizeText(text: string): string {\n if (typeof window === 'undefined') {\n return text.replace(/<[^>]*>/g, '');\n }\n\n try {\n return DOMPurify.sanitize(text, { ALLOWED_TAGS: [] });\n } catch (error) {\n throw new SecurityError('文本清理失败', error instanceof Error ? error : undefined);\n }\n }\n\n /**\n * 检查字符串是否包含潜在的危险内容\n */\n static containsDangerousContent(text: string): boolean {\n const dangerousPatterns = [\n /<script[\\s\\S]*?>[\\s\\S]*?<\\/script>/gi,\n /javascript:/gi,\n /on\\w+\\s*=/gi,\n /<iframe[\\s\\S]*?>/gi,\n /<object[\\s\\S]*?>/gi,\n /<embed[\\s\\S]*?>/gi,\n /<link[\\s\\S]*?>/gi,\n /<meta[\\s\\S]*?>/gi,\n /data:text\\/html/gi,\n /vbscript:/gi,\n /expression\\s*\\(/gi,\n /@import/gi,\n /<style[\\s\\S]*?>[\\s\\S]*?<\\/style>/gi,\n ];\n\n return dangerousPatterns.some((pattern) => pattern.test(text));\n }\n\n /**\n * 验证 URL 是否安全\n */\n static isSafeUrl(url: string): boolean {\n try {\n const urlObj = new URL(url);\n // 检查协议\n if (!['http:', 'https:'].includes(urlObj.protocol)) {\n return false;\n }\n // 检查是否包含危险内容\n return !this.containsDangerousContent(url);\n } catch {\n return false;\n }\n }\n\n /**\n * 检查字段名是否为敏感字段\n */\n static isSensitiveField(fieldName: string): boolean {\n const lowerFieldName = fieldName.toLowerCase();\n return SENSITIVE_FIELDS.some((field) => lowerFieldName.includes(field.toLowerCase()));\n }\n\n /**\n * 检查值是否包含敏感信息(基于模式匹配)\n */\n static containsSensitiveData(value: string): boolean {\n return SENSITIVE_PATTERNS.some((pattern) => pattern.test(value));\n }\n\n /**\n * 生成 CSP(Content Security Policy)头\n */\n static generateCSP(config?: {\n defaultSrc?: string[];\n scriptSrc?: string[];\n styleSrc?: string[];\n imgSrc?: string[];\n connectSrc?: string[];\n fontSrc?: string[];\n frameSrc?: string[];\n allowUnsafeInline?: boolean; // 是否允许 unsafe-inline(不推荐)\n allowUnsafeEval?: boolean; // 是否允许 unsafe-eval(不推荐)\n }): string {\n const directives: string[] = [];\n const allowUnsafeInline = config?.allowUnsafeInline ?? false;\n const allowUnsafeEval = config?.allowUnsafeEval ?? false;\n\n if (config?.defaultSrc) {\n directives.push(`default-src ${config.defaultSrc.join(' ')}`);\n } else {\n directives.push(\"default-src 'self'\");\n }\n\n if (config?.scriptSrc) {\n directives.push(`script-src ${config.scriptSrc.join(' ')}`);\n } else {\n // 默认不允许 unsafe-inline 和 unsafe-eval,提高安全性\n const scriptSrc = [\"'self'\"];\n if (allowUnsafeInline) {\n scriptSrc.push(\"'unsafe-inline'\");\n }\n if (allowUnsafeEval) {\n scriptSrc.push(\"'unsafe-eval'\");\n }\n directives.push(`script-src ${scriptSrc.join(' ')}`);\n }\n\n if (config?.styleSrc) {\n directives.push(`style-src ${config.styleSrc.join(' ')}`);\n } else {\n // 对于样式,可以使用 nonce 或 hash 替代 unsafe-inline\n const styleSrc = [\"'self'\"];\n if (allowUnsafeInline) {\n styleSrc.push(\"'unsafe-inline'\");\n }\n directives.push(`style-src ${styleSrc.join(' ')}`);\n }\n\n if (config?.imgSrc) {\n directives.push(`img-src ${config.imgSrc.join(' ')}`);\n } else {\n directives.push(\"img-src 'self' data: https:\");\n }\n\n if (config?.connectSrc) {\n directives.push(`connect-src ${config.connectSrc.join(' ')}`);\n } else {\n directives.push(\"connect-src 'self'\");\n }\n\n if (config?.fontSrc) {\n directives.push(`font-src ${config.fontSrc.join(' ')}`);\n } else {\n directives.push(\"font-src 'self' data:\");\n }\n\n if (config?.frameSrc) {\n directives.push(`frame-src ${config.frameSrc.join(' ')}`);\n } else {\n directives.push(\"frame-src 'none'\");\n }\n\n return directives.join('; ');\n }\n\n /**\n * 转义 HTML 特殊字符\n */\n static escapeHTML(text: string): string {\n const map: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n };\n return text.replace(/[&<>\"']/g, (char) => map[char]);\n }\n\n /**\n * 验证输入是否安全\n */\n static validateInput(input: unknown): {\n safe: boolean;\n sanitized?: string;\n reason?: string;\n } {\n if (typeof input !== 'string') {\n return { safe: true };\n }\n\n if (this.containsDangerousContent(input)) {\n return {\n safe: false,\n sanitized: this.sanitizeText(input),\n reason: '包含潜在的危险内容',\n };\n }\n\n // 检查是否包含敏感数据模式\n if (this.containsSensitiveData(input)) {\n return {\n safe: false,\n sanitized: this.sanitizeText(input),\n reason: '可能包含敏感信息',\n };\n }\n\n return { safe: true, sanitized: input };\n }\n\n /**\n * 深度脱敏处理(递归处理嵌套对象)\n */\n static deepSanitize(data: unknown, maxDepth: number = 10, currentDepth: number = 0): unknown {\n if (currentDepth >= maxDepth) {\n return '***'; // 防止无限递归\n }\n\n if (data === null || data === undefined) {\n return data;\n }\n\n if (typeof data === 'string') {\n if (this.containsDangerousContent(data) || this.containsSensitiveData(data)) {\n return this.sanitizeText(data);\n }\n return data;\n }\n\n if (typeof data === 'number' || typeof data === 'boolean') {\n return data;\n }\n\n if (Array.isArray(data)) {\n return data.map((item) => this.deepSanitize(item, maxDepth, currentDepth + 1));\n }\n\n if (typeof data === 'object') {\n const sanitized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (this.isSensitiveField(key)) {\n sanitized[key] = '***';\n } else {\n sanitized[key] = this.deepSanitize(value, maxDepth, currentDepth + 1);\n }\n }\n return sanitized;\n }\n\n return data;\n }\n}\n"],"names":["DOMPurify","SecurityError","SENSITIVE_FIELDS","SENSITIVE_PATTERNS","SecurityUtils","sanitizeHTML","html","config","window","allowHTML","allowedTags","length","allowedAttributes","sanitize","ALLOWED_TAGS","ALLOWED_ATTR","FORBID_TAGS","FORBID_ATTR","KEEP_CONTENT","RETURN_DOM","RETURN_DOM_FRAGMENT","RETURN_TRUSTED_TYPE","error","errorMessage","Error","message","console","substring","sanitizeText","text","replace","undefined","containsDangerousContent","dangerousPatterns","some","pattern","test","isSafeUrl","url","urlObj","URL","includes","protocol","isSensitiveField","fieldName","lowerFieldName","toLowerCase","field","containsSensitiveData","value","generateCSP","directives","allowUnsafeInline","allowUnsafeEval","defaultSrc","push","join","scriptSrc","styleSrc","imgSrc","connectSrc","fontSrc","frameSrc","escapeHTML","map","char","validateInput","input","safe","sanitized","reason","deepSanitize","data","maxDepth","currentDepth","Array","isArray","item","key","Object","entries"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/security.ts"],"sourcesContent":["export { SecurityUtils, SENSITIVE_FIELDS } from '@vlian/utils';\nexport type { XSSConfig } from '@vlian/utils';\n"],"names":["SecurityUtils","SENSITIVE_FIELDS"],"mappings":"AAAA,SAASA,aAAa,EAAEC,gBAAgB,QAAQ,eAAe"}
|
package/dist/utils/traceId.cjs
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* 日志追踪 ID 生成器
|
|
3
|
-
* 用于生成唯一的请求追踪 ID,便于日志关联和问题排查
|
|
4
|
-
*/ /**
|
|
5
|
-
* 追踪 ID 生成器
|
|
6
|
-
*/ "use strict";
|
|
1
|
+
"use strict";
|
|
7
2
|
Object.defineProperty(exports, "__esModule", {
|
|
8
3
|
value: true
|
|
9
4
|
});
|
|
@@ -15,126 +10,30 @@ function _export(target, all) {
|
|
|
15
10
|
}
|
|
16
11
|
_export(exports, {
|
|
17
12
|
get TraceIdGenerator () {
|
|
18
|
-
return TraceIdGenerator;
|
|
13
|
+
return _logger.TraceIdGenerator;
|
|
19
14
|
},
|
|
20
15
|
get clearCurrentTraceId () {
|
|
21
|
-
return clearCurrentTraceId;
|
|
16
|
+
return _logger.clearCurrentTraceId;
|
|
22
17
|
},
|
|
23
18
|
get generateTraceId () {
|
|
24
|
-
return generateTraceId;
|
|
19
|
+
return _logger.generateTraceId;
|
|
25
20
|
},
|
|
26
21
|
get getCurrentTraceId () {
|
|
27
|
-
return getCurrentTraceId;
|
|
22
|
+
return _logger.getCurrentTraceId;
|
|
28
23
|
},
|
|
29
24
|
get getTraceIdGenerator () {
|
|
30
|
-
return getTraceIdGenerator;
|
|
25
|
+
return _logger.getTraceIdGenerator;
|
|
31
26
|
},
|
|
32
27
|
get initTraceIdGenerator () {
|
|
33
|
-
return initTraceIdGenerator;
|
|
28
|
+
return _logger.initTraceIdGenerator;
|
|
34
29
|
},
|
|
35
30
|
get parseTraceId () {
|
|
36
|
-
return parseTraceId;
|
|
31
|
+
return _logger.parseTraceId;
|
|
37
32
|
},
|
|
38
33
|
get setCurrentTraceId () {
|
|
39
|
-
return setCurrentTraceId;
|
|
34
|
+
return _logger.setCurrentTraceId;
|
|
40
35
|
}
|
|
41
36
|
});
|
|
42
|
-
|
|
43
|
-
if (key in obj) {
|
|
44
|
-
Object.defineProperty(obj, key, {
|
|
45
|
-
value: value,
|
|
46
|
-
enumerable: true,
|
|
47
|
-
configurable: true,
|
|
48
|
-
writable: true
|
|
49
|
-
});
|
|
50
|
-
} else {
|
|
51
|
-
obj[key] = value;
|
|
52
|
-
}
|
|
53
|
-
return obj;
|
|
54
|
-
}
|
|
55
|
-
let TraceIdGenerator = class TraceIdGenerator {
|
|
56
|
-
/**
|
|
57
|
-
* 获取单例实例
|
|
58
|
-
*/ static getInstance(prefix) {
|
|
59
|
-
if (!TraceIdGenerator.instance) {
|
|
60
|
-
TraceIdGenerator.instance = new TraceIdGenerator(prefix);
|
|
61
|
-
}
|
|
62
|
-
return TraceIdGenerator.instance;
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* 生成追踪 ID
|
|
66
|
-
*/ generate() {
|
|
67
|
-
const timestamp = Date.now();
|
|
68
|
-
const random = Math.random().toString(36).substring(2, 9);
|
|
69
|
-
const counter = (this.counter++).toString(36).padStart(4, '0');
|
|
70
|
-
const parts = [
|
|
71
|
-
timestamp.toString(36),
|
|
72
|
-
random,
|
|
73
|
-
counter
|
|
74
|
-
];
|
|
75
|
-
if (this.prefix) {
|
|
76
|
-
parts.unshift(this.prefix);
|
|
77
|
-
}
|
|
78
|
-
return parts.join('-');
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* 从字符串解析追踪 ID(用于验证)
|
|
82
|
-
*/ static parse(traceId) {
|
|
83
|
-
const parts = traceId.split('-');
|
|
84
|
-
if (parts.length < 3) {
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
|
-
try {
|
|
88
|
-
const timestamp = parseInt(parts[parts.length - 3], 36);
|
|
89
|
-
const random = parts[parts.length - 2];
|
|
90
|
-
const counter = parseInt(parts[parts.length - 1], 36);
|
|
91
|
-
return {
|
|
92
|
-
prefix: parts.length > 3 ? parts.slice(0, -3).join('-') : undefined,
|
|
93
|
-
timestamp,
|
|
94
|
-
random,
|
|
95
|
-
counter
|
|
96
|
-
};
|
|
97
|
-
} catch {
|
|
98
|
-
return null;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
constructor(prefix = ''){
|
|
102
|
-
_define_property(this, "counter", 0);
|
|
103
|
-
_define_property(this, "prefix", void 0);
|
|
104
|
-
this.prefix = prefix;
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
_define_property(TraceIdGenerator, "instance", null);
|
|
108
|
-
/**
|
|
109
|
-
* 全局追踪 ID 生成器实例
|
|
110
|
-
*/ let globalTraceIdGenerator = null;
|
|
111
|
-
function initTraceIdGenerator(prefix) {
|
|
112
|
-
globalTraceIdGenerator = TraceIdGenerator.getInstance(prefix);
|
|
113
|
-
return globalTraceIdGenerator;
|
|
114
|
-
}
|
|
115
|
-
function getTraceIdGenerator() {
|
|
116
|
-
if (!globalTraceIdGenerator) {
|
|
117
|
-
globalTraceIdGenerator = TraceIdGenerator.getInstance();
|
|
118
|
-
}
|
|
119
|
-
return globalTraceIdGenerator;
|
|
120
|
-
}
|
|
121
|
-
function generateTraceId() {
|
|
122
|
-
return getTraceIdGenerator().generate();
|
|
123
|
-
}
|
|
124
|
-
function parseTraceId(traceId) {
|
|
125
|
-
return TraceIdGenerator.parse(traceId);
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* 当前请求的追踪 ID(使用 AsyncLocalStorage 或全局变量)
|
|
129
|
-
*/ let currentTraceId = null;
|
|
130
|
-
function setCurrentTraceId(traceId) {
|
|
131
|
-
currentTraceId = traceId;
|
|
132
|
-
}
|
|
133
|
-
function getCurrentTraceId() {
|
|
134
|
-
return currentTraceId;
|
|
135
|
-
}
|
|
136
|
-
function clearCurrentTraceId() {
|
|
137
|
-
currentTraceId = null;
|
|
138
|
-
}
|
|
37
|
+
const _logger = require("@vlian/logger");
|
|
139
38
|
|
|
140
39
|
//# sourceMappingURL=traceId.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/traceId.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../../src/utils/traceId.ts"],"sourcesContent":["export {\n TraceIdGenerator,\n initTraceIdGenerator,\n getTraceIdGenerator,\n generateTraceId,\n parseTraceId,\n setCurrentTraceId,\n getCurrentTraceId,\n clearCurrentTraceId,\n} from '@vlian/logger';\n"],"names":["TraceIdGenerator","clearCurrentTraceId","generateTraceId","getCurrentTraceId","getTraceIdGenerator","initTraceIdGenerator","parseTraceId","setCurrentTraceId"],"mappings":";;;;;;;;;;;QACEA;eAAAA,wBAAgB;;QAOhBC;eAAAA,2BAAmB;;QAJnBC;eAAAA,uBAAe;;QAGfC;eAAAA,yBAAiB;;QAJjBC;eAAAA,2BAAmB;;QADnBC;eAAAA,4BAAoB;;QAGpBC;eAAAA,oBAAY;;QACZC;eAAAA,yBAAiB;;;wBAGZ"}
|
package/dist/utils/traceId.d.ts
CHANGED
|
@@ -1,63 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* 日志追踪 ID 生成器
|
|
3
|
-
* 用于生成唯一的请求追踪 ID,便于日志关联和问题排查
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* 追踪 ID 生成器
|
|
7
|
-
*/
|
|
8
|
-
export declare class TraceIdGenerator {
|
|
9
|
-
private static instance;
|
|
10
|
-
private counter;
|
|
11
|
-
private readonly prefix;
|
|
12
|
-
private constructor();
|
|
13
|
-
/**
|
|
14
|
-
* 获取单例实例
|
|
15
|
-
*/
|
|
16
|
-
static getInstance(prefix?: string): TraceIdGenerator;
|
|
17
|
-
/**
|
|
18
|
-
* 生成追踪 ID
|
|
19
|
-
*/
|
|
20
|
-
generate(): string;
|
|
21
|
-
/**
|
|
22
|
-
* 从字符串解析追踪 ID(用于验证)
|
|
23
|
-
*/
|
|
24
|
-
static parse(traceId: string): {
|
|
25
|
-
prefix?: string;
|
|
26
|
-
timestamp: number;
|
|
27
|
-
random: string;
|
|
28
|
-
counter: number;
|
|
29
|
-
} | null;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* 初始化追踪 ID 生成器
|
|
33
|
-
*/
|
|
34
|
-
export declare function initTraceIdGenerator(prefix?: string): TraceIdGenerator;
|
|
35
|
-
/**
|
|
36
|
-
* 获取全局追踪 ID 生成器
|
|
37
|
-
*/
|
|
38
|
-
export declare function getTraceIdGenerator(): TraceIdGenerator;
|
|
39
|
-
/**
|
|
40
|
-
* 生成追踪 ID
|
|
41
|
-
*/
|
|
42
|
-
export declare function generateTraceId(): string;
|
|
43
|
-
/**
|
|
44
|
-
* 解析追踪 ID
|
|
45
|
-
*/
|
|
46
|
-
export declare function parseTraceId(traceId: string): {
|
|
47
|
-
prefix?: string;
|
|
48
|
-
timestamp: number;
|
|
49
|
-
random: string;
|
|
50
|
-
counter: number;
|
|
51
|
-
} | null;
|
|
52
|
-
/**
|
|
53
|
-
* 设置当前请求的追踪 ID
|
|
54
|
-
*/
|
|
55
|
-
export declare function setCurrentTraceId(traceId: string | null): void;
|
|
56
|
-
/**
|
|
57
|
-
* 获取当前请求的追踪 ID
|
|
58
|
-
*/
|
|
59
|
-
export declare function getCurrentTraceId(): string | null;
|
|
60
|
-
/**
|
|
61
|
-
* 清除当前请求的追踪 ID
|
|
62
|
-
*/
|
|
63
|
-
export declare function clearCurrentTraceId(): void;
|
|
1
|
+
export { TraceIdGenerator, initTraceIdGenerator, getTraceIdGenerator, generateTraceId, parseTraceId, setCurrentTraceId, getCurrentTraceId, clearCurrentTraceId, } from '@vlian/logger';
|