nodebbs 0.0.0 → 0.0.1

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 (59) hide show
  1. package/README.md +378 -249
  2. package/dist/commands/db/generate.d.ts +5 -0
  3. package/dist/commands/db/generate.js +12 -0
  4. package/dist/commands/db/index.d.ts +5 -0
  5. package/dist/commands/db/index.js +11 -0
  6. package/dist/commands/db/migrate.d.ts +5 -0
  7. package/dist/commands/db/migrate.js +12 -0
  8. package/dist/commands/db/push.d.ts +5 -0
  9. package/dist/commands/db/push.js +12 -0
  10. package/dist/commands/db/reset.d.ts +5 -0
  11. package/dist/commands/db/reset.js +22 -0
  12. package/dist/commands/db/seed.d.ts +5 -0
  13. package/dist/commands/db/seed.js +12 -0
  14. package/dist/commands/deploy/index.d.ts +8 -0
  15. package/dist/commands/deploy/index.js +89 -0
  16. package/dist/commands/dev/index.d.ts +9 -0
  17. package/dist/commands/dev/index.js +53 -0
  18. package/dist/commands/logs/api.d.ts +5 -0
  19. package/dist/commands/logs/api.js +11 -0
  20. package/dist/commands/logs/db.d.ts +5 -0
  21. package/dist/commands/logs/db.js +11 -0
  22. package/dist/commands/logs/index.d.ts +5 -0
  23. package/dist/commands/logs/index.js +11 -0
  24. package/dist/commands/logs/redis.d.ts +5 -0
  25. package/dist/commands/logs/redis.js +11 -0
  26. package/dist/commands/logs/web.d.ts +5 -0
  27. package/dist/commands/logs/web.js +11 -0
  28. package/dist/commands/restart/index.d.ts +5 -0
  29. package/dist/commands/restart/index.js +12 -0
  30. package/dist/commands/setup/index.d.ts +5 -0
  31. package/dist/commands/setup/index.js +12 -0
  32. package/dist/commands/shell/api.d.ts +5 -0
  33. package/dist/commands/shell/api.js +11 -0
  34. package/dist/commands/shell/db.d.ts +5 -0
  35. package/dist/commands/shell/db.js +11 -0
  36. package/dist/commands/shell/redis.d.ts +5 -0
  37. package/dist/commands/shell/redis.js +11 -0
  38. package/dist/commands/shell/web.d.ts +5 -0
  39. package/dist/commands/shell/web.js +11 -0
  40. package/dist/commands/status/index.d.ts +5 -0
  41. package/dist/commands/status/index.js +11 -0
  42. package/dist/commands/stop/index.d.ts +8 -0
  43. package/dist/commands/stop/index.js +37 -0
  44. package/dist/templates/docker-compose.lowmem.yml +126 -0
  45. package/dist/templates/docker-compose.prod.yml +120 -0
  46. package/dist/templates/docker-compose.yml +127 -0
  47. package/dist/templates/init-db.sql +14 -0
  48. package/dist/utils/docker.d.ts +8 -0
  49. package/dist/utils/docker.js +101 -0
  50. package/dist/utils/env.d.ts +2 -0
  51. package/dist/utils/env.js +108 -0
  52. package/dist/utils/logger.d.ts +7 -0
  53. package/dist/utils/logger.js +14 -0
  54. package/oclif.manifest.json +441 -26
  55. package/package.json +9 -3
  56. package/dist/commands/hello/index.d.ts +0 -12
  57. package/dist/commands/hello/index.js +0 -19
  58. package/dist/commands/hello/world.d.ts +0 -8
  59. package/dist/commands/hello/world.js +0 -14
