@nocobase/cli 2.1.0-alpha.3 → 2.1.0-alpha.31

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 (182) hide show
  1. package/LICENSE.txt +107 -0
  2. package/README.md +379 -19
  3. package/README.zh-CN.md +329 -0
  4. package/bin/run.cmd +3 -0
  5. package/bin/run.js +131 -0
  6. package/dist/commands/api/resource/create.js +15 -0
  7. package/dist/commands/api/resource/destroy.js +15 -0
  8. package/dist/commands/api/resource/get.js +15 -0
  9. package/dist/commands/api/resource/index.js +20 -0
  10. package/dist/commands/api/resource/list.js +16 -0
  11. package/dist/commands/api/resource/query.js +15 -0
  12. package/dist/commands/api/resource/update.js +15 -0
  13. package/dist/commands/app/down.js +266 -0
  14. package/dist/commands/app/logs.js +98 -0
  15. package/dist/commands/app/restart.js +75 -0
  16. package/dist/commands/app/start.js +253 -0
  17. package/dist/commands/app/stop.js +99 -0
  18. package/dist/commands/app/upgrade.js +582 -0
  19. package/{src/cli.js → dist/commands/build.js} +4 -11
  20. package/dist/commands/config/delete.js +30 -0
  21. package/dist/commands/config/get.js +29 -0
  22. package/dist/commands/config/index.js +20 -0
  23. package/dist/commands/config/list.js +29 -0
  24. package/dist/commands/config/set.js +35 -0
  25. package/dist/commands/db/check.js +238 -0
  26. package/dist/commands/db/logs.js +85 -0
  27. package/dist/commands/db/ps.js +60 -0
  28. package/dist/commands/db/shared.js +96 -0
  29. package/dist/commands/db/start.js +71 -0
  30. package/dist/commands/db/stop.js +71 -0
  31. package/{templates/plugin/src/client/models/index.ts → dist/commands/dev.js} +4 -4
  32. package/{src/index.js → dist/commands/down.js} +4 -6
  33. package/{src/commands/locale/react-js-cron/index.js → dist/commands/download.js} +4 -8
  34. package/dist/commands/env/add.js +312 -0
  35. package/dist/commands/env/auth.js +55 -0
  36. package/dist/commands/env/info.js +156 -0
  37. package/dist/commands/env/list.js +50 -0
  38. package/dist/commands/env/remove.js +59 -0
  39. package/dist/commands/env/shared.js +158 -0
  40. package/dist/commands/env/update.js +67 -0
  41. package/dist/commands/env/use.js +28 -0
  42. package/dist/commands/examples/prompts-stages.js +150 -0
  43. package/dist/commands/examples/prompts-test.js +181 -0
  44. package/dist/commands/init.js +1027 -0
  45. package/dist/commands/install.js +2206 -0
  46. package/dist/commands/license/activate.js +360 -0
  47. package/dist/commands/license/env.js +94 -0
  48. package/dist/commands/license/generate-id.js +108 -0
  49. package/dist/commands/license/id.js +56 -0
  50. package/dist/commands/license/index.js +20 -0
  51. package/dist/commands/license/plugins/clean.js +101 -0
  52. package/dist/commands/license/plugins/index.js +20 -0
  53. package/dist/commands/license/plugins/list.js +50 -0
  54. package/dist/commands/license/plugins/shared.js +325 -0
  55. package/dist/commands/license/plugins/sync.js +269 -0
  56. package/dist/commands/license/shared.js +414 -0
  57. package/dist/commands/license/status.js +50 -0
  58. package/dist/commands/logs.js +12 -0
  59. package/dist/commands/plugin/disable.js +66 -0
  60. package/dist/commands/plugin/enable.js +66 -0
  61. package/dist/commands/plugin/list.js +62 -0
  62. package/dist/commands/pm/disable.js +12 -0
  63. package/dist/commands/pm/enable.js +12 -0
  64. package/dist/commands/pm/list.js +12 -0
  65. package/dist/commands/restart.js +12 -0
  66. package/dist/commands/scaffold/migration.js +38 -0
  67. package/dist/commands/scaffold/plugin.js +37 -0
  68. package/dist/commands/self/check.js +71 -0
  69. package/dist/commands/self/index.js +20 -0
  70. package/dist/commands/self/update.js +86 -0
  71. package/dist/commands/skills/check.js +69 -0
  72. package/dist/commands/skills/index.js +20 -0
  73. package/dist/commands/skills/install.js +71 -0
  74. package/dist/commands/skills/remove.js +71 -0
  75. package/dist/commands/skills/update.js +78 -0
  76. package/dist/commands/source/build.js +58 -0
  77. package/dist/commands/source/dev.js +158 -0
  78. package/dist/commands/source/download.js +866 -0
  79. package/dist/commands/source/test.js +477 -0
  80. package/dist/commands/start.js +12 -0
  81. package/dist/commands/stop.js +12 -0
  82. package/dist/commands/test.js +12 -0
  83. package/dist/commands/upgrade.js +12 -0
  84. package/dist/generated/command-registry.js +133 -0
  85. package/dist/help/runtime-help.js +23 -0
  86. package/dist/lib/api-client.js +329 -0
  87. package/dist/lib/app-health.js +126 -0
  88. package/dist/lib/app-managed-resources.js +268 -0
  89. package/dist/lib/app-runtime.js +171 -0
  90. package/dist/lib/auth-store.js +328 -0
  91. package/dist/lib/bootstrap.js +384 -0
  92. package/dist/lib/build-config.js +18 -0
  93. package/dist/lib/builtin-db.js +86 -0
  94. package/dist/lib/cli-config.js +176 -0
  95. package/dist/lib/cli-home.js +47 -0
  96. package/dist/lib/cli-locale.js +129 -0
  97. package/dist/lib/command-discovery.js +39 -0
  98. package/dist/lib/db-connection-check.js +178 -0
  99. package/dist/lib/env-auth.js +872 -0
  100. package/dist/lib/env-config.js +87 -0
  101. package/dist/lib/generated-command.js +171 -0
  102. package/dist/lib/http-request.js +49 -0
  103. package/dist/lib/naming.js +70 -0
  104. package/dist/lib/openapi.js +62 -0
  105. package/dist/lib/plugin-storage.js +127 -0
  106. package/dist/lib/post-processors.js +23 -0
  107. package/dist/lib/prompt-catalog.js +581 -0
  108. package/dist/lib/prompt-validators.js +185 -0
  109. package/dist/lib/prompt-web-ui.js +2103 -0
  110. package/dist/lib/resource-command.js +343 -0
  111. package/dist/lib/resource-request.js +104 -0
  112. package/dist/lib/run-npm.js +250 -0
  113. package/dist/lib/runtime-env-vars.js +32 -0
  114. package/dist/lib/runtime-generator.js +498 -0
  115. package/dist/lib/runtime-store.js +56 -0
  116. package/dist/lib/self-manager.js +301 -0
  117. package/dist/lib/skills-manager.js +296 -0
  118. package/dist/lib/startup-update.js +281 -0
  119. package/dist/lib/ui.js +178 -0
  120. package/dist/locale/en-US.json +339 -0
  121. package/dist/locale/zh-CN.json +339 -0
  122. package/dist/post-processors/data-modeling.js +66 -0
  123. package/dist/post-processors/data-source-manager.js +114 -0
  124. package/dist/post-processors/index.js +19 -0
  125. package/nocobase-ctl.config.json +369 -0
  126. package/package.json +95 -26
  127. package/LICENSE +0 -661
  128. package/bin/index.js +0 -39
  129. package/nocobase.conf.tpl +0 -95
  130. package/src/commands/benchmark.js +0 -73
  131. package/src/commands/build.js +0 -49
  132. package/src/commands/clean.js +0 -30
  133. package/src/commands/client.js +0 -166
  134. package/src/commands/create-nginx-conf.js +0 -37
  135. package/src/commands/create-plugin.js +0 -33
  136. package/src/commands/dev.js +0 -200
  137. package/src/commands/doc.js +0 -76
  138. package/src/commands/e2e.js +0 -265
  139. package/src/commands/global.js +0 -43
  140. package/src/commands/index.js +0 -45
  141. package/src/commands/instance-id.js +0 -47
  142. package/src/commands/locale/cronstrue.js +0 -122
  143. package/src/commands/locale/react-js-cron/en-US.json +0 -75
  144. package/src/commands/locale/react-js-cron/zh-CN.json +0 -33
  145. package/src/commands/locale/react-js-cron/zh-TW.json +0 -33
  146. package/src/commands/locale.js +0 -81
  147. package/src/commands/p-test.js +0 -88
  148. package/src/commands/perf.js +0 -63
  149. package/src/commands/pkg.js +0 -321
  150. package/src/commands/pm2.js +0 -37
  151. package/src/commands/postinstall.js +0 -88
  152. package/src/commands/start.js +0 -148
  153. package/src/commands/tar.js +0 -36
  154. package/src/commands/test-coverage.js +0 -55
  155. package/src/commands/test.js +0 -107
  156. package/src/commands/umi.js +0 -33
  157. package/src/commands/update-deps.js +0 -72
  158. package/src/commands/upgrade.js +0 -47
  159. package/src/commands/view-license-key.js +0 -44
  160. package/src/license.js +0 -76
  161. package/src/logger.js +0 -75
  162. package/src/plugin-generator.js +0 -80
  163. package/src/util.js +0 -517
  164. package/templates/bundle-status.html +0 -338
  165. package/templates/create-app-package.json +0 -39
  166. package/templates/plugin/.npmignore.tpl +0 -2
  167. package/templates/plugin/README.md.tpl +0 -1
  168. package/templates/plugin/client.d.ts +0 -2
  169. package/templates/plugin/client.js +0 -1
  170. package/templates/plugin/package.json.tpl +0 -11
  171. package/templates/plugin/server.d.ts +0 -2
  172. package/templates/plugin/server.js +0 -1
  173. package/templates/plugin/src/client/client.d.ts +0 -249
  174. package/templates/plugin/src/client/index.tsx.tpl +0 -1
  175. package/templates/plugin/src/client/locale.ts +0 -21
  176. package/templates/plugin/src/client/plugin.tsx.tpl +0 -10
  177. package/templates/plugin/src/index.ts +0 -2
  178. package/templates/plugin/src/locale/en-US.json +0 -1
  179. package/templates/plugin/src/locale/zh-CN.json +0 -1
  180. package/templates/plugin/src/server/collections/.gitkeep +0 -0
  181. package/templates/plugin/src/server/index.ts.tpl +0 -1
  182. package/templates/plugin/src/server/plugin.ts.tpl +0 -19
