@h-ai/core 0.1.0-alpha.66 → 0.1.0-alpha.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/node.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { h as CoreFunctions, a1 as config, C as CoreOptions } from './core-function-config.node-7KVlEiFk.js';
2
- export { f as CoreConfig, g as CoreConfigSchema, a as CoreLogger, i as Env, j as EnvSchema, k as ErrorInfo, l as ErrorInfoValue, m as HaiCommonError, n as HaiConfigError, o as HaiError, p as HaiErrorDef, H as HaiResult, q as IdConfig, r as IdConfigSchema, s as InterpolationParams, L as Locale, t as LocaleInfo, u as LocaleMessages, v as LogContext, w as LogFormat, x as LogFormatSchema, y as LogLevel, B as LogLevelSchema, D as Logger, F as LoggerFunctions, G as LoggerOptions, J as LoggingConfig, K as LoggingConfigSchema, N as MatchHandlers, P as MessageDictionary, Q as MessageOptions, R as PaginatedResult, U as PaginationOptions, V as PaginationOptionsInput, X as ValidationFormError, Z as ZodMessageGetter, Y as ZodValidationFn, _ as ZodValidationMessageKey, $ as err, a0 as ok } from './core-function-config.node-7KVlEiFk.js';
1
+ import { h as CoreFunctions, $ as config, C as CoreOptions } from './core-function-config.node-DJ6Hb1ee.js';
2
+ export { f as CoreConfig, g as CoreConfigSchema, a as CoreLogger, i as Env, j as EnvSchema, k as ErrorInfo, l as ErrorInfoValue, m as HaiCommonError, n as HaiConfigError, o as HaiError, p as HaiErrorDef, H as HaiResult, q as InterpolationParams, L as Locale, r as LocaleInfo, s as LocaleMessages, t as LogContext, u as LogFormat, v as LogFormatSchema, w as LogLevel, x as LogLevelSchema, y as Logger, B as LoggerFunctions, D as LoggerOptions, F as LoggingConfig, G as LoggingConfigSchema, J as MatchHandlers, K as MessageDictionary, N as MessageOptions, P as PaginatedResult, Q as PaginationOptions, R as PaginationOptionsInput, V as ValidationFormError, Z as ZodMessageGetter, U as ZodValidationFn, X as ZodValidationMessageKey, Y as err, _ as ok } from './core-function-config.node-DJ6Hb1ee.js';
3
3
  import 'zod';
4
4
 
5
5
  /**
@@ -9,17 +9,28 @@ import 'zod';
9
9
  * @module core-main.node
10
10
  */
11
11
 
12
+ /**
13
+ * Node 入口的 Core 扩展:提供文件配置和初始化;不是额外的公开工厂。
14
+ * @example 模块内部上下文
15
+ * ```ts
16
+ * const tools: NodeCoreFunctions = core
17
+ * tools.init({ logging: { level: 'info' } })
18
+ * tools.logger.info('Core ready')
19
+ * ```
20
+ */
12
21
  type NodeCoreFunctions = CoreFunctions & {
13
22
  readonly config: typeof config;
14
23
  readonly init: typeof initCore;
15
24
  };
16
25
  /**
17
26
  * Core 服务对象 - 聚合常用功能(Node.js)。
18
- *
19
27
  * @example
20
28
  * ```ts
21
- * import { core } from '@h-ai/core'
22
- * core.init({ configDir: './config' })
29
+ * import { core, CoreConfigSchema } from '@h-ai/core'
30
+ * core.init({ configDir: './config' }) // 单项加载失败记录日志并继续。
31
+ * const required = core.config.validate('core', CoreConfigSchema)
32
+ * if (!required.success) core.logger.error('Required config unavailable', { error: required.error })
33
+ * else core.logger.info('Application ready', { name: required.data.name })
23
34
  * ```
24
35
  */
25
36
  declare const core: NodeCoreFunctions;
@@ -28,14 +39,19 @@ declare const core: NodeCoreFunctions;
28
39
  *
29
40
  * 执行流程:
30
41
  * 1. 配置日志(若提供 `options.logging`)
31
- * 2. 扫描并加载配置目录中的所有 YAML 文件
42
+ * 2. 扫描并加载运行时 YAML,跳过保留部署文件 `_deploy.yml` / `_deploy.yaml`
32
43
  * 3. 启用配置文件监听(若 `options.watchConfig` 为 true)
33
44
  *
45
+ * 单项 `config.load` 返回失败时记录日志并继续;必需配置由调用方 `config.validate` 并检查 success。
46
+ *
34
47
  * @param options - 初始化选项
48
+ * @throws 目录扫描、日志设置等异常仍会传播;不把单项配置的失败结果改为异常。
35
49
  *
36
- * @example
50
+ * @example 模块内部上下文
37
51
  * ```ts
38
52
  * core.init({ configDir: './config', watchConfig: true })
53
+ * const required = core.config.validate('core', CoreConfigSchema)
54
+ * if (!required.success) core.logger.error('Required config unavailable', { error: required.error })
39
55
  * ```
40
56
  */
41
57
  declare function initCore(options?: CoreOptions): void;
package/dist/node.js CHANGED
@@ -1,5 +1,8 @@
1
- import { createCore, i18n, err, HaiConfigError, ok, sanitize, typeUtils, CoreConfigSchema } from './chunk-RXNSRXYF.js';
2
- export { CoreConfigSchema, EnvSchema, HaiCommonError, HaiConfigError, IdConfigSchema, LogFormatSchema, LogLevelSchema, LoggingConfigSchema, err, ok } from './chunk-RXNSRXYF.js';
1
+ import { installRequestLocales, createCore, i18n, err, HaiConfigError, ok, sanitize, typeUtils, CoreConfigSchema } from './chunk-AWUFXC35.js';
2
+ export { CoreConfigSchema, EnvSchema, HaiCommonError, HaiConfigError, LogFormatSchema, LogLevelSchema, LoggingConfigSchema, err, ok } from './chunk-AWUFXC35.js';
3
+ import { AsyncLocalStorage } from 'async_hooks';
4
+ import { Buffer } from 'buffer';
5
+ import { timingSafeEqual } from 'crypto';
3
6
  import { existsSync, readFileSync, readdirSync, watch } from 'fs';
4
7
  import { join } from 'path';
5
8
  import process2 from 'process';
@@ -494,9 +497,6 @@ if (process2.platform === "win32" && process2.stdout.isTTY) {
494
497
  if (process2.stderr.setDefaultEncoding) {
495
498
  process2.stderr.setDefaultEncoding("utf8");
496
499
  }
497
- process2.env.LANG = "zh_CN.UTF-8";
498
- process2.env.LC_ALL = "zh_CN.UTF-8";
499
- process2.env.PYTHONIOENCODING = "utf-8";
500
500
  } catch (_e) {
501
501
  }
502
502
  }
@@ -644,6 +644,7 @@ var logger = {
644
644
  };
645
645
 
646
646
  // src/core-main.node.ts
647
+ installRequestLocales(new AsyncLocalStorage());
647
648
  var YAML_EXTENSION_REGEX = /\.ya?ml$/;
