1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/src/main/router/router.ts
Sebastian Malton cdeededa82
Fix loading helm release details (#6318)
* Fix loading helm release details

- The helm manifest can sometimes contain KubeJsonApiDataLists
  instead of just KubeJsonApiData entries

- Add additional logging to main for when a route handler throws so that
  we can gain more context in the future

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Update tests

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix usage of getHelmReleaseResources

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Add test to verify handling of Lists being returned

Signed-off-by: Sebastian Malton <sebastian@malton.name>

Signed-off-by: Sebastian Malton <sebastian@malton.name>
2022-10-07 09:16:36 -04:00

73 lines
2.2 KiB
TypeScript

/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import Call from "@hapi/call";
import type http from "http";
import type { Cluster } from "../../common/cluster/cluster";
import type { LensApiRequest, Route } from "./route";
import type { ServerIncomingMessage } from "../lens-proxy/lens-proxy";
import type { ParseRequest } from "./parse-request.injectable";
import type { CreateHandlerForRoute, RouteHandler } from "./create-handler-for-route.injectable";
export interface RouterRequestOpts {
req: http.IncomingMessage;
res: http.ServerResponse;
cluster: Cluster | undefined;
params: Partial<Record<string, string>>;
url: URL;
}
interface Dependencies {
parseRequest: ParseRequest;
createHandlerForRoute: CreateHandlerForRoute;
readonly routes: Route<unknown, string>[];
}
export class Router {
private readonly router = new Call.Router<RouteHandler>();
constructor(private readonly dependencies: Dependencies) {
for (const route of this.dependencies.routes) {
this.router.add({ method: route.method, path: route.path }, this.dependencies.createHandlerForRoute(route));
}
}
public async route(cluster: Cluster | undefined, req: ServerIncomingMessage, res: http.ServerResponse): Promise<boolean> {
const url = new URL(req.url, "http://localhost");
const path = url.pathname;
const method = req.method.toLowerCase();
const matchingRoute = this.router.route(method, path);
if (matchingRoute instanceof Error) {
return false;
}
const request = await this.getRequest({ req, res, cluster, url, params: matchingRoute.params });
await matchingRoute.route(request, res);
return true;
}
protected async getRequest(opts: RouterRequestOpts): Promise<LensApiRequest<string>> {
const { req, res, url, cluster, params } = opts;
const { payload } = await this.dependencies.parseRequest(req, null, {
parse: true,
output: "data",
});
return {
cluster,
path: url.pathname,
raw: {
req, res,
},
query: url.searchParams,
payload,
params,
};
}
}