Compare commits

...
Author SHA1 Message Date
ClintchizandClaude Opus 5 e819c5739e Revert "chore(example): regenerate basic-app queries"
Quality / quality (ubuntu-latest) (push) Failing after 12m38s
Quality / quality (windows-latest) (push) Canceled after 0s
The generator's placeholder style is not deterministic across runs: the
same command emitted $1 once and ? the next time, depending on the
database dialect active in the environment. Restoring the committed
output and reverting my earlier regeneration, which was environment
churn rather than an intended change.

Worth a look on its own: a generator whose output depends on ambient
environment makes check:generated-types environment-sensitive.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 19:26:07 +05:30
ClintchizandClaude Opus 5 ac164789bd fix(dev): serve the HMR client as an external script
A document's CSP nonce is fixed at load, so an inline script delivered by
a later response can never carry a nonce that document accepts. The HMR
client is now served at /__wrnexus/hmr-client.js, which script-src 'self'
already covers and which needs no nonce at all.

This removes one of the two inline scripts CSP was blocking in
development. The i18n data script is still blocked and needs the same
treatment; it is shared with the CSR navigation and HMR parsers, so
moving it spans @wrnexus/i18n, csr, and dev-server.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 19:25:40 +05:30
3 changed files with 19 additions and 6 deletions
+4 -4
View File
@@ -3,7 +3,7 @@ import type { Db, ExecResult } from "@wrnexus/db";
import { users } from "./schema.ts";
export async function GetUserByEmail(db: Db, args: { email: string }): Promise<{ id: number; email: string; name: string; active: boolean; passwordHash: string; createdAt: Date } | null> {
return (await db.one("SELECT * FROM users WHERE email = $1", [args.email], users)) as { id: number; email: string; name: string; active: boolean; passwordHash: string; createdAt: Date } | null;
return (await db.one("SELECT * FROM users WHERE email = ?", [args.email], users)) as { id: number; email: string; name: string; active: boolean; passwordHash: string; createdAt: Date } | null;
}
export async function ListUsers(db: Db): Promise<{ id: number; name: string; active: boolean }[]> {
@@ -11,13 +11,13 @@ export async function ListUsers(db: Db): Promise<{ id: number; name: string; act
}
export async function CountActive(db: Db, args: { active: boolean }): Promise<{ n: number } | null> {
return (await db.one("SELECT COUNT(*) AS n FROM users WHERE active = $1", [args.active])) as { n: number } | null;
return (await db.one("SELECT COUNT(*) AS n FROM users WHERE active = ?", [args.active])) as { n: number } | null;
}
export async function CreateUser(db: Db, args: { email: string; name: string; active: boolean }): Promise<ExecResult> {
return db.exec("INSERT INTO users (email, name, active) VALUES ($1, $2, $3)", [args.email, args.name, args.active]);
return db.exec("INSERT INTO users (email, name, active) VALUES (?, ?, ?)", [args.email, args.name, args.active]);
}
export async function DeactivateUser(db: Db, args: { id: number }): Promise<ExecResult> {
return db.exec("UPDATE users SET active = 0 WHERE id = $1", [args.id]);
return db.exec("UPDATE users SET active = 0 WHERE id = ?", [args.id]);
}
+2
View File
@@ -34,6 +34,7 @@ import type { AssetServer } from "./runtime.ts";
import { servePublicAsset } from "./public.ts";
import { servePluginAsset, type ServedPluginAsset } from "./plugin-assets.ts";
import { serveIslandArtifact, serveWrnBrowserArtifact } from "./pipeline.ts";
import { HMR_CLIENT_HREF, HMR_CLIENT_JS } from "./runtime.ts";
/** Style inputs the dev asset server needs to build `/__wrnexus/styles.css`. */
export interface DevStyles {
@@ -99,6 +100,7 @@ export function createDevAssetServer(
if (pathname.startsWith("/__wrnexus/island/")) {
return serveIslandArtifact(pathname) ?? new Response("Not Found", { status: 404 });
}
if (pathname === HMR_CLIENT_HREF) return jsResponse(HMR_CLIENT_JS);
if (pathname === "/__wrnexus/islands.js") return jsResponse(getIslandRuntime(true));
if (pathname === "/__wrnexus/reactive.js") return jsResponse(getReactiveRuntime(true));
if (pathname === "/__wrnexus/controllers.js")
+13 -2
View File
@@ -878,8 +878,19 @@ function randomNonce(): string {
}
/** The dev HMR client as a nonce-tagged inline script (strict-CSP friendly). */
function hmrClientTag(nonce: string): string {
return `<script nonce="${nonce}">${HMR_CLIENT_JS}</script>`;
/** Path the dev asset server publishes the HMR client on. */
export const HMR_CLIENT_HREF = "/__wrnexus/hmr-client.js";
/**
* The HMR client is served as an external module rather than inlined.
*
* A document's CSP nonce is fixed at load, so an inline script arriving from a
* later response — which is exactly what an HMR reload produces — can never
* carry a nonce this document accepts. An external file is covered by
* script-src 'self' and needs no nonce at all.
*/
function hmrClientTag(_nonce: string): string {
return `<script src="${HMR_CLIENT_HREF}"></script>`;
}
/** 403 for a rejected cross-site WebSocket handshake. */