@nocobase/cli 2.1.0-alpha.40 → 2.1.0-alpha.46

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 (56) hide show
  1. package/README.md +20 -8
  2. package/README.zh-CN.md +20 -8
  3. package/bin/run.js +9 -37
  4. package/dist/commands/app/destroy.js +225 -0
  5. package/dist/commands/app/down.js +24 -254
  6. package/dist/commands/app/restart.js +12 -5
  7. package/dist/commands/app/shared.js +122 -0
  8. package/dist/commands/app/start.js +41 -59
  9. package/dist/commands/app/stop.js +72 -26
  10. package/dist/commands/app/upgrade.js +312 -429
  11. package/dist/commands/config/delete.js +8 -1
  12. package/dist/commands/config/get.js +5 -0
  13. package/dist/commands/config/set.js +10 -1
  14. package/dist/commands/db/ps.js +5 -18
  15. package/dist/commands/db/start.js +23 -8
  16. package/dist/commands/env/add.js +66 -6
  17. package/dist/commands/env/auth.js +86 -27
  18. package/dist/commands/env/info.js +52 -8
  19. package/dist/commands/env/list.js +6 -7
  20. package/dist/commands/env/shared.js +41 -3
  21. package/dist/commands/env/status.js +10 -7
  22. package/dist/commands/init.js +214 -136
  23. package/dist/commands/install.js +364 -294
  24. package/dist/commands/license/plugins/shared.js +9 -3
  25. package/dist/commands/license/plugins/sync.js +54 -25
  26. package/dist/commands/self/update.js +58 -1
  27. package/dist/commands/source/dev.js +5 -5
  28. package/dist/commands/source/download.js +29 -25
  29. package/dist/generated/command-registry.js +3 -2
  30. package/dist/lib/api-client.js +6 -0
  31. package/dist/lib/api-command-compat.js +641 -0
  32. package/dist/lib/app-health.js +31 -18
  33. package/dist/lib/app-managed-resources.js +1 -1
  34. package/dist/lib/app-runtime.js +2 -2
  35. package/dist/lib/auth-store.js +56 -19
  36. package/dist/lib/backup.js +3 -3
  37. package/dist/lib/bootstrap.js +14 -8
  38. package/dist/lib/cli-config.js +137 -4
  39. package/dist/lib/cli-entry-error.js +44 -0
  40. package/dist/lib/cli-locale.js +19 -7
  41. package/dist/lib/db-connection-check.js +61 -0
  42. package/dist/lib/docker-log-stream.js +45 -0
  43. package/dist/lib/env-auth.js +98 -11
  44. package/dist/lib/env-config.js +3 -2
  45. package/dist/lib/env-guard.js +1 -1
  46. package/dist/lib/generated-command.js +17 -0
  47. package/dist/lib/prompt-validators.js +23 -5
  48. package/dist/lib/prompt-web-ui.js +143 -19
  49. package/dist/lib/run-npm.js +133 -23
  50. package/dist/lib/skills-manager.js +80 -4
  51. package/dist/lib/source-publish.js +4 -1
  52. package/dist/lib/startup-update.js +74 -50
  53. package/dist/lib/ui.js +4 -1
  54. package/dist/locale/en-US.json +92 -5
  55. package/dist/locale/zh-CN.json +92 -5
  56. package/package.json +34 -2
@@ -7,27 +7,28 @@
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 { getCurrentEnvName } from '../../lib/auth-store.js';
10
11
  import { ensureCrossEnvConfirmed, hasExplicitEnvSelection } from '../../lib/env-guard.js';
11
- import { formatMissingManagedAppEnvMessage, resolveManagedAppRuntime, runLocalNocoBaseCommand, stopDockerContainer, } from '../../lib/app-runtime.js';
12
- import { announceTargetEnv, failTask, startTask, succeedTask } from '../../lib/ui.js';
12
+ import { formatMissingManagedAppEnvMessage, resolveManagedAppRuntime, runLocalNocoBaseCommand, } from '../../lib/app-runtime.js';
13
+ import { announceTargetEnv, failTask, isInteractiveTerminal, printInfo, startTask, succeedTask } from '../../lib/ui.js';
14
+ import { builtinDbContainerName, removeDockerContainerIfExists } from './shared.js';
13
15
  function formatStopFailure(envName, message) {
14
- if (/does not exist/i.test(message)) {
15
- return [
16
- `Can't stop NocoBase for "${envName}" yet.`,
17
- 'The saved Docker app for this env could not be found on this machine.',
18
- 'If it was removed manually, reinstall or reconnect the env before trying again.',
19
- `Details: ${message}`,
20
- ].join('\n');
21
- }
22
16
  return [
23
17
  `Couldn't stop NocoBase for "${envName}".`,
24
18
  'Check that the local app or Docker runtime is still available, then try again.',
25
19
  `Details: ${message}`,
26
20
  ].join('\n');
27
21
  }
