@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
@@ -8,6 +8,7 @@
8
8
  */
9
9
  import { Command, Flags } from '@oclif/core';
10
10
  import pc from 'picocolors';
11
+ import crypto from 'node:crypto';
11
12
  import { existsSync } from 'node:fs';
12
13
  import path from 'node:path';
13
14
  import { stdin as stdinStream, stdout as stdoutStream } from 'node:process';
@@ -15,9 +16,9 @@ import { getEnv, upsertEnv } from "../lib/auth-store.js";
15
16
  import { runPromptCatalog, } from "../lib/prompt-catalog.js";
16
17
  import { applyCliLocale, localeText, translateCli } from "../lib/cli-locale.js";
17
18
  import { resolveDefaultConfigScope } from '../lib/cli-home.js';
18
- import { runPromptCatalogWebUI, } from "../lib/prompt-web-ui.js";
19
+ import { runPromptCatalogWebUI } from "../lib/prompt-web-ui.js";
19
20
  import { validateApiBaseUrl, validateEnvKey } from "../lib/prompt-validators.js";
20
- import { inspectSkillsStatus, installNocoBaseSkills, updateNocoBaseSkills, } from '../lib/skills-manager.js';
21
+ import { installNocoBaseSkills, isNpmRegistryUnavailable } from '../lib/skills-manager.js';
21
22
  import { omitKeys, pickKeys } from "../lib/object-utils.js";
22
23
  import { printInfo, printStage, printVerbose, printWarning } from '../lib/ui.js';
23
24
  import Download from "./download.js";
@@ -33,6 +34,8 @@ const INIT_ENV_ADD_FLAG_NAMES = [
33
34
  'auth-type',
34
35
  'access-token',
35
36
  'token',
37
+ 'username',
38
+ 'password',
36
39
  'skip-auth',
37
40
  ];
38
41
  const initText = (key, values) => localeText(`commands.init.${key}`, values);
