@nocobase/cli 2.1.0-beta.37 → 2.1.0-beta.38
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.
- package/README.md +19 -7
- package/README.zh-CN.md +19 -7
- package/dist/commands/app/destroy.js +225 -0
- package/dist/commands/app/down.js +24 -254
- package/dist/commands/app/shared.js +122 -0
- package/dist/commands/app/start.js +40 -59
- package/dist/commands/app/stop.js +72 -26
- package/dist/commands/app/upgrade.js +310 -427
- package/dist/commands/db/start.js +23 -8
- package/dist/commands/license/plugins/shared.js +9 -3
- package/dist/commands/license/plugins/sync.js +54 -25
- package/dist/commands/source/download.js +29 -25
- package/dist/generated/command-registry.js +3 -2
- package/dist/lib/api-client.js +6 -0
- package/dist/lib/api-command-compat.js +641 -0
- package/dist/lib/app-health.js +27 -21
- package/dist/lib/env-guard.js +1 -1
- package/dist/lib/generated-command.js +17 -0
- package/dist/lib/skills-manager.js +6 -0
- package/dist/lib/ui.js +4 -1
- package/dist/locale/en-US.json +51 -1
- package/dist/locale/zh-CN.json +51 -1
- package/package.json +34 -2
|
@@ -7,8 +7,9 @@
|
|
|
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 { formatMissingManagedAppEnvMessage, startDockerContainer
|
|
11
|
-
import {
|
|
10
|
+
import { formatMissingManagedAppEnvMessage, startDockerContainer } from '../../lib/app-runtime.js';
|
|
11
|
+
import { ensureBuiltinDbReady } from '../../lib/app-managed-resources.js';
|
|
12
|
+
import { announceTargetEnv, failTask, startTask, succeedTask, updateTask } from '../../lib/ui.js';
|
|
12
13
|
import { formatUnmanagedDbMessage, resolveDbRuntime } from './shared.js';
|
|
13
14
|
function formatDbStartFailure(envName, message) {
|
|
14
15
|
if (/does not exist/i.test(message)) {
|
|
@@ -45,6 +46,7 @@ export default class DbStart extends Command {
|
|
|
45
46
|
async run() {
|
|
46
47
|
const { flags } = await this.parse(DbStart);
|
|
47
48
|
const requestedEnv = flags.env?.trim() || undefined;
|
|
49
|
+
const verbose = Boolean(flags.verbose);
|
|
48
50
|
const runtime = await resolveDbRuntime(requestedEnv);
|
|
49
51
|
if (!runtime) {
|
|
50
52
|
this.error(formatMissingManagedAppEnvMessage(requestedEnv));
|
|
@@ -55,12 +57,25 @@ export default class DbStart extends Command {
|
|
|
55
57
|
announceTargetEnv(runtime.envName);
|
|
56
58
|
startTask(`Starting the built-in database for "${runtime.envName}"...`);
|
|
57
59
|
try {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
try {
|
|
61
|
+
const state = await startDockerContainer(runtime.containerName, {
|
|
62
|
+
stdio: verbose ? 'inherit' : 'ignore',
|
|
63
|
+
});
|
|
64
|
+
succeedTask(state === 'already-running'
|
|
65
|
+
? `The built-in database is already running for "${runtime.envName}"${runtime.address ? ` at ${runtime.address}` : ''}.`
|
|
66
|
+
: `The built-in database is running for "${runtime.envName}"${runtime.address ? ` at ${runtime.address}` : ''}.`);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
70
|
+
if (!/does not exist/i.test(message)) {
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
updateTask(`Restoring the built-in database for "${runtime.envName}"...`);
|
|
74
|
+
await ensureBuiltinDbReady(runtime.appRuntime, {
|
|
75
|
+
verbose,
|
|
76
|
+
});
|
|
77
|
+
succeedTask(`The built-in database is running for "${runtime.envName}"${runtime.address ? ` at ${runtime.address}` : ''}.`);
|
|
78
|
+
}
|
|
64
79
|
}
|
|
65
80
|
catch (error) {
|
|
66
81
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -11,8 +11,14 @@ import { access, mkdir, rm } from 'node:fs/promises';
|
|
|
11
11
|
import { Readable } from 'node:stream';
|
|
12
12
|
import { createGunzip } from 'node:zlib';
|
|
13
13
|
import * as tar from 'tar';
|
|
14
|
-
import { removeStoragePluginSymlink, resolvePluginStoragePath
|
|
15
|
-
import { parseLicenseKey, readSavedLicenseKey, resolveLicensePkgUrl
|
|
14
|
+
import { removeStoragePluginSymlink, resolvePluginStoragePath } from '../../../lib/plugin-storage.js';
|
|
15
|
+
import { parseLicenseKey, readSavedLicenseKey, resolveLicensePkgUrl } from '../shared.js';
|
|
16
|
+
export class MissingSavedLicenseKeyError extends Error {
|
|
17
|
+
constructor(envName) {
|
|
18
|
+
super(`No saved license key was found for env "${envName}". Run \`nb license activate\` first.`);
|
|
19
|
+
this.name = 'MissingSavedLicenseKeyError';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
16
22
|
async function resolvePkgBaseUrl(pkgUrl) {
|
|
17
23
|
return await resolveLicensePkgUrl(pkgUrl);
|
|
18
24
|
}
|
|
@@ -54,7 +60,7 @@ async function loginPkg(baseURL, keyData) {
|
|
|
54
60
|
export async function loadSavedLicenseKeyData(runtime) {
|
|
55
61
|
const licenseKey = await readSavedLicenseKey(runtime);
|
|
56
62
|
if (!licenseKey) {
|
|
57
|
-
throw new
|
|
63
|
+
throw new MissingSavedLicenseKeyError(runtime.envName);
|
|
58
64
|
}
|
|
59
65
|
return parseLicenseKey(licenseKey);
|
|
60
66
|
}
|
|
@@ -10,10 +10,10 @@ import { Command, Flags } from '@oclif/core';
|
|
|
10
10
|
import pc from 'picocolors';
|
|
11
11
|
import { readFile } from 'node:fs/promises';
|
|
12
12
|
import path from 'node:path';
|
|
13
|
-
import { DEFAULT_DOCKER_REGISTRY, DEFAULT_DOCKER_VERSION, resolveDockerImageRef
|
|
13
|
+
import { DEFAULT_DOCKER_REGISTRY, DEFAULT_DOCKER_VERSION, resolveDockerImageRef } from "../../../lib/docker-image.js";
|
|
14
14
|
import { ensureCrossEnvConfirmed, hasExplicitEnvSelection } from '../../../lib/env-guard.js';
|
|
15
|
-
import { createLicenseEnvFlag, licenseJsonFlag, licensePkgUrlFlag, licenseYesFlag, requireLicenseRuntime, } from '../shared.js';
|
|
16
|
-
import { syncLicensedPlugins } from './shared.js';
|
|
15
|
+
import { createLicenseEnvFlag, licenseJsonFlag, licensePkgUrlFlag, licenseYesFlag, readSavedLicenseKey, requireLicenseRuntime, } from '../shared.js';
|
|
16
|
+
import { MissingSavedLicenseKeyError, syncLicensedPlugins } from './shared.js';
|
|
17
17
|
import { resolvePluginStoragePath } from '../../../lib/plugin-storage.js';
|
|
18
18
|
import { commandOutput } from '../../../lib/run-npm.js';
|
|
19
19
|
import { announceTargetEnv, startTask, stopTask, succeedTask, updateTask } from '../../../lib/ui.js';
|
|
@@ -93,12 +93,7 @@ async function resolveDockerAppVersion(runtime) {
|
|
|
93
93
|
defaultRegistry: DEFAULT_DOCKER_REGISTRY,
|
|
94
94
|
defaultVersion: DEFAULT_DOCKER_VERSION,
|
|
95
95
|
});
|
|
96
|
-
const args = [
|
|
97
|
-
'run',
|
|
98
|
-
'--rm',
|
|
99
|
-
'--network',
|
|
100
|
-
runtime.workspaceName,
|
|
101
|
-
];
|
|
96
|
+
const args = ['run', '--rm', '--network', runtime.workspaceName];
|
|
102
97
|
const dockerPlatform = normalizeDockerPlatform(config.dockerPlatform);
|
|
103
98
|
if (dockerPlatform) {
|
|
104
99
|
args.push('--platform', dockerPlatform);
|
|
@@ -130,6 +125,16 @@ async function resolveManagedAppVersion(runtime) {
|
|
|
130
125
|
}
|
|
131
126
|
throw new Error(`Env "${runtime.envName}" does not support automatic app version detection.`);
|
|
132
127
|
}
|
|
128
|
+
function buildNoLicenseSkipPayload(runtime, dryRun) {
|
|
129
|
+
return {
|
|
130
|
+
ok: true,
|
|
131
|
+
env: runtime.envName,
|
|
132
|
+
kind: runtime.kind,
|
|
133
|
+
dryRun,
|
|
134
|
+
status: 'skipped',
|
|
135
|
+
skipReason: 'no-license-key',
|
|
136
|
+
};
|
|
137
|
+
}
|
|
133
138
|
export default class LicensePluginsSync extends Command {
|
|
134
139
|
static summary = 'Synchronize commercial plugins for the selected env';
|
|
135
140
|
static description = 'Synchronize the commercial plugins allowed by the current saved license key.';
|
|
@@ -150,6 +155,10 @@ export default class LicensePluginsSync extends Command {
|
|
|
150
155
|
version: Flags.string({
|
|
151
156
|
description: 'Registry version or dist-tag to synchronize. Defaults to the current workspace version.',
|
|
152
157
|
}),
|
|
158
|
+
'skip-if-no-license': Flags.boolean({
|
|
159
|
+
description: 'Skip without error when this env does not have a saved license key',
|
|
160
|
+
default: false,
|
|
161
|
+
}),
|
|
153
162
|
verbose: Flags.boolean({
|
|
154
163
|
description: 'Show detailed per-plugin sync logs',
|
|
155
164
|
default: false,
|
|
@@ -174,7 +183,17 @@ export default class LicensePluginsSync extends Command {
|
|
|
174
183
|
if (!flags.json) {
|
|
175
184
|
announceTargetEnv(runtime.envName);
|
|
176
185
|
}
|
|
177
|
-
|
|
186
|
+
if (flags['skip-if-no-license']) {
|
|
187
|
+
const savedLicenseKey = await readSavedLicenseKey(runtime);
|
|
188
|
+
if (!savedLicenseKey) {
|
|
189
|
+
const payload = buildNoLicenseSkipPayload(runtime, Boolean(flags['dry-run']));
|
|
190
|
+
if (flags.json) {
|
|
191
|
+
this.log(JSON.stringify(payload, null, 2));
|
|
192
|
+
}
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
const version = trimValue(flags.version) || (await resolveManagedAppVersion(runtime));
|
|
178
197
|
const registryVersion = normalizePluginRegistryVersion(version);
|
|
179
198
|
const shouldStreamLogs = !flags.json && Boolean(flags.verbose);
|
|
180
199
|
const pluginStoragePath = resolvePluginStoragePath(runtime.env.storagePath);
|
|
@@ -210,20 +229,32 @@ export default class LicensePluginsSync extends Command {
|
|
|
210
229
|
}
|
|
211
230
|
let result;
|
|
212
231
|
try {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
232
|
+
try {
|
|
233
|
+
result = await syncLicensedPlugins(runtime, {
|
|
234
|
+
pkgUrl: flags['pkg-url'],
|
|
235
|
+
version: registryVersion,
|
|
236
|
+
dryRun: Boolean(flags['dry-run']),
|
|
237
|
+
onProgress: shouldStreamLogs
|
|
238
|
+
? async (detail) => {
|
|
239
|
+
this.log(`${formatActionLabel(detail.action)} ${pc.bold(detail.packageName)}`);
|
|
240
|
+
this.log(pc.dim(` output: ${detail.outputDir}`));
|
|
241
|
+
if (detail.warning) {
|
|
242
|
+
this.log(pc.yellow(` warning: ${detail.warning}`));
|
|
243
|
+
}
|
|
223
244
|
}
|
|
245
|
+
: undefined,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
if (flags['skip-if-no-license'] && error instanceof MissingSavedLicenseKeyError) {
|
|
250
|
+
const payload = buildNoLicenseSkipPayload(runtime, Boolean(flags['dry-run']));
|
|
251
|
+
if (flags.json) {
|
|
252
|
+
this.log(JSON.stringify(payload, null, 2));
|
|
224
253
|
}
|
|
225
|
-
|
|
226
|
-
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
throw error;
|
|
257
|
+
}
|
|
227
258
|
}
|
|
228
259
|
finally {
|
|
229
260
|
if (loadingTimer) {
|
|
@@ -250,9 +281,7 @@ export default class LicensePluginsSync extends Command {
|
|
|
250
281
|
return;
|
|
251
282
|
}
|
|
252
283
|
if (loadingStarted) {
|
|
253
|
-
succeedTask(flags['dry-run']
|
|
254
|
-
? 'Commercial plugin sync preview is ready.'
|
|
255
|
-
: 'Commercial plugin sync completed.');
|
|
284
|
+
succeedTask(flags['dry-run'] ? 'Commercial plugin sync preview is ready.' : 'Commercial plugin sync completed.');
|
|
256
285
|
}
|
|
257
286
|
if (!flags.verbose) {
|
|
258
287
|
const changes = [];
|
|
@@ -70,6 +70,9 @@ function downloadSourceLabel(source) {
|
|
|
70
70
|
return source;
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
+
function downloadActionLabel(flags) {
|
|
74
|
+
return flags.replace ? 'Source refresh' : 'Download';
|
|
75
|
+
}
|
|
73
76
|
function normalizeDockerPlatform(value) {
|
|
74
77
|
const text = String(value ?? '').trim();
|
|
75
78
|
if (text === 'linux/amd64' || text === 'linux/arm64') {
|
|
@@ -228,7 +231,7 @@ export default class SourceDownload extends Command {
|
|
|
228
231
|
'npm-registry': Flags.string({
|
|
229
232
|
description: 'npm registry for npm/git downloads and dependency installation.',
|
|
230
233
|
}),
|
|
231
|
-
|
|
234
|
+
build: Flags.boolean({
|
|
232
235
|
allowNo: true,
|
|
233
236
|
description: 'Build npm/git source after dependencies are installed.',
|
|
234
237
|
default: true,
|
|
@@ -347,7 +350,8 @@ export default class SourceDownload extends Command {
|
|
|
347
350
|
message: downloadText('prompts.outputDir.message'),
|
|
348
351
|
placeholder: downloadText('prompts.outputDir.placeholder'),
|
|
349
352
|
initialValue: (values) => {
|
|
350
|
-
const version = resolveVersionFromResults(values, DEFAULT_DOWNLOAD_VERSION) ||
|
|
353
|
+
const version = resolveVersionFromResults(values, DEFAULT_DOWNLOAD_VERSION) ||
|
|
354
|
+
DEFAULT_DOWNLOAD_VERSION;
|
|
351
355
|
return defaultOutputDirForVersion(version);
|
|
352
356
|
},
|
|
353
357
|
required: true,
|
|
@@ -467,8 +471,7 @@ export default class SourceDownload extends Command {
|
|
|
467
471
|
initialValues.dockerPlatform = normalizeDockerPlatform(flags['docker-platform']);
|
|
468
472
|
initialValues.dockerSave = flags['docker-save'];
|
|
469
473
|
if (flags['npm-registry'] !== undefined) {
|
|
470
|
-
initialValues.npmRegistry =
|
|
471
|
-
typeof flags['npm-registry'] === 'string' ? flags['npm-registry'] : '';
|
|
474
|
+
initialValues.npmRegistry = typeof flags['npm-registry'] === 'string' ? flags['npm-registry'] : '';
|
|
472
475
|
}
|
|
473
476
|
for (const key of Object.keys(preset)) {
|
|
474
477
|
if (Object.prototype.hasOwnProperty.call(initialValues, key)) {
|
|
@@ -536,7 +539,7 @@ export default class SourceDownload extends Command {
|
|
|
536
539
|
return preset;
|
|
537
540
|
}
|
|
538
541
|
resolveEffectiveBuild(source, results, flags) {
|
|
539
|
-
if (source === 'npm' && !
|
|
542
|
+
if (source === 'npm' && !results.devDependencies) {
|
|
540
543
|
return false;
|
|
541
544
|
}
|
|
542
545
|
if (source === 'npm' || source === 'git') {
|
|
@@ -554,34 +557,29 @@ export default class SourceDownload extends Command {
|
|
|
554
557
|
? String(results.outputDir).trim() || undefined
|
|
555
558
|
: flags['output-dir']?.trim() || undefined;
|
|
556
559
|
const replace = results.replace !== undefined ? Boolean(results.replace) : flags.replace;
|
|
557
|
-
const gitUrl = results.gitUrl !== undefined
|
|
558
|
-
? String(results.gitUrl).trim() || undefined
|
|
559
|
-
: flags['git-url']?.trim() || undefined;
|
|
560
|
+
const gitUrl = results.gitUrl !== undefined ? String(results.gitUrl).trim() || undefined : flags['git-url']?.trim() || undefined;
|
|
560
561
|
const dockerRegistry = source === 'docker'
|
|
561
|
-
?
|
|
562
|
+
? results.dockerRegistry !== undefined
|
|
562
563
|
? String(results.dockerRegistry).trim() || undefined
|
|
563
|
-
: flags['docker-registry']?.trim() || defaultDockerRegistryForLang(flags.locale ?? process.env.NB_LOCALE)
|
|
564
|
+
: flags['docker-registry']?.trim() || defaultDockerRegistryForLang(flags.locale ?? process.env.NB_LOCALE)
|
|
564
565
|
: undefined;
|
|
565
566
|
const dockerPlatform = source === 'docker'
|
|
566
|
-
? normalizeDockerPlatform(results.dockerPlatform !== undefined
|
|
567
|
-
? results.dockerPlatform
|
|
568
|
-
: flags['docker-platform'])
|
|
567
|
+
? normalizeDockerPlatform(results.dockerPlatform !== undefined ? results.dockerPlatform : flags['docker-platform'])
|
|
569
568
|
: undefined;
|
|
570
569
|
const dockerSave = source === 'docker'
|
|
571
570
|
? results.dockerSave !== undefined
|
|
572
571
|
? Boolean(results.dockerSave)
|
|
573
572
|
: flags['docker-save']
|
|
574
573
|
: false;
|
|
575
|
-
const npmRegistryRaw = results.npmRegistry !== undefined
|
|
576
|
-
? String(results.npmRegistry)
|
|
577
|
-
: flags['npm-registry'] ?? '';
|
|
574
|
+
const npmRegistryRaw = results.npmRegistry !== undefined ? String(results.npmRegistry) : flags['npm-registry'] ?? '';
|
|
578
575
|
const npmRegistry = npmRegistryRaw.trim() || undefined;
|
|
576
|
+
const npmDevDependencies = devDependencies ?? false;
|
|
579
577
|
return {
|
|
580
578
|
source,
|
|
581
579
|
version,
|
|
582
580
|
replace,
|
|
583
|
-
...(source === 'npm' ? { 'dev-dependencies':
|
|
584
|
-
|
|
581
|
+
...(source === 'npm' ? { 'dev-dependencies': npmDevDependencies } : {}),
|
|
582
|
+
build: effectiveBuild,
|
|
585
583
|
'build-dts': normalizeBuildDts(source, effectiveBuild, buildDtsWant),
|
|
586
584
|
'output-dir': outputDir,
|
|
587
585
|
'git-url': gitUrl,
|
|
@@ -772,7 +770,9 @@ export default class SourceDownload extends Command {
|
|
|
772
770
|
await fsp.mkdir(parentDir, { recursive: true });
|
|
773
771
|
const registryEnv = this.npmRegistryEnv(flags);
|
|
774
772
|
this.finishPreparationTask();
|
|
775
|
-
this.log(
|
|
773
|
+
this.log(flags.replace
|
|
774
|
+
? `Refreshing NocoBase source in ${projectRoot} from npm`
|
|
775
|
+
: `Creating NocoBase app "${appName}" from npm`);
|
|
776
776
|
await this.runExternalCommand('npx', npxArgs, {
|
|
777
777
|
...this.runOptionsWithCwd(parentDir, registryEnv),
|
|
778
778
|
errorName: 'npx create-nocobase-app',
|
|
@@ -795,7 +795,7 @@ export default class SourceDownload extends Command {
|
|
|
795
795
|
...(this.isVerbose() ? ['--verbose'] : []),
|
|
796
796
|
]);
|
|
797
797
|
}
|
|
798
|
-
this.log(
|
|
798
|
+
this.log(`${flags.replace ? 'NocoBase source' : 'NocoBase app'} is ready at ${projectRoot}`);
|
|
799
799
|
return projectRoot;
|
|
800
800
|
}
|
|
801
801
|
async downloadFromGit(flags) {
|
|
@@ -808,9 +808,13 @@ export default class SourceDownload extends Command {
|
|
|
808
808
|
gitArgs.push('--branch', branch);
|
|
809
809
|
gitArgs.push('--depth', '1', repoUrl, outputDir);
|
|
810
810
|
this.finishPreparationTask();
|
|
811
|
-
this.log(
|
|
812
|
-
?
|
|
813
|
-
|
|
811
|
+
this.log(flags.replace
|
|
812
|
+
? branch === versionSpec
|
|
813
|
+
? `Refreshing NocoBase source from ${repoUrl} (${branch})`
|
|
814
|
+
: `Refreshing NocoBase source from ${repoUrl} (${branch}, resolved from ${versionSpec})`
|
|
815
|
+
: branch === versionSpec
|
|
816
|
+
? `Cloning NocoBase from ${repoUrl} (${branch})`
|
|
817
|
+
: `Cloning NocoBase from ${repoUrl} (${branch}, resolved from ${versionSpec})`);
|
|
814
818
|
await this.runExternalCommand('git', gitArgs, {
|
|
815
819
|
errorName: 'git clone',
|
|
816
820
|
loadingMessage: 'Cloning the repository',
|
|
@@ -830,7 +834,7 @@ export default class SourceDownload extends Command {
|
|
|
830
834
|
...(this.isVerbose() ? ['--verbose'] : []),
|
|
831
835
|
]);
|
|
832
836
|
}
|
|
833
|
-
this.log(
|
|
837
|
+
this.log(`${flags.replace ? 'NocoBase source' : 'NocoBase app'} is ready at ${projectRoot}`);
|
|
834
838
|
return projectRoot;
|
|
835
839
|
}
|
|
836
840
|
async download() {
|
|
@@ -869,7 +873,7 @@ export default class SourceDownload extends Command {
|
|
|
869
873
|
async run() {
|
|
870
874
|
try {
|
|
871
875
|
const result = await this.download();
|
|
872
|
-
this.logProgress(
|
|
876
|
+
this.logProgress(`${downloadActionLabel(result.resolved)} completed via ${downloadSourceLabel(result.resolved.source)}.`);
|
|
873
877
|
return result;
|
|
874
878
|
}
|
|
875
879
|
catch (error) {
|
|
@@ -50,13 +50,14 @@ function readEnvName(argv) {
|
|
|
50
50
|
}
|
|
51
51
|
return undefined;
|
|
52
52
|
}
|
|
53
|
-
function createRuntimeCommand(operation) {
|
|
53
|
+
function createRuntimeCommand(operation, runtimeVersion) {
|
|
54
54
|
return class RuntimeCommand extends GeneratedApiCommand {
|
|
55
55
|
static summary = operation.summary;
|
|
56
56
|
static description = operation.description;
|
|
57
57
|
static examples = operation.examples;
|
|
58
58
|
static flags = createGeneratedFlags(operation);
|
|
59
59
|
static operation = operation;
|
|
60
|
+
static runtimeVersion = runtimeVersion;
|
|
60
61
|
};
|
|
61
62
|
}
|
|
62
63
|
function createRuntimeIndexCommand(commandId, metadata) {
|
|
@@ -122,7 +123,7 @@ const runtime = loadRuntimeSync(env?.runtime?.version);
|
|
|
122
123
|
for (const operation of runtime?.commands ?? []) {
|
|
123
124
|
const commandSegments = operation.commandId.split(' ');
|
|
124
125
|
const commandKey = commandSegments.join(':');
|
|
125
|
-
registry[`api:${commandKey}`] = createRuntimeCommand(operation);
|
|
126
|
+
registry[`api:${commandKey}`] = createRuntimeCommand(operation, runtime?.version);
|
|
126
127
|
for (const [topicCommandId, metadata] of getRuntimeTopicEntries(operation)) {
|
|
127
128
|
const topicKey = `api:${topicCommandId.split(' ').join(':')}`;
|
|
128
129
|
if (!registry[topicKey]) {
|
package/dist/lib/api-client.js
CHANGED
|
@@ -23,6 +23,8 @@ import { resolveServerRequestTarget } from './env-auth.js';
|
|
|
23
23
|
import { fetchWithPreservedAuthRedirect } from './http-request.js';
|
|
24
24
|
const CLI_REQUEST_SOURCE_HEADER = 'x-request-source';
|
|
25
25
|
const CLI_REQUEST_SOURCE_VALUE = 'cli';
|
|
26
|
+
const CLI_VERSION_HEADER = 'x-nb-cli-version';
|
|
27
|
+
const SKILLS_VERSION_HEADER = 'x-nb-skills-version';
|
|
26
28
|
function stripUtf8Bom(text) {
|
|
27
29
|
return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
|
|
28
30
|
}
|
|
@@ -209,6 +211,10 @@ export async function executeApiRequest(options) {
|
|
|
209
211
|
const { baseUrl, token } = await resolveServerRequestTarget(options);
|
|
210
212
|
const headers = new Headers();
|
|
211
213
|
headers.set(CLI_REQUEST_SOURCE_HEADER, CLI_REQUEST_SOURCE_VALUE);
|
|
214
|
+
headers.set(CLI_VERSION_HEADER, options.cliVersion);
|
|
215
|
+
if (options.skillsVersion) {
|
|
216
|
+
headers.set(SKILLS_VERSION_HEADER, options.skillsVersion);
|
|
217
|
+
}
|
|
212
218
|
if (token) {
|
|
213
219
|
headers.set('authorization', `Bearer ${token}`);
|
|
214
220
|
}
|