From 3cfdc747fae8aa6f42ca58908f2b45db27badd14 Mon Sep 17 00:00:00 2001 From: Ajay Ghanwat Date: Tue, 14 Jul 2026 20:01:16 +0530 Subject: [PATCH] release: WRNexusJS 0.2.30 --- .publish/ai/package.json | 2 +- .publish/authz/package.json | 2 +- .publish/cli/package.json | 22 ++++----- .publish/compiler/package.json | 2 +- .publish/core/package.json | 2 +- .publish/csr/package.json | 4 +- .publish/db/package.json | 2 +- .publish/dev-server/package.json | 26 +++++------ .publish/encryption/package.json | 2 +- .publish/helpers/package.json | 4 +- .publish/i18n/package.json | 4 +- .publish/jwt/package.json | 2 +- .publish/mobile/package.json | 4 +- .publish/native/package.json | 2 +- .publish/oauth/package.json | 2 +- .publish/pubsub/package.json | 2 +- .publish/queue/package.json | 2 +- .publish/reactive/package.json | 2 +- .publish/router/package.json | 6 +-- .publish/ssr/package.json | 4 +- .publish/styles/package.json | 4 +- .publish/test/package.json | 2 +- .publish/tracking/package.json | 2 +- .publish/ui/package.json | 4 +- .publish/uploader/package.json | 4 +- .publish/validation/package.json | 2 +- packages/ai/package.json | 2 +- packages/authz/package.json | 2 +- packages/cli/package.json | 2 +- packages/cli/src/update.ts | 9 ++++ packages/compiler/package.json | 2 +- packages/core/package.json | 2 +- packages/csr/package.json | 2 +- packages/db/package.json | 2 +- packages/dev-server/package.json | 2 +- packages/dev-server/src/gateway.ts | 74 +++++++++++++++++++++++++----- packages/encryption/package.json | 2 +- packages/helpers/package.json | 2 +- packages/i18n/package.json | 2 +- packages/jwt/package.json | 2 +- packages/mobile/package.json | 2 +- packages/native/package.json | 2 +- packages/oauth/package.json | 2 +- packages/pubsub/package.json | 2 +- packages/queue/package.json | 2 +- packages/reactive/package.json | 2 +- packages/router/package.json | 2 +- packages/ssr/package.json | 2 +- packages/styles/package.json | 2 +- packages/test/package.json | 2 +- packages/tracking/package.json | 2 +- packages/ui/package.json | 2 +- packages/uploader/package.json | 2 +- packages/validation/package.json | 2 +- 54 files changed, 155 insertions(+), 96 deletions(-) diff --git a/.publish/ai/package.json b/.publish/ai/package.json index c81bfbc2..1b8f8489 100644 --- a/.publish/ai/package.json +++ b/.publish/ai/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/ai", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "Zero-dependency Claude (Anthropic) client for WrNexus apps.", "license": "MIT", diff --git a/.publish/authz/package.json b/.publish/authz/package.json index a067d076..c6b96741 100644 --- a/.publish/authz/package.json +++ b/.publish/authz/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/authz", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/authz — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/cli/package.json b/.publish/cli/package.json index 4f34180a..22b9f125 100644 --- a/.publish/cli/package.json +++ b/.publish/cli/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/cli", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/cli — part of the WrNexus framework.", "license": "MIT", @@ -28,16 +28,16 @@ "wrnexus": "./dist/index.js" }, "dependencies": { - "@wrnexus/core": "^0.2.29", - "@wrnexus/router": "^0.2.29", - "@wrnexus/csr": "^0.2.29", - "@wrnexus/compiler": "^0.2.29", - "@wrnexus/styles": "^0.2.29", - "@wrnexus/dev-server": "^0.2.29", - "@wrnexus/ui": "^0.2.29", - "@wrnexus/validation": "^0.2.29", - "@wrnexus/i18n": "^0.2.29", - "@wrnexus/db": "^0.2.29" + "@wrnexus/core": "^0.2.30", + "@wrnexus/router": "^0.2.30", + "@wrnexus/csr": "^0.2.30", + "@wrnexus/compiler": "^0.2.30", + "@wrnexus/styles": "^0.2.30", + "@wrnexus/dev-server": "^0.2.30", + "@wrnexus/ui": "^0.2.30", + "@wrnexus/validation": "^0.2.30", + "@wrnexus/i18n": "^0.2.30", + "@wrnexus/db": "^0.2.30" }, "files": [ "dist" diff --git a/.publish/compiler/package.json b/.publish/compiler/package.json index 0baba426..52525cf5 100644 --- a/.publish/compiler/package.json +++ b/.publish/compiler/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/compiler", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/compiler — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/core/package.json b/.publish/core/package.json index a4a79e4f..9d6a72d2 100644 --- a/.publish/core/package.json +++ b/.publish/core/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/core", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/core — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/csr/package.json b/.publish/csr/package.json index 218e7994..18d8d7eb 100644 --- a/.publish/csr/package.json +++ b/.publish/csr/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/csr", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/csr — part of the WrNexus framework.", "license": "MIT", @@ -21,7 +21,7 @@ } }, "dependencies": { - "@wrnexus/core": "^0.2.29" + "@wrnexus/core": "^0.2.30" }, "files": [ "dist" diff --git a/.publish/db/package.json b/.publish/db/package.json index 75003b05..a4038caa 100644 --- a/.publish/db/package.json +++ b/.publish/db/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/db", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/db — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/dev-server/package.json b/.publish/dev-server/package.json index 324ed4f5..d7535bf6 100644 --- a/.publish/dev-server/package.json +++ b/.publish/dev-server/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/dev-server", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/dev-server — part of the WrNexus framework.", "license": "MIT", @@ -25,18 +25,18 @@ } }, "dependencies": { - "@wrnexus/core": "^0.2.29", - "@wrnexus/router": "^0.2.29", - "@wrnexus/ssr": "^0.2.29", - "@wrnexus/csr": "^0.2.29", - "@wrnexus/compiler": "^0.2.29", - "@wrnexus/styles": "^0.2.29", - "@wrnexus/ui": "^0.2.29", - "@wrnexus/validation": "^0.2.29", - "@wrnexus/i18n": "^0.2.29", - "@wrnexus/db": "^0.2.29", - "@wrnexus/pubsub": "^0.2.29", - "@wrnexus/uploader": "^0.2.29" + "@wrnexus/core": "^0.2.30", + "@wrnexus/router": "^0.2.30", + "@wrnexus/ssr": "^0.2.30", + "@wrnexus/csr": "^0.2.30", + "@wrnexus/compiler": "^0.2.30", + "@wrnexus/styles": "^0.2.30", + "@wrnexus/ui": "^0.2.30", + "@wrnexus/validation": "^0.2.30", + "@wrnexus/i18n": "^0.2.30", + "@wrnexus/db": "^0.2.30", + "@wrnexus/pubsub": "^0.2.30", + "@wrnexus/uploader": "^0.2.30" }, "files": [ "dist" diff --git a/.publish/encryption/package.json b/.publish/encryption/package.json index 845cd9eb..2e77b39d 100644 --- a/.publish/encryption/package.json +++ b/.publish/encryption/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/encryption", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/encryption — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/helpers/package.json b/.publish/helpers/package.json index 1f538247..f61799ad 100644 --- a/.publish/helpers/package.json +++ b/.publish/helpers/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/helpers", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "Safe convenience helpers for WrNexus request contexts and common application flows.", "license": "MIT", @@ -21,7 +21,7 @@ } }, "dependencies": { - "@wrnexus/core": "^0.2.29" + "@wrnexus/core": "^0.2.30" }, "files": [ "dist" diff --git a/.publish/i18n/package.json b/.publish/i18n/package.json index aa2a8a46..286379d4 100644 --- a/.publish/i18n/package.json +++ b/.publish/i18n/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/i18n", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/i18n — part of the WrNexus framework.", "license": "MIT", @@ -21,7 +21,7 @@ } }, "dependencies": { - "@wrnexus/core": "^0.2.29" + "@wrnexus/core": "^0.2.30" }, "files": [ "dist" diff --git a/.publish/jwt/package.json b/.publish/jwt/package.json index 0087f5d0..b0dfd15b 100644 --- a/.publish/jwt/package.json +++ b/.publish/jwt/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/jwt", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/jwt — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/mobile/package.json b/.publish/mobile/package.json index e3efc4e3..a9a35491 100644 --- a/.publish/mobile/package.json +++ b/.publish/mobile/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/mobile", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/mobile — part of the WrNexus framework.", "license": "MIT", @@ -21,7 +21,7 @@ } }, "dependencies": { - "@wrnexus/native": "^0.2.29" + "@wrnexus/native": "^0.2.30" }, "files": [ "dist" diff --git a/.publish/native/package.json b/.publish/native/package.json index 74e22c8e..8fb55786 100644 --- a/.publish/native/package.json +++ b/.publish/native/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/native", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/native — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/oauth/package.json b/.publish/oauth/package.json index 30577247..c4b01dce 100644 --- a/.publish/oauth/package.json +++ b/.publish/oauth/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/oauth", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/oauth — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/pubsub/package.json b/.publish/pubsub/package.json index 44987175..698b072b 100644 --- a/.publish/pubsub/package.json +++ b/.publish/pubsub/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/pubsub", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/pubsub — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/queue/package.json b/.publish/queue/package.json index f5081005..b77d179b 100644 --- a/.publish/queue/package.json +++ b/.publish/queue/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/queue", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/queue — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/reactive/package.json b/.publish/reactive/package.json index a259566f..06d76545 100644 --- a/.publish/reactive/package.json +++ b/.publish/reactive/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/reactive", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/reactive — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/router/package.json b/.publish/router/package.json index f15718d0..af7b04c7 100644 --- a/.publish/router/package.json +++ b/.publish/router/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/router", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/router — part of the WrNexus framework.", "license": "MIT", @@ -21,8 +21,8 @@ } }, "dependencies": { - "@wrnexus/compiler": "^0.2.29", - "@wrnexus/core": "^0.2.29" + "@wrnexus/compiler": "^0.2.30", + "@wrnexus/core": "^0.2.30" }, "files": [ "dist" diff --git a/.publish/ssr/package.json b/.publish/ssr/package.json index 0efd0938..147047c5 100644 --- a/.publish/ssr/package.json +++ b/.publish/ssr/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/ssr", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/ssr — part of the WrNexus framework.", "license": "MIT", @@ -21,7 +21,7 @@ } }, "dependencies": { - "@wrnexus/core": "^0.2.29" + "@wrnexus/core": "^0.2.30" }, "files": [ "dist" diff --git a/.publish/styles/package.json b/.publish/styles/package.json index 2e34b7b7..b57e79d9 100644 --- a/.publish/styles/package.json +++ b/.publish/styles/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/styles", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/styles — part of the WrNexus framework.", "license": "MIT", @@ -21,7 +21,7 @@ } }, "dependencies": { - "@wrnexus/uploader": "^0.2.29" + "@wrnexus/uploader": "^0.2.30" }, "files": [ "dist" diff --git a/.publish/test/package.json b/.publish/test/package.json index 6f92d47a..4a08082a 100644 --- a/.publish/test/package.json +++ b/.publish/test/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/test", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/test — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/tracking/package.json b/.publish/tracking/package.json index 484110dc..c6be9e36 100644 --- a/.publish/tracking/package.json +++ b/.publish/tracking/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/tracking", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/tracking — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/ui/package.json b/.publish/ui/package.json index 549b0f11..752e7ae9 100644 --- a/.publish/ui/package.json +++ b/.publish/ui/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/ui", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/ui — part of the WrNexus framework.", "license": "MIT", @@ -22,7 +22,7 @@ "./ui.css": "./ui.css" }, "dependencies": { - "@wrnexus/core": "^0.2.29" + "@wrnexus/core": "^0.2.30" }, "files": [ "dist", diff --git a/.publish/uploader/package.json b/.publish/uploader/package.json index d8216971..cf24d2f5 100644 --- a/.publish/uploader/package.json +++ b/.publish/uploader/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/uploader", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/uploader — part of the WrNexus framework.", "license": "MIT", @@ -21,7 +21,7 @@ } }, "dependencies": { - "@wrnexus/core": "^0.2.29" + "@wrnexus/core": "^0.2.30" }, "files": [ "dist" diff --git a/.publish/validation/package.json b/.publish/validation/package.json index e387ef84..8e2d3758 100644 --- a/.publish/validation/package.json +++ b/.publish/validation/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/validation", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "description": "@wrnexus/validation — part of the WrNexus framework.", "license": "MIT", diff --git a/packages/ai/package.json b/packages/ai/package.json index a6b4439e..b119ebd8 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/ai", - "version": "0.2.29", + "version": "0.2.30", "private": true, "type": "module", "description": "Zero-dependency Claude (Anthropic) client for WrNexus apps.", diff --git a/packages/authz/package.json b/packages/authz/package.json index 0d55404e..eaa572b9 100644 --- a/packages/authz/package.json +++ b/packages/authz/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/authz", - "version": "0.2.29", + "version": "0.2.30", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/cli/package.json b/packages/cli/package.json index 954bfba6..781c7277 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/cli", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/cli/src/update.ts b/packages/cli/src/update.ts index 6f9b7a82..e15020d9 100644 --- a/packages/cli/src/update.ts +++ b/packages/cli/src/update.ts @@ -339,6 +339,15 @@ const MIGRATIONS: Migration[] = [ // Existing applications remain compatible with this release. }, }, + { + version: "0.2.30", + id: "workspace-config-auth-improvements", + description: + "Adds dynamic workspace origins, workspace forward-auth resolution, layout support, component tag syntax, and editor improvements.", + apply() { + // No generated application files require automatic migration. + }, + }, ]; /** Release tooling uses this to require an explicit migration entry per version. */ diff --git a/packages/compiler/package.json b/packages/compiler/package.json index 93fbe60b..363f0048 100644 --- a/packages/compiler/package.json +++ b/packages/compiler/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/compiler", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/core/package.json b/packages/core/package.json index 81ead3d2..0a518a6a 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/core", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/csr/package.json b/packages/csr/package.json index 6d929aaf..22c11e45 100644 --- a/packages/csr/package.json +++ b/packages/csr/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/csr", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/db/package.json b/packages/db/package.json index fe5cdf60..7f56db4d 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/db", - "version": "0.2.29", + "version": "0.2.30", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/dev-server/package.json b/packages/dev-server/package.json index 4ed22b4e..2567c2dd 100644 --- a/packages/dev-server/package.json +++ b/packages/dev-server/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/dev-server", - "version": "0.2.29", + "version": "0.2.30", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/dev-server/src/gateway.ts b/packages/dev-server/src/gateway.ts index f0592c3b..a00a75e0 100644 --- a/packages/dev-server/src/gateway.ts +++ b/packages/dev-server/src/gateway.ts @@ -14,18 +14,27 @@ import { join, resolve } from "node:path"; import { fileURLToPath } from "node:url"; import { RESTART_EXIT_CODE } from "./restart.ts"; -/** Per-app access control, enforced at the gateway before proxying. */ +export type GatewayForwardAuth = ( + | { + url: string; + app?: never; + path?: never; + } + | { + app: string; + path?: string; + url?: never; + } +) & { + headers?: string[]; +}; + export interface GatewayAuth { - /** HTTP Basic auth — one or more allowed user/password pairs. */ basic?: { user: string; pass: string } | Array<{ user: string; pass: string }>; - /** Allow only these client IPs (exact match; others get 403). */ + allowIps?: string[]; - /** - * Forward-auth (SSO): the gateway GETs `url` forwarding the request's cookies + - * Authorization; a 2xx allows the request, anything else blocks it (its status - * is returned). Point it at your own verify endpoint. - */ - forward?: { url: string }; + + forward?: GatewayForwardAuth; } export interface GatewayApp { @@ -162,6 +171,7 @@ async function checkAuth( auth: GatewayAuth | undefined, req: Request, ip: string, + internalOrigins: Readonly>, ): Promise { if (!auth) return null; @@ -189,12 +199,14 @@ async function checkAuth( } if (auth.forward) { + const verifyUrl = resolveForwardAuthUrl(auth.forward, internalOrigins); + try { - const res = await fetch(auth.forward.url, { + const res = await fetch(verifyUrl, { headers: forwardAuthHeaders(req), redirect: "manual", }); - if (!res.ok) return forwardAuthFailure(res, auth.forward.url); + if (!res.ok) return forwardAuthFailure(res, verifyUrl); } catch { return new Response("Auth service unavailable", { status: 503 }); } @@ -203,6 +215,40 @@ async function checkAuth( return null; } +function resolveForwardAuthUrl( + forward: NonNullable, + internalOrigins: Readonly>, +): string { + if (typeof forward.app === "string") { + const appName = forward.app; + const origin = internalOrigins[appName]; + + if (!origin) { + throw new Error(`Forward-auth app "${appName}" was not found.`); + } + + const path = forward.path ?? "/api/verify"; + + if (!path.startsWith("/")) { + throw new Error(`Forward-auth path must start with "/": ${path}`); + } + + return new URL(path, `${origin}/`).href; + } + + if (typeof forward.url === "string") { + const url = new URL(forward.url); + + if (url.protocol !== "http:" && url.protocol !== "https:") { + throw new Error(`Forward-auth URL must use HTTP or HTTPS: ${forward.url}`); + } + + return url.href; + } + + throw new Error("Forward auth requires either `app` or `url`."); +} + /** Baseline edge security headers, only where the app didn't already set them. */ function applyEdgeHeaders(res: Response): Response { const defaults: Record = { @@ -330,6 +376,10 @@ export async function startGateway(opts: GatewayOptions): Promise> = Object.freeze( + Object.fromEntries(targets.map((target) => [target.name, target.origin])), + ); + const stopChildren = () => { stopping = true; for (const target of targets) { @@ -390,7 +440,7 @@ export async function startGateway(opts: GatewayOptions): Promise