@nocobase/cli 2.1.0-alpha.20 → 2.1.0-alpha.22

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 (42) hide show
  1. package/README.md +256 -89
  2. package/README.zh-CN.md +332 -0
  3. package/bin/run.js +21 -2
  4. package/dist/commands/build.js +7 -1
  5. package/dist/commands/db/logs.js +85 -0
  6. package/dist/commands/db/ps.js +60 -0
  7. package/dist/commands/db/shared.js +81 -0
  8. package/dist/commands/db/start.js +55 -7
  9. package/dist/commands/db/stop.js +70 -0
  10. package/dist/commands/dev.js +112 -21
  11. package/dist/commands/down.js +193 -0
  12. package/dist/commands/download.js +633 -183
  13. package/dist/commands/env/add.js +260 -131
  14. package/dist/commands/env/auth.js +9 -8
  15. package/dist/commands/init.js +723 -103
  16. package/dist/commands/install.js +1702 -565
  17. package/dist/commands/logs.js +90 -0
  18. package/dist/commands/pm/disable.js +35 -3
  19. package/dist/commands/pm/enable.js +35 -3
  20. package/dist/commands/pm/list.js +37 -4
  21. package/dist/commands/prompts-stages.js +150 -0
  22. package/dist/commands/prompts-test.js +181 -0
  23. package/dist/commands/ps.js +116 -0
  24. package/dist/commands/start.js +171 -15
  25. package/dist/commands/stop.js +90 -0
  26. package/dist/commands/upgrade.js +559 -11
  27. package/dist/lib/api-client.js +49 -5
  28. package/dist/lib/app-runtime.js +142 -0
  29. package/dist/lib/auth-store.js +44 -3
  30. package/dist/lib/bootstrap.js +7 -3
  31. package/dist/lib/cli-locale.js +115 -0
  32. package/dist/lib/env-auth.js +427 -82
  33. package/dist/lib/prompt-catalog.js +574 -0
  34. package/dist/lib/prompt-validators.js +185 -0
  35. package/dist/lib/prompt-web-ui.js +2061 -0
  36. package/dist/lib/run-npm.js +71 -7
  37. package/dist/lib/runtime-generator.js +12 -1
  38. package/dist/locale/en-US.json +282 -0
  39. package/dist/locale/zh-CN.json +282 -0
  40. package/package.json +5 -4
  41. package/dist/commands/restart.js +0 -32
  42. package/dist/lib/init-browser-wizard.js +0 -431
