mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Convert internal deep linking handlers to be open/closed
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
b0ff941314
commit
db9472de36
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import prefixedLoggerInjectable from "../logger/prefixed-logger.injectable";
|
||||
|
||||
const protocolHandlerLoggerInjectable = getInjectable({
|
||||
id: "protocol-handler-logger",
|
||||
instantiate: (di) => di.inject(prefixedLoggerInjectable, "PROTOCOL-HANDLER"),
|
||||
});
|
||||
|
||||
export default protocolHandlerLoggerInjectable;
|
||||
@ -7,7 +7,6 @@ import type { match } from "react-router";
|
||||
import { matchPath } from "react-router";
|
||||
import { countBy } from "lodash";
|
||||
import { isDefined, iter } from "../utils";
|
||||
import { pathToRegexp } from "path-to-regexp";
|
||||
import type Url from "url-parse";
|
||||
import { RoutingError, RoutingErrorType } from "./error";
|
||||
import type { ExtensionsStore } from "../../extensions/extensions-store/extensions-store";
|
||||
@ -62,17 +61,13 @@ export function foldAttemptResults(mainAttempt: RouteAttempt, rendererAttempt: R
|
||||
export interface LensProtocolRouterDependencies {
|
||||
readonly extensionsStore: ExtensionsStore;
|
||||
readonly logger: Logger;
|
||||
readonly internalRoutes: Map<string, RouteHandler>;
|
||||
findExtensionInstanceByName: FindExtensionInstanceByName;
|
||||
}
|
||||
|
||||
export const extensionUrlDeepLinkingSchema = `/:${EXTENSION_PUBLISHER_MATCH}(@[A-Za-z0-9_]+)?/:${EXTENSION_NAME_MATCH}`;
|
||||
|
||||
export abstract class LensProtocolRouter {
|
||||
// Map between path schemas and the handlers
|
||||
protected internalRoutes = new Map<string, RouteHandler>();
|
||||
|
||||
public static readonly LoggingPrefix = "[PROTOCOL ROUTER]";
|
||||
|
||||
static readonly ExtensionUrlSchema = `/:${EXTENSION_PUBLISHER_MATCH}(@[A-Za-z0-9_]+)?/:${EXTENSION_NAME_MATCH}`;
|
||||
|
||||
constructor(protected readonly dependencies: LensProtocolRouterDependencies) {}
|
||||
|
||||
/**
|
||||
@ -81,7 +76,7 @@ export abstract class LensProtocolRouter {
|
||||
* @returns true if a route has been found
|
||||
*/
|
||||
protected _routeToInternal(url: Url<Record<string, string | undefined>>): RouteAttempt {
|
||||
return this._route(this.internalRoutes.entries(), url);
|
||||
return this._route(this.dependencies.internalRoutes.entries(), url);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -137,7 +132,7 @@ export abstract class LensProtocolRouter {
|
||||
data.extensionName = extensionName;
|
||||
}
|
||||
|
||||
this.dependencies.logger.info(`${LensProtocolRouter.LoggingPrefix}: No handler found`, data);
|
||||
this.dependencies.logger.info(`No handler found`, data);
|
||||
|
||||
return RouteAttempt.MISSING;
|
||||
}
|
||||
@ -171,7 +166,7 @@ export abstract class LensProtocolRouter {
|
||||
[EXTENSION_NAME_MATCH]: string;
|
||||
}
|
||||
|
||||
const match = matchPath<ExtensionUrlMatch>(url.pathname, LensProtocolRouter.ExtensionUrlSchema);
|
||||
const match = matchPath<ExtensionUrlMatch>(url.pathname, extensionUrlDeepLinkingSchema);
|
||||
|
||||
if (!match) {
|
||||
throw new RoutingError(RoutingErrorType.NO_EXTENSION_ID, url);
|
||||
@ -186,7 +181,7 @@ export abstract class LensProtocolRouter {
|
||||
});
|
||||
} catch (error) {
|
||||
this.dependencies.logger.info(
|
||||
`${LensProtocolRouter.LoggingPrefix}: Extension ${name} matched, but not installed (${error})`,
|
||||
`Extension ${name} matched, but not installed (${error})`,
|
||||
);
|
||||
|
||||
return name;
|
||||
@ -195,18 +190,18 @@ export abstract class LensProtocolRouter {
|
||||
const extension = this.dependencies.findExtensionInstanceByName(name);
|
||||
|
||||
if (typeof extension === "string") {
|
||||
this.dependencies.logger.info(`${LensProtocolRouter.LoggingPrefix}: Extension ${name} matched, but ${extension}`);
|
||||
this.dependencies.logger.info(`Extension ${name} matched, but ${extension}`);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
if (!extension.isBundled && !this.dependencies.extensionsStore.isEnabled(extension.id)) {
|
||||
this.dependencies.logger.info(`${LensProtocolRouter.LoggingPrefix}: Extension ${name} matched, but not enabled`);
|
||||
this.dependencies.logger.info(`Extension ${name} matched, but not enabled`);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
this.dependencies.logger.info(`${LensProtocolRouter.LoggingPrefix}: Extension ${name} matched`);
|
||||
this.dependencies.logger.info(`Extension ${name} matched`);
|
||||
|
||||
return extension;
|
||||
}
|
||||
@ -244,25 +239,4 @@ export abstract class LensProtocolRouter {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a handler under the `lens://app` tree of routing.
|
||||
* @param pathSchema the URI path schema to match against for this handler
|
||||
* @param handler a function that will be called if a protocol path matches
|
||||
*/
|
||||
public addInternalHandler(urlSchema: string, handler: RouteHandler): this {
|
||||
pathToRegexp(urlSchema); // verify now that the schema is valid
|
||||
this.dependencies.logger.info(`${LensProtocolRouter.LoggingPrefix}: internal registering ${urlSchema}`);
|
||||
this.internalRoutes.set(urlSchema, handler);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an internal protocol handler.
|
||||
* @param pathSchema the path schema that the handler was registered under
|
||||
*/
|
||||
public removeInternalHandler(urlSchema: string): void {
|
||||
this.internalRoutes.delete(urlSchema);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* 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 { RouteHandler } from "../../../common/protocol-handler/registration";
|
||||
|
||||
|
||||
export interface InternalRouteRegistration {
|
||||
path: string;
|
||||
handler: RouteHandler;
|
||||
}
|
||||
|
||||
export const internalDeepLinkingRouteInjectionToken = getInjectionToken<InternalRouteRegistration>({
|
||||
id: "internal-protocol-route-token",
|
||||
});
|
||||
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import navigateToAddClusterInjectable from "../../../common/front-end-routing/routes/add-cluster/navigate-to-add-cluster.injectable";
|
||||
import { internalDeepLinkingRouteInjectionToken } from "../common/internal-handler-token";
|
||||
|
||||
const addClusterDeepLinkingHandlerInjectable = getInjectable({
|
||||
id: "add-cluster-deep-linking-handler",
|
||||
instantiate: (di) => {
|
||||
const navigateToAddCluster = di.inject(navigateToAddClusterInjectable);
|
||||
|
||||
return {
|
||||
path: "/cluster",
|
||||
handler: () => navigateToAddCluster(),
|
||||
};
|
||||
},
|
||||
injectionToken: internalDeepLinkingRouteInjectionToken,
|
||||
});
|
||||
|
||||
export default addClusterDeepLinkingHandlerInjectable;
|
||||
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import React from "react";
|
||||
import getClusterByIdInjectable from "../../../common/cluster-store/get-by-id.injectable";
|
||||
import navigateToClusterViewInjectable from "../../../common/front-end-routing/routes/cluster-view/navigate-to-cluster-view.injectable";
|
||||
import showShortInfoNotificationInjectable from "../../../renderer/components/notifications/show-short-info.injectable";
|
||||
import { internalDeepLinkingRouteInjectionToken } from "../common/internal-handler-token";
|
||||
|
||||
const deprecatedViewClusterDeepLinkingHandlerInjectable = getInjectable({
|
||||
id: "deprecated-view-cluster-deep-linking-handler",
|
||||
instantiate: (di) => {
|
||||
const getClusterById = di.inject(getClusterByIdInjectable);
|
||||
const navigateToClusterView = di.inject(navigateToClusterViewInjectable);
|
||||
const showShortInfoNotification = di.inject(showShortInfoNotificationInjectable);
|
||||
|
||||
return {
|
||||
path: "/cluster/:clusterId",
|
||||
handler: ({ pathname: { clusterId }}) => {
|
||||
if (!clusterId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const cluster = getClusterById(clusterId);
|
||||
|
||||
if (cluster) {
|
||||
navigateToClusterView(clusterId);
|
||||
} else {
|
||||
showShortInfoNotification(
|
||||
<p>
|
||||
{"Unknown catalog entity "}
|
||||
<code>{clusterId}</code>
|
||||
.
|
||||
</p>,
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
injectionToken: internalDeepLinkingRouteInjectionToken,
|
||||
});
|
||||
|
||||
export default deprecatedViewClusterDeepLinkingHandlerInjectable;
|
||||
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import React from "react";
|
||||
import getClusterByIdInjectable from "../../../common/cluster-store/get-by-id.injectable";
|
||||
import navigateToEntitySettingsInjectable from "../../../common/front-end-routing/routes/entity-settings/navigate-to-entity-settings.injectable";
|
||||
import showShortInfoNotificationInjectable from "../../../renderer/components/notifications/show-short-info.injectable";
|
||||
import { internalDeepLinkingRouteInjectionToken } from "../common/internal-handler-token";
|
||||
|
||||
const depcratedViewClusterSettingsDeepLinkingHandlerInjectable = getInjectable({
|
||||
id: "depcrated-view-cluster-settings-deep-linking-handler",
|
||||
instantiate: (di) => {
|
||||
const getClusterById = di.inject(getClusterByIdInjectable);
|
||||
const navigateToEntitySettings = di.inject(navigateToEntitySettingsInjectable);
|
||||
const showShortInfoNotification = di.inject(showShortInfoNotificationInjectable);
|
||||
|
||||
return {
|
||||
path: "/cluster/:clusterId/settings",
|
||||
handler: ({ pathname: { clusterId }}) => {
|
||||
if (!clusterId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const cluster = getClusterById(clusterId);
|
||||
|
||||
if (cluster) {
|
||||
navigateToEntitySettings(clusterId);
|
||||
} else {
|
||||
showShortInfoNotification(
|
||||
<p>
|
||||
{"Unknown catalog entity "}
|
||||
<code>{clusterId}</code>
|
||||
.
|
||||
</p>,
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
injectionToken: internalDeepLinkingRouteInjectionToken,
|
||||
});
|
||||
|
||||
export default depcratedViewClusterSettingsDeepLinkingHandlerInjectable;
|
||||
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import navigateToExtensionsInjectable from "../../../common/front-end-routing/routes/extensions/navigate-to-extensions.injectable";
|
||||
import { extensionUrlDeepLinkingSchema, EXTENSION_NAME_MATCH, EXTENSION_PUBLISHER_MATCH } from "../../../common/protocol-handler";
|
||||
import attemptInstallByInfoInjectable from "../../../renderer/components/+extensions/attempt-install-by-info.injectable";
|
||||
import { internalDeepLinkingRouteInjectionToken } from "../common/internal-handler-token";
|
||||
|
||||
const installExtensionDeepLinkingHandlerInjectable = getInjectable({
|
||||
id: "install-extension-deep-linking-handler",
|
||||
instantiate: (di) => {
|
||||
const navigateToExtensions = di.inject(navigateToExtensionsInjectable);
|
||||
const attemptInstallByInfo = di.inject(attemptInstallByInfoInjectable);
|
||||
|
||||
return {
|
||||
path: `/extensions/install${extensionUrlDeepLinkingSchema}`,
|
||||
handler: ({ pathname, search: { version }}) => {
|
||||
const name = [
|
||||
pathname[EXTENSION_PUBLISHER_MATCH],
|
||||
pathname[EXTENSION_NAME_MATCH],
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("/");
|
||||
|
||||
navigateToExtensions();
|
||||
attemptInstallByInfo({ name, version, requireConfirmation: true });
|
||||
},
|
||||
};
|
||||
},
|
||||
injectionToken: internalDeepLinkingRouteInjectionToken,
|
||||
});
|
||||
|
||||
export default installExtensionDeepLinkingHandlerInjectable;
|
||||
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { pathToRegexp } from "path-to-regexp";
|
||||
import { internalDeepLinkingRouteInjectionToken } from "../common/internal-handler-token";
|
||||
|
||||
const internalDeepLinkingRoutesInjectable = getInjectable({
|
||||
id: "internal-deep-linking-routes",
|
||||
instantiate: (di) => {
|
||||
const registrations = di.injectMany(internalDeepLinkingRouteInjectionToken);
|
||||
|
||||
return new Map(registrations.map(registration => {
|
||||
pathToRegexp(registration.path); // verify now that the schema is valid
|
||||
|
||||
return [registration.path, registration.handler];
|
||||
}));
|
||||
},
|
||||
});
|
||||
|
||||
export default internalDeepLinkingRoutesInjectable;
|
||||
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import navigateToCatalogInjectable from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable";
|
||||
import { internalDeepLinkingRouteInjectionToken } from "../common/internal-handler-token";
|
||||
|
||||
const landingPageDeepLinkingHandlerInjectable = getInjectable({
|
||||
id: "landing-page-deep-linking-handler",
|
||||
instantiate: (di) => {
|
||||
const navigateToCatalog = di.inject(navigateToCatalogInjectable);
|
||||
|
||||
return {
|
||||
path: "/landing",
|
||||
handler: () => navigateToCatalog(),
|
||||
};
|
||||
},
|
||||
injectionToken: internalDeepLinkingRouteInjectionToken,
|
||||
});
|
||||
|
||||
export default landingPageDeepLinkingHandlerInjectable;
|
||||
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import navigateToPreferencesInjectable from "../../preferences/common/navigate-to-preferences.injectable";
|
||||
import { internalDeepLinkingRouteInjectionToken } from "../common/internal-handler-token";
|
||||
|
||||
const preferencesDeepLinkHandlerInjectable = getInjectable({
|
||||
id: "preferences-deep-link-handler",
|
||||
instantiate: (di) => {
|
||||
const navigateToPreferences = di.inject(navigateToPreferencesInjectable);
|
||||
|
||||
return {
|
||||
path: "/preferences",
|
||||
handler: ({ search: { highlight: tabId }}) => {
|
||||
if (tabId) {
|
||||
navigateToPreferences(tabId);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
injectionToken: internalDeepLinkingRouteInjectionToken,
|
||||
});
|
||||
|
||||
export default preferencesDeepLinkHandlerInjectable;
|
||||
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import navigateToCatalogInjectable from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable";
|
||||
import { internalDeepLinkingRouteInjectionToken } from "../common/internal-handler-token";
|
||||
|
||||
const specificLandingPageDeepLinkingHandlerInjectable = getInjectable({
|
||||
id: "specific-landing-page-deep-linking-handler",
|
||||
instantiate: (di) => {
|
||||
const navigateToCatalog = di.inject(navigateToCatalogInjectable);
|
||||
|
||||
return {
|
||||
path: "/landing/view/:group/:kind",
|
||||
handler: ({ pathname: { group, kind }}) => {
|
||||
navigateToCatalog({ group, kind });
|
||||
},
|
||||
};
|
||||
},
|
||||
injectionToken: internalDeepLinkingRouteInjectionToken,
|
||||
});
|
||||
|
||||
export default specificLandingPageDeepLinkingHandlerInjectable;
|
||||
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import React from "react";
|
||||
import navigateToCatalogInjectable from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable";
|
||||
import showShortInfoNotificationInjectable from "../../../renderer/components/notifications/show-short-info.injectable";
|
||||
import { internalDeepLinkingRouteInjectionToken } from "../common/internal-handler-token";
|
||||
|
||||
const unknownDeepLinkingActionHandlerInjectable = getInjectable({
|
||||
id: "unknown-deep-linking-action-handler",
|
||||
instantiate: (di) => {
|
||||
const showShortInfoNotification = di.inject(showShortInfoNotificationInjectable);
|
||||
const navigateToCatalog = di.inject(navigateToCatalogInjectable);
|
||||
|
||||
return {
|
||||
path: "/",
|
||||
handler: ({ tail }) => {
|
||||
if (tail) {
|
||||
showShortInfoNotification(
|
||||
<p>
|
||||
{"Unknown Action for "}
|
||||
<code>
|
||||
lens://app/
|
||||
{tail}
|
||||
</code>
|
||||
. Are you on the latest version?
|
||||
</p>,
|
||||
);
|
||||
}
|
||||
|
||||
navigateToCatalog();
|
||||
},
|
||||
};
|
||||
},
|
||||
injectionToken: internalDeepLinkingRouteInjectionToken,
|
||||
});
|
||||
|
||||
export default unknownDeepLinkingActionHandlerInjectable;
|
||||
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import React from "react";
|
||||
import navigateToEntitySettingsInjectable from "../../../common/front-end-routing/routes/entity-settings/navigate-to-entity-settings.injectable";
|
||||
import catalogEntityRegistryInjectable from "../../../renderer/api/catalog/entity/registry.injectable";
|
||||
import showShortInfoNotificationInjectable from "../../../renderer/components/notifications/show-short-info.injectable";
|
||||
import { internalDeepLinkingRouteInjectionToken } from "../common/internal-handler-token";
|
||||
|
||||
const viewEntitySettingsDeepLinkingHandlerInjectable = getInjectable({
|
||||
id: "view-entity-settings-deep-linking-handler",
|
||||
instantiate: (di) => {
|
||||
const entityRegistry = di.inject(catalogEntityRegistryInjectable);
|
||||
const navigateToEntitySettings = di.inject(navigateToEntitySettingsInjectable);
|
||||
const showShortInfoNotification = di.inject(showShortInfoNotificationInjectable);
|
||||
|
||||
return {
|
||||
path: "/entity/:entityId/settings",
|
||||
handler: ({ pathname: { entityId }}) => {
|
||||
// TODO: maybe improve typing in the future
|
||||
if (!entityId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const entity = entityRegistry.getById(entityId);
|
||||
|
||||
if (entity) {
|
||||
navigateToEntitySettings(entityId);
|
||||
} else {
|
||||
showShortInfoNotification(
|
||||
<p>
|
||||
{"Unknown catalog entity "}
|
||||
<code>{entityId}</code>
|
||||
.
|
||||
</p>,
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
injectionToken: internalDeepLinkingRouteInjectionToken,
|
||||
});
|
||||
|
||||
export default viewEntitySettingsDeepLinkingHandlerInjectable;
|
||||
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import navigateToExtensionsInjectable from "../../../common/front-end-routing/routes/extensions/navigate-to-extensions.injectable";
|
||||
import { internalDeepLinkingRouteInjectionToken } from "../common/internal-handler-token";
|
||||
|
||||
const viewExtensionsDeepLinkingHandlerInjectable = getInjectable({
|
||||
id: "view-extensions-deep-linking-handler",
|
||||
instantiate: (di) => {
|
||||
const navigateToExtensions = di.inject(navigateToExtensionsInjectable);
|
||||
|
||||
return {
|
||||
path: "/extensions",
|
||||
handler: () => navigateToExtensions(),
|
||||
};
|
||||
},
|
||||
injectionToken: internalDeepLinkingRouteInjectionToken,
|
||||
});
|
||||
|
||||
export default viewExtensionsDeepLinkingHandlerInjectable;
|
||||
@ -7,8 +7,9 @@ import { LensProtocolRouterMain } from "./lens-protocol-router-main";
|
||||
import extensionsStoreInjectable from "../../../extensions/extensions-store/extensions-store.injectable";
|
||||
import showApplicationWindowInjectable from "../../start-main-application/lens-window/show-application-window.injectable";
|
||||
import broadcastMessageInjectable from "../../../common/ipc/broadcast-message.injectable";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import findExtensionInstanceByNameInjectable from "../../../features/extensions/loader/common/find-instance-by-name.injectable";
|
||||
import internalDeepLinkingRoutesInjectable from "../../../features/deep-linking/renderer/internal-deep-linking-routes.injectable";
|
||||
import protocolHandlerLoggerInjectable from "../../../common/protocol-handler/logger.injectable";
|
||||
|
||||
const lensProtocolRouterMainInjectable = getInjectable({
|
||||
id: "lens-protocol-router-main",
|
||||
@ -17,8 +18,9 @@ const lensProtocolRouterMainInjectable = getInjectable({
|
||||
extensionsStore: di.inject(extensionsStoreInjectable),
|
||||
showApplicationWindow: di.inject(showApplicationWindowInjectable),
|
||||
broadcastMessage: di.inject(broadcastMessageInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
logger: di.inject(protocolHandlerLoggerInjectable),
|
||||
findExtensionInstanceByName: di.inject(findExtensionInstanceByNameInjectable),
|
||||
internalRoutes: di.inject(internalDeepLinkingRoutesInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@ -71,7 +71,7 @@ export class LensProtocolRouterMain extends proto.LensProtocolRouter {
|
||||
this.dependencies.showApplicationWindow().catch(noop);
|
||||
const routeInternally = checkHost(url);
|
||||
|
||||
this.dependencies.logger.info(`${proto.LensProtocolRouter.LoggingPrefix}: routing ${url.toString()}`);
|
||||
this.dependencies.logger.info(`routing ${url.toString()}`);
|
||||
|
||||
if (routeInternally) {
|
||||
this._routeToInternal(url);
|
||||
@ -82,9 +82,9 @@ export class LensProtocolRouterMain extends proto.LensProtocolRouter {
|
||||
this.dependencies.broadcastMessage(ProtocolHandlerInvalid, error ? String(error) : "unknown error", rawUrl);
|
||||
|
||||
if (error instanceof proto.RoutingError) {
|
||||
this.dependencies.logger.error(`${proto.LensProtocolRouter.LoggingPrefix}: ${error}`, { url: error.url });
|
||||
this.dependencies.logger.error(`${error}`, { url: error.url });
|
||||
} else {
|
||||
this.dependencies.logger.error(`${proto.LensProtocolRouter.LoggingPrefix}: ${error}`, { rawUrl });
|
||||
this.dependencies.logger.error(`${error}`, { rawUrl });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import bindProtocolAddRouteHandlersInjectable from "../../protocol-handler/bind-protocol-add-route-handlers/bind-protocol-add-route-handlers.injectable";
|
||||
import lensProtocolRouterRendererInjectable from "../../protocol-handler/lens-protocol-router-renderer/lens-protocol-router-renderer.injectable";
|
||||
import lensProtocolRouterRendererInjectable from "../../protocol-handler/lens-protocol-router-renderer.injectable";
|
||||
import registerIpcListenersInjectable from "../../ipc/register-ipc-listeners.injectable";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import unmountRootComponentInjectable from "../../window/unmount-root-component.injectable";
|
||||
@ -13,7 +12,6 @@ const initRootFrameInjectable = getInjectable({
|
||||
id: "init-root-frame",
|
||||
instantiate: (di) => {
|
||||
const registerIpcListeners = di.inject(registerIpcListenersInjectable);
|
||||
const bindProtocolAddRouteHandlers = di.inject(bindProtocolAddRouteHandlersInjectable);
|
||||
const lensProtocolRouterRenderer = di.inject(lensProtocolRouterRendererInjectable);
|
||||
const logger = di.inject(loggerInjectable);
|
||||
const unmountRootComponent = di.inject(unmountRootComponentInjectable);
|
||||
@ -21,7 +19,6 @@ const initRootFrameInjectable = getInjectable({
|
||||
return async () => {
|
||||
lensProtocolRouterRenderer.init();
|
||||
|
||||
bindProtocolAddRouteHandlers();
|
||||
registerIpcListeners();
|
||||
|
||||
window.addEventListener("beforeunload", () => {
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import attemptInstallByInfoInjectable from "../../components/+extensions/attempt-install-by-info.injectable";
|
||||
import { bindProtocolAddRouteHandlers } from "./bind-protocol-add-route-handlers";
|
||||
import lensProtocolRouterRendererInjectable from "../lens-protocol-router-renderer/lens-protocol-router-renderer.injectable";
|
||||
import navigateToCatalogInjectable from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable";
|
||||
import navigateToAddClusterInjectable from "../../../common/front-end-routing/routes/add-cluster/navigate-to-add-cluster.injectable";
|
||||
import navigateToExtensionsInjectable from "../../../common/front-end-routing/routes/extensions/navigate-to-extensions.injectable";
|
||||
import navigateToEntitySettingsInjectable from "../../../common/front-end-routing/routes/entity-settings/navigate-to-entity-settings.injectable";
|
||||
import navigateToClusterViewInjectable from "../../../common/front-end-routing/routes/cluster-view/navigate-to-cluster-view.injectable";
|
||||
import catalogEntityRegistryInjectable from "../../api/catalog/entity/registry.injectable";
|
||||
|
||||
// TODO: Importing from features is not OK. Make protocol-router to comply with Open Closed Principle to allow moving implementation under a feature
|
||||
import navigateToPreferencesInjectable from "../../../features/preferences/common/navigate-to-preferences.injectable";
|
||||
import getClusterByIdInjectable from "../../../common/cluster-store/get-by-id.injectable";
|
||||
import showShortInfoNotificationInjectable from "../../components/notifications/show-short-info.injectable";
|
||||
|
||||
const bindProtocolAddRouteHandlersInjectable = getInjectable({
|
||||
id: "bind-protocol-add-route-handlers",
|
||||
|
||||
instantiate: (di) => bindProtocolAddRouteHandlers({
|
||||
attemptInstallByInfo: di.inject(attemptInstallByInfoInjectable),
|
||||
lensProtocolRouterRenderer: di.inject(lensProtocolRouterRendererInjectable ),
|
||||
navigateToCatalog: di.inject(navigateToCatalogInjectable),
|
||||
navigateToAddCluster: di.inject(navigateToAddClusterInjectable),
|
||||
navigateToExtensions: di.inject(navigateToExtensionsInjectable),
|
||||
navigateToEntitySettings: di.inject(navigateToEntitySettingsInjectable),
|
||||
navigateToClusterView: di.inject(navigateToClusterViewInjectable),
|
||||
navigateToPreferences: di.inject(navigateToPreferencesInjectable),
|
||||
entityRegistry: di.inject(catalogEntityRegistryInjectable),
|
||||
getClusterById: di.inject(getClusterByIdInjectable),
|
||||
showShortInfoNotification: di.inject(showShortInfoNotificationInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
export default bindProtocolAddRouteHandlersInjectable;
|
||||
@ -1,143 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import type { LensProtocolRouterRenderer } from "../lens-protocol-router-renderer/lens-protocol-router-renderer";
|
||||
import type { CatalogEntityRegistry } from "../../api/catalog/entity/registry";
|
||||
import {
|
||||
EXTENSION_NAME_MATCH,
|
||||
EXTENSION_PUBLISHER_MATCH,
|
||||
LensProtocolRouter,
|
||||
} from "../../../common/protocol-handler";
|
||||
import type { ShowNotification } from "../../components/notifications";
|
||||
import type { NavigateToCatalog } from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable";
|
||||
import type { NavigateToEntitySettings } from "../../../common/front-end-routing/routes/entity-settings/navigate-to-entity-settings.injectable";
|
||||
import type { NavigateToClusterView } from "../../../common/front-end-routing/routes/cluster-view/navigate-to-cluster-view.injectable";
|
||||
import assert from "assert";
|
||||
import type { AttemptInstallByInfo } from "../../components/+extensions/attempt-install-by-info.injectable";
|
||||
import type { GetClusterById } from "../../../common/cluster-store/get-by-id.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
attemptInstallByInfo: AttemptInstallByInfo;
|
||||
lensProtocolRouterRenderer: LensProtocolRouterRenderer;
|
||||
navigateToCatalog: NavigateToCatalog;
|
||||
navigateToAddCluster: () => void;
|
||||
navigateToExtensions: () => void;
|
||||
navigateToEntitySettings: NavigateToEntitySettings;
|
||||
navigateToClusterView: NavigateToClusterView;
|
||||
navigateToPreferences: (tabId: string) => void;
|
||||
entityRegistry: CatalogEntityRegistry;
|
||||
getClusterById: GetClusterById;
|
||||
showShortInfoNotification: ShowNotification;
|
||||
}
|
||||
|
||||
export const bindProtocolAddRouteHandlers = ({
|
||||
attemptInstallByInfo,
|
||||
lensProtocolRouterRenderer,
|
||||
navigateToCatalog,
|
||||
navigateToAddCluster,
|
||||
navigateToExtensions,
|
||||
navigateToEntitySettings,
|
||||
navigateToClusterView,
|
||||
navigateToPreferences,
|
||||
entityRegistry,
|
||||
getClusterById,
|
||||
showShortInfoNotification,
|
||||
}: Dependencies) => () => {
|
||||
lensProtocolRouterRenderer
|
||||
.addInternalHandler("/preferences", ({ search: { highlight: tabId }}) => {
|
||||
if (tabId) {
|
||||
navigateToPreferences(tabId);
|
||||
}
|
||||
})
|
||||
.addInternalHandler("/", ({ tail }) => {
|
||||
if (tail) {
|
||||
showShortInfoNotification(
|
||||
<p>
|
||||
{"Unknown Action for "}
|
||||
<code>
|
||||
lens://app/
|
||||
{tail}
|
||||
</code>
|
||||
. Are you on the latest version?
|
||||
</p>,
|
||||
);
|
||||
}
|
||||
|
||||
navigateToCatalog();
|
||||
})
|
||||
.addInternalHandler("/landing", () => {
|
||||
navigateToCatalog();
|
||||
})
|
||||
.addInternalHandler("/landing/view/:group/:kind", ({ pathname: { group, kind }}) => {
|
||||
navigateToCatalog({ group, kind });
|
||||
})
|
||||
.addInternalHandler("/cluster", () => {
|
||||
navigateToAddCluster();
|
||||
})
|
||||
.addInternalHandler("/entity/:entityId/settings", ({ pathname: { entityId }}) => {
|
||||
assert(entityId);
|
||||
const entity = entityRegistry.getById(entityId);
|
||||
|
||||
if (entity) {
|
||||
navigateToEntitySettings(entityId);
|
||||
} else {
|
||||
showShortInfoNotification(
|
||||
<p>
|
||||
{"Unknown catalog entity "}
|
||||
<code>{entityId}</code>
|
||||
.
|
||||
</p>,
|
||||
);
|
||||
}
|
||||
})
|
||||
// Handlers below are deprecated and only kept for backward compact purposes
|
||||
.addInternalHandler("/cluster/:clusterId", ({ pathname: { clusterId }}) => {
|
||||
assert(clusterId);
|
||||
const cluster = getClusterById(clusterId);
|
||||
|
||||
if (cluster) {
|
||||
navigateToClusterView(clusterId);
|
||||
} else {
|
||||
showShortInfoNotification(
|
||||
<p>
|
||||
{"Unknown catalog entity "}
|
||||
<code>{clusterId}</code>
|
||||
.
|
||||
</p>,
|
||||
);
|
||||
}
|
||||
})
|
||||
.addInternalHandler("/cluster/:clusterId/settings", ({ pathname: { clusterId }}) => {
|
||||
assert(clusterId);
|
||||
const cluster = getClusterById(clusterId);
|
||||
|
||||
if (cluster) {
|
||||
navigateToEntitySettings(clusterId);
|
||||
} else {
|
||||
showShortInfoNotification(
|
||||
<p>
|
||||
{"Unknown catalog entity "}
|
||||
<code>{clusterId}</code>
|
||||
.
|
||||
</p>,
|
||||
);
|
||||
}
|
||||
})
|
||||
.addInternalHandler("/extensions", () => {
|
||||
navigateToExtensions();
|
||||
})
|
||||
.addInternalHandler(`/extensions/install${LensProtocolRouter.ExtensionUrlSchema}`, ({ pathname, search: { version }}) => {
|
||||
const name = [
|
||||
pathname[EXTENSION_PUBLISHER_MATCH],
|
||||
pathname[EXTENSION_NAME_MATCH],
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("/");
|
||||
|
||||
navigateToExtensions();
|
||||
attemptInstallByInfo({ name, version, requireConfirmation: true });
|
||||
});
|
||||
};
|
||||
@ -1,7 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
export { LensProtocolRouterRenderer } from "./lens-protocol-router-renderer/lens-protocol-router-renderer";
|
||||
export { bindProtocolAddRouteHandlers } from "./bind-protocol-add-route-handlers/bind-protocol-add-route-handlers";
|
||||
@ -4,21 +4,23 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { LensProtocolRouterRenderer } from "./lens-protocol-router-renderer";
|
||||
import extensionsStoreInjectable from "../../../extensions/extensions-store/extensions-store.injectable";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import showErrorNotificationInjectable from "../../components/notifications/show-error-notification.injectable";
|
||||
import showShortInfoNotificationInjectable from "../../components/notifications/show-short-info.injectable";
|
||||
import findExtensionInstanceByNameInjectable from "../../../features/extensions/loader/common/find-instance-by-name.injectable";
|
||||
import extensionsStoreInjectable from "../../extensions/extensions-store/extensions-store.injectable";
|
||||
import showErrorNotificationInjectable from "../components/notifications/show-error-notification.injectable";
|
||||
import showShortInfoNotificationInjectable from "../components/notifications/show-short-info.injectable";
|
||||
import findExtensionInstanceByNameInjectable from "../../features/extensions/loader/common/find-instance-by-name.injectable";
|
||||
import internalDeepLinkingRoutesInjectable from "../../features/deep-linking/renderer/internal-deep-linking-routes.injectable";
|
||||
import protocolHandlerLoggerInjectable from "../../common/protocol-handler/logger.injectable";
|
||||
|
||||
const lensProtocolRouterRendererInjectable = getInjectable({
|
||||
id: "lens-protocol-router-renderer",
|
||||
|
||||
instantiate: (di) => new LensProtocolRouterRenderer({
|
||||
extensionsStore: di.inject(extensionsStoreInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
logger: di.inject(protocolHandlerLoggerInjectable),
|
||||
showErrorNotification: di.inject(showErrorNotificationInjectable),
|
||||
showShortInfoNotification: di.inject(showShortInfoNotificationInjectable),
|
||||
findExtensionInstanceByName: di.inject(findExtensionInstanceByNameInjectable),
|
||||
internalRoutes: di.inject(internalDeepLinkingRoutesInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
@ -5,11 +5,11 @@
|
||||
|
||||
import React from "react";
|
||||
import { ipcRenderer } from "electron";
|
||||
import * as proto from "../../../common/protocol-handler";
|
||||
import * as proto from "../../common/protocol-handler";
|
||||
import Url from "url-parse";
|
||||
import type { LensProtocolRouterDependencies } from "../../../common/protocol-handler";
|
||||
import { foldAttemptResults, ProtocolHandlerInvalid, RouteAttempt } from "../../../common/protocol-handler";
|
||||
import type { ShowNotification } from "../../components/notifications";
|
||||
import type { LensProtocolRouterDependencies } from "../../common/protocol-handler";
|
||||
import { foldAttemptResults, ProtocolHandlerInvalid, RouteAttempt } from "../../common/protocol-handler";
|
||||
import type { ShowNotification } from "../components/notifications";
|
||||
|
||||
interface Dependencies extends LensProtocolRouterDependencies {
|
||||
showShortInfoNotification: ShowNotification;
|
||||
Loading…
Reference in New Issue
Block a user