diff --git a/src/context.ts b/src/context.ts new file mode 100644 index 0000000..008098f --- /dev/null +++ b/src/context.ts @@ -0,0 +1,5 @@ +export default interface Context { + html: HTMLRewriter + request: Request + url: URL +} diff --git a/src/index.ts b/src/index.ts index d2461da..41cef31 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,7 @@ import { Hono } from "hono" import { requestInit } from "./config" import { normalize } from "./encoding" import summary from "./summary" +import type Context from "./context" export interface Env { // Example binding to KV. Learn more at https://developers.cloudflare.com/workers/runtime-apis/kv/ // MY_KV_NAMESPACE: KVNamespace; @@ -33,7 +34,11 @@ app.get("/url", async (context) => { const response = (await fetch(url, requestInit(context.req.raw))) as any as Response url = new URL(response.url) const rewriter = new HTMLRewriter() - const summarized = summary(context.req.raw, url, rewriter) + const summarized = summary({ + html: rewriter, + request: context.req.raw, + url, + }) const reader = (rewriter.transform(await normalize(response)).body as ReadableStream).getReader() while (!(await reader.read()).done); return context.json(await summarized) diff --git a/src/summary/amazon/description.ts b/src/summary/amazon/description.ts index af5917d..525146b 100644 --- a/src/summary/amazon/description.ts +++ b/src/summary/amazon/description.ts @@ -2,20 +2,22 @@ import { decode } from "html-entities" import clip from "summaly/built/utils/clip" import { BufferedTextHandler, assign } from "../common" import type { PrioritizedReference } from "../common" +import type Context from "../../context" -export default function getDescription(url: URL, html: HTMLRewriter) { +export default function getDescription(context: Context) { + const { promise, resolve, reject } = Promise.withResolvers() const result: PrioritizedReference = { bits: 3, // 0-7 priority: 0, content: null, } - html.on( + context.html.on( "#productDescription", new BufferedTextHandler((text) => { assign(result, 7, decode(text)) }), ) - html.on('meta[property="og:description"]', { + context.html.on('meta[property="og:description"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -23,7 +25,7 @@ export default function getDescription(url: URL, html: HTMLRewriter) { } }, }) - html.on('meta[name="twitter:description"]', { + context.html.on('meta[name="twitter:description"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -31,7 +33,7 @@ export default function getDescription(url: URL, html: HTMLRewriter) { } }, }) - html.on('meta[name="description"]', { + context.html.on('meta[name="description"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -39,11 +41,10 @@ export default function getDescription(url: URL, html: HTMLRewriter) { } }, }) - return new Promise((resolve) => { - html.onDocument({ - end() { - resolve(result.content && clip(result.content, 300)) - }, - }) + context.html.onDocument({ + end() { + resolve(result.content && clip(result.content, 300)) + }, }) + return promise } diff --git a/src/summary/amazon/image.ts b/src/summary/amazon/image.ts index 3912148..e099580 100644 --- a/src/summary/amazon/image.ts +++ b/src/summary/amazon/image.ts @@ -1,14 +1,16 @@ import { decode } from "html-entities" import { assign, toAbsoluteURL } from "../common" import type { PrioritizedReference } from "../common" +import type Context from "../../context" -export default function getImage(url: URL, html: HTMLRewriter) { +export default function getImage(context: Context) { + const { promise, resolve, reject } = Promise.withResolvers() const result: PrioritizedReference = { bits: 4, // 0-15 priority: 0, content: null, } - html.on("#landingImage", { + context.html.on("#landingImage", { element(element) { const content = element.getAttribute("src") if (content) { @@ -16,7 +18,7 @@ export default function getImage(url: URL, html: HTMLRewriter) { } }, }) - html.on('meta[property="og:image"]', { + context.html.on('meta[property="og:image"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -24,7 +26,7 @@ export default function getImage(url: URL, html: HTMLRewriter) { } }, }) - html.on('meta[name="twitter:image"]', { + context.html.on('meta[name="twitter:image"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -32,7 +34,7 @@ export default function getImage(url: URL, html: HTMLRewriter) { } }, }) - html.on('link[rel="image_src"]', { + context.html.on('link[rel="image_src"]', { element(element) { const content = element.getAttribute("href") if (content) { @@ -40,7 +42,7 @@ export default function getImage(url: URL, html: HTMLRewriter) { } }, }) - html.on('link[rel="apple-touch-icon"]', { + context.html.on('link[rel="apple-touch-icon"]', { element(element) { const content = element.getAttribute("href") if (content) { @@ -48,7 +50,7 @@ export default function getImage(url: URL, html: HTMLRewriter) { } }, }) - html.on('link[rel="apple-touch-icon image_src"]', { + context.html.on('link[rel="apple-touch-icon image_src"]', { element(element) { const content = element.getAttribute("href") if (content) { @@ -56,11 +58,10 @@ export default function getImage(url: URL, html: HTMLRewriter) { } }, }) - return new Promise((resolve) => { - html.onDocument({ - end() { - resolve(result.content ? toAbsoluteURL(result.content, url.href) : null) - }, - }) + context.html.onDocument({ + end() { + resolve(result.content ? toAbsoluteURL(result.content, context.url.href) : null) + }, }) + return promise } diff --git a/src/summary/amazon/index.ts b/src/summary/amazon/index.ts index e62994e..4360011 100644 --- a/src/summary/amazon/index.ts +++ b/src/summary/amazon/index.ts @@ -10,12 +10,13 @@ import getPlayerUrlWidth from "../general/playerUrlWidth" import getSiteName from "../general/siteName" import getTitle from "./title" import getSensitive from "../general/sensitive" +import type Context from "../../context" -export default function amazon(url: URL, html: HTMLRewriter) { - const card = getCard(url, html) - const title = getTitle(url, html) - const thumbnail = getImage(url, html) - const player = Promise.all([card, getPlayerUrlGeneral(url, html), getPlayerUrlCommon(url, html), getPlayerUrlWidth(url, html), getPlayerUrlHeight(url, html)]).then(([card, general, common, width, height]) => { +export default function amazon(context: Context) { + const card = getCard(context) + const title = getTitle(context) + const thumbnail = getImage(context) + const player = Promise.all([card, getPlayerUrlGeneral(context), getPlayerUrlCommon(context), getPlayerUrlWidth(context), getPlayerUrlHeight(context)]).then(([card, general, common, width, height]) => { const url = (card !== "summary_large_image" && general) || common if (url !== null && width !== null && height !== null) { return { @@ -31,10 +32,10 @@ export default function amazon(url: URL, html: HTMLRewriter) { } } }) - const description = getDescription(url, html) - const siteName = getSiteName(url, html) - const favicon = getFavicon(url, html) - const sensitive = getSensitive(url, html) + const description = getDescription(context) + const siteName = getSiteName(context) + const favicon = getFavicon(context) + const sensitive = getSensitive(context) return Promise.all([title, thumbnail, player, description, siteName, favicon, sensitive]).then(([title, thumbnail, player, description, siteName, favicon, sensitive]) => { if (title === null) { @@ -51,7 +52,7 @@ export default function amazon(url: URL, html: HTMLRewriter) { sitename: siteName, icon: favicon, sensitive, - url: url.href, + url: context.url.href, } }) } diff --git a/src/summary/amazon/title.ts b/src/summary/amazon/title.ts index 51cff59..2bf8d59 100644 --- a/src/summary/amazon/title.ts +++ b/src/summary/amazon/title.ts @@ -2,20 +2,22 @@ import { decode } from "html-entities" import clip from "summaly/built/utils/clip" import { BufferedTextHandler, assign } from "../common" import type { PrioritizedReference } from "../common" +import type Context from "../../context" -export default function getTitle(url: URL, html: HTMLRewriter) { +export default function getTitle(context: Context) { + const { promise, resolve, reject } = Promise.withResolvers() const result: PrioritizedReference = { bits: 3, // 0-7 priority: 0, content: null, } - html.on( + context.html.on( "#title", new BufferedTextHandler((text) => { assign(result, 7, decode(text)) }), ) - html.on('meta[property="og:title"]', { + context.html.on('meta[property="og:title"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -23,7 +25,7 @@ export default function getTitle(url: URL, html: HTMLRewriter) { } }, }) - html.on('meta[name="twitter:title"]', { + context.html.on('meta[name="twitter:title"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -31,17 +33,16 @@ export default function getTitle(url: URL, html: HTMLRewriter) { } }, }) - html.on( + context.html.on( "title", new BufferedTextHandler((text) => { assign(result, 1, decode(text)) }), ) - return new Promise((resolve) => { - html.onDocument({ - end() { - resolve(result.content && clip(result.content, 100)) - }, - }) + context.html.onDocument({ + end() { + resolve(result.content && clip(result.content, 100)) + }, }) + return promise } diff --git a/src/summary/general/card.ts b/src/summary/general/card.ts index 025aa8f..387cbc0 100644 --- a/src/summary/general/card.ts +++ b/src/summary/general/card.ts @@ -1,14 +1,16 @@ import { decode } from "html-entities" import { assign } from "../common" +import type Context from "../../context" import type { PrioritizedReference } from "../common" -export default function getCard(url: URL, html: HTMLRewriter) { +export default function getCard(context: Context) { + const { promise, resolve, reject } = Promise.withResolvers() const result: PrioritizedReference = { bits: 2, // 0-3 priority: 0, content: null, } - html.on('meta[name="twitter:card"]', { + context.html.on('meta[name="twitter:card"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -16,7 +18,7 @@ export default function getCard(url: URL, html: HTMLRewriter) { } }, }) - html.on('meta[property="twitter:card"]', { + context.html.on('meta[property="twitter:card"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -24,11 +26,10 @@ export default function getCard(url: URL, html: HTMLRewriter) { } }, }) - return new Promise((resolve) => { - html.onDocument({ - end() { - resolve(result.content) - }, - }) + context.html.onDocument({ + end() { + resolve(result.content) + }, }) + return promise } diff --git a/src/summary/general/description.ts b/src/summary/general/description.ts index 60eab4a..67bc0a3 100644 --- a/src/summary/general/description.ts +++ b/src/summary/general/description.ts @@ -1,15 +1,17 @@ +import { decode } from "html-entities" import clip from "summaly/built/utils/clip" import { assign } from "../common" +import type Context from "../../context" import type { PrioritizedReference } from "../common" -import { decode } from "html-entities" -export default function getDescription(url: URL, html: HTMLRewriter) { +export default function getDescription(context: Context) { + const { promise, resolve, reject } = Promise.withResolvers() const result: PrioritizedReference = { bits: 2, // 0-3 priority: 0, content: null, } - html.on('meta[property="og:description"]', { + context.html.on('meta[property="og:description"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -17,7 +19,7 @@ export default function getDescription(url: URL, html: HTMLRewriter) { } }, }) - html.on('meta[name="twitter:description"]', { + context.html.on('meta[name="twitter:description"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -25,7 +27,7 @@ export default function getDescription(url: URL, html: HTMLRewriter) { } }, }) - html.on('meta[name="description"]', { + context.html.on('meta[name="description"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -33,11 +35,10 @@ export default function getDescription(url: URL, html: HTMLRewriter) { } }, }) - return new Promise((resolve) => { - html.onDocument({ - end() { - resolve(result.content && clip(result.content, 300)) - }, - }) + context.html.onDocument({ + end() { + resolve(result.content && clip(result.content, 300)) + }, }) + return promise } diff --git a/src/summary/general/favicon.ts b/src/summary/general/favicon.ts index 7e44326..e12c1e2 100644 --- a/src/summary/general/favicon.ts +++ b/src/summary/general/favicon.ts @@ -1,14 +1,16 @@ import { decode } from "html-entities" import { assign, toAbsoluteURL } from "../common" +import type Context from "../../context" import type { PrioritizedReference } from "../common" -export default function getFavicon(url: URL, html: HTMLRewriter) { +export default function getFavicon(context: Context) { + const { promise, resolve, reject } = Promise.withResolvers() const result: PrioritizedReference = { bits: 2, // 0-3 priority: 0, content: "/favicon.ico", } - html.on('link[rel="shortcut icon"]', { + context.html.on('link[rel="shortcut icon"]', { element(element) { const content = element.getAttribute("href") if (content) { @@ -16,7 +18,7 @@ export default function getFavicon(url: URL, html: HTMLRewriter) { } }, }) - html.on('link[rel="icon"]', { + context.html.on('link[rel="icon"]', { element(element) { const content = element.getAttribute("href") if (content) { @@ -24,11 +26,10 @@ export default function getFavicon(url: URL, html: HTMLRewriter) { } }, }) - return new Promise((resolve) => { - html.onDocument({ - end() { - resolve(toAbsoluteURL(result.content, url.href)) - }, - }) + context.html.onDocument({ + end() { + resolve(toAbsoluteURL(result.content, context.url.href)) + }, }) + return promise } diff --git a/src/summary/general/image.ts b/src/summary/general/image.ts index 8f5f703..6b78ba0 100644 --- a/src/summary/general/image.ts +++ b/src/summary/general/image.ts @@ -1,14 +1,16 @@ import { decode } from "html-entities" import { assign, toAbsoluteURL } from "../common" +import type Context from "../../context" import type { PrioritizedReference } from "../common" -export default function getImage(url: URL, html: HTMLRewriter) { +export default function getImage(context: Context) { + const { promise, resolve, reject } = Promise.withResolvers() const result: PrioritizedReference = { bits: 3, // 0-7 priority: 0, content: null, } - html.on('meta[property="og:image"]', { + context.html.on('meta[property="og:image"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -16,7 +18,7 @@ export default function getImage(url: URL, html: HTMLRewriter) { } }, }) - html.on('meta[name="twitter:image"]', { + context.html.on('meta[name="twitter:image"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -24,7 +26,7 @@ export default function getImage(url: URL, html: HTMLRewriter) { } }, }) - html.on('link[rel="image_src"]', { + context.html.on('link[rel="image_src"]', { element(element) { const content = element.getAttribute("href") if (content) { @@ -32,7 +34,7 @@ export default function getImage(url: URL, html: HTMLRewriter) { } }, }) - html.on('link[rel="apple-touch-icon"]', { + context.html.on('link[rel="apple-touch-icon"]', { element(element) { const content = element.getAttribute("href") if (content) { @@ -40,7 +42,7 @@ export default function getImage(url: URL, html: HTMLRewriter) { } }, }) - html.on('link[rel="apple-touch-icon image_src"]', { + context.html.on('link[rel="apple-touch-icon image_src"]', { element(element) { const content = element.getAttribute("href") if (content) { @@ -48,11 +50,10 @@ export default function getImage(url: URL, html: HTMLRewriter) { } }, }) - return new Promise((resolve) => { - html.onDocument({ - end() { - resolve(result.content ? toAbsoluteURL(result.content, url.href) : null) - }, - }) + context.html.onDocument({ + end() { + resolve(result.content ? toAbsoluteURL(result.content, context.url.href) : null) + }, }) + return promise } diff --git a/src/summary/general/index.ts b/src/summary/general/index.ts index 770230d..115280c 100644 --- a/src/summary/general/index.ts +++ b/src/summary/general/index.ts @@ -7,12 +7,13 @@ import getSiteName from "./siteName" import getTitle from "./title" import getSensitive from "./sensitive" import getPlayer, { Player } from "./player" +import type Context from "../../context" -export default function general(request: Request, url: URL, html: HTMLRewriter) { - const card = getCard(url, html) - const title = getTitle(url, html) - const image = getImage(url, html) - const player = Promise.all([card, getPlayer(request, url, html)]).then(([card, parsedPlayer]) => { +export default function general(context: Context) { + const card = getCard(context) + const title = getTitle(context) + const image = getImage(context) + const player = Promise.all([card, getPlayer(context)]).then(([card, parsedPlayer]) => { return { url: (card !== "summary_large_image" && parsedPlayer.urlGeneral) || parsedPlayer.urlCommon, width: parsedPlayer.width, @@ -20,10 +21,10 @@ export default function general(request: Request, url: URL, html: HTMLRewriter) allow: parsedPlayer.allow, } }) - const description = getDescription(url, html) - const siteName = getSiteName(url, html) - const favicon = getFavicon(url, html) - const sensitive = getSensitive(url, html) + const description = getDescription(context) + const siteName = getSiteName(context) + const favicon = getFavicon(context) + const sensitive = getSensitive(context) return Promise.all([card, title, image, player, description, siteName, favicon, sensitive]).then(([card, title, image, player, description, siteName, favicon, sensitive]) => { if (title === null) { @@ -41,7 +42,7 @@ export default function general(request: Request, url: URL, html: HTMLRewriter) icon: favicon, sensitive, large: card === "summary_large_image", - url: url.href, + url: context.url.href, } }) } diff --git a/src/summary/general/player.ts b/src/summary/general/player.ts index a40996a..2ac5026 100644 --- a/src/summary/general/player.ts +++ b/src/summary/general/player.ts @@ -3,6 +3,7 @@ import getPlayerUrlCommon from "./playerUrlCommon" import getPlayerUrlGeneral from "./playerUrlGeneral" import getPlayerUrlHeight from "./playerUrlHeight" import getPlayerUrlWidth from "./playerUrlWidth" +import type Context from "../../context" export interface Player { url: string | null @@ -16,12 +17,12 @@ export interface ParsedPlayer extends Omit { urlGeneral: string | null } -export default function getPlayer(request: Request, url: URL, html: HTMLRewriter): Promise { - const oEmbed = getPlayerOEmbed(request, url, html) - const urlGeneral = getPlayerUrlGeneral(url, html) - const urlCommon = getPlayerUrlCommon(url, html) - const width = getPlayerUrlWidth(url, html) - const height = getPlayerUrlHeight(url, html) +export default function getPlayer(context: Context): Promise { + const oEmbed = getPlayerOEmbed(context) + const urlGeneral = getPlayerUrlGeneral(context) + const urlCommon = getPlayerUrlCommon(context) + const width = getPlayerUrlWidth(context) + const height = getPlayerUrlHeight(context) return Promise.all([oEmbed, urlGeneral, urlCommon, width, height]).then(([oEmbed, urlGeneral, urlCommon, width, height]) => { if (oEmbed) { diff --git a/src/summary/general/playerOEmbed.ts b/src/summary/general/playerOEmbed.ts index ec760bf..b27b6e6 100644 --- a/src/summary/general/playerOEmbed.ts +++ b/src/summary/general/playerOEmbed.ts @@ -2,6 +2,7 @@ import { decode } from "html-entities" import { z } from "zod" import { requestInit } from "../../config" import { assign, PrioritizedReference } from "../common" +import type Context from "../../context" import type { ParsedPlayer } from "./player" const oEmbedBase = z.object({ @@ -41,7 +42,7 @@ const oEmbed = z.union([ }), ]) -export default function getPlayerOEmbed(request: Request, url: URL, html: HTMLRewriter) { +export default function getPlayerOEmbed(context: Context) { const { promise, resolve, reject } = Promise.withResolvers() const result: PrioritizedReference = { bits: 1, // 0-1 @@ -54,7 +55,7 @@ export default function getPlayerOEmbed(request: Request, url: URL, html: HTMLRe allow: [], }, } - html.on('link[type="application/json+oembed"]', { + context.html.on('link[type="application/json+oembed"]', { async element(element) { const oEmbedHref = decode(element.getAttribute("href") ?? "") if (!oEmbedHref) { @@ -62,7 +63,7 @@ export default function getPlayerOEmbed(request: Request, url: URL, html: HTMLRe } let init: RequestInit try { - init = requestInit(request) + init = requestInit(context.request) } catch (e) { reject(e) return @@ -120,7 +121,7 @@ export default function getPlayerOEmbed(request: Request, url: URL, html: HTMLRe } }, }) - html.onDocument({ + context.html.onDocument({ end() { resolve(result.content) }, diff --git a/src/summary/general/playerUrlCommon.ts b/src/summary/general/playerUrlCommon.ts index 689ef97..03a358f 100644 --- a/src/summary/general/playerUrlCommon.ts +++ b/src/summary/general/playerUrlCommon.ts @@ -1,14 +1,16 @@ import { decode } from "html-entities" import { assign, toAbsoluteURL } from "../common" +import type Context from "../../context" import type { PrioritizedReference } from "../common" -export default function getPlayerUrlCommon(url: URL, html: HTMLRewriter) { +export default function getPlayerUrlCommon(context: Context) { + const { promise, resolve, reject } = Promise.withResolvers() const result: PrioritizedReference = { bits: 2, // 0-3 priority: 0, content: null, } - html.on('meta[property="og:video"]', { + context.html.on('meta[property="og:video"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -16,7 +18,7 @@ export default function getPlayerUrlCommon(url: URL, html: HTMLRewriter) { } }, }) - html.on('meta[property="og:video:secure_url"]', { + context.html.on('meta[property="og:video:secure_url"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -24,7 +26,7 @@ export default function getPlayerUrlCommon(url: URL, html: HTMLRewriter) { } }, }) - html.on('meta[property="og:video:url"]', { + context.html.on('meta[property="og:video:url"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -32,11 +34,10 @@ export default function getPlayerUrlCommon(url: URL, html: HTMLRewriter) { } }, }) - return new Promise((resolve) => { - html.onDocument({ - end() { - resolve(result.content ? toAbsoluteURL(result.content, url.href) : null) - }, - }) + context.html.onDocument({ + end() { + resolve(result.content ? toAbsoluteURL(result.content, context.url.href) : null) + }, }) + return promise } diff --git a/src/summary/general/playerUrlGeneral.ts b/src/summary/general/playerUrlGeneral.ts index 927fb59..1142361 100644 --- a/src/summary/general/playerUrlGeneral.ts +++ b/src/summary/general/playerUrlGeneral.ts @@ -1,14 +1,16 @@ import { decode } from "html-entities" import { assign, toAbsoluteURL } from "../common" +import type Context from "../../context" import type { PrioritizedReference } from "../common" -export default function getPlayerUrlGeneral(url: URL, html: HTMLRewriter) { +export default function getPlayerUrlGeneral(context: Context) { + const { promise, resolve, reject } = Promise.withResolvers() const result: PrioritizedReference = { bits: 2, // 0-3 priority: 0, content: null, } - html.on('meta[property="twitter:player"]', { + context.html.on('meta[property="twitter:player"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -16,7 +18,7 @@ export default function getPlayerUrlGeneral(url: URL, html: HTMLRewriter) { } }, }) - html.on('meta[name="twitter:player"]', { + context.html.on('meta[name="twitter:player"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -24,11 +26,10 @@ export default function getPlayerUrlGeneral(url: URL, html: HTMLRewriter) { } }, }) - return new Promise((resolve) => { - html.onDocument({ - end() { - resolve(result.content ? toAbsoluteURL(result.content, url.href) : null) - }, - }) + context.html.onDocument({ + end() { + resolve(result.content ? toAbsoluteURL(result.content, context.url.href) : null) + }, }) + return promise } diff --git a/src/summary/general/playerUrlHeight.ts b/src/summary/general/playerUrlHeight.ts index 315fb3c..8931210 100644 --- a/src/summary/general/playerUrlHeight.ts +++ b/src/summary/general/playerUrlHeight.ts @@ -1,14 +1,16 @@ import { decode } from "html-entities" import { assign } from "../common" +import type Context from "../../context" import type { PrioritizedReference } from "../common" -export default function getPlayerUrlHeight(url: URL, html: HTMLRewriter) { +export default function getPlayerUrlHeight(context: Context) { + const { promise, resolve, reject } = Promise.withResolvers() const result: PrioritizedReference = { bits: 2, // 0-3 priority: 0, content: null, } - html.on('meta[property="twitter:player:height"]', { + context.html.on('meta[property="twitter:player:height"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -16,7 +18,7 @@ export default function getPlayerUrlHeight(url: URL, html: HTMLRewriter) { } }, }) - html.on('meta[name="twitter:player:height"]', { + context.html.on('meta[name="twitter:player:height"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -24,7 +26,7 @@ export default function getPlayerUrlHeight(url: URL, html: HTMLRewriter) { } }, }) - html.on('meta[property="og:video:height"]', { + context.html.on('meta[property="og:video:height"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -32,12 +34,11 @@ export default function getPlayerUrlHeight(url: URL, html: HTMLRewriter) { } }, }) - return new Promise((resolve) => { - html.onDocument({ - end() { - const content = parseInt(result.content!, 10) - resolve(Number.isNaN(content) ? null : content) - }, - }) + context.html.onDocument({ + end() { + const content = parseInt(result.content!, 10) + resolve(Number.isNaN(content) ? null : content) + }, }) + return promise } diff --git a/src/summary/general/playerUrlWidth.ts b/src/summary/general/playerUrlWidth.ts index 5c89b66..4006266 100644 --- a/src/summary/general/playerUrlWidth.ts +++ b/src/summary/general/playerUrlWidth.ts @@ -1,14 +1,16 @@ import { decode } from "html-entities" import { assign } from "../common" +import type Context from "../../context" import type { PrioritizedReference } from "../common" -export default function getPlayerUrlWidth(url: URL, html: HTMLRewriter) { +export default function getPlayerUrlWidth(context: Context) { + const { promise, resolve, reject } = Promise.withResolvers() const result: PrioritizedReference = { bits: 2, // 0-3 priority: 0, content: null, } - html.on('meta[property="twitter:player:width"]', { + context.html.on('meta[property="twitter:player:width"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -16,7 +18,7 @@ export default function getPlayerUrlWidth(url: URL, html: HTMLRewriter) { } }, }) - html.on('meta[name="twitter:player:width"]', { + context.html.on('meta[name="twitter:player:width"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -24,7 +26,7 @@ export default function getPlayerUrlWidth(url: URL, html: HTMLRewriter) { } }, }) - html.on('meta[property="og:video:width"]', { + context.html.on('meta[property="og:video:width"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -32,12 +34,11 @@ export default function getPlayerUrlWidth(url: URL, html: HTMLRewriter) { } }, }) - return new Promise((resolve) => { - html.onDocument({ - end() { - const content = parseInt(result.content!, 10) - resolve(Number.isNaN(content) ? null : content) - }, - }) + context.html.onDocument({ + end() { + const content = parseInt(result.content!, 10) + resolve(Number.isNaN(content) ? null : content) + }, }) + return promise } diff --git a/src/summary/general/sensitive.ts b/src/summary/general/sensitive.ts index 4a4c642..9eba206 100644 --- a/src/summary/general/sensitive.ts +++ b/src/summary/general/sensitive.ts @@ -1,22 +1,23 @@ import { assign } from "../common" +import type Context from "../../context" import type { PrioritizedReference } from "../common" -export default function getSensitive(url: URL, html: HTMLRewriter) { +export default function getSensitive(context: Context) { + const { promise, resolve, reject } = Promise.withResolvers() const result: PrioritizedReference = { bits: 1, // 0-1 priority: 0, content: false, } - html.on('.tweet[data-possibly-sensitive="true"]', { + context.html.on('.tweet[data-possibly-sensitive="true"]', { element() { assign(result, 1, true) }, }) - return new Promise((resolve) => { - html.onDocument({ - end() { - resolve(result.content) - }, - }) + context.html.onDocument({ + end() { + resolve(result.content) + }, }) + return promise } diff --git a/src/summary/general/siteName.ts b/src/summary/general/siteName.ts index 5ec189f..136e656 100644 --- a/src/summary/general/siteName.ts +++ b/src/summary/general/siteName.ts @@ -1,14 +1,16 @@ import { decode } from "html-entities" import { assign } from "../common" +import type Context from "../../context" import type { PrioritizedReference } from "../common" -export default function getSiteName(url: URL, html: HTMLRewriter) { +export default function getSiteName(context: Context) { + const { promise, resolve, reject } = Promise.withResolvers() const result: PrioritizedReference = { bits: 2, // 0-3 priority: 0, - content: url.hostname, + content: context.url.hostname, } - html.on('meta[property="og:site_name"]', { + context.html.on('meta[property="og:site_name"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -16,7 +18,7 @@ export default function getSiteName(url: URL, html: HTMLRewriter) { } }, }) - html.on('meta[name="application-name"]', { + context.html.on('meta[name="application-name"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -24,11 +26,10 @@ export default function getSiteName(url: URL, html: HTMLRewriter) { } }, }) - return new Promise((resolve) => { - html.onDocument({ - end() { - resolve(result.content) - }, - }) + context.html.onDocument({ + end() { + resolve(result.content) + }, }) + return promise } diff --git a/src/summary/general/title.ts b/src/summary/general/title.ts index 68d6d42..868044a 100644 --- a/src/summary/general/title.ts +++ b/src/summary/general/title.ts @@ -1,15 +1,17 @@ import { decode } from "html-entities" import clip from "summaly/built/utils/clip" import { BufferedTextHandler, assign } from "../common" +import type Context from "../../context" import type { PrioritizedReference } from "../common" -export default function getTitle(url: URL, html: HTMLRewriter) { +export default function getTitle(context: Context) { + const { promise, resolve, reject } = Promise.withResolvers() const result: PrioritizedReference = { bits: 2, // 0-3 priority: 0, content: null, } - html.on('meta[property="og:title"]', { + context.html.on('meta[property="og:title"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -17,7 +19,7 @@ export default function getTitle(url: URL, html: HTMLRewriter) { } }, }) - html.on('meta[name="twitter:title"]', { + context.html.on('meta[name="twitter:title"]', { element(element) { const content = element.getAttribute("content") if (content) { @@ -25,17 +27,16 @@ export default function getTitle(url: URL, html: HTMLRewriter) { } }, }) - html.on( + context.html.on( "title", new BufferedTextHandler((text) => { assign(result, 1, decode(text)) }), ) - return new Promise((resolve) => { - html.onDocument({ - end() { - resolve(result.content && clip(result.content, 100)) - }, - }) + context.html.onDocument({ + end() { + resolve(result.content && clip(result.content, 100)) + }, }) + return promise } diff --git a/src/summary/index.ts b/src/summary/index.ts index b9e838c..5f2f916 100644 --- a/src/summary/index.ts +++ b/src/summary/index.ts @@ -1,13 +1,14 @@ import amazon from "./amazon" import general from "./general" import wikipedia from "./wikipedia" +import type Context from "../context" -export default function summary(request: Request, url: URL, html: HTMLRewriter) { - if (url.hostname === "www.amazon.com" || url.hostname === "www.amazon.co.jp" || url.hostname === "www.amazon.ca" || url.hostname === "www.amazon.com.br" || url.hostname === "www.amazon.com.mx" || url.hostname === "www.amazon.co.uk" || url.hostname === "www.amazon.de" || url.hostname === "www.amazon.fr" || url.hostname === "www.amazon.it" || url.hostname === "www.amazon.es" || url.hostname === "www.amazon.nl" || url.hostname === "www.amazon.cn" || url.hostname === "www.amazon.in" || url.hostname === "www.amazon.au") { - return amazon(url, html) +export default function summary(context: Context) { + if (context.url.hostname === "www.amazon.com" || context.url.hostname === "www.amazon.co.jp" || context.url.hostname === "www.amazon.ca" || context.url.hostname === "www.amazon.com.br" || context.url.hostname === "www.amazon.com.mx" || context.url.hostname === "www.amazon.co.uk" || context.url.hostname === "www.amazon.de" || context.url.hostname === "www.amazon.fr" || context.url.hostname === "www.amazon.it" || context.url.hostname === "www.amazon.es" || context.url.hostname === "www.amazon.nl" || context.url.hostname === "www.amazon.cn" || context.url.hostname === "www.amazon.in" || context.url.hostname === "www.amazon.au") { + return amazon(context) } - if (`.${url.hostname}`.endsWith(".wikipedia.org")) { - return wikipedia(url, html) + if (`.${context.url.hostname}`.endsWith(".wikipedia.org")) { + return wikipedia(context) } - return general(request, url, html) + return general(context) } diff --git a/src/summary/wikipedia/index.ts b/src/summary/wikipedia/index.ts index d3edfa1..9860d40 100644 --- a/src/summary/wikipedia/index.ts +++ b/src/summary/wikipedia/index.ts @@ -1,10 +1,12 @@ import clip from "summaly/built/utils/clip" +import { requestInit } from "../../config" +import type Context from "../../context" -export default async function wikipedia(url: URL, html: HTMLRewriter) { - const lang = url.hostname.split(".")[0] - const title = url.pathname.split("/")[2] - const response = await fetch(`https://${lang}.wikipedia.org/w/api.php?format=json&action=query&prop=extracts&exintro=&explaintext=&titles=${title}`) - const json = await response.json() +export default async function wikipedia(context: Context) { + const lang = context.url.hostname.split(".")[0] + const title = context.url.pathname.split("/")[2] + const response = await fetch(`https://${lang}.wikipedia.org/w/api.php?format=json&action=query&prop=extracts&exintro=&explaintext=&titles=${title}`, requestInit(context.request)) + const json: any = await response.json() const info = json.query.pages[Object.keys(json.query.pages)[0]] return { title: info.title, @@ -15,8 +17,9 @@ export default async function wikipedia(url: URL, html: HTMLRewriter) { url: null, width: null, height: null, + allow: [], }, sitename: "Wikipedia", - url: url.href, + url: context.url.href, } }