@h-ai/core 0.1.0-alpha9 → 1.0.0-beta.10

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.
@@ -0,0 +1,2885 @@
1
+ import { z, ZodType } from 'zod';
2
+
3
+ /**
4
+ * @h-ai/core — 访问条件与请求策略配置;Schema 可在构建工具中使用,不依赖 Node API。
5
+ * @module core-access-config
6
+ */
7
+
8
+ /**
9
+ * 可信代理列表;auto 仅在受管的私有容器入口中使用本容器网段,普通宿主忽略转发头。
10
+ * @example
11
+ * ```ts
12
+ * import { TrustedProxiesSchema } from '@h-ai/core'
13
+ * const proxies = TrustedProxiesSchema.parse(['192.0.2.10'])
14
+ * ```
15
+ */
16
+ declare const TrustedProxiesSchema: z.ZodUnion<readonly [z.ZodLiteral<"auto">, z.ZodArray<z.ZodUnion<readonly [z.ZodIPv4, z.ZodIPv6, z.ZodCIDRv4, z.ZodCIDRv6]>>]>;
17
+ /**
18
+ * 可复用的可信 IP 与时间窗口条件;空列表不限制对应维度。
19
+ * @example
20
+ * ```ts
21
+ * import { AccessConditionSchema } from '@h-ai/core'
22
+ * const condition = AccessConditionSchema.parse({ allowIps: ['192.0.2.0/24'], timezone: 'Asia/Shanghai' })
23
+ * ```
24
+ */
25
+ declare const AccessConditionSchema: z.ZodObject<{
26
+ allowIps: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodIPv4, z.ZodIPv6, z.ZodCIDRv4, z.ZodCIDRv6]>>>;
27
+ denyIps: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodIPv4, z.ZodIPv6, z.ZodCIDRv4, z.ZodCIDRv6]>>>;
28
+ timezone: z.ZodDefault<z.ZodString>;
29
+ windows: z.ZodDefault<z.ZodArray<z.ZodObject<{
30
+ days: z.ZodArray<z.ZodNumber>;
31
+ start: z.ZodString;
32
+ end: z.ZodString;
33
+ }, z.core.$strict>>>;
34
+ }, z.core.$strict>;
35
+ /**
36
+ * 每次请求的访问策略:全局条件与所有命中规则必须同时满足;未命中规则不受该规则限制。
37
+ * @example
38
+ * ```ts
39
+ * import { RequestAccessPolicySchema } from '@h-ai/core'
40
+ * const policy = RequestAccessPolicySchema.parse({ rules: [{ id: 'external', paths: ['/api/v1/external/**'], allowIps: ['192.0.2.0/24'] }] })
41
+ * ```
42
+ */
43
+ declare const RequestAccessPolicySchema: z.ZodObject<{
44
+ global: z.ZodOptional<z.ZodObject<{
45
+ allowIps: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodIPv4, z.ZodIPv6, z.ZodCIDRv4, z.ZodCIDRv6]>>>;
46
+ denyIps: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodIPv4, z.ZodIPv6, z.ZodCIDRv4, z.ZodCIDRv6]>>>;
47
+ timezone: z.ZodDefault<z.ZodString>;
48
+ windows: z.ZodDefault<z.ZodArray<z.ZodObject<{
49
+ days: z.ZodArray<z.ZodNumber>;
50
+ start: z.ZodString;
51
+ end: z.ZodString;
52
+ }, z.core.$strict>>>;
53
+ }, z.core.$strict>>;
54
+ rules: z.ZodDefault<z.ZodArray<z.ZodObject<{
55
+ allowIps: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodIPv4, z.ZodIPv6, z.ZodCIDRv4, z.ZodCIDRv6]>>>;
56
+ denyIps: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodIPv4, z.ZodIPv6, z.ZodCIDRv4, z.ZodCIDRv6]>>>;
57
+ timezone: z.ZodDefault<z.ZodString>;
58
+ windows: z.ZodDefault<z.ZodArray<z.ZodObject<{
59
+ days: z.ZodArray<z.ZodNumber>;
60
+ start: z.ZodString;
61
+ end: z.ZodString;
62
+ }, z.core.$strict>>>;
63
+ id: z.ZodString;
64
+ paths: z.ZodArray<z.ZodString>;
65
+ methods: z.ZodDefault<z.ZodArray<z.ZodEnum<{
66
+ GET: "GET";
67
+ HEAD: "HEAD";
68
+ POST: "POST";
69
+ PUT: "PUT";
70
+ PATCH: "PATCH";
71
+ DELETE: "DELETE";
72
+ OPTIONS: "OPTIONS";
73
+ CONNECT: "CONNECT";
74
+ TRACE: "TRACE";
75
+ }>>>;
76
+ encryption: z.ZodOptional<z.ZodEnum<{
77
+ required: "required";
78
+ disabled: "disabled";
79
+ }>>;
80
+ }, z.core.$strict>>>;
81
+ }, z.core.$strict>;
82
+ /**
83
+ * 关闭策略、内联策略或单个独立 YAML 文件;文件与内联规则不能混合。
84
+ * @example
85
+ * ```ts
86
+ * import { RequestAccessConfigSchema } from '@h-ai/core'
87
+ * const config = RequestAccessConfigSchema.parse({ file: './config/security/request-access.yml' })
88
+ * ```
89
+ */
90
+ declare const RequestAccessConfigSchema: z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
91
+ file: z.ZodString;
92
+ }, z.core.$strict>, z.ZodObject<{
93
+ global: z.ZodOptional<z.ZodObject<{
94
+ allowIps: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodIPv4, z.ZodIPv6, z.ZodCIDRv4, z.ZodCIDRv6]>>>;
95
+ denyIps: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodIPv4, z.ZodIPv6, z.ZodCIDRv4, z.ZodCIDRv6]>>>;
96
+ timezone: z.ZodDefault<z.ZodString>;
97
+ windows: z.ZodDefault<z.ZodArray<z.ZodObject<{
98
+ days: z.ZodArray<z.ZodNumber>;
99
+ start: z.ZodString;
100
+ end: z.ZodString;
101
+ }, z.core.$strict>>>;
102
+ }, z.core.$strict>>;
103
+ rules: z.ZodDefault<z.ZodArray<z.ZodObject<{
104
+ allowIps: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodIPv4, z.ZodIPv6, z.ZodCIDRv4, z.ZodCIDRv6]>>>;
105
+ denyIps: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodIPv4, z.ZodIPv6, z.ZodCIDRv4, z.ZodCIDRv6]>>>;
106
+ timezone: z.ZodDefault<z.ZodString>;
107
+ windows: z.ZodDefault<z.ZodArray<z.ZodObject<{
108
+ days: z.ZodArray<z.ZodNumber>;
109
+ start: z.ZodString;
110
+ end: z.ZodString;
111
+ }, z.core.$strict>>>;
112
+ id: z.ZodString;
113
+ paths: z.ZodArray<z.ZodString>;
114
+ methods: z.ZodDefault<z.ZodArray<z.ZodEnum<{
115
+ GET: "GET";
116
+ HEAD: "HEAD";
117
+ POST: "POST";
118
+ PUT: "PUT";
119
+ PATCH: "PATCH";
120
+ DELETE: "DELETE";
121
+ OPTIONS: "OPTIONS";
122
+ CONNECT: "CONNECT";
123
+ TRACE: "TRACE";
124
+ }>>>;
125
+ encryption: z.ZodOptional<z.ZodEnum<{
126
+ required: "required";
127
+ disabled: "disabled";
128
+ }>>;
129
+ }, z.core.$strict>>>;
130
+ }, z.core.$strict>]>;
131
+
132
+ /**
133
+ * @h-ai/core — 核心配置 Schema
134
+ *
135
+ * 核心模块的配置 Schema 定义(使用 Zod 校验)
136
+ * @module core-config
137
+ */
138
+
139
+ /**
140
+ * 环境类型 Schema。
141
+ * @example
142
+ * ```ts
143
+ * import { EnvSchema } from '@h-ai/core'
144
+ * const config = EnvSchema.parse('production')
145
+ * ```
146
+ */
147
+ declare const EnvSchema: z.ZodEnum<{
148
+ development: "development";
149
+ production: "production";
150
+ test: "test";
151
+ staging: "staging";
152
+ }>;
153
+ /**
154
+ * 日志级别 Schema。
155
+ * @example
156
+ * ```ts
157
+ * import { LogLevelSchema } from '@h-ai/core'
158
+ * const config = LogLevelSchema.parse('info')
159
+ * ```
160
+ */
161
+ declare const LogLevelSchema: z.ZodEnum<{
162
+ error: "error";
163
+ trace: "trace";
164
+ debug: "debug";
165
+ info: "info";
166
+ warn: "warn";
167
+ fatal: "fatal";
168
+ }>;
169
+ /**
170
+ * 日志格式 Schema。
171
+ * @example
172
+ * ```ts
173
+ * import { LogFormatSchema } from '@h-ai/core'
174
+ * const config = LogFormatSchema.parse('json')
175
+ * ```
176
+ */
177
+ declare const LogFormatSchema: z.ZodEnum<{
178
+ json: "json";
179
+ pretty: "pretty";
180
+ }>;
181
+ /**
182
+ * 日志配置 Schema。
183
+ * @example
184
+ * ```ts
185
+ * import { LoggingConfigSchema } from '@h-ai/core'
186
+ * const config = LoggingConfigSchema.parse({ level: 'warn', format: 'json', redact: ['password'] })
187
+ * ```
188
+ */
189
+ declare const LoggingConfigSchema: z.ZodObject<{
190
+ level: z.ZodDefault<z.ZodEnum<{
191
+ error: "error";
192
+ trace: "trace";
193
+ debug: "debug";
194
+ info: "info";
195
+ warn: "warn";
196
+ fatal: "fatal";
197
+ }>>;
198
+ format: z.ZodDefault<z.ZodEnum<{
199
+ json: "json";
200
+ pretty: "pretty";
201
+ }>>;
202
+ context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
203
+ redact: z.ZodDefault<z.ZodArray<z.ZodString>>;
204
+ }, z.core.$strip>;
205
+ /**
206
+ * Core 配置 Schema。
207
+ *
208
+ * 描述应用的基础元数据和日志配置,通常通过 `_core.yml` 加载。
209
+ * 未声明的字段拒绝加载;业务配置放独立 app.yml 并使用应用 Schema 校验。
210
+ * ID 长度/前缀由每次 core.id 调用参数决定,不存在全局 ID 配置。
211
+ * @example
212
+ * ```ts
213
+ * import { CoreConfigSchema } from '@h-ai/core'
214
+ * const config = CoreConfigSchema.parse({ name: 'orders', env: 'production', logging: { level: 'info' } })
215
+ * ```
216
+ */
217
+ declare const CoreConfigSchema: z.ZodObject<{
218
+ name: z.ZodDefault<z.ZodString>;
219
+ version: z.ZodDefault<z.ZodString>;
220
+ env: z.ZodDefault<z.ZodEnum<{
221
+ development: "development";
222
+ production: "production";
223
+ test: "test";
224
+ staging: "staging";
225
+ }>>;
226
+ logging: z.ZodOptional<z.ZodObject<{
227
+ level: z.ZodDefault<z.ZodEnum<{
228
+ error: "error";
229
+ trace: "trace";
230
+ debug: "debug";
231
+ info: "info";
232
+ warn: "warn";
233
+ fatal: "fatal";
234
+ }>>;
235
+ format: z.ZodDefault<z.ZodEnum<{
236
+ json: "json";
237
+ pretty: "pretty";
238
+ }>>;
239
+ context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
240
+ redact: z.ZodDefault<z.ZodArray<z.ZodString>>;
241
+ }, z.core.$strip>>;
242
+ defaultLocale: z.ZodDefault<z.ZodString>;
243
+ }, z.core.$strict>;
244
+
245
+ /**
246
+ * 校验消息 key 集合(locale 无关的标识符)。
247
+ *
248
+ * 调用方负责把每个 key 映射到自己模块的 i18n 字典(例如 kit 的
249
+ * `kit_validationStringMin`、serv 的 `serv_validationStringMin`)。
250
+ *
251
+ * @example
252
+ * ```ts
253
+ * const key: ZodValidationMessageKey = 'validationRequired'
254
+ * ```
255
+ */
256
+ /**
257
+ * 创建按固定前缀派生消息 key 的 `ZodMessageGetter`。
258
+ *
259
+ * 适用于模块消息键遵循 `{prefix}_{ZodValidationMessageKey}` 命名约定的场景,
260
+ * 例如 `serv_validationRequired`、`kit_validationEmail`。
261
+ *
262
+ * @param prefix - 模块消息前缀,如 `serv`、`kit`
263
+ * @param getMessage - 实际消息获取函数,接收带前缀的消息 key
264
+ * @returns 可注入给 `core.zodValidation.*` 的 `ZodMessageGetter`
265
+ *
266
+ * @example
267
+ * ```ts
268
+ * const getMessage = createPrefixedZodMessageGetter<string>(
269
+ * 'serv',
270
+ * (messageKey, params) => `${messageKey}:${params?.min ?? ''}`,
271
+ * )
272
+ *
273
+ * getMessage('validationStringMin', { min: 3 })
274
+ * // 'serv_validationStringMin:3'
275
+ * ```
276
+ */
277
+ declare function createPrefixedZodMessageGetter<TMessageKey extends string>(prefix: string, getMessage: (messageKey: TMessageKey, params?: Record<string, string | number>) => string): ZodMessageGetter;
278
+ /**
279
+ * 一步把 Zod SafeParseError / ZodError 转为扁平 `ValidationFormError[]`。
280
+ *
281
+ * @param error - Zod `SafeParseError`、`ZodError` 或兼容的错误对象
282
+ * @param getMessage - 调用方注入的消息获取器
283
+ * @returns 扁平化后的表单错误列表
284
+ *
285
+ * @example
286
+ * ```ts
287
+ * const errors = mapZodErrorToFormErrors(
288
+ * {
289
+ * issues: [
290
+ * { path: ['email'], code: 'invalid_format', format: 'email', message: 'Invalid email address' },
291
+ * ],
292
+ * },
293
+ * key => key === 'validationEmail' ? '请输入合法邮箱地址' : '输入不合法',
294
+ * )
295
+ * ```
296
+ */
297
+ declare function mapZodErrorToFormErrors(error: unknown, getMessage: ZodMessageGetter): ValidationFormError[];
298
+ /**
299
+ * Zod 校验 i18n 工具集合(通过 `core.zodValidation` 暴露)。
300
+ *
301
+ * 按最小知识原则,仅暴露调用方真正需要的两个入口:
302
+ * 1. `createPrefixedZodMessageGetter()`:把模块前缀与消息获取器适配起来
303
+ * 2. `mapZodErrorToFormErrors()`:一步完成 ZodError → 本地化扁平错误列表
304
+ * @example
305
+ * ```ts
306
+ * import { core } from '@h-ai/core'
307
+ * const tools = core.zodValidation
308
+ * tools.mapZodErrorToFormErrors({ issues: [{ path: ['name'], code: 'invalid_type', expected: 'string', message: 'Invalid input' }] }, key => key)
309
+ * ```
310
+ */
311
+ declare const zodValidation: {
312
+ createPrefixedZodMessageGetter: typeof createPrefixedZodMessageGetter;
313
+ mapZodErrorToFormErrors: typeof mapZodErrorToFormErrors;
314
+ };
315
+
316
+ /**
317
+ * @h-ai/core — 配置管理(浏览器占位实现)
318
+ *
319
+ * 浏览器环境没有文件系统,不能加载 / 监听 YAML 配置文件。
320
+ * 该实现保持 `core.config` API 形态与 Node.js 一致,但所有文件相关操作
321
+ * 都返回明确的 SERVICE_UNAVAILABLE,避免运行时出现 `core.config` 为 undefined。
322
+ * @module core-function-config.browser
323
+ */
324
+
325
+ /**
326
+ * 浏览器端 config 占位对象,API 与 Node.js config 保持一致。
327
+ * @example 模块内部上下文
328
+ * ```ts
329
+ * const result = config.load('app', '/srv/app/config/app.yml')
330
+ * if (!result.success) result.error.message
331
+ * ```
332
+ */
333
+ declare const config$1: {
334
+ loadEnvFiles(_options: {
335
+ mode: string;
336
+ envDir?: string;
337
+ }): HaiResult<Record<string, string>>;
338
+ load<T>(_name: string, _filePath: string, _schema?: ZodType<T>): HaiResult<T>;
339
+ validate<T>(_name: string, _schema: ZodType<T>): HaiResult<T>;
340
+ get<T>(_name: string): T | undefined;
341
+ getOrThrow<T>(_name: string): T;
342
+ reload(_name: string): HaiResult<unknown>;
343
+ has(_name: string): boolean;
344
+ clear(_name?: string): void;
345
+ keys(): string[];
346
+ watch<T = unknown>(_name: string, callback: WatchCallback<T>): () => void;
347
+ unwatch(_name?: string): void;
348
+ isWatching(_name: string): boolean;
349
+ };
350
+
351
+ /** 通用环境配置:来源合并、结构覆盖与无损 dotenv 编解码,不依赖业务模块。 */
352
+
353
+ /**
354
+ * 单个环境来源中的字面变量,undefined 表示未设置。
355
+ * @example 模块内部上下文
356
+ * ```ts
357
+ * const values: Environment = { HAI_APP_NAME: 'Example' }
358
+ * ```
359
+ */
360
+ type Environment = Record<string, string | undefined>;
361
+ /**
362
+ * 从低到高合并来源;高来源父项删除旧细项,同来源始终先父后子。
363
+ * @example 模块内部上下文
364
+ * ```ts
365
+ * const values = mergeEnv([{ HAI_APP_NAME: 'base' }, { HAI_APP_NAME: 'test' }])
366
+ * ```
367
+ */
368
+ declare function mergeEnv(layers: readonly Environment[]): Record<string, string>;
369
+ /**
370
+ * dotenv 使用 Node 字面规则;补齐生成器双引号的 JSON 转义,拒绝同文件重复键。
371
+ * @example 模块内部上下文
372
+ * ```ts
373
+ * const values = parseEnvironment('HAI_APP_NAME=Example\n')
374
+ * ```
375
+ */
376
+ declare function parseEnvironment(text: string): Record<string, string>;
377
+ /**
378
+ * 所有值均按字面量编码;排序让模块 JSON 位于其细项之前。
379
+ * @example 模块内部上下文
380
+ * ```ts
381
+ * const text = stringifyEnv({ HAI_APP_NAME: 'Example' })
382
+ * ```
383
+ */
384
+ declare function stringifyEnv(values: Record<string, string>, options?: {
385
+ target?: 'node' | 'compose';
386
+ }): string;
387
+ /**
388
+ * 在给定结构上解析环境变量;父对象提供基础值,具体路径继续覆盖。
389
+ * @example 模块内部上下文
390
+ * ```ts
391
+ * const result = resolveEnvironment({ name: 'app', value: { name: 'Example' }, environment: { HAI_APP_NAME: 'Test' } })
392
+ * ```
393
+ */
394
+ declare function resolveEnvironment(options: {
395
+ name: string;
396
+ value: unknown;
397
+ environment?: Environment;
398
+ schema?: ZodType;
399
+ shape?: Readonly<Record<string, unknown>>;
400
+ missing?: 'error' | 'empty';
401
+ }, literal?: boolean): HaiResult<unknown>;
402
+ /**
403
+ * 默认展开对象,数组与动态键字典保留 JSON;不做模块名称判断。
404
+ * @example 模块内部上下文
405
+ * ```ts
406
+ * const values = toEnv({ prefix: 'HAI_APP', value: { name: 'Example', tags: ['demo'] } })
407
+ * ```
408
+ */
409
+ declare function toEnv(options: {
410
+ prefix: string;
411
+ value: unknown;
412
+ schema?: ZodType;
413
+ shape?: Readonly<Record<string, unknown>>;
414
+ }): Record<string, string>;
415
+
416
+ /**
417
+ * 配置管理对象。
418
+ * @example 模块内部上下文
419
+ * ```ts
420
+ * const result = config.load('app', '/srv/app/config/app.yml')
421
+ * if (!result.success) result.error.message
422
+ * ```
423
+ */
424
+ declare const config: {
425
+ /**
426
+ * 合并从低到高的环境来源;高来源父项替换旧节点,同来源细项覆盖父 JSON。
427
+ * @param layers - 按优先级排列的字面变量。
428
+ * @returns 合并后的变量,可能含秘密。
429
+ * @example
430
+ * ```ts
431
+ * import { core } from '@h-ai/core'
432
+ * const value = core.config.mergeEnv([{ HAI_APP_NAME: 'base' }, { HAI_APP_NAME: 'test' }])
433
+ * ```
434
+ */
435
+ mergeEnv: typeof mergeEnv;
436
+ /**
437
+ * 解析 dotenv 字面文本,拒绝重复键,不执行 shell 或变量展开。
438
+ * @param text - dotenv 文本,可能包含秘密。
439
+ * @returns 字面变量;重复键抛出不含变量值的错误。
440
+ * @example
441
+ * ```ts
442
+ * import { core } from '@h-ai/core'
443
+ * const value = core.config.parseEnv('HAI_APP_NAME=Example\n')
444
+ * ```
445
+ */
446
+ parseEnv: typeof parseEnvironment;
447
+ /**
448
+ * 无损编码 dotenv,父变量排在细项前;含秘密时只能写入受保护文件。
449
+ * @param values - 字面变量,不进行脱敏。
450
+ * @param options - 输出语法目标,默认 Node dotenv。
451
+ * @param options.target - Compose 目标同时处理其美元符号插值规则。
452
+ * @returns dotenv 文本;非法变量名抛错。
453
+ * @example
454
+ * ```ts
455
+ * import { core } from '@h-ai/core'
456
+ * const value = core.config.stringifyEnv({ HAI_APP_NAME: 'Example' })
457
+ * ```
458
+ */
459
+ stringifyEnv: typeof stringifyEnv;
460
+ /**
461
+ * 按已有结构或 Schema 解析父 JSON 和细项,不修改缓存或进程环境。
462
+ * @param options - 配置名、原始结构、变量、可选 Schema 和缺失插值规则。
463
+ * @returns 解析结果;调用方仍须执行最终 Schema 校验。
464
+ * @example
465
+ * ```ts
466
+ * import { core } from '@h-ai/core'
467
+ * const value = core.config.resolve({ name: 'app', value: { name: 'Example' }, environment: { HAI_APP_NAME: 'Test' } })
468
+ * ```
469
+ */
470
+ resolve: (options: Parameters<typeof resolveEnvironment>[0]) => HaiResult<unknown>;
471
+ /**
472
+ * 默认将对象展开为细项;数组、动态字典和空对象保留 JSON。
473
+ * @param options - 完整变量前缀、配置值和可选 Schema。
474
+ * @returns 字面环境变量,不脱敏;非法名称抛错。
475
+ * @example
476
+ * ```ts
477
+ * import { core } from '@h-ai/core'
478
+ * const value = core.config.toEnv({ prefix: 'HAI_APP', value: { name: 'Example', tags: ['demo'] } })
479
+ * ```
480
+ */
481
+ toEnv: typeof toEnv;
482
+ /**
483
+ * 读取 dotenv 文件并按统一顺序合并,不修改进程环境。
484
+ *
485
+ * 优先级:已有进程环境 > .env.<mode>.local > .env.local > .env.<mode> > .env。
486
+ * development/production 分别映射到 dev/prod;不存在的文件跳过。
487
+ * 返回值可能包含私有配置,仅在 Node 启动/构建边界注入,不下发浏览器。
488
+ * @param options - 文件所在目录及环境模式
489
+ * @param options.mode - dev/test/prod 或 Vite 的 development/production
490
+ * @param options.envDir - dotenv 所在目录,默认进程工作目录
491
+ * @returns 已合并的变量;非法模式或读取失败返回配置错误,不包含文件内容
492
+ * @example
493
+ * ```ts
494
+ * const env = core.config.loadEnvFiles({ mode: 'dev', envDir: '.' })
495
+ * if (!env.success) throw new Error(env.error.message)
496
+ * Object.assign(process.env, env.data)
497
+ * core.init({ configDir: './config' })
498
+ * ```
499
+ */
500
+ loadEnvFiles(options: {
501
+ mode: string;
502
+ envDir?: string;
503
+ }): HaiResult<Record<string, string>>;
504
+ /**
505
+ * 加载配置到缓存。
506
+ *
507
+ * 加载 YAML 文件并可选地用 Zod Schema 校验,成功后写入缓存。
508
+ *
509
+ * @param name - 配置名称(缓存 key)
510
+ * @param filePath - YAML 文件路径
511
+ * @param schema - 可选 Zod Schema(不传则跳过校验)
512
+ * @returns 成功时返回解析后的配置数据;失败时返回 HaiError
513
+ *
514
+ * @example
515
+ * ```ts
516
+ * const result = config.load('core', './config/_core.yml', CoreConfigSchema)
517
+ * if (result.success) {
518
+ * // result.data 为校验后的配置
519
+ * }
520
+ * ```
521
+ */
522
+ load<T>(name: string, filePath: string, schema?: ZodType<T>): HaiResult<T>;
523
+ /**
524
+ * 验证已加载的配置数据。
525
+ *
526
+ * 对缓存中的配置数据重新用 Schema 校验,校验通过后更新缓存。
527
+ *
528
+ * @param name - 配置名称
529
+ * @param schema - Zod 验证模式
530
+ * @returns 校验结果;未加载时返回 NOT_LOADED,格式错误返回 VALIDATION_ERROR
531
+ *
532
+ * @example
533
+ * ```ts
534
+ * const result = config.validate('app', AppSchema)
535
+ * if (!result.success) {
536
+ * // result.error.code 可能为 NOT_LOADED 或 VALIDATION_ERROR
537
+ * }
538
+ * ```
539
+ */
540
+ validate<T>(name: string, schema: ZodType<T>): HaiResult<T>;
541
+ /**
542
+ * 获取已加载的配置。
543
+ *
544
+ * @param name - 配置名称
545
+ * @returns 配置数据;未加载时返回 undefined
546
+ *
547
+ * @example
548
+ * ```ts
549
+ * const cfg = config.get<CoreConfig>('core')
550
+ * if (cfg) {
551
+ * // 使用 cfg
552
+ * }
553
+ * ```
554
+ */
555
+ get<T>(name: string): T | undefined;
556
+ /**
557
+ * 获取配置,不存在时抛出错误。
558
+ *
559
+ * @param name - 配置名称
560
+ * @returns 配置数据
561
+ * @throws 配置未加载时抛出 Error
562
+ *
563
+ * @example
564
+ * ```ts
565
+ * try {
566
+ * const cfg = config.getOrThrow<CoreConfig>('core')
567
+ * } catch (e) {
568
+ * // 配置未加载
569
+ * }
570
+ * ```
571
+ */
572
+ getOrThrow<T>(name: string): T;
573
+ /**
574
+ * 重新加载配置。
575
+ *
576
+ * 从磁盘重新读取配置文件并更新缓存,同时通知所有 watch 回调。
577
+ *
578
+ * @param name - 配置名称
579
+ * @returns 重载结果;未加载时返回 NOT_LOADED
580
+ *
581
+ * @example
582
+ * ```ts
583
+ * const result = config.reload('app')
584
+ * ```
585
+ */
586
+ reload(name: string): HaiResult<unknown>;
587
+ /**
588
+ * 检查配置是否已加载。
589
+ *
590
+ * @param name - 配置名称
591
+ * @returns 是否已加载到缓存
592
+ *
593
+ * @example
594
+ * ```ts
595
+ * if (config.has('db')) {
596
+ * const dbCfg = config.get('db')
597
+ * }
598
+ * ```
599
+ */
600
+ has(name: string): boolean;
601
+ /**
602
+ * 清除配置缓存(同时停止对应监听)。
603
+ *
604
+ * @param name - 配置名称;不传则清除全部
605
+ *
606
+ * @example
607
+ * ```ts
608
+ * config.clear('app') // 清除单个
609
+ * config.clear() // 清除全部
610
+ * ```
611
+ */
612
+ clear(name?: string): void;
613
+ /**
614
+ * 获取所有已加载的配置名称。
615
+ *
616
+ * @returns 配置名称数组
617
+ *
618
+ * @example
619
+ * ```ts
620
+ * const names = config.keys() // ['core', 'db', 'app']
621
+ * ```
622
+ */
623
+ keys(): string[];
624
+ /**
625
+ * 监听配置文件变更并自动重载。
626
+ *
627
+ * 普通写入、原子替换及删除重建均触发重载;失败保留最近成功的缓存并通知错误。
628
+ * 配置未加载时立即回调 NOT_LOADED 错误。
629
+ *
630
+ * @param name - 配置名称
631
+ * @param callback - 配置变更回调,接收新配置或错误
632
+ * @returns 取消监听函数
633
+ *
634
+ * @example
635
+ * ```ts
636
+ * const unwatch = config.watch('app', (cfg, error) => {
637
+ * if (error) { core.logger.error('reload failed', { error }); return }
638
+ * core.logger.info('config updated', { cfg })
639
+ * })
640
+ * // 取消监听
641
+ * unwatch()
642
+ * ```
643
+ */
644
+ watch<T = unknown>(name: string, callback: WatchCallback<T>): () => void;
645
+ /**
646
+ * 停止配置文件监听。
647
+ *
648
+ * @param name - 配置名称;不传则停止所有监听
649
+ *
650
+ * @example
651
+ * ```ts
652
+ * config.unwatch('app') // 停止单个
653
+ * config.unwatch() // 停止全部
654
+ * ```
655
+ */
656
+ unwatch(name?: string): void;
657
+ /**
658
+ * 检查是否正在监听某个配置。
659
+ *
660
+ * @param name - 配置名称
661
+ * @returns 是否有活跃的 watcher
662
+ *
663
+ * @example
664
+ * ```ts
665
+ * if (config.isWatching('app')) {
666
+ * config.unwatch('app')
667
+ * }
668
+ * ```
669
+ */
670
+ isWatching(name: string): boolean;
671
+ };
672
+
673
+ /**
674
+ * @h-ai/core — ID 生成器
675
+ *
676
+ * 基于 nanoid 的 ID 生成工具。
677
+ * @module core-function-id
678
+ */
679
+ /**
680
+ * ID 生成工具对象。
681
+ * @example
682
+ * ```ts
683
+ * import { core } from '@h-ai/core'
684
+ * const tools = core.id
685
+ * tools.withPrefix('order_')
686
+ * ```
687
+ */
688
+ declare const id: {
689
+ /**
690
+ * 生成标准 nanoid(默认 21 字符)。
691
+ *
692
+ * @param length - ID 长度
693
+ * @returns nanoid 字符串
694
+ *
695
+ * @example
696
+ * ```ts
697
+ * const id = core.id.generate(16)
698
+ * ```
699
+ */
700
+ generate(length?: number): string;
701
+ /**
702
+ * 生成短 ID(10 字符)。
703
+ *
704
+ * @example
705
+ * ```ts
706
+ * const shortId = core.id.short()
707
+ * ```
708
+ */
709
+ short(): string;
710
+ /**
711
+ * 生成带前缀的 ID。
712
+ *
713
+ * @param prefix - 前缀
714
+ * @param length - ID 长度
715
+ *
716
+ * @example
717
+ * ```ts
718
+ * const userId = core.id.withPrefix('user_')
719
+ * ```
720
+ */
721
+ withPrefix(prefix: string, length?: number): string;
722
+ /**
723
+ * 生成 Trace ID。
724
+ *
725
+ * @example
726
+ * ```ts
727
+ * const traceId = core.id.trace()
728
+ * ```
729
+ */
730
+ trace(): string;
731
+ /**
732
+ * 生成 Request ID。
733
+ *
734
+ * @example
735
+ * ```ts
736
+ * const requestId = core.id.request()
737
+ * ```
738
+ */
739
+ request(): string;
740
+ /**
741
+ * 生成 UUID v4。
742
+ *
743
+ * @example
744
+ * ```ts
745
+ * const uuid = core.id.uuid()
746
+ * ```
747
+ */
748
+ uuid(): string;
749
+ /**
750
+ * 验证是否为有效的 UUID v4。
751
+ *
752
+ * @example
753
+ * ```ts
754
+ * core.id.isValidUUID('f47ac10b-58cc-4372-a567-0e02b2c3d479')
755
+ * ```
756
+ */
757
+ isValidUUID(uuid: string): boolean;
758
+ /**
759
+ * 验证是否为有效的 nanoid。
760
+ *
761
+ * @param str - 待验证字符串
762
+ * @param length - 期望长度
763
+ *
764
+ * @example
765
+ * ```ts
766
+ * core.id.isValidNanoId('abc', 3)
767
+ * ```
768
+ */
769
+ isValidNanoId(str: string, length?: number): boolean;
770
+ };
771
+
772
+ /**
773
+ * @h-ai/core — i18n 国际化工具
774
+ *
775
+ * 国际化核心实现,为 JSON 消息字典提供通用类型支持。
776
+ * @module core-i18n-utils
777
+ */
778
+
779
+ declare function getGlobalLocale(): Locale;
780
+ declare function setGlobalLocale(locale: Locale): void;
781
+ /**
782
+ * 在独立的 Node 请求语言上下文中运行操作,异步子任务继承当前语言。
783
+ *
784
+ * 显式 MessageOptions.locale 优先于请求语言,请求结束不会改变进程启动默认值。
785
+ *
786
+ * @param locale - 当前请求的语言
787
+ * @param operation - 请求处理或 SSR 操作;保留原同步值或 Promise 返回类型
788
+ * @returns operation 的原始返回值
789
+ * @throws 浏览器入口没有 Node 请求上下文时抛出错误;浏览器使用 setGlobalLocale。
790
+ * @example
791
+ * ```ts
792
+ * const response = await core.i18n.runWithLocale('en-US', async () => {
793
+ * await loadData()
794
+ * return renderPage()
795
+ * })
796
+ * ```
797
+ */
798
+ declare function runWithLocale<T>(locale: Locale, operation: () => T): T;
799
+ /**
800
+ * 创建消息获取函数。
801
+ *
802
+ * 各模块通过此函数创建消息获取器,依次读取显式 locale、Node 请求语言和应用默认语言。
803
+ * 若指定的 locale 不支持,回退到默认语言;key 不存在时返回 key 本身。
804
+ *
805
+ * @param messages - 多语言消息对象
806
+ * @returns 消息获取函数
807
+ *
808
+ * @example
809
+ * ```ts
810
+ * const getMessage = createMessageGetter({
811
+ * 'zh-CN': { hello: '你好' },
812
+ * 'en-US': { hello: 'Hello' },
813
+ * })
814
+ * getMessage('hello') // '你好'
815
+ * getMessage('hello', { locale: 'en-US' }) // 'Hello'
816
+ * getMessage('msg', { params: { name: 'World' } }) // 插值
817
+ * ```
818
+ */
819
+ declare function createMessageGetter<K extends string>(messages: LocaleMessages<K>): (key: K, options?: MessageOptions) => string;
820
+ /**
821
+ * 语言上下文、字典消息获取与插值工具;Node 请求通过 runWithLocale 隔离语言。
822
+ * @example
823
+ * ```ts
824
+ * import { core } from '@h-ai/core'
825
+ * const tools = core.i18n
826
+ * const message = tools.createMessageGetter({ 'en-US': { hello: 'Hello' }, 'zh-CN': { hello: '你好' } })
827
+ * message('hello', { locale: 'en-US' })
828
+ * ```
829
+ */
830
+ declare const i18n: {
831
+ DEFAULT_LOCALES: LocaleInfo[];
832
+ DEFAULT_LOCALE: string;
833
+ setGlobalLocale: typeof setGlobalLocale;
834
+ getGlobalLocale: typeof getGlobalLocale;
835
+ runWithLocale: typeof runWithLocale;
836
+ createMessageGetter: typeof createMessageGetter;
837
+ 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" | "core_configUnsupportedInBrowser" | "core_cryptoRandomUnavailable" | "core_parallelConcurrencyInvalid" | "core_runtimeStartFailed" | "core_runtimeCloseFailed" | "core_runtimeEnvMissing" | "core_runtimeConfigInvalid" | "core_runtimeConfigProblem" | "core_runtimeErrorCode" | "core_requestAccessDenied", options?: MessageOptions) => string;
838
+ };
839
+
840
+ /**
841
+ * @h-ai/core — 数组操作工具
842
+ * @module core-util-array
843
+ */
844
+ /**
845
+ * 数组去重。
846
+ * @param arr - 输入数组
847
+ * @returns 去重后的新数组
848
+ * @remarks 保留首次出现的顺序;空数组返回空数组。
849
+ *
850
+ * @example
851
+ * ```ts
852
+ * array.unique([1, 1, 2]) // [1, 2]
853
+ * ```
854
+ */
855
+ declare function unique<T>(arr: T[]): T[];
856
+ /**
857
+ * 按条件分组。
858
+ * @param arr - 输入数组
859
+ * @param fn - 分组键生成函数
860
+ * @returns 分组结果对象
861
+ * @remarks 当数组为空时返回空对象;原型同名键也作为独立的自有分组。
862
+ *
863
+ * @example
864
+ * ```ts
865
+ * array.groupBy([{ r: 'a' }, { r: 'b' }], item => item.r)
866
+ * ```
867
+ */
868
+ declare function groupBy<T, K extends string | number>(arr: T[], fn: (item: T) => K): Record<K, T[]>;
869
+ /**
870
+ * 分割为指定大小的块。
871
+ * @param arr - 输入数组
872
+ * @param size - 每块大小(应为正整数)
873
+ * @returns 分块后的二维数组
874
+ * @remarks size <= 0 时结果为空数组。
875
+ *
876
+ * @example
877
+ * ```ts
878
+ * array.chunk([1, 2, 3], 2) // [[1,2],[3]]
879
+ * ```
880
+ */
881
+ declare function chunk<T>(arr: T[], size: number): T[][];
882
+ /**
883
+ * 获取第一个元素。
884
+ * @param arr - 输入数组
885
+ * @returns 第一个元素或 undefined
886
+ * @remarks 空数组返回 undefined。
887
+ *
888
+ * @example
889
+ * ```ts
890
+ * array.first([1, 2, 3]) // 1
891
+ * ```
892
+ */
893
+ declare function first<T>(arr: T[]): T | undefined;
894
+ /**
895
+ * 获取最后一个元素。
896
+ * @param arr - 输入数组
897
+ * @returns 最后一个元素或 undefined
898
+ * @remarks 空数组返回 undefined。
899
+ *
900
+ * @example
901
+ * ```ts
902
+ * array.last([1, 2, 3]) // 3
903
+ * ```
904
+ */
905
+ declare function last<T>(arr: T[]): T | undefined;
906
+ /**
907
+ * 数组扁平化。
908
+ * @param arr - 二维数组
909
+ * @returns 扁平化后的数组
910
+ * @remarks 仅扁平一层。
911
+ *
912
+ * @example
913
+ * ```ts
914
+ * array.flatten([[1], [2, 3]]) // [1, 2, 3]
915
+ * ```
916
+ */
917
+ declare function flatten<T>(arr: T[][]): T[];
918
+ /**
919
+ * 过滤掉 null 和 undefined。
920
+ * @param arr - 输入数组
921
+ * @returns 过滤后的数组
922
+ * @remarks 会保留 0、false、'' 等假值。
923
+ *
924
+ * @example
925
+ * ```ts
926
+ * array.compact([0, null, 1]) // [0, 1]
927
+ * ```
928
+ */
929
+ declare function compact<T>(arr: (T | null | undefined)[]): T[];
930
+ /**
931
+ * 随机打乱数组。
932
+ * @param arr - 输入数组
933
+ * @returns 打乱后的新数组
934
+ * @remarks 不修改原数组。
935
+ *
936
+ * @example
937
+ * ```ts
938
+ * const shuffled = array.shuffle([1, 2, 3])
939
+ * ```
940
+ */
941
+ declare function shuffle<T>(arr: T[]): T[];
942
+ /**
943
+ * 取数组交集。
944
+ * @param arr1 - 数组 1
945
+ * @param arr2 - 数组 2
946
+ * @returns 交集数组
947
+ * @remarks 保持 arr1 中的顺序。
948
+ *
949
+ * @example
950
+ * ```ts
951
+ * array.intersection([1, 2], [2, 3]) // [2]
952
+ * ```
953
+ */
954
+ declare function intersection<T>(arr1: T[], arr2: T[]): T[];
955
+ /**
956
+ * 取数组差集。
957
+ * @param arr1 - 数组 1
958
+ * @param arr2 - 数组 2
959
+ * @returns 差集数组(arr1 中存在且 arr2 不存在)
960
+ * @remarks 保持 arr1 中的顺序。
961
+ *
962
+ * @example
963
+ * ```ts
964
+ * array.difference([1, 2, 3], [2]) // [1, 3]
965
+ * ```
966
+ */
967
+ declare function difference<T>(arr1: T[], arr2: T[]): T[];
968
+ /**
969
+ * 数组操作工具对象。
970
+ * @example
971
+ * ```ts
972
+ * import { core } from '@h-ai/core'
973
+ * const tools = core.array
974
+ * tools.chunk([1, 2, 3], 2)
975
+ * ```
976
+ */
977
+ declare const array: {
978
+ unique: typeof unique;
979
+ groupBy: typeof groupBy;
980
+ chunk: typeof chunk;
981
+ first: typeof first;
982
+ last: typeof last;
983
+ flatten: typeof flatten;
984
+ compact: typeof compact;
985
+ shuffle: typeof shuffle;
986
+ intersection: typeof intersection;
987
+ difference: typeof difference;
988
+ };
989
+
990
+ /**
991
+ * @h-ai/core — 异步操作工具
992
+ * @module core-util-async
993
+ */
994
+ /**
995
+ * 延迟执行。
996
+ *
997
+ * @param ms - 延迟毫秒数
998
+ * @returns 延迟完成后的 Promise
999
+ *
1000
+ * @example
1001
+ * ```ts
1002
+ * await async.delay(1000)
1003
+ * ```
1004
+ */
1005
+ declare function delay(ms: number): Promise<void>;
1006
+ /**
1007
+ * 添加超时限制。
1008
+ *
1009
+ * @param promise - 目标 Promise
1010
+ * @param ms - 超时时间(毫秒)
1011
+ * @returns 原 Promise 的结果
1012
+ * @throws 超时将抛出错误
1013
+ *
1014
+ * @example
1015
+ * ```ts
1016
+ * await async.withTimeout(fetch('/api'), 5000)
1017
+ * ```
1018
+ */
1019
+ declare function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T>;
1020
+ /**
1021
+ * 重试操作。
1022
+ *
1023
+ * @param fn - 待重试函数
1024
+ * @param options - 重试配置
1025
+ * @param options.maxRetries - 最大重试次数
1026
+ * @param options.delay - 重试间隔(毫秒)
1027
+ * @returns 成功的结果
1028
+ * @throws 重试耗尽后抛出最后一次错误
1029
+ *
1030
+ * @example
1031
+ * ```ts
1032
+ * await async.retry(() => fetch('/api'), { maxRetries: 3, delay: 500 })
1033
+ * ```
1034
+ */
1035
+ declare function retry<T>(fn: () => Promise<T>, options?: {
1036
+ maxRetries?: number;
1037
+ delay?: number;
1038
+ }): Promise<T>;
1039
+ /**
1040
+ * 并行执行,限制并发数。
1041
+ *
1042
+ * @param items - 输入列表
1043
+ * @param fn - 处理函数
1044
+ * @param concurrency - 最大并发数,必须为大于 0 的安全整数
1045
+ * @returns 处理结果列表
1046
+ * @remarks 结果顺序与输入顺序一致。
1047
+ * @throws 并发数非法时拒绝为 RangeError,不执行任何任务;任务异常原样传播。
1048
+ *
1049
+ * @example
1050
+ * ```ts
1051
+ * await async.parallel([1, 2, 3], async n => n * 2, 2)
1052
+ * ```
1053
+ */
1054
+ declare function parallel<T, R>(items: T[], fn: (item: T, index: number) => Promise<R>, concurrency?: number): Promise<R[]>;
1055
+ /**
1056
+ * 串行执行。
1057
+ *
1058
+ * @param items - 输入列表
1059
+ * @param fn - 处理函数
1060
+ * @returns 处理结果列表
1061
+ *
1062
+ * @example
1063
+ * ```ts
1064
+ * await async.serial([1, 2], async n => n * 2)
1065
+ * ```
1066
+ */
1067
+ declare function serial<T, R>(items: T[], fn: (item: T, index: number) => Promise<R>): Promise<R[]>;
1068
+ /**
1069
+ * 防抖。
1070
+ *
1071
+ * @param fn - 目标函数
1072
+ * @param ms - 延迟毫秒数
1073
+ * @returns 防抖后的函数
1074
+ * @remarks 只会在最后一次调用后执行。
1075
+ *
1076
+ * @example
1077
+ * ```ts
1078
+ * const onInput = async.debounce(() => {}, 300)
1079
+ * ```
1080
+ */
1081
+ declare function debounce<Args extends unknown[]>(fn: (...args: Args) => unknown, ms: number): (...args: Args) => void;
1082
+ /**
1083
+ * 节流。
1084
+ *
1085
+ * @param fn - 目标函数
1086
+ * @param ms - 间隔毫秒数
1087
+ * @returns 节流后的函数
1088
+ * @remarks 在时间窗口内最多触发一次。
1089
+ *
1090
+ * @example
1091
+ * ```ts
1092
+ * const onScroll = async.throttle(() => {}, 200)
1093
+ * ```
1094
+ */
1095
+ declare function throttle<Args extends unknown[]>(fn: (...args: Args) => unknown, ms: number): (...args: Args) => void;
1096
+ /**
1097
+ * 异步操作工具对象。
1098
+ * @example
1099
+ * ```ts
1100
+ * import { core } from '@h-ai/core'
1101
+ * const tools = core.async
1102
+ * await tools.retry(async () => 'ready', { maxRetries: 2 })
1103
+ * ```
1104
+ */
1105
+ declare const async: {
1106
+ delay: typeof delay;
1107
+ withTimeout: typeof withTimeout;
1108
+ retry: typeof retry;
1109
+ parallel: typeof parallel;
1110
+ serial: typeof serial;
1111
+ debounce: typeof debounce;
1112
+ throttle: typeof throttle;
1113
+ };
1114
+
1115
+ /**
1116
+ * 生产进程默认要求跨主机共享状态;显式E2E测试可使用测试替身。
1117
+ * @param environment - 服务端实际进程环境,不接受请求参数
1118
+ * @param environment.NODE_ENV - 实际运行环境
1119
+ * @param environment.HAI_CORE_ENV - 框架环境文件声明的运行环境
1120
+ * @param environment.HAI_E2E - 显式真实端到端测试标记
1121
+ * @param environment.HAI_E2E_MOCK - 显式模拟端到端测试标记
1122
+ * @returns 是否拒绝仅本机/进程有效的状态后端
1123
+ * @example
1124
+ * ```ts
1125
+ * import { core } from '@h-ai/core'
1126
+ * const production = core.module.requiresSharedState({ HAI_CORE_ENV: 'production' }) // true
1127
+ * const test = core.module.requiresSharedState({ NODE_ENV: 'production', HAI_E2E: '1' }) // false
1128
+ * ```
1129
+ */
1130
+ declare function requiresSharedState(environment: {
1131
+ NODE_ENV?: string;
1132
+ HAI_CORE_ENV?: string;
1133
+ HAI_E2E?: string;
1134
+ HAI_E2E_MOCK?: string;
1135
+ }): boolean;
1136
+
1137
+ /**
1138
+ * @h-ai/core — 对象操作工具
1139
+ * @module core-util-object
1140
+ */
1141
+ /**
1142
+ * 深度克隆对象。
1143
+ * 使用 structuredClone(Node 17+ / 现代浏览器),支持 Date、Map、Set、RegExp、
1144
+ * ArrayBuffer、循环引用等 JSON 方案无法处理的类型。
1145
+ *
1146
+ * @param obj - 目标对象
1147
+ * @returns 深度克隆结果
1148
+ *
1149
+ * @example
1150
+ * ```ts
1151
+ * const cloned = object.deepClone({ a: 1, d: new Date() })
1152
+ * ```
1153
+ */
1154
+ declare function deepClone<T>(obj: T): T;
1155
+ /**
1156
+ * 深度合并多个对象。
1157
+ * @param objects - 需要合并的对象列表
1158
+ * @returns 合并后的新对象
1159
+ * @remarks 仅递归合并普通对象字段;数组、Date、Map、Set 和类实例由后值直接覆盖,不修改输入。
1160
+ *
1161
+ * @example
1162
+ * ```ts
1163
+ * const merged = object.deepMerge({ a: 1 }, { b: 2 })
1164
+ * ```
1165
+ */
1166
+ declare function deepMerge<T extends Record<string, unknown>>(...objects: Partial<T>[]): T;
1167
+ /**
1168
+ * 从对象中选取指定的键。
1169
+ * @param obj - 目标对象
1170
+ * @param keys - 要选取的键列表
1171
+ * @returns 仅包含指定键的新对象
1172
+ *
1173
+ * @example
1174
+ * ```ts
1175
+ * object.pick({ a: 1, b: 2 }, ['a'])
1176
+ * ```
1177
+ */
1178
+ declare function pick<T extends Record<string, unknown>, K extends keyof T>(obj: T, keys: K[]): Pick<T, K>;
1179
+ /**
1180
+ * 从对象中排除指定的键。
1181
+ * @param obj - 目标对象
1182
+ * @param keys - 要排除的键列表
1183
+ * @returns 排除指定键后的新对象
1184
+ *
1185
+ * @example
1186
+ * ```ts
1187
+ * object.omit({ a: 1, b: 2 }, ['b'])
1188
+ * ```
1189
+ */
1190
+ declare function omit<T extends Record<string, unknown>, K extends keyof T>(obj: T, keys: K[]): Omit<T, K>;
1191
+ /**
1192
+ * 获取对象的所有键。
1193
+ * @param obj - 目标对象
1194
+ * @returns 键列表
1195
+ *
1196
+ * @example
1197
+ * ```ts
1198
+ * object.keys({ a: 1, b: 2 })
1199
+ * ```
1200
+ */
1201
+ declare function keys<T extends Record<string, unknown>>(obj: T): (keyof T)[];
1202
+ /**
1203
+ * 获取对象的所有值。
1204
+ * @param obj - 目标对象
1205
+ * @returns 值列表
1206
+ *
1207
+ * @example
1208
+ * ```ts
1209
+ * object.values({ a: 1, b: 2 })
1210
+ * ```
1211
+ */
1212
+ declare function values<T extends Record<string, unknown>>(obj: T): T[keyof T][];
1213
+ /**
1214
+ * 获取对象的键值对数组。
1215
+ * @param obj - 目标对象
1216
+ * @returns 键值对数组
1217
+ *
1218
+ * @example
1219
+ * ```ts
1220
+ * object.entries({ a: 1 })
1221
+ * ```
1222
+ */
1223
+ declare function entries<T extends Record<string, unknown>>(obj: T): [keyof T, T[keyof T]][];
1224
+ /**
1225
+ * 从键值对数组创建对象。
1226
+ * @param entries - 键值对数组
1227
+ * @returns 生成的对象
1228
+ *
1229
+ * @example
1230
+ * ```ts
1231
+ * object.fromEntries([['a', 1]])
1232
+ * ```
1233
+ */
1234
+ declare function fromEntries<K extends string, V>(entries: [K, V][]): Record<K, V>;
1235
+ /**
1236
+ * 对象操作工具对象。
1237
+ * @example
1238
+ * ```ts
1239
+ * import { core } from '@h-ai/core'
1240
+ * const tools = core.object
1241
+ * tools.pick({ id: 'order-1', password: 'example-only' }, ['id'])
1242
+ * ```
1243
+ */
1244
+ declare const object: {
1245
+ deepClone: typeof deepClone;
1246
+ deepMerge: typeof deepMerge;
1247
+ pick: typeof pick;
1248
+ omit: typeof omit;
1249
+ keys: typeof keys;
1250
+ values: typeof values;
1251
+ entries: typeof entries;
1252
+ fromEntries: typeof fromEntries;
1253
+ };
1254
+
1255
+ /** 顺序启动、反序关闭的薄编排,不持有模块配置、依赖容器或业务服务。 */
1256
+
1257
+ /**
1258
+ * 编排宿主明确拥有的模块和业务钩子,不推断模块类型或初始化参数。
1259
+ * start/close 合并并发;启动失败反序回滚;关闭失败保留依赖和清理义务,下次 close/start 会重试。
1260
+ * @param definitions - 按真实依赖顺序声明的初始化和关闭动作。
1261
+ * @returns 不抛业务异常的生命周期控制器;仅报告安全诊断,配置失败附带原因和处理建议。
1262
+ * @example
1263
+ * ```ts
1264
+ * import { core, ok } from '@h-ai/core'
1265
+ * const runtime = core.module.createRuntime([
1266
+ * { name: 'application', start: () => ok(undefined), close: () => ok(undefined) },
1267
+ * ])
1268
+ * const started = await runtime.start()
1269
+ * if (started.success) await runtime.close()
1270
+ * ```
1271
+ */
1272
+ declare function createRuntime(definitions: readonly RuntimeStep[]): ModuleRuntime;
1273
+
1274
+ /**
1275
+ * 清理诊断文本中的显式凭据、URL 凭据及调用方已知的秘密值;不猜测无标签的任意文本。
1276
+ * @example
1277
+ * ```ts
1278
+ * import { core } from '@h-ai/core'
1279
+ * const safe = core.sanitize.sanitizeText('verificationCode=123456')
1280
+ * ```
1281
+ */
1282
+ declare function sanitizeText(text: string, secretValues?: readonly string[]): string;
1283
+ /**
1284
+ * 判断键名是否属于敏感字段
1285
+ * @param key - 原始字段名;会统一 camelCase、kebab-case 与 snake_case。
1286
+ * @param matcher - 自定义规则;省略时使用凭证字段默认规则。
1287
+ * @returns 当前字段名是否被匹配为敏感字段。
1288
+ * @example
1289
+ * ```ts
1290
+ * import { core } from '@h-ai/core'
1291
+ * const safe = core.sanitize.isSensitiveKey('apiKey')
1292
+ * ```
1293
+ */
1294
+ declare function isSensitiveKey(key: string, matcher?: SensitiveKeyMatcher): boolean;
1295
+ /**
1296
+ * 遮蔽 URL 的用户名、密码及敏感查询参数;OAuth 风格 fragment 按查询参数处理。
1297
+ *
1298
+ * 解析失败返回固定占位符,避免畸形地址把凭据原样写入日志。
1299
+ *
1300
+ * @param url - 待记录的绝对 URL
1301
+ * @param options - 与对象脱敏一致的匹配规则和替换值
1302
+ * @returns 可安全用于结构化日志的 URL
1303
+ * @example
1304
+ * ```ts
1305
+ * import { core } from '@h-ai/core'
1306
+ * const safe = core.sanitize.sanitizeUrl('https://service.example/path?token=example-only')
1307
+ * ```
1308
+ */
1309
+ declare function sanitizeUrl(url: string, options?: SanitizeSensitiveFieldsOptions): string;
1310
+ /**
1311
+ * 递归脱敏单个值。
1312
+ *
1313
+ * @param value - 原始值
1314
+ * @param key - 当前字段名;根节点传 null
1315
+ * @param options - 脱敏选项
1316
+ * @param cache - 循环引用 / 重复引用缓存
1317
+ * @returns 脱敏数据副本;类实例不保留原型和方法,普通对象循环保留,Error 规范化为有界诊断树,原值不被修改。
1318
+ * @example
1319
+ * ```ts
1320
+ * import { core } from '@h-ai/core'
1321
+ * const safe = core.sanitize.sanitizeSensitiveValue('example-only', 'password')
1322
+ * ```
1323
+ */
1324
+ declare function sanitizeSensitiveValue(value: unknown, key: string | null, options?: SanitizeSensitiveFieldsOptions, cache?: WeakMap<object, unknown>): unknown;
1325
+ /**
1326
+ * 对对象中的敏感字段执行递归脱敏,并自动处理 URL/endpoint 字段中的内嵌凭证。
1327
+ * Error 保留 name/message/stack/cause、aggregate errors 与枚举上下文;错误子图循环和过深路径用固定标记,普通对象循环保留。
1328
+ * 诊断文本不会自动解析自由文本中的秘密;记录前仍需调用方清理,或配置明确的 redact 路径。
1329
+ *
1330
+ * @param value - 原始对象/数组/值
1331
+ * @param options - 脱敏选项
1332
+ * 类实例只复制自有可枚举数据属性;不保留原型、访问器和 toJSON。Date 转 ISO 字符串,URL 转脱敏字符串。
1333
+ * @returns 用于诊断的脱敏副本,不作为原类实例使用。
1334
+ * @example
1335
+ * ```ts
1336
+ * import { core } from '@h-ai/core'
1337
+ * const safe = core.sanitize.sanitizeSensitiveFields({ password: 'example-only', id: 'order-1' })
1338
+ * ```
1339
+ */
1340
+ declare function sanitizeSensitiveFields<T>(value: T, options?: SanitizeSensitiveFieldsOptions): T;
1341
+ /**
1342
+ * 脱敏工具对象。
1343
+ * @example
1344
+ * ```ts
1345
+ * import { core } from '@h-ai/core'
1346
+ * const tools = core.sanitize
1347
+ * tools.sanitizeSensitiveFields({ apiKey: 'example-only', id: 'order-1' })
1348
+ * ```
1349
+ */
1350
+ declare const sanitize: {
1351
+ defaultSensitiveKeyRegex: RegExp;
1352
+ defaultSensitiveReplacement: string;
1353
+ isSensitiveKey: typeof isSensitiveKey;
1354
+ sanitizeUrl: typeof sanitizeUrl;
1355
+ sanitizeText: typeof sanitizeText;
1356
+ sanitizeSensitiveValue: typeof sanitizeSensitiveValue;
1357
+ sanitizeSensitiveFields: typeof sanitizeSensitiveFields;
1358
+ };
1359
+
1360
+ /**
1361
+ * @h-ai/core — 字符串操作工具
1362
+ * @module core-util-string
1363
+ */
1364
+ /**
1365
+ * 首字母大写。
1366
+ * @param str - 输入字符串
1367
+ * @returns 首字母大写后的字符串
1368
+ * @remarks 空字符串返回空字符串。
1369
+ *
1370
+ * @example
1371
+ * ```ts
1372
+ * string.capitalize('hello') // 'Hello'
1373
+ * ```
1374
+ */
1375
+ declare function capitalize(str: string): string;
1376
+ /**
1377
+ * 转换为 kebab-case。
1378
+ * @param str - 输入字符串
1379
+ * @returns kebab-case 字符串
1380
+ * @remarks 支持连续大写字母拆分(如 `getHTTPSUrl` → `get-https-url`)。
1381
+ *
1382
+ * @example
1383
+ * ```ts
1384
+ * string.kebabCase('helloWorld') // 'hello-world'
1385
+ * string.kebabCase('getHTTPSUrl') // 'get-https-url'
1386
+ * ```
1387
+ */
1388
+ declare function kebabCase(str: string): string;
1389
+ /**
1390
+ * 转换为 camelCase。
1391
+ * @param str - 输入字符串
1392
+ * @returns camelCase 字符串
1393
+ * @remarks 仅处理包含 '-' 的字符串。
1394
+ *
1395
+ * @example
1396
+ * ```ts
1397
+ * string.camelCase('hello-world') // 'helloWorld'
1398
+ * ```
1399
+ */
1400
+ declare function camelCase(str: string): string;
1401
+ /**
1402
+ * 截断字符串。
1403
+ * @param str - 输入字符串
1404
+ * @param length - 最大长度(小于等于 0 时返回原字符串)
1405
+ * @param suffix - 超出长度时的后缀
1406
+ * @returns 截断后的字符串
1407
+ *
1408
+ * @example
1409
+ * ```ts
1410
+ * string.truncate('hello world', 5) // 'hello...'
1411
+ * ```
1412
+ */
1413
+ declare function truncate(str: string, length: number, suffix?: string): string;
1414
+ /**
1415
+ * 转换为 snake_case。
1416
+ * @param str - 输入字符串
1417
+ * @returns snake_case 字符串
1418
+ * @remarks 支持连续大写字母拆分(如 `getHTTPSUrl` → `get_https_url`)。
1419
+ *
1420
+ * @example
1421
+ * ```ts
1422
+ * string.snakeCase('helloWorld') // 'hello_world'
1423
+ * string.snakeCase('getHTTPSUrl') // 'get_https_url'
1424
+ * ```
1425
+ */
1426
+ declare function snakeCase(str: string): string;
1427
+ /**
1428
+ * 转换为 PascalCase。
1429
+ * @param str - 输入字符串
1430
+ * @returns PascalCase 字符串
1431
+ * @remarks 支持 '-' 与 '_' 分隔。
1432
+ *
1433
+ * @example
1434
+ * ```ts
1435
+ * string.pascalCase('hello-world') // 'HelloWorld'
1436
+ * ```
1437
+ */
1438
+ declare function pascalCase(str: string): string;
1439
+ /**
1440
+ * 移除字符串两端的空白。
1441
+ * @param str - 输入字符串
1442
+ * @returns 去除两端空白后的字符串
1443
+ *
1444
+ * @example
1445
+ * ```ts
1446
+ * string.trim(' hi ') // 'hi'
1447
+ * ```
1448
+ */
1449
+ declare function trim(str: string): string;
1450
+ /**
1451
+ * 检查字符串是否为空或只包含空白。
1452
+ * @param str - 输入字符串
1453
+ * @returns 是否为空或全空白
1454
+ *
1455
+ * @example
1456
+ * ```ts
1457
+ * string.isBlank(' ') // true
1458
+ * ```
1459
+ */
1460
+ declare function isBlank(str: string): boolean;
1461
+ /**
1462
+ * 检查字符串是否不为空。
1463
+ * @param str - 输入字符串
1464
+ * @returns 是否非空
1465
+ *
1466
+ * @example
1467
+ * ```ts
1468
+ * string.isNotBlank('ok') // true
1469
+ * ```
1470
+ */
1471
+ declare function isNotBlank(str: string): boolean;
1472
+ /**
1473
+ * 填充字符串到指定长度(左侧)。
1474
+ * @param str - 输入字符串
1475
+ * @param length - 目标长度
1476
+ * @param char - 填充字符
1477
+ * @returns 填充后的字符串
1478
+ *
1479
+ * @example
1480
+ * ```ts
1481
+ * string.padStart('1', 3, '0') // '001'
1482
+ * ```
1483
+ */
1484
+ declare function padStart(str: string, length: number, char?: string): string;
1485
+ /**
1486
+ * 填充字符串到指定长度(右侧)。
1487
+ * @param str - 输入字符串
1488
+ * @param length - 目标长度
1489
+ * @param char - 填充字符
1490
+ * @returns 填充后的字符串
1491
+ *
1492
+ * @example
1493
+ * ```ts
1494
+ * string.padEnd('1', 3, '0') // '100'
1495
+ * ```
1496
+ */
1497
+ declare function padEnd(str: string, length: number, char?: string): string;
1498
+ /**
1499
+ * 无内容提前返回的字符串比较;Node 入口使用原生 timingSafeEqual 覆盖此实现。
1500
+ *
1501
+ * 浏览器 JavaScript 引擎不提供恒时保证,不能将此实现当作服务端凭证校验的安全边界。
1502
+ *
1503
+ * @param a - 字符串 a
1504
+ * @param b - 字符串 b
1505
+ * @returns 是否相等
1506
+ *
1507
+ * @example
1508
+ * ```ts
1509
+ * string.constantTimeEqual('abc', 'abc') // true
1510
+ * string.constantTimeEqual('abc', 'abd') // false
1511
+ * ```
1512
+ */
1513
+ declare function constantTimeEqual(a: string, b: string): boolean;
1514
+ /**
1515
+ * 字符串操作工具对象。
1516
+ * @example
1517
+ * ```ts
1518
+ * import { core } from '@h-ai/core'
1519
+ * const tools = core.string
1520
+ * tools.camelCase('order-created')
1521
+ * ```
1522
+ */
1523
+ declare const string: {
1524
+ capitalize: typeof capitalize;
1525
+ kebabCase: typeof kebabCase;
1526
+ camelCase: typeof camelCase;
1527
+ truncate: typeof truncate;
1528
+ snakeCase: typeof snakeCase;
1529
+ pascalCase: typeof pascalCase;
1530
+ trim: typeof trim;
1531
+ isBlank: typeof isBlank;
1532
+ isNotBlank: typeof isNotBlank;
1533
+ padStart: typeof padStart;
1534
+ padEnd: typeof padEnd;
1535
+ constantTimeEqual: typeof constantTimeEqual;
1536
+ };
1537
+
1538
+ /**
1539
+ * @h-ai/core — 时间操作工具
1540
+ * @module core-util-time
1541
+ */
1542
+ /**
1543
+ * 格式化日期。
1544
+ * @param date - 日期对象
1545
+ * @param format - 格式模板(默认 YYYY-MM-DD)
1546
+ * @returns 格式化后的字符串
1547
+ *
1548
+ * @example
1549
+ * ```ts
1550
+ * time.formatDate(new Date(), 'YYYY-MM-DD')
1551
+ * ```
1552
+ */
1553
+ declare function formatDate(date: Date, format?: string): string;
1554
+ /**
1555
+ * 相对时间描述。
1556
+ * @param date - 目标日期
1557
+ * @returns 相对时间文案
1558
+ * @remarks 使用 i18n 消息返回结果。
1559
+ *
1560
+ * @example
1561
+ * ```ts
1562
+ * time.timeAgo(new Date(Date.now() - 60000))
1563
+ * ```
1564
+ */
1565
+ declare function timeAgo(date: Date): string;
1566
+ /**
1567
+ * 获取当前时间戳(毫秒)。
1568
+ * @returns 当前时间戳(毫秒)
1569
+ *
1570
+ * @example
1571
+ * ```ts
1572
+ * const ts = time.now()
1573
+ * ```
1574
+ */
1575
+ declare function now(): number;
1576
+ /**
1577
+ * 获取当前时间戳(秒)。
1578
+ * @returns 当前时间戳(秒)
1579
+ *
1580
+ * @example
1581
+ * ```ts
1582
+ * const ts = time.nowSeconds()
1583
+ * ```
1584
+ */
1585
+ declare function nowSeconds(): number;
1586
+ /**
1587
+ * 解析日期字符串。
1588
+ * @param dateStr - 日期字符串
1589
+ * @returns Date 对象
1590
+ * @remarks 无效字符串将生成 Invalid Date。
1591
+ *
1592
+ * @example
1593
+ * ```ts
1594
+ * const date = time.parseDate('2024-01-01')
1595
+ * ```
1596
+ */
1597
+ declare function parseDate(dateStr: string): Date;
1598
+ /**
1599
+ * 判断是否为有效日期。
1600
+ * @param date - Date 对象
1601
+ * @returns 是否为有效日期
1602
+ *
1603
+ * @example
1604
+ * ```ts
1605
+ * time.isValidDate(new Date('invalid')) // false
1606
+ * ```
1607
+ */
1608
+ declare function isValidDate(date: Date): boolean;
1609
+ /**
1610
+ * 添加天数。
1611
+ * @param date - 原始日期
1612
+ * @param days - 增加天数(可为负数)
1613
+ * @returns 新的日期对象
1614
+ *
1615
+ * @example
1616
+ * ```ts
1617
+ * time.addDays(new Date(), 7)
1618
+ * ```
1619
+ */
1620
+ declare function addDays(date: Date, days: number): Date;
1621
+ /**
1622
+ * 添加小时。
1623
+ * @param date - 原始日期
1624
+ * @param hours - 增加小时(可为负数)
1625
+ * @returns 新的日期对象
1626
+ *
1627
+ * @example
1628
+ * ```ts
1629
+ * time.addHours(new Date(), 1)
1630
+ * ```
1631
+ */
1632
+ declare function addHours(date: Date, hours: number): Date;
1633
+ /**
1634
+ * 获取日期的开始时间(00:00:00)。
1635
+ * @param date - 目标日期
1636
+ * @returns 当天开始时间
1637
+ *
1638
+ * @example
1639
+ * ```ts
1640
+ * time.startOfDay(new Date())
1641
+ * ```
1642
+ */
1643
+ declare function startOfDay(date: Date): Date;
1644
+ /**
1645
+ * 获取日期的结束时间(23:59:59)。
1646
+ * @param date - 目标日期
1647
+ * @returns 当天结束时间
1648
+ *
1649
+ * @example
1650
+ * ```ts
1651
+ * time.endOfDay(new Date())
1652
+ * ```
1653
+ */
1654
+ declare function endOfDay(date: Date): Date;
1655
+ /**
1656
+ * 时间操作工具对象。
1657
+ * @example
1658
+ * ```ts
1659
+ * import { core } from '@h-ai/core'
1660
+ * const tools = core.time
1661
+ * tools.addDays(new Date('2026-01-01T00:00:00Z'), 1)
1662
+ * ```
1663
+ */
1664
+ declare const time: {
1665
+ formatDate: typeof formatDate;
1666
+ timeAgo: typeof timeAgo;
1667
+ now: typeof now;
1668
+ nowSeconds: typeof nowSeconds;
1669
+ parseDate: typeof parseDate;
1670
+ isValidDate: typeof isValidDate;
1671
+ addDays: typeof addDays;
1672
+ addHours: typeof addHours;
1673
+ startOfDay: typeof startOfDay;
1674
+ endOfDay: typeof endOfDay;
1675
+ };
1676
+
1677
+ /**
1678
+ * @h-ai/core — 类型检查工具
1679
+ * @module core-util-type
1680
+ */
1681
+ /**
1682
+ * 检查值是否已定义(非 null 和 undefined)。
1683
+ * @param value - 待检查值
1684
+ * @returns 是否已定义
1685
+ *
1686
+ * @example
1687
+ * ```ts
1688
+ * typeUtils.isDefined(0) // true
1689
+ * ```
1690
+ */
1691
+ declare function isDefined<T>(value: T | undefined | null): value is T;
1692
+ /**
1693
+ * 检查值是否为纯对象(排除数组)。
1694
+ * @param value - 待检查值
1695
+ * @returns 是否为纯对象
1696
+ *
1697
+ * @example
1698
+ * ```ts
1699
+ * typeUtils.isObject({}) // true
1700
+ * ```
1701
+ */
1702
+ declare function isObject(value: unknown): value is Record<string, unknown>;
1703
+ /**
1704
+ * 检查值是否为函数。
1705
+ * @param value - 待检查值
1706
+ * @returns 是否为函数
1707
+ *
1708
+ * @example
1709
+ * ```ts
1710
+ * typeUtils.isFunction(() => {}) // true
1711
+ * ```
1712
+ */
1713
+ declare function isFunction(value: unknown): value is (...args: unknown[]) => unknown;
1714
+ /**
1715
+ * 检查值是否为 Promise。
1716
+ * @param value - 待检查值
1717
+ * @returns 是否为 Promise
1718
+ *
1719
+ * @example
1720
+ * ```ts
1721
+ * typeUtils.isPromise(Promise.resolve()) // true
1722
+ * ```
1723
+ */
1724
+ declare function isPromise<T>(value: unknown): value is Promise<T>;
1725
+ /**
1726
+ * 检查值是否为字符串。
1727
+ * @param value - 待检查值
1728
+ * @returns 是否为字符串
1729
+ *
1730
+ * @example
1731
+ * ```ts
1732
+ * typeUtils.isString('a') // true
1733
+ * ```
1734
+ */
1735
+ declare function isString(value: unknown): value is string;
1736
+ /**
1737
+ * 检查值是否为数字。
1738
+ * @param value - 待检查值
1739
+ * @returns 是否为数字(排除 NaN)
1740
+ *
1741
+ * @example
1742
+ * ```ts
1743
+ * typeUtils.isNumber(1) // true
1744
+ * ```
1745
+ */
1746
+ declare function isNumber(value: unknown): value is number;
1747
+ /**
1748
+ * 检查值是否为布尔值。
1749
+ * @param value - 待检查值
1750
+ * @returns 是否为布尔值
1751
+ *
1752
+ * @example
1753
+ * ```ts
1754
+ * typeUtils.isBoolean(false) // true
1755
+ * ```
1756
+ */
1757
+ declare function isBoolean(value: unknown): value is boolean;
1758
+ /**
1759
+ * 检查值是否为数组。
1760
+ * @param value - 待检查值
1761
+ * @returns 是否为数组
1762
+ *
1763
+ * @example
1764
+ * ```ts
1765
+ * typeUtils.isArray([1, 2]) // true
1766
+ * ```
1767
+ */
1768
+ declare function isArray<T = unknown>(value: unknown): value is T[];
1769
+ /**
1770
+ * 类型检查工具对象。
1771
+ * @example
1772
+ * ```ts
1773
+ * import { core } from '@h-ai/core'
1774
+ * const tools = core.typeUtils
1775
+ * const value: unknown = 'order-1'
1776
+ * if (tools.isString(value)) value.toUpperCase()
1777
+ * ```
1778
+ */
1779
+ declare const typeUtils: {
1780
+ isDefined: typeof isDefined;
1781
+ isObject: typeof isObject;
1782
+ isFunction: typeof isFunction;
1783
+ isPromise: typeof isPromise;
1784
+ isString: typeof isString;
1785
+ isNumber: typeof isNumber;
1786
+ isBoolean: typeof isBoolean;
1787
+ isArray: typeof isArray;
1788
+ };
1789
+
1790
+ /**
1791
+ * @h-ai/core — 错误注册与处理
1792
+ *
1793
+ * 提供统一的错误定义生成与实例化能力。
1794
+ *
1795
+ * @module core-function-error
1796
+ */
1797
+
1798
+ /**
1799
+ * 错误提示末尾显示关联标识;重复格式化不会重复追加。
1800
+ * @example
1801
+ * ```ts
1802
+ * import { core } from '@h-ai/core'
1803
+ * const message = core.error.formatMessage({ message: '保存失败', traceId: 'request-1' })
1804
+ * ```
1805
+ */
1806
+ declare function formatMessage(error: Pick<HaiError, 'message' | 'traceId'>): string;
1807
+ /**
1808
+ * HTTP/UI 边界仅公开安全消息和关联标识;内部异常及扩展信息留在脱敏日志。
1809
+ * @example
1810
+ * ```ts
1811
+ * import { core } from '@h-ai/core'
1812
+ * const safe = core.error.toPublic({ code: 'app:failed', message: 'Internal detail', httpStatus: 500 }, 'request-1')
1813
+ * ```
1814
+ */
1815
+ declare function toPublic(error: HaiError, traceId?: string, locale?: string): HaiError;
1816
+ /**
1817
+ * 根据模块错误映射生成标准错误定义对象。
1818
+ *
1819
+ * 将错误信息映射(如 `{ CONFIG_NOT_FOUND: '010:500' }`)转换为结构化的 HaiErrorDef,
1820
+ * 自动组装完整的错误码(格式:`system:module:code`)以及对应的 HTTP 状态码。
1821
+ *
1822
+ * @template T - 错误信息映射的类型
1823
+ *
1824
+ * @param module - 模块名称(如 'core'、'db'、'api'),会作为错误码的第二段
1825
+ * @param errorInfo - 错误信息映射对象,值格式为 `'错误码数字:HTTP状态码'`(如 `'010:500'`)
1826
+ * @param system - 系统标识,默认 'hai',会作为错误码的第一段
1827
+ *
1828
+ * @returns 返回同类型的错误定义对象,每个 key 对应一个 HaiErrorDef 对象
1829
+ *
1830
+ * @example
1831
+ * ```ts
1832
+ * const ConfigErrorInfo = {
1833
+ * FILE_NOT_FOUND: '010:500',
1834
+ * PARSE_ERROR: '011:500',
1835
+ * VALIDATION_ERROR: '012:500',
1836
+ * } as const
1837
+ *
1838
+ * const ConfigError = buildHaiErrorsDef('core', ConfigErrorInfo)
1839
+ * // =>
1840
+ * // ConfigError.FILE_NOT_FOUND = {
1841
+ * // code: 'hai:core:010',
1842
+ * // httpStatus: 500,
1843
+ * // system: 'hai',
1844
+ * // module: 'core',
1845
+ * // }
1846
+ * ```
1847
+ */
1848
+ declare function buildHaiErrorsDef<T extends Record<string, string>>(module: string, errorInfo: T, system?: string): {
1849
+ [K in keyof T]: HaiErrorDef;
1850
+ };
1851
+ /**
1852
+ * 根据错误定义创建错误实例。
1853
+ *
1854
+ * 将 HaiErrorDef(错误定义)扩展为 HaiError(运行时错误实例),
1855
+ * 添加具体的错误消息、原因和建议等运行时信息。
1856
+ *
1857
+ * @param def - 错误定义对象(通常由 buildHaiErrorsDef 生成)
1858
+ * @param message - 错误消息(描述此次具体发生了什么)
1859
+ * @param cause - 原始错误原因(可选,用于链式错误追踪)
1860
+ * @param suggestion - 用户可采取的建议(可选,如 "'请检查配置文件格式')
1861
+ *
1862
+ * @returns 返回完整的 HaiError 实例,包含错误码、HTTP 状态、消息、原因和建议
1863
+ *
1864
+ * @example
1865
+ * ```ts
1866
+ * const err = buildHaiErrorInst(
1867
+ * HaiConfigError.FILE_NOT_FOUND,
1868
+ * 'config.yml 文件不存在',
1869
+ * new Error('ENOENT: no such file'),
1870
+ * '请确保 _core.yml 在项目根目录'
1871
+ * )
1872
+ * // => {
1873
+ * // code: 'hai:core:010',
1874
+ * // httpStatus: 500,
1875
+ * // system: 'hai',
1876
+ * // module: 'core',
1877
+ * // message: 'config.yml 文件不存在',
1878
+ * // cause: Error('ENOENT: no such file'),
1879
+ * // suggestion: '请确保 _core.yml 在项目根目录'
1880
+ * // }
1881
+ * ```
1882
+ */
1883
+ declare function buildHaiErrorInst(def: HaiErrorDef, message: string, cause?: unknown, suggestion?: string): HaiError;
1884
+ /**
1885
+ * 错误定义生成及错误实例组装工具;通过 core.error 使用。
1886
+ * @example
1887
+ * ```ts
1888
+ * import { core } from '@h-ai/core'
1889
+ * const tools = core.error
1890
+ * tools.buildHaiErrorsDef('orders', { NOT_FOUND: '001:404' })
1891
+ * ```
1892
+ */
1893
+ declare const error: {
1894
+ buildHaiErrorsDef: typeof buildHaiErrorsDef;
1895
+ buildHaiErrorInst: typeof buildHaiErrorInst;
1896
+ formatMessage: typeof formatMessage;
1897
+ toPublic: typeof toPublic;
1898
+ };
1899
+
1900
+ /**
1901
+ * Zod 校验错误使用的稳定消息键。
1902
+ * @example
1903
+ * ```ts
1904
+ * import type { ZodValidationMessageKey } from '@h-ai/core'
1905
+ * const value: ZodValidationMessageKey = 'validationRequired'
1906
+ * ```
1907
+ */
1908
+ type ZodValidationMessageKey = 'validationFailed' | 'validationRequired' | 'validationInvalid' | 'validationInvalidType' | 'validationUnexpectedFields' | 'validationStringMin' | 'validationStringMax' | 'validationNumberMin' | 'validationNumberMax' | 'validationArrayMin' | 'validationArrayMax' | 'validationTooSmall' | 'validationTooBig' | 'validationEmail' | 'validationUrl' | 'validationUuid' | 'validationEnum';
1909
+ /**
1910
+ * 把校验消息键及插值参数转换为显示文本的函数。
1911
+ * @example
1912
+ * ```ts
1913
+ * import type { ZodMessageGetter } from '@h-ai/core'
1914
+ * const message: ZodMessageGetter = (key, params) => key === 'validationRequired' ? 'Required' : `${key}: ${String(params?.field ?? '')}`
1915
+ * message('validationRequired')
1916
+ * ```
1917
+ */
1918
+ type ZodMessageGetter = (key: ZodValidationMessageKey, params?: Record<string, string | number>) => string;
1919
+ /**
1920
+ * 可绑定表单字段路径的本地化错误。
1921
+ * @example
1922
+ * ```ts
1923
+ * import type { ValidationFormError } from '@h-ai/core'
1924
+ * const value: ValidationFormError = { field: 'email', message: 'Enter an email address' }
1925
+ * ```
1926
+ */
1927
+ interface ValidationFormError {
1928
+ field: string;
1929
+ message: string;
1930
+ }
1931
+ /**
1932
+ * 共享 Zod 错误映射契约;业务自定义消息保持原文。
1933
+ * @example
1934
+ * ```ts
1935
+ * import { core, type ZodValidationFn } from '@h-ai/core'
1936
+ * import { z } from 'zod'
1937
+ * const validator: ZodValidationFn = core.zodValidation
1938
+ * const input = z.object({ email: z.email() }).safeParse({ email: 'invalid' })
1939
+ * if (!input.success) validator.mapZodErrorToFormErrors(input.error, key => key)
1940
+ * ```
1941
+ */
1942
+ interface ZodValidationFn {
1943
+ readonly createPrefixedZodMessageGetter: <TMessageKey extends string>(prefix: string, getMessage: (messageKey: TMessageKey, params?: Record<string, string | number>) => string) => ZodMessageGetter;
1944
+ readonly mapZodErrorToFormErrors: (error: unknown, getMessage: ZodMessageGetter) => ValidationFormError[];
1945
+ }
1946
+ /**
1947
+ * 业务操作的成功数据或标准失败;访问 data/error 前必须按 success 收窄。
1948
+ * @example
1949
+ * ```ts
1950
+ * import { ok, type HaiResult } from '@h-ai/core'
1951
+ * const result: HaiResult<{ id: string }> = ok({ id: 'order-1' })
1952
+ * const label = result.success ? result.data.id : result.error.message
1953
+ * ```
1954
+ */
1955
+ type HaiResult<T> = {
1956
+ success: true;
1957
+ data: T;
1958
+ } | {
1959
+ success: false;
1960
+ error: HaiError;
1961
+ };
1962
+ /**
1963
+ * 创建成功结果;不会自动捕获后续操作异常。
1964
+ * @param data - 成功分支的数据;保留原类型和对象引用。
1965
+ * @returns success 为 true、data 为输入值的结果。
1966
+ * @example
1967
+ * ```ts
1968
+ * import { ok } from '@h-ai/core'
1969
+ * const result = ok({ id: 'order-1' })
1970
+ * if (result.success) result.data.id.toUpperCase()
1971
+ * ```
1972
+ */
1973
+ declare function ok<T>(data: T): HaiResult<T>;
1974
+ /**
1975
+ * 创建失败结果;支持标准错误定义、已有 HaiError 与原生 Error。
1976
+ * @param errorOrDef - 已定义的错误、已有业务错误或原生异常。
1977
+ * @param message - 从错误定义创建实例时使用的消息。
1978
+ * @param cause - 原始原因;对外展示前应按边界脱敏。
1979
+ * @param suggestion - 可选的处理建议。
1980
+ * @returns success 为 false、error 为标准业务错误的结果。
1981
+ * @example
1982
+ * ```ts
1983
+ * import { err, HaiCommonError } from '@h-ai/core'
1984
+ * const result = err(HaiCommonError.NOT_FOUND, 'Order not found')
1985
+ * if (!result.success) result.error.httpStatus
1986
+ * ```
1987
+ */
1988
+ declare function err(errorOrDef: HaiErrorDef | HaiError | Error, message?: string, cause?: unknown, suggestion?: string): HaiResult<never>;
1989
+ /**
1990
+ * HaiResult 模式匹配处理器。
1991
+ *
1992
+ * 提供对 HaiResult 的模式匹配能力,分别处理成功和失败两种情况。
1993
+ *
1994
+ * @template T - 成功数据类型
1995
+ * @template R1 - ok 分支返回类型
1996
+ * @template R2 - err 分支返回类型
1997
+ * @example
1998
+ * ```ts
1999
+ * import { type MatchHandlers, ok } from '@h-ai/core'
2000
+ * const handlers: MatchHandlers<number, string, string> = { ok: n => String(n + 1), err: error => error.message }
2001
+ * const result = ok(2)
2002
+ * const label = result.success ? handlers.ok(result.data) : handlers.err(result.error)
2003
+ * ```
2004
+ */
2005
+ interface MatchHandlers<T, R1, R2> {
2006
+ /** 成功分支处理器 */
2007
+ ok: (data: T) => R1;
2008
+ /** 失败分支处理器 */
2009
+ err: (error: HaiError) => R2;
2010
+ }
2011
+ /**
2012
+ * 错误信息值格式:`错误码数字段:HTTP状态码`,例如 `001:500`。
2013
+ * @example
2014
+ * ```ts
2015
+ * import type { ErrorInfoValue } from '@h-ai/core'
2016
+ * const value: ErrorInfoValue = '001:500'
2017
+ * ```
2018
+ */
2019
+ type ErrorInfoValue = `${string}:${string}`;
2020
+ /**
2021
+ * 模块错误信息映射。
2022
+ * @example
2023
+ * ```ts
2024
+ * import type { ErrorInfo } from '@h-ai/core'
2025
+ * const value: ErrorInfo = { NOT_READY: '001:503' }
2026
+ * ```
2027
+ */
2028
+ type ErrorInfo = Record<string, ErrorInfoValue>;
2029
+ /**
2030
+ * 稳定的错误码与 HTTP 映射;消息在创建错误实例时填入。
2031
+ * @example
2032
+ * ```ts
2033
+ * import type { HaiErrorDef } from '@h-ai/core'
2034
+ * const value: HaiErrorDef = { code: 'app:orders:001', httpStatus: 409, system: 'app', module: 'orders' }
2035
+ * ```
2036
+ */
2037
+ interface HaiErrorDef {
2038
+ code: string | number;
2039
+ httpStatus: number;
2040
+ system: string;
2041
+ module: string;
2042
+ }
2043
+ /**
2044
+ * 可跨业务边界传递的错误;cause/ext 对外展示前仍需脱敏。
2045
+ * @example
2046
+ * ```ts
2047
+ * import type { HaiError } from '@h-ai/core'
2048
+ * const value: HaiError = { code: 'app:orders:001', message: 'Order already exists', httpStatus: 409 }
2049
+ * ```
2050
+ */
2051
+ interface HaiError {
2052
+ code: string | number;
2053
+ message: string;
2054
+ /** 用户提示与前后端诊断共用的关联标识。 */
2055
+ traceId?: string;
2056
+ httpStatus?: number;
2057
+ system?: string;
2058
+ module?: string;
2059
+ cause?: unknown;
2060
+ suggestion?: string;
2061
+ ext?: Record<string, unknown>;
2062
+ /** 由服务端明确批准公开的业务进度;边界转换为 ext,内部 ext 默认不公开。 */
2063
+ publicExt?: Record<string, unknown>;
2064
+ }
2065
+ /**
2066
+ * 跨模块通用错误定义及 HTTP 状态映射。
2067
+ * @example
2068
+ * ```ts
2069
+ * import { err, HaiCommonError } from '@h-ai/core'
2070
+ * const result = err(HaiCommonError.UNAUTHORIZED, 'Authentication required')
2071
+ * if (!result.success) result.error.code
2072
+ * ```
2073
+ */
2074
+ declare const HaiCommonError: {
2075
+ readonly NOT_INITIALIZED: HaiErrorDef;
2076
+ readonly INIT_FAILED: HaiErrorDef;
2077
+ readonly INIT_IN_PROGRESS: HaiErrorDef;
2078
+ readonly UNAUTHORIZED: HaiErrorDef;
2079
+ readonly FORBIDDEN: HaiErrorDef;
2080
+ readonly TOKEN_EXPIRED: HaiErrorDef;
2081
+ readonly TOKEN_INVALID: HaiErrorDef;
2082
+ readonly REQUEST_ACCESS_DENIED: HaiErrorDef;
2083
+ readonly VALIDATION_ERROR: HaiErrorDef;
2084
+ readonly INVALID_REQUEST: HaiErrorDef;
2085
+ readonly PARAMETER_MISSING: HaiErrorDef;
2086
+ readonly NOT_FOUND: HaiErrorDef;
2087
+ readonly ALREADY_EXISTS: HaiErrorDef;
2088
+ readonly CONFLICT: HaiErrorDef;
2089
+ readonly API_ERROR: HaiErrorDef;
2090
+ readonly NETWORK_ERROR: HaiErrorDef;
2091
+ readonly TIMEOUT: HaiErrorDef;
2092
+ readonly SERVICE_UNAVAILABLE: HaiErrorDef;
2093
+ readonly INTERNAL_ERROR: HaiErrorDef;
2094
+ readonly DATABASE_ERROR: HaiErrorDef;
2095
+ readonly UNKNOWN_ERROR: HaiErrorDef;
2096
+ };
2097
+ /**
2098
+ * 文件配置加载、校验、环境缺失及缓存读取的错误定义。
2099
+ * @example
2100
+ * ```ts
2101
+ * import { err, HaiConfigError } from '@h-ai/core'
2102
+ * const result = err(HaiConfigError.CONFIG_NOT_LOADED, 'App configuration is unavailable')
2103
+ * if (!result.success) result.error.message
2104
+ * ```
2105
+ */
2106
+ declare const HaiConfigError: {
2107
+ readonly CONFIG_FILE_NOT_FOUND: HaiErrorDef;
2108
+ readonly CONFIG_PARSE_ERROR: HaiErrorDef;
2109
+ readonly CONFIG_VALIDATION_ERROR: HaiErrorDef;
2110
+ readonly CONFIG_ENV_VAR_MISSING: HaiErrorDef;
2111
+ readonly CONFIG_NOT_LOADED: HaiErrorDef;
2112
+ };
2113
+ /**
2114
+ * 分页参数输入(可选字段,未提供时使用默认值)。
2115
+ * @example
2116
+ * ```ts
2117
+ * import type { PaginationOptionsInput } from '@h-ai/core'
2118
+ * const value: PaginationOptionsInput = { page: 2, pageSize: 20 }
2119
+ * ```
2120
+ */
2121
+ interface PaginationOptionsInput {
2122
+ /** 页码(从 1 开始,默认 1) */
2123
+ page?: number;
2124
+ /** 每页数量(默认由业务层决定) */
2125
+ pageSize?: number;
2126
+ }
2127
+ /**
2128
+ * 分页参数(必填,已确定具体值)。
2129
+ * @example
2130
+ * ```ts
2131
+ * import type { PaginationOptions } from '@h-ai/core'
2132
+ * const value: PaginationOptions = { page: 1, pageSize: 20 }
2133
+ * ```
2134
+ */
2135
+ interface PaginationOptions {
2136
+ /** 页码(从 1 开始) */
2137
+ page: number;
2138
+ /** 每页数量 */
2139
+ pageSize: number;
2140
+ }
2141
+ /**
2142
+ * 分页结果。
2143
+ *
2144
+ * @template T - 数据项类型
2145
+ * @example
2146
+ * ```ts
2147
+ * import type { PaginatedResult } from '@h-ai/core'
2148
+ * const page: PaginatedResult<{ id: string }> = { items: [{ id: 'order-1' }], total: 1, page: 1, pageSize: 20 }
2149
+ * const ids = page.items.map(item => item.id)
2150
+ * ```
2151
+ */
2152
+ interface PaginatedResult<T> {
2153
+ /** 当前页数据 */
2154
+ items: T[];
2155
+ /** 总数量 */
2156
+ total: number;
2157
+ /** 页码(从 1 开始) */
2158
+ page: number;
2159
+ /** 每页数量 */
2160
+ pageSize: number;
2161
+ }
2162
+ /**
2163
+ * 日志上下文。
2164
+ * @example
2165
+ * ```ts
2166
+ * import type { LogContext } from '@h-ai/core'
2167
+ * const value: LogContext = { requestId: 'request-1', level: 'info' }
2168
+ * ```
2169
+ */
2170
+ interface LogContext {
2171
+ timestamp?: Date;
2172
+ level?: LogLevel;
2173
+ message?: string;
2174
+ [key: string]: unknown;
2175
+ }
2176
+ /**
2177
+ * 可信关联范围,不包含访问令牌。Node 异步请求/任务隔离,浏览器仅同步作用域。
2178
+ * @example
2179
+ * ```ts
2180
+ * import type { RequestContext } from '@h-ai/core'
2181
+ * const context: RequestContext = { requestId: 'request-1', scopeId: 'tenant-1', userId: 'user-1' }
2182
+ * ```
2183
+ */
2184
+ interface RequestContext {
2185
+ readonly requestId?: string;
2186
+ readonly traceId?: string;
2187
+ readonly scopeId?: string;
2188
+ readonly userId?: string;
2189
+ readonly jobId?: string;
2190
+ /** 内部采集/存储路径可暂停观察回调,常规日志输出仍执行。 */
2191
+ readonly suppressLogObservers?: boolean;
2192
+ }
2193
+ /**
2194
+ * 经过当前级别和脱敏策略的日志,不代表日志已持久化。
2195
+ * @example
2196
+ * ```ts
2197
+ * import type { LogRecord } from '@h-ai/core'
2198
+ * const record: LogRecord = { timestamp: 1, level: 'error', message: 'Request failed', context: { requestId: 'request-1' } }
2199
+ * ```
2200
+ */
2201
+ interface LogRecord {
2202
+ readonly timestamp: number;
2203
+ readonly level: LogLevel;
2204
+ readonly message: string;
2205
+ readonly context: Readonly<LogContext>;
2206
+ }
2207
+ /**
2208
+ * 同步日志观察者;只做有界内存收集,I/O 由消费者异步处理。
2209
+ * @example
2210
+ * ```ts
2211
+ * import { core, type LogObserver } from '@h-ai/core'
2212
+ * const observer: LogObserver = record => { const requestId = record.context.requestId }
2213
+ * const unsubscribe = core.logger.observe(observer)
2214
+ * unsubscribe()
2215
+ * ```
2216
+ */
2217
+ type LogObserver = (record: LogRecord) => void;
2218
+ /**
2219
+ * 日志选项。
2220
+ * @example
2221
+ * ```ts
2222
+ * import type { LoggerOptions } from '@h-ai/core'
2223
+ * const value: LoggerOptions = { name: 'orders', level: 'debug', context: { service: 'api' } }
2224
+ * ```
2225
+ */
2226
+ interface LoggerOptions {
2227
+ name?: string;
2228
+ /** 显式级别保持不变;未指定时动态继承全局配置。 */
2229
+ level?: LogLevel;
2230
+ /** 显式格式保持不变;未指定时动态继承全局配置。 */
2231
+ format?: LogFormat;
2232
+ /** 固定上下文覆盖当前全局上下文,调用时上下文可进一步覆盖。 */
2233
+ context?: Record<string, unknown>;
2234
+ }
2235
+ /**
2236
+ * Logger 接口。
2237
+ * 统一的日志记录接口,具体实现由 Provider 提供。
2238
+ * @example
2239
+ * ```ts
2240
+ * import { core, type Logger } from '@h-ai/core'
2241
+ * const logger: Logger = core.logger.child({ service: 'orders' })
2242
+ * logger.info('Order created', { orderId: 'order-1' })
2243
+ * ```
2244
+ */
2245
+ interface Logger {
2246
+ trace: (message: string, context?: LogContext) => void;
2247
+ debug: (message: string, context?: LogContext) => void;
2248
+ info: (message: string, context?: LogContext) => void;
2249
+ warn: (message: string, context?: LogContext) => void;
2250
+ error: (message: string, context?: LogContext) => void;
2251
+ fatal: (message: string, context?: LogContext) => void;
2252
+ child: (context: Record<string, unknown>) => Logger;
2253
+ }
2254
+ /**
2255
+ * Core 公共 Logger — Logger 实例 + 管理方法。
2256
+ * @example
2257
+ * ```ts
2258
+ * import { core, type CoreLogger } from '@h-ai/core'
2259
+ * const logger: CoreLogger = core.logger
2260
+ * logger.configure({ level: 'warn', redact: ['password'] })
2261
+ * logger.child({ component: 'worker' }).warn('Retry scheduled')
2262
+ * ```
2263
+ */
2264
+ interface CoreLogger extends Logger {
2265
+ /**
2266
+ * 观察通过日志级别与脱敏策略的记录,返回取消函数;异常与同步重入被隔离。
2267
+ * @example
2268
+ * ```ts
2269
+ * import { core } from '@h-ai/core'
2270
+ * const records: string[] = []
2271
+ * const unsubscribe = core.logger.observe(record => { records.push(record.message) })
2272
+ * core.logger.info('Application ready')
2273
+ * unsubscribe()
2274
+ * ```
2275
+ */
2276
+ observe: (observer: LogObserver) => () => void;
2277
+ /** 创建新的 Logger 实例 */
2278
+ create: (options?: LoggerOptions) => Logger;
2279
+ /** 配置全局 Logger 选项,后续输出同时应用到已有默认、模块与 child Logger。 */
2280
+ configure: (config: Partial<LoggingConfig>) => void;
2281
+ /** 设置全局日志级别 */
2282
+ setLevel: (level: LogLevel) => void;
2283
+ /** 获取当前全局日志级别 */
2284
+ getLevel: () => LogLevel;
2285
+ }
2286
+ /**
2287
+ * Logger 函数组合(平台实现依赖)。
2288
+ *
2289
+ * 由各平台(Node.js / Browser)提供具体实现,通过 `createCore()` 注入。
2290
+ * @example
2291
+ * ```ts
2292
+ * import { core, type LoggerFunctions } from '@h-ai/core'
2293
+ * const platform: LoggerFunctions = { createLogger: options => core.logger.create(options), getLogger: name => core.logger.create({ name }), configureLogger: config => core.logger.configure(config), setLogLevel: level => core.logger.setLevel(level), getLogLevel: () => core.logger.getLevel() }
2294
+ * platform.createLogger({ name: 'worker' }).info('Worker ready')
2295
+ * ```
2296
+ */
2297
+ interface LoggerFunctions {
2298
+ /** 创建新的 Logger 实例 */
2299
+ createLogger: (options?: LoggerOptions) => Logger;
2300
+ /** 获取默认或命名 Logger 实例(单例) */
2301
+ getLogger: (name?: string) => Logger;
2302
+ /** 配置全局 Logger 选项(级别、格式、上下文等) */
2303
+ configureLogger: (config: Partial<LoggingConfig>) => void;
2304
+ /** 设置全局日志级别 */
2305
+ setLogLevel: (level: LogLevel) => void;
2306
+ /** 获取当前全局日志级别 */
2307
+ getLogLevel: () => LogLevel;
2308
+ }
2309
+ /**
2310
+ * Core 配置选项。
2311
+ * @example
2312
+ * ```ts
2313
+ * import type { CoreOptions } from '@h-ai/core'
2314
+ * const value: CoreOptions = { configDir: './config', watchConfig: false }
2315
+ * ```
2316
+ */
2317
+ interface CoreOptions {
2318
+ /** 日志配置 */
2319
+ logging?: Partial<LoggingConfig>;
2320
+ /**
2321
+ * 配置目录(约定优于配置模式)
2322
+ *
2323
+ * 指定后会自动扫描目录中的 yml/yaml 文件:
2324
+ * - `_core.yml` → 自动使用 CoreConfigSchema 校验
2325
+ * - `_xx.yml` → 加载为 'xx'(各模块自行调用 `config.validate` 校验)
2326
+ * - `app.yml` → 加载为 'app'(需使用方自行校验)
2327
+ * 项目构建和部署配置位于根目录 hai.json,不参与运行时 YAML 扫描。
2328
+ *
2329
+ * 单项加载返回失败时记日志并继续;必需配置须检查 `config.validate` 的 success。
2330
+ * 目录扫描等文件系统异常仍可能向调用方传播。
2331
+ *
2332
+ * @example
2333
+ * ```ts
2334
+ * core.init({ configDir: './config' })
2335
+ * ```
2336
+ */
2337
+ configDir?: string;
2338
+ /** 宿主显式提供模块 Schema,供扫描时识别可选字段和环境变量类型;Core 不注册业务模块。 */
2339
+ configSchemas?: Readonly<Record<string, z.ZodType>>;
2340
+ /** 是否启用配置文件监听(默认 false) */
2341
+ watchConfig?: boolean;
2342
+ }
2343
+ /**
2344
+ * 语言代码(ISO 639-1 + 地区代码)。
2345
+ * @example
2346
+ * ```ts
2347
+ * import type { Locale } from '@h-ai/core'
2348
+ * const value: Locale = 'en-US'
2349
+ * ```
2350
+ */
2351
+ type Locale = string;
2352
+ /**
2353
+ * 语言信息。
2354
+ * @example
2355
+ * ```ts
2356
+ * import type { LocaleInfo } from '@h-ai/core'
2357
+ * const value: LocaleInfo = { code: 'en-US', label: 'English' }
2358
+ * ```
2359
+ */
2360
+ interface LocaleInfo {
2361
+ /** 语言代码(如 'zh-CN'、'en-US') */
2362
+ code: Locale;
2363
+ /** 显示名称(如 '简体中文'、'English') */
2364
+ label: string;
2365
+ /** 是否为从右到左书写的语言(如阿拉伯语),默认 false */
2366
+ rtl?: boolean;
2367
+ }
2368
+ /**
2369
+ * 插值参数类型。
2370
+ *
2371
+ * 用于 i18n 消息模板中的 `{key}` 占位符替换。
2372
+ * @example
2373
+ * ```ts
2374
+ * import type { InterpolationParams } from '@h-ai/core'
2375
+ * const value: InterpolationParams = { name: 'Alice', count: 2 }
2376
+ * ```
2377
+ */
2378
+ type InterpolationParams = Record<string, string | number | boolean>;
2379
+ /**
2380
+ * 消息字典类型(单语言的 key-value 映射)。
2381
+ * @example
2382
+ * ```ts
2383
+ * import type { MessageDictionary } from '@h-ai/core'
2384
+ * const value: MessageDictionary = { greeting: 'Hello, {name}!' }
2385
+ * ```
2386
+ */
2387
+ type MessageDictionary = Record<string, string>;
2388
+ /**
2389
+ * 多语言消息集合。
2390
+ *
2391
+ * 以 locale 为键,每个 locale 下包含该语言的所有消息 key-value。
2392
+ *
2393
+ * @template K - 消息 key 的联合类型
2394
+ * @example
2395
+ * ```ts
2396
+ * import { core, type LocaleMessages } from '@h-ai/core'
2397
+ * const messages: LocaleMessages<'hello'> = { 'en-US': { hello: 'Hello, {name}!' }, 'zh-CN': { hello: '你好,{name}!' } }
2398
+ * const message = core.i18n.createMessageGetter(messages)
2399
+ * message('hello', { locale: 'en-US', params: { name: 'Alice' } })
2400
+ * ```
2401
+ */
2402
+ type LocaleMessages<K extends string = string> = Record<Locale, Record<K, string>>;
2403
+ /**
2404
+ * 消息获取选项。
2405
+ * @example
2406
+ * ```ts
2407
+ * import type { MessageOptions } from '@h-ai/core'
2408
+ * const value: MessageOptions = { locale: 'en-US', params: { name: 'Alice' } }
2409
+ * ```
2410
+ */
2411
+ interface MessageOptions {
2412
+ /** 指定 locale(不传时依次读取 Node 请求上下文、应用默认语言) */
2413
+ locale?: Locale;
2414
+ /** 插值参数 */
2415
+ params?: InterpolationParams;
2416
+ }
2417
+ /**
2418
+ * Core 服务聚合接口(createCore 返回类型)
2419
+ * @example
2420
+ * ```ts
2421
+ * import { core, type CoreFunctions } from '@h-ai/core'
2422
+ * function createRequestId(tools: CoreFunctions): string { return tools.id.request() }
2423
+ * const requestId = createRequestId(core)
2424
+ * ```
2425
+ */
2426
+ interface CoreFunctions {
2427
+ /**
2428
+ * Node 中跨 await 隔离请求关联,浏览器仅同步作用域;不向下游注入任何凭据。
2429
+ * @example
2430
+ * ```ts
2431
+ * import { core } from '@h-ai/core'
2432
+ * await core.context.run({ requestId: 'request-1' }, async () => {
2433
+ * await Promise.resolve()
2434
+ * core.logger.info('Work completed')
2435
+ * })
2436
+ * const outside = core.context.get()
2437
+ * ```
2438
+ */
2439
+ readonly context: {
2440
+ readonly get: () => Readonly<RequestContext>;
2441
+ readonly run: <T>(context: RequestContext, operation: () => T) => T;
2442
+ };
2443
+ /** 默认 Logger(懒加载单例),同时提供日志管理方法 */
2444
+ readonly logger: CoreLogger;
2445
+ /** 国际化工具 */
2446
+ readonly i18n: I18nFn;
2447
+ /** Zod 校验错误 → i18n 消息映射工具(kit / serv / api-client 共享) */
2448
+ readonly zodValidation: typeof zodValidation;
2449
+ /** ID 生成工具 */
2450
+ readonly id: IdFn;
2451
+ /** 类型检查工具 */
2452
+ readonly typeUtils: TypeUtilFn;
2453
+ /** 对象操作工具 */
2454
+ readonly object: ObjectFn;
2455
+ /** 脱敏工具 */
2456
+ readonly sanitize: SanitizeFn;
2457
+ /** 字符串操作工具 */
2458
+ readonly string: StringFn;
2459
+ /** 数组操作工具 */
2460
+ readonly array: ArrayFn;
2461
+ /** 异步操作工具 */
2462
+ readonly async: AsyncFn;
2463
+ /** 时间操作工具 */
2464
+ readonly time: TimeFn;
2465
+ /** 错误工具 */
2466
+ readonly error: ErrorFn;
2467
+ /** 模块基础工具 */
2468
+ readonly module: ModuleFn;
2469
+ }
2470
+ /**
2471
+ * Node 专属访问工具,通过 core.access 调用;浏览器不提供该能力。
2472
+ * @example
2473
+ * ```ts
2474
+ * import { core, type AccessFunctions } from '@h-ai/core'
2475
+ * const tools: AccessFunctions = core.access
2476
+ * const check = tools.createRequestCheck(false)
2477
+ * const decision = check('/api/v1/sync', 'POST', '192.0.2.10')
2478
+ * ```
2479
+ */
2480
+ interface AccessFunctions {
2481
+ /** 规范化可信宿主地址;非法 IP 返回 undefined。 */
2482
+ normalizeClientIp: (value?: string) => string | undefined;
2483
+ /** 启动编译可信代理;第二参数必须来自 socket 或受信平台。auto 只在受管私有代理部署生效。 */
2484
+ createClientIpResolver: (trustedProxies?: TrustedProxies | readonly string[]) => (request: Request, remoteAddress?: string) => string | undefined;
2485
+ /** 编译共享的 IP/时间条件,供登录许可和其他可信服务端流程使用。 */
2486
+ createConditionCheck: (condition: AccessCondition) => (ip?: string) => AccessDecision;
2487
+ /** 启动读取和编译请求策略;检查期间无文件 I/O、CIDR 解析或全规则扫描。 */
2488
+ createRequestCheck: (input?: RequestAccessConfigInput) => RequestAccessCheck;
2489
+ /** 启动读取最大 1 MiB 的 YAML;相对路径按服务工作目录或显式目录解析,配置失败抛出安全错误。 */
2490
+ loadPolicy: (input?: RequestAccessConfigInput, baseDirectory?: string) => RequestAccessPolicy | false;
2491
+ }
2492
+ /**
2493
+ * Node 入口的完整 Core 形态;访问检查和文件配置不属于浏览器运行时。
2494
+ * @example
2495
+ * ```ts
2496
+ * import { core, type NodeCoreFunctions } from '@h-ai/core'
2497
+ * const tools: NodeCoreFunctions = core
2498
+ * tools.init({ logging: { level: 'info' } })
2499
+ * ```
2500
+ */
2501
+ interface NodeCoreFunctions extends CoreFunctions {
2502
+ readonly access: AccessFunctions;
2503
+ readonly config: ConfigFn;
2504
+ readonly init: (options?: CoreOptions) => void;
2505
+ }
2506
+ /**
2507
+ * 浏览器 Core 形态;文件配置方法明确返回不可用,不包含 Node 的 access 能力。
2508
+ * @example
2509
+ * ```ts
2510
+ * import type { BrowserCoreFunctions } from '@h-ai/core'
2511
+ * function nextId(tools: BrowserCoreFunctions) { return tools.id.request() }
2512
+ * ```
2513
+ */
2514
+ interface BrowserCoreFunctions extends CoreFunctions {
2515
+ readonly config: BrowserConfigFn;
2516
+ readonly init: (options?: CoreOptions) => void;
2517
+ }
2518
+ /**
2519
+ * 运行环境标识;不会自行设置进程环境或初始化模块。
2520
+ * @example
2521
+ * ```ts
2522
+ * import type { Env } from '@h-ai/core'
2523
+ * const value: Env = 'production'
2524
+ * ```
2525
+ */
2526
+ type Env = z.infer<typeof EnvSchema>;
2527
+ /**
2528
+ * 日志输出级别;未显式配置的 Logger 动态继承全局级别。
2529
+ * @example
2530
+ * ```ts
2531
+ * import type { LogLevel } from '@h-ai/core'
2532
+ * const value: LogLevel = 'warn'
2533
+ * ```
2534
+ */
2535
+ type LogLevel = z.infer<typeof LogLevelSchema>;
2536
+ /**
2537
+ * 日志输出格式:JSON 或适合终端阅读的 pretty。
2538
+ * @example
2539
+ * ```ts
2540
+ * import type { LogFormat } from '@h-ai/core'
2541
+ * const value: LogFormat = 'json'
2542
+ * ```
2543
+ */
2544
+ type LogFormat = z.infer<typeof LogFormatSchema>;
2545
+ /**
2546
+ * 经过默认值填充的 Logger 配置;redact 是输出脱敏路径。
2547
+ * @example
2548
+ * ```ts
2549
+ * import { LoggingConfigSchema, type LoggingConfig } from '@h-ai/core'
2550
+ * const config: LoggingConfig = LoggingConfigSchema.parse({})
2551
+ * ```
2552
+ */
2553
+ type LoggingConfig = z.infer<typeof LoggingConfigSchema>;
2554
+ /**
2555
+ * 严格校验后的 Core 配置;业务配置使用独立 Schema。
2556
+ * @example
2557
+ * ```ts
2558
+ * import { CoreConfigSchema, type CoreConfig } from '@h-ai/core'
2559
+ * const config: CoreConfig = CoreConfigSchema.parse({})
2560
+ * ```
2561
+ */
2562
+ type CoreConfig = z.infer<typeof CoreConfigSchema>;
2563
+ /**
2564
+ * 可信代理配置;空数组显式忽略全部转发头。
2565
+ * @example
2566
+ * ```ts
2567
+ * import type { TrustedProxies } from '@h-ai/core'
2568
+ * const proxies: TrustedProxies = []
2569
+ * ```
2570
+ */
2571
+ type TrustedProxies = z.infer<typeof TrustedProxiesSchema>;
2572
+ /**
2573
+ * 已补齐默认值的 IP/时间条件。
2574
+ * @example
2575
+ * ```ts
2576
+ * import { AccessConditionSchema, type AccessCondition } from '@h-ai/core'
2577
+ * const condition: AccessCondition = AccessConditionSchema.parse({})
2578
+ * ```
2579
+ */
2580
+ type AccessCondition = z.infer<typeof AccessConditionSchema>;
2581
+ /**
2582
+ * 已验证的请求策略。
2583
+ * @example
2584
+ * ```ts
2585
+ * import { RequestAccessPolicySchema, type RequestAccessPolicy } from '@h-ai/core'
2586
+ * const policy: RequestAccessPolicy = RequestAccessPolicySchema.parse({ rules: [] })
2587
+ * ```
2588
+ */
2589
+ type RequestAccessPolicy = z.infer<typeof RequestAccessPolicySchema>;
2590
+ /**
2591
+ * 请求访问策略的输入;默认关闭由宿主配置决定。
2592
+ * @example
2593
+ * ```ts
2594
+ * import type { RequestAccessConfigInput } from '@h-ai/core'
2595
+ * const input: RequestAccessConfigInput = { rules: [{ id: 'external', paths: ['/api/v1/external/**'], allowIps: ['192.0.2.10'] }] }
2596
+ * ```
2597
+ */
2598
+ type RequestAccessConfigInput = z.input<typeof RequestAccessConfigSchema>;
2599
+ /**
2600
+ * 路径的应用层加解密要求;不改变 TLS、身份鉴别或访问条件。
2601
+ * @example
2602
+ * ```ts
2603
+ * import type { RequestEncryptionMode } from '@h-ai/core'
2604
+ * const mode: RequestEncryptionMode = 'disabled'
2605
+ * ```
2606
+ */
2607
+ type RequestEncryptionMode = NonNullable<RequestAccessPolicy['rules'][number]['encryption']>;
2608
+ /**
2609
+ * 启动编译后的请求检查器;加密选择只查路径索引,不重新计算 IP 或时间条件。
2610
+ * @example
2611
+ * ```ts
2612
+ * import { core, type RequestAccessCheck } from '@h-ai/core'
2613
+ * const check: RequestAccessCheck = core.access.createRequestCheck({ rules: [{ id: 'partner', paths: ['/api/v1/partner/**'], encryption: 'disabled' }] })
2614
+ * const mode = check.encryption('/api/v1/partner/sync', 'POST')
2615
+ * const decision = check('/api/v1/partner/sync', 'POST', '192.0.2.10')
2616
+ * ```
2617
+ */
2618
+ interface RequestAccessCheck {
2619
+ (pathname: string, method: string, ip?: string): AccessDecision;
2620
+ /** 是否存在强制加密的规则;宿主未装配加密时必须拒绝启动。 */
2621
+ readonly requiresEncryption: boolean;
2622
+ /** 选取路径及方法对应的模式;undefined 表示沿用宿主;无请求期 I/O 或全规则扫描。 */
2623
+ readonly encryption: (pathname: string, method: string) => RequestEncryptionMode | undefined;
2624
+ }
2625
+ /**
2626
+ * 安全判断只携带原因类别及规则编号,不向调用方复制策略内容。
2627
+ * @example
2628
+ * ```ts
2629
+ * import type { AccessDecision } from '@h-ai/core'
2630
+ * const decision: AccessDecision = { allowed: false, reason: 'address', ruleId: 'external' }
2631
+ * ```
2632
+ */
2633
+ type AccessDecision = Readonly<{
2634
+ allowed: true;
2635
+ } | {
2636
+ allowed: false;
2637
+ reason: 'address' | 'time' | 'path';
2638
+ ruleId?: string;
2639
+ }>;
2640
+ /**
2641
+ * id 子工具类型
2642
+ * @example
2643
+ * ```ts
2644
+ * import { core, type IdFn } from '@h-ai/core'
2645
+ * const tools: IdFn = core.id
2646
+ * tools.withPrefix('order_')
2647
+ * ```
2648
+ */
2649
+ type IdFn = typeof id;
2650
+ /**
2651
+ * error 子工具类型
2652
+ * @example 模块内部上下文
2653
+ * ```ts
2654
+ * const tools: ErrorFn = error
2655
+ * tools.buildHaiErrorsDef('orders', { NOT_FOUND: '001:404' })
2656
+ * ```
2657
+ */
2658
+ type ErrorFn = typeof error;
2659
+ /**
2660
+ * 监听回调类型。
2661
+ *
2662
+ * @template T - 配置数据类型
2663
+ * @example 模块内部上下文
2664
+ * ```ts
2665
+ * const callback: WatchCallback<{ enabled: boolean }> = (config, failure) => {
2666
+ * if (failure) { messages.push(failure.message); return }
2667
+ * if (config) messages.push(String(config.enabled))
2668
+ * }
2669
+ * const messages: string[] = []
2670
+ * ```
2671
+ */
2672
+ type WatchCallback<T = unknown> = (config: T | null, error?: HaiError) => void;
2673
+ /**
2674
+ * config 子工具类型
2675
+ * @example
2676
+ * ```ts
2677
+ * import { core, type ConfigFn } from '@h-ai/core'
2678
+ * const result = core.config.load('app', '/srv/app/config/app.yml')
2679
+ * if (!result.success) result.error.message
2680
+ * ```
2681
+ */
2682
+ type ConfigFn = typeof config;
2683
+ /**
2684
+ * config 子工具类型
2685
+ * @example
2686
+ * ```ts
2687
+ * import { core, type BrowserConfigFn } from '@h-ai/core'
2688
+ * const result = core.config.load('app', '/srv/app/config/app.yml')
2689
+ * if (!result.success) result.error.message
2690
+ * ```
2691
+ */
2692
+ type BrowserConfigFn = typeof config$1;
2693
+ /**
2694
+ * i18n 子工具类型
2695
+ * @example
2696
+ * ```ts
2697
+ * import { core, type I18nFn } from '@h-ai/core'
2698
+ * const tools: I18nFn = core.i18n
2699
+ * const message = tools.createMessageGetter({ 'en-US': { hello: 'Hello' }, 'zh-CN': { hello: '你好' } })
2700
+ * message('hello', { locale: 'en-US' })
2701
+ * ```
2702
+ */
2703
+ type I18nFn = typeof i18n;
2704
+ /**
2705
+ * array 子工具类型
2706
+ * @example
2707
+ * ```ts
2708
+ * import { core, type ArrayFn } from '@h-ai/core'
2709
+ * const tools: ArrayFn = core.array
2710
+ * tools.chunk([1, 2, 3], 2)
2711
+ * ```
2712
+ */
2713
+ type ArrayFn = typeof array;
2714
+ /**
2715
+ * async 子工具类型
2716
+ * @example
2717
+ * ```ts
2718
+ * import { core, type AsyncFn } from '@h-ai/core'
2719
+ * const tools: AsyncFn = core.async
2720
+ * await tools.retry(async () => 'ready', { maxRetries: 2 })
2721
+ * ```
2722
+ */
2723
+ type AsyncFn = typeof async;
2724
+ /**
2725
+ * object 子工具类型
2726
+ * @example
2727
+ * ```ts
2728
+ * import { core, type ObjectFn } from '@h-ai/core'
2729
+ * const tools: ObjectFn = core.object
2730
+ * tools.pick({ id: 'order-1', password: 'example-only' }, ['id'])
2731
+ * ```
2732
+ */
2733
+ type ObjectFn = typeof object;
2734
+ /**
2735
+ * string 子工具类型
2736
+ * @example
2737
+ * ```ts
2738
+ * import { core, type StringFn } from '@h-ai/core'
2739
+ * const tools: StringFn = core.string
2740
+ * tools.camelCase('order-created')
2741
+ * ```
2742
+ */
2743
+ type StringFn = typeof string;
2744
+ /**
2745
+ * time 子工具类型
2746
+ * @example
2747
+ * ```ts
2748
+ * import { core, type TimeFn } from '@h-ai/core'
2749
+ * const tools: TimeFn = core.time
2750
+ * tools.addDays(new Date('2026-01-01T00:00:00Z'), 1)
2751
+ * ```
2752
+ */
2753
+ type TimeFn = typeof time;
2754
+ /**
2755
+ * typeUtils 子工具类型
2756
+ * @example
2757
+ * ```ts
2758
+ * import { core, type TypeUtilFn } from '@h-ai/core'
2759
+ * const tools: TypeUtilFn = core.typeUtils
2760
+ * const value: unknown = 'order-1'
2761
+ * if (tools.isString(value)) value.toUpperCase()
2762
+ * ```
2763
+ */
2764
+ type TypeUtilFn = typeof typeUtils;
2765
+ /**
2766
+ * 未初始化工具集返回类型。
2767
+ *
2768
+ * 提供错误创建、HaiResult 包装和 Proxy 代理等能力,
2769
+ * 用于模块未初始化时的安全回退。
2770
+ *
2771
+ * @template E - 模块错误类型(必须继承 HaiError)
2772
+ * @example
2773
+ * ```ts
2774
+ * import { core, type HaiError, type NotInitializedKit } from '@h-ai/core'
2775
+ * const state: NotInitializedKit<HaiError> = core.module.createNotInitializedKit({ code: 'app:orders:001', httpStatus: 503, system: 'app', module: 'orders' }, () => 'Orders unavailable')
2776
+ * const result = state.result<string>()
2777
+ * if (!result.success) result.error.message
2778
+ * ```
2779
+ */
2780
+ interface NotInitializedKit<E extends HaiError> {
2781
+ /** 创建未初始化错误对象 */
2782
+ error: () => E;
2783
+ /** 创建包含未初始化错误的失败 HaiResult */
2784
+ result: <T>() => HaiResult<T>;
2785
+ /**
2786
+ * 创建 Proxy 代理,拦截所有方法调用并返回未初始化错误。
2787
+ *
2788
+ * @param mode - 'async'(默认)所有方法返回 `Promise<HaiResult>`;'sync' 所有方法返回 `HaiResult`
2789
+ */
2790
+ proxy: <T>(mode?: 'async' | 'sync') => T;
2791
+ }
2792
+ /** module 子工具类型 */
2793
+ /**
2794
+ * 未初始化代理的两个重载:错误定义或具体错误码。
2795
+ * @example
2796
+ * ```ts
2797
+ * import { core, type CreateNotInitializedKitFn } from '@h-ai/core'
2798
+ * const create: CreateNotInitializedKitFn = core.module.createNotInitializedKit
2799
+ * const state = create({ code: 'app:orders:001', httpStatus: 503, system: 'app', module: 'orders' }, () => 'Orders unavailable')
2800
+ * const result = state.result<string>()
2801
+ * if (!result.success) result.error.code
2802
+ * ```
2803
+ */
2804
+ interface CreateNotInitializedKitFn {
2805
+ (codeOrDef: HaiErrorDef, messageFn: () => string): NotInitializedKit<HaiError>;
2806
+ <E extends HaiError>(codeOrDef: E['code'], messageFn: () => string): NotInitializedKit<E>;
2807
+ }
2808
+ /**
2809
+ * 模块初始化占位与生产共享状态要求的工具契约。
2810
+ * @example 模块内部上下文
2811
+ * ```ts
2812
+ * function createHostRuntime(tools: ModuleFn) { return tools.createRuntime([]) }
2813
+ * ```
2814
+ */
2815
+ interface ModuleFn {
2816
+ /** 顺序启动和反序关闭真实模块;不持有业务配置。 */
2817
+ createRuntime: typeof createRuntime;
2818
+ createNotInitializedKit: CreateNotInitializedKitFn;
2819
+ /** 生产共享状态要求;浏览器工具为纯函数,不隐式读取进程环境。 */
2820
+ requiresSharedState: typeof requiresSharedState;
2821
+ }
2822
+ /**
2823
+ * 敏感字段匹配器
2824
+ * @example
2825
+ * ```ts
2826
+ * import { core, type SensitiveKeyMatcher } from '@h-ai/core'
2827
+ * const matcher: SensitiveKeyMatcher = ['password', 'credential']
2828
+ * const safe = core.sanitize.sanitizeSensitiveFields({ credential: 'example-only', id: 'order-1' }, { matcher })
2829
+ * ```
2830
+ */
2831
+ type SensitiveKeyMatcher = RegExp | string[] | ((key: string) => boolean);
2832
+ /**
2833
+ * 敏感字段脱敏选项
2834
+ * @example
2835
+ * ```ts
2836
+ * import { core, type SanitizeSensitiveFieldsOptions } from '@h-ai/core'
2837
+ * const options: SanitizeSensitiveFieldsOptions = { matcher: ['credential'], replacement: '[HIDDEN]' }
2838
+ * const safe = core.sanitize.sanitizeSensitiveFields({ credential: 'example-only' }, options)
2839
+ * ```
2840
+ */
2841
+ interface SanitizeSensitiveFieldsOptions {
2842
+ /** 自定义敏感字段匹配规则 */
2843
+ matcher?: SensitiveKeyMatcher;
2844
+ /** 自定义脱敏替换值 */
2845
+ replacement?: unknown;
2846
+ }
2847
+ /**
2848
+ * sanitize 子工具类型
2849
+ * @example
2850
+ * ```ts
2851
+ * import { core, type SanitizeFn } from '@h-ai/core'
2852
+ * const tools: SanitizeFn = core.sanitize
2853
+ * tools.sanitizeSensitiveFields({ apiKey: 'example-only', id: 'order-1' })
2854
+ * ```
2855
+ */
2856
+ type SanitizeFn = typeof sanitize;
2857
+ /**
2858
+ * 单个真实模块或业务钩子的资源所有权;close 应可重试。
2859
+ * @example 模块内部上下文
2860
+ * ```ts
2861
+ * const step: RuntimeStep = { name: 'example', start: () => {}, close: () => {} }
2862
+ * ```
2863
+ */
2864
+ interface RuntimeStep {
2865
+ name: string;
2866
+ enabled?: () => boolean;
2867
+ start: () => void | HaiResult<unknown> | Promise<void | HaiResult<unknown>>;
2868
+ close: () => void | HaiResult<unknown> | Promise<void | HaiResult<unknown>>;
2869
+ }
2870
+ /**
2871
+ * 初始化和关闭合并并发调用;失败关闭保留自身及尚未关闭的依赖,供下次重试。
2872
+ * @example
2873
+ * ```ts
2874
+ * import { core, type ModuleRuntime } from '@h-ai/core'
2875
+ * const runtime: ModuleRuntime = core.module.createRuntime([])
2876
+ * await runtime.close()
2877
+ * ```
2878
+ */
2879
+ interface ModuleRuntime {
2880
+ readonly isInitialized: boolean;
2881
+ start: () => Promise<HaiResult<void>>;
2882
+ close: () => Promise<HaiResult<void>>;
2883
+ }
2884
+
2885
+ export { type PaginationOptionsInput as $, type AccessCondition as A, type BrowserCoreFunctions as B, type ConfigFn as C, LogFormatSchema as D, type Env as E, type LogLevel as F, LogLevelSchema as G, HaiCommonError as H, type I18nFn as I, type LogObserver as J, type LogRecord as K, type Locale as L, type Logger as M, type LoggerFunctions as N, type LoggerOptions as O, type LoggingConfig as P, LoggingConfigSchema as Q, type MatchHandlers as R, type MessageDictionary as S, type MessageOptions as T, type ModuleFn as U, type ModuleRuntime as V, type NodeCoreFunctions as W, type NotInitializedKit as X, type ObjectFn as Y, type PaginatedResult as Z, type PaginationOptions as _, AccessConditionSchema as a, type RequestAccessCheck as a0, type RequestAccessConfigInput as a1, RequestAccessConfigSchema as a2, type RequestAccessPolicy as a3, RequestAccessPolicySchema as a4, type RequestContext as a5, type RequestEncryptionMode as a6, type RuntimeStep as a7, type SanitizeFn as a8, type SanitizeSensitiveFieldsOptions as a9, type SensitiveKeyMatcher as aa, type StringFn as ab, type TimeFn as ac, type TrustedProxies as ad, TrustedProxiesSchema as ae, type TypeUtilFn as af, type ValidationFormError as ag, type WatchCallback as ah, type ZodMessageGetter as ai, type ZodValidationFn as aj, type ZodValidationMessageKey as ak, err as al, ok as am, type AccessDecision as b, type AccessFunctions as c, type ArrayFn as d, type AsyncFn as e, type BrowserConfigFn as f, type CoreConfig as g, CoreConfigSchema as h, type CoreFunctions as i, type CoreLogger as j, type CoreOptions as k, type CreateNotInitializedKitFn as l, EnvSchema as m, type ErrorFn as n, type ErrorInfo as o, type ErrorInfoValue as p, HaiConfigError as q, type HaiError as r, type HaiErrorDef as s, type HaiResult as t, type IdFn as u, type InterpolationParams as v, type LocaleInfo as w, type LocaleMessages as x, type LogContext as y, type LogFormat as z };