@nocobase/cli 2.1.0-beta.33 → 2.1.0-beta.35

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 (62) hide show
  1. package/bin/run.js +2 -1
  2. package/bin/session-env.js +12 -0
  3. package/dist/commands/app/down.js +10 -13
  4. package/dist/commands/app/logs.js +0 -1
  5. package/dist/commands/app/restart.js +63 -2
  6. package/dist/commands/app/start.js +53 -18
  7. package/dist/commands/app/stop.js +0 -1
  8. package/dist/commands/app/upgrade.js +16 -4
  9. package/dist/commands/env/add.js +3 -4
  10. package/dist/commands/env/auth.js +3 -2
  11. package/dist/commands/env/remove.js +38 -13
  12. package/dist/commands/env/update.js +9 -2
  13. package/dist/commands/examples/prompts-stages.js +4 -4
  14. package/dist/commands/examples/prompts-test.js +4 -4
  15. package/dist/commands/init.js +38 -31
  16. package/dist/commands/install.js +100 -63
  17. package/dist/commands/license/activate.js +66 -64
  18. package/dist/commands/license/id.js +0 -1
  19. package/dist/commands/license/plugins/clean.js +0 -1
  20. package/dist/commands/license/plugins/list.js +0 -1
  21. package/dist/commands/license/plugins/sync.js +0 -1
  22. package/dist/commands/license/shared.js +3 -3
  23. package/dist/commands/license/status.js +0 -1
  24. package/dist/commands/plugin/disable.js +0 -1
  25. package/dist/commands/plugin/enable.js +0 -1
  26. package/dist/commands/plugin/list.js +0 -1
  27. package/dist/commands/self/update.js +12 -3
  28. package/dist/commands/skills/install.js +12 -3
  29. package/dist/commands/skills/remove.js +12 -3
  30. package/dist/commands/skills/update.js +12 -3
  31. package/dist/commands/source/dev.js +8 -2
  32. package/dist/commands/source/download.js +29 -17
  33. package/dist/commands/source/publish.js +92 -0
  34. package/dist/commands/source/registry/logs.js +70 -0
  35. package/dist/commands/source/registry/start.js +57 -0
  36. package/dist/commands/source/registry/status.js +33 -0
  37. package/dist/commands/source/registry/stop.js +48 -0
  38. package/dist/lib/app-managed-resources.js +30 -3
  39. package/dist/lib/bootstrap.js +12 -3
  40. package/dist/lib/db-connection-check.js +3 -23
  41. package/dist/lib/docker-env-file.js +52 -0
  42. package/dist/lib/env-auth.js +4 -3
  43. package/dist/lib/env-config.js +1 -0
  44. package/dist/lib/env-guard.js +8 -7
  45. package/dist/lib/generated-command.js +0 -1
  46. package/dist/lib/inquirer-theme.js +17 -0
  47. package/dist/lib/inquirer.js +244 -0
  48. package/dist/lib/object-utils.js +76 -0
  49. package/dist/lib/prompt-catalog-core.js +185 -0
  50. package/dist/lib/prompt-catalog-terminal.js +375 -0
  51. package/dist/lib/prompt-catalog.js +2 -573
  52. package/dist/lib/prompt-validators.js +56 -1
  53. package/dist/lib/resource-command.js +0 -1
  54. package/dist/lib/run-npm.js +8 -9
  55. package/dist/lib/skills-manager.js +75 -11
  56. package/dist/lib/source-publish.js +287 -0
  57. package/dist/lib/source-registry.js +188 -0
  58. package/dist/lib/startup-update.js +12 -8
  59. package/dist/lib/ui.js +28 -51
  60. package/dist/locale/en-US.json +8 -3
  61. package/dist/locale/zh-CN.json +8 -3
  62. package/package.json +7 -5
@@ -6,10 +6,10 @@
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 * as p from '@clack/prompts';
10
9
  import { Command, Flags } from '@oclif/core';
11
10
  import { readFile } from 'node:fs/promises';
