1- import express from 'express'
21import fs from 'node:fs/promises'
32import path from 'node:path'
43import { fileURLToPath } from 'node:url'
4+ import express from 'express'
55import { PAGES } from './har-index'
66
77const __dirname = path . dirname ( fileURLToPath ( import . meta. url ) )
@@ -13,7 +13,7 @@ const harCache = new Map<string, any>()
1313
1414// Create mapping from HAR filename to original URL
1515const harToUrlMap = Object . fromEntries (
16- Object . entries ( PAGES ) . map ( ( [ key , url ] ) => [ `${ key } .har` , url ] )
16+ Object . entries ( PAGES ) . map ( ( [ key , url ] ) => [ `${ key } .har` , url ] ) ,
1717)
1818
1919// Extract URL parts for location patching
@@ -22,14 +22,14 @@ function getUrlParts(filename: string) {
2222 if ( ! originalUrl ) {
2323 return null
2424 }
25-
25+
2626 try {
2727 const url = new URL ( originalUrl )
2828 return {
29+ host : url . host ,
2930 hostname : url . hostname ,
30- pathname : url . pathname ,
3131 href : originalUrl ,
32- host : url . host
32+ pathname : url . pathname ,
3333 }
3434 } catch {
3535 return null
@@ -39,9 +39,9 @@ function getUrlParts(filename: string) {
3939// Check if WXT dev server is running
4040async function checkDevServer ( ) : Promise < boolean > {
4141 try {
42- const response = await fetch ( 'http://localhost:3000/@vite/client' , {
42+ const response = await fetch ( 'http://localhost:3000/@vite/client' , {
4343 method : 'HEAD' ,
44- signal : AbortSignal . timeout ( 2000 )
44+ signal : AbortSignal . timeout ( 2000 ) ,
4545 } )
4646 return response . ok
4747 } catch {
@@ -54,7 +54,7 @@ async function loadHar(filename: string) {
5454 if ( harCache . has ( filename ) ) {
5555 return harCache . get ( filename )
5656 }
57-
57+
5858 const harPath = path . join ( __dirname , 'har' , filename )
5959 const harContent = await fs . readFile ( harPath , 'utf-8' )
6060 const harData = JSON . parse ( harContent )
@@ -67,19 +67,22 @@ app.get('/', async (req, res) => {
6767 try {
6868 const harDir = path . join ( __dirname , 'har' )
6969 const files = await fs . readdir ( harDir )
70- const harFiles = files . filter ( file => file . endsWith ( '.har' ) )
70+ const harFiles = files . filter ( ( file ) => file . endsWith ( '.har' ) )
7171 const devServerRunning = await checkDevServer ( )
72-
73- const devServerWarning = ! devServerRunning ? `
72+
73+ const devServerWarning = ! devServerRunning
74+ ? `
7475 <div style="background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 6px; padding: 15px; margin-bottom: 20px;">
7576 <strong>⚠️ Warning:</strong> WXT dev server is not running on localhost:3000<br>
7677 <small>Gitcasso-enabled links won't work. Run <code>npm run dev</code> to start the server and <strong>then refresh this page</strong>.</small>
7778 </div>
78- ` : ''
79-
80- const links = harFiles . map ( file => {
81- const basename = path . basename ( file , '.har' )
82- return `
79+ `
80+ : ''
81+
82+ const links = harFiles
83+ . map ( ( file ) => {
84+ const basename = path . basename ( file , '.har' )
85+ return `
8386 <li>
8487 <div style="margin-bottom: 10px; font-weight: bold; color: #555;">${ basename } </div>
8588 <div style="display: flex; gap: 10px;">
@@ -90,8 +93,9 @@ app.get('/', async (req, res) => {
9093 </div>
9194 </li>
9295 `
93- } ) . join ( '' )
94-
96+ } )
97+ . join ( '' )
98+
9599 res . send ( `
96100<!DOCTYPE html>
97101<html>
@@ -141,28 +145,29 @@ app.get('/page/:filename', async (req, res) => {
141145 if ( ! filename . endsWith ( '.har' ) ) {
142146 return res . status ( 400 ) . send ( 'Invalid file type' )
143147 }
144-
148+
145149 const harData = await loadHar ( filename )
146-
150+
147151 // Find the main HTML response
148- const mainEntry = harData . log . entries . find ( ( entry : any ) =>
149- entry . request . url . includes ( 'github.com' ) &&
150- entry . response . content . mimeType ?. includes ( 'text/html' ) &&
151- entry . response . content . text
152+ const mainEntry = harData . log . entries . find (
153+ ( entry : any ) =>
154+ entry . request . url . includes ( 'github.com' ) &&
155+ entry . response . content . mimeType ?. includes ( 'text/html' ) &&
156+ entry . response . content . text ,
152157 )
153-
158+
154159 if ( ! mainEntry ) {
155160 return res . status ( 404 ) . send ( 'No HTML content found in HAR file' )
156161 }
157-
162+
158163 let html = mainEntry . response . content . text
159-
164+
160165 // Replace external URLs with local asset URLs
161166 html = html . replace (
162167 / h t t p s : \/ \/ ( g i t h u b \. c o m | a s s e t s \. g i t h u b \. c o m | a v a t a r s \. g i t h u b u s e r c o n t e n t \. c o m | u s e r - i m a g e s \. g i t h u b u s e r c o n t e n t \. c o m ) / g,
163- `/asset/${ filename . replace ( '.har' , '' ) } `
168+ `/asset/${ filename . replace ( '.har' , '' ) } ` ,
164169 )
165-
170+
166171 res . send ( html )
167172 } catch ( error ) {
168173 console . error ( 'Error serving page:' , error )
@@ -177,34 +182,35 @@ app.get('/page/:filename/gitcasso', async (req, res) => {
177182 if ( ! filename . endsWith ( '.har' ) ) {
178183 return res . status ( 400 ) . send ( 'Invalid file type' )
179184 }
180-
185+
181186 // Get original URL parts for location patching
182187 const urlParts = getUrlParts ( filename )
183188 if ( ! urlParts ) {
184189 return res . status ( 400 ) . send ( 'Unknown HAR file - not found in har-index.ts' )
185190 }
186-
191+
187192 const harData = await loadHar ( filename )
188-
193+
189194 // Find the main HTML response
190- const mainEntry = harData . log . entries . find ( ( entry : any ) =>
191- entry . request . url . includes ( 'github.com' ) &&
192- entry . response . content . mimeType ?. includes ( 'text/html' ) &&
193- entry . response . content . text
195+ const mainEntry = harData . log . entries . find (
196+ ( entry : any ) =>
197+ entry . request . url . includes ( 'github.com' ) &&
198+ entry . response . content . mimeType ?. includes ( 'text/html' ) &&
199+ entry . response . content . text ,
194200 )
195-
201+
196202 if ( ! mainEntry ) {
197203 return res . status ( 404 ) . send ( 'No HTML content found in HAR file' )
198204 }
199-
205+
200206 let html = mainEntry . response . content . text
201-
207+
202208 // Replace external URLs with local asset URLs
203209 html = html . replace (
204210 / h t t p s : \/ \/ ( g i t h u b \. c o m | a s s e t s \. g i t h u b \. c o m | a v a t a r s \. g i t h u b u s e r c o n t e n t \. c o m | u s e r - i m a g e s \. g i t h u b u s e r c o n t e n t \. c o m ) / g,
205- `/asset/${ filename . replace ( '.har' , '' ) } `
211+ `/asset/${ filename . replace ( '.har' , '' ) } ` ,
206212 )
207-
213+
208214 // Inject patched content script with location patching
209215 const contentScriptTag = `
210216 <script>
@@ -256,14 +262,14 @@ app.get('/page/:filename/gitcasso', async (req, res) => {
256262 });
257263 </script>
258264 `
259-
265+
260266 // Insert script before closing body tag, or at the end if no body tag
261267 if ( html . includes ( '</body>' ) ) {
262268 html = html . replace ( '</body>' , `${ contentScriptTag } </body>` )
263269 } else {
264270 html += contentScriptTag
265271 }
266-
272+
267273 res . send ( html )
268274 } catch ( error ) {
269275 console . error ( 'Error serving page:' , error )
@@ -276,24 +282,24 @@ app.get('/asset/:harname/*', async (req, res) => {
276282 try {
277283 const harname = req . params . harname + '.har'
278284 const assetPath = ( req . params as any ) [ 0 ] as string
279-
285+
280286 const harData = await loadHar ( harname )
281-
287+
282288 // Find matching asset in HAR
283289 const assetEntry = harData . log . entries . find ( ( entry : any ) => {
284290 const url = new URL ( entry . request . url )
285291 return url . pathname === '/' + assetPath || url . pathname . endsWith ( '/' + assetPath )
286292 } )
287-
293+
288294 if ( ! assetEntry ) {
289295 return res . status ( 404 ) . send ( 'Asset not found' )
290296 }
291-
297+
292298 const content = assetEntry . response . content
293299 const mimeType = content . mimeType || 'application/octet-stream'
294-
300+
295301 res . set ( 'Content-Type' , mimeType )
296-
302+
297303 if ( content . encoding === 'base64' ) {
298304 res . send ( Buffer . from ( content . text , 'base64' ) )
299305 } else {
@@ -308,4 +314,4 @@ app.get('/asset/:harname/*', async (req, res) => {
308314app . listen ( PORT , ( ) => {
309315 console . log ( `HAR Page Viewer running at http://localhost:${ PORT } ` )
310316 console . log ( 'Click the links to view recorded GitHub pages' )
311- } )
317+ } )
0 commit comments