nodebbs 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +83 -99
  2. package/dist/commands/clean/index.d.ts +11 -0
  3. package/dist/commands/clean/index.js +93 -0
  4. package/dist/commands/db/backup.d.ts +9 -0
  5. package/dist/commands/db/backup.js +78 -0
  6. package/dist/commands/db/generate.d.ts +3 -0
  7. package/dist/commands/db/generate.js +9 -3
  8. package/dist/commands/db/index.d.ts +3 -0
  9. package/dist/commands/db/index.js +9 -3
  10. package/dist/commands/db/migrate.d.ts +3 -0
  11. package/dist/commands/db/migrate.js +8 -2
  12. package/dist/commands/db/push.d.ts +3 -0
  13. package/dist/commands/db/push.js +8 -2
  14. package/dist/commands/db/reset.d.ts +3 -0
  15. package/dist/commands/db/reset.js +10 -4
  16. package/dist/commands/db/seed.d.ts +3 -0
  17. package/dist/commands/db/seed.js +9 -3
  18. package/dist/commands/logs/api.d.ts +3 -0
  19. package/dist/commands/logs/api.js +8 -2
  20. package/dist/commands/logs/db.d.ts +3 -0
  21. package/dist/commands/logs/db.js +8 -2
  22. package/dist/commands/logs/index.d.ts +3 -0
  23. package/dist/commands/logs/index.js +8 -2
  24. package/dist/commands/logs/redis.d.ts +3 -0
  25. package/dist/commands/logs/redis.js +8 -2
  26. package/dist/commands/logs/web.d.ts +3 -0
  27. package/dist/commands/logs/web.js +9 -3
  28. package/dist/commands/restart/index.d.ts +3 -0
  29. package/dist/commands/restart/index.js +10 -2
  30. package/dist/commands/shell/api.d.ts +3 -0
  31. package/dist/commands/shell/api.js +9 -3
  32. package/dist/commands/shell/db.d.ts +3 -0
  33. package/dist/commands/shell/db.js +9 -3
  34. package/dist/commands/shell/redis.d.ts +3 -0
  35. package/dist/commands/shell/redis.js +9 -3
  36. package/dist/commands/shell/web.d.ts +3 -0
  37. package/dist/commands/shell/web.js +9 -3
  38. package/dist/commands/{dev → start}/index.d.ts +2 -2
  39. package/dist/commands/start/index.js +110 -0
  40. package/dist/commands/status/index.d.ts +3 -0
  41. package/dist/commands/status/index.js +8 -2
  42. package/dist/commands/stop/index.d.ts +1 -0
  43. package/dist/commands/stop/index.js +7 -1
  44. package/dist/templates/env +61 -0
  45. package/dist/utils/docker.js +3 -11
  46. package/dist/utils/env.js +19 -9
  47. package/dist/utils/selection.d.ts +5 -0
  48. package/dist/utils/selection.js +24 -0
  49. package/dist/utils/template.d.ts +11 -0
  50. package/dist/utils/template.js +18 -0
  51. package/oclif.manifest.json +380 -89
  52. package/package.json +21 -21
  53. package/dist/commands/deploy/index.d.ts +0 -8
  54. package/dist/commands/deploy/index.js +0 -95
  55. package/dist/commands/dev/index.js +0 -59
  56. package/dist/commands/setup/index.d.ts +0 -5
  57. package/dist/commands/setup/index.js +0 -12
package/README.md CHANGED
@@ -40,36 +40,24 @@ npx nodebbs [command]
40
40
 
41
41
  ## 🚀 快速开始
42
42
 
43
- ### 1. 初始化项目
43
+ ### 1. 启动服务
44
44
 
45
45
  ```bash
46
- # 首次使用,初始化项目环境
47
- npx nodebbs setup
48
- ```
49
-
50
- 这会创建 `.env` 文件,请编辑该文件并修改:
51
- - `POSTGRES_PASSWORD` - 数据库密码
52
- - `REDIS_PASSWORD` - Redis 密码
53
- - `JWT_SECRET` - JWT 密钥
46
+ # 启动所有服务(生产模式,包含完整检查)
47
+ npx nodebbs start
54
48
 
