@h-ai/kit 0.1.0-alpha.67 → 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.
Files changed (44) hide show
  1. package/README.en.md +39 -13
  2. package/README.ja.md +39 -13
  3. package/README.md +39 -13
  4. package/dist/adapter/index.d.ts +17 -2
  5. package/dist/adapter/index.js.map +1 -1
  6. package/dist/browser.d.ts +12 -6
  7. package/dist/browser.js +6 -7
  8. package/dist/browser.js.map +1 -1
  9. package/dist/{chunk-DVW7CQ3H.js → chunk-2PWGJCWX.js} +3 -3
  10. package/dist/chunk-2PWGJCWX.js.map +1 -0
  11. package/dist/{chunk-VOTDAVCB.js → chunk-2YYRP7HH.js} +17 -33
  12. package/dist/chunk-2YYRP7HH.js.map +1 -0
  13. package/dist/{chunk-MLSP67JF.js → chunk-333FGMGQ.js} +59 -111
  14. package/dist/chunk-333FGMGQ.js.map +1 -0
  15. package/dist/chunk-OVRZIDCD.js +175 -0
  16. package/dist/chunk-OVRZIDCD.js.map +1 -0
  17. package/dist/{chunk-L7BTMAKX.js → chunk-P6XH7G4N.js} +3 -6
  18. package/dist/chunk-P6XH7G4N.js.map +1 -0
  19. package/dist/{chunk-NVYIUBU7.js → chunk-XC7I2L3G.js} +2 -2
  20. package/dist/chunk-XC7I2L3G.js.map +1 -0
  21. package/dist/client/index.d.ts +47 -1
  22. package/dist/client/index.js +3 -3
  23. package/dist/client/index.js.map +1 -1
  24. package/dist/index.d.ts +217 -347
  25. package/dist/index.js +138 -83
  26. package/dist/index.js.map +1 -1
  27. package/dist/kit-a2a-types-CwT1AFQu.d.ts +136 -0
  28. package/dist/{index-B7s-0mZl.d.ts → kit-client-auth-HnZIYUia.d.ts} +220 -101
  29. package/dist/kit-crypto-types-Dd24aJ4m.d.ts +194 -0
  30. package/dist/{kit-i18n-D9Qqk-1k.d.ts → kit-i18n-DEzmzE5T.d.ts} +142 -29
  31. package/dist/{kit-types-ByWdbCeO.d.ts → kit-types-CnzhN-AS.d.ts} +240 -162
  32. package/dist/modules/a2a/index.d.ts +13 -111
  33. package/dist/modules/a2a/index.js +2 -2
  34. package/dist/modules/crypto/index.d.ts +28 -195
  35. package/dist/modules/crypto/index.js +3 -3
  36. package/dist/modules/crypto/index.js.map +1 -1
  37. package/package.json +10 -10
  38. package/dist/chunk-DVW7CQ3H.js.map +0 -1
  39. package/dist/chunk-L7BTMAKX.js.map +0 -1
  40. package/dist/chunk-MLSP67JF.js.map +0 -1
  41. package/dist/chunk-NVYIUBU7.js.map +0 -1
  42. package/dist/chunk-QHYNL24G.js +0 -117
  43. package/dist/chunk-QHYNL24G.js.map +0 -1
  44. package/dist/chunk-VOTDAVCB.js.map +0 -1
@@ -1,95 +1,10 @@
1
- import { RequestEvent, RequestHandler } from '@sveltejs/kit';
2
- import { f as HandleA2AOperations, h as HandleConfig } from '../../kit-types-ByWdbCeO.js';
1
+ import { K as KitA2AHandlerConfig } from '../../kit-a2a-types-CwT1AFQu.js';
2
+ export { A as A2AApiKeyAuthConfig, R as ResolvedA2AConfig, c as createA2AApiKeyAuthenticator, h as handleA2ARequest, r as resolveA2AConfig } from '../../kit-a2a-types-CwT1AFQu.js';
3
+ import { RequestHandler } from '@sveltejs/kit';
4
+ import '../../kit-types-CnzhN-AS.js';
3
5
  import '@h-ai/crypto';
4
6
  import '@h-ai/iam';
5
-
6
- /**
7
- * @h-ai/kit — A2A API Key 认证器
8
- *
9
- * 从请求头或 query 参数中提取 API Key,调用 IAM apiKey.verifyApiKey 验证。
10
- * @module kit-a2a-auth
11
- */
12
-
13
- /** A2A API Key 认证器配置 */
14
- interface A2AApiKeyAuthConfig {
15
- /** API Key 的传递位置 */
16
- in: 'header' | 'query';
17
- /** 参数名 */
18
- name: string;
19
- }
20
- /**
21
- * 创建 A2A API Key 认证函数
22
- *
23
- * 根据配置从请求头或 query 参数中提取 API Key,
24
- * 通过 `iam.apiKey.verifyApiKey()` 验证后返回调用方上下文。
25
- *
26
- * - 无 API Key → 返回 `null`(由调用方拒绝请求)
27
- * - 验证失败 → 返回 `null`(拒绝)
28
- * - 验证成功 → 返回 `{ agentId, apiKeyId, scopes }`
29
- *
30
- * @param config - API Key 提取配置
31
- * @returns authenticate 函数,可直接赋给 HandleA2AConfig.authenticate
32
- */
33
- declare function createA2AApiKeyAuthenticator(config: A2AApiKeyAuthConfig): (event: RequestEvent) => Promise<Record<string, unknown> | null>;
34
-
35
- /**
36
- * @h-ai/kit — A2A Handle 拦截器
37
- *
38
- * 在 SvelteKit Handle Hook 中拦截 A2A 端点(Agent Card 发现 + JSON-RPC 处理),
39
- * 自动处理请求并返回 Response,不匹配时返回 null 由 Handle 继续后续流程。
40
- * @module kit-a2a-handle
41
- */
42
-
43
- /** A2A 解析后的内部配置 */
44
- interface ResolvedA2AConfig {
45
- operations: HandleA2AOperations;
46
- cardPath: string;
47
- rpcPath: string;
48
- authenticate?: (event: RequestEvent) => Promise<Record<string, unknown> | null | undefined>;
49
- }
50
- /**
51
- * 解析 A2A 配置(简单模式 / 配置模式)
52
- *
53
- * - 简单模式:直接传入 `ai.a2a` 操作对象,使用默认路径
54
- * - 配置模式:传入 `{ operations, rpcPath?, cardPath?, authenticate? }`
55
- *
56
- * @param input - HandleConfig.a2a 配置
57
- * @returns 解析后的配置,或 `null` 表示未配置
58
- */
59
- declare function resolveA2AConfig(input: HandleConfig['a2a']): ResolvedA2AConfig | null;
60
- /**
61
- * 处理 A2A 端点请求
62
- *
63
- * 匹配 Agent Card GET 和 JSON-RPC POST 端点,返回 Response。
64
- * 不匹配时返回 `null`,由 Handle 继续后续流程。
65
- *
66
- * @param event - SvelteKit RequestEvent
67
- * @param requestId - 当前请求 ID(用于响应头)
68
- * @param config - 解析后的 A2A 配置
69
- * @returns 匹配时返回 Response,不匹配返回 null
70
- */
71
- declare function handleA2ARequest(event: RequestEvent, requestId: string, config: ResolvedA2AConfig): Promise<Response | null>;
72
-
73
- /**
74
- * @h-ai/kit — A2A 类型定义
75
- *
76
- * Kit A2A 路由处理器相关类型
77
- * @module kit-a2a-types
78
- */
79
-
80
- /** A2A 路由处理器配置 */
81
- interface KitA2AHandlerConfig {
82
- /**
83
- * 可选的认证回调
84
- *
85
- * 验证入站 A2A 请求的身份。返回 null/undefined 表示认证失败(401)。
86
- * 未配置此项才允许匿名请求;回调可抛出 SvelteKit HTTP 错误。
87
- *
88
- * - `'apiKey'`:自动使用 IAM API Key 认证
89
- * - 函数:自定义认证回调
90
- */
91
- authenticate?: 'apiKey' | ((event: RequestEvent) => Promise<Record<string, unknown> | null | undefined>);
92
- }
7
+ import '@h-ai/core';
93
8
 
