@onebots/core 0.5.0 → 1.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.md +3 -3
- package/lib/__tests__/config-validator.test.d.ts +4 -0
- package/lib/__tests__/config-validator.test.js +152 -0
- package/lib/__tests__/di-container.test.d.ts +4 -0
- package/lib/__tests__/di-container.test.js +114 -0
- package/lib/__tests__/errors.test.d.ts +4 -0
- package/lib/__tests__/errors.test.js +111 -0
- package/lib/__tests__/integration.test.d.ts +5 -0
- package/lib/__tests__/integration.test.js +112 -0
- package/lib/__tests__/lifecycle.test.d.ts +4 -0
- package/lib/__tests__/lifecycle.test.js +163 -0
- package/lib/account.d.ts +4 -1
- package/lib/account.js +6 -3
- package/lib/adapter.d.ts +67 -1
- package/lib/adapter.js +31 -4
- package/lib/base-app.d.ts +30 -3
- package/lib/base-app.js +295 -142
- package/lib/circuit-breaker.d.ts +94 -0
- package/lib/circuit-breaker.js +206 -0
- package/lib/config-validator.d.ts +51 -0
- package/lib/config-validator.js +184 -0
- package/lib/connection-pool.d.ts +68 -0
- package/lib/connection-pool.js +202 -0
- package/lib/db.d.ts +2 -1
- package/lib/db.js +11 -2
- package/lib/di-container.d.ts +60 -0
- package/lib/di-container.js +103 -0
- package/lib/errors.d.ts +157 -0
- package/lib/errors.js +257 -0
- package/lib/index.d.ts +13 -4
- package/lib/index.js +17 -3
- package/lib/lifecycle.d.ts +75 -0
- package/lib/lifecycle.js +175 -0
- package/lib/logger.d.ts +76 -0
- package/lib/logger.js +156 -0
- package/lib/metrics.d.ts +80 -0
- package/lib/metrics.js +201 -0
- package/lib/middleware/index.d.ts +8 -0
- package/lib/middleware/index.js +8 -0
- package/lib/middleware/metrics-collector.d.ts +9 -0
- package/lib/middleware/metrics-collector.js +64 -0
- package/lib/middleware/rate-limit.d.ts +32 -0
- package/lib/middleware/rate-limit.js +149 -0
- package/lib/middleware/security-audit.d.ts +33 -0
- package/lib/middleware/security-audit.js +223 -0
- package/lib/middleware/token-manager.d.ts +73 -0
- package/lib/middleware/token-manager.js +186 -0
- package/lib/middleware/token-validator.d.ts +42 -0
- package/lib/middleware/token-validator.js +198 -0
- package/lib/protocol.d.ts +2 -3
- package/lib/protocol.js +4 -0
- package/lib/rate-limiter.d.ts +88 -0
- package/lib/rate-limiter.js +196 -0
- package/lib/registry.d.ts +27 -0
- package/lib/registry.js +40 -5
- package/lib/retry.d.ts +87 -0
- package/lib/retry.js +205 -0
- package/lib/router.d.ts +43 -6
- package/lib/router.js +139 -12
- package/lib/timestamp.d.ts +42 -0
- package/lib/timestamp.js +72 -0
- package/lib/types.d.ts +1 -0
- package/lib/types.js +2 -1
- package/lib/utils.d.ts +2 -1
- package/lib/utils.js +11 -19
- package/package.json +24 -9
package/lib/db.d.ts
CHANGED
|
@@ -34,6 +34,7 @@ export declare namespace SqliteDB {
|
|
|
34
34
|
};
|
|
35
35
|
function Column(type: ColumnType, options?: Omit<Column, "type">): Column;
|
|
36
36
|
function Column(column: Column): Column;
|
|
37
|
+
/** 将值格式化为 SQL 字面量(字符串加单引号并转义,数字等直接返回,null/undefined 返回 NULL) */
|
|
37
38
|
function formatValue(value: any): string;
|
|
38
39
|
type QueryCondition<T extends {} = {}> = T & {
|
|
39
40
|
$and?: QueryCondition<T>;
|
|
@@ -62,7 +63,7 @@ export declare class Selection {
|
|
|
62
63
|
groupBy(field: string): this;
|
|
63
64
|
orderBy(field: string, order?: "ASC" | "DESC"): this;
|
|
64
65
|
get sql(): string;
|
|
65
|
-
run():
|
|
66
|
+
run(): Record<string, import("node:sqlite").SQLOutputValue>[];
|
|
66
67
|
}
|
|
67
68
|
export declare class Insertion {
|
|
68
69
|
#private;
|
package/lib/db.js
CHANGED
|
@@ -88,8 +88,17 @@ export class SqliteDB {
|
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
SqliteDB.Column = Column;
|
|
91
|
+
/** 将值格式化为 SQL 字面量(字符串加单引号并转义,数字等直接返回,null/undefined 返回 NULL) */
|
|
91
92
|
function formatValue(value) {
|
|
92
|
-
|
|
93
|
+
if (value === undefined || value === null)
|
|
94
|
+
return 'NULL';
|
|
95
|
+
if (typeof value === 'number')
|
|
96
|
+
return String(value);
|
|
97
|
+
const s = typeof value === 'string' ? value : JSON.stringify(value);
|
|
98
|
+
if (typeof s !== 'string')
|
|
99
|
+
return 'NULL';
|
|
100
|
+
// 字符串必须用单引号包裹,否则 SQL 会将其解析为列名(如 "no such column: zhin")
|
|
101
|
+
return "'" + s.replace(/'/g, "''") + "'";
|
|
93
102
|
}
|
|
94
103
|
SqliteDB.formatValue = formatValue;
|
|
95
104
|
function generateWhereClause(conditions, logic = "AND") {
|
|
@@ -128,7 +137,7 @@ export class SqliteDB {
|
|
|
128
137
|
else if (key === "$between" && Array.isArray(value) && value.length === 2) {
|
|
129
138
|
subClauses.push(`BETWEEN ${value[0]} AND ${value[1]}`);
|
|
130
139
|
}
|
|
131
|
-
else if (
|
|
140
|
+
else if (value === undefined || value === null) {
|
|
132
141
|
subClauses.push(`${key} IS NULL`);
|
|
133
142
|
}
|
|
134
143
|
else {
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 依赖注入容器
|
|
3
|
+
* 提供依赖注入和生命周期管理
|
|
4
|
+
*/
|
|
5
|
+
import type { Class } from './utils.js';
|
|
6
|
+
export type Token<T = any> = string | symbol | Class<T>;
|
|
7
|
+
export type Factory<T = any> = (container: Container) => T;
|
|
8
|
+
export type Provider<T = any> = Class<T> | Factory<T>;
|
|
9
|
+
export interface ServiceOptions {
|
|
10
|
+
/** 是否单例 */
|
|
11
|
+
singleton?: boolean;
|
|
12
|
+
/** 依赖的token列表 */
|
|
13
|
+
deps?: Token[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* 依赖注入容器
|
|
17
|
+
*/
|
|
18
|
+
export declare class Container {
|
|
19
|
+
private services;
|
|
20
|
+
/**
|
|
21
|
+
* 注册服务
|
|
22
|
+
*/
|
|
23
|
+
register<T>(token: Token<T>, provider: Provider<T>, options?: ServiceOptions): void;
|
|
24
|
+
/**
|
|
25
|
+
* 注册单例服务
|
|
26
|
+
*/
|
|
27
|
+
registerSingleton<T>(token: Token<T>, provider: Provider<T>, deps?: Token[]): void;
|
|
28
|
+
/**
|
|
29
|
+
* 注册瞬态服务(每次获取都创建新实例)
|
|
30
|
+
*/
|
|
31
|
+
registerTransient<T>(token: Token<T>, provider: Provider<T>, deps?: Token[]): void;
|
|
32
|
+
/**
|
|
33
|
+
* 获取服务实例
|
|
34
|
+
*/
|
|
35
|
+
get<T>(token: Token<T>): T;
|
|
36
|
+
/**
|
|
37
|
+
* 检查服务是否已注册
|
|
38
|
+
*/
|
|
39
|
+
has(token: Token): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* 解析依赖
|
|
42
|
+
*/
|
|
43
|
+
private resolveDependencies;
|
|
44
|
+
/**
|
|
45
|
+
* 判断是否为类
|
|
46
|
+
*/
|
|
47
|
+
private isClass;
|
|
48
|
+
/**
|
|
49
|
+
* 清除所有服务
|
|
50
|
+
*/
|
|
51
|
+
clear(): void;
|
|
52
|
+
/**
|
|
53
|
+
* 移除服务
|
|
54
|
+
*/
|
|
55
|
+
remove(token: Token): boolean;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 全局容器实例
|
|
59
|
+
*/
|
|
60
|
+
export declare const container: Container;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 依赖注入容器
|
|
3
|
+
* 提供依赖注入和生命周期管理
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* 依赖注入容器
|
|
7
|
+
*/
|
|
8
|
+
export class Container {
|
|
9
|
+
services = new Map();
|
|
10
|
+
/**
|
|
11
|
+
* 注册服务
|
|
12
|
+
*/
|
|
13
|
+
register(token, provider, options = {}) {
|
|
14
|
+
this.services.set(token, {
|
|
15
|
+
provider,
|
|
16
|
+
options: {
|
|
17
|
+
singleton: true,
|
|
18
|
+
...options,
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 注册单例服务
|
|
24
|
+
*/
|
|
25
|
+
registerSingleton(token, provider, deps) {
|
|
26
|
+
this.register(token, provider, {
|
|
27
|
+
singleton: true,
|
|
28
|
+
deps,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 注册瞬态服务(每次获取都创建新实例)
|
|
33
|
+
*/
|
|
34
|
+
registerTransient(token, provider, deps) {
|
|
35
|
+
this.register(token, provider, {
|
|
36
|
+
singleton: false,
|
|
37
|
+
deps,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 获取服务实例
|
|
42
|
+
*/
|
|
43
|
+
get(token) {
|
|
44
|
+
const service = this.services.get(token);
|
|
45
|
+
if (!service) {
|
|
46
|
+
throw new Error(`Service not found: ${String(token)}`);
|
|
47
|
+
}
|
|
48
|
+
// 如果是单例且已有实例,直接返回
|
|
49
|
+
if (service.options.singleton && service.instance !== undefined) {
|
|
50
|
+
return service.instance;
|
|
51
|
+
}
|
|
52
|
+
// 创建实例
|
|
53
|
+
let instance;
|
|
54
|
+
if (this.isClass(service.provider)) {
|
|
55
|
+
// 类构造函数
|
|
56
|
+
const deps = this.resolveDependencies(service.options.deps || []);
|
|
57
|
+
instance = new service.provider(...deps);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
// 工厂函数
|
|
61
|
+
instance = service.provider(this);
|
|
62
|
+
}
|
|
63
|
+
// 如果是单例,保存实例
|
|
64
|
+
if (service.options.singleton) {
|
|
65
|
+
service.instance = instance;
|
|
66
|
+
}
|
|
67
|
+
return instance;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 检查服务是否已注册
|
|
71
|
+
*/
|
|
72
|
+
has(token) {
|
|
73
|
+
return this.services.has(token);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 解析依赖
|
|
77
|
+
*/
|
|
78
|
+
resolveDependencies(tokens) {
|
|
79
|
+
return tokens.map(token => this.get(token));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* 判断是否为类
|
|
83
|
+
*/
|
|
84
|
+
isClass(provider) {
|
|
85
|
+
return typeof provider === 'function' && provider.prototype && provider.prototype.constructor === provider;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* 清除所有服务
|
|
89
|
+
*/
|
|
90
|
+
clear() {
|
|
91
|
+
this.services.clear();
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 移除服务
|
|
95
|
+
*/
|
|
96
|
+
remove(token) {
|
|
97
|
+
return this.services.delete(token);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 全局容器实例
|
|
102
|
+
*/
|
|
103
|
+
export const container = new Container();
|
package/lib/errors.d.ts
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 错误处理和分类系统
|
|
3
|
+
* 提供统一的错误类型和处理机制
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* 错误分类枚举
|
|
7
|
+
*/
|
|
8
|
+
export declare enum ErrorCategory {
|
|
9
|
+
/** 网络相关错误 */
|
|
10
|
+
NETWORK = "NETWORK",
|
|
11
|
+
/** 配置相关错误 */
|
|
12
|
+
CONFIG = "CONFIG",
|
|
13
|
+
/** 运行时错误 */
|
|
14
|
+
RUNTIME = "RUNTIME",
|
|
15
|
+
/** 验证错误 */
|
|
16
|
+
VALIDATION = "VALIDATION",
|
|
17
|
+
/** 资源错误 */
|
|
18
|
+
RESOURCE = "RESOURCE",
|
|
19
|
+
/** 协议错误 */
|
|
20
|
+
PROTOCOL = "PROTOCOL",
|
|
21
|
+
/** 适配器错误 */
|
|
22
|
+
ADAPTER = "ADAPTER",
|
|
23
|
+
/** 未知错误 */
|
|
24
|
+
UNKNOWN = "UNKNOWN"
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 错误严重程度
|
|
28
|
+
*/
|
|
29
|
+
export declare enum ErrorSeverity {
|
|
30
|
+
/** 低 - 可以忽略或自动恢复 */
|
|
31
|
+
LOW = "LOW",
|
|
32
|
+
/** 中 - 需要记录但可以继续运行 */
|
|
33
|
+
MEDIUM = "MEDIUM",
|
|
34
|
+
/** 高 - 影响功能,需要处理 */
|
|
35
|
+
HIGH = "HIGH",
|
|
36
|
+
/** 严重 - 可能导致服务停止 */
|
|
37
|
+
CRITICAL = "CRITICAL"
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 基础错误类
|
|
41
|
+
*/
|
|
42
|
+
export declare class OneBotsError extends Error {
|
|
43
|
+
readonly category: ErrorCategory;
|
|
44
|
+
readonly severity: ErrorSeverity;
|
|
45
|
+
readonly code: string;
|
|
46
|
+
readonly context?: Record<string, any>;
|
|
47
|
+
readonly timestamp: Date;
|
|
48
|
+
readonly cause?: Error;
|
|
49
|
+
constructor(message: string, options?: {
|
|
50
|
+
category?: ErrorCategory;
|
|
51
|
+
severity?: ErrorSeverity;
|
|
52
|
+
code?: string;
|
|
53
|
+
context?: Record<string, any>;
|
|
54
|
+
cause?: Error;
|
|
55
|
+
});
|
|
56
|
+
/**
|
|
57
|
+
* 转换为可序列化的对象
|
|
58
|
+
*/
|
|
59
|
+
toJSON(): {
|
|
60
|
+
name: string;
|
|
61
|
+
message: string;
|
|
62
|
+
category: ErrorCategory;
|
|
63
|
+
severity: ErrorSeverity;
|
|
64
|
+
code: string;
|
|
65
|
+
context: Record<string, any>;
|
|
66
|
+
timestamp: string;
|
|
67
|
+
stack: string;
|
|
68
|
+
cause: {
|
|
69
|
+
message: string;
|
|
70
|
+
stack: string;
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* 转换为字符串
|
|
75
|
+
*/
|
|
76
|
+
toString(): string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* 网络错误
|
|
80
|
+
*/
|
|
81
|
+
export declare class NetworkError extends OneBotsError {
|
|
82
|
+
constructor(message: string, options?: {
|
|
83
|
+
context?: Record<string, any>;
|
|
84
|
+
cause?: Error;
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* 配置错误
|
|
89
|
+
*/
|
|
90
|
+
export declare class ConfigError extends OneBotsError {
|
|
91
|
+
constructor(message: string, options?: {
|
|
92
|
+
context?: Record<string, any>;
|
|
93
|
+
cause?: Error;
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* 验证错误
|
|
98
|
+
*/
|
|
99
|
+
export declare class ValidationError extends OneBotsError {
|
|
100
|
+
constructor(message: string, options?: {
|
|
101
|
+
context?: Record<string, any>;
|
|
102
|
+
cause?: Error;
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 资源错误
|
|
107
|
+
*/
|
|
108
|
+
export declare class ResourceError extends OneBotsError {
|
|
109
|
+
constructor(message: string, options?: {
|
|
110
|
+
context?: Record<string, any>;
|
|
111
|
+
cause?: Error;
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* 协议错误
|
|
116
|
+
*/
|
|
117
|
+
export declare class ProtocolError extends OneBotsError {
|
|
118
|
+
constructor(message: string, options?: {
|
|
119
|
+
context?: Record<string, any>;
|
|
120
|
+
cause?: Error;
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* 适配器错误
|
|
125
|
+
*/
|
|
126
|
+
export declare class AdapterError extends OneBotsError {
|
|
127
|
+
constructor(message: string, options?: {
|
|
128
|
+
context?: Record<string, any>;
|
|
129
|
+
cause?: Error;
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* 运行时错误
|
|
134
|
+
*/
|
|
135
|
+
export declare class RuntimeError extends OneBotsError {
|
|
136
|
+
constructor(message: string, options?: {
|
|
137
|
+
context?: Record<string, any>;
|
|
138
|
+
cause?: Error;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 错误处理工具函数
|
|
143
|
+
*/
|
|
144
|
+
export declare class ErrorHandler {
|
|
145
|
+
/**
|
|
146
|
+
* 包装错误,转换为 OneBotsError
|
|
147
|
+
*/
|
|
148
|
+
static wrap(error: unknown, context?: Record<string, any>): OneBotsError;
|
|
149
|
+
/**
|
|
150
|
+
* 判断错误是否可恢复
|
|
151
|
+
*/
|
|
152
|
+
static isRecoverable(error: OneBotsError): boolean;
|
|
153
|
+
/**
|
|
154
|
+
* 判断错误是否致命
|
|
155
|
+
*/
|
|
156
|
+
static isFatal(error: OneBotsError): boolean;
|
|
157
|
+
}
|
package/lib/errors.js
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 错误处理和分类系统
|
|
3
|
+
* 提供统一的错误类型和处理机制
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* 错误分类枚举
|
|
7
|
+
*/
|
|
8
|
+
export var ErrorCategory;
|
|
9
|
+
(function (ErrorCategory) {
|
|
10
|
+
/** 网络相关错误 */
|
|
11
|
+
ErrorCategory["NETWORK"] = "NETWORK";
|
|
12
|
+
/** 配置相关错误 */
|
|
13
|
+
ErrorCategory["CONFIG"] = "CONFIG";
|
|
14
|
+
/** 运行时错误 */
|
|
15
|
+
ErrorCategory["RUNTIME"] = "RUNTIME";
|
|
16
|
+
/** 验证错误 */
|
|
17
|
+
ErrorCategory["VALIDATION"] = "VALIDATION";
|
|
18
|
+
/** 资源错误 */
|
|
19
|
+
ErrorCategory["RESOURCE"] = "RESOURCE";
|
|
20
|
+
/** 协议错误 */
|
|
21
|
+
ErrorCategory["PROTOCOL"] = "PROTOCOL";
|
|
22
|
+
/** 适配器错误 */
|
|
23
|
+
ErrorCategory["ADAPTER"] = "ADAPTER";
|
|
24
|
+
/** 未知错误 */
|
|
25
|
+
ErrorCategory["UNKNOWN"] = "UNKNOWN";
|
|
26
|
+
})(ErrorCategory || (ErrorCategory = {}));
|
|
27
|
+
/**
|
|
28
|
+
* 错误严重程度
|
|
29
|
+
*/
|
|
30
|
+
export var ErrorSeverity;
|
|
31
|
+
(function (ErrorSeverity) {
|
|
32
|
+
/** 低 - 可以忽略或自动恢复 */
|
|
33
|
+
ErrorSeverity["LOW"] = "LOW";
|
|
34
|
+
/** 中 - 需要记录但可以继续运行 */
|
|
35
|
+
ErrorSeverity["MEDIUM"] = "MEDIUM";
|
|
36
|
+
/** 高 - 影响功能,需要处理 */
|
|
37
|
+
ErrorSeverity["HIGH"] = "HIGH";
|
|
38
|
+
/** 严重 - 可能导致服务停止 */
|
|
39
|
+
ErrorSeverity["CRITICAL"] = "CRITICAL";
|
|
40
|
+
})(ErrorSeverity || (ErrorSeverity = {}));
|
|
41
|
+
/**
|
|
42
|
+
* 基础错误类
|
|
43
|
+
*/
|
|
44
|
+
export class OneBotsError extends Error {
|
|
45
|
+
category;
|
|
46
|
+
severity;
|
|
47
|
+
code;
|
|
48
|
+
context;
|
|
49
|
+
timestamp;
|
|
50
|
+
cause;
|
|
51
|
+
constructor(message, options = {}) {
|
|
52
|
+
super(message);
|
|
53
|
+
this.name = 'OneBotsError';
|
|
54
|
+
this.category = options.category || ErrorCategory.UNKNOWN;
|
|
55
|
+
this.severity = options.severity || ErrorSeverity.MEDIUM;
|
|
56
|
+
this.code = options.code || 'UNKNOWN_ERROR';
|
|
57
|
+
this.context = options.context;
|
|
58
|
+
this.cause = options.cause;
|
|
59
|
+
this.timestamp = new Date();
|
|
60
|
+
// 保持错误堆栈
|
|
61
|
+
if (Error.captureStackTrace) {
|
|
62
|
+
Error.captureStackTrace(this, OneBotsError);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 转换为可序列化的对象
|
|
67
|
+
*/
|
|
68
|
+
toJSON() {
|
|
69
|
+
return {
|
|
70
|
+
name: this.name,
|
|
71
|
+
message: this.message,
|
|
72
|
+
category: this.category,
|
|
73
|
+
severity: this.severity,
|
|
74
|
+
code: this.code,
|
|
75
|
+
context: this.context,
|
|
76
|
+
timestamp: this.timestamp.toISOString(),
|
|
77
|
+
stack: this.stack,
|
|
78
|
+
cause: this.cause ? {
|
|
79
|
+
message: this.cause.message,
|
|
80
|
+
stack: this.cause.stack,
|
|
81
|
+
} : undefined,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* 转换为字符串
|
|
86
|
+
*/
|
|
87
|
+
toString() {
|
|
88
|
+
return `[${this.category}:${this.code}] ${this.message}`;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* 网络错误
|
|
93
|
+
*/
|
|
94
|
+
export class NetworkError extends OneBotsError {
|
|
95
|
+
constructor(message, options) {
|
|
96
|
+
super(message, {
|
|
97
|
+
category: ErrorCategory.NETWORK,
|
|
98
|
+
severity: ErrorSeverity.MEDIUM,
|
|
99
|
+
code: 'NETWORK_ERROR',
|
|
100
|
+
...options,
|
|
101
|
+
});
|
|
102
|
+
this.name = 'NetworkError';
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 配置错误
|
|
107
|
+
*/
|
|
108
|
+
export class ConfigError extends OneBotsError {
|
|
109
|
+
constructor(message, options) {
|
|
110
|
+
super(message, {
|
|
111
|
+
category: ErrorCategory.CONFIG,
|
|
112
|
+
severity: ErrorSeverity.HIGH,
|
|
113
|
+
code: 'CONFIG_ERROR',
|
|
114
|
+
...options,
|
|
115
|
+
});
|
|
116
|
+
this.name = 'ConfigError';
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* 验证错误
|
|
121
|
+
*/
|
|
122
|
+
export class ValidationError extends OneBotsError {
|
|
123
|
+
constructor(message, options) {
|
|
124
|
+
super(message, {
|
|
125
|
+
category: ErrorCategory.VALIDATION,
|
|
126
|
+
severity: ErrorSeverity.MEDIUM,
|
|
127
|
+
code: 'VALIDATION_ERROR',
|
|
128
|
+
...options,
|
|
129
|
+
});
|
|
130
|
+
this.name = 'ValidationError';
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* 资源错误
|
|
135
|
+
*/
|
|
136
|
+
export class ResourceError extends OneBotsError {
|
|
137
|
+
constructor(message, options) {
|
|
138
|
+
super(message, {
|
|
139
|
+
category: ErrorCategory.RESOURCE,
|
|
140
|
+
severity: ErrorSeverity.HIGH,
|
|
141
|
+
code: 'RESOURCE_ERROR',
|
|
142
|
+
...options,
|
|
143
|
+
});
|
|
144
|
+
this.name = 'ResourceError';
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* 协议错误
|
|
149
|
+
*/
|
|
150
|
+
export class ProtocolError extends OneBotsError {
|
|
151
|
+
constructor(message, options) {
|
|
152
|
+
super(message, {
|
|
153
|
+
category: ErrorCategory.PROTOCOL,
|
|
154
|
+
severity: ErrorSeverity.MEDIUM,
|
|
155
|
+
code: 'PROTOCOL_ERROR',
|
|
156
|
+
...options,
|
|
157
|
+
});
|
|
158
|
+
this.name = 'ProtocolError';
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* 适配器错误
|
|
163
|
+
*/
|
|
164
|
+
export class AdapterError extends OneBotsError {
|
|
165
|
+
constructor(message, options) {
|
|
166
|
+
super(message, {
|
|
167
|
+
category: ErrorCategory.ADAPTER,
|
|
168
|
+
severity: ErrorSeverity.HIGH,
|
|
169
|
+
code: 'ADAPTER_ERROR',
|
|
170
|
+
...options,
|
|
171
|
+
});
|
|
172
|
+
this.name = 'AdapterError';
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* 运行时错误
|
|
177
|
+
*/
|
|
178
|
+
export class RuntimeError extends OneBotsError {
|
|
179
|
+
constructor(message, options) {
|
|
180
|
+
super(message, {
|
|
181
|
+
category: ErrorCategory.RUNTIME,
|
|
182
|
+
severity: ErrorSeverity.HIGH,
|
|
183
|
+
code: 'RUNTIME_ERROR',
|
|
184
|
+
...options,
|
|
185
|
+
});
|
|
186
|
+
this.name = 'RuntimeError';
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* 错误处理工具函数
|
|
191
|
+
*/
|
|
192
|
+
export class ErrorHandler {
|
|
193
|
+
/**
|
|
194
|
+
* 包装错误,转换为 OneBotsError
|
|
195
|
+
*/
|
|
196
|
+
static wrap(error, context) {
|
|
197
|
+
if (error instanceof OneBotsError) {
|
|
198
|
+
if (context) {
|
|
199
|
+
return new OneBotsError(error.message, {
|
|
200
|
+
category: error.category,
|
|
201
|
+
severity: error.severity,
|
|
202
|
+
code: error.code,
|
|
203
|
+
context: { ...error.context, ...context },
|
|
204
|
+
cause: error.cause || error,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
return error;
|
|
208
|
+
}
|
|
209
|
+
if (error instanceof Error) {
|
|
210
|
+
// 尝试从错误消息推断错误类型
|
|
211
|
+
const message = error.message.toLowerCase();
|
|
212
|
+
let category = ErrorCategory.UNKNOWN;
|
|
213
|
+
let code = 'UNKNOWN_ERROR';
|
|
214
|
+
if (message.includes('network') || message.includes('connection') || message.includes('timeout')) {
|
|
215
|
+
category = ErrorCategory.NETWORK;
|
|
216
|
+
code = 'NETWORK_ERROR';
|
|
217
|
+
}
|
|
218
|
+
else if (message.includes('config') || message.includes('configuration')) {
|
|
219
|
+
category = ErrorCategory.CONFIG;
|
|
220
|
+
code = 'CONFIG_ERROR';
|
|
221
|
+
}
|
|
222
|
+
else if (message.includes('validation') || message.includes('invalid')) {
|
|
223
|
+
category = ErrorCategory.VALIDATION;
|
|
224
|
+
code = 'VALIDATION_ERROR';
|
|
225
|
+
}
|
|
226
|
+
else if (message.includes('not found') || message.includes('missing')) {
|
|
227
|
+
category = ErrorCategory.RESOURCE;
|
|
228
|
+
code = 'RESOURCE_NOT_FOUND';
|
|
229
|
+
}
|
|
230
|
+
return new OneBotsError(error.message, {
|
|
231
|
+
category,
|
|
232
|
+
severity: ErrorSeverity.MEDIUM,
|
|
233
|
+
code,
|
|
234
|
+
context,
|
|
235
|
+
cause: error,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
return new OneBotsError(String(error), {
|
|
239
|
+
category: ErrorCategory.UNKNOWN,
|
|
240
|
+
severity: ErrorSeverity.MEDIUM,
|
|
241
|
+
code: 'UNKNOWN_ERROR',
|
|
242
|
+
context,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* 判断错误是否可恢复
|
|
247
|
+
*/
|
|
248
|
+
static isRecoverable(error) {
|
|
249
|
+
return error.severity === ErrorSeverity.LOW || error.severity === ErrorSeverity.MEDIUM;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* 判断错误是否致命
|
|
253
|
+
*/
|
|
254
|
+
static isFatal(error) {
|
|
255
|
+
return error.severity === ErrorSeverity.CRITICAL;
|
|
256
|
+
}
|
|
257
|
+
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
|
-
export type {} from 'koa-bodyparser';
|
|
2
1
|
export * from "./account.js";
|
|
3
2
|
export * from "./adapter.js";
|
|
4
3
|
export * from "./base-app.js";
|
|
5
|
-
export * from './router.js';
|
|
6
|
-
export * from "./types.js";
|
|
7
4
|
export * from "./router.js";
|
|
5
|
+
export * from "./types.js";
|
|
8
6
|
export * from "./utils.js";
|
|
7
|
+
export * from "./timestamp.js";
|
|
9
8
|
export * from "./message-utils.js";
|
|
10
9
|
export * from "./protocol.js";
|
|
11
10
|
export * from "./registry.js";
|
|
12
|
-
export * from "./registry.js";
|
|
13
11
|
export * from "./db.js";
|
|
12
|
+
export * from "./errors.js";
|
|
13
|
+
export * from "./logger.js";
|
|
14
|
+
export * from "./config-validator.js";
|
|
15
|
+
export * from "./di-container.js";
|
|
16
|
+
export * from "./lifecycle.js";
|
|
17
|
+
export * from "./retry.js";
|
|
18
|
+
export * from "./rate-limiter.js";
|
|
19
|
+
export * from "./circuit-breaker.js";
|
|
20
|
+
export * from "./metrics.js";
|
|
21
|
+
export * from "./connection-pool.js";
|
|
22
|
+
export * from "./middleware/index.js";
|
package/lib/index.js
CHANGED
|
@@ -1,12 +1,26 @@
|
|
|
1
|
+
// Core modules
|
|
1
2
|
export * from "./account.js";
|
|
2
3
|
export * from "./adapter.js";
|
|
3
4
|
export * from "./base-app.js";
|
|
4
|
-
export * from './router.js';
|
|
5
|
-
export * from "./types.js";
|
|
6
5
|
export * from "./router.js";
|
|
6
|
+
export * from "./types.js";
|
|
7
7
|
export * from "./utils.js";
|
|
8
|
+
export * from "./timestamp.js";
|
|
8
9
|
export * from "./message-utils.js";
|
|
9
10
|
export * from "./protocol.js";
|
|
10
11
|
export * from "./registry.js";
|
|
11
|
-
export * from "./registry.js";
|
|
12
12
|
export * from "./db.js";
|
|
13
|
+
// Enhanced modules
|
|
14
|
+
export * from "./errors.js";
|
|
15
|
+
export * from "./logger.js";
|
|
16
|
+
export * from "./config-validator.js";
|
|
17
|
+
export * from "./di-container.js";
|
|
18
|
+
export * from "./lifecycle.js";
|
|
19
|
+
// Utilities
|
|
20
|
+
export * from "./retry.js";
|
|
21
|
+
export * from "./rate-limiter.js";
|
|
22
|
+
export * from "./circuit-breaker.js";
|
|
23
|
+
export * from "./metrics.js";
|
|
24
|
+
export * from "./connection-pool.js";
|
|
25
|
+
// Middleware
|
|
26
|
+
export * from "./middleware/index.js";
|