create-zhin-app 1.0.9 → 1.0.10

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/README.md CHANGED
@@ -5,9 +5,12 @@
5
5
  ## 核心特性
6
6
 
7
7
  - 🚀 **一键创建**: 使用标准的 `npm create` / `yarn create` / `pnpm create` 命令
8
- - **Workspace 结构**: 自动创建 pnpm workspace,支持插件开发
9
- - �🔧 **智能配置**: 自动安装 pnpm、项目依赖
10
- - 🎯 **交互式配置**: 选择运行时、配置格式
8
+ - 📦 **Workspace 结构**: 自动创建 pnpm workspace,支持插件开发
9
+ - 🔧 **智能配置**: 自动安装 pnpm、项目依赖
10
+ - 🎯 **交互式配置**: 选择运行时、配置格式、数据库类型
11
+ - 🗄️ **数据库支持**: 支持 SQLite、MySQL、PostgreSQL、MongoDB、Redis
12
+ - 🔐 **安全配置**: 自动生成 HTTP 认证和环境变量管理
13
+ - 📊 **日志配置**: 内置完整的日志等级和清理配置
11
14
  - 🌐 **零安装**: 无需全局安装,直接使用
12
15
 
13
16
  ## 快速开始
@@ -51,10 +54,15 @@ pnpm build
51
54
  4. **HTTP 认证配置**: 配置 Web 控制台登录信息
52
55
  - 默认用户名:当前系统用户名
53
56
  - 默认密码:随机生成 6 位字符串
54
- 5. **创建 Workspace**: 生成 pnpm workspace 结构
55
- 6. **生成 .env 文件**: 保存 HTTP 认证信息
56
- 7. **自动安装依赖**: 在项目根目录执行 `pnpm install`
57
- 8. **完成提示**: 显示登录信息和下一步操作
57
+ 5. **数据库配置**: 选择数据库类型和连接参数
58
+ - SQLite (默认,零配置)
59
+ - MySQL、PostgreSQL、MongoDB、Redis
60
+ - 自动安装对应的数据库驱动包
61
+ 6. **创建 Workspace**: 生成 pnpm workspace 结构
62
+ 7. **生成配置文件**: 包含数据库、日志等完整配置
63
+ 8. **生成 .env 文件**: 保存 HTTP 认证和数据库连接信息
64
+ 9. **自动安装依赖**: 在项目根目录执行 `pnpm install`
65
+ 10. **完成提示**: 显示登录信息、数据库配置和下一步操作
58
66
 
59
67
  ## 支持的参数
60
68
 
@@ -75,6 +83,12 @@ npm create zhin-app my-awesome-bot
75
83
  4. 🔐 配置 Web 控制台登录信息
76
84
  - 用户名(默认:当前系统用户名)
77
85
  - 密码(默认:随机 6 位字符)
86
+ 5. 🗄️ 配置数据库
87
+ - SQLite(推荐,零配置)
88
+ - MySQL(主机、端口、用户名、密码、数据库名)
89
+ - PostgreSQL(主机、端口、用户名、密码、数据库名)
90
+ - MongoDB(连接字符串、数据库名)
91
+ - Redis(主机、端口、密码、数据库索引)
78
92
 
79
93
  ### 快速创建(跳过交互)
80
94
 
@@ -96,8 +110,11 @@ npm create zhin-app my-bot --yes
96
110
  - 配置格式: TypeScript (`zhin.config.ts`)
97
111
  - 运行时: Node.js
98
112
  - 包管理器: pnpm(自动安装)
113
+ - 数据库: SQLite (`./data/bot.db`, WAL 模式)
99
114
  - HTTP 用户名: 当前系统用户名
100
115
  - HTTP 密码: 随机生成 6 位字符
116
+ - 日志等级: INFO
117
+ - 日志清理: 7 天,10000 条记录
101
118
 
102
119
  ## 使用场景
103
120
 
