Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/unfold/site/manifest.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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;
Expand Down
18 changes: 18 additions & 0 deletions src/unfold/site/site_url.ts
Original file line number Diff line number Diff line change
@@ -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));
}
};