Skip to content

Commit e8f6d30

Browse files
committed
Make providers endpoint-agnostic
A provider can now be registered on multiple endpoints (or potentially moved if needed).
1 parent 2819fd5 commit e8f6d30

File tree

5 files changed

+40
-29
lines changed

5 files changed

+40
-29
lines changed

src/node/app/proxy.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export class ProxyHttpProvider extends HttpProvider {
2424
const port = route.base.replace(/^\//, "")
2525
return {
2626
proxy: {
27-
base: `${this.options.base}/${port}`,
27+
base: `${route.providerBase}/${port}`,
2828
port,
2929
},
3030
}
@@ -35,7 +35,7 @@ export class ProxyHttpProvider extends HttpProvider {
3535
const port = route.base.replace(/^\//, "")
3636
return {
3737
proxy: {
38-
base: `${this.options.base}/${port}`,
38+
base: `${route.providerBase}/${port}`,
3939
port,
4040
},
4141
}

src/node/app/vscode.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ export class VscodeHttpProvider extends HttpProvider {
131131
if (!this.isRoot(route)) {
132132
throw new HttpError("Not found", HttpCode.NotFound)
133133
} else if (!this.authenticated(request)) {
134-
return { redirect: "/login", query: { to: this.options.base } }
134+
return { redirect: "/login", query: { to: route.providerBase } }
135135
}
136136
try {
137137
return await this.getRoot(request, route)

src/node/entry.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ const main = async (args: Args, cliArgs: Args, configArgs: Args): Promise<void>
7171
}
7272

7373
const httpServer = new HttpServer(options)
74-
httpServer.registerHttpProvider("/", VscodeHttpProvider, args)
74+
httpServer.registerHttpProvider(["/", "/vscode"], VscodeHttpProvider, args)
7575
httpServer.registerHttpProvider("/update", UpdateHttpProvider, false)
7676
httpServer.registerHttpProvider("/proxy", ProxyHttpProvider)
7777
httpServer.registerHttpProvider("/login", LoginHttpProvider, args.config!, envPassword)

src/node/http.ts

+36-24
Original file line numberDiff line numberDiff line change
@@ -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

134133
export 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

162165
export 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
/**

test/update.test.ts

-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ describe("update", () => {
5151
_provider = new UpdateHttpProvider(
5252
{
5353
auth: AuthType.None,
54-
base: "/update",
5554
commit: "test",
5655
},
5756
true,

0 commit comments

Comments
 (0)