@h-ai/cli 0.1.0-alpha.59 → 0.1.0-alpha.60

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 (84) hide show
  1. package/README.en.md +9 -1
  2. package/README.ja.md +9 -1
  3. package/README.md +9 -1
  4. package/dist/{chunk-WUSFJFW5.js → chunk-P6X63D3I.js} +64 -6
  5. package/dist/chunk-P6X63D3I.js.map +1 -0
  6. package/dist/cli-config-templates-EFABFSCY.js +5 -0
  7. package/dist/{cli-config-templates-6XA7V6CC.js.map → cli-config-templates-EFABFSCY.js.map} +1 -1
  8. package/dist/index.js +6 -4
  9. package/dist/index.js.map +1 -1
  10. package/package.json +7 -7
  11. package/templates/README.md +8 -0
  12. package/templates/apps/api/apps/{{projectName}}-service/README.md.hbs +12 -0
  13. package/templates/apps/api/apps/{{projectName}}-service/src/app.ts.hbs +4 -7
  14. package/templates/apps/api/apps/{{projectName}}-service/src/lib/server/init.ts.hbs +11 -1
  15. package/templates/apps/api/apps/{{projectName}}-service/tests/service.test.ts.hbs +2 -1
  16. package/templates/apps/api/e2e/api-service.spec.ts.hbs +72 -6
  17. package/templates/apps/api/package.json.hbs +4 -0
  18. package/templates/apps/fullstack/apps/{{projectName}}-app/README.md.hbs +10 -0
  19. package/templates/apps/fullstack/apps/{{projectName}}-app/project.inlang/settings.json.hbs +1 -1
  20. package/templates/apps/fullstack/apps/{{projectName}}-desktop/README.md.hbs +10 -0
  21. package/templates/apps/fullstack/apps/{{projectName}}-desktop/project.inlang/settings.json.hbs +1 -1
  22. package/templates/apps/fullstack/apps/{{projectName}}-miniapp/README.md.hbs +2 -0
  23. package/templates/apps/fullstack/apps/{{projectName}}-miniapp/project.inlang/settings.json.hbs +1 -1
  24. package/templates/apps/fullstack/apps/{{projectName}}-web/README.md.hbs +10 -0
  25. package/templates/apps/fullstack/apps/{{projectName}}-web/project.inlang/settings.json.hbs +1 -1
  26. package/templates/apps/fullstack/e2e/fullstack.spec.ts.hbs +63 -1
  27. package/templates/apps/fullstack/packages/{{projectName}}-contract/README.md.hbs +1 -1
  28. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/admin-contract.ts.hbs +8 -1
  29. package/templates/apps/fullstack/packages/{{projectName}}-contract/src/admin-schemas.ts.hbs +1 -1
  30. package/templates/apps/fullstack/packages/{{projectName}}-serv/README.md.hbs +10 -0
  31. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_iam.yml.hbs +46 -0
  32. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_reach.yml.hbs +21 -0
  33. package/templates/apps/fullstack/packages/{{projectName}}-serv/package.json.hbs +1 -0
  34. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/admin-service.ts.hbs +1 -1
  35. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/admin-procedures.ts.hbs +2 -2
  36. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/runtime.ts.hbs +7 -3
  37. package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/app-server.test.ts.hbs +11 -4
  38. package/templates/apps/fullstack/packages/{{projectName}}-shared/README.md.hbs +12 -0
  39. package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/en-US.json.hbs +2 -2
  40. package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/zh-CN.json.hbs +2 -2
  41. package/templates/apps/fullstack/packages/{{projectName}}-shared/package.json.hbs +1 -0
  42. package/templates/apps/fullstack/packages/{{projectName}}-shared/project.inlang/settings.json.hbs +1 -1
  43. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/api-client.ts.hbs +3 -0
  44. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AdminWorkspace.svelte.hbs +32 -23
  45. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/ProfileSettings.svelte.hbs +24 -24
  46. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/UserManagement.svelte.hbs +1 -1
  47. package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/management-store.svelte.ts.hbs +20 -20
  48. package/templates/apps/fullstack/packages/{{projectName}}-shared/tests/management-store.test.ts.hbs +7 -8
  49. package/templates/apps/mobile-app/src/App.svelte.hbs +43 -0
  50. package/templates/base/e2e/app.spec.ts.hbs +105 -0
  51. package/templates/base/package.json.hbs +1 -1
  52. package/templates/base/src/hooks.server.ts.hbs +2 -2
  53. package/templates/base/src/lib/server/init.ts.hbs +1 -1
  54. package/templates/base/src/routes/+layout.server.ts.hbs +6 -0
  55. package/templates/base/tests/scaffold.test.ts.hbs +3 -0
  56. package/templates/base/vite.config.ts.hbs +1 -0
  57. package/templates/features/iam/routes-admin/(auth)/+layout.svelte.hbs +2 -16
  58. package/templates/features/iam/routes-admin/(auth)/auth/forgot-password/+page.svelte.hbs +10 -0
  59. package/templates/features/iam/routes-admin/(auth)/auth/login/+page.svelte.hbs +6 -95
  60. package/templates/features/iam/routes-admin/(auth)/auth/register/+page.svelte.hbs +6 -117
  61. package/templates/features/iam/routes-admin/(auth)/auth/reset-password/+page.svelte.hbs +10 -0
  62. package/templates/features/iam/routes-h5/auth/forgot-password/+page.svelte.hbs +10 -0
  63. package/templates/features/iam/routes-h5/auth/login/+page.svelte.hbs +6 -97
  64. package/templates/features/iam/routes-h5/auth/register/+page.svelte.hbs +6 -112
  65. package/templates/features/iam/routes-h5/auth/reset-password/+page.svelte.hbs +10 -0
  66. package/templates/features/iam/routes-shared/api/auth/config/+server.ts +4 -0
  67. package/templates/features/iam/routes-shared/api/auth/login/+server.ts +1 -33
  68. package/templates/features/iam/routes-shared/api/auth/login/ldap/+server.ts +4 -0
  69. package/templates/features/iam/routes-shared/api/auth/login/otp/+server.ts +4 -0
  70. package/templates/features/iam/routes-shared/api/auth/otp/send/+server.ts +4 -0
  71. package/templates/features/iam/routes-shared/api/auth/password-reset/confirm/+server.ts +4 -0
  72. package/templates/features/iam/routes-shared/api/auth/password-reset/request/+server.ts +4 -0
  73. package/templates/features/iam/routes-shared/api/auth/register/+server.ts +1 -23
  74. package/templates/features/iam/routes-website/auth/forgot-password/+page.svelte.hbs +10 -0
  75. package/templates/features/iam/routes-website/auth/login/+page.svelte.hbs +11 -0
  76. package/templates/features/iam/routes-website/auth/register/+page.svelte.hbs +11 -0
  77. package/templates/features/iam/routes-website/auth/reset-password/+page.svelte.hbs +10 -0
  78. package/templates/skills/hai-api-client/SKILL.md +5 -0
  79. package/templates/skills/hai-iam/SKILL.md +9 -2
  80. package/templates/skills/hai-iam/reference.md +76 -11
  81. package/templates/skills/hai-reach/SKILL.md +2 -0
  82. package/templates/skills/hai-ui/reference.md +45 -0
  83. package/dist/chunk-WUSFJFW5.js.map +0 -1
  84. package/dist/cli-config-templates-6XA7V6CC.js +0 -5
