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

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 (77) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +63 -380
  3. package/assets/env-proxy/nginx/app.conf.tpl +23 -0
  4. package/assets/env-proxy/nginx/nocobase.conf.tpl +5 -0
  5. package/assets/env-proxy/nginx/snippets/dist-location.conf +5 -0
  6. package/assets/env-proxy/nginx/snippets/gzip.conf +17 -0
  7. package/assets/env-proxy/nginx/snippets/log-format-http.conf +13 -0
  8. package/assets/env-proxy/nginx/snippets/maps-http.conf +14 -0
  9. package/assets/env-proxy/nginx/snippets/mime-types.conf +98 -0
  10. package/assets/env-proxy/nginx/snippets/proxy-location.conf +17 -0
  11. package/assets/env-proxy/nginx/snippets/spa-location.conf +6 -0
  12. package/assets/env-proxy/nginx/snippets/uploads-location.conf +21 -0
  13. package/bin/run.js +40 -3
  14. package/dist/commands/app/autostart/disable.js +55 -0
  15. package/dist/commands/app/autostart/enable.js +55 -0
  16. package/dist/commands/app/autostart/list.js +37 -0
  17. package/dist/commands/app/autostart/run.js +84 -0
  18. package/dist/commands/app/autostart/shared.js +49 -0
  19. package/dist/commands/app/destroy.js +21 -12
  20. package/dist/commands/app/down.js +2 -2
  21. package/dist/commands/app/logs.js +2 -1
  22. package/dist/commands/app/restart.js +89 -24
  23. package/dist/commands/app/shared.js +3 -2
  24. package/dist/commands/app/start.js +142 -38
  25. package/dist/commands/app/stop.js +31 -2
  26. package/dist/commands/app/upgrade.js +9 -5
  27. package/dist/commands/config/delete.js +6 -1
  28. package/dist/commands/config/get.js +6 -1
  29. package/dist/commands/config/set.js +7 -2
  30. package/dist/commands/env/add.js +24 -44
  31. package/dist/commands/env/info.js +3 -2
  32. package/dist/commands/env/proxy/caddy.js +28 -0
  33. package/dist/commands/env/proxy/index.js +353 -0
  34. package/dist/commands/env/proxy/nginx.js +28 -0
  35. package/dist/commands/env/remove.js +112 -22
  36. package/dist/commands/env/shared.js +17 -9
  37. package/dist/commands/env/update.js +385 -21
  38. package/dist/commands/init.js +350 -98
  39. package/dist/commands/install.js +218 -75
  40. package/dist/commands/license/activate.js +63 -244
  41. package/dist/commands/license/plugins/shared.js +64 -13
  42. package/dist/commands/plugin/import.js +108 -0
  43. package/dist/commands/revision/create.js +89 -0
  44. package/dist/commands/source/test.js +13 -14
  45. package/dist/lib/app-health.js +5 -5
  46. package/dist/lib/app-managed-resources.js +24 -8
  47. package/dist/lib/app-public-path.js +80 -0
  48. package/dist/lib/app-runtime.js +10 -1
  49. package/dist/lib/auth-store.js +119 -4
  50. package/dist/lib/cli-config.js +191 -3
  51. package/dist/lib/cli-entry-error.js +8 -0
  52. package/dist/lib/command-log.js +284 -0
  53. package/dist/lib/docker-env-file.js +10 -2
  54. package/dist/lib/env-auth.js +4 -1
  55. package/dist/lib/env-command-config.js +45 -0
  56. package/dist/lib/env-config.js +7 -2
  57. package/dist/lib/env-guard.js +9 -10
  58. package/dist/lib/env-paths.js +101 -0
  59. package/dist/lib/env-proxy.js +1295 -0
  60. package/dist/lib/inquirer.js +4 -5
  61. package/dist/lib/managed-env-file.js +98 -0
  62. package/dist/lib/plugin-import.js +279 -0
  63. package/dist/lib/prompt-catalog-core.js +3 -2
  64. package/dist/lib/prompt-validators.js +14 -0
  65. package/dist/lib/prompt-web-ui.js +8 -1
  66. package/dist/lib/run-npm.js +56 -12
  67. package/dist/lib/skills-manager.js +3 -1
  68. package/dist/lib/source-publish.js +18 -1
  69. package/dist/lib/ui.js +2 -1
  70. package/dist/locale/en-US.json +116 -22
  71. package/dist/locale/zh-CN.json +113 -19
  72. package/package.json +5 -7
  73. package/scripts/build.mjs +34 -0
  74. package/scripts/clean.mjs +9 -0
  75. package/tsconfig.json +19 -0
  76. package/LICENSE.txt +0 -107
  77. package/README.zh-CN.md +0 -355
