@h-ai/kit 0.1.0-alpha9 → 1.0.0-beta.1

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 (52) hide show
  1. package/README.en.md +430 -0
  2. package/README.ja.md +430 -0
  3. package/README.md +351 -40
  4. package/dist/adapter/index.d.ts +17 -2
  5. package/dist/adapter/index.js.map +1 -1
  6. package/dist/browser.d.ts +19 -8
  7. package/dist/browser.js +10 -7
  8. package/dist/browser.js.map +1 -1
  9. package/dist/chunk-3OHUSKHI.js +175 -0
  10. package/dist/chunk-3OHUSKHI.js.map +1 -0
  11. package/dist/chunk-5VWPH7DO.js +126 -0
  12. package/dist/chunk-5VWPH7DO.js.map +1 -0
  13. package/dist/chunk-7EH47MTW.js +141 -0
  14. package/dist/chunk-7EH47MTW.js.map +1 -0
  15. package/dist/chunk-JRQPMPQC.js +63 -0
  16. package/dist/chunk-JRQPMPQC.js.map +1 -0
  17. package/dist/chunk-USFJN7IO.js +187 -0
  18. package/dist/chunk-USFJN7IO.js.map +1 -0
  19. package/dist/chunk-YKJRQCWR.js +363 -0
  20. package/dist/chunk-YKJRQCWR.js.map +1 -0
  21. package/dist/client/index.d.ts +51 -2
  22. package/dist/client/index.js +21 -2
  23. package/dist/client/index.js.map +1 -1
  24. package/dist/index.d.ts +303 -409
  25. package/dist/index.js +598 -310
  26. package/dist/index.js.map +1 -1
  27. package/dist/kit-a2a-types-4dapztu2.d.ts +136 -0
  28. package/dist/kit-client-auth-BnhrkzZF.d.ts +422 -0
  29. package/dist/kit-crypto-types-CXr888wf.d.ts +200 -0
  30. package/dist/kit-i18n-EBzZKYN-.d.ts +502 -0
  31. package/dist/kit-types-BkNdyKj8.d.ts +822 -0
  32. package/dist/modules/a2a/index.d.ts +15 -113
  33. package/dist/modules/a2a/index.js +2 -55
  34. package/dist/modules/a2a/index.js.map +1 -1
  35. package/dist/modules/crypto/index.d.ts +31 -79
  36. package/dist/modules/crypto/index.js +3 -3
  37. package/dist/modules/crypto/index.js.map +1 -1
  38. package/package.json +36 -22
  39. package/dist/chunk-475WECWK.js +0 -110
  40. package/dist/chunk-475WECWK.js.map +0 -1
  41. package/dist/chunk-6TMSXG7J.js +0 -169
  42. package/dist/chunk-6TMSXG7J.js.map +0 -1
  43. package/dist/chunk-AD6S473Y.js +0 -137
  44. package/dist/chunk-AD6S473Y.js.map +0 -1
  45. package/dist/chunk-FRYJMRTP.js +0 -71
  46. package/dist/chunk-FRYJMRTP.js.map +0 -1
  47. package/dist/chunk-PHS7ZD5L.js +0 -274
  48. package/dist/chunk-PHS7ZD5L.js.map +0 -1
  49. package/dist/index-BotXLTck.d.ts +0 -203
  50. package/dist/kit-crypto-types-C-gEvx04.d.ts +0 -253
  51. package/dist/kit-i18n-CgpNTh9G.d.ts +0 -206
  52. package/dist/kit-types-BHlDNNpd.d.ts +0 -618
@@ -1,95 +1,10 @@
1
- import { RequestEvent, RequestHandler } from '@sveltejs/kit';
2
- import { f as HandleA2AOperations, h as HandleConfig } from '../../kit-types-BHlDNNpd.js';
1
+ import { K as KitA2AHandlerConfig } from '../../kit-a2a-types-4dapztu2.js';
2
+ export { A as A2AApiKeyAuthConfig, R as ResolvedA2AConfig, c as createA2AApiKeyAuthenticator, h as handleA2ARequest, r as resolveA2AConfig } from '../../kit-a2a-types-4dapztu2.js';
3
+ import { RequestHandler } from '@sveltejs/kit';
4
+ import '../../kit-types-BkNdyKj8.js';
5
+ import '@h-ai/core';
6
+ import '@h-ai/crypto';
3
7
  import '@h-ai/iam';
