From 66b4f280c9745d08fec264de460f6e87415b6363 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 31 Jul 2026 03:24:51 +0000 Subject: [PATCH] fix: restore site_url.ts and the imports manifest.ts never got MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This repo has not compiled since 2026-02-05. Commit 029e519 "WIP: json-ld checkpoint" added 202 lines to manifest.ts and deleted site_url.ts in the same change, and it is on main. The result was a hard type error, so the whole test suite refused to run. Three fixes, all recovered rather than invented: 1. site_url.ts restored verbatim from 1628c51, its last living commit. Not rewritten — `git show` of the deleted blob, 18 lines, normalizeSiteUrl and its two helpers. 2. `import type { VaultNode }` added. The type already existed and was exported from inputs/jsonld/types.ts; the WIP commit used it without importing it. 3. `import { loadVault }` added, likewise already exported from inputs/jsonld/loader.ts. One function had to be written, and its shape is dictated by the surrounding code rather than chosen: manifest.ts calls requireSiteUrl(value, fallback), but the only definition was a private zero-argument one in site_build_config.ts. Its two siblings in manifest.ts — requireSiteDir and requireVaultPath — fix the signature and style, and `defaultSiteUrl` sat defined-but-unused in the same file, which is what it was written for. Hence: prefer the explicit option, then the WebSite node's url, else defaultSiteUrl(). Unlike its siblings it does not throw, because defaultSiteUrl already yields a normalized value. deno check src/unfold/site/manifest.ts: passes deno test: 101 passed, 12 failed (previously: could not compile, 0 ran) THE 12 REMAINING FAILURES ARE NOT ADDRESSED AND ARE NOT FROM THIS CHANGE. They share one root cause: the tests read a `vault/` directory of JSON-LD, and while `vault/` exists it holds no .jsonld files at all — the repo's 39 .jsonld files live under hash-named top-level directories such as 2bcdd7ffb6ed9b59/web_site/site.jsonld. That is an unfinished move from the same WIP era. Fixing it means deciding where vault content is supposed to live, which is a product question, not a build fix, so it is left alone and reported. Worth noting one of those failures does exercise the new requireSiteUrl: with no WebSite node present it correctly falls back to defaultSiteUrl(), and the test wants the node's url. That test needs the fixture, not different logic. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01LF9Cu8u4dkCEM8MXC1QeDL --- src/unfold/site/manifest.ts | 11 +++++++++++ src/unfold/site/site_url.ts | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 src/unfold/site/site_url.ts diff --git a/src/unfold/site/manifest.ts b/src/unfold/site/manifest.ts index 8eb0fc8..3648886 100644 --- a/src/unfold/site/manifest.ts +++ b/src/unfold/site/manifest.ts @@ -1,5 +1,7 @@ import { DOMParser, type HTMLDocument } from "deno-dom-wasm"; import { normalizeSiteUrl } from "./site_url.ts"; +import type { VaultNode } from "../inputs/jsonld/types.ts"; +import { loadVault } from "../inputs/jsonld/loader.ts"; type ManifestPage = { path: string; @@ -209,6 +211,15 @@ const requireVaultPath = (value?: string): string => { return raw; }; +/// Unlike its siblings above, this does not throw: `defaultSiteUrl` already +/// supplies a normalized SITE_URL-or-placeholder, so an absent site URL has a +/// sensible answer. The fallback argument carries the WebSite node's url when +/// building from the vault graph. +const requireSiteUrl = (value?: string, fallback?: string): string => { + const raw = value?.trim() || fallback?.trim(); + return raw ? normalizeSiteUrl(raw) : defaultSiteUrl(); +}; + const hasJsonLdType = (node: VaultNode, type: string): boolean => { const value = node["@type"]; if (!value) return false; diff --git a/src/unfold/site/site_url.ts b/src/unfold/site/site_url.ts new file mode 100644 index 0000000..9ecb3d6 --- /dev/null +++ b/src/unfold/site/site_url.ts @@ -0,0 +1,18 @@ +const stripTrailingSlash = (value: string): string => value.replace(/\/$/, ""); + +const stripFoldEnginePrefix = (pathname: string): string => + pathname.replace(/^\/fold-engine(?=\/|$)/, ""); + +export const normalizeSiteUrl = (value: string): string => { + const trimmed = stripTrailingSlash(value.trim()); + try { + const url = new URL(trimmed); + const normalizedPath = stripFoldEnginePrefix( + stripTrailingSlash(url.pathname), + ); + url.pathname = normalizedPath || "/"; + return stripTrailingSlash(url.toString()); + } catch { + return stripTrailingSlash(stripFoldEnginePrefix(trimmed)); + } +};