nodebbs 0.0.6 → 0.0.8

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
@@ -11,14 +11,11 @@ NodeBBS CLI 是一个专为全栈开发者设计的命令行工具,用于简
11
11
 
12
12
  ### 特性
13
13
 
14
- - �️ **交互式菜单** - 支持键盘导航的可视化命令选择(新增)
15
- - �🚀 **快速启动** - 一键启动开发环境
14
+ - �️ **交互式菜单** - 支持键盘导航的可视化命令选择
16
15
  - 🎯 **全栈友好** - 命令设计贴近开发者思维
17
- - 🔧 **服务级控制** - 可以单独管理每个服务
18
16
  - 📊 **实时日志** - 方便查看各服务日志
19
17
  - 💾 **数据库管理** - 内置数据库迁移和管理工具
20
18
  - 🌐 **内置模板** - 无需本地配置文件即可使用
21
- - 🇨🇳 **中文界面** - 所有输出均为中文
22
19
 
23
20
  ## 📦 安装
24
21
 
@@ -45,28 +42,11 @@ npx nodebbs [command]
45
42
 
46
43
  ## 🚀 快速开始
47
44
 
48
- ### 1. 启动服务
49
-
50
- ```bash
51
- # 启动所有服务(生产模式,包含完整检查)
52
- npx nodebbs start
53
-
54
- # 重新构建并启动(跳过检查,用于更新)
55
- npx nodebbs start --build
56
- ```
57
-
58
- ### 2. 查看服务状态
59
-
60
45
  ```bash
61
- # 查看所有服务状态
62
- npx nodebbs status
46
+ npx nodebbs
63
47
  ```
64
-
65
- ### 3. 访问应用
66
-
67
- - **Web 前端**: http://localhost:3100
68
- - **API 文档**: http://localhost:7100/docs
69
- - **健康检查**: http://localhost:7100/api
48
+ - **start**: 开始部署(首次使用推荐选择此项)
49
+ - **rebuild**: 重新构建并启动(跳过检查,通常在代码更新后选择此项)
70
50
 
71
51
  ## 📚 命令参考
72
52
 
@@ -217,22 +197,6 @@ npx nodebbs shell:redis
217
197
 
218
198
  ### 数据库管理
219
199
 
220
-
221
-
222
- #### `nodebbs db:generate`
223
- 生成数据库迁移文件
224
-
225
- ```bash
226
- npx nodebbs db:generate
227
- ```
228
-
229
- #### `nodebbs db:migrate`
230
- 执行数据库迁移
231
-
232
- ```bash
233
- npx nodebbs db:migrate
234
- ```
235
-
236
200
  #### `nodebbs db:push`
237
201
  推送数据库 schema
238
202
 
@@ -278,83 +242,7 @@ npx nodebbs clean --cache
278
242
 
279
243
  ## 🎯 使用场景
280
244
 
281
- ### 场景 1:新开发者加入项目
282
-
283
- ```bash
284
- # 1. 启动服务
285
- npx nodebbs start
286
-
287
- # 2. 初始化数据库
288
- npx nodebbs db:push
289
- npx nodebbs db:seed
290
-
291
- # 3. 查看服务状态
292
- npx nodebbs status
293
- ```
294
-
295
- ### 场景 2:日常开发
296
-
297
- ```bash
298
- # 启动服务
299
- npx nodebbs start
300
-
301
- # 查看 API 日志
302
- npx nodebbs logs:api
303
-
304
- # 进入 API 容器调试
305
- npx nodebbs shell:api
306
-
307
-
308
-
309
- # 重置测试数据
310
- npx nodebbs db:reset
311
- ```
312
-
313
- ### 场景 3:代码更新后重新构建
314
-
315
- ```bash
316
- # 停止服务
317
- npx nodebbs stop
318
-
319
- # 重新构建并启动
320
- npx nodebbs start --build
321
-
322
- # 查看日志确认启动成功
323
- npx nodebbs logs
324
- ```
325
-
326
- ### 场景 4:生产部署
327
-
328
- ```bash
329
- # 部署到生产环境
330
- npx nodebbs start -e production
331
-
332
- # 查看服务状态
333
- npx nodebbs status
334
-
335
- # 查看日志
336
- npx nodebbs logs
337
-
338
- # 执行数据库迁移
339
- npx nodebbs db:migrate
340
- ```
341
-
342
- ### 场景 5:数据库操作
343
-
344
- ```bash
345
-
346
-
347
- # 运行迁移
348
- npx nodebbs db:migrate
349
-
350
- # 填充数据
351
- npx nodebbs db:seed
352
-
353
- # 进入数据库命令行
354
- npx nodebbs shell:db
355
- ```
356
-
357
- ### 场景 6:离线服务器部署
245
+ ### 离线服务器部署
358
246
 
