feat: configure workspace environment runtimes
This commit is contained in:
@@ -25,6 +25,12 @@ export interface WorkspaceEnvironmentConfig {
|
||||
protocol?: "http" | "https";
|
||||
rootDomain?: string;
|
||||
port?: number;
|
||||
hostname?: string;
|
||||
runtime?: "development" | "production";
|
||||
hmr?: boolean;
|
||||
build?: boolean;
|
||||
migrate?: boolean;
|
||||
profile?: string;
|
||||
}
|
||||
|
||||
export interface WorkspaceApp {
|
||||
@@ -54,7 +60,7 @@ export interface WorkspaceApp {
|
||||
export interface WorkspaceConfig {
|
||||
defaultEnvironment?: WorkspaceEnvironment;
|
||||
|
||||
environments?: Record<WorkspaceEnvironment, WorkspaceEnvironmentConfig>;
|
||||
environments?: Partial<Record<WorkspaceEnvironment, WorkspaceEnvironmentConfig>>;
|
||||
|
||||
apps: WorkspaceApp[];
|
||||
security?: GatewaySecurity;
|
||||
@@ -81,6 +87,12 @@ export const workspaceFiles = (name: string): Record<string, string> => ({
|
||||
// Map each app to the domains it serves. \`wrnexus gateway\` runs them all behind
|
||||
// one port and routes by Host header (add these hosts to your /etc/hosts).
|
||||
const config: WorkspaceConfig = {
|
||||
defaultEnvironment: "development",
|
||||
environments: {
|
||||
development: { protocol: "http", rootDomain: "localhost", port: 3000, runtime: "development", hmr: true, build: false, migrate: false },
|
||||
staging: { protocol: "https", rootDomain: "staging.example.com", port: 443, runtime: "production", hmr: false, build: true, migrate: true },
|
||||
production: { protocol: "https", rootDomain: "example.com", port: 443, runtime: "production", hmr: false, build: true, migrate: true },
|
||||
},
|
||||
// Gateway-wide security (all optional):
|
||||
security: {
|
||||
trustedHostsOnly: true, // reject requests for unknown domains
|
||||
@@ -398,26 +410,23 @@ export async function runGateway(root: string, args: string[]): Promise<void> {
|
||||
(args.includes("--prod") ? "production" : config.defaultEnvironment || "development");
|
||||
|
||||
const resolved = resolveWorkspaceConfig(config, environment);
|
||||
const environmentConfig = resolved.config;
|
||||
const runtime =
|
||||
environmentConfig.runtime ?? (environment === "development" ? "development" : "production");
|
||||
|
||||
const port = portArg
|
||||
? Number(portArg.split("=")[1])
|
||||
: resolved.environment === "development"
|
||||
? 3000
|
||||
: 80;
|
||||
: (environmentConfig.port ?? (runtime === "development" ? 3000 : 80));
|
||||
|
||||
const hostname = hostArg?.split("=")[1];
|
||||
const hostname = hostArg?.split("=")[1] ?? environmentConfig.hostname;
|
||||
|
||||
const { startGateway } = await import("@wrnexus/dev-server");
|
||||
|
||||
await startGateway({
|
||||
port,
|
||||
hostname,
|
||||
mode:
|
||||
environment === "production" ||
|
||||
args.includes("--prod") ||
|
||||
process.env.NODE_ENV === "production"
|
||||
? "production"
|
||||
: "development",
|
||||
mode: args.includes("--prod") || process.env.NODE_ENV === "production" ? "production" : runtime,
|
||||
hmr: runtime === "development" ? (environmentConfig.hmr ?? true) : false,
|
||||
environment,
|
||||
security: resolved.security,
|
||||
apps: resolved.apps.map((app) => ({
|
||||
@@ -458,16 +467,21 @@ export function workspaceMigrationTargets(appRoot: string): Array<string | null>
|
||||
export async function runProduction(root: string, args: string[]): Promise<void> {
|
||||
const workspaceRoot = resolve(root);
|
||||
const config = await loadWorkspaceConfig(workspaceRoot);
|
||||
const shouldBuild = !args.includes("--no-build");
|
||||
const shouldMigrate = !args.includes("--no-migrate");
|
||||
const prepareOnly = args.includes("--prepare-only");
|
||||
const environmentArg = args.find((arg) => arg.startsWith("--environment="));
|
||||
const profileArg = args.find((arg) => arg.startsWith("--profile="));
|
||||
const environment = environmentArg?.split("=")[1] || profileArg?.split("=")[1] || "production";
|
||||
const environmentConfig = config.environments?.[environment] ?? {};
|
||||
const profile = environmentConfig.profile ?? environment;
|
||||
const shouldBuild =
|
||||
!args.includes("--no-build") && (args.includes("--build") || environmentConfig.build !== false);
|
||||
const shouldMigrate =
|
||||
!args.includes("--no-migrate") &&
|
||||
(args.includes("--migrate") || environmentConfig.migrate !== false);
|
||||
|
||||
process.env.NODE_ENV = "production";
|
||||
process.env.WRNEXUS_ENV = environment;
|
||||
process.env.WRNEXUS_PROFILE = environment;
|
||||
process.env.WRNEXUS_PROFILE = profile;
|
||||
console.log(`\n ⚡ Preparing WRNexus workspace (${environment})\n`);
|
||||
|
||||
if (shouldBuild) {
|
||||
@@ -512,8 +526,12 @@ export async function runProduction(root: string, args: string[]): Promise<void>
|
||||
gatewayArgs.push(`--environment=${environment}`);
|
||||
}
|
||||
if (!gatewayArgs.includes("--prod")) gatewayArgs.push("--prod");
|
||||
if (!gatewayArgs.some((arg) => arg.startsWith("--host="))) gatewayArgs.push("--host=0.0.0.0");
|
||||
if (!gatewayArgs.some((arg) => arg.startsWith("--port="))) gatewayArgs.push("--port=3000");
|
||||
if (
|
||||
!gatewayArgs.some((arg) => arg.startsWith("--host=")) &&
|
||||
environmentConfig.hostname === undefined
|
||||
) {
|
||||
gatewayArgs.push("--host=0.0.0.0");
|
||||
}
|
||||
await runGateway(workspaceRoot, gatewayArgs);
|
||||
}
|
||||
|
||||
@@ -555,6 +573,7 @@ export interface ResolvedWorkspaceApp extends WorkspaceApp {
|
||||
|
||||
export interface ResolvedWorkspaceConfig {
|
||||
environment: WorkspaceEnvironment;
|
||||
config: WorkspaceEnvironmentConfig;
|
||||
apps: ResolvedWorkspaceApp[];
|
||||
security?: GatewaySecurity;
|
||||
}
|
||||
@@ -635,6 +654,7 @@ export function resolveWorkspaceConfig(
|
||||
|
||||
return {
|
||||
environment,
|
||||
config: environmentConfig,
|
||||
apps,
|
||||
security: config.security,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user