@@ -6,10 +6,12 @@
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 { fileURLToPath } from 'node:url';
9
10
  import { Command, Flags } from '@oclif/core';
10
11
  import { getCurrentEnvName } from '../../lib/auth-store.js';
11
12
  import { ensureCrossEnvConfirmed, hasExplicitEnvSelection } from '../../lib/env-guard.js';
12
- import { formatMissingManagedAppEnvMessage, resolveManagedAppRuntime, runLocalNocoBaseCommand, } from '../../lib/app-runtime.js';
13
+ import { formatMissingManagedAppEnvMessage, managedAppLifecycleEnvVars, resolveManagedAppRuntime, runLocalNocoBaseCommand, } from '../../lib/app-runtime.js';
14
+ import { resolveProjectCwd, runNocoBaseCommand } from '../../lib/run-npm.js';
13
15
  import { announceTargetEnv, failTask, isInteractiveTerminal, printInfo, startTask, succeedTask } from '../../lib/ui.js';
14
16
  import { builtinDbContainerName, removeDockerContainerIfExists } from './shared.js';
15
17
  function formatStopFailure(envName, message) {
@@ -26,6 +28,33 @@ function formatStopCrossEnvConfirmationRequiredMessage(currentEnv, requestedEnv)
26
28
  'Re-run the command with `--yes` to confirm this one-off cross-env stop, or switch the current env first.',
27
29
  ].join('\n');
28
30
  }
