@nocobase/cli 2.1.11-test.9 → 2.1.12

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.
@@ -99,6 +99,17 @@ function normalizeAuthConfig(config) {
99
99
  ? settings.log.retentionDays
100
100
  : undefined;
101
101
  const logEnabled = typeof settings.log?.enabled === 'boolean' ? settings.log.enabled : undefined;
102
+ const hasBinSettings = settings.bin?.docker ||
103
+ settings.bin?.caddy ||
104
+ settings.bin?.git ||
105
+ settings.bin?.nginx ||
106
+ settings.bin?.pnpm ||
107
+ settings.bin?.yarn;
108
+ const hasProxySettings = settings.proxy?.nbCliRoot ||
109
+ settings.proxy?.caddyDriver ||
110
+ settings.proxy?.nginxDriver ||
111
+ settings.proxy?.upstreamHost ||
112
+ settings.proxy?.host;
102
113
  return {
103
114
  name: config.name || config.dockerResourcePrefix,
104
115
  settings: {
@@ -123,12 +134,7 @@ function normalizeAuthConfig(config) {
123
134
  },
124
135
  }
125
136
  : {}),
126
- ...(settings.bin?.docker ||
127
- settings.bin?.caddy ||
128
- settings.bin?.git ||
129
- settings.bin?.nginx ||
130
- settings.bin?.pnpm ||
131
- settings.bin?.yarn
137
+ ...(hasBinSettings
132
138
  ? {
133
139
  bin: {
134
140
  ...(settings.bin?.docker ? { docker: normalizeOptionalString(settings.bin.docker) } : {}),
@@ -140,11 +146,7 @@ function normalizeAuthConfig(config) {
140
146
  },
141
147
  }
142
148
  : {}),
143
- ...(settings.proxy?.nbCliRoot ||
144
- settings.proxy?.caddyDriver ||
145
- settings.proxy?.nginxDriver ||
146
- settings.proxy?.upstreamHost ||
147
- settings.proxy?.host
149
+ ...(hasProxySettings
148
150
  ? {
149
151
  proxy: {
150
152
  ...(settings.proxy?.nbCliRoot ? { nbCliRoot: normalizeOptionalString(settings.proxy.nbCliRoot) } : {}),
@@ -10,7 +10,7 @@ import { spawn } from 'node:child_process';
10
10
  import net from 'node:net';
11
11
  import { translateCli } from "./cli-locale.js";
12
12
  const API_BASE_URL_EXAMPLE = 'http://localhost:13000/api';
13
- const ENV_KEY_PATTERN = /^[A-Za-z0-9]+$/;
13
+ const ENV_KEY_PATTERN = /^[A-Za-z0-9_-]+$/;
14
14
  const APP_PUBLIC_PATH_PATTERN = /^\/(?:[A-Za-z0-9_-]+(?:\/[A-Za-z0-9_-]+)*)?\/?$/;
15
15
  const TCP_PORT_EXAMPLE = '13000';
16
16
  const API_BASE_URL_REQUEST_TIMEOUT_MS = 5_000;
@@ -7,6 +7,7 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
  import fs from 'node:fs';
10
+ import os from 'node:os';
10
11
  import path from 'node:path';
11
12
  import { fileURLToPath } from 'node:url';
12
13
  import { commandOutput, run } from './run-npm.js';
@@ -124,6 +125,7 @@ function detectInstallMethod(packageRoot, options = {}) {
124
125
  })) {
125
126
  return 'pnpm-global';
126
127
  }
128
+ // Best-effort fallback for environments where pnpm probes are unavailable.
127
129
  if (isPnpmGlobalPath(packageRoot)) {
128
130
  return 'pnpm-global';
129
131
  }
@@ -141,6 +143,39 @@ function isPnpmGlobalPath(packageRoot) {
141
143
  }
142
144
  return segments.slice(globalIndex + 2).includes('node_modules');
143
145
  }
146
+ function normalizePnpmGlobalNodeModulesRoot(pnpmGlobalRoot) {
147
+ const normalizedGlobalRoot = normalizePath(pnpmGlobalRoot);
148
+ return path.basename(normalizedGlobalRoot) === 'node_modules'
149
+ ? normalizedGlobalRoot
150
+ : path.join(normalizedGlobalRoot, 'node_modules');
151
+ }
152
+ function readSiblingPnpmGlobalNodeModulesRoots(pnpmGlobalRoot) {
153
+ const globalNodeModulesDir = normalizePnpmGlobalNodeModulesRoot(pnpmGlobalRoot);
154
+ const globalProjectDir = path.dirname(globalNodeModulesDir);
155
+ let entries;
156
+ try {
157
+ entries = fs.readdirSync(globalProjectDir);
158
+ }
159
+ catch {
160
+ return [];
161
+ }
162
+ return entries
163
+ .filter((entry) => {
164
+ if (entry === path.basename(globalNodeModulesDir)) {
165
+ return false;
166
+ }
167
+ try {
168
+ return fs.statSync(path.join(globalProjectDir, entry)).isDirectory();
169
+ }
170
+ catch {
171
+ return false;
172
+ }
173
+ })
174
+ .map((entry) => path.join(globalProjectDir, entry, 'node_modules'));
175
+ }
176
+ function readPnpmGlobalNodeModulesRoots(pnpmGlobalRoot) {
177
+ return [normalizePnpmGlobalNodeModulesRoot(pnpmGlobalRoot), ...readSiblingPnpmGlobalNodeModulesRoots(pnpmGlobalRoot)];
178
+ }
144
179
  function packageNameToPath(packageName) {
145
180
  return packageName.split('/').filter(Boolean);
146
181
  }
@@ -156,10 +191,7 @@ function isPnpmGlobalRootPath(pnpmGlobalRoot, packageRoot) {
156
191
  if (isSubPath(pnpmGlobalRoot, packageRoot)) {
157
192
  return true;
158
193
  }
159
- const normalizedGlobalRoot = normalizePath(pnpmGlobalRoot);
160
- const globalNodeModulesDir = path.basename(normalizedGlobalRoot) === 'node_modules'
161
- ? normalizedGlobalRoot
162
- : path.join(normalizedGlobalRoot, 'node_modules');
194
+ const globalNodeModulesDir = normalizePnpmGlobalNodeModulesRoot(pnpmGlobalRoot);
163
195
  const globalProjectDir = path.dirname(globalNodeModulesDir);
164
196
  if (!isSubPath(globalProjectDir, packageRoot)) {
165
197
  return false;
@@ -172,7 +204,7 @@ function isPnpmGlobalRootPath(pnpmGlobalRoot, packageRoot) {
172
204
  return segments.slice(pnpmStoreIndex + 1).includes('node_modules');
173
205
  }
174
206
  function isPnpmGlobalPackagePath(pnpmGlobalRoot, packageRoot, packageName) {
175
- return isSameRealPath(path.join(pnpmGlobalRoot, ...packageNameToPath(packageName)), packageRoot);
207
+ return readPnpmGlobalNodeModulesRoots(pnpmGlobalRoot).some((pnpmGlobalNodeModulesRoot) => isSameRealPath(path.join(pnpmGlobalNodeModulesRoot, ...packageNameToPath(packageName)), packageRoot));
176
208
  }
177
209
  function isPnpmGlobalBinProjectPath(pnpmGlobalBin, packageRoot, packageName) {
178
210
  const pnpmHome = path.dirname(normalizePath(pnpmGlobalBin));
@@ -188,9 +220,9 @@ function isPnpmGlobalBinProjectPath(pnpmGlobalBin, packageRoot, packageName) {
188
220
  return false;
189
221
  }
190
222
  return entries.some((entry) => {
191
- const pnpmGlobalRoot = path.join(globalDir, entry, 'node_modules');
192
- return isPnpmGlobalRootPath(pnpmGlobalRoot, packageRoot)
193
- || isPnpmGlobalPackagePath(pnpmGlobalRoot, packageRoot, packageName);
223
+ const pnpmGlobalRoot = path.join(globalDir, entry);
224
+ return (isPnpmGlobalRootPath(pnpmGlobalRoot, packageRoot)
225
+ || isPnpmGlobalPackagePath(pnpmGlobalRoot, packageRoot, packageName));
194
226
  });
195
227
  }
196
228
  function isPnpmGlobalInstallPath(options) {
@@ -217,9 +249,27 @@ function cleanCommandPath(value) {
217
249
  const trimmed = value.trim();
218
250
  return trimmed ? trimmed : undefined;
219
251
  }
252
+ function resolvePackageManagerProbeCwd() {
253
+ const candidates = [os.homedir(), os.tmpdir(), path.parse(process.cwd()).root];
254
+ for (const candidate of candidates) {
255
+ if (!candidate) {
256
+ continue;
257
+ }
258
+ try {
259
+ if (fs.statSync(candidate).isDirectory()) {
260
+ return candidate;
261
+ }
262
+ }
263
+ catch {
264
+ // Ignore invalid probe cwd candidates and continue to the next one.
265
+ }
266
+ }
267
+ return undefined;
268
+ }
220
269
  async function readGlobalPrefix(commandOutputFn) {
221
270
  try {
222
271
  return cleanCommandPath(await commandOutputFn('npm', ['prefix', '-g'], {
272
+ cwd: resolvePackageManagerProbeCwd(),
223
273
  errorName: 'npm prefix',
224
274
  }));
225
275
  }
@@ -230,6 +280,7 @@ async function readGlobalPrefix(commandOutputFn) {
230
280
  async function readPnpmGlobalBin(commandOutputFn) {
231
281
  try {
232
282
  return cleanCommandPath(await commandOutputFn('pnpm', ['bin', '-g'], {
283
+ cwd: resolvePackageManagerProbeCwd(),
233
284
  errorName: 'pnpm bin',
234
285
  }));
235
286
  }
@@ -240,6 +291,7 @@ async function readPnpmGlobalBin(commandOutputFn) {
240
291
  async function readPnpmGlobalRoot(commandOutputFn) {
241
292
  try {
242
293
  return cleanCommandPath(await commandOutputFn('pnpm', ['root', '-g'], {
294
+ cwd: resolvePackageManagerProbeCwd(),
243
295
  errorName: 'pnpm root',
244
296
  }));
245
297
  }
@@ -250,6 +302,7 @@ async function readPnpmGlobalRoot(commandOutputFn) {
250
302
  async function readYarnGlobalDir(commandOutputFn) {
251
303
  try {
252
304
  return cleanCommandPath(await commandOutputFn('yarn', ['global', 'dir'], {
305
+ cwd: resolvePackageManagerProbeCwd(),
253
306
  errorName: 'yarn global dir',
254
307
  }));
255
308
  }
@@ -260,6 +313,7 @@ async function readYarnGlobalDir(commandOutputFn) {
260
313
  async function readYarnGlobalBin(commandOutputFn) {
261
314
  try {
262
315
  return cleanCommandPath(await commandOutputFn('yarn', ['global', 'bin'], {
316
+ cwd: resolvePackageManagerProbeCwd(),
263
317
  errorName: 'yarn global bin',
264
318
  }));
265
319
  }
@@ -367,6 +421,7 @@ export async function inspectSelfStatus(options = {}) {
367
421
  const channel = options.channel && options.channel !== 'auto' ? options.channel : detectChannel(currentVersion);
368
422
  const commandOutputFn = options.commandOutputFn ?? commandOutput;
369
423
  const { installMethod, globalPrefix } = await inspectSelfInstall({
424
+ currentBinPath: options.currentBinPath,
370
425
  packageName,
371
426
  packageRoot,
372
427
  commandOutputFn,
@@ -68,7 +68,7 @@
68
68
  "unreachable": "Unable to connect to the API base URL. Check the address and make sure the server is reachable. Details: {{details}}"
69
69
  },
70
70
  "envKey": {
71
- "invalid": "Use letters and numbers only."
71
+ "invalid": "Use letters, numbers, hyphens, and underscores only."
72
72
  },
73
73
  "appPublicPath": {
74
74
  "invalid": "Use / or a slash-separated path like /nocobase/ or /foo-bar/baz_2/. Each path segment may contain letters, numbers, hyphens, and underscores only."
@@ -68,7 +68,7 @@
68
68
  "unreachable": "无法连接到该 API 地址,请检查地址是否正确,并确认服务可访问。详情:{{details}}"
69
69
  },
70
70
  "envKey": {
71
- "invalid": "仅支持字母和数字。"
71
+ "invalid": "仅支持字母、数字、中划线和下划线。"
72
72
  },
73
73
  "appPublicPath": {
74
74
  "invalid": "请输入 /,或类似 /nocobase/、/foo-bar/baz_2/ 这样的路径。每个路径段仅支持字母、数字、中划线和下划线。"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocobase/cli",
3
- "version": "2.1.11-test.9",
3
+ "version": "2.1.12",
4
4
  "description": "NocoBase Command Line Tool",
5
5
  "type": "module",
6
6
  "main": "dist/generated/command-registry.js",
@@ -142,5 +142,6 @@
142
142
  "repository": {
143
143
  "type": "git",
144
144
  "url": "git+https://github.com/nocobase/nocobase.git"
145
- }
145
+ },
146
+ "gitHead": "3a69ed089fbb5a3e8700c0134f83d654f0190d25"
146
147
  }