@@ -0,0 +1,332 @@
1
+ # NocoBase CLI
2
+
3
+ NocoBase CLI (`nb`) 是用于在本地工作区初始化、连接和管理 NocoBase 应用的命令行工具。它可以帮助你准备 NocoBase 应用、保存 CLI env 配置,并提供启动、停止、查看日志、升级和清理等日常管理命令,让 coding agent 可以连接并使用 NocoBase。
4
+
5
+ CLI 支持两种常见的初始化方式:
6
+
7
+ - 连接已有的 NocoBase 应用,让 coding agent 直接使用。
8
+ - 通过 Docker、npm 或 Git 安装一个新的 NocoBase 应用,并保存为 CLI env。
9
+
10
+ ## 前提条件
11
+
12
+ - Node.js v20+
13
+ - Yarn 1.x
14
+ - Git:选择 Git 源码安装时需要
15
+ - Docker:使用 Docker 方式安装,或使用内置数据库时需要
16
+
17
+ ## 安装
18
+
19
+ 全局安装 CLI:
20
+
21
+ ```bash
22
+ npm install -g @nocobase/cli@alpha
23
+ ```
24
+
25
+ 查看可用命令:
26
+
27
+ ```bash
28
+ nb --help
29
+ nb init --help
30
+ ```
31
+
32
+ ## 核心概念
33
+
34
+ - **Workspace**:当前项目目录,CLI 会在这里保存 `.nocobase` 配置。
35
+ - **Env**:CLI 保存的一个 NocoBase 连接配置。在 `nb init` 中,app name 也就是 env name。
36
+ - **Source**:本地应用的来源,支持 `docker`、`npm` 和 `git`。
37
+ - **Remote env**:只保存已有 NocoBase 应用 API 连接的 env。
38
+ - **Runtime resources**:由 CLI 管理的本地运行资源,包括应用进程、Docker 应用容器、内置数据库容器、源码目录和存储目录。
39
+
40
+ ## 快速开始
41
+
42
+ ### 交互式初始化
43
+
44
+ 在终端中启动引导式初始化:
45
+
46
+ ```bash
47
+ nb init
48
+ ```
49
+
50
+ 使用浏览器表单完成初始化:
51
+
52
+ ```bash
53
+ nb init --ui
54
+ ```
55
+
56
+ `nb init` 可以连接已有的 NocoBase 应用,也可以安装一个新的 NocoBase 应用。创建新应用时,还可以为当前工作区安装 NocoBase AI coding skills (`nocobase/skills`)。
57
+
58
+ ### 非交互式初始化
59
+
60
+ 跳过交互提示时,必须提供 app/env name:
61
+
62
+ ```bash
63
+ nb init --env app1 --yes
64
+ ```
65
+
66
+ 使用 Docker 安装:
67
+
68
+ ```bash
69
+ nb init --env app1 --yes --source docker --version alpha
70
+ ```
71
+
72
+ 使用 npm 安装:
73
+
74
+ ```bash
75
+ nb init --env app1 --yes --source npm --version alpha --app-port 13080
76
+ ```
77
+
78
+ 使用 Git 源码安装:
79
+
80
+ ```bash
81
+ nb init --env app1 --yes --source git --version alpha
82
+ ```
83
+
84
+ 对于 Git 源码安装,`--version alpha` 实际会解析为 `develop` 分支。
85
+
86
+ 使用 Git 分支安装:
87
+
88
+ ```bash
89
+ nb init --env app1 --yes --source git --version fix/cli-v2
90
+ ```
91
+
92
+ `--version` 是三种 source 共用的版本参数:
93
+
94
+ - npm:包版本号
95
+ - Docker:镜像 tag
96
+ - Git:git ref,例如 branch 或 tag
97
+
98
+ 默认情况下,新建本地应用会使用以下目录:
99
+
100
+ - 源码目录:`./<envName>/source/`
101
+ - 存储目录:`./<envName>/storage/`
102
+
103
+ ### 恢复中断的初始化
104
+
105
+ 如果 `nb init` 在 env 配置已经保存之后中断了,可以继续上一次初始化流程:
106
+
107
+ ```bash
108
+ nb init --env app1 --resume
109
+ ```
110
+
111
+ 对应的底层高级命令是:
112
+
113
+ ```bash
114
+ nb install --env app1 --resume
115
+ ```
116
+
117
+ `--resume` 会复用工作区里已保存的 env config,包括应用、source、数据库和 env 连接相关配置。在交互模式下,只会继续补齐缺失的初始化参数。
118
+
119
+ 在非交互模式下,需要重新传这些只用于初始化、不会保存到 env config 的参数:
120
+
121
+ - `--lang`
122
+ - `--root-username`
123
+ - `--root-email`
124
+ - `--root-password`
125
+ - `--root-nickname`
126
+
127
+ ## 常用命令
128
+
129
+ | 命令 | 说明 |
130
+ | --- | --- |
131
+ | `nb init` | 初始化 NocoBase,并连接为 coding agent 可使用的 CLI env。 |
132
+ | `nb install` | `nb init` 内部会使用的高级命令,用于安装本地 NocoBase 应用并保存 env 配置。通常建议直接使用 `nb init`。 |
133
+ | `nb download` | `nb init` 或 `nb upgrade` 会使用的高级命令,用于从 Docker、npm 或 Git 获取 NocoBase。通常很少直接使用。 |
134
+ | `nb start` | 启动选中的本地应用或 Docker 容器。 |
135
+ | `nb stop` | 停止选中的本地应用或 Docker 容器。 |
136
+ | `nb dev` | 为 npm/Git 源码 env 启动开发模式。 |
137
+ | `nb logs` | 查看 npm/Git 或 Docker env 的应用日志。 |
138
+ | `nb ps` | 查看已配置 env 的运行状态。 |
139
+ | `nb db` | 查看或管理本地 env 的内置数据库运行状态。 |
140
+ | `nb upgrade` | 更新源码/镜像并重启选中的应用。 |
141
+ | `nb down` | 停止并移除某个 env 的本地运行容器。 |
142
+ | `nb env` | 管理已保存的 CLI env 连接。 |
143
+ | `nb api` | 通过 CLI 调用 NocoBase API 资源。 |
144
+ | `nb pm` | 管理选中 NocoBase env 的插件。 |
145
+
146
+ 推荐在应用和运行时相关命令里显式使用 `--env`;`-e` 是它的简写:
147
+
148
+ ```bash
149
+ nb start --env app1
150
+ nb logs --env app1
151
+ nb ps --env app1
152
+ nb db ps --env app1
153
+ ```
154
+
155
+ 等价的简写示例:
156
+
157
+ ```bash
158
+ nb start -e app1
159
+ nb logs -e app1
160
+ nb upgrade -e app1
161
+ nb db start -e app1
162
+ ```
163
+
164
+ ## 运行方式
165
+
166
+ ### Docker
167
+
168
+ Docker env 会通过已保存的 Docker 容器和镜像进行管理:
169
+
170
+ ```bash
171
+ nb init --env app1 --yes --source docker --version alpha
172
+ nb start --env app1
173
+ nb logs --env app1
174
+ nb stop --env app1
175
+ ```
176
+
177
+ Docker 下载支持指定平台:
178
+
179
+ ```bash
180
+ nb download --source docker --version alpha --docker-platform auto
181
+ nb download --source docker --version alpha --docker-platform linux/amd64
182
+ nb download --source docker --version alpha --docker-platform linux/arm64
183
+ ```
184
+
185
+ ### npm 和 Git
186
+
187
+ npm 和 Git env 会使用本地源码目录,并支持开发模式:
188
+
189
+ ```bash
190
+ nb init --env app1 --yes --source git --version alpha
191
+ nb dev --env app1
192
+ ```
193
+
194
+ `nb dev` 只支持 npm/Git 源码 env。Docker env 可以通过 `nb logs` 查看日志,remote env 只支持 API 和 env 相关操作。
195
+
196
+ ### 已有 NocoBase 应用
197
+
198
+ 如果要连接已有应用,可以运行 `nb init` 并选择已有应用流程,也可以直接添加 env:
199
+
200
+ ```bash
201
+ nb env add app1 --base-url http://localhost:13000/api
202
+ ```
203
+
204
+ `nb env add` 会在需要时自动进入认证流程。
205
+
206
+ ## 升级
207
+
208
+ 升级会更新已保存的源码或镜像,然后重启应用:
209
+
210
+ ```bash
211
+ nb upgrade --env app1
212
+ ```
213
+
214
+ 如果只想使用当前已保存的本地源码或 Docker 镜像重启应用,可以使用 `--skip-code-update` 或 `-s`:
215
+
216
+ ```bash
217
+ nb upgrade --env app1 -s
218
+ ```
219
+
220
+ ## 数据库命令
221
+
222
+ 可以使用 `nb db` 查看或管理本地 env 的内置数据库运行状态:
223
+
224
+ ```bash
225
+ nb db ps
226
+ nb db ps --env app1
227
+ nb db start --env app1
228
+ nb db stop --env app1
229
+ nb db logs --env app1
230
+ ```
231
+
232
+ 说明:
233
+
234
+ - `nb db start` 和 `nb db stop` 只适用于启用了内置数据库的 env。
235
+ - `nb db logs` 只适用于启用了内置数据库的 env。
236
+ - 对于没有 CLI 托管数据库容器的 env,`nb db ps` 也会显示 `external` 或 `remote` 状态。
237
+
238
+ ## 清理
239
+
240
+ 关闭并清理某个本地 env:
241
+
242
+ ```bash
243
+ nb down --env app1
244
+ ```
245
+
246
+ 默认情况下,`nb down` 会停止应用,并在存在时移除应用容器和数据库容器。它不会删除用户数据、源码文件和 CLI env 配置。
247
+
248
+ 如需执行破坏性清理,需要显式指定参数:
249
+
250
+ ```bash
251
+ nb down --env app1 --remove-data
252
+ nb down --env app1 --remove-source
253
+ nb down --env app1 --remove-env
254
+ ```
255
+
256
+ - `--remove-data`:删除 storage 和托管数据库数据。除非使用 `--yes`,否则需要二次确认。
257
+ - `--remove-source`:删除 npm/Git 源码目录。
258
+ - `--remove-env`:删除已保存的 CLI env 配置。
259
+
260
+ ## Env 管理
261
+
262
+ 查看当前 env:
263
+
264
+ ```bash
265
+ nb env
266
+ ```
267
+
268
+ 查看已配置的 env:
269
+
270
+ ```bash
271
+ nb env list
272
+ ```
273
+
274
+ 切换当前 env:
275
+
276
+ ```bash
277
+ nb env use app1
278
+ ```
279
+
280
+ 当凭证需要刷新时,重新认证某个 env:
281
+
282
+ ```bash
283
+ nb env auth app1
284
+ ```
285
+
286
+ 从选中的应用更新运行时命令元数据:
287
+
288
+ ```bash
289
+ nb env update app1
290
+ ```
291
+
292
+ ## API 命令
293
+
294
+ CLI 可以通过已配置的 env 调用 NocoBase 资源 API:
295
+
296
+ ```bash
297
+ nb api resource list --resource users -e app1
298
+ nb api resource get --resource users --filter-by-tk 1 -e app1
299
+ nb api resource create --resource users --values '{"nickname":"Ada"}' -e app1
300
+ ```
301
+
302
+ 如果需要输出原始 JSON,可以使用 `-j, --json-output`:
303
+
304
+ ```bash
305
+ nb api resource list --resource users -e app1 -j
306
+ ```
307
+
308
+ 可用的 API 命令分类:
309
+
310
+ | 命令 | 说明 |
311
+ | --- | --- |
312
+ | `nb api acl` | 基于角色、资源和操作管理访问控制。 |
313
+ | `nb api api-keys` | 管理用于 HTTP API 访问的 API keys。 |
314
+ | `nb api app` | 管理应用相关资源。 |
315
+ | `nb api authenticators` | 管理用户认证,包括密码认证、短信认证、SSO 协议和可扩展认证方式。 |
316
+ | `nb api data-modeling` | 管理数据源、数据表和数据库建模资源。 |
317
+ | `nb api file-manager` | 管理文件存储服务、文件集合和附件字段。 |
318
+ | `nb api flow-surfaces` | 组合和更新页面、标签页、区块、字段和操作等界面结构。 |
319
+ | `nb api pm` | 通过 API 命令管理插件。 |
320
+ | `nb api resource` | 操作通用集合资源。 |
321
+ | `nb api system-settings` | 调整系统标题、Logo、语言和其他全局设置。 |
322
+ | `nb api theme-editor` | 自定义 UI 颜色和尺寸,保存并切换主题。 |
323
+ | `nb api workflow` | 管理用于业务自动化的工作流资源。 |
324
+
325
+ ## 本地数据
326
+
327
+ CLI 会在工作区的 `.nocobase` 中保存配置:
328
+
329
+ - `config.json`:env 定义、当前 env 和工作区级配置。
330
+ - `versions/<version>/commands.json`:从目标应用生成并缓存的运行时命令。
331
+
332
+ 源码文件、storage 文件、Docker 容器和数据库数据等运行时数据,会根据 env 的 source 和安装选项分别管理。
package/bin/run.js CHANGED
@@ -2,10 +2,12 @@
2
2
 
