@h-ai/kit 1.0.0-beta.17 → 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.
Files changed (43) hide show
  1. package/README.en.md +53 -33
  2. package/README.ja.md +53 -33
  3. package/README.md +54 -33
  4. package/dist/adapter/index.d.ts +8 -7
  5. package/dist/adapter/index.js.map +1 -1
  6. package/dist/browser.d.ts +9 -26
  7. package/dist/browser.js +4 -4
  8. package/dist/browser.js.map +1 -1
  9. package/dist/{chunk-JRQPMPQC.js → chunk-BCEBXG4X.js} +2 -2
  10. package/dist/chunk-BCEBXG4X.js.map +1 -0
  11. package/dist/{chunk-7EH47MTW.js → chunk-BVGXHIXR.js} +30 -9
  12. package/dist/chunk-BVGXHIXR.js.map +1 -0
  13. package/dist/{chunk-WCMEGLBL.js → chunk-GQZCU6PC.js} +11 -5
  14. package/dist/chunk-GQZCU6PC.js.map +1 -0
  15. package/dist/{chunk-5JW3VW4Q.js → chunk-JL2C5ZGQ.js} +38 -11
  16. package/dist/chunk-JL2C5ZGQ.js.map +1 -0
  17. package/dist/{chunk-6KS67QUS.js → chunk-WYGIKXHE.js} +20 -7
  18. package/dist/chunk-WYGIKXHE.js.map +1 -0
  19. package/dist/client/index.d.ts +6 -5
  20. package/dist/client/index.js +5 -5
  21. package/dist/client/index.js.map +1 -1
  22. package/dist/index.d.ts +18 -711
  23. package/dist/index.js +264 -149
  24. package/dist/index.js.map +1 -1
  25. package/dist/{kit-a2a-types-ikgvWS3T.d.ts → kit-a2a-types-CeDikRAX.d.ts} +3 -2
  26. package/dist/kit-config-CCksTmi5.d.ts +182 -0
  27. package/dist/kit-crypto-types-CqFENBqm.d.ts +47 -0
  28. package/dist/kit-types-BUDaKGB0.d.ts +2057 -0
  29. package/dist/modules/a2a/index.d.ts +9 -5
  30. package/dist/modules/a2a/index.js +1 -1
  31. package/dist/modules/crypto/index.d.ts +8 -105
  32. package/dist/modules/crypto/index.js +3 -149
  33. package/dist/modules/crypto/index.js.map +1 -1
  34. package/package.json +22 -22
  35. package/dist/chunk-5JW3VW4Q.js.map +0 -1
  36. package/dist/chunk-6KS67QUS.js.map +0 -1
  37. package/dist/chunk-7EH47MTW.js.map +0 -1
  38. package/dist/chunk-JRQPMPQC.js.map +0 -1
  39. package/dist/chunk-WCMEGLBL.js.map +0 -1
  40. package/dist/kit-client-auth-DeWmc-1u.d.ts +0 -406
  41. package/dist/kit-crypto-types-Brd0l8Hv.d.ts +0 -204
  42. package/dist/kit-i18n-CjwdGeKY.d.ts +0 -506
  43. package/dist/kit-types-CnfBC89D.d.ts +0 -832
