1
1
import { EventEmitter } from 'events' ;
2
2
import { URL } from 'url' ;
3
3
import * as http from 'http' ;
4
+ import * as path from 'path' ;
4
5
5
6
import { request , GaxiosResponse } from 'gaxios' ;
6
7
7
8
import { Queue } from './queue' ;
8
9
import { getLinks } from './links' ;
9
10
import { startWebServer } from './server' ;
10
- import { CheckOptions , processOptions } from './options' ;
11
+ import { CheckOptions , InternalCheckOptions , processOptions } from './options' ;
11
12
12
13
export { CheckOptions } ;
13
14
@@ -92,6 +93,7 @@ export class LinkChecker extends EventEmitter {
92
93
}
93
94
options . path [ i ] = `http://localhost:${ port } /${ options . path [ i ] } ` ;
94
95
}
96
+ options . staticHttpServerHost = `http://localhost:${ port } /` ;
95
97
}
96
98
97
99
if ( process . env . LINKINATOR_DEBUG ) {
@@ -146,10 +148,10 @@ export class LinkChecker extends EventEmitter {
146
148
const proto = opts . url . protocol ;
147
149
if ( proto !== 'http:' && proto !== 'https:' ) {
148
150
const r : LinkResult = {
149
- url : opts . url . href ,
151
+ url : mapUrl ( opts . url . href , opts . checkOptions ) ,
150
152
status : 0 ,
151
153
state : LinkState . SKIPPED ,
152
- parent : opts . parent ,
154
+ parent : mapUrl ( opts . parent , opts . checkOptions ) ,
153
155
} ;
154
156
opts . results . push ( r ) ;
155
157
this . emit ( 'link' , r ) ;
@@ -162,7 +164,7 @@ export class LinkChecker extends EventEmitter {
162
164
( await opts . checkOptions . linksToSkip ( opts . url . href ) )
163
165
) {
164
166
const result : LinkResult = {
165
- url : opts . url . href ,
167
+ url : mapUrl ( opts . url . href , opts . checkOptions ) ,
166
168
state : LinkState . SKIPPED ,
167
169
parent : opts . parent ,
168
170
} ;
@@ -181,9 +183,9 @@ export class LinkChecker extends EventEmitter {
181
183
182
184
if ( skips . length > 0 ) {
183
185
const result : LinkResult = {
184
- url : opts . url . href ,
186
+ url : mapUrl ( opts . url . href , opts . checkOptions ) ,
185
187
state : LinkState . SKIPPED ,
186
- parent : opts . parent ,
188
+ parent : mapUrl ( opts . parent , opts . checkOptions ) ,
187
189
} ;
188
190
opts . results . push ( result ) ;
189
191
this . emit ( 'link' , result ) ;
@@ -285,10 +287,10 @@ export class LinkChecker extends EventEmitter {
285
287
}
286
288
287
289
const result : LinkResult = {
288
- url : opts . url . href ,
290
+ url : mapUrl ( opts . url . href , opts . checkOptions ) ,
289
291
status,
290
292
state,
291
- parent : opts . parent ,
293
+ parent : mapUrl ( opts . parent , opts . checkOptions ) ,
292
294
failureDetails : failures ,
293
295
} ;
294
296
opts . results . push ( result ) ;
@@ -303,10 +305,10 @@ export class LinkChecker extends EventEmitter {
303
305
// creating a new URL obj, treat it as a broken link.
304
306
if ( ! result . url ) {
305
307
const r = {
306
- url : result . link ,
308
+ url : mapUrl ( result . link , opts . checkOptions ) ,
307
309
status : 0 ,
308
310
state : LinkState . BROKEN ,
309
- parent : opts . url . href ,
311
+ parent : mapUrl ( opts . url . href , opts . checkOptions ) ,
310
312
} ;
311
313
opts . results . push ( r ) ;
312
314
this . emit ( 'link' , r ) ;
@@ -427,3 +429,35 @@ function isHtml(response: GaxiosResponse): boolean {
427
429
! ! contentType . match ( / a p p l i c a t i o n \/ x h t m l \+ x m l / g)
428
430
) ;
429
431
}
432
+
433
+ /**
434
+ * When running a local static web server for the user, translate paths from
435
+ * the Url generated back to something closer to a local filesystem path.
436
+ * @example
437
+ * http://localhost:0000/test/route/README.md => test/route/README.md
438
+ * @param url The url that was checked
439
+ * @param options Original CheckOptions passed into the client
440
+ */
441
+ function mapUrl ( url ?: string , options ?: InternalCheckOptions ) : string {
442
+ if ( ! url ) {
443
+ return url ! ;
444
+ }
445
+ let newUrl = url ;
446
+
447
+ // trim the starting http://localhost:0000 if we stood up a local static server
448
+ if (
449
+ options ?. staticHttpServerHost ?. length &&
450
+ url ?. startsWith ( options . staticHttpServerHost )
451
+ ) {
452
+ newUrl = url . slice ( options . staticHttpServerHost . length ) ;
453
+
454
+ // add the full filesystem path back if we trimmed it
455
+ if ( options ?. syntheticServerRoot ?. length ) {
456
+ newUrl = path . join ( options . syntheticServerRoot , newUrl ) ;
457
+ }
458
+ if ( newUrl === '' ) {
459
+ newUrl = `.${ path . sep } ` ;
460
+ }
461
+ }
462
+ return newUrl ! ;
463
+ }
0 commit comments