From 4df0adde53c228782c8a80ebbc9736b186ef0746 Mon Sep 17 00:00:00 2001 From: Graham Barber Date: Sat, 6 Jun 2026 13:15:27 -0700 Subject: [PATCH] fix(types): resolve pre-existing deno check failures Four type errors had accumulated from dependency and TS-lib drift, unrelated to recent feature work. Clearing them so deno check passes. - theme/stylesheet.ts, theme/typescript.ts: terrazzo 2.1.0's build() now requires a resolver in its options. parse() already returns one, so destructure resolver and thread it through both build() calls. - server/dev.ts: esbuild's OutputFile.contents types as Uint8Array, which no longer satisfies BodyInit under the current TS lib. Serve the bundle via the .text getter instead, lossless for a JS payload and free of the byte-buffer typing. - core/layout.ts: make isImageOnlyParagraph a type guard (node is ComarkElement), matching isMediaBlock. The body already narrows via isElement, so the guard is sound and the invalid "only as ComarkElement" cast drops out. deno.lock gains one transitive entry (@deno/graph) pulled in while running the theme build. Co-Authored-By: Claude Opus 4.8 --- deno.lock | 5 +++++ packages/core/layout.ts | 4 ++-- packages/server/dev.ts | 8 +++++++- packages/theme/stylesheet.ts | 4 ++-- packages/theme/typescript.ts | 4 ++-- 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/deno.lock b/deno.lock index 6f4eb17..112d8b1 100644 --- a/deno.lock +++ b/deno.lock @@ -9,6 +9,7 @@ "jsr:@deno-library/progress@^1.5.1": "1.5.1", "jsr:@deno/cache-dir@0.22.2": "0.22.2", "jsr:@deno/esbuild-plugin@^1.1.5": "1.1.5", + "jsr:@deno/graph@0.86": "0.86.9", "jsr:@deno/loader@~0.3.3": "0.3.4", "jsr:@es-toolkit/es-toolkit@^1.39.9": "1.39.9", "jsr:@eta-dev/eta@^3.5.0": "3.5.0", @@ -114,6 +115,7 @@ "@deno/cache-dir@0.22.2": { "integrity": "0c84b8db6175618cc2e25ed7d7648d83b38e298c14c1aae1e4b4e1b2219b840c", "dependencies": [ + "jsr:@deno/graph", "jsr:@std/fmt@^1.0.3", "jsr:@std/fs@^1.0.6", "jsr:@std/io@0.225", @@ -128,6 +130,9 @@ "npm:esbuild@~0.25.5" ] }, + "@deno/graph@0.86.9": { + "integrity": "c4f353a695bcc5246c099602977dabc6534eacea9999a35a8cb24e807192e6a1" + }, "@deno/loader@0.3.4": { "integrity": "c56003bc7027606301c3fe62704723b207a9e508c9fb154cf5131abb9d4d2673" }, diff --git a/packages/core/layout.ts b/packages/core/layout.ts index 31ce20b..accef9d 100644 --- a/packages/core/layout.ts +++ b/packages/core/layout.ts @@ -39,7 +39,7 @@ function isHeading(node: ComarkNode): boolean { return t !== undefined && HEADINGS.has(t); } -function isImageOnlyParagraph(node: ComarkNode): boolean { +function isImageOnlyParagraph(node: ComarkNode): node is ComarkElement { if (!isElement(node) || node[0] !== "p") return false; const kids = childrenOf(node); return kids.length === 1 && isElement(kids[0]) && kids[0][0] === "img"; @@ -162,7 +162,7 @@ export function detectLayout( return { layout, children: [...heads, figureFor(only, caption)] }; } if (isImageOnlyParagraph(only)) { - const img = childrenOf(only as ComarkElement)[0] as ComarkElement; + const img = childrenOf(only)[0] as ComarkElement; if (noHeading) { return { layout: "image-full", children: [figureFor(img, caption)] }; } diff --git a/packages/server/dev.ts b/packages/server/dev.ts index dcdec64..46973a4 100644 --- a/packages/server/dev.ts +++ b/packages/server/dev.ts @@ -59,7 +59,13 @@ function makeHandler(path: string) { write: false, }); - return new Response(outputFiles[0].contents, { + // Serve the bundle via OutputFile.text (a string getter) rather + // than .contents (Uint8Array). esbuild types .contents as a + // plain Uint8Array, which under recent TS lib.dom is + // Uint8Array and no longer matches BodyInit's + // Uint8Array. The text form is lossless for a JS + // bundle and sidesteps the byte-buffer typing entirely. + return new Response(outputFiles[0].text, { headers: { "Content-Type": "text/javascript", "Cache-Control": "no-store", diff --git a/packages/theme/stylesheet.ts b/packages/theme/stylesheet.ts index e3e02fa..75626bc 100644 --- a/packages/theme/stylesheet.ts +++ b/packages/theme/stylesheet.ts @@ -64,8 +64,8 @@ export async function compileCss(themePath?: string) { }); } - const { tokens, sources } = await parse(files, { config }); - const buildResult = await build(tokens, { sources, config }); + const { tokens, sources, resolver } = await parse(files, { config }); + const buildResult = await build(tokens, { sources, config, resolver }); return buildResult.outputFiles.map((f) => f.contents).join("\n\n"); } diff --git a/packages/theme/typescript.ts b/packages/theme/typescript.ts index ed51446..99ef98c 100644 --- a/packages/theme/typescript.ts +++ b/packages/theme/typescript.ts @@ -89,8 +89,8 @@ export async function compileJs() { } } - const { tokens, sources } = await parse(files, { config }); - const buildResult = await build(tokens, { sources, config }); + const { tokens, sources, resolver } = await parse(files, { config }); + const buildResult = await build(tokens, { sources, config, resolver }); for (const { filename, contents } of buildResult.outputFiles) { await Deno.writeTextFile(new URL(filename, import.meta.url), contents); -- 2.51.2