55
- ### 2. 启动开发环境
56
-
57
- ```bash
58
- # 启动所有服务
59
- npx nodebbs dev
60
-
61
- # 或者重新构建并启动
62
- npx nodebbs dev --rebuild
49
+ # 重新构建并启动(跳过检查,用于更新)
50
+ npx nodebbs start --build
63
51
  ```
64
52
 
65
- ### 3. 查看服务状态
53
+ ### 2. 查看服务状态
66
54
 
67
55
  ```bash
68
56
  # 查看所有服务状态
69
57
  npx nodebbs status
70
58
  ```
71
59
 
72
- ### 4. 访问应用
60
+ ### 3. 访问应用
73
61
 
74
62
  - **Web 前端**: http://localhost:3100
75
63
  - **API 文档**: http://localhost:7100/docs
@@ -77,62 +65,47 @@ npx nodebbs status
77
65
 
78
66
  ## 📚 命令参考
79
67
 
80
- ### 核心命令
81
-
82
- #### `nodebbs setup`
83
- 初始化项目(首次使用)
68
+ #### `nodebbs start`
69
+ 启动 NodeBBS 服务
84
70
 
85
71
  ```bash
86
- npx nodebbs setup
87
- ```
88
-
89
- #### `nodebbs dev`
90
- 启动开发环境
91
-
92
- ```bash
93
- # 启动所有服务
94
- npx nodebbs dev
95
-
96
- # 重新构建并启动
97
- npx nodebbs dev --rebuild
98
- npx nodebbs dev -r
72
+ # 交互式启动(推荐初次使用)
73
+ npx nodebbs start
99
74
 
100
75
  # 指定环境启动
101
- npx nodebbs dev -e production
102
- npx nodebbs dev -e lowmem
103
- npx nodebbs dev -e basic
76
+ npx nodebbs start -e production
77
+
78
+ # 重新构建并启动(跳过检查)
79
+ npx nodebbs start --build
104
80
  ```
105
81
 
106
82
  **参数**:
107
83
  - `-e, --env` - 部署环境(production, lowmem, basic)
108
- - `-r, --rebuild` - 重新构建镜像
84
+ - `-b, --build` - 重新构建镜像并启动(跳过健康检查和初始化)
109
85
 
110
- #### `nodebbs deploy`
111
- 部署到生产环境
112
-
113
- ```bash
114
- # 完整部署流程
115
- npx nodebbs deploy
116
-
117
- # 指定环境部署
118
- npx nodebbs deploy -e production
119
- ```
120
-
121
- 包含:
86
+ 启动流程包含:
122
87
  - Docker 环境检查
123
88
  - 环境变量验证
124
89
  - 镜像构建
125
90
  - 服务启动
126
- - 健康检查
127
- - 数据库初始化(可选)
91
+ - 健康检查(默认开启,使用 `--build` 跳过)
92
+ - 数据库初始化(默认开启,使用 `--build` 跳过)
93
+
94
+ #### `nodebbs restart`
95
+ 重启所有服务(不更新镜像,支持环境选择)
96
+
97
+ ```bash
98
+ npx nodebbs restart
99
+ npx nodebbs restart -e production
100
+ ```
128
101
 
129
102
  #### `nodebbs stop`
130
- 停止服务
103
+ 停止服务(支持环境选择)
131
104
 
132
105
  ```bash
133
- # 停止所有服务
134
106
  npx nodebbs stop
135
-
107
+ npx nodebbs stop -e production
108
+ ```
136
109
  # 停止服务并删除数据卷(危险!)
137
110
  npx nodebbs stop --volumes
138
111
  npx nodebbs stop -v
@@ -141,27 +114,25 @@ npx nodebbs stop -v
141
114
  **参数**:
142
115
  - `-v, --volumes` - 同时删除数据卷
143
116
 
144
- #### `nodebbs restart`
145
- 重启所有服务
146
-
147
- ```bash
148
- npx nodebbs restart
149
- ```
150
-
151
117
  #### `nodebbs status`
152
118
  查看服务状态
153
119
 
154
120
  ```bash
155
121
  npx nodebbs status
122
+ # 查看指定环境状态
123
+ npx nodebbs status -e production
156
124
  ```
157
125
 
158
126
  ### 日志管理
