@h-ai/core 1.0.0-beta.18 → 1.0.0-beta.19
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.en.md +85 -19
- package/README.ja.md +85 -19
- package/README.md +85 -19
- package/dist/browser.d.ts +2 -2
- package/dist/browser.js +39 -11
- package/dist/browser.js.map +1 -1
- package/dist/{chunk-MYNB4HIZ.js → chunk-WU6HUTBO.js} +224 -44
- package/dist/chunk-WU6HUTBO.js.map +1 -0
- package/dist/{core-types-n2KjBtto.d.ts → core-types-Dp3Vr2uI.d.ts} +7 -4
- package/dist/node.d.ts +2 -2
- package/dist/node.js +195 -49
- package/dist/node.js.map +1 -1
- package/package.json +6 -6
- package/dist/chunk-MYNB4HIZ.js.map +0 -1
package/README.en.md
CHANGED
|
@@ -93,7 +93,9 @@ The startup boundary stops when required configuration is unavailable. `core.ini
|
|
|
93
93
|
import { core } from '@h-ai/core'
|
|
94
94
|
|
|
95
95
|
// 浏览器不读取 YAML;此处只设置日志,输出 warn 及以上级别。
|
|
96
|
-
core.init({
|
|
96
|
+
core.init({
|
|
97
|
+
logging: { level: 'warn' }
|
|
98
|
+
}) // 返回 undefined;之后 info 日志被过滤。
|
|
97
99
|
|
|
98
100
|
// 设置当前页面使用的默认消息语言。
|
|
99
101
|
core.i18n.setGlobalLocale('zh-CN') // 返回 undefined;页面默认消息使用中文。
|
|
@@ -131,7 +133,9 @@ import { core } from '@h-ai/core'
|
|
|
131
133
|
import { z } from 'zod'
|
|
132
134
|
|
|
133
135
|
// 读取上方 config/app.yml;Schema 同时描述类型和校验规则。
|
|
134
|
-
const AppSchema = z.object({
|
|
136
|
+
const AppSchema = z.object({
|
|
137
|
+
port: z.number().int().min(1).max(65535)
|
|
138
|
+
})
|
|
135
139
|
const loaded = core.config.load('app', './config/app.yml', AppSchema)
|
|
136
140
|
if (!loaded.success)
|
|
137
141
|
throw new Error(loaded.error.message, { cause: loaded.error })
|
|
@@ -230,11 +234,25 @@ import { core } from '@h-ai/core'
|
|
|
230
234
|
import { z } from 'zod'
|
|
231
235
|
|
|
232
236
|
// 用显式环境数据演示覆盖顺序、数值/布尔转换与字符串保留。
|
|
233
|
-
const AppSchema = z.object({
|
|
237
|
+
const AppSchema = z.object({
|
|
238
|
+
port: z.number(),
|
|
239
|
+
enabled: z.boolean(),
|
|
240
|
+
label: z.string(),
|
|
241
|
+
code: z.string()
|
|
242
|
+
})
|
|
234
243
|
const resolved = core.config.resolve({
|
|
235
244
|
name: 'app',
|
|
236
|
-
|
|
237
|
-
value: {
|
|
245
|
+
|
|
246
|
+
value: {
|
|
247
|
+
// eslint-disable-next-line no-template-curly-in-string -- 保留供配置解析器处理的字面占位符。
|
|
248
|
+
port: '${PORT:3000}',
|
|
249
|
+
// eslint-disable-next-line no-template-curly-in-string -- 保留供配置解析器处理的字面占位符。
|
|
250
|
+
enabled: '${ENABLED:false}',
|
|
251
|
+
// eslint-disable-next-line no-template-curly-in-string -- 保留供配置解析器处理的字面占位符。
|
|
252
|
+
label: 'server-${PORT:3000}',
|
|
253
|
+
// eslint-disable-next-line no-template-curly-in-string -- 保留供配置解析器处理的字面占位符。
|
|
254
|
+
code: '${APP_CODE:00123}'
|
|
255
|
+
},
|
|
238
256
|
environment: { PORT: '4000', HAI_APP_PORT: '5000' },
|
|
239
257
|
schema: AppSchema,
|
|
240
258
|
})
|
|
@@ -265,9 +283,18 @@ resolve() also lets build/deploy tools calculate settings in memory. toEnv() con
|
|
|
265
283
|
import { core } from '@h-ai/core'
|
|
266
284
|
|
|
267
285
|
// 配置生成器把普通对象转成 HAI_APP_PORT 等变量;数组保留为 JSON。
|
|
268
|
-
const values = core.config.toEnv({
|
|
286
|
+
const values = core.config.toEnv({
|
|
287
|
+
prefix: 'HAI_APP',
|
|
288
|
+
value: {
|
|
289
|
+
port: 3000,
|
|
290
|
+
tags: ['local']
|
|
291
|
+
}
|
|
292
|
+
})
|
|
269
293
|
// values:{ HAI_APP_PORT: '3000', HAI_APP_TAGS: '["local"]' }。
|
|
270
|
-
const merged = core.config.mergeEnv([
|
|
294
|
+
const merged = core.config.mergeEnv([
|
|
295
|
+
values,
|
|
296
|
+
{ HAI_APP_PORT: '4000' }
|
|
297
|
+
])
|
|
271
298
|
// merged:{ HAI_APP_PORT: '4000', HAI_APP_TAGS: '["local"]' }。
|
|
272
299
|
const text = core.config.stringifyEnv(merged) // 编码为可写入 .env 的文本。
|
|
273
300
|
// text 含以下两行,每行以换行符结尾:
|
|
@@ -295,7 +322,9 @@ core.logger.trace('Processing detail', { step: 1 })
|
|
|
295
322
|
core.logger.debug('Read started')
|
|
296
323
|
core.logger.info('Order created', { orderId: 'order-1' })
|
|
297
324
|
core.logger.warn('Retry scheduled')
|
|
298
|
-
core.logger.error('Operation failed', {
|
|
325
|
+
core.logger.error('Operation failed', {
|
|
326
|
+
error: new Error('Example failure')
|
|
327
|
+
})
|
|
299
328
|
core.logger.fatal('Service cannot continue')
|
|
300
329
|
// 六次日志调用均返回 undefined;分别输出对应级别、上面的消息及所传字段。
|
|
301
330
|
// 例如 info 日志的消息为 'Order created',字段 orderId 为 'order-1'。
|
|
@@ -307,10 +336,16 @@ create() makes a named logger; child() attaches fixed context. configure() sets
|
|
|
307
336
|
import { core } from '@h-ai/core'
|
|
308
337
|
|
|
309
338
|
// 全局配置可作用于已经创建的 Logger;redact 补充业务隐私字段。
|
|
310
|
-
core.logger.configure({
|
|
339
|
+
core.logger.configure({
|
|
340
|
+
level: 'info',
|
|
341
|
+
format: 'json',
|
|
342
|
+
redact: ['customer.email']
|
|
343
|
+
}) // 返回 undefined;后续日志按此配置输出。
|
|
311
344
|
const orders = core.logger.create({ name: 'orders' }) // 返回 Logger 对象,可调用 info/warn 等方法。
|
|
312
345
|
const request = core.logger.child({ requestId: 'request-1' }) // 返回带固定 requestId 的 Logger。
|
|
313
|
-
orders.info('Order created', {
|
|
346
|
+
orders.info('Order created', {
|
|
347
|
+
customer: { email: 'user@example.com' }
|
|
348
|
+
}) // 返回 undefined;输出中 customer.email 为 '[REDACTED]'。
|
|
314
349
|
request.warn('Request needs attention') // 返回 undefined;输出中 requestId 为 'request-1'。
|
|
315
350
|
core.logger.getLevel() // 'info'。
|
|
316
351
|
```
|
|
@@ -370,7 +405,10 @@ core.sanitize.sanitizeSensitiveValue('example-only', 'password') // '[REDACTED]'
|
|
|
370
405
|
const safe = core.sanitize.sanitizeSensitiveFields({ password: 'example-only', email: 'user@example.com' })
|
|
371
406
|
// safe:{ password: '[REDACTED]', email: 'user@example.com' },原对象不变。
|
|
372
407
|
// 默认仅遮蔽凭据;额外业务隐私可在已处理凭据的副本上继续清理。
|
|
373
|
-
core.sanitize.sanitizeSensitiveFields(safe, {
|
|
408
|
+
core.sanitize.sanitizeSensitiveFields(safe, {
|
|
409
|
+
matcher: ['email'],
|
|
410
|
+
replacement: '***'
|
|
411
|
+
})
|
|
374
412
|
// => { password: '[REDACTED]', email: '***' }
|
|
375
413
|
core.sanitize.sanitizeUrl('https://user:example-only@example.com/?token=example-only')
|
|
376
414
|
// => 'https://[REDACTED]:[REDACTED]@example.com/?token=[REDACTED]'
|
|
@@ -449,6 +487,10 @@ Internal `cause` / `ext` are private by default. Field errors for 400/422 can re
|
|
|
449
487
|
|
|
450
488
|
These constants belong to `HaiConfigError`; cross-module failures use `HaiCommonError`.
|
|
451
489
|
|
|
490
|
+
`HaiCommonError.RATE_LIMIT_EXCEEDED` maps to `hai:common:203` / HTTP 429. Kit shortcut responses and guards use the same common error definitions.
|
|
491
|
+
|
|
492
|
+
HTTP/UI boundaries expose business messages only for explicit valid 4xx statuses. Missing or invalid `httpStatus` is treated as 500 with a safe message. Custom business errors must carry a complete error definition or an explicit status.
|
|
493
|
+
|
|
452
494
|
### Messages and locales: `core.i18n`
|
|
453
495
|
|
|
454
496
|
Create message getters with parameter interpolation, read built-in Core messages, and manage locale selection. Constants list framework locales and do not register application translations.
|
|
@@ -478,7 +520,9 @@ const message = core.i18n.createMessageGetter({
|
|
|
478
520
|
// createMessageGetter 返回消息函数;如 message('welcome', { locale: 'zh-CN', params: { name: 'Alice' } }) 得到 '欢迎 Alice'。
|
|
479
521
|
const greeting = await core.i18n.runWithLocale('en-US', async () => {
|
|
480
522
|
await Promise.resolve()
|
|
481
|
-
return message('welcome', {
|
|
523
|
+
return message('welcome', {
|
|
524
|
+
params: { name: 'Alice' }
|
|
525
|
+
})
|
|
482
526
|
})
|
|
483
527
|
// greeting:'Welcome Alice';runWithLocale 返回回调的结果,此处等待 Promise 得到字符串。
|
|
484
528
|
core.logger.info('Greeting prepared', { greeting })
|
|
@@ -500,7 +544,9 @@ const message = core.zodValidation.createPrefixedZodMessageGetter('core', key =>
|
|
|
500
544
|
? core.i18n.coreM('core_validationEmail', { locale: 'zh-CN' })
|
|
501
545
|
: core.i18n.coreM('core_errorValidation', { locale: 'zh-CN' }))
|
|
502
546
|
// 返回消息函数;message('validationEmail') 得到 '请输入有效的邮箱地址'。
|
|
503
|
-
const parsed = z.object({
|
|
547
|
+
const parsed = z.object({
|
|
548
|
+
email: z.email()
|
|
549
|
+
}).safeParse({ email: 'invalid' })
|
|
504
550
|
if (!parsed.success) {
|
|
505
551
|
const errors = core.zodValidation.mapZodErrorToFormErrors(parsed.error, message)
|
|
506
552
|
// errors:[{ field: 'email', message: '请输入有效的邮箱地址' }]。
|
|
@@ -617,10 +663,14 @@ import { AccessConditionSchema, core } from '@h-ai/core'
|
|
|
617
663
|
|
|
618
664
|
core.access.normalizeClientIp('::ffff:198.51.100.23') // 198.51.100.23。
|
|
619
665
|
const resolve = core.access.createClientIpResolver(['192.0.2.10']) // 返回 IP 解析函数,只信任这个代理。
|
|
620
|
-
const request = new Request('https://example.test/api/orders', {
|
|
666
|
+
const request = new Request('https://example.test/api/orders', {
|
|
667
|
+
headers: { 'x-forwarded-for': '198.51.100.23' }
|
|
668
|
+
})
|
|
621
669
|
// 第二参数必须来自真实 socket/可信平台;这里用测试地址模拟代理对端。
|
|
622
670
|
const clientIp = resolve(request, '192.0.2.10') // '198.51.100.23',读取受信代理的转发头。
|
|
623
|
-
const check = core.access.createConditionCheck(AccessConditionSchema.parse({
|
|
671
|
+
const check = core.access.createConditionCheck(AccessConditionSchema.parse({
|
|
672
|
+
allowIps: ['198.51.100.0/24']
|
|
673
|
+
}))
|
|
624
674
|
// createConditionCheck 返回检查函数;check(clientIp) 得到 { allowed: true }。
|
|
625
675
|
core.logger.info('Address checked', { allowed: check(clientIp).allowed })
|
|
626
676
|
```
|
|
@@ -632,7 +682,15 @@ import { core } from '@h-ai/core'
|
|
|
632
682
|
|
|
633
683
|
// 可改为 loadPolicy({ file: './config/security/request-access.yml' }) 在启动时读独立文件。
|
|
634
684
|
const policy = core.access.loadPolicy({
|
|
635
|
-
rules: [
|
|
685
|
+
rules: [
|
|
686
|
+
{
|
|
687
|
+
id: 'external-api',
|
|
688
|
+
paths: ['/api/external/**'],
|
|
689
|
+
methods: ['POST'],
|
|
690
|
+
allowIps: ['192.0.2.0/24'],
|
|
691
|
+
encryption: 'disabled'
|
|
692
|
+
}
|
|
693
|
+
],
|
|
636
694
|
})
|
|
637
695
|
// policy.rules[0] 保留上方规则,并补 denyIps: []、windows: []、timezone: 'UTC'。
|
|
638
696
|
const check = core.access.createRequestCheck(policy) // 返回请求检查函数,另带 encryption 方法和 requiresEncryption 属性。
|
|
@@ -702,7 +760,9 @@ core.object.omit(settings, ['port']) // { name: 'orders' }。
|
|
|
702
760
|
core.object.keys(settings) // ['name', 'port'],元素类型为 'name' | 'port'。
|
|
703
761
|
core.object.values(settings) // ['orders', 4000]。
|
|
704
762
|
core.object.entries(settings) // [['name', 'orders'], ['port', 4000]]。
|
|
705
|
-
core.object.fromEntries([
|
|
763
|
+
core.object.fromEntries([
|
|
764
|
+
['mode', 'local']
|
|
765
|
+
]) // { mode: 'local' }。
|
|
706
766
|
```
|
|
707
767
|
|
|
708
768
|
deepClone uses structuredClone for cloneable Date/Map/Set/cyclic values and throws for unsupported values such as functions. deepMerge recursively merges plain objects only; later arrays, dates, collections, and class instances replace earlier values without modifying inputs. It does not clone instances.
|
|
@@ -739,11 +799,17 @@ import { core } from '@h-ai/core'
|
|
|
739
799
|
|
|
740
800
|
core.array.unique([1, 1, 2]) // [1, 2]。
|
|
741
801
|
core.array.chunk([1, 2, 3], 2) // [[1, 2], [3]]。
|
|
742
|
-
core.array.groupBy([
|
|
802
|
+
core.array.groupBy([
|
|
803
|
+
{ role: 'admin' },
|
|
804
|
+
{ role: 'user' }
|
|
805
|
+
], item => item.role)
|
|
743
806
|
// => { admin: [{ role: 'admin' }], user: [{ role: 'user' }] }
|
|
744
807
|
core.array.first([1, 2, 3]) // 1;空数组为 undefined。
|
|
745
808
|
core.array.last([1, 2, 3]) // 3;空数组为 undefined。
|
|
746
|
-
core.array.flatten([
|
|
809
|
+
core.array.flatten([
|
|
810
|
+
[1],
|
|
811
|
+
[2, 3]
|
|
812
|
+
]) // [1, 2, 3],只展开一层。
|
|
747
813
|
core.array.compact([0, null, 1, undefined]) // [0, 1],保留 0/false/空字符串。
|
|
748
814
|
core.array.shuffle([1, 2, 3]) // 如 [2, 3, 1],次序随机;新数组不修改输入。
|
|
749
815
|
core.array.intersection([1, 2], [2, 3]) // [2]。
|
package/README.ja.md
CHANGED
|
@@ -93,7 +93,9 @@ core.logger.info('Application ready', { name: config.data.name }) // 返回 unde
|
|
|
93
93
|
import { core } from '@h-ai/core'
|
|
94
94
|
|
|
95
95
|
// 浏览器不读取 YAML;此处只设置日志,输出 warn 及以上级别。
|
|
96
|
-
core.init({
|
|
96
|
+
core.init({
|
|
97
|
+
logging: { level: 'warn' }
|
|
98
|
+
}) // 返回 undefined;之后 info 日志被过滤。
|
|
97
99
|
|
|
98
100
|
// 设置当前页面使用的默认消息语言。
|
|
99
101
|
core.i18n.setGlobalLocale('zh-CN') // 返回 undefined;页面默认消息使用中文。
|
|
@@ -131,7 +133,9 @@ import { core } from '@h-ai/core'
|
|
|
131
133
|
import { z } from 'zod'
|
|
132
134
|
|
|
133
135
|
// 读取上方 config/app.yml;Schema 同时描述类型和校验规则。
|
|
134
|
-
const AppSchema = z.object({
|
|
136
|
+
const AppSchema = z.object({
|
|
137
|
+
port: z.number().int().min(1).max(65535)
|
|
138
|
+
})
|
|
135
139
|
const loaded = core.config.load('app', './config/app.yml', AppSchema)
|
|
136
140
|
if (!loaded.success)
|
|
137
141
|
throw new Error(loaded.error.message, { cause: loaded.error })
|
|
@@ -230,11 +234,25 @@ import { core } from '@h-ai/core'
|
|
|
230
234
|
import { z } from 'zod'
|
|
231
235
|
|
|
232
236
|
// 用显式环境数据演示覆盖顺序、数值/布尔转换与字符串保留。
|
|
233
|
-
const AppSchema = z.object({
|
|
237
|
+
const AppSchema = z.object({
|
|
238
|
+
port: z.number(),
|
|
239
|
+
enabled: z.boolean(),
|
|
240
|
+
label: z.string(),
|
|
241
|
+
code: z.string()
|
|
242
|
+
})
|
|
234
243
|
const resolved = core.config.resolve({
|
|
235
244
|
name: 'app',
|
|
236
|
-
|
|
237
|
-
value: {
|
|
245
|
+
|
|
246
|
+
value: {
|
|
247
|
+
// eslint-disable-next-line no-template-curly-in-string -- 保留供配置解析器处理的字面占位符。
|
|
248
|
+
port: '${PORT:3000}',
|
|
249
|
+
// eslint-disable-next-line no-template-curly-in-string -- 保留供配置解析器处理的字面占位符。
|
|
250
|
+
enabled: '${ENABLED:false}',
|
|
251
|
+
// eslint-disable-next-line no-template-curly-in-string -- 保留供配置解析器处理的字面占位符。
|
|
252
|
+
label: 'server-${PORT:3000}',
|
|
253
|
+
// eslint-disable-next-line no-template-curly-in-string -- 保留供配置解析器处理的字面占位符。
|
|
254
|
+
code: '${APP_CODE:00123}'
|
|
255
|
+
},
|
|
238
256
|
environment: { PORT: '4000', HAI_APP_PORT: '5000' },
|
|
239
257
|
schema: AppSchema,
|
|
240
258
|
})
|
|
@@ -265,9 +283,18 @@ resolve() はビルド・デプロイ時のメモリ上の設定計算にも使
|
|
|
265
283
|
import { core } from '@h-ai/core'
|
|
266
284
|
|
|
267
285
|
// 配置生成器把普通对象转成 HAI_APP_PORT 等变量;数组保留为 JSON。
|
|
268
|
-
const values = core.config.toEnv({
|
|
286
|
+
const values = core.config.toEnv({
|
|
287
|
+
prefix: 'HAI_APP',
|
|
288
|
+
value: {
|
|
289
|
+
port: 3000,
|
|
290
|
+
tags: ['local']
|
|
291
|
+
}
|
|
292
|
+
})
|
|
269
293
|
// values:{ HAI_APP_PORT: '3000', HAI_APP_TAGS: '["local"]' }。
|
|
270
|
-
const merged = core.config.mergeEnv([
|
|
294
|
+
const merged = core.config.mergeEnv([
|
|
295
|
+
values,
|
|
296
|
+
{ HAI_APP_PORT: '4000' }
|
|
297
|
+
])
|
|
271
298
|
// merged:{ HAI_APP_PORT: '4000', HAI_APP_TAGS: '["local"]' }。
|
|
272
299
|
const text = core.config.stringifyEnv(merged) // 编码为可写入 .env 的文本。
|
|
273
300
|
// text 含以下两行,每行以换行符结尾:
|
|
@@ -295,7 +322,9 @@ core.logger.trace('Processing detail', { step: 1 })
|
|
|
295
322
|
core.logger.debug('Read started')
|
|
296
323
|
core.logger.info('Order created', { orderId: 'order-1' })
|
|
297
324
|
core.logger.warn('Retry scheduled')
|
|
298
|
-
core.logger.error('Operation failed', {
|
|
325
|
+
core.logger.error('Operation failed', {
|
|
326
|
+
error: new Error('Example failure')
|
|
327
|
+
})
|
|
299
328
|
core.logger.fatal('Service cannot continue')
|
|
300
329
|
// 六次日志调用均返回 undefined;分别输出对应级别、上面的消息及所传字段。
|
|
301
330
|
// 例如 info 日志的消息为 'Order created',字段 orderId 为 'order-1'。
|
|
@@ -307,10 +336,16 @@ create() は名前付き Logger、child() は固定項目付き Logger を作り
|
|
|
307
336
|
import { core } from '@h-ai/core'
|
|
308
337
|
|
|
309
338
|
// 全局配置可作用于已经创建的 Logger;redact 补充业务隐私字段。
|
|
310
|
-
core.logger.configure({
|
|
339
|
+
core.logger.configure({
|
|
340
|
+
level: 'info',
|
|
341
|
+
format: 'json',
|
|
342
|
+
redact: ['customer.email']
|
|
343
|
+
}) // 返回 undefined;后续日志按此配置输出。
|
|
311
344
|
const orders = core.logger.create({ name: 'orders' }) // 返回 Logger 对象,可调用 info/warn 等方法。
|
|
312
345
|
const request = core.logger.child({ requestId: 'request-1' }) // 返回带固定 requestId 的 Logger。
|
|
313
|
-
orders.info('Order created', {
|
|
346
|
+
orders.info('Order created', {
|
|
347
|
+
customer: { email: 'user@example.com' }
|
|
348
|
+
}) // 返回 undefined;输出中 customer.email 为 '[REDACTED]'。
|
|
314
349
|
request.warn('Request needs attention') // 返回 undefined;输出中 requestId 为 'request-1'。
|
|
315
350
|
core.logger.getLevel() // 'info'。
|
|
316
351
|
```
|
|
@@ -370,7 +405,10 @@ core.sanitize.sanitizeSensitiveValue('example-only', 'password') // '[REDACTED]'
|
|
|
370
405
|
const safe = core.sanitize.sanitizeSensitiveFields({ password: 'example-only', email: 'user@example.com' })
|
|
371
406
|
// safe:{ password: '[REDACTED]', email: 'user@example.com' },原对象不变。
|
|
372
407
|
// 默认仅遮蔽凭据;额外业务隐私可在已处理凭据的副本上继续清理。
|
|
373
|
-
core.sanitize.sanitizeSensitiveFields(safe, {
|
|
408
|
+
core.sanitize.sanitizeSensitiveFields(safe, {
|
|
409
|
+
matcher: ['email'],
|
|
410
|
+
replacement: '***'
|
|
411
|
+
})
|
|
374
412
|
// => { password: '[REDACTED]', email: '***' }
|
|
375
413
|
core.sanitize.sanitizeUrl('https://user:example-only@example.com/?token=example-only')
|
|
376
414
|
// => 'https://[REDACTED]:[REDACTED]@example.com/?token=[REDACTED]'
|
|
@@ -449,6 +487,10 @@ HTTP/UI 境界では `core.error.toPublic(error, traceId?, locale?)` を使い
|
|
|
449
487
|
|
|
450
488
|
これらは `HaiConfigError` の定数です。モジュール共通のエラーは `HaiCommonError` を使います。
|
|
451
489
|
|
|
490
|
+
`HaiCommonError.RATE_LIMIT_EXCEEDED` は `hai:common:203` / HTTP 429 に対応します。Kit の応答ヘルパーとガードも共通エラー定義を使用します。
|
|
491
|
+
|
|
492
|
+
HTTP/UI 境界で業務メッセージを公開するのは、明示された有効な4xx状態のみです。`httpStatus` が未指定または不正な場合は500として安全なメッセージを返します。独自の業務エラーには完全なエラー定義または明示的な状態を指定してください。
|
|
493
|
+
|
|
452
494
|
### メッセージと言語:`core.i18n`
|
|
453
495
|
|
|
454
496
|
パラメーター置換付きのメッセージ取得関数を作り、Core 内蔵メッセージや言語を取得・設定します。定数は内蔵言語一覧であり、アプリ翻訳の自動登録は行いません。
|
|
@@ -478,7 +520,9 @@ const message = core.i18n.createMessageGetter({
|
|
|
478
520
|
// createMessageGetter 返回消息函数;如 message('welcome', { locale: 'zh-CN', params: { name: 'Alice' } }) 得到 '欢迎 Alice'。
|
|
479
521
|
const greeting = await core.i18n.runWithLocale('en-US', async () => {
|
|
480
522
|
await Promise.resolve()
|
|
481
|
-
return message('welcome', {
|
|
523
|
+
return message('welcome', {
|
|
524
|
+
params: { name: 'Alice' }
|
|
525
|
+
})
|
|
482
526
|
})
|
|
483
527
|
// greeting:'Welcome Alice';runWithLocale 返回回调的结果,此处等待 Promise 得到字符串。
|
|
484
528
|
core.logger.info('Greeting prepared', { greeting })
|
|
@@ -500,7 +544,9 @@ const message = core.zodValidation.createPrefixedZodMessageGetter('core', key =>
|
|
|
500
544
|
? core.i18n.coreM('core_validationEmail', { locale: 'zh-CN' })
|
|
501
545
|
: core.i18n.coreM('core_errorValidation', { locale: 'zh-CN' }))
|
|
502
546
|
// 返回消息函数;message('validationEmail') 得到 '请输入有效的邮箱地址'。
|
|
503
|
-
const parsed = z.object({
|
|
547
|
+
const parsed = z.object({
|
|
548
|
+
email: z.email()
|
|
549
|
+
}).safeParse({ email: 'invalid' })
|
|
504
550
|
if (!parsed.success) {
|
|
505
551
|
const errors = core.zodValidation.mapZodErrorToFormErrors(parsed.error, message)
|
|
506
552
|
// errors:[{ field: 'email', message: '请输入有效的邮箱地址' }]。
|
|
@@ -617,10 +663,14 @@ import { AccessConditionSchema, core } from '@h-ai/core'
|
|
|
617
663
|
|
|
618
664
|
core.access.normalizeClientIp('::ffff:198.51.100.23') // 198.51.100.23。
|
|
619
665
|
const resolve = core.access.createClientIpResolver(['192.0.2.10']) // 返回 IP 解析函数,只信任这个代理。
|
|
620
|
-
const request = new Request('https://example.test/api/orders', {
|
|
666
|
+
const request = new Request('https://example.test/api/orders', {
|
|
667
|
+
headers: { 'x-forwarded-for': '198.51.100.23' }
|
|
668
|
+
})
|
|
621
669
|
// 第二参数必须来自真实 socket/可信平台;这里用测试地址模拟代理对端。
|
|
622
670
|
const clientIp = resolve(request, '192.0.2.10') // '198.51.100.23',读取受信代理的转发头。
|
|
623
|
-
const check = core.access.createConditionCheck(AccessConditionSchema.parse({
|
|
671
|
+
const check = core.access.createConditionCheck(AccessConditionSchema.parse({
|
|
672
|
+
allowIps: ['198.51.100.0/24']
|
|
673
|
+
}))
|
|
624
674
|
// createConditionCheck 返回检查函数;check(clientIp) 得到 { allowed: true }。
|
|
625
675
|
core.logger.info('Address checked', { allowed: check(clientIp).allowed })
|
|
626
676
|
```
|
|
@@ -632,7 +682,15 @@ import { core } from '@h-ai/core'
|
|
|
632
682
|
|
|
633
683
|
// 可改为 loadPolicy({ file: './config/security/request-access.yml' }) 在启动时读独立文件。
|
|
634
684
|
const policy = core.access.loadPolicy({
|
|
635
|
-
rules: [
|
|
685
|
+
rules: [
|
|
686
|
+
{
|
|
687
|
+
id: 'external-api',
|
|
688
|
+
paths: ['/api/external/**'],
|
|
689
|
+
methods: ['POST'],
|
|
690
|
+
allowIps: ['192.0.2.0/24'],
|
|
691
|
+
encryption: 'disabled'
|
|
692
|
+
}
|
|
693
|
+
],
|
|
636
694
|
})
|
|
637
695
|
// policy.rules[0] 保留上方规则,并补 denyIps: []、windows: []、timezone: 'UTC'。
|
|
638
696
|
const check = core.access.createRequestCheck(policy) // 返回请求检查函数,另带 encryption 方法和 requiresEncryption 属性。
|
|
@@ -702,7 +760,9 @@ core.object.omit(settings, ['port']) // { name: 'orders' }。
|
|
|
702
760
|
core.object.keys(settings) // ['name', 'port'],元素类型为 'name' | 'port'。
|
|
703
761
|
core.object.values(settings) // ['orders', 4000]。
|
|
704
762
|
core.object.entries(settings) // [['name', 'orders'], ['port', 4000]]。
|
|
705
|
-
core.object.fromEntries([
|
|
763
|
+
core.object.fromEntries([
|
|
764
|
+
['mode', 'local']
|
|
765
|
+
]) // { mode: 'local' }。
|
|
706
766
|
```
|
|
707
767
|
|
|
708
768
|
deepClone は structuredClone で Date/Map/Set/循環など複製可能な値を扱い、関数など非対応値では例外です。deepMerge は通常オブジェクトのみ再帰結合し、配列・Date・集合・クラスは後の値で置換し、入力は変更しません。インスタンスの複製ではありません。
|
|
@@ -739,11 +799,17 @@ import { core } from '@h-ai/core'
|
|
|
739
799
|
|
|
740
800
|
core.array.unique([1, 1, 2]) // [1, 2]。
|
|
741
801
|
core.array.chunk([1, 2, 3], 2) // [[1, 2], [3]]。
|
|
742
|
-
core.array.groupBy([
|
|
802
|
+
core.array.groupBy([
|
|
803
|
+
{ role: 'admin' },
|
|
804
|
+
{ role: 'user' }
|
|
805
|
+
], item => item.role)
|
|
743
806
|
// => { admin: [{ role: 'admin' }], user: [{ role: 'user' }] }
|
|
744
807
|
core.array.first([1, 2, 3]) // 1;空数组为 undefined。
|
|
745
808
|
core.array.last([1, 2, 3]) // 3;空数组为 undefined。
|
|
746
|
-
core.array.flatten([
|
|
809
|
+
core.array.flatten([
|
|
810
|
+
[1],
|
|
811
|
+
[2, 3]
|
|
812
|
+
]) // [1, 2, 3],只展开一层。
|
|
747
813
|
core.array.compact([0, null, 1, undefined]) // [0, 1],保留 0/false/空字符串。
|
|
748
814
|
core.array.shuffle([1, 2, 3]) // 如 [2, 3, 1],次序随机;新数组不修改输入。
|
|
749
815
|
core.array.intersection([1, 2], [2, 3]) // [2]。
|
package/README.md
CHANGED
|
@@ -93,7 +93,9 @@ core.logger.info('Application ready', { name: config.data.name }) // 返回 unde
|
|
|
93
93
|
import { core } from '@h-ai/core'
|
|
94
94
|
|
|
95
95
|
// 浏览器不读取 YAML;此处只设置日志,输出 warn 及以上级别。
|
|
96
|
-
core.init({
|
|
96
|
+
core.init({
|
|
97
|
+
logging: { level: 'warn' }
|
|
98
|
+
}) // 返回 undefined;之后 info 日志被过滤。
|
|
97
99
|
|
|
98
100
|
// 设置当前页面使用的默认消息语言。
|
|
99
101
|
core.i18n.setGlobalLocale('zh-CN') // 返回 undefined;页面默认消息使用中文。
|
|
@@ -131,7 +133,9 @@ import { core } from '@h-ai/core'
|
|
|
131
133
|
import { z } from 'zod'
|
|
132
134
|
|
|
133
135
|
// 读取上方 config/app.yml;Schema 同时描述类型和校验规则。
|
|
134
|
-
const AppSchema = z.object({
|
|
136
|
+
const AppSchema = z.object({
|
|
137
|
+
port: z.number().int().min(1).max(65535)
|
|
138
|
+
})
|
|
135
139
|
const loaded = core.config.load('app', './config/app.yml', AppSchema)
|
|
136
140
|
if (!loaded.success)
|
|
137
141
|
throw new Error(loaded.error.message, { cause: loaded.error })
|
|
@@ -230,11 +234,25 @@ import { core } from '@h-ai/core'
|
|
|
230
234
|
import { z } from 'zod'
|
|
231
235
|
|
|
232
236
|
// 用显式环境数据演示覆盖顺序、数值/布尔转换与字符串保留。
|
|
233
|
-
const AppSchema = z.object({
|
|
237
|
+
const AppSchema = z.object({
|
|
238
|
+
port: z.number(),
|
|
239
|
+
enabled: z.boolean(),
|
|
240
|
+
label: z.string(),
|
|
241
|
+
code: z.string()
|
|
242
|
+
})
|
|
234
243
|
const resolved = core.config.resolve({
|
|
235
244
|
name: 'app',
|
|
236
|
-
|
|
237
|
-
value: {
|
|
245
|
+
|
|
246
|
+
value: {
|
|
247
|
+
// eslint-disable-next-line no-template-curly-in-string -- 保留供配置解析器处理的字面占位符。
|
|
248
|
+
port: '${PORT:3000}',
|
|
249
|
+
// eslint-disable-next-line no-template-curly-in-string -- 保留供配置解析器处理的字面占位符。
|
|
250
|
+
enabled: '${ENABLED:false}',
|
|
251
|
+
// eslint-disable-next-line no-template-curly-in-string -- 保留供配置解析器处理的字面占位符。
|
|
252
|
+
label: 'server-${PORT:3000}',
|
|
253
|
+
// eslint-disable-next-line no-template-curly-in-string -- 保留供配置解析器处理的字面占位符。
|
|
254
|
+
code: '${APP_CODE:00123}'
|
|
255
|
+
},
|
|
238
256
|
environment: { PORT: '4000', HAI_APP_PORT: '5000' },
|
|
239
257
|
schema: AppSchema,
|
|
240
258
|
})
|
|
@@ -265,9 +283,18 @@ core.logger.info('Config resolved', { settings: validated.data })
|
|
|
265
283
|
import { core } from '@h-ai/core'
|
|
266
284
|
|
|
267
285
|
// 配置生成器把普通对象转成 HAI_APP_PORT 等变量;数组保留为 JSON。
|
|
268
|
-
const values = core.config.toEnv({
|
|
286
|
+
const values = core.config.toEnv({
|
|
287
|
+
prefix: 'HAI_APP',
|
|
288
|
+
value: {
|
|
289
|
+
port: 3000,
|
|
290
|
+
tags: ['local']
|
|
291
|
+
}
|
|
292
|
+
})
|
|
269
293
|
// values:{ HAI_APP_PORT: '3000', HAI_APP_TAGS: '["local"]' }。
|
|
270
|
-
const merged = core.config.mergeEnv([
|
|
294
|
+
const merged = core.config.mergeEnv([
|
|
295
|
+
values,
|
|
296
|
+
{ HAI_APP_PORT: '4000' }
|
|
297
|
+
])
|
|
271
298
|
// merged:{ HAI_APP_PORT: '4000', HAI_APP_TAGS: '["local"]' }。
|
|
272
299
|
const text = core.config.stringifyEnv(merged) // 编码为可写入 .env 的文本。
|
|
273
300
|
// text 含以下两行,每行以换行符结尾:
|
|
@@ -295,7 +322,9 @@ core.logger.trace('Processing detail', { step: 1 })
|
|
|
295
322
|
core.logger.debug('Read started')
|
|
296
323
|
core.logger.info('Order created', { orderId: 'order-1' })
|
|
297
324
|
core.logger.warn('Retry scheduled')
|
|
298
|
-
core.logger.error('Operation failed', {
|
|
325
|
+
core.logger.error('Operation failed', {
|
|
326
|
+
error: new Error('Example failure')
|
|
327
|
+
})
|
|
299
328
|
core.logger.fatal('Service cannot continue')
|
|
300
329
|
// 六次日志调用均返回 undefined;分别输出对应级别、上面的消息及所传字段。
|
|
301
330
|
// 例如 info 日志的消息为 'Order created',字段 orderId 为 'order-1'。
|
|
@@ -307,10 +336,16 @@ core.logger.fatal('Service cannot continue')
|
|
|
307
336
|
import { core } from '@h-ai/core'
|
|
308
337
|
|
|
309
338
|
// 全局配置可作用于已经创建的 Logger;redact 补充业务隐私字段。
|
|
310
|
-
core.logger.configure({
|
|
339
|
+
core.logger.configure({
|
|
340
|
+
level: 'info',
|
|
341
|
+
format: 'json',
|
|
342
|
+
redact: ['customer.email']
|
|
343
|
+
}) // 返回 undefined;后续日志按此配置输出。
|
|
311
344
|
const orders = core.logger.create({ name: 'orders' }) // 返回 Logger 对象,可调用 info/warn 等方法。
|
|
312
345
|
const request = core.logger.child({ requestId: 'request-1' }) // 返回带固定 requestId 的 Logger。
|
|
313
|
-
orders.info('Order created', {
|
|
346
|
+
orders.info('Order created', {
|
|
347
|
+
customer: { email: 'user@example.com' }
|
|
348
|
+
}) // 返回 undefined;输出中 customer.email 为 '[REDACTED]'。
|
|
314
349
|
request.warn('Request needs attention') // 返回 undefined;输出中 requestId 为 'request-1'。
|
|
315
350
|
core.logger.getLevel() // 'info'。
|
|
316
351
|
```
|
|
@@ -370,7 +405,10 @@ core.sanitize.sanitizeSensitiveValue('example-only', 'password') // '[REDACTED]'
|
|
|
370
405
|
const safe = core.sanitize.sanitizeSensitiveFields({ password: 'example-only', email: 'user@example.com' })
|
|
371
406
|
// safe:{ password: '[REDACTED]', email: 'user@example.com' },原对象不变。
|
|
372
407
|
// 默认仅遮蔽凭据;额外业务隐私可在已处理凭据的副本上继续清理。
|
|
373
|
-
core.sanitize.sanitizeSensitiveFields(safe, {
|
|
408
|
+
core.sanitize.sanitizeSensitiveFields(safe, {
|
|
409
|
+
matcher: ['email'],
|
|
410
|
+
replacement: '***'
|
|
411
|
+
})
|
|
374
412
|
// => { password: '[REDACTED]', email: '***' }
|
|
375
413
|
core.sanitize.sanitizeUrl('https://user:example-only@example.com/?token=example-only')
|
|
376
414
|
// => 'https://[REDACTED]:[REDACTED]@example.com/?token=[REDACTED]'
|
|
@@ -449,6 +487,10 @@ if (!failed.success)
|
|
|
449
487
|
|
|
450
488
|
以上常量来自 `HaiConfigError`;跨模块通用错误使用 `HaiCommonError`。
|
|
451
489
|
|
|
490
|
+
通用错误 `HaiCommonError.RATE_LIMIT_EXCEEDED` 对应 `hai:common:203` / HTTP 429;Kit 的快捷响应和守卫同样使用通用错误码。
|
|
491
|
+
|
|
492
|
+
HTTP/UI 边界只对明确的有效 4xx 状态公开业务提示;错误缺少 `httpStatus` 或状态非法时按 500 返回安全提示。手写业务错误须提供完整错误定义或显式状态,不能依赖缺省状态展示原文。
|
|
493
|
+
|
|
452
494
|
### 消息与语言:`core.i18n`
|
|
453
495
|
|
|
454
496
|
为业务字典创建带参数替换的消息获取器,也可取得 Core 内置消息和当前语言。常量列出框架内置语言,不会自动为应用注册翻译。
|
|
@@ -478,7 +520,9 @@ const message = core.i18n.createMessageGetter({
|
|
|
478
520
|
// createMessageGetter 返回消息函数;如 message('welcome', { locale: 'zh-CN', params: { name: 'Alice' } }) 得到 '欢迎 Alice'。
|
|
479
521
|
const greeting = await core.i18n.runWithLocale('en-US', async () => {
|
|
480
522
|
await Promise.resolve()
|
|
481
|
-
return message('welcome', {
|
|
523
|
+
return message('welcome', {
|
|
524
|
+
params: { name: 'Alice' }
|
|
525
|
+
})
|
|
482
526
|
})
|
|
483
527
|
// greeting:'Welcome Alice';runWithLocale 返回回调的结果,此处等待 Promise 得到字符串。
|
|
484
528
|
core.logger.info('Greeting prepared', { greeting })
|
|
@@ -500,7 +544,9 @@ const message = core.zodValidation.createPrefixedZodMessageGetter('core', key =>
|
|
|
500
544
|
? core.i18n.coreM('core_validationEmail', { locale: 'zh-CN' })
|
|
501
545
|
: core.i18n.coreM('core_errorValidation', { locale: 'zh-CN' }))
|
|
502
546
|
// 返回消息函数;message('validationEmail') 得到 '请输入有效的邮箱地址'。
|
|
503
|
-
const parsed = z.object({
|
|
547
|
+
const parsed = z.object({
|
|
548
|
+
email: z.email()
|
|
549
|
+
}).safeParse({ email: 'invalid' })
|
|
504
550
|
if (!parsed.success) {
|
|
505
551
|
const errors = core.zodValidation.mapZodErrorToFormErrors(parsed.error, message)
|
|
506
552
|
// errors:[{ field: 'email', message: '请输入有效的邮箱地址' }]。
|
|
@@ -617,10 +663,14 @@ import { AccessConditionSchema, core } from '@h-ai/core'
|
|
|
617
663
|
|
|
618
664
|
core.access.normalizeClientIp('::ffff:198.51.100.23') // 198.51.100.23。
|
|
619
665
|
const resolve = core.access.createClientIpResolver(['192.0.2.10']) // 返回 IP 解析函数,只信任这个代理。
|
|
620
|
-
const request = new Request('https://example.test/api/orders', {
|
|
666
|
+
const request = new Request('https://example.test/api/orders', {
|
|
667
|
+
headers: { 'x-forwarded-for': '198.51.100.23' }
|
|
668
|
+
})
|
|
621
669
|
// 第二参数必须来自真实 socket/可信平台;这里用测试地址模拟代理对端。
|
|
622
670
|
const clientIp = resolve(request, '192.0.2.10') // '198.51.100.23',读取受信代理的转发头。
|
|
623
|
-
const check = core.access.createConditionCheck(AccessConditionSchema.parse({
|
|
671
|
+
const check = core.access.createConditionCheck(AccessConditionSchema.parse({
|
|
672
|
+
allowIps: ['198.51.100.0/24']
|
|
673
|
+
}))
|
|
624
674
|
// createConditionCheck 返回检查函数;check(clientIp) 得到 { allowed: true }。
|
|
625
675
|
core.logger.info('Address checked', { allowed: check(clientIp).allowed })
|
|
626
676
|
```
|
|
@@ -632,7 +682,15 @@ import { core } from '@h-ai/core'
|
|
|
632
682
|
|
|
633
683
|
// 可改为 loadPolicy({ file: './config/security/request-access.yml' }) 在启动时读独立文件。
|
|
634
684
|
const policy = core.access.loadPolicy({
|
|
635
|
-
rules: [
|
|
685
|
+
rules: [
|
|
686
|
+
{
|
|
687
|
+
id: 'external-api',
|
|
688
|
+
paths: ['/api/external/**'],
|
|
689
|
+
methods: ['POST'],
|
|
690
|
+
allowIps: ['192.0.2.0/24'],
|
|
691
|
+
encryption: 'disabled'
|
|
692
|
+
}
|
|
693
|
+
],
|
|
636
694
|
})
|
|
637
695
|
// policy.rules[0] 保留上方规则,并补 denyIps: []、windows: []、timezone: 'UTC'。
|
|
638
696
|
const check = core.access.createRequestCheck(policy) // 返回请求检查函数,另带 encryption 方法和 requiresEncryption 属性。
|
|
@@ -702,7 +760,9 @@ core.object.omit(settings, ['port']) // { name: 'orders' }。
|
|
|
702
760
|
core.object.keys(settings) // ['name', 'port'],元素类型为 'name' | 'port'。
|
|
703
761
|
core.object.values(settings) // ['orders', 4000]。
|
|
704
762
|
core.object.entries(settings) // [['name', 'orders'], ['port', 4000]]。
|
|
705
|
-
core.object.fromEntries([
|
|
763
|
+
core.object.fromEntries([
|
|
764
|
+
['mode', 'local']
|
|
765
|
+
]) // { mode: 'local' }。
|
|
706
766
|
```
|
|
707
767
|
|
|
708
768
|
deepClone 使用 structuredClone,支持 Date/Map/Set/循环等可克隆值;不可克隆的函数等会抛错。deepMerge 只递归普通对象,数组、Date、集合和类实例由后值覆盖,不修改输入;不把它当作实例克隆。
|
|
@@ -739,11 +799,17 @@ import { core } from '@h-ai/core'
|
|
|
739
799
|
|
|
740
800
|
core.array.unique([1, 1, 2]) // [1, 2]。
|
|
741
801
|
core.array.chunk([1, 2, 3], 2) // [[1, 2], [3]]。
|
|
742
|
-
core.array.groupBy([
|
|
802
|
+
core.array.groupBy([
|
|
803
|
+
{ role: 'admin' },
|
|
804
|
+
{ role: 'user' }
|
|
805
|
+
], item => item.role)
|
|
743
806
|
// => { admin: [{ role: 'admin' }], user: [{ role: 'user' }] }
|
|
744
807
|
core.array.first([1, 2, 3]) // 1;空数组为 undefined。
|
|
745
808
|
core.array.last([1, 2, 3]) // 3;空数组为 undefined。
|
|
746
|
-
core.array.flatten([
|
|
809
|
+
core.array.flatten([
|
|
810
|
+
[1],
|
|
811
|
+
[2, 3]
|
|
812
|
+
]) // [1, 2, 3],只展开一层。
|
|
747
813
|
core.array.compact([0, null, 1, undefined]) // [0, 1],保留 0/false/空字符串。
|
|
748
814
|
core.array.shuffle([1, 2, 3]) // 如 [2, 3, 1],次序随机;新数组不修改输入。
|
|
749
815
|
core.array.intersection([1, 2], [2, 3]) // [2]。
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as BrowserCoreFunctions } from './core-types-
|
|
2
|
-
export { A as AccessCondition, a as AccessConditionSchema, b as AccessDecision, c as AccessFunctions, d as ArrayFn, e as AsyncFn, f as BrowserConfigFn, C as ConfigFn, g as CoreConfig, h as CoreConfigSchema, i as CoreFunctions, j as CoreLogger, k as CoreOptions, l as CreateNotInitializedKitFn, E as Env, m as EnvSchema, n as ErrorFn, o as ErrorInfo, p as ErrorInfoValue, H as HaiCommonError, q as HaiConfigError, r as HaiError, s as HaiErrorDef, t as HaiResult, I as I18nFn, u as IdFn, v as InterpolationParams, L as Locale, w as LocaleInfo, x as LocaleMessages, y as LogContext, z as LogFormat, D as LogFormatSchema, F as LogLevel, G as LogLevelSchema, J as LogObserver, K as LogRecord, M as Logger, N as LoggerFunctions, O as LoggerOptions, P as LoggingConfig, Q as LoggingConfigSchema, R as MatchHandlers, S as MessageDictionary, T as MessageOptions, U as ModuleFn, V as ModuleRuntime, W as NodeCoreFunctions, X as NotInitializedKit, Y as ObjectFn, Z as PaginatedResult, _ as PaginationOptions, $ as PaginationOptionsInput, a0 as RequestAccessCheck, a1 as RequestAccessConfigInput, a2 as RequestAccessConfigSchema, a3 as RequestAccessPolicy, a4 as RequestAccessPolicySchema, a5 as RequestContext, a6 as RequestEncryptionMode, a7 as RuntimeStep, a8 as SanitizeFn, a9 as SanitizeSensitiveFieldsOptions, aa as SensitiveKeyMatcher, ab as StringFn, ac as TimeFn, ad as TrustedProxies, ae as TrustedProxiesSchema, af as TypeUtilFn, ag as ValidationFormError, ah as WatchCallback, ai as ZodMessageGetter, aj as ZodValidationFn, ak as ZodValidationMessageKey, al as err, am as ok } from './core-types-
|
|
1
|
+
import { B as BrowserCoreFunctions } from './core-types-Dp3Vr2uI.js';
|
|
2
|
+
export { A as AccessCondition, a as AccessConditionSchema, b as AccessDecision, c as AccessFunctions, d as ArrayFn, e as AsyncFn, f as BrowserConfigFn, C as ConfigFn, g as CoreConfig, h as CoreConfigSchema, i as CoreFunctions, j as CoreLogger, k as CoreOptions, l as CreateNotInitializedKitFn, E as Env, m as EnvSchema, n as ErrorFn, o as ErrorInfo, p as ErrorInfoValue, H as HaiCommonError, q as HaiConfigError, r as HaiError, s as HaiErrorDef, t as HaiResult, I as I18nFn, u as IdFn, v as InterpolationParams, L as Locale, w as LocaleInfo, x as LocaleMessages, y as LogContext, z as LogFormat, D as LogFormatSchema, F as LogLevel, G as LogLevelSchema, J as LogObserver, K as LogRecord, M as Logger, N as LoggerFunctions, O as LoggerOptions, P as LoggingConfig, Q as LoggingConfigSchema, R as MatchHandlers, S as MessageDictionary, T as MessageOptions, U as ModuleFn, V as ModuleRuntime, W as NodeCoreFunctions, X as NotInitializedKit, Y as ObjectFn, Z as PaginatedResult, _ as PaginationOptions, $ as PaginationOptionsInput, a0 as RequestAccessCheck, a1 as RequestAccessConfigInput, a2 as RequestAccessConfigSchema, a3 as RequestAccessPolicy, a4 as RequestAccessPolicySchema, a5 as RequestContext, a6 as RequestEncryptionMode, a7 as RuntimeStep, a8 as SanitizeFn, a9 as SanitizeSensitiveFieldsOptions, aa as SensitiveKeyMatcher, ab as StringFn, ac as TimeFn, ad as TrustedProxies, ae as TrustedProxiesSchema, af as TypeUtilFn, ag as ValidationFormError, ah as WatchCallback, ai as ZodMessageGetter, aj as ZodValidationFn, ak as ZodValidationMessageKey, al as err, am as ok } from './core-types-Dp3Vr2uI.js';
|
|
3
3
|
import 'zod';
|
|
4
4
|
|
|
5
5
|
/**
|