diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index eb791a64..3b3b1b30 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -47,6 +47,7 @@ Usage: Add an app to the current workspace wrnexus gateway [--port=3000] Serve every workspace app behind one port, routed by domain wrnexus production [workspace-dir] Build, migrate, and serve the complete production workspace + wrnexus [workspace-dir] Run a configured workspace environment (development/staging/custom) wrnexus generate Scaffold a page | component | api | schema wrnexus generate routes | docker | mobile Generate routes or scaffold deployment targets @@ -195,10 +196,32 @@ async function main(): Promise { case "-h": help(); break; - default: - console.error(`Unknown command: ${command}\n`); - help(); - process.exit(1); + default: { + const { loadWorkspaceConfig, runGateway, runProduction } = await import("./workspace.ts"); + const workspaceRoot = rest.find((a) => !a.startsWith("--")) ?? "."; + try { + const workspace = await loadWorkspaceConfig(resolve(workspaceRoot)); + const knownEnvironments = new Set([ + "development", + "production", + workspace.defaultEnvironment, + ...Object.keys(workspace.environments ?? {}), + ]); + if (!knownEnvironments.has(command)) throw new Error("unknown-environment-command"); + const environmentArgs = rest.filter((arg) => arg !== workspaceRoot); + environmentArgs.push(`--environment=${command}`); + if (command === "development") { + await runGateway(workspaceRoot, environmentArgs); + } else { + await runProduction(workspaceRoot, environmentArgs); + } + } catch (error) { + if (error instanceof Error && error.message !== "unknown-environment-command") throw error; + console.error(`Unknown command or workspace environment: ${command}\n`); + help(); + process.exit(1); + } + } } } diff --git a/packages/cli/src/workspace.ts b/packages/cli/src/workspace.ts index 5af6a0a8..a2f6e560 100644 --- a/packages/cli/src/workspace.ts +++ b/packages/cli/src/workspace.ts @@ -412,7 +412,12 @@ export async function runGateway(root: string, args: string[]): Promise { await startGateway({ port, hostname, - mode: environment === "production" ? "production" : "development", + mode: + environment === "production" || + args.includes("--prod") || + process.env.NODE_ENV === "production" + ? "production" + : "development", environment, security: resolved.security, apps: resolved.apps.map((app) => ({ @@ -506,6 +511,7 @@ export async function runProduction(root: string, args: string[]): Promise if (!gatewayArgs.some((arg) => arg.startsWith("--environment="))) { 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"); await runGateway(workspaceRoot, gatewayArgs); diff --git a/packages/ui/components/AnnouncementBar.wrn b/packages/ui/components/AnnouncementBar.wrn index 14d34937..e9783d63 100644 --- a/packages/ui/components/AnnouncementBar.wrn +++ b/packages/ui/components/AnnouncementBar.wrn @@ -1,12 +1,19 @@ component AnnouncementBar { props { - class = "" - badge = "New" - message = "WrNexus Organizations is now available." - description = "Build secure multi-tenant applications with teams, roles, domains, and enterprise SSO." - href = "/organizations" - actionLabel = "Explore organizations" - ariaLabel = "Announcement" + class: string = "" + badge: string = "New" + message: string = "WrNexus Organizations is now available." + description: string = "Build secure multi-tenant applications with teams, roles, domains, and enterprise SSO." + href: string = "/organizations" + actionLabel: string = "Explore organizations" + ariaLabel: string = "Announcement" + badgeIcon: string = "icon-[lucide--sparkles]" + actionIcon: string = "icon-[lucide--arrow-right]" + dismissLabel: string = "Dismiss announcement" + showBadge: boolean = true + showDescription: boolean = true + showAction: boolean = true + dismissible: boolean = true } state visible = true @@ -33,10 +40,10 @@ component AnnouncementBar { >
- @@ -49,24 +56,24 @@ component AnnouncementBar { {message} -
- - @@ -114,7 +129,7 @@ component PublicFooter { > - Thanks. Please check your inbox to confirm your subscription. + {newsletterSuccessMessage} @@ -126,8 +141,8 @@ component PublicFooter {
- WrNexus + {brandName} - Identity Cloud + {brandTagline} @@ -169,7 +184,7 @@ component PublicFooter {
- @@ -581,7 +598,7 @@ component PublicFooter { Legal - @@ -92,7 +114,7 @@ component PublicHeader { class:dark:hover:bg-white/5="activeMenu !== 'solutions'" class:dark:hover:text-white="activeMenu !== 'solutions'" > - Solutions + {solutionsLabel} @@ -115,7 +137,7 @@ component PublicHeader { class:dark:hover:bg-white/5="activeMenu !== 'developers'" class:dark:hover:text-white="activeMenu !== 'developers'" > - Developers + {developersLabel} @@ -138,23 +160,25 @@ component PublicHeader { class:dark:hover:bg-white/5="activeMenu !== 'resources'" class:dark:hover:text-white="activeMenu !== 'resources'" > - Resources + {resourcesLabel} - Pricing + {pricingLabel} +