@nocobase/cli 2.2.0-beta.1 → 2.2.0-beta.11
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/assets/env-proxy/nginx/snippets/proxy-location.conf +1 -0
- package/bin/early-locale.js +89 -0
- package/bin/node-version.js +35 -0
- package/bin/run.js +9 -0
- package/bin/windows-admin.js +60 -0
- package/dist/commands/app/destroy.js +4 -3
- package/dist/commands/app/restart.js +38 -0
- package/dist/commands/app/shared.js +49 -3
- package/dist/commands/app/start.js +95 -0
- package/dist/commands/app/upgrade.js +11 -0
- package/dist/commands/env/info.js +11 -1
- package/dist/commands/examples/prompts-stages.js +2 -2
- package/dist/commands/examples/prompts-test.js +2 -2
- package/dist/commands/init.js +33 -11
- package/dist/commands/install.js +159 -107
- package/dist/commands/license/activate.js +4 -1
- package/dist/commands/license/shared.js +24 -15
- package/dist/commands/proxy/caddy/generate.js +93 -7
- package/dist/commands/proxy/nginx/generate.js +98 -7
- package/dist/commands/revision/create.js +1 -1
- package/dist/commands/self/check.js +1 -1
- package/dist/commands/self/update.js +4 -4
- package/dist/commands/skills/check.js +4 -5
- package/dist/commands/skills/install.js +18 -1
- package/dist/commands/skills/update.js +19 -4
- package/dist/commands/source/dev.js +9 -5
- package/dist/commands/source/download.js +85 -16
- package/dist/lib/api-command-compat.js +51 -8
- package/dist/lib/app-managed-resources.js +104 -5
- package/dist/lib/auth-store.js +102 -12
- package/dist/lib/cli-config.js +73 -1
- package/dist/lib/docker-image.js +94 -6
- package/dist/lib/env-auth.js +291 -45
- package/dist/lib/env-config.js +11 -0
- package/dist/lib/env-proxy-config.js +48 -0
- package/dist/lib/env-proxy.js +164 -58
- package/dist/lib/hook-script.js +160 -0
- package/dist/lib/prompt-catalog-terminal.js +32 -19
- package/dist/lib/prompt-validators.js +1 -1
- package/dist/lib/prompt-web-ui.js +20 -13
- package/dist/lib/proxy-caddy.js +77 -9
- package/dist/lib/proxy-nginx.js +71 -11
- package/dist/lib/run-npm.js +4 -0
- package/dist/lib/self-manager.js +254 -46
- package/dist/lib/skills-manager.js +116 -23
- package/dist/lib/source-publish.js +2 -2
- package/dist/lib/startup-update.js +1 -1
- package/dist/locale/en-US.json +49 -43
- package/dist/locale/zh-CN.json +49 -43
- package/package.json +8 -2
- package/scripts/build.mjs +0 -34
- package/scripts/clean.mjs +0 -9
- package/tsconfig.json +0 -19
package/dist/lib/auth-store.js
CHANGED
|
@@ -11,7 +11,9 @@ import path from 'node:path';
|
|
|
11
11
|
import { resolveAppPublicPath } from './app-public-path.js';
|
|
12
12
|
import { resolveCliHomeDir, resolveConfiguredEnvPath, resolveEnvRelativePath } from './cli-home.js';
|
|
13
13
|
import { normalizeCliLocale } from './cli-locale.js';
|
|
14
|
+
import { normalizeEnvProxyConfig, normalizeEnvProxyProviderConfig, } from './env-proxy-config.js';
|
|
14
15
|
import { inferConfiguredAppPathFromLegacyConfig, resolveConfiguredAppPath, resolveConfiguredSourcePath, resolveConfiguredStoragePath, } from './env-paths.js';
|
|
16
|
+
import { ENV_CONFIG_SCHEMA_VERSION, normalizeEnvConfigSchemaVersion } from './env-config.js';
|
|
15
17
|
import { cleanupCurrentSessionAfterEnvRemoval, resolveEffectiveCurrentEnv, setSessionCurrentEnv, } from './session-store.js';
|
|
16
18
|
function normalizeStoredEnvKind(value) {
|
|
17
19
|
const kind = String(value ?? '').trim();
|
|
@@ -76,14 +78,18 @@ function normalizeEnvConfigEntry(entry) {
|
|
|
76
78
|
if (!entry) {
|
|
77
79
|
return entry;
|
|
78
80
|
}
|
|
79
|
-
const { kind: _kind, apiBaseUrl: _apiBaseUrl, baseUrl: _baseUrl, apibaseUrl: _legacyApiBaseUrl, ...rest } = entry;
|
|
81
|
+
const { kind: _kind, apiBaseUrl: _apiBaseUrl, baseUrl: _baseUrl, apibaseUrl: _legacyApiBaseUrl, schemaVersion: _schemaVersion, ...rest } = entry;
|
|
80
82
|
const normalizedKind = resolveEnvKind(entry);
|
|
81
83
|
const apiBaseUrl = readEnvApiBaseUrl(entry);
|
|
84
|
+
const schemaVersion = normalizeEnvConfigSchemaVersion(entry.schemaVersion);
|
|
85
|
+
const proxy = normalizeEnvProxyConfig(entry.proxy);
|
|
82
86
|
return {
|
|
83
87
|
...rest,
|
|
88
|
+
...(schemaVersion ? { schemaVersion } : {}),
|
|
84
89
|
...(normalizedKind ? { kind: normalizedKind } : {}),
|
|
85
90
|
...(apiBaseUrl !== undefined ? { apiBaseUrl } : {}),
|
|
86
91
|
...(normalizeOptionalString(entry.appPublicPath) ? { appPublicPath: resolveAppPublicPath(entry.appPublicPath) } : {}),
|
|
92
|
+
...(proxy ? { proxy } : {}),
|
|
87
93
|
};
|
|
88
94
|
}
|
|
89
95
|
function normalizeAuthConfig(config) {
|
|
@@ -96,6 +102,17 @@ function normalizeAuthConfig(config) {
|
|
|
96
102
|
? settings.log.retentionDays
|
|
97
103
|
: undefined;
|
|
98
104
|
const logEnabled = typeof settings.log?.enabled === 'boolean' ? settings.log.enabled : undefined;
|
|
105
|
+
const hasBinSettings = settings.bin?.docker ||
|
|
106
|
+
settings.bin?.caddy ||
|
|
107
|
+
settings.bin?.git ||
|
|
108
|
+
settings.bin?.nginx ||
|
|
109
|
+
settings.bin?.pnpm ||
|
|
110
|
+
settings.bin?.yarn;
|
|
111
|
+
const hasProxySettings = settings.proxy?.nbCliRoot ||
|
|
112
|
+
settings.proxy?.caddyDriver ||
|
|
113
|
+
settings.proxy?.nginxDriver ||
|
|
114
|
+
settings.proxy?.upstreamHost ||
|
|
115
|
+
settings.proxy?.host;
|
|
99
116
|
return {
|
|
100
117
|
name: config.name || config.dockerResourcePrefix,
|
|
101
118
|
settings: {
|
|
@@ -111,31 +128,35 @@ function normalizeAuthConfig(config) {
|
|
|
111
128
|
...(updatePolicy ? { update: { policy: updatePolicy } } : {}),
|
|
112
129
|
...(settings.license?.pkgUrl ? { license: { pkgUrl: normalizeOptionalString(settings.license.pkgUrl) } } : {}),
|
|
113
130
|
...(settings.docker?.network || settings.docker?.containerPrefix
|
|
131
|
+
|| settings.docker?.nbImageRegistry || settings.docker?.nbImageVariant
|
|
114
132
|
? {
|
|
115
133
|
docker: {
|
|
116
134
|
...(settings.docker?.network ? { network: normalizeOptionalString(settings.docker.network) } : {}),
|
|
117
135
|
...(settings.docker?.containerPrefix
|
|
118
136
|
? { containerPrefix: normalizeOptionalString(settings.docker.containerPrefix) }
|
|
119
137
|
: {}),
|
|
138
|
+
...(settings.docker?.nbImageRegistry
|
|
139
|
+
? { nbImageRegistry: normalizeOptionalString(settings.docker.nbImageRegistry) }
|
|
140
|
+
: {}),
|
|
141
|
+
...(settings.docker?.nbImageVariant
|
|
142
|
+
? { nbImageVariant: normalizeOptionalString(settings.docker.nbImageVariant) }
|
|
143
|
+
: {}),
|
|
120
144
|
},
|
|
121
145
|
}
|
|
122
146
|
: {}),
|
|
123
|
-
...(
|
|
147
|
+
...(hasBinSettings
|
|
124
148
|
? {
|
|
125
149
|
bin: {
|
|
126
150
|
...(settings.bin?.docker ? { docker: normalizeOptionalString(settings.bin.docker) } : {}),
|
|
127
151
|
...(settings.bin?.caddy ? { caddy: normalizeOptionalString(settings.bin.caddy) } : {}),
|
|
128
152
|
...(settings.bin?.git ? { git: normalizeOptionalString(settings.bin.git) } : {}),
|
|
129
153
|
...(settings.bin?.nginx ? { nginx: normalizeOptionalString(settings.bin.nginx) } : {}),
|
|
154
|
+
...(settings.bin?.pnpm ? { pnpm: normalizeOptionalString(settings.bin.pnpm) } : {}),
|
|
130
155
|
...(settings.bin?.yarn ? { yarn: normalizeOptionalString(settings.bin.yarn) } : {}),
|
|
131
156
|
},
|
|
132
157
|
}
|
|
133
158
|
: {}),
|
|
134
|
-
...(
|
|
135
|
-
settings.proxy?.caddyDriver ||
|
|
136
|
-
settings.proxy?.nginxDriver ||
|
|
137
|
-
settings.proxy?.upstreamHost ||
|
|
138
|
-
settings.proxy?.host
|
|
159
|
+
...(hasProxySettings
|
|
139
160
|
? {
|
|
140
161
|
proxy: {
|
|
141
162
|
...(settings.proxy?.nbCliRoot ? { nbCliRoot: normalizeOptionalString(settings.proxy.nbCliRoot) } : {}),
|
|
@@ -366,7 +387,13 @@ function areAuthConfigsEquivalent(left, right) {
|
|
|
366
387
|
async function writeEnv(envName, updater, options = {}) {
|
|
367
388
|
const config = await loadExactAuthConfig(options);
|
|
368
389
|
const previous = config.envs[envName];
|
|
369
|
-
|
|
390
|
+
const next = updater(previous);
|
|
391
|
+
config.envs[envName] = {
|
|
392
|
+
...next,
|
|
393
|
+
schemaVersion: normalizeEnvConfigSchemaVersion(next.schemaVersion) ??
|
|
394
|
+
normalizeEnvConfigSchemaVersion(previous?.schemaVersion) ??
|
|
395
|
+
ENV_CONFIG_SCHEMA_VERSION,
|
|
396
|
+
};
|
|
370
397
|
await saveAuthConfig(config, options);
|
|
371
398
|
}
|
|
372
399
|
function normalizeConfiguredAuthType(value) {
|
|
@@ -377,18 +404,19 @@ export function resolveConfiguredAuthType(config) {
|
|
|
377
404
|
}
|
|
378
405
|
export async function upsertEnv(envName, config, options = {}) {
|
|
379
406
|
await writeEnv(envName, (previous) => {
|
|
380
|
-
const { apiBaseUrl: _apiBaseUrl, baseUrl: _baseUrl, apibaseUrl: _legacyApiBaseUrl, accessToken, authType, authUsername, ...rest } = config;
|
|
407
|
+
const { apiBaseUrl: _apiBaseUrl, baseUrl: _baseUrl, apibaseUrl: _legacyApiBaseUrl, accessToken, authType, authUsername, schemaVersion, ...rest } = config;
|
|
381
408
|
const nextApiBaseUrl = readEnvApiBaseUrl(config);
|
|
382
409
|
const previousApiBaseUrl = readEnvApiBaseUrl(previous);
|
|
383
410
|
const baseUrlChanged = previousApiBaseUrl !== nextApiBaseUrl;
|
|
384
411
|
const previousAuthType = resolveConfiguredAuthType(previous);
|
|
385
412
|
const requestedAuthType = normalizeConfiguredAuthType(authType);
|
|
386
|
-
const
|
|
413
|
+
const nextAccessToken = normalizeOptionalString(accessToken);
|
|
414
|
+
const nextAuthType = requestedAuthType ?? (nextAccessToken ? 'token' : previousAuthType);
|
|
387
415
|
const nextAuthUsername = nextAuthType === 'basic' ? normalizeOptionalString(authUsername) ?? previous?.authUsername : undefined;
|
|
388
|
-
const nextAuth =
|
|
416
|
+
const nextAuth = nextAccessToken
|
|
389
417
|
? {
|
|
390
418
|
type: 'token',
|
|
391
|
-
accessToken,
|
|
419
|
+
accessToken: nextAccessToken,
|
|
392
420
|
}
|
|
393
421
|
: nextAuthType === 'oauth' && !baseUrlChanged && previous?.auth?.type === 'oauth'
|
|
394
422
|
? previous.auth
|
|
@@ -396,6 +424,9 @@ export async function upsertEnv(envName, config, options = {}) {
|
|
|
396
424
|
const authChanged = !areAuthConfigsEquivalent(previous?.auth, nextAuth);
|
|
397
425
|
const authTypeChanged = previousAuthType !== nextAuthType;
|
|
398
426
|
const authUsernameChanged = previous?.authUsername !== nextAuthUsername;
|
|
427
|
+
const nextSchemaVersion = normalizeEnvConfigSchemaVersion(schemaVersion) ??
|
|
428
|
+
normalizeEnvConfigSchemaVersion(previous?.schemaVersion) ??
|
|
429
|
+
ENV_CONFIG_SCHEMA_VERSION;
|
|
399
430
|
return {
|
|
400
431
|
...previous,
|
|
401
432
|
apiBaseUrl: nextApiBaseUrl,
|
|
@@ -403,6 +434,7 @@ export async function upsertEnv(envName, config, options = {}) {
|
|
|
403
434
|
authUsername: nextAuthUsername,
|
|
404
435
|
auth: nextAuth,
|
|
405
436
|
...rest,
|
|
437
|
+
schemaVersion: nextSchemaVersion,
|
|
406
438
|
runtime: baseUrlChanged || authChanged || authTypeChanged || authUsernameChanged ? undefined : previous?.runtime,
|
|
407
439
|
};
|
|
408
440
|
}, options);
|
|
@@ -487,6 +519,64 @@ export async function setEnvRuntime(envName, runtime, options = {}) {
|
|
|
487
519
|
};
|
|
488
520
|
await saveAuthConfig(config, options);
|
|
489
521
|
}
|
|
522
|
+
export function resolveEnvProxyEntry(config, provider) {
|
|
523
|
+
const proxy = normalizeEnvProxyConfig(config?.proxy);
|
|
524
|
+
const resolved = {
|
|
525
|
+
...(proxy?.host ? { host: proxy.host } : {}),
|
|
526
|
+
...(proxy?.port !== undefined ? { port: proxy.port } : {}),
|
|
527
|
+
...((provider === 'nginx' ? proxy?.nginx : proxy?.caddy) ?? {}),
|
|
528
|
+
};
|
|
529
|
+
return Object.keys(resolved).length > 0 ? resolved : undefined;
|
|
530
|
+
}
|
|
531
|
+
export async function setEnvProxyEntry(envName, provider, entry, options = {}) {
|
|
532
|
+
await writeEnv(envName, (previous) => {
|
|
533
|
+
const currentProxy = normalizeEnvProxyConfig(previous?.proxy) ?? {};
|
|
534
|
+
const nextEntry = normalizeEnvProxyProviderConfig(entry);
|
|
535
|
+
const nextProxy = { ...currentProxy };
|
|
536
|
+
if (nextEntry && 'host' in nextEntry) {
|
|
537
|
+
const host = normalizeOptionalString(nextEntry.host);
|
|
538
|
+
if (host) {
|
|
539
|
+
nextProxy.host = host;
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
delete nextProxy.host;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
if (nextEntry && 'port' in nextEntry) {
|
|
546
|
+
const portValue = nextEntry.port;
|
|
547
|
+
const port = typeof portValue === 'number' && Number.isInteger(portValue) && portValue >= 1 && portValue <= 65535
|
|
548
|
+
? portValue
|
|
549
|
+
: undefined;
|
|
550
|
+
if (port !== undefined) {
|
|
551
|
+
nextProxy.port = port;
|
|
552
|
+
}
|
|
553
|
+
else {
|
|
554
|
+
delete nextProxy.port;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
const providerConfig = nextEntry && Object.keys(nextEntry).some((key) => key !== 'host' && key !== 'port')
|
|
558
|
+
? Object.fromEntries(Object.entries(nextEntry).filter(([key]) => key !== 'host' && key !== 'port'))
|
|
559
|
+
: undefined;
|
|
560
|
+
if (provider === 'nginx') {
|
|
561
|
+
if (providerConfig && Object.keys(providerConfig).length > 0) {
|
|
562
|
+
nextProxy.nginx = providerConfig;
|
|
563
|
+
}
|
|
564
|
+
else {
|
|
565
|
+
delete nextProxy.nginx;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
else if (providerConfig && Object.keys(providerConfig).length > 0) {
|
|
569
|
+
nextProxy.caddy = providerConfig;
|
|
570
|
+
}
|
|
571
|
+
else {
|
|
572
|
+
delete nextProxy.caddy;
|
|
573
|
+
}
|
|
574
|
+
return {
|
|
575
|
+
...previous,
|
|
576
|
+
proxy: nextProxy,
|
|
577
|
+
};
|
|
578
|
+
}, options);
|
|
579
|
+
}
|
|
490
580
|
export async function clearEnvRootSetup(envName, options = {}) {
|
|
491
581
|
const config = await loadExactAuthConfig(options);
|
|
492
582
|
const current = config.envs[envName];
|
package/dist/lib/cli-config.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { loadExactAuthConfig, saveAuthConfig } from './auth-store.js';
|
|
10
10
|
import { resolveCliHomeRoot, resolveDefaultConfigScope } from './cli-home.js';
|
|
11
11
|
import { CLI_LOCALE_FLAG_OPTIONS, normalizeCliLocale, resolveCliLocale } from './cli-locale.js';
|
|
12
|
+
import { DEFAULT_NB_IMAGE_REGISTRY, DEFAULT_NB_IMAGE_VARIANT, NB_IMAGE_REGISTRY_OPTIONS, NB_IMAGE_VARIANT_OPTIONS, normalizeNbImageRegistry, normalizeNbImageVariant, } from './docker-image.js';
|
|
12
13
|
export const DEFAULT_LICENSE_PKG_URL = 'https://pkg.nocobase.com/';
|
|
13
14
|
export const DEFAULT_DOCKER_NETWORK = 'nocobase';
|
|
14
15
|
export const DEFAULT_DOCKER_CONTAINER_PREFIX = 'nb';
|
|
@@ -16,6 +17,7 @@ export const DEFAULT_DOCKER_BIN = 'docker';
|
|
|
16
17
|
export const DEFAULT_CADDY_BIN = 'caddy';
|
|
17
18
|
export const DEFAULT_GIT_BIN = 'git';
|
|
18
19
|
export const DEFAULT_NGINX_BIN = 'nginx';
|
|
20
|
+
export const DEFAULT_PNPM_BIN = 'pnpm';
|
|
19
21
|
export const PROXY_PROVIDER_OPTIONS = ['nginx', 'caddy'];
|
|
20
22
|
export const DEFAULT_PROXY_PROVIDER = 'nginx';
|
|
21
23
|
export const NGINX_PROXY_DRIVER_OPTIONS = ['local', 'docker'];
|
|
@@ -36,10 +38,13 @@ export const SUPPORTED_CLI_CONFIG_KEYS = [
|
|
|
36
38
|
'license.pkg-url',
|
|
37
39
|
'docker.network',
|
|
38
40
|
'docker.container-prefix',
|
|
41
|
+
'nb-image-registry',
|
|
42
|
+
'nb-image-variant',
|
|
39
43
|
'bin.docker',
|
|
40
44
|
'bin.caddy',
|
|
41
45
|
'bin.git',
|
|
42
46
|
'bin.nginx',
|
|
47
|
+
'bin.pnpm',
|
|
43
48
|
'proxy.nb-cli-root',
|
|
44
49
|
'proxy.caddy-driver',
|
|
45
50
|
'proxy.nginx-driver',
|
|
@@ -127,7 +132,11 @@ function pruneSettings(config) {
|
|
|
127
132
|
delete config.settings?.license;
|
|
128
133
|
}
|
|
129
134
|
const docker = config.settings?.docker;
|
|
130
|
-
if (docker &&
|
|
135
|
+
if (docker &&
|
|
136
|
+
!trimValue(docker.network) &&
|
|
137
|
+
!trimValue(docker.containerPrefix) &&
|
|
138
|
+
!trimValue(docker.nbImageRegistry) &&
|
|
139
|
+
!trimValue(docker.nbImageVariant)) {
|
|
131
140
|
delete config.settings?.docker;
|
|
132
141
|
}
|
|
133
142
|
const bin = config.settings?.bin;
|
|
@@ -136,6 +145,7 @@ function pruneSettings(config) {
|
|
|
136
145
|
!trimValue(bin.caddy) &&
|
|
137
146
|
!trimValue(bin.git) &&
|
|
138
147
|
!trimValue(bin.nginx) &&
|
|
148
|
+
!trimValue(bin.pnpm) &&
|
|
139
149
|
!trimValue(bin.yarn)) {
|
|
140
150
|
delete config.settings?.bin;
|
|
141
151
|
}
|
|
@@ -179,6 +189,10 @@ export function getExplicitCliConfigValue(config, key) {
|
|
|
179
189
|
return trimValue(config.settings?.docker?.network);
|
|
180
190
|
case 'docker.container-prefix':
|
|
181
191
|
return trimValue(config.settings?.docker?.containerPrefix);
|
|
192
|
+
case 'nb-image-registry':
|
|
193
|
+
return normalizeNbImageRegistry(config.settings?.docker?.nbImageRegistry);
|
|
194
|
+
case 'nb-image-variant':
|
|
195
|
+
return normalizeNbImageVariant(config.settings?.docker?.nbImageVariant);
|
|
182
196
|
case 'bin.docker':
|
|
183
197
|
return trimValue(config.settings?.bin?.docker);
|
|
184
198
|
case 'bin.caddy':
|
|
@@ -187,6 +201,8 @@ export function getExplicitCliConfigValue(config, key) {
|
|
|
187
201
|
return trimValue(config.settings?.bin?.git);
|
|
188
202
|
case 'bin.nginx':
|
|
189
203
|
return trimValue(config.settings?.bin?.nginx);
|
|
204
|
+
case 'bin.pnpm':
|
|
205
|
+
return trimValue(config.settings?.bin?.pnpm);
|
|
190
206
|
case 'proxy.nb-cli-root':
|
|
191
207
|
return trimValue(config.settings?.proxy?.nbCliRoot);
|
|
192
208
|
case 'proxy.caddy-driver':
|
|
@@ -225,6 +241,12 @@ export function getEffectiveCliConfigValue(config, key) {
|
|
|
225
241
|
return trimValue(config.name) || DEFAULT_DOCKER_NETWORK;
|
|
226
242
|
case 'docker.container-prefix':
|
|
227
243
|
return trimValue(config.name) || DEFAULT_DOCKER_CONTAINER_PREFIX;
|
|
244
|
+
case 'nb-image-registry':
|
|
245
|
+
return explicit ?? (resolveCliLocale(undefined, { configuredLocale: trimValue(config.settings?.locale) }) === 'zh-CN'
|
|
246
|
+
? 'aliyun'
|
|
247
|
+
: DEFAULT_NB_IMAGE_REGISTRY);
|
|
248
|
+
case 'nb-image-variant':
|
|
249
|
+
return explicit ?? DEFAULT_NB_IMAGE_VARIANT;
|
|
228
250
|
case 'bin.docker':
|
|
229
251
|
return DEFAULT_DOCKER_BIN;
|
|
230
252
|
case 'bin.caddy':
|
|
@@ -233,6 +255,8 @@ export function getEffectiveCliConfigValue(config, key) {
|
|
|
233
255
|
return DEFAULT_GIT_BIN;
|
|
234
256
|
case 'bin.nginx':
|
|
235
257
|
return DEFAULT_NGINX_BIN;
|
|
258
|
+
case 'bin.pnpm':
|
|
259
|
+
return DEFAULT_PNPM_BIN;
|
|
236
260
|
case 'proxy.nb-cli-root':
|
|
237
261
|
return explicit ?? resolveCliHomeRoot();
|
|
238
262
|
case 'proxy.caddy-driver':
|
|
@@ -298,6 +322,20 @@ export function normalizeCliConfigValue(key, value) {
|
|
|
298
322
|
}
|
|
299
323
|
return driver;
|
|
300
324
|
}
|
|
325
|
+
if (key === 'nb-image-registry') {
|
|
326
|
+
const registry = normalizeNbImageRegistry(normalized);
|
|
327
|
+
if (!registry) {
|
|
328
|
+
throw new Error(`Config key "${key}" must be one of: ${NB_IMAGE_REGISTRY_OPTIONS.join(', ')}`);
|
|
329
|
+
}
|
|
330
|
+
return registry;
|
|
331
|
+
}
|
|
332
|
+
if (key === 'nb-image-variant') {
|
|
333
|
+
const variant = normalizeNbImageVariant(normalized);
|
|
334
|
+
if (!variant) {
|
|
335
|
+
throw new Error(`Config key "${key}" must be one of: ${NB_IMAGE_VARIANT_OPTIONS.join(', ')}`);
|
|
336
|
+
}
|
|
337
|
+
return variant;
|
|
338
|
+
}
|
|
301
339
|
return normalized;
|
|
302
340
|
}
|
|
303
341
|
export async function loadCliConfig(options = {}) {
|
|
@@ -363,6 +401,18 @@ export async function setCliConfigValue(key, value, options = {}) {
|
|
|
363
401
|
containerPrefix: normalized,
|
|
364
402
|
};
|
|
365
403
|
break;
|
|
404
|
+
case 'nb-image-registry':
|
|
405
|
+
config.settings.docker = {
|
|
406
|
+
...(config.settings.docker ?? {}),
|
|
407
|
+
nbImageRegistry: normalized,
|
|
408
|
+
};
|
|
409
|
+
break;
|
|
410
|
+
case 'nb-image-variant':
|
|
411
|
+
config.settings.docker = {
|
|
412
|
+
...(config.settings.docker ?? {}),
|
|
413
|
+
nbImageVariant: normalized,
|
|
414
|
+
};
|
|
415
|
+
break;
|
|
366
416
|
case 'bin.docker':
|
|
367
417
|
config.settings.bin = {
|
|
368
418
|
...(config.settings.bin ?? {}),
|
|
@@ -387,6 +437,12 @@ export async function setCliConfigValue(key, value, options = {}) {
|
|
|
387
437
|
nginx: normalized,
|
|
388
438
|
};
|
|
389
439
|
break;
|
|
440
|
+
case 'bin.pnpm':
|
|
441
|
+
config.settings.bin = {
|
|
442
|
+
...(config.settings.bin ?? {}),
|
|
443
|
+
pnpm: normalized,
|
|
444
|
+
};
|
|
445
|
+
break;
|
|
390
446
|
case 'proxy.nb-cli-root':
|
|
391
447
|
config.settings.proxy = {
|
|
392
448
|
...(config.settings.proxy ?? {}),
|
|
@@ -476,6 +532,16 @@ export async function deleteCliConfigValue(key, options = {}) {
|
|
|
476
532
|
delete config.settings.docker.containerPrefix;
|
|
477
533
|
}
|
|
478
534
|
break;
|
|
535
|
+
case 'nb-image-registry':
|
|
536
|
+
if (config.settings.docker) {
|
|
537
|
+
delete config.settings.docker.nbImageRegistry;
|
|
538
|
+
}
|
|
539
|
+
break;
|
|
540
|
+
case 'nb-image-variant':
|
|
541
|
+
if (config.settings.docker) {
|
|
542
|
+
delete config.settings.docker.nbImageVariant;
|
|
543
|
+
}
|
|
544
|
+
break;
|
|
479
545
|
case 'bin.docker':
|
|
480
546
|
if (config.settings.bin) {
|
|
481
547
|
delete config.settings.bin.docker;
|
|
@@ -496,6 +562,11 @@ export async function deleteCliConfigValue(key, options = {}) {
|
|
|
496
562
|
delete config.settings.bin.nginx;
|
|
497
563
|
}
|
|
498
564
|
break;
|
|
565
|
+
case 'bin.pnpm':
|
|
566
|
+
if (config.settings.bin) {
|
|
567
|
+
delete config.settings.bin.pnpm;
|
|
568
|
+
}
|
|
569
|
+
break;
|
|
499
570
|
case 'proxy.nb-cli-root':
|
|
500
571
|
if (config.settings.proxy) {
|
|
501
572
|
delete config.settings.proxy.nbCliRoot;
|
|
@@ -556,6 +627,7 @@ const CONFIGURABLE_COMMAND_KEYS = {
|
|
|
556
627
|
caddy: 'bin.caddy',
|
|
557
628
|
git: 'bin.git',
|
|
558
629
|
nginx: 'bin.nginx',
|
|
630
|
+
pnpm: 'bin.pnpm',
|
|
559
631
|
yarn: 'bin.yarn',
|
|
560
632
|
};
|
|
561
633
|
export function isConfigurableCommandName(value) {
|
package/dist/lib/docker-image.js
CHANGED
|
@@ -9,7 +9,30 @@
|
|
|
9
9
|
export const DEFAULT_DOCKER_REGISTRY = 'nocobase/nocobase';
|
|
10
10
|
export const DEFAULT_DOCKER_REGISTRY_ZH_CN = 'registry.cn-shanghai.aliyuncs.com/nocobase/nocobase';
|
|
11
11
|
export const DEFAULT_DOCKER_VERSION = 'alpha';
|
|
12
|
+
export const NB_IMAGE_REGISTRY_OPTIONS = ['dockerhub', 'aliyun'];
|
|
13
|
+
export const DEFAULT_NB_IMAGE_REGISTRY = 'dockerhub';
|
|
14
|
+
export const NB_IMAGE_VARIANT_OPTIONS = ['standard', 'no-nginx', 'full', 'full-no-nginx'];
|
|
15
|
+
export const DEFAULT_NB_IMAGE_VARIANT = 'full';
|
|
12
16
|
export const DOCKER_IMAGE_FULL_SUFFIX = '-full';
|
|
17
|
+
export const DOCKER_IMAGE_NO_NGINX_SUFFIX = '-no-nginx';
|
|
18
|
+
export const DOCKER_IMAGE_FULL_NO_NGINX_SUFFIX = '-full-no-nginx';
|
|
19
|
+
export const DEFAULT_KINGBASE_IMAGE = 'registry.cn-shanghai.aliyuncs.com/nocobase/kingbase:v009r001c001b0030_single_x86';
|
|
20
|
+
const OFFICIAL_DOCKER_REGISTRY_REPOSITORIES = {
|
|
21
|
+
dockerhub: DEFAULT_DOCKER_REGISTRY,
|
|
22
|
+
aliyun: DEFAULT_DOCKER_REGISTRY_ZH_CN,
|
|
23
|
+
};
|
|
24
|
+
const DEFAULT_BUILTIN_DB_IMAGES = {
|
|
25
|
+
postgres: 'postgres:16',
|
|
26
|
+
mysql: 'mysql:8',
|
|
27
|
+
mariadb: 'mariadb:11',
|
|
28
|
+
kingbase: DEFAULT_KINGBASE_IMAGE,
|
|
29
|
+
};
|
|
30
|
+
const ALIYUN_BUILTIN_DB_IMAGES = {
|
|
31
|
+
postgres: 'registry.cn-shanghai.aliyuncs.com/nocobase/postgres:16',
|
|
32
|
+
mysql: 'registry.cn-shanghai.aliyuncs.com/nocobase/mysql:8',
|
|
33
|
+
mariadb: 'registry.cn-shanghai.aliyuncs.com/nocobase/mariadb:11',
|
|
34
|
+
kingbase: DEFAULT_KINGBASE_IMAGE,
|
|
35
|
+
};
|
|
13
36
|
const OFFICIAL_FULL_IMAGE_REGISTRIES = new Set([
|
|
14
37
|
DEFAULT_DOCKER_REGISTRY,
|
|
15
38
|
DEFAULT_DOCKER_REGISTRY_ZH_CN,
|
|
@@ -17,21 +40,86 @@ const OFFICIAL_FULL_IMAGE_REGISTRIES = new Set([
|
|
|
17
40
|
function trimValue(value) {
|
|
18
41
|
return String(value ?? '').trim();
|
|
19
42
|
}
|
|
43
|
+
export function normalizeNbImageRegistry(value) {
|
|
44
|
+
const normalized = trimValue(value);
|
|
45
|
+
if (!normalized) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
return NB_IMAGE_REGISTRY_OPTIONS.includes(normalized)
|
|
49
|
+
? normalized
|
|
50
|
+
: undefined;
|
|
51
|
+
}
|
|
52
|
+
export function normalizeNbImageVariant(value) {
|
|
53
|
+
const normalized = trimValue(value);
|
|
54
|
+
if (!normalized) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
return NB_IMAGE_VARIANT_OPTIONS.includes(normalized)
|
|
58
|
+
? normalized
|
|
59
|
+
: undefined;
|
|
60
|
+
}
|
|
61
|
+
export function resolveOfficialDockerRegistry(value) {
|
|
62
|
+
const registry = normalizeNbImageRegistry(value) ?? DEFAULT_NB_IMAGE_REGISTRY;
|
|
63
|
+
return OFFICIAL_DOCKER_REGISTRY_REPOSITORIES[registry];
|
|
64
|
+
}
|
|
65
|
+
export function inferNbImageRegistryFromRepository(value) {
|
|
66
|
+
const repository = trimValue(value);
|
|
67
|
+
return Object.entries(OFFICIAL_DOCKER_REGISTRY_REPOSITORIES).find(([, candidate]) => candidate === repository)?.[0];
|
|
68
|
+
}
|
|
69
|
+
function hasKnownVariantSuffix(tag) {
|
|
70
|
+
return (tag.endsWith(DOCKER_IMAGE_FULL_NO_NGINX_SUFFIX) ||
|
|
71
|
+
tag.endsWith(DOCKER_IMAGE_NO_NGINX_SUFFIX) ||
|
|
72
|
+
tag.endsWith(DOCKER_IMAGE_FULL_SUFFIX));
|
|
73
|
+
}
|
|
20
74
|
export function shouldUseFullDockerImageTag(registry) {
|
|
21
75
|
return OFFICIAL_FULL_IMAGE_REGISTRIES.has(trimValue(registry));
|
|
22
76
|
}
|
|
23
|
-
export function normalizeDockerImageTag(registry, version) {
|
|
77
|
+
export function normalizeDockerImageTag(registry, version, options) {
|
|
24
78
|
const tag = trimValue(version) || DEFAULT_DOCKER_VERSION;
|
|
25
|
-
if (
|
|
79
|
+
if (hasKnownVariantSuffix(tag)) {
|
|
26
80
|
return tag;
|
|
27
81
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
82
|
+
const explicitVariant = normalizeNbImageVariant(options?.variant) ?? normalizeNbImageVariant(options?.defaultVariant);
|
|
83
|
+
const inferredVariant = shouldUseFullDockerImageTag(registry) ? DEFAULT_NB_IMAGE_VARIANT : 'standard';
|
|
84
|
+
const variant = explicitVariant ?? inferredVariant;
|
|
85
|
+
switch (variant) {
|
|
86
|
+
case 'standard':
|
|
87
|
+
return tag;
|
|
88
|
+
case 'no-nginx':
|
|
89
|
+
return `${tag}${DOCKER_IMAGE_NO_NGINX_SUFFIX}`;
|
|
90
|
+
case 'full':
|
|
91
|
+
return `${tag}${DOCKER_IMAGE_FULL_SUFFIX}`;
|
|
92
|
+
case 'full-no-nginx':
|
|
93
|
+
return `${tag}${DOCKER_IMAGE_FULL_NO_NGINX_SUFFIX}`;
|
|
94
|
+
}
|
|
31
95
|
}
|
|
32
96
|
export function resolveDockerImageRef(registry, version, options) {
|
|
33
97
|
const resolvedRegistry = trimValue(registry) || options?.defaultRegistry || DEFAULT_DOCKER_REGISTRY;
|
|
34
98
|
const rawVersion = trimValue(version) || options?.defaultVersion || DEFAULT_DOCKER_VERSION;
|
|
35
|
-
const normalizedTag = normalizeDockerImageTag(resolvedRegistry, rawVersion
|
|
99
|
+
const normalizedTag = normalizeDockerImageTag(resolvedRegistry, rawVersion, {
|
|
100
|
+
variant: options?.variant,
|
|
101
|
+
defaultVariant: options?.defaultVariant,
|
|
102
|
+
});
|
|
36
103
|
return `${resolvedRegistry}:${normalizedTag}`;
|
|
37
104
|
}
|
|
105
|
+
function extractDockerImageTag(imageRef) {
|
|
106
|
+
const ref = trimValue(imageRef);
|
|
107
|
+
const lastSlashIndex = ref.lastIndexOf('/');
|
|
108
|
+
const lastColonIndex = ref.lastIndexOf(':');
|
|
109
|
+
if (lastColonIndex <= lastSlashIndex) {
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
return ref.slice(lastColonIndex + 1) || undefined;
|
|
113
|
+
}
|
|
114
|
+
export function resolveDockerImageContainerPort(imageRef) {
|
|
115
|
+
const tag = extractDockerImageTag(imageRef);
|
|
116
|
+
return tag?.endsWith(DOCKER_IMAGE_NO_NGINX_SUFFIX) ? '13000' : '80';
|
|
117
|
+
}
|
|
118
|
+
export function resolveBuiltinDbImage(dbDialect, options) {
|
|
119
|
+
const dialect = trimValue(dbDialect) || 'postgres';
|
|
120
|
+
const configuredRegistry = normalizeNbImageRegistry(options?.registry) ??
|
|
121
|
+
inferNbImageRegistryFromRepository(options?.registry) ??
|
|
122
|
+
DEFAULT_NB_IMAGE_REGISTRY;
|
|
123
|
+
const defaults = configuredRegistry === 'aliyun' ? ALIYUN_BUILTIN_DB_IMAGES : DEFAULT_BUILTIN_DB_IMAGES;
|
|
124
|
+
return defaults[dialect] ?? defaults.postgres;
|
|
125
|
+
}
|