@h-ai/core 0.1.0-alpha.13 → 0.1.0-alpha.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -0
- package/dist/browser.d.ts +3 -2
- package/dist/browser.js +2 -2
- package/dist/{chunk-STH6Q4GV.js → chunk-JM2QORKH.js} +118 -2
- package/dist/chunk-JM2QORKH.js.map +1 -0
- package/dist/{core-util-module-B-wH5_ZT.d.ts → core-types-aT8pmvMq.d.ts} +126 -45
- package/dist/node.d.ts +195 -33
- package/dist/node.js +4 -2
- package/dist/node.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-STH6Q4GV.js.map +0 -1
package/README.md
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
- **HaiResult 类型** — 函数式错误处理(`ok` / `err`),所有模块统一返回值
|
|
8
8
|
- **统一日志** — Node.js 基于 pino,浏览器基于 loglevel,API 一致
|
|
9
9
|
- **国际化(i18n)** — 集中式 locale 管理 + 类型安全的消息获取器
|
|
10
|
+
- **Zod 校验错误映射** — 兼容 Zod v3/v4 的 issue 提取与默认英文消息本地化
|
|
10
11
|
- **配置管理** — YAML 加载、环境变量插值、Zod 校验、文件监听(Node.js 专用)
|
|
11
12
|
- **ID 生成** — nanoid 与 UUID v4
|
|
12
13
|
- **错误定义** — 标准化错误码体系,支持跨模块统一的错误定义与实例创建
|
|
@@ -172,6 +173,67 @@ core.i18n.DEFAULT_LOCALES // [{ code: 'zh-CN', label: '简体中文' }, { code:
|
|
|
172
173
|
core.i18n.DEFAULT_LOCALE // 'zh-CN'
|
|
173
174
|
```
|
|
174
175
|
|
|
176
|
+
### Zod 校验错误 i18n 映射
|
|
177
|
+
|
|
178
|
+
`core.zodValidation` 用于把 Zod `SafeParseError` / `ZodError` 转为扁平表单错误,并将 Zod
|
|
179
|
+
默认英文消息映射为调用方自己的 i18n 文案。
|
|
180
|
+
|
|
181
|
+
- 两个公开入口:
|
|
182
|
+
- `createPrefixedZodMessageGetter()`:按模块前缀自动派生 `serv_validation*` / `kit_validation*` 这类 key,省掉手写 `KEY_MAP`
|
|
183
|
+
- `mapZodErrorToFormErrors()`:一步完成提取 + 本地化 + 扁平化
|
|
184
|
+
- 自定义业务消息不会被覆盖;只有 Zod 默认英文消息才会被替换
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
import type { ZodMessageGetter } from '@h-ai/core'
|
|
188
|
+
import { core } from '@h-ai/core'
|
|
189
|
+
import { z } from 'zod'
|
|
190
|
+
|
|
191
|
+
const LoginSchema = z.object({
|
|
192
|
+
email: z.string().email(),
|
|
193
|
+
password: z.string().min(8),
|
|
194
|
+
nickname: z.string().min(1, '请填写昵称'),
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
const getMessage: ZodMessageGetter = (key, params) => {
|
|
198
|
+
switch (key) {
|
|
199
|
+
case 'validationEmail':
|
|
200
|
+
return '请输入合法邮箱地址'
|
|
201
|
+
case 'validationStringMin':
|
|
202
|
+
return `至少输入 ${params?.min} 个字符`
|
|
203
|
+
case 'validationRequired':
|
|
204
|
+
return '此项为必填项'
|
|
205
|
+
default:
|
|
206
|
+
return '输入不合法'
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const result = LoginSchema.safeParse({
|
|
211
|
+
email: 'bad',
|
|
212
|
+
password: '123',
|
|
213
|
+
nickname: '',
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
if (!result.success) {
|
|
217
|
+
const getMessage = core.zodValidation.createPrefixedZodMessageGetter(
|
|
218
|
+
'kit',
|
|
219
|
+
(messageKey, params) => {
|
|
220
|
+
if (messageKey === 'kit_validationEmail')
|
|
221
|
+
return '请输入合法邮箱地址'
|
|
222
|
+
if (messageKey === 'kit_validationStringMin')
|
|
223
|
+
return `至少输入 ${params?.min} 个字符`
|
|
224
|
+
return '输入不合法'
|
|
225
|
+
},
|
|
226
|
+
)
|
|
227
|
+
const errors = core.zodValidation.mapZodErrorToFormErrors(result.error, getMessage)
|
|
228
|
+
|
|
229
|
+
errors[0]?.field // 'email'
|
|
230
|
+
errors[0]?.message // '请输入合法邮箱地址'
|
|
231
|
+
errors[2]?.message // '请填写昵称'(schema 自定义消息原样保留)
|
|
232
|
+
|
|
233
|
+
core.logger.info('Validation failed', { errors })
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
175
237
|
### 配置管理(Node.js 专用)
|
|
176
238
|
|
|
177
239
|
```typescript
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { b as CoreOptions, e as CoreLogger, N as I18nFn, O as zodValidation, Q as IdFn, T as TypeUtilFn, R as ObjectFn, S as StringFn, U as ArrayFn, W as AsyncFn, X as TimeFn, Y as ErrorFn, _ as ModuleFn } from './core-types-aT8pmvMq.js';
|
|
2
|
+
export { c as CoreConfig, d as CoreConfigSchema, C as CoreFunctions, E as Env, f as EnvSchema, g as ErrorInfo, h as ErrorInfoValue, i as HaiCommonError, j as HaiConfigError, a as HaiError, k as HaiErrorDef, H as HaiResult, I as IdConfig, l as IdConfigSchema, m as InterpolationParams, L as Locale, n as LocaleInfo, o as LocaleMessages, p as LogContext, q as LogFormat, r as LogFormatSchema, s as LogLevel, t as LogLevelSchema, u as Logger, v as LoggerFunctions, w as LoggerOptions, x as LoggingConfig, y as LoggingConfigSchema, M as MatchHandlers, z as MessageDictionary, A as MessageOptions, P as PaginatedResult, B as PaginationOptions, D as PaginationOptionsInput, V as ValidationFormError, Z as ZodMessageGetter, F as ZodValidationFn, G as ZodValidationMessageKey, J as err, K as ok } from './core-types-aT8pmvMq.js';
|
|
3
3
|
import 'zod';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -16,6 +16,7 @@ declare const core: {
|
|
|
16
16
|
init: typeof initCore;
|
|
17
17
|
logger: CoreLogger;
|
|
18
18
|
i18n: I18nFn;
|
|
19
|
+
zodValidation: typeof zodValidation;
|
|
19
20
|
id: IdFn;
|
|
20
21
|
typeUtils: TypeUtilFn;
|
|
21
22
|
object: ObjectFn;
|
package/dist/browser.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { __commonJS, __toESM, createCore } from './chunk-
|
|
2
|
-
export { CoreConfigSchema, EnvSchema, HaiCommonError, HaiConfigError, IdConfigSchema, LogFormatSchema, LogLevelSchema, LoggingConfigSchema, err, ok } from './chunk-
|
|
1
|
+
import { __commonJS, __toESM, createCore } from './chunk-JM2QORKH.js';
|
|
2
|
+
export { CoreConfigSchema, EnvSchema, HaiCommonError, HaiConfigError, IdConfigSchema, LogFormatSchema, LogLevelSchema, LoggingConfigSchema, err, ok } from './chunk-JM2QORKH.js';
|
|
3
3
|
|
|
4
4
|
// ../../node_modules/loglevel/lib/loglevel.js
|
|
5
5
|
var require_loglevel = __commonJS({
|
|
@@ -14208,6 +14208,109 @@ var i18n = {
|
|
|
14208
14208
|
coreM
|
|
14209
14209
|
};
|
|
14210
14210
|
|
|
14211
|
+
// src/i18n/core-zod-mapper.ts
|
|
14212
|
+
function createPrefixedZodMessageGetter(prefix, getMessage) {
|
|
14213
|
+
return (key, params) => getMessage(`${prefix}_${key}`, params);
|
|
14214
|
+
}
|
|
14215
|
+
var ZOD_DEFAULT_MESSAGE_PATTERNS = [
|
|
14216
|
+
/^Too small:/,
|
|
14217
|
+
/^Too big:/,
|
|
14218
|
+
/^Invalid input:/,
|
|
14219
|
+
/^Invalid option:/,
|
|
14220
|
+
/^Invalid string:/,
|
|
14221
|
+
/^Invalid email$/,
|
|
14222
|
+
/^Invalid email address$/,
|
|
14223
|
+
/^Invalid url$/i,
|
|
14224
|
+
/^Invalid UUID$/,
|
|
14225
|
+
/^Invalid enum value/,
|
|
14226
|
+
/^Required$/,
|
|
14227
|
+
/^String must contain/,
|
|
14228
|
+
/^Number must be/,
|
|
14229
|
+
/^Array must contain/
|
|
14230
|
+
];
|
|
14231
|
+
function extractZodIssues(error49) {
|
|
14232
|
+
if (!error49 || typeof error49 !== "object")
|
|
14233
|
+
return [];
|
|
14234
|
+
const obj = error49;
|
|
14235
|
+
return obj.issues ?? obj.errors ?? [];
|
|
14236
|
+
}
|
|
14237
|
+
function isDefaultZodMessage(message) {
|
|
14238
|
+
return ZOD_DEFAULT_MESSAGE_PATTERNS.some((pattern) => pattern.test(message));
|
|
14239
|
+
}
|
|
14240
|
+
function formatLimit(value) {
|
|
14241
|
+
if (typeof value === "number" || typeof value === "bigint")
|
|
14242
|
+
return String(value);
|
|
14243
|
+
return void 0;
|
|
14244
|
+
}
|
|
14245
|
+
function getIssueTarget(issue2) {
|
|
14246
|
+
return issue2.origin ?? issue2.type;
|
|
14247
|
+
}
|
|
14248
|
+
function getIssueFormat(issue2) {
|
|
14249
|
+
if (typeof issue2.format === "string")
|
|
14250
|
+
return issue2.format;
|
|
14251
|
+
if (typeof issue2.validation === "string")
|
|
14252
|
+
return issue2.validation;
|
|
14253
|
+
return void 0;
|
|
14254
|
+
}
|
|
14255
|
+
function localizeZodIssue(issue2, getMessage) {
|
|
14256
|
+
if (!isDefaultZodMessage(issue2.message))
|
|
14257
|
+
return issue2.message;
|
|
14258
|
+
const target = getIssueTarget(issue2);
|
|
14259
|
+
const format = getIssueFormat(issue2);
|
|
14260
|
+
const min = formatLimit(issue2.minimum);
|
|
14261
|
+
const max = formatLimit(issue2.maximum);
|
|
14262
|
+
if (issue2.code === "too_small") {
|
|
14263
|
+
if (target === "string" && min)
|
|
14264
|
+
return getMessage("validationStringMin", { min });
|
|
14265
|
+
if ((target === "number" || target === "bigint") && min)
|
|
14266
|
+
return getMessage("validationNumberMin", { min });
|
|
14267
|
+
if (target === "array" && min)
|
|
14268
|
+
return getMessage("validationArrayMin", { min });
|
|
14269
|
+
if (min)
|
|
14270
|
+
return getMessage("validationTooSmall", { min });
|
|
14271
|
+
}
|
|
14272
|
+
if (issue2.code === "too_big") {
|
|
14273
|
+
if (target === "string" && max)
|
|
14274
|
+
return getMessage("validationStringMax", { max });
|
|
14275
|
+
if ((target === "number" || target === "bigint") && max)
|
|
14276
|
+
return getMessage("validationNumberMax", { max });
|
|
14277
|
+
if (target === "array" && max)
|
|
14278
|
+
return getMessage("validationArrayMax", { max });
|
|
14279
|
+
if (max)
|
|
14280
|
+
return getMessage("validationTooBig", { max });
|
|
14281
|
+
}
|
|
14282
|
+
if (issue2.code === "invalid_type") {
|
|
14283
|
+
if (issue2.received === "undefined" || issue2.message.includes("received undefined"))
|
|
14284
|
+
return getMessage("validationRequired");
|
|
14285
|
+
return getMessage("validationInvalidType");
|
|
14286
|
+
}
|
|
14287
|
+
if (issue2.code === "invalid_format" || issue2.code === "invalid_string") {
|
|
14288
|
+
if (format === "email")
|
|
14289
|
+
return getMessage("validationEmail");
|
|
14290
|
+
if (format === "url")
|
|
14291
|
+
return getMessage("validationUrl");
|
|
14292
|
+
if (format === "uuid")
|
|
14293
|
+
return getMessage("validationUuid");
|
|
14294
|
+
return getMessage("validationInvalid");
|
|
14295
|
+
}
|
|
14296
|
+
if (issue2.code === "invalid_value" || issue2.code === "invalid_enum_value")
|
|
14297
|
+
return getMessage("validationEnum");
|
|
14298
|
+
return getMessage("validationInvalid");
|
|
14299
|
+
}
|
|
14300
|
+
function mapZodIssuesToFormErrors(issues, getMessage) {
|
|
14301
|
+
return issues.map((issue2) => ({
|
|
14302
|
+
field: issue2.path.join(".") || "_",
|
|
14303
|
+
message: localizeZodIssue(issue2, getMessage)
|
|
14304
|
+
}));
|
|
14305
|
+
}
|
|
14306
|
+
function mapZodErrorToFormErrors(error49, getMessage) {
|
|
14307
|
+
return mapZodIssuesToFormErrors(extractZodIssues(error49), getMessage);
|
|
14308
|
+
}
|
|
14309
|
+
var zodValidation = {
|
|
14310
|
+
createPrefixedZodMessageGetter,
|
|
14311
|
+
mapZodErrorToFormErrors
|
|
14312
|
+
};
|
|
14313
|
+
|
|
14211
14314
|
// src/utils/core-util-array.ts
|
|
14212
14315
|
function unique(arr) {
|
|
14213
14316
|
return [...new Set(arr)];
|
|
@@ -14672,6 +14775,19 @@ function createCore(loggerFns) {
|
|
|
14672
14775
|
* ```
|
|
14673
14776
|
*/
|
|
14674
14777
|
i18n,
|
|
14778
|
+
/**
|
|
14779
|
+
* Zod 校验错误 → i18n 消息映射工具(kit / serv / api-client 共享)。
|
|
14780
|
+
*
|
|
14781
|
+
* 调用方注入自己的 `ZodMessageGetter`,把统一的校验消息 key 映射到本模块的 i18n 字典。
|
|
14782
|
+
*
|
|
14783
|
+
* @example
|
|
14784
|
+
* ```ts
|
|
14785
|
+
* import { core } from '@h-ai/core'
|
|
14786
|
+
*
|
|
14787
|
+
* const errors = core.zodValidation.mapZodErrorToFormErrors(zodError, getMessage)
|
|
14788
|
+
* ```
|
|
14789
|
+
*/
|
|
14790
|
+
zodValidation,
|
|
14675
14791
|
// ─── ID ───
|
|
14676
14792
|
/**
|
|
14677
14793
|
* ID 生成工具。
|
|
@@ -14782,5 +14898,5 @@ function createCore(loggerFns) {
|
|
|
14782
14898
|
}
|
|
14783
14899
|
|
|
14784
14900
|
export { CoreConfigSchema, EnvSchema, HaiCommonError, HaiConfigError, IdConfigSchema, LogFormatSchema, LogLevelSchema, LoggingConfigSchema, __commonJS, __toESM, createCore, err, i18n, ok, typeUtils };
|
|
14785
|
-
//# sourceMappingURL=chunk-
|
|
14786
|
-
//# sourceMappingURL=chunk-
|
|
14901
|
+
//# sourceMappingURL=chunk-JM2QORKH.js.map
|
|
14902
|
+
//# sourceMappingURL=chunk-JM2QORKH.js.map
|