3
3
  import { spawnSync } from 'node:child_process';
4
4
  import fs from 'node:fs';
5
+ import { createRequire } from 'node:module';
5
6
  import path from 'node:path';
6
7
  import { fileURLToPath, pathToFileURL } from 'node:url';
7
8
 
8
9
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
10
+ const requireFromCli = createRequire(import.meta.url);
9
11
  const root = path.resolve(__dirname, '..');
10
12
  const realRoot = fs.realpathSync(root);
11
13
  const isSourcePackage = realRoot.split(path.sep).join('/').endsWith('/packages/core/cli');
@@ -15,13 +17,30 @@ if (process.env.NB_CLI_USE_DIST === '1') {
15
17
  }
16
18
 
17
19
  /**
18
- * In the monorepo, plain `node` cannot load `.ts`. Re-exec once with `--import tsx`
20
+ * In the monorepo, plain `node` cannot load `.ts`. Re-exec once with `--import <tsx>`
19
21
  * (same effect as a dedicated dev entry with `#!/usr/bin/env -S node --import tsx`).
22
+ *
23
+ * Use the tsx package resolved from this CLI install (not CWD), so `nb` works when
24
+ * invoked from a project directory that does not depend on `tsx`.
20
25
  */
21
26
  function reexecWithTsx() {
27
+ let tsxEntry;
28
+ try {
29
+ tsxEntry = requireFromCli.resolve('tsx');
30
+ } catch {
31
+ console.error(
32
+ [
33
+ 'Cannot load dev dependency `tsx` for the NocoBase CLI.',
34
+ 'Install monorepo dependencies (e.g. `yarn install` at the repo root),',
35
+ 'or set NB_CLI_USE_DIST=1 to run the compiled CLI without TypeScript sources.',
36
+ ].join(' '),
37
+ );
38
+ process.exit(1);
39
+ }
40
+
22
41
  const result = spawnSync(
23
42
  process.execPath,
24
- ['--import', 'tsx', '--disable-warning=ExperimentalWarning', ...process.argv.slice(1)],
43
+ ['--import', pathToFileURL(tsxEntry).href, '--disable-warning=ExperimentalWarning', ...process.argv.slice(1)],
25
44
  {
26
45
  stdio: 'inherit',
27
46
  env: {
@@ -8,6 +8,7 @@
8
8
  */
9
9
  import { Args, Command, Flags } from '@oclif/core';
10
10
  import { runNocoBaseCommand } from "../lib/run-npm.js";
11
+ import { setVerboseMode } from '../lib/ui.js';
11
12
  export default class Build extends Command {
12
13
  static args = {
13
14
  /** Matches `nb build @nocobase/acl @nocobase/actions` — zero or more package names. */
@@ -29,9 +30,11 @@ export default class Build extends Command {
29
30
  'cwd': Flags.string({ description: 'Current working directory', char: 'c', required: false }),
30
31
  'no-dts': Flags.boolean({ description: 'not generate dts' }),
31
32
  sourcemap: Flags.boolean({ description: 'generate sourcemap' }),
33
+ verbose: Flags.boolean({ description: 'Show detailed command output', default: false }),
32
34
  };
33
35
  async run() {
34
36
  const { args, flags } = await this.parse(Build);
37
+ setVerboseMode(flags.verbose);
35
38
  const packages = args.packages ?? [];
36
39
  const npmArgs = ['build', ...packages];
37
40
  if (flags['no-dts']) {
@@ -41,7 +44,10 @@ export default class Build extends Command {
41
44
  npmArgs.push('--sourcemap');
42
45
  }
43
46
  try {
44
- await runNocoBaseCommand(npmArgs, { cwd: flags['cwd'] });
47
+ await runNocoBaseCommand(npmArgs, {
48
+ cwd: flags['cwd'],
49
+ stdio: flags.verbose ? 'inherit' : 'ignore',
50
+ });
45
51
  }
46
52
  catch (error) {
47
53
  const message = error instanceof Error ? error.message : String(error);
@@ -0,0 +1,85 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+ import { Command, Flags } from '@oclif/core';
10
+ import { formatMissingManagedAppEnvMessage } from '../../lib/app-runtime.js';
11
+ import { run } from '../../lib/run-npm.js';
12
+ import { printInfo } from '../../lib/ui.js';
13
+ import { formatUnmanagedDbLogsMessage, resolveDbRuntime } from './shared.js';
14
+ function formatDbLogsFailure(envName, message) {
15
+ if (/does not exist/i.test(message)) {
16
+ return [
17
+ `Can't show database logs for "${envName}" yet.`,
18
+ 'The saved built-in database container for this env could not be found on this machine.',
19
+ 'Try reinstalling the env, or check whether the container was removed outside the CLI.',
20
+ `Details: ${message}`,
21
+ ].join('\n');
22
+ }
23
+ return [
24
+ `Couldn't show database logs for "${envName}".`,
25
+ 'Check that the built-in database runtime for this env is still available, then try again.',
26
+ `Details: ${message}`,
27
+ ].join('\n');
28
+ }
29
+ export default class DbLogs extends Command {
30
+ static description = 'Show logs for the built-in database container of the selected env.';
31
+ static examples = [
32
+ '<%= config.bin %> <%= command.id %>',
33
+ '<%= config.bin %> <%= command.id %> --env app1',
34
+ '<%= config.bin %> <%= command.id %> --env app1 --tail 200',
35
+ '<%= config.bin %> <%= command.id %> --env app1 --no-follow',
36
+ ];
37
+ static flags = {
38
+ env: Flags.string({
39
+ char: 'e',
40
+ description: 'CLI env name to inspect built-in database logs for. Defaults to the current env when omitted',
41
+ }),
42
+ tail: Flags.integer({
43
+ description: 'Number of recent log lines to show before following',
44
+ default: 100,
45
+ min: 0,
46
+ }),
47
+ follow: Flags.boolean({
48
+ char: 'f',
49
+ description: 'Keep streaming new log lines',
50
+ default: true,
51
+ allowNo: true,
52
+ }),
53
+ };
54
+ async run() {
55
+ const { flags } = await this.parse(DbLogs);
56
+ const requestedEnv = flags.env?.trim() || undefined;
57
+ const runtime = await resolveDbRuntime(requestedEnv);
58
+ if (!runtime) {
59
+ this.error(formatMissingManagedAppEnvMessage(requestedEnv));
60
+ }
61
+ if (runtime.kind !== 'builtin') {
62
+ this.error(formatUnmanagedDbLogsMessage(runtime));
63
+ }
64
+ const tail = String(flags.tail ?? 100);
65
+ const follow = flags.follow !== false;
66
+ printInfo(follow
67
+ ? `Showing built-in database logs for "${runtime.envName}" (press Ctrl+C to stop).`
68
+ : `Showing recent built-in database logs for "${runtime.envName}".`);
69
+ const dockerArgs = ['logs', '--tail', tail];
70
+ if (follow) {
71
+ dockerArgs.push('--follow');
72
+ }
73
+ dockerArgs.push(runtime.containerName);
74
+ try {
75
+ await run('docker', dockerArgs, {
76
+ errorName: 'docker logs',
77
+ stdio: 'inherit',
78
+ });
79
+ }
80
+ catch (error) {
81
+ const message = error instanceof Error ? error.message : String(error);
82
+ this.error(formatDbLogsFailure(runtime.envName, message));
83
+ }
84
+ }
85
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+ import { Command, Flags } from '@oclif/core';
10
+ import { formatMissingManagedAppEnvMessage } from '../../lib/app-runtime.js';
11
+ import { listEnvs } from '../../lib/auth-store.js';
12
+ import { renderTable } from '../../lib/ui.js';
13
+ import { builtinDbStatus, resolveDbRuntime } from './shared.js';
14
+ export default class DbPs extends Command {
15
+ static description = 'Show built-in database runtime status for configured envs without starting or stopping anything.';
16
+ static examples = [
17
+ '<%= config.bin %> <%= command.id %>',
18
+ '<%= config.bin %> <%= command.id %> --env app1',
19
+ ];
20
+ static flags = {
21
+ env: Flags.string({
22
+ char: 'e',
23
+ description: 'CLI env name to inspect. Omit to show all configured envs',
24
+ }),
25
+ };
26
+ async run() {
27
+ const { flags } = await this.parse(DbPs);
28
+ const requestedEnv = flags.env?.trim() || undefined;
29
+ const envNames = requestedEnv
30
+ ? [requestedEnv]
31
+ : Object.keys((await listEnvs()).envs).sort();
32
+ if (!envNames.length) {
33
+ this.log('No NocoBase env is configured yet. Run `nb init` to create one first.');
34
+ return;
35
+ }
36
+ const rows = [];
37
+ for (const envName of envNames) {
38
+ const runtime = await resolveDbRuntime(envName);
39
+ if (!runtime) {
40
+ if (requestedEnv) {
41
+ this.error(formatMissingManagedAppEnvMessage(envName));
42
+ }
43
+ rows.push([envName, '-', '-', 'missing', '']);
44
+ continue;
45
+ }
46
+ const type = runtime.kind === 'builtin' ? 'builtin' : runtime.status;
47
+ const status = runtime.kind === 'builtin'
48
+ ? await builtinDbStatus(runtime.containerName)
49
+ : runtime.status;
50
+ rows.push([
51
+ runtime.envName,
52
+ type,
53
+ runtime.dbDialect,
54
+ status,
55
+ runtime.address,
56
+ ]);
57
+ }
58
+ this.log(renderTable(['Env', 'Type', 'Dialect', 'Status', 'Address'], rows));
59
+ }
60
+ }
@@ -0,0 +1,81 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+ import { buildDockerDbContainerName, dockerContainerExists, dockerContainerIsRunning, resolveManagedAppRuntime, } from '../../lib/app-runtime.js';
10
+ function formatAddress(host, port, fallbackHost) {
11
+ const normalizedHost = String(host ?? '').trim() || String(fallbackHost ?? '').trim();
12
+ const normalizedPort = String(port ?? '').trim();
13
+ if (normalizedHost && normalizedPort) {
14
+ return `${normalizedHost}:${normalizedPort}`;
15
+ }
16
+ return normalizedHost || normalizedPort || '';
17
+ }
18
+ export async function resolveDbRuntime(envName) {
19
+ const runtime = await resolveManagedAppRuntime(envName);
20
+ if (!runtime) {
21
+ return undefined;
22
+ }
23
+ const source = runtime.kind === 'remote' ? 'remote' : runtime.source;
24
+ const dbDialect = String(runtime.env.config.dbDialect ?? 'postgres').trim() || 'postgres';
25
+ if (runtime.kind !== 'remote' && runtime.env.config.builtinDb) {
26
+ const containerName = buildDockerDbContainerName(runtime.envName, dbDialect, runtime.workspaceName);
27
+ return {
28
+ kind: 'builtin',
29
+ envName: runtime.envName,
30
+ source,
31
+ dbDialect,
32
+ containerName,
33
+ address: formatAddress(runtime.env.config.dbHost, runtime.env.config.dbPort, containerName),
34
+ appRuntime: runtime,
35
+ };
36
+ }
37
+ return {
38
+ kind: 'external',
39
+ envName: runtime.envName,
40
+ source,
41
+ dbDialect,
42
+ address: formatAddress(runtime.env.config.dbHost, runtime.env.config.dbPort),
43
+ status: runtime.kind === 'remote' ? 'remote' : 'external',
44
+ appRuntime: runtime,
45
+ };
46
+ }
47
+ export async function builtinDbStatus(containerName) {
48
+ if (!(await dockerContainerExists(containerName))) {
49
+ return 'missing';
50
+ }
51
+ return await dockerContainerIsRunning(containerName) ? 'running' : 'stopped';
52
+ }
53
+ export function formatUnmanagedDbMessage(action, runtime) {
54
+ const verb = action === 'start' ? 'start' : 'stop';
55
+ if (runtime.appRuntime.kind === 'remote') {
56
+ return [
57
+ `Can't ${verb} the database for "${runtime.envName}" from this machine.`,
58
+ 'This env only has an API connection, so there is no CLI-managed database container here.',
59
+ 'If you need CLI-managed database start and stop, create a local env with the built-in database option enabled.',
60
+ ].join('\n');
61
+ }
62
+ return [
63
+ `Can't ${verb} the database for "${runtime.envName}" from this machine.`,
64
+ 'This env does not use a CLI-managed built-in database, so there is no saved database container to manage here.',
65
+ 'If you need CLI-managed database start and stop, recreate the env with the built-in database option enabled.',
66
+ ].join('\n');
67
+ }
68
+ export function formatUnmanagedDbLogsMessage(runtime) {
69
+ if (runtime.appRuntime.kind === 'remote') {
70
+ return [
71
+ `Can't show database logs for "${runtime.envName}" from this machine.`,
72
+ 'This env only has an API connection, so there is no CLI-managed database container here.',
73
+ 'If you need CLI-managed database logs, create a local env with the built-in database option enabled.',
74
+ ].join('\n');
75
+ }
76
+ return [
77
+ `Can't show database logs for "${runtime.envName}" from this machine.`,
78
+ 'This env does not use a CLI-managed built-in database, so there is no saved database container to read logs from here.',
79
+ 'If you need CLI-managed database logs, recreate the env with the built-in database option enabled.',
80
+ ].join('\n');
81
+ }