@h-ai/cli 0.1.0-alpha.43 → 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.
@@ -45,8 +45,8 @@ function generateCoreConfig(cfg) {
45
45
 
46
46
  name: ${name}
47
47
  version: 0.1.0
48
- env: \${HAI_ENV:development}
49
- debug: \${HAI_DEBUG:false}
48
+ env: development
49
+ debug: false
50
50
 
51
51
  defaultLocale: ${locale}
52
52
  supportedLocales:
@@ -87,13 +87,13 @@ function generateDbConfig(cfg) {
87
87
  type: sqlite
88
88
 
89
89
  # SQLite \u6570\u636E\u5E93\u8DEF\u5F84
90
- database: \${HAI_RELDB_DATABASE:${database}}
90
+ database: ${database}
91
91
 
92
92
  # PostgreSQL/MySQL \u914D\u7F6E\uFF08\u53EF\u9009\uFF09
93
- # host: \${HAI_RELDB_HOST:localhost}
94
- # port: \${HAI_RELDB_PORT:5432}
95
- # user: \${HAI_RELDB_USER:postgres}
96
- # password: \${HAI_RELDB_PASSWORD:}
93
+ # host: localhost
94
+ # port: 5432
95
+ # user: postgres
96
+ # password: ''
97
97
  `;
98
98
  }
99
99
  const user = dbType === "postgresql" ? "postgres" : "root";
@@ -105,13 +105,13 @@ database: \${HAI_RELDB_DATABASE:${database}}
105
105
  type: ${dbType}
106
106
 
107
107
  # \u6570\u636E\u5E93\u540D\u79F0
108
- database: \${HAI_RELDB_DATABASE:${database}}
108
+ database: ${database}
109
109
 
110
110
  # \u8FDE\u63A5\u914D\u7F6E
111
- host: \${HAI_RELDB_HOST:${host}}
112
- port: \${HAI_RELDB_PORT:${port}}
113
- user: \${HAI_RELDB_USER:${user}}
114
- password: \${HAI_RELDB_PASSWORD:}
111
+ host: ${host}
112
+ port: ${port}
113
+ user: ${user}
114
+ password: ''
115
115
  `;
116
116
  }
117
117
  function generateCacheConfig(cfg) {
@@ -125,11 +125,11 @@ function generateCacheConfig(cfg) {
125
125
  type: memory
126
126
 
127
127
  # Redis \u914D\u7F6E\uFF08\u5F53 type \u4E3A redis \u65F6\u4F7F\u7528\uFF09
128
- # url: \${HAI_CACHE_REDIS_URL:redis://localhost:6379/0}
129
- # host: \${HAI_CACHE_REDIS_HOST:localhost}
130
- # port: \${HAI_CACHE_REDIS_PORT:6379}
131
- # password: \${HAI_CACHE_REDIS_PASSWORD:}
132
- # keyPrefix: \${HAI_CACHE_KEY_PREFIX:hai:}
128
+ # url: redis://localhost:6379/0
129
+ # host: localhost
130
+ # port: 6379
131
+ # password: ''
132
+ # keyPrefix: 'hai:'
133
133
  `;
134
134
  }
135
135
  const host = cfg?.host ?? "localhost";
@@ -142,10 +142,10 @@ type: memory
142
142
  type: redis
143
143
 
144
144
  # Redis \u914D\u7F6E
145
- host: \${HAI_CACHE_REDIS_HOST:${host}}
146
- port: \${HAI_CACHE_REDIS_PORT:${port}}
147
- password: \${HAI_CACHE_REDIS_PASSWORD:}
148
- keyPrefix: \${HAI_CACHE_KEY_PREFIX:hai:}
145
+ host: ${host}
146
+ port: ${port}
147
+ password: ''
148
+ keyPrefix: 'hai:'
149
149
  `;
150
150
  }
151
151
  function generateIamConfig(cfg) {
@@ -200,18 +200,18 @@ defaultProvider: local
200
200
  providers:
201
201
  local:
202
202
  type: local
203
- root: \${HAI_STORAGE_PATH:${localPath}}
203
+ root: ${localPath}
204
204
  maxFileSize: 10485760 # 10MB
205
205
 
206
206
  # S3 \u914D\u7F6E\uFF08\u53EF\u9009\uFF09
207
207
  # s3:
208
208
  # type: s3
209
- # bucket: \${HAI_STORAGE_S3_BUCKET}
210
- # region: \${HAI_STORAGE_S3_REGION:us-east-1}
211
- # accessKeyId: \${HAI_STORAGE_S3_ACCESS_KEY}
212
- # secretAccessKey: \${HAI_STORAGE_S3_SECRET_KEY}
213
- # endpoint: \${HAI_STORAGE_S3_ENDPOINT}
214
- # forcePathStyle: \${HAI_STORAGE_S3_FORCE_PATH_STYLE:false}
209
+ # bucket: my-bucket
210
+ # region: us-east-1
211
+ # accessKeyId: ''
212
+ # secretAccessKey: ''
213
+ # endpoint: ''
214
+ # forcePathStyle: false
215
215
  `;
216
216
  }
217
217
  return `# =============================================================================
@@ -225,17 +225,17 @@ defaultProvider: s3
225
225
  providers:
226
226
  s3:
227
227
  type: s3
228
- bucket: \${HAI_STORAGE_S3_BUCKET}
229
- region: \${HAI_STORAGE_S3_REGION:us-east-1}
230
- accessKeyId: \${HAI_STORAGE_S3_ACCESS_KEY}
231
- secretAccessKey: \${HAI_STORAGE_S3_SECRET_KEY}
232
- # endpoint: \${HAI_STORAGE_S3_ENDPOINT}
233
- # forcePathStyle: \${HAI_STORAGE_S3_FORCE_PATH_STYLE:false}
228
+ bucket: ''
229
+ region: us-east-1
230
+ accessKeyId: ''
231
+ secretAccessKey: ''
232
+ # endpoint: ''
233
+ # forcePathStyle: false
234
234
 
235
235
  # \u672C\u5730\u5B58\u50A8\uFF08\u53EF\u9009\uFF09
236
236
  # local:
237
237
  # type: local
238
- # root: \${HAI_STORAGE_PATH:./data/uploads}
238
+ # root: ./data/uploads
239
239
  # maxFileSize: 10485760 # 10MB
240
240
  `;
241
241
  }
@@ -247,10 +247,10 @@ function generateAiConfig(cfg) {
247
247
 
248
248
  # LLM \u914D\u7F6E\uFF08\u5FC5\u586B\uFF09
249
249
  llm:
250
- # API Key\uFF08\u7559\u7A7A\u65F6\u81EA\u52A8\u8BFB\u53D6 HAI_AI_LLM_API_KEY / OPENAI_API_KEY \u73AF\u5883\u53D8\u91CF\uFF09
251
- apiKey: \${HAI_AI_LLM_API_KEY:}
252
- # Base URL\uFF08\u7559\u7A7A\u65F6\u81EA\u52A8\u8BFB\u53D6 HAI_AI_LLM_BASE_URL / OPENAI_BASE_URL\uFF0C\u9ED8\u8BA4 https://api.openai.com/v1\uFF09
253
- # baseUrl: \${HAI_AI_LLM_BASE_URL:}
250
+ # API Key\uFF08\u7EA6\u5B9A\u73AF\u5883\u53D8\u91CF HAI_AI_LLM_APIKEY \u4F18\u5148\uFF09
251
+ apiKey: ''
252
+ # Base URL\uFF08\u7EA6\u5B9A\u73AF\u5883\u53D8\u91CF HAI_AI_LLM_BASEURL \u4F18\u5148\uFF09
253
+ # baseUrl: https://api.openai.com/v1
254
254
  # \u9ED8\u8BA4\u6A21\u578B
255
255
  model: ${model}
256
256
  # \u5168\u5C40\u6700\u5927 Token \u6570\uFF08\u9ED8\u8BA4 4096\uFF09
@@ -266,7 +266,7 @@ llm:
266
266
  # model: gpt-4o-mini
267
267
  # - id: smart
268
268
  # model: gpt-4o
269
- # apiKey: \${HAI_AI_LLM_API_KEY:}
269
+ # apiKey: ''
270
270
 
271
271
  # \u573A\u666F\u6A21\u578B\u6620\u5C04\uFF08\u53EF\u9009\uFF09
272
272
  # scenarios:
@@ -281,18 +281,18 @@ function generateEnvExample(features, configs) {
281
281
  # =============================================================================
282
282
  #
283
283
  # Copy this file to .env and fill in actual values.
284
- # Config files in config/ reference these variables via \${VAR_NAME:default} syntax.
284
+ # Config files use literal defaults; matching HAI variables override YAML leaves.
285
285
  #
286
- # Naming convention: HAI_<MODULE>_<SETTING>
286
+ # Naming convention: HAI_<config name>_<YAML path>
287
287
  # =============================================================================`);
288
288
  sections.push(`
289
289
  # =============================================================================
290
290
  # Application
291
291
  # =============================================================================
292
292
  # Environment: development | production | test
293
- HAI_ENV=development
293
+ HAI_CORE_ENV=development
294
294
  # Enable debug mode
295
- HAI_DEBUG=false`);
295
+ HAI_CORE_DEBUG=false`);
296
296
  if (features.includes("db")) {
297
297
  const dbType = configs?.db?.type ?? "sqlite";
298
298
  const dbDatabase = configs?.db?.database ?? (dbType === "sqlite" ? "./data/app.db" : "hai");
@@ -302,30 +302,28 @@ HAI_DEBUG=false`);
302
302
  # Database (@h-ai/reldb)
303
303
  # =============================================================================
304
304
  # Database type: sqlite | postgresql | mysql
305
- HAI_RELDB_TYPE=${dbType}
305
+ HAI_DB_TYPE=${dbType}
306
306
  # SQLite: file path; PostgreSQL/MySQL: database name
307
- HAI_RELDB_DATABASE=${dbDatabase}${isSqlite ? `
307
+ HAI_DB_DATABASE=${dbDatabase}${isSqlite ? `
308
308
  # PostgreSQL/MySQL connection (uncomment when not using sqlite)
309
- # HAI_RELDB_HOST=localhost
310
- # HAI_RELDB_PORT=5432
311
- # HAI_RELDB_USER=postgres
312
- # HAI_RELDB_PASSWORD=` : `
309
+ # HAI_DB_HOST=localhost
310
+ # HAI_DB_PORT=5432
311
+ # HAI_DB_USER=postgres
312
+ # HAI_DB_PASSWORD=` : `
313
313
  # Connection
314
- HAI_RELDB_HOST=${configs?.db?.host ?? "localhost"}
315
- HAI_RELDB_PORT=${configs?.db?.port ?? (dbType === "postgresql" ? 5432 : 3306)}
316
- HAI_RELDB_USER=${dbType === "postgresql" ? "postgres" : "root"}
317
- HAI_RELDB_PASSWORD=`}`);
314
+ HAI_DB_HOST=${configs?.db?.host ?? "localhost"}
315
+ HAI_DB_PORT=${configs?.db?.port ?? (dbType === "postgresql" ? 5432 : 3306)}
316
+ HAI_DB_USER=${dbType === "postgresql" ? "postgres" : "root"}
317
+ HAI_DB_PASSWORD=`}`);
318
318
  }
