@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.
- package/dist/{chunk-CFCXOKGV.js → chunk-U4PA632G.js} +123 -125
- package/dist/chunk-U4PA632G.js.map +1 -0
- package/dist/cli-config-templates-GSXKLGU5.js +5 -0
- package/dist/{cli-config-templates-5J5VKWWD.js.map → cli-config-templates-GSXKLGU5.js.map} +1 -1
- package/dist/index.js +2 -2
- package/package.json +2 -2
- package/templates/apps/api/apps/{{projectName}}-service/config/_core.yml.hbs +1 -1
- package/templates/apps/api/apps/{{projectName}}-service/config/_serv.yml.hbs +2 -2
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_core.yml.hbs +3 -3
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_serv.yml.hbs +2 -2
- package/templates/base/package.json.hbs +1 -1
- package/templates/skills/hai-ai/SKILL.md +6 -3
- package/templates/skills/hai-build/SKILL.md +9 -6
- package/templates/skills/hai-cache/SKILL.md +9 -6
- package/templates/skills/hai-core/SKILL.md +14 -9
- package/templates/skills/hai-deploy/SKILL.md +3 -0
- package/templates/skills/hai-iam/SKILL.md +7 -4
- package/templates/skills/hai-payment/SKILL.md +14 -11
- package/templates/skills/hai-reach/SKILL.md +3 -0
- package/templates/skills/hai-reldb/SKILL.md +9 -6
- package/templates/skills/hai-serv/SKILL.md +28 -3
- package/templates/skills/hai-storage/SKILL.md +10 -7
- package/templates/skills/hai-vecdb/SKILL.md +8 -5
- package/dist/chunk-CFCXOKGV.js.map +0 -1
- package/dist/cli-config-templates-5J5VKWWD.js +0 -5
|
@@ -45,8 +45,8 @@ function generateCoreConfig(cfg) {
|
|
|
45
45
|
|
|
46
46
|
name: ${name}
|
|
47
47
|
version: 0.1.0
|
|
48
|
-
env:
|
|
49
|
-
debug:
|
|
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:
|
|
90
|
+
database: ${database}
|
|
91
91
|
|
|
92
92
|
# PostgreSQL/MySQL \u914D\u7F6E\uFF08\u53EF\u9009\uFF09
|
|
93
|
-
# host:
|
|
94
|
-
# port:
|
|
95
|
-
# user:
|
|
96
|
-
# 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:
|
|
108
|
+
database: ${database}
|
|
109
109
|
|
|
110
110
|
# \u8FDE\u63A5\u914D\u7F6E
|
|
111
|
-
host:
|
|
112
|
-
port:
|
|
113
|
-
user:
|
|
114
|
-
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:
|
|
129
|
-
# host:
|
|
130
|
-
# port:
|
|
131
|
-
# password:
|
|
132
|
-
# keyPrefix:
|
|
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:
|
|
146
|
-
port:
|
|
147
|
-
password:
|
|
148
|
-
keyPrefix:
|
|
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:
|
|
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:
|
|
210
|
-
# region:
|
|
211
|
-
# accessKeyId:
|
|
212
|
-
# secretAccessKey:
|
|
213
|
-
# endpoint:
|
|
214
|
-
# forcePathStyle:
|
|
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:
|
|
229
|
-
region:
|
|
230
|
-
accessKeyId:
|
|
231
|
-
secretAccessKey:
|
|
232
|
-
# endpoint:
|
|
233
|
-
# forcePathStyle:
|
|
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:
|
|
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\
|
|
251
|
-
apiKey:
|
|
252
|
-
# Base URL\uFF08\
|
|
253
|
-
# baseUrl:
|
|
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:
|
|
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
|
|
284
|
+
# Config files use literal defaults; matching HAI variables override YAML leaves.
|
|
285
285
|
#
|
|
286
|
-
# Naming convention: HAI_<
|
|
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
|
-
|
|
293
|
+
HAI_CORE_ENV=development
|
|
294
294
|
# Enable debug mode
|
|
295
|
-
|
|
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
|
-
|
|
305
|
+
HAI_DB_TYPE=${dbType}
|
|
306
306
|
# SQLite: file path; PostgreSQL/MySQL: database name
|
|
307
|
-
|
|
307
|
+
HAI_DB_DATABASE=${dbDatabase}${isSqlite ? `
|
|
308
308
|
# PostgreSQL/MySQL connection (uncomment when not using sqlite)
|
|
309
|
-
#
|
|
310
|
-
#
|
|
311
|
-
#
|
|
312
|
-
#
|
|
309
|
+
# HAI_DB_HOST=localhost
|
|
310
|
+
# HAI_DB_PORT=5432
|
|
311
|
+
# HAI_DB_USER=postgres
|
|
312
|
+
# HAI_DB_PASSWORD=` : `
|
|
313
313
|
# Connection
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
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
|
-
|
|
325
|
-
#
|
|
326
|
-
#
|
|
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
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
#
|
|
346
|
-
#
|
|
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
|
-
#
|
|
359
|
-
#
|
|
360
|
-
#
|
|
361
|
-
#
|
|
362
|
-
#
|
|
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
|
-
#
|
|
376
|
-
|
|
373
|
+
# Default storage provider: local | s3
|
|
374
|
+
HAI_STORAGE_DEFAULTPROVIDER=s3
|
|
377
375
|
# S3 / S3-compatible
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
#
|
|
383
|
-
#
|
|
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
|
-
#
|
|
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
|
-
#
|
|
392
|
-
|
|
389
|
+
# Default storage provider: local | s3
|
|
390
|
+
HAI_STORAGE_DEFAULTPROVIDER=local
|
|
393
391
|
# Local storage root path
|
|
394
|
-
|
|
392
|
+
HAI_STORAGE_PROVIDERS_LOCAL_ROOT=${configs?.storage?.localPath ?? "./data/uploads"}
|
|
395
393
|
# S3 / S3-compatible (uncomment when type=s3)
|
|
396
|
-
#
|
|
397
|
-
#
|
|
398
|
-
#
|
|
399
|
-
#
|
|
400
|
-
#
|
|
401
|
-
#
|
|
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
|
-
|
|
413
|
-
#
|
|
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
|
-
|
|
423
|
-
#
|
|
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
|
-
|
|
433
|
-
#
|
|
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
|
-
#
|
|
449
|
-
#
|
|
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
|
-
#
|
|
472
|
-
#
|
|
473
|
-
#
|
|
474
|
-
#
|
|
475
|
-
#
|
|
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
|
-
#
|
|
478
|
-
#
|
|
479
|
-
#
|
|
475
|
+
# HAI_PAYMENT_ALIPAY_APPID=
|
|
476
|
+
# HAI_PAYMENT_ALIPAY_PRIVATEKEY=
|
|
477
|
+
# HAI_PAYMENT_ALIPAY_ALIPAYPUBLICKEY=
|
|
480
478
|
# Stripe
|
|
481
|
-
#
|
|
482
|
-
#
|
|
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:
|
|
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:
|
|
554
|
-
# port:
|
|
555
|
-
# database:
|
|
556
|
-
# user:
|
|
557
|
-
# 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:
|
|
564
|
-
# apiKey:
|
|
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:
|
|
659
|
-
# apiV3Key:
|
|
660
|
-
# serialNo:
|
|
661
|
-
# privateKey:
|
|
662
|
-
# appId:
|
|
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:
|
|
667
|
-
# privateKey:
|
|
668
|
-
# alipayPublicKey:
|
|
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:
|
|
675
|
-
# webhookSecret:
|
|
672
|
+
# secretKey: ''
|
|
673
|
+
# webhookSecret: ''
|
|
676
674
|
`;
|
|
677
675
|
}
|
|
678
676
|
|
|
679
677
|
export { generateConfigFile, generateEnvExample };
|
|
680
|
-
//# sourceMappingURL=chunk-
|
|
681
|
-
//# sourceMappingURL=chunk-
|
|
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":";;AAgBO,SAAS,kBAAA,CAAmB,WAAmB,OAAA,EAAiC;AACrF,EAAA,QAAQ,SAAA;AAAW,IACjB,KAAK,MAAA;AACH,MAAA,OAAO,kBAAA,CAAmB,SAAS,IAAI,CAAA;AAAA,IACzC,KAAK,MAAA;AACH,MAAA,OAAO,kBAAA,EAAmB;AAAA,IAC5B,KAAK,IAAA;AACH,MAAA,OAAO,gBAAA,CAAiB,SAAS,EAAE,CAAA;AAAA,IACrC,KAAK,OAAA;AACH,MAAA,OAAO,mBAAA,CAAoB,SAAS,KAAK,CAAA;AAAA,IAC3C,KAAK,KAAA;AACH,MAAA,OAAO,iBAAA,CAAkB,SAAS,GAAG,CAAA;AAAA,IACvC,KAAK,SAAA;AACH,MAAA,OAAO,qBAAA,CAAsB,SAAS,OAAO,CAAA;AAAA,IAC/C,KAAK,IAAA;AACH,MAAA,OAAO,gBAAA,CAAiB,SAAS,EAAE,CAAA;AAAA,IACrC,KAAK,QAAA;AACH,MAAA,OAAO,oBAAA,EAAqB;AAAA,IAC9B,KAAK,OAAA;AACH,MAAA,OAAO,mBAAA,EAAoB;AAAA,IAC7B,KAAK,OAAA;AACH,MAAA,OAAO,mBAAA,EAAoB;AAAA,IAC7B,KAAK,WAAA;AACH,MAAA,OAAO,uBAAA,EAAwB;AAAA,IACjC,KAAK,OAAA;AACH,MAAA,OAAO,mBAAA,EAAoB;AAAA,IAC7B,KAAK,SAAA;AACH,MAAA,OAAO,qBAAA,EAAsB;AAAA,IAC/B;AACE,MAAA,OAAO,KAAK,SAAS,CAAA;AAAA,CAAA;AAAA;AAE3B;AAEA,SAAS,mBAAmB,GAAA,EAAgC;AAC1D,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,QAAA;AAC1B,EAAA,MAAM,MAAA,GAAS,KAAK,aAAA,IAAiB,OAAA;AACrC,EAAA,MAAM,gBAAA,GAAmB,WAAW,OAAA,GAChC,CAAA;AAAA,SAAA,CAAA,GACA,CAAA;AAAA,SAAA,CAAA;AAEJ,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA,MAAA,EAID,IAAI;AAAA;AAAA;AAAA;;AAAA,eAAA,EAKK,MAAM;AAAA;AAAA,EAErB,gBAAgB;AAAA,CAAA;AAElB;AAEA,SAAS,kBAAA,GAA6B;AACpC,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,CAAA;AAkBT;AAEA,SAAS,iBAAiB,GAAA,EAA8B;AACtD,EAAA,MAAM,MAAA,GAAS,KAAK,IAAA,IAAQ,QAAA;AAC5B,EAAA,MAAM,QAAA,GAAW,GAAA,EAAK,QAAA,KAAa,MAAA,KAAW,WAAW,eAAA,GAAkB,KAAA,CAAA;AAC3E,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,WAAA;AAC1B,EAAA,MAAM,IAAA,GAAO,GAAA,EAAK,IAAA,KAAS,MAAA,KAAW,eAAe,IAAA,GAAO,IAAA,CAAA;AAE5D,EAAA,IAAI,WAAW,QAAA,EAAU;AACvB,IAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA,UAAA,EAQC,QAAQ;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,EAQlB;AAEA,EAAA,MAAM,IAAA,GAAO,MAAA,KAAW,YAAA,GAAe,UAAA,GAAa,MAAA;AAEpD,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA,MAAA,EAKD,MAAM;;AAAA;AAAA,UAAA,EAGF,QAAQ;;AAAA;AAAA,MAAA,EAGZ,IAAI;AAAA,MAAA,EACJ,IAAI;AAAA,MAAA,EACJ,IAAI;AAAA;AAAA,CAAA;AAGZ;AAEA,SAAS,oBAAoB,GAAA,EAAiC;AAC5D,EAAA,MAAM,SAAA,GAAY,KAAK,IAAA,IAAQ,QAAA;AAE/B,EAAA,IAAI,cAAc,QAAA,EAAU;AAC1B,IAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,EAcT;AAEA,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,WAAA;AAC1B,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,IAAA;AAE1B,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA,MAAA,EAQD,IAAI;AAAA,MAAA,EACJ,IAAI;AAAA;AAAA;AAAA,CAAA;AAIZ;AAEA,SAAS,kBAAkB,GAAA,EAA+B;AACxD,EAAA,MAAM,aAAA,GAAgB,KAAK,aAAA,IAAiB,IAAA;AAC5C,EAAA,MAAM,QAAA,GAAW,KAAK,QAAA,IAAY,KAAA;AAElC,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,YAAA,EAMK,aAAa;AAAA,OAAA,EAClB,QAAQ;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,CAAA;AA0BjB;AAEA,SAAS,sBAAsB,GAAA,EAAmC;AAChE,EAAA,MAAM,WAAA,GAAc,KAAK,IAAA,IAAQ,OAAA;AAEjC,EAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,IAAA,MAAM,SAAA,GAAY,KAAK,SAAA,IAAa,gBAAA;AACpC,IAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,UAAA,EAWC,SAAS;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,EAanB;AAEA,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAwBT;AAEA,SAAS,iBAAiB,GAAA,EAA8B;AACtD,EAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,IAAS,aAAA;AAI5B,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAA,EAWE,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAqBhB;AASO,SAAS,kBAAA,CAAmB,UAAuB,OAAA,EAAiC;AACzF,EAAA,MAAM,WAAqB,EAAC;AAG5B,EAAA,QAAA,CAAS,IAAA,CAAK,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+EAAA,CAQgE,CAAA;AAG9E,EAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAA,CAOK,CAAA;AAGnB,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,IAAI,CAAA,EAAG;AAC3B,IAAA,MAAM,MAAA,GAAS,OAAA,EAAS,EAAA,EAAI,IAAA,IAAQ,QAAA;AACpC,IAAA,MAAM,aAAa,OAAA,EAAS,EAAA,EAAI,QAAA,KAAa,MAAA,KAAW,WAAW,eAAA,GAAkB,KAAA,CAAA;AACrF,IAAA,MAAM,WAAW,MAAA,KAAW,QAAA;AAC5B,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA,YAAA,EAKJ,MAAM;AAAA;AAAA,gBAAA,EAEF,UAAU,GAAG,QAAA,GAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAA,CAAA,GAMA;AAAA;AAAA,YAAA,EAEU,OAAA,EAAS,EAAA,EAAI,IAAA,IAAQ,WAAW;AAAA,YAAA,EAChC,SAAS,EAAA,EAAI,IAAA,KAAS,MAAA,KAAW,YAAA,GAAe,OAAO,IAAA,CAAK;AAAA,YAAA,EAC5D,MAAA,KAAW,YAAA,GAAe,UAAA,GAAa,MAAM;AAAA,gBAAA,CAC1C,CAAA,CAAE,CAAA;AAAA,EACjB;AAGA,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,KAAK,CAAA,EAAG;AAC5B,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAQjB,CAAA;AAAA,EACC;AAGA,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,OAAO,CAAA,EAAG;AAC9B,IAAA,MAAM,SAAA,GAAY,OAAA,EAAS,KAAA,EAAO,IAAA,IAAQ,QAAA;AAC1C,IAAA,IAAI,cAAc,OAAA,EAAS;AACzB,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAAA,EAOH,OAAA,EAAS,KAAA,EAAO,IAAA,IAAQ,WAAW;AAAA,eAAA,EACnC,OAAA,EAAS,KAAA,EAAO,IAAA,IAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAAA,CAMjB,CAAA;AAAA,IACxB,CAAA,MACK;AACH,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAAA,CAcQ,CAAA;AAAA,IACxB;AAAA,EACF;AAGA,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,SAAS,CAAA,EAAG;AAChC,IAAA,MAAM,WAAA,GAAc,OAAA,EAAS,OAAA,EAAS,IAAA,IAAQ,OAAA;AAC9C,IAAA,IAAI,gBAAgB,IAAA,EAAM;AACxB,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iDAAA,CAc8B,CAAA;AAAA,IAC9C,CAAA,MACK;AACH,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iCAAA,EAOe,OAAA,EAAS,OAAA,EAAS,SAAA,IAAa,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+CAAA,CAOlC,CAAA;AAAA,IAC5C;AAAA,EACF;AAGA,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,IAAI,CAAA,EAAG;AAC3B,IAAA,MAAM,QAAA,GAAW,OAAA,EAAS,EAAA,EAAI,eAAA,IAAmB,QAAA;AACjD,IAAA,IAAI,aAAa,WAAA,EAAa;AAC5B,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAA,CAQF,CAAA;AAAA,IACd,CAAA,MAAA,IACS,aAAa,QAAA,EAAU;AAC9B,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAA,CAQF,CAAA;AAAA,IACd,CAAA,MACK;AACH,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAA,CAQF,CAAA;AAAA,IACd;AAAA,EACF;AAGA,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,OAAO,CAAA,EAAG;AAC9B,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAWjB,CAAA;AAAA,EACC;AAGA,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,OAAO,CAAA,EAAG;AAC9B,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAUjB,CAAA;AAAA,EACC;AAGA,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,SAAS,CAAA,EAAG;AAChC,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAiBjB,CAAA;AAAA,EACC;AAGA,EAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAMf,CAAA;AAEC,EAAA,OAAO,QAAA,CAAS,KAAK,IAAI,CAAA;AAC3B;AAEA,SAAS,oBAAA,GAA+B;AACtC,EAAA,OAAO,CAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAyCT;AAEA,SAAS,mBAAA,GAA8B;AACrC,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AA4BT;AAEA,SAAS,mBAAA,GAA8B;AACrC,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAwCT;AAEA,SAAS,uBAAA,GAAkC;AACzC,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA,CAAA;AAsBT;AAEA,SAAS,mBAAA,GAA8B;AACrC,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA,CAAA;AAgBT;AAEA,SAAS,qBAAA,GAAgC;AACvC,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAyBT","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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"cli-config-templates-
|
|
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-
|
|
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-
|
|
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.
|
|
4
|
+
"version": "0.1.0-alpha.45",
|
|
5
5
|
"description": "Hai Framework CLI for project scaffolding and code generation.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"keywords": [
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"ora": "^9.1.0",
|
|
35
35
|
"prompts": "^2.4.2",
|
|
36
36
|
"yaml": "^2.7.0",
|
|
37
|
-
"@h-ai/core": "0.1.0-alpha.
|
|
37
|
+
"@h-ai/core": "0.1.0-alpha.45"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/fs-extra": "^11.0.4",
|
|
@@ -14,8 +14,8 @@ http:
|
|
|
14
14
|
rpc: false
|
|
15
15
|
|
|
16
16
|
cors:
|
|
17
|
-
origin:
|
|
18
|
-
nativeOrigins:
|
|
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:
|
|
12
|
-
debug:
|
|
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:
|
|
21
|
-
nativeOrigins:
|
|
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.
|
|
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:
|
|
69
|
-
baseUrl:
|
|
70
|
-
model:
|
|
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
|
|
196
|
+
所有模块配置使用 YAML 保存默认值;`HAI_<配置名>_<YAML 路径>` 环境变量
|
|
197
|
+
自动覆盖对应叶子项,且优先级更高:
|
|
197
198
|
|
|
198
199
|
```yaml
|
|
199
200
|
# config/_core.yml
|
|
200
|
-
app
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
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:
|
|
45
|
+
type: memory # memory | redis
|
|
46
46
|
# Redis 配置(type=redis 时生效):
|
|
47
|
-
# host:
|
|
48
|
-
# port:
|
|
49
|
-
# password:
|
|
50
|
-
# db:
|
|
51
|
-
# keyPrefix:
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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:
|
|
151
|
-
maxRetries:
|
|
154
|
+
debug: false
|
|
155
|
+
maxRetries: 3
|
|
156
|
+
# 只有特殊变量名才需要显式语法:
|
|
152
157
|
url: http://${HOST}:${PORT} # → string(混合文本,不还原)
|
|
153
158
|
```
|
|
154
159
|
|
|
@@ -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:
|
|
57
|
+
minLength: 8
|
|
58
58
|
requireUppercase: true
|
|
59
59
|
requireNumber: true
|
|
60
60
|
session:
|
|
61
|
-
maxAge:
|
|
62
|
-
refreshTokenMaxAge:
|
|
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:
|
|
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:
|
|
55
|
-
mchId:
|
|
56
|
-
apiV3Key:
|
|
57
|
-
privateKey:
|
|
58
|
-
serialNo:
|
|
59
|
-
platformCert:
|
|
54
|
+
appId: ''
|
|
55
|
+
mchId: ''
|
|
56
|
+
apiV3Key: ''
|
|
57
|
+
privateKey: ''
|
|
58
|
+
serialNo: ''
|
|
59
|
+
platformCert: '' # 可选,回调验签需要
|
|
60
60
|
|
|
61
61
|
alipay:
|
|
62
|
-
appId:
|
|
63
|
-
privateKey:
|
|
64
|
-
alipayPublicKey:
|
|
62
|
+
appId: ''
|
|
63
|
+
privateKey: ''
|
|
64
|
+
alipayPublicKey: ''
|
|
65
65
|
signType: RSA2 # 可选,默认 RSA2
|
|
66
66
|
sandbox: false # 可选,默认 false
|
|
67
67
|
|
|
68
68
|
stripe:
|
|
69
|
-
secretKey:
|
|
70
|
-
webhookSecret:
|
|
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:
|
|
45
|
-
database:
|
|
44
|
+
type: sqlite
|
|
45
|
+
database: ./data/app.db
|
|
46
46
|
# PostgreSQL/MySQL 额外字段:
|
|
47
|
-
# host:
|
|
48
|
-
# port:
|
|
49
|
-
# user:
|
|
50
|
-
# 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 —
|
|
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 层**
|
|
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
|
|
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:
|
|
44
|
+
type: local # local | s3
|
|
45
45
|
# 本地存储
|
|
46
|
-
root:
|
|
46
|
+
root: ./data/storage
|
|
47
47
|
# S3 存储(type=s3 时生效)
|
|
48
|
-
# endpoint:
|
|
49
|
-
# region:
|
|
50
|
-
# accessKeyId:
|
|
51
|
-
# secretAccessKey:
|
|
52
|
-
# 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:
|
|
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:
|
|
57
|
-
# apiKey:
|
|
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:
|
|
65
|
-
# apiKey:
|
|
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":";;AAgBO,SAAS,kBAAA,CAAmB,WAAmB,OAAA,EAAiC;AACrF,EAAA,QAAQ,SAAA;AAAW,IACjB,KAAK,MAAA;AACH,MAAA,OAAO,kBAAA,CAAmB,SAAS,IAAI,CAAA;AAAA,IACzC,KAAK,MAAA;AACH,MAAA,OAAO,kBAAA,EAAmB;AAAA,IAC5B,KAAK,IAAA;AACH,MAAA,OAAO,gBAAA,CAAiB,SAAS,EAAE,CAAA;AAAA,IACrC,KAAK,OAAA;AACH,MAAA,OAAO,mBAAA,CAAoB,SAAS,KAAK,CAAA;AAAA,IAC3C,KAAK,KAAA;AACH,MAAA,OAAO,iBAAA,CAAkB,SAAS,GAAG,CAAA;AAAA,IACvC,KAAK,SAAA;AACH,MAAA,OAAO,qBAAA,CAAsB,SAAS,OAAO,CAAA;AAAA,IAC/C,KAAK,IAAA;AACH,MAAA,OAAO,gBAAA,CAAiB,SAAS,EAAE,CAAA;AAAA,IACrC,KAAK,QAAA;AACH,MAAA,OAAO,oBAAA,EAAqB;AAAA,IAC9B,KAAK,OAAA;AACH,MAAA,OAAO,mBAAA,EAAoB;AAAA,IAC7B,KAAK,OAAA;AACH,MAAA,OAAO,mBAAA,EAAoB;AAAA,IAC7B,KAAK,WAAA;AACH,MAAA,OAAO,uBAAA,EAAwB;AAAA,IACjC,KAAK,OAAA;AACH,MAAA,OAAO,mBAAA,EAAoB;AAAA,IAC7B,KAAK,SAAA;AACH,MAAA,OAAO,qBAAA,EAAsB;AAAA,IAC/B;AACE,MAAA,OAAO,KAAK,SAAS,CAAA;AAAA,CAAA;AAAA;AAE3B;AAEA,SAAS,mBAAmB,GAAA,EAAgC;AAC1D,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,QAAA;AAC1B,EAAA,MAAM,MAAA,GAAS,KAAK,aAAA,IAAiB,OAAA;AACrC,EAAA,MAAM,gBAAA,GAAmB,WAAW,OAAA,GAChC,CAAA;AAAA,SAAA,CAAA,GACA,CAAA;AAAA,SAAA,CAAA;AAEJ,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA,MAAA,EAID,IAAI;AAAA;AAAA;AAAA;;AAAA,eAAA,EAKK,MAAM;AAAA;AAAA,EAErB,gBAAgB;AAAA,CAAA;AAElB;AAEA,SAAS,kBAAA,GAA6B;AACpC,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,CAAA;AAkBT;AAEA,SAAS,iBAAiB,GAAA,EAA8B;AACtD,EAAA,MAAM,MAAA,GAAS,KAAK,IAAA,IAAQ,QAAA;AAC5B,EAAA,MAAM,QAAA,GAAW,GAAA,EAAK,QAAA,KAAa,MAAA,KAAW,WAAW,eAAA,GAAkB,KAAA,CAAA;AAC3E,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,WAAA;AAC1B,EAAA,MAAM,IAAA,GAAO,GAAA,EAAK,IAAA,KAAS,MAAA,KAAW,eAAe,IAAA,GAAO,IAAA,CAAA;AAE5D,EAAA,IAAI,WAAW,QAAA,EAAU;AACvB,IAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA,gCAAA,EAQuB,QAAQ,CAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,EAQxC;AAEA,EAAA,MAAM,IAAA,GAAO,MAAA,KAAW,YAAA,GAAe,UAAA,GAAa,MAAA;AAEpD,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA,MAAA,EAKD,MAAM;;AAAA;AAAA,gCAAA,EAGoB,QAAQ,CAAA;;AAAA;AAAA,wBAAA,EAGhB,IAAI,CAAA;AAAA,wBAAA,EACJ,IAAI,CAAA;AAAA,wBAAA,EACJ,IAAI,CAAA;AAAA;AAAA,CAAA;AAG9B;AAEA,SAAS,oBAAoB,GAAA,EAAiC;AAC5D,EAAA,MAAM,SAAA,GAAY,KAAK,IAAA,IAAQ,QAAA;AAE/B,EAAA,IAAI,cAAc,QAAA,EAAU;AAC1B,IAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,EAcT;AAEA,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,WAAA;AAC1B,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,IAAA;AAE1B,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA,8BAAA,EAQuB,IAAI,CAAA;AAAA,8BAAA,EACJ,IAAI,CAAA;AAAA;AAAA;AAAA,CAAA;AAIpC;AAEA,SAAS,kBAAkB,GAAA,EAA+B;AACxD,EAAA,MAAM,aAAA,GAAgB,KAAK,aAAA,IAAiB,IAAA;AAC5C,EAAA,MAAM,QAAA,GAAW,KAAK,QAAA,IAAY,KAAA;AAElC,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,YAAA,EAMK,aAAa;AAAA,OAAA,EAClB,QAAQ;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,CAAA;AA0BjB;AAEA,SAAS,sBAAsB,GAAA,EAAmC;AAChE,EAAA,MAAM,WAAA,GAAc,KAAK,IAAA,IAAQ,OAAA;AAEjC,EAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,IAAA,MAAM,SAAA,GAAY,KAAK,SAAA,IAAa,gBAAA;AACpC,IAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,8BAAA,EAWqB,SAAS,CAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,EAavC;AAEA,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAwBT;AAEA,SAAS,iBAAiB,GAAA,EAA8B;AACtD,EAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,IAAS,aAAA;AAI5B,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAA,EAWE,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAqBhB;AASO,SAAS,kBAAA,CAAmB,UAAuB,OAAA,EAAiC;AACzF,EAAA,MAAM,WAAqB,EAAC;AAG5B,EAAA,QAAA,CAAS,IAAA,CAAK,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+EAAA,CAQgE,CAAA;AAG9E,EAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAAA,CAOA,CAAA;AAGd,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,IAAI,CAAA,EAAG;AAC3B,IAAA,MAAM,MAAA,GAAS,OAAA,EAAS,EAAA,EAAI,IAAA,IAAQ,QAAA;AACpC,IAAA,MAAM,aAAa,OAAA,EAAS,EAAA,EAAI,QAAA,KAAa,MAAA,KAAW,WAAW,eAAA,GAAkB,KAAA,CAAA;AACrF,IAAA,MAAM,WAAW,MAAA,KAAW,QAAA;AAC5B,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA,eAAA,EAKD,MAAM;AAAA;AAAA,mBAAA,EAEF,UAAU,GAAG,QAAA,GAC9B;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAA,CAAA,GAMA;AAAA;AAAA,eAAA,EAEa,OAAA,EAAS,EAAA,EAAI,IAAA,IAAQ,WAAW;AAAA,eAAA,EAChC,SAAS,EAAA,EAAI,IAAA,KAAS,MAAA,KAAW,YAAA,GAAe,OAAO,IAAA,CAAK;AAAA,eAAA,EAC5D,MAAA,KAAW,YAAA,GAAe,UAAA,GAAa,MAAM;AAAA,mBAAA,CAC1C,CAAA,CAAE,CAAA;AAAA,EACpB;AAGA,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,KAAK,CAAA,EAAG;AAC5B,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAUjB,CAAA;AAAA,EACC;AAGA,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,OAAO,CAAA,EAAG;AAC9B,IAAA,MAAM,SAAA,GAAY,OAAA,EAAS,KAAA,EAAO,IAAA,IAAQ,QAAA;AAC1C,IAAA,IAAI,cAAc,OAAA,EAAS;AACzB,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAA,EAOG,OAAA,EAAS,KAAA,EAAO,IAAA,IAAQ,WAAW;AAAA,qBAAA,EACnC,OAAA,EAAS,KAAA,EAAO,IAAA,IAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAAA,CAMvB,CAAA;AAAA,IACxB,CAAA,MACK;AACH,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAAA,CAcQ,CAAA;AAAA,IACxB;AAAA,EACF;AAGA,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,SAAS,CAAA,EAAG;AAChC,IAAA,MAAM,WAAA,GAAc,OAAA,EAAS,OAAA,EAAS,IAAA,IAAQ,OAAA;AAC9C,IAAA,IAAI,gBAAgB,IAAA,EAAM;AACxB,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iCAAA,CAcc,CAAA;AAAA,IAC9B,CAAA,MACK;AACH,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAA,EAOD,OAAA,EAAS,OAAA,EAAS,SAAA,IAAa,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uCAAA,CAO1B,CAAA;AAAA,IACpC;AAAA,EACF;AAGA,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,IAAI,CAAA,EAAG;AAC3B,IAAA,MAAM,QAAA,GAAW,OAAA,EAAS,EAAA,EAAI,eAAA,IAAmB,QAAA;AACjD,IAAA,IAAI,aAAa,WAAA,EAAa;AAC5B,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAA,CAQF,CAAA;AAAA,IACd,CAAA,MAAA,IACS,aAAa,QAAA,EAAU;AAC9B,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAA,CAQF,CAAA;AAAA,IACd,CAAA,MACK;AACH,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAA,CAQF,CAAA;AAAA,IACd;AAAA,EACF;AAGA,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,OAAO,CAAA,EAAG;AAC9B,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAWjB,CAAA;AAAA,EACC;AAGA,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,OAAO,CAAA,EAAG;AAC9B,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAUjB,CAAA;AAAA,EACC;AAGA,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,SAAS,CAAA,EAAG;AAChC,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAiBjB,CAAA;AAAA,EACC;AAGA,EAAA,QAAA,CAAS,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAMf,CAAA;AAEC,EAAA,OAAO,QAAA,CAAS,KAAK,IAAI,CAAA;AAC3B;AAEA,SAAS,oBAAA,GAA+B;AACtC,EAAA,OAAO,CAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAyCT;AAEA,SAAS,mBAAA,GAA8B;AACrC,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AA4BT;AAEA,SAAS,mBAAA,GAA8B;AACrC,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAwCT;AAEA,SAAS,uBAAA,GAAkC;AACzC,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA,CAAA;AAsBT;AAEA,SAAS,mBAAA,GAA8B;AACrC,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA,CAAA;AAgBT;AAEA,SAAS,qBAAA,GAAgC;AACvC,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAyBT","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"]}
|