12
11
  import { ensureCrossEnvConfirmed, hasExplicitEnvSelection } from '../../lib/env-guard.js';
12
+ import { input, password as promptPassword, select } from "../../lib/inquirer.js";
13
13
  import { createLicenseEnvFlag, ensureInstanceId, licenseJsonFlag, licensePkgUrlFlag, licenseYesFlag, redactLicenseKey, requireLicenseRuntime, resolveLicenseKeyFile, resolveLicenseServiceUrl, saveLicenseKey, sanitizeLicenseOutput, validateLicenseKey, } from './shared.js';
14
14
  import { announceTargetEnv, isInteractiveTerminal } from '../../lib/ui.js';
15
15
  import { appUrl } from '../env/shared.js';
@@ -17,102 +17,107 @@ function resolveOnlineInputValue(value) {
17
17
  return String(value ?? '').trim();
18
18
  }
19
19
  async function promptActivationMode() {
20
- const answer = await p.select({
21
- message: 'How do you want to activate the license?',
22
- options: [
23
- { value: 'key', label: 'Use an existing license key' },
24
- { value: 'online', label: 'Request and activate a license online' },
25
- { value: 'cancel', label: 'Cancel' },
26
- ],
27
- initialValue: 'key',
28
- });
29
- if (p.isCancel(answer)) {
30
- p.cancel('License activation cancelled.');
20
+ try {
21
+ return await select({
22
+ message: 'How do you want to activate the license?',
23
+ choices: [
24
+ { value: 'key', name: 'Use an existing license key' },
25
+ { value: 'online', name: 'Request and activate a license online' },
26
+ { value: 'cancel', name: 'Cancel' },
27
+ ],
28
+ default: 'key',
29
+ });
30
+ }
31
+ catch {
31
32
  return 'cancel';
32
33
  }
33
- return answer;
34
34
  }
35
35
  async function promptLicenseKeyInput() {
36
- const answer = await p.select({
37
- message: 'How do you want to provide the license key?',
38
- options: [
39
- { value: 'key', label: 'Paste the license key' },
40
- { value: 'file', label: 'Read the key from a file' },
41
- ],
42
- initialValue: 'key',
43
- });
44
- if (p.isCancel(answer)) {
45
- p.cancel('License activation cancelled.');
36
+ let answer;
37
+ try {
38
+ answer = await select({
39
+ message: 'How do you want to provide the license key?',
40
+ choices: [
41
+ { value: 'key', name: 'Paste the license key' },
42
+ { value: 'file', name: 'Read the key from a file' },
43
+ ],
44
+ default: 'key',
45
+ });
46
+ }
47
+ catch {
46
48
  return {};
47
49
  }
48
50
  if (answer === 'key') {
49
- const key = await p.text({
50
- message: 'License key',
51
- validate: (value) => String(value ?? '').trim() ? undefined : 'License key is required.',
52
- });
53
- if (p.isCancel(key)) {
54
- p.cancel('License activation cancelled.');
51
+ try {
52
+ const key = await input({
53
+ message: 'License key',
54
+ validate: (value) => String(value ?? '').trim() ? true : 'License key is required.',
55
+ });
56
+ return { key: String(key ?? '').trim() || undefined };
57
+ }
58
+ catch {
55
59
  return {};
56
60
  }
57
- return { key: String(key ?? '').trim() || undefined };
58
61
  }
59
- const keyFile = await p.text({
60
- message: 'Path to the license key file',
61
- validate: (value) => String(value ?? '').trim() ? undefined : 'License key file path is required.',
62
- });
63
- if (p.isCancel(keyFile)) {
64
- p.cancel('License activation cancelled.');
62
+ try {
63
+ const keyFile = await input({
64
+ message: 'Path to the license key file',
65
+ validate: (value) => String(value ?? '').trim() ? true : 'License key file path is required.',
66
+ });
67
+ return { keyFile: String(keyFile ?? '').trim() || undefined };
68
+ }
69
+ catch {
65
70
  return {};
66
71
  }
67
- return { keyFile: String(keyFile ?? '').trim() || undefined };
68
72
  }
69
73
  async function promptOnlineActivationInput(initial) {
70
74
  let account = String(initial.account ?? '').trim();
71
75
  if (!account) {
72
- const answer = await p.text({
73
- message: 'Service account',
74
- validate: (value) => String(value ?? '').trim() ? undefined : 'Service account is required.',
75
- });
76
- if (p.isCancel(answer)) {
77
- p.cancel('License activation cancelled.');
76
+ try {
77
+ const answer = await input({
78
+ message: 'Service account',
79
+ validate: (value) => String(value ?? '').trim() ? true : 'Service account is required.',
80
+ });
81
+ account = String(answer ?? '').trim();
82
+ }
83
+ catch {
78
84
  return;
79
85
  }
80
- account = String(answer ?? '').trim();
81
86
  }
82
87
  if (!account) {
83
- p.cancel('License activation cancelled.');
84
88
  return;
85
89
  }
86
90
  let password = String(initial.password ?? '').trim();
87
91
  if (!password) {
88
- const answer = await p.password({
89
- message: 'Service password',
90
- validate: (value) => String(value ?? '').trim() ? undefined : 'Service password is required.',
91
- });
92
- if (p.isCancel(answer)) {
93
- p.cancel('License activation cancelled.');
92
+ try {
93
+ const answer = await promptPassword({
94
+ message: 'Service password',
95
+ mask: '•',
96
+ validate: (value) => String(value ?? '').trim() ? true : 'Service password is required.',
97
+ });
98
+ password = String(answer ?? '').trim();
99
+ }
100
+ catch {
94
101
  return;
95
102
  }
96
- password = String(answer ?? '').trim();
97
103
  }
98
104
  if (!password) {
99
- p.cancel('License activation cancelled.');
100
105
  return;
101
106
  }
102
107
  let appName = String(initial.appName ?? '').trim();
103
108
  if (!appName) {
104
- const answer = await p.text({
105
- message: 'Application name',
106
- validate: (value) => String(value ?? '').trim() ? undefined : 'Application name is required.',
107
- });
108
- if (p.isCancel(answer)) {
109
- p.cancel('License activation cancelled.');
109
+ try {
110
+ const answer = await input({
111
+ message: 'Application name',
112
+ validate: (value) => String(value ?? '').trim() ? true : 'Application name is required.',
113
+ });
114
+ appName = String(answer ?? '').trim();
115
+ }
116
+ catch {
110
117
  return;
111
118
  }
112
- appName = String(answer ?? '').trim();
113
119
  }
114
120
  if (!appName) {
115
- p.cancel('License activation cancelled.');
116
121
  return;
117
122
  }
118
123
  return {
@@ -206,7 +211,6 @@ export default class LicenseActivate extends Command {
206
211
  yes: flags.yes,
207
212
  });
208
213
  if (!confirmed) {
209
- this.log('Canceled.');
210
214
  return;
211
215
  }
212
216
  }
@@ -223,7 +227,6 @@ export default class LicenseActivate extends Command {
223
227
  }
224
228
  const mode = await promptActivationMode();
225
229
  if (mode === 'cancel') {
226
- this.log('Cancelled license activation.');
227
230
  return;
228
231
  }
229
232
  if (mode === 'online') {
@@ -258,7 +261,6 @@ export default class LicenseActivate extends Command {
258
261
  }
259
262
  const prompted = await promptOnlineActivationInput(initialOnline);
260
263
  if (!prompted) {
261
- this.log('Cancelled license activation.');
262
264
  return;
263
265
  }
264
266
  onlineInput = prompted;
@@ -39,7 +39,6 @@ export default class LicenseId extends Command {
39
39
  yes: flags.yes,
40
40
  });
41
41
  if (!confirmed) {
42
- this.log('Canceled.');
43
42
  return;
44
43
  }
45
44
  }
@@ -56,7 +56,6 @@ export default class LicensePluginsClean extends Command {
56
56
  yes: flags.yes,
57
57
  });
58
58
  if (!confirmed) {
59
- this.log('Canceled.');
60
59
  return;
61
60
  }
62
61
  }
@@ -36,7 +36,6 @@ export default class LicensePluginsList extends Command {
36
36
  yes: flags.yes,
37
37
  });
38
38
  if (!confirmed) {
39
- this.log('Canceled.');
40
39
  return;
41
40
  }
42
41
  }
@@ -167,7 +167,6 @@ export default class LicensePluginsSync extends Command {
167
167
  yes: flags.yes,
168
168
  });
169
169
  if (!confirmed) {
170
- this.log('Canceled.');
171
170
  return;
172
171
  }
173
172
  }
