@nocobase/cli 2.2.0-beta.6 → 2.2.0-beta.7
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/dist/commands/install.js
CHANGED
|
@@ -15,7 +15,7 @@ import { appendAppPublicPath } from '../lib/app-public-path.js';
|
|
|
15
15
|
import { runPromptCatalog, } from "../lib/prompt-catalog.js";
|
|
16
16
|
import { applyCliLocale, localeText, resolveCliLocale, translateCli } from "../lib/cli-locale.js";
|
|
17
17
|
import { resolveConfiguredEnvPath, resolveDefaultConfigScope, resolveEnvRoot, resolveEnvRelativePath, } from '../lib/cli-home.js';
|
|
18
|
-
import { defaultDockerContainerPrefix, defaultDockerNetworkName } from '../lib/app-runtime.js';
|
|
18
|
+
import { defaultDockerContainerPrefix, defaultDockerNetworkName, managedAppLifecycleEnvVars, } from '../lib/app-runtime.js';
|
|
19
19
|
import { resolveDefaultApiHost, resolveDockerContainerPrefix, resolveDockerNetworkName } from '../lib/cli-config.js';
|
|
20
20
|
import { DEFAULT_DOCKER_VERSION, resolveDockerImageRef } from "../lib/docker-image.js";
|
|
21
21
|
import { findAvailableTcpPort, validateAppPublicPath, validateAvailableTcpPort, validateTcpPort, validateEnvKey, } from "../lib/prompt-validators.js";
|
|
@@ -1960,7 +1960,7 @@ export default class Install extends Command {
|
|
|
1960
1960
|
}
|
|
1961
1961
|
static resolveAbsoluteStoragePath(envName, appResults) {
|
|
1962
1962
|
const configuredStoragePath = resolveConfiguredStoragePathValue(appResults, envName);
|
|
1963
|
-
return resolveConfiguredEnvPath(configuredStoragePath) ?? resolveEnvRelativePath(defaultInstallStoragePath(envName));
|
|
1963
|
+
return (resolveConfiguredEnvPath(configuredStoragePath) ?? resolveEnvRelativePath(defaultInstallStoragePath(envName)));
|
|
1964
1964
|
}
|
|
1965
1965
|
async prepareHookScriptForInstall(params) {
|
|
1966
1966
|
const appPath = Install.resolveAbsoluteAppPath(params.envName, params.appResults);
|
|
@@ -2057,7 +2057,9 @@ export default class Install extends Command {
|
|
|
2057
2057
|
const dbDialect = String(params.dbResults.dbDialect ?? 'postgres').trim() || 'postgres';
|
|
2058
2058
|
const appKey = Install.resolveManagedAppKey(params.appResults.appKey);
|
|
2059
2059
|
const timeZone = Install.resolveManagedTimeZone(params.appResults.timeZone);
|
|
2060
|
+
const lifecycleEnvVars = managedAppLifecycleEnvVars();
|
|
2060
2061
|
const env = {
|
|
2062
|
+
...lifecycleEnvVars,
|
|
2061
2063
|
STORAGE_PATH: storagePath,
|
|
2062
2064
|
APP_PORT: String(params.appResults.appPort ?? DEFAULT_INSTALL_APP_PORT).trim() || DEFAULT_INSTALL_APP_PORT,
|
|
2063
2065
|
APP_KEY: appKey,
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { Command, Flags } from '@oclif/core';
|
|
10
10
|
import { ensureCrossEnvConfirmed, hasExplicitEnvSelection } from '../../lib/env-guard.js';
|
|
11
|
-
import { ensureLocalPostinstall } from '../../lib/app-managed-resources.js';
|
|
11
|
+
import { ensureLocalPostinstall, ensureNpmSourceDevDependencies } from '../../lib/app-managed-resources.js';
|
|
12
12
|
import { formatMissingManagedAppEnvMessage, resolveManagedAppRuntime, runLocalNocoBaseCommand, } from '../../lib/app-runtime.js';
|
|
13
|
+
import { findAvailableTcpPort } from '../../lib/prompt-validators.js';
|
|
13
14
|
import { announceTargetEnv, failTask, printInfo, startTask, succeedTask } from '../../lib/ui.js';
|
|
14
15
|
function formatUnsupportedRuntimeMessage(kind, envName) {
|
|
15
16
|
if (kind === 'docker') {
|
|
@@ -129,10 +130,7 @@ export default class SourceDev extends Command {
|
|
|
129
130
|
this.error(formatUnsupportedRuntimeMessage(runtime.kind, runtime.envName));
|
|
130
131
|
}
|
|
131
132
|
announceTargetEnv(runtime.envName);
|
|
132
|
-
const devPort = flags.port ||
|
|
133
|
-
(runtime.env.appPort !== undefined && runtime.env.appPort !== null
|
|
134
|
-
? String(runtime.env.appPort).trim()
|
|
135
|
-
: undefined);
|
|
133
|
+
const devPort = flags.port?.trim() || (await findAvailableTcpPort());
|
|
136
134
|
const appUrl = appUrlForPort(devPort);
|
|
137
135
|
if (await isAppAlreadyRunning(appUrl)) {
|
|
138
136
|
this.error([
|
|
@@ -160,6 +158,12 @@ export default class SourceDev extends Command {
|
|
|
160
158
|
}
|
|
161
159
|
printInfo(`Starting NocoBase dev mode for "${runtime.envName}" from ${runtime.projectRoot}. Press Ctrl+C to stop.`);
|
|
162
160
|
try {
|
|
161
|
+
await ensureNpmSourceDevDependencies(runtime, {
|
|
162
|
+
onStartTask: startTask,
|
|
163
|
+
onSucceedTask: succeedTask,
|
|
164
|
+
onFailTask: failTask,
|
|
165
|
+
verbose: true,
|
|
166
|
+
});
|
|
163
167
|
await ensureLocalPostinstall(runtime, {
|
|
164
168
|
onStartTask: startTask,
|
|
165
169
|
onSucceedTask: succeedTask,
|
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
|
-
import {
|
|
9
|
+
import { existsSync } from 'node:fs';
|
|
10
|
+
import path from 'node:path';
|
|
11
|
+
import { mkdir, readFile, readdir, writeFile } from 'node:fs/promises';
|
|
10
12
|
import { resolveAppPublicPath } from './app-public-path.js';
|
|
11
13
|
import { dockerContainerExists, managedAppLifecycleEnvVars, runLocalNocoBaseCommand, startDockerContainer, } from './app-runtime.js';
|
|
12
14
|
import { deriveBuiltinDbConnection, resolveBuiltinDbConnection } from './builtin-db.js';
|
|
@@ -91,6 +93,15 @@ function formatLocalPostinstallFailure(envName, message) {
|
|
|
91
93
|
`Details: ${message}`,
|
|
92
94
|
].join('\n');
|
|
93
95
|
}
|
|
96
|
+
function formatNpmSourceDevDependenciesFailure(envName, projectRoot, message) {
|
|
97
|
+
return [
|
|
98
|
+
`Couldn't prepare source dev dependencies for "${envName}".`,
|
|
99
|
+
'`nb source dev` requires @nocobase/devtools in npm source envs.',
|
|
100
|
+
`Source directory: ${projectRoot}`,
|
|
101
|
+
`Run \`cd ${projectRoot} && yarn install\` after fixing package.json, then try again.`,
|
|
102
|
+
`Details: ${message}`,
|
|
103
|
+
].join('\n');
|
|
104
|
+
}
|
|
94
105
|
function formatSavedDockerSettingsIncomplete(envName, missing) {
|
|
95
106
|
return [
|
|
96
107
|
`Can't start NocoBase for "${envName}" yet.`,
|
|
@@ -115,6 +126,45 @@ async function localProjectHasFiles(projectRoot) {
|
|
|
115
126
|
return false;
|
|
116
127
|
}
|
|
117
128
|
}
|
|
129
|
+
function isRecord(value) {
|
|
130
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
131
|
+
}
|
|
132
|
+
async function readPackageJson(projectRoot) {
|
|
133
|
+
const packageJsonPath = path.join(projectRoot, 'package.json');
|
|
134
|
+
const content = await readFile(packageJsonPath, 'utf-8');
|
|
135
|
+
const parsed = JSON.parse(content);
|
|
136
|
+
if (!isRecord(parsed)) {
|
|
137
|
+
throw new Error(`${packageJsonPath} must contain a JSON object.`);
|
|
138
|
+
}
|
|
139
|
+
return parsed;
|
|
140
|
+
}
|
|
141
|
+
function getStringDependency(packageJson, section, packageName) {
|
|
142
|
+
const dependencies = packageJson[section];
|
|
143
|
+
if (!isRecord(dependencies)) {
|
|
144
|
+
return undefined;
|
|
145
|
+
}
|
|
146
|
+
const version = dependencies[packageName];
|
|
147
|
+
return typeof version === 'string' && version.trim() ? version.trim() : undefined;
|
|
148
|
+
}
|
|
149
|
+
function ensureDevDependencies(packageJson) {
|
|
150
|
+
const devDependencies = packageJson.devDependencies;
|
|
151
|
+
if (devDependencies === undefined) {
|
|
152
|
+
const next = {};
|
|
153
|
+
packageJson.devDependencies = next;
|
|
154
|
+
return next;
|
|
155
|
+
}
|
|
156
|
+
if (!isRecord(devDependencies)) {
|
|
157
|
+
throw new Error('package.json devDependencies must be an object.');
|
|
158
|
+
}
|
|
159
|
+
return devDependencies;
|
|
160
|
+
}
|
|
161
|
+
function hasNpmSourceDevtools(projectRoot) {
|
|
162
|
+
return existsSync(path.join(projectRoot, 'node_modules', '@nocobase', 'devtools', 'package.json'));
|
|
163
|
+
}
|
|
164
|
+
function npmRegistryEnv(runtime) {
|
|
165
|
+
const npmRegistry = String(runtime.env.config?.npmRegistry ?? '').trim();
|
|
166
|
+
return npmRegistry ? { npm_config_registry: npmRegistry } : undefined;
|
|
167
|
+
}
|
|
118
168
|
export async function buildSavedDockerRunArgs(runtime, options) {
|
|
119
169
|
const config = runtime.env.config ?? {};
|
|
120
170
|
const storagePath = trimValue(resolveConfiguredStoragePath(config));
|
|
@@ -345,3 +395,43 @@ export async function ensureLocalPostinstall(runtime, options) {
|
|
|
345
395
|
throw new Error(formatLocalPostinstallFailure(runtime.envName, error instanceof Error ? error.message : String(error)));
|
|
346
396
|
}
|
|
347
397
|
}
|
|
398
|
+
export async function ensureNpmSourceDevDependencies(runtime, options) {
|
|
399
|
+
if (runtime.source !== 'npm') {
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
let taskStarted = false;
|
|
403
|
+
try {
|
|
404
|
+
const packageJson = await readPackageJson(runtime.projectRoot);
|
|
405
|
+
const appVersion = getStringDependency(packageJson, 'dependencies', '@nocobase/app');
|
|
406
|
+
const devtoolsVersion = getStringDependency(packageJson, 'devDependencies', '@nocobase/devtools');
|
|
407
|
+
let updatedPackageJson = false;
|
|
408
|
+
if (!devtoolsVersion) {
|
|
409
|
+
if (!appVersion) {
|
|
410
|
+
throw new Error('Cannot determine @nocobase/devtools version because dependencies["@nocobase/app"] is missing.');
|
|
411
|
+
}
|
|
412
|
+
const devDependencies = ensureDevDependencies(packageJson);
|
|
413
|
+
devDependencies['@nocobase/devtools'] = appVersion;
|
|
414
|
+
updatedPackageJson = true;
|
|
415
|
+
await writeFile(path.join(runtime.projectRoot, 'package.json'), `${JSON.stringify(packageJson, null, 2)}\n`, 'utf-8');
|
|
416
|
+
}
|
|
417
|
+
const needsInstall = updatedPackageJson || !hasNpmSourceDevtools(runtime.projectRoot);
|
|
418
|
+
if (!needsInstall) {
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
options?.onStartTask?.(`Preparing source dev dependencies for "${runtime.envName}"...`);
|
|
422
|
+
taskStarted = true;
|
|
423
|
+
await run('yarn', ['install'], {
|
|
424
|
+
cwd: runtime.projectRoot,
|
|
425
|
+
env: npmRegistryEnv(runtime),
|
|
426
|
+
errorName: 'yarn install',
|
|
427
|
+
stdio: commandStdio(options?.verbose),
|
|
428
|
+
});
|
|
429
|
+
options?.onSucceedTask?.(`Source dev dependencies are ready for "${runtime.envName}".`);
|
|
430
|
+
}
|
|
431
|
+
catch (error) {
|
|
432
|
+
if (taskStarted) {
|
|
433
|
+
options?.onFailTask?.(`Failed to prepare source dev dependencies for "${runtime.envName}".`);
|
|
434
|
+
}
|
|
435
|
+
throw new Error(formatNpmSourceDevDependenciesFailure(runtime.envName, runtime.projectRoot, error instanceof Error ? error.message : String(error)));
|
|
436
|
+
}
|
|
437
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/cli",
|
|
3
|
-
"version": "2.2.0-beta.
|
|
3
|
+
"version": "2.2.0-beta.7",
|
|
4
4
|
"description": "NocoBase Command Line Tool",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/generated/command-registry.js",
|
|
@@ -143,5 +143,5 @@
|
|
|
143
143
|
"type": "git",
|
|
144
144
|
"url": "git+https://github.com/nocobase/nocobase.git"
|
|
145
145
|
},
|
|
146
|
-
"gitHead": "
|
|
146
|
+
"gitHead": "e6a3fa8963a73cd9ddfc1273d71b0012483e1ad8"
|
|
147
147
|
}
|