94
9
  /**
95
10
  * @h-ai/kit — A2A 路由处理器
@@ -105,18 +20,10 @@ interface KitA2AHandlerConfig {
105
20
  *
106
21
  * @param getAgentCard - 获取 Agent Card 的回调(通常调用 `ai.a2a.getAgentCard()`)
107
22
  * @returns SvelteKit GET 处理器
108
- *
109
- * @example
23
+ * @example 模块内部上下文
110
24
  * ```ts
111
- * // src/routes/.well-known/agent-card.json/+server.ts
112
- * import { ai } from '@h-ai/ai'
113
- * import { createAgentCardHandler } from '@h-ai/kit/a2a'
114
- *
115
- * export const GET = createAgentCardHandler(() => {
116
- * const result = ai.a2a.getAgentCard()
117
- * if (!result.success) throw new Error(result.error.message)
118
- * return result.data
119
- * })
25
+ * const handler = createAgentCardHandler(() => ({ name: 'Example agent', url: 'https://agent.example.com/a2a' }))
26
+ * void handler
120
27
  * ```
121
28
  */
122
29
  declare function createAgentCardHandler(getAgentCard: () => object): RequestHandler;
@@ -129,16 +36,11 @@ declare function createAgentCardHandler(getAgentCard: () => object): RequestHand
129
36
  * @param handleRequest - JSON-RPC 请求处理回调(通常调用 `ai.a2a.handleRequest()`)
130
37
  * @param config - 可选配置(认证等)
131
38
  * @returns SvelteKit POST 处理器
132
- *
133
- * @example
39
+ * @example 模块内部上下文
134
40
  * ```ts
135
- * // src/routes/a2a/+server.ts
136
- * import { ai } from '@h-ai/ai'
137
- * import { createA2AHandler } from '@h-ai/kit/a2a'
138
- *
139
- * export const POST = createA2AHandler(
140
- * (body, context) => ai.a2a.handleRequest(body, context),
141
- * )
41
+ * function build(operations: Parameters<typeof createA2AHandler>[0]) {
42
+ * return createA2AHandler(operations, { authenticate: async () => null })
43
+ * }
142
44
  * ```
143
45
  */