159
127
 
160
128
  #### `nodebbs logs`
161
- 查看所有服务日志
129
+ 查看服务日志
162
130
 
163
131
  ```bash
132
+ # 查看所有日志
164
133
  npx nodebbs logs
134
+ # 查看指定环境日志
135
+ npx nodebbs logs -e production
165
136
  ```
166
137
 
167
138
  #### `nodebbs logs:api`
@@ -194,11 +165,14 @@ npx nodebbs logs:redis
194
165
 
195
166
  ### Shell 访问
196
167
 
197
- #### `nodebbs shell:api`
198
- 进入 API 容器
168
+ #### `nodebbs shell`
169
+ 进入容器 Shell (支持 api, web, db, redis)
199
170
 
200
171
  ```bash
172
+ # 进入 API 容器
201
173
  npx nodebbs shell:api
174
+ # 进入生产环境 API 容器
175
+ npx nodebbs shell:api -e production
202
176
  ```
203
177
 
204
178
  #### `nodebbs shell:web`
@@ -266,30 +240,49 @@ npx nodebbs db:seed
266
240
  npx nodebbs db:reset
267
241
  ```
268
242
 
243
+ #### `nodebbs db:backup`
244
+ 备份数据库
245
+
246
+ ```bash
247
+ npx nodebbs db:backup
248
+ npx nodebbs db:backup -o backup.sql
249
+ ```
250
+
251
+ #### `nodebbs clean`
252
+ 清理 Docker 缓存和残留资源
253
+
254
+ ```bash
255
+ # 交互式选择清理项目
256
+ npx nodebbs clean
257
+
258
+ # 自动清理所有(构建缓存、无用镜像、网络)
259
+ npx nodebbs clean -a
260
+
261
+ # 仅清理构建缓存
262
+ npx nodebbs clean --cache
263
+ ```
264
+
269
265
  ## 🎯 使用场景
270
266
 
271
267
  ### 场景 1:新开发者加入项目
272
268
 
273
269
  ```bash
274
- # 1. 初始化项目
275
- npx nodebbs setup
270
+ # 1. 启动服务
271
+ npx nodebbs start
276
272
 
277
- # 2. 启动开发环境
278
- npx nodebbs dev
279
-
280
- # 3. 初始化数据库
273
+ # 2. 初始化数据库
281
274
  npx nodebbs db:push
282
275
  npx nodebbs db:seed
283
276
 
284
- # 4. 查看服务状态
277
+ # 3. 查看服务状态
285
278
  npx nodebbs status
286
279
  ```
287
280
 
288
281
  ### 场景 2:日常开发
289
282
 
290
283
  ```bash
291
- # 启动开发环境
292
- npx nodebbs dev
284
+ # 启动服务
285
+ npx nodebbs start
293
286
 
294
287
  # 查看 API 日志
295
288
  npx nodebbs logs:api
@@ -311,7 +304,7 @@ npx nodebbs db:reset
311
304
  npx nodebbs stop
312
305
 
313
306
  # 重新构建并启动
314
- npx nodebbs dev --rebuild
307
+ npx nodebbs start --build
315
308
 
316
309
  # 查看日志确认启动成功
317
310
  npx nodebbs logs
@@ -321,7 +314,7 @@ npx nodebbs logs
321
314
 
322
315
  ```bash
323
316
  # 部署到生产环境
324
- npx nodebbs deploy -e production
317
+ npx nodebbs start -e production
325
318
 
326
319
  # 查看服务状态
327
320
  npx nodebbs status
@@ -355,13 +348,11 @@ npx nodebbs shell:db
355
348
 
356
349
  | Makefile 命令 | NodeBBS CLI 命令 |
357
350
  |--------------|-----------------|
358
- | `make init` | `npx nodebbs setup` |
359
- | `make up` | `npx nodebbs dev` |
360
- | `make build` | `npx nodebbs dev --rebuild` |
361
- | `make rebuild` | `npx nodebbs dev --rebuild` |
362
- | `ENV=prod make rebuild` | `npx nodebbs deploy -e production` |
351
+ | `make up` | `npx nodebbs start` |
352
+ | `make build` | `npx nodebbs start --build` |
353
+ | `make rebuild` | `npx nodebbs start --build` |
354
+ | `ENV=prod make rebuild` | `npx nodebbs start -e production --build` |
363
355
  | `make down` | `npx nodebbs stop` |
364
- | `make restart` | `npx nodebbs restart` |
365
356
  | `make ps` | `npx nodebbs status` |
366
357
  | `make logs` | `npx nodebbs logs` |
367
358
  | `make logs-api` | `npx nodebbs logs:api` |
@@ -400,6 +391,8 @@ API_URL=http://localhost:7100
400
391
  CORS_ORIGIN=*
401
392
  ```