@@ -1,832 +0,0 @@
1
- import { HaiResult, TrustedProxies, RequestAccessConfigInput } from '@h-ai/core';
2
- import { CryptoFunctions, TransportServerKeyRing, TransportKeyStore } from '@h-ai/crypto';
3
- import { AuthnOperations } from '@h-ai/iam';
4
- import { RequestEvent } from '@sveltejs/kit';
5
-
6
- /**
7
- * @h-ai/kit — 速率限制中间件
8
- *
9
- * 以首个成功请求为起点的固定窗口限流;后续计数不延长窗口。
10
- * 内置内存存储(`MemoryRateLimitStore`),并支持通过 `RateLimitStore` 接入
11
- * Redis 等外部存储后端。
12
- * @module kit-ratelimit
13
- */
14
-
15
- /**
16
- * 速率限制存储条目
17
- * @example
18
- * ```ts
19
- * import type { RateLimitEntry } from '@h-ai/kit'
20
- *
21
- * const value: RateLimitEntry = { count: 1, resetAt: Date.now() + 60_000 }
22
- * void value
23
- * ```
24
- */
25
- interface RateLimitEntry {
26
- /** 当前窗口内的请求次数 */
27
- count: number;
28
- /** 窗口重置时间戳(ms) */
29
- resetAt: number;
30
- }
31
- /**
32
- * 原子固定窗口计数器;故障抛错由中间件转为503,禁止读改写回退。
33
- * @example
34
- * ```ts
35
- * import type { RateLimitStore } from '@h-ai/kit'
36
- *
37
- * async function count(store: RateLimitStore) {
38
- * return store.increment('client_1', 60_000)
39
- * }
40
- * ```
41
- */
42
- interface RateLimitStore {
43
- /** shared要求共享后端;memory仅限显式开发/测试。 */
44
- readonly scope: 'shared' | 'memory';
45
- /** 原子计数并保留首次请求的窗口,返回提交后的计数/重置点。 */
46
- increment: (key: string, windowMs: number) => Promise<RateLimitEntry> | RateLimitEntry;
47
- }
48
- /**
49
- * 共享缓存的最小结构契约;使用其单键CAS与服务端TTL,不使用锁或客户端到期清零。
50
- * @example
51
- * ```ts
52
- * import type { RateLimitCache } from '@h-ai/kit'
53
- * import { cache } from '@h-ai/cache'
54
- *
55
- * const backend: RateLimitCache = cache
56
- * void backend
57
- * ```
58
- */
59
- interface RateLimitCache {
60
- readonly config: {
61
- type: string;
62
- } | null;
63
- readonly kv: {
64
- get: <T>(key: string) => Promise<HaiResult<T | null>>;
65
- compareAndSwap: (key: string, expected: RateLimitEntry | undefined, value: RateLimitEntry, options: {
66
- px?: number;
67
- keepTtl?: boolean;
68
- }) => Promise<HaiResult<boolean>>;
69
- };
70
- }
71
- /**
72
- * 创建共享缓存固定窗口计数器;Redis/Cluster的CAS与TTL构成原子边界。
73
- * 只有缓存键实际过期才新建窗口,节点时钟只影响响应头估算,不提前重置计数。
74
- * @param backend - 已初始化的cache模块;每次请求重新核对provider,防止切换后回退内存
75
- * @param options - 业务限流命名空间与显式开发内存选项
76
- * @param options.namespace - 同一策略的稳定业务范围
77
- * @param options.allowMemory - 仅开发或显式HAI_E2E测试允许内存cache
78
- * @returns 无内部定时器、不接管cache生命周期的计数器;基础设施错误显式抛错
79
- * @example
80
- * ```ts
81
- * import { kit } from '@h-ai/kit'
82
- *
83
- * import { cache } from '@h-ai/cache'
84
- *
85
- * // 应用在启动时先初始化 Redis cache,关闭时由应用统一回收。
86
- * const store = kit.middleware.createCacheRateLimitStore(cache, { namespace: 'api' })
87
- * void store
88
- * ```
89
- */
90
- declare function createCacheRateLimitStore(backend: RateLimitCache, options: {
91
- namespace: string;
92
- allowMemory?: boolean;
93
- }): RateLimitStore;
94
- /**
95
- * 创建显式开发/测试计数器;无定时器,最多保存 10000 个窗口,生产拒绝内存模式。
96
- * @returns 由调用者持有的计数器;丢弃引用即可回收,无需关闭,也不接管外部 store。
97
- * @example
98
- * ```ts
99
- * import { kit } from '@h-ai/kit'
100
- *
101
- * // 开发/测试进程;生产环境会明确拒绝内存计数。
102
- * const store = kit.middleware.createMemoryRateLimitStore()
103
- * const entry = await store.increment('client_1', 60_000)
104
- * void entry.count
105
- * ```
106
- */
107
- declare function createMemoryRateLimitStore(): MemoryRateLimitStore;
108
- /**
109
- * 内存速率限制存储
110
- *
111
- * 基于 Map 实现,仅用于单进程开发/测试;每次请求最多扫描 64 项过期窗口,
112
- * 不持有定时器。最多 10000 项,容量耗尽时拒绝新 key,不驱逐有效计数以免绕过限流。
113
- * @example
114
- * ```ts
115
- * import { kit } from '@h-ai/kit'
116
- *
117
- * // 仅开发/测试;丢弃引用即可回收,无内部定时器。
118
- * const store = kit.middleware.createMemoryRateLimitStore()
119
- * void store.increment('client_1', 60_000)
120
- * ```
121
- */
122
- declare class MemoryRateLimitStore implements RateLimitStore {
123
- readonly scope: "memory";
124
- private store;
125
- private cleanupCursor;
126
- /**
127
- * 有界惰性回收;保留迭代位置,避免每次从头扫描使尾部过期项永久滞留。
128
- * @param now - 当前请求时间,等于 resetAt 时窗口已经失效。
129
- */
130
- private prune;
131
- /**
132
- * 原子自增(内存实现为同步操作,天然原子)
133
- *
134
- * @param key - 限流键
135
- * @param windowMs - 窗口时长
136
- * @returns 自增后的快照,修改返回对象不会改变已保存的计数。
137
- * @throws 新 key 超出容量或期限非法;中间件将其转换为 503。
138
- * @example store.increment('client', 60_000)
139
- */
140
- increment(key: string, windowMs: number): RateLimitEntry;
141
- }
142
- /**
143
- * 创建速率限制中间件
144
- *
145
- * 基于必选原子存储的固定窗口限流:
146
- * - 超限时返回 429,并在响应头中告知重置时间
147
- * - 正常响应附带 `X-RateLimit-*` 头
148
- * - 必须显式传入 store;生产使用共享计数器,故障返回503
149
- *
150
- * @param config - 限流配置
151
- * @returns Middleware 实例
152
- * @example
153
- * ```ts
154
- * import { kit } from '@h-ai/kit'
155
- *
156
- * import { cache } from '@h-ai/cache'
157
- *
158
- * // Redis 由应用初始化和关闭;多节点复用相同 namespace。
159
- * const middleware = kit.middleware.rateLimit({ windowMs: 60_000, maxRequests: 100, store: kit.middleware.createCacheRateLimitStore(cache, { namespace: 'api' }) })
160
- * void middleware
161
- * ```
162
- */
163
- declare function rateLimitMiddleware(config: RateLimitConfig): Middleware;
164
-
165
- /**
166
- * @h-ai/kit — 类型定义
167
- *
168
- * SvelteKit 集成相关类型
169
- * @module kit-types
170
- */
171
-
172
- /**
173
- * 服务器监听配置(对应 `config/_kit.yml` 的 `server`)。
174
- * @example
175
- * ```ts
176
- * import type { KitServerConfig } from '@h-ai/kit'
177
- *
178
- * const value: KitServerConfig = { host: '127.0.0.1', port: 3000 }
179
- * void value
180
- * ```
181
- */
182
- interface KitServerConfig {
183
- readonly host: string;
184
- readonly port: number;
185
- }
186
- /**
187
- * `config/_kit.yml` 中的服务器监听输入类型。
188
- * @example
189
- * ```ts
190
- * import type { KitServerConfigInput } from '@h-ai/kit'
191
- *
192
- * const value: KitServerConfigInput = { port: 4000 }
193
- * void value
194
- * ```
195
- */
196
- type KitServerConfigInput = Partial<KitServerConfig>;
197
- /**
198
- * `config/_kit.yml` 中的 transport 配置。
199
- * @example
200
- * ```ts
201
- * import type { KitTransportConfig } from '@h-ai/kit'
202
- *
203
- * const value: KitTransportConfig = { keyExchangePath: '/api/_hai/key-exchange', excludePaths: ['/api/health'] }
204
- * void value
205
- * ```
206
- */
207
- interface KitTransportConfig {
208
- /** 双向明文 UTF-8 字节上限;省略使用 1 MiB,范围 1 KiB~64 MiB。 */
209
- readonly maxPlaintextBytes?: number;
210
- /** 请求时间允许领先服务器的秒数,默认 30,整数范围 0~300。 */
211
- readonly maxFutureSkewSeconds?: number;
212
- /** 请求从签发起的有效秒数,默认 300,整数范围 1~600。 */
213
- readonly maxRequestAgeSeconds?: number;
214
- /** 按完整路径段匹配的明文容量;* 匹配单段。 */
215
- readonly routePlaintextBytes?: Readonly<Record<string, number>>;
216
- readonly keyExchangePath: `/${string}`;
217
- readonly excludePaths: readonly `/${string}`[];
218
- }
219
- /**
220
- * `config/_kit.yml` 的顶层配置结构。
221
- * @example
222
- * ```ts
223
- * import type { KitConfig } from '@h-ai/kit'
224
- *
225
- * const value: KitConfig = { server: { host: '127.0.0.1', port: 3000 }, transport: false, trustedProxies: 'auto', access: false }
226
- * void value
227
- * ```
228
- */
229
- interface KitConfig {
230
- readonly server: KitServerConfig;
231
- readonly transport: false | KitTransportConfig;
232
- /** auto 仅在受管私有容器入口采用容器网段;普通宿主忽略转发头。 */
233
- readonly trustedProxies: TrustedProxies;
234
- /** 每次请求的地址/时间/路径限制,默认 false;不会限制由静态服务器直接提供的资源。 */
235
- readonly access: RequestAccessConfigInput;
236
- }
237
- /**
238
- * `config/_kit.yml` 中的 transport 输入类型。
239
- * @example
240
- * ```ts
241
- * import type { KitTransportConfigInput } from '@h-ai/kit'
242
- *
243
- * const value: KitTransportConfigInput = { excludePaths: ['/api/health'] }
244
- * void value
245
- * ```
246
- */
247
- type KitTransportConfigInput = Partial<{
248
- readonly maxPlaintextBytes: number | 'auto';
249
- readonly maxFutureSkewSeconds: number;
250
- readonly maxRequestAgeSeconds: number;
251
- readonly routePlaintextBytes: Readonly<Record<string, number>>;
252
- readonly keyExchangePath: `/${string}`;
253
- readonly excludePaths: readonly `/${string}`[];
254
- }>;
255
- /**
256
- * `config/_kit.yml` 的顶层输入类型。
257
- * @example
258
- * ```ts
259
- * import type { KitConfigInput } from '@h-ai/kit'
260
- *
261
- * const value: KitConfigInput = { transport: false }
262
- * void value
263
- * ```
264
- */
265
- interface KitConfigInput {
266
- readonly server?: KitServerConfigInput;
267
- readonly transport?: false | KitTransportConfigInput;
268
- readonly trustedProxies?: TrustedProxies;
269
- readonly access?: RequestAccessConfigInput;
270
- }
271
- /**
272
- * 浏览器可接收的 Kit 公共配置,仅包含传输协议路径和开关。
273
- * @example
274
- * ```ts
275
- * import type { KitPublicConfig } from '@h-ai/kit'
276
- * const config: KitPublicConfig = { transport: false }
277
- * ```
278
- */
279
- type KitPublicConfig = Pick<KitConfig, 'transport'>;
280
- /**
281
- * kit.auth 认证操作(由 createHandle auth.operations 注入)
282
- *
283
- * 注入后,kit.auth.login / kit.auth.logout 等函数自动委托到 iam.auth 对应方法。
284
- * 传入 `iam.auth` 即可,kit 会自动提取所需方法。
285
- * @example
286
- * ```ts
287
- * import type { AuthOperations } from '@h-ai/kit'
288
- * import { iam } from '@h-ai/iam'
289
- *
290
- * // 在 IAM 初始化后注入其当前操作对象。
291
- * const operations: AuthOperations = iam.auth
292
- * void operations
293
- * ```
294
- */
295
- type AuthOperations = Pick<AuthnOperations, 'login' | 'loginWithOtp' | 'loginWithLdap' | 'loginWithApiKey' | 'registerAndLogin' | 'logout'>;
296
- /**
297
- * 认证操作提供器:支持直接传对象或按需返回最新对象的工厂函数
298
- * @example
299
- * ```ts
300
- * import type { AuthOperationsProvider } from '@h-ai/kit'
301
- * import { iam } from '@h-ai/iam'
302
- *
303
- * const operations: AuthOperationsProvider = () => iam.auth
304
- * void operations
305
- * ```
306
- */
307
- type AuthOperationsProvider = AuthOperations | (() => AuthOperations);
308
- /**
309
- * 会话数据最小接口
310
- *
311
- * 守卫和权限检查函数所需的最小会话形状。
312
- * 应用层扩展的 session(如添加 displayName / avatarUrl 等字段)
313
- * 只要包含此接口的字段即可直接传入守卫函数,无需类型断言。
314
- * @example
315
- * ```ts
316
- * import type { SessionLike } from '@h-ai/kit'
317
- *
318
- * const value: SessionLike = { userId: 'user_1', roles: ['editor'], permissions: ['article:read'] }
319
- * void value
320
- * ```
321
- */
322
- interface SessionLike {
323
- /** 用户 ID */
324
- userId: string;
325
- /** 角色列表 */
326
- roles: string[];
327
- /** 权限列表 */
328
- permissions: string[];
329
- /** 允许任意扩展字段 */
330
- [key: string]: unknown;
331
- }
332
- /**
333
- * 用户会话数据
334
- *
335
- * 在 Handle Hook 中通过 `validateSession` 解析后注入 `event.locals.session`。
336
- * 守卫和中间件通过此结构判断用户身份、角色与权限。
337
- *
338
- * 应用层可通过 `& { displayName: string }` 等方式扩展,
339
- * 扩展后的类型自动兼容所有守卫和权限检查函数(它们接受 `SessionLike`)。
340
- * @example
341
- * ```ts
342
- * import type { SessionData } from '@h-ai/kit'
343
- *
344
- * const value: SessionData = { userId: 'user_1', username: 'alice', roles: ['editor'], permissions: ['article:read'] }
345
- * void value
346
- * ```
347
- */
348
- interface SessionData {
349
- /** 用户 ID */
350
- userId: string;
351
- /** 用户名 */
352
- username?: string;
353
- /** 角色列表 */
354
- roles: string[];
355
- /** 权限列表 */
356
- permissions: string[];
357
- /** 自定义数据 */
358
- data?: Record<string, unknown>;
359
- /** 允许任意扩展字段 */
360
- [key: string]: unknown;
361
- }
362
- /**
363
- * 扩展的请求事件
364
- *
365
- * 在 SvelteKit 原生 `RequestEvent` 基础上注入会话和请求 ID。
366
- * @example
367
- * ```ts
368
- * import type { HaiRequestEvent } from '@h-ai/kit'
369
- *
370
- * function requestLabel(event: HaiRequestEvent) {
371
- * return { requestId: event.requestId, userId: event.session?.userId }
372
- * }
373
- * ```
374
- */
375
- interface HaiRequestEvent extends RequestEvent {
376
- /** 会话数据 */
377
- session?: SessionData;
378
- /** 请求 ID */
379
- requestId: string;
380
- }
381
- /**
382
- * 中间件上下文
383
- *
384
- * 由 `createHandle` 构建,传递给所有中间件函数。
385
- * 包含当前请求事件、已解析的会话以及请求唯一 ID。
386
- * @example
387
- * ```ts
388
- * import type { MiddlewareContext } from '@h-ai/kit'
389
- *
390
- * function requestLabel(context: MiddlewareContext) {
391
- * return context.event.url.pathname + ':' + context.requestId
392
- * }
393
- * ```
394
- */
395
- interface MiddlewareContext {
396
- /** 请求事件 */
397
- event: RequestEvent;
398
- /** 会话数据 */
399
- session?: SessionData;
400
- /** 请求 ID */
401
- requestId: string;
402
- }
403
- /**
404
- * 中间件函数
405
- *
406
- * 遵循洋葱模型:调用 `next()` 前执行前置逻辑,调用后执行后置逻辑。
407
- * @example
408
- * ```ts
409
- * import type { Middleware } from '@h-ai/kit'
410
- *
411
- * const value: Middleware = async (_context, next) => { const response = await next(); response.headers.set('X-Example', 'enabled'); return response }
412
- * void value
413
- * ```
414
- */
415
- type Middleware = (context: MiddlewareContext, next: () => Promise<Response>) => Promise<Response>;
416
- /**
417
- * 路由守卫结果
418
- *
419
- * 守卫函数必须返回此结构。`allowed: true` 表示放行,否则根据
420
- * `redirect` / `message` / `status` 决定拦截行为。
421
- * @example
422
- * ```ts
423
- * import type { GuardResult } from '@h-ai/kit'
424
- *
425
- * const value: GuardResult = { allowed: false, status: 403 }
426
- * void value
427
- * ```
428
- */
429
- interface GuardResult {
430
- /** 是否允许访问 */
431
- allowed: boolean;
432
- /** 重定向 URL(拒绝时) */
433
- redirect?: string;
434
- /** 错误消息(拒绝时) */
435
- message?: string;
436
- /** HTTP 状态码 */
437
- status?: number;
438
- }
439
- /**
440
- * 路由守卫函数
441
- *
442
- * 接收请求事件与可选会话,返回 `GuardResult`(同步或异步均可)。
443
- * @example
444
- * ```ts
445
- * import type { RouteGuard } from '@h-ai/kit'
446
- *
447
- * const value: RouteGuard = (_event, session) => ({ allowed: session?.permissions.includes('article:read') ?? false, status: 403 })
448
- * void value
449
- * ```
450
- */
451
- type RouteGuard = (event: RequestEvent, session?: SessionData) => Promise<GuardResult> | GuardResult;
452
- /**
453
- * 守卫配置
454
- *
455
- * 在 `createHandle({ guards })` 中使用。
456
- * `paths` 支持 `/*` 和 `/**` 通配符,`exclude` 优先于 `paths`。
457
- * @example
458
- * ```ts
459
- * import type { GuardConfig } from '@h-ai/kit'
460
- *
461
- * const value: GuardConfig = { paths: ['/admin/**'], guard: (_event, session) => ({ allowed: Boolean(session) }) }
462
- * void value
463
- * ```
464
- */
465
- interface GuardConfig {
466
- /** 守卫函数 */
467
- guard: RouteGuard;
468
- /** 适用路径(glob 模式) */
469
- paths?: string[];
470
- /** 排除路径 */
471
- exclude?: string[];
472
- }
473
- /**
474
- * 认证配置
475
- *
476
- * 在 `HandleConfig.auth` 中使用,自动完成:
477
- * 1. 从 Bearer header / Cookie 提取 Token
478
- * 2. 调用 verifyToken 恢复会话
479
- * 3. 根据 protectedPaths / publicPaths 自动生成路由守卫
480
- *
481
- * API 路径(以 `/api/` 开头)未认证时返回 401 JSON;
482
- * 非 API 路径未认证时重定向到 `loginUrl`(若配置)或返回 401。
483
- * @example
484
- * ```ts
485
- * import type { HandleAuthConfig } from '@h-ai/kit'
486
- *
487
- * const value: HandleAuthConfig = { verifyToken: async () => null, protectedPaths: ['/admin/**'], loginUrl: '/auth/login' }
488
- * void value
489
- * ```
490
- */
491
- interface HandleAuthConfig {
492
- /** 令牌验证函数,返回 SessionData 或 null */
493
- verifyToken: (token: string) => Promise<SessionData | null>;
494
- /**
495
- * 认证操作。
496
- *
497
- * - 直接对象:`operations: iam.auth`
498
- * - 工厂函数:`operations: () => iam.auth`(推荐,避免模块加载阶段捕获旧引用)
499
- */
500
- operations?: AuthOperationsProvider;
501
- /** 未认证时 UI 路由重定向地址(如 `'/auth/login'`) */
502
- loginUrl?: string;
503
- /** Token Cookie 名(默认 `'hai_access_token'`) */
504
- cookieName?: string;
505
- /** 需要认证的路径(支持 `/*` `/**` 通配符) */
506
- protectedPaths?: string[];
507
- /** 免认证的路径(优先于 protectedPaths) */
508
- publicPaths?: string[];
509
- }
510
- /**
511
- * Handle Hook 配置
512
- *
513
- * 传给 `kit.createHandle()` 的配置。
514
- *
515
- * 自动完成:
516
- * 1. 生成 requestId 并注入 `event.locals`
517
- * 2. 根据 `auth` 配置解析会话
518
- * 3. 执行路由守卫
519
- * 4. 执行中间件链(logging / rateLimit / 自定义)
520
- * 5. 调用 resolve + 附加 `X-Request-Id` 响应头
521
- * @example
522
- * ```ts
523
- * import type { HandleConfig } from '@h-ai/kit'
524
- *
525
- * const value: HandleConfig = { logging: true, auth: { verifyToken: async () => null, protectedPaths: ['/admin/**'] } }
526
- * void value
527
- * ```
528
- */
529
- interface HandleConfig {
530
- /** 可信入口地址;auto 只信任受管私有容器网段,空数组忽略转发头。 */
531
- trustedProxies?: TrustedProxies;
532
- /** 每次请求的 IP/时间/路径策略;独立文件在创建 Handle 时读取并验证一次。 */
533
- access?: RequestAccessConfigInput;
534
- /**
535
- * 认证配置
536
- *
537
- * 提供后自动完成 Token 解析、会话恢复、路由守卫等。
538
- * 不提供则不做认证处理。
539
- */
540
- auth?: HandleAuthConfig;
541
- /**
542
- * 速率限制配置
543
- *
544
- * 提供对象启用速率限制;设为 `false` 显式禁用。
545
- * 不提供则不开启速率限制。
546
- */
547
- rateLimit?: Omit<RateLimitConfig, 'windowMs' | 'maxRequests'> & {
548
- windowMs?: number;
549
- maxRequests?: number;
550
- } | false;
551
- /**
552
- * 请求日志配置
553
- *
554
- * - `true`(默认):启用日志中间件
555
- * - `{ logBody: true }`:启用并记录请求体
556
- * - `false`:禁用日志
557
- */
558
- logging?: boolean | {
559
- logBody?: boolean;
560
- };
561
- /**
562
- * 加密配置(传输加密 + Cookie 加密)
563
- *
564
- * 启用后 kit 自动在 Handle 中完成:
565
- * - 传输加密:请求体解密 / 响应体加密 / 密钥交换端点
566
- * - Cookie 加密:对指定 Cookie 的 get/set 自动 AES 加解密
567
- */
568
- crypto?: HookCryptoConfig;
569
- /** 自定义错误处理(不提供则使用内置的 500 JSON 响应) */
570
- onError?: (error: unknown, event: RequestEvent) => Response | Promise<Response>;
571
- /** 自定义守卫(在 auth 自动守卫之后执行) */
572
- guards?: GuardConfig[];
573
- /** 自定义中间件(在内置 logging / rateLimit 之后执行) */
574
- middleware?: Middleware[];
575
- /**
576
- * A2A 协议集成
577
- *
578
- * 传入 `ai.a2a` 操作对象后,自动挂载 Agent Card 发现端点和 JSON-RPC 处理端点。
579
- *
580
- * - 简单模式:`a2a: ai.a2a`(使用默认路径)
581
- * - 配置模式:`a2a: { operations: ai.a2a, rpcPath: '/api/a2a' }`
582
- */
583
- a2a?: HandleA2AOperations | HandleA2AConfig;
584
- }
585
- /**
586
- * A2A 操作接口(用于 Handle 集成)
587
- *
588
- * 与 `ai.a2a` 结构兼容,可直接传入 `ai.a2a` 对象。
589
- * @example
590
- * ```ts
591
- * import type { HandleA2AOperations } from '@h-ai/kit'
592
- * import { ai } from '@h-ai/ai'
593
- *
594
- * function operationsAfterInit(): HandleA2AOperations { return ai.a2a }
595
- * ```
596
- */
597
- interface HandleA2AOperations {
598
- /** 获取 Agent Card(返回 HaiResult 对象) */
599
- getAgentCard: () => {
600
- success: boolean;
601
- data?: unknown;
602
- error?: unknown;
603
- };
604
- /** 处理 JSON-RPC 请求 */
605
- handleRequest: (body: unknown, context?: Record<string, unknown>) => Promise<{
606
- streaming: boolean;
607
- body?: unknown;
608
- stream?: AsyncGenerator<unknown, void, undefined>;
609
- }>;
610
- }
611
- /**
612
- * A2A Handle 配置(高级模式)
613
- * @example
614
- * ```ts
615
- * import type { HandleA2AConfig } from '@h-ai/kit'
616
- * import { ai } from '@h-ai/ai'
617
- *
618
- * function configAfterInit(): HandleA2AConfig { return { operations: ai.a2a, authenticate: async () => null } }
619
- * ```
620
- */
621
- interface HandleA2AConfig {
622
- /** A2A 操作接口(通常传入 `ai.a2a`) */
623
- operations: HandleA2AOperations;
624
- /** Agent Card 端点路径(默认 `/.well-known/agent-card.json`) */
625
- cardPath?: string;
626
- /** JSON-RPC 端点路径(默认 `/a2a`) */
627
- rpcPath?: string;
628
- /**
629
- * A2A 认证
630
- *
631
- * - `'apiKey'`:使用 IAM API Key 认证(读取 Agent Card.securitySchemes.apiKey)
632
- * - 函数:自定义认证回调;返回 null/undefined 拒绝请求(401)
633
- * 未配置此项才允许匿名请求。
634
- */
635
- authenticate?: 'apiKey' | ((event: RequestEvent) => Promise<Record<string, unknown> | null | undefined>);
636
- }
637
- /**
638
- * 传输加密详细配置
639
- * @example
640
- * ```ts
641
- * import type { TransportEncryptionOptions } from '@h-ai/kit'
642
- * import type { TransportServerKeyRing, TransportKeyStore } from '@h-ai/crypto'
643
- *
644
- * function transport(serverKeyRing: TransportServerKeyRing, keyStore: TransportKeyStore): TransportEncryptionOptions {
645
- * return { serverKeyRing, keyStore, excludePaths: ['/api/health'] }
646
- * }
647
- * ```
648
- */
649
- interface TransportEncryptionOptions {
650
- /** 宿主构建挂载目录,默认空字符串;SvelteKit 传入 $app/paths.base。 */
651
- basePath?: string;
652
- /** 双向业务明文 UTF-8 字节上限;默认 1 MiB,整数范围 1 KiB~64 MiB。 */
653
- maxPlaintextBytes?: number;
654
- /** 请求时间允许领先服务器的秒数,默认 30,整数范围 0~300。 */
655
- maxFutureSkewSeconds?: number;
656
- /** 请求从签发起的有效秒数,默认 300,整数范围 1~600。 */
657
- maxRequestAgeSeconds?: number;
658
- /** 路由明文容量;* 匹配一个完整路径段。 */
659
- routePlaintextBytes?: Readonly<Record<string, number>>;
660
- /** 受管服务端版本化密钥环,不进入公开 YAML/客户端配置。 */
661
- serverKeyRing: TransportServerKeyRing;
662
- /** 密钥交换端点路径(默认 `'/api/_hai/key-exchange'`) */
663
- keyExchangePath?: string;
664
- /** 排除路径(不加密),支持精确匹配和前缀匹配 */
665
- excludePaths?: readonly string[];
666
- /** 共享客户端公钥存储;适用于多节点部署。 */
667
- keyStore: TransportKeyStore;
668
- }
669
- /**
670
- * Handle Hook 加密配置
671
- *
672
- * 在 `kit.createHandle({ crypto: { ... } })` 中使用。
673
- * @example
674
- * ```ts
675
- * import type { HookCryptoConfig, TransportEncryptionOptions } from '@h-ai/kit'
676
- * import { crypto } from '@h-ai/crypto'
677
- *
678
- * function config(transport: TransportEncryptionOptions): HookCryptoConfig { return { crypto, transport } }
679
- * ```
680
- */
681
- interface HookCryptoConfig {
682
- /** 注入 @h-ai/crypto 实例 */
683
- crypto: CryptoFunctions;
684
- /**
685
- * 启用传输加密。
686
- * - `false` 或省略:关闭
687
- * - 对象:必填受管 serverKeyRing / keyStore,可附加公开路径配置
688
- */
689
- transport?: false | TransportEncryptionOptions;
690
- /**
691
- * 需要加密的 Cookie 名称列表
692
- *
693
- * 列出的 Cookie 在 set 时自动 SM4-CBC 加密,get 时自动解密。
694
- */
695
- encryptedCookies?: string[];
696
- /**
697
- * Cookie 加密密钥(32 字符十六进制 = 16 字节 SM4 密钥)
698
- *
699
- * 如不提供,则从环境变量 `HAI_KIT_COOKIE_KEY` 读取。
700
- * 配置了 `encryptedCookies` 但两者都未设置时,`kit.createHandle()` 会立即抛出配置错误,
701
- * 避免受保护 Cookie 静默降级为明文。
702
- */
703
- cookieEncryptionKey?: string;
704
- }
705
- /**
706
- * API 响应包装
707
- *
708
- * `kit.response.*` 系列函数统一返回此结构的 JSON 响应。
709
- * 成功时 `success: true` 且 `data` 有值;失败时 `success: false` 且 `error` 有值。
710
- * @example
711
- * ```ts
712
- * import type { ApiResponse } from '@h-ai/kit'
713
- *
714
- * const value: ApiResponse<{ id: string }> = { success: true, data: { id: 'article_1' } }
715
- * void value
716
- * ```
717
- */
718
- interface ApiResponse<T = unknown> {
719
- /** 是否成功 */
720
- success: boolean;
721
- /** 数据 */
722
- data?: T;
723
- /** 错误信息 */
724
- error?: {
725
- code: string;
726
- message: string;
727
- traceId?: string;
728
- details?: unknown;
729
- };
730
- /** 请求 ID */
731
- requestId?: string;
732
- }
733
- /**
734
- * 表单验证错误
735
- *
736
- * 由 `kit.validate.*` 在校验失败时返回。
737
- * `field` 使用点号路径(如 `'address.city'`),`_` 表示全局错误。
738
- * @example
739
- * ```ts
740
- * import type { FormError } from '@h-ai/kit'
741
- *
742
- * const value: FormError = { field: 'title', message: 'Title is required' }
743
- * void value
744
- * ```
745
- */
746
- interface FormError {
747
- /** 字段名 */
748
- field: string;
749
- /** 错误消息 */
750
- message: string;
751
- }
752
- /**
753
- * 表单验证结果
754
- *
755
- * @template T - Zod schema 推导出的数据类型
756
- * @example
757
- * ```ts
758
- * import type { FormValidationResult } from '@h-ai/kit'
759
- *
760
- * const value: FormValidationResult<{ title: string }> = { valid: true, data: { title: 'Example' }, errors: [] }
761
- * void value
762
- * ```
763
- */
764
- interface FormValidationResult<T> {
765
- /** 是否有效 */
766
- valid: boolean;
767
- /** 解析后的数据 */
768
- data?: T;
769
- /** 错误列表 */
770
- errors: FormError[];
771
- }
772
- /**
773
- * 速率限制配置
774
- *
775
- * 基于可插拔原子存储的固定窗口限流。超限后返回 429 状态码与 `Retry-After` 响应头。
776
- * 必须显式传入 store;生产使用共享计数器,故障返回503。
777
- * @example
778
- * ```ts
779
- * import type { RateLimitConfig } from '@h-ai/kit'
780
- * import { kit } from '@h-ai/kit'
781
- * import { cache } from '@h-ai/cache'
782
- *
783
- * const config: RateLimitConfig = { windowMs: 60_000, maxRequests: 100, store: kit.middleware.createCacheRateLimitStore(cache, { namespace: 'api' }) }
784
- * void config
785
- * ```
786
- */
787
- interface RateLimitConfig {
788
- /** 时间窗口 (ms) */
789
- windowMs: number;
790
- /** 最大请求数 */
791
- maxRequests: number;
792
- /** 自定义 key 生成 */
793
- keyGenerator?: (event: RequestEvent) => string;
794
- /** 超限处理 */
795
- onLimitReached?: (event: RequestEvent) => Response;
796
- /**
797
- * 自定义存储实现
798
- *
799
- * 必须提供原子 increment;不支持 get+set 回退。共享缓存由调用方初始化和关闭。
800
- */
801
- store: RateLimitStore;
802
- }
803
- /**
804
- * CORS 中间件配置
805
- *
806
- * 配置跨域资源共享策略。预检请求(OPTIONS)自动返回 204。
807
- * @example
808
- * ```ts
809
- * import type { CorsConfig } from '@h-ai/kit'
810
- *
811
- * const value: CorsConfig = { origin: ['https://app.example.com'], credentials: true }
812
- * void value
813
- * ```
814
- */
815
- interface CorsConfig {
816
- /** 允许的源(支持通配符,如 `*.example.com`) */
817
- origin?: string | string[] | ((origin: string) => boolean);
818
- /** 允许的方法 */
819
- methods?: string[];
820
- /** 允许的头 */
821
- allowedHeaders?: string[];
822
- /** 暴露的头 */
823
- exposedHeaders?: string[];
824
- /** 是否允许凭证 */
825
- credentials?: boolean;
826
- /** 预检缓存时间 (秒) */
827
- maxAge?: number;
828
- /** 是否自动允许 Capacitor WebView origin(默认 true) */
829
- capacitor?: boolean;
830
- }
831
-
832
- export { type ApiResponse as A, type CorsConfig as C, type FormError as F, type GuardConfig as G, type HaiRequestEvent as H, type KitConfig as K, type Middleware as M, type RateLimitConfig as R, type SessionData as S, type TransportEncryptionOptions as T, type AuthOperations as a, type AuthOperationsProvider as b, type FormValidationResult as c, type GuardResult as d, type HandleA2AConfig as e, type HandleA2AOperations as f, type HandleAuthConfig as g, type HandleConfig as h, type HookCryptoConfig as i, type KitConfigInput as j, type KitPublicConfig as k, type KitServerConfig as l, type KitServerConfigInput as m, type KitTransportConfig as n, type KitTransportConfigInput as o, type MiddlewareContext as p, type RouteGuard as q, type SessionLike as r, rateLimitMiddleware as s, createCacheRateLimitStore as t, createMemoryRateLimitStore as u, MemoryRateLimitStore as v, type RateLimitCache as w, type RateLimitEntry as x, type RateLimitStore as y };