22
+ function formatStopCrossEnvConfirmationRequiredMessage(currentEnv, requestedEnv) {
23
+ return [
24
+ `Refusing to stop env "${requestedEnv}" because the current env is "${currentEnv}" and interactive confirmation is unavailable in the current session.`,
25
+ '',
26
+ 'Re-run the command with `--yes` to confirm this one-off cross-env stop, or switch the current env first.',
27
+ ].join('\n');
28
+ }
28
29
  export default class AppStop extends Command {
29
30
  static hidden = false;
30
- static description = 'Stop NocoBase for the selected env. Local npm/git installs stop the app process, and Docker installs stop the saved app container.';
31
+ static description = 'Stop NocoBase for the selected env. Local npm/git installs stop the app process, and Docker installs remove the saved app container.';
31
32
  static examples = [
32
33
  '<%= config.bin %> <%= command.id %>',
33
34
  '<%= config.bin %> <%= command.id %> --env local',
@@ -44,6 +45,15 @@ export default class AppStop extends Command {
44
45
  description: 'Confirm using --env when it targets a different env than the current env',
45
46
  default: false,
46
47
  }),
48
+ force: Flags.boolean({
49
+ char: 'f',
50
+ hidden: true,
51
+ default: false,
52
+ }),
53
+ 'with-db': Flags.boolean({
54
+ description: 'Also remove the CLI-managed built-in database container when present',
55
+ default: false,
56
+ }),
47
57
  verbose: Flags.boolean({
48
58
  description: 'Show raw shutdown output from the underlying local or Docker command',
49
59
  default: false,
@@ -53,13 +63,23 @@ export default class AppStop extends Command {
53
63
  const { flags } = await this.parse(AppStop);
54
64
  const requestedEnv = flags.env?.trim() || undefined;
55
65
  if (requestedEnv && hasExplicitEnvSelection(this.argv)) {
56
- const confirmed = await ensureCrossEnvConfirmed({
57
- command: this,
58
- requestedEnv,
59
- yes: flags.yes,
60
- });
61
- if (!confirmed) {
62
- return;
66
+ const skipCrossEnvConfirmation = flags.yes || flags.force;
67
+ if (!isInteractiveTerminal()) {
68
+ const currentEnv = await getCurrentEnvName();
69
+ const normalizedCurrentEnv = String(currentEnv ?? '').trim() || undefined;
70
+ if (normalizedCurrentEnv && normalizedCurrentEnv !== requestedEnv && !skipCrossEnvConfirmation) {
71
+ this.error(formatStopCrossEnvConfirmationRequiredMessage(normalizedCurrentEnv, requestedEnv));
72
+ }
73
+ }
74
+ else {
75
+ const confirmed = await ensureCrossEnvConfirmed({
76
+ command: this,
77
+ requestedEnv,
78
+ yes: skipCrossEnvConfirmation,
79
+ });
80
+ if (!confirmed) {
81
+ return;
82
+ }
63
83
  }
64
84
  }
65
85
  const runtime = await resolveManagedAppRuntime(requestedEnv);
@@ -83,32 +103,58 @@ export default class AppStop extends Command {
83
103
  }
84
104
  announceTargetEnv(runtime.envName);
85
105
  if (runtime.kind === 'docker') {
106
+ startTask(`Removing the saved Docker app container for "${runtime.envName}"...`);
107
+ try {
108
+ const state = await removeDockerContainerIfExists(runtime.containerName, {
109
+ stdio: commandStdio,
110
+ });
111
+ succeedTask(state === 'removed'
112
+ ? `Docker app container removed for "${runtime.envName}".`
113
+ : `No Docker app container found for "${runtime.envName}".`);
114
+ }
115
+ catch (error) {
116
+ const message = error instanceof Error ? error.message : String(error);
117
+ failTask(`Failed to stop NocoBase for "${runtime.envName}".`);
118
+ this.error(formatStopFailure(runtime.envName, message));
119
+ }
120
+ }
121
+ else {
86
122
  startTask(`Stopping NocoBase for "${runtime.envName}"...`);
87
123
  try {
88
- const state = await stopDockerContainer(runtime.containerName, {
124
+ await runLocalNocoBaseCommand(runtime, ['pm2', 'kill'], {
89
125
  stdio: commandStdio,
90
126
  });
91
- succeedTask(state === 'already-stopped'
92
- ? `NocoBase is already stopped for "${runtime.envName}".`
93
- : `NocoBase has stopped for "${runtime.envName}".`);
127
+ succeedTask(`NocoBase has stopped for "${runtime.envName}".`);
94
128
  }
95
129
  catch (error) {
96
130
  const message = error instanceof Error ? error.message : String(error);
97
131
  failTask(`Failed to stop NocoBase for "${runtime.envName}".`);
98
132
  this.error(formatStopFailure(runtime.envName, message));
99
133
  }
134
+ }
135
+ if (!flags['with-db']) {
136
+ return;
137
+ }
138
+ if (runtime.kind !== 'local' && runtime.kind !== 'docker') {
139
+ return;
140
+ }
141
+ const dbContainerName = builtinDbContainerName(runtime);
142
+ if (!dbContainerName) {
143
+ printInfo(`Env "${runtime.envName}" does not use a CLI-managed built-in database. Only the app runtime was stopped.`);
100
144
  return;
101
145
  }
102
- startTask(`Stopping NocoBase for "${runtime.envName}"...`);
146
+ startTask(`Removing the built-in database container for "${runtime.envName}"...`);
103
147
  try {
104
- await runLocalNocoBaseCommand(runtime, ['pm2', 'kill'], {
148
+ const state = await removeDockerContainerIfExists(dbContainerName, {
105
149
  stdio: commandStdio,
106
150
  });
107
- succeedTask(`NocoBase has stopped for "${runtime.envName}".`);
151
+ succeedTask(state === 'removed'
152
+ ? `Built-in database container removed for "${runtime.envName}".`
153
+ : `No built-in database container found for "${runtime.envName}".`);
108
154
  }
109
155
  catch (error) {
110
156
  const message = error instanceof Error ? error.message : String(error);
111
- failTask(`Failed to stop NocoBase for "${runtime.envName}".`);
157
+ failTask(`Failed to stop the built-in database for "${runtime.envName}".`);
112
158
  this.error(formatStopFailure(runtime.envName, message));
113
159
  }
114
160
  }