31
+ function isMissingManagedLocalProjectError(message) {
32
+ return (message.includes('The specified --cwd does not exist:') ||
33
+ message.includes('The specified --cwd is not a directory:') ||
34
+ message.includes("Couldn't find a NocoBase source project from --cwd:"));
35
+ }
36
+ async function stopLocalRuntimeWithFallback(runtime, options) {
37
+ const env = managedAppLifecycleEnvVars();
38
+ try {
39
+ await runLocalNocoBaseCommand(runtime, ['pm2', 'kill'], {
40
+ env,
41
+ stdio: options.stdio,
42
+ });
43
+ return;
44
+ }
45
+ catch (error) {
46
+ const message = error instanceof Error ? error.message : String(error);
47
+ if (!isMissingManagedLocalProjectError(message)) {
48
+ throw error;
49
+ }
50
+ }
51
+ const cliProjectCwd = resolveProjectCwd(fileURLToPath(new URL('.', import.meta.url)));
52
+ await runNocoBaseCommand(['pm2', 'kill'], {
53
+ cwd: cliProjectCwd,
54
+ env,
55
+ stdio: options.stdio,
56
+ });
57
+ }
29
58
  export default class AppStop extends Command {
30
59
  static hidden = false;
31
60
  static description = 'Stop NocoBase for the selected env. Local npm/git installs stop the app process, and Docker installs remove the saved app container.';
@@ -121,7 +150,7 @@ export default class AppStop extends Command {
121
150
  else {
122
151
  startTask(`Stopping NocoBase for "${runtime.envName}"...`);
123
152
  try {
124
- await runLocalNocoBaseCommand(runtime, ['pm2', 'kill'], {
153
+ await stopLocalRuntimeWithFallback(runtime, {
125
154
  stdio: commandStdio,
126
155
  });
127
156
  succeedTask(`NocoBase has stopped for "${runtime.envName}".`);
@@ -13,6 +13,7 @@ import { ensureCrossEnvConfirmed, hasExplicitEnvSelection } from '../../lib/env-
13
13
  import { DEFAULT_DOCKER_REGISTRY } from "../../lib/docker-image.js";
14
14
  import { confirm } from "../../lib/inquirer.js";
15
15
  import { announceTargetEnv, isInteractiveTerminal, printInfo, printWarning, succeedTask } from '../../lib/ui.js';
16
+ import { resolveAppUrlFromApiBaseUrl } from '../env/shared.js';
16
17
  function trimValue(value) {
17
18
  return String(value ?? '').trim();
18
19
  }
@@ -25,15 +26,16 @@ function formatAppUrl(port) {
25
26
  return value ? `http://127.0.0.1:${value}` : undefined;
26
27
  }
27
28
  function formatDisplayUrl(apiBaseUrl, appPort) {
29
+ const resolvedFromApiBaseUrl = resolveAppUrlFromApiBaseUrl(apiBaseUrl);
30
+ if (resolvedFromApiBaseUrl) {
31
+ return resolvedFromApiBaseUrl;
32
+ }
28
33
  const appUrl = formatAppUrl(appPort);
29
34
  if (appUrl) {
30
35
  return appUrl;
31
36
  }
32
37
  const value = trimValue(apiBaseUrl);
33
- if (!value) {
34
- return undefined;
35
- }
36
- return value.replace(/\/api\/?$/, '');
38
+ return value ? value.replace(/\/api\/?$/, '') : undefined;
37
39
  }
38
40
  function readEnvValue(env, key) {
39
41
  return trimValue(env.config[key]);
@@ -493,8 +495,10 @@ export default class AppUpgrade extends Command {
493
495
  });
494
496
  }
495
497
  await runWithSuppressedTargetEnvLog(async () => {
498
+ const startArgv = buildManagedActionArgv(runtime.envName, parsed, { quickstart: true });
499
+ startArgv.push('--no-sync-licensed-plugins');
496
500
  await runWithSuppressedStartSuccessLog(async () => {
497
- await runCommand('app:start', buildManagedActionArgv(runtime.envName, parsed, { quickstart: true }));
501
+ await runCommand('app:start', startArgv);
498
502
  });
499
503
  });
500
504
  if (resolvedVersion.persistDownloadVersion) {
@@ -14,12 +14,17 @@ export default class ConfigDelete extends Command {
14
14
  static examples = [
15
15
  '<%= config.bin %> <%= command.id %> locale',
16
16
  '<%= config.bin %> <%= command.id %> update.policy',
17
- '<%= config.bin %> <%= command.id %> license.pkg-url',
18
17
  '<%= config.bin %> <%= command.id %> docker.network',
19
18
  '<%= config.bin %> <%= command.id %> docker.container-prefix',
20
19
  '<%= config.bin %> <%= command.id %> bin.docker',
20
+ '<%= config.bin %> <%= command.id %> bin.caddy',
21
21
  '<%= config.bin %> <%= command.id %> bin.git',
22
+ '<%= config.bin %> <%= command.id %> bin.nginx',
23
+ '<%= config.bin %> <%= command.id %> proxy.nb-cli-root',
24
+ '<%= config.bin %> <%= command.id %> proxy.upstream-host',
22
25
  '<%= config.bin %> <%= command.id %> bin.yarn',
26
+ '<%= config.bin %> <%= command.id %> log.enabled',
27
+ '<%= config.bin %> <%= command.id %> log.retention-days',
23
28
  ];
24
29
  static args = {
25
30
  key: Args.string({
@@ -13,12 +13,17 @@ export default class ConfigGet extends Command {
13
13
  static examples = [
14
14
  '<%= config.bin %> <%= command.id %> locale',
15
15
  '<%= config.bin %> <%= command.id %> update.policy',
16
- '<%= config.bin %> <%= command.id %> license.pkg-url',
17
16
  '<%= config.bin %> <%= command.id %> docker.network',
18
17
  '<%= config.bin %> <%= command.id %> docker.container-prefix',
19
18
  '<%= config.bin %> <%= command.id %> bin.docker',
19
+ '<%= config.bin %> <%= command.id %> bin.caddy',
20
20
  '<%= config.bin %> <%= command.id %> bin.git',
21
+ '<%= config.bin %> <%= command.id %> bin.nginx',
22
+ '<%= config.bin %> <%= command.id %> proxy.nb-cli-root',
23
+ '<%= config.bin %> <%= command.id %> proxy.upstream-host',
21
24
  '<%= config.bin %> <%= command.id %> bin.yarn',
25
+ '<%= config.bin %> <%= command.id %> log.enabled',
26
+ '<%= config.bin %> <%= command.id %> log.retention-days',
22
27
  ];
23
28
  static args = {
24
29
  key: Args.string({
@@ -11,16 +11,21 @@ import { assertSupportedCliConfigKey, setCliConfigValue } from '../../lib/cli-co
11
11
  import { clearLegacyStartupUpdatePolicyForCurrentInstall } from '../../lib/startup-update.js';
12
12
  export default class ConfigSet extends Command {
13
13
  static summary = 'Set a CLI configuration value';
14
- static description = 'Set a supported CLI configuration key. Supported keys: locale, update.policy, license.pkg-url, docker.network, docker.container-prefix, bin.docker, bin.git, bin.yarn.';
14
+ static description = 'Set a CLI configuration value for a supported configuration key.';
15
15
  static examples = [
16
16
  '<%= config.bin %> <%= command.id %> locale zh-CN',
17
17
  '<%= config.bin %> <%= command.id %> update.policy prompt',
18
- '<%= config.bin %> <%= command.id %> license.pkg-url https://pkg.nocobase.com/',
19
18
  '<%= config.bin %> <%= command.id %> docker.network nocobase',
20
19
  '<%= config.bin %> <%= command.id %> docker.container-prefix nb',
21
20
  '<%= config.bin %> <%= command.id %> bin.docker /usr/local/bin/docker',
21
+ '<%= config.bin %> <%= command.id %> bin.caddy /usr/bin/caddy',
22
22
  '<%= config.bin %> <%= command.id %> bin.git /usr/bin/git',
23
+ '<%= config.bin %> <%= command.id %> bin.nginx /usr/sbin/nginx',
24
+ '<%= config.bin %> <%= command.id %> proxy.nb-cli-root /workspace',
25
+ '<%= config.bin %> <%= command.id %> proxy.upstream-host host.docker.internal',
23
26
  '<%= config.bin %> <%= command.id %> bin.yarn yarn',
27
+ '<%= config.bin %> <%= command.id %> log.enabled false',
28
+ '<%= config.bin %> <%= command.id %> log.retention-days 14',
24
29
  ];
25
30
  static args = {
26
31
  key: Args.string({
@@ -9,44 +9,12 @@
9
9
  import { Args, Command, Flags } from '@oclif/core';
10
10
  import { setCurrentEnv, upsertEnv } from '../../lib/auth-store.js';
11
11
  import { resolveDefaultConfigScope } from '../../lib/cli-home.js';
12
- import { buildStoredEnvConfig, } from '../../lib/env-config.js';
12
+ import { ENV_BOOLEAN_CONFIG_FLAG_MAP, ENV_STRING_CONFIG_FLAG_MAP } from '../../lib/env-command-config.js';
13
+ import { buildStoredEnvConfig } from '../../lib/env-config.js';
13
14
  import { runPromptCatalog, } from '../../lib/prompt-catalog.js';
14
15
  import { applyCliLocale, CLI_LOCALE_FLAG_DESCRIPTION, CLI_LOCALE_FLAG_OPTIONS, localeText, } from '../../lib/cli-locale.js';
15
16
  import { validateApiBaseUrl } from '../../lib/prompt-validators.js';
16
17
  import { printInfo, printStage, printSuccess, printVerbose, setVerboseMode } from '../../lib/ui.js';
17
- const ENV_RUNTIME_FLAG_MAP = {
18
- source: 'source',
19
- 'download-version': 'downloadVersion',
20
- 'docker-registry': 'dockerRegistry',
21
- 'docker-platform': 'dockerPlatform',
22
- 'git-url': 'gitUrl',
23
- 'npm-registry': 'npmRegistry',
24
- 'app-root-path': 'appRootPath',
25
- 'storage-path': 'storagePath',
26
- 'app-port': 'appPort',
27
- 'app-key': 'appKey',
28
- timezone: 'timezone',
29
- 'db-dialect': 'dbDialect',
30
- 'builtin-db-image': 'builtinDbImage',
31
- 'db-host': 'dbHost',
32
- 'db-port': 'dbPort',
33
- 'db-database': 'dbDatabase',
34
- 'db-user': 'dbUser',
35
- 'db-password': 'dbPassword',
36
- 'db-schema': 'dbSchema',
37
- 'db-table-prefix': 'dbTablePrefix',
38
- 'root-username': 'rootUsername',
39
- 'root-email': 'rootEmail',
40
- 'root-password': 'rootPassword',
41
- 'root-nickname': 'rootNickname',
42
- };
43
- const ENV_BOOLEAN_RUNTIME_FLAG_MAP = {
44
- 'builtin-db': 'builtinDb',
45
- 'dev-dependencies': 'devDependencies',
46
- build: 'build',
47
- 'build-dts': 'buildDts',
48
- 'db-underscored': 'dbUnderscored',
49
- };
50
18
  const envAddText = (key, values) => localeText(`commands.envAdd.${key}`, values);
51
19
  const envAddAccessTokenPrompt = {
52
20
  type: 'text',
@@ -182,14 +150,28 @@ export default class EnvAdd extends Command {
182
150
  hidden: true,
183
151
  description: 'Whether declaration files were emitted during build for this env',
184
152
  }),
153
+ 'app-path': Flags.string({
154
+ hidden: true,
155
+ description: 'App path saved with this env',
156
+ }),
185
157
  'app-root-path': Flags.string({
186
158
  hidden: true,
159
+ deprecated: true,
187
160
  description: 'Application root path saved with this env',
188
161
  }),
189
162
  'storage-path': Flags.string({
190
163
  hidden: true,
164
+ deprecated: true,
191
165
  description: 'Storage path saved with this env',
192
166
  }),
167
+ 'app-public-path': Flags.string({
168
+ hidden: true,
169
+ description: 'Application public path saved with this env',
170
+ }),
171
+ 'env-file': Flags.string({
172
+ hidden: true,
173
+ description: 'Docker env file saved with this env',
174
+ }),
193
175
  'app-port': Flags.string({
194
176
  hidden: true,
195
177
  description: 'Application HTTP port saved with this env',
@@ -283,17 +265,17 @@ export default class EnvAdd extends Command {
283
265
  type: 'select',
284
266
  message: envAddText('prompts.authType.message'),
285
267
  options: [
286
- {
287
- value: 'basic',
288
- label: envAddText('prompts.authType.basicLabel'),
289
- hint: envAddText('prompts.authType.basicHint'),
290
- },
291
268
  {
292
269
  value: 'oauth',
293
270
  label: envAddText('prompts.authType.oauthLabel'),
294
271
  hint: envAddText('prompts.authType.oauthHint'),
295
272
  },
296
273
  { value: 'token', label: envAddText('prompts.authType.tokenLabel') },
274
+ {
275
+ value: 'basic',
276
+ label: envAddText('prompts.authType.basicLabel'),
277
+ hint: envAddText('prompts.authType.basicHint'),
278
+ },
297
279
  ],
298
280
  initialValue: 'oauth',
299
281
  required: true,
@@ -360,20 +342,18 @@ export default class EnvAdd extends Command {
360
342
  }
361
343
  buildEnvConfig(results, flags) {
362
344
  const authType = String(results.authType ?? '').trim();
363
- const authUsername = authType === 'basic'
364
- ? String(results.username ?? flags.username ?? '').trim()
365
- : '';
345
+ const authUsername = authType === 'basic' ? String(results.username ?? flags.username ?? '').trim() : '';
366
346
  const envConfigInput = {
367
347
  apiBaseUrl: results.apiBaseUrl,
368
348
  authType,
369
349
  authUsername: authUsername || undefined,
370
350
  accessToken: results.accessToken,
371
351
  };
372
- for (const [flagName, configKey] of Object.entries(ENV_RUNTIME_FLAG_MAP)) {
352
+ for (const [flagName, configKey] of Object.entries(ENV_STRING_CONFIG_FLAG_MAP)) {
373
353
  const value = flags[flagName];
374
354
  envConfigInput[configKey] = value;
375
355
  }
376
- for (const [flagName, configKey] of Object.entries(ENV_BOOLEAN_RUNTIME_FLAG_MAP)) {
356
+ for (const [flagName, configKey] of Object.entries(ENV_BOOLEAN_CONFIG_FLAG_MAP)) {
377
357
  const value = flags[flagName];
378
358
  envConfigInput[configKey] = value;
379
359
  }
@@ -10,7 +10,7 @@ import { Args, Command, Flags } from '@oclif/core';
10
10
  import { formatMissingManagedAppEnvMessage, resolveManagedAppRuntime } from '../../lib/app-runtime.js';
11
11
  import { resolveBuiltinDbConnection } from '../../lib/builtin-db.js';
12
12
  import { renderTable } from '../../lib/ui.js';
13
- import { appRootPath, appUrl, dbStatus, runtimeStatus, storagePath } from './shared.js';
13
+ import { appPath, appUrl, dbStatus, runtimeStatus, sourcePath, storagePath } from './shared.js';
14
14
  const MISSING_FIELD = Symbol('missingField');
15
15
  const FORBIDDEN_FIELD_PATH_SEGMENTS = new Set(['__proto__', 'constructor', 'prototype']);
16
16
  function normalizeJsonValue(value) {
@@ -120,7 +120,8 @@ export default class EnvInfo extends Command {
120
120
  const dbDialect = builtinDbConnection?.dbDialect ?? runtime.env.config.dbDialect;
121
121
  const appGroup = {
122
122
  url: appUrl(runtime),
123
- appRootPath: appRootPath(runtime),
123
+ appPath: appPath(runtime),
124
+ sourcePath: sourcePath(runtime),
124
125
  storagePath: storagePath(runtime),
125
126
  appPort: runtime.env.config.appPort,
126
127
  appStatus: await runtimeStatus(runtime),
@@ -0,0 +1,28 @@
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 } from '@oclif/core';
10
+ import { createEnvProxyCaddyFlags, ENV_PROXY_NAME_ARG, runEnvProxyCommand } from './index.js';
11
+ export default class EnvProxyCaddy extends Command {
12
+ static summary = 'Generate Caddy proxy files for one managed env';
13
+ static examples = [
14
+ '<%= config.bin %> <%= command.id %>',
15
+ '<%= config.bin %> <%= command.id %> --env app1',
16
+ '<%= config.bin %> <%= command.id %> --env app1 --host a.local.nocobase.com --port 8080',
17
+ '<%= config.bin %> <%= command.id %> --env app1 --install --reload',
18
+ '<%= config.bin %> <%= command.id %> --env app1 --print',
19
+ ];
20
+ static args = {
21
+ name: ENV_PROXY_NAME_ARG,
22
+ };
23
+ static flags = createEnvProxyCaddyFlags();
24
+ async run() {
25
+ const { args, flags } = await this.parse(EnvProxyCaddy);
26
+ await runEnvProxyCommand(this, args, flags, 'caddy');
27
+ }
28
+ }