@@ -0,0 +1,71 @@
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, stopDockerContainer, } from '../../lib/app-runtime.js';
11
+ import { announceTargetEnv, failTask, startTask, succeedTask } from '../../lib/ui.js';
12
+ import { formatUnmanagedDbMessage, resolveDbRuntime } from './shared.js';
13
+ function formatDbStopFailure(envName, message) {
14
+ if (/does not exist/i.test(message)) {
15
+ return [
16
+ `Can't stop the database for "${envName}" yet.`,
17
+ 'The saved built-in database container 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
+ return [
23
+ `Couldn't stop the database for "${envName}".`,
24
+ 'Check that the built-in database runtime for this env is still available, then try again.',
25
+ `Details: ${message}`,
26
+ ].join('\n');
27
+ }
28
+ export default class DbStop extends Command {
29
+ static description = 'Stop the built-in database container for the selected env.';
30
+ static examples = [
31
+ '<%= config.bin %> <%= command.id %>',
32
+ '<%= config.bin %> <%= command.id %> --env app1',
33
+ '<%= config.bin %> <%= command.id %> --env app1 --verbose',
34
+ ];
35
+ static flags = {
36
+ env: Flags.string({
37
+ char: 'e',
38
+ description: 'CLI env name to stop the built-in database for. Defaults to the current env when omitted',
39
+ }),
40
+ verbose: Flags.boolean({
41
+ description: 'Show raw shutdown output from the underlying Docker command',
42
+ default: false,
43
+ }),
44
+ };
45
+ async run() {
46
+ const { flags } = await this.parse(DbStop);
47
+ const requestedEnv = flags.env?.trim() || undefined;
48
+ const runtime = await resolveDbRuntime(requestedEnv);
49
+ if (!runtime) {
50
+ this.error(formatMissingManagedAppEnvMessage(requestedEnv));
51
+ }
52
+ if (runtime.kind !== 'builtin') {
53
+ this.error(formatUnmanagedDbMessage('stop', runtime));
54
+ }
55
+ announceTargetEnv(runtime.envName);
56
+ startTask(`Stopping the built-in database for "${runtime.envName}"...`);
57
+ try {
58
+ const state = await stopDockerContainer(runtime.containerName, {
59
+ stdio: flags.verbose ? 'inherit' : 'ignore',
60
+ });
61
+ succeedTask(state === 'already-stopped'
62
+ ? `The built-in database is already stopped for "${runtime.envName}".`
63
+ : `The built-in database has stopped for "${runtime.envName}".`);
64
+ }
65
+ catch (error) {
66
+ const message = error instanceof Error ? error.message : String(error);
67
+ failTask(`Failed to stop the built-in database for "${runtime.envName}".`);
68
+ this.error(formatDbStopFailure(runtime.envName, message));
69
+ }
70
+ }
71
+ }
@@ -6,7 +6,7 @@
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
-
10
- import { ModelConstructor } from '@nocobase/flow-engine';
11
-
12
- export default {} as Record<string, ModelConstructor>;
9
+ import SourceDev from './source/dev.js';
10
+ export default class Dev extends SourceDev {
11
+ static hidden = true;
12
+ }
@@ -6,9 +6,7 @@
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
-
10
- const util = require('./util');
11
-
12
- module.exports = {
13
- ...util,
14
- };
9
+ import AppDown from './app/down.js';
10
+ export default class Down extends AppDown {
11
+ static hidden = true;
12
+ }
@@ -6,12 +6,8 @@
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
-
10
- exports.getReactJsCron = (lang) => {
11
- const langs = {
12
- 'en-US': require('./en-US.json'),
13
- 'zh-CN': require('./zh-CN.json'),
14
- 'z-TW': require('./zh-TW.json'),
15
- }
16
- return langs[lang] || langs['en-US'];
9
+ export { defaultDockerRegistryForLang } from './source/download.js';
10
+ import SourceDownload from './source/download.js';
11
+ export default class Download extends SourceDownload {
12
+ static hidden = true;
17
13
  }
@@ -0,0 +1,312 @@
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 { Args, Command, Flags } from '@oclif/core';
10
+ import { upsertEnv } from '../../lib/auth-store.js';
11
+ import { resolveDefaultConfigScope } from '../../lib/cli-home.js';
12
+ import { buildStoredEnvConfig, } from '../../lib/env-config.js';
13
+ import { runPromptCatalog, } from '../../lib/prompt-catalog.js';
14
+ import { applyCliLocale, CLI_LOCALE_FLAG_DESCRIPTION, CLI_LOCALE_FLAG_OPTIONS, localeText, } from '../../lib/cli-locale.js';
15
+ import { validateApiBaseUrl } from '../../lib/prompt-validators.js';
16
+ import { printVerbose, setVerboseMode } from '../../lib/ui.js';
17
+ import * as p from '@clack/prompts';
18
+ const ENV_RUNTIME_FLAG_MAP = {
19
+ source: 'source',
20
+ 'download-version': 'downloadVersion',
21
+ 'docker-registry': 'dockerRegistry',
22
+ 'docker-platform': 'dockerPlatform',
23
+ 'git-url': 'gitUrl',
24
+ 'npm-registry': 'npmRegistry',
25
+ 'app-root-path': 'appRootPath',
26
+ 'storage-path': 'storagePath',
27
+ 'app-port': 'appPort',
28
+ 'app-key': 'appKey',
29
+ timezone: 'timezone',
30
+ 'db-dialect': 'dbDialect',
31
+ 'builtin-db-image': 'builtinDbImage',
32
+ 'db-host': 'dbHost',
33
+ 'db-port': 'dbPort',
34
+ 'db-database': 'dbDatabase',
35
+ 'db-user': 'dbUser',
36
+ 'db-password': 'dbPassword',
37
+ 'root-username': 'rootUsername',
38
+ 'root-email': 'rootEmail',
39
+ 'root-password': 'rootPassword',
40
+ 'root-nickname': 'rootNickname',
41
+ };
42
+ const ENV_BOOLEAN_RUNTIME_FLAG_MAP = {
43
+ 'builtin-db': 'builtinDb',
44
+ 'dev-dependencies': 'devDependencies',
45
+ build: 'build',
46
+ 'build-dts': 'buildDts',
47
+ };
48
+ const envAddText = (key, values) => localeText(`commands.envAdd.${key}`, values);
49
+ export default class EnvAdd extends Command {
50
+ static summary = 'Save a named NocoBase API endpoint (token or OAuth), then switch the CLI to use it';
51
+ static examples = [
52
+ '<%= config.bin %> <%= command.id %>',
53
+ '<%= config.bin %> <%= command.id %> local',
54
+ '<%= config.bin %> <%= command.id %> local --api-base-url http://localhost:13000/api --auth-type oauth',
55
+ ];
56
+ static args = {
57
+ name: Args.string({
58
+ description: 'Label for this environment (optional first argument; in a TTY, prompted when omitted; required when not using a TTY)',
59
+ required: false,
60
+ }),
61
+ };
62
+ static flags = {
63
+ env: Flags.string({
64
+ char: 'e',
65
+ hidden: true,
66
+ deprecated: true,
67
+ description: 'Environment name (same as the optional positional argument; for compatibility with -e/--env on other commands)',
68
+ }),
69
+ verbose: Flags.boolean({
70
+ description: 'Print detailed progress while writing config',
71
+ default: false,
72
+ }),
73
+ locale: Flags.string({
74
+ description: CLI_LOCALE_FLAG_DESCRIPTION,
75
+ options: CLI_LOCALE_FLAG_OPTIONS,
76
+ }),
77
+ 'no-intro': Flags.boolean({
78
+ hidden: true,
79
+ description: 'Skip command intro when invoked by another CLI command',
80
+ default: false,
81
+ }),
82
+ 'default-api-base-url': Flags.string({
83
+ char: 'd',
84
+ hidden: true,
85
+ 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',
86
+ }),
87
+ 'api-base-url': Flags.string({
88
+ char: 'u',
89
+ description: 'Root URL for HTTP API calls, including the /api prefix (e.g. http://localhost:13000/api); prompted in a TTY when omitted',
90
+ }),
91
+ 'auth-type': Flags.string({
92
+ char: 'a',
93
+ description: 'Authentication: token (API key) or oauth (browser login via `nb env auth`); prompted in a TTY when omitted',
94
+ options: ['token', 'oauth'],
95
+ }),
96
+ 'access-token': Flags.string({
97
+ char: 't',
98
+ aliases: ['token'],
99
+ description: 'API key or access token when using --auth-type token (prompted in a TTY when omitted)',
100
+ }),
101
+ source: Flags.string({
102
+ hidden: true,
103
+ description: 'Application source saved with this env',
104
+ }),
105
+ 'download-version': Flags.string({
106
+ hidden: true,
107
+ description: 'Downloaded app version saved with this env',
108
+ }),
109
+ 'docker-registry': Flags.string({
110
+ hidden: true,
111
+ description: 'Docker registry saved with this env',
112
+ }),
113
+ 'docker-platform': Flags.string({
114
+ hidden: true,
115
+ description: 'Docker image platform saved with this env',
116
+ }),
117
+ 'git-url': Flags.string({
118
+ hidden: true,
119
+ description: 'Git repository URL saved with this env',
120
+ }),
121
+ 'npm-registry': Flags.string({
122
+ hidden: true,
123
+ description: 'npm registry saved with this env',
124
+ }),
125
+ 'dev-dependencies': Flags.boolean({
126
+ allowNo: true,
127
+ hidden: true,
128
+ description: 'Whether development dependencies were installed for this env',
129
+ }),
130
+ build: Flags.boolean({
131
+ allowNo: true,
132
+ hidden: true,
133
+ description: 'Whether the app was built after download for this env',
134
+ }),
135
+ 'build-dts': Flags.boolean({
136
+ allowNo: true,
137
+ hidden: true,
138
+ description: 'Whether declaration files were emitted during build for this env',
139
+ }),
140
+ 'app-root-path': Flags.string({
141
+ hidden: true,
142
+ description: 'Application root path saved with this env',
143
+ }),
144
+ 'storage-path': Flags.string({
145
+ hidden: true,
146
+ description: 'Storage path saved with this env',
147
+ }),
148
+ 'app-port': Flags.string({
149
+ hidden: true,
150
+ description: 'Application HTTP port saved with this env',
151
+ }),
152
+ 'app-key': Flags.string({
153
+ hidden: true,
154
+ description: 'Application secret key saved with this env',
155
+ }),
156
+ timezone: Flags.string({
157
+ hidden: true,
158
+ description: 'Application timezone saved with this env',
159
+ }),
160
+ 'builtin-db': Flags.boolean({
161
+ allowNo: true,
162
+ hidden: true,
163
+ description: 'Whether this env uses a CLI-managed built-in database',
164
+ }),
165
+ 'db-dialect': Flags.string({
166
+ hidden: true,
167
+ description: 'Database dialect saved with this env',
168
+ }),
169
+ 'builtin-db-image': Flags.string({
170
+ hidden: true,
171
+ description: 'Built-in database image saved with this env',
172
+ }),
173
+ 'db-host': Flags.string({
174
+ hidden: true,
175
+ description: 'Database host saved with this env',
176
+ }),
177
+ 'db-port': Flags.string({
178
+ hidden: true,
179
+ description: 'Database port saved with this env',
180
+ }),
181
+ 'db-database': Flags.string({
182
+ hidden: true,
183
+ description: 'Database name saved with this env',
184
+ }),
185
+ 'db-user': Flags.string({
186
+ hidden: true,
187
+ description: 'Database user saved with this env',
188
+ }),
189
+ 'db-password': Flags.string({
190
+ hidden: true,
191
+ description: 'Database password saved with this env',
192
+ }),
193
+ 'root-username': Flags.string({
194
+ hidden: true,
195
+ description: 'Initial root username saved with this env',
196
+ }),
197
+ 'root-email': Flags.string({
198
+ hidden: true,
199
+ description: 'Initial root email saved with this env',
200
+ }),
201
+ 'root-password': Flags.string({
202
+ hidden: true,
203
+ description: 'Initial root password saved with this env',
204
+ }),
205
+ 'root-nickname': Flags.string({
206
+ hidden: true,
207
+ description: 'Initial root nickname saved with this env',
208
+ }),
209
+ };
210
+ static prompts = {
211
+ name: {
212
+ type: 'text',
213
+ message: envAddText('prompts.name.message'),
214
+ placeholder: envAddText('prompts.name.placeholder'),
215
+ required: true,
216
+ },
217
+ apiBaseUrl: {
218
+ type: 'text',
219
+ message: envAddText('prompts.apiBaseUrl.message'),
220
+ placeholder: envAddText('prompts.apiBaseUrl.placeholder'),
221
+ required: true,
222
+ validate: validateApiBaseUrl,
223
+ },
224
+ authType: {
225
+ type: 'select',
226
+ message: envAddText('prompts.authType.message'),
227
+ options: [
228
+ {
229
+ value: 'oauth',
230
+ label: envAddText('prompts.authType.oauthLabel'),
231
+ hint: envAddText('prompts.authType.oauthHint'),
232
+ },
233
+ { value: 'token', label: envAddText('prompts.authType.tokenLabel') },
234
+ ],
235
+ initialValue: 'oauth',
236
+ required: true,
237
+ },
238
+ accessToken: {
239
+ type: 'text',
240
+ message: envAddText('prompts.accessToken.message'),
241
+ placeholder: envAddText('prompts.accessToken.placeholder'),
242
+ required: true,
243
+ hidden: (values) => values.authType !== 'token',
244
+ },
245
+ };
246
+ buildPromptValues(nameArg, flags) {
247
+ const values = {};
248
+ const name = nameArg?.trim() || flags.env?.trim();
249
+ if (name) {
250
+ values.name = name;
251
+ }
252
+ const apiFromFlag = flags['api-base-url'];
253
+ if (typeof apiFromFlag === 'string' && apiFromFlag.trim() !== '') {
254
+ values.apiBaseUrl = apiFromFlag.trim();
255
+ }
256
+ if (flags['auth-type']) {
257
+ values.authType = flags['auth-type'];
258
+ }
259
+ const token = flags['access-token'] ?? flags.token;
260
+ if (typeof token === 'string' && token !== '') {
261
+ values.accessToken = token;
262
+ }
263
+ return values;
264
+ }
265
+ buildPromptInitialValues(flags) {
266
+ const initialValues = {};
267
+ const defaultApiBaseUrl = flags['default-api-base-url']?.trim();
268
+ if (defaultApiBaseUrl) {
269
+ initialValues.apiBaseUrl = defaultApiBaseUrl;
270
+ }
271
+ return initialValues;
272
+ }
273
+ buildEnvConfig(results, flags) {
274
+ const envConfigInput = {
275
+ apiBaseUrl: results.apiBaseUrl,
276
+ authType: results.authType,
277
+ accessToken: results.accessToken,
278
+ };
279
+ for (const [flagName, configKey] of Object.entries(ENV_RUNTIME_FLAG_MAP)) {
280
+ const value = flags[flagName];
281
+ envConfigInput[configKey] = value;
282
+ }
283
+ for (const [flagName, configKey] of Object.entries(ENV_BOOLEAN_RUNTIME_FLAG_MAP)) {
284
+ const value = flags[flagName];
285
+ envConfigInput[configKey] = value;
286
+ }
287
+ return buildStoredEnvConfig(envConfigInput);
288
+ }
289
+ async run() {
290
+ const { args, flags } = await this.parse(EnvAdd);
291
+ const parsedFlags = flags;
292
+ applyCliLocale(parsedFlags.locale);
293
+ setVerboseMode(parsedFlags.verbose);
294
+ if (!parsedFlags['no-intro']) {
295
+ p.intro('Connect a NocoBase Environment');
296
+ }
297
+ const results = await runPromptCatalog(EnvAdd.prompts, {
298
+ values: this.buildPromptValues(args.name, parsedFlags),
299
+ initialValues: this.buildPromptInitialValues(parsedFlags),
300
+ command: this,
301
+ });
302
+ const envName = String(results.name);
303
+ const envConfig = this.buildEnvConfig(results, parsedFlags);
304
+ printVerbose(`Saving env "${envName}" globally.`);
305
+ await upsertEnv(envName, envConfig, { scope: resolveDefaultConfigScope() });
306
+ if (results.authType === 'oauth') {
307
+ await this.config.runCommand('env:auth', [envName]);
308
+ }
309
+ await this.config.runCommand('env:update', [envName]);
310
+ p.outro(`Env "${envName}" added successfully.`);
311
+ }
312
+ }
@@ -0,0 +1,55 @@
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 { Args, Command, Flags } from '@oclif/core';
10
+ import { getCurrentEnvName } from '../../lib/auth-store.js';
11
+ import { resolveDefaultConfigScope } from '../../lib/cli-home.js';
12
+ import { authenticateEnvWithOauth } from '../../lib/env-auth.js';
13
+ import { failTask, startTask, succeedTask } from '../../lib/ui.js';
14
+ export default class EnvAuth extends Command {
15
+ static summary = 'Sign in to a saved NocoBase environment with OAuth';
16
+ static examples = [
17
+ '<%= config.bin %> <%= command.id %>',
18
+ '<%= config.bin %> <%= command.id %> prod',
19
+ ];
20
+ static args = {
21
+ name: Args.string({
22
+ description: 'Environment name (omit to use the current env)',
23
+ required: false,
24
+ }),
25
+ };
26
+ static flags = {
27
+ env: Flags.string({
28
+ char: 'e',
29
+ hidden: true,
30
+ deprecated: true,
31
+ description: 'Environment name (same as the optional positional argument; for compatibility with -e/--env on other commands)',
32
+ }),
33
+ };
34
+ async run() {
35
+ const { args, flags } = await this.parse(EnvAuth);
36
+ const nameArg = args.name?.trim();
37
+ const nameFlag = flags.env?.trim() || undefined;
38
+ if (nameArg && nameFlag && nameArg !== nameFlag) {
39
+ this.error(`Environment name was provided both as the argument ("${nameArg}") and as --env ("${nameFlag}"). Please use only one.`);
40
+ }
41
+ const envName = nameArg || nameFlag || (await getCurrentEnvName({ scope: resolveDefaultConfigScope() }));
42
+ startTask(`Starting browser sign-in for "${envName}"...`);
43
+ try {
44
+ await authenticateEnvWithOauth({
45
+ envName,
46
+ scope: resolveDefaultConfigScope(),
47
+ });
48
+ succeedTask(`Signed in to "${envName}".`);
49
+ }
50
+ catch (error) {
51
+ failTask(`Sign-in failed for "${envName}".`);
52
+ throw error;
53
+ }
54
+ }
55
+ }
@@ -0,0 +1,156 @@
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 { Args, Command, Flags } from '@oclif/core';
10
+ import { formatMissingManagedAppEnvMessage, resolveManagedAppRuntime } from '../../lib/app-runtime.js';
11
+ import { resolveBuiltinDbConnection } from '../../lib/builtin-db.js';
12
+ import { renderTable } from '../../lib/ui.js';
13
+ import { appRootPath, dbStatus, runtimeStatus, storagePath } from './shared.js';
14
+ function normalizeJsonValue(value) {
15
+ if (value === undefined || value === null || value === '') {
16
+ return '-';
17
+ }
18
+ if (typeof value === 'boolean' || typeof value === 'number') {
19
+ return value;
20
+ }
21
+ return String(value);
22
+ }
23
+ function normalizeValue(value) {
24
+ if (value === undefined || value === null || value === '') {
25
+ return '-';
26
+ }
27
+ if (typeof value === 'boolean') {
28
+ return value ? 'true' : 'false';
29
+ }
30
+ return String(value);
31
+ }
32
+ function maskSecret(value, showSecrets) {
33
+ const normalized = normalizeValue(value);
34
+ if (normalized === '-') {
35
+ return normalized;
36
+ }
37
+ return showSecrets ? normalized : '********';
38
+ }
39
+ function createGroupTable(title, values) {
40
+ const rows = Object.entries(values).map(([field, value]) => [field, normalizeValue(value)]);
41
+ return `${title}\n${renderTable(['Field', 'Value'], rows)}`;
42
+ }
43
+ function serializeGroup(values) {
44
+ return Object.fromEntries(Object.entries(values).map(([field, value]) => [field, normalizeJsonValue(value)]));
45
+ }
46
+ export default class EnvInfo extends Command {
47
+ static hidden = false;
48
+ static description = 'Show grouped details for the selected NocoBase env, including app, database, API, and auth settings.';
49
+ static examples = [
50
+ '<%= config.bin %> <%= command.id %> app1',
51
+ '<%= config.bin %> <%= command.id %> app1 --json',
52
+ '<%= config.bin %> <%= command.id %> app1 --show-secrets',
53
+ '<%= config.bin %> <%= command.id %> --env app1',
54
+ ];
55
+ static args = {
56
+ name: Args.string({
57
+ description: 'CLI env name to inspect. Defaults to the current env when omitted',
58
+ required: false,
59
+ }),
60
+ };
61
+ static flags = {
62
+ env: Flags.string({
63
+ char: 'e',
64
+ description: 'CLI env name to inspect. Defaults to the current env when omitted',
65
+ }),
66
+ json: Flags.boolean({
67
+ description: 'Output the result as JSON',
68
+ default: false,
69
+ }),
70
+ 'show-secrets': Flags.boolean({
71
+ description: 'Show secret values in plain text',
72
+ default: false,
73
+ }),
74
+ };
75
+ async run() {
76
+ const { args, flags } = await this.parse(EnvInfo);
77
+ const envNameArg = args.name?.trim() || undefined;
78
+ const envNameFlag = flags.env?.trim() || undefined;
79
+ if (envNameArg && envNameFlag && envNameArg !== envNameFlag) {
80
+ this.error(`Environment name was provided both as the argument ("${envNameArg}") and as --env ("${envNameFlag}"). Please use only one.`);
81
+ }
82
+ const requestedEnv = envNameArg || envNameFlag;
83
+ const showSecrets = flags['show-secrets'];
84
+ const runtime = await resolveManagedAppRuntime(requestedEnv);
85
+ if (!runtime) {
86
+ this.error(formatMissingManagedAppEnvMessage(requestedEnv));
87
+ }
88
+ const auth = runtime.env.auth;
89
+ const builtinDbConnection = (runtime.kind === 'local' || runtime.kind === 'docker') && runtime.env.config.builtinDb
90
+ ? await resolveBuiltinDbConnection(runtime)
91
+ : undefined;
92
+ const appGroup = {
93
+ appRootPath: appRootPath(runtime),
94
+ storagePath: storagePath(runtime),
95
+ appPort: runtime.env.config.appPort,
96
+ appStatus: await runtimeStatus(runtime),
97
+ source: runtime.source,
98
+ downloadVersion: runtime.env.config.downloadVersion,
99
+ dockerRegistry: runtime.env.config.dockerRegistry,
100
+ dockerPlatform: runtime.env.config.dockerPlatform,
101
+ timezone: runtime.env.config.timezone,
102
+ };
103
+ const dbGroup = {
104
+ databaseStatus: await dbStatus(runtime),
105
+ builtinDb: runtime.env.config.builtinDb,
106
+ dbDialect: runtime.env.config.dbDialect,
107
+ builtinDbImage: runtime.env.config.builtinDbImage,
108
+ dbHost: builtinDbConnection?.dbHost ?? runtime.env.config.dbHost,
109
+ dbPort: builtinDbConnection?.dbPort ?? runtime.env.config.dbPort,
110
+ dbDatabase: runtime.env.config.dbDatabase,
111
+ dbUser: runtime.env.config.dbUser,
112
+ dbPassword: maskSecret(runtime.env.config.dbPassword, showSecrets),
113
+ };
114
+ const authGroup = {
115
+ type: auth?.type,
116
+ expiresAt: auth?.type === 'oauth' ? auth.expiresAt : undefined,
117
+ scope: auth?.type === 'oauth' ? auth.scope : undefined,
118
+ issuer: auth?.type === 'oauth' ? auth.issuer : undefined,
119
+ clientId: auth?.type === 'oauth' ? auth.clientId : undefined,
120
+ resource: auth?.type === 'oauth' ? auth.resource : undefined,
121
+ accessToken: maskSecret(auth?.accessToken, showSecrets),
122
+ refreshToken: maskSecret(auth?.type === 'oauth' ? auth.refreshToken : undefined, showSecrets),
123
+ };
124
+ const apiGroup = {
125
+ apiBaseUrl: runtime.env.apiBaseUrl,
126
+ 'auth.type': authGroup.type,
127
+ 'auth.expiresAt': authGroup.expiresAt,
128
+ 'auth.scope': authGroup.scope,
129
+ 'auth.issuer': authGroup.issuer,
130
+ 'auth.clientId': authGroup.clientId,
131
+ 'auth.resource': authGroup.resource,
132
+ 'auth.accessToken': authGroup.accessToken,
133
+ 'auth.refreshToken': authGroup.refreshToken,
134
+ };
135
+ const output = {
136
+ ok: true,
137
+ env: runtime.envName,
138
+ kind: runtime.kind,
139
+ app: serializeGroup(appGroup),
140
+ db: serializeGroup(dbGroup),
141
+ api: {
142
+ apiBaseUrl: normalizeJsonValue(runtime.env.apiBaseUrl),
143
+ auth: serializeGroup(authGroup),
144
+ },
145
+ };
146
+ if (flags.json) {
147
+ this.log(JSON.stringify(output, null, 2));
148
+ return;
149
+ }
150
+ this.log([
151
+ createGroupTable('App', appGroup),
152
+ createGroupTable('DB', dbGroup),
153
+ createGroupTable('API', apiGroup),
154
+ ].join('\n\n'));
155
+ }
156
+ }