4
- import '../../kit-crypto-types-C-gEvx04.js';
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 表示匿名请求,
86
- * 抛出异常或返回 Response 表示认证失败。
87
- *
88
- * - `'apiKey'`:自动使用 IAM API Key 认证
89
- * - 函数:自定义认证回调
90
- */
91
- authenticate?: 'apiKey' | ((event: RequestEvent) => Promise<Record<string, unknown> | null | undefined>);
92
- }
93
8
 
94
9
  /**
95
10
  * @h-ai/kit — A2A 路由处理器
@@ -105,21 +20,13 @@ 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
- declare function createAgentCardHandler(getAgentCard: () => Record<string, unknown>): RequestHandler;
29
+ declare function createAgentCardHandler(getAgentCard: () => object): RequestHandler;
123
30
  /**
124
31
  * 创建 A2A JSON-RPC POST 处理器
125
32
  *
@@ -129,16 +36,11 @@ declare function createAgentCardHandler(getAgentCard: () => Record<string, unkno
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,57 +1,4 @@
1
- import { createA2AApiKeyAuthenticator } from '../../chunk-475WECWK.js';
2
- export { createA2AApiKeyAuthenticator, handleA2ARequest, resolveA2AConfig } from '../../chunk-475WECWK.js';
3
-
4
- // src/modules/a2a/kit-a2a-helpers.ts
5
- function createAgentCardHandler(getAgentCard) {
6
- return async () => {
7
- const card = getAgentCard();
8
- return new Response(JSON.stringify(card), {
9
- headers: { "Content-Type": "application/json" }
10
- });
11
- };
12
- }
13
- function createA2AHandler(handleRequest, config) {
14
- return async (event) => {
15
- let context;
16
- if (config?.authenticate) {
17
- const authFn = typeof config.authenticate === "function" ? config.authenticate : createA2AApiKeyAuthenticator({ in: "header", name: "x-api-key" });
18
- const authResult = await authFn(event);
19
- if (authResult) {
20
- context = authResult;
21
- }
22
- }
23
- const requestBody = await event.request.json();
24
- const result = await handleRequest(requestBody, context);
25
- if (result.streaming && result.stream) {
26
- const stream = result.stream;
27
- const readableStream = new ReadableStream({
28
- async start(controller) {
29
- const encoder = new TextEncoder();
30
- try {
31
- for await (const chunk of stream) {
32
- controller.enqueue(encoder.encode(`data: ${JSON.stringify(chunk)}
33
-
34
- `));
35
- }
36
- } finally {
37
- controller.close();
38
- }
39
- }
40
- });
41
- return new Response(readableStream, {
42
- headers: {
43
- "Content-Type": "text/event-stream",
44
- "Cache-Control": "no-cache",
45
- "Connection": "keep-alive"
46
- }
47
- });
48
- }
49
- return new Response(JSON.stringify(result.body), {
50
- headers: { "Content-Type": "application/json" }
51
- });
52
- };
53
- }
54
-
55
- export { createA2AHandler, createAgentCardHandler };
1
+ export { createA2AApiKeyAuthenticator, createA2AHandler, createAgentCardHandler, handleA2ARequest, resolveA2AConfig } from '../../chunk-7EH47MTW.js';
2
+ import '../../chunk-USFJN7IO.js';
56
3
  //# sourceMappingURL=index.js.map
57
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/modules/a2a/kit-a2a-helpers.ts"],"names":[],"mappings":";;;;AAiCO,SAAS,uBACd,YAAA,EACgB;AAChB,EAAA,OAAO,YAAY;AACjB,IAAA,MAAM,OAAO,YAAA,EAAa;AAC1B,IAAA,OAAO,IAAI,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,EAAG;AAAA,MACxC,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,KAC/C,CAAA;AAAA,EACH,CAAA;AACF;AAuBO,SAAS,gBAAA,CACd,eAKA,MAAA,EACgB;AAChB,EAAA,OAAO,OAAO,KAAA,KAAwB;AAEpC,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI,QAAQ,YAAA,EAAc;AACxB,MAAA,MAAM,MAAA,GAAS,OAAO,MAAA,CAAO,YAAA,KAAiB,UAAA,GAC1C,MAAA,CAAO,YAAA,GACP,4BAAA,CAA6B,EAAE,EAAA,EAAI,QAAA,EAAU,IAAA,EAAM,aAAa,CAAA;AACpE,MAAA,MAAM,UAAA,GAAa,MAAM,MAAA,CAAO,KAAK,CAAA;AACrC,MAAA,IAAI,UAAA,EAAY;AACd,QAAA,OAAA,GAAU,UAAA;AAAA,MACZ;AAAA,IACF;AAGA,IAAA,MAAM,WAAA,GAAc,MAAM,KAAA,CAAM,OAAA,CAAQ,IAAA,EAAK;AAC7C,IAAA,MAAM,MAAA,GAAS,MAAM,aAAA,CAAc,WAAA,EAAa,OAAO,CAAA;AAEvD,IAAA,IAAI,MAAA,CAAO,SAAA,IAAa,MAAA,CAAO,MAAA,EAAQ;AAErC,MAAA,MAAM,SAAS,MAAA,CAAO,MAAA;AACtB,MAAA,MAAM,cAAA,GAAiB,IAAI,cAAA,CAAe;AAAA,QACxC,MAAM,MAAM,UAAA,EAAY;AACtB,UAAA,MAAM,OAAA,GAAU,IAAI,WAAA,EAAY;AAChC,UAAA,IAAI;AACF,YAAA,WAAA,MAAiB,SAAS,MAAA,EAAQ;AAChC,cAAA,UAAA,CAAW,QAAQ,OAAA,CAAQ,MAAA,CAAO,SAAS,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC;;AAAA,CAAM,CAAC,CAAA;AAAA,YACzE;AAAA,UACF,CAAA,SACA;AACE,YAAA,UAAA,CAAW,KAAA,EAAM;AAAA,UACnB;AAAA,QACF;AAAA,OACD,CAAA;AAED,MAAA,OAAO,IAAI,SAAS,cAAA,EAAgB;AAAA,QAClC,OAAA,EAAS;AAAA,UACP,cAAA,EAAgB,mBAAA;AAAA,UAChB,eAAA,EAAiB,UAAA;AAAA,UACjB,YAAA,EAAc;AAAA;AAChB,OACD,CAAA;AAAA,IACH;AAGA,IAAA,OAAO,IAAI,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,IAAI,CAAA,EAAG;AAAA,MAC/C,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,KAC/C,CAAA;AAAA,EACH,CAAA;AACF","file":"index.js","sourcesContent":["/**\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 { 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: () => Record<string, unknown>,\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 context = authResult\n }\n }\n\n // 解析 JSON-RPC 请求体\n const requestBody = await event.request.json()\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 async start(controller) {\n const encoder = new TextEncoder()\n try {\n for await (const chunk of stream) {\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(chunk)}\\n\\n`))\n }\n }\n finally {\n controller.close()\n }\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"]}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -1,8 +1,8 @@
1
1
  import { Cookies, RequestEvent } from '@sveltejs/kit';
2
- import { C as CryptoCsrfConfig, E as EncryptedCookieConfig, a as CryptoServiceLike, W as WebhookVerifyConfig, d as TransportEncryptionManager, T as TransportCryptoServiceLike, b as EncryptedPayload, c as TransportEncryptionConfig } from '../../kit-crypto-types-C-gEvx04.js';
3
- export { e as TransportKeyPair } from '../../kit-crypto-types-C-gEvx04.js';
4
- import { HaiResult } from '@h-ai/core';
5
- import { M as Middleware } from '../../kit-types-BHlDNNpd.js';
2
+ import { C as CryptoCsrfConfig, E as EncryptedCookieConfig, a as CryptoServiceLike, W as WebhookVerifyConfig, T as TransportEncryptionConfig } from '../../kit-crypto-types-CXr888wf.js';
3
+ import { RequestAccessCheck } from '@h-ai/core';
4
+ import { M as Middleware } from '../../kit-types-BkNdyKj8.js';
5
+ export { EncryptedPayload, TransportEncryptionManager, TransportKeyPair } from '@h-ai/crypto';
6
6
  import '@h-ai/iam';
7
7
 
8
8
  /**
@@ -19,13 +19,11 @@ import '@h-ai/iam';
19
19
  *
20
20
  * @param config - 签名验证配置
21
21
  * @returns 签名是否合法
22
- *
23
- * @example
22
+ * @example 模块内部上下文
24
23
  * ```ts
25
- * const valid = await verifyWebhookSignature({
26
- * crypto, event, secretKey: 'wh_secret', signatureHeader: 'X-Signature',
27
- * })
28
- * if (!valid) return new Response('Invalid signature', { status: 401 })
24
+ * async function authorized(config: WebhookVerifyConfig) {
25
+ * return verifyWebhookSignature(config) // 使用原始 body;读取后不可再次消费同一流。
26
+ * }
29
27
  * ```
30
28
  */