359
247
  1. **在开发机打包**:
360
248
  ```bash
@@ -491,38 +379,6 @@ npx nodebbs stop
491
379
  npx nodebbs stop --volumes
492
380
  ```
493
381
 
494
- ## 📝 开发
495
-
496
- ### 本地开发
497
-
498
- ```bash
499
- # 克隆仓库
500
- git clone https://github.com/aiprojecthub/nodebbs.git
501
- cd nodebbs
502
-
503
- # 安装依赖
504
- pnpm install
505
-
506
- # 构建
507
- pnpm build
508
-
509
- # 运行
510
- ./bin/run.js [command]
511
- ```
512
-
513
- ### 测试命令
514
-
515
- ```bash
516
- # 查看帮助
517
- ./bin/run.js --help
518
-
519
- # 测试 start 命令
520
- ./bin/run.js start --help
521
-
522
- # 测试 logs 命令
523
- ./bin/run.js logs --help
524
- ```
525
-
526
382
  ## 🔗 相关链接
527
383
 
528
384
  - [NodeBBS 项目](https://github.com/aiprojecthub/nodebbs)
@@ -29,8 +29,13 @@ export async function runInteractive(root) {
29
29
  }
30
30
  await navigate(tree, [], config);
31
31
  }
32
+ const GLOBAL_PRIORITY = ['start', 'stop', 'restart', 'rebuild', 'status', 'logs', 'shell', 'db', 'pack'];
33
+ const SCOPED_PRIORITIES = {
34
+ 'logs': ['all', 'web', 'api', 'db', 'redis'],
35
+ };
32
36
  async function navigate(node, breadcrumbs, config) {
33
- const priorityOrder = ['start', 'rebuild', 'stop', 'restart', 'status', 'logs', 'pack', 'shell', 'db'];
37
+ const currentPath = breadcrumbs.join(':');
38
+ const priorityOrder = SCOPED_PRIORITIES[currentPath] || GLOBAL_PRIORITY;
34
39
  while (true) {
35
40
  const keys = Object.keys(node.children).sort((a, b) => {
36
41
  const indexA = priorityOrder.indexOf(a);
@@ -47,7 +52,16 @@ async function navigate(node, breadcrumbs, config) {
47
52
  // Otherwise sort alphabetically
48
53
  return a.localeCompare(b);
49
54
  });
50
- const choices = keys.map(key => {
55
+ const choices = [];
56
+ // 如果当前节点本身就是一个命令,添加运行选项
57
+ if (node.command) {
58
+ choices.push({
59
+ name: `${node.command.description || node.command.id}`,
60
+ value: '__SELF__',
61
+ short: 'all'
62
+ });
63
+ }
64
+ const subChoices = keys.map(key => {
51
65
  const child = node.children[key];
52
66
  const hasSubcommands = Object.keys(child.children).length > 0;
53
67
  let label = key;
@@ -83,6 +97,7 @@ async function navigate(node, breadcrumbs, config) {
83
97
  short: key
84
98
  };
85
99
  });
100
+ choices.push(...subChoices);
86
101
  // 添加导航选项
87
102
  // 即使支持 Esc,保留显式选项也有助于发现性
88
103
  if (breadcrumbs.length > 0) {
@@ -116,6 +131,31 @@ async function navigate(node, breadcrumbs, config) {
116
131
  if (selection === '__BACK__') {
117
132
  return;
118
133
  }
134
+ if (selection === '__SELF__' && node.command) {
135
+ console.log(`正在运行: ${node.command.id}`);
136
+ try {
137
+ await config.runCommand(node.command.id);
138
+ }
139
+ catch (error) {
140
+ // Ctrl+C: 退出程序
141
+ if (error.name === 'ExitPromptError') {
142
+ console.log('\n用户退出。');
143
+ process.exit(0);
144
+ }
145
+ // 手动取消: 返回菜单
146
+ if (error.name === 'CancelError') {
147
+ console.log('\n操作已取消。');
148
+ continue;
149
+ }
150
+ console.error(error);
151
+ }
152
+ console.log('\n命令执行完成。');
153
+ // 动态导入 input 以保持轻量
154
+ const { input } = await import('@inquirer/prompts');
155
+ await input({ message: '按回车键继续...' });
156
+ // 继续循环
157
+ continue;
158
+ }
119
159
  const selectedNode = node.children[selection];
120
160
  if (Object.keys(selectedNode.children).length > 0) {
121
161
  // 有子命令,进入子菜单
@@ -91,76 +91,6 @@
91
91
  "backup.js"
92
92
  ]
93
93
  },
94
- "db:generate": {
95
- "aliases": [],
96
- "args": {},
97
- "description": "生成 Prisma Client (db:generate)",
98
- "flags": {
99
- "env": {
100
- "char": "e",
101
- "description": "部署环境 (production, lowmem, basic)",
102
- "name": "env",
103
- "hasDynamicHelp": false,
104
- "multiple": false,
105
- "options": [
106
- "production",
107
- "lowmem",
108
- "basic"
109
- ],
110
- "type": "option"
111
- }
112
- },
113
- "hasDynamicHelp": false,
114
- "hiddenAliases": [],
115
- "id": "db:generate",
116
- "pluginAlias": "nodebbs",
117
- "pluginName": "nodebbs",
118
- "pluginType": "core",
119
- "strict": true,
120
- "enableJsonFlag": false,
121
- "isESM": true,
122
- "relativePath": [
123
- "dist",
124
- "commands",
125
- "db",
126
- "generate.js"
127
- ]
128
- },
129
- "db:migrate": {
130
- "aliases": [],
131
- "args": {},
132
- "description": "执行数据库迁移 (db:migrate)",
133
- "flags": {
134
- "env": {
135
- "char": "e",
136
- "description": "部署环境 (production, lowmem, basic)",
137
- "name": "env",
138
- "hasDynamicHelp": false,
139
- "multiple": false,
140
- "options": [
141
- "production",
142
- "lowmem",
143
- "basic"
144
- ],
145
- "type": "option"
146
- }
147
- },
148
- "hasDynamicHelp": false,
149
- "hiddenAliases": [],
150
- "id": "db:migrate",
151
- "pluginAlias": "nodebbs",
152
- "pluginName": "nodebbs",
153
- "pluginType": "core",
154
- "strict": true,
155
- "enableJsonFlag": false,
156
- "isESM": true,
157
- "relativePath": [
158
- "dist",
159
- "commands",
160
- "db",
161
- "migrate.js"
162
- ]
163
- },
164
94
  "db:push": {
165
95
  "aliases": [],
166
96
  "args": {},
@@ -266,10 +196,10 @@
266
196
  "seed.js"
267
197
  ]
268
198
  },
269
- "logs:api": {
199
+ "logs:all": {
270
200
  "aliases": [],
271
201
  "args": {},
272
- "description": "查看 API 服务日志",
202
+ "description": "查看所有服务日志",
273
203
  "flags": {
274
204
  "env": {
275
205
  "char": "e",
@@ -287,7 +217,7 @@
287
217
  },
288
218
  "hasDynamicHelp": false,
289
219
  "hiddenAliases": [],
290
- "id": "logs:api",
220
+ "id": "logs:all",
291
221
  "pluginAlias": "nodebbs",
292
222
  "pluginName": "nodebbs",
293
223
  "pluginType": "core",
@@ -298,13 +228,13 @@
298
228
  "dist",
299
229
  "commands",
300
230
  "logs",
301
- "api.js"
231
+ "all.js"
302
232
  ]
303
233
  },
304
- "logs:db": {
234
+ "logs:api": {
305
235
  "aliases": [],
306
236
  "args": {},
307
- "description": "查看数据库日志",
237
+ "description": "查看 API 服务日志",
308
238
  "flags": {
309
239
  "env": {
310
240
  "char": "e",
@@ -322,7 +252,7 @@
322
252
  },
323
253
  "hasDynamicHelp": false,
324
254
  "hiddenAliases": [],
325
- "id": "logs:db",
255
+ "id": "logs:api",
326
256
  "pluginAlias": "nodebbs",
327
257
  "pluginName": "nodebbs",
328
258
  "pluginType": "core",
@@ -333,13 +263,13 @@
333
263
  "dist",
334
264
  "commands",
335
265
  "logs",
336
- "db.js"
266
+ "api.js"
337
267
  ]
338
268
  },
339
- "logs": {
269
+ "logs:db": {
340
270
  "aliases": [],
341
271
  "args": {},
342
- "description": "查看所有服务日志",
272
+ "description": "查看数据库日志",
343
273
  "flags": {
344
274
  "env": {
345
275
  "char": "e",
@@ -357,7 +287,7 @@
357
287
  },
358
288
  "hasDynamicHelp": false,
359
289
  "hiddenAliases": [],
360
- "id": "logs",
290
+ "id": "logs:db",
361
291
  "pluginAlias": "nodebbs",
362
292
  "pluginName": "nodebbs",
363
293
  "pluginType": "core",
@@ -368,7 +298,7 @@
368
298
  "dist",
369
299
  "commands",
370
300
  "logs",
371
- "index.js"
301
+ "db.js"
372
302
  ]
373
303
  },
374
304
  "logs:redis": {
@@ -788,5 +718,5 @@
788
718
  ]
789
719
  }
790
720
  },
791
- "version": "0.0.6"
721
+ "version": "0.0.8"
792
722
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nodebbs",
3
3
  "description": "NodeBBS 论坛系统专业运维工具",
4
- "version": "0.0.6",
4
+ "version": "0.0.8",
5
5
  "author": "wengqianshan",
6
6
  "bin": {
7
7
  "nodebbs": "./bin/run.js"
@@ -58,8 +58,8 @@
58
58
  ],
59
59
  "topicSeparator": " ",
60
60
  "topics": {
61
- "hello": {
62
- "description": "向世界和他人问好"
61
+ "logs": {
62
+ "description": "查看服务日志"
63
63
  },
64
64
  "db": {
65
65
  "description": "数据库操作 (备份, 迁移, 种子数据等)"
@@ -1,8 +0,0 @@
1
- import { Command } from '@oclif/core';
2
- export default class DbGenerate extends Command {
3
- static description: string;
4
- static flags: {
5
- env: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
- };
7
- run(): Promise<void>;
8
- }
@@ -1,18 +0,0 @@
1
- import { Command } from '@oclif/core';
2
- import { execCompose, getComposeFiles } from '../../utils/docker.js';
3
- import { logger } from '../../utils/logger.js';
4
- import { EnvFlag, selectEnvironment } from '../../utils/selection.js';
5
- export default class DbGenerate extends Command {
6
- static description = '生成 Prisma Client (db:generate)';
7
- static flags = {
8
- env: EnvFlag,
9
- };
10
- async run() {
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...');
15
- await execCompose(files, 'api', ['npm', 'run', 'db:generate'], isBuiltIn);
16
- logger.success('数据库迁移文件生成完成');
17
- }
18
- }
@@ -1,8 +0,0 @@
1
- import { Command } from '@oclif/core';
2
- export default class DbMigrate extends Command {
3
- static description: string;
4
- static flags: {
5
- env: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
- };
7
- run(): Promise<void>;
8
- }
@@ -1,18 +0,0 @@
1
- import { Command } from '@oclif/core';
2
- import { execCompose, getComposeFiles } from '../../utils/docker.js';
3
- import { logger } from '../../utils/logger.js';
4
- import { EnvFlag, selectEnvironment } from '../../utils/selection.js';
5
- export default class DbMigrate extends Command {
6
- static description = '执行数据库迁移 (db:migrate)';
7
- static flags = {
8
- env: EnvFlag,
9
- };
10
- async run() {
11
- const { flags } = await this.parse(DbMigrate);
12
- const env = await selectEnvironment(flags.env);
13
- const { files, isBuiltIn } = await getComposeFiles(env);
14
- logger.info('正在执行数据库迁移...');
15
- await execCompose(files, 'api', ['npm', 'run', 'db:migrate'], isBuiltIn);
16
- logger.success('数据库迁移完成');
17
- }
18
- }
File without changes
File without changes