@nocobase/cli 2.1.0-alpha.23 → 2.1.0-alpha.25
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 +37 -2
- package/README.zh-CN.md +6 -2
- package/bin/run.js +28 -11
- package/dist/commands/db/shared.js +19 -5
- package/dist/commands/dev.js +8 -1
- package/dist/commands/down.js +10 -6
- package/dist/commands/env/add.js +14 -34
- package/dist/commands/env/auth.js +6 -13
- package/dist/commands/env/list.js +10 -15
- package/dist/commands/env/remove.js +4 -10
- package/dist/commands/env/update.js +7 -13
- package/dist/commands/env/use.js +5 -13
- package/dist/commands/init.js +190 -62
- package/dist/commands/install.js +101 -33
- package/dist/commands/logs.js +8 -1
- package/dist/commands/pm/list.js +8 -1
- package/dist/commands/ps.js +18 -15
- package/dist/commands/restart.js +74 -0
- package/dist/commands/self/check.js +71 -0
- package/dist/commands/self/index.js +20 -0
- package/dist/commands/self/update.js +86 -0
- package/dist/commands/skills/check.js +69 -0
- package/dist/commands/skills/index.js +20 -0
- package/dist/commands/skills/install.js +71 -0
- package/dist/commands/skills/update.js +71 -0
- package/dist/commands/start.js +8 -1
- package/dist/commands/stop.js +8 -1
- package/dist/commands/test.js +466 -0
- package/dist/commands/upgrade.js +12 -1
- package/dist/lib/api-client.js +3 -2
- package/dist/lib/app-runtime.js +16 -5
- package/dist/lib/auth-store.js +159 -43
- package/dist/lib/bootstrap.js +13 -12
- package/dist/lib/cli-home.js +33 -2
- package/dist/lib/env-auth.js +3 -3
- package/dist/lib/generated-command.js +10 -2
- package/dist/lib/http-request.js +49 -0
- package/dist/lib/resource-command.js +10 -2
- package/dist/lib/run-npm.js +82 -8
- package/dist/lib/runtime-generator.js +1 -1
- package/dist/lib/self-manager.js +246 -0
- package/dist/lib/skills-manager.js +269 -0
- package/dist/lib/startup-update.js +203 -0
- package/dist/locale/en-US.json +4 -1
- package/dist/locale/zh-CN.json +4 -1
- package/package.json +10 -4
package/README.md
CHANGED
|
@@ -58,7 +58,7 @@ nb init --ui
|
|
|
58
58
|
|
|
59
59
|
`nb init` can either connect to an existing NocoBase app or install a new one.
|
|
60
60
|
When creating a new app, it can also install NocoBase AI coding skills
|
|
61
|
-
(`nocobase/skills`)
|
|
61
|
+
(`nocobase/skills`) globally.
|
|
62
62
|
|
|
63
63
|
### Non-Interactive Setup
|
|
64
64
|
|
|
@@ -138,6 +138,7 @@ In non-interactive mode, pass these setup-only flags again because they are not
|
|
|
138
138
|
| `nb download` | Advanced command used by `nb init` or `nb upgrade` to fetch NocoBase from Docker, npm, or Git. It is rarely used directly. |
|
|
139
139
|
| `nb start` | Start the selected local app or Docker container. |
|
|
140
140
|
| `nb stop` | Stop the selected local app or Docker container. |
|
|
141
|
+
| `nb restart` | Stop, then start the selected local app or Docker container. |
|
|
141
142
|
| `nb dev` | Run development mode for npm/Git source envs. |
|
|
142
143
|
| `nb logs` | Show app logs for npm/Git or Docker envs. |
|
|
143
144
|
| `nb ps` | Show runtime status for configured envs. |
|
|
@@ -147,11 +148,14 @@ In non-interactive mode, pass these setup-only flags again because they are not
|
|
|
147
148
|
| `nb env` | Manage saved CLI env connections. |
|
|
148
149
|
| `nb api` | Call NocoBase API resources from the CLI. |
|
|
149
150
|
| `nb pm` | Manage plugins for the selected NocoBase env. |
|
|
151
|
+
| `nb self` | Check or update the installed NocoBase CLI. |
|
|
152
|
+
| `nb skills` | Check, install, or update global NocoBase AI coding skills. |
|
|
150
153
|
|
|
151
154
|
Recommended style: use `--env` explicitly for app/runtime commands. `-e` is the short form:
|
|
152
155
|
|
|
153
156
|
```bash
|
|
154
157
|
nb start --env app1
|
|
158
|
+
nb restart --env app1
|
|
155
159
|
nb logs --env app1
|
|
156
160
|
nb ps --env app1
|
|
157
161
|
nb db ps --env app1
|
|
@@ -161,11 +165,41 @@ Equivalent shorthand examples:
|
|
|
161
165
|
|
|
162
166
|
```bash
|
|
163
167
|
nb start -e app1
|
|
168
|
+
nb restart -e app1
|
|
164
169
|
nb logs -e app1
|
|
165
170
|
nb upgrade -e app1
|
|
166
171
|
nb db start -e app1
|
|
167
172
|
```
|
|
168
173
|
|
|
174
|
+
## CLI And Skills Updates
|
|
175
|
+
|
|
176
|
+
Check whether the installed CLI itself is up to date:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
nb self check
|
|
180
|
+
nb self check --json
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Update the CLI when it is installed globally with npm:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
nb self update
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Check whether the global NocoBase AI coding skills are installed:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
nb skills check
|
|
193
|
+
nb skills check --json
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Install the skills for the first time, or update an existing `nocobase/skills` install:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
nb skills install
|
|
200
|
+
nb skills update
|
|
201
|
+
```
|
|
202
|
+
|
|
169
203
|
## Runtime Types
|
|
170
204
|
|
|
171
205
|
### Docker
|
|
@@ -175,6 +209,7 @@ Docker envs are managed through saved Docker containers and images:
|
|
|
175
209
|
```bash
|
|
176
210
|
nb init --env app1 --yes --source docker --version alpha
|
|
177
211
|
nb start --env app1
|
|
212
|
+
nb restart --env app1
|
|
178
213
|
nb logs --env app1
|
|
179
214
|
nb stop --env app1
|
|
180
215
|
```
|
|
@@ -205,7 +240,7 @@ To connect an existing app, use `nb init` and choose the existing-app setup
|
|
|
205
240
|
path, or add the env directly:
|
|
206
241
|
|
|
207
242
|
```bash
|
|
208
|
-
nb env add app1 --base-url http://localhost:13000/api
|
|
243
|
+
nb env add app1 --api-base-url http://localhost:13000/api
|
|
209
244
|
```
|
|
210
245
|
|
|
211
246
|
`nb env add` will start the authentication flow automatically when needed.
|
package/README.zh-CN.md
CHANGED
|
@@ -53,7 +53,7 @@ nb init
|
|
|
53
53
|
nb init --ui
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
`nb init` 可以连接已有的 NocoBase 应用,也可以安装一个新的 NocoBase
|
|
56
|
+
`nb init` 可以连接已有的 NocoBase 应用,也可以安装一个新的 NocoBase 应用。创建新应用时,还可以全局安装 NocoBase AI coding skills (`nocobase/skills`)。
|
|
57
57
|
|
|
58
58
|
### 非交互式初始化
|
|
59
59
|
|
|
@@ -133,6 +133,7 @@ nb install --env app1 --resume
|
|
|
133
133
|
| `nb download` | `nb init` 或 `nb upgrade` 会使用的高级命令,用于从 Docker、npm 或 Git 获取 NocoBase。通常很少直接使用。 |
|
|
134
134
|
| `nb start` | 启动选中的本地应用或 Docker 容器。 |
|
|
135
135
|
| `nb stop` | 停止选中的本地应用或 Docker 容器。 |
|
|
136
|
+
| `nb restart` | 先停止,再启动选中的本地应用或 Docker 容器。 |
|
|
136
137
|
| `nb dev` | 为 npm/Git 源码 env 启动开发模式。 |
|
|
137
138
|
| `nb logs` | 查看 npm/Git 或 Docker env 的应用日志。 |
|
|
138
139
|
| `nb ps` | 查看已配置 env 的运行状态。 |
|
|
@@ -147,6 +148,7 @@ nb install --env app1 --resume
|
|
|
147
148
|
|
|
148
149
|
```bash
|
|
149
150
|
nb start --env app1
|
|
151
|
+
nb restart --env app1
|
|
150
152
|
nb logs --env app1
|
|
151
153
|
nb ps --env app1
|
|
152
154
|
nb db ps --env app1
|
|
@@ -156,6 +158,7 @@ nb db ps --env app1
|
|
|
156
158
|
|
|
157
159
|
```bash
|
|
158
160
|
nb start -e app1
|
|
161
|
+
nb restart -e app1
|
|
159
162
|
nb logs -e app1
|
|
160
163
|
nb upgrade -e app1
|
|
161
164
|
nb db start -e app1
|
|
@@ -170,6 +173,7 @@ Docker env 会通过已保存的 Docker 容器和镜像进行管理:
|
|
|
170
173
|
```bash
|
|
171
174
|
nb init --env app1 --yes --source docker --version alpha
|
|
172
175
|
nb start --env app1
|
|
176
|
+
nb restart --env app1
|
|
173
177
|
nb logs --env app1
|
|
174
178
|
nb stop --env app1
|
|
175
179
|
```
|
|
@@ -198,7 +202,7 @@ nb dev --env app1
|
|
|
198
202
|
如果要连接已有应用,可以运行 `nb init` 并选择已有应用流程,也可以直接添加 env:
|
|
199
203
|
|
|
200
204
|
```bash
|
|
201
|
-
nb env add app1 --base-url http://localhost:13000/api
|
|
205
|
+
nb env add app1 --api-base-url http://localhost:13000/api
|
|
202
206
|
```
|
|
203
207
|
|
|
204
208
|
`nb env add` 会在需要时自动进入认证流程。
|
package/bin/run.js
CHANGED
|
@@ -38,18 +38,20 @@ function reexecWithTsx() {
|
|
|
38
38
|
process.exit(1);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
41
|
+
const reexecArgs = ['--import', pathToFileURL(tsxEntry).href];
|
|
42
|
+
const supportedFlags = Array.from(process.allowedNodeEnvironmentFlags);
|
|
43
|
+
if (supportedFlags.some((flag) => flag === '--disable-warning' || flag.startsWith('--disable-warning='))) {
|
|
44
|
+
reexecArgs.push('--disable-warning=ExperimentalWarning');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const result = spawnSync(process.execPath, [...reexecArgs, ...process.argv.slice(1)], {
|
|
48
|
+
stdio: 'inherit',
|
|
49
|
+
env: {
|
|
50
|
+
...process.env,
|
|
51
|
+
_NOCO_CLI_TSX_CHILD: '1',
|
|
52
|
+
NODE_ENV: 'development',
|
|
51
53
|
},
|
|
52
|
-
);
|
|
54
|
+
});
|
|
53
55
|
process.exit(result.status === null ? 1 : result.status);
|
|
54
56
|
}
|
|
55
57
|
|
|
@@ -59,6 +61,10 @@ if (isDev && !process.env._NOCO_CLI_TSX_CHILD) {
|
|
|
59
61
|
|
|
60
62
|
const bootstrapPath = isDev ? path.join(root, 'src/lib/bootstrap.ts') : path.join(root, 'dist/lib/bootstrap.js');
|
|
61
63
|
const { ensureRuntimeFromArgv } = await import(pathToFileURL(bootstrapPath).href);
|
|
64
|
+
const startupUpdatePath = isDev
|
|
65
|
+
? path.join(root, 'src/lib/startup-update.ts')
|
|
66
|
+
: path.join(root, 'dist/lib/startup-update.js');
|
|
67
|
+
const { maybeRunStartupUpdatePrompt } = await import(pathToFileURL(startupUpdatePath).href);
|
|
62
68
|
const { flush, run, settings } = await import('@oclif/core');
|
|
63
69
|
|
|
64
70
|
if (isDev) {
|
|
@@ -100,6 +106,17 @@ function formatCliEntryError(error, argv) {
|
|
|
100
106
|
|
|
101
107
|
try {
|
|
102
108
|
const argv = process.argv.slice(2);
|
|
109
|
+
const startupUpdate = await maybeRunStartupUpdatePrompt(argv);
|
|
110
|
+
if (startupUpdate.kind === 'updated') {
|
|
111
|
+
const result = spawnSync(process.execPath, process.argv.slice(1), {
|
|
112
|
+
stdio: 'inherit',
|
|
113
|
+
env: {
|
|
114
|
+
...process.env,
|
|
115
|
+
NB_SKIP_STARTUP_UPDATE: '1',
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
process.exit(result.status === null ? 1 : result.status);
|
|
119
|
+
}
|
|
103
120
|
if (argv[0] === 'api') {
|
|
104
121
|
await ensureRuntimeFromArgv(argv, {
|
|
105
122
|
configFile: path.join(root, 'nocobase-ctl.config.json'),
|
|
@@ -20,9 +20,9 @@ export async function resolveDbRuntime(envName) {
|
|
|
20
20
|
if (!runtime) {
|
|
21
21
|
return undefined;
|
|
22
22
|
}
|
|
23
|
-
const source = runtime.kind === '
|
|
23
|
+
const source = runtime.kind === 'http' || runtime.kind === 'ssh' ? runtime.kind : runtime.source;
|
|
24
24
|
const dbDialect = String(runtime.env.config.dbDialect ?? 'postgres').trim() || 'postgres';
|
|
25
|
-
if (runtime.kind
|
|
25
|
+
if ((runtime.kind === 'local' || runtime.kind === 'docker') && runtime.env.config.builtinDb) {
|
|
26
26
|
const containerName = buildDockerDbContainerName(runtime.envName, dbDialect, runtime.workspaceName);
|
|
27
27
|
return {
|
|
28
28
|
kind: 'builtin',
|
|
@@ -40,7 +40,7 @@ export async function resolveDbRuntime(envName) {
|
|
|
40
40
|
source,
|
|
41
41
|
dbDialect,
|
|
42
42
|
address: formatAddress(runtime.env.config.dbHost, runtime.env.config.dbPort),
|
|
43
|
-
status: runtime.kind === '
|
|
43
|
+
status: runtime.kind === 'http' || runtime.kind === 'ssh' ? runtime.kind : 'external',
|
|
44
44
|
appRuntime: runtime,
|
|
45
45
|
};
|
|
46
46
|
}
|
|
@@ -52,13 +52,20 @@ export async function builtinDbStatus(containerName) {
|
|
|
52
52
|
}
|
|
53
53
|
export function formatUnmanagedDbMessage(action, runtime) {
|
|
54
54
|
const verb = action === 'start' ? 'start' : 'stop';
|
|
55
|
-
if (runtime.appRuntime.kind === '
|
|
55
|
+
if (runtime.appRuntime.kind === 'http') {
|
|
56
56
|
return [
|
|
57
57
|
`Can't ${verb} the database for "${runtime.envName}" from this machine.`,
|
|
58
58
|
'This env only has an API connection, so there is no CLI-managed database container here.',
|
|
59
59
|
'If you need CLI-managed database start and stop, create a local env with the built-in database option enabled.',
|
|
60
60
|
].join('\n');
|
|
61
61
|
}
|
|
62
|
+
if (runtime.appRuntime.kind === 'ssh') {
|
|
63
|
+
return [
|
|
64
|
+
`Can't ${verb} the database for "${runtime.envName}" yet.`,
|
|
65
|
+
'SSH env support is reserved but not implemented yet.',
|
|
66
|
+
'Use a local env with the built-in database option enabled if you need CLI-managed database operations right now.',
|
|
67
|
+
].join('\n');
|
|
68
|
+
}
|
|
62
69
|
return [
|
|
63
70
|
`Can't ${verb} the database for "${runtime.envName}" from this machine.`,
|
|
64
71
|
'This env does not use a CLI-managed built-in database, so there is no saved database container to manage here.',
|
|
@@ -66,13 +73,20 @@ export function formatUnmanagedDbMessage(action, runtime) {
|
|
|
66
73
|
].join('\n');
|
|
67
74
|
}
|
|
68
75
|
export function formatUnmanagedDbLogsMessage(runtime) {
|
|
69
|
-
if (runtime.appRuntime.kind === '
|
|
76
|
+
if (runtime.appRuntime.kind === 'http') {
|
|
70
77
|
return [
|
|
71
78
|
`Can't show database logs for "${runtime.envName}" from this machine.`,
|
|
72
79
|
'This env only has an API connection, so there is no CLI-managed database container here.',
|
|
73
80
|
'If you need CLI-managed database logs, create a local env with the built-in database option enabled.',
|
|
74
81
|
].join('\n');
|
|
75
82
|
}
|
|
83
|
+
if (runtime.appRuntime.kind === 'ssh') {
|
|
84
|
+
return [
|
|
85
|
+
`Can't show database logs for "${runtime.envName}" yet.`,
|
|
86
|
+
'SSH env support is reserved but not implemented yet.',
|
|
87
|
+
'Use a local env with the built-in database option enabled if you need CLI-managed database logs right now.',
|
|
88
|
+
].join('\n');
|
|
89
|
+
}
|
|
76
90
|
return [
|
|
77
91
|
`Can't show database logs for "${runtime.envName}" from this machine.`,
|
|
78
92
|
'This env does not use a CLI-managed built-in database, so there is no saved database container to read logs from here.',
|
package/dist/commands/dev.js
CHANGED
|
@@ -17,6 +17,13 @@ function formatUnsupportedRuntimeMessage(kind, envName) {
|
|
|
17
17
|
`Use \`nb logs --env ${envName}\` to inspect the Docker app, or create a source-based env with \`nb init --env ${envName} --source git\`.`,
|
|
18
18
|
].join('\n');
|
|
19
19
|
}
|
|
20
|
+
if (kind === 'ssh') {
|
|
21
|
+
return [
|
|
22
|
+
`Can't run dev mode for "${envName}" yet.`,
|
|
23
|
+
'SSH env support is reserved but not implemented yet.',
|
|
24
|
+
`Create a source-based env with \`nb init --env ${envName} --source git\` if you want local development mode right now.`,
|
|
25
|
+
].join('\n');
|
|
26
|
+
}
|
|
20
27
|
return [
|
|
21
28
|
`Can't run dev mode for "${envName}".`,
|
|
22
29
|
'This env only has an API connection, but `nb dev` requires a local npm or Git source directory.',
|
|
@@ -99,7 +106,7 @@ export default class Dev extends Command {
|
|
|
99
106
|
if (!runtime) {
|
|
100
107
|
this.error(formatMissingManagedAppEnvMessage(requestedEnv));
|
|
101
108
|
}
|
|
102
|
-
if (runtime.kind === 'docker' || runtime.kind === '
|
|
109
|
+
if (runtime.kind === 'docker' || runtime.kind === 'http' || runtime.kind === 'ssh') {
|
|
103
110
|
this.error(formatUnsupportedRuntimeMessage(runtime.kind, runtime.envName));
|
|
104
111
|
}
|
|
105
112
|
const devPort = flags.port
|
package/dist/commands/down.js
CHANGED
|
@@ -12,14 +12,11 @@ import os from 'node:os';
|
|
|
12
12
|
import path from 'node:path';
|
|
13
13
|
import { buildDockerDbContainerName, formatMissingManagedAppEnvMessage, resolveManagedAppRuntime, runLocalNocoBaseCommand, } from '../lib/app-runtime.js';
|
|
14
14
|
import { removeEnv } from '../lib/auth-store.js';
|
|
15
|
+
import { resolveConfiguredEnvPath } from '../lib/cli-home.js';
|
|
15
16
|
import { commandSucceeds, run } from '../lib/run-npm.js';
|
|
16
17
|
import { confirmAction, failTask, isInteractiveTerminal, printInfo, startTask, succeedTask, } from '../lib/ui.js';
|
|
17
18
|
function resolveConfiguredPath(value) {
|
|
18
|
-
|
|
19
|
-
if (!text) {
|
|
20
|
-
return undefined;
|
|
21
|
-
}
|
|
22
|
-
return path.isAbsolute(text) ? text : path.resolve(process.cwd(), text);
|
|
19
|
+
return resolveConfiguredEnvPath(value);
|
|
23
20
|
}
|
|
24
21
|
function assertSafeRemovalPath(target, label) {
|
|
25
22
|
const resolved = path.resolve(target);
|
|
@@ -113,13 +110,20 @@ export default class Down extends Command {
|
|
|
113
110
|
if (!runtime) {
|
|
114
111
|
this.error(formatMissingManagedAppEnvMessage(requestedEnv));
|
|
115
112
|
}
|
|
116
|
-
if (runtime.kind === '
|
|
113
|
+
if (runtime.kind === 'http') {
|
|
117
114
|
this.error([
|
|
118
115
|
`Can't bring down "${runtime.envName}" from this machine.`,
|
|
119
116
|
'This env only has an API connection, so there is no saved local app, Docker app, or managed database to remove here.',
|
|
120
117
|
'Use `nb env remove` if you only want to remove the CLI connection config.',
|
|
121
118
|
].join('\n'));
|
|
122
119
|
}
|
|
120
|
+
if (runtime.kind === 'ssh') {
|
|
121
|
+
this.error([
|
|
122
|
+
`Can't bring down "${runtime.envName}" yet.`,
|
|
123
|
+
'SSH env support is reserved but not implemented yet.',
|
|
124
|
+
'Use `nb env remove` if you only want to remove the saved CLI config for now.',
|
|
125
|
+
].join('\n'));
|
|
126
|
+
}
|
|
123
127
|
if (flags['remove-data']) {
|
|
124
128
|
let confirmed = false;
|
|
125
129
|
try {
|
package/dist/commands/env/add.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { Args, Command, Flags } from '@oclif/core';
|
|
10
10
|
import { upsertEnv } from '../../lib/auth-store.js';
|
|
11
|
+
import { resolveDefaultConfigScope } from '../../lib/cli-home.js';
|
|
11
12
|
import { runPromptCatalog, } from '../../lib/prompt-catalog.js';
|
|
12
13
|
import { applyCliLocale, CLI_LOCALE_FLAG_DESCRIPTION, CLI_LOCALE_FLAG_OPTIONS, localeText, } from '../../lib/cli-locale.js';
|
|
13
14
|
import { validateApiBaseUrl } from '../../lib/prompt-validators.js';
|
|
@@ -45,7 +46,7 @@ export default class EnvAdd extends Command {
|
|
|
45
46
|
static examples = [
|
|
46
47
|
'<%= config.bin %> <%= command.id %>',
|
|
47
48
|
'<%= config.bin %> <%= command.id %> local',
|
|
48
|
-
'<%= config.bin %> <%= command.id %> local --
|
|
49
|
+
'<%= config.bin %> <%= command.id %> local --api-base-url http://localhost:13000/api --auth-type oauth',
|
|
49
50
|
];
|
|
50
51
|
static args = {
|
|
51
52
|
name: Args.string({
|
|
@@ -73,12 +74,6 @@ export default class EnvAdd extends Command {
|
|
|
73
74
|
description: 'Skip command intro when invoked by another CLI command',
|
|
74
75
|
default: false,
|
|
75
76
|
}),
|
|
76
|
-
scope: Flags.string({
|
|
77
|
-
char: 's',
|
|
78
|
-
description: 'Where to store env config: project (.nocobase in the repo) or global (user-level); prompted in a TTY when omitted',
|
|
79
|
-
options: ['project', 'global'],
|
|
80
|
-
default: 'project',
|
|
81
|
-
}),
|
|
82
77
|
'default-api-base-url': Flags.string({
|
|
83
78
|
char: 'd',
|
|
84
79
|
hidden: true,
|
|
@@ -86,7 +81,6 @@ export default class EnvAdd extends Command {
|
|
|
86
81
|
}),
|
|
87
82
|
'api-base-url': Flags.string({
|
|
88
83
|
char: 'u',
|
|
89
|
-
aliases: ['base-url'],
|
|
90
84
|
description: 'Root URL for HTTP API calls, including the /api prefix (e.g. http://localhost:13000/api); prompted in a TTY when omitted',
|
|
91
85
|
}),
|
|
92
86
|
'auth-type': Flags.string({
|
|
@@ -199,24 +193,6 @@ export default class EnvAdd extends Command {
|
|
|
199
193
|
placeholder: envAddText('prompts.name.placeholder'),
|
|
200
194
|
required: true,
|
|
201
195
|
},
|
|
202
|
-
scope: {
|
|
203
|
-
type: 'select',
|
|
204
|
-
message: envAddText('prompts.scope.message'),
|
|
205
|
-
options: [
|
|
206
|
-
{
|
|
207
|
-
value: 'project',
|
|
208
|
-
label: envAddText('prompts.scope.projectLabel'),
|
|
209
|
-
hint: envAddText('prompts.scope.projectHint'),
|
|
210
|
-
},
|
|
211
|
-
{
|
|
212
|
-
value: 'global',
|
|
213
|
-
label: envAddText('prompts.scope.globalLabel'),
|
|
214
|
-
hint: envAddText('prompts.scope.globalHint'),
|
|
215
|
-
},
|
|
216
|
-
],
|
|
217
|
-
initialValue: 'project',
|
|
218
|
-
required: true,
|
|
219
|
-
},
|
|
220
196
|
apiBaseUrl: {
|
|
221
197
|
type: 'text',
|
|
222
198
|
message: envAddText('prompts.apiBaseUrl.message'),
|
|
@@ -252,10 +228,7 @@ export default class EnvAdd extends Command {
|
|
|
252
228
|
if (name) {
|
|
253
229
|
values.name = name;
|
|
254
230
|
}
|
|
255
|
-
|
|
256
|
-
values.scope = flags.scope;
|
|
257
|
-
}
|
|
258
|
-
const apiFromFlag = flags['api-base-url'] ?? flags['base-url'];
|
|
231
|
+
const apiFromFlag = flags['api-base-url'];
|
|
259
232
|
if (typeof apiFromFlag === 'string' && apiFromFlag.trim() !== '') {
|
|
260
233
|
values.apiBaseUrl = apiFromFlag.trim();
|
|
261
234
|
}
|
|
@@ -277,8 +250,16 @@ export default class EnvAdd extends Command {
|
|
|
277
250
|
return initialValues;
|
|
278
251
|
}
|
|
279
252
|
buildEnvConfig(results, flags) {
|
|
253
|
+
const source = String(flags.source ?? '').trim();
|
|
254
|
+
const appRootPath = String(flags['app-root-path'] ?? '').trim();
|
|
255
|
+
const kind = source === 'docker'
|
|
256
|
+
? 'docker'
|
|
257
|
+
: source === 'npm' || source === 'git' || source === 'local' || appRootPath
|
|
258
|
+
? 'local'
|
|
259
|
+
: 'http';
|
|
280
260
|
const envConfig = {
|
|
281
|
-
|
|
261
|
+
kind,
|
|
262
|
+
apiBaseUrl: String(results.apiBaseUrl ?? ''),
|
|
282
263
|
};
|
|
283
264
|
for (const [flagName, configKey] of Object.entries(ENV_RUNTIME_FLAG_MAP)) {
|
|
284
265
|
const value = flags[flagName];
|
|
@@ -314,10 +295,9 @@ export default class EnvAdd extends Command {
|
|
|
314
295
|
command: this,
|
|
315
296
|
});
|
|
316
297
|
const envName = String(results.name);
|
|
317
|
-
const scope = results.scope;
|
|
318
298
|
const envConfig = this.buildEnvConfig(results, parsedFlags);
|
|
319
|
-
printVerbose(`Saving env "${envName}"
|
|
320
|
-
await upsertEnv(envName, envConfig, { scope });
|
|
299
|
+
printVerbose(`Saving env "${envName}" globally.`);
|
|
300
|
+
await upsertEnv(envName, envConfig, { scope: resolveDefaultConfigScope() });
|
|
321
301
|
if (results.authType === 'oauth') {
|
|
322
302
|
await this.config.runCommand('env:auth', [envName]);
|
|
323
303
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { Args, Command, Flags } from '@oclif/core';
|
|
10
10
|
import { getCurrentEnvName } from '../../lib/auth-store.js';
|
|
11
|
-
import {
|
|
11
|
+
import { resolveDefaultConfigScope } from '../../lib/cli-home.js';
|
|
12
12
|
import { authenticateEnvWithOauth } from '../../lib/env-auth.js';
|
|
13
13
|
import { failTask, startTask, succeedTask } from '../../lib/ui.js';
|
|
14
14
|
export default class EnvAuth extends Command {
|
|
@@ -16,7 +16,6 @@ export default class EnvAuth extends Command {
|
|
|
16
16
|
static examples = [
|
|
17
17
|
'<%= config.bin %> <%= command.id %>',
|
|
18
18
|
'<%= config.bin %> <%= command.id %> prod',
|
|
19
|
-
'<%= config.bin %> <%= command.id %> --scope global',
|
|
20
19
|
];
|
|
21
20
|
static args = {
|
|
22
21
|
name: Args.string({
|
|
@@ -31,31 +30,25 @@ export default class EnvAuth extends Command {
|
|
|
31
30
|
deprecated: true,
|
|
32
31
|
description: 'Environment name (same as the optional positional argument; for compatibility with -e/--env on other commands)',
|
|
33
32
|
}),
|
|
34
|
-
scope: Flags.string({
|
|
35
|
-
char: 's',
|
|
36
|
-
description: 'Config scope',
|
|
37
|
-
options: ['project', 'global'],
|
|
38
|
-
}),
|
|
39
33
|
};
|
|
40
34
|
async run() {
|
|
41
35
|
const { args, flags } = await this.parse(EnvAuth);
|
|
42
|
-
const scope = flags.scope;
|
|
43
36
|
const nameArg = args.name?.trim();
|
|
44
37
|
const nameFlag = flags.env?.trim() || undefined;
|
|
45
38
|
if (nameArg && nameFlag && nameArg !== nameFlag) {
|
|
46
39
|
this.error(`Environment name was provided both as the argument ("${nameArg}") and as --env ("${nameFlag}"). Please use only one.`);
|
|
47
40
|
}
|
|
48
|
-
const envName = nameArg || nameFlag || (await getCurrentEnvName({ scope }));
|
|
49
|
-
startTask(`Starting browser sign-in for "${envName}"
|
|
41
|
+
const envName = nameArg || nameFlag || (await getCurrentEnvName({ scope: resolveDefaultConfigScope() }));
|
|
42
|
+
startTask(`Starting browser sign-in for "${envName}"...`);
|
|
50
43
|
try {
|
|
51
44
|
await authenticateEnvWithOauth({
|
|
52
45
|
envName,
|
|
53
|
-
scope,
|
|
46
|
+
scope: resolveDefaultConfigScope(),
|
|
54
47
|
});
|
|
55
|
-
succeedTask(`Signed in to "${envName}"
|
|
48
|
+
succeedTask(`Signed in to "${envName}".`);
|
|
56
49
|
}
|
|
57
50
|
catch (error) {
|
|
58
|
-
failTask(`Sign-in failed for "${envName}"
|
|
51
|
+
failTask(`Sign-in failed for "${envName}".`);
|
|
59
52
|
throw error;
|
|
60
53
|
}
|
|
61
54
|
}
|
|
@@ -6,35 +6,30 @@
|
|
|
6
6
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
|
-
import { Command
|
|
9
|
+
import { Command } from '@oclif/core';
|
|
10
10
|
import { listEnvs } from '../../lib/auth-store.js';
|
|
11
|
-
import {
|
|
11
|
+
import { resolveDefaultConfigScope } from '../../lib/cli-home.js';
|
|
12
12
|
import { renderTable } from '../../lib/ui.js';
|
|
13
|
+
function resolveApiBaseUrl(config) {
|
|
14
|
+
return String(config.apiBaseUrl ?? config.baseUrl ?? config.apibaseUrl ?? '').trim();
|
|
15
|
+
}
|
|
13
16
|
export default class EnvList extends Command {
|
|
14
17
|
static summary = 'List configured environments';
|
|
15
18
|
static examples = [
|
|
16
19
|
'<%= config.bin %> <%= command.id %>',
|
|
17
20
|
];
|
|
18
|
-
static flags = {
|
|
19
|
-
scope: Flags.string({
|
|
20
|
-
char: 's',
|
|
21
|
-
description: 'Config scope',
|
|
22
|
-
options: ['project', 'global'],
|
|
23
|
-
}),
|
|
24
|
-
};
|
|
25
21
|
async run() {
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
const { currentEnv, envs } = await listEnvs({ scope });
|
|
22
|
+
await this.parse(EnvList);
|
|
23
|
+
const { currentEnv, envs } = await listEnvs({ scope: resolveDefaultConfigScope() });
|
|
29
24
|
const names = Object.keys(envs).sort();
|
|
30
25
|
if (!names.length) {
|
|
31
|
-
this.log(
|
|
32
|
-
this.log('Run `nb env add <name> --base-url <url>` to add one.');
|
|
26
|
+
this.log('No envs configured.');
|
|
27
|
+
this.log('Run `nb env add <name> --api-base-url <url>` to add one.');
|
|
33
28
|
return;
|
|
34
29
|
}
|
|
35
30
|
const rows = names.map((name) => {
|
|
36
31
|
const env = envs[name];
|
|
37
|
-
return [name === currentEnv ? '*' : '', name, env
|
|
32
|
+
return [name === currentEnv ? '*' : '', name, resolveApiBaseUrl(env), env.auth?.type ?? '', env.runtime?.version ?? ''];
|
|
38
33
|
});
|
|
39
34
|
this.log(renderTable(['Current', 'Name', 'Base URL', 'Auth', 'Runtime'], rows));
|
|
40
35
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { Args, Command, Flags } from '@oclif/core';
|
|
10
10
|
import { getCurrentEnvName, removeEnv } from '../../lib/auth-store.js';
|
|
11
|
-
import {
|
|
11
|
+
import { resolveDefaultConfigScope } from '../../lib/cli-home.js';
|
|
12
12
|
import { confirmAction, isInteractiveTerminal, printVerbose, setVerboseMode } from '../../lib/ui.js';
|
|
13
13
|
export default class EnvRemove extends Command {
|
|
14
14
|
static summary = 'Remove a configured environment';
|
|
@@ -26,11 +26,6 @@ export default class EnvRemove extends Command {
|
|
|
26
26
|
description: 'Show detailed progress output',
|
|
27
27
|
default: false,
|
|
28
28
|
}),
|
|
29
|
-
scope: Flags.string({
|
|
30
|
-
char: 's',
|
|
31
|
-
description: 'Config scope',
|
|
32
|
-
options: ['project', 'global'],
|
|
33
|
-
}),
|
|
34
29
|
};
|
|
35
30
|
static args = {
|
|
36
31
|
name: Args.string({
|
|
@@ -41,8 +36,7 @@ export default class EnvRemove extends Command {
|
|
|
41
36
|
async run() {
|
|
42
37
|
const { args, flags } = await this.parse(EnvRemove);
|
|
43
38
|
setVerboseMode(flags.verbose);
|
|
44
|
-
const
|
|
45
|
-
const currentEnv = await getCurrentEnvName({ scope });
|
|
39
|
+
const currentEnv = await getCurrentEnvName({ scope: resolveDefaultConfigScope() });
|
|
46
40
|
if (args.name === currentEnv && !flags.force) {
|
|
47
41
|
if (!isInteractiveTerminal()) {
|
|
48
42
|
this.error('Refusing to remove the current env without confirmation. Re-run with `--force`.');
|
|
@@ -54,8 +48,8 @@ export default class EnvRemove extends Command {
|
|
|
54
48
|
}
|
|
55
49
|
}
|
|
56
50
|
printVerbose(`Removing env "${args.name}"`);
|
|
57
|
-
const result = await removeEnv(args.name, { scope });
|
|
58
|
-
this.log(`Removed env "${result.removed}"
|
|
51
|
+
const result = await removeEnv(args.name, { scope: resolveDefaultConfigScope() });
|
|
52
|
+
this.log(`Removed env "${result.removed}".`);
|
|
59
53
|
if (result.hasEnvs) {
|
|
60
54
|
this.log(`Current env: ${result.currentEnv}`);
|
|
61
55
|
return;
|
|
@@ -11,7 +11,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
11
11
|
import { Args, Command, Flags } from '@oclif/core';
|
|
12
12
|
import { getCurrentEnvName } from '../../lib/auth-store.js';
|
|
13
13
|
import { updateEnvRuntime } from '../../lib/bootstrap.js';
|
|
14
|
-
import {
|
|
14
|
+
import { resolveDefaultConfigScope } from '../../lib/cli-home.js';
|
|
15
15
|
import { failTask, startTask, succeedTask } from '../../lib/ui.js';
|
|
16
16
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
17
17
|
export default class EnvUpdate extends Command {
|
|
@@ -31,12 +31,7 @@ export default class EnvUpdate extends Command {
|
|
|
31
31
|
description: 'Show detailed progress output',
|
|
32
32
|
default: false,
|
|
33
33
|
}),
|
|
34
|
-
|
|
35
|
-
char: 's',
|
|
36
|
-
description: 'Config scope',
|
|
37
|
-
options: ['project', 'global'],
|
|
38
|
-
}),
|
|
39
|
-
'base-url': Flags.string({
|
|
34
|
+
'api-base-url': Flags.string({
|
|
40
35
|
description: 'NocoBase API base URL override. When provided, persist it to the target env before saving the refreshed runtime.',
|
|
41
36
|
}),
|
|
42
37
|
role: Flags.string({
|
|
@@ -49,21 +44,20 @@ export default class EnvUpdate extends Command {
|
|
|
49
44
|
};
|
|
50
45
|
async run() {
|
|
51
46
|
const { args, flags } = await this.parse(EnvUpdate);
|
|
52
|
-
const scope = flags.scope;
|
|
53
47
|
const envName = args.name;
|
|
54
|
-
const envLabel = envName ?? (await getCurrentEnvName({ scope }));
|
|
55
|
-
startTask(`Updating env runtime: ${envLabel}
|
|
48
|
+
const envLabel = envName ?? (await getCurrentEnvName({ scope: resolveDefaultConfigScope() }));
|
|
49
|
+
startTask(`Updating env runtime: ${envLabel}`);
|
|
56
50
|
try {
|
|
57
51
|
const runtime = await updateEnvRuntime({
|
|
58
52
|
envName,
|
|
59
|
-
scope,
|
|
60
|
-
baseUrl: flags['base-url'],
|
|
53
|
+
scope: resolveDefaultConfigScope(),
|
|
54
|
+
baseUrl: flags['api-base-url'],
|
|
61
55
|
role: flags.role,
|
|
62
56
|
token: flags.token,
|
|
63
57
|
configFile: path.join(path.dirname(path.dirname(path.dirname(__dirname))), 'nocobase-ctl.config.json'),
|
|
64
58
|
verbose: flags.verbose,
|
|
65
59
|
});
|
|
66
|
-
succeedTask(`Updated env "${envLabel}" to runtime "${runtime.version}"
|
|
60
|
+
succeedTask(`Updated env "${envLabel}" to runtime "${runtime.version}".`);
|
|
67
61
|
}
|
|
68
62
|
catch (error) {
|
|
69
63
|
failTask(`Failed to update env "${envLabel}".`);
|
package/dist/commands/env/use.js
CHANGED
|
@@ -6,21 +6,14 @@
|
|
|
6
6
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
|
-
import { Args, Command
|
|
9
|
+
import { Args, Command } from '@oclif/core';
|
|
10
10
|
import { setCurrentEnv } from '../../lib/auth-store.js';
|
|
11
|
-
import {
|
|
11
|
+
import { resolveDefaultConfigScope } from '../../lib/cli-home.js';
|
|
12
12
|
export default class EnvUse extends Command {
|
|
13
13
|
static summary = 'Switch the current environment';
|
|
14
14
|
static examples = [
|
|
15
15
|
'<%= config.bin %> <%= command.id %> local',
|
|
16
16
|
];
|
|
17
|
-
static flags = {
|
|
18
|
-
scope: Flags.string({
|
|
19
|
-
char: 's',
|
|
20
|
-
description: 'Config scope',
|
|
21
|
-
options: ['project', 'global'],
|
|
22
|
-
}),
|
|
23
|
-
};
|
|
24
17
|
static args = {
|
|
25
18
|
name: Args.string({
|
|
26
19
|
description: 'Configured environment name',
|
|
@@ -28,9 +21,8 @@ export default class EnvUse extends Command {
|
|
|
28
21
|
}),
|
|
29
22
|
};
|
|
30
23
|
async run() {
|
|
31
|
-
const { args
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
this.log(`Current env: ${args.name}${scope ? ` (${formatCliHomeScope(scope)} scope)` : ''}`);
|
|
24
|
+
const { args } = await this.parse(EnvUse);
|
|
25
|
+
await setCurrentEnv(args.name, { scope: resolveDefaultConfigScope() });
|
|
26
|
+
this.log(`Current env: ${args.name}`);
|
|
35
27
|
}
|
|
36
28
|
}
|