319
319
  if (features.includes("iam")) {
320
320
  sections.push(`
321
321
  # =============================================================================
322
322
  # IAM (@h-ai/iam)
323
323
  # =============================================================================
324
- HAI_IAM_SESSION_SECRET=change-me-to-a-strong-random-string-min-32-chars
325
- # HAI_IAM_PASSWORD_MIN_LENGTH=8
326
- # HAI_IAM_SESSION_MAX_AGE=86400
327
- # HAI_IAM_REFRESH_TOKEN_MAX_AGE=604800
328
- # HAI_IAM_MAX_LOGIN_ATTEMPTS=5
324
+ # HAI_IAM_PASSWORD_MINLENGTH=8
325
+ # HAI_IAM_SESSION_MAXAGE=86400
326
+ # HAI_IAM_SESSION_REFRESHTOKENMAXAGE=604800
329
327
  # HAI_KIT_COOKIE_KEY= # 32-char hex for SM4-CBC cookie encryption
330
328
  `);
331
329
  }
@@ -339,11 +337,11 @@ HAI_IAM_SESSION_SECRET=change-me-to-a-strong-random-string-min-32-chars
339
337
  # Cache type: memory | redis
340
338
  HAI_CACHE_TYPE=redis
341
339
  # Redis connection
342
- HAI_CACHE_REDIS_HOST=${configs?.cache?.host ?? "localhost"}
343
- HAI_CACHE_REDIS_PORT=${configs?.cache?.port ?? 6379}
344
- HAI_CACHE_REDIS_PASSWORD=
345
- # HAI_CACHE_REDIS_URL=redis://localhost:6379/0
346
- # HAI_CACHE_REDIS_DB=0
340
+ HAI_CACHE_HOST=${configs?.cache?.host ?? "localhost"}
341
+ HAI_CACHE_PORT=${configs?.cache?.port ?? 6379}
342
+ HAI_CACHE_PASSWORD=
343
+ # HAI_CACHE_URL=redis://localhost:6379/0
344
+ # HAI_CACHE_DB=0
347
345
  # HAI_CACHE_CONNECT_TIMEOUT=10000
348
346
  # HAI_CACHE_COMMAND_TIMEOUT=5000
349
347
  # HAI_CACHE_KEY_PREFIX=hai:`);
@@ -355,11 +353,11 @@ HAI_CACHE_REDIS_PASSWORD=
355
353
  # Cache type: memory | redis
356
354
  HAI_CACHE_TYPE=memory
357
355
  # Redis connection (uncomment when type=redis)
358
- # HAI_CACHE_REDIS_URL=redis://localhost:6379/0
359
- # HAI_CACHE_REDIS_HOST=localhost
360
- # HAI_CACHE_REDIS_PORT=6379
361
- # HAI_CACHE_REDIS_PASSWORD=
362
- # HAI_CACHE_REDIS_DB=0
356
+ # HAI_CACHE_URL=redis://localhost:6379/0
357
+ # HAI_CACHE_HOST=localhost
358
+ # HAI_CACHE_PORT=6379
359
+ # HAI_CACHE_PASSWORD=
360
+ # HAI_CACHE_DB=0
363
361
  # HAI_CACHE_CONNECT_TIMEOUT=10000
364
362
  # HAI_CACHE_COMMAND_TIMEOUT=5000
365
363
  # HAI_CACHE_KEY_PREFIX=hai:`);
@@ -372,33 +370,33 @@ HAI_CACHE_TYPE=memory
372
370
  # =============================================================================
373
371
  # Storage (@h-ai/storage)
374
372
  # =============================================================================
375
- # Storage type: local | s3
376
- HAI_STORAGE_TYPE=s3
373
+ # Default storage provider: local | s3
374
+ HAI_STORAGE_DEFAULTPROVIDER=s3
377
375
  # S3 / S3-compatible
378
- HAI_STORAGE_S3_BUCKET=
379
- HAI_STORAGE_S3_REGION=us-east-1
380
- HAI_STORAGE_S3_ACCESS_KEY=
381
- HAI_STORAGE_S3_SECRET_KEY=
382
- # HAI_STORAGE_S3_ENDPOINT= # Custom endpoint for MinIO / Aliyun OSS etc.
383
- # HAI_STORAGE_S3_FORCE_PATH_STYLE=false
376
+ HAI_STORAGE_PROVIDERS_S3_BUCKET=
377
+ HAI_STORAGE_PROVIDERS_S3_REGION=us-east-1
378
+ HAI_STORAGE_PROVIDERS_S3_ACCESSKEYID=
379
+ HAI_STORAGE_PROVIDERS_S3_SECRETACCESSKEY=
380
+ # HAI_STORAGE_PROVIDERS_S3_ENDPOINT= # Custom endpoint for MinIO / Aliyun OSS etc.
381
+ # HAI_STORAGE_PROVIDERS_S3_FORCEPATHSTYLE=false
384
382
  # Local storage (uncomment when type=local)