package/README.en.md CHANGED
@@ -227,7 +227,15 @@ Projects in `apps/*` reference local packages through `workspace:*` and can use
227
227
  node packages/cli/dist/index.js create ../my-new-project
228
228
  ```
229
229
 
230
- ### 5. Run tests
230
+ ## 5. Configuration driven authentication
231
+
232
+ Agreements support configuration-loaded userAgreementMarkdown/privacyPolicyMarkdown and URLs. Markdown takes priority for the same agreement and is safely rendered in a modal.
233
+
234
+ Admin/H5/website templates with IAM include AuthPanel and standard routes; mobile and fullstack clients share API actions. Server config/_iam.yml controls methods, registration, recovery, agreement modals and branding. LDAP/Reach are optional: install ldapts only for the default LDAP client, then enable login.ldap and set connection settings. Email/SMS use Reach templates or custom callbacks. Forms expose header/extraFields/footer snippets and AuthPanel forwards login*/register* snippets. Multiple nodes share a database and Redis.
235
+
236
+ [完整 IAM 配置 / IAM configuration](../iam/README.en.md)
237
+
238
+ ### 6. Run tests
231
239
 
232
240
  ```bash
233
241
  # 单元测试 + E2E 模板生成测试
package/README.ja.md CHANGED
@@ -227,7 +227,15 @@ hai create my-app
227
227
  node packages/cli/dist/index.js create ../my-new-project
228
228
  ```
229
229
 
230
- ### 5. テスト実行
230
+ ## 5. 設定による認証画面
231
+
232
+ 規約は設定の userAgreementMarkdown/privacyPolicyMarkdown または URL を使用できます。同じ規約は Markdown 本文を優先して安全な Modal で描画します。
233
+
234
+ IAM を選択した admin/h5/website は AuthPanel と標準 route を生成し、mobile と fullstack は API actions を共用します。サーバーの _iam.yml で認証方式、登録、復旧、規約 Modal、ブランドを設定します。LDAP/Reach は任意です。既定 LDAP クライアントを使用する時だけ ldapts をインストールし、login.ldap と接続設定を指定します。メール/SMS は Reach テンプレートまたは独自コールバックを使用します。フォームは header/extraFields/footer、AuthPanel は login*/register* snippet を提供します。複数ノードは DB と Redis を共有します。
235
+
236
+ [完整 IAM 配置 / IAM configuration](../iam/README.ja.md)
237
+
238
+ ### 6. テスト実行
231
239
 
232
240
  ```bash
233
241
  # 单元测试 + E2E 模板生成测试
package/README.md CHANGED
@@ -227,7 +227,15 @@ monorepo 内的 `apps/*` 项目已通过 `workspace:*` 协议引用本地包,
227
227
  node packages/cli/dist/index.js create ../my-new-project
228
228
  ```
229
229
 
230
- ### 5. 运行测试
230
+ ## 5. 配置驱动认证页面
231
+
232
+ 协议支持配置中的 userAgreementMarkdown/privacyPolicyMarkdown 正文及 URL;同主题优先 Markdown,由安全渲染器在弹窗显示。
233
+
234
+ 选用 IAM 的 admin/h5/website 模板提供 AuthPanel 和标准认证路由;mobile-app 与 fullstack Web/App/Desktop 使用 API 客户端共享动作。修改服务端 config/_iam.yml 控制登录方式、注册、重置、协议弹窗和品牌。LDAP/Reach 均可选:默认 LDAP 客户端需要应用安装 ldapts,再启用 login.ldap 并配置连接;短信/邮件可选择 Reach 模板或自定义发送回调。表单预留 header/extraFields/footer,AuthPanel 透传 login*/register* snippet。分布式部署使用共享数据库与 Redis。
235
+
236
+ [完整 IAM 配置 / IAM configuration](../iam/README.md)
237
+
238
+ ### 6. 运行测试
231
239
 
232
240
  ```bash
233
241
  # 单元测试 + E2E 模板生成测试
@@ -170,6 +170,52 @@ login:
170
170
  otp: ${loginOtp}
171
171
  ldap: false
172
172
 