31
29
  declare function verifyWebhookSignature(config: WebhookVerifyConfig): Promise<boolean>;
@@ -38,6 +36,12 @@ declare function verifyWebhookSignature(config: WebhookVerifyConfig): Promise<bo
38
36
  * @param algorithm - 哈希算法(默认 `'sha256'`)
39
37
  * @returns 签名字符串
40
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
+ * ```
41
45
  */
42
46
  declare function signRequest(crypto: CryptoServiceLike, body: string, secretKey: string, algorithm?: string): Promise<string>;
43
47
  /**
@@ -48,14 +52,12 @@ declare function signRequest(crypto: CryptoServiceLike, body: string, secretKey:
48
52
  *
49
53
  * @param config - CSRF 配置(crypto 实例、Cookie 名、Header 名等)
50
54
  * @returns `{ generate, verify, createHandle }`
51
- *
52
- * @example
55
+ * @example 模块内部上下文
53
56
  * ```ts
54
- * const csrf = createCsrfManager({ crypto })
55
- * // 在 load 中生成
56
- * const token = await csrf.generate(cookies)
57
- * // 在 action 中验证
58
- * const ok = await csrf.verify(event)
57
+ * function csrf(config: CryptoCsrfConfig) {
58
+ * const manager = createCsrfManager(config)
59
+ * return manager
60
+ * }
59
61
  * ```
60
62
  */
61
63
  declare function createCsrfManager(config: CryptoCsrfConfig): {
@@ -82,12 +84,11 @@ declare function createCsrfManager(config: CryptoCsrfConfig): {
82
84
  *
83
85
  * @param config - 加密 Cookie 配置(含加密密钥)
84
86
  * @returns `{ set, get, delete }`
85
- *
86
- * @example
87
+ * @example 模块内部上下文
87
88
  * ```ts
