@@ -79,9 +79,8 @@ export interface HttpResponse<T = string | Buffer | object> {
7979 */
8080 mime ?: string
8181 /**
82- * Redirect to this path. Will rewrite against the base path but NOT the
83- * provider endpoint so you must include it. This allows redirecting outside
84- * of your endpoint.
82+ * Redirect to this path. This is constructed against the site base (not the
83+ * provider's base).
8584 */
8685 redirect ?: string
8786 /**
@@ -133,12 +132,16 @@ export interface HttpServerOptions {
133132
134133export interface Route {
135134 /**
136- * Base path part (in /test/path it would be "/test").
135+ * Provider base path part (for /provider/base/path it would be /provider).
136+ */
137+ providerBase : string
138+ /**
139+ * Base path part (for /provider/base/path it would be /base).
137140 */
138141 base : string
139142 /**
140- * Remaining part of the route (in /test/path it would be "/path"). It can be
141- * blank.
143+ * Remaining part of the route after factoring out the base and provider base
144+ * (for /provider/base/path it would be /path). It can be blank.
142145 */
143146 requestPath : string
144147 /**
@@ -161,7 +164,6 @@ interface ProviderRoute extends Route {
161164
162165export interface HttpProviderOptions {
163166 readonly auth : AuthType
164- readonly base : string
165167 readonly commit : string
166168 readonly password ?: string
167169}
@@ -518,41 +520,51 @@ export class HttpServer {
518520 /**
519521 * Register a provider for a top-level endpoint.
520522 */
521- public registerHttpProvider < T extends HttpProvider > ( endpoint : string , provider : HttpProvider0 < T > ) : T
522- public registerHttpProvider < A1 , T extends HttpProvider > ( endpoint : string , provider : HttpProvider1 < A1 , T > , a1 : A1 ) : T
523+ public registerHttpProvider < T extends HttpProvider > ( endpoint : string | string [ ] , provider : HttpProvider0 < T > ) : T
524+ public registerHttpProvider < A1 , T extends HttpProvider > (
525+ endpoint : string | string [ ] ,
526+ provider : HttpProvider1 < A1 , T > ,
527+ a1 : A1 ,
528+ ) : T
523529 public registerHttpProvider < A1 , A2 , T extends HttpProvider > (
524- endpoint : string ,
530+ endpoint : string | string [ ] ,
525531 provider : HttpProvider2 < A1 , A2 , T > ,
526532 a1 : A1 ,
527533 a2 : A2 ,
528534 ) : T
529535 public registerHttpProvider < A1 , A2 , A3 , T extends HttpProvider > (
530- endpoint : string ,
536+ endpoint : string | string [ ] ,
531537 provider : HttpProvider3 < A1 , A2 , A3 , T > ,
532538 a1 : A1 ,
533539 a2 : A2 ,
534540 a3 : A3 ,
535541 ) : T
536542 // eslint-disable-next-line @typescript-eslint/no-explicit-any
537- public registerHttpProvider ( endpoint : string , provider : any , ...args : any [ ] ) : any {
538- endpoint = endpoint . replace ( / ^ \/ + | \/ + $ / g, "" )
539- if ( this . providers . has ( `/${ endpoint } ` ) ) {
540- throw new Error ( `${ endpoint } is already registered` )
541- }
542- if ( / \/ / . test ( endpoint ) ) {
543- throw new Error ( `Only top-level endpoints are supported (got ${ endpoint } )` )
544- }
543+ public registerHttpProvider ( endpoint : string | string [ ] , provider : any , ...args : any [ ] ) : void {
545544 const p = new provider (
546545 {
547546 auth : this . options . auth || AuthType . None ,
548- base : `/${ endpoint } ` ,
549547 commit : this . options . commit ,
550548 password : this . options . password ,
551549 } ,
552550 ...args ,
553551 )
554- this . providers . set ( `/${ endpoint } ` , p )
555- return p
552+ const endpoints = ( typeof endpoint === "string" ? [ endpoint ] : endpoint ) . map ( ( e ) => e . replace ( / ^ \/ + | \/ + $ / g, "" ) )
553+ endpoints . forEach ( ( endpoint ) => {
554+ if ( / \/ / . test ( endpoint ) ) {
555+ throw new Error ( `Only top-level endpoints are supported (got ${ endpoint } )` )
556+ }
557+ const existingProvider = this . providers . get ( `/${ endpoint } ` )
558+ this . providers . set ( `/${ endpoint } ` , p )
559+ if ( existingProvider ) {
560+ logger . debug ( `Overridding existing /${ endpoint } provider` )
561+ // If the existing provider isn't registered elsewhere we can dispose.
562+ if ( ! Array . from ( this . providers . values ( ) ) . find ( ( p ) => p === existingProvider ) ) {
563+ logger . debug ( `Disposing existing /${ endpoint } provider` )
564+ existingProvider . dispose ( )
565+ }
566+ }
567+ } )
556568 }
557569
558570 /**
@@ -759,15 +771,15 @@ export class HttpServer {
759771 // that by shifting the next base out of the request path.
760772 let provider = this . providers . get ( base )
761773 if ( base !== "/" && provider ) {
762- return { ...parse ( requestPath ) , fullPath, query : parsedUrl . query , provider, originalPath }
774+ return { ...parse ( requestPath ) , providerBase : base , fullPath, query : parsedUrl . query , provider, originalPath }
763775 }
764776
765777 // Fall back to the top-level provider.
766778 provider = this . providers . get ( "/" )
767779 if ( ! provider ) {
768780 throw new Error ( `No provider for ${ base } ` )
769781 }
770- return { base, fullPath, requestPath, query : parsedUrl . query , provider, originalPath }
782+ return { base, providerBase : "/" , fullPath, requestPath, query : parsedUrl . query , provider, originalPath }
771783 }
772784
773785 /**
0 commit comments