@nocobase/cli 2.1.0-alpha.25 → 2.1.0-alpha.27
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 +61 -49
- package/README.zh-CN.md +40 -47
- package/dist/commands/app/down.js +259 -0
- package/dist/commands/app/logs.js +98 -0
- package/dist/commands/app/restart.js +75 -0
- package/dist/commands/app/start.js +252 -0
- package/dist/commands/app/stop.js +98 -0
- package/dist/commands/app/upgrade.js +579 -0
- package/dist/commands/build.js +3 -48
- package/dist/commands/config/delete.js +30 -0
- package/dist/commands/config/get.js +29 -0
- package/dist/commands/config/index.js +20 -0
- package/dist/commands/config/list.js +29 -0
- package/dist/commands/config/set.js +35 -0
- package/dist/commands/db/check.js +230 -0
- package/dist/commands/db/shared.js +1 -1
- package/dist/commands/dev.js +3 -147
- package/dist/commands/down.js +3 -188
- package/dist/commands/download.js +4 -856
- package/dist/commands/env/add.js +28 -23
- package/dist/commands/env/info.js +152 -0
- package/dist/commands/env/list.js +23 -9
- package/dist/commands/env/shared.js +158 -0
- package/dist/commands/{prompts-stages.js → examples/prompts-stages.js} +3 -3
- package/dist/commands/{prompts-test.js → examples/prompts-test.js} +3 -3
- package/dist/commands/init.js +83 -6
- package/dist/commands/install.js +361 -82
- package/dist/commands/license/activate.js +357 -0
- package/dist/commands/license/env.js +94 -0
- package/dist/commands/license/generate-id.js +107 -0
- package/dist/commands/license/id.js +52 -0
- package/dist/commands/license/index.js +20 -0
- package/dist/commands/license/plugins/clean.js +98 -0
- package/dist/commands/license/plugins/index.js +20 -0
- package/dist/commands/license/plugins/list.js +50 -0
- package/dist/commands/license/plugins/shared.js +325 -0
- package/dist/commands/license/plugins/sync.js +267 -0
- package/dist/commands/license/shared.js +411 -0
- package/dist/commands/license/status.js +50 -0
- package/dist/commands/logs.js +3 -88
- package/dist/commands/plugin/disable.js +64 -0
- package/dist/commands/plugin/enable.js +64 -0
- package/dist/commands/plugin/list.js +62 -0
- package/dist/commands/pm/disable.js +3 -54
- package/dist/commands/pm/enable.js +3 -54
- package/dist/commands/pm/list.js +3 -52
- package/dist/commands/restart.js +3 -65
- package/dist/commands/scaffold/migration.js +1 -1
- package/dist/commands/scaffold/plugin.js +1 -1
- package/dist/commands/skills/remove.js +71 -0
- package/dist/commands/skills/update.js +7 -0
- package/dist/commands/source/build.js +58 -0
- package/dist/commands/source/dev.js +157 -0
- package/dist/commands/source/download.js +866 -0
- package/dist/commands/source/test.js +467 -0
- package/dist/commands/start.js +3 -209
- package/dist/commands/stop.js +3 -88
- package/dist/commands/test.js +3 -457
- package/dist/commands/upgrade.js +3 -585
- package/dist/help/runtime-help.js +3 -0
- package/dist/lib/api-client.js +94 -9
- package/dist/lib/app-health.js +126 -0
- package/dist/lib/app-managed-resources.js +264 -0
- package/dist/lib/app-runtime.js +26 -10
- package/dist/lib/auth-store.js +29 -63
- package/dist/lib/build-config.js +8 -0
- package/dist/lib/cli-config.js +176 -0
- package/dist/lib/cli-home.js +12 -26
- package/dist/lib/cli-locale.js +15 -1
- package/dist/lib/db-connection-check.js +178 -0
- package/dist/lib/env-config.js +80 -0
- package/dist/lib/generated-command.js +23 -3
- package/dist/lib/plugin-storage.js +127 -0
- package/dist/lib/prompt-validators.js +4 -4
- package/dist/lib/prompt-web-ui.js +13 -6
- package/dist/lib/runtime-generator.js +89 -10
- package/dist/lib/self-manager.js +57 -2
- package/dist/lib/skills-manager.js +34 -7
- package/dist/lib/startup-update.js +85 -7
- package/dist/locale/en-US.json +16 -13
- package/dist/locale/zh-CN.json +16 -13
- package/nocobase-ctl.config.json +82 -0
- package/package.json +41 -6
- package/dist/commands/ps.js +0 -119
|
@@ -6,860 +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
|
-
import
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
import { stdin as stdinStream, stdout as stdoutStream } from 'node:process';
|
|
14
|
-
import { runPromptCatalog, } from "../lib/prompt-catalog.js";
|
|
15
|
-
import { applyCliLocale, CLI_LOCALE_FLAG_DESCRIPTION, CLI_LOCALE_FLAG_OPTIONS, localeText, resolveCliLocale, translateCli, } from "../lib/cli-locale.js";
|
|
16
|
-
import { run } from "../lib/run-npm.js";
|
|
17
|
-
import { printVerbose, setVerboseMode, startTask, stopTask, updateTask } from '../lib/ui.js';
|
|
18
|
-
const DEFAULT_DOCKER_REGISTRY = 'nocobase/nocobase';
|
|
19
|
-
const DEFAULT_DOCKER_REGISTRY_ZH_CN = 'registry.cn-shanghai.aliyuncs.com/nocobase/nocobase';
|
|
20
|
-
const DEFAULT_DOCKER_PLATFORM = 'auto';
|
|
21
|
-
const DEFAULT_DOWNLOAD_VERSION = 'beta';
|
|
22
|
-
const downloadText = (key, values) => localeText(`commands.download.${key}`, values);
|
|
23
|
-
const downloadTranslatedText = (key, values, fallback) => translateCli(`commands.download.${key}`, values, { fallback });
|
|
24
|
-
function defaultOutputDirForVersion(versionTag) {
|
|
25
|
-
const safe = versionTag.replace(/[/\\]/g, '-');
|
|
26
|
-
return `./nocobase-${safe}`;
|
|
27
|
-
}
|
|
28
|
-
async function pathExists(target) {
|
|
29
|
-
try {
|
|
30
|
-
await fsp.access(target);
|
|
31
|
-
return true;
|
|
32
|
-
}
|
|
33
|
-
catch {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
export function defaultDockerRegistryForLang(lang) {
|
|
38
|
-
return resolveCliLocale(String(lang ?? '').trim() || undefined) === 'zh-CN'
|
|
39
|
-
? DEFAULT_DOCKER_REGISTRY_ZH_CN
|
|
40
|
-
: DEFAULT_DOCKER_REGISTRY;
|
|
41
|
-
}
|
|
42
|
-
function defaultDockerRegistryForPromptValues(_values) {
|
|
43
|
-
return defaultDockerRegistryForLang(process.env.NB_LOCALE);
|
|
44
|
-
}
|
|
45
|
-
function argvHasToken(argv, tokens) {
|
|
46
|
-
return tokens.some((t) => argv.includes(t));
|
|
47
|
-
}
|
|
48
|
-
function gitRefForVersion(versionSpec) {
|
|
49
|
-
const versionToRef = {
|
|
50
|
-
latest: 'main',
|
|
51
|
-
beta: 'next',
|
|
52
|
-
alpha: 'develop',
|
|
53
|
-
};
|
|
54
|
-
return versionToRef[versionSpec] || versionSpec;
|
|
55
|
-
}
|
|
56
|
-
/** `build-dts` only applies when `build` is true and source is npm/git. */
|
|
57
|
-
function normalizeBuildDts(source, build, wantDts) {
|
|
58
|
-
if (source !== 'npm' && source !== 'git') {
|
|
59
|
-
return false;
|
|
60
|
-
}
|
|
61
|
-
return Boolean(build && wantDts);
|
|
62
|
-
}
|
|
63
|
-
function downloadSourceLabel(source) {
|
|
64
|
-
switch (source) {
|
|
65
|
-
case 'docker':
|
|
66
|
-
return 'Docker image';
|
|
67
|
-
case 'npm':
|
|
68
|
-
return 'npm package';
|
|
69
|
-
case 'git':
|
|
70
|
-
return 'Git repository';
|
|
71
|
-
default:
|
|
72
|
-
return source;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
function normalizeDockerPlatform(value) {
|
|
76
|
-
const text = String(value ?? '').trim();
|
|
77
|
-
if (text === 'linux/amd64' || text === 'linux/arm64') {
|
|
78
|
-
return text;
|
|
79
|
-
}
|
|
80
|
-
return DEFAULT_DOCKER_PLATFORM;
|
|
81
|
-
}
|
|
82
|
-
function dockerPlatformArg(value) {
|
|
83
|
-
const platform = normalizeDockerPlatform(value);
|
|
84
|
-
if (platform === 'auto') {
|
|
85
|
-
return undefined;
|
|
86
|
-
}
|
|
87
|
-
return platform;
|
|
88
|
-
}
|
|
89
|
-
function formatDownloadStageFailure(stage) {
|
|
90
|
-
return [
|
|
91
|
-
downloadTranslatedText(`failures.${stage}.title`),
|
|
92
|
-
downloadTranslatedText(`failures.${stage}.body`),
|
|
93
|
-
downloadTranslatedText(`failures.${stage}.hint`),
|
|
94
|
-
].join('\n');
|
|
95
|
-
}
|
|
96
|
-
function formatDownloadFailure(message, verbose) {
|
|
97
|
-
if (verbose) {
|
|
98
|
-
return message;
|
|
99
|
-
}
|
|
100
|
-
const lower = message.toLowerCase();
|
|
101
|
-
if (lower.includes('yarn install')) {
|
|
102
|
-
return formatDownloadStageFailure('dependencyInstall');
|
|
103
|
-
}
|
|
104
|
-
if (lower.includes('git clone')) {
|
|
105
|
-
return formatDownloadStageFailure('gitClone');
|
|
106
|
-
}
|
|
107
|
-
if (lower.includes('docker pull')) {
|
|
108
|
-
return formatDownloadStageFailure('dockerPull');
|
|
109
|
-
}
|
|
110
|
-
if (lower.includes('docker save')) {
|
|
111
|
-
return formatDownloadStageFailure('dockerSave');
|
|
112
|
-
}
|
|
113
|
-
if (lower.includes('create-nocobase-app') || lower.includes('npx create-nocobase-app')) {
|
|
114
|
-
return formatDownloadStageFailure('scaffold');
|
|
115
|
-
}
|
|
116
|
-
if (lower.includes('nocobase command')) {
|
|
117
|
-
return formatDownloadStageFailure('build');
|
|
118
|
-
}
|
|
119
|
-
if (lower.includes('exited with code') || lower.includes('exited due to signal')) {
|
|
120
|
-
return formatDownloadStageFailure('generic');
|
|
121
|
-
}
|
|
122
|
-
return message;
|
|
123
|
-
}
|
|
124
|
-
const EXTERNAL_COMMAND_LOADING_DELAY_MS = 8_000;
|
|
125
|
-
const EXTERNAL_COMMAND_LOADING_UPDATE_MS = 15_000;
|
|
126
|
-
function normalizeVersionPreset(value) {
|
|
127
|
-
const text = String(value ?? '').trim();
|
|
128
|
-
if (text === 'latest' || text === 'beta' || text === 'alpha') {
|
|
129
|
-
return text;
|
|
130
|
-
}
|
|
131
|
-
return 'other';
|
|
132
|
-
}
|
|
133
|
-
function versionPresetForValue(value) {
|
|
134
|
-
return normalizeVersionPreset(value);
|
|
135
|
-
}
|
|
136
|
-
function otherVersionValue(value) {
|
|
137
|
-
const text = String(value ?? '').trim();
|
|
138
|
-
return normalizeVersionPreset(text) === 'other' ? text : '';
|
|
139
|
-
}
|
|
140
|
-
function resolveVersionFromResults(results, fallback) {
|
|
141
|
-
const preset = normalizeVersionPreset(results.version ?? fallback);
|
|
142
|
-
if (preset === 'other') {
|
|
143
|
-
return String(results.otherVersion ?? fallback ?? '').trim();
|
|
144
|
-
}
|
|
145
|
-
return preset;
|
|
146
|
-
}
|
|
147
|
-
export default class Download extends Command {
|
|
148
|
-
_flags;
|
|
149
|
-
preparationTaskActive = false;
|
|
150
|
-
static description = 'Scaffold or fetch NocoBase from npm, Docker, or Git. `--version` is the shared version input: package version for npm, image tag for Docker, and git ref for Git.';
|
|
151
|
-
static examples = [
|
|
152
|
-
'<%= config.bin %> <%= command.id %>',
|
|
153
|
-
'<%= config.bin %> <%= command.id %> -y --source npm --version alpha',
|
|
154
|
-
'<%= config.bin %> <%= command.id %> -y --source npm --version alpha --no-build',
|
|
155
|
-
'<%= config.bin %> <%= command.id %> --source npm --version alpha',
|
|
156
|
-
'<%= config.bin %> <%= command.id %> --source npm --version alpha --output-dir=./app',
|
|
157
|
-
'<%= config.bin %> <%= command.id %> --source docker --version alpha --docker-registry=nocobase/nocobase --docker-platform=linux/arm64',
|
|
158
|
-
'<%= config.bin %> <%= command.id %> -y --source docker --version alpha --docker-save -o ./docker-images',
|
|
159
|
-
'<%= config.bin %> <%= command.id %> --source git --version alpha --git-url=git@github.com:nocobase/nocobase.git',
|
|
160
|
-
'<%= config.bin %> <%= command.id %> --source git --version fix/cli-v2',
|
|
161
|
-
'<%= config.bin %> <%= command.id %> -y --source git --version fix/cli-v2 --no-build',
|
|
162
|
-
'<%= config.bin %> <%= command.id %> -y --source npm --version alpha --build-dts',
|
|
163
|
-
'<%= config.bin %> <%= command.id %> -y --source npm --version alpha --npm-registry=https://registry.npmmirror.com',
|
|
164
|
-
];
|
|
165
|
-
static flags = {
|
|
166
|
-
yes: Flags.boolean({
|
|
167
|
-
char: 'y',
|
|
168
|
-
description: 'Use defaults and skip interactive prompts.',
|
|
169
|
-
default: false,
|
|
170
|
-
}),
|
|
171
|
-
verbose: Flags.boolean({
|
|
172
|
-
description: 'Show detailed command output',
|
|
173
|
-
default: false,
|
|
174
|
-
}),
|
|
175
|
-
locale: Flags.string({
|
|
176
|
-
description: CLI_LOCALE_FLAG_DESCRIPTION,
|
|
177
|
-
options: CLI_LOCALE_FLAG_OPTIONS,
|
|
178
|
-
}),
|
|
179
|
-
'no-intro': Flags.boolean({
|
|
180
|
-
hidden: true,
|
|
181
|
-
description: 'Skip command intro when invoked by another CLI command',
|
|
182
|
-
default: false,
|
|
183
|
-
}),
|
|
184
|
-
source: Flags.string({
|
|
185
|
-
char: 's',
|
|
186
|
-
description: 'How to get NocoBase: Docker image, npm package, or Git repository.',
|
|
187
|
-
options: ['docker', 'npm', 'git'],
|
|
188
|
-
required: false,
|
|
189
|
-
}),
|
|
190
|
-
version: Flags.string({
|
|
191
|
-
char: 'v',
|
|
192
|
-
description: 'Shared version input. For npm this is the package version, for Docker the image tag, and for Git a git ref such as a branch name (for example: alpha, beta, latest, fix/cli-v2).',
|
|
193
|
-
}),
|
|
194
|
-
replace: Flags.boolean({
|
|
195
|
-
char: 'r',
|
|
196
|
-
description: 'Replace the target directory if it already exists.',
|
|
197
|
-
default: false,
|
|
198
|
-
}),
|
|
199
|
-
'dev-dependencies': Flags.boolean({
|
|
200
|
-
char: 'D',
|
|
201
|
-
allowNo: true,
|
|
202
|
-
description: 'Install development dependencies for npm/git source installs.',
|
|
203
|
-
default: false,
|
|
204
|
-
}),
|
|
205
|
-
'output-dir': Flags.string({
|
|
206
|
-
char: 'o',
|
|
207
|
-
description: 'Download target directory, or Docker tarball directory when --docker-save is enabled.',
|
|
208
|
-
}),
|
|
209
|
-
'git-url': Flags.string({
|
|
210
|
-
description: 'Git repository URL to clone when --source git is used.',
|
|
211
|
-
}),
|
|
212
|
-
'docker-registry': Flags.string({
|
|
213
|
-
description: 'Docker registry to pull when --source docker is used; combine it with --version as the image tag.',
|
|
214
|
-
}),
|
|
215
|
-
'docker-platform': Flags.string({
|
|
216
|
-
description: 'Docker image platform to pull; use auto to let Docker choose.',
|
|
217
|
-
options: ['auto', 'linux/amd64', 'linux/arm64'],
|
|
218
|
-
}),
|
|
219
|
-
'docker-save': Flags.boolean({
|
|
220
|
-
allowNo: true,
|
|
221
|
-
description: 'Also save the pulled Docker image as a tarball.',
|
|
222
|
-
default: false,
|
|
223
|
-
}),
|
|
224
|
-
'npm-registry': Flags.string({
|
|
225
|
-
description: 'npm registry for npm/git downloads and dependency installation.',
|
|
226
|
-
}),
|
|
227
|
-
'build': Flags.boolean({
|
|
228
|
-
allowNo: true,
|
|
229
|
-
description: 'Build npm/git source after dependencies are installed.',
|
|
230
|
-
default: true,
|
|
231
|
-
}),
|
|
232
|
-
'build-dts': Flags.boolean({
|
|
233
|
-
description: 'Generate TypeScript declaration files during the npm/git build.',
|
|
234
|
-
default: false,
|
|
235
|
-
}),
|
|
236
|
-
};
|
|
237
|
-
static prompts = {
|
|
238
|
-
source: {
|
|
239
|
-
type: 'select',
|
|
240
|
-
variant: 'radio',
|
|
241
|
-
message: downloadText('prompts.source.message'),
|
|
242
|
-
options: [
|
|
243
|
-
{
|
|
244
|
-
value: 'docker',
|
|
245
|
-
label: downloadText('prompts.source.dockerLabel'),
|
|
246
|
-
hint: downloadText('prompts.source.dockerHint'),
|
|
247
|
-
},
|
|
248
|
-
{
|
|
249
|
-
value: 'npm',
|
|
250
|
-
label: downloadText('prompts.source.npmLabel'),
|
|
251
|
-
hint: downloadText('prompts.source.npmHint'),
|
|
252
|
-
},
|
|
253
|
-
{
|
|
254
|
-
value: 'git',
|
|
255
|
-
label: downloadText('prompts.source.gitLabel'),
|
|
256
|
-
hint: downloadText('prompts.source.gitHint'),
|
|
257
|
-
},
|
|
258
|
-
],
|
|
259
|
-
yesInitialValue: 'docker',
|
|
260
|
-
initialValue: 'docker',
|
|
261
|
-
required: true,
|
|
262
|
-
},
|
|
263
|
-
version: {
|
|
264
|
-
type: 'select',
|
|
265
|
-
variant: 'radio',
|
|
266
|
-
message: downloadText('prompts.version.message'),
|
|
267
|
-
options: [
|
|
268
|
-
{
|
|
269
|
-
value: 'latest',
|
|
270
|
-
label: downloadText('prompts.version.latestLabel'),
|
|
271
|
-
hint: downloadText('prompts.version.latestHint'),
|
|
272
|
-
disabled: true,
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
value: 'beta',
|
|
276
|
-
label: downloadText('prompts.version.betaLabel'),
|
|
277
|
-
hint: downloadText('prompts.version.betaHint'),
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
value: 'alpha',
|
|
281
|
-
label: downloadText('prompts.version.alphaLabel'),
|
|
282
|
-
hint: downloadText('prompts.version.alphaHint'),
|
|
283
|
-
},
|
|
284
|
-
{
|
|
285
|
-
value: 'other',
|
|
286
|
-
label: downloadText('prompts.version.otherLabel'),
|
|
287
|
-
hint: downloadText('prompts.version.otherHint'),
|
|
288
|
-
},
|
|
289
|
-
],
|
|
290
|
-
initialValue: DEFAULT_DOWNLOAD_VERSION,
|
|
291
|
-
yesInitialValue: DEFAULT_DOWNLOAD_VERSION,
|
|
292
|
-
required: true,
|
|
293
|
-
},
|
|
294
|
-
otherVersion: {
|
|
295
|
-
type: 'text',
|
|
296
|
-
message: downloadText('prompts.otherVersion.message'),
|
|
297
|
-
placeholder: downloadText('prompts.otherVersion.placeholder'),
|
|
298
|
-
required: true,
|
|
299
|
-
hidden: (values) => normalizeVersionPreset(values.version) !== 'other',
|
|
300
|
-
},
|
|
301
|
-
dockerRegistry: {
|
|
302
|
-
type: 'text',
|
|
303
|
-
message: downloadText('prompts.dockerRegistry.message'),
|
|
304
|
-
placeholder: downloadText('prompts.dockerRegistry.placeholder'),
|
|
305
|
-
initialValue: defaultDockerRegistryForPromptValues,
|
|
306
|
-
required: true,
|
|
307
|
-
hidden: (values) => values.source !== 'docker',
|
|
308
|
-
},
|
|
309
|
-
dockerPlatform: {
|
|
310
|
-
type: 'select',
|
|
311
|
-
message: downloadText('prompts.dockerPlatform.message'),
|
|
312
|
-
options: [
|
|
313
|
-
{
|
|
314
|
-
value: 'auto',
|
|
315
|
-
label: downloadText('prompts.dockerPlatform.autoLabel'),
|
|
316
|
-
hint: downloadText('prompts.dockerPlatform.autoHint'),
|
|
317
|
-
},
|
|
318
|
-
{ value: 'linux/amd64', label: 'linux/amd64' },
|
|
319
|
-
{ value: 'linux/arm64', label: 'linux/arm64' },
|
|
320
|
-
],
|
|
321
|
-
initialValue: DEFAULT_DOCKER_PLATFORM,
|
|
322
|
-
yesInitialValue: DEFAULT_DOCKER_PLATFORM,
|
|
323
|
-
required: true,
|
|
324
|
-
hidden: (values) => values.source !== 'docker',
|
|
325
|
-
},
|
|
326
|
-
dockerSave: {
|
|
327
|
-
type: 'boolean',
|
|
328
|
-
message: downloadText('prompts.dockerSave.message'),
|
|
329
|
-
initialValue: false,
|
|
330
|
-
hidden: (values) => values.source !== 'docker',
|
|
331
|
-
},
|
|
332
|
-
gitUrl: {
|
|
333
|
-
type: 'text',
|
|
334
|
-
message: downloadText('prompts.gitUrl.message'),
|
|
335
|
-
placeholder: downloadText('prompts.gitUrl.placeholder'),
|
|
336
|
-
initialValue: 'https://github.com/nocobase/nocobase.git',
|
|
337
|
-
yesInitialValue: 'https://github.com/nocobase/nocobase.git',
|
|
338
|
-
required: true,
|
|
339
|
-
hidden: (values) => values.source !== 'git',
|
|
340
|
-
},
|
|
341
|
-
outputDir: {
|
|
342
|
-
type: 'text',
|
|
343
|
-
message: downloadText('prompts.outputDir.message'),
|
|
344
|
-
placeholder: downloadText('prompts.outputDir.placeholder'),
|
|
345
|
-
initialValue: (values) => {
|
|
346
|
-
const version = resolveVersionFromResults(values, DEFAULT_DOWNLOAD_VERSION) || DEFAULT_DOWNLOAD_VERSION;
|
|
347
|
-
return defaultOutputDirForVersion(version);
|
|
348
|
-
},
|
|
349
|
-
required: true,
|
|
350
|
-
hidden: (values) => {
|
|
351
|
-
const s = values.source;
|
|
352
|
-
if (s === 'npm' || s === 'git') {
|
|
353
|
-
return false;
|
|
354
|
-
}
|
|
355
|
-
if (s === 'docker') {
|
|
356
|
-
return !values.dockerSave;
|
|
357
|
-
}
|
|
358
|
-
return true;
|
|
359
|
-
},
|
|
360
|
-
},
|
|
361
|
-
npmRegistry: {
|
|
362
|
-
type: 'text',
|
|
363
|
-
message: downloadText('prompts.npmRegistry.message'),
|
|
364
|
-
placeholder: downloadText('prompts.npmRegistry.placeholder'),
|
|
365
|
-
initialValue: '',
|
|
366
|
-
hidden: (values) => values.source !== 'npm' && values.source !== 'git',
|
|
367
|
-
},
|
|
368
|
-
replace: {
|
|
369
|
-
type: 'boolean',
|
|
370
|
-
message: downloadText('prompts.replace.message'),
|
|
371
|
-
initialValue: false,
|
|
372
|
-
hidden: (values) => Download.hideOutputDirAndReplaceSteps(values),
|
|
373
|
-
},
|
|
374
|
-
devDependencies: {
|
|
375
|
-
type: 'boolean',
|
|
376
|
-
message: downloadText('prompts.devDependencies.message'),
|
|
377
|
-
initialValue: false,
|
|
378
|
-
hidden: (values) => values.source !== 'npm',
|
|
379
|
-
},
|
|
380
|
-
build: {
|
|
381
|
-
type: 'boolean',
|
|
382
|
-
message: downloadText('prompts.build.message'),
|
|
383
|
-
initialValue: true,
|
|
384
|
-
yesInitialValue: true,
|
|
385
|
-
hidden: () => true,
|
|
386
|
-
},
|
|
387
|
-
buildDts: {
|
|
388
|
-
type: 'boolean',
|
|
389
|
-
message: downloadText('prompts.buildDts.message'),
|
|
390
|
-
initialValue: false,
|
|
391
|
-
hidden: (values) => values.source !== 'git',
|
|
392
|
-
},
|
|
393
|
-
};
|
|
394
|
-
/** When true, `outputDir` / `replace` prompts are skipped (same condition for both). */
|
|
395
|
-
static hideOutputDirAndReplaceSteps(values) {
|
|
396
|
-
const s = values.source;
|
|
397
|
-
if (s === 'npm' || s === 'git') {
|
|
398
|
-
return false;
|
|
399
|
-
}
|
|
400
|
-
if (s === 'docker') {
|
|
401
|
-
return !values.dockerSave;
|
|
402
|
-
}
|
|
403
|
-
return true;
|
|
404
|
-
}
|
|
405
|
-
resolveOutputDir(flags) {
|
|
406
|
-
const explicit = flags['output-dir'];
|
|
407
|
-
if (explicit) {
|
|
408
|
-
return explicit;
|
|
409
|
-
}
|
|
410
|
-
return defaultOutputDirForVersion(flags.version || 'latest');
|
|
411
|
-
}
|
|
412
|
-
async ensureOutputDirAvailable(outputDir, replace) {
|
|
413
|
-
const outputAbs = path.resolve(process.cwd(), outputDir);
|
|
414
|
-
if (replace) {
|
|
415
|
-
await fsp.rm(outputAbs, { recursive: true, force: true });
|
|
416
|
-
return outputAbs;
|
|
417
|
-
}
|
|
418
|
-
if (await pathExists(outputAbs)) {
|
|
419
|
-
this.error(`Download target already exists: ${outputDir}. Use --replace to remove it before continuing.`);
|
|
420
|
-
}
|
|
421
|
-
return outputAbs;
|
|
422
|
-
}
|
|
423
|
-
dockerTarPath(flags, outputAbs) {
|
|
424
|
-
const image = String(flags['docker-registry'] ?? '').trim() || defaultDockerRegistryForLang(process.env.NB_LOCALE);
|
|
425
|
-
const tag = flags.version ?? 'latest';
|
|
426
|
-
const safeBase = `${image.replace(/[/:]/g, '-')}-${tag.replace(/[/\\]/g, '-')}`;
|
|
427
|
-
return path.join(outputAbs, `${safeBase}.tar`);
|
|
428
|
-
}
|
|
429
|
-
/**
|
|
430
|
-
* Defaults for prompts only. Keys present in **`preset`** are omitted so `runPromptCatalog` uses
|
|
431
|
-
* **`values`** (preset) alone for those steps — no duplicate prefill for skipped prompts.
|
|
432
|
-
*/
|
|
433
|
-
buildInitialValuesFromParsed(flags, preset) {
|
|
434
|
-
const initialValues = {};
|
|
435
|
-
const localeDefaultDockerRegistry = defaultDockerRegistryForLang(flags.locale ?? process.env.NB_LOCALE);
|
|
436
|
-
const source = flags.source?.trim();
|
|
437
|
-
if (source) {
|
|
438
|
-
initialValues.source = source;
|
|
439
|
-
}
|
|
440
|
-
if (flags.version !== undefined) {
|
|
441
|
-
const version = flags.version.trim() || 'latest';
|
|
442
|
-
initialValues.version = versionPresetForValue(version);
|
|
443
|
-
initialValues.otherVersion = otherVersionValue(version);
|
|
444
|
-
}
|
|
445
|
-
initialValues.replace = flags.replace;
|
|
446
|
-
initialValues.devDependencies = flags['dev-dependencies'];
|
|
447
|
-
initialValues.build = flags.build;
|
|
448
|
-
initialValues.buildDts = flags['build-dts'];
|
|
449
|
-
if (flags['output-dir'] !== undefined) {
|
|
450
|
-
initialValues.outputDir = flags['output-dir']?.trim() ?? '';
|
|
451
|
-
}
|
|
452
|
-
if (flags['git-url'] !== undefined) {
|
|
453
|
-
initialValues.gitUrl = flags['git-url']?.trim() ?? '';
|
|
454
|
-
}
|
|
455
|
-
if (flags['docker-registry'] !== undefined) {
|
|
456
|
-
initialValues.dockerRegistry = String(flags['docker-registry'] ?? '').trim();
|
|
457
|
-
}
|
|
458
|
-
else {
|
|
459
|
-
initialValues.dockerRegistry = localeDefaultDockerRegistry;
|
|
460
|
-
}
|
|
461
|
-
initialValues.dockerPlatform = normalizeDockerPlatform(flags['docker-platform']);
|
|
462
|
-
initialValues.dockerSave = flags['docker-save'];
|
|
463
|
-
if (flags['npm-registry'] !== undefined) {
|
|
464
|
-
initialValues.npmRegistry =
|
|
465
|
-
typeof flags['npm-registry'] === 'string' ? flags['npm-registry'] : '';
|
|
466
|
-
}
|
|
467
|
-
for (const key of Object.keys(preset)) {
|
|
468
|
-
if (Object.prototype.hasOwnProperty.call(initialValues, key)) {
|
|
469
|
-
delete initialValues[key];
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
return initialValues;
|
|
473
|
-
}
|
|
474
|
-
/**
|
|
475
|
-
* Preset `values` for `runPromptCatalog`: any key here skips that prompt and fixes the result.
|
|
476
|
-
* Keys not listed are resolved interactively (TTY) or from catalog defaults / `initialValues` (non-TTY / `-y`).
|
|
477
|
-
*/
|
|
478
|
-
buildPresetValuesFromFlags(flags) {
|
|
479
|
-
const preset = {};
|
|
480
|
-
const argv = process.argv.slice(2);
|
|
481
|
-
if (flags.source !== undefined && String(flags.source).trim() !== '') {
|
|
482
|
-
preset.source = String(flags.source).trim();
|
|
483
|
-
}
|
|
484
|
-
if (flags.version !== undefined) {
|
|
485
|
-
const version = String(flags.version).trim() || 'latest';
|
|
486
|
-
preset.version = versionPresetForValue(version);
|
|
487
|
-
if (normalizeVersionPreset(version) === 'other') {
|
|
488
|
-
preset.otherVersion = version;
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
if (flags['docker-registry'] !== undefined) {
|
|
492
|
-
const v = String(flags['docker-registry'] ?? '').trim();
|
|
493
|
-
if (v) {
|
|
494
|
-
preset.dockerRegistry = v;
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
if (argvHasToken(argv, ['--docker-platform'])) {
|
|
498
|
-
preset.dockerPlatform = normalizeDockerPlatform(flags['docker-platform']);
|
|
499
|
-
}
|
|
500
|
-
if (flags['output-dir'] !== undefined) {
|
|
501
|
-
const v = flags['output-dir']?.trim();
|
|
502
|
-
if (v) {
|
|
503
|
-
preset.outputDir = v;
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
if (flags['git-url'] !== undefined) {
|
|
507
|
-
const v = flags['git-url']?.trim();
|
|
508
|
-
if (v) {
|
|
509
|
-
preset.gitUrl = v;
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
if (flags['npm-registry'] !== undefined) {
|
|
513
|
-
preset.npmRegistry = typeof flags['npm-registry'] === 'string' ? flags['npm-registry'] : '';
|
|
514
|
-
}
|
|
515
|
-
if (argvHasToken(argv, ['--replace', '-r'])) {
|
|
516
|
-
preset.replace = flags.replace;
|
|
517
|
-
}
|
|
518
|
-
if (argvHasToken(argv, ['--dev-dependencies', '--no-dev-dependencies', '-D'])) {
|
|
519
|
-
preset.devDependencies = flags['dev-dependencies'];
|
|
520
|
-
}
|
|
521
|
-
if (argvHasToken(argv, ['--docker-save', '--no-docker-save'])) {
|
|
522
|
-
preset.dockerSave = flags['docker-save'];
|
|
523
|
-
}
|
|
524
|
-
if (argvHasToken(argv, ['--build', '--no-build'])) {
|
|
525
|
-
preset.build = flags.build;
|
|
526
|
-
}
|
|
527
|
-
if (argvHasToken(argv, ['--build-dts', '--no-build-dts'])) {
|
|
528
|
-
preset.buildDts = flags['build-dts'];
|
|
529
|
-
}
|
|
530
|
-
return preset;
|
|
531
|
-
}
|
|
532
|
-
resolveEffectiveBuild(source, results, flags) {
|
|
533
|
-
if (source === 'npm' && !Boolean(results.devDependencies)) {
|
|
534
|
-
return false;
|
|
535
|
-
}
|
|
536
|
-
if (source === 'npm' || source === 'git') {
|
|
537
|
-
return results.build !== undefined ? Boolean(results.build) : flags.build;
|
|
538
|
-
}
|
|
539
|
-
return flags.build;
|
|
540
|
-
}
|
|
541
|
-
mapCatalogResultsToResolved(results, flags) {
|
|
542
|
-
const source = String(results.source);
|
|
543
|
-
const version = resolveVersionFromResults(results, flags.version) || 'latest';
|
|
544
|
-
const devDependencies = source === 'npm' ? Boolean(results.devDependencies) : undefined;
|
|
545
|
-
const effectiveBuild = this.resolveEffectiveBuild(source, results, flags);
|
|
546
|
-
const buildDtsWant = results.buildDts !== undefined ? Boolean(results.buildDts) : flags['build-dts'];
|
|
547
|
-
const outputDir = results.outputDir !== undefined
|
|
548
|
-
? String(results.outputDir).trim() || undefined
|
|
549
|
-
: flags['output-dir']?.trim() || undefined;
|
|
550
|
-
const replace = results.replace !== undefined ? Boolean(results.replace) : flags.replace;
|
|
551
|
-
const gitUrl = results.gitUrl !== undefined
|
|
552
|
-
? String(results.gitUrl).trim() || undefined
|
|
553
|
-
: flags['git-url']?.trim() || undefined;
|
|
554
|
-
const dockerRegistry = source === 'docker'
|
|
555
|
-
? (results.dockerRegistry !== undefined
|
|
556
|
-
? String(results.dockerRegistry).trim() || undefined
|
|
557
|
-
: flags['docker-registry']?.trim() || defaultDockerRegistryForLang(flags.locale ?? process.env.NB_LOCALE))
|
|
558
|
-
: undefined;
|
|
559
|
-
const dockerPlatform = source === 'docker'
|
|
560
|
-
? normalizeDockerPlatform(results.dockerPlatform !== undefined
|
|
561
|
-
? results.dockerPlatform
|
|
562
|
-
: flags['docker-platform'])
|
|
563
|
-
: undefined;
|
|
564
|
-
const dockerSave = source === 'docker'
|
|
565
|
-
? results.dockerSave !== undefined
|
|
566
|
-
? Boolean(results.dockerSave)
|
|
567
|
-
: flags['docker-save']
|
|
568
|
-
: false;
|
|
569
|
-
const npmRegistryRaw = results.npmRegistry !== undefined
|
|
570
|
-
? String(results.npmRegistry)
|
|
571
|
-
: flags['npm-registry'] ?? '';
|
|
572
|
-
const npmRegistry = npmRegistryRaw.trim() || undefined;
|
|
573
|
-
return {
|
|
574
|
-
source,
|
|
575
|
-
version,
|
|
576
|
-
replace,
|
|
577
|
-
...(source === 'npm' ? { 'dev-dependencies': devDependencies } : {}),
|
|
578
|
-
'build': effectiveBuild,
|
|
579
|
-
'build-dts': normalizeBuildDts(source, effectiveBuild, buildDtsWant),
|
|
580
|
-
'output-dir': outputDir,
|
|
581
|
-
'git-url': gitUrl,
|
|
582
|
-
'docker-registry': dockerRegistry,
|
|
583
|
-
...(source === 'docker' ? { 'docker-platform': dockerPlatform } : {}),
|
|
584
|
-
...(source === 'docker' ? { 'docker-save': dockerSave } : {}),
|
|
585
|
-
...(npmRegistry ? { 'npm-registry': npmRegistry } : {}),
|
|
586
|
-
};
|
|
587
|
-
}
|
|
588
|
-
async resolveDownloadFlags(flags) {
|
|
589
|
-
const nonInteractive = !stdinStream.isTTY || !stdoutStream.isTTY || flags.yes;
|
|
590
|
-
if (nonInteractive && !flags.source?.trim()) {
|
|
591
|
-
this.error('Download source is required in non-interactive mode. Use --source npm, --source git, or --source docker.');
|
|
592
|
-
}
|
|
593
|
-
const presetValues = this.buildPresetValuesFromFlags(flags);
|
|
594
|
-
const initialValues = this.buildInitialValuesFromParsed(flags, presetValues);
|
|
595
|
-
const results = await runPromptCatalog(Download.prompts, {
|
|
596
|
-
initialValues,
|
|
597
|
-
values: presetValues,
|
|
598
|
-
yes: flags.yes,
|
|
599
|
-
command: this,
|
|
600
|
-
hooks: {
|
|
601
|
-
onCancel: () => {
|
|
602
|
-
p.cancel('Download cancelled.');
|
|
603
|
-
this.exit(0);
|
|
604
|
-
},
|
|
605
|
-
onMissingNonInteractive: (message) => {
|
|
606
|
-
this.error(message);
|
|
607
|
-
},
|
|
608
|
-
},
|
|
609
|
-
});
|
|
610
|
-
const source = String(results.source ?? '').trim();
|
|
611
|
-
const version = resolveVersionFromResults(results, flags.version);
|
|
612
|
-
if (!source || !['docker', 'npm', 'git'].includes(source)) {
|
|
613
|
-
this.error('Download source is required. Choose npm, git, or docker.');
|
|
614
|
-
}
|
|
615
|
-
if (!version) {
|
|
616
|
-
this.error('Version is required. Choose alpha, beta, latest, or enter another version.');
|
|
617
|
-
}
|
|
618
|
-
if (flags['docker-save'] && source !== 'docker') {
|
|
619
|
-
this.error('--docker-save is only available when --source docker is selected.');
|
|
620
|
-
}
|
|
621
|
-
return this.mapCatalogResultsToResolved(results, flags);
|
|
622
|
-
}
|
|
623
|
-
npmRegistryUrl(flags) {
|
|
624
|
-
const url = flags['npm-registry']?.trim();
|
|
625
|
-
return url || undefined;
|
|
626
|
-
}
|
|
627
|
-
npmRegistryEnv(flags) {
|
|
628
|
-
const url = this.npmRegistryUrl(flags);
|
|
629
|
-
if (!url) {
|
|
630
|
-
return undefined;
|
|
631
|
-
}
|
|
632
|
-
return { npm_config_registry: url };
|
|
633
|
-
}
|
|
634
|
-
isVerbose() {
|
|
635
|
-
const flags = this._flags;
|
|
636
|
-
return Boolean(flags?.verbose);
|
|
637
|
-
}
|
|
638
|
-
commandStdio() {
|
|
639
|
-
return this.isVerbose() ? 'inherit' : 'ignore';
|
|
640
|
-
}
|
|
641
|
-
formatCommandForLog(name, args, cwd) {
|
|
642
|
-
const quotedArgs = args.map((arg) => (/\s/.test(arg) ? JSON.stringify(arg) : arg));
|
|
643
|
-
const commandLine = [name, ...quotedArgs].join(' ');
|
|
644
|
-
return cwd ? `${commandLine} (cwd: ${cwd})` : commandLine;
|
|
645
|
-
}
|
|
646
|
-
async runExternalCommand(name, args, options) {
|
|
647
|
-
const cwd = options?.cwd;
|
|
648
|
-
printVerbose(`Running command: ${this.formatCommandForLog(name, args, cwd)}`);
|
|
649
|
-
let loadingStarted = false;
|
|
650
|
-
let loadingTimer;
|
|
651
|
-
let updateTimer;
|
|
652
|
-
let elapsedSeconds = 0;
|
|
653
|
-
if (!this.isVerbose() && options?.loadingMessage) {
|
|
654
|
-
loadingTimer = setTimeout(() => {
|
|
655
|
-
loadingStarted = true;
|
|
656
|
-
elapsedSeconds = Math.floor(EXTERNAL_COMMAND_LOADING_DELAY_MS / 1000);
|
|
657
|
-
startTask(`${options.loadingMessage}. Please wait...`);
|
|
658
|
-
updateTimer = setInterval(() => {
|
|
659
|
-
elapsedSeconds += Math.floor(EXTERNAL_COMMAND_LOADING_UPDATE_MS / 1000);
|
|
660
|
-
updateTask(`${options.loadingMessage}. Still working... (${elapsedSeconds}s elapsed)`);
|
|
661
|
-
}, EXTERNAL_COMMAND_LOADING_UPDATE_MS);
|
|
662
|
-
}, EXTERNAL_COMMAND_LOADING_DELAY_MS);
|
|
663
|
-
}
|
|
664
|
-
try {
|
|
665
|
-
await run(name, args, {
|
|
666
|
-
...options,
|
|
667
|
-
stdio: this.commandStdio(),
|
|
668
|
-
});
|
|
669
|
-
}
|
|
670
|
-
finally {
|
|
671
|
-
if (loadingTimer) {
|
|
672
|
-
clearTimeout(loadingTimer);
|
|
673
|
-
}
|
|
674
|
-
if (updateTimer) {
|
|
675
|
-
clearInterval(updateTimer);
|
|
676
|
-
}
|
|
677
|
-
if (loadingStarted) {
|
|
678
|
-
stopTask();
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
startPreparationTask(message) {
|
|
683
|
-
if (this.isVerbose()) {
|
|
684
|
-
p.log.step(message);
|
|
685
|
-
return;
|
|
686
|
-
}
|
|
687
|
-
this.preparationTaskActive = true;
|
|
688
|
-
startTask(message);
|
|
689
|
-
}
|
|
690
|
-
finishPreparationTask() {
|
|
691
|
-
if (!this.preparationTaskActive) {
|
|
692
|
-
return;
|
|
693
|
-
}
|
|
694
|
-
this.preparationTaskActive = false;
|
|
695
|
-
stopTask();
|
|
696
|
-
}
|
|
697
|
-
runOptionsWithCwd(cwd, registryEnv) {
|
|
698
|
-
if (registryEnv) {
|
|
699
|
-
return { cwd, env: registryEnv };
|
|
700
|
-
}
|
|
701
|
-
return { cwd };
|
|
702
|
-
}
|
|
703
|
-
buildCommandArgv(projectRoot, flags) {
|
|
704
|
-
const argv = ['--cwd', projectRoot];
|
|
705
|
-
if (!flags['build-dts']) {
|
|
706
|
-
argv.push('--no-dts');
|
|
707
|
-
}
|
|
708
|
-
return argv;
|
|
709
|
-
}
|
|
710
|
-
async downloadFromDocker(flags) {
|
|
711
|
-
const image = String(flags['docker-registry'] ?? '').trim() || defaultDockerRegistryForLang(process.env.NB_LOCALE);
|
|
712
|
-
const tag = flags.version ?? 'latest';
|
|
713
|
-
const imageRef = `${image}:${tag}`;
|
|
714
|
-
const platform = dockerPlatformArg(flags['docker-platform']);
|
|
715
|
-
const pullArgs = ['pull'];
|
|
716
|
-
if (platform) {
|
|
717
|
-
pullArgs.push('--platform', platform);
|
|
718
|
-
}
|
|
719
|
-
pullArgs.push(imageRef);
|
|
720
|
-
this.finishPreparationTask();
|
|
721
|
-
p.log.step(`Pulling Docker image ${imageRef}`);
|
|
722
|
-
await this.runExternalCommand('docker', pullArgs, {
|
|
723
|
-
errorName: 'docker pull',
|
|
724
|
-
loadingMessage: 'Pulling the Docker image',
|
|
725
|
-
});
|
|
726
|
-
p.log.info(`Docker image is ready: ${imageRef}`);
|
|
727
|
-
if (!flags['docker-save']) {
|
|
728
|
-
return;
|
|
729
|
-
}
|
|
730
|
-
const outputDir = this.resolveOutputDir(flags);
|
|
731
|
-
const outAbs = flags.replace
|
|
732
|
-
? path.resolve(process.cwd(), outputDir)
|
|
733
|
-
: await this.ensureOutputDirAvailable(outputDir, false);
|
|
734
|
-
if (flags.replace) {
|
|
735
|
-
await fsp.rm(outAbs, { recursive: true, force: true });
|
|
736
|
-
}
|
|
737
|
-
await fsp.mkdir(outAbs, { recursive: true });
|
|
738
|
-
const tarPath = this.dockerTarPath(flags, outAbs);
|
|
739
|
-
p.log.step(`Saving Docker image tarball to ${tarPath}`);
|
|
740
|
-
await this.runExternalCommand('docker', ['save', '-o', tarPath, imageRef], {
|
|
741
|
-
errorName: 'docker save',
|
|
742
|
-
loadingMessage: 'Saving the Docker image tarball',
|
|
743
|
-
});
|
|
744
|
-
p.log.info(`Docker image tarball saved: ${tarPath}`);
|
|
745
|
-
}
|
|
746
|
-
async downloadFromNpm(flags) {
|
|
747
|
-
const versionSpec = flags.version || 'latest';
|
|
748
|
-
const outputDir = this.resolveOutputDir(flags);
|
|
749
|
-
const projectRoot = path.resolve(process.cwd(), outputDir);
|
|
750
|
-
await this.ensureOutputDirAvailable(outputDir, flags.replace);
|
|
751
|
-
const parentDir = path.dirname(projectRoot);
|
|
752
|
-
const appName = path.basename(projectRoot);
|
|
753
|
-
const npxArgs = ['-y', `create-nocobase-app@${versionSpec}`, appName];
|
|
754
|
-
if (!flags['dev-dependencies']) {
|
|
755
|
-
npxArgs.push('--skip-dev-dependencies');
|
|
756
|
-
}
|
|
757
|
-
await fsp.mkdir(parentDir, { recursive: true });
|
|
758
|
-
const registryEnv = this.npmRegistryEnv(flags);
|
|
759
|
-
this.finishPreparationTask();
|
|
760
|
-
p.log.step(`Creating NocoBase app "${appName}" from npm`);
|
|
761
|
-
await this.runExternalCommand('npx', npxArgs, {
|
|
762
|
-
...this.runOptionsWithCwd(parentDir, registryEnv),
|
|
763
|
-
errorName: 'npx create-nocobase-app',
|
|
764
|
-
loadingMessage: 'Creating the app scaffold',
|
|
765
|
-
});
|
|
766
|
-
const installArgs = ['install'];
|
|
767
|
-
if (!flags['dev-dependencies']) {
|
|
768
|
-
installArgs.push('--production');
|
|
769
|
-
}
|
|
770
|
-
p.log.step(`Installing dependencies in ${projectRoot}`);
|
|
771
|
-
await this.runExternalCommand('yarn', installArgs, {
|
|
772
|
-
...this.runOptionsWithCwd(projectRoot, registryEnv),
|
|
773
|
-
errorName: 'yarn install',
|
|
774
|
-
loadingMessage: 'Installing dependencies',
|
|
775
|
-
});
|
|
776
|
-
if (flags.build && flags['dev-dependencies']) {
|
|
777
|
-
p.log.step(`Building app in ${projectRoot}`);
|
|
778
|
-
await this.config.runCommand('build', [
|
|
779
|
-
...this.buildCommandArgv(projectRoot, flags),
|
|
780
|
-
...(this.isVerbose() ? ['--verbose'] : []),
|
|
781
|
-
]);
|
|
782
|
-
}
|
|
783
|
-
p.log.info(`NocoBase app is ready at ${projectRoot}`);
|
|
784
|
-
return projectRoot;
|
|
785
|
-
}
|
|
786
|
-
async downloadFromGit(flags) {
|
|
787
|
-
const repoUrl = flags['git-url'] ?? 'https://github.com/nocobase/nocobase.git';
|
|
788
|
-
const versionSpec = flags.version || 'latest';
|
|
789
|
-
const outputDir = this.resolveOutputDir(flags);
|
|
790
|
-
await this.ensureOutputDirAvailable(outputDir, flags.replace);
|
|
791
|
-
const branch = gitRefForVersion(versionSpec);
|
|
792
|
-
const gitArgs = ['clone'];
|
|
793
|
-
gitArgs.push('--branch', branch);
|
|
794
|
-
gitArgs.push('--depth', '1', repoUrl, outputDir);
|
|
795
|
-
this.finishPreparationTask();
|
|
796
|
-
p.log.step(branch === versionSpec
|
|
797
|
-
? `Cloning NocoBase from ${repoUrl} (${branch})`
|
|
798
|
-
: `Cloning NocoBase from ${repoUrl} (${branch}, resolved from ${versionSpec})`);
|
|
799
|
-
await this.runExternalCommand('git', gitArgs, {
|
|
800
|
-
errorName: 'git clone',
|
|
801
|
-
loadingMessage: 'Cloning the repository',
|
|
802
|
-
});
|
|
803
|
-
const projectRoot = path.resolve(process.cwd(), outputDir);
|
|
804
|
-
const registryEnv = this.npmRegistryEnv(flags);
|
|
805
|
-
p.log.step(`Installing dependencies in ${projectRoot}`);
|
|
806
|
-
await this.runExternalCommand('yarn', ['install'], {
|
|
807
|
-
...this.runOptionsWithCwd(projectRoot, registryEnv),
|
|
808
|
-
errorName: 'yarn install',
|
|
809
|
-
loadingMessage: 'Installing dependencies',
|
|
810
|
-
});
|
|
811
|
-
if (flags.build) {
|
|
812
|
-
p.log.step(`Building app in ${projectRoot}`);
|
|
813
|
-
await this.config.runCommand('build', [
|
|
814
|
-
...this.buildCommandArgv(projectRoot, flags),
|
|
815
|
-
...(this.isVerbose() ? ['--verbose'] : []),
|
|
816
|
-
]);
|
|
817
|
-
}
|
|
818
|
-
p.log.info(`NocoBase app is ready at ${projectRoot}`);
|
|
819
|
-
return projectRoot;
|
|
820
|
-
}
|
|
821
|
-
async download() {
|
|
822
|
-
const { flags } = await this.parse(Download);
|
|
823
|
-
this._flags = flags;
|
|
824
|
-
applyCliLocale(this._flags.locale);
|
|
825
|
-
setVerboseMode(Boolean(flags.verbose));
|
|
826
|
-
if (!flags['no-intro']) {
|
|
827
|
-
p.intro('Get NocoBase');
|
|
828
|
-
}
|
|
829
|
-
const resolved = await this.resolveDownloadFlags(flags);
|
|
830
|
-
const source = resolved.source;
|
|
831
|
-
this.startPreparationTask(`Preparing download from ${downloadSourceLabel(source)}`);
|
|
832
|
-
try {
|
|
833
|
-
switch (source) {
|
|
834
|
-
case 'npm': {
|
|
835
|
-
const projectRoot = await this.downloadFromNpm(resolved);
|
|
836
|
-
return { resolved, projectRoot };
|
|
837
|
-
}
|
|
838
|
-
case 'docker': {
|
|
839
|
-
await this.downloadFromDocker(resolved);
|
|
840
|
-
return { resolved, projectRoot: undefined };
|
|
841
|
-
}
|
|
842
|
-
case 'git': {
|
|
843
|
-
const projectRoot = await this.downloadFromGit(resolved);
|
|
844
|
-
return { resolved, projectRoot };
|
|
845
|
-
}
|
|
846
|
-
default:
|
|
847
|
-
this.error(`Unsupported download source: ${resolved.source}`);
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
finally {
|
|
851
|
-
this.finishPreparationTask();
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
|
-
async run() {
|
|
855
|
-
try {
|
|
856
|
-
const result = await this.download();
|
|
857
|
-
p.outro(`Download completed via ${downloadSourceLabel(result.resolved.source)}.`);
|
|
858
|
-
return result;
|
|
859
|
-
}
|
|
860
|
-
catch (error) {
|
|
861
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
862
|
-
this.error(formatDownloadFailure(message, this.isVerbose()));
|
|
863
|
-
}
|
|
864
|
-
}
|
|
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;
|
|
865
13
|
}
|