diff --git a/package.json b/package.json index e728f1f..f6fb438 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@kevisual/use-config", - "version": "1.0.28", + "version": "1.0.29", "types": "dist/config.d.ts", "scripts": { "build": "npm run clean && code-builder build --dts", @@ -18,8 +18,9 @@ "license": "UNLICENSED", "type": "module", "devDependencies": { + "@kevisual/code-builder": "^0.0.3", "@kevisual/context": "^0.0.4", - "@types/node": "^25.0.7", + "@types/node": "^25.2.0", "dotenv": "^17.2.3" }, "exports": { @@ -29,7 +30,8 @@ }, "./context": "./dist/app.js", "./file-store": "./dist/app.js", - "./env": "./dist/app.js" + "./env": "./dist/app.js", + "./env-config": "./src/env-config.ts" }, "peerDependencies": { "dotenv": "^17" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..430956b --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,71 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@kevisual/load': + specifier: ^0.0.6 + version: 0.0.6 + devDependencies: + '@kevisual/code-builder': + specifier: ^0.0.3 + version: 0.0.3 + '@kevisual/context': + specifier: ^0.0.4 + version: 0.0.4 + '@types/node': + specifier: ^25.2.0 + version: 25.2.0 + dotenv: + specifier: ^17.2.3 + version: 17.2.3 + +packages: + + '@kevisual/code-builder@0.0.3': + resolution: {integrity: sha512-mw8HMYBI9otzBv0ASB/Rqb9g03NxpXlR97ScaLb5xeQFNwO/ohdrLdwuNohUBIzLosMWUkuTGIBzV63UhlgIvw==} + hasBin: true + + '@kevisual/context@0.0.4': + resolution: {integrity: sha512-HJeLeZQLU+7tCluSfOyvkgKLs0HjCZrdJlZgEgKRSa8XTwZfMAUt6J7qZTbrZAHBlPtX68EPu/PI8JMCeu3WAQ==} + + '@kevisual/load@0.0.6': + resolution: {integrity: sha512-+3YTFehRcZ1haGel5DKYMUwmi5i6f2psyaPZlfkKU/cOXgkpwoG9/BEqPCnPjicKqqnksEpixVRkyHJ+5bjLVA==} + + '@types/node@25.2.0': + resolution: {integrity: sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==} + + dotenv@17.2.3: + resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} + engines: {node: '>=12'} + + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + +snapshots: + + '@kevisual/code-builder@0.0.3': {} + + '@kevisual/context@0.0.4': {} + + '@kevisual/load@0.0.6': + dependencies: + eventemitter3: 5.0.4 + + '@types/node@25.2.0': + dependencies: + undici-types: 7.16.0 + + dotenv@17.2.3: {} + + eventemitter3@5.0.4: {} + + undici-types@7.16.0: {} diff --git a/src/env-config.ts b/src/env-config.ts new file mode 100644 index 0000000..e4cb90c --- /dev/null +++ b/src/env-config.ts @@ -0,0 +1,284 @@ +export type ConfigEnvItem = { + title: string; + description?: string; + tags?: string[]; +} +export const configEnvList = [ + // 基础配置 + { + title: 'PORT', + description: '服务端口号', + tags: ['基础', '服务'] + }, + // Redis 配置 + { + title: 'REDIS_HOST', + description: 'Redis 服务器地址', + tags: ['Redis', '数据库', '缓存'] + }, + { + title: 'REDIS_PORT', + description: 'Redis 服务器端口', + tags: ['Redis', '数据库', '缓存'] + }, + { + title: 'REDIS_PASSWORD', + description: 'Redis 连接密码', + tags: ['Redis', '数据库', '缓存', '安全'] + }, + { + title: 'REDIS_VERSION', + description: 'Redis 版本号', + tags: ['Redis', '数据库', '缓存'] + }, + { + title: 'REDIS_DB', + description: 'Redis 数据库索引', + tags: ['Redis', '数据库', '缓存'] + }, + { + title: 'REDIS_USER', + description: 'Redis 用户名', + tags: ['Redis', '数据库', '缓存', '安全'] + }, + // PostgreSQL 配置 + { + title: 'POSTGRES_HOST', + description: 'PostgreSQL 服务器地址', + tags: ['PostgreSQL', '数据库', '关系型数据库'] + }, + { + title: 'POSTGRES_PORT', + description: 'PostgreSQL 服务器端口', + tags: ['PostgreSQL', '数据库', '关系型数据库'] + }, + { + title: 'POSTGRES_PASSWORD', + description: 'PostgreSQL 连接密码', + tags: ['PostgreSQL', '数据库', '关系型数据库', '安全'] + }, + { + title: 'POSTGRES_USER', + description: 'PostgreSQL 用户名', + tags: ['PostgreSQL', '数据库', '关系型数据库', '安全'] + }, + { + title: 'POSTGRES_DB', + description: 'PostgreSQL 数据库名称', + tags: ['PostgreSQL', '数据库', '关系型数据库'] + }, + // MongoDB 配置 + { + title: 'MONGO_URI', + description: 'MongoDB 连接字符串', + tags: ['MongoDB', '数据库', 'NoSQL'] + }, + // Drizzle ORM 配置 + { + title: 'DATABASE_URL', + description: '数据库连接 URL(用于 Drizzle ORM)', + tags: ['数据库', 'ORM', 'Drizzle', '常用'] + }, + // MinIO 配置 + { + title: 'MINIO_ENDPOINT', + description: 'MinIO 服务地址', + tags: ['MinIO', '对象存储', '存储'] + }, + { + title: 'MINIO_BUCKET_NAME', + description: 'MinIO 存储桶名称', + tags: ['MinIO', '对象存储', '存储'] + }, + { + title: 'MINIO_ACCESS_KEY', + description: 'MinIO 访问密钥', + tags: ['MinIO', '对象存储', '存储', '安全'] + }, + { + title: 'MINIO_SECRET_KEY', + description: 'MinIO 秘密密钥', + tags: ['MinIO', '对象存储', '存储', '安全'] + }, + { + title: 'MINIO_USE_SSL', + description: 'MinIO 是否使用 SSL', + tags: ['MinIO', '对象存储', '存储', '安全'] + }, + // S3 配置 + { + title: 'S3_ACCESS_KEY_ID', + description: 'S3 访问密钥 ID', + tags: ['S3', '对象存储', '存储', 'AWS', '安全'] + }, + { + title: 'S3_SECRET_ACCESS_KEY', + description: 'S3 秘密访问密钥', + tags: ['S3', '对象存储', '存储', 'AWS', '安全'] + }, + { + title: 'S3_REGION', + description: 'S3 区域', + tags: ['S3', '对象存储', '存储', 'AWS'] + }, + { + title: 'S3_BUCKET_NAME', + description: 'S3 存储桶名称', + tags: ['S3', '对象存储', '存储', 'AWS'] + }, + { + title: 'S3_ENDPOINT', + description: 'S3 服务端点', + tags: ['S3', '对象存储', '存储', 'AWS'] + }, + { + title: 'S3_FORCE_PATH_STYLE', + description: '是否强制路径式访问 S3(MinIO 一般需要开启)', + tags: ['S3', '对象存储', '存储', 'AWS'] + }, + // KEVISUAL 服务配置 + { + title: 'KEVISUAL_TOKEN', + description: 'KEVISUAL 服务认证令牌', + tags: ['KEVISUAL', '服务', '安全'] + }, + { + title: 'KEVISUAL_API_URL', + description: 'KEVISUAL API 地址', + tags: ['KEVISUAL', '服务', 'API'] + }, + // AI 配置 + { + title: 'KEVISUAL_NEW_API_KEY', + description: 'KEVISUAL AI API 密钥', + tags: ['AI', 'KEVISUAL', '安全'] + }, + { + title: 'BAILIAN_API_KEY', + description: '百炼 API 密钥', + tags: ['AI', '百炼', '安全', '常用'] + }, + { + title: 'ZHIPU_API_KEY', + description: '智谱 API 密钥', + tags: ['AI', '智谱', '安全', '常用'] + }, + { + title: 'MINIMAX_API_KEY', + description: 'MiniMax API 密钥', + tags: ['AI', 'MiniMax', '安全', '常用'] + }, + { + title: 'VOLCENGINE_API_KEY', + description: '火山引擎 API 密钥', + tags: ['AI', '火山引擎', '安全', '常用'] + }, + { + title: 'BAILIAN_CODE_API_KEY', + description: '百炼代码规划 API 密钥', + tags: ['AI', '百炼', '代码', '安全', '常用'] + }, + // 即梦配置 + { + title: 'JIMENG_API_URL', + description: '即梦 API 地址', + tags: ['即梦', 'API'] + }, + { + title: 'JIMENG_API_KEY', + description: '即梦 API 密钥', + tags: ['即梦', 'API', '安全', '常用'] + }, + { + title: 'JIMENG_TIMEOUT', + description: '即梦 API 超时时间', + tags: ['即梦', 'API'] + }, + // OpenCode 配置 + { + title: 'OPENCODE_URL', + description: 'OpenCode 服务地址', + tags: ['OpenCode', '服务', 'API', '常用'] + }, + { + title: 'OPENCODE_API_KEY', + description: 'OpenCode API 密钥', + tags: ['OpenCode', 'API', '安全', '常用'] + }, + { + title: 'OPENCODE_SERVER_PASSWORD', + description: 'OpenCode 服务器密码', + tags: ['OpenCode', '服务', '安全'] + }, + { + title: "OPENCODE_SERVER_USERNAME", + description: "OpenCode 服务器用户名", + tags: ['OpenCode', '服务', '安全'] + }, + // 通知配置 + { + title: 'FEISHU_NOTIFY_WEBHOOK_URL', + description: '飞书通知 Webhook 地址', + tags: ['通知', '飞书', 'Webhook'] + }, + // NocoDB 配置 + { + title: 'NOCODB_URL', + description: 'NocoDB 服务地址', + tags: ['NocoDB', '数据库', '服务'] + }, + { + title: 'NOCODB_API_KEY', + description: 'NocoDB API 密钥', + tags: ['NocoDB', '数据库', 'API', '安全'] + }, + // MeiliSearch 配置 + { + title: 'MEILISEARCH_URL', + description: 'MeiliSearch 服务地址', + tags: ['MeiliSearch', '搜索引擎', '服务', '常用'] + }, + { + title: 'MEILISEARCH_API_KEY', + description: 'MeiliSearch API 密钥', + tags: ['MeiliSearch', '搜索引擎', 'API', '安全', '常用'] + }, + // PocketBase 配置 + { + title: 'POCKETBASE_URL', + description: 'PocketBase 服务地址', + tags: ['PocketBase', '后端', '服务'] + }, + { + title: 'POCKETBASE_TOKEN', + description: 'PocketBase 认证令牌', + tags: ['PocketBase', '后端', '安全'] + }, + // CNB 配置 + { + title: 'CNB_TOKEN', + description: 'CNB 认证令牌', + tags: ['CNB', 'Cool', '安全', '常用'] + }, + { + title: 'CNB_API_KEY', + description: 'CNB API 密钥', + tags: ['CNB', 'Cool', 'API', '安全', '常用'] + }, + { + title: 'CNB_COOKIE', + description: 'CNB Cookie', + tags: ['CNB', 'Cool', '安全', '常用'] + }, + { + title: 'CNB_REPO_SLUG', + description: 'CNB 仓库标识', + tags: ['CNB', 'Cool'] + }, + // Kubernetes 配置 + { + title: 'KUBECONFIG_DATA', + description: 'Kubernetes 配置数据', + tags: ['Kubernetes', 'K8s', '容器', '部署'] + } +] as const; \ No newline at end of file diff --git a/src/env.ts b/src/env.ts index bb2db5f..b461841 100644 --- a/src/env.ts +++ b/src/env.ts @@ -2,80 +2,14 @@ import fs from 'node:fs'; import path from 'node:path'; import dotenv from 'dotenv'; import { fileURLToPath } from 'url'; +import { configEnvList } from './env-config.ts'; + +// 从 configEnvList 推断配置键名 +type ConfigKeys = typeof configEnvList[number]['title']; // 配置类型 export type Config = { - PORT?: string; - // redis - REDIS_HOST?: string; - REDIS_PORT?: string; - REDIS_PASSWORD?: string; - REDIS_VERSION?: string; - REDIS_DB?: string; - REDIS_USER?: string; - // postgres - POSTGRES_HOST?: string; - POSTGRES_PORT?: string; - POSTGRES_PASSWORD?: string; - POSTGRES_USER?: string; - POSTGRES_DB?: string; - // mongo - MONGO_URI?: string; - // DB: for drizzleorm - DATABASE_URL?: string; - - // minio - MINIO_ENDPOINT?: string; - MINIO_BUCKET_NAME?: string; - MINIO_ACCESS_KEY?: string; - MINIO_SECRET_KEY?: string; - MINIO_USE_SSL?: string; - // s3 - S3_ACCESS_KEY_ID?: string; - S3_SECRET_ACCESS_KEY?: string; - S3_REGION?: string; - S3_BUCKET_NAME?: string; - S3_ENDPOINT?: string; - S3_FORCE_PATH_STYLE?: string; - - // KEVISUAL 服务相关 - KEVISUAL_TOKEN?: string; - KEVISUAL_API_URL?: string; - - // AI - KEVISUAL_NEW_API?: string; - BAILIAN_API_KEY?: string; - ZHIPU_API_KEY?: string; - MINIMAX_API_KEY?: string; - DOUBAO_API_KEY?: string; - - JIMENG_API_URL?: string; - JIMENG_API_KEY?: string; - JIMENG_TIMEOUT?: string; - - OPENCODE_URL?: string; - OPENCODE_API_KEY?: string; - - // ## Notify - FEISHU_NOTIFY_WEBHOOK_URL?: string; - - // NOCODEB - NOCODB_URL?: string; - NOCODB_API_KEY?: string; - - // MEILISEARCH - MEILISEARCH_URL?: string; - MEILISEARCH_API_KEY?: string - - // PocketBase - POCKETBASE_URL?: string; - POCKETBASE_TOKEN?: string; - - CNB_TOKEN?: string; - CNB_COOKIE?: string; - - KUBECONFIG_DATA?: string; - // 其他自定义配置 + [K in ConfigKeys]?: string; } & T; export const initConfig: Config = { PORT: '3000', @@ -224,7 +158,7 @@ export const useKey = (key: keyof Config, opts?: { defaultValue?: str v = process.env[key]; } if (!v) { - return opts?.defaultValue || null; + return opts?.defaultValue || ''; } if (opts?.isNumber && typeof v === 'string') { return Number(v); @@ -235,6 +169,20 @@ export const useKey = (key: keyof Config, opts?: { defaultValue?: str return v; }; +export const useValue = (key: keyof Config, values: any, opts?: { defaultValue?: string; isNumber?: boolean; isBoolean?: boolean }): string | number | boolean => { + let v = values[key as string]; + if (!v) { + return '' + } + if (opts?.isNumber && typeof v === 'string') { + return Number(v); + } + if (opts?.isBoolean && typeof v === 'string') { + return v === 'true'; + } + return v; +} + /** * 写入json配置文件 * @param config 配置