402
393
 
394
+ > **提示**:可以使用 `openssl rand -hex 32` 命令生成安全的随机密钥。
395
+
403
396
  ## 🛠️ 高级用法
404
397
 
405
398
  ### 内置模板
@@ -408,7 +401,7 @@ NodeBBS CLI 内置了 Docker Compose 配置文件,即使项目中没有这些
408
401
 
409
402
  ```bash
410
403
  # 在任何目录运行
411
- npx nodebbs dev
404
+ npx nodebbs start
412
405
  ```
413
406
 
414
407
  CLI 会自动:
@@ -474,7 +467,7 @@ npx nodebbs stop --volumes
474
467
 
475
468
  ```bash
476
469
  # 克隆仓库
477
- git clone https://github.com/nodebbs/nodebbs.git
470
+ git clone https://github.com/aiprojecthub/nodebbs.git
478
471
  cd nodebbs
479
472
 
480
473
  # 安装依赖
@@ -493,26 +486,17 @@ pnpm build
493
486
  # 查看帮助
494
487
  ./bin/run.js --help
495
488
 
496
- # 测试 dev 命令
497
- ./bin/run.js dev --help
489
+ # 测试 start 命令
490
+ ./bin/run.js start --help
498
491
 
499
492
  # 测试 logs 命令
500
493
  ./bin/run.js logs --help
501
494
  ```
502
495
 
503
- ## 🤝 贡献
504
-
505
- 欢迎贡献!请查看 [CONTRIBUTING.md](CONTRIBUTING.md) 了解详情。
506
-
507
- ## 📄 许可证
508
-
509
- MIT License - 详见 [LICENSE](LICENSE) 文件
510
-
511
496
  ## 🔗 相关链接
512
497
 
