Skip to content

Commit c5217bc

Browse files
committed
Switch from HTMLRewriter to string replace for rewriting CDN URLs
HTMLRewriter is ok for picking out the `src` of a script tag, but I found for other projects I want to rewrite links in other places, like img tags or strings within the actual scripts. This switches to a more generic string replacement approach that will find CDN URLs in those other places too. String replacement should be ok to do here because it will only be used on html files that easily fit in memory, and none of these projects are very complicated.
1 parent 6c8c139 commit c5217bc

File tree

1 file changed

+22
-21
lines changed

1 file changed

+22
-21
lines changed

scripts/server.ts

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,22 @@ import { styleText } from 'bun:util';
33
const project = 'osm-auth';
44
const hostname = '127.0.0.1';
55
const port = 8080;
6-
const matchCDN = new RegExp(`jsdelivr.*${project}.*(\/dist.*)$`, 'i');
6+
const matchCDN = new RegExp(`(['"\`])(https?:\/\/cdn.jsdelivr.*${project}.*\/)(dist.*["'\`])`, 'gi');
77

88

99
// Replace urls for CDN `dist/*` files with local `dist/*` files.
1010
// e.g. 'https://cdn.jsdelivr.net/npm/path/to/dist/file.min.js' -> '/dist/file.js'
11-
const rewriter = new HTMLRewriter().on('script', {
12-
element(script) {
13-
const src = script.getAttribute('src');
14-
const cdn = src?.match(matchCDN);
15-
if (cdn) {
16-
const local = cdn[1].replace('.min', '');
17-
script.setAttribute('src', local);
18-
}
19-
},
20-
});
11+
function replaceCDNPath(s: string): string {
12+
return s.replaceAll(matchCDN, replacer);
13+
}
14+
15+
// The replacer function for replaceAll:
16+
// p1 = " - begin string
17+
// p2 = cdn url - removed
18+
// p3 = dist/file" - 'dist' + file (if any) + end string
19+
function replacer(match: string, p1: string, p2: string, p3: string): string {
20+
return p1 + p3.replace('.min', '');
21+
}
2122

2223

2324
// Start the server!
@@ -33,35 +34,35 @@ const server = Bun.serve({
3334
const last = path.length - 1;
3435
console.log(styleText('yellowBright', `${req.method}: ${url.pathname}`));
3536

36-
path[0] = 'docs'; // leading '/' -> serve from './docs'
37-
if (path[last] === '') { // no filename, default to 'index.html'
37+
path[0] = 'docs'; // leading '/' -> serve from './docs/*'
38+
if (path[last] === '') { // no filename, default to 'index.html'
3839
path[last] = 'index.html';
3940
}
4041
if (path[1] === 'dist') { // Also allow serving files from './dist/*'
4142
path.shift(); // (remove leading 'docs')
4243
}
4344

44-
const filePath = './' + path.join('/');
45+
const filepath = './' + path.join('/');
4546

4647
try {
47-
const file = Bun.file(filePath);
48+
const file = Bun.file(filepath);
4849
if (await file.exists()) {
49-
console.log(styleText('greenBright', `200: Found → '${filePath}'`));
50+
console.log(styleText('greenBright', `200: Found → '${filepath}'`));
5051

51-
if (/html$/.test(filePath)) {
52-
const content = rewriter.transform(await file.text());
53-
return new Response(content, { headers: { 'content-type': 'text/html' }});
52+
if (/html$/.test(filepath)) {
53+
const content: string = await file.text();
54+
return new Response(replaceCDNPath(content), { headers: { 'content-type': 'text/html' }});
5455
} else {
5556
return new Response(file);
5657
}
5758
}
5859
} catch (error) {
5960
// Handle potential errors during file access
60-
console.error(`Error serving file: ${filePath}`, error);
61+
console.error(`Error serving file: ${filepath}`, error);
6162
}
6263

6364
// If file not found or error, return 404
64-
console.log(styleText('redBright', `404: Not Found → '${filePath}'`));
65+
console.log(styleText('redBright', `404: Not Found → '${filepath}'`));
6566
return new Response('Not Found', { status: 404 });
6667
}
6768
});

0 commit comments

Comments
 (0)