385
- # HAI_STORAGE_PATH=./data/uploads`);
383
+ # HAI_STORAGE_PROVIDERS_LOCAL_ROOT=./data/uploads`);
386
384
  } else {
387
385
  sections.push(`
388
386
  # =============================================================================
389
387
  # Storage (@h-ai/storage)
390
388
  # =============================================================================
391
- # Storage type: local | s3
392
- HAI_STORAGE_TYPE=local
389
+ # Default storage provider: local | s3
390
+ HAI_STORAGE_DEFAULTPROVIDER=local
393
391
  # Local storage root path
394
- HAI_STORAGE_PATH=${configs?.storage?.localPath ?? "./data/uploads"}
392
+ HAI_STORAGE_PROVIDERS_LOCAL_ROOT=${configs?.storage?.localPath ?? "./data/uploads"}
395
393
  # S3 / S3-compatible (uncomment when type=s3)
396
- # HAI_STORAGE_S3_BUCKET=
397
- # HAI_STORAGE_S3_REGION=us-east-1
398
- # HAI_STORAGE_S3_ACCESS_KEY=
399
- # HAI_STORAGE_S3_SECRET_KEY=
400
- # HAI_STORAGE_S3_ENDPOINT= # Custom endpoint for MinIO / Aliyun OSS etc.
401
- # HAI_STORAGE_S3_FORCE_PATH_STYLE=false`);
394
+ # HAI_STORAGE_PROVIDERS_S3_BUCKET=
395
+ # HAI_STORAGE_PROVIDERS_S3_REGION=us-east-1
396
+ # HAI_STORAGE_PROVIDERS_S3_ACCESSKEYID=
397
+ # HAI_STORAGE_PROVIDERS_S3_SECRETACCESSKEY=
398
+ # HAI_STORAGE_PROVIDERS_S3_ENDPOINT= # Custom endpoint for MinIO / Aliyun OSS etc.
399
+ # HAI_STORAGE_PROVIDERS_S3_FORCEPATHSTYLE=false`);
402
400
  }
403
401
  }
404
402
  if (features.includes("ai")) {
@@ -409,8 +407,8 @@ HAI_STORAGE_PATH=${configs?.storage?.localPath ?? "./data/uploads"}
409
407
  # AI (@h-ai/ai)
410
408
  # =============================================================================
411
409
  # OpenAI-compatible API Key (Anthropic models via OpenAI-compatible proxy)
412
- HAI_AI_LLM_API_KEY=
413
- # HAI_AI_LLM_BASE_URL= # Custom base URL
410
+ HAI_AI_LLM_APIKEY=
411
+ # HAI_AI_LLM_BASEURL= # Custom base URL
414
412
  # Optional compatibility fallback
415
413
  # OPENAI_API_KEY=`);
416
414
  } else if (provider === "openai") {
@@ -419,8 +417,8 @@ HAI_AI_LLM_API_KEY=
419
417
  # AI (@h-ai/ai)
420
418
  # =============================================================================
421
419
  # OpenAI / OpenAI-compatible
422
- HAI_AI_LLM_API_KEY=
423
- # HAI_AI_LLM_BASE_URL= # Custom base URL (e.g. local proxy, Azure)
420
+ HAI_AI_LLM_APIKEY=
421
+ # HAI_AI_LLM_BASEURL= # Custom base URL (e.g. local proxy, Azure)
424
422
  # Optional compatibility fallback
425
423
  # OPENAI_API_KEY=`);
426
424
  } else {
@@ -429,8 +427,8 @@ HAI_AI_LLM_API_KEY=
429
427
  # AI (@h-ai/ai)
430
428
  # =============================================================================
431
429
  # OpenAI-compatible provider
432
- HAI_AI_LLM_API_KEY=
433
- # HAI_AI_LLM_BASE_URL= # Custom base URL
430
+ HAI_AI_LLM_APIKEY=
431
+ # HAI_AI_LLM_BASEURL= # Custom base URL
434
432
  # Optional compatibility fallback
435
433
  # OPENAI_API_KEY=`);
436
434
  }
@@ -445,8 +443,8 @@ HAI_VECDB_TYPE=lancedb
445
443
  # LanceDB data path
446
444
  HAI_VECDB_PATH=./data/vecdb
447
445
  # Qdrant (uncomment when type=qdrant)
448
- # HAI_VECDB_QDRANT_URL=http://localhost:6333
449
- # HAI_VECDB_QDRANT_API_KEY=
446
+ # HAI_VECDB_URL=http://localhost:6333
447
+ # HAI_VECDB_APIKEY=
450
448
  `);
451
449
  }
452
450
  if (features.includes("reach")) {
@@ -468,18 +466,18 @@ HAI_VECDB_PATH=./data/vecdb
468
466
  # Payment (@h-ai/payment)
469
467
  # =============================================================================
470
468
  # WeChat Pay
471
- # HAI_PAYMENT_WECHAT_MCH_ID=
472
- # HAI_PAYMENT_WECHAT_API_V3_KEY=
473
- # HAI_PAYMENT_WECHAT_SERIAL_NO=
474
- # HAI_PAYMENT_WECHAT_PRIVATE_KEY=
475
- # HAI_PAYMENT_WECHAT_APP_ID=
469
+ # HAI_PAYMENT_WECHAT_MCHID=
470
+ # HAI_PAYMENT_WECHAT_APIV3KEY=
471
+ # HAI_PAYMENT_WECHAT_SERIALNO=
472
+ # HAI_PAYMENT_WECHAT_PRIVATEKEY=
473
+ # HAI_PAYMENT_WECHAT_APPID=
476
474
  # Alipay
477
- # HAI_PAYMENT_ALIPAY_APP_ID=
478
- # HAI_PAYMENT_ALIPAY_PRIVATE_KEY=
479
- # HAI_PAYMENT_ALIPAY_PUBLIC_KEY=
475
+ # HAI_PAYMENT_ALIPAY_APPID=
476
+ # HAI_PAYMENT_ALIPAY_PRIVATEKEY=
477
+ # HAI_PAYMENT_ALIPAY_ALIPAYPUBLICKEY=
480
478
  # Stripe
481
- # HAI_PAYMENT_STRIPE_SECRET_KEY=
482
- # HAI_PAYMENT_STRIPE_WEBHOOK_SECRET=
479
+ # HAI_PAYMENT_STRIPE_SECRETKEY=
480
+ # HAI_PAYMENT_STRIPE_WEBHOOKSECRET=
483
481
  `);
484
482
  }
485
483
  sections.push(`
@@ -543,25 +541,25 @@ function generateVecdbConfig() {
543
541
  type: lancedb
544
542
 
545
543
  # LanceDB \u6570\u636E\u76EE\u5F55
546
- path: \${HAI_VECDB_PATH:./data/vecdb}
544
+ path: ./data/vecdb
547
545
 
548
546
  # \u8DDD\u79BB\u5EA6\u91CF: cosine | euclidean | dot
549
547
  # metric: cosine
550
548
 
551
549
  # pgvector \u914D\u7F6E\uFF08\u5F53 type \u4E3A pgvector \u65F6\u4F7F\u7528\uFF09
552
550
  # type: pgvector
553
- # host: \${HAI_RELDB_HOST:localhost}
554
- # port: \${HAI_RELDB_PORT:5432}
555
- # database: \${HAI_RELDB_DATABASE:hai}
556
- # user: \${HAI_RELDB_USER:postgres}
557
- # password: \${HAI_RELDB_PASSWORD:}
551
+ # host: localhost
552
+ # port: 5432
553
+ # database: hai
554
+ # user: postgres
555
+ # password: ''
558
556
  # indexType: hnsw
559
557
  # tablePrefix: vec_
560
558
 
561
559
  # Qdrant \u914D\u7F6E\uFF08\u5F53 type \u4E3A qdrant \u65F6\u4F7F\u7528\uFF09
562
560
  # type: qdrant
563
- # url: \${HAI_VECDB_QDRANT_URL:http://localhost:6333}
564
- # apiKey: \${HAI_VECDB_QDRANT_API_KEY:}
561
+ # url: http://localhost:6333
562
+ # apiKey: ''
565
563
  `;
566
564
  }
