Refresh UI components and showcase; release updated framework packages

This commit is contained in:
Clintchiz committed 2026-09-20 18:13:24 +05:30
1 parent d800228585
commit c77f5e1cec
293 files changed
+22544 -35778

No files matched your search

+14 -3
View File
@@ -60,6 +60,7 @@ import { loadLocales, resolveI18n } from "@wrnexus/i18n";
import { pathToFileURL } from "node:url";
import { checkPerformanceBudgets } from "@wrnexus/core";
import { currentCliVersion } from "./update-notifier.ts";
import { shouldInlineCss } from "./inline-css.ts";
import {
createPluginRunner,
discoverPlugins,
@@ -73,7 +74,6 @@ import {
// the generated entry resolves whether @wrnexus/dev-server is a workspace or an
// installed dependency. Bun.build bundles it into a self-contained server.js.
const PROD_MODULE = "@wrnexus/dev-server";
const INLINE_CSS_LIMIT_BYTES = 4096;
const fwd = (p: string) => p.replace(/\\/g, "/");
@@ -648,7 +648,7 @@ export async function runBuild(appRoot: string): Promise<void> {
// theme stylesheet is selected from the request cookie and loaded first.
writeFileSync(join(distDir, "styles.css"), combinedCss, "utf8");
hasStyles = true;
if (Buffer.byteLength(combinedCss, "utf8") <= INLINE_CSS_LIMIT_BYTES) {
if (shouldInlineCss(combinedCss, config.styles?.inlineMaxBytes)) {
inlineStyles = combinedCss;
}
console.log(`✓ Styles: ${join(distDir, "styles.css")}`);
@@ -709,7 +709,16 @@ applyAuthzManifestEarly([${authzSetupEntries}]);
const runtimeConfigPath = ["wrnexus.config.ts", "wrnexus.config.js", "wrnexus.config.mjs"]
.map((name) => resolve(appRoot, name))
.find(existsSync);
if (runtimeConfigPath) imports.push(`import ${JSON.stringify(fwd(runtimeConfigPath))};`);
if (runtimeConfigPath && config.auth) {
// Importing config creates the engine, but does not run plugin.configure.
// Initialize route options before route/middleware modules are evaluated.
// Credentials are read by the config at server startup, never serialized here.
writeFileSync(join(distDir, ".auth-runtime.ts"),
`import config from ${JSON.stringify(fwd(runtimeConfigPath))};\n` +
`import { configureAuthRuntime } from "@wrnexus/auth/plugin";\n` +
`configureAuthRuntime(config.auth);\n`, "utf8");
imports.push(`import "./.auth-runtime.ts";`);
} else if (runtimeConfigPath) imports.push(`import ${JSON.stringify(fwd(runtimeConfigPath))};`);
const manifestRoutes = (routes: Route[]): string => {
const parts = routes.map((r) => {
@@ -796,6 +805,7 @@ applyAuthzManifestEarly([${authzSetupEntries}]);
const entry = `// AUTO-GENERATED production server entry — do not edit.
import { join } from "node:path";
import { createProductionServer } from ${JSON.stringify(PROD_MODULE)};
import { productionConnections } from "@wrnexus/cli/runtime-connections";
${imports.join("\n")}
await createProductionServer(
@@ -855,6 +865,7 @@ await createProductionServer(
tenancy: ${JSON.stringify(config.tenancy ?? {})},
navigation: ${JSON.stringify(config.navigation ?? {})},
developmentRuntime: process.env.WRNEXUS_PRODUCTION_DEV === "1",
...productionConnections(),
},
);
`;
+14
View File
@@ -0,0 +1,14 @@
/** Keep the default conservative; sites can opt in for a measured first-load improvement. */
export function shouldInlineCss(css: string, configuredLimit: number | undefined): boolean {
const limit = configuredLimit ?? 4096;
if (!Number.isSafeInteger(limit) || limit < 0) {
throw new Error("styles.inlineMaxBytes must be a non-negative safe integer");
}
if (!limit || Buffer.byteLength(css, "utf8") > limit) return false;
// Moving CSS into HTML must not change the base of relative asset URLs.
for (const match of css.matchAll(/url\(\s*([^)]+)\s*\)/gi)) {
const url = match[1]!.trim().replace(/^["']|["']$/g, "");
if (!/^(?:\/|https?:|data:)/i.test(url)) return false;
}
return true;
}
+14
View File
@@ -0,0 +1,14 @@
/** Deployment-time connection overrides for immutable production images. */
export function productionConnections(value = process.env.WRNEXUS_RUNTIME_CONNECTIONS) {
if (!value) return {};
const parsed = JSON.parse(value);
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
throw new Error("WRNEXUS_RUNTIME_CONNECTIONS must be a JSON object");
const allowed = new Set(["db", "databases", "realtime", "queue", "storage"]);
for (const key of Object.keys(parsed)) {
if (!allowed.has(key)) throw new Error(`Unsupported runtime connection: ${key}`);
if (!parsed[key] || typeof parsed[key] !== "object" || Array.isArray(parsed[key]))
throw new Error(`Runtime connection ${key} must be an object`);
}
return parsed;
}