@h-ai/cli 0.1.0-alpha.44 → 0.1.0-alpha.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@h-ai/cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.0-alpha.
|
|
4
|
+
"version": "0.1.0-alpha.45",
|
|
5
5
|
"description": "Hai Framework CLI for project scaffolding and code generation.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"keywords": [
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"ora": "^9.1.0",
|
|
35
35
|
"prompts": "^2.4.2",
|
|
36
36
|
"yaml": "^2.7.0",
|
|
37
|
-
"@h-ai/core": "0.1.0-alpha.
|
|
37
|
+
"@h-ai/core": "0.1.0-alpha.45"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/fs-extra": "^11.0.4",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "{{projectName}}",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.45",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "{{#if_eq appType 'admin'}}Enterprise management system built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'website'}}Enterprise website built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'h5'}}Mobile H5 app built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'api'}}REST API service built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'mobile-app'}}Mobile app built with hai Agent Framework{{/if_eq}}",
|
|
6
6
|
"keywords": ["hai", {{#unless isSvelteOnlyApp}}"sveltekit", {{/unless}}"svelte5", "{{appType}}"],
|
|
@@ -39,6 +39,7 @@ description: 使用 @h-ai/serv 将 oRPC contract 挂载为最小 HTTP App 抽象
|
|
|
39
39
|
- 通过 `serv.createRuntimeSecurityPolicy(...)` 对生产 CORS Origin、原生 WebView Origin、Secure Cookie 与 API 文档暴露执行 fail-closed 策略
|
|
40
40
|
- 启用传输加密:`serv.createApp({ transport: { crypto } })`
|
|
41
41
|
- 高级场景通过 `createApp({ middlewares })` 自定义 HTTP middleware,或通过共享类型自定义 procedure wrapper
|
|
42
|
+
- 公开只读文件通过 `serv.storageAssets(...)` 统一处理安全 key、MIME 白名单、GET/HEAD、ETag 与缓存头
|
|
42
43
|
- 为 Audio WebSocket 配置一次性 ticket 校验、IAM/模型/配额授权与并发释放钩子
|
|
43
44
|
|
|
44
45
|
---
|
|
@@ -299,7 +300,7 @@ export function createServerApp() {
|
|
|
299
300
|
http?, // ServHttpConfigInput — HTTP 端点配置(见下方配置节)
|
|
300
301
|
middlewares?, // readonly ServMiddlewareMount[] — 自定义 HTTP middleware(日志/CORS/限流/租户头校验)
|
|
301
302
|
iam?, // ServIam — 顶层 IAM 句柄,同时驱动 access token 校验与 refresh cookie【推荐】
|
|
302
|
-
refreshCookie?, // RefreshCookieConfig —
|
|
303
|
+
refreshCookie?, // RefreshCookieConfig — 浏览器 cookie / 受信原生 body 的 refresh token 通道
|
|
303
304
|
transport?, // { crypto, keyExchangePath?, excludePaths?, maxClients? } — 统一传输加密
|
|
304
305
|
verifyToken?, // (token) => Promise<HaiResult<ServSession>> — 逃脱口:不使用 iam 时提供自定义校验
|
|
305
306
|
createContext?, // CreateServContext — 高级:完全接管上下文构造(设置后 serv 不再自动填充 session)
|
|
@@ -453,9 +454,13 @@ const app = serv.createApp({
|
|
|
453
454
|
},
|
|
454
455
|
{
|
|
455
456
|
path: '/assets/*',
|
|
456
|
-
middleware:
|
|
457
|
-
|
|
458
|
-
|
|
457
|
+
middleware: serv.storageAssets({
|
|
458
|
+
storage,
|
|
459
|
+
pathPrefix: '/assets/',
|
|
460
|
+
keyPattern: /^public\/[\w-]+\.png$/,
|
|
461
|
+
allowedContentTypes: ['image/png'],
|
|
462
|
+
cacheControl: 'public, max-age=31536000, immutable',
|
|
463
|
+
crossOriginResourcePolicy: 'cross-origin',
|
|
459
464
|
}),
|
|
460
465
|
},
|
|
461
466
|
],
|
|
@@ -465,7 +470,8 @@ const app = serv.createApp({
|
|
|
465
470
|
执行顺序固定为:`securityHeaders` → `middlewares` → `transport`(若启用)→ health/refresh-cookie/OpenAPI/RPC/docs/oRPC routes。
|
|
466
471
|
|
|
467
472
|
- `middlewares` 先于 `transport` 执行,因此 CORS preflight 或二进制端点可以直接短路;短路响应仍带内置安全头,但不会经过 transport。
|
|
468
|
-
-
|
|
473
|
+
- 公开只读文件优先使用 `serv.storageAssets(...)`;应用仍须显式提供 key/MIME 白名单、缓存与跨域策略,框架不内置头像等业务概念。
|
|
474
|
+
- 私有资源、Range 下载或动态授权继续使用自定义 middleware/procedure。
|
|
469
475
|
- 若需要读取解密后的业务 body,请改用 context / procedure 层扩展。
|
|
470
476
|
- 浏览器若需读取自定义响应头(例如 transport 的 `X-Encrypted`),记得通过 `serv.cors({ exposedHeaders: [...] })` 显式暴露。
|
|
471
477
|
|
|
@@ -695,6 +701,7 @@ procedure 包装器内置以下错误:
|
|
|
695
701
|
`serv.parseRequestContext()` / `extractBearerToken()` 解析、`buildAuthContextFactory()` 校验的就是它。
|
|
696
702
|
- `refreshToken`:长期凭证,启用 `refreshCookie` 后只保存在 httpOnly cookie;
|
|
697
703
|
它不会走 `Authorization`,也不会被 `extractBearerToken()` 读取,只会在 `/auth/refresh` 被服务端取出。
|
|
704
|
+
受信原生客户端可通过 `nativeTokenTransport` 改用 JSON body,但必须同时校验客户端标识与 Origin。
|
|
698
705
|
|
|
699
706
|
### 适用场景
|
|
700
707
|
|
|
@@ -709,6 +716,9 @@ procedure 包装器内置以下错误:
|
|
|
709
716
|
4. serv 读取 cookie → 调用 `iam.session.refresh` → 返回新 access token + 更新 cookie(响应体不暴露 refresh token)
|
|
710
717
|
5. POST `/auth/logout` → serv 清除 cookie(`Max-Age=0`)
|
|
711
718
|
|
|
719
|
+
原生客户端匹配 `nativeTokenTransport.isRequest` 后,登录/注册/刷新响应保留轮换后的
|
|
720
|
+
`refreshToken`,刷新请求从 `{ refreshToken }` body 读取,且不读写浏览器 Cookie。
|
|
721
|
+
|
|
712
722
|
若同时启用 `transport: { crypto }`,`/auth/refresh` 也必须走加密链路;cookie-only 刷新请求允许空 body,服务端不要把 `Request.body === null` 误判为需要解密的请求体。
|
|
713
723
|
|
|
714
724
|
### 配置
|
|
@@ -724,6 +734,12 @@ const app = serv.createApp({
|
|
|
724
734
|
// maxAge?: number 默认 30 * 24 * 3600(30 天)
|
|
725
735
|
// secure?: boolean 默认 NODE_ENV=production 时开启
|
|
726
736
|
// onRefresh?: (token) => ... 可选:覆盖默认的 iam.session.refresh
|
|
737
|
+
nativeTokenTransport: {
|
|
738
|
+
// 必须 fail-closed:同时校验平台标识与允许的原生 Origin。
|
|
739
|
+
isRequest: request =>
|
|
740
|
+
request.headers.get('x-client-platform') === 'capacitor'
|
|
741
|
+
&& security.isNativeOrigin(request.headers.get('origin') ?? ''),
|
|
742
|
+
},
|
|
727
743
|
},
|
|
728
744
|
// ✅ 顶层 iam 同时为 access token 校验提供默认实现,无需再传 verifyToken
|
|
729
745
|
})
|