@nocobase/cli 2.1.0-alpha.20 → 2.1.0-alpha.21
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 +256 -89
- package/README.zh-CN.md +332 -0
- package/bin/run.js +21 -2
- package/dist/commands/build.js +7 -1
- package/dist/commands/db/logs.js +85 -0
- package/dist/commands/db/ps.js +60 -0
- package/dist/commands/db/shared.js +81 -0
- package/dist/commands/db/start.js +55 -7
- package/dist/commands/db/stop.js +70 -0
- package/dist/commands/dev.js +112 -21
- package/dist/commands/down.js +193 -0
- package/dist/commands/download.js +622 -183
- package/dist/commands/env/add.js +233 -131
- package/dist/commands/env/auth.js +9 -8
- package/dist/commands/init.js +696 -103
- package/dist/commands/install.js +1588 -566
- package/dist/commands/logs.js +90 -0
- package/dist/commands/pm/disable.js +35 -3
- package/dist/commands/pm/enable.js +35 -3
- package/dist/commands/pm/list.js +37 -4
- package/dist/commands/prompts-stages.js +144 -0
- package/dist/commands/prompts-test.js +175 -0
- package/dist/commands/ps.js +116 -0
- package/dist/commands/start.js +171 -15
- package/dist/commands/stop.js +90 -0
- package/dist/commands/upgrade.js +559 -11
- package/dist/lib/app-runtime.js +142 -0
- package/dist/lib/auth-store.js +44 -3
- package/dist/lib/bootstrap.js +7 -3
- package/dist/lib/env-auth.js +427 -82
- package/dist/lib/prompt-catalog.js +552 -0
- package/dist/lib/prompt-validators.js +184 -0
- package/dist/lib/prompt-web-ui.js +2027 -0
- package/dist/lib/run-npm.js +71 -7
- package/package.json +3 -3
- package/dist/commands/restart.js +0 -32
- package/dist/lib/init-browser-wizard.js +0 -431
package/dist/commands/env/add.js
CHANGED
|
@@ -7,10 +7,36 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
import { Args, Command, Flags } from '@oclif/core';
|
|
10
|
-
import * as p from '@clack/prompts';
|
|
11
10
|
import { upsertEnv } from '../../lib/auth-store.js';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
11
|
+
import { runPromptCatalog, } from '../../lib/prompt-catalog.js';
|
|
12
|
+
import { validateApiBaseUrl } from '../../lib/prompt-validators.js';
|
|
13
|
+
import { printVerbose, setVerboseMode } from '../../lib/ui.js';
|
|
14
|
+
import * as p from '@clack/prompts';
|
|
15
|
+
const ENV_RUNTIME_FLAG_MAP = {
|
|
16
|
+
source: 'source',
|
|
17
|
+
'download-version': 'downloadVersion',
|
|
18
|
+
'docker-registry': 'dockerRegistry',
|
|
19
|
+
'docker-platform': 'dockerPlatform',
|
|
20
|
+
'git-url': 'gitUrl',
|
|
21
|
+
'npm-registry': 'npmRegistry',
|
|
22
|
+
'app-root-path': 'appRootPath',
|
|
23
|
+
'storage-path': 'storagePath',
|
|
24
|
+
'app-port': 'appPort',
|
|
25
|
+
'app-key': 'appKey',
|
|
26
|
+
timezone: 'timezone',
|
|
27
|
+
'db-dialect': 'dbDialect',
|
|
28
|
+
'db-host': 'dbHost',
|
|
29
|
+
'db-port': 'dbPort',
|
|
30
|
+
'db-database': 'dbDatabase',
|
|
31
|
+
'db-user': 'dbUser',
|
|
32
|
+
'db-password': 'dbPassword',
|
|
33
|
+
};
|
|
34
|
+
const ENV_BOOLEAN_RUNTIME_FLAG_MAP = {
|
|
35
|
+
'builtin-db': 'builtinDb',
|
|
36
|
+
'dev-dependencies': 'devDependencies',
|
|
37
|
+
build: 'build',
|
|
38
|
+
'build-dts': 'buildDts',
|
|
39
|
+
};
|
|
14
40
|
export default class EnvAdd extends Command {
|
|
15
41
|
static summary = 'Save a named NocoBase API endpoint (token or OAuth), then switch the CLI to use it';
|
|
16
42
|
static examples = [
|
|
@@ -35,10 +61,21 @@ export default class EnvAdd extends Command {
|
|
|
35
61
|
description: 'Print detailed progress while writing config',
|
|
36
62
|
default: false,
|
|
37
63
|
}),
|
|
64
|
+
'no-intro': Flags.boolean({
|
|
65
|
+
hidden: true,
|
|
66
|
+
description: 'Skip command intro when invoked by another CLI command',
|
|
67
|
+
default: false,
|
|
68
|
+
}),
|
|
38
69
|
scope: Flags.string({
|
|
39
70
|
char: 's',
|
|
40
71
|
description: 'Where to store env config: project (.nocobase in the repo) or global (user-level); prompted in a TTY when omitted',
|
|
41
72
|
options: ['project', 'global'],
|
|
73
|
+
default: 'project',
|
|
74
|
+
}),
|
|
75
|
+
'default-api-base-url': Flags.string({
|
|
76
|
+
char: 'd',
|
|
77
|
+
hidden: true,
|
|
78
|
+
description: 'Default API base URL for HTTP API calls, including the /api prefix (e.g. http://localhost:13000/api); prompted in a TTY when omitted',
|
|
42
79
|
}),
|
|
43
80
|
'api-base-url': Flags.string({
|
|
44
81
|
char: 'u',
|
|
@@ -55,144 +92,209 @@ export default class EnvAdd extends Command {
|
|
|
55
92
|
aliases: ['token'],
|
|
56
93
|
description: 'API key or access token when using --auth-type token (prompted in a TTY when omitted)',
|
|
57
94
|
}),
|
|
95
|
+
source: Flags.string({
|
|
96
|
+
hidden: true,
|
|
97
|
+
description: 'Application source saved with this env',
|
|
98
|
+
}),
|
|
99
|
+
'download-version': Flags.string({
|
|
100
|
+
hidden: true,
|
|
101
|
+
description: 'Downloaded app version saved with this env',
|
|
102
|
+
}),
|
|
103
|
+
'docker-registry': Flags.string({
|
|
104
|
+
hidden: true,
|
|
105
|
+
description: 'Docker registry saved with this env',
|
|
106
|
+
}),
|
|
107
|
+
'docker-platform': Flags.string({
|
|
108
|
+
hidden: true,
|
|
109
|
+
description: 'Docker image platform saved with this env',
|
|
110
|
+
}),
|
|
111
|
+
'git-url': Flags.string({
|
|
112
|
+
hidden: true,
|
|
113
|
+
description: 'Git repository URL saved with this env',
|
|
114
|
+
}),
|
|
115
|
+
'npm-registry': Flags.string({
|
|
116
|
+
hidden: true,
|
|
117
|
+
description: 'npm registry saved with this env',
|
|
118
|
+
}),
|
|
119
|
+
'dev-dependencies': Flags.boolean({
|
|
120
|
+
allowNo: true,
|
|
121
|
+
hidden: true,
|
|
122
|
+
description: 'Whether development dependencies were installed for this env',
|
|
123
|
+
}),
|
|
124
|
+
build: Flags.boolean({
|
|
125
|
+
allowNo: true,
|
|
126
|
+
hidden: true,
|
|
127
|
+
description: 'Whether the app was built after download for this env',
|
|
128
|
+
}),
|
|
129
|
+
'build-dts': Flags.boolean({
|
|
130
|
+
allowNo: true,
|
|
131
|
+
hidden: true,
|
|
132
|
+
description: 'Whether declaration files were emitted during build for this env',
|
|
133
|
+
}),
|
|
134
|
+
'app-root-path': Flags.string({
|
|
135
|
+
hidden: true,
|
|
136
|
+
description: 'Application root path saved with this env',
|
|
137
|
+
}),
|
|
138
|
+
'storage-path': Flags.string({
|
|
139
|
+
hidden: true,
|
|
140
|
+
description: 'Storage path saved with this env',
|
|
141
|
+
}),
|
|
142
|
+
'app-port': Flags.string({
|
|
143
|
+
hidden: true,
|
|
144
|
+
description: 'Application HTTP port saved with this env',
|
|
145
|
+
}),
|
|
146
|
+
'app-key': Flags.string({
|
|
147
|
+
hidden: true,
|
|
148
|
+
description: 'Application secret key saved with this env',
|
|
149
|
+
}),
|
|
150
|
+
timezone: Flags.string({
|
|
151
|
+
hidden: true,
|
|
152
|
+
description: 'Application timezone saved with this env',
|
|
153
|
+
}),
|
|
154
|
+
'builtin-db': Flags.boolean({
|
|
155
|
+
allowNo: true,
|
|
156
|
+
hidden: true,
|
|
157
|
+
description: 'Whether this env uses a CLI-managed built-in database',
|
|
158
|
+
}),
|
|
159
|
+
'db-dialect': Flags.string({
|
|
160
|
+
hidden: true,
|
|
161
|
+
description: 'Database dialect saved with this env',
|
|
162
|
+
}),
|
|
163
|
+
'db-host': Flags.string({
|
|
164
|
+
hidden: true,
|
|
165
|
+
description: 'Database host saved with this env',
|
|
166
|
+
}),
|
|
167
|
+
'db-port': Flags.string({
|
|
168
|
+
hidden: true,
|
|
169
|
+
description: 'Database port saved with this env',
|
|
170
|
+
}),
|
|
171
|
+
'db-database': Flags.string({
|
|
172
|
+
hidden: true,
|
|
173
|
+
description: 'Database name saved with this env',
|
|
174
|
+
}),
|
|
175
|
+
'db-user': Flags.string({
|
|
176
|
+
hidden: true,
|
|
177
|
+
description: 'Database user saved with this env',
|
|
178
|
+
}),
|
|
179
|
+
'db-password': Flags.string({
|
|
180
|
+
hidden: true,
|
|
181
|
+
description: 'Database password saved with this env',
|
|
182
|
+
}),
|
|
58
183
|
};
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
184
|
+
static prompts = {
|
|
185
|
+
name: {
|
|
186
|
+
type: 'text',
|
|
187
|
+
message: 'What would you like to call this environment?',
|
|
188
|
+
placeholder: 'default',
|
|
189
|
+
required: true,
|
|
190
|
+
},
|
|
191
|
+
scope: {
|
|
192
|
+
type: 'select',
|
|
193
|
+
message: 'Where should this connection be saved?',
|
|
194
|
+
options: [
|
|
195
|
+
{ value: 'project', label: 'Project', hint: '.nocobase in this repo' },
|
|
196
|
+
{ value: 'global', label: 'Global', hint: 'user-level config' },
|
|
197
|
+
],
|
|
198
|
+
initialValue: 'project',
|
|
199
|
+
required: true,
|
|
200
|
+
},
|
|
201
|
+
apiBaseUrl: {
|
|
202
|
+
type: 'text',
|
|
203
|
+
message: 'What is the API base URL?',
|
|
204
|
+
placeholder: 'http://localhost:13000/api',
|
|
205
|
+
required: true,
|
|
206
|
+
validate: validateApiBaseUrl,
|
|
207
|
+
},
|
|
208
|
+
authType: {
|
|
209
|
+
type: 'select',
|
|
210
|
+
message: 'How would you like to sign in?',
|
|
211
|
+
options: [
|
|
212
|
+
{ value: 'oauth', label: 'OAuth (browser login)', hint: 'runs nb env auth after save' },
|
|
213
|
+
{ value: 'token', label: 'API token / API key' },
|
|
214
|
+
],
|
|
215
|
+
initialValue: 'oauth',
|
|
216
|
+
required: true,
|
|
217
|
+
},
|
|
218
|
+
accessToken: {
|
|
219
|
+
type: 'text',
|
|
220
|
+
message: 'Enter an API token or API key',
|
|
221
|
+
placeholder: 'Enter your API token / API key',
|
|
222
|
+
required: true,
|
|
223
|
+
hidden: (values) => values.authType !== 'token',
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
buildPromptValues(nameArg, flags) {
|
|
227
|
+
const values = {};
|
|
228
|
+
const name = nameArg?.trim() || flags.env?.trim();
|
|
229
|
+
if (name) {
|
|
230
|
+
values.name = name;
|
|
70
231
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
let baseUrl = flags['api-base-url'] ?? flags['base-url'];
|
|
74
|
-
let authType = flags['auth-type'];
|
|
75
|
-
const interactive = isInteractiveTerminal();
|
|
76
|
-
if (!interactive) {
|
|
77
|
-
const missing = [];
|
|
78
|
-
if (!name?.trim()) {
|
|
79
|
-
missing.push('<name> (first argument or --env)');
|
|
80
|
-
}
|
|
81
|
-
if (!scope) {
|
|
82
|
-
missing.push('--scope');
|
|
83
|
-
}
|
|
84
|
-
if (!baseUrl) {
|
|
85
|
-
missing.push('--api-base-url');
|
|
86
|
-
}
|
|
87
|
-
if (!authType) {
|
|
88
|
-
missing.push('--auth-type');
|
|
89
|
-
}
|
|
90
|
-
if (missing.length > 0) {
|
|
91
|
-
this.error(`Non-interactive mode requires: ${missing.join(', ')}. Example: nb env add -e local --scope project --api-base-url http://localhost:13000/api --auth-type oauth`);
|
|
92
|
-
}
|
|
232
|
+
if (flags.scope) {
|
|
233
|
+
values.scope = flags.scope;
|
|
93
234
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
message: 'Environment name',
|
|
98
|
-
placeholder: 'default',
|
|
99
|
-
defaultValue: 'default',
|
|
100
|
-
});
|
|
101
|
-
if (p.isCancel(answer)) {
|
|
102
|
-
this.exitCancelled();
|
|
103
|
-
}
|
|
104
|
-
name = answer;
|
|
105
|
-
}
|
|
106
|
-
if (!scope) {
|
|
107
|
-
const answer = await p.select({
|
|
108
|
-
message: 'Where should this env be stored?',
|
|
109
|
-
options: [
|
|
110
|
-
{ value: 'project', label: 'Project', hint: '.nocobase in this repo' },
|
|
111
|
-
{ value: 'global', label: 'Global', hint: 'user-level config' },
|
|
112
|
-
],
|
|
113
|
-
initialValue: 'project',
|
|
114
|
-
});
|
|
115
|
-
if (p.isCancel(answer)) {
|
|
116
|
-
this.exitCancelled();
|
|
117
|
-
}
|
|
118
|
-
scope = answer;
|
|
119
|
-
}
|
|
120
|
-
if (!baseUrl) {
|
|
121
|
-
const answer = await p.text({
|
|
122
|
-
message: 'API base URL',
|
|
123
|
-
placeholder: 'http://localhost:13000/api',
|
|
124
|
-
defaultValue: 'http://localhost:13000/api',
|
|
125
|
-
});
|
|
126
|
-
if (p.isCancel(answer)) {
|
|
127
|
-
this.exitCancelled();
|
|
128
|
-
}
|
|
129
|
-
baseUrl = answer;
|
|
130
|
-
}
|
|
131
|
-
if (!authType) {
|
|
132
|
-
const answer = await p.select({
|
|
133
|
-
message: 'How do you want to authenticate?',
|
|
134
|
-
options: [
|
|
135
|
-
{ value: 'oauth', label: 'OAuth (browser login)', hint: 'runs nb env auth after save' },
|
|
136
|
-
{ value: 'token', label: 'API token / API key' },
|
|
137
|
-
],
|
|
138
|
-
initialValue: 'oauth',
|
|
139
|
-
});
|
|
140
|
-
if (p.isCancel(answer)) {
|
|
141
|
-
this.exitCancelled();
|
|
142
|
-
}
|
|
143
|
-
authType = answer;
|
|
144
|
-
}
|
|
235
|
+
const apiFromFlag = flags['api-base-url'] ?? flags['base-url'];
|
|
236
|
+
if (typeof apiFromFlag === 'string' && apiFromFlag.trim() !== '') {
|
|
237
|
+
values.apiBaseUrl = apiFromFlag.trim();
|
|
145
238
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
if (accessTokenFlagPresent && !flags['access-token'] && !flags['token']) {
|
|
149
|
-
if (!interactive) {
|
|
150
|
-
this.error('When passing --access-token (or --token) without a value, run in a TTY or provide the token as the flag value.');
|
|
151
|
-
}
|
|
152
|
-
const prompted = await p.password({
|
|
153
|
-
message: 'Access token / API key',
|
|
154
|
-
validate: (value) => (value.trim() ? undefined : 'Token cannot be empty'),
|
|
155
|
-
});
|
|
156
|
-
if (p.isCancel(prompted)) {
|
|
157
|
-
this.exitCancelled();
|
|
158
|
-
}
|
|
159
|
-
flags['access-token'] = prompted;
|
|
239
|
+
if (flags['auth-type']) {
|
|
240
|
+
values.authType = flags['auth-type'];
|
|
160
241
|
}
|
|
161
|
-
|
|
162
|
-
if (
|
|
163
|
-
|
|
242
|
+
const token = flags['access-token'] ?? flags.token;
|
|
243
|
+
if (typeof token === 'string' && token !== '') {
|
|
244
|
+
values.accessToken = token;
|
|
164
245
|
}
|
|
165
|
-
|
|
166
|
-
|
|
246
|
+
return values;
|
|
247
|
+
}
|
|
248
|
+
buildPromptInitialValues(flags) {
|
|
249
|
+
const initialValues = {};
|
|
250
|
+
const defaultApiBaseUrl = flags['default-api-base-url']?.trim();
|
|
251
|
+
if (defaultApiBaseUrl) {
|
|
252
|
+
initialValues.apiBaseUrl = defaultApiBaseUrl;
|
|
167
253
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
token = answer;
|
|
254
|
+
return initialValues;
|
|
255
|
+
}
|
|
256
|
+
buildEnvConfig(results, flags) {
|
|
257
|
+
const envConfig = {
|
|
258
|
+
baseUrl: String(results.apiBaseUrl ?? ''),
|
|
259
|
+
};
|
|
260
|
+
for (const [flagName, configKey] of Object.entries(ENV_RUNTIME_FLAG_MAP)) {
|
|
261
|
+
const value = flags[flagName];
|
|
262
|
+
if (typeof value === 'string' && value.trim() !== '') {
|
|
263
|
+
envConfig[configKey] = value.trim();
|
|
180
264
|
}
|
|
181
|
-
|
|
182
|
-
|
|
265
|
+
}
|
|
266
|
+
for (const [flagName, configKey] of Object.entries(ENV_BOOLEAN_RUNTIME_FLAG_MAP)) {
|
|
267
|
+
const value = flags[flagName];
|
|
268
|
+
if (typeof value === 'boolean') {
|
|
269
|
+
envConfig[configKey] = value;
|
|
183
270
|
}
|
|
184
|
-
printVerbose(`Saving env "${name}" with API base URL ${baseUrl} (token auth)`);
|
|
185
|
-
await upsertEnv(name, { baseUrl, accessToken: token }, { scope });
|
|
186
|
-
this.log(`Saved env "${name}" and set it as current${scope ? ` in ${formatCliHomeScope(scope)} scope` : ''}.`);
|
|
187
|
-
return;
|
|
188
271
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
272
|
+
if (results.authType === 'token' && results.accessToken != null) {
|
|
273
|
+
envConfig.accessToken = String(results.accessToken);
|
|
274
|
+
}
|
|
275
|
+
return envConfig;
|
|
276
|
+
}
|
|
277
|
+
async run() {
|
|
278
|
+
const { args, flags } = await this.parse(EnvAdd);
|
|
279
|
+
const parsedFlags = flags;
|
|
280
|
+
setVerboseMode(parsedFlags.verbose);
|
|
281
|
+
if (!parsedFlags['no-intro']) {
|
|
282
|
+
p.intro('Connect a NocoBase Environment');
|
|
283
|
+
}
|
|
284
|
+
const results = await runPromptCatalog(EnvAdd.prompts, {
|
|
285
|
+
values: this.buildPromptValues(args.name, parsedFlags),
|
|
286
|
+
initialValues: this.buildPromptInitialValues(parsedFlags),
|
|
287
|
+
command: this,
|
|
288
|
+
});
|
|
289
|
+
const envName = String(results.name);
|
|
290
|
+
const scope = results.scope;
|
|
291
|
+
const envConfig = this.buildEnvConfig(results, parsedFlags);
|
|
292
|
+
printVerbose(`Saving env "${envName}" with scope "${scope}".`);
|
|
293
|
+
await upsertEnv(envName, envConfig, { scope });
|
|
294
|
+
if (results.authType === 'oauth') {
|
|
295
|
+
await this.config.runCommand('env:auth', [envName]);
|
|
195
296
|
}
|
|
196
|
-
await this.config.runCommand('env:
|
|
297
|
+
await this.config.runCommand('env:update', [envName]);
|
|
298
|
+
p.outro(`Env "${envName}" added successfully.`);
|
|
197
299
|
}
|
|
198
300
|
}
|
|
@@ -12,14 +12,16 @@ import { formatCliHomeScope } 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 {
|
|
15
|
-
static summary = '
|
|
15
|
+
static summary = 'Sign in to a saved NocoBase environment with OAuth';
|
|
16
16
|
static examples = [
|
|
17
|
+
'<%= config.bin %> <%= command.id %>',
|
|
17
18
|
'<%= config.bin %> <%= command.id %> prod',
|
|
19
|
+
'<%= config.bin %> <%= command.id %> --scope global',
|
|
18
20
|
];
|
|
19
21
|
static args = {
|
|
20
22
|
name: Args.string({
|
|
21
23
|
description: 'Environment name (omit to use the current env)',
|
|
22
|
-
required:
|
|
24
|
+
required: false,
|
|
23
25
|
}),
|
|
24
26
|
};
|
|
25
27
|
static flags = {
|
|
@@ -41,20 +43,19 @@ export default class EnvAuth extends Command {
|
|
|
41
43
|
const nameArg = args.name?.trim();
|
|
42
44
|
const nameFlag = flags.env?.trim() || undefined;
|
|
43
45
|
if (nameArg && nameFlag && nameArg !== nameFlag) {
|
|
44
|
-
this.error(`Environment name was
|
|
46
|
+
this.error(`Environment name was provided both as the argument ("${nameArg}") and as --env ("${nameFlag}"). Please use only one.`);
|
|
45
47
|
}
|
|
46
|
-
const envName = nameArg || nameFlag ||
|
|
47
|
-
|
|
48
|
-
startTask(`Authenticating env: ${envLabel}${scope ? ` (${formatCliHomeScope(scope)})` : ''}`);
|
|
48
|
+
const envName = nameArg || nameFlag || (await getCurrentEnvName({ scope }));
|
|
49
|
+
startTask(`Starting browser sign-in for "${envName}"${scope ? ` (${formatCliHomeScope(scope)} scope)` : ''}...`);
|
|
49
50
|
try {
|
|
50
51
|
await authenticateEnvWithOauth({
|
|
51
52
|
envName,
|
|
52
53
|
scope,
|
|
53
54
|
});
|
|
54
|
-
succeedTask(`
|
|
55
|
+
succeedTask(`Signed in to "${envName}"${scope ? ` in ${formatCliHomeScope(scope)} scope` : ''}.`);
|
|
55
56
|
}
|
|
56
57
|
catch (error) {
|
|
57
|
-
failTask(`
|
|
58
|
+
failTask(`Sign-in failed for "${envName}"${scope ? ` in ${formatCliHomeScope(scope)} scope` : ''}.`);
|
|
58
59
|
throw error;
|
|
59
60
|
}
|
|
60
61
|
}
|