@@ -0,0 +1,5 @@
1
+ import { InitOptions, DatabaseConfig } from './types.js';
2
+ export declare function generateDatabaseEnvVars(config: DatabaseConfig): string;
3
+ export declare function generateDatabaseConfig(config: DatabaseConfig, format: 'ts' | 'js' | 'yaml' | 'json'): string;
4
+ export declare function createConfigFile(appPath: string, format: string, options: InitOptions): Promise<void>;
5
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGzD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CA+CtE;AAGD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAgG5G;AAGD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,iBAiJ3F"}
package/lib/config.js ADDED
@@ -0,0 +1,271 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+ // 生成数据库环境变量
4
+ export function generateDatabaseEnvVars(config) {
5
+ const envVars = [];
6
+ switch (config.dialect) {
7
+ case 'mysql':
8
+ envVars.push('# MySQL 数据库配置', `DB_HOST=${config.host || 'localhost'}`, `DB_PORT=${config.port || 3306}`, `DB_USER=${config.user || 'root'}`, `DB_PASSWORD=${config.password || ''}`, `DB_DATABASE=${config.database || 'zhin_bot'}`);
9
+ break;
10
+ case 'pg':
11
+ envVars.push('# PostgreSQL 数据库配置', `DB_HOST=${config.host || 'localhost'}`, `DB_PORT=${config.port || 5432}`, `DB_USER=${config.user || 'postgres'}`, `DB_PASSWORD=${config.password || ''}`, `DB_DATABASE=${config.database || 'zhin_bot'}`);
12
+ break;
13
+ case 'mongodb':
14
+ envVars.push('# MongoDB 数据库配置', `DB_URL=${config.url || 'mongodb://localhost:27017'}`, `DB_NAME=${config.dbName || 'zhin_bot'}`);
15
+ break;
16
+ case 'redis':
17
+ envVars.push('# Redis 数据库配置', `REDIS_HOST=${config.socket?.host || 'localhost'}`, `REDIS_PORT=${config.socket?.port || 6379}`, `REDIS_PASSWORD=${config.password || ''}`, `REDIS_DB=${config.database || 0}`);
18
+ break;
19
+ case 'sqlite':
20
+ default:
21
+ // SQLite 不需要额外的环境变量
22
+ break;
23
+ }
24
+ return envVars.length > 0 ? `\n\n${envVars.join('\n')}` : '';
25
+ }
26
+ // 生成数据库配置代码
27
+ export function generateDatabaseConfig(config, format) {
28
+ // 根据数据库类型生成使用环境变量的配置
29
+ let configObj = { dialect: config.dialect };
30
+ switch (config.dialect) {
31
+ case 'mysql':
32
+ configObj = {
33
+ dialect: 'mysql',
34
+ host: format === 'yaml' ? '${DB_HOST}' : 'env.DB_HOST',
35
+ port: format === 'yaml' ? '${DB_PORT}' : 'parseInt(env.DB_PORT || "3306")',
36
+ user: format === 'yaml' ? '${DB_USER}' : 'env.DB_USER',
37
+ password: format === 'yaml' ? '${DB_PASSWORD}' : 'env.DB_PASSWORD',
38
+ database: format === 'yaml' ? '${DB_DATABASE}' : 'env.DB_DATABASE'
39
+ };
40
+ break;
41
+ case 'pg':
42
+ configObj = {
43
+ dialect: 'pg',
44
+ host: format === 'yaml' ? '${DB_HOST}' : 'env.DB_HOST',
45
+ port: format === 'yaml' ? '${DB_PORT}' : 'parseInt(env.DB_PORT || "5432")',
46
+ user: format === 'yaml' ? '${DB_USER}' : 'env.DB_USER',
47
+ password: format === 'yaml' ? '${DB_PASSWORD}' : 'env.DB_PASSWORD',
48
+ database: format === 'yaml' ? '${DB_DATABASE}' : 'env.DB_DATABASE'
49
+ };
50
+ break;
51
+ case 'mongodb':
52
+ configObj = {
53
+ dialect: 'mongodb',
54
+ url: format === 'yaml' ? '${DB_URL}' : 'env.DB_URL',
55
+ dbName: format === 'yaml' ? '${DB_NAME}' : 'env.DB_NAME'
56
+ };
57
+ break;
58
+ case 'redis':
59
+ configObj = {
60
+ dialect: 'redis',
61
+ socket: {
62
+ host: format === 'yaml' ? '${REDIS_HOST}' : 'env.REDIS_HOST',
63
+ port: format === 'yaml' ? '${REDIS_PORT}' : 'parseInt(env.REDIS_PORT || "6379")'
64
+ },
65
+ password: format === 'yaml' ? '${REDIS_PASSWORD}' : 'env.REDIS_PASSWORD || undefined',
66
+ database: format === 'yaml' ? '${REDIS_DB}' : 'parseInt(env.REDIS_DB || "0")'
67
+ };
68
+ break;
69
+ case 'sqlite':
70
+ default:
71
+ configObj = config;
72
+ break;
73
+ }
74
+ switch (format) {
75
+ case 'ts':
76
+ case 'js':
77
+ if (config.dialect === 'sqlite') {
78
+ return `database: ${JSON.stringify(configObj, null, 2).replace(/^/gm, ' ').trim()},`;
79
+ }
80
+ else {
81
+ // 对于其他数据库,手动构建配置以保持可读性
82
+ let configLines = ['{'];
83
+ configLines.push(` dialect: '${configObj.dialect}',`);
84
+ Object.entries(configObj).forEach(([key, value]) => {
85
+ if (key === 'dialect')
86
+ return;
87
+ if (typeof value === 'object' && value !== null) {
88
+ configLines.push(` ${key}: {`);
89
+ Object.entries(value).forEach(([subKey, subValue]) => {
90
+ if (typeof subValue === 'string' && subValue.startsWith('env.')) {
91
+ configLines.push(` ${subKey}: ${subValue},`);
92
+ }
93
+ else if (typeof subValue === 'string' && subValue.includes('parseInt(')) {
94
+ configLines.push(` ${subKey}: ${subValue},`);
95
+ }
96
+ else {
97
+ configLines.push(` ${subKey}: '${subValue}',`);
98
+ }
99
+ });
100
+ configLines.push(' },');
101
+ }
102
+ else if (typeof value === 'string' && value.startsWith('env.')) {
103
+ configLines.push(` ${key}: ${value},`);
104
+ }
105
+ else if (typeof value === 'string' && value.includes('parseInt(')) {
106
+ configLines.push(` ${key}: ${value},`);
107
+ }
108
+ else {
109
+ configLines.push(` ${key}: '${value}',`);
110
+ }
111
+ });
112
+ configLines.push(' }');
113
+ return `database: ${configLines.join('\n ')},`;
114
+ }
115
+ case 'yaml':
116
+ return Object.entries(configObj)
117
+ .map(([key, value]) => ` ${key}: ${typeof value === 'object' ? JSON.stringify(value).replace(/"/g, '') : value}`)
118
+ .join('\n');
119
+ case 'json':
120
+ const jsonStr = JSON.stringify(configObj, null, 2).replace(/^/gm, ' ');
121
+ return ` "database": ${jsonStr},`;
122
+ default:
123
+ return '';
124
+ }
125
+ }
126
+ // 创建配置文件
127
+ export async function createConfigFile(appPath, format, options) {
128
+ const databaseConfig = options.database ? generateDatabaseConfig(options.database, format) : '';
129
+ const configMap = {
130
+ ts: ['zhin.config.ts',
131
+ `import { defineConfig, LogLevel } from 'zhin.js';
132
+
133
+ export default defineConfig(async (env) => {
134
+ return {
135
+ ${databaseConfig ? ` ${databaseConfig.replace(/^ /, '')}` : ''}
136
+ bots: [{
137
+ name: \`\${process.pid}\`,
138
+ context: 'process'
139
+ }],
140
+ log_level: LogLevel.INFO,
141
+ log: {
142
+ maxDays: 7,
143
+ maxRecords: 10000,
144
+ cleanupInterval: 24
145
+ },
146
+ plugin_dirs: [
147
+ env.PLUGIN_DIR || './src/plugins',
148
+ 'node_modules',
149
+ 'node_modules/@zhin.js'
150
+ ],
151
+ plugins: [
152
+ 'adapter-process',
153
+ 'http',
154
+ 'console',
155
+ 'example'
156
+ ],
157
+ http: {
158
+ port: 8086,
159
+ username: env.HTTP_USERNAME,
160
+ password: env.HTTP_PASSWORD,
161
+ base: '/api'
162
+ },
163
+ debug: env.DEBUG === 'true'
164
+ };
165
+ });
166
+ `],
167
+ js: ['zhin.config.js',
168
+ `import { defineConfig, LogLevel } from 'zhin.js';
169
+
170
+ export default defineConfig(async (env) => {
171
+ return {
172
+ ${databaseConfig ? ` ${databaseConfig.replace(/^ /, '')}` : ''}
173
+ bots: [{
174
+ name: \`\${process.pid}\`,
175
+ context: 'process'
176
+ }],
177
+ log_level: LogLevel.INFO,
178
+ log: {
179
+ maxDays: 7,
180
+ maxRecords: 10000,
181
+ cleanupInterval: 24
182
+ },
183
+ plugin_dirs: [
184
+ env.PLUGIN_DIR || './src/plugins',
185
+ 'node_modules',
186
+ 'node_modules/@zhin.js'
187
+ ],
188
+ plugins: [
189
+ 'adapter-process',
190
+ 'http',
191
+ 'console',
192
+ 'example'
193
+ ],
194
+ http: {
195
+ port: 8086,
196
+ username: env.HTTP_USERNAME,
197
+ password: env.HTTP_PASSWORD,
198
+ base: '/api'
199
+ },
200
+ debug: env.DEBUG === 'true'
201
+ };
202
+ });
203
+ `],
204
+ yaml: ['zhin.config.yml',
205
+ `${databaseConfig ? `database:\n${databaseConfig}\n\n` : ''}bots:
206
+ - name: \${process.pid}
207
+ context: process
208
+
209
+ log_level: 1
210
+ log:
211
+ maxDays: 7
212
+ maxRecords: 10000
213
+ cleanupInterval: 24
214
+
215
+ plugin_dirs:
216
+ - ./src/plugins
217
+ - node_modules
218
+ - node_modules/@zhin.js
219
+
220
+ plugins:
221
+ - adapter-process
222
+ - http
223
+ - console
224
+ - example
225
+
226
+ http:
227
+ port: 8086
228
+ username: \${HTTP_USERNAME}
229
+ password: \${HTTP_PASSWORD}
230
+ base: /api
231
+
232
+ debug: false
233
+ `],
234
+ json: ['zhin.config.json',
235
+ `{
236
+ ${databaseConfig ? `${databaseConfig}` : ''}
237
+ "bots": [{
238
+ "name": "\${process.pid}",
239
+ "context": "process"
240
+ }],
241
+ "log_level": 1,
242
+ "log": {
243
+ "maxDays": 7,
244
+ "maxRecords": 10000,
245
+ "cleanupInterval": 24
246
+ },
247
+ "plugin_dirs": [
248
+ "./src/plugins",
249
+ "node_modules",
250
+ "node_modules/@zhin.js"
251
+ ],
252
+ "plugins": [
253
+ "adapter-process",
254
+ "http",
255
+ "console",
256
+ "example"
257
+ ],
258
+ "http": {
259
+ "port": 8086,
260
+ "username": "\${HTTP_USERNAME}",
261
+ "password": "\${HTTP_PASSWORD}",
262
+ "base": "/api"
263
+ },
264
+ "debug": false
265
+ }
266
+ `]
267
+ };
268
+ const [filename, content] = configMap[format] || configMap.ts;
269
+ await fs.writeFile(path.join(appPath, filename), content);
270
+ }
271
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { DatabaseConfig } from './types.js';
2
+ export declare function configureDatabaseOptions(): Promise<DatabaseConfig>;
3
+ //# sourceMappingURL=database.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG5C,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,cAAc,CAAC,CA+BxE"}
@@ -0,0 +1,260 @@
1
+ import inquirer from 'inquirer';
2
+ // 配置数据库选项
3
+ export async function configureDatabaseOptions() {
4
+ const { dialect } = await inquirer.prompt([
5
+ {
6
+ type: 'list',
7
+ name: 'dialect',
8
+ message: '选择数据库类型:',
9
+ choices: [
10
+ { name: 'SQLite (推荐, 零配置)', value: 'sqlite' },
11
+ { name: 'MySQL', value: 'mysql' },
12
+ { name: 'PostgreSQL', value: 'pg' },
13
+ { name: 'MongoDB', value: 'mongodb' },
14
+ { name: 'Redis', value: 'redis' }
15
+ ],
16
+ default: 'sqlite'
17
+ }
18
+ ]);
19
+ switch (dialect) {
20
+ case 'sqlite':
21
+ return await configureSQLite();
22
+ case 'mysql':
23
+ return await configureMySQL();
24
+ case 'pg':
25
+ return await configurePostgreSQL();
26
+ case 'mongodb':
27
+ return await configureMongoDB();
28
+ case 'redis':
29
+ return await configureRedis();
30
+ default:
31
+ throw new Error(`未支持的数据库类型: ${dialect}`);
32
+ }
33
+ }
34
+ // SQLite 配置
35
+ async function configureSQLite() {
36
+ const { filename, mode } = await inquirer.prompt([
37
+ {
38
+ type: 'input',
39
+ name: 'filename',
40
+ message: 'SQLite 数据库文件路径:',
41
+ default: './data/bot.db',
42
+ validate: (input) => {
43
+ if (!input.trim())
44
+ return '文件路径不能为空';
45
+ return true;
46
+ }
47
+ },
48
+ {
49
+ type: 'list',
50
+ name: 'mode',
51
+ message: 'SQLite 模式:',
52
+ choices: [
53
+ { name: 'WAL (推荐, 并发性能好)', value: 'wal' },
54
+ { name: 'DELETE (默认)', value: 'delete' },
55
+ { name: 'MEMORY (内存数据库)', value: 'memory' }
56
+ ],
57
+ default: 'wal'
58
+ }
59
+ ]);
60
+ return {
61
+ dialect: 'sqlite',
62
+ filename,
63
+ mode
64
+ };
65
+ }
66
+ // MySQL 配置
67
+ async function configureMySQL() {
68
+ const config = await inquirer.prompt([
69
+ {
70
+ type: 'input',
71
+ name: 'host',
72
+ message: 'MySQL 主机地址:',
73
+ default: 'localhost'
74
+ },
75
+ {
76
+ type: 'input',
77
+ name: 'port',
78
+ message: 'MySQL 端口:',
79
+ default: '3306',
80
+ validate: (input) => {
81
+ const port = parseInt(input);
82
+ if (isNaN(port) || port < 1 || port > 65535) {
83
+ return '请输入有效的端口号 (1-65535)';
84
+ }
85
+ return true;
86
+ }
87
+ },
88
+ {
89
+ type: 'input',
90
+ name: 'user',
91
+ message: 'MySQL 用户名:',
92
+ default: 'root'
93
+ },
94
+ {
95
+ type: 'password',
96
+ name: 'password',
97
+ message: 'MySQL 密码:'
98
+ },
99
+ {
100
+ type: 'input',
101
+ name: 'database',
102
+ message: 'MySQL 数据库名:',
103
+ default: 'zhin_bot',
104
+ validate: (input) => {
105
+ if (!input.trim())
106
+ return '数据库名不能为空';
107
+ return true;
108
+ }
109
+ }
110
+ ]);
111
+ return {
112
+ dialect: 'mysql',
113
+ host: config.host,
114
+ port: parseInt(config.port),
115
+ user: config.user,
116
+ password: config.password,
117
+ database: config.database
118
+ };
119
+ }
120
+ // PostgreSQL 配置
121
+ async function configurePostgreSQL() {
122
+ const config = await inquirer.prompt([
123
+ {
124
+ type: 'input',
125
+ name: 'host',
126
+ message: 'PostgreSQL 主机地址:',
127
+ default: 'localhost'
128
+ },
129
+ {
130
+ type: 'input',
131
+ name: 'port',
132
+ message: 'PostgreSQL 端口:',
133
+ default: '5432',
134
+ validate: (input) => {
135
+ const port = parseInt(input);
136
+ if (isNaN(port) || port < 1 || port > 65535) {
137
+ return '请输入有效的端口号 (1-65535)';
138
+ }
139
+ return true;
140
+ }
141
+ },
142
+ {
143
+ type: 'input',
144
+ name: 'user',
145
+ message: 'PostgreSQL 用户名:',
146
+ default: 'postgres'
147
+ },
148
+ {
149
+ type: 'password',
150
+ name: 'password',
151
+ message: 'PostgreSQL 密码:'
152
+ },
153
+ {
154
+ type: 'input',
155
+ name: 'database',
156
+ message: 'PostgreSQL 数据库名:',
157
+ default: 'zhin_bot',
158
+ validate: (input) => {
159
+ if (!input.trim())
160
+ return '数据库名不能为空';
161
+ return true;
162
+ }
163
+ }
164
+ ]);
165
+ return {
166
+ dialect: 'pg',
167
+ host: config.host,
168
+ port: parseInt(config.port),
169
+ user: config.user,
170
+ password: config.password,
171
+ database: config.database
172
+ };
173
+ }
174
+ // MongoDB 配置
175
+ async function configureMongoDB() {
176
+ const { url, dbName } = await inquirer.prompt([
177
+ {
178
+ type: 'input',
179
+ name: 'url',
180
+ message: 'MongoDB 连接字符串:',
181
+ default: 'mongodb://localhost:27017',
182
+ validate: (input) => {
183
+ if (!input.trim())
184
+ return '连接字符串不能为空';
185
+ if (!input.startsWith('mongodb://') && !input.startsWith('mongodb+srv://')) {
186
+ return '请输入有效的 MongoDB 连接字符串';
187
+ }
188
+ return true;
189
+ }
190
+ },
191
+ {
192
+ type: 'input',
193
+ name: 'dbName',
194
+ message: 'MongoDB 数据库名:',
195
+ default: 'zhin_bot',
196
+ validate: (input) => {
197
+ if (!input.trim())
198
+ return '数据库名不能为空';
199
+ return true;
200
+ }
201
+ }
202
+ ]);
203
+ return {
204
+ dialect: 'mongodb',
205
+ url,
206
+ dbName
207
+ };
208
+ }
209
+ // Redis 配置
210
+ async function configureRedis() {
211
+ const config = await inquirer.prompt([
212
+ {
213
+ type: 'input',
214
+ name: 'host',
215
+ message: 'Redis 主机地址:',
216
+ default: 'localhost'
217
+ },
218
+ {
219
+ type: 'input',
220
+ name: 'port',
221
+ message: 'Redis 端口:',
222
+ default: '6379',
223
+ validate: (input) => {
224
+ const port = parseInt(input);
225
+ if (isNaN(port) || port < 1 || port > 65535) {
226
+ return '请输入有效的端口号 (1-65535)';
227
+ }
228
+ return true;
229
+ }
230
+ },
231
+ {
232
+ type: 'password',
233
+ name: 'password',
234
+ message: 'Redis 密码 (可选):'
235
+ },
236
+ {
237
+ type: 'input',
238
+ name: 'db',
239
+ message: 'Redis 数据库索引:',
240
+ default: '0',
241
+ validate: (input) => {
242
+ const db = parseInt(input);
243
+ if (isNaN(db) || db < 0) {
244
+ return '请输入有效的数据库索引 (>= 0)';
245
+ }
246
+ return true;
247
+ }
248
+ }
249
+ ]);
250
+ return {
251
+ dialect: 'redis',
252
+ socket: {
253
+ host: config.host,
254
+ port: parseInt(config.port)
255
+ },
256
+ password: config.password || undefined,
257
+ database: parseInt(config.db)
258
+ };
259
+ }
260
+ //# sourceMappingURL=database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"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"}