content: ao-the-asset

This commit is contained in:
fn
2026-04-27 15:17:32 +01:00
parent 3f059905d8
commit 7c9dc57c29
4 changed files with 125 additions and 5 deletions

View File

@@ -1,5 +1,5 @@
import DOMPurify from "dompurify";
import { marked } from "marked";
import { marked, type Tokens } from "marked";
import { parse as parseYaml } from "yaml";
import { AO_PROCESS_ID, AO_URL, ARWEAVE_GATEWAY, MANIFEST_TX_ID } from "./config";
import { parseManifest, type Frontmatter, type ManifestPost } from "./types";
@@ -16,6 +16,52 @@ marked.setOptions({
breaks: false
});
const escapeHtml = (value: string): string =>
value
.replaceAll("&", "&")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll('"', "&quot;");
const getTweetEmbedUrl = (value: string): string | null => {
let url: URL;
try {
url = new URL(value.trim());
} catch {
return null;
}
if (url.protocol !== "https:" && url.protocol !== "http:") return null;
const hostname = url.hostname.toLowerCase().replace(/^www\./, "");
const isTweetHost =
hostname === "x.com" || hostname === "twitter.com" || hostname === "mobile.twitter.com";
if (!isTweetHost) return null;
const [handle, statusSegment, statusId] = url.pathname.split("/").filter(Boolean);
if (!handle || !statusSegment || !statusId) return null;
if (!/^[a-z0-9_]{1,15}$/i.test(handle)) return null;
if (statusSegment !== "status" && statusSegment !== "statuses") return null;
if (!/^\d+$/.test(statusId)) return null;
return `https://twitter.com/${handle}/status/${statusId}`;
};
marked.use({
renderer: {
paragraph(this, token: Tokens.Paragraph): string {
const tweetUrl = getTweetEmbedUrl(token.text);
if (!tweetUrl) {
return `<p>${this.parser.parseInline(token.tokens)}</p>\n`;
}
const href = escapeHtml(tweetUrl);
const link = `<a href="${href}">${href}</a>`;
return `<blockquote class="twitter-tweet" data-theme="light" data-dnt="true">${link}</blockquote>\n`;
}
}
});
export const arweaveUrl = (txId: string): string => `${ARWEAVE_GATEWAY}/${txId}`;
export const getReadableDate = (date?: string | null): string | null => {