144
46
  declare function createA2AHandler(handleRequest: (body: unknown, context?: Record<string, unknown>) => Promise<{
@@ -147,4 +49,4 @@ declare function createA2AHandler(handleRequest: (body: unknown, context?: Recor
147
49
  stream?: AsyncGenerator<unknown, void, undefined>;
148
50
  }>, config?: KitA2AHandlerConfig): RequestHandler;
149
51
 
150
- export { type A2AApiKeyAuthConfig, type KitA2AHandlerConfig, type ResolvedA2AConfig, createA2AApiKeyAuthenticator, createA2AHandler, createAgentCardHandler, handleA2ARequest, resolveA2AConfig };
52
+ export { KitA2AHandlerConfig, createA2AHandler, createAgentCardHandler };
@@ -1,4 +1,4 @@
1
- export { createA2AApiKeyAuthenticator, createA2AHandler, createAgentCardHandler, handleA2ARequest, resolveA2AConfig } from '../../chunk-DVW7CQ3H.js';
2
- import '../../chunk-QHYNL24G.js';
1
+ export { createA2AApiKeyAuthenticator, createA2AHandler, createAgentCardHandler, handleA2ARequest, resolveA2AConfig } from '../../chunk-2PWGJCWX.js';
2
+ import '../../chunk-OVRZIDCD.js';
3
3
  //# sourceMappingURL=index.js.map
4
4
  //# sourceMappingURL=index.js.map
@@ -1,172 +1,9 @@
1
- import { RequestEvent, Cookies } from '@sveltejs/kit';
2
- import { CryptoFunctions, TransportKeyStore } from '@h-ai/crypto';
1
+ import { Cookies, RequestEvent } from '@sveltejs/kit';
2
+ import { C as CryptoCsrfConfig, E as EncryptedCookieConfig, a as CryptoServiceLike, W as WebhookVerifyConfig, T as TransportEncryptionConfig } from '../../kit-crypto-types-Dd24aJ4m.js';
3
+ import { M as Middleware } from '../../kit-types-CnzhN-AS.js';
3
4
  export { EncryptedPayload, TransportEncryptionManager, TransportKeyPair } from '@h-ai/crypto';
4
- import { M as Middleware } from '../../kit-types-ByWdbCeO.js';
5
5
  import '@h-ai/iam';
6
-
7
- /**
8
- * @h-ai/kit — Crypto 类型定义
9
- *
10
- * Crypto 模块集成相关类型
11
- * @module kit-crypto-types
12
- */
13
-
14
- /**
15
- * Crypto 服务接口(简化版,与 @h-ai/crypto 兼容)
16
- */
17
- interface CryptoServiceLike {
18
- hmac: {
19
- sign: (data: string, key: string, algorithm?: string) => Promise<{
20
- success: boolean;
21
- data?: string;
22
- error?: {
23
- code: number;
24
- message: string;
25
- };
26
- }>;
27
- verify: (data: string, key: string, signature: string, algorithm?: string) => Promise<{
28
- success: boolean;
29
- data?: boolean;
30
- error?: {
31
- code: number;
32
- message: string;
33
- };
34
- }>;
35
- };
36
- hash: {
37
- digest: (data: string, algorithm?: string) => Promise<{
38
- success: boolean;
39
- data?: string;
40
- error?: {
41
- code: number;
42
- message: string;
43
- };
44
- }>;
45
- timingSafeEqual: (a: string, b: string) => Promise<{
46
- success: boolean;
47
- data?: boolean;
48
- error?: {
49
- code: number;
50
- message: string;
51
- };
52
- }>;
53
- };
54
- aes: {
55
- encrypt: (data: string, key: string) => Promise<{
56
- success: boolean;
57
- data?: string;
58
- error?: {
59
- code: number;
60
- message: string;
61
- };
62
- }>;
63
- decrypt: (data: string, key: string) => Promise<{
64
- success: boolean;
65
- data?: string;
66
- error?: {
67
- code: number;
68
- message: string;
69
- };
70
- }>;
71
- };
72
- random: {
73
- bytes: (length: number) => Promise<{
74
- success: boolean;
75
- data?: Uint8Array;
76
- error?: {
77
- code: number;
78
- message: string;
79
- };
80
- }>;
81
- };
82
- }
83
- /**
84
- * Webhook 验证配置
85
- */
86
- interface WebhookVerifyConfig {
87
- /** Crypto 服务实例 */
88
- crypto: CryptoServiceLike;
89
- /** 请求事件 */
90
- event: RequestEvent;
91
- /** 签名密钥 */
92
- secretKey: string;
93
- /** 签名头名称 */
94
- signatureHeader?: string;
95
- /** 算法 */
96
- algorithm?: 'sha256' | 'sha512';
97
- /** 编码 */
98
- encoding?: 'hex' | 'base64';
99
- }
100
- /**
101
- * CSRF 配置
102
- */
103
- interface CryptoCsrfConfig {
104
- /** Crypto 服务实例 */
105
- crypto: CryptoServiceLike;
106
- /** Cookie 名称 */
107
- cookieName?: string;
108
- /** Header 名称 */
109
- headerName?: string;
110
- /** 表单字段名称 */
111
- formFieldName?: string;
112
- /** Token 长度 */
113
- tokenLength?: number;
114
- /** Cookie 选项 */
115
- cookieOptions?: {
116
- path?: string;
117
- httpOnly?: boolean;
118
- secure?: boolean;
119
- sameSite?: 'strict' | 'lax' | 'none';
120
- maxAge?: number;
121
- };
122
- }
123
- /**
124
- * 加密 Cookie 配置
125
- */
126
- interface EncryptedCookieConfig {
127
- /** Crypto 服务实例 */
128
- crypto: CryptoServiceLike;
129
- /** 加密密钥 */
130
- encryptionKey: string;
131
- /** Cookie 选项 */
132
- cookieOptions?: {
133
- path?: string;
134
- httpOnly?: boolean;
135
- secure?: boolean;
136
- sameSite?: 'strict' | 'lax' | 'none';
137
- maxAge?: number;
138
- };
139
- }
140
-
141
- /**
142
- * 传输加密配置。
143
- *
144
- * kit 不再维护本地加解密实现;服务端管理器由 `crypto.transport.createServer()` 创建,
145
- * 协议常量与载荷类型统一来自 `@h-ai/crypto`。
146
- */
147
- interface TransportEncryptionConfig {
148
- /** 是否启用传输加密(默认 false) */
149
- enabled: boolean;
150
- /** @h-ai/crypto 服务实例 */
151
- crypto: CryptoFunctions;
152
- /** 密钥交换端点路径(默认 `/api/_hai/key-exchange`) */
153
- keyExchangePath?: string;
154
- /** 排除路径(不加密),支持精确匹配和前缀匹配 */
155
- excludePaths?: string[];
156
- /** 是否加密响应(默认 true) */
157
- encryptResponse?: boolean;
158
- /** 服务端可缓存的客户端公钥数量上限(默认 10000) */
159
- maxClients?: number;
160
- /** 共享客户端公钥存储(如 Redis / reldb);未传时默认使用进程内内存实现。 */
161
- keyStore?: TransportKeyStore;
162
- /**
163
- * 是否强制要求传输加密(默认 true)
164
- *
165
- * - `true`:非排除路径上缺少 X-Client-Id 请求头时返回 400,防止绕过加密。
166
- * - `false`:缺少 X-Client-Id 时透传明文,仅适用于渐进式迁移场景,不建议生产启用。
167
- */
168
- requireEncryption?: boolean;
169
- }
6
+ import '@h-ai/core';
170
7
 
171
8
  /**
172
9
  * @h-ai/kit — Crypto Helpers
@@ -182,13 +19,11 @@ interface TransportEncryptionConfig {
182
19
  *
183
20
  * @param config - 签名验证配置
184
21
  * @returns 签名是否合法
185
- *
186
- * @example
22
+ * @example 模块内部上下文
187
23
  * ```ts
188
- * const valid = await verifyWebhookSignature({
189
- * crypto, event, secretKey: 'wh_secret', signatureHeader: 'X-Signature',
190
- * })
191
- * if (!valid) return new Response('Invalid signature', { status: 401 })
24
+ * async function authorized(config: WebhookVerifyConfig) {
25
+ * return verifyWebhookSignature(config) // 使用原始 body;读取后不可再次消费同一流。
26
+ * }
192
27
  * ```
193
28
  */
194
29
  declare function verifyWebhookSignature(config: WebhookVerifyConfig): Promise<boolean>;
@@ -201,6 +36,12 @@ declare function verifyWebhookSignature(config: WebhookVerifyConfig): Promise<bo
201
36
  * @param algorithm - 哈希算法(默认 `'sha256'`)
202
37
  * @returns 签名字符串
203
38
  * @throws 签名失败时抛出 Error
39
+ * @example 模块内部上下文
40
+ * ```ts
41
+ * async function sign(crypto: CryptoServiceLike, secretKey: string) {
42
+ * return signRequest(crypto, JSON.stringify({ id: 'article_1' }), secretKey)
43
+ * }
44
+ * ```
204
45
  */
205
46
  declare function signRequest(crypto: CryptoServiceLike, body: string, secretKey: string, algorithm?: string): Promise<string>;
206
47
  /**
@@ -211,14 +52,12 @@ declare function signRequest(crypto: CryptoServiceLike, body: string, secretKey:
211
52
  *
212
53
  * @param config - CSRF 配置(crypto 实例、Cookie 名、Header 名等)
213
54
  * @returns `{ generate, verify, createHandle }`
214
- *
215
- * @example
55
+ * @example 模块内部上下文
216
56
  * ```ts
217
- * const csrf = createCsrfManager({ crypto })
218
- * // 在 load 中生成
219
- * const token = await csrf.generate(cookies)
220
- * // 在 action 中验证
221
- * const ok = await csrf.verify(event)
57
+ * function csrf(config: CryptoCsrfConfig) {
58
+ * const manager = createCsrfManager(config)
59
+ * return manager
60
+ * }
222
61
  * ```
223
62
  */
224
63
  declare function createCsrfManager(config: CryptoCsrfConfig): {
@@ -245,12 +84,11 @@ declare function createCsrfManager(config: CryptoCsrfConfig): {
245
84
  *
246
85
  * @param config - 加密 Cookie 配置(含加密密钥)
247
86
  * @returns `{ set, get, delete }`
248
- *
249
- * @example
87
+ * @example 模块内部上下文
250
88
  * ```ts
251
- * const enc = createEncryptedCookie({ crypto, encryptionKey: 'my-32byte-key' })
252
- * await enc.set(cookies, 'prefs', { theme: 'dark' })
253
- * const prefs = await enc.get(cookies, 'prefs')
89
+ * function cookies(config: EncryptedCookieConfig) {
90
+ * return createEncryptedCookie(config)
91
+ * }
254
92
  * ```
255
93
  */
256
94
  declare function createEncryptedCookie(config: EncryptedCookieConfig): {
@@ -280,18 +118,13 @@ declare function createEncryptedCookie(config: EncryptedCookieConfig): {
280
118
  *
281
119
  * @param config - 传输加密配置
282
120
  * @returns SvelteKit 中间件
283
- *
284
- * @example
121
+ * @example 模块内部上下文
285
122
  * ```ts
286
- * import { crypto } from '@h-ai/crypto'
287
- * import { kit } from '@h-ai/kit'
288
- *
289
- * // 传输加密通过 createHandle 的 crypto 配置自动启用:
290
- * export const handle = kit.createHandle({
291
- * crypto: { crypto, transport: true },
292
- * })
123
+ * function install(config: TransportEncryptionConfig) {
124
+ * return transportEncryptionMiddleware(config) // 受管密钥环、共享 keyStore 与 crypto 生命周期由应用管理。
125
+ * }
293
126
  * ```
294
127
  */
295
128
  declare function transportEncryptionMiddleware(config: TransportEncryptionConfig): Middleware;
296
129
 
297
- export { type CryptoCsrfConfig, type CryptoServiceLike, type EncryptedCookieConfig, type TransportEncryptionConfig, type WebhookVerifyConfig, createCsrfManager, createEncryptedCookie, signRequest, transportEncryptionMiddleware, verifyWebhookSignature };
130
+ export { CryptoCsrfConfig, CryptoServiceLike, EncryptedCookieConfig, TransportEncryptionConfig, WebhookVerifyConfig, createCsrfManager, createEncryptedCookie, signRequest, transportEncryptionMiddleware, verifyWebhookSignature };
@@ -1,6 +1,6 @@
1
- export { transportEncryptionMiddleware } from '../../chunk-MLSP67JF.js';
2
- import '../../chunk-NVYIUBU7.js';
3
- import { kitM } from '../../chunk-QHYNL24G.js';
1
+ export { transportEncryptionMiddleware } from '../../chunk-333FGMGQ.js';
2
+ import '../../chunk-XC7I2L3G.js';
3
+ import { kitM } from '../../chunk-OVRZIDCD.js';
4
4
 
5
5
  // src/modules/crypto/kit-crypto-helpers.ts
6
6
  async function verifyWebhookSignature(config) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/modules/crypto/kit-crypto-helpers.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @h-ai/kit — Crypto Helpers\n *\n * 集成 @h-ai/crypto 的 SvelteKit 工具\n * @module kit-crypto-helpers\n */\n\nimport type { Cookies, RequestEvent } from '@sveltejs/kit'\nimport type {\n CryptoCsrfConfig,\n CryptoServiceLike,\n EncryptedCookieConfig,\n WebhookVerifyConfig,\n} from './kit-crypto-types.js'\nimport { kitM } from '../../kit-i18n.js'\n\n/**\n * 验证 Webhook 签名\n *\n * 从请求头取出签名,用 HMAC 对原始 Body 进行比较验证。\n *\n * @param config - 签名验证配置\n * @returns 签名是否合法\n *\n * @example\n * ```ts\n * const valid = await verifyWebhookSignature({\n * crypto, event, secretKey: 'wh_secret', signatureHeader: 'X-Signature',\n * })\n * if (!valid) return new Response('Invalid signature', { status: 401 })\n * ```\n */\nexport async function verifyWebhookSignature(config: WebhookVerifyConfig): Promise<boolean> {\n const {\n crypto,\n event,\n secretKey,\n signatureHeader = 'X-Signature',\n algorithm = 'sha256',\n } = config\n\n const signature = event.request.headers.get(signatureHeader)\n if (!signature) {\n return false\n }\n\n const body = await event.request.text()\n\n try {\n const result = await crypto.hmac.verify(body, secretKey, signature, algorithm)\n return result.success && result.data === true\n }\n catch {\n return false\n }\n}\n\n/**\n * 生成请求 HMAC 签名(用于调用外部服务)\n *\n * @param crypto - @h-ai/crypto 服务实例\n * @param body - 请求体字符串\n * @param secretKey - 共享密钥\n * @param algorithm - 哈希算法(默认 `'sha256'`)\n * @returns 签名字符串\n * @throws 签名失败时抛出 Error\n */\nexport async function signRequest(\n crypto: CryptoServiceLike,\n body: string,\n secretKey: string,\n algorithm = 'sha256',\n): Promise<string> {\n const result = await crypto.hmac.sign(body, secretKey, algorithm)\n if (!result.success) {\n throw new Error(result.error?.message || kitM('kit_signFailed'))\n }\n return result.data!\n}\n\n/**\n * 创建 CSRF Token 管理器\n *\n * 基于 `@h-ai/crypto` 随机字节 + 时间安全比较,\n * 提供 token 生成、验证和 SvelteKit handle 中间件。\n *\n * @param config - CSRF 配置(crypto 实例、Cookie 名、Header 名等)\n * @returns `{ generate, verify, createHandle }`\n *\n * @example\n * ```ts\n * const csrf = createCsrfManager({ crypto })\n * // 在 load 中生成\n * const token = await csrf.generate(cookies)\n * // 在 action 中验证\n * const ok = await csrf.verify(event)\n * ```\n */\nexport function createCsrfManager(config: CryptoCsrfConfig) {\n const {\n crypto,\n cookieName = 'csrf_token',\n headerName = 'X-CSRF-Token',\n formFieldName = '_csrf',\n tokenLength = 32,\n cookieOptions = {},\n } = config\n\n return {\n /**\n * 生成新的 CSRF Token 并设置 Cookie\n */\n async generate(cookies: Cookies): Promise<string> {\n const result = await crypto.random.bytes(tokenLength)\n if (!result.success) {\n throw new Error(kitM('kit_csrfTokenFailed'))\n }\n\n const token = Array.from(result.data!)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('')\n\n cookies.set(cookieName, token, {\n path: '/',\n httpOnly: true,\n secure: true,\n sameSite: 'strict',\n ...cookieOptions,\n })\n\n return token\n },\n\n /**\n * 验证 CSRF Token\n */\n async verify(event: RequestEvent): Promise<boolean> {\n const cookieToken = event.cookies.get(cookieName)\n if (!cookieToken) {\n return false\n }\n\n // 从 header 或 form data 获取 token\n let requestToken = event.request.headers.get(headerName)\n\n if (!requestToken && event.request.method === 'POST') {\n try {\n const formData = await event.request.clone().formData()\n const fieldValue = formData.get(formFieldName)\n requestToken = typeof fieldValue === 'string' ? fieldValue : null\n }\n catch {\n // 不是 form data\n }\n }\n\n if (!requestToken) {\n return false\n }\n\n // 时间安全的比较\n const result = await crypto.hash.timingSafeEqual(cookieToken, requestToken)\n return result.success && result.data === true\n },\n\n /**\n * 创建 CSRF 验证中间件\n */\n createHandle() {\n return async ({ event, resolve }: { event: RequestEvent, resolve: (event: RequestEvent) => Promise<Response> }) => {\n // 跳过安全方法\n const safeMethods = ['GET', 'HEAD', 'OPTIONS']\n if (safeMethods.includes(event.request.method)) {\n return resolve(event)\n }\n\n const isValid = await this.verify(event)\n if (!isValid) {\n return new Response(kitM('kit_csrfVerifyFailed'), { status: 403 })\n }\n\n return resolve(event)\n }\n },\n }\n}\n\n/**\n * 创建加密 Cookie 管理器\n *\n * 使用 AES 对 Cookie 值进行加解密,防止客户端篡改。\n *\n * @param config - 加密 Cookie 配置(含加密密钥)\n * @returns `{ set, get, delete }`\n *\n * @example\n * ```ts\n * const enc = createEncryptedCookie({ crypto, encryptionKey: 'my-32byte-key' })\n * await enc.set(cookies, 'prefs', { theme: 'dark' })\n * const prefs = await enc.get(cookies, 'prefs')\n * ```\n */\nexport function createEncryptedCookie(config: EncryptedCookieConfig) {\n const { crypto, encryptionKey, cookieOptions = {} } = config\n\n return {\n /**\n * 设置加密 Cookie\n */\n async set(cookies: Cookies, name: string, value: unknown): Promise<void> {\n const json = JSON.stringify(value)\n const result = await crypto.aes.encrypt(json, encryptionKey)\n\n if (!result.success) {\n throw new Error(kitM('kit_encryptFailed'))\n }\n\n cookies.set(name, result.data!, {\n path: '/',\n httpOnly: true,\n secure: true,\n sameSite: 'lax',\n ...cookieOptions,\n })\n },\n\n /**\n * 获取并解密 Cookie\n */\n async get<T = unknown>(cookies: Cookies, name: string): Promise<T | null> {\n const encrypted = cookies.get(name)\n if (!encrypted) {\n return null\n }\n\n try {\n const result = await crypto.aes.decrypt(encrypted, encryptionKey)\n if (!result.success) {\n return null\n }\n\n return JSON.parse(result.data!) as T\n }\n catch {\n return null\n }\n },\n\n /**\n * 删除 Cookie\n */\n delete(cookies: Cookies, name: string): void {\n cookies.delete(name, { path: '/' })\n },\n }\n}\n"]}
1
+ {"version":3,"sources":["../../../src/modules/crypto/kit-crypto-helpers.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @h-ai/kit — Crypto Helpers\n *\n * 集成 @h-ai/crypto 的 SvelteKit 工具\n * @module kit-crypto-helpers\n */\n\nimport type { Cookies, RequestEvent } from '@sveltejs/kit'\nimport type {\n CryptoCsrfConfig,\n CryptoServiceLike,\n EncryptedCookieConfig,\n WebhookVerifyConfig,\n} from './kit-crypto-types.js'\nimport { kitM } from '../../kit-i18n.js'\n\n/**\n * 验证 Webhook 签名\n *\n * 从请求头取出签名,用 HMAC 对原始 Body 进行比较验证。\n *\n * @param config - 签名验证配置\n * @returns 签名是否合法\n * @example 模块内部上下文\n * ```ts\n * async function authorized(config: WebhookVerifyConfig) {\n * return verifyWebhookSignature(config) // 使用原始 body;读取后不可再次消费同一流。\n * }\n * ```\n */\nexport async function verifyWebhookSignature(config: WebhookVerifyConfig): Promise<boolean> {\n const {\n crypto,\n event,\n secretKey,\n signatureHeader = 'X-Signature',\n algorithm = 'sha256',\n } = config\n\n const signature = event.request.headers.get(signatureHeader)\n if (!signature) {\n return false\n }\n\n const body = await event.request.text()\n\n try {\n const result = await crypto.hmac.verify(body, secretKey, signature, algorithm)\n return result.success && result.data === true\n }\n catch {\n return false\n }\n}\n\n/**\n * 生成请求 HMAC 签名(用于调用外部服务)\n *\n * @param crypto - @h-ai/crypto 服务实例\n * @param body - 请求体字符串\n * @param secretKey - 共享密钥\n * @param algorithm - 哈希算法(默认 `'sha256'`)\n * @returns 签名字符串\n * @throws 签名失败时抛出 Error\n * @example 模块内部上下文\n * ```ts\n * async function sign(crypto: CryptoServiceLike, secretKey: string) {\n * return signRequest(crypto, JSON.stringify({ id: 'article_1' }), secretKey)\n * }\n * ```\n */\nexport async function signRequest(\n crypto: CryptoServiceLike,\n body: string,\n secretKey: string,\n algorithm = 'sha256',\n): Promise<string> {\n const result = await crypto.hmac.sign(body, secretKey, algorithm)\n if (!result.success) {\n throw new Error(result.error?.message || kitM('kit_signFailed'))\n }\n return result.data!\n}\n\n/**\n * 创建 CSRF Token 管理器\n *\n * 基于 `@h-ai/crypto` 随机字节 + 时间安全比较,\n * 提供 token 生成、验证和 SvelteKit handle 中间件。\n *\n * @param config - CSRF 配置(crypto 实例、Cookie 名、Header 名等)\n * @returns `{ generate, verify, createHandle }`\n * @example 模块内部上下文\n * ```ts\n * function csrf(config: CryptoCsrfConfig) {\n * const manager = createCsrfManager(config)\n * return manager\n * }\n * ```\n */\nexport function createCsrfManager(config: CryptoCsrfConfig) {\n const {\n crypto,\n cookieName = 'csrf_token',\n headerName = 'X-CSRF-Token',\n formFieldName = '_csrf',\n tokenLength = 32,\n cookieOptions = {},\n } = config\n\n return {\n /**\n * 生成新的 CSRF Token 并设置 Cookie\n */\n async generate(cookies: Cookies): Promise<string> {\n const result = await crypto.random.bytes(tokenLength)\n if (!result.success) {\n throw new Error(kitM('kit_csrfTokenFailed'))\n }\n\n const token = Array.from(result.data!)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('')\n\n cookies.set(cookieName, token, {\n path: '/',\n httpOnly: true,\n secure: true,\n sameSite: 'strict',\n ...cookieOptions,\n })\n\n return token\n },\n\n /**\n * 验证 CSRF Token\n */\n async verify(event: RequestEvent): Promise<boolean> {\n const cookieToken = event.cookies.get(cookieName)\n if (!cookieToken) {\n return false\n }\n\n // 从 header 或 form data 获取 token\n let requestToken = event.request.headers.get(headerName)\n\n if (!requestToken && event.request.method === 'POST') {\n try {\n const formData = await event.request.clone().formData()\n const fieldValue = formData.get(formFieldName)\n requestToken = typeof fieldValue === 'string' ? fieldValue : null\n }\n catch {\n // 不是 form data\n }\n }\n\n if (!requestToken) {\n return false\n }\n\n // 时间安全的比较\n const result = await crypto.hash.timingSafeEqual(cookieToken, requestToken)\n return result.success && result.data === true\n },\n\n /**\n * 创建 CSRF 验证中间件\n */\n createHandle() {\n return async ({ event, resolve }: { event: RequestEvent, resolve: (event: RequestEvent) => Promise<Response> }) => {\n // 跳过安全方法\n const safeMethods = ['GET', 'HEAD', 'OPTIONS']\n if (safeMethods.includes(event.request.method)) {\n return resolve(event)\n }\n\n const isValid = await this.verify(event)\n if (!isValid) {\n return new Response(kitM('kit_csrfVerifyFailed'), { status: 403 })\n }\n\n return resolve(event)\n }\n },\n }\n}\n\n/**\n * 创建加密 Cookie 管理器\n *\n * 使用 AES 对 Cookie 值进行加解密,防止客户端篡改。\n *\n * @param config - 加密 Cookie 配置(含加密密钥)\n * @returns `{ set, get, delete }`\n * @example 模块内部上下文\n * ```ts\n * function cookies(config: EncryptedCookieConfig) {\n * return createEncryptedCookie(config)\n * }\n * ```\n */\nexport function createEncryptedCookie(config: EncryptedCookieConfig) {\n const { crypto, encryptionKey, cookieOptions = {} } = config\n\n return {\n /**\n * 设置加密 Cookie\n */\n async set(cookies: Cookies, name: string, value: unknown): Promise<void> {\n const json = JSON.stringify(value)\n const result = await crypto.aes.encrypt(json, encryptionKey)\n\n if (!result.success) {\n throw new Error(kitM('kit_encryptFailed'))\n }\n\n cookies.set(name, result.data!, {\n path: '/',\n httpOnly: true,\n secure: true,\n sameSite: 'lax',\n ...cookieOptions,\n })\n },\n\n /**\n * 获取并解密 Cookie\n */\n async get<T = unknown>(cookies: Cookies, name: string): Promise<T | null> {\n const encrypted = cookies.get(name)\n if (!encrypted) {\n return null\n }\n\n try {\n const result = await crypto.aes.decrypt(encrypted, encryptionKey)\n if (!result.success) {\n return null\n }\n\n return JSON.parse(result.data!) as T\n }\n catch {\n return null\n }\n },\n\n /**\n * 删除 Cookie\n */\n delete(cookies: Cookies, name: string): void {\n cookies.delete(name, { path: '/' })\n },\n }\n}\n"]}
package/package.json CHANGED
@@ -1,13 +1,16 @@
1
1
  {
2
2
  "name": "@h-ai/kit",
3
3
  "type": "module",
4
- "version": "0.1.0-alpha.67",
4
+ "version": "0.1.0-alpha.68",
5
5
  "description": "Hai Framework SvelteKit integration module.",
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/index.d.ts",
10
- "browser": "./dist/browser.js",
11
14
  "import": "./dist/index.js"
12
15
  },
13
16
  "./client": {
@@ -18,10 +21,6 @@
18
21
  "types": "./dist/modules/crypto/index.d.ts",
19
22
  "import": "./dist/modules/crypto/index.js"
20
23
  },
21
- "./vite": {
22
- "types": "./dist/vite/index.d.ts",
23
- "import": "./dist/vite/index.js"
24
- },
25
24
  "./adapter": {
26
25
  "types": "./dist/adapter/index.d.ts",
27
26
  "import": "./dist/adapter/index.js"
@@ -58,13 +57,14 @@
58
57
  }
59
58
  },
60
59
  "dependencies": {
61
- "@h-ai/api-contract": "0.1.0-alpha.67",
62
- "@h-ai/core": "0.1.0-alpha.67",
63
- "@h-ai/crypto": "0.1.0-alpha.67",
64
- "@h-ai/iam": "0.1.0-alpha.67",
60
+ "@h-ai/api-contract": "0.1.0-alpha.68",
61
+ "@h-ai/core": "0.1.0-alpha.68",
62
+ "@h-ai/crypto": "0.1.0-alpha.68",
63
+ "@h-ai/iam": "0.1.0-alpha.68",
65
64
  "zod": "^4.6.5"
66
65
  },
67
66
  "devDependencies": {
67
+ "@h-ai/cache": "0.1.0-alpha.68",
68
68
  "@sveltejs/kit": "^2.70.3",
69
69
  "@types/node": "^26.6.5",
70
70
  "rimraf": "^6.1.3",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/modules/a2a/kit-a2a-auth.ts","../src/modules/a2a/kit-a2a-helpers.ts","../src/modules/a2a/kit-a2a-handle.ts"],"names":[],"mappings":"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","file":"chunk-DVW7CQ3H.js","sourcesContent":["/**\n * @h-ai/kit — A2A API Key 认证器\n *\n * 从请求头或 query 参数中提取 API Key,调用 IAM apiKey.verifyApiKey 验证。\n * @module kit-a2a-auth\n */\n\nimport type { RequestEvent } from '@sveltejs/kit'\nimport { iam } from '@h-ai/iam'\n\n/** A2A API Key 认证器配置 */\nexport interface A2AApiKeyAuthConfig {\n /** API Key 的传递位置 */\n in: 'header' | 'query'\n /** 参数名 */\n name: string\n}\n\n/**\n * 创建 A2A API Key 认证函数\n *\n * 根据配置从请求头或 query 参数中提取 API Key,\n * 通过 `iam.apiKey.verifyApiKey()` 验证后返回调用方上下文。\n *\n * - 无 API Key → 返回 `null`(由调用方拒绝请求)\n * - 验证失败 → 返回 `null`(拒绝)\n * - 验证成功 → 返回 `{ agentId, apiKeyId, scopes }`\n *\n * @param config - API Key 提取配置\n * @returns authenticate 函数,可直接赋给 HandleA2AConfig.authenticate\n */\nexport function createA2AApiKeyAuthenticator(\n config: A2AApiKeyAuthConfig,\n): (event: RequestEvent) => Promise<Record<string, unknown> | null> {\n return async (event: RequestEvent) => {\n const rawKey = config.in === 'header'\n ? event.request.headers.get(config.name)\n : event.url.searchParams.get(config.name)\n\n if (!rawKey)\n return null\n\n const result = await iam.apiKey.verifyApiKey(rawKey)\n if (!result.success)\n return null\n\n return {\n agentId: result.data.userId,\n apiKeyId: result.data.id,\n scopes: result.data.scopes,\n }\n }\n}\n","/**\n * @h-ai/kit — A2A 路由处理器\n *\n * 提供 SvelteKit 路由工厂:Agent Card 端点和 JSON-RPC 处理端点。\n * @module kit-a2a-helpers\n */\n\nimport type { RequestEvent, RequestHandler } from '@sveltejs/kit'\n\nimport type { KitA2AHandlerConfig } from './kit-a2a-types.js'\nimport { kitM } from '../../kit-i18n.js'\nimport { createA2AApiKeyAuthenticator } from './kit-a2a-auth.js'\n\n/**\n * 创建 Agent Card GET 处理器\n *\n * 返回当前 Agent 的 Agent Card(JSON),通常挂载在 `/.well-known/agent-card.json`。\n *\n * @param getAgentCard - 获取 Agent Card 的回调(通常调用 `ai.a2a.getAgentCard()`)\n * @returns SvelteKit GET 处理器\n *\n * @example\n * ```ts\n * // src/routes/.well-known/agent-card.json/+server.ts\n * import { ai } from '@h-ai/ai'\n * import { createAgentCardHandler } from '@h-ai/kit/a2a'\n *\n * export const GET = createAgentCardHandler(() => {\n * const result = ai.a2a.getAgentCard()\n * if (!result.success) throw new Error(result.error.message)\n * return result.data\n * })\n * ```\n */\nexport function createAgentCardHandler(\n getAgentCard: () => object,\n): RequestHandler {\n return async () => {\n const card = getAgentCard()\n return new Response(JSON.stringify(card), {\n headers: { 'Content-Type': 'application/json' },\n })\n }\n}\n\n/**\n * 创建 A2A JSON-RPC POST 处理器\n *\n * 将 SvelteKit Request 转换为 JSON-RPC body,委托给 `handleRequest` 回调处理。\n * 支持单条响应和流式(SSE)响应。\n *\n * @param handleRequest - JSON-RPC 请求处理回调(通常调用 `ai.a2a.handleRequest()`)\n * @param config - 可选配置(认证等)\n * @returns SvelteKit POST 处理器\n *\n * @example\n * ```ts\n * // src/routes/a2a/+server.ts\n * import { ai } from '@h-ai/ai'\n * import { createA2AHandler } from '@h-ai/kit/a2a'\n *\n * export const POST = createA2AHandler(\n * (body, context) => ai.a2a.handleRequest(body, context),\n * )\n * ```\n */\nexport function createA2AHandler(\n handleRequest: (body: unknown, context?: Record<string, unknown>) => Promise<{\n streaming: boolean\n body?: unknown\n stream?: AsyncGenerator<unknown, void, undefined>\n }>,\n config?: KitA2AHandlerConfig,\n): RequestHandler {\n return async (event: RequestEvent) => {\n // 可选认证\n let context: Record<string, unknown> | undefined\n if (config?.authenticate) {\n const authFn = typeof config.authenticate === 'function'\n ? config.authenticate\n : createA2AApiKeyAuthenticator({ in: 'header', name: 'x-api-key' })\n const authResult = await authFn(event)\n if (!authResult)\n return Response.json({ error: { code: 'A2A_AUTH_FAILED', message: kitM('kit_a2aAuthFailed') } }, { status: 401 })\n context = authResult\n }\n\n // 解析 JSON-RPC 请求体\n let requestBody: unknown\n try {\n requestBody = await event.request.json()\n }\n catch {\n return Response.json({ jsonrpc: '2.0', id: null, error: { code: -32700, message: kitM('kit_a2aParseError') } }, { status: 400 })\n }\n const result = await handleRequest(requestBody, context)\n\n if (result.streaming && result.stream) {\n // 流式响应:SSE 格式\n const stream = result.stream\n const readableStream = new ReadableStream({\n // 按下游拉取推进迭代,避免 start 中无界预读;断开时释放生成器。\n async pull(controller) {\n try {\n const chunk = await stream.next()\n if (chunk.done)\n controller.close()\n else\n controller.enqueue(new TextEncoder().encode(`data: ${JSON.stringify(chunk.value)}\\n\\n`))\n }\n catch (error) {\n controller.error(error)\n }\n },\n async cancel() {\n await stream.return()\n },\n })\n\n return new Response(readableStream, {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n },\n })\n }\n\n // 单条响应\n return new Response(JSON.stringify(result.body), {\n headers: { 'Content-Type': 'application/json' },\n })\n }\n}\n","/**\n * @h-ai/kit — A2A Handle 拦截器\n *\n * 在 SvelteKit Handle Hook 中拦截 A2A 端点(Agent Card 发现 + JSON-RPC 处理),\n * 自动处理请求并返回 Response,不匹配时返回 null 由 Handle 继续后续流程。\n * @module kit-a2a-handle\n */\n\nimport type { RequestEvent } from '@sveltejs/kit'\nimport type { HandleA2AConfig, HandleA2AOperations, HandleConfig } from '../../kit-types.js'\nimport { kitM } from '../../kit-i18n.js'\nimport { createA2AApiKeyAuthenticator } from './kit-a2a-auth.js'\nimport { createA2AHandler } from './kit-a2a-helpers.js'\n\n// ─── 解析后的 A2A 内部配置 ───\n\n/** A2A 解析后的内部配置 */\nexport interface ResolvedA2AConfig {\n operations: HandleA2AOperations\n cardPath: string\n rpcPath: string\n authenticate?: (event: RequestEvent) => Promise<Record<string, unknown> | null | undefined>\n}\n\n// ─── A2A 配置解析 ───\n\n/**\n * 解析 A2A 配置(简单模式 / 配置模式)\n *\n * - 简单模式:直接传入 `ai.a2a` 操作对象,使用默认路径\n * - 配置模式:传入 `{ operations, rpcPath?, cardPath?, authenticate? }`\n *\n * @param input - HandleConfig.a2a 配置\n * @returns 解析后的配置,或 `null` 表示未配置\n */\nexport function resolveA2AConfig(\n input: HandleConfig['a2a'],\n): ResolvedA2AConfig | null {\n if (!input)\n return null\n\n // 简单模式:直接传入操作对象\n if ('getAgentCard' in input && 'handleRequest' in input) {\n return {\n operations: input as HandleA2AOperations,\n cardPath: '/.well-known/agent-card.json',\n rpcPath: '/a2a',\n }\n }\n\n // 配置模式:带 operations 字段\n const cfg = input as HandleA2AConfig\n return {\n operations: cfg.operations,\n cardPath: cfg.cardPath ?? '/.well-known/agent-card.json',\n rpcPath: cfg.rpcPath ?? '/a2a',\n authenticate: resolveAuthenticate(cfg.authenticate, cfg.operations),\n }\n}\n\n/**\n * 解析 authenticate 配置\n *\n * - `undefined` → 无认证\n * - `'apiKey'` → 从 Agent Card security 配置创建 API Key 认证器\n * - 函数 → 直接使用\n */\nfunction resolveAuthenticate(\n authenticate: HandleA2AConfig['authenticate'],\n operations: HandleA2AOperations,\n): ResolvedA2AConfig['authenticate'] {\n if (!authenticate)\n return undefined\n\n if (typeof authenticate === 'function')\n return authenticate\n\n // 'apiKey' 快捷方式:从 Agent Card 获取 security 配置\n const cardResult = operations.getAgentCard()\n const securitySchemes = cardResult.success && cardResult.data\n ? (cardResult.data as { securitySchemes?: Record<string, { type: string, in?: string, name?: string }> }).securitySchemes\n : undefined\n const apiKeyCfg = securitySchemes?.apiKey\n\n return createA2AApiKeyAuthenticator({\n in: apiKeyCfg?.in === 'query' ? 'query' : 'header',\n name: apiKeyCfg?.name ?? 'x-api-key',\n })\n}\n\n// ─── A2A 请求处理 ───\n\n/**\n * 处理 A2A 端点请求\n *\n * 匹配 Agent Card GET 和 JSON-RPC POST 端点,返回 Response。\n * 不匹配时返回 `null`,由 Handle 继续后续流程。\n *\n * @param event - SvelteKit RequestEvent\n * @param requestId - 当前请求 ID(用于响应头)\n * @param config - 解析后的 A2A 配置\n * @returns 匹配时返回 Response,不匹配返回 null\n */\nexport async function handleA2ARequest(\n event: RequestEvent,\n requestId: string,\n config: ResolvedA2AConfig,\n): Promise<Response | null> {\n const { pathname } = event.url\n\n // Agent Card 发现端点\n if (pathname === config.cardPath && event.request.method === 'GET') {\n const result = config.operations.getAgentCard()\n if (result.success) {\n return new Response(JSON.stringify(result.data), {\n headers: { 'Content-Type': 'application/json', 'X-Request-Id': requestId },\n })\n }\n return new Response(\n JSON.stringify({ error: { code: 'A2A_NOT_CONFIGURED', message: kitM('kit_a2aCardUnavailable') } }),\n { status: 503, headers: { 'Content-Type': 'application/json', 'X-Request-Id': requestId } },\n )\n }\n\n // A2A JSON-RPC 端点\n if (pathname === config.rpcPath && event.request.method === 'POST') {\n // Hook 与显式路由共享认证、JSON-RPC 错误和流式生命周期逻辑。\n const handler = createA2AHandler(\n (body, context) => config.operations.handleRequest(body, context),\n { authenticate: config.authenticate },\n )\n const response = await handler(event)\n response.headers.set('X-Request-Id', requestId)\n return response\n }\n\n return null\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/crud/kit-crud.ts","../src/kit-config.ts"],"names":[],"mappings":"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","file":"chunk-L7BTMAKX.js","sourcesContent":["/**\n * @h-ai/kit — CRUD 操作定义\n *\n * 声明式 CRUD 资源定义工厂函数。\n * @module kit-crud\n */\n\nimport type {\n CrudFieldDef,\n CrudFieldOptions,\n CrudOperations,\n CrudResourceDef,\n CrudTableColumn,\n CrudText,\n} from './kit-crud-types.js'\n\n/**\n * 解析 CrudText 为字符串\n */\nfunction resolveText(text: CrudText): string {\n return typeof text === 'function' ? text() : text\n}\n\n/**\n * 按 order 排序字段\n */\nfunction sortFields(fields: CrudFieldDef[]): CrudFieldDef[] {\n return [...fields].sort((a, b) => (a.order ?? 0) - (b.order ?? 0))\n}\n\n/**\n * 解析选项列表\n */\nfunction resolveOptions(options: CrudFieldOptions | undefined): Array<{ label: string, value: string | number | boolean }> {\n if (!options)\n return []\n return typeof options === 'function' ? options() : options\n}\n\n/**\n * 定义 CRUD 资源\n *\n * 返回 CrudOperations 对象,包含字段过滤、列构建和 API 代理等能力。\n * 与 @h-ai/ui 的 CrudPage 组件配合使用。\n *\n * @param resource - 资源定义\n * @returns CRUD 操作对象\n *\n * @example\n * ```ts\n * const userCrud = defineCrud({\n * name: 'user',\n * label: () => m.users_title(),\n * fields: [\n * { id: 'username', label: '用户名', type: 'string', validation: { required: true } },\n * { id: 'email', label: '邮箱', type: 'email' },\n * ],\n * api: { list, get, create, update, remove },\n * })\n * ```\n */\nexport function defineCrud<T = Record<string, unknown>>(\n resource: CrudResourceDef<T>,\n): CrudOperations<T> {\n const fields = resource.fields\n\n function getListFields(): CrudFieldDef[] {\n return sortFields(fields.filter(f => f.inList !== false))\n }\n\n function getFilterFields(): CrudFieldDef[] {\n return sortFields(fields.filter(f => f.filterable === true))\n }\n\n function getCreateFields(): CrudFieldDef[] {\n return sortFields(fields.filter(f => f.inCreate !== false))\n }\n\n function getEditFields(): CrudFieldDef[] {\n return sortFields(fields.filter(f => f.inEdit !== false))\n }\n\n function getDetailFields(): CrudFieldDef[] {\n return sortFields(fields.filter(f => f.inDetail !== false))\n }\n\n function toTableColumns(): CrudTableColumn[] {\n return getListFields().map(f => ({\n key: f.id,\n label: resolveText(f.label),\n width: f.width,\n align: f.align,\n render: f.render\n ? (item: Record<string, unknown>) => f.render!(item[f.id], item)\n : undefined,\n }))\n }\n\n function getDefaultValues(): Record<string, unknown> {\n const defaults: Record<string, unknown> = {}\n for (const f of fields) {\n if (f.defaultValue !== undefined) {\n defaults[f.id] = f.defaultValue\n }\n else if (f.type === 'boolean' || f.type === 'checkbox') {\n defaults[f.id] = false\n }\n else if (f.type === 'multi-select') {\n defaults[f.id] = []\n }\n else if (f.type === 'number') {\n defaults[f.id] = undefined\n }\n else {\n defaults[f.id] = ''\n }\n }\n return defaults\n }\n\n return {\n resource,\n getListFields,\n getFilterFields,\n getCreateFields,\n getEditFields,\n getDetailFields,\n toTableColumns,\n getDefaultValues,\n api: resource.api,\n }\n}\n\n// re-export 解析工具,供 UI 层使用\nexport { resolveOptions, resolveText }\n","/**\n * @h-ai/kit — transport 配置\n *\n * 为 `config/_kit.yml` 提供统一的 transport 配置结构、默认值与校验逻辑,\n * 方便应用层用一份配置同时驱动 `hooks.server.ts` 与 `kit.client.create()`。\n * @module kit-config\n */\n\nimport { z } from 'zod'\n\nconst AbsolutePathSchema = z.custom<`/${string}`>(\n value => typeof value === 'string' && value.startsWith('/'),\n 'path must start with /',\n)\n\n/** 服务器监听配置(对应 `config/_kit.yml` 的 `server`)。 */\nexport interface KitServerConfig {\n readonly host: string\n readonly port: number\n}\n\n/** `config/_kit.yml` 中的服务器监听输入类型。 */\nexport type KitServerConfigInput = Partial<KitServerConfig>\n\n/** `config/_kit.yml` 中的 transport 配置。 */\nexport interface KitTransportConfig {\n readonly keyExchangePath: `/${string}`\n readonly excludePaths: readonly `/${string}`[]\n readonly requireEncryption: boolean\n readonly encryptResponse: boolean\n readonly maxClients: number\n}\n\n/** `config/_kit.yml` 的顶层配置结构。 */\nexport interface KitConfig {\n readonly server: KitServerConfig\n readonly transport: false | KitTransportConfig\n}\n\n/** `config/_kit.yml` 中的 transport 输入类型。 */\nexport type KitTransportConfigInput = Partial<{\n readonly keyExchangePath: `/${string}`\n readonly excludePaths: readonly `/${string}`[]\n readonly requireEncryption: boolean\n readonly encryptResponse: boolean\n readonly maxClients: number\n}>\n\n/** `config/_kit.yml` 的顶层输入类型。 */\nexport interface KitConfigInput {\n readonly server?: KitServerConfigInput\n readonly transport?: false | KitTransportConfigInput\n}\n\nconst KitTransportConfigInputSchema = z.union([\n z.literal(false),\n z.object({\n keyExchangePath: AbsolutePathSchema.default('/api/_hai/key-exchange'),\n excludePaths: z.array(AbsolutePathSchema).default([]),\n requireEncryption: z.boolean().default(true),\n encryptResponse: z.boolean().default(true),\n maxClients: z.number().int().positive().default(10000),\n }),\n])\n\nconst ServerConfigInputSchema = z.object({\n host: z.string().min(1).default('127.0.0.1'),\n port: z.number().int().min(1).max(65535).default(3000),\n})\n\n/** `config/_kit.yml` 对应的配置 Schema。 */\nexport const KitConfigSchema = z.object({\n server: ServerConfigInputSchema.optional(),\n transport: KitTransportConfigInputSchema.optional(),\n}).transform(({ server, transport }) => ({\n server: resolveKitServerConfig(server ?? {}),\n transport: resolveKitTransportConfig(transport ?? false),\n}))\n\n/**\n * 读取 `HOST` / `PORT` 环境变量覆盖(环境变量高于配置文件)。\n *\n * 浏览器端 `process` 不存在时安全回退为空;`PORT` 仅采纳 1-65535 的整数。\n */\nfunction readServerEnvOverride(): KitServerConfigInput {\n // eslint-disable-next-line node/prefer-global/process\n const env = typeof process !== 'undefined' ? process.env : undefined\n const override: { host?: string, port?: number } = {}\n const host = env?.HOST\n if (host)\n override.host = host\n const rawPort = env?.PORT\n if (rawPort) {\n const port = Number(rawPort)\n if (Number.isInteger(port) && port >= 1 && port <= 65535)\n override.port = port\n }\n return override\n}\n\n/**\n * 解析服务器监听配置并补齐默认值。\n *\n * 优先级:`HOST` / `PORT` 环境变量 > `config/_kit.yml` 的 `server` > 默认 `127.0.0.1:3000`。\n *\n * @param input - `config/_kit.yml` 中的 server 配置\n * @returns 完整 server 配置\n */\nexport function resolveKitServerConfig(input: KitServerConfigInput = {}): KitServerConfig {\n return { ...ServerConfigInputSchema.parse(input), ...readServerEnvOverride() }\n}\n\n/**\n * 解析 transport 配置并补齐默认值。\n *\n * @param input - `config/_kit.yml` 中的 transport 配置\n * @returns 完整 transport 配置;`false` 表示关闭\n */\nexport function resolveKitTransportConfig(\n input: false | KitTransportConfigInput = false,\n): false | KitTransportConfig {\n return KitTransportConfigInputSchema.parse(input)\n}\n\n/**\n * 解析 `config/_kit.yml` 顶层配置并补齐默认值。\n *\n * 适合同一份配置同时供 SvelteKit 服务端 hook 与浏览器端 client 读取。\n */\nexport function resolveKitConfig(input: KitConfigInput = {}): KitConfig {\n return KitConfigSchema.parse(input)\n}\n"]}