@@ -10,12 +10,12 @@ import { Flags } from '@oclif/core';
10
10
  import { mkdir, readFile, writeFile } from 'node:fs/promises';
11
11
  import path from 'node:path';
12
12
  import { getEnvAsync, getInstanceIdAsync, keyDecrypt } from '@nocobase/license-kit';
13
- import _ from 'lodash';
14
13
  import { checkExternalDbConnection, readExternalDbConnectionConfig, } from "../../lib/db-connection-check.js";
15
14
  import { DEFAULT_DOCKER_REGISTRY, DEFAULT_DOCKER_VERSION, resolveDockerImageRef, } from "../../lib/docker-image.js";
16
15
  import { formatMissingManagedAppEnvMessage, resolveManagedAppRuntime } from '../../lib/app-runtime.js';
17
16
  import { buildRuntimeEnvVars } from '../../lib/runtime-env-vars.js';
18
17
  import { resolveLicensePkgUrlFromConfig } from '../../lib/cli-config.js';
18
+ import { deepEqual, omitKeys } from "../../lib/object-utils.js";
19
19
  import { commandOutput } from '../../lib/run-npm.js';
20
20
  import { appUrl } from '../env/shared.js';
21
21
  export function createLicenseEnvFlag(description) {
@@ -296,7 +296,7 @@ export function isDbMatch(env, keyData) {
296
296
  if (currentDb?.id && licenseDb?.id) {
297
297
  return currentDb.id === licenseDb.id;
298
298
  }
299
- return _.isEqual(_.omit(currentDb, ['id']), _.omit(licenseDb, ['id']));
299
+ return deepEqual(omitKeys(currentDb, ['id']), omitKeys(licenseDb, ['id']));
300
300
  }
301
301
  export function isSysMatch(env, keyData) {
302
302
  const instance = keyData?.instanceData;
@@ -307,7 +307,7 @@ export function isSysMatch(env, keyData) {
307
307
  sys: item?.sys ?? null,
308
308
  osVer: item?.osVer ?? null,
309
309
  });
310
- return _.isEqual(normalize(env), normalize(instance));
310
+ return deepEqual(normalize(env), normalize(instance));
311
311
  }