@@ -51,8 +54,8 @@ function existingAppOnly(def) {
51
54
  function newInstallOnly(def) {
52
55
  return withExtraHidden(def, (values) => values.hasNocobase !== 'no');
53
56
  }
54
- function downloadInNewInstallOnly(def) {
55
- return withExtraHidden(def, (values) => values.hasNocobase !== 'no' || values.fetchSource !== true);
57
+ function newInstallDownloadExecutionOnly(def) {
58
+ return withExtraHidden(def, (values) => values.hasNocobase !== 'no' || values.skipDownload === true);
56
59
  }
57
60
  function argvHasToken(argv, tokens) {
58
61
  return tokens.some((token) => argv.includes(token));
@@ -65,9 +68,7 @@ function resolveInitDownloadVersion(results) {
65
68
  return preset;
66
69
  }
67
70
  function initVersionPromptValue(version) {
68
- return version === 'latest' || version === 'beta' || version === 'alpha'
69
- ? version
70
- : 'other';
71
+ return version === 'latest' || version === 'beta' || version === 'alpha' ? version : 'other';
71
72
  }
72
73
  function yesInitialValue(def, fallback) {
73
74
  if ('yesInitialValue' in def && def.yesInitialValue !== undefined) {
@@ -76,8 +77,7 @@ function yesInitialValue(def, fallback) {
76
77
  return fallback;
77
78
  }
78
79
  function hasDownloadOverride(flags) {
79
- return Boolean(String(flags.source ?? '').trim()
80
- || String(flags.version ?? '').trim());
80
+ return Boolean(String(flags.source ?? '').trim() || String(flags.version ?? '').trim());
81
81
  }
82
82
  function explicitApiBaseUrlFlag(flags) {
83
83
  return String(flags['api-base-url'] ?? '').trim();
@@ -85,6 +85,16 @@ function explicitApiBaseUrlFlag(flags) {
85
85
  function explicitDbHostFlag(flags) {
86
86
  return String(flags['db-host'] ?? '').trim();
87
87
  }
88
+ function optionalInitString(value) {
89
+ const text = String(value ?? '').trim();
90
+ return text || undefined;
91
+ }
92
+ function resolveManagedAppKey(value) {
93
+ return optionalInitString(value) ?? crypto.randomBytes(32).toString('hex');
94
+ }
95
+ function resolveManagedTimeZone(value) {
96
+ return optionalInitString(value) ?? (Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC');
97
+ }
88
98
  function shouldAllowExistingInitEnv() {
89
99
  return argvHasToken(process.argv.slice(2), ['--force', '-f']);
90
100
  }
@@ -125,9 +135,7 @@ function formatSkippedAppNameRequiredMessage() {
125
135
  ].join('\n');
126
136
  }
127
137
  function shellQuoteArg(value) {
128
- return /^[A-Za-z0-9_@%+=:,./-]+$/.test(value)
129
- ? value
130
- : `'${value.replace(/'/g, `'\\''`)}'`;
138
+ return /^[A-Za-z0-9_@%+=:,./-]+$/.test(value) ? value : `'${value.replace(/'/g, `'\\''`)}'`;
131
139
  }
132
140
  function initTitle() {
133
141
  return 'Set up NocoBase';
@@ -234,20 +242,27 @@ Prompt modes:
234
242
  validate: validateApiBaseUrl,
235
243
  }),
236
244
  authType: existingAppOnly(EnvAdd.prompts.authType),
245
+ username: existingAppOnly(EnvAdd.prompts.username),
246
+ password: existingAppOnly(EnvAdd.prompts.password),
237
247
  accessToken: existingAppOnly(EnvAdd.prompts.accessToken),
238
248
  lang: newInstallOnly(Install.appPrompts.lang),
239
249
  appRootPath: newInstallOnly(Install.appPrompts.appRootPath),
240
250
  appPort: newInstallOnly(Install.appPrompts.appPort),
241
251
  storagePath: newInstallOnly(Install.appPrompts.storagePath),
242
- fetchSource: newInstallOnly(Install.appPrompts.fetchSource),
243
- source: downloadInNewInstallOnly(Download.prompts.source),
244
- version: downloadInNewInstallOnly(Download.prompts.version),
245
- otherVersion: downloadInNewInstallOnly(Download.prompts.otherVersion),
246
- dockerRegistry: downloadInNewInstallOnly(Download.prompts.dockerRegistry),
247
- dockerPlatform: downloadInNewInstallOnly(Download.prompts.dockerPlatform),
248
- dockerSave: downloadInNewInstallOnly(Download.prompts.dockerSave),
249
- gitUrl: downloadInNewInstallOnly(Download.prompts.gitUrl),
250
- outputDir: downloadInNewInstallOnly({
252
+ skipDownload: newInstallOnly({
253
+ type: 'boolean',
254
+ message: initText('prompts.skipDownload.message'),
255
+ initialValue: false,
256
+ yesInitialValue: false,
257
+ }),
258
+ source: newInstallOnly(Download.prompts.source),
259
+ version: newInstallOnly(Download.prompts.version),
260
+ otherVersion: newInstallOnly(Download.prompts.otherVersion),
261
+ dockerRegistry: newInstallOnly(Download.prompts.dockerRegistry),
262
+ dockerPlatform: newInstallOnly(Download.prompts.dockerPlatform),
263
+ dockerSave: newInstallDownloadExecutionOnly(Download.prompts.dockerSave),
264
+ gitUrl: newInstallOnly(Download.prompts.gitUrl),
265
+ outputDir: newInstallDownloadExecutionOnly({
251
266
  ...DOWNLOAD_OUTPUT_DIR_PROMPT,
252
267
  hidden: (values) => {
253
268
  const source = String(values.source ?? '').trim();
@@ -268,11 +283,11 @@ Prompt modes:
268
283
  return typeof initialValue === 'function' ? initialValue(values) : String(initialValue ?? '');
269
284
  },
270
285
  }),
271
- npmRegistry: downloadInNewInstallOnly(Download.prompts.npmRegistry),
272
- replace: downloadInNewInstallOnly(Download.prompts.replace),
273
- devDependencies: downloadInNewInstallOnly(Download.prompts.devDependencies),
274
- build: downloadInNewInstallOnly(Download.prompts.build),
275
- buildDts: downloadInNewInstallOnly(Download.prompts.buildDts),
286
+ npmRegistry: newInstallOnly(Download.prompts.npmRegistry),
287
+ replace: newInstallDownloadExecutionOnly(Download.prompts.replace),
288
+ devDependencies: newInstallDownloadExecutionOnly(Download.prompts.devDependencies),
289
+ build: newInstallDownloadExecutionOnly(Download.prompts.build),
290
+ buildDts: newInstallDownloadExecutionOnly(Download.prompts.buildDts),
276
291
  dbDialect: newInstallOnly(Install.dbPrompts.dbDialect),
277
292
  builtinDb: newInstallOnly(Install.dbPrompts.builtinDb),
278
293
  builtinDbImage: newInstallOnly(Install.dbPrompts.builtinDbImage),
@@ -281,23 +296,36 @@ Prompt modes:
281
296
  dbDatabase: newInstallOnly(Install.dbPrompts.dbDatabase),
282
297
  dbUser: newInstallOnly(Install.dbPrompts.dbUser),
283
298
  dbPassword: newInstallOnly(Install.dbPrompts.dbPassword),
299
+ dbSchema: newInstallOnly(Install.dbPrompts.dbSchema),
300
+ dbTablePrefix: newInstallOnly(Install.dbPrompts.dbTablePrefix),
301
+ dbUnderscored: newInstallOnly(Install.dbPrompts.dbUnderscored),
284
302
  rootUsername: newInstallOnly(Install.rootUserPrompts.rootUsername),
285
303
  rootEmail: newInstallOnly(Install.rootUserPrompts.rootEmail),
286
304
  rootPassword: newInstallOnly(Install.rootUserPrompts.rootPassword),
287
305
  rootNickname: newInstallOnly(Install.rootUserPrompts.rootNickname),
288
306
  };
289
307
  buildPromptCatalog(flags) {
290
- if (!flags['skip-auth']) {
291
- return Init.prompts;
292
- }
293
- const accessTokenPrompt = {
294
- ...EnvAdd.prompts.accessToken,
295
- hidden: () => true,
296
- };
297
- return {
308
+ const prompts = {
298
309
  ...Init.prompts,
299
- accessToken: existingAppOnly(accessTokenPrompt),
300
310
  };
311
+ if (flags['skip-auth']) {
312
+ const accessTokenPrompt = {
313
+ ...EnvAdd.prompts.accessToken,
314
+ hidden: () => true,
315
+ };
316
+ const usernamePrompt = {
317
+ ...EnvAdd.prompts.username,
318
+ hidden: () => true,
319
+ };
320
+ const passwordPrompt = {
321
+ ...EnvAdd.prompts.password,
322
+ hidden: () => true,
323
+ };
324
+ prompts.username = existingAppOnly(usernamePrompt);
325
+ prompts.password = existingAppOnly(passwordPrompt);
326
+ prompts.accessToken = existingAppOnly(accessTokenPrompt);
327
+ }
328
+ return prompts;
301
329
  }
302
330
  parsedFlagsForPromptSeeds;
303
331
  static flags = {
@@ -319,7 +347,7 @@ Prompt modes:
319
347
  default: false,
320
348
  }),
321
349
  'skip-skills': Flags.boolean({
322
- description: 'Skip installing or updating NocoBase AI coding skills during init',
350
+ description: 'Skip installing NocoBase AI coding skills during init',
323
351
  default: false,
324
352
  }),
325
353
  'ui-host': Flags.string({
@@ -344,15 +372,14 @@ Prompt modes:
344
372
  if (normalizedFlags.ui && normalizedFlags.yes) {
345
373
  this.error('--ui cannot be used with --yes.');
346
374
  }
347
- if (normalizedFlags['skip-auth']
348
- && (normalizedFlags['access-token'] !== undefined || normalizedFlags.token !== undefined)) {
375
+ if (normalizedFlags['skip-auth'] &&
376
+ (normalizedFlags['access-token'] !== undefined || normalizedFlags.token !== undefined)) {
349
377
  this.error('--skip-auth cannot be used with --access-token or --token.');
350
378
  }
351
379
  if (normalizedFlags.ui && normalizedFlags.resume) {
352
380
  this.error('--ui cannot be used with --resume.');
353
381
  }
354
- if (!normalizedFlags.ui &&
355
- (normalizedFlags['ui-host'] !== undefined || normalizedFlags['ui-port'] !== undefined)) {
382
+ if (!normalizedFlags.ui && (normalizedFlags['ui-host'] !== undefined || normalizedFlags['ui-port'] !== undefined)) {
356
383
  this.error('--ui-host and --ui-port require --ui.');
357
384
  }
358
385
  if (normalizedFlags.resume) {
@@ -454,8 +481,17 @@ Prompt modes:
454
481
  command: this,
455
482
  });
456
483
  const normalizedResults = {
484
+ ...pickKeys(presetValues, [
485
+ 'authType',
486
+ 'accessToken',
487
+ 'dbSchema',
488
+ 'dbTablePrefix',
489
+ 'dbUnderscored',
490
+ 'skipAuth',
491
+ 'username',
492
+ 'password',
493
+ ]),
457
494
  ...results,
458
- ...pickKeys(presetValues, ['dbSchema', 'dbTablePrefix', 'dbUnderscored', 'skipAuth']),
459
495
  };
460
496
  const hasNocobase = normalizedResults.hasNocobase === 'yes';
461
497
  const existingEnv = !hasNocobase
@@ -510,9 +546,7 @@ Prompt modes:
510
546
  }
511
547
  }
512
548
  const downloadSeed = { ...presetValues };
513
- if (flags.yes
514
- && !Object.prototype.hasOwnProperty.call(downloadSeed, 'source')
515
- && downloadSeed.fetchSource !== false) {
549
+ if (flags.yes && !Object.prototype.hasOwnProperty.call(downloadSeed, 'source')) {
516
550
  downloadSeed.source = 'docker';
517
551
  }
518
552
  const dbInitial = await Install.buildDbPromptInitialValues({
@@ -544,6 +578,8 @@ Prompt modes:
544
578
  catalog: {
545
579
  apiBaseUrl: c.apiBaseUrl,
546
580
  authType: c.authType,
581
+ username: c.username,
582
+ password: c.password,
547
583
  accessToken: c.accessToken,
548
584
  },
549
585
  },
@@ -555,7 +591,7 @@ Prompt modes:
555
591
  appRootPath: c.appRootPath,
556
592
  appPort: c.appPort,
557
593
  storagePath: c.storagePath,
558
- fetchSource: c.fetchSource,
594
+ skipDownload: c.skipDownload,
559
595
  },
560
596
  },
561
597
  {
@@ -589,6 +625,9 @@ Prompt modes:
589
625
  dbDatabase: c.dbDatabase,
590
626
  dbUser: c.dbUser,
591
627
  dbPassword: c.dbPassword,
628
+ dbSchema: c.dbSchema,
629
+ dbTablePrefix: c.dbTablePrefix,
630
+ dbUnderscored: c.dbUnderscored,
592
631
  },
593
632
  },
594
633
  {
@@ -614,8 +653,7 @@ Prompt modes:
614
653
  preset.hasNocobase = 'yes';
615
654
  preset.apiBaseUrl = apiBaseUrl;
616
655
  }
617
- else if (flags['default-api-base-url'] !== undefined
618
- && String(flags['default-api-base-url']).trim() !== '') {
656
+ else if (flags['default-api-base-url'] !== undefined && String(flags['default-api-base-url']).trim() !== '') {
619
657
  preset.apiBaseUrl = String(flags['default-api-base-url']).trim();
620
658
  }
621
659
  if (flags['auth-type'] !== undefined && String(flags['auth-type']).trim() !== '') {
@@ -628,6 +666,12 @@ Prompt modes:
628
666
  if (flags['access-token'] !== undefined || flags.token !== undefined) {
629
667
  preset.accessToken = accessToken;
630
668
  }
669
+ if (flags.username !== undefined) {
670
+ preset.username = String(flags.username ?? '').trim();
671
+ }
672
+ if (flags.password !== undefined) {
673
+ preset.password = String(flags.password ?? '');
674
+ }
631
675
  if (flags.lang !== undefined && String(flags.lang).trim() !== '') {
632
676
  preset.lang = String(flags.lang).trim();
633
677
  }
@@ -683,8 +727,15 @@ Prompt modes:
683
727
  if (argvHasToken(argv, ['--db-underscored', '--no-db-underscored'])) {
684
728
  preset.dbUnderscored = Boolean(flags['db-underscored']);
685
729
  }
686
- if (argvHasToken(argv, ['--fetch-source'])) {
687
- preset.fetchSource = Boolean(flags['fetch-source']);
730
+ if (argvHasToken(argv, ['--skip-download'])) {
731
+ preset.skipDownload = Boolean(flags['skip-download']);
732
+ if (preset.skipDownload) {
733
+ preset.dockerSave = false;
734
+ preset.replace = false;
735
+ preset.devDependencies = false;
736
+ preset.build = false;
737
+ preset.buildDts = false;
738
+ }
688
739
  }
689
740
  if (flags.source !== undefined && String(flags.source).trim() !== '') {
690
741
  preset.source = String(flags.source).trim();
@@ -747,25 +798,23 @@ Prompt modes:
747
798
  }
748
799
  try {
749
800
  logInitStage('Syncing agent skills');
750
- const status = await inspectSkillsStatus();
751
- if (!status.installed) {
752
- printVerbose('Installing NocoBase agent skills (nb skills install)');
753
- await installNocoBaseSkills();
754
- printInfo('Agent skills ready.');
755
- return;
756
- }
757
- printVerbose('Updating NocoBase agent skills (nb skills update)');
758
- await updateNocoBaseSkills();
801
+ await installNocoBaseSkills();
759
802
  printInfo('Agent skills ready.');
760
803
  }
761
804
  catch (error) {
762
805
  const message = error instanceof Error ? error.message : String(error);
806
+ if (isNpmRegistryUnavailable(error)) {
807
+ printWarning(translateCli('commands.init.messages.skillsSyncRegistryUnavailable'));
808
+ printVerbose(`Skipped agent skills sync because the npm registry was unavailable: ${message}`);
809
+ return;
810
+ }
763
811
  this.error(pc.red(`Skills sync failed: ${message}`));
764
812
  this.exit(1);
765
813
  }
766
814
  }
767
815
  async persistManagedEnvConfig(results, flags = {}) {
768
816
  const envName = String(results.appName ?? DEFAULT_INIT_APP_NAME).trim() || DEFAULT_INIT_APP_NAME;
817
+ const existingEnv = await getEnv(envName, { scope: resolveDefaultConfigScope() });
769
818
  const appPort = String(results.appPort ?? '').trim();
770
819
  const source = String(results.source ?? '').trim();
771
820
  const version = resolveInitDownloadVersion(results);
@@ -786,12 +835,18 @@ Prompt modes:
786
835
  const dbTablePrefix = String(results.dbTablePrefix ?? '').trim();
787
836
  const apiBaseUrl = String(results.apiBaseUrl ?? '').trim();
788
837
  const authType = String(results.authType ?? '').trim() || 'oauth';
838
+ const authUsername = authType === 'basic' ? String(results.username ?? results.rootUsername ?? '').trim() : '';
789
839
  const accessToken = String(results.accessToken ?? '');
840
+ const skipDownload = results.skipDownload === true;
841
+ const appKey = resolveManagedAppKey(results.appKey ?? existingEnv?.config.appKey);
842
+ const timeZone = resolveManagedTimeZone(results.timeZone ?? existingEnv?.config.timezone);
790
843
  const builtinDb = explicitDbHostFlag(flags)
791
844
  ? false
792
845
  : results.builtinDb === undefined
793
846
  ? undefined
794
847
  : Boolean(results.builtinDb);
848
+ results.appKey = appKey;
849
+ results.timeZone = timeZone;
795
850
  await upsertEnv(envName, {
796
851
  ...(source === 'docker'
797
852
  ? { kind: 'docker' }
@@ -802,7 +857,8 @@ Prompt modes:
802
857
  : {}),
803
858
  ...(apiBaseUrl ? { apiBaseUrl } : appPort ? { apiBaseUrl: `http://127.0.0.1:${appPort}/api` } : {}),
804
859
  ...(authType ? { authType } : {}),
805
- ...(authType === 'token' && accessToken ? { accessToken } : {}),
860
+ ...(authUsername ? { authUsername } : {}),
861
+ ...((authType === 'token' || authType === 'basic') && accessToken ? { accessToken } : {}),
806
862
  ...(source ? { source } : {}),
807
863
  ...(version ? { downloadVersion: version } : {}),
808
864
  ...(dockerRegistry ? { dockerRegistry } : {}),
@@ -812,9 +868,13 @@ Prompt modes:
812
868
  ...(appRootPath ? { appRootPath } : {}),
813
869
  ...(storagePath ? { storagePath } : {}),
814
870
  ...(appPort ? { appPort } : {}),
815
- ...(results.devDependencies !== undefined ? { devDependencies: Boolean(results.devDependencies) } : {}),
816
- ...(results.build !== undefined ? { build: Boolean(results.build) } : {}),
817
- ...(results.buildDts !== undefined ? { buildDts: Boolean(results.buildDts) } : {}),
871
+ ...(appKey ? { appKey } : {}),
872
+ ...(timeZone ? { timezone: timeZone } : {}),
873
+ ...(!skipDownload && results.devDependencies !== undefined
874
+ ? { devDependencies: Boolean(results.devDependencies) }
875
+ : {}),
876
+ ...(!skipDownload && results.build !== undefined ? { build: Boolean(results.build) } : {}),
877
+ ...(!skipDownload && results.buildDts !== undefined ? { buildDts: Boolean(results.buildDts) } : {}),
818
878
  ...(builtinDb !== undefined ? { builtinDb } : {}),
819
879
  ...(dbDialect ? { dbDialect } : {}),
820
880
  ...(builtinDbImage || builtinDb === false ? { builtinDbImage: builtinDbImage || undefined } : {}),
@@ -834,12 +894,20 @@ Prompt modes:
834
894
  argv.push('--api-base-url', String(results.apiBaseUrl ?? DEFAULT_INIT_API_BASE_URL));
835
895
  argv.push('--auth-type', String(results.authType ?? 'oauth'));
836
896
  const accessToken = String(results.accessToken ?? '');
897
+ const username = String(results.username ?? '').trim();
898
+ const password = String(results.password ?? '');
837
899
  if (results.skipAuth === true) {
838
900
  argv.push('--skip-auth');
839
901
  }
840
902
  else if (results.authType === 'token' && accessToken) {
841
903
  argv.push('--access-token', accessToken);
842
904
  }
905
+ if (results.authType === 'basic' && username) {
906
+ argv.push('--username', username);
907
+ }
908
+ if (results.authType === 'basic' && results.skipAuth !== true && password) {
909
+ argv.push('--password', password);
910
+ }
843
911
  return argv;
844
912
  }
845
913
  buildInstallArgv(results, flags, options) {
@@ -851,15 +919,18 @@ Prompt modes:
851
919
  const processArgv = process.argv.slice(2);
852
920
  const envName = String(results.appName ?? DEFAULT_INIT_APP_NAME).trim() || DEFAULT_INIT_APP_NAME;
853
921
  const source = String(results.source ?? '').trim();
922
+ const skipDownload = Boolean(flags['skip-download']) || results.skipDownload === true;
854
923
  const hasNocobase = String(results.hasNocobase ?? '').trim() === 'yes';
855
924
  const apiBaseUrl = String(results.apiBaseUrl ?? '').trim();
856
925
  const authType = String(results.authType ?? '').trim();
857
926
  const accessToken = String(results.accessToken ?? '');
927
+ const username = String(results.username ?? flags.username ?? '').trim();
928
+ const password = String(results.password ?? flags.password ?? '');
858
929
  argv.push('--env', envName);
859
930
  if (options?.resume) {
860
931
  argv.push('--resume');
861
932
  }
862
- if (Boolean(flags.verbose)) {
933
+ if (flags.verbose) {
863
934
  argv.push('--verbose');
864
935
  }
865
936
  if (hasNocobase && apiBaseUrl) {
@@ -874,6 +945,12 @@ Prompt modes:
874
945
  if (authType === 'token' && accessToken) {
875
946
  argv.push('--access-token', accessToken);
876
947
  }
948
+ if (authType === 'basic' && username) {
949
+ argv.push('--username', username);
950
+ }
951
+ if (authType === 'basic' && password) {
952
+ argv.push('--password', password);
953
+ }
877
954
  const lang = String(results.lang ?? '').trim();
878
955
  if (lang) {
879
956
  argv.push('--lang', lang);
@@ -890,54 +967,56 @@ Prompt modes:
890
967
  if (storagePath) {
891
968
  argv.push('--storage-path', storagePath);
892
969
  }
893
- if (Boolean(flags.force)) {
970
+ if (flags.force) {
894
971
  argv.push('--force');
895
972
  }
896
- if (Boolean(results.fetchSource)) {
897
- argv.push('--fetch-source');
898
- if (source) {
899
- argv.push('--source', source);
900
- }
901
- const version = resolveInitDownloadVersion(results);
902
- if (version) {
903
- argv.push('--version', version);
904
- }
973
+ if (source) {
974
+ argv.push('--source', source);
975
+ }
976
+ const version = resolveInitDownloadVersion(results);
977
+ if (version) {
978
+ argv.push('--version', version);
979
+ }
980
+ const gitUrl = String(results.gitUrl ?? '').trim();
981
+ if (gitUrl) {
982
+ argv.push('--git-url', gitUrl);
983
+ }
984
+ const dockerRegistry = String(results.dockerRegistry ?? '').trim();
985
+ if (dockerRegistry) {
986
+ argv.push('--docker-registry', dockerRegistry);
987
+ }
988
+ const dockerPlatform = String(results.dockerPlatform ?? '').trim();
989
+ if (dockerPlatform) {
990
+ argv.push('--docker-platform', dockerPlatform);
991
+ }
992
+ const npmRegistry = String(results.npmRegistry ?? '').trim();
993
+ if (npmRegistry) {
994
+ argv.push('--npm-registry', npmRegistry);
995
+ }
996
+ if (skipDownload) {
997
+ argv.push('--skip-download');
998
+ }
999
+ else {
905
1000
  const outputDir = String(results.outputDir ?? '').trim();
906
1001
  if (outputDir) {
907
1002
  argv.push('--output-dir', outputDir);
908
1003
  }
909
- const gitUrl = String(results.gitUrl ?? '').trim();
910
- if (gitUrl) {
911
- argv.push('--git-url', gitUrl);
912
- }
913
- const dockerRegistry = String(results.dockerRegistry ?? '').trim();
914
- if (dockerRegistry) {
915
- argv.push('--docker-registry', dockerRegistry);
916
- }
917
- const dockerPlatform = String(results.dockerPlatform ?? '').trim();
918
- if (dockerPlatform) {
919
- argv.push('--docker-platform', dockerPlatform);
920
- }
921
- const npmRegistry = String(results.npmRegistry ?? '').trim();
922
- if (npmRegistry) {
923
- argv.push('--npm-registry', npmRegistry);
924
- }
925
- if (Boolean(results.replace)) {
1004
+ if (results.replace) {
926
1005
  argv.push('--replace');
927
1006
  }
928
- if (Boolean(results.devDependencies)) {
1007
+ if (results.devDependencies) {
929
1008
  argv.push('--dev-dependencies');
930
1009
  }
931
- if (Boolean(results.dockerSave)) {
1010
+ if (results.dockerSave) {
932
1011
  argv.push('--docker-save');
933
1012
  }
934
- if (results.build !== undefined && !Boolean(results.build)) {
1013
+ if (results.build !== undefined && !results.build) {
935
1014
  argv.push('--no-build');
936
1015
  }
937
1016
  else if (argvHasToken(processArgv, ['--build', '--no-build']) && flags.build === false) {
938
1017
  argv.push('--no-build');
939
1018
  }
940
- if (Boolean(results.buildDts)) {
1019
+ if (results.buildDts) {
941
1020
  argv.push('--build-dts');
942
1021
  }
943
1022
  }
@@ -965,9 +1044,9 @@ Prompt modes:
965
1044
  const dbPortWasProvided = argvHasToken(processArgv, ['--db-port']);
966
1045
  const dockerBuiltinDbPortIsHidden = builtinDb && source === 'docker';
967
1046
  const dbDefaultPort = defaultDbPortForDialect(dbDialect);
968
- if (dbPort
969
- && (!dockerBuiltinDbPortIsHidden || dbPortWasProvided)
970
- && (!flags.yes || dbPortWasProvided || dbPort !== dbDefaultPort)) {
1047
+ if (dbPort &&
1048
+ (!dockerBuiltinDbPortIsHidden || dbPortWasProvided) &&
1049
+ (!flags.yes || dbPortWasProvided || dbPort !== dbDefaultPort)) {
971
1050
  argv.push('--db-port', dbPort);
972
1051
  }
973
1052
  const dbDatabase = String(results.dbDatabase ?? '').trim();
@@ -991,7 +1070,7 @@ Prompt modes:
991
1070
  argv.push('--db-table-prefix', dbTablePrefix);
992
1071
  }
993
1072
  if (results.dbUnderscored !== undefined) {
994
- argv.push(Boolean(results.dbUnderscored) ? '--db-underscored' : '--no-db-underscored');
1073
+ argv.push(results.dbUnderscored ? '--db-underscored' : '--no-db-underscored');
995
1074
  }
996
1075
  const rootUsername = String(results.rootUsername ?? '').trim();
997
1076
  if (rootUsername) {
@@ -1013,50 +1092,54 @@ Prompt modes:
1013
1092
  }
1014
1093
  buildManagedInstallResumeCommand(results, flags) {
1015
1094
  const argv = ['nb', 'init'];
1016
- if (Boolean(flags.yes)) {
1095
+ if (flags.yes) {
1017
1096
  argv.push('--yes');
1018
1097
  }
1019
1098
  const envName = String(results.appName ?? DEFAULT_INIT_APP_NAME).trim() || DEFAULT_INIT_APP_NAME;
1020
1099
  argv.push('--env', envName);
1021
- if (Boolean(results.fetchSource)) {
1022
- const source = String(results.source ?? '').trim();
1023
- if (source) {
1024
- argv.push('--source', source);
1025
- }
1026
- const version = resolveInitDownloadVersion(results);
1027
- if (version) {
1028
- argv.push('--version', version);
1029
- }
1100
+ const source = String(results.source ?? '').trim();
1101
+ const skipDownload = Boolean(flags['skip-download']) || results.skipDownload === true;
1102
+ if (source) {
1103
+ argv.push('--source', source);
1104
+ }
1105
+ const version = resolveInitDownloadVersion(results);
1106
+ if (version) {
1107
+ argv.push('--version', version);
1108
+ }
1109
+ const gitUrl = String(results.gitUrl ?? '').trim();
1110
+ if (gitUrl) {
1111
+ argv.push('--git-url', gitUrl);
1112
+ }
1113
+ const dockerRegistry = String(results.dockerRegistry ?? '').trim();
1114
+ if (dockerRegistry) {
1115
+ argv.push('--docker-registry', dockerRegistry);
1116
+ }
1117
+ const dockerPlatform = String(results.dockerPlatform ?? '').trim();
1118
+ if (dockerPlatform) {
1119
+ argv.push('--docker-platform', dockerPlatform);
1120
+ }
1121
+ const npmRegistry = String(results.npmRegistry ?? '').trim();
1122
+ if (npmRegistry) {
1123
+ argv.push('--npm-registry', npmRegistry);
1124
+ }
1125
+ if (skipDownload) {
1126
+ argv.push('--skip-download');
1127
+ }
1128
+ else {
1030
1129
  const outputDir = String(results.outputDir ?? '').trim();
1031
1130
  if (outputDir && outputDir !== String(results.appRootPath ?? '').trim()) {
1032
1131
  argv.push('--output-dir', outputDir);
1033
1132
  }
1034
- const gitUrl = String(results.gitUrl ?? '').trim();
1035
- if (gitUrl) {
1036
- argv.push('--git-url', gitUrl);
1037
- }
1038
- const dockerRegistry = String(results.dockerRegistry ?? '').trim();
1039
- if (dockerRegistry) {
1040
- argv.push('--docker-registry', dockerRegistry);
1041
- }
1042
- const dockerPlatform = String(results.dockerPlatform ?? '').trim();
1043
- if (dockerPlatform) {
1044
- argv.push('--docker-platform', dockerPlatform);
1045
- }
1046
- const npmRegistry = String(results.npmRegistry ?? '').trim();
1047
- if (npmRegistry) {
1048
- argv.push('--npm-registry', npmRegistry);
1049
- }
1050
- if (Boolean(results.devDependencies)) {
1133
+ if (results.devDependencies) {
1051
1134
  argv.push('--dev-dependencies');
1052
1135
  }
1053
- if (Boolean(results.dockerSave)) {
1136
+ if (results.dockerSave) {
1054
1137
  argv.push('--docker-save');
1055
1138
  }
1056
- if (results.build !== undefined && !Boolean(results.build)) {
1139
+ if (results.build !== undefined && !results.build) {
1057
1140
  argv.push('--no-build');
1058
1141
  }
1059
- if (Boolean(results.buildDts)) {
1142
+ if (results.buildDts) {
1060
1143
  argv.push('--build-dts');
1061
1144
  }
1062
1145
  }
@@ -1065,11 +1148,7 @@ Prompt modes:
1065
1148
  }
1066
1149
  formatManagedInstallFailureMessage(message, results, flags) {
1067
1150
  const command = this.buildManagedInstallResumeCommand(results, flags);
1068
- return [
1069
- message,
1070
- '',
1071
- translateCli('commands.init.messages.resumeAfterInstallFailure', { command }),
1072
- ].join('\n');
1151
+ return [message, '', translateCli('commands.init.messages.resumeAfterInstallFailure', { command })].join('\n');
1073
1152
  }
1074
1153
  buildResumeInstallArgv(flags) {
1075
1154
  const preset = this.buildPresetValuesFromFlags(flags);
@@ -1080,10 +1159,9 @@ Prompt modes:
1080
1159
  preset.rootPassword ??= yesInitialValue(Install.rootUserPrompts.rootPassword, 'admin123');
1081
1160
  preset.rootNickname ??= yesInitialValue(Install.rootUserPrompts.rootNickname, 'Super Admin');
1082
1161
  }
1083
- if (hasDownloadOverride(flags)) {
1084
- preset.fetchSource ??= true;
1162
+ if (!flags['skip-download']) {
1163
+ preset.replace ??= true;
1085
1164
  }
1086
- preset.replace ??= true;
1087
1165
  return this.buildInstallArgv(preset, flags, {
1088
1166
  nonInteractive: Boolean(flags.yes),
1089
1167
  resume: true,