648
649
  function createNodeCore() {
649
650
  const baseCore = createCore({
@@ -655,6 +656,24 @@ function createNodeCore() {
655
656
  });
656
657
  return {
657
658
  ...baseCore,
659
+ string: {
660
+ ...baseCore.string,
661
+ /**
662
+ * Node 凭证比较使用原生恒时原语;不同长度直接失败,长度本身不受保护。
663
+ * UTF-16LE 保留孤立代理项,避免 UTF-8 替换字符把两个不同字符串误判为相等。
664
+ * @param a - 第一个原始字符串,不做 Unicode 归一化。
665
+ * @param b - 第二个原始字符串,不做 Unicode 归一化。
666
+ * @returns 字符串的 UTF-16 单元是否完全一致。
667
+ * @example
668
+ * ```ts
669
+ * import { core } from '@h-ai/core'
670
+ * const matches = core.string.constantTimeEqual('example-only', 'example-only')
671
+ * ```
672
+ */
673
+ constantTimeEqual(a, b) {
674
+ return a.length === b.length && timingSafeEqual(Buffer.from(a, "utf16le"), Buffer.from(b, "utf16le"));
675
+ }
676
+ },
658
677
  /** Zod 校验错误 → i18n 消息映射工具(kit / serv / api-client 共享)。 */
659
678
  zodValidation: baseCore.zodValidation,
660
679
  /** 配置管理 */
@@ -675,6 +694,8 @@ function scanConfigDir(configDir) {
675
694
  (f) => f.endsWith(".yml") || f.endsWith(".yaml")
676
695
  );
677
696
  for (const file of files) {
697
+ if (file === "_deploy.yml" || file === "_deploy.yaml")
698
+ continue;
678
699
  const filePath = join(configDir, file);
679
700
  const baseName = file.replace(YAML_EXTENSION_REGEX, "");
680
701
  if (baseName.startsWith("_")) {
package/dist/node.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/functions/core-function-config.node.ts","../src/functions/core-function-logger.node.ts","../src/core-main.node.ts"],"names":["process","result","config","logger","existsSync","join"],"mappings":"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","file":"node.js","sourcesContent":["/**\n * @h-ai/core — 配置管理(Node.js 专用)\n *\n * 提供 YAML 配置文件加载、约定式环境变量映射、显式环境变量插值、缓存管理。\n * @module core-function-config.node\n */\n\nimport type { ZodType } from 'zod'\nimport type { HaiError, HaiResult } from '../core-types.js'\n\nimport { existsSync, readFileSync, watch } from 'node:fs'\nimport { join } from 'node:path'\nimport process from 'node:process'\nimport { parseEnv } from 'node:util'\nimport { parse } from 'yaml'\n\n// ─── 配置文件监听 ───\n\nimport { err, HaiConfigError, ok } from '../core-types.js'\nimport { i18n } from '../i18n/core-i18n-utils.js'\nimport { typeUtils } from '../utils/core-util-type.js'\n\n/** 缓存项(存储已加载的配置及其元信息) */\ninterface CacheEntry<T = unknown> {\n /** 解析后的配置数据 */\n data: T\n /** 配置文件路径 */\n filePath: string\n /** Zod 校验 Schema(重载时复用,无 Schema 加载时为 undefined) */\n schema?: ZodType<T>\n /** 加载时间戳(毫秒) */\n loadedAt: number\n}\n\n// ─── 内部工具 ───\n\n/** 环境变量插值正则(支持 ${VAR} 与 ${VAR:default}) */\nconst ENV_VAR_PATTERN = /\\$\\{([^}:]+)(?::([^}]*))?\\}/g\n\n/** 判断整个字符串是否恰好是单个 ${VAR} 或 ${VAR:default}(用于类型还原) */\nconst FULL_VAR_PATTERN = /^\\$\\{[^}:]+(?::[^}]*)?\\}$/\n\n/**\n * 将环境变量字符串按 YAML 标量规则还原类型。\n *\n * @param value - 环境变量原始字符串\n * @returns 空字符串保持不变;其余值尽量还原为 YAML 原生类型\n */\nfunction parseEnvValue(value: string): unknown {\n // YAML 会把空文档解析为 null;空环境变量仍是明确的字符串值,不能改变其类型。\n if (value === '')\n return ''\n\n try {\n const parsed = parse(value)\n return parsed === undefined ? value : parsed\n }\n catch {\n return value\n }\n}\n\n/**\n * 将配置名或 YAML 路径片段规范化为环境变量片段。\n *\n * camelCase 不拆词,例如 apiKey → APIKEY;非字母数字字符统一为下划线。\n *\n * @param segment - 配置名、键名或数组索引\n * @returns 可用于环境变量名的片段\n */\nfunction normalizeEnvSegment(segment: string): string {\n return segment\n .replace(/[^a-z0-9]+/gi, '_')\n .replace(/^_+|_+$/g, '')\n .toUpperCase()\n}\n\n/**\n * 构建配置项的约定环境变量名。\n *\n * @example `ai` + `llm.apiKey` → `HAI_AI_LLM_APIKEY`\n *\n * @param name - 配置名称\n * @param path - YAML 中从根到叶子的键路径;数组索引也作为一段\n * @returns 以 HAI 开头的环境变量名\n */\nfunction buildConventionEnvName(name: string, path: string[]): string {\n return ['HAI', name, ...path]\n .map(normalizeEnvSegment)\n .filter(Boolean)\n .join('_')\n}\n\n/**\n * 解析配置中的环境变量。\n *\n * 每个叶子配置项都会优先读取 `HAI_<配置名>_<YAML 路径>`;\n * 约定变量不存在时再解析显式 `${VAR}`,显式语法用于指定特殊变量名。\n *\n * @param value - 任意配置值(字符串、数组、对象或原始值)\n * @param name - 配置名称\n * @param path - 当前值的 YAML 路径\n * @returns 插值后的结果;当环境变量缺失且未提供默认值时返回 ENV_VAR_MISSING 错误\n */\nfunction resolveEnv(value: unknown, name: string, path: string[] = []): HaiResult<unknown> {\n // 对象和数组也可整体覆盖,云配置可以注入原 YAML 未声明的连接字段。\n const conventionEnvValue = process.env[buildConventionEnvName(name, path)]\n if (conventionEnvValue !== undefined)\n return ok(parseEnvValue(conventionEnvValue))\n\n if (typeof value === 'string') {\n ENV_VAR_PATTERN.lastIndex = 0\n const hasExplicitEnv = ENV_VAR_PATTERN.test(value)\n ENV_VAR_PATTERN.lastIndex = 0\n\n if (!hasExplicitEnv)\n return ok(value)\n\n let result = value\n // 避免在 while 条件中赋值(满足 lint 规则 no-cond-assign)\n while (true) {\n const match = ENV_VAR_PATTERN.exec(value)\n if (!match)\n break\n\n const [fullMatch, varName, defaultValue] = match\n const envValue = process.env[varName]\n\n // 未提供默认值且环境变量不存在时,返回错误\n if (envValue === undefined && defaultValue === undefined) {\n return err(HaiConfigError.CONFIG_ENV_VAR_MISSING, i18n.coreM('core_configEnvVarMissing', { params: { varName } }))\n }\n result = result.replace(fullMatch, () => envValue ?? defaultValue ?? '')\n }\n\n // 当原值整体是单个 ${VAR:default} 时,插值结果需还原为 YAML 原生类型。\n if (FULL_VAR_PATTERN.test(value))\n return ok(parseEnvValue(result))\n\n return ok(result)\n }\n\n if (Array.isArray(value)) {\n const results: unknown[] = []\n for (const [index, item] of value.entries()) {\n const r = resolveEnv(item, name, [...path, String(index)])\n if (!r.success)\n return r\n results.push(r.data)\n }\n return ok(results)\n }\n\n if (typeUtils.isObject(value)) {\n const results: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value)) {\n const r = resolveEnv(v, name, [...path, k])\n if (!r.success)\n return r\n results[k] = r.data\n }\n return ok(results)\n }\n\n return ok(value)\n}\n\n// ─── 配置管理器 ───\n\n/** 配置缓存 */\nconst configCache = new Map<string, CacheEntry>()\n\n/**\n * 监听回调类型。\n *\n * @template T - 配置数据类型\n *\n * @example\n * ```ts\n * const callback: WatchCallback<AppConfig> = (cfg, error) => {\n * if (error) { core.logger.error('Config reload failed', { error }); return }\n * // 使用更新后的 cfg\n * }\n * ```\n */\nexport type WatchCallback<T = unknown> = (config: T | null, error?: HaiError) => void\n\n/** 配置监听条目(包含文件 watcher 和回调集合) */\ninterface WatchEntry {\n /** fs.watch 返回的 watcher 实例 */\n watcher: ReturnType<typeof watch>\n /** 已注册的回调函数集合 */\n callbacks: Set<WatchCallback<unknown>>\n /** 防抖定时器(用于 stopWatching 时清理) */\n debounceTimer: ReturnType<typeof setTimeout> | null\n}\n\n/** 配置监听映射 */\nconst watchEntries = new Map<string, WatchEntry>()\n\n/**\n * 创建未加载错误。\n *\n * @param name - 配置名称\n * @returns HaiError,错误码为 NOT_LOADED\n */\nfunction createNotLoadedError(name: string): HaiError {\n const result = err(HaiConfigError.CONFIG_NOT_LOADED, i18n.coreM('core_configNotLoaded', { params: { name } }))\n if (!result.success)\n return result.error\n\n throw new Error('unreachable')\n}\n\n/**\n * 通知监听回调。\n *\n * @param name - 配置名称\n * @param result - 重载结果(成功时传配置数据,失败时传错误)\n */\nfunction notifyWatchCallbacks(name: string, result: HaiResult<unknown>): void {\n const entry = watchEntries.get(name)\n if (!entry)\n return\n\n if (result.success) {\n for (const callback of entry.callbacks) {\n try {\n callback(result.data, undefined)\n }\n catch { /* 隔离单个回调异常,不影响其他回调 */ }\n }\n }\n else {\n for (const callback of entry.callbacks) {\n try {\n callback(null, result.error)\n }\n catch { /* 隔离单个回调异常,不影响其他回调 */ }\n }\n }\n}\n\n/**\n * 加载 YAML 配置文件(不带 Schema 验证)。\n *\n * 流程:检查文件存在 → 读取 YAML → 约定式环境变量映射与显式插值。\n *\n * @param name - 配置名称,用于生成 `HAI_<配置名>_<YAML 路径>` 环境变量名\n * @param filePath - YAML 文件路径\n * @returns 解析结果;可能的错误码:FILE_NOT_FOUND / PARSE_ERROR / ENV_VAR_MISSING\n */\nfunction loadYaml(name: string, filePath: string): HaiResult<unknown> {\n if (!existsSync(filePath)) {\n return err(HaiConfigError.CONFIG_FILE_NOT_FOUND, i18n.coreM('core_configFileNotExist', { params: { filePath } }))\n }\n\n try {\n const content = readFileSync(filePath, 'utf-8')\n const parsed = parse(content)\n return resolveEnv(parsed, name)\n }\n catch (error) {\n return err(HaiConfigError.CONFIG_PARSE_ERROR, i18n.coreM('core_configParseFailed', { params: { filePath } }), error)\n }\n}\n\n/**\n * 加载并验证配置文件。\n *\n * 流程:加载 YAML → 环境变量映射与插值 → Zod Schema 校验。\n *\n * @param name - 配置名称\n * @param filePath - YAML 文件路径\n * @param schema - Zod 校验 Schema\n * @returns 校验后的配置数据;可能的错误码:FILE_NOT_FOUND / PARSE_ERROR / ENV_VAR_MISSING / VALIDATION_ERROR\n */\nfunction loadConfig<T>(\n name: string,\n filePath: string,\n schema: ZodType<T>,\n): HaiResult<T> {\n const yamlResult = loadYaml(name, filePath)\n if (!yamlResult.success)\n return yamlResult\n\n const parseResult = schema.safeParse(yamlResult.data)\n if (!parseResult.success) {\n return err(HaiConfigError.CONFIG_VALIDATION_ERROR, i18n.coreM('core_configValidationFailed'), parseResult.error.issues)\n }\n\n return ok(parseResult.data)\n}\n\n/**\n * 加载配置并写入缓存。\n *\n * @param name - 配置名称(缓存 key)\n * @param filePath - YAML 文件路径\n * @param schema - 可选 Zod Schema(不传则跳过校验)\n * @returns 加载结果;成功时同时更新缓存\n */\nfunction loadAndCache<T>(\n name: string,\n filePath: string,\n schema?: ZodType<T>,\n): HaiResult<T> {\n const result = schema ? loadConfig(name, filePath, schema) : loadYaml(name, filePath) as HaiResult<T>\n if (result.success) {\n configCache.set(name, {\n data: result.data,\n filePath,\n schema: schema as ZodType<unknown> | undefined,\n loadedAt: Date.now(),\n })\n }\n return result\n}\n\n/**\n * 校验已加载的配置并写回缓存。\n *\n * 从缓存中取出原始数据重新用 Schema 校验,校验通过后更新缓存。\n *\n * @param name - 配置名称\n * @param schema - Zod Schema\n * @returns 校验结果;未加载时返回 NOT_LOADED,校验失败返回 VALIDATION_ERROR\n */\nfunction validateLoadedConfig<T>(name: string, schema: ZodType<T>): HaiResult<T> {\n const entry = configCache.get(name)\n if (!entry) {\n return err(createNotLoadedError(name))\n }\n\n const parseResult = schema.safeParse(entry.data)\n if (!parseResult.success) {\n return err(HaiConfigError.CONFIG_VALIDATION_ERROR, i18n.coreM('core_configValidationFailed'), parseResult.error.issues)\n }\n\n const validated = parseResult.data\n configCache.set(name, {\n ...entry,\n data: validated,\n schema,\n loadedAt: Date.now(),\n })\n\n return ok(validated)\n}\n\n/**\n * 重新加载配置并通知监听器。\n *\n * 从缓存中获取文件路径和 Schema,重新加载并触发所有 watch 回调。\n *\n * @param name - 配置名称\n * @returns 重载结果;未加载时返回 NOT_LOADED\n */\nfunction reloadAndNotify(name: string): HaiResult<unknown> {\n const entry = configCache.get(name)\n if (!entry) {\n const result = err(createNotLoadedError(name))\n notifyWatchCallbacks(name, result)\n return result\n }\n\n // 无 Schema 时直接加载 YAML(不做校验),避免 schema 为 undefined 导致运行时崩溃\n const result = entry.schema ? loadConfig(name, entry.filePath, entry.schema) : loadYaml(name, entry.filePath)\n if (result.success) {\n configCache.set(name, {\n ...entry,\n data: result.data,\n loadedAt: Date.now(),\n })\n }\n notifyWatchCallbacks(name, result)\n return result\n}\n\n/**\n * 启动配置文件监听。\n *\n * 使用 `fs.watch` 监听文件变更,变更时自动重载并通知回调。\n * 同一配置名只会创建一个 watcher,多次调用返回同一实例。\n *\n * @param name - 配置名称\n * @returns WatchEntry 实例;配置未加载时返回 null\n */\nfunction startFileWatcher(name: string): WatchEntry | null {\n const existing = watchEntries.get(name)\n if (existing)\n return existing\n\n const entry = configCache.get(name)\n if (!entry)\n return null\n\n try {\n const watchEntry: WatchEntry = {\n watcher: null!,\n callbacks: new Set(),\n debounceTimer: null,\n }\n\n // 防抖定时器:fs.watch 可能对同一次文件保存触发多次 'change' 事件\n const watcher = watch(entry.filePath, (eventType) => {\n if (eventType === 'change') {\n if (watchEntry.debounceTimer)\n clearTimeout(watchEntry.debounceTimer)\n watchEntry.debounceTimer = setTimeout(() => {\n watchEntry.debounceTimer = null\n reloadAndNotify(name)\n }, 100)\n }\n })\n\n watchEntry.watcher = watcher\n watchEntries.set(name, watchEntry)\n return watchEntry\n }\n catch {\n return null\n }\n}\n\n/**\n * 注册监听回调。\n *\n * 启动文件 watcher(若尚未启动)并注册回调。\n * 配置未加载时立即回调 NOT_LOADED 错误。\n *\n * @param name - 配置名称\n * @param callback - 变更回调\n * @returns 取消监听函数;调用后自动清理(无回调时关闭 watcher)\n */\nfunction registerWatch<T>(name: string, callback: WatchCallback<T>): () => void {\n const entry = startFileWatcher(name)\n if (!entry) {\n callback(null, createNotLoadedError(name))\n return () => { }\n }\n\n entry.callbacks.add(callback as WatchCallback<unknown>)\n\n return () => {\n const current = watchEntries.get(name)\n if (!current)\n return\n\n current.callbacks.delete(callback as WatchCallback<unknown>)\n if (current.callbacks.size === 0) {\n if (current.debounceTimer)\n clearTimeout(current.debounceTimer)\n current.watcher.close()\n watchEntries.delete(name)\n }\n }\n}\n\n/**\n * 停止监听(内部实现)。\n *\n * @param name - 配置名称;不传则停止所有监听并清空映射\n */\nfunction stopWatching(name?: string): void {\n if (name) {\n const entry = watchEntries.get(name)\n if (entry) {\n if (entry.debounceTimer)\n clearTimeout(entry.debounceTimer)\n entry.watcher.close()\n watchEntries.delete(name)\n }\n }\n else {\n for (const entry of watchEntries.values()) {\n if (entry.debounceTimer)\n clearTimeout(entry.debounceTimer)\n entry.watcher.close()\n }\n watchEntries.clear()\n }\n}\n\n/**\n * 清理缓存(同时停止对应监听)。\n *\n * @param name - 配置名称;不传则清理全部缓存并停止所有监听\n */\nfunction clearCache(name?: string): void {\n if (name) {\n configCache.delete(name)\n stopWatching(name)\n }\n else {\n configCache.clear()\n stopWatching()\n }\n}\n\n/**\n * 配置管理对象。\n *\n * @example\n * ```ts\n * const result = config.load('app', './config/app.yml')\n * if (result.success) {\n * const cfg = config.get('app')\n * }\n * ```\n */\nexport const config = {\n /**\n * 读取 dotenv 文件并按统一顺序合并,不修改进程环境。\n *\n * 优先级:已有进程环境 > .env.local > .env.<mode> > .env。\n * development/production 分别映射到 dev/prod;不存在的文件跳过。\n * 返回值可能包含私有配置,仅在 Node 启动/构建边界注入,不下发浏览器。\n * @param options - 文件所在目录及环境模式\n * @param options.mode - dev/test/prod 或 Vite 的 development/production\n * @param options.envDir - dotenv 所在目录,默认进程工作目录\n * @returns 已合并的变量;非法模式或读取失败返回配置错误,不包含文件内容\n * @example\n * ```ts\n * const env = core.config.loadEnvFiles({ mode: 'dev', envDir: '.' })\n * if (!env.success) throw new Error(env.error.message)\n * Object.assign(process.env, env.data)\n * core.init({ configDir: './config' })\n * ```\n */\n loadEnvFiles(options: { mode: string, envDir?: string }): HaiResult<Record<string, string>> {\n const mode = options.mode === 'development' ? 'dev' : options.mode === 'production' ? 'prod' : options.mode\n if (!/^[a-z0-9][\\w-]*$/i.test(mode))\n return err(HaiConfigError.CONFIG_VALIDATION_ERROR, i18n.coreM('core_configValidationFailed'))\n const envDir = options.envDir ?? process.cwd()\n try {\n const merged: Record<string, string> = {}\n for (const name of ['.env', `.env.${mode}`, '.env.local']) {\n const file = join(envDir, name)\n if (existsSync(file))\n Object.assign(merged, parseEnv(readFileSync(file, 'utf8')))\n }\n for (const name of Object.keys(merged)) {\n if (process.env[name] !== undefined)\n merged[name] = process.env[name]\n }\n return ok(merged)\n }\n catch {\n // dotenv 解析异常可能携带原始行,错误边界不暴露文件内容。\n return err(HaiConfigError.CONFIG_PARSE_ERROR, i18n.coreM('core_configParseFailed', { params: { filePath: envDir } }))\n }\n },\n\n /**\n * 加载配置到缓存。\n *\n * 加载 YAML 文件并可选地用 Zod Schema 校验,成功后写入缓存。\n *\n * @param name - 配置名称(缓存 key)\n * @param filePath - YAML 文件路径\n * @param schema - 可选 Zod Schema(不传则跳过校验)\n * @returns 成功时返回解析后的配置数据;失败时返回 HaiError\n *\n * @example\n * ```ts\n * const result = config.load('core', './config/_core.yml', CoreConfigSchema)\n * if (result.success) {\n * // result.data 为校验后的配置\n * }\n * ```\n */\n load<T>(name: string, filePath: string, schema?: ZodType<T>): HaiResult<T> {\n return loadAndCache(name, filePath, schema)\n },\n\n /**\n * 验证已加载的配置数据。\n *\n * 对缓存中的配置数据重新用 Schema 校验,校验通过后更新缓存。\n *\n * @param name - 配置名称\n * @param schema - Zod 验证模式\n * @returns 校验结果;未加载时返回 NOT_LOADED,格式错误返回 VALIDATION_ERROR\n *\n * @example\n * ```ts\n * const result = config.validate('app', AppSchema)\n * if (!result.success) {\n * // result.error.code 可能为 NOT_LOADED 或 VALIDATION_ERROR\n * }\n * ```\n */\n validate<T>(name: string, schema: ZodType<T>): HaiResult<T> {\n return validateLoadedConfig(name, schema)\n },\n\n /**\n * 获取已加载的配置。\n *\n * @param name - 配置名称\n * @returns 配置数据;未加载时返回 undefined\n *\n * @example\n * ```ts\n * const cfg = config.get<CoreConfig>('core')\n * if (cfg) {\n * // 使用 cfg\n * }\n * ```\n */\n get<T>(name: string): T | undefined {\n return configCache.get(name)?.data as T | undefined\n },\n\n /**\n * 获取配置,不存在时抛出错误。\n *\n * @param name - 配置名称\n * @returns 配置数据\n * @throws 配置未加载时抛出 Error\n *\n * @example\n * ```ts\n * try {\n * const cfg = config.getOrThrow<CoreConfig>('core')\n * } catch (e) {\n * // 配置未加载\n * }\n * ```\n */\n getOrThrow<T>(name: string): T {\n const data = this.get<T>(name)\n if (data === undefined) {\n throw new Error(i18n.coreM('core_configNotLoaded', { params: { name } }))\n }\n return data\n },\n\n /**\n * 重新加载配置。\n *\n * 从磁盘重新读取配置文件并更新缓存,同时通知所有 watch 回调。\n *\n * @param name - 配置名称\n * @returns 重载结果;未加载时返回 NOT_LOADED\n *\n * @example\n * ```ts\n * const result = config.reload('app')\n * ```\n */\n reload(name: string): HaiResult<unknown> {\n return reloadAndNotify(name)\n },\n\n /**\n * 检查配置是否已加载。\n *\n * @param name - 配置名称\n * @returns 是否已加载到缓存\n *\n * @example\n * ```ts\n * if (config.has('db')) {\n * const dbCfg = config.get('db')\n * }\n * ```\n */\n has(name: string): boolean {\n return configCache.has(name)\n },\n\n /**\n * 清除配置缓存(同时停止对应监听)。\n *\n * @param name - 配置名称;不传则清除全部\n *\n * @example\n * ```ts\n * config.clear('app') // 清除单个\n * config.clear() // 清除全部\n * ```\n */\n clear(name?: string): void {\n clearCache(name)\n },\n\n /**\n * 获取所有已加载的配置名称。\n *\n * @returns 配置名称数组\n *\n * @example\n * ```ts\n * const names = config.keys() // ['core', 'db', 'app']\n * ```\n */\n keys(): string[] {\n return Array.from(configCache.keys())\n },\n\n /**\n * 监听配置文件变更并自动重载。\n *\n * 文件变更时自动重新加载并调用回调。配置未加载时立即回调 NOT_LOADED 错误。\n *\n * @param name - 配置名称\n * @param callback - 配置变更回调,接收新配置或错误\n * @returns 取消监听函数\n *\n * @example\n * ```ts\n * const unwatch = config.watch('app', (cfg, error) => {\n * if (error) { core.logger.error('reload failed', { error }); return }\n * core.logger.info('config updated', { cfg })\n * })\n * // 取消监听\n * unwatch()\n * ```\n */\n watch<T = unknown>(name: string, callback: WatchCallback<T>): () => void {\n return registerWatch(name, callback)\n },\n\n /**\n * 停止配置文件监听。\n *\n * @param name - 配置名称;不传则停止所有监听\n *\n * @example\n * ```ts\n * config.unwatch('app') // 停止单个\n * config.unwatch() // 停止全部\n * ```\n */\n unwatch(name?: string): void {\n stopWatching(name)\n },\n\n /**\n * 检查是否正在监听某个配置。\n *\n * @param name - 配置名称\n * @returns 是否有活跃的 watcher\n *\n * @example\n * ```ts\n * if (config.isWatching('app')) {\n * config.unwatch('app')\n * }\n * ```\n */\n isWatching(name: string): boolean {\n return watchEntries.has(name)\n },\n}\n\n/** config 子工具类型 */\nexport type ConfigFn = typeof config\n","/**\n * @h-ai/core — Logger(Node.js 版本,基于 pino)\n *\n * 提供统一的日志接口,Node.js 环境使用 pino 实现。\n * @module core-function-logger.node\n */\n\nimport type { LogFormat, LoggingConfig, LogLevel } from '../core-config.js'\nimport type { LogContext, Logger, LoggerFunctions, LoggerOptions } from '../core-types.js'\nimport { execSync } from 'node:child_process'\nimport { createRequire } from 'node:module'\nimport process from 'node:process'\nimport pino from 'pino'\nimport { sanitize as sanitizeUtils } from '../utils/core-util-sanitize.js'\n\n// ESM 场景下通过 createRequire 复用 CommonJS 的 resolve 能力,用来探测可选依赖是否存在。\nconst nodeRequire = createRequire(import.meta.url)\n\nif (process.platform === 'win32' && process.stdout.isTTY) {\n try {\n // 强制切换控制台代码页为 UTF-8(避免 GBK/GB2312 导致的乱码)\n execSync('chcp 65001 > nul', { stdio: 'ignore' })\n\n // 设置 stdout/stderr 编码为 UTF-8\n if (process.stdout.setDefaultEncoding) {\n process.stdout.setDefaultEncoding('utf8')\n }\n if (process.stderr.setDefaultEncoding) {\n process.stderr.setDefaultEncoding('utf8')\n }\n\n // 通过环境变量强制 Node.js 使用 UTF-8\n process.env.LANG = 'zh_CN.UTF-8'\n process.env.LC_ALL = 'zh_CN.UTF-8'\n process.env.PYTHONIOENCODING = 'utf-8'\n }\n // eslint-disable-next-line unused-imports/no-unused-vars\n catch (_e) {\n // 忽略错误,某些环境可能不支持\n }\n}\n\n// ─── 全局配置 ───\n\n/** 全局日志级别(默认 'info') */\nlet globalLevel: LogLevel = 'info'\n\n/** 全局日志格式(默认 'pretty',适合开发环境) */\nlet globalFormat: LogFormat = 'pretty'\n\n/** 全局默认上下文(每条日志自动附带) */\nlet globalContext: Record<string, unknown> = {}\n\n/** 全局脱敏字段路径列表(如 ['password', 'token']) */\nlet globalRedact: string[] = []\n\n/** 格式和脱敏规则变化时,已有 Logger 在下次输出时更新底层实例。 */\nlet outputRevision = 0\n\n/** 默认 Logger 单例缓存 */\nlet defaultLogger: Logger | null = null\n\n/**\n * 配置全局 Logger 选项。\n *\n * @param config - 日志配置\n *\n * @example\n * ```ts\n * logger.configureLogger({ level: 'debug' })\n * ```\n */\nfunction configureLogger(config: Partial<LoggingConfig>): void {\n if (config.level)\n globalLevel = config.level\n if (config.format) {\n globalFormat = config.format\n outputRevision++\n }\n if (config.context)\n globalContext = { ...globalContext, ...config.context }\n if (config.redact) {\n globalRedact = [...config.redact]\n outputRevision++\n }\n}\n\n/**\n * 设置全局日志级别。\n *\n * @param level - 日志级别\n *\n * @example\n * ```ts\n * logger.setLogLevel('warn')\n * ```\n */\nfunction setLogLevel(level: LogLevel): void {\n globalLevel = level\n}\n\n/**\n * 获取当前全局日志级别。\n *\n * @example\n * ```ts\n * const level = logger.getLogLevel()\n * ```\n */\nfunction getLogLevel(): LogLevel {\n return globalLevel\n}\n\nfunction sanitizeLogContext(ctx?: LogContext): LogContext | undefined {\n if (!ctx || Object.keys(ctx).length === 0) {\n return ctx\n }\n\n return sanitizeUtils.sanitizeSensitiveFields(ctx) as LogContext\n}\n\n// ─── Logger 实现 ───\n\n/**\n * 包装 pino 实例为统一 Logger 接口。\n *\n * 将 pino 的原生方法映射为 Logger 接口,自动合并上下文。\n *\n * @param resolvePino - 当前配置对应的 pino 实例\n * @param resolveContext - 当前基础上下文(会与每次调用时的 ctx 合并)\n * @returns 统一 Logger 实例\n */\nfunction wrapPino(resolvePino: () => pino.Logger, resolveContext: () => Record<string, unknown>): Logger {\n return {\n trace(message: string, ctx?: LogContext) {\n resolvePino().trace(sanitizeLogContext({ ...resolveContext(), ...ctx }) ?? {}, message)\n },\n debug(message: string, ctx?: LogContext) {\n resolvePino().debug(sanitizeLogContext({ ...resolveContext(), ...ctx }) ?? {}, message)\n },\n info(message: string, ctx?: LogContext) {\n resolvePino().info(sanitizeLogContext({ ...resolveContext(), ...ctx }) ?? {}, message)\n },\n warn(message: string, ctx?: LogContext) {\n resolvePino().warn(sanitizeLogContext({ ...resolveContext(), ...ctx }) ?? {}, message)\n },\n error(message: string, ctx?: LogContext) {\n resolvePino().error(sanitizeLogContext({ ...resolveContext(), ...ctx }) ?? {}, message)\n },\n fatal(message: string, ctx?: LogContext) {\n resolvePino().fatal(sanitizeLogContext({ ...resolveContext(), ...ctx }) ?? {}, message)\n },\n child(childContext: Record<string, unknown>): Logger {\n // 只保存本地上下文,输出时继承父级的当前配置;不绑定旧 pino child。\n return wrapPino(resolvePino, () => ({ ...resolveContext(), ...childContext }))\n },\n }\n}\n\n/**\n * 创建 Logger 实例。\n *\n * @param options - Logger 选项\n * @returns Logger 实例\n *\n * @example\n * ```ts\n * const appLogger = logger.createLogger({ name: 'api', level: 'info' })\n * appLogger.info('ready')\n * ```\n */\nfunction createLogger(options: LoggerOptions = {}): Logger {\n const localOptions = { ...options, context: { ...options.context } }\n let revision = outputRevision\n let output = createPinoOutput(localOptions)\n const resolvePino = (): pino.Logger => {\n if (revision !== outputRevision) {\n const updated = createPinoOutput(localOptions)\n output.close()\n output = updated\n revision = outputRevision\n }\n const level = localOptions.level ?? globalLevel\n if (output.instance.level !== level)\n output.instance.level = level\n return output.instance\n }\n return wrapPino(resolvePino, () => ({ ...globalContext, ...localOptions.context }))\n}\n\n/** 底层输出只负责格式和脱敏;已有包装在输出时应用当前全局配置。 */\nfunction createPinoOutput(options: LoggerOptions): { instance: pino.Logger, close: () => void } {\n const level = options.level ?? globalLevel\n const format = options.format ?? globalFormat\n\n // 先构造一份与输出介质无关的基础配置,后面再按 transport 能力决定是否启用 pretty。\n const pinoOptions: pino.LoggerOptions = {\n level,\n name: options.name,\n formatters: {\n level: label => ({ level: label }),\n },\n }\n\n // redact 支持\n if (globalRedact.length > 0) {\n pinoOptions.redact = {\n paths: globalRedact,\n censor: '[REDACTED]',\n }\n }\n\n let pinoInstance: pino.Logger\n let transport: ReturnType<typeof pino.transport> | undefined\n\n if (format === 'pretty' && isPrettyTransportAvailable()) {\n // 只有在 pino-pretty 可解析时才挂载 transport,避免可选依赖缺失直接导致 logger 初始化失败。\n try {\n transport = pino.transport({\n target: 'pino-pretty',\n options: {\n colorize: true,\n translateTime: 'SYS:standard',\n ignore: 'pid,hostname',\n },\n })\n pinoInstance = pino(pinoOptions, transport)\n }\n catch (error) {\n // 其他初始化异常应重新抛出,便于排查\n if (isPrettyTransportUnavailable(error)) {\n pinoInstance = pino(pinoOptions)\n }\n else {\n throw error\n }\n }\n }\n else {\n pinoInstance = pino(pinoOptions)\n }\n\n return { instance: pinoInstance, close: () => transport?.end() }\n}\n\nfunction isPrettyTransportAvailable(): boolean {\n try {\n // pino-pretty 是可选依赖,这里用 resolve 做能力探测,避免在缺失场景下直接 import 失败。\n nodeRequire.resolve('pino-pretty')\n return true\n }\n catch {\n return false\n }\n}\n\nfunction isPrettyTransportUnavailable(error: unknown): boolean {\n const message\n = error instanceof Error\n ? error.message\n : typeof error === 'string'\n ? error\n : ''\n\n const normalized = message.toLowerCase()\n\n return normalized.includes('pino-pretty')\n && (normalized.includes('cannot find module')\n || normalized.includes('unable to determine transport target')\n || normalized.includes('cannot load')\n || normalized.includes('not found'))\n}\n\n// ─── 默认 Logger 实例 ───\n\n/**\n * 获取默认 Logger 实例(单例)。\n *\n * @example\n * ```ts\n * const defaultLogger = logger.getLogger()\n * ```\n */\nfunction getLogger(): Logger {\n if (!defaultLogger) {\n defaultLogger = createLogger()\n }\n return defaultLogger\n}\n\n// ─── 对外出口 ───\n\n/**\n * Node.js Logger 函数集合。\n *\n * @example\n * ```ts\n * logger.createLogger({ name: 'service' }).info('boot')\n * ```\n */\nexport const logger: LoggerFunctions = {\n configureLogger,\n setLogLevel,\n getLogLevel,\n createLogger,\n getLogger,\n}\n","/**\n * @h-ai/core — Core 服务聚合(Node.js)\n *\n * 提供 Node.js 环境的 core 对象,聚合常用功能。 所有功能统一通过 core 对象访问,并提供配置加载能力。\n * @module core-main.node\n */\n\nimport type { CoreFunctions, CoreOptions } from './core-types.js'\nimport { existsSync, readdirSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { CoreConfigSchema } from './core-config.js'\nimport { createCore } from './core-main.js'\nimport { config } from './functions/core-function-config.node.js'\nimport { logger } from './functions/core-function-logger.node.js'\n\nconst YAML_EXTENSION_REGEX = /\\.ya?ml$/\ntype NodeCoreFunctions = CoreFunctions & {\n readonly config: typeof config\n readonly init: typeof initCore\n}\n\n// ─── Core 实例 ───\n\n/**\n * 创建 Node.js 版本的 core 对象。\n *\n * @example\n * ```ts\n * import { core } from '@h-ai/core'\n * core.logger.info('ready')\n * ```\n */\nfunction createNodeCore(): NodeCoreFunctions {\n const baseCore = createCore({\n createLogger: logger.createLogger,\n getLogger: logger.getLogger,\n configureLogger: logger.configureLogger,\n setLogLevel: logger.setLogLevel,\n getLogLevel: logger.getLogLevel,\n })\n\n // 扩展 config 和 init 功能\n return {\n ...baseCore,\n /** Zod 校验错误 → i18n 消息映射工具(kit / serv / api-client 共享)。 */\n zodValidation: baseCore.zodValidation,\n /** 配置管理 */\n config,\n /** 初始化 Core */\n init: initCore,\n }\n}\n\n/**\n * Core 服务对象 - 聚合常用功能(Node.js)。\n *\n * @example\n * ```ts\n * import { core } from '@h-ai/core'\n * core.init({ configDir: './config' })\n * ```\n */\nexport const core: NodeCoreFunctions = createNodeCore()\n\n// ─── Initialization ───\n\n/**\n * 配置加载项(描述单个待加载的配置文件)。\n */\ninterface ConfigLoadItem {\n /** 配置名称(用作缓存 key,如 'core'、'db'、'app') */\n name: string\n /** 配置文件绝对路径 */\n filePath: string\n}\n\n/**\n * 扫描配置目录并构建配置加载项列表。\n *\n * 约定:\n * - 以 `_` 开头的文件为内置模块配置(如 `_core.yml` → name='core')\n * - 其他文件为业务配置(如 `app.yml` → name='app')\n *\n * @param configDir - 配置目录路径\n * @returns 配置加载项列表;目录不存在时返回空数组并输出警告\n *\n * @example\n * ```ts\n * const items = scanConfigDir('./config')\n * // [{ name: 'core', filePath: './config/_core.yml' }, { name: 'app', filePath: './config/app.yml' }]\n * ```\n */\nfunction scanConfigDir(\n configDir: string,\n): ConfigLoadItem[] {\n const logger = core.logger\n const items: ConfigLoadItem[] = []\n\n if (!existsSync(configDir)) {\n logger.warn(`[core] Config directory not found: ${configDir}`)\n return items\n }\n\n const files = readdirSync(configDir).filter(f =>\n f.endsWith('.yml') || f.endsWith('.yaml'),\n )\n\n for (const file of files) {\n const filePath = join(configDir, file)\n const baseName = file.replace(YAML_EXTENSION_REGEX, '')\n\n // 判断是否为内置模块配置(以 _ 开头)\n if (baseName.startsWith('_')) {\n const moduleName = baseName.slice(1) // 去掉 _ 前缀\n items.push({\n name: moduleName,\n filePath,\n })\n }\n else {\n // 业务配置(文件名作为配置名)\n items.push({\n name: baseName,\n filePath,\n })\n }\n }\n return items\n}\n\n/**\n * 初始化 Core(内部实现,通过 `core.init()` 调用)。\n *\n * 执行流程:\n * 1. 配置日志(若提供 `options.logging`)\n * 2. 扫描并加载配置目录中的所有 YAML 文件\n * 3. 启用配置文件监听(若 `options.watchConfig` 为 true)\n *\n * @param options - 初始化选项\n *\n * @example\n * ```ts\n * core.init({ configDir: './config', watchConfig: true })\n * ```\n */\nfunction initCore(options: CoreOptions = {}): void {\n const startTime = Date.now()\n const logger = core.logger\n\n // 1. Configure logging\n if (options.logging) {\n core.logger.configure(options.logging)\n }\n\n let configItems: ConfigLoadItem[] = []\n\n if (options.configDir) {\n // 约定优于配置模式\n configItems = scanConfigDir(options.configDir)\n }\n\n // 先应用 core 的日志配置,避免其它配置加载日志使用初始化前的级别与格式。\n configItems.sort((left, right) => Number(right.name === 'core') - Number(left.name === 'core'))\n\n // 2. Load config files\n for (const item of configItems) {\n if (item.name === 'core') {\n const result = config.load(item.name, item.filePath, CoreConfigSchema)\n if (result.success) {\n if (!options.logging) {\n core.logger.configure(result.data.logging || {})\n }\n logger.info(`[core] Config loaded: ${item.name} <- ${item.filePath}`)\n }\n else {\n logger.error(`[core] Config load failed: ${item.name}`, {\n error: result.error,\n })\n }\n }\n else {\n const result = config.load(item.name, item.filePath)\n if (result.success) {\n logger.info(`[core] Config loaded: ${item.name} <- ${item.filePath}`)\n }\n else {\n logger.error(`[core] Config load failed: ${item.name}`, {\n error: result.error,\n })\n }\n }\n }\n\n // 3. Enable config file watching\n if (options.watchConfig && configItems.length > 0) {\n setupConfigWatch(configItems)\n }\n\n const duration = Date.now() - startTime\n logger.info(`[core] Initialized (${duration}ms)`)\n}\n\n/**\n * 启用配置文件监听。\n *\n * 为每个已加载的配置项注册文件 watcher,变更时自动重载并输出日志。\n *\n * @param configs - 需要监听的配置项列表\n */\nfunction setupConfigWatch(configs: ConfigLoadItem[]): void {\n const logger = core.logger\n\n for (const item of configs) {\n config.watch(item.name, (_config, error) => {\n if (error) {\n logger.error(`[core] Config reload failed: ${item.name}`, { error })\n return\n }\n logger.info(`[core] Config reloaded: ${item.name}`)\n })\n\n logger.debug(`[core] Config watch enabled: ${item.name}`)\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/functions/core-function-config.node.ts","../src/functions/core-function-logger.node.ts","../src/core-main.node.ts"],"names":["process","result","config","logger","existsSync","join"],"mappings":"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","file":"node.js","sourcesContent":["/**\n * @h-ai/core — 配置管理(Node.js 专用)\n *\n * 提供 YAML 配置文件加载、约定式环境变量映射、显式环境变量插值、缓存管理。\n * @module core-function-config.node\n */\n\nimport type { ZodType } from 'zod'\nimport type { HaiError, HaiResult } from '../core-types.js'\n\nimport { existsSync, readFileSync, watch } from 'node:fs'\nimport { join } from 'node:path'\nimport process from 'node:process'\nimport { parseEnv } from 'node:util'\nimport { parse } from 'yaml'\n\n// ─── 配置文件监听 ───\n\nimport { err, HaiConfigError, ok } from '../core-types.js'\nimport { i18n } from '../i18n/core-i18n-utils.js'\nimport { typeUtils } from '../utils/core-util-type.js'\n\n/**\n * 缓存项(存储已加载的配置及其元信息)\n * @example 模块内部上下文\n * ```ts\n * const entry: CacheEntry<{ enabled: boolean }> = { data: { enabled: true }, filePath: '/srv/app/config/app.yml', loadedAt: Date.now() }\n * const enabled = entry.data.enabled\n * ```\n */\ninterface CacheEntry<T = unknown> {\n /** 解析后的配置数据 */\n data: T\n /** 配置文件路径 */\n filePath: string\n /** Zod 校验 Schema(重载时复用,无 Schema 加载时为 undefined) */\n schema?: ZodType<T>\n /** 加载时间戳(毫秒) */\n loadedAt: number\n}\n\n// ─── 内部工具 ───\n\n/** 环境变量插值正则(支持 ${VAR} 与 ${VAR:default}) */\nconst ENV_VAR_PATTERN = /\\$\\{([^}:]+)(?::([^}]*))?\\}/g\n\n/** 判断整个字符串是否恰好是单个 ${VAR} 或 ${VAR:default}(用于类型还原) */\nconst FULL_VAR_PATTERN = /^\\$\\{[^}:]+(?::[^}]*)?\\}$/\n\n/**\n * 将环境变量字符串按 YAML 标量规则还原类型。\n *\n * @param value - 环境变量原始字符串\n * @returns 空字符串保持不变;其余值尽量还原为 YAML 原生类型\n */\nfunction parseEnvValue(value: string): unknown {\n // YAML 会把空文档解析为 null;空环境变量仍是明确的字符串值,不能改变其类型。\n if (value === '')\n return ''\n\n try {\n const parsed = parse(value)\n return parsed === undefined ? value : parsed\n }\n catch {\n return value\n }\n}\n\n/**\n * 将配置名或 YAML 路径片段规范化为环境变量片段。\n *\n * camelCase 不拆词,例如 apiKey → APIKEY;非字母数字字符统一为下划线。\n *\n * @param segment - 配置名、键名或数组索引\n * @returns 可用于环境变量名的片段\n */\nfunction normalizeEnvSegment(segment: string): string {\n return segment\n .replace(/[^a-z0-9]+/gi, '_')\n .replace(/^_+|_+$/g, '')\n .toUpperCase()\n}\n\n/**\n * 构建配置项的约定环境变量名。\n *\n * @example `ai` + `llm.apiKey` → `HAI_AI_LLM_APIKEY`\n *\n * @param name - 配置名称\n * @param path - YAML 中从根到叶子的键路径;数组索引也作为一段\n * @returns 以 HAI 开头的环境变量名\n */\nfunction buildConventionEnvName(name: string, path: string[]): string {\n return ['HAI', name, ...path]\n .map(normalizeEnvSegment)\n .filter(Boolean)\n .join('_')\n}\n\n/**\n * 解析配置中的环境变量。\n *\n * 每个叶子配置项都会优先读取 `HAI_<配置名>_<YAML 路径>`;\n * 约定变量不存在时再解析显式 `${VAR}`,显式语法用于指定特殊变量名。\n *\n * @param value - 任意配置值(字符串、数组、对象或原始值)\n * @param name - 配置名称\n * @param path - 当前值的 YAML 路径\n * @returns 插值后的结果;当环境变量缺失且未提供默认值时返回 ENV_VAR_MISSING 错误\n */\nfunction resolveEnv(value: unknown, name: string, path: string[] = []): HaiResult<unknown> {\n // 对象和数组也可整体覆盖,云配置可以注入原 YAML 未声明的连接字段。\n const conventionEnvValue = process.env[buildConventionEnvName(name, path)]\n if (conventionEnvValue !== undefined)\n return ok(parseEnvValue(conventionEnvValue))\n\n if (typeof value === 'string') {\n ENV_VAR_PATTERN.lastIndex = 0\n const hasExplicitEnv = ENV_VAR_PATTERN.test(value)\n ENV_VAR_PATTERN.lastIndex = 0\n\n if (!hasExplicitEnv)\n return ok(value)\n\n let result = value\n // 避免在 while 条件中赋值(满足 lint 规则 no-cond-assign)\n while (true) {\n const match = ENV_VAR_PATTERN.exec(value)\n if (!match)\n break\n\n const [fullMatch, varName, defaultValue] = match\n const envValue = process.env[varName]\n\n // 未提供默认值且环境变量不存在时,返回错误\n if (envValue === undefined && defaultValue === undefined) {\n return err(HaiConfigError.CONFIG_ENV_VAR_MISSING, i18n.coreM('core_configEnvVarMissing', { params: { varName } }))\n }\n result = result.replace(fullMatch, () => envValue ?? defaultValue ?? '')\n }\n\n // 当原值整体是单个 ${VAR:default} 时,插值结果需还原为 YAML 原生类型。\n if (FULL_VAR_PATTERN.test(value))\n return ok(parseEnvValue(result))\n\n return ok(result)\n }\n\n if (Array.isArray(value)) {\n const results: unknown[] = []\n for (const [index, item] of value.entries()) {\n const r = resolveEnv(item, name, [...path, String(index)])\n if (!r.success)\n return r\n results.push(r.data)\n }\n return ok(results)\n }\n\n if (typeUtils.isObject(value)) {\n const results: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value)) {\n const r = resolveEnv(v, name, [...path, k])\n if (!r.success)\n return r\n results[k] = r.data\n }\n return ok(results)\n }\n\n return ok(value)\n}\n\n// ─── 配置管理器 ───\n\n/** 配置缓存 */\nconst configCache = new Map<string, CacheEntry>()\n\n/**\n * 监听回调类型。\n *\n * @template T - 配置数据类型\n * @example 模块内部上下文\n * ```ts\n * const callback: WatchCallback<{ enabled: boolean }> = (config, failure) => {\n * if (failure) { messages.push(failure.message); return }\n * if (config) messages.push(String(config.enabled))\n * }\n * const messages: string[] = []\n * ```\n */\nexport type WatchCallback<T = unknown> = (config: T | null, error?: HaiError) => void\n\n/**\n * 配置监听条目(包含文件 watcher 和回调集合)\n * @example 模块内部上下文\n * ```ts\n * const watcher = watch('/srv/app/config/app.yml', () => {})\n * const entry: WatchEntry = { watcher, callbacks: new Set(), debounceTimer: null }\n * entry.watcher.close()\n * ```\n */\ninterface WatchEntry {\n /** fs.watch 返回的 watcher 实例 */\n watcher: ReturnType<typeof watch>\n /** 已注册的回调函数集合 */\n callbacks: Set<WatchCallback<unknown>>\n /** 防抖定时器(用于 stopWatching 时清理) */\n debounceTimer: ReturnType<typeof setTimeout> | null\n}\n\n/** 配置监听映射 */\nconst watchEntries = new Map<string, WatchEntry>()\n\n/**\n * 创建未加载错误。\n *\n * @param name - 配置名称\n * @returns HaiError,错误码为 NOT_LOADED\n */\nfunction createNotLoadedError(name: string): HaiError {\n const result = err(HaiConfigError.CONFIG_NOT_LOADED, i18n.coreM('core_configNotLoaded', { params: { name } }))\n if (!result.success)\n return result.error\n\n throw new Error('unreachable')\n}\n\n/**\n * 通知监听回调。\n *\n * @param name - 配置名称\n * @param result - 重载结果(成功时传配置数据,失败时传错误)\n */\nfunction notifyWatchCallbacks(name: string, result: HaiResult<unknown>): void {\n const entry = watchEntries.get(name)\n if (!entry)\n return\n\n if (result.success) {\n for (const callback of entry.callbacks) {\n try {\n callback(result.data, undefined)\n }\n catch { /* 隔离单个回调异常,不影响其他回调 */ }\n }\n }\n else {\n for (const callback of entry.callbacks) {\n try {\n callback(null, result.error)\n }\n catch { /* 隔离单个回调异常,不影响其他回调 */ }\n }\n }\n}\n\n/**\n * 加载 YAML 配置文件(不带 Schema 验证)。\n *\n * 流程:检查文件存在 → 读取 YAML → 约定式环境变量映射与显式插值。\n *\n * @param name - 配置名称,用于生成 `HAI_<配置名>_<YAML 路径>` 环境变量名\n * @param filePath - YAML 文件路径\n * @returns 解析结果;可能的错误码:FILE_NOT_FOUND / PARSE_ERROR / ENV_VAR_MISSING\n */\nfunction loadYaml(name: string, filePath: string): HaiResult<unknown> {\n if (!existsSync(filePath)) {\n return err(HaiConfigError.CONFIG_FILE_NOT_FOUND, i18n.coreM('core_configFileNotExist', { params: { filePath } }))\n }\n\n try {\n const content = readFileSync(filePath, 'utf-8')\n const parsed = parse(content)\n return resolveEnv(parsed, name)\n }\n catch (error) {\n return err(HaiConfigError.CONFIG_PARSE_ERROR, i18n.coreM('core_configParseFailed', { params: { filePath } }), error)\n }\n}\n\n/**\n * 加载并验证配置文件。\n *\n * 流程:加载 YAML → 环境变量映射与插值 → Zod Schema 校验。\n *\n * @param name - 配置名称\n * @param filePath - YAML 文件路径\n * @param schema - Zod 校验 Schema\n * @returns 校验后的配置数据;可能的错误码:FILE_NOT_FOUND / PARSE_ERROR / ENV_VAR_MISSING / VALIDATION_ERROR\n */\nfunction loadConfig<T>(\n name: string,\n filePath: string,\n schema: ZodType<T>,\n): HaiResult<T> {\n const yamlResult = loadYaml(name, filePath)\n if (!yamlResult.success)\n return yamlResult\n\n const parseResult = schema.safeParse(yamlResult.data)\n if (!parseResult.success) {\n return err(HaiConfigError.CONFIG_VALIDATION_ERROR, i18n.coreM('core_configValidationFailed'), parseResult.error.issues)\n }\n\n return ok(parseResult.data)\n}\n\n/**\n * 加载配置并写入缓存。\n *\n * @param name - 配置名称(缓存 key)\n * @param filePath - YAML 文件路径\n * @param schema - 可选 Zod Schema(不传则跳过校验)\n * @returns 加载结果;成功时同时更新缓存\n */\nfunction loadAndCache<T>(\n name: string,\n filePath: string,\n schema?: ZodType<T>,\n): HaiResult<T> {\n const result = schema ? loadConfig(name, filePath, schema) : loadYaml(name, filePath) as HaiResult<T>\n if (result.success) {\n configCache.set(name, {\n data: result.data,\n filePath,\n schema: schema as ZodType<unknown> | undefined,\n loadedAt: Date.now(),\n })\n }\n return result\n}\n\n/**\n * 校验已加载的配置并写回缓存。\n *\n * 从缓存中取出原始数据重新用 Schema 校验,校验通过后更新缓存。\n *\n * @param name - 配置名称\n * @param schema - Zod Schema\n * @returns 校验结果;未加载时返回 NOT_LOADED,校验失败返回 VALIDATION_ERROR\n */\nfunction validateLoadedConfig<T>(name: string, schema: ZodType<T>): HaiResult<T> {\n const entry = configCache.get(name)\n if (!entry) {\n return err(createNotLoadedError(name))\n }\n\n const parseResult = schema.safeParse(entry.data)\n if (!parseResult.success) {\n return err(HaiConfigError.CONFIG_VALIDATION_ERROR, i18n.coreM('core_configValidationFailed'), parseResult.error.issues)\n }\n\n const validated = parseResult.data\n configCache.set(name, {\n ...entry,\n data: validated,\n schema,\n loadedAt: Date.now(),\n })\n\n return ok(validated)\n}\n\n/**\n * 重新加载配置并通知监听器。\n *\n * 从缓存中获取文件路径和 Schema,重新加载并触发所有 watch 回调。\n *\n * @param name - 配置名称\n * @returns 重载结果;未加载时返回 NOT_LOADED\n */\nfunction reloadAndNotify(name: string): HaiResult<unknown> {\n const entry = configCache.get(name)\n if (!entry) {\n const result = err(createNotLoadedError(name))\n notifyWatchCallbacks(name, result)\n return result\n }\n\n // 无 Schema 时直接加载 YAML(不做校验),避免 schema 为 undefined 导致运行时崩溃\n const result = entry.schema ? loadConfig(name, entry.filePath, entry.schema) : loadYaml(name, entry.filePath)\n if (result.success) {\n configCache.set(name, {\n ...entry,\n data: result.data,\n loadedAt: Date.now(),\n })\n }\n notifyWatchCallbacks(name, result)\n return result\n}\n\n/**\n * 启动配置文件监听。\n *\n * 使用 `fs.watch` 监听文件变更,变更时自动重载并通知回调。\n * 同一配置名只会创建一个 watcher,多次调用返回同一实例。\n *\n * @param name - 配置名称\n * @returns WatchEntry 实例;配置未加载时返回 null\n */\nfunction startFileWatcher(name: string): WatchEntry | null {\n const existing = watchEntries.get(name)\n if (existing)\n return existing\n\n const entry = configCache.get(name)\n if (!entry)\n return null\n\n try {\n const watchEntry: WatchEntry = {\n watcher: null!,\n callbacks: new Set(),\n debounceTimer: null,\n }\n\n // 防抖定时器:fs.watch 可能对同一次文件保存触发多次 'change' 事件\n const watcher = watch(entry.filePath, (eventType) => {\n if (eventType === 'change') {\n if (watchEntry.debounceTimer)\n clearTimeout(watchEntry.debounceTimer)\n watchEntry.debounceTimer = setTimeout(() => {\n watchEntry.debounceTimer = null\n reloadAndNotify(name)\n }, 100)\n }\n })\n\n watchEntry.watcher = watcher\n watchEntries.set(name, watchEntry)\n return watchEntry\n }\n catch {\n return null\n }\n}\n\n/**\n * 注册监听回调。\n *\n * 启动文件 watcher(若尚未启动)并注册回调。\n * 配置未加载时立即回调 NOT_LOADED 错误。\n *\n * @param name - 配置名称\n * @param callback - 变更回调\n * @returns 取消监听函数;调用后自动清理(无回调时关闭 watcher)\n */\nfunction registerWatch<T>(name: string, callback: WatchCallback<T>): () => void {\n const entry = startFileWatcher(name)\n if (!entry) {\n callback(null, createNotLoadedError(name))\n return () => { }\n }\n\n entry.callbacks.add(callback as WatchCallback<unknown>)\n\n return () => {\n const current = watchEntries.get(name)\n if (!current)\n return\n\n current.callbacks.delete(callback as WatchCallback<unknown>)\n if (current.callbacks.size === 0) {\n if (current.debounceTimer)\n clearTimeout(current.debounceTimer)\n current.watcher.close()\n watchEntries.delete(name)\n }\n }\n}\n\n/**\n * 停止监听(内部实现)。\n *\n * @param name - 配置名称;不传则停止所有监听并清空映射\n */\nfunction stopWatching(name?: string): void {\n if (name) {\n const entry = watchEntries.get(name)\n if (entry) {\n if (entry.debounceTimer)\n clearTimeout(entry.debounceTimer)\n entry.watcher.close()\n watchEntries.delete(name)\n }\n }\n else {\n for (const entry of watchEntries.values()) {\n if (entry.debounceTimer)\n clearTimeout(entry.debounceTimer)\n entry.watcher.close()\n }\n watchEntries.clear()\n }\n}\n\n/**\n * 清理缓存(同时停止对应监听)。\n *\n * @param name - 配置名称;不传则清理全部缓存并停止所有监听\n */\nfunction clearCache(name?: string): void {\n if (name) {\n configCache.delete(name)\n stopWatching(name)\n }\n else {\n configCache.clear()\n stopWatching()\n }\n}\n\n/**\n * 配置管理对象。\n * @example 模块内部上下文\n * ```ts\n * const result = config.load('app', '/srv/app/config/app.yml')\n * if (!result.success) result.error.message\n * ```\n */\nexport const config = {\n /**\n * 读取 dotenv 文件并按统一顺序合并,不修改进程环境。\n *\n * 优先级:已有进程环境 > .env.local > .env.<mode> > .env。\n * development/production 分别映射到 dev/prod;不存在的文件跳过。\n * 返回值可能包含私有配置,仅在 Node 启动/构建边界注入,不下发浏览器。\n * @param options - 文件所在目录及环境模式\n * @param options.mode - dev/test/prod 或 Vite 的 development/production\n * @param options.envDir - dotenv 所在目录,默认进程工作目录\n * @returns 已合并的变量;非法模式或读取失败返回配置错误,不包含文件内容\n * @example\n * ```ts\n * const env = core.config.loadEnvFiles({ mode: 'dev', envDir: '.' })\n * if (!env.success) throw new Error(env.error.message)\n * Object.assign(process.env, env.data)\n * core.init({ configDir: './config' })\n * ```\n */\n loadEnvFiles(options: { mode: string, envDir?: string }): HaiResult<Record<string, string>> {\n const mode = options.mode === 'development' ? 'dev' : options.mode === 'production' ? 'prod' : options.mode\n if (!/^[a-z0-9][\\w-]*$/i.test(mode))\n return err(HaiConfigError.CONFIG_VALIDATION_ERROR, i18n.coreM('core_configValidationFailed'))\n const envDir = options.envDir ?? process.cwd()\n try {\n const merged: Record<string, string> = {}\n for (const name of ['.env', `.env.${mode}`, '.env.local']) {\n const file = join(envDir, name)\n if (existsSync(file))\n Object.assign(merged, parseEnv(readFileSync(file, 'utf8')))\n }\n for (const name of Object.keys(merged)) {\n if (process.env[name] !== undefined)\n merged[name] = process.env[name]\n }\n return ok(merged)\n }\n catch {\n // dotenv 解析异常可能携带原始行,错误边界不暴露文件内容。\n return err(HaiConfigError.CONFIG_PARSE_ERROR, i18n.coreM('core_configParseFailed', { params: { filePath: envDir } }))\n }\n },\n\n /**\n * 加载配置到缓存。\n *\n * 加载 YAML 文件并可选地用 Zod Schema 校验,成功后写入缓存。\n *\n * @param name - 配置名称(缓存 key)\n * @param filePath - YAML 文件路径\n * @param schema - 可选 Zod Schema(不传则跳过校验)\n * @returns 成功时返回解析后的配置数据;失败时返回 HaiError\n *\n * @example\n * ```ts\n * const result = config.load('core', './config/_core.yml', CoreConfigSchema)\n * if (result.success) {\n * // result.data 为校验后的配置\n * }\n * ```\n */\n load<T>(name: string, filePath: string, schema?: ZodType<T>): HaiResult<T> {\n return loadAndCache(name, filePath, schema)\n },\n\n /**\n * 验证已加载的配置数据。\n *\n * 对缓存中的配置数据重新用 Schema 校验,校验通过后更新缓存。\n *\n * @param name - 配置名称\n * @param schema - Zod 验证模式\n * @returns 校验结果;未加载时返回 NOT_LOADED,格式错误返回 VALIDATION_ERROR\n *\n * @example\n * ```ts\n * const result = config.validate('app', AppSchema)\n * if (!result.success) {\n * // result.error.code 可能为 NOT_LOADED 或 VALIDATION_ERROR\n * }\n * ```\n */\n validate<T>(name: string, schema: ZodType<T>): HaiResult<T> {\n return validateLoadedConfig(name, schema)\n },\n\n /**\n * 获取已加载的配置。\n *\n * @param name - 配置名称\n * @returns 配置数据;未加载时返回 undefined\n *\n * @example\n * ```ts\n * const cfg = config.get<CoreConfig>('core')\n * if (cfg) {\n * // 使用 cfg\n * }\n * ```\n */\n get<T>(name: string): T | undefined {\n return configCache.get(name)?.data as T | undefined\n },\n\n /**\n * 获取配置,不存在时抛出错误。\n *\n * @param name - 配置名称\n * @returns 配置数据\n * @throws 配置未加载时抛出 Error\n *\n * @example\n * ```ts\n * try {\n * const cfg = config.getOrThrow<CoreConfig>('core')\n * } catch (e) {\n * // 配置未加载\n * }\n * ```\n */\n getOrThrow<T>(name: string): T {\n const data = this.get<T>(name)\n if (data === undefined) {\n throw new Error(i18n.coreM('core_configNotLoaded', { params: { name } }))\n }\n return data\n },\n\n /**\n * 重新加载配置。\n *\n * 从磁盘重新读取配置文件并更新缓存,同时通知所有 watch 回调。\n *\n * @param name - 配置名称\n * @returns 重载结果;未加载时返回 NOT_LOADED\n *\n * @example\n * ```ts\n * const result = config.reload('app')\n * ```\n */\n reload(name: string): HaiResult<unknown> {\n return reloadAndNotify(name)\n },\n\n /**\n * 检查配置是否已加载。\n *\n * @param name - 配置名称\n * @returns 是否已加载到缓存\n *\n * @example\n * ```ts\n * if (config.has('db')) {\n * const dbCfg = config.get('db')\n * }\n * ```\n */\n has(name: string): boolean {\n return configCache.has(name)\n },\n\n /**\n * 清除配置缓存(同时停止对应监听)。\n *\n * @param name - 配置名称;不传则清除全部\n *\n * @example\n * ```ts\n * config.clear('app') // 清除单个\n * config.clear() // 清除全部\n * ```\n */\n clear(name?: string): void {\n clearCache(name)\n },\n\n /**\n * 获取所有已加载的配置名称。\n *\n * @returns 配置名称数组\n *\n * @example\n * ```ts\n * const names = config.keys() // ['core', 'db', 'app']\n * ```\n */\n keys(): string[] {\n return Array.from(configCache.keys())\n },\n\n /**\n * 监听配置文件变更并自动重载。\n *\n * 文件变更时自动重新加载并调用回调。配置未加载时立即回调 NOT_LOADED 错误。\n *\n * @param name - 配置名称\n * @param callback - 配置变更回调,接收新配置或错误\n * @returns 取消监听函数\n *\n * @example\n * ```ts\n * const unwatch = config.watch('app', (cfg, error) => {\n * if (error) { core.logger.error('reload failed', { error }); return }\n * core.logger.info('config updated', { cfg })\n * })\n * // 取消监听\n * unwatch()\n * ```\n */\n watch<T = unknown>(name: string, callback: WatchCallback<T>): () => void {\n return registerWatch(name, callback)\n },\n\n /**\n * 停止配置文件监听。\n *\n * @param name - 配置名称;不传则停止所有监听\n *\n * @example\n * ```ts\n * config.unwatch('app') // 停止单个\n * config.unwatch() // 停止全部\n * ```\n */\n unwatch(name?: string): void {\n stopWatching(name)\n },\n\n /**\n * 检查是否正在监听某个配置。\n *\n * @param name - 配置名称\n * @returns 是否有活跃的 watcher\n *\n * @example\n * ```ts\n * if (config.isWatching('app')) {\n * config.unwatch('app')\n * }\n * ```\n */\n isWatching(name: string): boolean {\n return watchEntries.has(name)\n },\n}\n\n/**\n * config 子工具类型\n * @example 模块内部上下文\n * ```ts\n * const result = config.load('app', '/srv/app/config/app.yml')\n * if (!result.success) result.error.message\n * ```\n */\nexport type ConfigFn = typeof config\n","/**\n * @h-ai/core — Logger(Node.js 版本,基于 pino)\n *\n * 提供统一的日志接口,Node.js 环境使用 pino 实现。\n * @module core-function-logger.node\n */\n\nimport type { LogFormat, LoggingConfig, LogLevel } from '../core-config.js'\nimport type { LogContext, Logger, LoggerFunctions, LoggerOptions } from '../core-types.js'\nimport { execSync } from 'node:child_process'\nimport { createRequire } from 'node:module'\nimport process from 'node:process'\nimport pino from 'pino'\nimport { sanitize as sanitizeUtils } from '../utils/core-util-sanitize.js'\n\n// ESM 场景下通过 createRequire 复用 CommonJS 的 resolve 能力,用来探测可选依赖是否存在。\nconst nodeRequire = createRequire(import.meta.url)\n\nif (process.platform === 'win32' && process.stdout.isTTY) {\n try {\n // 强制切换控制台代码页为 UTF-8(避免 GBK/GB2312 导致的乱码)\n execSync('chcp 65001 > nul', { stdio: 'ignore' })\n\n // 设置 stdout/stderr 编码为 UTF-8\n if (process.stdout.setDefaultEncoding) {\n process.stdout.setDefaultEncoding('utf8')\n }\n if (process.stderr.setDefaultEncoding) {\n process.stderr.setDefaultEncoding('utf8')\n }\n\n // 仅调整当前终端,不改写调用方语言或子进程编码环境。\n }\n // eslint-disable-next-line unused-imports/no-unused-vars\n catch (_e) {\n // 忽略错误,某些环境可能不支持\n }\n}\n\n// ─── 全局配置 ───\n\n/** 全局日志级别(默认 'info') */\nlet globalLevel: LogLevel = 'info'\n\n/** 全局日志格式(默认 'pretty',适合开发环境) */\nlet globalFormat: LogFormat = 'pretty'\n\n/** 全局默认上下文(每条日志自动附带) */\nlet globalContext: Record<string, unknown> = {}\n\n/** 全局脱敏字段路径列表(如 ['password', 'token']) */\nlet globalRedact: string[] = []\n\n/** 格式和脱敏规则变化时,已有 Logger 在下次输出时更新底层实例。 */\nlet outputRevision = 0\n\n/** 默认 Logger 单例缓存 */\nlet defaultLogger: Logger | null = null\n\n/**\n * 配置全局 Logger 选项。\n *\n * @param config - 日志配置\n *\n * @example\n * ```ts\n * logger.configureLogger({ level: 'debug' })\n * ```\n */\nfunction configureLogger(config: Partial<LoggingConfig>): void {\n if (config.level)\n globalLevel = config.level\n if (config.format) {\n globalFormat = config.format\n outputRevision++\n }\n if (config.context)\n globalContext = { ...globalContext, ...config.context }\n if (config.redact) {\n globalRedact = [...config.redact]\n outputRevision++\n }\n}\n\n/**\n * 设置全局日志级别。\n *\n * @param level - 日志级别\n *\n * @example\n * ```ts\n * logger.setLogLevel('warn')\n * ```\n */\nfunction setLogLevel(level: LogLevel): void {\n globalLevel = level\n}\n\n/**\n * 获取当前全局日志级别。\n *\n * @example\n * ```ts\n * const level = logger.getLogLevel()\n * ```\n */\nfunction getLogLevel(): LogLevel {\n return globalLevel\n}\n\nfunction sanitizeLogContext(ctx?: LogContext): LogContext | undefined {\n if (!ctx || Object.keys(ctx).length === 0) {\n return ctx\n }\n\n return sanitizeUtils.sanitizeSensitiveFields(ctx) as LogContext\n}\n\n// ─── Logger 实现 ───\n\n/**\n * 包装 pino 实例为统一 Logger 接口。\n *\n * 将 pino 的原生方法映射为 Logger 接口,自动合并上下文。\n *\n * @param resolvePino - 当前配置对应的 pino 实例\n * @param resolveContext - 当前基础上下文(会与每次调用时的 ctx 合并)\n * @returns 统一 Logger 实例\n */\nfunction wrapPino(resolvePino: () => pino.Logger, resolveContext: () => Record<string, unknown>): Logger {\n return {\n trace(message: string, ctx?: LogContext) {\n resolvePino().trace(sanitizeLogContext({ ...resolveContext(), ...ctx }) ?? {}, message)\n },\n debug(message: string, ctx?: LogContext) {\n resolvePino().debug(sanitizeLogContext({ ...resolveContext(), ...ctx }) ?? {}, message)\n },\n info(message: string, ctx?: LogContext) {\n resolvePino().info(sanitizeLogContext({ ...resolveContext(), ...ctx }) ?? {}, message)\n },\n warn(message: string, ctx?: LogContext) {\n resolvePino().warn(sanitizeLogContext({ ...resolveContext(), ...ctx }) ?? {}, message)\n },\n error(message: string, ctx?: LogContext) {\n resolvePino().error(sanitizeLogContext({ ...resolveContext(), ...ctx }) ?? {}, message)\n },\n fatal(message: string, ctx?: LogContext) {\n resolvePino().fatal(sanitizeLogContext({ ...resolveContext(), ...ctx }) ?? {}, message)\n },\n child(childContext: Record<string, unknown>): Logger {\n // 只保存本地上下文,输出时继承父级的当前配置;不绑定旧 pino child。\n return wrapPino(resolvePino, () => ({ ...resolveContext(), ...childContext }))\n },\n }\n}\n\n/**\n * 创建 Logger 实例。\n *\n * @param options - Logger 选项\n * @returns Logger 实例\n *\n * @example\n * ```ts\n * const appLogger = logger.createLogger({ name: 'api', level: 'info' })\n * appLogger.info('ready')\n * ```\n */\nfunction createLogger(options: LoggerOptions = {}): Logger {\n const localOptions = { ...options, context: { ...options.context } }\n let revision = outputRevision\n let output = createPinoOutput(localOptions)\n const resolvePino = (): pino.Logger => {\n if (revision !== outputRevision) {\n const updated = createPinoOutput(localOptions)\n output.close()\n output = updated\n revision = outputRevision\n }\n const level = localOptions.level ?? globalLevel\n if (output.instance.level !== level)\n output.instance.level = level\n return output.instance\n }\n return wrapPino(resolvePino, () => ({ ...globalContext, ...localOptions.context }))\n}\n\n/** 底层输出只负责格式和脱敏;已有包装在输出时应用当前全局配置。 */\nfunction createPinoOutput(options: LoggerOptions): { instance: pino.Logger, close: () => void } {\n const level = options.level ?? globalLevel\n const format = options.format ?? globalFormat\n\n // 先构造一份与输出介质无关的基础配置,后面再按 transport 能力决定是否启用 pretty。\n const pinoOptions: pino.LoggerOptions = {\n level,\n name: options.name,\n formatters: {\n level: label => ({ level: label }),\n },\n }\n\n // redact 支持\n if (globalRedact.length > 0) {\n pinoOptions.redact = {\n paths: globalRedact,\n censor: '[REDACTED]',\n }\n }\n\n let pinoInstance: pino.Logger\n let transport: ReturnType<typeof pino.transport> | undefined\n\n if (format === 'pretty' && isPrettyTransportAvailable()) {\n // 只有在 pino-pretty 可解析时才挂载 transport,避免可选依赖缺失直接导致 logger 初始化失败。\n try {\n transport = pino.transport({\n target: 'pino-pretty',\n options: {\n colorize: true,\n translateTime: 'SYS:standard',\n ignore: 'pid,hostname',\n },\n })\n pinoInstance = pino(pinoOptions, transport)\n }\n catch (error) {\n // 其他初始化异常应重新抛出,便于排查\n if (isPrettyTransportUnavailable(error)) {\n pinoInstance = pino(pinoOptions)\n }\n else {\n throw error\n }\n }\n }\n else {\n pinoInstance = pino(pinoOptions)\n }\n\n return { instance: pinoInstance, close: () => transport?.end() }\n}\n\nfunction isPrettyTransportAvailable(): boolean {\n try {\n // pino-pretty 是可选依赖,这里用 resolve 做能力探测,避免在缺失场景下直接 import 失败。\n nodeRequire.resolve('pino-pretty')\n return true\n }\n catch {\n return false\n }\n}\n\nfunction isPrettyTransportUnavailable(error: unknown): boolean {\n const message\n = error instanceof Error\n ? error.message\n : typeof error === 'string'\n ? error\n : ''\n\n const normalized = message.toLowerCase()\n\n return normalized.includes('pino-pretty')\n && (normalized.includes('cannot find module')\n || normalized.includes('unable to determine transport target')\n || normalized.includes('cannot load')\n || normalized.includes('not found'))\n}\n\n// ─── 默认 Logger 实例 ───\n\n/**\n * 获取默认 Logger 实例(单例)。\n *\n * @example\n * ```ts\n * const defaultLogger = logger.getLogger()\n * ```\n */\nfunction getLogger(): Logger {\n if (!defaultLogger) {\n defaultLogger = createLogger()\n }\n return defaultLogger\n}\n\n// ─── 对外出口 ───\n\n/**\n * Node.js Logger 函数集合。\n * @example\n * ```ts\n * import { core } from '@h-ai/core'\n * const logger = core.logger.create({ name: 'orders' })\n * logger.info('Order created', { orderId: 'order-1' })\n * ```\n */\nexport const logger: LoggerFunctions = {\n configureLogger,\n setLogLevel,\n getLogLevel,\n createLogger,\n getLogger,\n}\n","/**\n * @h-ai/core — Core 服务聚合(Node.js)\n *\n * 提供 Node.js 环境的 core 对象,聚合常用功能。 所有功能统一通过 core 对象访问,并提供配置加载能力。\n * @module core-main.node\n */\n\nimport type { CoreFunctions, CoreOptions } from './core-types.js'\nimport { AsyncLocalStorage } from 'node:async_hooks'\nimport { Buffer } from 'node:buffer'\nimport { timingSafeEqual } from 'node:crypto'\nimport { existsSync, readdirSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { CoreConfigSchema } from './core-config.js'\nimport { createCore } from './core-main.js'\nimport { config } from './functions/core-function-config.node.js'\nimport { logger } from './functions/core-function-logger.node.js'\nimport { installRequestLocales } from './i18n/core-i18n-utils.js'\n\n// 请求语言跨 await 保持隔离,避免并行 SSR 修改另一个请求的默认语言。\ninstallRequestLocales(new AsyncLocalStorage())\n\nconst YAML_EXTENSION_REGEX = /\\.ya?ml$/\n/**\n * Node 入口的 Core 扩展:提供文件配置和初始化;不是额外的公开工厂。\n * @example 模块内部上下文\n * ```ts\n * const tools: NodeCoreFunctions = core\n * tools.init({ logging: { level: 'info' } })\n * tools.logger.info('Core ready')\n * ```\n */\ntype NodeCoreFunctions = CoreFunctions & {\n readonly config: typeof config\n readonly init: typeof initCore\n}\n\n// ─── Core 实例 ───\n\n/**\n * 创建 Node.js 版本的 core 对象。\n *\n * @example\n * ```ts\n * import { core } from '@h-ai/core'\n * core.logger.info('ready')\n * ```\n */\nfunction createNodeCore(): NodeCoreFunctions {\n const baseCore = createCore({\n createLogger: logger.createLogger,\n getLogger: logger.getLogger,\n configureLogger: logger.configureLogger,\n setLogLevel: logger.setLogLevel,\n getLogLevel: logger.getLogLevel,\n })\n\n // 扩展 config 和 init 功能\n return {\n ...baseCore,\n string: {\n ...baseCore.string,\n /**\n * Node 凭证比较使用原生恒时原语;不同长度直接失败,长度本身不受保护。\n * UTF-16LE 保留孤立代理项,避免 UTF-8 替换字符把两个不同字符串误判为相等。\n * @param a - 第一个原始字符串,不做 Unicode 归一化。\n * @param b - 第二个原始字符串,不做 Unicode 归一化。\n * @returns 字符串的 UTF-16 单元是否完全一致。\n * @example\n * ```ts\n * import { core } from '@h-ai/core'\n * const matches = core.string.constantTimeEqual('example-only', 'example-only')\n * ```\n */\n constantTimeEqual(a: string, b: string): boolean {\n return a.length === b.length && timingSafeEqual(Buffer.from(a, 'utf16le'), Buffer.from(b, 'utf16le'))\n },\n },\n /** Zod 校验错误 → i18n 消息映射工具(kit / serv / api-client 共享)。 */\n zodValidation: baseCore.zodValidation,\n /** 配置管理 */\n config,\n /** 初始化 Core */\n init: initCore,\n }\n}\n\n/**\n * Core 服务对象 - 聚合常用功能(Node.js)。\n * @example\n * ```ts\n * import { core, CoreConfigSchema } from '@h-ai/core'\n * core.init({ configDir: './config' }) // 单项加载失败记录日志并继续。\n * const required = core.config.validate('core', CoreConfigSchema)\n * if (!required.success) core.logger.error('Required config unavailable', { error: required.error })\n * else core.logger.info('Application ready', { name: required.data.name })\n * ```\n */\nexport const core: NodeCoreFunctions = createNodeCore()\n\n// ─── Initialization ───\n\n/**\n * 配置加载项(描述单个待加载的配置文件)。\n * @example 模块内部上下文\n * ```ts\n * const item: ConfigLoadItem = { name: 'core', filePath: join('/srv/app', 'config', '_core.yml') }\n * const cacheName = item.name\n * ```\n */\ninterface ConfigLoadItem {\n /** 配置名称(用作缓存 key,如 'core'、'db'、'app') */\n name: string\n /** 配置文件绝对路径 */\n filePath: string\n}\n\n/**\n * 扫描配置目录并构建配置加载项列表。\n *\n * 约定:\n * - 以 `_` 开头的文件为内置模块配置(如 `_core.yml` → name='core')\n * - 其他文件为业务配置(如 `app.yml` → name='app')\n * - `_deploy.yml` / `_deploy.yaml` 留给部署 CLI 独立解析,不参与运行时加载和监听;业务 `deploy.yml` 不受影响\n *\n * @param configDir - 配置目录路径\n * @returns 配置加载项列表;目录不存在时返回空数组并输出警告\n * @throws 目录存在但不可读取等文件系统异常会向调用方传播。\n *\n * @example 模块内部上下文\n * ```ts\n * const items = scanConfigDir('./config')\n * core.logger.debug('Runtime configs selected', { names: items.map(item => item.name) })\n * ```\n */\nfunction scanConfigDir(\n configDir: string,\n): ConfigLoadItem[] {\n const logger = core.logger\n const items: ConfigLoadItem[] = []\n\n if (!existsSync(configDir)) {\n logger.warn(`[core] Config directory not found: ${configDir}`)\n return items\n }\n\n const files = readdirSync(configDir).filter(f =>\n f.endsWith('.yml') || f.endsWith('.yaml'),\n )\n\n for (const file of files) {\n // 部署凭据由 CLI 按目标环境加载,不能要求应用启动时提供 SSH / 云平台参数。\n if (file === '_deploy.yml' || file === '_deploy.yaml')\n continue\n const filePath = join(configDir, file)\n const baseName = file.replace(YAML_EXTENSION_REGEX, '')\n\n // 判断是否为内置模块配置(以 _ 开头)\n if (baseName.startsWith('_')) {\n const moduleName = baseName.slice(1) // 去掉 _ 前缀\n items.push({\n name: moduleName,\n filePath,\n })\n }\n else {\n // 业务配置(文件名作为配置名)\n items.push({\n name: baseName,\n filePath,\n })\n }\n }\n return items\n}\n\n/**\n * 初始化 Core(内部实现,通过 `core.init()` 调用)。\n *\n * 执行流程:\n * 1. 配置日志(若提供 `options.logging`)\n * 2. 扫描并加载运行时 YAML,跳过保留部署文件 `_deploy.yml` / `_deploy.yaml`\n * 3. 启用配置文件监听(若 `options.watchConfig` 为 true)\n *\n * 单项 `config.load` 返回失败时记录日志并继续;必需配置由调用方 `config.validate` 并检查 success。\n *\n * @param options - 初始化选项\n * @throws 目录扫描、日志设置等异常仍会传播;不把单项配置的失败结果改为异常。\n *\n * @example 模块内部上下文\n * ```ts\n * core.init({ configDir: './config', watchConfig: true })\n * const required = core.config.validate('core', CoreConfigSchema)\n * if (!required.success) core.logger.error('Required config unavailable', { error: required.error })\n * ```\n */\nfunction initCore(options: CoreOptions = {}): void {\n const startTime = Date.now()\n const logger = core.logger\n\n // 1. Configure logging\n if (options.logging) {\n core.logger.configure(options.logging)\n }\n\n let configItems: ConfigLoadItem[] = []\n\n if (options.configDir) {\n // 约定优于配置模式\n configItems = scanConfigDir(options.configDir)\n }\n\n // 先应用 core 的日志配置,避免其它配置加载日志使用初始化前的级别与格式。\n configItems.sort((left, right) => Number(right.name === 'core') - Number(left.name === 'core'))\n\n // 2. Load config files\n for (const item of configItems) {\n if (item.name === 'core') {\n const result = config.load(item.name, item.filePath, CoreConfigSchema)\n if (result.success) {\n if (!options.logging) {\n core.logger.configure(result.data.logging || {})\n }\n logger.info(`[core] Config loaded: ${item.name} <- ${item.filePath}`)\n }\n else {\n logger.error(`[core] Config load failed: ${item.name}`, {\n error: result.error,\n })\n }\n }\n else {\n const result = config.load(item.name, item.filePath)\n if (result.success) {\n logger.info(`[core] Config loaded: ${item.name} <- ${item.filePath}`)\n }\n else {\n logger.error(`[core] Config load failed: ${item.name}`, {\n error: result.error,\n })\n }\n }\n }\n\n // 3. Enable config file watching\n if (options.watchConfig && configItems.length > 0) {\n setupConfigWatch(configItems)\n }\n\n const duration = Date.now() - startTime\n logger.info(`[core] Initialized (${duration}ms)`)\n}\n\n/**\n * 启用配置文件监听。\n *\n * 为每个已加载的配置项注册文件 watcher,变更时自动重载并输出日志。\n *\n * @param configs - 需要监听的配置项列表\n */\nfunction setupConfigWatch(configs: ConfigLoadItem[]): void {\n const logger = core.logger\n\n for (const item of configs) {\n config.watch(item.name, (_config, error) => {\n if (error) {\n logger.error(`[core] Config reload failed: ${item.name}`, { error })\n return\n }\n logger.info(`[core] Config reloaded: ${item.name}`)\n })\n\n logger.debug(`[core] Config watch enabled: ${item.name}`)\n }\n}\n"]}
package/package.json CHANGED
@@ -1,13 +1,16 @@
1
1
  {
2
2
  "name": "@h-ai/core",
3
3
  "type": "module",
4
- "version": "0.1.0-alpha.66",
4
+ "version": "0.1.0-alpha.68",
5
5
  "description": "Hai Framework core module with shared utilities, types, configuration, and logging.",
6
6
  "license": "Apache-2.0",
7
7
  "exports": {
8
8
  ".": {
9
+ "browser": {
10
+ "types": "./dist/browser.d.ts",
11
+ "default": "./dist/browser.js"
12
+ },
9
13
  "types": "./dist/node.d.ts",
10
- "browser": "./dist/browser.js",
11
14
  "import": "./dist/node.js",
12
15
  "default": "./dist/node.js"
13
16
  }