88
- * const enc = createEncryptedCookie({ crypto, encryptionKey: 'my-32byte-key' })
89
- * await enc.set(cookies, 'prefs', { theme: 'dark' })
90
- * const prefs = await enc.get(cookies, 'prefs')
89
+ * function cookies(config: EncryptedCookieConfig) {
90
+ * return createEncryptedCookie(config)
91
+ * }
91
92
  * ```
92
93
  */
93
94
  declare function createEncryptedCookie(config: EncryptedCookieConfig): {
@@ -105,52 +106,6 @@ declare function createEncryptedCookie(config: EncryptedCookieConfig): {
105
106
  delete(cookies: Cookies, name: string): void;
106
107
  };
107
108
 
108
- /**
109
- * @h-ai/kit — 传输加密核心
110
- *
111
- * 基于非对称 + 对称的混合传输加密。
112
- * @module kit-transport-encryption
113
- */
114
-
115
- /**
116
- * 创建传输加密管理器
117
- *
118
- * 启动时生成服务端非对称密钥对,通过 clientId → publicKey 的内存 Map 管理客户端密钥。
119
- * 内置 LRU 淘汰机制,超过 maxClients 上限时自动移除最早注册的客户端。
120
- *
121
- * 注意:clientKeys 存储在进程内存中,多节点部署时各节点状态独立。
122
- * 客户端密钥交换后的后续请求必须路由到同一节点(如使用 sticky session),
123
- * 否则传输加密功能不可用。
124
- *
125
- * @param cryptoService - 传输加密服务实例(非对称 + 对称)
126
- * @param maxClients - 最大客户端数量(默认 10000),超过时淘汰最早注册的
127
- * @returns 成功返回传输加密管理器,密钥对生成失败时返回错误
128
- */
129
- declare function createTransportEncryption(cryptoService: TransportCryptoServiceLike, maxClients?: number): HaiResult<TransportEncryptionManager>;
130
- /**
131
- * 创建密钥交换端点处理器
132
- *
133
- * 返回一个标准的 POST 处理函数,用于接收客户端公钥并返回服务端公钥与 clientId。
134
- *
135
- * @param manager - 传输加密管理器
136
- * @returns POST 处理函数,可直接用于 SvelteKit +server.ts
137
- *
138
- * @example
139
- * ```ts
140
- * // src/routes/api/kit/key-exchange/+server.ts
141
- * import { keyExchangeHandler } from '$lib/server/transport'
142
- * export const POST = keyExchangeHandler
143
- * ```
144
- */
145
- declare function createKeyExchangeHandler(manager: TransportEncryptionManager): (request: Request) => Promise<Response>;
146
- /**
147
- * 校验加密载荷格式是否合法
148
- *
149
- * @param payload - 待校验对象
150
- * @returns 是否为合法的 EncryptedPayload
151
- */
152
- declare function isValidEncryptedPayload(payload: unknown): payload is EncryptedPayload;
153
-
154
109
  /**
155
110
  * @h-ai/kit — 传输加密中间件
156
111
  *
@@ -162,19 +117,16 @@ declare function isValidEncryptedPayload(payload: unknown): payload is Encrypted
162
117
  * 创建传输加密中间件
163
118
  *
164
119
  * @param config - 传输加密配置
120
+ * @param encryption - 已编译的路径/方法选择器;省略时沿用宿主默认范围。
165
121
  * @returns SvelteKit 中间件
166
- *
167
- * @example
122
+ * @throws 显式启用但管理器初始化失败时抛出配置错误,调用方须停止宿主装配。
123
+ * @example 模块内部上下文
168
124
  * ```ts
