@h-ai/core 0.1.0-alpha5
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/LICENSE +202 -0
- package/README.md +422 -0
- package/dist/browser.d.ts +43 -0
- package/dist/browser.js +115 -0
- package/dist/browser.js.map +1 -0
- package/dist/chunk-2GTCDC56.js +14761 -0
- package/dist/chunk-2GTCDC56.js.map +1 -0
- package/dist/core-util-module-B-wH5_ZT.d.ts +1626 -0
- package/dist/node.d.ts +82 -0
- package/dist/node.js +643 -0
- package/dist/node.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,1626 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @h-ai/core — 核心配置 Schema
|
|
5
|
+
*
|
|
6
|
+
* 核心模块的配置 Schema 定义(使用 Zod 校验)
|
|
7
|
+
* @module core-config
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 环境类型 Schema。
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* EnvSchema.parse('development')
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
declare const EnvSchema: z.ZodEnum<{
|
|
19
|
+
development: "development";
|
|
20
|
+
production: "production";
|
|
21
|
+
test: "test";
|
|
22
|
+
staging: "staging";
|
|
23
|
+
}>;
|
|
24
|
+
type Env = z.infer<typeof EnvSchema>;
|
|
25
|
+
/**
|
|
26
|
+
* 日志级别 Schema。
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* LogLevelSchema.parse('info')
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
declare const LogLevelSchema: z.ZodEnum<{
|
|
34
|
+
trace: "trace";
|
|
35
|
+
debug: "debug";
|
|
36
|
+
info: "info";
|
|
37
|
+
warn: "warn";
|
|
38
|
+
error: "error";
|
|
39
|
+
fatal: "fatal";
|
|
40
|
+
}>;
|
|
41
|
+
type LogLevel = z.infer<typeof LogLevelSchema>;
|
|
42
|
+
/**
|
|
43
|
+
* 日志格式 Schema。
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* LogFormatSchema.parse('json')
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
declare const LogFormatSchema: z.ZodEnum<{
|
|
51
|
+
json: "json";
|
|
52
|
+
pretty: "pretty";
|
|
53
|
+
}>;
|
|
54
|
+
type LogFormat = z.infer<typeof LogFormatSchema>;
|
|
55
|
+
/**
|
|
56
|
+
* 日志配置 Schema。
|
|
57
|
+
*
|
|
58
|
+
* @example 最小配置(全部使用默认值)
|
|
59
|
+
* ```ts
|
|
60
|
+
* LoggingConfigSchema.parse({})
|
|
61
|
+
* // => { level: 'info', format: 'json', redact: [] }
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @example 开发环境(pretty 格式 + debug 级别)
|
|
65
|
+
* ```ts
|
|
66
|
+
* LoggingConfigSchema.parse({ level: 'debug', format: 'pretty' })
|
|
67
|
+
* // => { level: 'debug', format: 'pretty', redact: [] }
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* @example 带上下文与脱敏
|
|
71
|
+
* ```ts
|
|
72
|
+
* LoggingConfigSchema.parse({
|
|
73
|
+
* level: 'warn',
|
|
74
|
+
* format: 'json',
|
|
75
|
+
* context: { service: 'api-gateway', region: 'us-east-1' },
|
|
76
|
+
* redact: ['password', 'token', 'headers.authorization'],
|
|
77
|
+
* })
|
|
78
|
+
* // => { level: 'warn', format: 'json', context: { service: 'api-gateway', region: 'us-east-1' }, redact: ['password', 'token', 'headers.authorization'] }
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @example 在 _core.yml 中配置
|
|
82
|
+
* ```yaml
|
|
83
|
+
* logging:
|
|
84
|
+
* level: info
|
|
85
|
+
* format: json
|
|
86
|
+
* context:
|
|
87
|
+
* service: my-app
|
|
88
|
+
* redact:
|
|
89
|
+
* - password
|
|
90
|
+
* - token
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
declare const LoggingConfigSchema: z.ZodObject<{
|
|
94
|
+
level: z.ZodDefault<z.ZodEnum<{
|
|
95
|
+
trace: "trace";
|
|
96
|
+
debug: "debug";
|
|
97
|
+
info: "info";
|
|
98
|
+
warn: "warn";
|
|
99
|
+
error: "error";
|
|
100
|
+
fatal: "fatal";
|
|
101
|
+
}>>;
|
|
102
|
+
format: z.ZodDefault<z.ZodEnum<{
|
|
103
|
+
json: "json";
|
|
104
|
+
pretty: "pretty";
|
|
105
|
+
}>>;
|
|
106
|
+
context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
107
|
+
redact: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
108
|
+
}, z.core.$strip>;
|
|
109
|
+
type LoggingConfig = z.infer<typeof LoggingConfigSchema>;
|
|
110
|
+
/**
|
|
111
|
+
* ID 生成器配置 Schema。
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```ts
|
|
115
|
+
* IdConfigSchema.parse({ length: 12 })
|
|
116
|
+
* // => { length: 12 }
|
|
117
|
+
*
|
|
118
|
+
* IdConfigSchema.parse({ prefix: 'usr_', length: 16 })
|
|
119
|
+
* // => { prefix: 'usr_', length: 16 }
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
declare const IdConfigSchema: z.ZodObject<{
|
|
123
|
+
prefix: z.ZodOptional<z.ZodString>;
|
|
124
|
+
length: z.ZodDefault<z.ZodNumber>;
|
|
125
|
+
}, z.core.$strip>;
|
|
126
|
+
type IdConfig = z.infer<typeof IdConfigSchema>;
|
|
127
|
+
/**
|
|
128
|
+
* Core 配置 Schema。
|
|
129
|
+
*
|
|
130
|
+
* 描述应用的基础配置,通常通过 `_core.yml` 加载。
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```ts
|
|
134
|
+
* CoreConfigSchema.parse({ name: 'demo', env: 'production' })
|
|
135
|
+
* // => { name: 'demo', version: '0.1.0', env: 'production', debug: false, defaultLocale: 'zh-CN' }
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
declare const CoreConfigSchema: z.ZodObject<{
|
|
139
|
+
name: z.ZodDefault<z.ZodString>;
|
|
140
|
+
version: z.ZodDefault<z.ZodString>;
|
|
141
|
+
env: z.ZodDefault<z.ZodEnum<{
|
|
142
|
+
development: "development";
|
|
143
|
+
production: "production";
|
|
144
|
+
test: "test";
|
|
145
|
+
staging: "staging";
|
|
146
|
+
}>>;
|
|
147
|
+
debug: z.ZodDefault<z.ZodBoolean>;
|
|
148
|
+
logging: z.ZodOptional<z.ZodObject<{
|
|
149
|
+
level: z.ZodDefault<z.ZodEnum<{
|
|
150
|
+
trace: "trace";
|
|
151
|
+
debug: "debug";
|
|
152
|
+
info: "info";
|
|
153
|
+
warn: "warn";
|
|
154
|
+
error: "error";
|
|
155
|
+
fatal: "fatal";
|
|
156
|
+
}>>;
|
|
157
|
+
format: z.ZodDefault<z.ZodEnum<{
|
|
158
|
+
json: "json";
|
|
159
|
+
pretty: "pretty";
|
|
160
|
+
}>>;
|
|
161
|
+
context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
162
|
+
redact: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
163
|
+
}, z.core.$strip>>;
|
|
164
|
+
id: z.ZodOptional<z.ZodObject<{
|
|
165
|
+
prefix: z.ZodOptional<z.ZodString>;
|
|
166
|
+
length: z.ZodDefault<z.ZodNumber>;
|
|
167
|
+
}, z.core.$strip>>;
|
|
168
|
+
defaultLocale: z.ZodDefault<z.ZodString>;
|
|
169
|
+
}, z.core.$strip>;
|
|
170
|
+
type CoreConfig = z.infer<typeof CoreConfigSchema>;
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* @h-ai/core — 错误注册与处理
|
|
174
|
+
*
|
|
175
|
+
* 提供统一的错误定义生成与实例化能力。
|
|
176
|
+
*
|
|
177
|
+
* @module core-function-error
|
|
178
|
+
*/
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* 根据模块错误映射生成标准错误定义对象。
|
|
182
|
+
*
|
|
183
|
+
* 将错误信息映射(如 `{ CONFIG_NOT_FOUND: '010:500' }`)转换为结构化的 HaiErrorDef,
|
|
184
|
+
* 自动组装完整的错误码(格式:`system:module:code`)以及对应的 HTTP 状态码。
|
|
185
|
+
*
|
|
186
|
+
* @template T - 错误信息映射的类型
|
|
187
|
+
*
|
|
188
|
+
* @param module - 模块名称(如 'core'、'db'、'api'),会作为错误码的第二段
|
|
189
|
+
* @param errorInfo - 错误信息映射对象,值格式为 `'错误码数字:HTTP状态码'`(如 `'010:500'`)
|
|
190
|
+
* @param system - 系统标识,默认 'hai',会作为错误码的第一段
|
|
191
|
+
*
|
|
192
|
+
* @returns 返回同类型的错误定义对象,每个 key 对应一个 HaiErrorDef 对象
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```ts
|
|
196
|
+
* const ConfigErrorInfo = {
|
|
197
|
+
* FILE_NOT_FOUND: '010:500',
|
|
198
|
+
* PARSE_ERROR: '011:500',
|
|
199
|
+
* VALIDATION_ERROR: '012:500',
|
|
200
|
+
* } as const
|
|
201
|
+
*
|
|
202
|
+
* const ConfigError = buildHaiErrorsDef('core', ConfigErrorInfo)
|
|
203
|
+
* // =>
|
|
204
|
+
* // ConfigError.FILE_NOT_FOUND = {
|
|
205
|
+
* // code: 'hai:core:010',
|
|
206
|
+
* // httpStatus: 500,
|
|
207
|
+
* // system: 'hai',
|
|
208
|
+
* // module: 'core',
|
|
209
|
+
* // }
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
declare function buildHaiErrorsDef<T extends Record<string, string>>(module: string, errorInfo: T, system?: string): {
|
|
213
|
+
[K in keyof T]: HaiErrorDef;
|
|
214
|
+
};
|
|
215
|
+
/**
|
|
216
|
+
* 根据错误定义创建错误实例。
|
|
217
|
+
*
|
|
218
|
+
* 将 HaiErrorDef(错误定义)扩展为 HaiError(运行时错误实例),
|
|
219
|
+
* 添加具体的错误消息、原因和建议等运行时信息。
|
|
220
|
+
*
|
|
221
|
+
* @param def - 错误定义对象(通常由 buildHaiErrorsDef 生成)
|
|
222
|
+
* @param message - 错误消息(描述此次具体发生了什么)
|
|
223
|
+
* @param cause - 原始错误原因(可选,用于链式错误追踪)
|
|
224
|
+
* @param suggestion - 用户可采取的建议(可选,如 "'请检查配置文件格式')
|
|
225
|
+
*
|
|
226
|
+
* @returns 返回完整的 HaiError 实例,包含错误码、HTTP 状态、消息、原因和建议
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* ```ts
|
|
230
|
+
* const err = buildHaiErrorInst(
|
|
231
|
+
* HaiConfigError.FILE_NOT_FOUND,
|
|
232
|
+
* 'config.yml 文件不存在',
|
|
233
|
+
* new Error('ENOENT: no such file'),
|
|
234
|
+
* '请确保 _core.yml 在项目根目录'
|
|
235
|
+
* )
|
|
236
|
+
* // => {
|
|
237
|
+
* // code: 'hai:core:010',
|
|
238
|
+
* // httpStatus: 500,
|
|
239
|
+
* // system: 'hai',
|
|
240
|
+
* // module: 'core',
|
|
241
|
+
* // message: 'config.yml 文件不存在',
|
|
242
|
+
* // cause: Error('ENOENT: no such file'),
|
|
243
|
+
* // suggestion: '请确保 _core.yml 在项目根目录'
|
|
244
|
+
* // }
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
declare function buildHaiErrorInst(def: HaiErrorDef, message: string, cause?: unknown, suggestion?: string): HaiError;
|
|
248
|
+
declare const error: {
|
|
249
|
+
buildHaiErrorsDef: typeof buildHaiErrorsDef;
|
|
250
|
+
buildHaiErrorInst: typeof buildHaiErrorInst;
|
|
251
|
+
};
|
|
252
|
+
/** error 子工具类型 */
|
|
253
|
+
type ErrorFn = typeof error;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* @h-ai/core — ID 生成器
|
|
257
|
+
*
|
|
258
|
+
* 基于 nanoid 的 ID 生成工具。
|
|
259
|
+
* @module core-function-id
|
|
260
|
+
*/
|
|
261
|
+
/**
|
|
262
|
+
* ID 生成工具对象。
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* ```ts
|
|
266
|
+
* const id1 = id.generate()
|
|
267
|
+
* const id2 = id.short()
|
|
268
|
+
* ```
|
|
269
|
+
*/
|
|
270
|
+
declare const id: {
|
|
271
|
+
/**
|
|
272
|
+
* 生成标准 nanoid(默认 21 字符)。
|
|
273
|
+
*
|
|
274
|
+
* @param length - ID 长度
|
|
275
|
+
* @returns nanoid 字符串
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* ```ts
|
|
279
|
+
* const id = core.id.generate(16)
|
|
280
|
+
* ```
|
|
281
|
+
*/
|
|
282
|
+
generate(length?: number): string;
|
|
283
|
+
/**
|
|
284
|
+
* 生成短 ID(10 字符)。
|
|
285
|
+
*
|
|
286
|
+
* @example
|
|
287
|
+
* ```ts
|
|
288
|
+
* const shortId = core.id.short()
|
|
289
|
+
* ```
|
|
290
|
+
*/
|
|
291
|
+
short(): string;
|
|
292
|
+
/**
|
|
293
|
+
* 生成带前缀的 ID。
|
|
294
|
+
*
|
|
295
|
+
* @param prefix - 前缀
|
|
296
|
+
* @param length - ID 长度
|
|
297
|
+
*
|
|
298
|
+
* @example
|
|
299
|
+
* ```ts
|
|
300
|
+
* const userId = core.id.withPrefix('user_')
|
|
301
|
+
* ```
|
|
302
|
+
*/
|
|
303
|
+
withPrefix(prefix: string, length?: number): string;
|
|
304
|
+
/**
|
|
305
|
+
* 生成 Trace ID。
|
|
306
|
+
*
|
|
307
|
+
* @example
|
|
308
|
+
* ```ts
|
|
309
|
+
* const traceId = core.id.trace()
|
|
310
|
+
* ```
|
|
311
|
+
*/
|
|
312
|
+
trace(): string;
|
|
313
|
+
/**
|
|
314
|
+
* 生成 Request ID。
|
|
315
|
+
*
|
|
316
|
+
* @example
|
|
317
|
+
* ```ts
|
|
318
|
+
* const requestId = core.id.request()
|
|
319
|
+
* ```
|
|
320
|
+
*/
|
|
321
|
+
request(): string;
|
|
322
|
+
/**
|
|
323
|
+
* 生成 UUID v4。
|
|
324
|
+
*
|
|
325
|
+
* @example
|
|
326
|
+
* ```ts
|
|
327
|
+
* const uuid = core.id.uuid()
|
|
328
|
+
* ```
|
|
329
|
+
*/
|
|
330
|
+
uuid(): string;
|
|
331
|
+
/**
|
|
332
|
+
* 验证是否为有效的 UUID v4。
|
|
333
|
+
*
|
|
334
|
+
* @example
|
|
335
|
+
* ```ts
|
|
336
|
+
* core.id.isValidUUID('f47ac10b-58cc-4372-a567-0e02b2c3d479')
|
|
337
|
+
* ```
|
|
338
|
+
*/
|
|
339
|
+
isValidUUID(uuid: string): boolean;
|
|
340
|
+
/**
|
|
341
|
+
* 验证是否为有效的 nanoid。
|
|
342
|
+
*
|
|
343
|
+
* @param str - 待验证字符串
|
|
344
|
+
* @param length - 期望长度
|
|
345
|
+
*
|
|
346
|
+
* @example
|
|
347
|
+
* ```ts
|
|
348
|
+
* core.id.isValidNanoId('abc', 3)
|
|
349
|
+
* ```
|
|
350
|
+
*/
|
|
351
|
+
isValidNanoId(str: string, length?: number): boolean;
|
|
352
|
+
};
|
|
353
|
+
/** id 子工具类型 */
|
|
354
|
+
type IdFn = typeof id;
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* @h-ai/core — i18n 国际化工具
|
|
358
|
+
*
|
|
359
|
+
* 国际化核心实现,为 JSON 消息字典提供通用类型支持。
|
|
360
|
+
* @module core-i18n-utils
|
|
361
|
+
*/
|
|
362
|
+
|
|
363
|
+
declare function getGlobalLocale(): Locale;
|
|
364
|
+
declare function setGlobalLocale(locale: Locale): void;
|
|
365
|
+
/**
|
|
366
|
+
* 创建消息获取函数。
|
|
367
|
+
*
|
|
368
|
+
* 各模块通过此函数创建自己的消息获取器,自动读取全局 locale。
|
|
369
|
+
* 若指定的 locale 不支持,回退到默认语言;key 不存在时返回 key 本身。
|
|
370
|
+
*
|
|
371
|
+
* @param messages - 多语言消息对象
|
|
372
|
+
* @returns 消息获取函数
|
|
373
|
+
*
|
|
374
|
+
* @example
|
|
375
|
+
* ```ts
|
|
376
|
+
* const getMessage = createMessageGetter({
|
|
377
|
+
* 'zh-CN': { hello: '你好' },
|
|
378
|
+
* 'en-US': { hello: 'Hello' },
|
|
379
|
+
* })
|
|
380
|
+
* getMessage('hello') // '你好'
|
|
381
|
+
* getMessage('hello', { locale: 'en-US' }) // 'Hello'
|
|
382
|
+
* getMessage('msg', { params: { name: 'World' } }) // 插值
|
|
383
|
+
* ```
|
|
384
|
+
*/
|
|
385
|
+
declare function createMessageGetter<K extends string>(messages: LocaleMessages<K>): (key: K, options?: MessageOptions) => string;
|
|
386
|
+
declare const i18n: {
|
|
387
|
+
DEFAULT_LOCALES: LocaleInfo[];
|
|
388
|
+
DEFAULT_LOCALE: string;
|
|
389
|
+
setGlobalLocale: typeof setGlobalLocale;
|
|
390
|
+
getGlobalLocale: typeof getGlobalLocale;
|
|
391
|
+
createMessageGetter: typeof createMessageGetter;
|
|
392
|
+
coreM: (key: "$schema" | "core_errorUnknown" | "core_errorNetwork" | "core_errorTimeout" | "core_errorNotFound" | "core_errorUnauthorized" | "core_errorForbidden" | "core_errorValidation" | "core_errorInternal" | "core_actionConfirm" | "core_actionCancel" | "core_actionSave" | "core_actionDelete" | "core_actionEdit" | "core_actionCreate" | "core_actionUpdate" | "core_actionSearch" | "core_actionReset" | "core_actionSubmit" | "core_actionLoading" | "core_actionRetry" | "core_statusSuccess" | "core_statusFailed" | "core_statusPending" | "core_statusProcessing" | "core_statusCompleted" | "core_statusCancelled" | "core_validationRequired" | "core_validationMinLength" | "core_validationMaxLength" | "core_validationEmail" | "core_validationUrl" | "core_validationNumber" | "core_validationInteger" | "core_validationPositive" | "core_validationPattern" | "core_timeJustNow" | "core_timeSecondsAgo" | "core_timeMinutesAgo" | "core_timeHoursAgo" | "core_timeDaysAgo" | "core_timeWeeksAgo" | "core_timeMonthsAgo" | "core_timeYearsAgo" | "core_browserFeatureUnsupported" | "core_configEnvVarMissing" | "core_configFileNotExist" | "core_configParseFailed" | "core_configValidationFailed" | "core_configNotLoaded", options?: MessageOptions) => string;
|
|
393
|
+
};
|
|
394
|
+
/** i18n 子工具类型 */
|
|
395
|
+
type I18nFn = typeof i18n;
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* @h-ai/core — 数组操作工具
|
|
399
|
+
* @module core-util-array
|
|
400
|
+
*/
|
|
401
|
+
/**
|
|
402
|
+
* 数组去重。
|
|
403
|
+
* @param arr - 输入数组
|
|
404
|
+
* @returns 去重后的新数组
|
|
405
|
+
* @remarks 保留首次出现的顺序;空数组返回空数组。
|
|
406
|
+
*
|
|
407
|
+
* @example
|
|
408
|
+
* ```ts
|
|
409
|
+
* array.unique([1, 1, 2]) // [1, 2]
|
|
410
|
+
* ```
|
|
411
|
+
*/
|
|
412
|
+
declare function unique<T>(arr: T[]): T[];
|
|
413
|
+
/**
|
|
414
|
+
* 按条件分组。
|
|
415
|
+
* @param arr - 输入数组
|
|
416
|
+
* @param fn - 分组键生成函数
|
|
417
|
+
* @returns 分组结果对象
|
|
418
|
+
* @remarks 当数组为空时返回空对象。
|
|
419
|
+
*
|
|
420
|
+
* @example
|
|
421
|
+
* ```ts
|
|
422
|
+
* array.groupBy([{ r: 'a' }, { r: 'b' }], item => item.r)
|
|
423
|
+
* ```
|
|
424
|
+
*/
|
|
425
|
+
declare function groupBy<T, K extends string | number>(arr: T[], fn: (item: T) => K): Record<K, T[]>;
|
|
426
|
+
/**
|
|
427
|
+
* 分割为指定大小的块。
|
|
428
|
+
* @param arr - 输入数组
|
|
429
|
+
* @param size - 每块大小(应为正整数)
|
|
430
|
+
* @returns 分块后的二维数组
|
|
431
|
+
* @remarks size <= 0 时结果为空数组。
|
|
432
|
+
*
|
|
433
|
+
* @example
|
|
434
|
+
* ```ts
|
|
435
|
+
* array.chunk([1, 2, 3], 2) // [[1,2],[3]]
|
|
436
|
+
* ```
|
|
437
|
+
*/
|
|
438
|
+
declare function chunk<T>(arr: T[], size: number): T[][];
|
|
439
|
+
/**
|
|
440
|
+
* 获取第一个元素。
|
|
441
|
+
* @param arr - 输入数组
|
|
442
|
+
* @returns 第一个元素或 undefined
|
|
443
|
+
* @remarks 空数组返回 undefined。
|
|
444
|
+
*
|
|
445
|
+
* @example
|
|
446
|
+
* ```ts
|
|
447
|
+
* array.first([1, 2, 3]) // 1
|
|
448
|
+
* ```
|
|
449
|
+
*/
|
|
450
|
+
declare function first<T>(arr: T[]): T | undefined;
|
|
451
|
+
/**
|
|
452
|
+
* 获取最后一个元素。
|
|
453
|
+
* @param arr - 输入数组
|
|
454
|
+
* @returns 最后一个元素或 undefined
|
|
455
|
+
* @remarks 空数组返回 undefined。
|
|
456
|
+
*
|
|
457
|
+
* @example
|
|
458
|
+
* ```ts
|
|
459
|
+
* array.last([1, 2, 3]) // 3
|
|
460
|
+
* ```
|
|
461
|
+
*/
|
|
462
|
+
declare function last<T>(arr: T[]): T | undefined;
|
|
463
|
+
/**
|
|
464
|
+
* 数组扁平化。
|
|
465
|
+
* @param arr - 二维数组
|
|
466
|
+
* @returns 扁平化后的数组
|
|
467
|
+
* @remarks 仅扁平一层。
|
|
468
|
+
*
|
|
469
|
+
* @example
|
|
470
|
+
* ```ts
|
|
471
|
+
* array.flatten([[1], [2, 3]]) // [1, 2, 3]
|
|
472
|
+
* ```
|
|
473
|
+
*/
|
|
474
|
+
declare function flatten<T>(arr: T[][]): T[];
|
|
475
|
+
/**
|
|
476
|
+
* 过滤掉 null 和 undefined。
|
|
477
|
+
* @param arr - 输入数组
|
|
478
|
+
* @returns 过滤后的数组
|
|
479
|
+
* @remarks 会保留 0、false、'' 等假值。
|
|
480
|
+
*
|
|
481
|
+
* @example
|
|
482
|
+
* ```ts
|
|
483
|
+
* array.compact([0, null, 1]) // [0, 1]
|
|
484
|
+
* ```
|
|
485
|
+
*/
|
|
486
|
+
declare function compact<T>(arr: (T | null | undefined)[]): T[];
|
|
487
|
+
/**
|
|
488
|
+
* 随机打乱数组。
|
|
489
|
+
* @param arr - 输入数组
|
|
490
|
+
* @returns 打乱后的新数组
|
|
491
|
+
* @remarks 不修改原数组。
|
|
492
|
+
*
|
|
493
|
+
* @example
|
|
494
|
+
* ```ts
|
|
495
|
+
* const shuffled = array.shuffle([1, 2, 3])
|
|
496
|
+
* ```
|
|
497
|
+
*/
|
|
498
|
+
declare function shuffle<T>(arr: T[]): T[];
|
|
499
|
+
/**
|
|
500
|
+
* 取数组交集。
|
|
501
|
+
* @param arr1 - 数组 1
|
|
502
|
+
* @param arr2 - 数组 2
|
|
503
|
+
* @returns 交集数组
|
|
504
|
+
* @remarks 保持 arr1 中的顺序。
|
|
505
|
+
*
|
|
506
|
+
* @example
|
|
507
|
+
* ```ts
|
|
508
|
+
* array.intersection([1, 2], [2, 3]) // [2]
|
|
509
|
+
* ```
|
|
510
|
+
*/
|
|
511
|
+
declare function intersection<T>(arr1: T[], arr2: T[]): T[];
|
|
512
|
+
/**
|
|
513
|
+
* 取数组差集。
|
|
514
|
+
* @param arr1 - 数组 1
|
|
515
|
+
* @param arr2 - 数组 2
|
|
516
|
+
* @returns 差集数组(arr1 中存在且 arr2 不存在)
|
|
517
|
+
* @remarks 保持 arr1 中的顺序。
|
|
518
|
+
*
|
|
519
|
+
* @example
|
|
520
|
+
* ```ts
|
|
521
|
+
* array.difference([1, 2, 3], [2]) // [1, 3]
|
|
522
|
+
* ```
|
|
523
|
+
*/
|
|
524
|
+
declare function difference<T>(arr1: T[], arr2: T[]): T[];
|
|
525
|
+
/**
|
|
526
|
+
* 数组操作工具对象。
|
|
527
|
+
*
|
|
528
|
+
* @example
|
|
529
|
+
* ```ts
|
|
530
|
+
* array.unique([1, 1, 2])
|
|
531
|
+
* ```
|
|
532
|
+
*/
|
|
533
|
+
declare const array: {
|
|
534
|
+
unique: typeof unique;
|
|
535
|
+
groupBy: typeof groupBy;
|
|
536
|
+
chunk: typeof chunk;
|
|
537
|
+
first: typeof first;
|
|
538
|
+
last: typeof last;
|
|
539
|
+
flatten: typeof flatten;
|
|
540
|
+
compact: typeof compact;
|
|
541
|
+
shuffle: typeof shuffle;
|
|
542
|
+
intersection: typeof intersection;
|
|
543
|
+
difference: typeof difference;
|
|
544
|
+
};
|
|
545
|
+
/** array 子工具类型 */
|
|
546
|
+
type ArrayFn = typeof array;
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* @h-ai/core — 异步操作工具
|
|
550
|
+
* @module core-util-async
|
|
551
|
+
*/
|
|
552
|
+
/**
|
|
553
|
+
* 延迟执行。
|
|
554
|
+
*
|
|
555
|
+
* @param ms - 延迟毫秒数
|
|
556
|
+
* @returns 延迟完成后的 Promise
|
|
557
|
+
*
|
|
558
|
+
* @example
|
|
559
|
+
* ```ts
|
|
560
|
+
* await async.delay(1000)
|
|
561
|
+
* ```
|
|
562
|
+
*/
|
|
563
|
+
declare function delay(ms: number): Promise<void>;
|
|
564
|
+
/**
|
|
565
|
+
* 添加超时限制。
|
|
566
|
+
*
|
|
567
|
+
* @param promise - 目标 Promise
|
|
568
|
+
* @param ms - 超时时间(毫秒)
|
|
569
|
+
* @returns 原 Promise 的结果
|
|
570
|
+
* @throws 超时将抛出错误
|
|
571
|
+
*
|
|
572
|
+
* @example
|
|
573
|
+
* ```ts
|
|
574
|
+
* await async.withTimeout(fetch('/api'), 5000)
|
|
575
|
+
* ```
|
|
576
|
+
*/
|
|
577
|
+
declare function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T>;
|
|
578
|
+
/**
|
|
579
|
+
* 重试操作。
|
|
580
|
+
*
|
|
581
|
+
* @param fn - 待重试函数
|
|
582
|
+
* @param options - 重试配置
|
|
583
|
+
* @param options.maxRetries - 最大重试次数
|
|
584
|
+
* @param options.delay - 重试间隔(毫秒)
|
|
585
|
+
* @returns 成功的结果
|
|
586
|
+
* @throws 重试耗尽后抛出最后一次错误
|
|
587
|
+
*
|
|
588
|
+
* @example
|
|
589
|
+
* ```ts
|
|
590
|
+
* await async.retry(() => fetch('/api'), { maxRetries: 3, delay: 500 })
|
|
591
|
+
* ```
|
|
592
|
+
*/
|
|
593
|
+
declare function retry<T>(fn: () => Promise<T>, options?: {
|
|
594
|
+
maxRetries?: number;
|
|
595
|
+
delay?: number;
|
|
596
|
+
}): Promise<T>;
|
|
597
|
+
/**
|
|
598
|
+
* 并行执行,限制并发数。
|
|
599
|
+
*
|
|
600
|
+
* @param items - 输入列表
|
|
601
|
+
* @param fn - 处理函数
|
|
602
|
+
* @param concurrency - 最大并发数
|
|
603
|
+
* @returns 处理结果列表
|
|
604
|
+
* @remarks 结果顺序与输入顺序一致。
|
|
605
|
+
*
|
|
606
|
+
* @example
|
|
607
|
+
* ```ts
|
|
608
|
+
* await async.parallel([1, 2, 3], async n => n * 2, 2)
|
|
609
|
+
* ```
|
|
610
|
+
*/
|
|
611
|
+
declare function parallel<T, R>(items: T[], fn: (item: T, index: number) => Promise<R>, concurrency?: number): Promise<R[]>;
|
|
612
|
+
/**
|
|
613
|
+
* 串行执行。
|
|
614
|
+
*
|
|
615
|
+
* @param items - 输入列表
|
|
616
|
+
* @param fn - 处理函数
|
|
617
|
+
* @returns 处理结果列表
|
|
618
|
+
*
|
|
619
|
+
* @example
|
|
620
|
+
* ```ts
|
|
621
|
+
* await async.serial([1, 2], async n => n * 2)
|
|
622
|
+
* ```
|
|
623
|
+
*/
|
|
624
|
+
declare function serial<T, R>(items: T[], fn: (item: T, index: number) => Promise<R>): Promise<R[]>;
|
|
625
|
+
/**
|
|
626
|
+
* 防抖。
|
|
627
|
+
*
|
|
628
|
+
* @param fn - 目标函数
|
|
629
|
+
* @param ms - 延迟毫秒数
|
|
630
|
+
* @returns 防抖后的函数
|
|
631
|
+
* @remarks 只会在最后一次调用后执行。
|
|
632
|
+
*
|
|
633
|
+
* @example
|
|
634
|
+
* ```ts
|
|
635
|
+
* const onInput = async.debounce(() => {}, 300)
|
|
636
|
+
* ```
|
|
637
|
+
*/
|
|
638
|
+
declare function debounce<T extends (...args: unknown[]) => unknown>(fn: T, ms: number): (...args: Parameters<T>) => void;
|
|
639
|
+
/**
|
|
640
|
+
* 节流。
|
|
641
|
+
*
|
|
642
|
+
* @param fn - 目标函数
|
|
643
|
+
* @param ms - 间隔毫秒数
|
|
644
|
+
* @returns 节流后的函数
|
|
645
|
+
* @remarks 在时间窗口内最多触发一次。
|
|
646
|
+
*
|
|
647
|
+
* @example
|
|
648
|
+
* ```ts
|
|
649
|
+
* const onScroll = async.throttle(() => {}, 200)
|
|
650
|
+
* ```
|
|
651
|
+
*/
|
|
652
|
+
declare function throttle<T extends (...args: unknown[]) => unknown>(fn: T, ms: number): (...args: Parameters<T>) => void;
|
|
653
|
+
/**
|
|
654
|
+
* 异步操作工具对象。
|
|
655
|
+
*
|
|
656
|
+
* @example
|
|
657
|
+
* ```ts
|
|
658
|
+
* await async.delay(100)
|
|
659
|
+
* ```
|
|
660
|
+
*/
|
|
661
|
+
declare const async: {
|
|
662
|
+
delay: typeof delay;
|
|
663
|
+
withTimeout: typeof withTimeout;
|
|
664
|
+
retry: typeof retry;
|
|
665
|
+
parallel: typeof parallel;
|
|
666
|
+
serial: typeof serial;
|
|
667
|
+
debounce: typeof debounce;
|
|
668
|
+
throttle: typeof throttle;
|
|
669
|
+
};
|
|
670
|
+
/** async 子工具类型 */
|
|
671
|
+
type AsyncFn = typeof async;
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* @h-ai/core — 对象操作工具
|
|
675
|
+
* @module core-util-object
|
|
676
|
+
*/
|
|
677
|
+
/**
|
|
678
|
+
* 深度克隆对象。
|
|
679
|
+
* 使用 structuredClone(Node 17+ / 现代浏览器),支持 Date、Map、Set、RegExp、
|
|
680
|
+
* ArrayBuffer、循环引用等 JSON 方案无法处理的类型。
|
|
681
|
+
*
|
|
682
|
+
* @param obj - 目标对象
|
|
683
|
+
* @returns 深度克隆结果
|
|
684
|
+
*
|
|
685
|
+
* @example
|
|
686
|
+
* ```ts
|
|
687
|
+
* const cloned = object.deepClone({ a: 1, d: new Date() })
|
|
688
|
+
* ```
|
|
689
|
+
*/
|
|
690
|
+
declare function deepClone<T>(obj: T): T;
|
|
691
|
+
/**
|
|
692
|
+
* 深度合并多个对象。
|
|
693
|
+
* @param objects - 需要合并的对象列表
|
|
694
|
+
* @returns 合并后的新对象
|
|
695
|
+
* @remarks 仅合并纯对象字段,数组会被直接覆盖。
|
|
696
|
+
*
|
|
697
|
+
* @example
|
|
698
|
+
* ```ts
|
|
699
|
+
* const merged = object.deepMerge({ a: 1 }, { b: 2 })
|
|
700
|
+
* ```
|
|
701
|
+
*/
|
|
702
|
+
declare function deepMerge<T extends Record<string, unknown>>(...objects: Partial<T>[]): T;
|
|
703
|
+
/**
|
|
704
|
+
* 从对象中选取指定的键。
|
|
705
|
+
* @param obj - 目标对象
|
|
706
|
+
* @param keys - 要选取的键列表
|
|
707
|
+
* @returns 仅包含指定键的新对象
|
|
708
|
+
*
|
|
709
|
+
* @example
|
|
710
|
+
* ```ts
|
|
711
|
+
* object.pick({ a: 1, b: 2 }, ['a'])
|
|
712
|
+
* ```
|
|
713
|
+
*/
|
|
714
|
+
declare function pick<T extends Record<string, unknown>, K extends keyof T>(obj: T, keys: K[]): Pick<T, K>;
|
|
715
|
+
/**
|
|
716
|
+
* 从对象中排除指定的键。
|
|
717
|
+
* @param obj - 目标对象
|
|
718
|
+
* @param keys - 要排除的键列表
|
|
719
|
+
* @returns 排除指定键后的新对象
|
|
720
|
+
*
|
|
721
|
+
* @example
|
|
722
|
+
* ```ts
|
|
723
|
+
* object.omit({ a: 1, b: 2 }, ['b'])
|
|
724
|
+
* ```
|
|
725
|
+
*/
|
|
726
|
+
declare function omit<T extends Record<string, unknown>, K extends keyof T>(obj: T, keys: K[]): Omit<T, K>;
|
|
727
|
+
/**
|
|
728
|
+
* 获取对象的所有键。
|
|
729
|
+
* @param obj - 目标对象
|
|
730
|
+
* @returns 键列表
|
|
731
|
+
*
|
|
732
|
+
* @example
|
|
733
|
+
* ```ts
|
|
734
|
+
* object.keys({ a: 1, b: 2 })
|
|
735
|
+
* ```
|
|
736
|
+
*/
|
|
737
|
+
declare function keys<T extends Record<string, unknown>>(obj: T): (keyof T)[];
|
|
738
|
+
/**
|
|
739
|
+
* 获取对象的所有值。
|
|
740
|
+
* @param obj - 目标对象
|
|
741
|
+
* @returns 值列表
|
|
742
|
+
*
|
|
743
|
+
* @example
|
|
744
|
+
* ```ts
|
|
745
|
+
* object.values({ a: 1, b: 2 })
|
|
746
|
+
* ```
|
|
747
|
+
*/
|
|
748
|
+
declare function values<T extends Record<string, unknown>>(obj: T): T[keyof T][];
|
|
749
|
+
/**
|
|
750
|
+
* 获取对象的键值对数组。
|
|
751
|
+
* @param obj - 目标对象
|
|
752
|
+
* @returns 键值对数组
|
|
753
|
+
*
|
|
754
|
+
* @example
|
|
755
|
+
* ```ts
|
|
756
|
+
* object.entries({ a: 1 })
|
|
757
|
+
* ```
|
|
758
|
+
*/
|
|
759
|
+
declare function entries<T extends Record<string, unknown>>(obj: T): [keyof T, T[keyof T]][];
|
|
760
|
+
/**
|
|
761
|
+
* 从键值对数组创建对象。
|
|
762
|
+
* @param entries - 键值对数组
|
|
763
|
+
* @returns 生成的对象
|
|
764
|
+
*
|
|
765
|
+
* @example
|
|
766
|
+
* ```ts
|
|
767
|
+
* object.fromEntries([['a', 1]])
|
|
768
|
+
* ```
|
|
769
|
+
*/
|
|
770
|
+
declare function fromEntries<K extends string, V>(entries: [K, V][]): Record<K, V>;
|
|
771
|
+
/**
|
|
772
|
+
* 对象操作工具对象。
|
|
773
|
+
*
|
|
774
|
+
* @example
|
|
775
|
+
* ```ts
|
|
776
|
+
* object.deepMerge({ a: 1 }, { b: 2 })
|
|
777
|
+
* ```
|
|
778
|
+
*/
|
|
779
|
+
declare const object: {
|
|
780
|
+
deepClone: typeof deepClone;
|
|
781
|
+
deepMerge: typeof deepMerge;
|
|
782
|
+
pick: typeof pick;
|
|
783
|
+
omit: typeof omit;
|
|
784
|
+
keys: typeof keys;
|
|
785
|
+
values: typeof values;
|
|
786
|
+
entries: typeof entries;
|
|
787
|
+
fromEntries: typeof fromEntries;
|
|
788
|
+
};
|
|
789
|
+
/** object 子工具类型 */
|
|
790
|
+
type ObjectFn = typeof object;
|
|
791
|
+
|
|
792
|
+
/**
|
|
793
|
+
* @h-ai/core — 字符串操作工具
|
|
794
|
+
* @module core-util-string
|
|
795
|
+
*/
|
|
796
|
+
/**
|
|
797
|
+
* 首字母大写。
|
|
798
|
+
* @param str - 输入字符串
|
|
799
|
+
* @returns 首字母大写后的字符串
|
|
800
|
+
* @remarks 空字符串返回空字符串。
|
|
801
|
+
*
|
|
802
|
+
* @example
|
|
803
|
+
* ```ts
|
|
804
|
+
* string.capitalize('hello') // 'Hello'
|
|
805
|
+
* ```
|
|
806
|
+
*/
|
|
807
|
+
declare function capitalize(str: string): string;
|
|
808
|
+
/**
|
|
809
|
+
* 转换为 kebab-case。
|
|
810
|
+
* @param str - 输入字符串
|
|
811
|
+
* @returns kebab-case 字符串
|
|
812
|
+
* @remarks 支持连续大写字母拆分(如 `getHTTPSUrl` → `get-https-url`)。
|
|
813
|
+
*
|
|
814
|
+
* @example
|
|
815
|
+
* ```ts
|
|
816
|
+
* string.kebabCase('helloWorld') // 'hello-world'
|
|
817
|
+
* string.kebabCase('getHTTPSUrl') // 'get-https-url'
|
|
818
|
+
* ```
|
|
819
|
+
*/
|
|
820
|
+
declare function kebabCase(str: string): string;
|
|
821
|
+
/**
|
|
822
|
+
* 转换为 camelCase。
|
|
823
|
+
* @param str - 输入字符串
|
|
824
|
+
* @returns camelCase 字符串
|
|
825
|
+
* @remarks 仅处理包含 '-' 的字符串。
|
|
826
|
+
*
|
|
827
|
+
* @example
|
|
828
|
+
* ```ts
|
|
829
|
+
* string.camelCase('hello-world') // 'helloWorld'
|
|
830
|
+
* ```
|
|
831
|
+
*/
|
|
832
|
+
declare function camelCase(str: string): string;
|
|
833
|
+
/**
|
|
834
|
+
* 截断字符串。
|
|
835
|
+
* @param str - 输入字符串
|
|
836
|
+
* @param length - 最大长度(小于等于 0 时返回原字符串)
|
|
837
|
+
* @param suffix - 超出长度时的后缀
|
|
838
|
+
* @returns 截断后的字符串
|
|
839
|
+
*
|
|
840
|
+
* @example
|
|
841
|
+
* ```ts
|
|
842
|
+
* string.truncate('hello world', 5) // 'hello...'
|
|
843
|
+
* ```
|
|
844
|
+
*/
|
|
845
|
+
declare function truncate(str: string, length: number, suffix?: string): string;
|
|
846
|
+
/**
|
|
847
|
+
* 转换为 snake_case。
|
|
848
|
+
* @param str - 输入字符串
|
|
849
|
+
* @returns snake_case 字符串
|
|
850
|
+
* @remarks 支持连续大写字母拆分(如 `getHTTPSUrl` → `get_https_url`)。
|
|
851
|
+
*
|
|
852
|
+
* @example
|
|
853
|
+
* ```ts
|
|
854
|
+
* string.snakeCase('helloWorld') // 'hello_world'
|
|
855
|
+
* string.snakeCase('getHTTPSUrl') // 'get_https_url'
|
|
856
|
+
* ```
|
|
857
|
+
*/
|
|
858
|
+
declare function snakeCase(str: string): string;
|
|
859
|
+
/**
|
|
860
|
+
* 转换为 PascalCase。
|
|
861
|
+
* @param str - 输入字符串
|
|
862
|
+
* @returns PascalCase 字符串
|
|
863
|
+
* @remarks 支持 '-' 与 '_' 分隔。
|
|
864
|
+
*
|
|
865
|
+
* @example
|
|
866
|
+
* ```ts
|
|
867
|
+
* string.pascalCase('hello-world') // 'HelloWorld'
|
|
868
|
+
* ```
|
|
869
|
+
*/
|
|
870
|
+
declare function pascalCase(str: string): string;
|
|
871
|
+
/**
|
|
872
|
+
* 移除字符串两端的空白。
|
|
873
|
+
* @param str - 输入字符串
|
|
874
|
+
* @returns 去除两端空白后的字符串
|
|
875
|
+
*
|
|
876
|
+
* @example
|
|
877
|
+
* ```ts
|
|
878
|
+
* string.trim(' hi ') // 'hi'
|
|
879
|
+
* ```
|
|
880
|
+
*/
|
|
881
|
+
declare function trim(str: string): string;
|
|
882
|
+
/**
|
|
883
|
+
* 检查字符串是否为空或只包含空白。
|
|
884
|
+
* @param str - 输入字符串
|
|
885
|
+
* @returns 是否为空或全空白
|
|
886
|
+
*
|
|
887
|
+
* @example
|
|
888
|
+
* ```ts
|
|
889
|
+
* string.isBlank(' ') // true
|
|
890
|
+
* ```
|
|
891
|
+
*/
|
|
892
|
+
declare function isBlank(str: string): boolean;
|
|
893
|
+
/**
|
|
894
|
+
* 检查字符串是否不为空。
|
|
895
|
+
* @param str - 输入字符串
|
|
896
|
+
* @returns 是否非空
|
|
897
|
+
*
|
|
898
|
+
* @example
|
|
899
|
+
* ```ts
|
|
900
|
+
* string.isNotBlank('ok') // true
|
|
901
|
+
* ```
|
|
902
|
+
*/
|
|
903
|
+
declare function isNotBlank(str: string): boolean;
|
|
904
|
+
/**
|
|
905
|
+
* 填充字符串到指定长度(左侧)。
|
|
906
|
+
* @param str - 输入字符串
|
|
907
|
+
* @param length - 目标长度
|
|
908
|
+
* @param char - 填充字符
|
|
909
|
+
* @returns 填充后的字符串
|
|
910
|
+
*
|
|
911
|
+
* @example
|
|
912
|
+
* ```ts
|
|
913
|
+
* string.padStart('1', 3, '0') // '001'
|
|
914
|
+
* ```
|
|
915
|
+
*/
|
|
916
|
+
declare function padStart(str: string, length: number, char?: string): string;
|
|
917
|
+
/**
|
|
918
|
+
* 填充字符串到指定长度(右侧)。
|
|
919
|
+
* @param str - 输入字符串
|
|
920
|
+
* @param length - 目标长度
|
|
921
|
+
* @param char - 填充字符
|
|
922
|
+
* @returns 填充后的字符串
|
|
923
|
+
*
|
|
924
|
+
* @example
|
|
925
|
+
* ```ts
|
|
926
|
+
* string.padEnd('1', 3, '0') // '100'
|
|
927
|
+
* ```
|
|
928
|
+
*/
|
|
929
|
+
declare function padEnd(str: string, length: number, char?: string): string;
|
|
930
|
+
/**
|
|
931
|
+
* 常量时间字符串比较。
|
|
932
|
+
*
|
|
933
|
+
* 防止时序侧信道攻击:无论输入差异位置如何,执行时间恒定。
|
|
934
|
+
* 兼容 Node.js 与浏览器环境(纯 JS 实现,无平台依赖)。
|
|
935
|
+
*
|
|
936
|
+
* @param a - 字符串 a
|
|
937
|
+
* @param b - 字符串 b
|
|
938
|
+
* @returns 是否相等
|
|
939
|
+
*
|
|
940
|
+
* @example
|
|
941
|
+
* ```ts
|
|
942
|
+
* string.constantTimeEqual('abc', 'abc') // true
|
|
943
|
+
* string.constantTimeEqual('abc', 'abd') // false
|
|
944
|
+
* ```
|
|
945
|
+
*/
|
|
946
|
+
declare function constantTimeEqual(a: string, b: string): boolean;
|
|
947
|
+
/**
|
|
948
|
+
* 字符串操作工具对象。
|
|
949
|
+
*
|
|
950
|
+
* @example
|
|
951
|
+
* ```ts
|
|
952
|
+
* string.capitalize('hello')
|
|
953
|
+
* ```
|
|
954
|
+
*/
|
|
955
|
+
declare const string: {
|
|
956
|
+
capitalize: typeof capitalize;
|
|
957
|
+
kebabCase: typeof kebabCase;
|
|
958
|
+
camelCase: typeof camelCase;
|
|
959
|
+
truncate: typeof truncate;
|
|
960
|
+
snakeCase: typeof snakeCase;
|
|
961
|
+
pascalCase: typeof pascalCase;
|
|
962
|
+
trim: typeof trim;
|
|
963
|
+
isBlank: typeof isBlank;
|
|
964
|
+
isNotBlank: typeof isNotBlank;
|
|
965
|
+
padStart: typeof padStart;
|
|
966
|
+
padEnd: typeof padEnd;
|
|
967
|
+
constantTimeEqual: typeof constantTimeEqual;
|
|
968
|
+
};
|
|
969
|
+
/** string 子工具类型 */
|
|
970
|
+
type StringFn = typeof string;
|
|
971
|
+
|
|
972
|
+
/**
|
|
973
|
+
* @h-ai/core — 时间操作工具
|
|
974
|
+
* @module core-util-time
|
|
975
|
+
*/
|
|
976
|
+
/**
|
|
977
|
+
* 格式化日期。
|
|
978
|
+
* @param date - 日期对象
|
|
979
|
+
* @param format - 格式模板(默认 YYYY-MM-DD)
|
|
980
|
+
* @returns 格式化后的字符串
|
|
981
|
+
*
|
|
982
|
+
* @example
|
|
983
|
+
* ```ts
|
|
984
|
+
* time.formatDate(new Date(), 'YYYY-MM-DD')
|
|
985
|
+
* ```
|
|
986
|
+
*/
|
|
987
|
+
declare function formatDate(date: Date, format?: string): string;
|
|
988
|
+
/**
|
|
989
|
+
* 相对时间描述。
|
|
990
|
+
* @param date - 目标日期
|
|
991
|
+
* @returns 相对时间文案
|
|
992
|
+
* @remarks 使用 i18n 消息返回结果。
|
|
993
|
+
*
|
|
994
|
+
* @example
|
|
995
|
+
* ```ts
|
|
996
|
+
* time.timeAgo(new Date(Date.now() - 60000))
|
|
997
|
+
* ```
|
|
998
|
+
*/
|
|
999
|
+
declare function timeAgo(date: Date): string;
|
|
1000
|
+
/**
|
|
1001
|
+
* 获取当前时间戳(毫秒)。
|
|
1002
|
+
* @returns 当前时间戳(毫秒)
|
|
1003
|
+
*
|
|
1004
|
+
* @example
|
|
1005
|
+
* ```ts
|
|
1006
|
+
* const ts = time.now()
|
|
1007
|
+
* ```
|
|
1008
|
+
*/
|
|
1009
|
+
declare function now(): number;
|
|
1010
|
+
/**
|
|
1011
|
+
* 获取当前时间戳(秒)。
|
|
1012
|
+
* @returns 当前时间戳(秒)
|
|
1013
|
+
*
|
|
1014
|
+
* @example
|
|
1015
|
+
* ```ts
|
|
1016
|
+
* const ts = time.nowSeconds()
|
|
1017
|
+
* ```
|
|
1018
|
+
*/
|
|
1019
|
+
declare function nowSeconds(): number;
|
|
1020
|
+
/**
|
|
1021
|
+
* 解析日期字符串。
|
|
1022
|
+
* @param dateStr - 日期字符串
|
|
1023
|
+
* @returns Date 对象
|
|
1024
|
+
* @remarks 无效字符串将生成 Invalid Date。
|
|
1025
|
+
*
|
|
1026
|
+
* @example
|
|
1027
|
+
* ```ts
|
|
1028
|
+
* const date = time.parseDate('2024-01-01')
|
|
1029
|
+
* ```
|
|
1030
|
+
*/
|
|
1031
|
+
declare function parseDate(dateStr: string): Date;
|
|
1032
|
+
/**
|
|
1033
|
+
* 判断是否为有效日期。
|
|
1034
|
+
* @param date - Date 对象
|
|
1035
|
+
* @returns 是否为有效日期
|
|
1036
|
+
*
|
|
1037
|
+
* @example
|
|
1038
|
+
* ```ts
|
|
1039
|
+
* time.isValidDate(new Date('invalid')) // false
|
|
1040
|
+
* ```
|
|
1041
|
+
*/
|
|
1042
|
+
declare function isValidDate(date: Date): boolean;
|
|
1043
|
+
/**
|
|
1044
|
+
* 添加天数。
|
|
1045
|
+
* @param date - 原始日期
|
|
1046
|
+
* @param days - 增加天数(可为负数)
|
|
1047
|
+
* @returns 新的日期对象
|
|
1048
|
+
*
|
|
1049
|
+
* @example
|
|
1050
|
+
* ```ts
|
|
1051
|
+
* time.addDays(new Date(), 7)
|
|
1052
|
+
* ```
|
|
1053
|
+
*/
|
|
1054
|
+
declare function addDays(date: Date, days: number): Date;
|
|
1055
|
+
/**
|
|
1056
|
+
* 添加小时。
|
|
1057
|
+
* @param date - 原始日期
|
|
1058
|
+
* @param hours - 增加小时(可为负数)
|
|
1059
|
+
* @returns 新的日期对象
|
|
1060
|
+
*
|
|
1061
|
+
* @example
|
|
1062
|
+
* ```ts
|
|
1063
|
+
* time.addHours(new Date(), 1)
|
|
1064
|
+
* ```
|
|
1065
|
+
*/
|
|
1066
|
+
declare function addHours(date: Date, hours: number): Date;
|
|
1067
|
+
/**
|
|
1068
|
+
* 获取日期的开始时间(00:00:00)。
|
|
1069
|
+
* @param date - 目标日期
|
|
1070
|
+
* @returns 当天开始时间
|
|
1071
|
+
*
|
|
1072
|
+
* @example
|
|
1073
|
+
* ```ts
|
|
1074
|
+
* time.startOfDay(new Date())
|
|
1075
|
+
* ```
|
|
1076
|
+
*/
|
|
1077
|
+
declare function startOfDay(date: Date): Date;
|
|
1078
|
+
/**
|
|
1079
|
+
* 获取日期的结束时间(23:59:59)。
|
|
1080
|
+
* @param date - 目标日期
|
|
1081
|
+
* @returns 当天结束时间
|
|
1082
|
+
*
|
|
1083
|
+
* @example
|
|
1084
|
+
* ```ts
|
|
1085
|
+
* time.endOfDay(new Date())
|
|
1086
|
+
* ```
|
|
1087
|
+
*/
|
|
1088
|
+
declare function endOfDay(date: Date): Date;
|
|
1089
|
+
/**
|
|
1090
|
+
* 时间操作工具对象。
|
|
1091
|
+
*
|
|
1092
|
+
* @example
|
|
1093
|
+
* ```ts
|
|
1094
|
+
* time.formatDate(new Date())
|
|
1095
|
+
* ```
|
|
1096
|
+
*/
|
|
1097
|
+
declare const time: {
|
|
1098
|
+
formatDate: typeof formatDate;
|
|
1099
|
+
timeAgo: typeof timeAgo;
|
|
1100
|
+
now: typeof now;
|
|
1101
|
+
nowSeconds: typeof nowSeconds;
|
|
1102
|
+
parseDate: typeof parseDate;
|
|
1103
|
+
isValidDate: typeof isValidDate;
|
|
1104
|
+
addDays: typeof addDays;
|
|
1105
|
+
addHours: typeof addHours;
|
|
1106
|
+
startOfDay: typeof startOfDay;
|
|
1107
|
+
endOfDay: typeof endOfDay;
|
|
1108
|
+
};
|
|
1109
|
+
/** time 子工具类型 */
|
|
1110
|
+
type TimeFn = typeof time;
|
|
1111
|
+
|
|
1112
|
+
/**
|
|
1113
|
+
* @h-ai/core — 类型检查工具
|
|
1114
|
+
* @module core-util-type
|
|
1115
|
+
*/
|
|
1116
|
+
/**
|
|
1117
|
+
* 检查值是否已定义(非 null 和 undefined)。
|
|
1118
|
+
* @param value - 待检查值
|
|
1119
|
+
* @returns 是否已定义
|
|
1120
|
+
*
|
|
1121
|
+
* @example
|
|
1122
|
+
* ```ts
|
|
1123
|
+
* typeUtils.isDefined(0) // true
|
|
1124
|
+
* ```
|
|
1125
|
+
*/
|
|
1126
|
+
declare function isDefined<T>(value: T | undefined | null): value is T;
|
|
1127
|
+
/**
|
|
1128
|
+
* 检查值是否为纯对象(排除数组)。
|
|
1129
|
+
* @param value - 待检查值
|
|
1130
|
+
* @returns 是否为纯对象
|
|
1131
|
+
*
|
|
1132
|
+
* @example
|
|
1133
|
+
* ```ts
|
|
1134
|
+
* typeUtils.isObject({}) // true
|
|
1135
|
+
* ```
|
|
1136
|
+
*/
|
|
1137
|
+
declare function isObject(value: unknown): value is Record<string, unknown>;
|
|
1138
|
+
/**
|
|
1139
|
+
* 检查值是否为函数。
|
|
1140
|
+
* @param value - 待检查值
|
|
1141
|
+
* @returns 是否为函数
|
|
1142
|
+
*
|
|
1143
|
+
* @example
|
|
1144
|
+
* ```ts
|
|
1145
|
+
* typeUtils.isFunction(() => {}) // true
|
|
1146
|
+
* ```
|
|
1147
|
+
*/
|
|
1148
|
+
declare function isFunction(value: unknown): value is (...args: unknown[]) => unknown;
|
|
1149
|
+
/**
|
|
1150
|
+
* 检查值是否为 Promise。
|
|
1151
|
+
* @param value - 待检查值
|
|
1152
|
+
* @returns 是否为 Promise
|
|
1153
|
+
*
|
|
1154
|
+
* @example
|
|
1155
|
+
* ```ts
|
|
1156
|
+
* typeUtils.isPromise(Promise.resolve()) // true
|
|
1157
|
+
* ```
|
|
1158
|
+
*/
|
|
1159
|
+
declare function isPromise<T>(value: unknown): value is Promise<T>;
|
|
1160
|
+
/**
|
|
1161
|
+
* 检查值是否为字符串。
|
|
1162
|
+
* @param value - 待检查值
|
|
1163
|
+
* @returns 是否为字符串
|
|
1164
|
+
*
|
|
1165
|
+
* @example
|
|
1166
|
+
* ```ts
|
|
1167
|
+
* typeUtils.isString('a') // true
|
|
1168
|
+
* ```
|
|
1169
|
+
*/
|
|
1170
|
+
declare function isString(value: unknown): value is string;
|
|
1171
|
+
/**
|
|
1172
|
+
* 检查值是否为数字。
|
|
1173
|
+
* @param value - 待检查值
|
|
1174
|
+
* @returns 是否为数字(排除 NaN)
|
|
1175
|
+
*
|
|
1176
|
+
* @example
|
|
1177
|
+
* ```ts
|
|
1178
|
+
* typeUtils.isNumber(1) // true
|
|
1179
|
+
* ```
|
|
1180
|
+
*/
|
|
1181
|
+
declare function isNumber(value: unknown): value is number;
|
|
1182
|
+
/**
|
|
1183
|
+
* 检查值是否为布尔值。
|
|
1184
|
+
* @param value - 待检查值
|
|
1185
|
+
* @returns 是否为布尔值
|
|
1186
|
+
*
|
|
1187
|
+
* @example
|
|
1188
|
+
* ```ts
|
|
1189
|
+
* typeUtils.isBoolean(false) // true
|
|
1190
|
+
* ```
|
|
1191
|
+
*/
|
|
1192
|
+
declare function isBoolean(value: unknown): value is boolean;
|
|
1193
|
+
/**
|
|
1194
|
+
* 检查值是否为数组。
|
|
1195
|
+
* @param value - 待检查值
|
|
1196
|
+
* @returns 是否为数组
|
|
1197
|
+
*
|
|
1198
|
+
* @example
|
|
1199
|
+
* ```ts
|
|
1200
|
+
* typeUtils.isArray([1, 2]) // true
|
|
1201
|
+
* ```
|
|
1202
|
+
*/
|
|
1203
|
+
declare function isArray<T = unknown>(value: unknown): value is T[];
|
|
1204
|
+
/**
|
|
1205
|
+
* 类型检查工具对象。
|
|
1206
|
+
*
|
|
1207
|
+
* @example
|
|
1208
|
+
* ```ts
|
|
1209
|
+
* typeUtils.isDefined('x')
|
|
1210
|
+
* ```
|
|
1211
|
+
*/
|
|
1212
|
+
declare const typeUtils: {
|
|
1213
|
+
isDefined: typeof isDefined;
|
|
1214
|
+
isObject: typeof isObject;
|
|
1215
|
+
isFunction: typeof isFunction;
|
|
1216
|
+
isPromise: typeof isPromise;
|
|
1217
|
+
isString: typeof isString;
|
|
1218
|
+
isNumber: typeof isNumber;
|
|
1219
|
+
isBoolean: typeof isBoolean;
|
|
1220
|
+
isArray: typeof isArray;
|
|
1221
|
+
};
|
|
1222
|
+
/** typeUtils 子工具类型 */
|
|
1223
|
+
type TypeUtilFn = typeof typeUtils;
|
|
1224
|
+
|
|
1225
|
+
/**
|
|
1226
|
+
* @h-ai/core — 类型定义
|
|
1227
|
+
*
|
|
1228
|
+
* 核心模块的公共类型(前后端通用)
|
|
1229
|
+
* @module core-types
|
|
1230
|
+
*/
|
|
1231
|
+
|
|
1232
|
+
type HaiResult<T> = {
|
|
1233
|
+
success: true;
|
|
1234
|
+
data: T;
|
|
1235
|
+
} | {
|
|
1236
|
+
success: false;
|
|
1237
|
+
error: HaiError;
|
|
1238
|
+
};
|
|
1239
|
+
declare function ok<T>(data: T): HaiResult<T>;
|
|
1240
|
+
declare function err(errorOrDef: HaiErrorDef | HaiError | Error, message?: string, cause?: unknown, suggestion?: string): HaiResult<never>;
|
|
1241
|
+
/**
|
|
1242
|
+
* HaiResult 模式匹配处理器。
|
|
1243
|
+
*
|
|
1244
|
+
* 提供对 HaiResult 的模式匹配能力,分别处理成功和失败两种情况。
|
|
1245
|
+
*
|
|
1246
|
+
* @template T - 成功数据类型
|
|
1247
|
+
* @template R1 - ok 分支返回类型
|
|
1248
|
+
* @template R2 - err 分支返回类型
|
|
1249
|
+
*
|
|
1250
|
+
* @example
|
|
1251
|
+
* ```ts
|
|
1252
|
+
* const handlers: MatchHandlers<number, number, number> = {
|
|
1253
|
+
* ok: n => n + 1,
|
|
1254
|
+
* err: () => 0,
|
|
1255
|
+
* }
|
|
1256
|
+
* ```
|
|
1257
|
+
*/
|
|
1258
|
+
interface MatchHandlers<T, R1, R2> {
|
|
1259
|
+
/** 成功分支处理器 */
|
|
1260
|
+
ok: (data: T) => R1;
|
|
1261
|
+
/** 失败分支处理器 */
|
|
1262
|
+
err: (error: HaiError) => R2;
|
|
1263
|
+
}
|
|
1264
|
+
/** 错误信息值格式:`错误码数字段:HTTP状态码`,例如 `001:500`。 */
|
|
1265
|
+
type ErrorInfoValue = `${string}:${string}`;
|
|
1266
|
+
/** 模块错误信息映射。 */
|
|
1267
|
+
type ErrorInfo = Record<string, ErrorInfoValue>;
|
|
1268
|
+
interface HaiErrorDef {
|
|
1269
|
+
code: string | number;
|
|
1270
|
+
httpStatus: number;
|
|
1271
|
+
system: string;
|
|
1272
|
+
module: string;
|
|
1273
|
+
}
|
|
1274
|
+
interface HaiError {
|
|
1275
|
+
code: string | number;
|
|
1276
|
+
message: string;
|
|
1277
|
+
httpStatus?: number;
|
|
1278
|
+
system?: string;
|
|
1279
|
+
module?: string;
|
|
1280
|
+
cause?: unknown;
|
|
1281
|
+
suggestion?: string;
|
|
1282
|
+
ext?: Record<string, unknown>;
|
|
1283
|
+
}
|
|
1284
|
+
declare const HaiCommonError: {
|
|
1285
|
+
readonly NOT_INITIALIZED: HaiErrorDef;
|
|
1286
|
+
readonly INIT_FAILED: HaiErrorDef;
|
|
1287
|
+
readonly INIT_IN_PROGRESS: HaiErrorDef;
|
|
1288
|
+
readonly UNAUTHORIZED: HaiErrorDef;
|
|
1289
|
+
readonly FORBIDDEN: HaiErrorDef;
|
|
1290
|
+
readonly TOKEN_EXPIRED: HaiErrorDef;
|
|
1291
|
+
readonly TOKEN_INVALID: HaiErrorDef;
|
|
1292
|
+
readonly VALIDATION_ERROR: HaiErrorDef;
|
|
1293
|
+
readonly INVALID_REQUEST: HaiErrorDef;
|
|
1294
|
+
readonly PARAMETER_MISSING: HaiErrorDef;
|
|
1295
|
+
readonly NOT_FOUND: HaiErrorDef;
|
|
1296
|
+
readonly ALREADY_EXISTS: HaiErrorDef;
|
|
1297
|
+
readonly CONFLICT: HaiErrorDef;
|
|
1298
|
+
readonly API_ERROR: HaiErrorDef;
|
|
1299
|
+
readonly NETWORK_ERROR: HaiErrorDef;
|
|
1300
|
+
readonly TIMEOUT: HaiErrorDef;
|
|
1301
|
+
readonly SERVICE_UNAVAILABLE: HaiErrorDef;
|
|
1302
|
+
readonly INTERNAL_ERROR: HaiErrorDef;
|
|
1303
|
+
readonly DATABASE_ERROR: HaiErrorDef;
|
|
1304
|
+
readonly UNKNOWN_ERROR: HaiErrorDef;
|
|
1305
|
+
};
|
|
1306
|
+
declare const HaiConfigError: {
|
|
1307
|
+
readonly CONFIG_FILE_NOT_FOUND: HaiErrorDef;
|
|
1308
|
+
readonly CONFIG_PARSE_ERROR: HaiErrorDef;
|
|
1309
|
+
readonly CONFIG_VALIDATION_ERROR: HaiErrorDef;
|
|
1310
|
+
readonly CONFIG_ENV_VAR_MISSING: HaiErrorDef;
|
|
1311
|
+
readonly CONFIG_NOT_LOADED: HaiErrorDef;
|
|
1312
|
+
};
|
|
1313
|
+
/**
|
|
1314
|
+
* 分页参数输入(可选字段,未提供时使用默认值)。
|
|
1315
|
+
*
|
|
1316
|
+
* @example
|
|
1317
|
+
* ```ts
|
|
1318
|
+
* const input: PaginationOptionsInput = { page: 2, pageSize: 20 }
|
|
1319
|
+
* ```
|
|
1320
|
+
*/
|
|
1321
|
+
interface PaginationOptionsInput {
|
|
1322
|
+
/** 页码(从 1 开始,默认 1) */
|
|
1323
|
+
page?: number;
|
|
1324
|
+
/** 每页数量(默认由业务层决定) */
|
|
1325
|
+
pageSize?: number;
|
|
1326
|
+
}
|
|
1327
|
+
/**
|
|
1328
|
+
* 分页参数(必填,已确定具体值)。
|
|
1329
|
+
*
|
|
1330
|
+
* @example
|
|
1331
|
+
* ```ts
|
|
1332
|
+
* const options: PaginationOptions = { page: 1, pageSize: 20 }
|
|
1333
|
+
* ```
|
|
1334
|
+
*/
|
|
1335
|
+
interface PaginationOptions {
|
|
1336
|
+
/** 页码(从 1 开始) */
|
|
1337
|
+
page: number;
|
|
1338
|
+
/** 每页数量 */
|
|
1339
|
+
pageSize: number;
|
|
1340
|
+
}
|
|
1341
|
+
/**
|
|
1342
|
+
* 分页结果。
|
|
1343
|
+
*
|
|
1344
|
+
* @template T - 数据项类型
|
|
1345
|
+
*
|
|
1346
|
+
* @example
|
|
1347
|
+
* ```ts
|
|
1348
|
+
* const result: PaginatedResult<User> = {
|
|
1349
|
+
* items: [{ id: 1, name: 'Alice' }],
|
|
1350
|
+
* total: 100,
|
|
1351
|
+
* page: 1,
|
|
1352
|
+
* pageSize: 20,
|
|
1353
|
+
* }
|
|
1354
|
+
* ```
|
|
1355
|
+
*/
|
|
1356
|
+
interface PaginatedResult<T> {
|
|
1357
|
+
/** 当前页数据 */
|
|
1358
|
+
items: T[];
|
|
1359
|
+
/** 总数量 */
|
|
1360
|
+
total: number;
|
|
1361
|
+
/** 页码(从 1 开始) */
|
|
1362
|
+
page: number;
|
|
1363
|
+
/** 每页数量 */
|
|
1364
|
+
pageSize: number;
|
|
1365
|
+
}
|
|
1366
|
+
/**
|
|
1367
|
+
* 日志上下文。
|
|
1368
|
+
*
|
|
1369
|
+
* @example
|
|
1370
|
+
* ```ts
|
|
1371
|
+
* const context: LogContext = { requestId: 'req-1' }
|
|
1372
|
+
* ```
|
|
1373
|
+
*/
|
|
1374
|
+
interface LogContext {
|
|
1375
|
+
timestamp?: Date;
|
|
1376
|
+
level?: LogLevel;
|
|
1377
|
+
message?: string;
|
|
1378
|
+
[key: string]: unknown;
|
|
1379
|
+
}
|
|
1380
|
+
/**
|
|
1381
|
+
* 日志选项。
|
|
1382
|
+
*
|
|
1383
|
+
* @example
|
|
1384
|
+
* ```ts
|
|
1385
|
+
* const options: LoggerOptions = { name: 'api', level: 'debug' }
|
|
1386
|
+
* ```
|
|
1387
|
+
*/
|
|
1388
|
+
interface LoggerOptions {
|
|
1389
|
+
name?: string;
|
|
1390
|
+
level?: LogLevel;
|
|
1391
|
+
format?: LogFormat;
|
|
1392
|
+
context?: Record<string, unknown>;
|
|
1393
|
+
}
|
|
1394
|
+
/**
|
|
1395
|
+
* Logger 接口。
|
|
1396
|
+
* 统一的日志记录接口,具体实现由 Provider 提供。
|
|
1397
|
+
*
|
|
1398
|
+
* @example
|
|
1399
|
+
* ```ts
|
|
1400
|
+
* core.logger.info('ready', { requestId: 'req-1' })
|
|
1401
|
+
* ```
|
|
1402
|
+
*/
|
|
1403
|
+
interface Logger {
|
|
1404
|
+
trace: (message: string, context?: LogContext) => void;
|
|
1405
|
+
debug: (message: string, context?: LogContext) => void;
|
|
1406
|
+
info: (message: string, context?: LogContext) => void;
|
|
1407
|
+
warn: (message: string, context?: LogContext) => void;
|
|
1408
|
+
error: (message: string, context?: LogContext) => void;
|
|
1409
|
+
fatal: (message: string, context?: LogContext) => void;
|
|
1410
|
+
child: (context: Record<string, unknown>) => Logger;
|
|
1411
|
+
}
|
|
1412
|
+
/**
|
|
1413
|
+
* Core 公共 Logger — Logger 实例 + 管理方法。
|
|
1414
|
+
*
|
|
1415
|
+
* @example
|
|
1416
|
+
* ```ts
|
|
1417
|
+
* core.logger.info('ready')
|
|
1418
|
+
* core.logger.configure({ level: 'debug' })
|
|
1419
|
+
* core.logger.setLevel('warn')
|
|
1420
|
+
* const level = core.logger.getLevel()
|
|
1421
|
+
* const db = core.logger.create({ name: 'db' })
|
|
1422
|
+
* ```
|
|
1423
|
+
*/
|
|
1424
|
+
interface CoreLogger extends Logger {
|
|
1425
|
+
/** 创建新的 Logger 实例 */
|
|
1426
|
+
create: (options?: LoggerOptions) => Logger;
|
|
1427
|
+
/** 配置全局 Logger 选项(级别、格式、上下文等) */
|
|
1428
|
+
configure: (config: Partial<LoggingConfig>) => void;
|
|
1429
|
+
/** 设置全局日志级别 */
|
|
1430
|
+
setLevel: (level: LogLevel) => void;
|
|
1431
|
+
/** 获取当前全局日志级别 */
|
|
1432
|
+
getLevel: () => LogLevel;
|
|
1433
|
+
}
|
|
1434
|
+
/**
|
|
1435
|
+
* Logger 函数组合(平台实现依赖)。
|
|
1436
|
+
*
|
|
1437
|
+
* 由各平台(Node.js / Browser)提供具体实现,通过 `createCore()` 注入。
|
|
1438
|
+
*
|
|
1439
|
+
* @example
|
|
1440
|
+
* ```ts
|
|
1441
|
+
* const fns: LoggerFunctions = {
|
|
1442
|
+
* createLogger,
|
|
1443
|
+
* getLogger,
|
|
1444
|
+
* configureLogger,
|
|
1445
|
+
* setLogLevel,
|
|
1446
|
+
* getLogLevel,
|
|
1447
|
+
* }
|
|
1448
|
+
* ```
|
|
1449
|
+
*/
|
|
1450
|
+
interface LoggerFunctions {
|
|
1451
|
+
/** 创建新的 Logger 实例 */
|
|
1452
|
+
createLogger: (options?: LoggerOptions) => Logger;
|
|
1453
|
+
/** 获取默认或命名 Logger 实例(单例) */
|
|
1454
|
+
getLogger: (name?: string) => Logger;
|
|
1455
|
+
/** 配置全局 Logger 选项(级别、格式、上下文等) */
|
|
1456
|
+
configureLogger: (config: Partial<LoggingConfig>) => void;
|
|
1457
|
+
/** 设置全局日志级别 */
|
|
1458
|
+
setLogLevel: (level: LogLevel) => void;
|
|
1459
|
+
/** 获取当前全局日志级别 */
|
|
1460
|
+
getLogLevel: () => LogLevel;
|
|
1461
|
+
}
|
|
1462
|
+
/**
|
|
1463
|
+
* Core 配置选项。
|
|
1464
|
+
*
|
|
1465
|
+
* @example
|
|
1466
|
+
* ```ts
|
|
1467
|
+
* const options: CoreOptions = { configDir: './config', watchConfig: true }
|
|
1468
|
+
* ```
|
|
1469
|
+
*/
|
|
1470
|
+
interface CoreOptions {
|
|
1471
|
+
/** 日志配置 */
|
|
1472
|
+
logging?: Partial<LoggingConfig>;
|
|
1473
|
+
/**
|
|
1474
|
+
* 配置目录(约定优于配置模式)
|
|
1475
|
+
*
|
|
1476
|
+
* 指定后会自动扫描目录中的 yml/yaml 文件:
|
|
1477
|
+
* - `_core.yml` → 自动使用 CoreConfigSchema 校验
|
|
1478
|
+
* - `_xx.yml` → 加载为 'xx'(各模块自行调用 `config.validate` 校验)
|
|
1479
|
+
* - `app.yml` → 加载为 'app'(需使用方自行校验)
|
|
1480
|
+
*
|
|
1481
|
+
* @example
|
|
1482
|
+
* ```ts
|
|
1483
|
+
* core.init({ configDir: './config' })
|
|
1484
|
+
* ```
|
|
1485
|
+
*/
|
|
1486
|
+
configDir?: string;
|
|
1487
|
+
/** 是否启用配置文件监听(默认 false) */
|
|
1488
|
+
watchConfig?: boolean;
|
|
1489
|
+
}
|
|
1490
|
+
/**
|
|
1491
|
+
* 语言代码(ISO 639-1 + 地区代码)。
|
|
1492
|
+
*
|
|
1493
|
+
* @example 'zh-CN', 'en-US', 'ja-JP'
|
|
1494
|
+
*/
|
|
1495
|
+
type Locale = string;
|
|
1496
|
+
/**
|
|
1497
|
+
* 语言信息。
|
|
1498
|
+
*
|
|
1499
|
+
* @example
|
|
1500
|
+
* ```ts
|
|
1501
|
+
* const locale: LocaleInfo = { code: 'zh-CN', label: '简体中文' }
|
|
1502
|
+
* ```
|
|
1503
|
+
*/
|
|
1504
|
+
interface LocaleInfo {
|
|
1505
|
+
/** 语言代码(如 'zh-CN'、'en-US') */
|
|
1506
|
+
code: Locale;
|
|
1507
|
+
/** 显示名称(如 '简体中文'、'English') */
|
|
1508
|
+
label: string;
|
|
1509
|
+
/** 是否为从右到左书写的语言(如阿拉伯语),默认 false */
|
|
1510
|
+
rtl?: boolean;
|
|
1511
|
+
}
|
|
1512
|
+
/**
|
|
1513
|
+
* 插值参数类型。
|
|
1514
|
+
*
|
|
1515
|
+
* 用于 i18n 消息模板中的 `{key}` 占位符替换。
|
|
1516
|
+
*
|
|
1517
|
+
* @example
|
|
1518
|
+
* ```ts
|
|
1519
|
+
* const params: InterpolationParams = { name: 'Alice', count: 3 }
|
|
1520
|
+
* // 模板 'Hello, {name}! You have {count} items.'
|
|
1521
|
+
* ```
|
|
1522
|
+
*/
|
|
1523
|
+
type InterpolationParams = Record<string, string | number | boolean>;
|
|
1524
|
+
/**
|
|
1525
|
+
* 消息字典类型(单语言的 key-value 映射)。
|
|
1526
|
+
*
|
|
1527
|
+
* @example
|
|
1528
|
+
* ```ts
|
|
1529
|
+
* const dict: MessageDictionary = { hello: '你好', bye: '再见' }
|
|
1530
|
+
* ```
|
|
1531
|
+
*/
|
|
1532
|
+
type MessageDictionary = Record<string, string>;
|
|
1533
|
+
/**
|
|
1534
|
+
* 多语言消息集合。
|
|
1535
|
+
*
|
|
1536
|
+
* 以 locale 为键,每个 locale 下包含该语言的所有消息 key-value。
|
|
1537
|
+
*
|
|
1538
|
+
* @template K - 消息 key 的联合类型
|
|
1539
|
+
*
|
|
1540
|
+
* @example
|
|
1541
|
+
* ```ts
|
|
1542
|
+
* const messages: LocaleMessages<'hello' | 'bye'> = {
|
|
1543
|
+
* 'zh-CN': { hello: '你好', bye: '再见' },
|
|
1544
|
+
* 'en-US': { hello: 'Hello', bye: 'Bye' },
|
|
1545
|
+
* }
|
|
1546
|
+
* ```
|
|
1547
|
+
*/
|
|
1548
|
+
type LocaleMessages<K extends string = string> = Record<Locale, Record<K, string>>;
|
|
1549
|
+
/**
|
|
1550
|
+
* 消息获取选项。
|
|
1551
|
+
*
|
|
1552
|
+
* @example
|
|
1553
|
+
* ```ts
|
|
1554
|
+
* getMessage('hello', { locale: 'en-US', params: { name: 'World' } })
|
|
1555
|
+
* ```
|
|
1556
|
+
*/
|
|
1557
|
+
interface MessageOptions {
|
|
1558
|
+
/** 指定 locale(不传则使用全局 locale) */
|
|
1559
|
+
locale?: Locale;
|
|
1560
|
+
/** 插值参数 */
|
|
1561
|
+
params?: InterpolationParams;
|
|
1562
|
+
}
|
|
1563
|
+
/** Core 服务聚合接口(createCore 返回类型) */
|
|
1564
|
+
interface CoreFunctions {
|
|
1565
|
+
/** 默认 Logger(懒加载单例),同时提供日志管理方法 */
|
|
1566
|
+
readonly logger: CoreLogger;
|
|
1567
|
+
/** 国际化工具 */
|
|
1568
|
+
readonly i18n: I18nFn;
|
|
1569
|
+
/** ID 生成工具 */
|
|
1570
|
+
readonly id: IdFn;
|
|
1571
|
+
/** 类型检查工具 */
|
|
1572
|
+
readonly typeUtils: TypeUtilFn;
|
|
1573
|
+
/** 对象操作工具 */
|
|
1574
|
+
readonly object: ObjectFn;
|
|
1575
|
+
/** 字符串操作工具 */
|
|
1576
|
+
readonly string: StringFn;
|
|
1577
|
+
/** 数组操作工具 */
|
|
1578
|
+
readonly array: ArrayFn;
|
|
1579
|
+
/** 异步操作工具 */
|
|
1580
|
+
readonly async: AsyncFn;
|
|
1581
|
+
/** 时间操作工具 */
|
|
1582
|
+
readonly time: TimeFn;
|
|
1583
|
+
/** 错误工具 */
|
|
1584
|
+
readonly error: ErrorFn;
|
|
1585
|
+
/** 模块基础工具 */
|
|
1586
|
+
readonly module: ModuleFn;
|
|
1587
|
+
}
|
|
1588
|
+
|
|
1589
|
+
/**
|
|
1590
|
+
* @h-ai/core — 模块初始化工具
|
|
1591
|
+
*
|
|
1592
|
+
* 封装各模块共同的「未初始化」错误处理模式,消除跨模块冗余。
|
|
1593
|
+
* @module core-util-module
|
|
1594
|
+
*/
|
|
1595
|
+
|
|
1596
|
+
/**
|
|
1597
|
+
* 未初始化工具集返回类型。
|
|
1598
|
+
*
|
|
1599
|
+
* 提供错误创建、HaiResult 包装和 Proxy 代理等能力,
|
|
1600
|
+
* 用于模块未初始化时的安全回退。
|
|
1601
|
+
*
|
|
1602
|
+
* @template E - 模块错误类型(必须继承 HaiError)
|
|
1603
|
+
*/
|
|
1604
|
+
interface NotInitializedKit<E extends HaiError> {
|
|
1605
|
+
/** 创建未初始化错误对象 */
|
|
1606
|
+
error: () => E;
|
|
1607
|
+
/** 创建包含未初始化错误的失败 HaiResult */
|
|
1608
|
+
result: <T>() => HaiResult<T>;
|
|
1609
|
+
/**
|
|
1610
|
+
* 创建 Proxy 代理,拦截所有方法调用并返回未初始化错误。
|
|
1611
|
+
*
|
|
1612
|
+
* @param mode - 'async'(默认)所有方法返回 `Promise<HaiResult>`;'sync' 所有方法返回 `HaiResult`
|
|
1613
|
+
*/
|
|
1614
|
+
proxy: <T>(mode?: 'async' | 'sync') => T;
|
|
1615
|
+
}
|
|
1616
|
+
/** module 子工具类型 */
|
|
1617
|
+
/** overloaded function type for createNotInitializedKit */
|
|
1618
|
+
interface CreateNotInitializedKitFn {
|
|
1619
|
+
(codeOrDef: HaiErrorDef, messageFn: () => string): NotInitializedKit<HaiError>;
|
|
1620
|
+
<E extends HaiError>(codeOrDef: E['code'], messageFn: () => string): NotInitializedKit<E>;
|
|
1621
|
+
}
|
|
1622
|
+
interface ModuleFn {
|
|
1623
|
+
createNotInitializedKit: CreateNotInitializedKitFn;
|
|
1624
|
+
}
|
|
1625
|
+
|
|
1626
|
+
export { type ArrayFn as A, type LoggerFunctions as B, type CoreOptions as C, type LoggerOptions as D, type ErrorFn as E, type LoggingConfig as F, LoggingConfigSchema as G, type HaiError as H, type I18nFn as I, type MatchHandlers as J, type MessageDictionary as K, type Locale as L, type ModuleFn as M, type MessageOptions as N, type ObjectFn as O, type PaginatedResult as P, type PaginationOptions as Q, type PaginationOptionsInput as R, type StringFn as S, type TypeUtilFn as T, err as U, ok as V, type HaiResult as a, type CoreLogger as b, type IdFn as c, type AsyncFn as d, type TimeFn as e, type CoreConfig as f, CoreConfigSchema as g, type CoreFunctions as h, type Env as i, EnvSchema as j, type ErrorInfo as k, type ErrorInfoValue as l, HaiCommonError as m, HaiConfigError as n, type HaiErrorDef as o, type IdConfig as p, IdConfigSchema as q, type InterpolationParams as r, type LocaleInfo as s, type LocaleMessages as t, type LogContext as u, type LogFormat as v, LogFormatSchema as w, type LogLevel as x, LogLevelSchema as y, type Logger as z };
|