Skip to content

Commit 64ea03a

Browse files
committed
actually replace links
1 parent c3ba225 commit 64ea03a

File tree

3 files changed

+58
-33
lines changed

3 files changed

+58
-33
lines changed

staticalize.ts

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
import { call, type Operation, resource, spawn, useAbortSignal } from "effection";
1+
import {
2+
call,
3+
type Operation,
4+
resource,
5+
spawn,
6+
until,
7+
useAbortSignal,
8+
} from "effection";
29
import { dirname, join, normalize } from "@std/path";
310
import { ensureDir } from "@std/fs/ensure-dir";
411
import { stringify } from "@libs/xml/stringify";
512
import { fromHtml } from "hast-util-from-html";
6-
//import { toHtml } from "hast-util-to-html";
13+
import { toHtml } from "hast-util-to-html";
714
import { selectAll } from "hast-util-select";
815
import { parse } from "@libs/xml/parse";
916
import { useTaskBuffer } from "./task-buffer.ts";
@@ -43,7 +50,7 @@ export function* staticalize(options: StaticalizeOptions): Operation<void> {
4350
return Array.isArray(urls) ? urls : [urls];
4451
});
4552

46-
let downloader = yield* useDownloader({ host, outdir: dir });
53+
let downloader = yield* useDownloader({ host, base, outdir: dir });
4754

4855
yield* call(() => ensureDir(dir));
4956

@@ -82,13 +89,14 @@ interface Downloader extends Operation<void> {
8289

8390
interface DownloaderOptions {
8491
host: URL;
92+
base: URL;
8593
outdir: string;
8694
}
8795

8896
function useDownloader(opts: DownloaderOptions): Operation<Downloader> {
8997
let seen = new Map<string, boolean>();
9098
return resource(function* (provide) {
91-
let { host, outdir } = opts;
99+
let { host, base, outdir } = opts;
92100

93101
let buffer = yield* useTaskBuffer(75);
94102

@@ -116,27 +124,45 @@ function useDownloader(opts: DownloaderOptions): Operation<Downloader> {
116124
if (response.ok) {
117125
if (response.headers.get("Content-Type")?.includes("html")) {
118126
let destpath = join(path, "index.html");
119-
let content = yield* call(() => response.text());
120-
let html = fromHtml(content);
127+
let content = yield* until(response.text());
128+
let html = fromHtml(content);
121129

122130
let links = selectAll("link[href]", html);
123131

124132
for (let link of links) {
125-
let href = link.properties.href as string
133+
let href = link.properties.href as string;
126134
yield* downloader.download(href, source);
135+
136+
// replace self-referencing absolute urls with the destination site
137+
if (href.startsWith(host.origin)) {
138+
let url = new URL(href);
139+
url.host = base.host;
140+
url.port = base.port;
141+
url.protocol = base.protocol;
142+
link.properties.href = url.href;
143+
}
127144
}
128-
145+
129146
let assets = selectAll("[src]", html);
130147

131148
for (let element of assets) {
132-
let src = element.properties.src as string;
149+
let src = element.properties.src as string;
133150
yield* downloader.download(src, source);
151+
152+
// replace self-referencing absolute urls with the destination sie
153+
if (src.startsWith(host.origin)) {
154+
let url = new URL(src);
155+
url.host = base.host;
156+
url.port = base.port;
157+
url.protocol = base.protocol;
158+
element.properties.src = url.href;
159+
}
134160
}
135161

136162
yield* call(async () => {
137163
let destdir = dirname(destpath);
138164
await ensureDir(destdir);
139-
await Deno.writeTextFile(destpath, content);
165+
await Deno.writeTextFile(destpath, toHtml(html));
140166
});
141167
} else {
142168
yield* call(async () => {

task-buffer.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import {
22
createChannel,
33
Err,
44
Ok,
5-
Operation,
6-
Resolve,
5+
type Operation,
6+
type Resolve,
77
resource,
8-
Result,
8+
type Result,
99
spawn,
10-
Stream,
11-
Task,
10+
type Stream,
11+
type Task,
1212
useScope,
1313
withResolvers,
1414
} from "effection";

test/staticalize.test.ts

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { emptyDir, exists } from "@std/fs";
66

77
import { Hono } from "jsr:@hono/hono";
88
import { parse } from "@libs/xml";
9-
import { run, Task } from "effection";
9+
import { run, type Task } from "effection";
1010

1111
describe("staticalize", () => {
1212
let server: ReturnType<typeof Deno.serve>;
@@ -58,13 +58,13 @@ describe("staticalize", () => {
5858
});
5959

6060
await expect(content("test/dist/index.html")).resolves.toEqual(
61-
"<h1>Index</h1>",
61+
"<html><head></head><body><h1>Index</h1></body></html>",
6262
);
6363
await expect(content("test/dist/about/index.html")).resolves.toEqual(
64-
"<h1>About</h1>",
64+
"<html><head></head><body><h1>About</h1></body></html>",
6565
);
6666
await expect(content("test/dist/contact/index.html")).resolves.toEqual(
67-
"<h1>Contact</h1>",
67+
"<html><head></head><body><h1>Contact</h1></body></html>",
6868
);
6969

7070
let xml = parse(await Deno.readTextFile("test/dist/sitemap.xml"));
@@ -88,7 +88,7 @@ describe("staticalize", () => {
8888
dir: "test/dist",
8989
});
9090
expect(content("test/dist/deeply/nested/page/index.html")).resolves.toEqual(
91-
"<h1>Nested</h1>",
91+
"<html><head></head><body><h1>Nested</h1></body></html>",
9292
);
9393
});
9494

@@ -188,18 +188,19 @@ describe("staticalize", () => {
188188
await expect(exists("test/dist/assets/styles.css")).resolves.toEqual(true);
189189
});
190190

191-
it.skip("replaces references to absolute assets that have the sae host that we're scraping", async () => {
191+
it("replaces references to absolute assets that have the sae host that we're scraping", async () => {
192192
const html = `
193193
<html>
194194
<head>
195195
<link rel="canonical" href="${host}"/>
196-
<link rel="alternate" href="${host}alt"/>
196+
<script src="${host}main.js"/>
197197
</head>
198+
<body></body>
198199
</html>
199-
`
200-
app.get("/", (c) =>
201-
c.html(html))
200+
`;
201+
app.get("/", (c) => c.html(html))
202202
.get("/alt", (c) => c.html(html))
203+
.get("/main.js", (c) => c.text("console.log('hi')"))
203204
.get(...sitemap(["/"]));
204205

205206
await staticalize({
@@ -208,14 +209,12 @@ describe("staticalize", () => {
208209
dir: "test/dist",
209210
});
210211

211-
await expect(content("test/dist/index.html")).resolves.toEqual(`
212-
<html>
213-
<head>
214-
<link rel="canonical" href="https://fs.com/"/>
215-
<link rel="alternate" href="https://fs.com/alt"/>
216-
</head>
217-
</html>
218-
`);
212+
await expect(content("test/dist/index.html")).resolves.toMatch(
213+
`<link rel="canonical" href="https://fs.com/">`,
214+
);
215+
await expect(content("test/dist/index.html")).resolves.toMatch(
216+
`<script src="https://fs.com/main.js">`,
217+
);
219218
});
220219
});
221220

0 commit comments

Comments
 (0)