1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

chore: extract route from core

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
Jari Kolehmainen 2023-05-26 14:40:18 +03:00
parent a22229ba60
commit 0685470009
40 changed files with 241 additions and 136 deletions

View File

@ -205,6 +205,7 @@
"@k8slens/react-application": "^1.0.0",
"@k8slens/resizing-anchor": "^1.0.0",
"@k8slens/resource-templates": "^1.0.0",
"@k8slens/route": "^1.0.0",
"@k8slens/routing": "^1.0.0",
"@k8slens/run-many": "^1.0.0",
"@k8slens/startable-stoppable": "^1.0.0",

27
package-lock.json generated
View File

@ -3817,6 +3817,10 @@
"resolved": "packages/resource-templates",
"link": true
},
"node_modules/@k8slens/route": {
"resolved": "packages/utility-features/route",
"link": true
},
"node_modules/@k8slens/routing": {
"resolved": "packages/routing",
"link": true
@ -3833,10 +3837,6 @@
"resolved": "packages/utility-features/startable-stoppable",
"link": true
},
"node_modules/@k8slens/table-tokens": {
"resolved": "packages/table",
"link": true
},
"node_modules/@k8slens/test-utils": {
"resolved": "packages/utility-features/test-utils",
"link": true
@ -34010,6 +34010,7 @@
"@k8slens/react-application": "^1.0.0",
"@k8slens/resizing-anchor": "^1.0.0",
"@k8slens/resource-templates": "^1.0.0",
"@k8slens/route": "^1.0.0",
"@k8slens/routing": "^1.0.0",
"@k8slens/run-many": "^1.0.0",
"@k8slens/startable-stoppable": "^1.0.0",
@ -34325,10 +34326,10 @@
"@k8slens/react-application": "^1.0.0-alpha.5",
"@k8slens/resizing-anchor": "^1.0.0-alpha.5",
"@k8slens/resource-templates": "^1.0.0-alpha.1",
"@k8slens/route": "^1.0.0",
"@k8slens/routing": "^1.0.0-alpha.5",
"@k8slens/run-many": "^1.0.0-alpha.1",
"@k8slens/startable-stoppable": "^1.0.0-alpha.1",
"@k8slens/table-tokens": "^6.5.0-alpha.7",
"@k8slens/tooltip": "^1.0.0-alpha.5",
"@k8slens/utilities": "^1.0.0-alpha.1",
"@kubernetes/client-node": "^0.18.1",
@ -35312,6 +35313,7 @@
"packages/table": {
"name": "@k8slens/table-tokens",
"version": "6.5.0",
"extraneous": true,
"license": "MIT",
"devDependencies": {
"@k8slens/webpack": "^6.5.0",
@ -35682,6 +35684,21 @@
"@testing-library/react": "^12.1.5"
}
},
"packages/utility-features/route": {
"version": "1.0.0",
"license": "MIT",
"devDependencies": {
"@k8slens/webpack": "^6.5.0-alpha.9"
},
"peerDependencies": {
"@k8slens/test-utils": "^1.0.0-alpha.3",
"@k8slens/utilities": "^1.0.0-alpha.1",
"@ogre-tools/fp": "^16.1.0",
"@ogre-tools/injectable": "^16.1.0",
"http-proxy": "^1.18.1",
"joi": "^17.9.1"
}
},
"packages/utility-features/run-many": {
"name": "@k8slens/run-many",
"version": "1.0.0",

View File

@ -227,6 +227,7 @@
"@k8slens/react-application": "^1.0.0-alpha.5",
"@k8slens/resizing-anchor": "^1.0.0-alpha.5",
"@k8slens/resource-templates": "^1.0.0-alpha.1",
"@k8slens/route": "^1.0.0",
"@k8slens/routing": "^1.0.0-alpha.5",
"@k8slens/run-many": "^1.0.0-alpha.1",
"@k8slens/startable-stoppable": "^1.0.0-alpha.1",

View File

@ -3,7 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { LensApiRequest, Route } from "../router/route";
import type { LensApiRequest, Route } from "@k8slens/route";
import staticFileRouteInjectable from "../routes/files/static-file-route.injectable";
import { getDiForUnitTesting } from "../getDiForUnitTesting";

View File

@ -0,0 +1,71 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { Cluster } from "../../common/cluster/cluster";
import type { BaseRoutePaths, LensApiRequest, RouteResponse, ValidatorBaseRoutePaths } from "@k8slens/route";
export interface ClusterLensApiRequest<Path extends string> extends LensApiRequest<Path> {
cluster: Cluster;
}
export interface ClusterRoute<TResponse, Path extends string> extends BaseRoutePaths<Path> {
handler: ClusterRouteHandler<TResponse, Path>;
}
export interface ClusterRouteHandler<Response, Path extends string>{
(request: ClusterLensApiRequest<Path>): RouteResponse<Response> | Promise<RouteResponse<Response>>;
}
export interface BindClusterHandler<Path extends string> {
<TResponse>(handler: ClusterRouteHandler<TResponse, Path>): ClusterRoute<TResponse, Path>;
}
export function clusterRoute<Path extends string>(parts: BaseRoutePaths<Path>): BindClusterHandler<Path> {
return (handler) => ({
...parts,
handler: ({ cluster, ...rest }) => {
if (!cluster) {
return {
error: "Cluster missing",
statusCode: 400,
};
}
return handler({ cluster, ...rest });
},
});
}
export interface ValidatedClusterLensApiRequest<Path extends string, Payload> extends ClusterLensApiRequest<Path> {
payload: Payload;
}
export interface ValidatedClusterRouteHandler<Payload, Response, Path extends string> {
(request: ValidatedClusterLensApiRequest<Path, Payload>): RouteResponse<Response> | Promise<RouteResponse<Response>>;
}
export interface BindValidatedClusterHandler<Path extends string, Payload> {
<Response>(handler: ValidatedClusterRouteHandler<Payload, Response, Path>): ClusterRoute<Response, Path>;
}
export function payloadValidatedClusterRoute<Path extends string, Payload>({ payloadValidator, ...parts }: ValidatorBaseRoutePaths<Path, Payload>): BindValidatedClusterHandler<Path, Payload> {
const boundClusterRoute = clusterRoute(parts);
return (handler) => boundClusterRoute(({ payload, ...rest }) => {
const validationResult = payloadValidator.validate(payload);
if (validationResult.error) {
return {
error: validationResult.error,
statusCode: 400,
};
}
return handler({
payload: validationResult.value,
...rest,
});
});
}

View File

@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import type { ServerResponse } from "http";
import { loggerInjectionToken } from "@k8slens/logger";
import { object } from "@k8slens/utilities";
import type { LensApiRequest, Route } from "./route";
import type { LensApiRequest, Route } from "@k8slens/route";
import { contentTypes } from "./router-content-types";
export type RouteHandler = (request: LensApiRequest<string>, response: ServerResponse) => Promise<void>;

View File

@ -2,15 +2,7 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { LensApiResult } from "./route";
export interface LensApiResultContentType {
resultMapper: (result: LensApiResult<unknown>) => ({
statusCode: number;
content: unknown;
headers: Record<string, string>;
});
}
import type { LensApiResult, LensApiResultContentType } from "@k8slens/route";
const resultMapperFor =
(contentType: string): LensApiResultContentType["resultMapper"] =>

View File

@ -3,15 +3,14 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { Injectable, InjectionToken } from "@ogre-tools/injectable";
import { getInjectable, getInjectionToken } from "@ogre-tools/injectable";
import { getInjectable } from "@ogre-tools/injectable";
import { routeInjectionToken } from "@k8slens/route";
import type { Route } from "@k8slens/route";
import { Router } from "./router";
import parseRequestInjectable from "./parse-request.injectable";
import type { Route } from "./route";
import createHandlerForRouteInjectable from "./create-handler-for-route.injectable";
import type { ClusterRoute } from "./cluster-route";
export const routeInjectionToken = getInjectionToken<Route<unknown, string>>({
id: "route-injection-token",
});
export function getRouteInjectable<T, Path extends string>(
opts: Omit<Injectable<Route<T, Path>, Route<T, Path>, void>, "lifecycle" | "injectionToken">,
@ -22,6 +21,15 @@ export function getRouteInjectable<T, Path extends string>(
});
}
export function getClusterRouteInjectable<T, Path extends string>(
opts: Omit<Injectable<ClusterRoute<T, Path>, ClusterRoute<T, Path>, void>, "lifecycle" | "injectionToken">,
) {
return getInjectable({
...opts,
injectionToken: routeInjectionToken as unknown as InjectionToken<ClusterRoute<T, Path>, void>,
});
}
const routerInjectable = getInjectable({
id: "router",

View File

@ -3,7 +3,8 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import routerInjectable, { routeInjectionToken } from "./router.injectable";
import routerInjectable from "./router.injectable";
import { routeInjectionToken } from "@k8slens/route";
import { getDiForUnitTesting } from "../getDiForUnitTesting";
import type { Router } from "./router";
import type { Cluster } from "../../common/cluster/cluster";
@ -14,7 +15,7 @@ import asyncFn from "@async-fn/jest";
import parseRequestInjectable from "./parse-request.injectable";
import { contentTypes } from "./router-content-types";
import directoryForUserDataInjectable from "../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
import type { Route } from "./route";
import type { Route } from "@k8slens/route";
import type { SetRequired } from "type-fest";
import normalizedPlatformInjectable from "../../common/vars/normalized-platform.injectable";
import kubectlBinaryNameInjectable from "../kubectl/binary-name.injectable";

View File

@ -6,10 +6,11 @@
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 { LensApiRequest, Route } from "@k8slens/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";
import type { ClusterLensApiRequest } from "./cluster-route";
export interface RouterRequestOpts {
req: http.IncomingMessage;
@ -51,7 +52,7 @@ export class Router {
return true;
}
protected async getRequest(opts: RouterRequestOpts): Promise<LensApiRequest<string>> {
protected async getRequest(opts: RouterRequestOpts): Promise<LensApiRequest<string> | ClusterLensApiRequest<string>> {
const { req, res, url, cluster, params } = opts;
const { payload } = await this.dependencies.parseRequest(req, null, {
parse: true,

View File

@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import httpProxy from "http-proxy";
import path from "path";
import { webpackDevServerPort } from "../../../../webpack/vars";
import type { LensApiRequest, RouteResponse } from "../../router/route";
import type { LensApiRequest, RouteResponse } from "@k8slens/route";
const devStaticFileRouteHandlerInjectable = getInjectable({
id: "dev-static-file-route-handler",

View File

@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
import readFileBufferInjectable from "../../../common/fs/read-file-buffer.injectable";
import joinPathsInjectable from "../../../common/path/join-paths.injectable";
import staticFilesDirectoryInjectable from "../../../common/vars/static-files-directory.injectable";
import type { LensApiRequest } from "../../router/route";
import type { LensApiRequest } from "@k8slens/route";
import path from "path";
import { contentTypes } from "../../router/router-content-types";
import { prefixedLoggerInjectable } from "@k8slens/logger";

View File

@ -4,7 +4,7 @@
*/
import { getRouteInjectable } from "../../router/router.injectable";
import isDevelopmentInjectable from "../../../common/vars/is-development.injectable";
import { route } from "../../router/route";
import { route } from "@k8slens/route";
import prodStaticFileRouteHandlerInjectable from "./production.injectable";
import devStaticFileRouteHandlerInjectable from "./development.injectable";

View File

@ -4,7 +4,7 @@
*/
import { getRouteInjectable } from "../../../router/router.injectable";
import { apiPrefix } from "../../../../common/vars";
import { route } from "../../../router/route";
import { route } from "@k8slens/route";
import getHelmChartReadmeInjectable from "../../../helm/helm-service/get-helm-chart-readme.injectable";
const getHelmChartReadmeRouteInjectable = getRouteInjectable({

View File

@ -4,7 +4,7 @@
*/
import { getRouteInjectable } from "../../../router/router.injectable";
import { apiPrefix } from "../../../../common/vars";
import { route } from "../../../router/route";
import { route } from "@k8slens/route";
import getHelmChartValuesInjectable from "../../../helm/helm-service/get-helm-chart-values.injectable";
const getHelmChartRouteValuesInjectable = getRouteInjectable({

View File

@ -4,7 +4,7 @@
*/
import { getRouteInjectable } from "../../../router/router.injectable";
import { apiPrefix } from "../../../../common/vars";
import { route } from "../../../router/route";
import { route } from "@k8slens/route";
import getHelmChartVersionsInjectable from "../../../helm/helm-service/get-helm-chart-versions.injectable";
const getHelmChartVersionsRouteInjectable = getRouteInjectable({

View File

@ -4,7 +4,7 @@
*/
import { getRouteInjectable } from "../../../router/router.injectable";
import { apiPrefix } from "../../../../common/vars";
import { route } from "../../../router/route";
import { route } from "@k8slens/route";
import listHelmChartsInjectable from "../../../helm/helm-service/list-helm-charts.injectable";
const listHelmChartsRouteInjectable = getRouteInjectable({

View File

@ -3,11 +3,11 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { apiPrefix } from "../../../../common/vars";
import { getRouteInjectable } from "../../../router/router.injectable";
import { clusterRoute } from "../../../router/route";
import { getClusterRouteInjectable } from "../../../router/router.injectable";
import { clusterRoute } from "../../../router/cluster-route";
import deleteClusterHelmReleaseInjectable from "../../../helm/helm-service/delete-helm-release.injectable";
const deleteReleaseRouteInjectable = getRouteInjectable({
const deleteReleaseRouteInjectable = getClusterRouteInjectable({
id: "delete-release-route",
instantiate: (di) => {

View File

@ -3,11 +3,11 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { apiPrefix } from "../../../../common/vars";
import { getRouteInjectable } from "../../../router/router.injectable";
import { clusterRoute } from "../../../router/route";
import { getClusterRouteInjectable } from "../../../router/router.injectable";
import { clusterRoute } from "../../../router/cluster-route";
import getClusterHelmReleaseHistoryInjectable from "../../../helm/helm-service/get-helm-release-history.injectable";
const getReleaseRouteHistoryInjectable = getRouteInjectable({
const getReleaseRouteHistoryInjectable = getClusterRouteInjectable({
id: "get-release-history-route",
instantiate: (di) => {

View File

@ -3,13 +3,13 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { apiPrefix } from "../../../../common/vars";
import { getRouteInjectable } from "../../../router/router.injectable";
import { getClusterRouteInjectable } from "../../../router/router.injectable";
import { getBoolean } from "../../../utils/parse-query";
import { contentTypes } from "../../../router/router-content-types";
import { clusterRoute } from "../../../router/route";
import { clusterRoute } from "../../../router/cluster-route";
import getClusterHelmReleaseValuesInjectable from "../../../helm/helm-service/get-helm-release-values.injectable";
const getReleaseRouteValuesInjectable = getRouteInjectable({
const getReleaseRouteValuesInjectable = getClusterRouteInjectable({
id: "get-release-values-route",
instantiate: (di) => {

View File

@ -3,9 +3,9 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { apiPrefix } from "../../../../common/vars";
import { getRouteInjectable } from "../../../router/router.injectable";
import { getClusterRouteInjectable } from "../../../router/router.injectable";
import Joi from "joi";
import { payloadValidatedClusterRoute } from "../../../router/route";
import { payloadValidatedClusterRoute } from "../../../router/cluster-route";
import type { InstallChartArgs } from "../../../helm/helm-service/install-helm-chart.injectable";
import installClusterHelmChartInjectable from "../../../helm/helm-service/install-helm-chart.injectable";
@ -27,7 +27,7 @@ const installChartArgsValidator = Joi.object<InstallChartArgs, true, InstallChar
.required(),
});
const installChartRouteInjectable = getRouteInjectable({
const installChartRouteInjectable = getClusterRouteInjectable({
id: "install-chart-route",
instantiate: (di) => {

View File

@ -3,9 +3,9 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { apiPrefix } from "../../../../common/vars";
import { getRouteInjectable } from "../../../router/router.injectable";
import { getClusterRouteInjectable } from "../../../router/router.injectable";
import Joi from "joi";
import { payloadValidatedClusterRoute } from "../../../router/route";
import { payloadValidatedClusterRoute } from "../../../router/cluster-route";
import rollbackClusterHelmReleaseInjectable from "../../../helm/helm-service/rollback-helm-release.injectable";
interface RollbackReleasePayload {
@ -18,7 +18,7 @@ const rollbackReleasePayloadValidator = Joi.object<RollbackReleasePayload, true,
.required(),
});
const rollbackReleaseRouteInjectable = getRouteInjectable({
const rollbackReleaseRouteInjectable = getClusterRouteInjectable({
id: "rollback-release-route",
instantiate: (di) => {

View File

@ -3,8 +3,8 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { apiPrefix } from "../../../../common/vars";
import { getRouteInjectable } from "../../../router/router.injectable";
import { payloadValidatedClusterRoute } from "../../../router/route";
import { getClusterRouteInjectable } from "../../../router/router.injectable";
import { payloadValidatedClusterRoute } from "../../../router/cluster-route";
import Joi from "joi";
import type { UpdateChartArgs } from "../../../helm/helm-service/update-helm-release.injectable";
import updateHelmReleaseInjectable from "../../../helm/helm-service/update-helm-release.injectable";
@ -21,7 +21,7 @@ const updateChartArgsValidator = Joi.object<UpdateChartArgs, true, UpdateChartAr
.required(),
});
const updateReleaseRouteInjectable = getRouteInjectable({
const updateReleaseRouteInjectable = getClusterRouteInjectable({
id: "update-release-route",
instantiate: (di) => {

View File

@ -4,14 +4,14 @@
*/
import { apiPrefix } from "../../../common/vars";
import { getRouteInjectable } from "../../router/router.injectable";
import { getClusterRouteInjectable } from "../../router/router.injectable";
import { CoreV1Api } from "@kubernetes/client-node";
import { clusterRoute } from "../../router/route";
import { clusterRoute } from "../../router/cluster-route";
import * as yaml from "js-yaml";
import loadProxyKubeconfigInjectable from "../../cluster/load-proxy-kubeconfig.injectable";
import clusterApiUrlInjectable from "../../../features/cluster/connections/main/api-url.injectable";
const getServiceAccountRouteInjectable = getRouteInjectable({
const getServiceAccountRouteInjectable = getClusterRouteInjectable({
id: "get-service-account-route",
instantiate: (di) => clusterRoute({

View File

@ -4,11 +4,11 @@
*/
import { apiPrefix } from "../../../common/vars";
import { getRouteInjectable } from "../../router/router.injectable";
import { getClusterRouteInjectable } from "../../router/router.injectable";
import type { ClusterPrometheusMetadata } from "../../../common/cluster-types";
import { ClusterMetadataKey } from "../../../common/cluster-types";
import type { Cluster } from "../../../common/cluster/cluster";
import { clusterRoute } from "../../router/route";
import { clusterRoute } from "../../router/cluster-route";
import { isObject } from "lodash";
import { isRequestError, object } from "@k8slens/utilities";
import type { GetMetrics } from "../../get-metrics.injectable";
@ -54,7 +54,7 @@ const loadMetricsFor = (getMetrics: GetMetrics) => async (promQueries: string[],
return Promise.all(queries.map(loadMetric));
};
const addMetricsRouteInjectable = getRouteInjectable({
const addMetricsRouteInjectable = getClusterRouteInjectable({
id: "add-metrics-route",
instantiate: (di) => {

View File

@ -5,7 +5,7 @@
import { apiPrefix } from "../../../common/vars";
import { getRouteInjectable } from "../../router/router.injectable";
import { route } from "../../router/route";
import { route } from "@k8slens/route";
import prometheusProvidersInjectable from "../../prometheus/providers.injectable";
const getMetricProvidersRouteInjectable = getRouteInjectable({

View File

@ -2,12 +2,12 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getRouteInjectable } from "../../router/router.injectable";
import { getClusterRouteInjectable } from "../../router/router.injectable";
import { apiPrefix } from "../../../common/vars";
import { PortForward } from "./functionality/port-forward";
import { clusterRoute } from "../../router/route";
import { clusterRoute } from "../../router/cluster-route";
const getCurrentPortForwardRouteInjectable = getRouteInjectable({
const getCurrentPortForwardRouteInjectable = getClusterRouteInjectable({
id: "get-current-port-forward-route",
instantiate: () => clusterRoute({

View File

@ -2,15 +2,15 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getRouteInjectable } from "../../router/router.injectable";
import { getClusterRouteInjectable } from "../../router/router.injectable";
import { apiPrefix } from "../../../common/vars";
import { PortForward } from "./functionality/port-forward";
import createPortForwardInjectable from "./functionality/create-port-forward.injectable";
import { clusterRoute } from "../../router/route";
import { clusterRoute } from "../../router/cluster-route";
import { loggerInjectionToken } from "@k8slens/logger";
import kubeconfigManagerInjectable from "../../kubeconfig-manager/kubeconfig-manager.injectable";
const startPortForwardRouteInjectable = getRouteInjectable({
const startPortForwardRouteInjectable = getClusterRouteInjectable({
id: "start-current-port-forward-route",
instantiate: (di) => {

View File

@ -2,13 +2,13 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getRouteInjectable } from "../../router/router.injectable";
import { getClusterRouteInjectable } from "../../router/router.injectable";
import { apiPrefix } from "../../../common/vars";
import { PortForward } from "./functionality/port-forward";
import { clusterRoute } from "../../router/route";
import { clusterRoute } from "../../router/cluster-route";
import { loggerInjectionToken } from "@k8slens/logger";
const stopCurrentPortForwardRouteInjectable = getRouteInjectable({
const stopCurrentPortForwardRouteInjectable = getClusterRouteInjectable({
id: "stop-current-port-forward-route",
instantiate: (di) => {

View File

@ -2,13 +2,13 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getRouteInjectable } from "../../router/router.injectable";
import { getClusterRouteInjectable } from "../../router/router.injectable";
import { apiPrefix } from "../../../common/vars";
import { payloadValidatedClusterRoute } from "../../router/route";
import { payloadValidatedClusterRoute } from "../../router/cluster-route";
import Joi from "joi";
import resourceApplierInjectable from "../../resource-applier/create-resource-applier.injectable";
const createResourceRouteInjectable = getRouteInjectable({
const createResourceRouteInjectable = getClusterRouteInjectable({
id: "create-resource-route",
instantiate: (di) => payloadValidatedClusterRoute({

View File

@ -2,9 +2,9 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getRouteInjectable } from "../../router/router.injectable";
import { getClusterRouteInjectable } from "../../router/router.injectable";
import { apiPrefix } from "../../../common/vars";
import { payloadValidatedClusterRoute } from "../../router/route";
import { payloadValidatedClusterRoute } from "../../router/cluster-route";
import Joi from "joi";
import type { Patch } from "rfc6902";
import resourceApplierInjectable from "../../resource-applier/create-resource-applier.injectable";
@ -37,7 +37,7 @@ const patchResourcePayloadValidator = Joi.object<PatchResourcePayload, true, Pat
),
});
const patchResourceRouteInjectable = getRouteInjectable({
const patchResourceRouteInjectable = getClusterRouteInjectable({
id: "patch-resource-route",
instantiate: (di) => payloadValidatedClusterRoute({

View File

@ -3,7 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getRouteInjectable } from "../../router/router.injectable";
import { route } from "../../router/route";
import { route } from "@k8slens/route";
import { buildVersionInitializable } from "../../../features/vars/build-version/common/token";
const getVersionRouteInjectable = getRouteInjectable({

View File

@ -0,0 +1,4 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

View File

@ -0,0 +1,7 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
export * from "./src/route";
export { routeInjectionToken } from "./src/route-injection-token";

View File

@ -0,0 +1,3 @@
const config = require("@k8slens/jest").monorepoPackageConfig(__dirname).configForReact;
module.exports = { ...config, coverageThreshold: undefined };

View File

@ -0,0 +1,38 @@
{
"name": "@k8slens/route",
"version": "1.0.0",
"type": "commonjs",
"description": "Route for Lens",
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"private": false,
"files": [
"dist"
],
"main": "dist/index.js",
"types": "dist/index.d.ts",
"author": {
"name": "OpenLens Authors",
"email": "info@k8slens.dev"
},
"license": "MIT",
"homepage": "https://github.com/lensapp/lens",
"scripts": {
"clean": "rimraf dist/",
"build": "lens-webpack-build",
"test:unit": "jest --coverage --runInBand"
},
"peerDependencies": {
"@k8slens/test-utils": "^1.0.0-alpha.3",
"@k8slens/utilities": "^1.0.0-alpha.1",
"@ogre-tools/fp": "^16.1.0",
"@ogre-tools/injectable": "^16.1.0",
"http-proxy": "^1.18.1",
"joi": "^17.9.1"
},
"devDependencies": {
"@k8slens/webpack": "^6.5.0-alpha.9"
}
}

View File

@ -0,0 +1,11 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectionToken } from "@ogre-tools/injectable";
import type { Route } from "./route";
export const routeInjectionToken = getInjectionToken<Route<unknown, string>>({
id: "route-injection-token",
});

View File

@ -3,13 +3,19 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { Cluster } from "../../common/cluster/cluster";
import type http from "http";
import type httpProxy from "http-proxy";
import type { LensApiResultContentType } from "./router-content-types";
import type { URLSearchParams } from "url";
import type Joi from "joi";
export interface LensApiResultContentType {
resultMapper: (result: LensApiResult<unknown>) => ({
statusCode: number;
content: unknown;
headers: Record<string, string>;
});
}
export type InferParam<
T extends string,
PathParams extends Record<string, string>,
@ -33,7 +39,6 @@ export interface LensApiRequest<Path extends string> {
path: Path;
payload: unknown;
params: InferParamFromPath<Path>;
cluster: Cluster | undefined;
query: URLSearchParams;
raw: {
req: http.IncomingMessage;
@ -41,10 +46,6 @@ export interface LensApiRequest<Path extends string> {
};
}
export interface ClusterLensApiRequest<Path extends string> extends LensApiRequest<Path> {
cluster: Cluster;
}
export interface LensApiResult<Response> {
statusCode?: number;
response?: Response;
@ -79,6 +80,7 @@ export interface Route<TResponse, Path extends string> extends BaseRoutePaths<Pa
handler: RouteHandler<TResponse, Path>;
}
export interface BindHandler<Path extends string> {
<TResponse>(handler: RouteHandler<TResponse, Path>): Route<TResponse, Path>;
}
@ -89,59 +91,3 @@ export function route<Path extends string>(parts: BaseRoutePaths<Path>): BindHan
handler,
});
}
export interface ClusterRouteHandler<Response, Path extends string>{
(request: ClusterLensApiRequest<Path>): RouteResponse<Response> | Promise<RouteResponse<Response>>;
}
export interface BindClusterHandler<Path extends string> {
<TResponse>(handler: ClusterRouteHandler<TResponse, Path>): Route<TResponse, Path>;
}
export function clusterRoute<Path extends string>(parts: BaseRoutePaths<Path>): BindClusterHandler<Path> {
return (handler) => ({
...parts,
handler: ({ cluster, ...rest }) => {
if (!cluster) {
return {
error: "Cluster missing",
statusCode: 400,
};
}
return handler({ cluster, ...rest });
},
});
}
export interface ValidatedClusterLensApiRequest<Path extends string, Payload> extends ClusterLensApiRequest<Path> {
payload: Payload;
}
export interface ValidatedClusterRouteHandler<Payload, Response, Path extends string> {
(request: ValidatedClusterLensApiRequest<Path, Payload>): RouteResponse<Response> | Promise<RouteResponse<Response>>;
}
export interface BindValidatedClusterHandler<Path extends string, Payload> {
<Response>(handler: ValidatedClusterRouteHandler<Payload, Response, Path>): Route<Response, Path>;
}
export function payloadValidatedClusterRoute<Path extends string, Payload>({ payloadValidator, ...parts }: ValidatorBaseRoutePaths<Path, Payload>): BindValidatedClusterHandler<Path, Payload> {
const boundClusterRoute = clusterRoute(parts);
return (handler) => boundClusterRoute(({ payload, ...rest }) => {
const validationResult = payloadValidator.validate(payload);
if (validationResult.error) {
return {
error: validationResult.error,
statusCode: 400,
};
}
return handler({
payload: validationResult.value,
...rest,
});
});
}

View File

@ -0,0 +1,3 @@
{
"extends": "@k8slens/typescript/config/base.json"
}

View File

@ -0,0 +1 @@
module.exports = require("@k8slens/webpack").configForNode;