312
312
  export async function getLicenseStatus(keyData) {
313
313
  if (!keyData) {
@@ -38,7 +38,6 @@ export default class LicenseStatus extends Command {
38
38
  yes: flags.yes,
39
39
  });
40
40
  if (!confirmed) {
41
- this.log('Canceled.');
42
41
  return;
43
42
  }
44
43
  }
@@ -47,7 +47,6 @@ export default class PluginDisable extends Command {
47
47
  yes: flags.yes,
48
48
  });
49
49
  if (!confirmed) {
50
- this.log('Canceled.');
51
50
  return;
52
51
  }
53
52
  }
@@ -47,7 +47,6 @@ export default class PluginEnable extends Command {
47
47
  yes: flags.yes,
48
48
  });
49
49
  if (!confirmed) {
50
- this.log('Canceled.');
51
50
  return;
52
51
  }
53
52
  }
@@ -41,7 +41,6 @@ export default class PluginList extends Command {
41
41
  yes: flags.yes,
42
42
  });
43
43
  if (!confirmed) {
44
- this.log('Canceled.');
45
44
  return;
46
45
  }
47
46
  }
@@ -7,7 +7,8 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
  import { Command, Flags } from '@oclif/core';
10
- import { confirmAction, setVerboseMode } from '../../lib/ui.js';
10
+ import { confirm } from "../../lib/inquirer.js";
11
+ import { setVerboseMode } from '../../lib/ui.js';
11
12
  import { formatSelfUpdateUnavailableMessage, formatUnsupportedSelfUpdateMessage, inspectSelfStatus, updateSelf, } from '../../lib/self-manager.js';