513
- - [NodeBBS 项目](https://github.com/nodebbs/nodebbs)
514
- - [问题反馈](https://github.com/nodebbs/nodebbs/issues)
515
- - [更新日志](CHANGELOG.md)
498
+ - [NodeBBS 项目](https://github.com/aiprojecthub/nodebbs)
499
+ - [问题反馈](https://github.com/aiprojecthub/nodebbs/issues)
516
500
 
517
501
  ## 💡 提示
518
502
 
@@ -0,0 +1,11 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Clean extends Command {
3
+ static description: string;
4
+ static flags: {
5
+ all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
6
+ cache: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ images: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ };
10
+ run(): Promise<void>;
11
+ }
@@ -0,0 +1,93 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { checkbox, confirm } from '@inquirer/prompts';
3
+ import { logger } from '../../utils/logger.js';
4
+ import { execa } from 'execa';
5
+ export default class Clean extends Command {
6
+ static description = '清理 Docker 缓存和残留资源';
7
+ static flags = {
8
+ all: Flags.boolean({
9
+ char: 'a',
10
+ description: '清理所有 (构建缓存、无用镜像、网络)',
11
+ default: false,
12
+ }),
13
+ cache: Flags.boolean({
14
+ description: '清理构建缓存',
15
+ default: false,
16
+ }),
17
+ images: Flags.boolean({
18
+ description: '清理无用镜像 (dangling)',
19
+ default: false,
20
+ }),
21
+ force: Flags.boolean({
22
+ char: 'f',
23
+ description: '跳过确认提示',
24
+ default: false,
25
+ }),
26
+ };
27
+ async run() {
28
+ const { flags } = await this.parse(Clean);
29
+ let targets = [];
30
+ // Determine targets from flags
31
+ if (flags.all) {
32
+ targets = ['cache', 'images', 'networks'];
33
+ }
34
+ else {
35
+ if (flags.cache)
36
+ targets.push('cache');
37
+ if (flags.images)
38
+ targets.push('images');
39
+ }
40
+ // Interactive selection if no flags
41
+ if (targets.length === 0) {
42
+ targets = await checkbox({
43
+ message: '请选择要清理的项目:',
44
+ choices: [
45
+ { name: '构建缓存 (Build Cache)', value: 'cache' },
46
+ { name: '无用镜像 (Dangling Images)', value: 'images' },
47
+ { name: '无用网络 (Unused Networks)', value: 'networks' },
48
+ ],
49
+ });
50
+ }
51
+ if (targets.length === 0) {
52
+ logger.info('未选择任何清理项目。');
53
+ return;
54
+ }
55
+ // Confirmation
56
+ if (!flags.force) {
57
+ logger.warning(`即将清理: ${targets.join(', ')}`);
58
+ const confirmed = await confirm({
59
+ message: '确认继续?',
60
+ default: false
61
+ });
62
+ if (!confirmed) {
63
+ logger.info('操作已取消。');
64
+ return;
65
+ }
66
+ }
67
+ // Execute
68
+ try {
69
+ if (targets.includes('cache')) {
70
+ logger.info('正在清理构建缓存...');
71
+ await execa('docker', ['builder', 'prune', '-f'], { stdio: 'inherit' });
72
+ logger.success('构建缓存已清理');
73
+ }
74
+ if (targets.includes('images')) {
75
+ logger.info('正在清理无用镜像...');
76
+ await execa('docker', ['image', 'prune', '-f'], { stdio: 'inherit' });
77
+ logger.success('无用镜像已清理');
78
+ }
79
+ if (targets.includes('networks')) {
80
+ logger.info('正在清理无用网络...');
81
+ await execa('docker', ['network', 'prune', '-f'], { stdio: 'inherit' });
82
+ logger.success('无用网络已清理');
83
+ }
84
+ }
85
+ catch (error) {
86
+ logger.error('清理过程中发生错误');
87
+ if (error instanceof Error) {
88
+ logger.error(error.message);
89
+ }
90
+ this.exit(1);
91
+ }
92
+ }
93
+ }
@@ -0,0 +1,9 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class DbBackup extends Command {
3
+ static description: string;
4
+ static flags: {
5
+ env: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
+ output: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
@@ -0,0 +1,78 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { getComposeFiles } from '../../utils/docker.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ import { execa } from 'execa';
5
+ import fs from 'node:fs';
6
+ import path from 'node:path';
7
+ import dotenv from 'dotenv';
8
+ import { EnvFlag, selectEnvironment } from '../../utils/selection.js';
9
+ export default class DbBackup extends Command {
10
+ static description = '备份数据库 (PostgreSQL)';
11
+ static flags = {
12
+ env: EnvFlag,
13
+ output: Flags.string({
14
+ char: 'o',
15
+ description: '输出文件路径',
16
+ }),
17
+ };
18
+ async run() {
19
+ const { flags } = await this.parse(DbBackup);
20
+ // 1. Select Environment
21
+ const env = await selectEnvironment(flags.env);
22
+ // 2. Determine Output File
23
+ let outputFile = flags.output;
24
+ if (!outputFile) {
25
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
26
+ outputFile = `backup_${timestamp}.sql`;
27
+ }
28
+ // Ensure absolute path
29
+ const outputPath = path.resolve(process.cwd(), outputFile);
30
+ // 3. Get Compose Files
31
+ const { files, isBuiltIn } = await getComposeFiles(env);
32
+ logger.info(`正在备份数据库到: ${outputPath}`);
33
+ logger.info('环境: ' + env);
34
+ // Load Env Config
35
+ const envConfig = dotenv.config().parsed || {};
36
+ const dbUser = envConfig.POSTGRES_USER || 'postgres';
37
+ const dbName = envConfig.POSTGRES_DB || 'nodebbs';
38
+ const dbPassword = envConfig.POSTGRES_PASSWORD;
39
+ // 4. Construct Compose Args
40
+ const composeArgs = files.flatMap(f => ['-f', f]);
41
+ if (isBuiltIn) {
42
+ composeArgs.push('--project-directory', process.cwd());
43
+ }
44
+ // 5. Run pg_dump
45
+ const dumpArgs = [...composeArgs, 'exec', '-T'];
46
+ // Inject password if available
47
+ if (dbPassword) {
48
+ dumpArgs.push('-e', `PGPASSWORD=${dbPassword}`);
49
+ }
50
+ dumpArgs.push('postgres', 'pg_dump', '-U', dbUser, dbName);
51
+ try {
52
+ const subprocess = execa('docker', ['compose', ...dumpArgs]);
53
+ if (subprocess.stdout) {
54
+ subprocess.stdout.pipe(fs.createWriteStream(outputPath));
55
+ }
56
+ await subprocess;
57
+ // check file size
58
+ const stats = fs.statSync(outputPath);
59
+ if (stats.size === 0) {
60
+ logger.error('备份文件为空,备份可能失败。');
61
+ }
62
+ else {
63
+ logger.success(`数据库备份成功!文件大小: ${(stats.size / 1024 / 1024).toFixed(2)} MB`);
64
+ }
65
+ }
66
+ catch (error) {
67
+ logger.error('数据库备份失败');
68
+ if (error instanceof Error) {
69
+ logger.error(error.message);
70
+ }
71
+ // Cleanup empty file if failed
72
+ if (fs.existsSync(outputPath) && fs.statSync(outputPath).size === 0) {
73
+ fs.unlinkSync(outputPath);
74
+ }
75
+ this.exit(1);
76
+ }
77
+ }
78
+ }
@@ -1,5 +1,8 @@
1
1
  import { Command } from '@oclif/core';
2
2
  export default class DbGenerate extends Command {
3
3
  static description: string;
4
+ static flags: {
5
+ env: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
+ };
4
7
  run(): Promise<void>;
5
8
  }
@@ -1,11 +1,17 @@
1
1
  import { Command } from '@oclif/core';
2
2
  import { execCompose, getComposeFiles } from '../../utils/docker.js';
3
3
  import { logger } from '../../utils/logger.js';
4
+ import { EnvFlag, selectEnvironment } from '../../utils/selection.js';
4
5
  export default class DbGenerate extends Command {
5
- static description = '生成数据库迁移文件';
6
+ static description = '生成 Prisma Client (db:generate)';
7
+ static flags = {
8
+ env: EnvFlag,
9
+ };
6
10
  async run() {
7
- const { files, isBuiltIn } = await getComposeFiles('basic');
8
- logger.info('正在生成数据库迁移...');
11
+ const { flags } = await this.parse(DbGenerate);
12
+ const env = await selectEnvironment(flags.env);
13
+ const { files, isBuiltIn } = await getComposeFiles(env);
14
+ logger.info('正在生成 Prisma Client...');
9
15
  await execCompose(files, 'api', ['npm', 'run', 'db:generate'], isBuiltIn);
10
16
  logger.success('数据库迁移文件生成完成');
11
17
  }
@@ -1,5 +1,8 @@
1
1
  import { Command } from '@oclif/core';
2
2
  export default class Db extends Command {
3
3
  static description: string;
4
+ static flags: {
5
+ env: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
+ };
4
7
  run(): Promise<void>;
5
8
  }
@@ -1,11 +1,17 @@
1
1
  import { Command } from '@oclif/core';
2
2
  import { execCompose, getComposeFiles } from '../../utils/docker.js';
3
3
  import { logger } from '../../utils/logger.js';
4
+ import { EnvFlag, selectEnvironment } from '../../utils/selection.js';
4
5
  export default class Db extends Command {
5
- static description = '打开数据库管理界面(Drizzle Studio)';
6
+ static description = '数据库管理命令';
7
+ static flags = {
8
+ env: EnvFlag,
9
+ };
6
10
  async run() {
7
- const { files, isBuiltIn } = await getComposeFiles('basic');
8
- logger.info('正在启动 Drizzle Studio...');
11
+ const { flags } = await this.parse(Db);
12
+ const env = await selectEnvironment(flags.env);
13
+ const { files, isBuiltIn } = await getComposeFiles(env);
14
+ logger.info('正在进入数据库 shell...');
9
15
  await execCompose(files, 'api', ['npm', 'run', 'db:studio'], isBuiltIn);
10
16
  }
11
17
  }
@@ -1,5 +1,8 @@
1
1
  import { Command } from '@oclif/core';
2
2
  export default class DbMigrate extends Command {
3
3
  static description: string;
4
+ static flags: {
5
+ env: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
+ };
4
7
  run(): Promise<void>;
5
8
  }
@@ -1,10 +1,16 @@
1
1
  import { Command } from '@oclif/core';
2
2
  import { execCompose, getComposeFiles } from '../../utils/docker.js';
3
3
  import { logger } from '../../utils/logger.js';
4
+ import { EnvFlag, selectEnvironment } from '../../utils/selection.js';
4
5
  export default class DbMigrate extends Command {
5
- static description = '执行数据库迁移';
6
+ static description = '执行数据库迁移 (db:migrate)';
7
+ static flags = {
8
+ env: EnvFlag,
9
+ };
6
10
  async run() {
7
- const { files, isBuiltIn } = await getComposeFiles('basic');
11
+ const { flags } = await this.parse(DbMigrate);
12
+ const env = await selectEnvironment(flags.env);
13
+ const { files, isBuiltIn } = await getComposeFiles(env);
8
14
  logger.info('正在执行数据库迁移...');
9
15
  await execCompose(files, 'api', ['npm', 'run', 'db:migrate'], isBuiltIn);
10
16
  logger.success('数据库迁移完成');
@@ -1,5 +1,8 @@
1
1
  import { Command } from '@oclif/core';
2
2
  export default class DbPush extends Command {
3
3
  static description: string;
4
+ static flags: {
5
+ env: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
+ };
4
7
  run(): Promise<void>;
5
8
  }
@@ -1,10 +1,16 @@
1
1
  import { Command } from '@oclif/core';
2
2
  import { execCompose, getComposeFiles } from '../../utils/docker.js';
3
3
  import { logger } from '../../utils/logger.js';
4
+ import { EnvFlag, selectEnvironment } from '../../utils/selection.js';
4
5
  export default class DbPush extends Command {
5
- static description = '推送数据库 schema';
6
+ static description = '推送数据库 schema (db:push)';
7
+ static flags = {
8
+ env: EnvFlag,
9
+ };
6
10
  async run() {
7
- const { files, isBuiltIn } = await getComposeFiles('basic');
11
+ const { flags } = await this.parse(DbPush);
12
+ const env = await selectEnvironment(flags.env);
13
+ const { files, isBuiltIn } = await getComposeFiles(env);
8
14
  logger.info('正在推送数据库 schema...');
9
15
  await execCompose(files, 'api', ['npm', 'run', 'db:push'], isBuiltIn);
10
16
  logger.success('Schema 推送完成');
@@ -1,5 +1,8 @@
1
1
  import { Command } from '@oclif/core';
2
2
  export default class DbReset extends Command {
3
3
  static description: string;
4
+ static flags: {
5
+ env: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
+ };
4
7
  run(): Promise<void>;
5
8
  }
@@ -1,12 +1,18 @@
1
1
  import { Command } from '@oclif/core';
2
+ import { confirm } from '@inquirer/prompts';
2
3
  import { execCompose, getComposeFiles } from '../../utils/docker.js';
3
4
  import { logger } from '../../utils/logger.js';
4
- import { confirm } from '@inquirer/prompts';
5
+ import { EnvFlag, selectEnvironment } from '../../utils/selection.js';
5
6
  export default class DbReset extends Command {
6
- static description = '重置并重新初始化数据';
7
+ static description = '重置数据库 (db:reset) - 危险操作!';
8
+ static flags = {
9
+ env: EnvFlag,
10
+ };
7
11
  async run() {
8
- const { files, isBuiltIn } = await getComposeFiles('basic');
9
- logger.warning('警告:这将清空数据库并重新初始化!');
12
+ const { flags } = await this.parse(DbReset);
13
+ const env = await selectEnvironment(flags.env);
14
+ const { files, isBuiltIn } = await getComposeFiles(env);
15
+ logger.warning('警告:这将清除所有数据!');
10
16
  const confirmReset = await confirm({
11
17
  message: '确认继续?',
12
18
  default: false