567
565
  function generateReachConfig() {
@@ -655,27 +653,27 @@ function generatePaymentConfig() {
655
653
 
656
654
  # \u5FAE\u4FE1\u652F\u4ED8\uFF08\u6309\u9700\u5F00\u542F\uFF09
657
655
  # wechat:
658
- # mchId: \${HAI_PAYMENT_WECHAT_MCH_ID}
659
- # apiV3Key: \${HAI_PAYMENT_WECHAT_API_V3_KEY}
660
- # serialNo: \${HAI_PAYMENT_WECHAT_SERIAL_NO}
661
- # privateKey: \${HAI_PAYMENT_WECHAT_PRIVATE_KEY}
662
- # appId: \${HAI_PAYMENT_WECHAT_APP_ID}
656
+ # mchId: ''
657
+ # apiV3Key: ''
658
+ # serialNo: ''
659
+ # privateKey: ''
660
+ # appId: ''
663
661
 
664
662
  # \u652F\u4ED8\u5B9D\uFF08\u6309\u9700\u5F00\u542F\uFF09
665
663
  # alipay:
666
- # appId: \${HAI_PAYMENT_ALIPAY_APP_ID}
667
- # privateKey: \${HAI_PAYMENT_ALIPAY_PRIVATE_KEY}
668
- # alipayPublicKey: \${HAI_PAYMENT_ALIPAY_PUBLIC_KEY}
664
+ # appId: ''
665
+ # privateKey: ''
666
+ # alipayPublicKey: ''
669
667
  # signType: RSA2
670
668
  # sandbox: false
671
669
 
672
670
  # Stripe\uFF08\u6309\u9700\u5F00\u542F\uFF09
673
671
  # stripe:
674
- # secretKey: \${HAI_PAYMENT_STRIPE_SECRET_KEY}
675
- # webhookSecret: \${HAI_PAYMENT_STRIPE_WEBHOOK_SECRET}
672
+ # secretKey: ''
673
+ # webhookSecret: ''
676
674
  `;
677
675
  }
678
676
 
679
677
  export { generateConfigFile, generateEnvExample };
680
- //# sourceMappingURL=chunk-CFCXOKGV.js.map
681
- //# sourceMappingURL=chunk-CFCXOKGV.js.map
678
+ //# sourceMappingURL=chunk-U4PA632G.js.map
679
+ //# sourceMappingURL=chunk-U4PA632G.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/cli-config-templates.ts"],"names":[],"mappings":"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","file":"chunk-U4PA632G.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'\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\nname: ${name}\nversion: 0.1.0\nenv: development\ndebug: false\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# 密码策略\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 const storageType = cfg?.type ?? 'local'\n\n if (storageType === 'local') {\n const localPath = cfg?.localPath ?? './data/uploads'\n return `# =============================================================================\n# 存储配置\n# =============================================================================\n\n# 默认 Provider\ndefaultProvider: local\n\n# Provider 配置\nproviders:\n local:\n type: local\n root: ${localPath}\n maxFileSize: 10485760 # 10MB\n\n # S3 配置(可选)\n # s3:\n # type: s3\n # bucket: my-bucket\n # region: us-east-1\n # accessKeyId: ''\n # secretAccessKey: ''\n # endpoint: ''\n # forcePathStyle: false\n`\n }\n\n return `# =============================================================================\n# 存储配置\n# =============================================================================\n\n# 默认 Provider\ndefaultProvider: s3\n\n# Provider 配置\nproviders:\n s3:\n type: s3\n bucket: ''\n region: us-east-1\n accessKeyId: ''\n secretAccessKey: ''\n # endpoint: ''\n # forcePathStyle: false\n\n # 本地存储(可选)\n # local:\n # type: local\n # root: ./data/uploads\n # maxFileSize: 10485760 # 10MB\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_DEFAULTPROVIDER=s3\n# S3 / S3-compatible\nHAI_STORAGE_PROVIDERS_S3_BUCKET=\nHAI_STORAGE_PROVIDERS_S3_REGION=us-east-1\nHAI_STORAGE_PROVIDERS_S3_ACCESSKEYID=\nHAI_STORAGE_PROVIDERS_S3_SECRETACCESSKEY=\n# HAI_STORAGE_PROVIDERS_S3_ENDPOINT= # Custom endpoint for MinIO / Aliyun OSS etc.\n# HAI_STORAGE_PROVIDERS_S3_FORCEPATHSTYLE=false\n# Local storage (uncomment when type=local)\n# HAI_STORAGE_PROVIDERS_LOCAL_ROOT=./data/uploads`)\n }\n else {\n sections.push(`\n# =============================================================================\n# Storage (@h-ai/storage)\n# =============================================================================\n# Default storage provider: local | s3\nHAI_STORAGE_DEFAULTPROVIDER=local\n# Local storage root path\nHAI_STORAGE_PROVIDERS_LOCAL_ROOT=${configs?.storage?.localPath ?? './data/uploads'}\n# S3 / S3-compatible (uncomment when type=s3)\n# HAI_STORAGE_PROVIDERS_S3_BUCKET=\n# HAI_STORAGE_PROVIDERS_S3_REGION=us-east-1\n# HAI_STORAGE_PROVIDERS_S3_ACCESSKEYID=\n# HAI_STORAGE_PROVIDERS_S3_SECRETACCESSKEY=\n# HAI_STORAGE_PROVIDERS_S3_ENDPOINT= # Custom endpoint for MinIO / Aliyun OSS etc.\n# HAI_STORAGE_PROVIDERS_S3_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# 基础设施服务(按需开启)\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\n # 邮件 (Resend)\n # email:\n # provisioner: resend\n # apiKey: \\${HAI_DEPLOY_RESEND_API_KEY}\n\n # 短信 (阿里云)\n # sms:\n # provisioner: aliyun\n # accessKeyId: \\${HAI_DEPLOY_ALIYUN_ACCESS_KEY_ID}\n # accessKeySecret: \\${HAI_DEPLOY_ALIYUN_ACCESS_KEY_SECRET}\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# 模板(可选)\n# templates:\n# - name: verification_code\n# provider: email\n# subject: \"验证码: {code}\"\n# body: \"您的验证码是 {code},有效期 {minutes} 分钟。\"\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# 审计日志表名\ntableName: hai_audit_logs\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-U4PA632G.js';
3
+ import './chunk-2H7UOFLK.js';
4
+ //# sourceMappingURL=cli-config-templates-GSXKLGU5.js.map
5
+ //# sourceMappingURL=cli-config-templates-GSXKLGU5.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"cli-config-templates-5J5VKWWD.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"cli-config-templates-GSXKLGU5.js"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { generateConfigFile } from './chunk-CFCXOKGV.js';
2
+ import { generateConfigFile } from './chunk-U4PA632G.js';
3
3
  import './chunk-WUYLYCW2.js';
4
4
  import './chunk-2H7UOFLK.js';
5
5
  import process3 from 'process';
@@ -1076,7 +1076,7 @@ async function createProject(options) {
1076
1076
  });
1077
1077
  await generateFromTemplates(projectPath, context);
1078
1078
  if (resolvedOptions.appType !== "fullstack") {
1079
- const { generateConfigFile: generateConfigFile2, generateEnvExample } = await import('./cli-config-templates-5J5VKWWD.js');
1079
+ const { generateConfigFile: generateConfigFile2, generateEnvExample } = await import('./cli-config-templates-GSXKLGU5.js');
1080
1080
  const configs = resolvedOptions.moduleConfigs;
1081
1081
  const isApiWorkspace = resolvedOptions.appType === "api";
1082
1082
  const configDir = isApiWorkspace ? path2.join(projectPath, "apps", `${resolvedOptions.name}-service`, "config") : path2.join(projectPath, "config");
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.43",
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.43"
37
+ "@h-ai/core": "0.1.0-alpha.45"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/fs-extra": "^11.0.4",
@@ -4,7 +4,7 @@
4
4
 
5
5
  name: {{projectName}} API Service
6
6
  version: 0.1.0
7
- env: ${HAI_ENV:development}
7
+ env: development
8
8
  debug: false
9
9
 
10
10
  defaultLocale: {{defaultLocale}}
@@ -14,8 +14,8 @@ http:
14
14
  rpc: false
15
15
 
16
16
  cors:
17
- origin: ${HAI_CORS_ORIGIN:*}
18
- nativeOrigins: ${HAI_NATIVE_ORIGINS:http://localhost,https://tauri.localhost,tauri://localhost,capacitor://localhost}
17
+ origin: '*'
18
+ nativeOrigins: http://localhost,https://tauri.localhost,tauri://localhost,capacitor://localhost
19
19
  {{#if features.iam}} credentials: true
20
20
  {{else}} credentials: false
21
21
  {{/if}} allowedHeaders:
@@ -3,12 +3,12 @@
3
3
  # =============================================================================
4
4
  #
5
5
  # 后端服务的应用级配置,由 core.config 在启动时加载。
6
- # 敏感信息请通过环境变量注入。
6
+ # 每个叶子项都可由约定式 HAI 环境变量覆盖,敏感值不要写入文件。
7
7
  # =============================================================================
8
8
 
9
9
  name: {{fullstack.servPackageName}}
10
10
  version: 0.1.0
11
- env: ${HAI_ENV:development}
12
- debug: ${HAI_DEBUG:false}
11
+ env: development
12
+ debug: false
13
13
 
14
14
  defaultLocale: {{fullstack.i18n.baseLocale}}
@@ -17,8 +17,8 @@ http:
17
17
  rpc: false
18
18
 
19
19
  cors:
20
- origin: ${HAI_CORS_ORIGIN:*}
21
- nativeOrigins: ${HAI_NATIVE_ORIGINS:http://localhost,https://tauri.localhost,tauri://localhost,capacitor://localhost}
20
+ origin: '*'
21
+ nativeOrigins: http://localhost,https://tauri.localhost,tauri://localhost,capacitor://localhost
22
22
  credentials: false
23
23
  allowedHeaders:
24
24
  - Authorization
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "{{projectName}}",
3
- "version": "0.1.0-alpha.43",
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}}"],
@@ -65,9 +65,9 @@ await ai.close()
65
65
 
66
66
  ```yaml
67
67
  llm:
68
- apiKey: ${HAI_AI_LLM_API_KEY:}
69
- baseUrl: ${HAI_AI_LLM_BASE_URL:https://api.openai.com/v1}
70
- model: ${HAI_AI_LLM_MODEL:gpt-4o-mini}
68
+ apiKey: ''
69
+ baseUrl: https://api.openai.com/v1
70
+ model: gpt-4o-mini
71
71
  api: chat # chat(默认)| responses | anthropic——底层协议,对使用方透明
72
72
  timeout: 60000
73
73
  tempModelCacheTtl: 600000 # 临时模型客户端缓存 TTL(毫秒,默认 10 分钟)
@@ -97,6 +97,9 @@ memory:
97
97
  # allowEphemeralFallback: true # 仅明确接受重启丢失数据时开启
98
98
  ```
99
99
 
100
+ 约定环境变量优先于 YAML,例如 `HAI_AI_LLM_APIKEY`、
101
+ `HAI_AI_LLM_BASEURL`、`HAI_AI_LLM_MODEL`。
102
+
100
103
  `ai.config` 是脱敏快照;`apiKey`、`privateKey`、URL 内嵌凭证会被隐藏。
101
104
 
102
105
  ## 常用 API
@@ -193,17 +193,20 @@ export async function initCapacitor() {
193
193
 
194
194
  ### 配置文件格式
195
195
 
196
- 所有模块配置使用 YAML,支持 `${ENV_VAR:default}` 环境变量语法:
196
+ 所有模块配置使用 YAML 保存默认值;`HAI_<配置名>_<YAML 路径>` 环境变量
197
+ 自动覆盖对应叶子项,且优先级更高:
197
198
 
198
199
  ```yaml
199
200
  # config/_core.yml
200
- app:
201
- name: ${HAI_APP_NAME:my-app}
202
- env: ${HAI_ENV:development}
203
- log:
204
- level: ${HAI_LOG_LEVEL:info}
201
+ name: my-app
202
+ env: development
203
+ logging:
204
+ level: info
205
205
  ```
206
206
 
207
+ 以上字段分别对应 `HAI_CORE_NAME`、`HAI_CORE_ENV`、
208
+ `HAI_CORE_LOGGING_LEVEL`。
209
+
207
210
  ---
208
211
 
209
212
  ## 技能导航
@@ -42,15 +42,18 @@ description: 使用 @h-ai/cache 进行内存或 Redis 缓存操作(kv/hash/lis
42
42
 
43
43
  ```yaml
44
44
  # config/_cache.yml
45
- type: ${HAI_CACHE_TYPE:memory} # memory | redis
45
+ type: memory # memory | redis
46
46
  # Redis 配置(type=redis 时生效):
47
- # host: ${HAI_CACHE_REDIS_HOST:localhost}
48
- # port: ${HAI_CACHE_REDIS_PORT:6379}
49
- # password: ${HAI_CACHE_REDIS_PASSWORD:}
50
- # db: ${HAI_CACHE_REDIS_DB:0}
51
- # keyPrefix: ${HAI_CACHE_KEY_PREFIX:hai:}
47
+ # host: localhost
48
+ # port: 6379
49
+ # password: ''
50
+ # db: 0
51
+ # keyPrefix: 'hai:'
52
52
  ```
53
53
 
54
+ 约定环境变量优先于 YAML,例如 `HAI_CACHE_TYPE`、`HAI_CACHE_HOST`、
55
+ `HAI_CACHE_KEYPREFIX`。
56
+
54
57
  ### 2. 初始化与关闭
55
58
 
56
59
  ```typescript
@@ -131,7 +131,12 @@ const unwatch = core.config.watch('db', (cfg, error) => {
131
131
  unwatch()
132
132
  ```
133
133
 
134
- 配置文件格式(YAML,支持环境变量插值):
134
+ 配置文件格式(YAML,支持约定式环境变量映射和显式插值):
135
+
136
+ - 每个 YAML 叶子配置项自动映射为 `HAI_<配置名>_<YAML 路径>`;配置名和 key 转大写、层级以 `_` 分隔,camelCase 不拆词
137
+ - 例如 `core.config.load('ai', ...)` 加载的 `llm.apiKey` 对应 `HAI_AI_LLM_APIKEY`,`llm.models[0].temperature` 对应 `HAI_AI_LLM_MODELS_0_TEMPERATURE`
138
+ - 约定环境变量存在时覆盖 YAML 值并按 YAML 标量规则还原类型;不存在时保留 YAML 值,且不会新增 YAML 中未声明的配置项
139
+ - 优先级固定为约定环境变量 > 显式 `${VAR}` > YAML 默认值;显式语法只用于指定特殊变量名
135
140
 
136
141
  - `${VAR}` — 读取 `process.env.VAR`;缺失则返回 `HaiConfigError.CONFIG_ENV_VAR_MISSING` 错误
137
142
  - `${VAR:default}` — 读取 `process.env.VAR`;缺失则使用默认值
@@ -140,15 +145,15 @@ unwatch()
140
145
 
141
146
  ```yaml
142
147
  # config/_core.yml
143
- app:
144
- name: ${HAI_APP_NAME:my-app} # → string
145
- env: ${HAI_ENV:development} # → string
146
- log:
147
- level: ${HAI_LOG_LEVEL:info} # → string
148
- format: ${HAI_LOG_FORMAT:pretty} # → string,pretty | json
148
+ name: my-app
149
+ env: development
150
+ logging:
151
+ level: info
152
+ format: pretty
149
153
  feature:
150
- debug: ${DEBUG:false} # → boolean false(类型还原)
151
- maxRetries: ${MAX_RETRIES:3} # → number 3(类型还原)
154
+ debug: false
155
+ maxRetries: 3
156
+ # 只有特殊变量名才需要显式语法:
152
157
  url: http://${HOST}:${PORT} # → string(混合文本,不还原)
153
158
  ```
154
159
 
@@ -66,6 +66,9 @@ services:
66
66
  accessKeySecret: ${HAI_DEPLOY_ALIYUN_ACCESS_KEY_SECRET}
67
67
  ```
68
68
 
69
+ 这些凭证名由 `deploy.credentials` 管理,属于显式特殊映射;若同时设置
70
+ `HAI_DEPLOY_PROVIDER_TOKEN` 等约定变量,约定变量仍拥有最高优先级。
71
+
69
72
  ### 2. 初始化与关闭
70
73
 
71
74
  ```typescript
@@ -54,12 +54,12 @@ description: 使用 @h-ai/iam 进行身份认证(密码/OTP/LDAP/API Key)、
54
54
  ```yaml
55
55
  # config/_iam.yml
56
56
  password:
57
- minLength: ${HAI_IAM_PASSWORD_MIN_LENGTH:8}
57
+ minLength: 8
58
58
  requireUppercase: true
59
59
  requireNumber: true
60
60
  session:
61
- maxAge: ${HAI_IAM_SESSION_MAX_AGE:86400}
62
- refreshTokenMaxAge: ${HAI_IAM_REFRESH_TOKEN_MAX_AGE:604800} # 7 天
61
+ maxAge: 86400
62
+ refreshTokenMaxAge: 604800 # 7 天
63
63
  sliding: true
64
64
  singleDevice: false
65
65
  login:
@@ -68,13 +68,16 @@ login:
68
68
  register:
69
69
  enabled: true
70
70
  security:
71
- maxLoginAttempts: ${HAI_IAM_MAX_LOGIN_ATTEMPTS:5}
71
+ maxLoginAttempts: 5
72
72
  lockoutDuration: 900
73
73
  rbac:
74
74
  defaultRole: user
75
75
  superAdminRole: super_admin
76
76
  ```
77
77
 
78
+ 约定环境变量优先于 YAML,例如 `HAI_IAM_PASSWORD_MINLENGTH`、
79
+ `HAI_IAM_SESSION_MAXAGE`、`HAI_IAM_SECURITY_MAXLOGINATTEMPTS`。
80
+
78
81
  ### 2. 初始化
79
82
 
80
83
  ```typescript
@@ -51,26 +51,29 @@ description: 使用 @h-ai/payment 接入微信支付、支付宝、Stripe 统一
51
51
  ```yaml
52
52
  # config/_payment.yml(自行创建)
53
53
  wechat:
54
- appId: ${HAI_PAYMENT_WECHAT_APP_ID}
55
- mchId: ${HAI_PAYMENT_WECHAT_MCH_ID}
56
- apiV3Key: ${HAI_PAYMENT_WECHAT_API_V3_KEY}
57
- privateKey: ${HAI_PAYMENT_WECHAT_PRIVATE_KEY}
58
- serialNo: ${HAI_PAYMENT_WECHAT_SERIAL_NO}
59
- platformCert: ${HAI_PAYMENT_WECHAT_PLATFORM_CERT} # 可选,回调验签需要
54
+ appId: ''
55
+ mchId: ''
56
+ apiV3Key: ''
57
+ privateKey: ''
58
+ serialNo: ''
59
+ platformCert: '' # 可选,回调验签需要
60
60
 
61
61
  alipay:
62
- appId: ${HAI_PAYMENT_ALIPAY_APP_ID}
63
- privateKey: ${HAI_PAYMENT_ALIPAY_PRIVATE_KEY}
64
- alipayPublicKey: ${HAI_PAYMENT_ALIPAY_PUBLIC_KEY}
62
+ appId: ''
63
+ privateKey: ''
64
+ alipayPublicKey: ''
65
65
  signType: RSA2 # 可选,默认 RSA2
66
66
  sandbox: false # 可选,默认 false
67
67
 
68
68
  stripe:
69
- secretKey: ${HAI_PAYMENT_STRIPE_SECRET_KEY}
70
- webhookSecret: ${HAI_PAYMENT_STRIPE_WEBHOOK_SECRET}
69
+ secretKey: ''
70
+ webhookSecret: ''
71
71
  webhookToleranceSeconds: 300 # 可选,默认 300 秒
72
72
  ```
73
73
 
74
+ 约定环境变量优先于 YAML,例如 `HAI_PAYMENT_WECHAT_APIV3KEY`、
75
+ `HAI_PAYMENT_STRIPE_WEBHOOKSECRET`。生产密钥只放环境或密钥管理器。
76
+
74
77
  ### 2. 初始化(服务端)
75
78
 
76
79
  ```typescript
@@ -88,6 +88,9 @@ dnd:
88
88
  end: '08:00'
89
89
  ```
90
90
 
91
+ `providers` 是数组,因此示例保留稳定、可读的显式厂商变量名;若同时设置
92
+ 按索引生成的约定变量(如 `HAI_REACH_PROVIDERS_0_HOST`),约定变量优先。
93
+
91
94
  API Provider 只接受 HTTP(S) URL。回调地址若来自不可信输入,业务层必须先做域名 allowlist,并由企业网络出口策略限制内网访问;不要在日志中记录完整 URL、收件人或第三方响应体。
92
95
 
93
96
  ### 2. 初始化与关闭
@@ -41,13 +41,13 @@ description: 使用 @h-ai/reldb 进行 SQLite/PostgreSQL/MySQL 的初始化、SQ
41
41
 
42
42
  ```yaml
43
43
  # config/_db.yml
44
- type: ${HAI_RELDB_TYPE:sqlite}
45
- database: ${HAI_RELDB_DATABASE:./data/app.db}
44
+ type: sqlite
45
+ database: ./data/app.db
46
46
  # PostgreSQL/MySQL 额外字段:
47
- # host: ${HAI_RELDB_HOST:localhost}
48
- # port: ${HAI_RELDB_PORT:5432}
49
- # user: ${HAI_RELDB_USER:postgres}
50
- # password: ${HAI_RELDB_PASSWORD:}
47
+ # host: localhost
48
+ # port: 5432
49
+ # user: postgres
50
+ # password: ''
51
51
  operationLog:
52
52
  read: false # query / get / queryPage
53
53
  write: false # DDL, execute / batch, tx.begin / tx.commit / tx.rollback
@@ -55,6 +55,9 @@ operationLog:
55
55
  level: debug # info | debug | trace
56
56
  ```
57
57
 
58
+ 约定环境变量优先于 YAML,例如 `HAI_DB_TYPE`、`HAI_DB_DATABASE`、
59
+ `HAI_DB_OPERATIONLOG_LEVEL`。
60
+
58
61
  `operationLog` 在 reldb provider-base 的 DML 操作层统一输出日志,不要在 `reldb-main.ts`、各 raw provider 或调用方重复包装。`read` 覆盖 `query/get/queryPage`,`write` 覆盖 DDL、`execute/batch` 与 `tx.begin/commit/rollback`,`maxLength` 用于截断序列化后的 SQL 参数和批量语句,`level` 默认 `debug`。
59
62
 
60
63
  ### 2. 初始化与关闭
@@ -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 — httpOnly refresh cookie 刷新路径(见下方 cookie 节)
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)
@@ -418,7 +419,7 @@ const adminOnly = serv.requireAuth(
418
419
 
419
420
  #### HTTP middleware
420
421
 
421
- 适用于请求日志、trace、限流、CORS、租户头校验等 **HTTP 层** 横切逻辑。常见 CORS 场景可直接复用 `serv.cors(...)`:
422
+ 适用于请求日志、trace、限流、CORS、租户头校验等 **HTTP 层** 横切逻辑,也可挂载不适合进入 JSON/oRPC contract 的 WebSocket、文件和二进制端点。常见 CORS 场景可直接复用 `serv.cors(...)`:
422
423
 
423
424
  ```typescript
424
425
  import type { ServMiddleware } from '@h-ai/serv'
@@ -451,13 +452,27 @@ const app = serv.createApp({
451
452
  await next()
452
453
  },
453
454
  },
455
+ {
456
+ path: '/assets/*',
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',
464
+ }),
465
+ },
454
466
  ],
455
467
  })
456
468
  ```
457
469
 
458
470
  执行顺序固定为:`securityHeaders` → `middlewares` → `transport`(若启用)→ health/refresh-cookie/OpenAPI/RPC/docs/oRPC routes。
459
471
 
460
- - `middlewares` 先于 `transport` 执行,因此 CORS 这类 preflight middleware 可以直接短路返回;若需要读取解密后的业务 body,请改用 context / procedure 层扩展。
472
+ - `middlewares` 先于 `transport` 执行,因此 CORS preflight 或二进制端点可以直接短路;短路响应仍带内置安全头,但不会经过 transport。
473
+ - 公开只读文件优先使用 `serv.storageAssets(...)`;应用仍须显式提供 key/MIME 白名单、缓存与跨域策略,框架不内置头像等业务概念。
474
+ - 私有资源、Range 下载或动态授权继续使用自定义 middleware/procedure。
475
+ - 若需要读取解密后的业务 body,请改用 context / procedure 层扩展。
461
476
  - 浏览器若需读取自定义响应头(例如 transport 的 `X-Encrypted`),记得通过 `serv.cors({ exposedHeaders: [...] })` 显式暴露。
462
477
 
463
478
  #### Context pipeline
@@ -686,6 +701,7 @@ procedure 包装器内置以下错误:
686
701
  `serv.parseRequestContext()` / `extractBearerToken()` 解析、`buildAuthContextFactory()` 校验的就是它。
687
702
  - `refreshToken`:长期凭证,启用 `refreshCookie` 后只保存在 httpOnly cookie;
688
703
  它不会走 `Authorization`,也不会被 `extractBearerToken()` 读取,只会在 `/auth/refresh` 被服务端取出。
704
+ 受信原生客户端可通过 `nativeTokenTransport` 改用 JSON body,但必须同时校验客户端标识与 Origin。
689
705
 
690
706
  ### 适用场景
691
707
 
@@ -700,6 +716,9 @@ procedure 包装器内置以下错误:
700
716
  4. serv 读取 cookie → 调用 `iam.session.refresh` → 返回新 access token + 更新 cookie(响应体不暴露 refresh token)
701
717
  5. POST `/auth/logout` → serv 清除 cookie(`Max-Age=0`)
702
718
 
719
+ 原生客户端匹配 `nativeTokenTransport.isRequest` 后,登录/注册/刷新响应保留轮换后的
720
+ `refreshToken`,刷新请求从 `{ refreshToken }` body 读取,且不读写浏览器 Cookie。
721
+
703
722
  若同时启用 `transport: { crypto }`,`/auth/refresh` 也必须走加密链路;cookie-only 刷新请求允许空 body,服务端不要把 `Request.body === null` 误判为需要解密的请求体。
704
723
 
705
724
  ### 配置
@@ -715,6 +734,12 @@ const app = serv.createApp({
715
734
  // maxAge?: number 默认 30 * 24 * 3600(30 天)
716
735
  // secure?: boolean 默认 NODE_ENV=production 时开启
717
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
+ },
718
743
  },
719
744
  // ✅ 顶层 iam 同时为 access token 校验提供默认实现,无需再传 verifyToken
720
745
  })
@@ -41,15 +41,15 @@ description: 使用 @h-ai/storage 进行文件存储操作(本地/S3),包
41
41
 
42
42
  ```yaml
43
43
  # config/_storage.yml
44
- type: ${HAI_STORAGE_TYPE:local} # local | s3
44
+ type: local # local | s3
45
45
  # 本地存储
46
- root: ${HAI_STORAGE_PATH:./data/storage}
46
+ root: ./data/storage
47
47
  # S3 存储(type=s3 时生效)
48
- # endpoint: ${HAI_STORAGE_S3_ENDPOINT:}
49
- # region: ${HAI_STORAGE_S3_REGION:us-east-1}
50
- # accessKeyId: ${HAI_STORAGE_S3_ACCESS_KEY:}
51
- # secretAccessKey: ${HAI_STORAGE_S3_SECRET_KEY:}
52
- # bucket: ${HAI_STORAGE_S3_BUCKET:my-bucket}
48
+ # endpoint: ''
49
+ # region: us-east-1
50
+ # accessKeyId: ''
51
+ # secretAccessKey: ''
52
+ # bucket: my-bucket
53
53
  # forcePathStyle: false
54
54
  # prefix: ''
55
55
  # publicUrl: ''
@@ -60,6 +60,9 @@ operationLog:
60
60
  level: debug # info | debug | trace
61
61
  ```
62
62
 
63
+ 约定环境变量优先于 YAML,例如 `HAI_STORAGE_ROOT`、
64
+ `HAI_STORAGE_ACCESSKEYID`、`HAI_STORAGE_SECRETACCESSKEY`。
65
+
63
66
  `operationLog` 在 Local/S3 Provider 的真实 file/dir/presign 操作处输出日志,不要在 `storage-main.ts` 或调用方重复包装。文件内容不会写入日志,上传数据只记录字节长度;`maxLength` 用于截断序列化后的参数,`level` 默认 `debug`。
64
67
 
65
68
  ### 2. 初始化与关闭
@@ -47,22 +47,22 @@ path: ./data/vecdb
47
47
 
48
48
  # pgvector
49
49
  # type: pgvector
50
- # url: ${HAI_VECDB_PG_URL:postgres://user:pass@localhost:5432/mydb}
50
+ # url: postgres://user:pass@localhost:5432/mydb
51
51
  # indexType: hnsw
52
52
  # tablePrefix: vec_
53
53
 
54
54
  # Qdrant
55
55
  # type: qdrant
56
- # url: ${HAI_VECDB_QDRANT_URL:http://localhost:6333}
57
- # apiKey: ${HAI_VECDB_QDRANT_API_KEY:}
56
+ # url: http://localhost:6333
57
+ # apiKey: ''
58
58
 
59
59
  # Chroma(嵌入式:提供 path 且无 url 时自动拉起本地 `chroma run` 服务并持久化)
60
60
  # type: chroma
61
61
  # path: ./data/chroma
62
62
  # Chroma(直连已有服务,不拉起进程)
63
63
  # type: chroma
64
- # url: ${HAI_VECDB_CHROMA_URL:http://localhost:8000}
65
- # apiKey: ${HAI_VECDB_CHROMA_API_KEY:}
64
+ # url: http://localhost:8000
65
+ # apiKey: ''
66
66
  # serverCommand: chroma # 嵌入式模式拉起服务的可执行命令(默认 chroma,来自 chromadb 包)
67
67
  # startupTimeout: 30000 # 嵌入式服务就绪等待超时(毫秒)
68
68
  operationLog:
@@ -72,6 +72,9 @@ operationLog:
72
72
  level: debug # info | debug | trace
73
73
  ```
74
74
 
75
+ 约定环境变量优先于 YAML,例如 `HAI_VECDB_URL`、
76
+ `HAI_VECDB_APIKEY`、`HAI_VECDB_OPERATIONLOG_LEVEL`。
77
+
75
78
  `operationLog` 在集合/向量操作进入真实 Provider 前输出日志,不要在 `vecdb-main.ts` 或调用方重复包装。`maxLength` 用于截断序列化后的向量、文档和过滤条件,`level` 默认 `debug`。
76
79
 
77
80
  ### 2. 初始化与关闭
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/cli-config-templates.ts"],"names":[],"mappings":"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","file":"chunk-CFCXOKGV.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'\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\nname: ${name}\nversion: 0.1.0\nenv: \\${HAI_ENV:development}\ndebug: \\${HAI_DEBUG:false}\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: \\${HAI_RELDB_DATABASE:${database}}\n\n# PostgreSQL/MySQL 配置(可选)\n# host: \\${HAI_RELDB_HOST:localhost}\n# port: \\${HAI_RELDB_PORT:5432}\n# user: \\${HAI_RELDB_USER:postgres}\n# password: \\${HAI_RELDB_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: \\${HAI_RELDB_DATABASE:${database}}\n\n# 连接配置\nhost: \\${HAI_RELDB_HOST:${host}}\nport: \\${HAI_RELDB_PORT:${port}}\nuser: \\${HAI_RELDB_USER:${user}}\npassword: \\${HAI_RELDB_PASSWORD:}\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: \\${HAI_CACHE_REDIS_URL:redis://localhost:6379/0}\n# host: \\${HAI_CACHE_REDIS_HOST:localhost}\n# port: \\${HAI_CACHE_REDIS_PORT:6379}\n# password: \\${HAI_CACHE_REDIS_PASSWORD:}\n# keyPrefix: \\${HAI_CACHE_KEY_PREFIX: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: \\${HAI_CACHE_REDIS_HOST:${host}}\nport: \\${HAI_CACHE_REDIS_PORT:${port}}\npassword: \\${HAI_CACHE_REDIS_PASSWORD:}\nkeyPrefix: \\${HAI_CACHE_KEY_PREFIX: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# 密码策略\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 const storageType = cfg?.type ?? 'local'\n\n if (storageType === 'local') {\n const localPath = cfg?.localPath ?? './data/uploads'\n return `# =============================================================================\n# 存储配置\n# =============================================================================\n\n# 默认 Provider\ndefaultProvider: local\n\n# Provider 配置\nproviders:\n local:\n type: local\n root: \\${HAI_STORAGE_PATH:${localPath}}\n maxFileSize: 10485760 # 10MB\n\n # S3 配置(可选)\n # s3:\n # type: s3\n # bucket: \\${HAI_STORAGE_S3_BUCKET}\n # region: \\${HAI_STORAGE_S3_REGION:us-east-1}\n # accessKeyId: \\${HAI_STORAGE_S3_ACCESS_KEY}\n # secretAccessKey: \\${HAI_STORAGE_S3_SECRET_KEY}\n # endpoint: \\${HAI_STORAGE_S3_ENDPOINT}\n # forcePathStyle: \\${HAI_STORAGE_S3_FORCE_PATH_STYLE:false}\n`\n }\n\n return `# =============================================================================\n# 存储配置\n# =============================================================================\n\n# 默认 Provider\ndefaultProvider: s3\n\n# Provider 配置\nproviders:\n s3:\n type: s3\n bucket: \\${HAI_STORAGE_S3_BUCKET}\n region: \\${HAI_STORAGE_S3_REGION:us-east-1}\n accessKeyId: \\${HAI_STORAGE_S3_ACCESS_KEY}\n secretAccessKey: \\${HAI_STORAGE_S3_SECRET_KEY}\n # endpoint: \\${HAI_STORAGE_S3_ENDPOINT}\n # forcePathStyle: \\${HAI_STORAGE_S3_FORCE_PATH_STYLE:false}\n\n # 本地存储(可选)\n # local:\n # type: local\n # root: \\${HAI_STORAGE_PATH:./data/uploads}\n # maxFileSize: 10485760 # 10MB\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_API_KEY / OPENAI_API_KEY 环境变量)\n apiKey: \\${HAI_AI_LLM_API_KEY:}\n # Base URL(留空时自动读取 HAI_AI_LLM_BASE_URL / OPENAI_BASE_URL,默认 https://api.openai.com/v1)\n # baseUrl: \\${HAI_AI_LLM_BASE_URL:}\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: \\${HAI_AI_LLM_API_KEY:}\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 in config/ reference these variables via \\${VAR_NAME:default} syntax.\n#\n# Naming convention: HAI_<MODULE>_<SETTING>\n# =============================================================================`)\n\n // 应用基础(始终生成)\n sections.push(`\n# =============================================================================\n# Application\n# =============================================================================\n# Environment: development | production | test\nHAI_ENV=development\n# Enable debug mode\nHAI_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_RELDB_TYPE=${dbType}\n# SQLite: file path; PostgreSQL/MySQL: database name\nHAI_RELDB_DATABASE=${dbDatabase}${isSqlite\n ? `\n# PostgreSQL/MySQL connection (uncomment when not using sqlite)\n# HAI_RELDB_HOST=localhost\n# HAI_RELDB_PORT=5432\n# HAI_RELDB_USER=postgres\n# HAI_RELDB_PASSWORD=`\n : `\n# Connection\nHAI_RELDB_HOST=${configs?.db?.host ?? 'localhost'}\nHAI_RELDB_PORT=${configs?.db?.port ?? (dbType === 'postgresql' ? 5432 : 3306)}\nHAI_RELDB_USER=${dbType === 'postgresql' ? 'postgres' : 'root'}\nHAI_RELDB_PASSWORD=`}`)\n }\n\n // IAM / Session\n if (features.includes('iam')) {\n sections.push(`\n# =============================================================================\n# IAM (@h-ai/iam)\n# =============================================================================\nHAI_IAM_SESSION_SECRET=change-me-to-a-strong-random-string-min-32-chars\n# HAI_IAM_PASSWORD_MIN_LENGTH=8\n# HAI_IAM_SESSION_MAX_AGE=86400\n# HAI_IAM_REFRESH_TOKEN_MAX_AGE=604800\n# HAI_IAM_MAX_LOGIN_ATTEMPTS=5\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_REDIS_HOST=${configs?.cache?.host ?? 'localhost'}\nHAI_CACHE_REDIS_PORT=${configs?.cache?.port ?? 6379}\nHAI_CACHE_REDIS_PASSWORD=\n# HAI_CACHE_REDIS_URL=redis://localhost:6379/0\n# HAI_CACHE_REDIS_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_REDIS_URL=redis://localhost:6379/0\n# HAI_CACHE_REDIS_HOST=localhost\n# HAI_CACHE_REDIS_PORT=6379\n# HAI_CACHE_REDIS_PASSWORD=\n# HAI_CACHE_REDIS_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# Storage type: local | s3\nHAI_STORAGE_TYPE=s3\n# S3 / S3-compatible\nHAI_STORAGE_S3_BUCKET=\nHAI_STORAGE_S3_REGION=us-east-1\nHAI_STORAGE_S3_ACCESS_KEY=\nHAI_STORAGE_S3_SECRET_KEY=\n# HAI_STORAGE_S3_ENDPOINT= # Custom endpoint for MinIO / Aliyun OSS etc.\n# HAI_STORAGE_S3_FORCE_PATH_STYLE=false\n# Local storage (uncomment when type=local)\n# HAI_STORAGE_PATH=./data/uploads`)\n }\n else {\n sections.push(`\n# =============================================================================\n# Storage (@h-ai/storage)\n# =============================================================================\n# Storage type: local | s3\nHAI_STORAGE_TYPE=local\n# Local storage root path\nHAI_STORAGE_PATH=${configs?.storage?.localPath ?? './data/uploads'}\n# S3 / S3-compatible (uncomment when type=s3)\n# HAI_STORAGE_S3_BUCKET=\n# HAI_STORAGE_S3_REGION=us-east-1\n# HAI_STORAGE_S3_ACCESS_KEY=\n# HAI_STORAGE_S3_SECRET_KEY=\n# HAI_STORAGE_S3_ENDPOINT= # Custom endpoint for MinIO / Aliyun OSS etc.\n# HAI_STORAGE_S3_FORCE_PATH_STYLE=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_API_KEY=\n# HAI_AI_LLM_BASE_URL= # 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_API_KEY=\n# HAI_AI_LLM_BASE_URL= # 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_API_KEY=\n# HAI_AI_LLM_BASE_URL= # 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_QDRANT_URL=http://localhost:6333\n# HAI_VECDB_QDRANT_API_KEY=\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_MCH_ID=\n# HAI_PAYMENT_WECHAT_API_V3_KEY=\n# HAI_PAYMENT_WECHAT_SERIAL_NO=\n# HAI_PAYMENT_WECHAT_PRIVATE_KEY=\n# HAI_PAYMENT_WECHAT_APP_ID=\n# Alipay\n# HAI_PAYMENT_ALIPAY_APP_ID=\n# HAI_PAYMENT_ALIPAY_PRIVATE_KEY=\n# HAI_PAYMENT_ALIPAY_PUBLIC_KEY=\n# Stripe\n# HAI_PAYMENT_STRIPE_SECRET_KEY=\n# HAI_PAYMENT_STRIPE_WEBHOOK_SECRET=\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# 基础设施服务(按需开启)\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\n # 邮件 (Resend)\n # email:\n # provisioner: resend\n # apiKey: \\${HAI_DEPLOY_RESEND_API_KEY}\n\n # 短信 (阿里云)\n # sms:\n # provisioner: aliyun\n # accessKeyId: \\${HAI_DEPLOY_ALIYUN_ACCESS_KEY_ID}\n # accessKeySecret: \\${HAI_DEPLOY_ALIYUN_ACCESS_KEY_SECRET}\n`\n}\n\nfunction generateVecdbConfig(): string {\n return `# =============================================================================\n# 向量数据库配置 (@h-ai/vecdb)\n# =============================================================================\n\n# 数据库类型: lancedb | pgvector | qdrant\ntype: lancedb\n\n# LanceDB 数据目录\npath: \\${HAI_VECDB_PATH:./data/vecdb}\n\n# 距离度量: cosine | euclidean | dot\n# metric: cosine\n\n# pgvector 配置(当 type 为 pgvector 时使用)\n# type: pgvector\n# host: \\${HAI_RELDB_HOST:localhost}\n# port: \\${HAI_RELDB_PORT:5432}\n# database: \\${HAI_RELDB_DATABASE:hai}\n# user: \\${HAI_RELDB_USER:postgres}\n# password: \\${HAI_RELDB_PASSWORD:}\n# indexType: hnsw\n# tablePrefix: vec_\n\n# Qdrant 配置(当 type 为 qdrant 时使用)\n# type: qdrant\n# url: \\${HAI_VECDB_QDRANT_URL:http://localhost:6333}\n# apiKey: \\${HAI_VECDB_QDRANT_API_KEY:}\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# 模板(可选)\n# templates:\n# - name: verification_code\n# provider: email\n# subject: \"验证码: {code}\"\n# body: \"您的验证码是 {code},有效期 {minutes} 分钟。\"\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# 审计日志表名\ntableName: hai_audit_logs\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: \\${HAI_PAYMENT_WECHAT_MCH_ID}\n# apiV3Key: \\${HAI_PAYMENT_WECHAT_API_V3_KEY}\n# serialNo: \\${HAI_PAYMENT_WECHAT_SERIAL_NO}\n# privateKey: \\${HAI_PAYMENT_WECHAT_PRIVATE_KEY}\n# appId: \\${HAI_PAYMENT_WECHAT_APP_ID}\n\n# 支付宝(按需开启)\n# alipay:\n# appId: \\${HAI_PAYMENT_ALIPAY_APP_ID}\n# privateKey: \\${HAI_PAYMENT_ALIPAY_PRIVATE_KEY}\n# alipayPublicKey: \\${HAI_PAYMENT_ALIPAY_PUBLIC_KEY}\n# signType: RSA2\n# sandbox: false\n\n# Stripe(按需开启)\n# stripe:\n# secretKey: \\${HAI_PAYMENT_STRIPE_SECRET_KEY}\n# webhookSecret: \\${HAI_PAYMENT_STRIPE_WEBHOOK_SECRET}\n`\n}\n"]}
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env node
2
- export { generateConfigFile, generateEnvExample } from './chunk-CFCXOKGV.js';
3
- import './chunk-2H7UOFLK.js';
4
- //# sourceMappingURL=cli-config-templates-5J5VKWWD.js.map
5
- //# sourceMappingURL=cli-config-templates-5J5VKWWD.js.map