Refresh UI components and showcase; release updated framework packages
This commit is contained in:
1 parent
d800228585
commit
c77f5e1cec
293 files changed
+22544
-35778
No files matched your search
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/core",
|
||||
"version": "0.8.15",
|
||||
"version": "0.8.16",
|
||||
"type": "module",
|
||||
"main": "src/index.ts",
|
||||
"exports": {
|
||||
|
||||
@@ -120,6 +120,9 @@ export function createContext<Params extends Record<string, string> = Record<str
|
||||
req: Request,
|
||||
url: URL,
|
||||
): Context<Params> {
|
||||
// The caller supplies the validated public URL (including trusted proxies).
|
||||
// Request-based handlers must see the same origin as ctx.url.
|
||||
if (req.url !== url.href) req = new Request(url, req);
|
||||
const cookies = createCookieStore(req);
|
||||
return {
|
||||
req,
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { getRequestContext } from "./request-context.ts";
|
||||
import { Buffer } from "node:buffer";
|
||||
|
||||
type Registry = { id: string; definitions: unknown[] };
|
||||
const registries = new WeakMap<object, Registry>();
|
||||
|
||||
/** Hoist nested templates out of each other for linear-size hydration data. */
|
||||
export function encodeControlTemplate(value: unknown): string {
|
||||
const ctx = getRequestContext();
|
||||
if (!ctx) return Buffer.from(JSON.stringify(value), "utf8").toString("base64");
|
||||
let registry = registries.get(ctx);
|
||||
if (!registry) {
|
||||
registry = { id: `wrn-controls-${crypto.randomUUID()}`, definitions: [] };
|
||||
registries.set(ctx, registry);
|
||||
}
|
||||
const index = registry.definitions.push(value) - 1;
|
||||
return `@${registry.id}:${index}`;
|
||||
}
|
||||
|
||||
export function renderControlTemplates(): string {
|
||||
const ctx = getRequestContext();
|
||||
const registry = ctx && registries.get(ctx);
|
||||
if (!registry) return "";
|
||||
const json = JSON.stringify(registry.definitions).replace(/</g, "\\u003c");
|
||||
return `<script type="application/json" data-wrn-controls id="${registry.id}">${json}</script>`;
|
||||
}
|
||||
@@ -237,3 +237,4 @@ export type {
|
||||
IdempotencyRecord,
|
||||
IdempotencyStore,
|
||||
} from "./platform.ts";
|
||||
export { encodeControlTemplate, renderControlTemplates } from "./control-templates.ts";
|
||||
@@ -0,0 +1,43 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { encodeControlTemplate, renderControlTemplates } from "../src/control-templates.ts";
|
||||
import { runWithRequestContext } from "../src/request-context.ts";
|
||||
import { createContext } from "../src/context.ts";
|
||||
import { resolveRequestUrl } from "../src/headers.ts";
|
||||
|
||||
test("nested controls use short references and HTML-safe isolated registries", async () => {
|
||||
const results = await Promise.all(["first", "second"].map((name) =>
|
||||
runWithRequestContext({} as never, async () => {
|
||||
let body = `</script><p>${name}</p>`;
|
||||
for (let i = 0; i < 30; i++) {
|
||||
body = `<template data-wrn-if="${encodeControlTemplate([{cond: null, body}])}"></template>`;
|
||||
}
|
||||
await Promise.resolve();
|
||||
const html = renderControlTemplates();
|
||||
expect(html.length).toBeLessThan(7000);
|
||||
expect(html.match(/<\/script>/g)).toHaveLength(1);
|
||||
return html;
|
||||
}),
|
||||
));
|
||||
expect(results[0]).toContain("first");
|
||||
expect(results[0]).not.toContain("second");
|
||||
expect(results[1]).not.toContain("first");
|
||||
expect(renderControlTemplates()).toBe("");
|
||||
});
|
||||
|
||||
test("standalone rendering keeps the base64 format", () => {
|
||||
expect(JSON.parse(Buffer.from(encodeControlTemplate([1]), "base64").toString())).toEqual([1]);
|
||||
});
|
||||
|
||||
test("trusted proxy request URL and body agree with context; untrusted headers are ignored", async () => {
|
||||
for (const trust of [true, false]) {
|
||||
const request = new Request("http://internal:3000/api/captcha/challenge", {
|
||||
method: "POST", body: '{"test":1}',
|
||||
headers: { "x-forwarded-proto": "https", "x-forwarded-host": "wrnexus.com", origin: "https://evil.example" },
|
||||
});
|
||||
const context = createContext(request, resolveRequestUrl(request, trust));
|
||||
expect(context.req.url).toBe(context.url.href);
|
||||
expect(context.url.origin).toBe(trust ? "https://wrnexus.com" : "http://internal:3000");
|
||||
expect(context.req.headers.get("origin")).toBe("https://evil.example");
|
||||
expect(await context.req.json()).toEqual({ test: 1 });
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user