@nocobase/cli 2.2.0-alpha.2 → 2.2.0-alpha.4
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/app.conf.tpl +23 -0
- package/assets/env-proxy/nginx/nocobase.conf.tpl +5 -0
- package/assets/env-proxy/nginx/snippets/dist-location.conf +5 -0
- package/assets/env-proxy/nginx/snippets/gzip.conf +17 -0
- package/assets/env-proxy/nginx/snippets/log-format-http.conf +13 -0
- package/assets/env-proxy/nginx/snippets/maps-http.conf +14 -0
- package/assets/env-proxy/nginx/snippets/mime-types.conf +98 -0
- package/assets/env-proxy/nginx/snippets/proxy-location.conf +17 -0
- package/assets/env-proxy/nginx/snippets/spa-location.conf +6 -0
- package/assets/env-proxy/nginx/snippets/uploads-location.conf +21 -0
- package/dist/commands/install.js +0 -10
- package/dist/commands/proxy/caddy/generate.js +82 -4
- package/dist/commands/proxy/nginx/generate.js +87 -4
- package/dist/lib/app-managed-resources.js +0 -2
- package/dist/lib/env-auth.js +291 -45
- package/dist/lib/env-proxy.js +138 -58
- package/dist/lib/prompt-validators.js +1 -1
- package/dist/lib/proxy-caddy.js +24 -2
- package/dist/lib/proxy-nginx.js +18 -4
- package/dist/locale/en-US.json +2 -2
- package/dist/locale/zh-CN.json +2 -2
- package/package.json +3 -2
package/dist/lib/env-proxy.js
CHANGED
|
@@ -259,7 +259,7 @@ export function applyEnvProxyAppEntryOptions(content, provider, options) {
|
|
|
259
259
|
function toCaddyPathMatcher(prefixPath) {
|
|
260
260
|
return `${prefixPath}*`;
|
|
261
261
|
}
|
|
262
|
-
export async function loadEnvProxySettings(runtime) {
|
|
262
|
+
export async function loadEnvProxySettings(runtime, options) {
|
|
263
263
|
const { envFilePath, envValues } = await readManagedRuntimeEnvValues(runtime);
|
|
264
264
|
const appPublicPath = resolveAppPublicPath(runtime.env.config.appPublicPath || envValues.APP_PUBLIC_PATH || DEFAULT_APP_PUBLIC_PATH);
|
|
265
265
|
const apiClientShareToken = /^true$/i.test(String(envValues.API_CLIENT_SHARE_TOKEN ?? '').trim());
|
|
@@ -274,7 +274,9 @@ export async function loadEnvProxySettings(runtime) {
|
|
|
274
274
|
wsPath: prefixRuntimePath(appPublicPath, envValues.WS_PATH || DEFAULT_WS_PATH),
|
|
275
275
|
pluginStaticsPath: prefixRuntimePath(appPublicPath, envValues.PLUGIN_STATICS_PATH || DEFAULT_PLUGIN_STATICS_PATH, { trailingSlash: true }),
|
|
276
276
|
modernClientPrefix: normalizeModernClientPrefix(envValues.APP_MODERN_CLIENT_PREFIX),
|
|
277
|
-
cdnBaseUrl: trimValue(
|
|
277
|
+
cdnBaseUrl: trimValue(options?.cdnBaseUrl) ??
|
|
278
|
+
trimValue(runtime.env.envVars?.CDN_BASE_URL) ??
|
|
279
|
+
trimValue(envValues.CDN_BASE_URL),
|
|
278
280
|
apiClientStoragePrefix: trimValue(envValues.API_CLIENT_STORAGE_PREFIX) ?? DEFAULT_API_CLIENT_STORAGE_PREFIX,
|
|
279
281
|
apiClientStorageType: trimValue(envValues.API_CLIENT_STORAGE_TYPE) ?? DEFAULT_API_CLIENT_STORAGE_TYPE,
|
|
280
282
|
apiClientShareToken,
|
|
@@ -284,6 +286,40 @@ export async function loadEnvProxySettings(runtime) {
|
|
|
284
286
|
},
|
|
285
287
|
};
|
|
286
288
|
}
|
|
289
|
+
function createManualProxyEnvSettings(input) {
|
|
290
|
+
const appPublicPath = resolveAppPublicPath(input.appPublicPath || DEFAULT_APP_PUBLIC_PATH);
|
|
291
|
+
return {
|
|
292
|
+
appPublicPath,
|
|
293
|
+
apiBasePath: prefixRuntimePath(appPublicPath, DEFAULT_API_BASE_PATH, {
|
|
294
|
+
trailingSlash: true,
|
|
295
|
+
}),
|
|
296
|
+
distPath: resolveDistPublicPath(appPublicPath),
|
|
297
|
+
wsPath: prefixRuntimePath(appPublicPath, DEFAULT_WS_PATH),
|
|
298
|
+
pluginStaticsPath: prefixRuntimePath(appPublicPath, DEFAULT_PLUGIN_STATICS_PATH, {
|
|
299
|
+
trailingSlash: true,
|
|
300
|
+
}),
|
|
301
|
+
modernClientPrefix: DEFAULT_MODERN_CLIENT_PREFIX,
|
|
302
|
+
cdnBaseUrl: trimValue(input.cdnBaseUrl),
|
|
303
|
+
apiClientStoragePrefix: DEFAULT_API_CLIENT_STORAGE_PREFIX,
|
|
304
|
+
apiClientStorageType: DEFAULT_API_CLIENT_STORAGE_TYPE,
|
|
305
|
+
apiClientShareToken: false,
|
|
306
|
+
wsUrl: '',
|
|
307
|
+
esmCdnBaseUrl: DEFAULT_ESM_CDN_BASE_URL,
|
|
308
|
+
esmCdnSuffix: '',
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
function normalizeManualNginxInput(input) {
|
|
312
|
+
return {
|
|
313
|
+
name: String(input.name).trim(),
|
|
314
|
+
appPort: String(input.appPort).trim(),
|
|
315
|
+
storagePath: String(input.storagePath).trim(),
|
|
316
|
+
distRootPath: String(input.distRootPath).trim(),
|
|
317
|
+
runtimeVersion: String(input.runtimeVersion).trim(),
|
|
318
|
+
appPublicPath: trimValue(input.appPublicPath),
|
|
319
|
+
upstreamHost: trimValue(input.upstreamHost),
|
|
320
|
+
cdnBaseUrl: trimValue(input.cdnBaseUrl),
|
|
321
|
+
};
|
|
322
|
+
}
|
|
287
323
|
async function parseVersionFromPackageJson(content, sourceLabel) {
|
|
288
324
|
let parsed;
|
|
289
325
|
try {
|
|
@@ -525,65 +561,91 @@ function buildNginxRuntimeConfig(context, variant) {
|
|
|
525
561
|
function buildCaddyRuntimeConfig(context, variant) {
|
|
526
562
|
return buildNginxRuntimeConfig(context, variant);
|
|
527
563
|
}
|
|
528
|
-
async function buildEnvProxyNginxRenderContext(
|
|
529
|
-
const apiPort = trimValue(runtime.env.appPort ?? runtime.env.config.appPort);
|
|
530
|
-
if (!apiPort) {
|
|
531
|
-
throw new Error(translateCli('commands.envProxy.errors.missingAppPort', { envName: runtime.envName }, {
|
|
532
|
-
fallback: `Missing appPort for env "${runtime.envName}". Save or update the app port before generating proxy config.`,
|
|
533
|
-
}));
|
|
534
|
-
}
|
|
535
|
-
const activeVersion = trimValue(await readDistClientActiveVersion(runtime.env.storagePath));
|
|
536
|
-
if (!activeVersion) {
|
|
537
|
-
throw new Error(translateCli('commands.envProxy.errors.missingVersion', { envName: runtime.envName }, {
|
|
538
|
-
fallback: `Couldn't determine the app version for env "${runtime.envName}". Run \`nb env update ${runtime.envName}\` and try again.`,
|
|
539
|
-
}));
|
|
540
|
-
}
|
|
541
|
-
const { envFilePath, settings } = await loadEnvProxySettings(runtime);
|
|
564
|
+
async function buildEnvProxyNginxRenderContext(source, options) {
|
|
542
565
|
const proxyHost = await resolveProxyUpstreamHost(options);
|
|
543
|
-
const backendUrl = `http://${proxyHost}:${apiPort}`;
|
|
544
|
-
const cdnBaseUrl = settings.cdnBaseUrl ?? buildDefaultCdnBaseUrl(settings.appPublicPath, activeVersion);
|
|
545
|
-
const entryDir = resolveEnvProxyEntryDir(
|
|
546
|
-
const publicDir = resolveEnvProxyNginxPublicOutputDir(
|
|
566
|
+
const backendUrl = `http://${proxyHost}:${source.apiPort}`;
|
|
567
|
+
const cdnBaseUrl = source.settings.cdnBaseUrl ?? buildDefaultCdnBaseUrl(source.settings.appPublicPath, source.activeVersion);
|
|
568
|
+
const entryDir = resolveEnvProxyEntryDir(source.envName, { scope: options?.scope });
|
|
569
|
+
const publicDir = resolveEnvProxyNginxPublicOutputDir(source.envName, { scope: options?.scope });
|
|
547
570
|
const snippetsDir = resolveEnvProxyNginxSnippetsOutputDir({ scope: options?.scope });
|
|
548
|
-
const distRootDir =
|
|
549
|
-
const uploadsDir = path.join(
|
|
571
|
+
const distRootDir = source.distRootPath;
|
|
572
|
+
const uploadsDir = path.join(source.storagePath, 'uploads');
|
|
550
573
|
const mappedEntryDir = await mapProxyPathFromCliRoot(entryDir, options);
|
|
551
574
|
const mappedPublicDir = await mapProxyPathFromCliRoot(publicDir, options);
|
|
552
575
|
const mappedSnippetsDir = await mapProxyPathFromCliRoot(snippetsDir, options);
|
|
553
576
|
const mappedDistRootDir = await mapProxyPathFromCliRoot(distRootDir, options);
|
|
554
577
|
const mappedUploadsDir = await mapProxyPathFromCliRoot(uploadsDir, options);
|
|
555
|
-
const v2PublicPath = `${settings.appPublicPath.replace(/\/$/, '')}/${settings.modernClientPrefix}/`;
|
|
578
|
+
const v2PublicPath = `${source.settings.appPublicPath.replace(/\/$/, '')}/${source.settings.modernClientPrefix}/`;
|
|
556
579
|
return {
|
|
557
|
-
envName:
|
|
558
|
-
envFilePath,
|
|
559
|
-
apiBasePath: settings.apiBasePath,
|
|
560
|
-
apiClientShareToken: settings.apiClientShareToken,
|
|
561
|
-
apiClientStoragePrefix: settings.apiClientStoragePrefix,
|
|
562
|
-
apiClientStorageType: settings.apiClientStorageType,
|
|
563
|
-
apiPort,
|
|
564
|
-
appPublicPath: settings.appPublicPath,
|
|
580
|
+
envName: source.envName,
|
|
581
|
+
envFilePath: source.envFilePath,
|
|
582
|
+
apiBasePath: source.settings.apiBasePath,
|
|
583
|
+
apiClientShareToken: source.settings.apiClientShareToken,
|
|
584
|
+
apiClientStoragePrefix: source.settings.apiClientStoragePrefix,
|
|
585
|
+
apiClientStorageType: source.settings.apiClientStorageType,
|
|
586
|
+
apiPort: source.apiPort,
|
|
587
|
+
appPublicPath: source.settings.appPublicPath,
|
|
565
588
|
backendUrl,
|
|
566
589
|
cdnBaseUrl: ensureTrailingSlash(cdnBaseUrl),
|
|
567
|
-
distPath: settings.distPath,
|
|
590
|
+
distPath: source.settings.distPath,
|
|
568
591
|
distRootDir: mappedDistRootDir,
|
|
569
592
|
entryDir: mappedEntryDir,
|
|
570
593
|
publicDir: mappedPublicDir,
|
|
571
|
-
esmCdnBaseUrl: settings.esmCdnBaseUrl,
|
|
572
|
-
esmCdnSuffix: settings.esmCdnSuffix,
|
|
573
|
-
indexV1Path: await mapProxyPathFromCliRoot(resolveEnvProxyNginxIndexOutputPath(
|
|
574
|
-
indexV2Path: await mapProxyPathFromCliRoot(resolveEnvProxyNginxIndexOutputPath(
|
|
575
|
-
modernClientPrefix: settings.modernClientPrefix,
|
|
594
|
+
esmCdnBaseUrl: source.settings.esmCdnBaseUrl,
|
|
595
|
+
esmCdnSuffix: source.settings.esmCdnSuffix,
|
|
596
|
+
indexV1Path: await mapProxyPathFromCliRoot(resolveEnvProxyNginxIndexOutputPath(source.envName, 'v1', { scope: options?.scope }), options),
|
|
597
|
+
indexV2Path: await mapProxyPathFromCliRoot(resolveEnvProxyNginxIndexOutputPath(source.envName, 'v2', { scope: options?.scope }), options),
|
|
598
|
+
modernClientPrefix: source.settings.modernClientPrefix,
|
|
576
599
|
proxyHost,
|
|
577
600
|
snippetsDir: mappedSnippetsDir,
|
|
578
601
|
uploadsDir: mappedUploadsDir,
|
|
579
602
|
v2PublicPath,
|
|
580
|
-
wsPath: settings.wsPath,
|
|
581
|
-
wsUrl: settings.wsUrl,
|
|
603
|
+
wsPath: source.settings.wsPath,
|
|
604
|
+
wsUrl: source.settings.wsUrl,
|
|
605
|
+
activeVersion: source.activeVersion,
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
async function resolveRuntimeNginxBundleSource(runtime, options) {
|
|
609
|
+
const apiPort = trimValue(runtime.env.appPort ?? runtime.env.config.appPort);
|
|
610
|
+
if (!apiPort) {
|
|
611
|
+
throw new Error(translateCli('commands.envProxy.errors.missingAppPort', { envName: runtime.envName }, {
|
|
612
|
+
fallback: `Missing appPort for env "${runtime.envName}". Save or update the app port before generating proxy config.`,
|
|
613
|
+
}));
|
|
614
|
+
}
|
|
615
|
+
const activeVersion = trimValue(await readDistClientActiveVersion(runtime.env.storagePath));
|
|
616
|
+
if (!activeVersion) {
|
|
617
|
+
throw new Error(translateCli('commands.envProxy.errors.missingVersion', { envName: runtime.envName }, {
|
|
618
|
+
fallback: `Couldn't determine the app version for env "${runtime.envName}". Run \`nb env update ${runtime.envName}\` and try again.`,
|
|
619
|
+
}));
|
|
620
|
+
}
|
|
621
|
+
const { envFilePath, settings } = await loadEnvProxySettings(runtime, options);
|
|
622
|
+
return {
|
|
623
|
+
envName: runtime.envName,
|
|
624
|
+
envFilePath,
|
|
625
|
+
storagePath: runtime.env.storagePath,
|
|
626
|
+
distRootPath: resolveDistClientRoot(runtime.env.storagePath),
|
|
627
|
+
settings,
|
|
628
|
+
apiPort,
|
|
582
629
|
activeVersion,
|
|
583
630
|
};
|
|
584
631
|
}
|
|
632
|
+
async function resolveManualNginxBundleSource(input) {
|
|
633
|
+
const normalized = normalizeManualNginxInput(input);
|
|
634
|
+
return {
|
|
635
|
+
envName: normalized.name,
|
|
636
|
+
envFilePath: undefined,
|
|
637
|
+
storagePath: normalized.storagePath,
|
|
638
|
+
distRootPath: normalized.distRootPath,
|
|
639
|
+
settings: createManualProxyEnvSettings(normalized),
|
|
640
|
+
apiPort: normalized.appPort,
|
|
641
|
+
activeVersion: normalized.runtimeVersion,
|
|
642
|
+
};
|
|
643
|
+
}
|
|
585
644
|
async function buildEnvProxyCaddyRenderContext(runtime, options) {
|
|
586
|
-
return await
|
|
645
|
+
return await buildEnvProxyCaddyRenderContextFromSource(await resolveRuntimeNginxBundleSource(runtime), options);
|
|
646
|
+
}
|
|
647
|
+
async function buildEnvProxyCaddyRenderContextFromSource(source, options) {
|
|
648
|
+
return await buildEnvProxyNginxRenderContext(source, {
|
|
587
649
|
...options,
|
|
588
650
|
provider: 'caddy',
|
|
589
651
|
});
|
|
@@ -636,11 +698,20 @@ export function resolveEnvProxyCaddyIndexOutputPath(envName, variant, options) {
|
|
|
636
698
|
return path.join(resolveEnvProxyCaddyPublicOutputDir(envName, { scope: options?.scope }), `index-${variant}.html`);
|
|
637
699
|
}
|
|
638
700
|
export async function buildEnvProxyNginxBundle(runtime, options) {
|
|
639
|
-
|
|
701
|
+
return await buildNginxBundleFromSource(await resolveRuntimeNginxBundleSource(runtime, options), options);
|
|
702
|
+
}
|
|
703
|
+
export async function buildManualEnvProxyNginxBundle(input, options) {
|
|
704
|
+
return await buildNginxBundleFromSource(await resolveManualNginxBundleSource(input), {
|
|
705
|
+
...options,
|
|
706
|
+
upstreamHost: trimValue(input.upstreamHost) ?? options?.upstreamHost,
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
async function buildNginxBundleFromSource(source, options) {
|
|
710
|
+
const context = await buildEnvProxyNginxRenderContext(source, options);
|
|
640
711
|
const appTemplate = await readEnvProxyNginxAssetText('app.conf.tpl');
|
|
641
712
|
const mainTemplate = await readEnvProxyNginxAssetText('nocobase.conf.tpl');
|
|
642
|
-
const sourceIndexV1Path = path.join(
|
|
643
|
-
const sourceIndexV2Path = path.join(
|
|
713
|
+
const sourceIndexV1Path = path.join(source.distRootPath, context.activeVersion, 'index.html');
|
|
714
|
+
const sourceIndexV2Path = path.join(source.distRootPath, context.activeVersion, DEFAULT_MODERN_CLIENT_PREFIX, 'index.html');
|
|
644
715
|
const [sourceIndexV1Content, sourceIndexV2Content] = await Promise.all([
|
|
645
716
|
readFile(sourceIndexV1Path, 'utf8'),
|
|
646
717
|
readFile(sourceIndexV2Path, 'utf8'),
|
|
@@ -667,13 +738,13 @@ export async function buildEnvProxyNginxBundle(runtime, options) {
|
|
|
667
738
|
wsPath: context.wsPath,
|
|
668
739
|
};
|
|
669
740
|
return {
|
|
670
|
-
envName:
|
|
741
|
+
envName: source.envName,
|
|
671
742
|
envFilePath: context.envFilePath,
|
|
672
|
-
entryDir: resolveEnvProxyEntryDir(
|
|
673
|
-
publicDir: resolveEnvProxyNginxPublicOutputDir(
|
|
674
|
-
appConfigPath: resolveEnvProxyAppOutputPath(
|
|
675
|
-
indexV1Path: resolveEnvProxyNginxIndexOutputPath(
|
|
676
|
-
indexV2Path: resolveEnvProxyNginxIndexOutputPath(
|
|
743
|
+
entryDir: resolveEnvProxyEntryDir(source.envName, { scope: options?.scope, provider: 'nginx' }),
|
|
744
|
+
publicDir: resolveEnvProxyNginxPublicOutputDir(source.envName, { scope: options?.scope }),
|
|
745
|
+
appConfigPath: resolveEnvProxyAppOutputPath(source.envName, { scope: options?.scope, provider: 'nginx' }),
|
|
746
|
+
indexV1Path: resolveEnvProxyNginxIndexOutputPath(source.envName, 'v1', { scope: options?.scope }),
|
|
747
|
+
indexV2Path: resolveEnvProxyNginxIndexOutputPath(source.envName, 'v2', { scope: options?.scope }),
|
|
677
748
|
mainConfigPath: resolveEnvProxyMainOutputPath({ scope: options?.scope, provider: 'nginx' }),
|
|
678
749
|
snippetsDir: resolveEnvProxyNginxSnippetsOutputDir({ scope: options?.scope }),
|
|
679
750
|
appPublicPath: context.appPublicPath,
|
|
@@ -694,9 +765,18 @@ export async function buildEnvProxyNginxBundle(runtime, options) {
|
|
|
694
765
|
};
|
|
695
766
|
}
|
|
696
767
|
export async function buildEnvProxyCaddyBundle(runtime, options) {
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
768
|
+
return await buildCaddyBundleFromSource(await resolveRuntimeNginxBundleSource(runtime), options);
|
|
769
|
+
}
|
|
770
|
+
export async function buildManualEnvProxyCaddyBundle(input, options) {
|
|
771
|
+
return await buildCaddyBundleFromSource(await resolveManualNginxBundleSource(input), {
|
|
772
|
+
...options,
|
|
773
|
+
upstreamHost: trimValue(input.upstreamHost) ?? options?.upstreamHost,
|
|
774
|
+
});
|
|
775
|
+
}
|
|
776
|
+
async function buildCaddyBundleFromSource(source, options) {
|
|
777
|
+
const context = await buildEnvProxyCaddyRenderContextFromSource(source, options);
|
|
778
|
+
const sourceIndexV1Path = path.join(source.distRootPath, context.activeVersion, 'index.html');
|
|
779
|
+
const sourceIndexV2Path = path.join(source.distRootPath, context.activeVersion, DEFAULT_MODERN_CLIENT_PREFIX, 'index.html');
|
|
700
780
|
const [sourceIndexV1Content, sourceIndexV2Content] = await Promise.all([
|
|
701
781
|
readFile(sourceIndexV1Path, 'utf8'),
|
|
702
782
|
readFile(sourceIndexV2Path, 'utf8'),
|
|
@@ -707,9 +787,9 @@ export async function buildEnvProxyCaddyBundle(runtime, options) {
|
|
|
707
787
|
const sourceV2PublicPath = extractRuntimePublicPath(sourceIndexV2Content);
|
|
708
788
|
const indexV1AssetPublicPath = context.cdnBaseUrl;
|
|
709
789
|
const indexV2AssetPublicPath = `${trimTrailingSlash(context.cdnBaseUrl)}/${DEFAULT_MODERN_CLIENT_PREFIX}/`;
|
|
710
|
-
const appConfigPath = resolveEnvProxyAppOutputPath(
|
|
711
|
-
const entryDir = resolveEnvProxyEntryDir(
|
|
712
|
-
const publicDir = resolveEnvProxyCaddyPublicOutputDir(
|
|
790
|
+
const appConfigPath = resolveEnvProxyAppOutputPath(source.envName, { scope: options?.scope, provider: 'caddy' });
|
|
791
|
+
const entryDir = resolveEnvProxyEntryDir(source.envName, { scope: options?.scope, provider: 'caddy' });
|
|
792
|
+
const publicDir = resolveEnvProxyCaddyPublicOutputDir(source.envName, { scope: options?.scope });
|
|
713
793
|
const renderedPublicDir = await mapProxyPathFromCliRoot(publicDir, { ...options, provider: 'caddy' });
|
|
714
794
|
const appConfigContent = renderCaddyAppTemplate(buildCaddySiteAddress(), {
|
|
715
795
|
appPublicPath: context.appPublicPath,
|
|
@@ -725,13 +805,13 @@ export async function buildEnvProxyCaddyBundle(runtime, options) {
|
|
|
725
805
|
wsPath: context.wsPath,
|
|
726
806
|
}, renderedPublicDir);
|
|
727
807
|
return {
|
|
728
|
-
envName:
|
|
808
|
+
envName: source.envName,
|
|
729
809
|
envFilePath: context.envFilePath,
|
|
730
810
|
entryDir,
|
|
731
811
|
publicDir,
|
|
732
812
|
appConfigPath,
|
|
733
|
-
indexV1Path: resolveEnvProxyCaddyIndexOutputPath(
|
|
734
|
-
indexV2Path: resolveEnvProxyCaddyIndexOutputPath(
|
|
813
|
+
indexV1Path: resolveEnvProxyCaddyIndexOutputPath(source.envName, 'v1', { scope: options?.scope }),
|
|
814
|
+
indexV2Path: resolveEnvProxyCaddyIndexOutputPath(source.envName, 'v2', { scope: options?.scope }),
|
|
735
815
|
mainConfigPath: resolveEnvProxyMainOutputPath({ scope: options?.scope, provider: 'caddy' }),
|
|
736
816
|
appPublicPath: context.appPublicPath,
|
|
737
817
|
apiBasePath: context.apiBasePath,
|
|
@@ -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-
|
|
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;
|
package/dist/lib/proxy-caddy.js
CHANGED
|
@@ -11,7 +11,7 @@ import path from 'node:path';
|
|
|
11
11
|
import { dockerContainerExists, dockerContainerIsRunning, startDockerContainer, stopDockerContainer, } from './app-runtime.js';
|
|
12
12
|
import { CADDY_PROXY_DRIVER_OPTIONS, DEFAULT_CADDY_PROXY_DRIVER, getCliConfigValue, normalizeCaddyProxyDriver, resolveDockerContainerPrefix, setCliConfigValue, } from './cli-config.js';
|
|
13
13
|
import { resolveCliHomeRoot } from './cli-home.js';
|
|
14
|
-
import { applyEnvProxyAppEntryOptions, buildEnvProxyCaddyBundle, buildEnvProxyMainConfig, mapProxyPathFromCliRoot, resolveEnvProxyMainOutputPath, } from './env-proxy.js';
|
|
14
|
+
import { applyEnvProxyAppEntryOptions, buildManualEnvProxyCaddyBundle, buildEnvProxyCaddyBundle, buildEnvProxyMainConfig, mapProxyPathFromCliRoot, resolveEnvProxyMainOutputPath, } from './env-proxy.js';
|
|
15
15
|
import { run } from './run-npm.js';
|
|
16
16
|
const DOCKER_CADDY_PROXY_CONTAINER_SUFFIX = 'caddy-proxy';
|
|
17
17
|
const DOCKER_CADDY_PROXY_IMAGE = 'caddy:latest';
|
|
@@ -62,8 +62,9 @@ export async function resolveCaddyProxyRuntimeContext(options) {
|
|
|
62
62
|
upstreamHost: resolveCaddyProxyUpstreamHost(driver),
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
|
-
export async function writeCaddyProxyBundle(runtime, appEntryOptions, runtimeContext) {
|
|
65
|
+
export async function writeCaddyProxyBundle(runtime, appEntryOptions, runtimeContext, options) {
|
|
66
66
|
const bundle = await buildEnvProxyCaddyBundle(runtime, {
|
|
67
|
+
cdnBaseUrl: options?.cdnBaseUrl,
|
|
67
68
|
runtimeCliRoot: runtimeContext.runtimeCliRoot,
|
|
68
69
|
upstreamHost: runtimeContext.upstreamHost,
|
|
69
70
|
});
|
|
@@ -82,6 +83,27 @@ export async function writeCaddyProxyBundle(runtime, appEntryOptions, runtimeCon
|
|
|
82
83
|
status,
|
|
83
84
|
};
|
|
84
85
|
}
|
|
86
|
+
export async function writeManualCaddyProxyBundle(input, appEntryOptions, runtimeContext, options) {
|
|
87
|
+
const bundle = await buildManualEnvProxyCaddyBundle(input, {
|
|
88
|
+
cdnBaseUrl: options?.cdnBaseUrl,
|
|
89
|
+
runtimeCliRoot: runtimeContext.runtimeCliRoot,
|
|
90
|
+
upstreamHost: input.upstreamHost || runtimeContext.upstreamHost,
|
|
91
|
+
});
|
|
92
|
+
const currentAppConfigContent = await readOptionalTextFile(bundle.appConfigPath);
|
|
93
|
+
const nextAppConfigContent = applyEnvProxyAppEntryOptions(bundle.appConfigContent, 'caddy', appEntryOptions);
|
|
94
|
+
const status = currentAppConfigContent ? 'updated' : 'created';
|
|
95
|
+
await Promise.all([mkdir(bundle.entryDir, { recursive: true }), mkdir(bundle.publicDir, { recursive: true })]);
|
|
96
|
+
await Promise.all([
|
|
97
|
+
writeFile(bundle.appConfigPath, nextAppConfigContent, 'utf8'),
|
|
98
|
+
writeFile(bundle.indexV1Path, bundle.indexV1Content, 'utf8'),
|
|
99
|
+
writeFile(bundle.indexV2Path, bundle.indexV2Content, 'utf8'),
|
|
100
|
+
writeFile(bundle.mainConfigPath, bundle.mainConfigContent, 'utf8'),
|
|
101
|
+
]);
|
|
102
|
+
return {
|
|
103
|
+
bundle,
|
|
104
|
+
status,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
85
107
|
function resolveLocalCaddyPidFilePath() {
|
|
86
108
|
return path.join(path.dirname(resolveEnvProxyMainOutputPath({ provider: 'caddy' })), 'caddy.pid');
|
|
87
109
|
}
|
package/dist/lib/proxy-nginx.js
CHANGED
|
@@ -11,7 +11,7 @@ import path from 'node:path';
|
|
|
11
11
|
import { dockerContainerExists, dockerContainerIsRunning, startDockerContainer, stopDockerContainer, } from './app-runtime.js';
|
|
12
12
|
import { DEFAULT_NGINX_PROXY_DRIVER, getCliConfigValue, NGINX_PROXY_DRIVER_OPTIONS, normalizeNginxProxyDriver, resolveDockerContainerPrefix, setCliConfigValue, } from './cli-config.js';
|
|
13
13
|
import { resolveCliHomeRoot } from './cli-home.js';
|
|
14
|
-
import { applyEnvProxyAppEntryOptions, appConfigHasManagedNginxBlock, buildEnvProxyMainConfig, buildEnvProxyNginxBundle, extractManagedNginxConfigBlock, installEnvProxyProvider, mapProxyPathFromCliRoot, reloadEnvProxyProvider, resolveEnvProxyMainOutputPath, replaceManagedNginxConfigBlock, syncEnvProxyNginxSnippets, } from './env-proxy.js';
|
|
14
|
+
import { applyEnvProxyAppEntryOptions, appConfigHasManagedNginxBlock, buildManualEnvProxyNginxBundle, buildEnvProxyMainConfig, buildEnvProxyNginxBundle, extractManagedNginxConfigBlock, installEnvProxyProvider, mapProxyPathFromCliRoot, reloadEnvProxyProvider, resolveEnvProxyMainOutputPath, replaceManagedNginxConfigBlock, syncEnvProxyNginxSnippets, } from './env-proxy.js';
|
|
15
15
|
import { run } from './run-npm.js';
|
|
16
16
|
const DOCKER_NGINX_PROXY_CONTAINER_SUFFIX = 'nginx-proxy';
|
|
17
17
|
const DOCKER_NGINX_PROXY_IMAGE = 'nginx:latest';
|
|
@@ -66,11 +66,23 @@ function buildNginxManagedBlockMissingMessage(appConfigPath) {
|
|
|
66
66
|
return (`The editable nginx app entry config at ${appConfigPath} does not contain the NocoBase managed block. ` +
|
|
67
67
|
'Restore the managed block or delete the file and regenerate the proxy config.');
|
|
68
68
|
}
|
|
69
|
-
export async function writeNginxProxyBundle(runtime, appEntryOptions, runtimeContext) {
|
|
69
|
+
export async function writeNginxProxyBundle(runtime, appEntryOptions, runtimeContext, options) {
|
|
70
70
|
const bundle = await buildEnvProxyNginxBundle(runtime, {
|
|
71
|
+
cdnBaseUrl: options?.cdnBaseUrl,
|
|
71
72
|
runtimeCliRoot: runtimeContext.runtimeCliRoot,
|
|
72
73
|
upstreamHost: runtimeContext.upstreamHost,
|
|
73
74
|
});
|
|
75
|
+
return await writeResolvedNginxProxyBundle(bundle, appEntryOptions, options);
|
|
76
|
+
}
|
|
77
|
+
export async function writeManualNginxProxyBundle(input, appEntryOptions, runtimeContext, options) {
|
|
78
|
+
const bundle = await buildManualEnvProxyNginxBundle(input, {
|
|
79
|
+
cdnBaseUrl: options?.cdnBaseUrl,
|
|
80
|
+
runtimeCliRoot: runtimeContext.runtimeCliRoot,
|
|
81
|
+
upstreamHost: runtimeContext.upstreamHost,
|
|
82
|
+
});
|
|
83
|
+
return await writeResolvedNginxProxyBundle(bundle, appEntryOptions, options);
|
|
84
|
+
}
|
|
85
|
+
async function writeResolvedNginxProxyBundle(bundle, appEntryOptions, options) {
|
|
74
86
|
const managedConfigBlock = extractManagedNginxConfigBlock(bundle.appConfigContent);
|
|
75
87
|
if (!managedConfigBlock) {
|
|
76
88
|
throw new Error('Failed to render the managed nginx config block.');
|
|
@@ -79,10 +91,12 @@ export async function writeNginxProxyBundle(runtime, appEntryOptions, runtimeCon
|
|
|
79
91
|
let nextAppConfigContent = applyEnvProxyAppEntryOptions(bundle.appConfigContent, 'nginx', appEntryOptions);
|
|
80
92
|
let status = 'created';
|
|
81
93
|
if (currentAppConfigContent) {
|
|
82
|
-
if (!appConfigHasManagedNginxBlock(currentAppConfigContent)) {
|
|
94
|
+
if (!appConfigHasManagedNginxBlock(currentAppConfigContent) && !options?.force) {
|
|
83
95
|
throw new Error(buildNginxManagedBlockMissingMessage(bundle.appConfigPath));
|
|
84
96
|
}
|
|
85
|
-
nextAppConfigContent =
|
|
97
|
+
nextAppConfigContent = appConfigHasManagedNginxBlock(currentAppConfigContent)
|
|
98
|
+
? applyEnvProxyAppEntryOptions(replaceManagedNginxConfigBlock(currentAppConfigContent, managedConfigBlock), 'nginx', appEntryOptions)
|
|
99
|
+
: applyEnvProxyAppEntryOptions(bundle.appConfigContent, 'nginx', appEntryOptions);
|
|
86
100
|
status = 'updated';
|
|
87
101
|
}
|
|
88
102
|
await Promise.all([mkdir(bundle.entryDir, { recursive: true }), mkdir(bundle.publicDir, { recursive: true })]);
|
package/dist/locale/en-US.json
CHANGED
|
@@ -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
|
|
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."
|
|
@@ -263,7 +263,7 @@
|
|
|
263
263
|
"version": {
|
|
264
264
|
"message": "Which version would you like to use?",
|
|
265
265
|
"latestLabel": "latest",
|
|
266
|
-
"latestHint": "Stable release. Best for production use and the most predictable experience.
|
|
266
|
+
"latestHint": "Stable release. Best for production use and the most predictable experience.",
|
|
267
267
|
"betaLabel": "beta",
|
|
268
268
|
"betaHint": "Preview release. Good for trying upcoming features before general release.",
|
|
269
269
|
"alphaLabel": "alpha",
|
package/dist/locale/zh-CN.json
CHANGED
|
@@ -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/ 这样的路径。每个路径段仅支持字母、数字、中划线和下划线。"
|
|
@@ -263,7 +263,7 @@
|
|
|
263
263
|
"version": {
|
|
264
264
|
"message": "你想使用哪个版本?",
|
|
265
265
|
"latestLabel": "latest",
|
|
266
|
-
"latestHint": "
|
|
266
|
+
"latestHint": "稳定版。适合生产环境和希望获得稳定体验的场景。",
|
|
267
267
|
"betaLabel": "beta",
|
|
268
268
|
"betaHint": "测试版。包含即将发布的新功能,适合提前体验和反馈。",
|
|
269
269
|
"alphaLabel": "alpha",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/cli",
|
|
3
|
-
"version": "2.2.0-alpha.
|
|
3
|
+
"version": "2.2.0-alpha.4",
|
|
4
4
|
"description": "NocoBase Command Line Tool",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/generated/command-registry.js",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"author": "",
|
|
14
14
|
"license": "Apache-2.0",
|
|
15
15
|
"files": [
|
|
16
|
+
"assets",
|
|
16
17
|
"bin",
|
|
17
18
|
"dist",
|
|
18
19
|
"nocobase-ctl.config.json"
|
|
@@ -143,5 +144,5 @@
|
|
|
143
144
|
"type": "git",
|
|
144
145
|
"url": "git+https://github.com/nocobase/nocobase.git"
|
|
145
146
|
},
|
|
146
|
-
"gitHead": "
|
|
147
|
+
"gitHead": "81bf8733db4bccf08a6bc5e6d97f274bce349161"
|
|
147
148
|
}
|