173
+ # \u6CE8\u518C\u4E0E\u767B\u5F55\u5B89\u5168
174
+ register:
175
+ enabled: true
176
+ defaultEnabled: true
177
+ security:
178
+ maxLoginAttempts: 5
179
+ lockoutDuration: 900
180
+
181
+ # LDAP \u53EF\u9009\uFF1A\u5B89\u88C5 ldapts \u540E\u5F00\u542F login.ldap\uFF0C\u5E76\u58F0\u660E ldap \u8FDE\u63A5\u914D\u7F6E\uFF1B\u4E5F\u53EF\u6CE8\u5165\u5DE5\u5382\u3002
182
+ # OTP \u9700\u542F\u7528 login.otp\uFF0C\u5E76\u9009\u62E9 Reach \u6807\u51C6\u6A21\u677F\u6216\u81EA\u5B9A\u4E49\u53D1\u9001\u56DE\u8C03\u3002
183
+ otp:
184
+ email: true
185
+ sms: true
186
+ length: 6
187
+ expiresIn: 300
188
+ maxAttempts: 3
189
+ resendInterval: 60
190
+ passwordReset:
191
+ enabled: true
192
+ mode: email # phone \u4F7F\u7528 password_reset_sms \u6A21\u677F
193
+ tokenExpiresIn: 3600
194
+ maxAttempts: 3
195
+ # resetUrl: https://example.com/auth/reset-password
196
+ agreements:
197
+ showOnRegister: true
198
+ showOnLogin: false
199
+ # \u7528 | \u914D\u7F6E Markdown \u6B63\u6587\uFF1B\u540C\u4E3B\u9898\u540C\u65F6\u63D0\u4F9B URL \u65F6\u4F18\u5148\u663E\u793A\u6B63\u6587\u3002
200
+ userAgreementMarkdown: |
201
+ # \u7528\u6237\u534F\u8BAE\u793A\u4F8B
202
+
203
+ \u8BF7\u59A5\u5584\u4FDD\u7BA1\u8D26\u6237\u51ED\u636E\uFF0C\u5E76\u6309\u5E94\u7528\u63D0\u4F9B\u7684\u529F\u80FD\u4F7F\u7528\u670D\u52A1\u3002
204
+ privacyPolicyMarkdown: |
205
+ # \u9690\u79C1\u653F\u7B56\u793A\u4F8B
206
+
207
+ \u6CE8\u518C\u8D44\u6599\u7528\u4E8E\u8D26\u6237\u7BA1\u7406\uFF0C\u4F1A\u8BDD\u4FE1\u606F\u7528\u4E8E\u8EAB\u4EFD\u8BA4\u8BC1\u3002
208
+ # userAgreementUrl: https://example.com/terms
209
+ # privacyPolicyUrl: https://example.com/privacy
210
+ ui:
211
+ variant: card
212
+ # title: Account center
213
+ # subtitle: Welcome back
214
+ # brandTitle: Your application
215
+ # brandText: Sign in securely
216
+ # logoUrl: /logo.svg
217
+ # illustrationUrl: /auth-illustration.svg
218
+
173
219
  # \u5BC6\u7801\u7B56\u7565
174
220
  password:
175
221
  minLength: 8
@@ -594,12 +640,24 @@ providers:
594
640
  # accessKeySecret: \${HAI_REACH_SMS_SECRET_KEY}
595
641
  # signName: MyApp
596
642
 
597
- # \u6A21\u677F\uFF08\u53EF\u9009\uFF09
643
+ # IAM \u6807\u51C6\u6A21\u677F\uFF1A\u4FDD\u7559\u7A7A\u6570\u7EC4\u4EE5\u652F\u6301 HAI_REACH_TEMPLATES \u6574\u4F53\u8986\u76D6\u3002
644
+ templates: []
645
+ # \u5F00\u542F\u5BF9\u5E94 Provider \u540E\uFF0C\u5C06\u7A7A\u6570\u7EC4\u66FF\u6362\u4E3A\u9700\u8981\u7684\u6A21\u677F\u5217\u8868\uFF0C\u4F8B\u5982\uFF1A
598
646
  # templates:
599
- # - name: verification_code
647
+ # - name: otp_email
648
+ # provider: email
649
+ # subject: "Verification code"
650
+ # body: "Your verification code is {code}."
651
+ # - name: otp_sms
652
+ # provider: sms
653
+ # body: "Your verification code is {code}."
654
+ # - name: password_reset
600
655
  # provider: email
601
- # subject: "\u9A8C\u8BC1\u7801: {code}"
602
- # body: "\u60A8\u7684\u9A8C\u8BC1\u7801\u662F {code}\uFF0C\u6709\u6548\u671F {minutes} \u5206\u949F\u3002"
656
+ # subject: "Password reset"
657
+ # body: "Reset your password: {resetUrl}. Expires at {expiresAt}."
658
+ # - name: password_reset_sms
659
+ # provider: sms
660
+ # body: "Reset your password: {resetUrl}. Expires at {expiresAt}."
603
661
 
604
662
  # \u514D\u6253\u6270\uFF08\u53EF\u9009\uFF09
605
663
  # dnd:
@@ -677,5 +735,5 @@ function generatePaymentConfig() {
677
735
  }
678
736
 
679
737
  export { generateConfigFile, generateEnvExample };