12
13
  export default class SelfUpdate extends Command {
13
14
  static summary = 'Update the globally installed NocoBase CLI';
@@ -50,9 +51,17 @@ export default class SelfUpdate extends Command {
50
51
  this.error(formatSelfUpdateUnavailableMessage(status));
51
52
  }
52
53
  if (!flags.yes && status.updateAvailable) {
53
- const confirmed = await confirmAction(`Update ${status.packageName} from ${status.currentVersion} to ${status.latestVersion}?`, { defaultValue: false });
54
+ let confirmed = false;
55
+ try {
56
+ confirmed = await confirm({
57
+ message: `Update ${status.packageName} from ${status.currentVersion} to ${status.latestVersion}?`,
58
+ default: false,
59
+ });
60
+ }
61
+ catch {
62
+ return;
63
+ }
54
64
  if (!confirmed) {
55
- this.log('Skipped CLI update.');
56
65
  return;
57
66
  }
58
67
  }
@@ -7,7 +7,8 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
  import { Command, Flags } from '@oclif/core';
10
- import { confirmAction, setVerboseMode } from '../../lib/ui.js';
10
+ import { confirm } from "../../lib/inquirer.js";
11
+ import { setVerboseMode } from '../../lib/ui.js';
11
12
  import { installNocoBaseSkills } from '../../lib/skills-manager.js';
12
13
  export default class SkillsInstall extends Command {
13
14
  static summary = 'Install the NocoBase AI coding skills globally';
@@ -36,9 +37,17 @@ export default class SkillsInstall extends Command {
36
37
  const { flags } = await this.parse(SkillsInstall);
37
38
  setVerboseMode(flags.verbose);
38
39
  if (!flags.yes) {
39
- const confirmed = await confirmAction('Install the NocoBase AI coding skills globally?', { defaultValue: true });
40
+ let confirmed = false;
41
+ try {
42
+ confirmed = await confirm({
43
+ message: 'Install the NocoBase AI coding skills globally?',
44
+ default: true,
45
+ });
46
+ }
47
+ catch {
48
+ return;
49
+ }
40
50
  if (!confirmed) {
41
- this.log('Skipped skills install.');
42
51
  return;
43
52
  }
44
53
  }
@@ -7,7 +7,8 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
  import { Command, Flags } from '@oclif/core';
10
- import { confirmAction, setVerboseMode } from '../../lib/ui.js';
10
+ import { confirm } from "../../lib/inquirer.js";
11
+ import { setVerboseMode } from '../../lib/ui.js';
11
12
  import { removeNocoBaseSkills } from '../../lib/skills-manager.js';
12
13
  export default class SkillsRemove extends Command {
13
14
  static summary = 'Remove the globally installed NocoBase AI coding skills';
@@ -36,9 +37,17 @@ export default class SkillsRemove extends Command {
36
37
  const { flags } = await this.parse(SkillsRemove);
37
38
  setVerboseMode(flags.verbose);
38
39
  if (!flags.yes) {
39
- const confirmed = await confirmAction('Remove the globally installed NocoBase AI coding skills?', { defaultValue: true });
40
+ let confirmed = false;
41
+ try {
42
+ confirmed = await confirm({
43
+ message: 'Remove the globally installed NocoBase AI coding skills?',
44
+ default: true,
45
+ });
46
+ }
47
+ catch {
48
+ return;
49
+ }
40
50
  if (!confirmed) {
41
- this.log('Skipped skills removal.');
42
51
  return;
43
52
  }
44
53
  }
@@ -7,7 +7,8 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
  import { Command, Flags } from '@oclif/core';
10
- import { confirmAction, setVerboseMode } from '../../lib/ui.js';
10
+ import { confirm } from "../../lib/inquirer.js";
11
+ import { setVerboseMode } from '../../lib/ui.js';
11
12
  import { updateNocoBaseSkills } from '../../lib/skills-manager.js';
12
13
  export default class SkillsUpdate extends Command {
13
14
  static summary = 'Update the globally installed NocoBase AI coding skills';
@@ -36,9 +37,17 @@ export default class SkillsUpdate extends Command {
36
37
  const { flags } = await this.parse(SkillsUpdate);
37
38
  setVerboseMode(flags.verbose);
38
39
  if (!flags.yes) {
39
- const confirmed = await confirmAction('Update the globally installed NocoBase AI coding skills?', { defaultValue: true });
40
+ let confirmed = false;
41
+ try {
42
+ confirmed = await confirm({
43
+ message: 'Update the globally installed NocoBase AI coding skills?',
44
+ default: true,
45
+ });
46
+ }
47
+ catch {
48
+ return;
49
+ }
40
50
  if (!confirmed) {
41
- this.log('Skipped skills update.');
42
51
  return;
43
52
  }
44
53
  }
@@ -8,8 +8,9 @@
8
8
  */
9
9
  import { Command, Flags } from '@oclif/core';
10
10
  import { ensureCrossEnvConfirmed, hasExplicitEnvSelection } from '../../lib/env-guard.js';
11
+ import { ensureLocalPostinstall } from '../../lib/app-managed-resources.js';
11
12
  import { formatMissingManagedAppEnvMessage, resolveManagedAppRuntime, runLocalNocoBaseCommand, } from '../../lib/app-runtime.js';
12
- import { announceTargetEnv, printInfo } from '../../lib/ui.js';
13
+ import { announceTargetEnv, failTask, printInfo, startTask, succeedTask } from '../../lib/ui.js';
13
14
  function formatUnsupportedRuntimeMessage(kind, envName) {
14
15
  if (kind === 'docker') {
15
16
  return [
@@ -117,7 +118,6 @@ export default class SourceDev extends Command {
117
118
  yes: flags.yes,
118
119
  });
119
120
  if (!confirmed) {
120
- this.log('Canceled.');
121
121
  return;
122
122
  }
123
123
  }
@@ -160,6 +160,12 @@ export default class SourceDev extends Command {
160
160
  }
161
161
  printInfo(`Starting NocoBase dev mode for "${runtime.envName}" from ${runtime.projectRoot}. Press Ctrl+C to stop.`);
162
162
  try {
163
+ await ensureLocalPostinstall(runtime, {
164
+ onStartTask: startTask,
165
+ onSucceedTask: succeedTask,
166
+ onFailTask: failTask,
167
+ verbose: true,
168
+ });
163
169
  await runLocalNocoBaseCommand(runtime, npmArgs, {
164
170
  stdio: 'inherit',
165
171
  });
@@ -8,7 +8,6 @@
8
8
  */
9
9
  import fsp from 'node:fs/promises';
10
10
  import { Command, Flags } from '@oclif/core';
11
- import * as p from '@clack/prompts';
12
11
  import path from 'node:path';
13
12
  import { stdin as stdinStream, stdout as stdoutStream } from 'node:process';
14
13
  import { runPromptCatalog, } from "../../lib/prompt-catalog.js";
@@ -181,6 +180,11 @@ export default class SourceDownload extends Command {
181
180
  description: 'Skip command intro when invoked by another CLI command',
182
181
  default: false,
183
182
  }),
183
+ 'compact-log': Flags.boolean({
184
+ hidden: true,
185
+ description: 'Reduce default logs when invoked inside another setup flow',
186
+ default: false,
187
+ }),
184
188
  source: Flags.string({
185
189
  char: 's',
186
190
  description: 'How to get NocoBase: Docker image, npm package, or Git repository.',
@@ -601,7 +605,6 @@ export default class SourceDownload extends Command {
601
605
  command: this,
602
606
  hooks: {
603
607
  onCancel: () => {
604
- p.cancel('Download cancelled.');
605
608
  this.exit(0);
606
609
  },
607
610
  onMissingNonInteractive: (message) => {
@@ -640,6 +643,15 @@ export default class SourceDownload extends Command {
640
643
  commandStdio() {
641
644
  return this.isVerbose() ? 'inherit' : 'ignore';
642
645
  }
646
+ useCompactLog() {
647
+ const flags = this._flags;
648
+ return Boolean(flags?.['compact-log']);
649
+ }
650
+ logProgress(message) {
651
+ if (this.isVerbose() || !this.useCompactLog()) {
652
+ this.log(message);
653
+ }
654
+ }
643
655
  formatCommandForLog(name, args, cwd) {
644
656
  const quotedArgs = args.map((arg) => (/\s/.test(arg) ? JSON.stringify(arg) : arg));
645
657
  const commandLine = [name, ...quotedArgs].join(' ');
@@ -683,7 +695,7 @@ export default class SourceDownload extends Command {
683
695
  }
684
696
  startPreparationTask(message) {
685
697
  if (this.isVerbose()) {
686
- p.log.step(message);
698
+ this.log(message);
687
699
  return;
688
700
  }
689
701
  this.preparationTaskActive = true;
@@ -721,12 +733,12 @@ export default class SourceDownload extends Command {
721
733
  }
722
734
  pullArgs.push(imageRef);
723
735
  this.finishPreparationTask();
724
- p.log.step(`Pulling Docker image ${imageRef}`);
736
+ this.logProgress(`Pulling Docker image ${imageRef}`);
725
737
  await this.runExternalCommand('docker', pullArgs, {
726
738
  errorName: 'docker pull',
727
739
  loadingMessage: 'Pulling the Docker image',
728
740
  });
729
- p.log.info(`Docker image is ready: ${imageRef}`);
741
+ this.logProgress(`Docker image is ready: ${imageRef}`);
730
742
  if (!flags['docker-save']) {
731
743
  return;
732
744
  }
@@ -739,12 +751,12 @@ export default class SourceDownload extends Command {
739
751
  }
740
752
  await fsp.mkdir(outAbs, { recursive: true });
741
753
  const tarPath = this.dockerTarPath(flags, outAbs);
742
- p.log.step(`Saving Docker image tarball to ${tarPath}`);
754
+ this.log(`Saving Docker image tarball to ${tarPath}`);
743
755
  await this.runExternalCommand('docker', ['save', '-o', tarPath, imageRef], {
744
756
  errorName: 'docker save',
745
757
  loadingMessage: 'Saving the Docker image tarball',
746
758
  });
747
- p.log.info(`Docker image tarball saved: ${tarPath}`);
759
+ this.log(`Docker image tarball saved: ${tarPath}`);
748
760
  }
749
761
  async downloadFromNpm(flags) {
750
762
  const versionSpec = flags.version || 'latest';
@@ -760,7 +772,7 @@ export default class SourceDownload extends Command {
760
772
  await fsp.mkdir(parentDir, { recursive: true });
761
773
  const registryEnv = this.npmRegistryEnv(flags);
762
774
  this.finishPreparationTask();
763
- p.log.step(`Creating NocoBase app "${appName}" from npm`);
775
+ this.log(`Creating NocoBase app "${appName}" from npm`);
764
776
  await this.runExternalCommand('npx', npxArgs, {
765
777
  ...this.runOptionsWithCwd(parentDir, registryEnv),
766
778
  errorName: 'npx create-nocobase-app',
@@ -770,20 +782,20 @@ export default class SourceDownload extends Command {
770
782
  if (!flags['dev-dependencies']) {
771
783
  installArgs.push('--production');
772
784
  }
773
- p.log.step(`Installing dependencies in ${projectRoot}`);
785
+ this.log(`Installing dependencies in ${projectRoot}`);
774
786
  await this.runExternalCommand('yarn', installArgs, {
775
787
  ...this.runOptionsWithCwd(projectRoot, registryEnv),
776
788
  errorName: 'yarn install',
777
789
  loadingMessage: 'Installing dependencies',
778
790
  });
779
791
  if (flags.build && flags['dev-dependencies']) {
780
- p.log.step(`Building app in ${projectRoot}`);
792
+ this.log(`Building app in ${projectRoot}`);
781
793
  await this.config.runCommand('source:build', [
782
794
  ...this.buildCommandArgv(projectRoot, flags),
783
795
  ...(this.isVerbose() ? ['--verbose'] : []),
784
796
  ]);
785
797
  }
786
- p.log.info(`NocoBase app is ready at ${projectRoot}`);
798
+ this.log(`NocoBase app is ready at ${projectRoot}`);
787
799
  return projectRoot;
788
800
  }
789
801
  async downloadFromGit(flags) {
@@ -796,7 +808,7 @@ export default class SourceDownload extends Command {
796
808
  gitArgs.push('--branch', branch);
797
809
  gitArgs.push('--depth', '1', repoUrl, outputDir);
798
810
  this.finishPreparationTask();
799
- p.log.step(branch === versionSpec
811
+ this.log(branch === versionSpec
800
812
  ? `Cloning NocoBase from ${repoUrl} (${branch})`
801
813
  : `Cloning NocoBase from ${repoUrl} (${branch}, resolved from ${versionSpec})`);
802
814
  await this.runExternalCommand('git', gitArgs, {
@@ -805,20 +817,20 @@ export default class SourceDownload extends Command {
805
817
  });
806
818
  const projectRoot = path.resolve(process.cwd(), outputDir);
807
819
  const registryEnv = this.npmRegistryEnv(flags);
808
- p.log.step(`Installing dependencies in ${projectRoot}`);
820
+ this.log(`Installing dependencies in ${projectRoot}`);
809
821
  await this.runExternalCommand('yarn', ['install'], {
810
822
  ...this.runOptionsWithCwd(projectRoot, registryEnv),
811
823
  errorName: 'yarn install',
812
824
  loadingMessage: 'Installing dependencies',
813
825
  });
814
826
  if (flags.build) {
815
- p.log.step(`Building app in ${projectRoot}`);
827
+ this.log(`Building app in ${projectRoot}`);
816
828
  await this.config.runCommand('source:build', [
817
829
  ...this.buildCommandArgv(projectRoot, flags),
818
830
  ...(this.isVerbose() ? ['--verbose'] : []),
819
831
  ]);
820
832
  }
821
- p.log.info(`NocoBase app is ready at ${projectRoot}`);
833
+ this.log(`NocoBase app is ready at ${projectRoot}`);
822
834
  return projectRoot;
823
835
  }
824
836
  async download() {
@@ -827,7 +839,7 @@ export default class SourceDownload extends Command {
827
839
  applyCliLocale(this._flags.locale);
828
840
  setVerboseMode(Boolean(flags.verbose));
829
841
  if (!flags['no-intro']) {
830
- p.intro('Get NocoBase');
842
+ this.log('Get NocoBase');
831
843
  }
832
844
  const resolved = await this.resolveDownloadFlags(flags);
833
845
  const source = resolved.source;
@@ -857,7 +869,7 @@ export default class SourceDownload extends Command {
857
869
  async run() {
858
870
  try {
859
871
  const result = await this.download();
860
- p.outro(`Download completed via ${downloadSourceLabel(result.resolved.source)}.`);
872
+ this.logProgress(`Download completed via ${downloadSourceLabel(result.resolved.source)}.`);
861
873
  return result;
862
874
  }
863
875
  catch (error) {