169
- * import { crypto } from '@h-ai/crypto'
170
- * import { kit } from '@h-ai/kit'
171
- *
172
- * // 传输加密通过 createHandle 的 crypto 配置自动启用:
173
- * export const handle = kit.createHandle({
174
- * crypto: { crypto, transport: true },
175
- * })
125
+ * function install(config: TransportEncryptionConfig) {
126
+ * return transportEncryptionMiddleware(config) // 受管密钥环、共享 keyStore 与 crypto 生命周期由应用管理。
127
+ * }
176
128
  * ```
177
129
  */
178
- declare function transportEncryptionMiddleware(config: TransportEncryptionConfig): Middleware;
130
+ declare function transportEncryptionMiddleware(config: TransportEncryptionConfig, encryption?: RequestAccessCheck['encryption']): Middleware;
179
131
 
180
- export { CryptoCsrfConfig, CryptoServiceLike, EncryptedCookieConfig, EncryptedPayload, TransportCryptoServiceLike, TransportEncryptionConfig, TransportEncryptionManager, WebhookVerifyConfig, createCsrfManager, createEncryptedCookie, createKeyExchangeHandler, createTransportEncryption, isValidEncryptedPayload, signRequest, transportEncryptionMiddleware, verifyWebhookSignature };
132
+ export { CryptoCsrfConfig, CryptoServiceLike, EncryptedCookieConfig, TransportEncryptionConfig, WebhookVerifyConfig, createCsrfManager, createEncryptedCookie, signRequest, transportEncryptionMiddleware, verifyWebhookSignature };
@@ -1,6 +1,6 @@
1
- export { transportEncryptionMiddleware } from '../../chunk-AD6S473Y.js';
2
- import { kitM } from '../../chunk-6TMSXG7J.js';
3
- export { createKeyExchangeHandler, createTransportEncryption, isValidEncryptedPayload } from '../../chunk-6TMSXG7J.js';
1
+ export { transportEncryptionMiddleware } from '../../chunk-3OHUSKHI.js';
2
+ import '../../chunk-JRQPMPQC.js';
3
+ import { kitM } from '../../chunk-USFJN7IO.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-alpha9",
4
+ "version": "1.0.0-beta.1",
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"
@@ -40,13 +39,20 @@
40
39
  "publishConfig": {
41
40
  "access": "public"
42
41
  },
42
+ "engines": {
43
+ "node": "^22.23.4 || ^24.22.1 || ^26.12.1"
44
+ },
43
45
  "peerDependencies": {
44
- "@sveltejs/adapter-node": "^5.0.0",
45
- "@sveltejs/adapter-static": "^3.0.0",
46
- "@sveltejs/kit": "^2.53.4",
47
- "svelte": "^5.53.6"
46
+ "@h-ai/feedback": "1.0.0-beta.1",
47
+ "@sveltejs/adapter-node": "^5.5.7",
48
+ "@sveltejs/adapter-static": "^3.0.10",
49
+ "@sveltejs/kit": "^2.70.3",
50
+ "svelte": "^5.57.2"
48
51
  },
49
52
  "peerDependenciesMeta": {
53
+ "@h-ai/feedback": {
54
+ "optional": true
55
+ },
50
56
  "@sveltejs/adapter-node": {
51
57
  "optional": true
52
58
  },
@@ -55,27 +61,35 @@
55
61
  }
56
62
  },
57
63
  "dependencies": {
58
- "zod": "^4.3.6",
59
- "@h-ai/core": "0.1.0-alpha9",
60
- "@h-ai/iam": "0.1.0-alpha9"
64
+ "@h-ai/api-contract": "1.0.0-beta.1",
65
+ "@h-ai/audit": "1.0.0-beta.1",
66
+ "@h-ai/core": "1.0.0-beta.1",
67
+ "@h-ai/crypto": "1.0.0-beta.1",
68
+ "@h-ai/iam": "1.0.0-beta.1",
69
+ "zod": "^4.6.5"
61
70
  },
62
71
  "devDependencies": {
63
- "@sveltejs/kit": "^2.15.0",
64
- "@types/node": "^25.1.0",
65
- "rimraf": "^6.0.1",
66
- "svelte": "^5.53.5",
67
- "tsup": "^8.3.5",
68
- "typescript": "^5.7.2",
69
- "vitest": "^4.0.18"
72
+ "@h-ai/cache": "1.0.0-beta.1",
73
+ "@h-ai/feedback": "1.0.0-beta.1",
74
+ "@h-ai/reldb": "1.0.0-beta.1",
75
+ "@sveltejs/kit": "^2.70.3",
76
+ "@types/node": "^26.6.5",
77
+ "rimraf": "^6.1.3",
78
+ "svelte": "^5.57.2",
79
+ "testcontainers": "^12.2.0",
80
+ "tsup": "^8.5.1",
81
+ "typescript": "^6.0.3",
82
+ "vitest": "^4.1.11"
70
83
  },
71
84
  "scripts": {
72
85
  "build": "tsup",
73
86
  "dev": "tsup --watch",
74
87
  "test": "vitest run",
75
88
  "test:watch": "vitest",
76
- "typecheck": "tsc --noEmit",
89
+ "typecheck": "node ../../scripts/typecheck.mjs --noEmit",
77
90
  "lint": "eslint .",
78
91
  "lint:fix": "eslint . --fix",
79
- "clean": "rimraf dist .turbo"
92
+ "clean": "rimraf dist .turbo",
93
+ "build:clean": "rimraf dist"
80
94
  }
81
95
  }