680
- //# sourceMappingURL=chunk-WUSFJFW5.js.map
681
- //# sourceMappingURL=chunk-WUSFJFW5.js.map
738
+ //# sourceMappingURL=chunk-P6X63D3I.js.map
739
+ //# sourceMappingURL=chunk-P6X63D3I.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/cli-config-templates.ts"],"names":[],"mappings":"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","file":"chunk-P6X63D3I.js","sourcesContent":["/**\n * @h-ai/cli — 配置文件模板\n *\n * 为各模块生成默认配置文件内容。\n * @module cli-config-templates\n */\n\nimport type { AiModuleConfig, CacheModuleConfig, CoreModuleConfig, DbModuleConfig, FeatureId, IamModuleConfig, ModuleConfigs, StorageModuleConfig } from '../cli-types.js'\nimport { stringify } from 'yaml'\n\n/**\n * 生成模块配置文件内容\n *\n * @param moduleKey - 模块标识(core/serv/db/cache/iam/storage/ai)\n * @param configs - 用户自定义配置值\n * @returns YAML 格式的配置内容\n */\nexport function generateConfigFile(moduleKey: string, configs?: ModuleConfigs): string {\n switch (moduleKey) {\n case 'core':\n return generateCoreConfig(configs?.core)\n case 'serv':\n return generateServConfig()\n case 'db':\n return generateDbConfig(configs?.db)\n case 'cache':\n return generateCacheConfig(configs?.cache)\n case 'iam':\n return generateIamConfig(configs?.iam)\n case 'storage':\n return generateStorageConfig(configs?.storage)\n case 'ai':\n return generateAiConfig(configs?.ai)\n case 'deploy':\n return generateDeployConfig()\n case 'vecdb':\n return generateVecdbConfig()\n case 'reach':\n return generateReachConfig()\n case 'scheduler':\n return generateSchedulerConfig()\n case 'audit':\n return generateAuditConfig()\n case 'payment':\n return generatePaymentConfig()\n default:\n return `# ${moduleKey} 配置\\n`\n }\n}\n\nfunction generateCoreConfig(cfg?: CoreModuleConfig): string {\n const name = cfg?.name ?? 'my-app'\n const locale = cfg?.defaultLocale ?? 'zh-CN'\n const supportedLocales = locale === 'en-US'\n ? ` - en-US\\n - zh-CN`\n : ` - zh-CN\\n - en-US`\n\n return `# =============================================================================\n# 应用配置\n# =============================================================================\n\n${stringify({ name }).trim()}\nversion: 0.1.0\nenv: development\ndebug: false\n\nlogging:\n level: info\n format: json\n redact:\n - password\n - token\n - secret\n\ndefaultLocale: ${locale}\nsupportedLocales:\n${supportedLocales}\n`\n}\n\nfunction generateServConfig(): string {\n return `# =============================================================================\n# Service / HTTP 入口配置\n# =============================================================================\n\nhttp:\n apiPrefix: /api/v1\n openapi:\n path: /openapi.json\n docs:\n path: /docs\n health:\n path: /health\n readyPath: /ready\n rpc: false\n\n# 开发期默认关闭 transport;启用 @h-ai/crypto 后可按需改为对象配置\ntransport: false\n`\n}\n\nfunction generateDbConfig(cfg?: DbModuleConfig): string {\n const dbType = cfg?.type ?? 'sqlite'\n const database = cfg?.database ?? (dbType === 'sqlite' ? './data/app.db' : 'hai')\n const host = cfg?.host ?? 'localhost'\n const port = cfg?.port ?? (dbType === 'postgresql' ? 5432 : 3306)\n\n if (dbType === 'sqlite') {\n return `# =============================================================================\n# 数据库配置\n# =============================================================================\n\n# 数据库类型: sqlite | postgresql | mysql\ntype: sqlite\n\n# SQLite 数据库路径\ndatabase: ${database}\n\n# PostgreSQL/MySQL 配置(可选)\n# host: localhost\n# port: 5432\n# user: postgres\n# password: ''\n`\n }\n\n const user = dbType === 'postgresql' ? 'postgres' : 'root'\n\n return `# =============================================================================\n# 数据库配置\n# =============================================================================\n\n# 数据库类型: sqlite | postgresql | mysql\ntype: ${dbType}\n\n# 数据库名称\ndatabase: ${database}\n\n# 连接配置\nhost: ${host}\nport: ${port}\nuser: ${user}\npassword: ''\n`\n}\n\nfunction generateCacheConfig(cfg?: CacheModuleConfig): string {\n const cacheType = cfg?.type ?? 'memory'\n\n if (cacheType === 'memory') {\n return `# =============================================================================\n# 缓存配置\n# =============================================================================\n\n# 缓存类型: memory | redis\ntype: memory\n\n# Redis 配置(当 type 为 redis 时使用)\n# url: redis://localhost:6379/0\n# host: localhost\n# port: 6379\n# password: ''\n# keyPrefix: 'hai:'\n`\n }\n\n const host = cfg?.host ?? 'localhost'\n const port = cfg?.port ?? 6379\n\n return `# =============================================================================\n# 缓存配置\n# =============================================================================\n\n# 缓存类型: memory | redis\ntype: redis\n\n# Redis 配置\nhost: ${host}\nport: ${port}\npassword: ''\nkeyPrefix: 'hai:'\n`\n}\n\nfunction generateIamConfig(cfg?: IamModuleConfig): string {\n const loginPassword = cfg?.loginPassword ?? true\n const loginOtp = cfg?.loginOtp ?? false\n\n return `# =============================================================================\n# IAM 配置\n# =============================================================================\n\n# 登录配置\nlogin:\n password: ${loginPassword}\n otp: ${loginOtp}\n ldap: false\n\n# 注册与登录安全\nregister:\n enabled: true\n defaultEnabled: true\nsecurity:\n maxLoginAttempts: 5\n lockoutDuration: 900\n\n# LDAP 可选:安装 ldapts 后开启 login.ldap,并声明 ldap 连接配置;也可注入工厂。\n# OTP 需启用 login.otp,并选择 Reach 标准模板或自定义发送回调。\notp:\n email: true\n sms: true\n length: 6\n expiresIn: 300\n maxAttempts: 3\n resendInterval: 60\npasswordReset:\n enabled: true\n mode: email # phone 使用 password_reset_sms 模板\n tokenExpiresIn: 3600\n maxAttempts: 3\n # resetUrl: https://example.com/auth/reset-password\nagreements:\n showOnRegister: true\n showOnLogin: false\n # 用 | 配置 Markdown 正文;同主题同时提供 URL 时优先显示正文。\n userAgreementMarkdown: |\n # 用户协议示例\n\n 请妥善保管账户凭据,并按应用提供的功能使用服务。\n privacyPolicyMarkdown: |\n # 隐私政策示例\n\n 注册资料用于账户管理,会话信息用于身份认证。\n # userAgreementUrl: https://example.com/terms\n # privacyPolicyUrl: https://example.com/privacy\nui:\n variant: card\n # title: Account center\n # subtitle: Welcome back\n # brandTitle: Your application\n # brandText: Sign in securely\n # logoUrl: /logo.svg\n # illustrationUrl: /auth-illustration.svg\n\n# 密码策略\npassword:\n minLength: 8\n maxLength: 128\n requireUppercase: false\n requireLowercase: false\n requireNumber: false\n requireSpecialChar: false\n\n# 会话配置\nsession:\n maxAge: 86400 # 会话超时(秒),默认 24 小时\n sliding: true # 滑动窗口(每次请求刷新过期时间)\n singleDevice: false # 单设备登录\n refreshTokenMaxAge: 604800 # refreshToken 过期(秒),默认 7 天\n\n# RBAC 配置\nrbac:\n defaultRole: user\n\n# 是否自动创建默认数据\nseedDefaultData: true\n`\n}\n\nfunction generateStorageConfig(cfg?: StorageModuleConfig): string {\n if ((cfg?.type ?? 'local') === 'local') {\n return `# 存储配置;HAI_STORAGE 可整体替换为 S3 配置。\ntype: local\nroot: ${cfg?.localPath ?? './data/uploads'}\n`\n }\n return `# S3 存储配置\ntype: s3\nbucket: ''\nregion: us-east-1\naccessKeyId: ''\nsecretAccessKey: ''\nendpoint: https://s3.amazonaws.com\nforcePathStyle: false\n`\n}\n\nfunction generateAiConfig(cfg?: AiModuleConfig): string {\n const model = cfg?.model ?? 'gpt-4o-mini'\n\n // AIConfigSchema 结构:llm(必填)+ 可选子模块\n // LLMConfigSchema 支持顶层 apiKey/model,以及多模型 models 数组\n return `# =============================================================================\n# AI 配置\n# =============================================================================\n\n# LLM 配置(必填)\nllm:\n # API Key(约定环境变量 HAI_AI_LLM_APIKEY 优先)\n apiKey: ''\n # Base URL(约定环境变量 HAI_AI_LLM_BASEURL 优先)\n # baseUrl: https://api.openai.com/v1\n # 默认模型\n model: ${model}\n # 全局最大 Token 数(默认 4096)\n # maxTokens: 4096\n # 采样温度(0-2,默认 0.7)\n # temperature: 0.7\n # 请求超时(毫秒,默认 60000)\n # timeout: 60000\n\n # 多模型配置(可选,用于场景路由)\n # models:\n # - id: fast\n # model: gpt-4o-mini\n # - id: smart\n # model: gpt-4o\n # apiKey: ''\n\n # 场景模型映射(可选)\n # scenarios:\n # default: fast\n # analysis: smart\n`\n}\n\n/**\n * 根据选中的功能模块生成 .env.example 内容\n *\n * @param features - 选中的功能模块列表\n * @param configs - 用户自定义配置值\n * @returns .env.example 文件内容\n */\nexport function generateEnvExample(features: FeatureId[], configs?: ModuleConfigs): string {\n const sections: string[] = []\n\n // 文件头\n sections.push(`# =============================================================================\n# Environment Variables\n# =============================================================================\n#\n# Copy this file to .env and fill in actual values.\n# Config files use literal defaults; matching HAI variables override YAML leaves.\n#\n# Naming convention: HAI_<config name>_<YAML path>\n# =============================================================================`)\n\n // 应用基础(始终生成)\n sections.push(`\n# =============================================================================\n# Application\n# =============================================================================\n# Environment: development | production | test\nHAI_CORE_ENV=development\n# Enable debug mode\nHAI_CORE_DEBUG=false`)\n\n // 数据库\n if (features.includes('db')) {\n const dbType = configs?.db?.type ?? 'sqlite'\n const dbDatabase = configs?.db?.database ?? (dbType === 'sqlite' ? './data/app.db' : 'hai')\n const isSqlite = dbType === 'sqlite'\n sections.push(`\n# =============================================================================\n# Database (@h-ai/reldb)\n# =============================================================================\n# Database type: sqlite | postgresql | mysql\nHAI_DB_TYPE=${dbType}\n# SQLite: file path; PostgreSQL/MySQL: database name\nHAI_DB_DATABASE=${dbDatabase}${isSqlite\n ? `\n# PostgreSQL/MySQL connection (uncomment when not using sqlite)\n# HAI_DB_HOST=localhost\n# HAI_DB_PORT=5432\n# HAI_DB_USER=postgres\n# HAI_DB_PASSWORD=`\n : `\n# Connection\nHAI_DB_HOST=${configs?.db?.host ?? 'localhost'}\nHAI_DB_PORT=${configs?.db?.port ?? (dbType === 'postgresql' ? 5432 : 3306)}\nHAI_DB_USER=${dbType === 'postgresql' ? 'postgres' : 'root'}\nHAI_DB_PASSWORD=`}`)\n }\n\n // IAM / Session\n if (features.includes('iam')) {\n sections.push(`\n# =============================================================================\n# IAM (@h-ai/iam)\n# =============================================================================\n# HAI_IAM_PASSWORD_MINLENGTH=8\n# HAI_IAM_SESSION_MAXAGE=86400\n# HAI_IAM_SESSION_REFRESHTOKENMAXAGE=604800\n# HAI_KIT_COOKIE_KEY= # 32-char hex for SM4-CBC cookie encryption\n`)\n }\n\n // 缓存\n if (features.includes('cache')) {\n const cacheType = configs?.cache?.type ?? 'memory'\n if (cacheType === 'redis') {\n sections.push(`\n# =============================================================================\n# Cache (@h-ai/cache)\n# =============================================================================\n# Cache type: memory | redis\nHAI_CACHE_TYPE=redis\n# Redis connection\nHAI_CACHE_HOST=${configs?.cache?.host ?? 'localhost'}\nHAI_CACHE_PORT=${configs?.cache?.port ?? 6379}\nHAI_CACHE_PASSWORD=\n# HAI_CACHE_URL=redis://localhost:6379/0\n# HAI_CACHE_DB=0\n# HAI_CACHE_CONNECT_TIMEOUT=10000\n# HAI_CACHE_COMMAND_TIMEOUT=5000\n# HAI_CACHE_KEY_PREFIX=hai:`)\n }\n else {\n sections.push(`\n# =============================================================================\n# Cache (@h-ai/cache)\n# =============================================================================\n# Cache type: memory | redis\nHAI_CACHE_TYPE=memory\n# Redis connection (uncomment when type=redis)\n# HAI_CACHE_URL=redis://localhost:6379/0\n# HAI_CACHE_HOST=localhost\n# HAI_CACHE_PORT=6379\n# HAI_CACHE_PASSWORD=\n# HAI_CACHE_DB=0\n# HAI_CACHE_CONNECT_TIMEOUT=10000\n# HAI_CACHE_COMMAND_TIMEOUT=5000\n# HAI_CACHE_KEY_PREFIX=hai:`)\n }\n }\n\n // 存储\n if (features.includes('storage')) {\n const storageType = configs?.storage?.type ?? 'local'\n if (storageType === 's3') {\n sections.push(`\n# =============================================================================\n# Storage (@h-ai/storage)\n# =============================================================================\n# Default storage provider: local | s3\nHAI_STORAGE_TYPE=s3\n# S3 / S3-compatible\nHAI_STORAGE_BUCKET=\nHAI_STORAGE_REGION=us-east-1\nHAI_STORAGE_ACCESSKEYID=\nHAI_STORAGE_SECRETACCESSKEY=\n# HAI_STORAGE_ENDPOINT= # Custom endpoint for MinIO / Aliyun OSS etc.\n# HAI_STORAGE_FORCEPATHSTYLE=false\n# Local storage (uncomment when type=local)\n# HAI_STORAGE_ROOT=./data/uploads`)\n }\n else {\n sections.push(`\n# =============================================================================\n# Storage (@h-ai/storage)\n# =============================================================================\n# Default storage provider: local | s3\nHAI_STORAGE_TYPE=local\n# Local storage root path\nHAI_STORAGE_ROOT=${configs?.storage?.localPath ?? './data/uploads'}\n# S3 / S3-compatible (uncomment when type=s3)\n# HAI_STORAGE_BUCKET=\n# HAI_STORAGE_REGION=us-east-1\n# HAI_STORAGE_ACCESSKEYID=\n# HAI_STORAGE_SECRETACCESSKEY=\n# HAI_STORAGE_ENDPOINT= # Custom endpoint for MinIO / Aliyun OSS etc.\n# HAI_STORAGE_FORCEPATHSTYLE=false`)\n }\n }\n\n // AI\n if (features.includes('ai')) {\n const provider = configs?.ai?.defaultProvider ?? 'openai'\n if (provider === 'anthropic') {\n sections.push(`\n# =============================================================================\n# AI (@h-ai/ai)\n# =============================================================================\n# OpenAI-compatible API Key (Anthropic models via OpenAI-compatible proxy)\nHAI_AI_LLM_APIKEY=\n# HAI_AI_LLM_BASEURL= # Custom base URL\n# Optional compatibility fallback\n# OPENAI_API_KEY=`)\n }\n else if (provider === 'openai') {\n sections.push(`\n# =============================================================================\n# AI (@h-ai/ai)\n# =============================================================================\n# OpenAI / OpenAI-compatible\nHAI_AI_LLM_APIKEY=\n# HAI_AI_LLM_BASEURL= # Custom base URL (e.g. local proxy, Azure)\n# Optional compatibility fallback\n# OPENAI_API_KEY=`)\n }\n else {\n sections.push(`\n# =============================================================================\n# AI (@h-ai/ai)\n# =============================================================================\n# OpenAI-compatible provider\nHAI_AI_LLM_APIKEY=\n# HAI_AI_LLM_BASEURL= # Custom base URL\n# Optional compatibility fallback\n# OPENAI_API_KEY=`)\n }\n }\n\n // VecDB\n if (features.includes('vecdb')) {\n sections.push(`\n# =============================================================================\n# Vector Database (@h-ai/vecdb)\n# =============================================================================\n# Backend type: lancedb | pgvector | qdrant\nHAI_VECDB_TYPE=lancedb\n# LanceDB data path\nHAI_VECDB_PATH=./data/vecdb\n# Qdrant (uncomment when type=qdrant)\n# HAI_VECDB_URL=http://localhost:6333\n# HAI_VECDB_APIKEY=\n`)\n }\n\n // Reach\n if (features.includes('reach')) {\n sections.push(`\n# =============================================================================\n# Reach (@h-ai/reach)\n# =============================================================================\n# SMTP (uncomment when enabling email provider)\n# HAI_REACH_SMTP_HOST=smtp.example.com\n# HAI_REACH_SMTP_PORT=465\n# HAI_REACH_SMTP_USER=\n# HAI_REACH_SMTP_PASS=\n# HAI_REACH_SMTP_FROM=noreply@example.com\n`)\n }\n\n // Payment\n if (features.includes('payment')) {\n sections.push(`\n# =============================================================================\n# Payment (@h-ai/payment)\n# =============================================================================\n# WeChat Pay\n# HAI_PAYMENT_WECHAT_MCHID=\n# HAI_PAYMENT_WECHAT_APIV3KEY=\n# HAI_PAYMENT_WECHAT_SERIALNO=\n# HAI_PAYMENT_WECHAT_PRIVATEKEY=\n# HAI_PAYMENT_WECHAT_APPID=\n# Alipay\n# HAI_PAYMENT_ALIPAY_APPID=\n# HAI_PAYMENT_ALIPAY_PRIVATEKEY=\n# HAI_PAYMENT_ALIPAY_ALIPAYPUBLICKEY=\n# Stripe\n# HAI_PAYMENT_STRIPE_SECRETKEY=\n# HAI_PAYMENT_STRIPE_WEBHOOKSECRET=\n`)\n }\n\n // 测试(始终生成)\n sections.push(`\n# =============================================================================\n# Testing\n# =============================================================================\n# E2E test mode (relaxes rate limiting etc.)\n# HAI_E2E=1\n`)\n\n return sections.join('\\n')\n}\n\nfunction generateDeployConfig(): string {\n return `# =============================================================================\n# 部署配置 (@h-ai/deploy)\n# =============================================================================\n# 部署平台凭证通过 ~/.hai/credentials.yml 管理\n# 环境变量引用格式: \\${VAR_NAME:default_value}\n\n# 部署平台\nprovider:\n type: vercel\n token: \\${HAI_DEPLOY_VERCEL_TOKEN}\n\n# ---------------------------------------------------------------------------\n# 方式二:docker-ssh — 将应用容器化后通过 SSH 部署到任意 Linux 主机\n# 远程主机只需具备 SSH + docker/podman + compose,本地需 docker 或 podman\n# 切换时用下方 provider 替换上面的 vercel provider\n# ---------------------------------------------------------------------------\n# provider:\n# type: docker-ssh\n# ssh:\n# host: \\${HAI_DEPLOY_SSH_HOST}\n# port: 22\n# username: deploy\n# identityFile: \\${HAI_DEPLOY_SSH_KEY} # 私钥文件路径(省略则用 ssh-agent)\n# remote:\n# baseDir: /opt/hai/apps\n# runtime: auto # auto 优先 podman,其次 docker\n# expose:\n# type: port\n# containerPort: 3000\n# hostPort: 18080 # 访问地址 http://<host>:18080\n\n# 本地构建运行时(docker-ssh 使用;auto 优先 podman)\n# container:\n# runtime: auto\n\n# 基础设施服务(按需开启)\nservices:\n # PostgreSQL 数据库 (Neon)\n # db:\n # provisioner: neon\n # apiKey: \\${HAI_DEPLOY_NEON_API_KEY}\n\n # Redis 缓存 (Upstash)\n # cache:\n # provisioner: upstash\n # email: \\${HAI_DEPLOY_UPSTASH_EMAIL}\n # apiKey: \\${HAI_DEPLOY_UPSTASH_API_KEY}\n\n # S3 存储 (Cloudflare R2)\n # storage:\n # provisioner: cloudflare-r2\n # accountId: \\${HAI_DEPLOY_CF_ACCOUNT_ID}\n # apiToken: \\${HAI_DEPLOY_CF_API_TOKEN}\n # accessKeyId: \\${HAI_DEPLOY_R2_ACCESS_KEY_ID}\n # secretAccessKey: \\${HAI_DEPLOY_R2_SECRET_ACCESS_KEY}\n\n # 邮件 (Resend)\n # email:\n # provisioner: resend\n # apiKey: \\${HAI_DEPLOY_RESEND_API_KEY}\n # from: \\${HAI_DEPLOY_RESEND_FROM}\n\n # 短信 (阿里云)\n # sms:\n # provisioner: aliyun\n # accessKeyId: \\${HAI_DEPLOY_ALIYUN_ACCESS_KEY_ID}\n # accessKeySecret: \\${HAI_DEPLOY_ALIYUN_ACCESS_KEY_SECRET}\n # signName: \\${HAI_DEPLOY_ALIYUN_SIGN_NAME}\n\n# docker-ssh 说明:\n# - 应用镜像使用工程自带的 Dockerfile(adapter-node),本地构建后经 SSH 传输并 load\n# - compose 会按上方启用的 db/cache/storage 自动追加 postgres/redis/minio sidecar\n# - 若同时配置了对应云 Provisioner,则优先使用云资源,不再自建 sidecar\n`\n}\n\nfunction generateVecdbConfig(): string {\n return `# =============================================================================\n# 向量数据库配置 (@h-ai/vecdb)\n# =============================================================================\n\n# 数据库类型: lancedb | pgvector | qdrant\ntype: lancedb\n\n# LanceDB 数据目录\npath: ./data/vecdb\n\n# 距离度量: cosine | euclidean | dot\n# metric: cosine\n\n# pgvector 配置(当 type 为 pgvector 时使用)\n# type: pgvector\n# host: localhost\n# port: 5432\n# database: hai\n# user: postgres\n# password: ''\n# indexType: hnsw\n# tablePrefix: vec_\n\n# Qdrant 配置(当 type 为 qdrant 时使用)\n# type: qdrant\n# url: http://localhost:6333\n# apiKey: ''\n`\n}\n\nfunction generateReachConfig(): string {\n return `# =============================================================================\n# 消息推送配置 (@h-ai/reach)\n# =============================================================================\n\nproviders:\n # 控制台输出(开发/测试用)\n - name: console_dev\n type: console\n\n # SMTP 邮件(按需开启)\n # - name: email\n # type: smtp\n # host: \\${HAI_REACH_SMTP_HOST:smtp.example.com}\n # port: \\${HAI_REACH_SMTP_PORT:465}\n # secure: true\n # user: \\${HAI_REACH_SMTP_USER:}\n # pass: \\${HAI_REACH_SMTP_PASS:}\n # from: \\${HAI_REACH_SMTP_FROM:noreply@example.com}\n\n # 阿里云短信(按需开启)\n # - name: sms\n # type: aliyun-sms\n # accessKeyId: \\${HAI_REACH_SMS_ACCESS_KEY}\n # accessKeySecret: \\${HAI_REACH_SMS_SECRET_KEY}\n # signName: MyApp\n\n# IAM 标准模板:保留空数组以支持 HAI_REACH_TEMPLATES 整体覆盖。\ntemplates: []\n# 开启对应 Provider 后,将空数组替换为需要的模板列表,例如:\n# templates:\n# - name: otp_email\n# provider: email\n# subject: \"Verification code\"\n# body: \"Your verification code is {code}.\"\n# - name: otp_sms\n# provider: sms\n# body: \"Your verification code is {code}.\"\n# - name: password_reset\n# provider: email\n# subject: \"Password reset\"\n# body: \"Reset your password: {resetUrl}. Expires at {expiresAt}.\"\n# - name: password_reset_sms\n# provider: sms\n# body: \"Reset your password: {resetUrl}. Expires at {expiresAt}.\"\n\n# 免打扰(可选)\n# dnd:\n# enabled: true\n# strategy: delay\n# start: \"22:00\"\n# end: \"08:00\"\n`\n}\n\nfunction generateSchedulerConfig(): string {\n return `# =============================================================================\n# 任务调度配置 (@h-ai/scheduler)\n# =============================================================================\n\n# 是否启用数据库日志(需要 @h-ai/reldb)\nenableDb: true\n\n# 执行日志表名\ntableName: hai_scheduler_logs\n\n# 任务定义表名\ntaskTableName: hai_scheduler_tasks\n\n# 分布式锁表名\nlockTableName: hai_scheduler_locks\n\n# 检查间隔(毫秒)\ntickInterval: 1000\n\n# 锁过期时间(毫秒)\nlockExpireMs: 300000\n`\n}\n\nfunction generateAuditConfig(): string {\n return `# =============================================================================\n# 审计日志配置 (@h-ai/audit)\n# =============================================================================\n\n# 用户表名(用于 JOIN 查询)\nuserTable: hai_iam_users\n\n# 用户表主键列名\nuserIdColumn: id\n\n# 用户名列名\nuserNameColumn: username\n`\n}\n\nfunction generatePaymentConfig(): string {\n return `# =============================================================================\n# 支付配置 (@h-ai/payment)\n# =============================================================================\n\n# 微信支付(按需开启)\n# wechat:\n# mchId: ''\n# apiV3Key: ''\n# serialNo: ''\n# privateKey: ''\n# appId: ''\n\n# 支付宝(按需开启)\n# alipay:\n# appId: ''\n# privateKey: ''\n# alipayPublicKey: ''\n# signType: RSA2\n# sandbox: false\n\n# Stripe(按需开启)\n# stripe:\n# secretKey: ''\n# webhookSecret: ''\n`\n}\n"]}
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ export { generateConfigFile, generateEnvExample } from './chunk-P6X63D3I.js';
3
+ import './chunk-2H7UOFLK.js';
4
+ //# sourceMappingURL=cli-config-templates-EFABFSCY.js.map
5
+ //# sourceMappingURL=cli-config-templates-EFABFSCY.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"cli-config-templates-6XA7V6CC.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"cli-config-templates-EFABFSCY.js"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { generateConfigFile } from './chunk-WUSFJFW5.js';
2
+ import { generateConfigFile } from './chunk-P6X63D3I.js';
3
3
  import { cliM } from './chunk-WWG3U5ZD.js';
