release: WRNexusJS 0.8.0
Quality / quality (ubuntu-latest) (push) Failing after 21s
Quality / quality (windows-latest) (push) Canceled after 0s

This commit is contained in:
2026-08-02 23:18:51 +05:30
parent 87507edf59
commit 586a6db8ff
625 changed files with 243608 additions and 11210 deletions
+190 -7
View File
@@ -40,7 +40,12 @@ function help(): void {
Usage:
wrnexus dev [app-dir] [--port=3000] [--host=::]
Start the development server (live reload)
wrnexus dev [app-dir] --services Start local production-service simulators with the app
wrnexus dev [app-dir] --production-runtime
wrnexus dev [app-dir] --services [--services-port=3099] [--services-http]
Rebuild and reload the exact production artifact
wrnexus build [app-dir] Build a production server bundle + assets
wrnexus preview [app-dir] Serve the existing exact production output
wrnexus create <app-name> Scaffold a new app
wrnexus workspace <name> Scaffold a monorepo (apps/* + shared packages/*)
wrnexus workspace add <name> [--domain=name.localhost]
@@ -51,6 +56,9 @@ Usage:
wrnexus generate <type> <name> Scaffold a page | component | api | schema
wrnexus generate routes | docker | mobile
Generate routes or scaffold deployment targets
wrnexus generate types [app-dir] Generate application-wide route/component/key types
wrnexus routes [app-dir] Generate typed named routes
wrnexus typecheck [app-dir] Generate types and check TypeScript plus every .wrn file
wrnexus mobile add <package...> Install Capacitor or Expo native packages
wrnexus mobile compile Compile .wrn pages into native Expo routes
wrnexus native list List cross-platform native capabilities
@@ -58,12 +66,35 @@ Usage:
wrnexus eject <name...> Copy a Wire UI component into app/components
wrnexus update [dir] [--latest] Upgrade deps, migrate project files, and verify the app
wrnexus db <cmd> Migrations: migrate | rollback | status | seed | generate | new
wrnexus test [app-dir] [--watch] Run the app's tests (bun test, 'test' profile)
wrnexus test [level] [app-dir] [--watch]
Run unit | component | api | browser | visual | accessibility | performance
wrnexus profiles [app-dir] List config profiles (dev/prod/uat/…) and their env files
wrnexus doctor [app-dir] Check project structure, versions, syntax, routes, and config
wrnexus doctor [app-dir] [--fix] Check project health; optionally apply safe repairs
wrnexus compatibility <check|explain|upgrade> [app-dir]
Inspect or explicitly upgrade behavior defaults
wrnexus contracts <check|snapshot> [app-dir]
Detect breaking boundary contract changes
wrnexus security <audit|headers|test> [app-dir]
Audit ASVS controls, inspect headers, or run abuse tests
wrnexus api <generate|docs> [app-dir] Generate OpenAPI, docs, Postman, examples and SDKs
wrnexus sdk generate <language> [app-dir]
Generate TypeScript, JavaScript, Java, Go, or Python SDK
wrnexus deploy <target> [app-dir] Generate docker | kubernetes | systemd | railway | render | fly
wrnexus mcp [app-dir] Start the WRNexus MCP server over stdio
wrnexus i18n <extract|validate> [app-dir]
Extract and audit translation keys
wrnexus report [app-dir] [--file=app/pages/page.wrn]
Create a sanitized reproduction bundle
wrnexus playground [--port=4173] Start the shareable WRN compiler playground
wrnexus config [app-dir] --explain Print the fully resolved profile configuration
wrnexus analyze [app-dir] Inspect dist/build-report.json and performance budgets
wrnexus explain <route|build|hydration|bundle> [subject] [app-dir]
Explain compiler and production build decisions
wrnexus explain <cache|permission> <subject> [app-dir]
Explain route caching or permission enforcement
wrnexus inspect <target> [app-dir] Inspect packages | plugins | routes | assets | runtimes | styles | migrations | bundle
wrnexus inspect component <name> [app-dir]
Inspect a component's typed public contract
wrnexus generate system <name> Scaffold a complete framework-native package
Profiles: pass --profile=<name> to dev/build/db (or set WRNEXUS_PROFILE) to load
@@ -91,7 +122,31 @@ async function main(): Promise<void> {
const port = portArg ? Number(portArg.split("=")[1]) : 3000;
const host = hostArg?.split("=")[1] || "::";
bootstrapProfile(appRoot, "development", rest);
runDev(appRoot, port, host);
let developmentCertificate:
| { certFile: string; keyFile: string; cert: string; key: string; reused: boolean }
| undefined;
if (rest.includes("--services") && !rest.includes("--services-http")) {
const { ensureLocalCertificate } = await import("./services.ts");
developmentCertificate = await ensureLocalCertificate(appRoot);
}
if (rest.includes("--services")) {
const { startLocalServices } = await import("./services.ts");
await startLocalServices({
appRoot,
port: Number(
rest.find((value) => value.startsWith("--services-port="))?.split("=")[1] ?? 3099,
),
https: !rest.includes("--services-http"),
origin: `${rest.includes("--services-http") ? "http" : "https"}://localhost:${port}`,
certificate: developmentCertificate,
});
}
if (rest.includes("--production-runtime")) {
const { runProductionDev } = await import("./dev.ts");
await runProductionDev(appRoot, port, host);
} else {
runDev(appRoot, port, host, developmentCertificate);
}
break;
}
case "build": {
@@ -101,6 +156,15 @@ async function main(): Promise<void> {
await runBuild(appRoot);
break;
}
case "preview": {
const appRoot = rest.find((a) => !a.startsWith("--")) ?? ".";
const port = Number(rest.find((a) => a.startsWith("--port="))?.split("=")[1] ?? 3000);
const hostname = rest.find((a) => a.startsWith("--host="))?.split("=")[1] || "::";
bootstrapProfile(appRoot, "production", rest);
const { runPreview } = await import("./preview.ts");
runPreview(appRoot, { port, hostname });
break;
}
case "create":
createApp(rest[0] ?? "");
break;
@@ -129,10 +193,18 @@ async function main(): Promise<void> {
case "g": {
if (rest[0] === "routes") {
const { regenerateRoutes } = await import("./routes.ts");
const n = regenerateRoutes(join(process.cwd(), "app"));
const n = regenerateRoutes(join(resolve(rest[1] ?? "."), "app"));
console.log(`✓ Generated app/routes.gen.ts (${n} routes)`);
break;
}
if (rest[0] === "types") {
const { generateApplicationTypesWithPlugins } = await import("./types.ts");
const result = await generateApplicationTypesWithPlugins(rest[1] ?? ".");
console.log(
`✓ Generated ${result.file} (${result.routes} routes, ${result.components} components)`,
);
break;
}
if (rest[0] === "docker") {
const { generateDocker } = await import("./docker.ts");
generateDocker(process.cwd());
@@ -153,6 +225,20 @@ async function main(): Promise<void> {
runGenerate(".", rest[0], rest[1]);
break;
}
case "routes": {
const appRoot = resolve(rest.find((arg) => !arg.startsWith("--")) ?? ".");
const { regenerateRoutes } = await import("./routes.ts");
const count = regenerateRoutes(join(appRoot, "app"));
console.log(`✓ Generated app/routes.gen.ts (${count} routes)`);
break;
}
case "typecheck": {
const { runTypecheck } = await import("./types.ts");
const healthy = await runTypecheck(rest.find((arg) => !arg.startsWith("--")) ?? ".");
if (!healthy) process.exitCode = 1;
else console.log("✓ Application types are valid");
break;
}
case "eject": {
const { runEject } = await import("./eject.ts");
const args = rest.filter((a) => !a.startsWith("--"));
@@ -191,10 +277,87 @@ async function main(): Promise<void> {
}
case "doctor": {
const { runDoctor } = await import("./doctor.ts");
const healthy = await runDoctor(rest.find((a) => !a.startsWith("--")) ?? ".");
const healthy = await runDoctor(rest.find((a) => !a.startsWith("--")) ?? ".", {
fix: rest.includes("--fix"),
});
if (!healthy) process.exitCode = 1;
break;
}
case "compatibility": {
const { runCompatibilityCommand } = await import("./compatibility-command.ts");
const subcommand = rest.find((value) => !value.startsWith("--")) ?? "check";
const appRoot = rest.filter((value) => !value.startsWith("--"))[1] ?? ".";
if (!["check", "explain", "upgrade"].includes(subcommand))
throw new Error(`WRN-COMPATIBILITY-COMMAND: unknown command '${subcommand}'.`);
const current = await runCompatibilityCommand(appRoot, subcommand, rest);
if (!current && subcommand !== "explain") process.exitCode = 1;
break;
}
case "contracts": {
const { runContractsCommand } = await import("./contracts-command.ts");
const subcommand = rest.find((value) => !value.startsWith("--")) ?? "check";
const appRoot = rest.filter((value) => !value.startsWith("--"))[1] ?? ".";
const result = await runContractsCommand(appRoot, subcommand, rest);
if (!result.ok) process.exitCode = 1;
break;
}
case "security": {
const values = rest.filter((value) => !value.startsWith("--"));
const { runSecurityCommand } = await import("./security-command.ts");
const healthy = await runSecurityCommand(values[1] ?? ".", values[0] ?? "audit", rest);
if (!healthy) process.exitCode = 1;
break;
}
case "api": {
const values = rest.filter((value) => !value.startsWith("--"));
if (!["generate", "docs"].includes(values[0] ?? ""))
throw new Error("WRN-API-COMMAND: use api generate or api docs.");
const { runApiCommand } = await import("./api-command.ts");
runApiCommand(values[1] ?? ".", "api", rest);
break;
}
case "sdk": {
const values = rest.filter((value) => !value.startsWith("--"));
if (values[0] !== "generate")
throw new Error("WRN-SDK-COMMAND: use sdk generate <language>.");
const { runApiCommand } = await import("./api-command.ts");
runApiCommand(values[2] ?? ".", "sdk", rest);
break;
}
case "deploy": {
const values = rest.filter((value) => !value.startsWith("--"));
const { generateDeployment } = await import("./deploy.ts");
const files = generateDeployment(values[1] ?? ".", values[0] ?? "");
console.log(`✓ Deployment preset '${values[0]}' ready (${files.length} new files)`);
break;
}
case "mcp": {
const { runMcpStdio } = await import("@wrnexus/mcp/stdio");
await runMcpStdio(resolve(rest.find((value) => !value.startsWith("--")) ?? "."));
break;
}
case "i18n": {
const values = rest.filter((value) => !value.startsWith("--"));
const { runI18nCommand } = await import("./i18n-command.ts");
if (!runI18nCommand(values[1] ?? ".", values[0] ?? "validate")) process.exitCode = 1;
break;
}
case "report": {
const { runReport } = await import("./report.ts");
runReport(rest.find((value) => !value.startsWith("--")) ?? ".", rest);
break;
}
case "playground": {
const { createPlaygroundHandler } = await import("@wrnexus/playground");
const port = Number(rest.find((value) => value.startsWith("--port="))?.split("=")[1] ?? 4173);
const server = Bun.serve({
port,
hostname: "127.0.0.1",
fetch: createPlaygroundHandler(),
});
console.log(`▶ WRNexus playground: http://localhost:${server.port}`);
break;
}
case "config": {
const { runConfigCommand } = await import("./config-command.ts");
await runConfigCommand(rest.find((a) => !a.startsWith("--")) ?? ".", rest);
@@ -202,6 +365,12 @@ async function main(): Promise<void> {
}
case "inspect": {
const target = rest.find((arg) => !arg.startsWith("--"));
if (target === "component") {
const values = rest.filter((arg) => !arg.startsWith("--"));
const { runInspectComponent } = await import("./inspect.ts");
runInspectComponent(values[2] ?? ".", values[1] ?? "", rest);
break;
}
const appRoot = rest.filter((arg) => !arg.startsWith("--"))[1] ?? ".";
const { runInspect } = await import("./inspect.ts");
await runInspect(appRoot, target, rest);
@@ -213,13 +382,25 @@ async function main(): Promise<void> {
if (!healthy) process.exitCode = 1;
break;
}
case "explain": {
const values = rest.filter((value) => !value.startsWith("--"));
const target = values[0] ?? "build";
const subject = target === "build" || target === "bundle" ? "" : (values[1] ?? "");
const appRoot =
target === "build" || target === "bundle" ? (values[1] ?? ".") : (values[2] ?? ".");
const { runExplain } = await import("./explain.ts");
runExplain(appRoot, target, subject, rest);
break;
}
case "test": {
const appRoot = rest.find((a) => !a.startsWith("--")) ?? ".";
const { TEST_LEVELS, runTests } = await import("./test.ts");
const values = rest.filter((value) => !value.startsWith("--"));
const hasLevel = TEST_LEVELS.includes(values[0] as (typeof TEST_LEVELS)[number]);
const appRoot = (hasLevel ? values[1] : values[0]) ?? ".";
const flag = rest.find((a) => a.startsWith("--profile="));
// Tests default to the `test` profile (config + .env.test), unless overridden.
process.env.WRNEXUS_PROFILE = resolveProfile({ explicit: flag?.split("=")[1] ?? "test" });
loadEnv(resolve(appRoot), process.env.WRNEXUS_PROFILE);
const { runTests } = await import("./test.ts");
runTests(appRoot, rest);
break;
}
@@ -259,6 +440,8 @@ async function main(): Promise<void> {
}
} catch (error) {
if (error instanceof Error && error.message !== "unknown-environment-command") throw error;
const { runPluginCliCommand } = await import("./plugin-command.ts");
if (await runPluginCliCommand(workspaceRoot, command, rest)) break;
console.error(`Unknown command or workspace environment: ${command}\n`);
help();
process.exit(1);