@@ -0,0 +1,5 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class DbGenerate extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
@@ -0,0 +1,12 @@
1
+ import { Command } from '@oclif/core';
2
+ import { execCompose, getComposeFiles } from '../../utils/docker.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ export default class DbGenerate extends Command {
5
+ static description = '生成数据库迁移文件';
6
+ async run() {
7
+ const { files, isBuiltIn } = await getComposeFiles('basic');
8
+ logger.info('正在生成数据库迁移...');
9
+ await execCompose(files, 'api', ['npm', 'run', 'db:generate'], isBuiltIn);
10
+ logger.success('数据库迁移文件生成完成');
11
+ }
12
+ }
@@ -0,0 +1,5 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Db extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
@@ -0,0 +1,11 @@
1
+ import { Command } from '@oclif/core';
2
+ import { execCompose, getComposeFiles } from '../../utils/docker.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ export default class Db extends Command {
5
+ static description = '打开数据库管理界面(Drizzle Studio)';
6
+ async run() {
7
+ const { files, isBuiltIn } = await getComposeFiles('basic');
8
+ logger.info('正在启动 Drizzle Studio...');
9
+ await execCompose(files, 'api', ['npm', 'run', 'db:studio'], isBuiltIn);
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class DbMigrate extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
@@ -0,0 +1,12 @@
1
+ import { Command } from '@oclif/core';
2
+ import { execCompose, getComposeFiles } from '../../utils/docker.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ export default class DbMigrate extends Command {
5
+ static description = '执行数据库迁移';
6
+ async run() {
7
+ const { files, isBuiltIn } = await getComposeFiles('basic');
8
+ logger.info('正在执行数据库迁移...');
9
+ await execCompose(files, 'api', ['npm', 'run', 'db:migrate'], isBuiltIn);
10
+ logger.success('数据库迁移完成');
11
+ }
12
+ }
@@ -0,0 +1,5 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class DbPush extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
@@ -0,0 +1,12 @@
1
+ import { Command } from '@oclif/core';
2
+ import { execCompose, getComposeFiles } from '../../utils/docker.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ export default class DbPush extends Command {
5
+ static description = '推送数据库 schema';
6
+ async run() {
7
+ const { files, isBuiltIn } = await getComposeFiles('basic');
8
+ logger.info('正在推送数据库 schema...');
9
+ await execCompose(files, 'api', ['npm', 'run', 'db:push'], isBuiltIn);
10
+ logger.success('Schema 推送完成');
11
+ }
12
+ }
@@ -0,0 +1,5 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class DbReset extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
@@ -0,0 +1,22 @@
1
+ import { Command } from '@oclif/core';
2
+ import { execCompose, getComposeFiles } from '../../utils/docker.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ import { confirm } from '@inquirer/prompts';
5
+ export default class DbReset extends Command {
6
+ static description = '重置并重新初始化数据';
7
+ async run() {
8
+ const { files, isBuiltIn } = await getComposeFiles('basic');
9
+ logger.warning('警告:这将清空数据库并重新初始化!');
10
+ const confirmReset = await confirm({
11
+ message: '确认继续?',
12
+ default: false
13
+ });
14
+ if (!confirmReset) {
15
+ logger.info('操作已取消。');
16
+ this.exit(0);
17
+ }
18
+ logger.info('正在重置数据...');
19
+ await execCompose(files, 'api', ['npm', 'run', 'seed:reset'], isBuiltIn);
20
+ logger.success('数据重置完成');
21
+ }
22
+ }
@@ -0,0 +1,5 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class DbSeed extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
@@ -0,0 +1,12 @@
1
+ import { Command } from '@oclif/core';
2
+ import { execCompose, getComposeFiles } from '../../utils/docker.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ export default class DbSeed extends Command {
5
+ static description = '初始化数据库数据';
6
+ async run() {
7
+ const { files, isBuiltIn } = await getComposeFiles('basic');
8
+ logger.info('正在初始化数据库数据...');
9
+ await execCompose(files, 'api', ['npm', 'run', 'seed'], isBuiltIn);
10
+ logger.success('数据初始化完成');
11
+ }
12
+ }
@@ -0,0 +1,8 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Deploy extends Command {
3
+ static description: string;
4
+ static flags: {
5
+ name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
+ };
7
+ run(): Promise<void>;
8
+ }
@@ -0,0 +1,89 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { select, confirm } from '@inquirer/prompts';
3
+ import { checkDocker, runCompose, waitForHealth, execCompose, getComposeFiles } from '../../utils/docker.js';
4
+ import { initEnv, checkEnv } from '../../utils/env.js';
5
+ import { logger } from '../../utils/logger.js';
6
+ export default class Deploy extends Command {
7
+ static description = '部署 NodeBBS';
8
+ static flags = {
9
+ name: Flags.string({ char: 'n', description: 'name to print' }),
10
+ };
11
+ async run() {
12
+ logger.header('NodeBBS Docker 部署');
13
+ // 1. Select Environment
14
+ const env = await select({
15
+ message: '请选择部署环境:',
16
+ choices: [
17
+ { name: '标准生产环境 (2C4G+) [推荐]', value: 'production' },
18
+ { name: '低配环境 (1C1G/1C2G)', value: 'lowmem' },
19
+ { name: '基础环境 (仅用于测试)', value: 'basic' }
20
+ ]
21
+ });
22
+ // 2. Get Compose Files
23
+ const { files: composeFiles, isBuiltIn } = await getComposeFiles(env);
24
+ if (isBuiltIn) {
25
+ logger.info('使用内置 Docker Compose 模板...');
26
+ }
27
+ else {
28
+ logger.info('使用项目 Docker Compose 文件...');
29
+ }
30
+ if (env === 'production') {
31
+ logger.success('已选择:标准生产环境');
32
+ }
33
+ else if (env === 'lowmem') {
34
+ logger.success('已选择:低配环境');
35
+ }
36
+ else {
37
+ logger.success('已选择:基础环境');
38
+ logger.warning('注意:无资源限制,不推荐用于生产环境。');
39
+ }
40
+ // 3. Check Docker
41
+ await checkDocker();
42
+ // 4. Init & Check Env
43
+ await initEnv();
44
+ await checkEnv(env);
45
+ const continueDeploy = await confirm({
46
+ message: '是否继续部署?',
47
+ default: true
48
+ });
49
+ if (!continueDeploy) {
50
+ logger.info('部署已取消。');
51
+ this.exit(0);
52
+ }
53
+ // 5. Build Images
54
+ logger.info('正在构建 Docker 镜像...');
55
+ await runCompose(composeFiles, ['build', '--no-cache'], isBuiltIn);
56
+ logger.success('镜像构建完成');
57
+ // 6. Start Services
58
+ logger.info('正在启动服务...');
59
+ await runCompose(composeFiles, ['up', '-d'], isBuiltIn);
60
+ logger.success('服务已启动');
61
+ // 7. Wait for Health
62
+ await waitForHealth(composeFiles, isBuiltIn);
63
+ // 8. Init Database
64
+ const pushDb = await confirm({
65
+ message: '是否推送数据库 schema?',
66
+ default: false
67
+ });
68
+ if (pushDb) {
69
+ logger.info('正在推送数据库 schema...');
70
+ await execCompose(composeFiles, 'api', ['npm', 'run', 'db:push'], isBuiltIn);
71
+ logger.success('数据库 schema 推送完成');
72
+ }
73
+ const seedDb = await confirm({
74
+ message: '是否初始化种子数据?',
75
+ default: false
76
+ });
77
+ if (seedDb) {
78
+ logger.info('正在初始化数据...');
79
+ await execCompose(composeFiles, 'api', ['npm', 'run', 'seed'], isBuiltIn);
80
+ logger.success('数据初始化完成');
81
+ }
82
+ // 9. Show Info
83
+ logger.header('部署完成!');
84
+ logger.info(`环境: ${env}`);
85
+ console.log(` Web 前端: http://localhost:3100`);
86
+ console.log(` API 文档: http://localhost:7100/docs`);
87
+ console.log(` 健康检查: http://localhost:7100/api`);
88
+ }
89
+ }
@@ -0,0 +1,9 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Dev extends Command {
3
+ static description: string;
4
+ static flags: {
5
+ env: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
+ rebuild: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
@@ -0,0 +1,53 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { select } from '@inquirer/prompts';
3
+ import { runCompose, getComposeFiles } from '../../utils/docker.js';
4
+ import { logger } from '../../utils/logger.js';
5
+ export default class Dev extends Command {
6
+ static description = '启动开发环境';
7
+ static flags = {
8
+ env: Flags.string({
9
+ char: 'e',
10
+ description: '部署环境 (production, lowmem, basic)',
11
+ options: ['production', 'lowmem', 'basic'],
12
+ }),
13
+ rebuild: Flags.boolean({
14
+ char: 'r',
15
+ description: '重新构建镜像',
16
+ default: false,
17
+ }),
18
+ };
19
+ async run() {
20
+ const { flags } = await this.parse(Dev);
21
+ // 如果没有指定环境,询问用户
22
+ let env = flags.env;
23
+ if (!env) {
24
+ env = await select({
25
+ message: '请选择部署环境:',
26
+ choices: [
27
+ { name: '标准生产环境 (2C4G+) [推荐]', value: 'production' },
28
+ { name: '低配环境 (1C1G/1C2G)', value: 'lowmem' },
29
+ { name: '基础环境 (仅用于测试)', value: 'basic' },
30
+ ],
31
+ });
32
+ }
33
+ const { files, isBuiltIn } = await getComposeFiles(env);
34
+ if (isBuiltIn) {
35
+ logger.info('使用内置 Docker Compose 模板...');
36
+ }
37
+ else {
38
+ logger.info('使用项目 Docker Compose 文件...');
39
+ }
40
+ if (flags.rebuild) {
41
+ logger.info('正在重新构建并启动服务...');
42
+ await runCompose(files, ['up', '-d', '--build'], isBuiltIn);
43
+ logger.success('服务已重新构建并启动!');
44
+ }
45
+ else {
46
+ logger.info('正在启动服务...');
47
+ await runCompose(files, ['up', '-d'], isBuiltIn);
48
+ logger.success('服务已启动!');
49
+ }
50
+ console.log(` Web 前端: http://localhost:3100`);
51
+ console.log(` API 文档: http://localhost:7100/docs`);
52
+ }
53
+ }
@@ -0,0 +1,5 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class LogsApi extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
@@ -0,0 +1,11 @@
1
+ import { Command } from '@oclif/core';
2
+ import { runCompose, getComposeFiles } from '../../utils/docker.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ export default class LogsApi extends Command {
5
+ static description = '查看 API 服务日志';
6
+ async run() {
7
+ const { files, isBuiltIn } = await getComposeFiles('basic');
8
+ logger.info('正在显示 API 服务日志...');
9
+ await runCompose(files, ['logs', '-f', 'api'], isBuiltIn);
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class LogsDb extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
@@ -0,0 +1,11 @@
1
+ import { Command } from '@oclif/core';
2
+ import { runCompose, getComposeFiles } from '../../utils/docker.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ export default class LogsDb extends Command {
5
+ static description = '查看数据库日志';
6
+ async run() {
7
+ const { files, isBuiltIn } = await getComposeFiles('basic');
8
+ logger.info('正在显示数据库日志...');
9
+ await runCompose(files, ['logs', '-f', 'postgres'], isBuiltIn);
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Logs extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
@@ -0,0 +1,11 @@
1
+ import { Command } from '@oclif/core';
2
+ import { runCompose, getComposeFiles } from '../../utils/docker.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ export default class Logs extends Command {
5
+ static description = '查看所有服务日志';
6
+ async run() {
7
+ const { files, isBuiltIn } = await getComposeFiles('basic');
8
+ logger.info('正在显示所有服务日志...');
9
+ await runCompose(files, ['logs', '-f'], isBuiltIn);
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class LogsRedis extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
@@ -0,0 +1,11 @@
1
+ import { Command } from '@oclif/core';
2
+ import { runCompose, getComposeFiles } from '../../utils/docker.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ export default class LogsRedis extends Command {
5
+ static description = '查看 Redis 日志';
6
+ async run() {
7
+ const { files, isBuiltIn } = await getComposeFiles('basic');
8
+ logger.info('正在显示 Redis 日志...');
9
+ await runCompose(files, ['logs', '-f', 'redis'], isBuiltIn);
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class LogsWeb extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
@@ -0,0 +1,11 @@
1
+ import { Command } from '@oclif/core';
2
+ import { runCompose, getComposeFiles } from '../../utils/docker.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ export default class LogsWeb extends Command {
5
+ static description = '查看 Web 服务日志';
6
+ async run() {
7
+ const { files, isBuiltIn } = await getComposeFiles('basic');
8
+ logger.info('正在显示 Web 服务日志...');
9
+ await runCompose(files, ['logs', '-f', 'web'], isBuiltIn);
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Restart extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
@@ -0,0 +1,12 @@
1
+ import { Command } from '@oclif/core';
2
+ import { runCompose, getComposeFiles } from '../../utils/docker.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ export default class Restart extends Command {
5
+ static description = '重启所有服务';
6
+ async run() {
7
+ const { files, isBuiltIn } = await getComposeFiles('basic');
8
+ logger.info('正在重启服务...');
9
+ await runCompose(files, ['restart'], isBuiltIn);
10
+ logger.success('服务已重启');
11
+ }
12
+ }
@@ -0,0 +1,5 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Setup extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
@@ -0,0 +1,12 @@
1
+ import { Command } from '@oclif/core';
2
+ import { initEnv } from '../../utils/env.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ export default class Setup extends Command {
5
+ static description = '初始化项目(首次使用)';
6
+ async run() {
7
+ logger.header('NodeBBS 项目初始化');
8
+ await initEnv();
9
+ logger.success('初始化完成!');
10
+ logger.info('请编辑 .env 文件,修改数据库密码、Redis 密码和 JWT 密钥。');
11
+ }
12
+ }
@@ -0,0 +1,5 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ShellApi extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
@@ -0,0 +1,11 @@
1
+ import { Command } from '@oclif/core';
2
+ import { runCompose, getComposeFiles } from '../../utils/docker.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ export default class ShellApi extends Command {
5
+ static description = '进入 API 容器';
6
+ async run() {
7
+ const { files, isBuiltIn } = await getComposeFiles('basic');
8
+ logger.info('进入 API 容器...');
9
+ await runCompose(files, ['exec', 'api', 'sh'], isBuiltIn);
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ShellDb extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
@@ -0,0 +1,11 @@
1
+ import { Command } from '@oclif/core';
2
+ import { runCompose, getComposeFiles } from '../../utils/docker.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ export default class ShellDb extends Command {
5
+ static description = '进入数据库';
6
+ async run() {
7
+ const { files, isBuiltIn } = await getComposeFiles('basic');
8
+ logger.info('进入数据库...');
9
+ await runCompose(files, ['exec', 'postgres', 'psql', '-U', 'postgres', '-d', 'nodebbs'], isBuiltIn);
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ShellRedis extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
@@ -0,0 +1,11 @@
1
+ import { Command } from '@oclif/core';
2
+ import { runCompose, getComposeFiles } from '../../utils/docker.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ export default class ShellRedis extends Command {
5
+ static description = '进入 Redis';
6
+ async run() {
7
+ const { files, isBuiltIn } = await getComposeFiles('basic');
8
+ logger.info('进入 Redis...');
9
+ await runCompose(files, ['exec', 'redis', 'redis-cli'], isBuiltIn);
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ShellWeb extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
@@ -0,0 +1,11 @@
1
+ import { Command } from '@oclif/core';
2
+ import { runCompose, getComposeFiles } from '../../utils/docker.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ export default class ShellWeb extends Command {
5
+ static description = '进入 Web 容器';
6
+ async run() {
7
+ const { files, isBuiltIn } = await getComposeFiles('basic');
8
+ logger.info('进入 Web 容器...');
9
+ await runCompose(files, ['exec', 'web', 'sh'], isBuiltIn);
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Status extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
@@ -0,0 +1,11 @@
1
+ import { Command } from '@oclif/core';
2
+ import { runCompose, getComposeFiles } from '../../utils/docker.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ export default class Status extends Command {
5
+ static description = '查看服务状态';
6
+ async run() {
7
+ const { files, isBuiltIn } = await getComposeFiles('basic');
8
+ logger.info('服务状态:');
9
+ await runCompose(files, ['ps'], isBuiltIn);
10
+ }
11
+ }
@@ -0,0 +1,8 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Stop extends Command {
3
+ static description: string;
4
+ static flags: {
5
+ volumes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
6
+ };
7
+ run(): Promise<void>;
8
+ }
@@ -0,0 +1,37 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { runCompose, getComposeFiles } from '../../utils/docker.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ import { confirm } from '@inquirer/prompts';
5
+ export default class Stop extends Command {
6
+ static description = '停止服务';
7
+ static flags = {
8
+ volumes: Flags.boolean({
9
+ char: 'v',
10
+ description: '同时删除数据卷(危险!)',
11
+ default: false,
12
+ }),
13
+ };
14
+ async run() {
15
+ const { flags } = await this.parse(Stop);
16
+ const { files, isBuiltIn } = await getComposeFiles('basic');
17
+ if (flags.volumes) {
18
+ logger.warning('警告:这将删除所有数据!');
19
+ const confirmDelete = await confirm({
20
+ message: '确认继续?',
21
+ default: false,
22
+ });
23
+ if (!confirmDelete) {
24
+ logger.info('操作已取消。');
25
+ this.exit(0);
26
+ }
27
+ logger.info('正在停止服务并删除数据卷...');
28
+ await runCompose(files, ['down', '-v'], isBuiltIn);
29
+ logger.success('服务已停止,数据卷已删除');
30
+ }
31
+ else {
32
+ logger.info('正在停止服务...');
33
+ await runCompose(files, ['down'], isBuiltIn);
34
+ logger.success('服务已停止');
35
+ }
36
+ }
37
+ }