4
4
  import './chunk-2H7UOFLK.js';
5
5
  import process4 from 'process';
@@ -289,6 +289,7 @@ var FULLSTACK_SERV_CATALOG_PACKAGE_NAMES = [
289
289
  "@h-ai/core",
290
290
  "@h-ai/crypto",
291
291
  "@h-ai/iam",
292
+ "@h-ai/reach",
292
293
  "@h-ai/reldb",
293
294
  "@h-ai/serv",
294
295
  "@h-ai/storage",
@@ -296,6 +297,7 @@ var FULLSTACK_SERV_CATALOG_PACKAGE_NAMES = [
296
297
  ];
297
298
  var FULLSTACK_SHARED_CATALOG_PACKAGE_NAMES = [
298
299
  "@h-ai/api-client",
300
+ "@h-ai/api-contract",
299
301
  "@h-ai/core",
300
302
  "@h-ai/crypto",
301
303
  "@h-ai/ui",
@@ -415,7 +417,7 @@ function buildApiWorkspaceCatalogPackages(featureMap) {
415
417
  function buildAppHaiCatalogPackages(options) {
416
418
  const packageNames = [];
417
419
  if (options.isSvelteOnlyApp) {
418
- packageNames.push("@h-ai/api-client", "@h-ai/capacitor", "@h-ai/ui");
420
+ packageNames.push("@h-ai/api-client", "@h-ai/api-contract", "@h-ai/capacitor", "@h-ai/ui");
419
421
  return pickCatalogPackages(packageNames, HAI_CATALOG_PACKAGES);
420
422
  }
421
423
  packageNames.push("@h-ai/core", "@h-ai/kit");
@@ -484,7 +486,7 @@ var FEATURE_ROUTE_DIRS = {
484
486
  audit: ["routes"]
485
487
  };
486
488
  var FEATURE_APP_ROUTE_DIRS = {
487
- iam: ["admin", "h5"]
489
+ iam: ["admin", "h5", "website"]
488
490
  };
489
491
  var FEATURE_ID_REGEX = /^[a-z0-9-]+$/;
490
492
  var HBS_SUFFIX_REGEX = /\.hbs$/;
@@ -1115,7 +1117,7 @@ async function createProject(options) {
1115
1117
  });
1116
1118
  await generateFromTemplates(projectPath, context);
1117
1119
  {
1118
- const { generateConfigFile: generateConfigFile2, generateEnvExample } = await import('./cli-config-templates-6XA7V6CC.js');
1120
+ const { generateConfigFile: generateConfigFile2, generateEnvExample } = await import('./cli-config-templates-EFABFSCY.js');
1119
1121
  const configs = resolvedOptions.moduleConfigs;
1120
1122
  const isApiWorkspace = resolvedOptions.appType === "api";
1121
1123
  const isFullstack = resolvedOptions.appType === "fullstack";