| void {
return;
}
}
diff --git a/src/extensions/lens-renderer-extension.ts b/src/extensions/lens-renderer-extension.ts
index e9105dbcd9..fb26d383b0 100644
--- a/src/extensions/lens-renderer-extension.ts
+++ b/src/extensions/lens-renderer-extension.ts
@@ -20,7 +20,7 @@
*/
import type {
- AppPreferenceRegistration, ClusterPageMenuRegistration, KubeObjectDetailRegistration, KubeObjectMenuRegistration,
+ AppPreferenceRegistration, CatalogEntityDetailRegistration, ClusterPageMenuRegistration, KubeObjectDetailRegistration, KubeObjectMenuRegistration,
KubeObjectStatusRegistration, PageMenuRegistration, PageRegistration, StatusBarRegistration, WelcomeMenuRegistration, WorkloadsOverviewDetailRegistration,
} from "./registries";
import type { Cluster } from "../main/cluster";
@@ -43,6 +43,7 @@ export class LensRendererExtension extends LensExtension {
kubeWorkloadsOverviewItems: WorkloadsOverviewDetailRegistration[] = [];
commands: CommandRegistration[] = [];
welcomeMenus: WelcomeMenuRegistration[] = [];
+ catalogEntityDetailItems: CatalogEntityDetailRegistration[] = [];
async navigate(pageId?: string, params?: P) {
const { navigate } = await import("../renderer/navigation");
diff --git a/src/extensions/registries/catalog-entity-detail-registry.ts b/src/extensions/registries/catalog-entity-detail-registry.ts
new file mode 100644
index 0000000000..0ed00b7a8b
--- /dev/null
+++ b/src/extensions/registries/catalog-entity-detail-registry.ts
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2021 OpenLens Authors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+import type React from "react";
+import { BaseRegistry } from "./base-registry";
+
+export interface CatalogEntityDetailComponents {
+ Details: React.ComponentType;
+}
+
+export interface CatalogEntityDetailRegistration {
+ kind: string;
+ apiVersions: string[];
+ components: CatalogEntityDetailComponents;
+ priority?: number;
+}
+
+export class CatalogEntityDetailRegistry extends BaseRegistry {
+ getItemsForKind(kind: string, apiVersion: string) {
+ const items = this.getItems().filter((item) => {
+ return item.kind === kind && item.apiVersions.includes(apiVersion);
+ });
+
+ return items.sort((a, b) => (b.priority ?? 50) - (a.priority ?? 50));
+ }
+}
+
+export const catalogEntityDetailRegistry = new CatalogEntityDetailRegistry();
diff --git a/src/extensions/registries/index.ts b/src/extensions/registries/index.ts
index e3a6490d61..b9ba986521 100644
--- a/src/extensions/registries/index.ts
+++ b/src/extensions/registries/index.ts
@@ -33,4 +33,5 @@ export * from "./command-registry";
export * from "./entity-setting-registry";
export * from "./welcome-menu-registry";
export * from "./protocol-handler-registry";
+export * from "./catalog-entity-detail-registry";
export * from "./workloads-overview-detail-registry";
diff --git a/src/main/catalog-sources/kubeconfig-sync.ts b/src/main/catalog-sources/kubeconfig-sync.ts
index c4650644da..af6d7e150d 100644
--- a/src/main/catalog-sources/kubeconfig-sync.ts
+++ b/src/main/catalog-sources/kubeconfig-sync.ts
@@ -29,7 +29,7 @@ import type stream from "stream";
import { Disposer, ExtendedObservableMap, iter, Singleton } from "../../common/utils";
import logger from "../logger";
import type { KubeConfig } from "@kubernetes/client-node";
-import { loadConfigFromString, splitConfig, validateKubeConfig } from "../../common/kube-helpers";
+import { loadConfigFromString, splitConfig } from "../../common/kube-helpers";
import { Cluster } from "../cluster";
import { catalogEntityFromCluster } from "../cluster-manager";
import { UserStore } from "../../common/user-store";
@@ -130,18 +130,16 @@ export class KubeconfigSyncManager extends Singleton {
}
// exported for testing
-export function configToModels(config: KubeConfig, filePath: string): UpdateClusterModel[] {
+export function configToModels(rootConfig: KubeConfig, filePath: string): UpdateClusterModel[] {
const validConfigs = [];
- for (const contextConfig of splitConfig(config)) {
- const error = validateKubeConfig(contextConfig, contextConfig.currentContext);
-
+ for (const { config, error } of splitConfig(rootConfig)) {
if (error) {
- logger.debug(`${logPrefix} context failed validation: ${error}`, { context: contextConfig.currentContext, filePath });
+ logger.debug(`${logPrefix} context failed validation: ${error}`, { context: config.currentContext, filePath });
} else {
validConfigs.push({
kubeConfigPath: filePath,
- contextName: contextConfig.currentContext,
+ contextName: config.currentContext,
});
}
}
@@ -156,7 +154,13 @@ type RootSource = ObservableMap;
export function computeDiff(contents: string, source: RootSource, filePath: string): void {
runInAction(() => {
try {
- const rawModels = configToModels(loadConfigFromString(contents), filePath);
+ const { config, error } = loadConfigFromString(contents);
+
+ if (error) {
+ logger.warn(`${logPrefix} encountered errors while loading config: ${error.message}`, { filePath, details: error.details });
+ }
+
+ const rawModels = configToModels(config, filePath);
const models = new Map(rawModels.map(m => [m.contextName, m]));
logger.debug(`${logPrefix} File now has ${models.size} entries`, { filePath });
diff --git a/src/main/cluster.ts b/src/main/cluster.ts
index e5db4adbb3..df0da0a552 100644
--- a/src/main/cluster.ts
+++ b/src/main/cluster.ts
@@ -27,7 +27,7 @@ import { ContextHandler } from "./context-handler";
import { AuthorizationV1Api, CoreV1Api, HttpError, KubeConfig, V1ResourceAttributes } from "@kubernetes/client-node";
import { Kubectl } from "./kubectl";
import { KubeconfigManager } from "./kubeconfig-manager";
-import { loadConfig, validateKubeConfig } from "../common/kube-helpers";
+import { loadConfigFromFile, loadConfigFromFileSync, validateKubeConfig } from "../common/kube-helpers";
import { apiResourceRecord, apiResources, KubeApiResource, KubeResource } from "../common/rbac";
import logger from "./logger";
import { VersionDetector } from "./cluster-detectors/version-detector";
@@ -258,14 +258,14 @@ export class Cluster implements ClusterModel, ClusterState {
this.id = model.id;
this.updateModel(model);
- const kubeconfig = this.getKubeconfig();
- const error = validateKubeConfig(kubeconfig, this.contextName, { validateCluster: true, validateUser: false, validateExec: false});
+ const { config } = loadConfigFromFileSync(this.kubeConfigPath);
+ const validationError = validateKubeConfig(config, this.contextName);
- if (error) {
- throw error;
+ if (validationError) {
+ throw validationError;
}
- this.apiUrl = kubeconfig.getCluster(kubeconfig.getContextObject(this.contextName).cluster).server;
+ this.apiUrl = config.getCluster(config.getContextObject(this.contextName).cluster).server;
if (ipcMain) {
// for the time being, until renderer gets its own cluster type
@@ -470,17 +470,20 @@ export class Cluster implements ClusterModel, ClusterState {
this.allowedResources = await this.getAllowedResources();
}
- protected getKubeconfig(): KubeConfig {
- return loadConfig(this.kubeConfigPath);
+ async getKubeconfig(): Promise {
+ const { config } = await loadConfigFromFile(this.kubeConfigPath);
+
+ return config;
}
/**
* @internal
*/
async getProxyKubeconfig(): Promise {
- const kubeconfigPath = await this.getProxyKubeconfigPath();
+ const proxyKCPath = await this.getProxyKubeconfigPath();
+ const { config } = await loadConfigFromFile(proxyKCPath);
- return loadConfig(kubeconfigPath);
+ return config;
}
/**
diff --git a/src/main/index.ts b/src/main/index.ts
index 0396f840a1..3abbfecd17 100644
--- a/src/main/index.ts
+++ b/src/main/index.ts
@@ -93,11 +93,7 @@ if (!app.requestSingleInstanceLock()) {
for (const arg of process.argv) {
if (arg.toLowerCase().startsWith("lens://")) {
- try {
- lprm.route(arg);
- } catch (error) {
- logger.error(`${LensProtocolRouterMain.LoggingPrefix}: an error occured`, { error, rawUrl: arg });
- }
+ lprm.route(arg);
}
}
}
@@ -107,11 +103,7 @@ app.on("second-instance", (event, argv) => {
for (const arg of argv) {
if (arg.toLowerCase().startsWith("lens://")) {
- try {
- lprm.route(arg);
- } catch (error) {
- logger.error(`${LensProtocolRouterMain.LoggingPrefix}: an error occured`, { error, rawUrl: arg });
- }
+ lprm.route(arg);
}
}
@@ -196,7 +188,7 @@ app.on("ready", async () => {
installDeveloperTools();
if (!startHidden) {
- windowManager.initMainWindow();
+ windowManager.ensureMainWindow();
}
ipcMain.on(IpcRendererNavigationEvents.LOADED, () => {
@@ -244,7 +236,7 @@ app.on("activate", (event, hasVisibleWindows) => {
logger.info("APP:ACTIVATE", { hasVisibleWindows });
if (!hasVisibleWindows) {
- WindowManager.getInstance(false)?.initMainWindow(false);
+ WindowManager.getInstance(false)?.ensureMainWindow(false);
}
});
@@ -274,12 +266,7 @@ app.on("will-quit", (event) => {
app.on("open-url", (event, rawUrl) => {
// lens:// protocol handler
event.preventDefault();
-
- try {
- LensProtocolRouterMain.getInstance().route(rawUrl);
- } catch (error) {
- logger.error(`${LensProtocolRouterMain.LoggingPrefix}: an error occured`, { error, rawUrl });
- }
+ LensProtocolRouterMain.getInstance().route(rawUrl);
});
/**
diff --git a/src/main/kubeconfig-manager.ts b/src/main/kubeconfig-manager.ts
index f06ee014c7..fc2e14a3cb 100644
--- a/src/main/kubeconfig-manager.ts
+++ b/src/main/kubeconfig-manager.ts
@@ -25,7 +25,7 @@ import type { ContextHandler } from "./context-handler";
import { app } from "electron";
import path from "path";
import fs from "fs-extra";
-import { dumpConfigYaml, loadConfig } from "../common/kube-helpers";
+import { dumpConfigYaml } from "../common/kube-helpers";
import logger from "./logger";
import { LensProxy } from "./proxy/lens-proxy";
@@ -86,9 +86,9 @@ export class KubeconfigManager {
*/
protected async createProxyKubeconfig(): Promise {
const { configDir, cluster } = this;
- const { contextName, kubeConfigPath, id } = cluster;
- const tempFile = path.normalize(path.join(configDir, `kubeconfig-${id}`));
- const kubeConfig = loadConfig(kubeConfigPath);
+ const { contextName, id } = cluster;
+ const tempFile = path.join(configDir, `kubeconfig-${id}`);
+ const kubeConfig = await cluster.getKubeconfig();
const proxyConfig: Partial = {
currentContext: contextName,
clusters: [
diff --git a/src/main/window-manager.ts b/src/main/window-manager.ts
index 4e5588e47a..25b9e4ca88 100644
--- a/src/main/window-manager.ts
+++ b/src/main/window-manager.ts
@@ -21,19 +21,23 @@
import type { ClusterId } from "../common/cluster-store";
import { makeObservable, observable } from "mobx";
-import { app, BrowserWindow, dialog, shell, webContents } from "electron";
+import { app, BrowserWindow, dialog, ipcMain, shell, webContents } from "electron";
import windowStateKeeper from "electron-window-state";
import { appEventBus } from "../common/event-bus";
import { subscribeToBroadcast } from "../common/ipc";
import { initMenu } from "./menu";
import { initTray } from "./tray";
-import { Singleton } from "../common/utils";
+import { delay, Singleton } from "../common/utils";
import { ClusterFrameInfo, clusterFrameMap } from "../common/cluster-frames";
import { IpcRendererNavigationEvents } from "../renderer/navigation/events";
import logger from "./logger";
import { productName } from "../common/vars";
import { LensProxy } from "./proxy/lens-proxy";
+function isHideable(window: BrowserWindow | null): boolean {
+ return Boolean(window && !window.isDestroyed());
+}
+
export class WindowManager extends Singleton {
protected mainWindow: BrowserWindow;
protected splashWindow: BrowserWindow;
@@ -54,7 +58,7 @@ export class WindowManager extends Singleton {
return `http://localhost:${LensProxy.getInstance().port}`;
}
- async initMainWindow(showSplash = true) {
+ private async initMainWindow(showSplash: boolean) {
// Manage main window size and position with state persistence
if (!this.windowState) {
this.windowState = windowStateKeeper({
@@ -120,13 +124,8 @@ export class WindowManager extends Singleton {
if (showSplash) await this.showSplash();
logger.info(`[WINDOW-MANAGER]: Loading Main window from url: ${this.mainUrl} ...`);
await this.mainWindow.loadURL(this.mainUrl);
- this.mainWindow.show();
- this.splashWindow?.close();
- setTimeout(() => {
- appEventBus.emit({ name: "app", action: "start" });
- }, 1000);
} catch (error) {
- logger.error("Showing main window failed", { error });
+ logger.error("Loading main window failed", { error });
dialog.showErrorBox("ERROR!", error.toString());
}
}
@@ -146,9 +145,32 @@ export class WindowManager extends Singleton {
});
}
- async ensureMainWindow(): Promise {
- if (!this.mainWindow) await this.initMainWindow();
- this.mainWindow.show();
+ async ensureMainWindow(showSplash = true): Promise {
+ // This needs to be ready to hear the IPC message before the window is loaded
+ let viewHasLoaded = Promise.resolve();
+
+ if (!this.mainWindow) {
+ viewHasLoaded = new Promise(resolve => {
+ ipcMain.once(IpcRendererNavigationEvents.LOADED, () => resolve());
+ });
+ await this.initMainWindow(showSplash);
+ }
+
+ try {
+ await viewHasLoaded;
+ await delay(50); // wait just a bit longer to let the first round of rendering happen
+ logger.info("[WINDOW-MANAGER]: Main window has reported that it has loaded");
+
+ this.mainWindow.show();
+ this.splashWindow?.close();
+ this.splashWindow = undefined;
+ setTimeout(() => {
+ appEventBus.emit({ name: "app", action: "start" });
+ }, 1000);
+ } catch (error) {
+ logger.error(`Showing main window failed: ${error.stack || error}`);
+ dialog.showErrorBox("ERROR!", error.toString());
+ }
return this.mainWindow;
}
@@ -206,8 +228,13 @@ export class WindowManager extends Singleton {
}
hide() {
- if (this.mainWindow && !this.mainWindow.isDestroyed()) this.mainWindow.hide();
- if (this.splashWindow && !this.splashWindow.isDestroyed()) this.splashWindow.hide();
+ if (isHideable(this.mainWindow)) {
+ this.mainWindow.hide();
+ }
+
+ if (isHideable(this.splashWindow)) {
+ this.splashWindow.hide();
+ }
}
destroy() {
diff --git a/src/migrations/cluster-store/3.6.0-beta.1.ts b/src/migrations/cluster-store/3.6.0-beta.1.ts
index df51510f23..5339d5232b 100644
--- a/src/migrations/cluster-store/3.6.0-beta.1.ts
+++ b/src/migrations/cluster-store/3.6.0-beta.1.ts
@@ -27,7 +27,7 @@ import { app, remote } from "electron";
import { migration } from "../migration-wrapper";
import fse from "fs-extra";
import { ClusterModel, ClusterStore } from "../../common/cluster-store";
-import { loadConfig } from "../../common/kube-helpers";
+import { loadConfigFromFileSync } from "../../common/kube-helpers";
export default migration({
version: "3.6.0-beta.1",
@@ -46,9 +46,13 @@ export default migration({
* migrate kubeconfig
*/
try {
+ const absPath = ClusterStore.getCustomKubeConfigPath(cluster.id);
+
+ fse.ensureDirSync(path.dirname(absPath));
+ fse.writeFileSync(absPath, cluster.kubeConfig, { encoding: "utf-8", mode: 0o600 });
// take the embedded kubeconfig and dump it into a file
- cluster.kubeConfigPath = ClusterStore.embedCustomKubeConfig(cluster.id, cluster.kubeConfig);
- cluster.contextName = loadConfig(cluster.kubeConfigPath).getCurrentContext();
+ cluster.kubeConfigPath = absPath;
+ cluster.contextName = loadConfigFromFileSync(cluster.kubeConfigPath).config.getCurrentContext();
delete cluster.kubeConfig;
} catch (error) {
diff --git a/src/renderer/api/kube-watch-api.ts b/src/renderer/api/kube-watch-api.ts
index f8ed7129b1..1a0f7e0b17 100644
--- a/src/renderer/api/kube-watch-api.ts
+++ b/src/renderer/api/kube-watch-api.ts
@@ -26,8 +26,8 @@ import type { KubeObjectStore } from "../kube-object.store";
import type { ClusterContext } from "../components/context";
import plimit from "p-limit";
-import { comparer, IReactionDisposer, observable, reaction, makeObservable } from "mobx";
-import { autoBind, noop } from "../utils";
+import { comparer, observable, reaction, makeObservable } from "mobx";
+import { autoBind, Disposer, noop } from "../utils";
import type { KubeApi } from "./kube-api";
import type { KubeJsonApiData } from "./kube-json-api";
import { isDebugging, isProduction } from "../../common/vars";
@@ -80,7 +80,7 @@ export class KubeWatchApi {
};
}
- subscribeStores(stores: KubeObjectStore[], opts: IKubeWatchSubscribeStoreOptions = {}): () => void {
+ subscribeStores(stores: KubeObjectStore[], opts: IKubeWatchSubscribeStoreOptions = {}): Disposer {
const { preload = true, waitUntilLoaded = true, loadOnce = false, } = opts;
const subscribingNamespaces = opts.namespaces ?? this.context?.allNamespaces ?? [];
const unsubscribeList: Function[] = [];
@@ -88,7 +88,7 @@ export class KubeWatchApi {
const load = (namespaces = subscribingNamespaces) => this.preloadStores(stores, { namespaces, loadOnce });
let preloading = preload && load();
- let cancelReloading: IReactionDisposer = noop;
+ let cancelReloading: Disposer = noop;
const subscribe = () => {
if (isUnsubscribed) return;
diff --git a/src/renderer/components/+add-cluster/add-cluster.tsx b/src/renderer/components/+add-cluster/add-cluster.tsx
index 9c91550d47..3479fe0426 100644
--- a/src/renderer/components/+add-cluster/add-cluster.tsx
+++ b/src/renderer/components/+add-cluster/add-cluster.tsx
@@ -20,35 +20,48 @@
*/
import "./add-cluster.scss";
-import React from "react";
+
+import type { KubeConfig } from "@kubernetes/client-node";
+import fse from "fs-extra";
+import { debounce } from "lodash";
+import { action, computed, observable, makeObservable } from "mobx";
import { observer } from "mobx-react";
-import { action, observable, runInAction, makeObservable } from "mobx";
-import { KubeConfig } from "@kubernetes/client-node";
+import path from "path";
+import React from "react";
+
+import { catalogURL } from "../+catalog";
+import { ClusterStore } from "../../../common/cluster-store";
+import { appEventBus } from "../../../common/event-bus";
+import { loadConfigFromString, splitConfig } from "../../../common/kube-helpers";
+import { docsUrl } from "../../../common/vars";
+import { navigate } from "../../navigation";
+import { iter } from "../../utils";
import { AceEditor } from "../ace-editor";
import { Button } from "../button";
-import { loadConfig, splitConfig, validateKubeConfig } from "../../../common/kube-helpers";
-import { ClusterStore } from "../../../common/cluster-store";
-import { v4 as uuid } from "uuid";
-import { navigate } from "../../navigation";
-import { UserStore } from "../../../common/user-store";
-import { Notifications } from "../notifications";
-import { ExecValidationNotFoundError } from "../../../common/custom-errors";
-import { appEventBus } from "../../../common/event-bus";
import { PageLayout } from "../layout/page-layout";
-import { docsUrl } from "../../../common/vars";
-import { catalogURL } from "../+catalog";
-import { preferencesURL } from "../+preferences";
-import { Input } from "../input";
+import { Notifications } from "../notifications";
+
+interface Option {
+ config: KubeConfig;
+ error?: string;
+}
+
+function getContexts(config: KubeConfig): Map {
+ return new Map(
+ splitConfig(config)
+ .map(({ config, error }) => [config.currentContext, {
+ config,
+ error,
+ }])
+ );
+}
+
@observer
export class AddCluster extends React.Component {
- @observable.ref kubeConfigLocal: KubeConfig;
- @observable.ref error: React.ReactNode;
+ @observable kubeContexts = observable.map();
@observable customConfig = "";
- @observable proxyServer = "";
@observable isWaiting = false;
- @observable showSettings = false;
-
- kubeContexts = observable.map();
+ @observable errorText: string;
constructor(props: {}) {
super(props);
@@ -59,159 +72,75 @@ export class AddCluster extends React.Component {
appEventBus.emit({ name: "cluster-add", action: "start" });
}
- componentWillUnmount() {
- UserStore.getInstance().markNewContextsAsSeen();
+ @computed get allErrors(): string[] {
+ return [
+ this.errorText,
+ ...iter.map(this.kubeContexts.values(), ({ error }) => error)
+ ].filter(Boolean);
}
@action
- refreshContexts() {
- this.kubeContexts.clear();
+ refreshContexts = debounce(() => {
+ const { config, error } = loadConfigFromString(this.customConfig.trim() || "{}");
- try {
- this.error = "";
- const contexts = this.getContexts(loadConfig(this.customConfig || "{}"));
-
- console.log(contexts);
-
- this.kubeContexts.replace(contexts);
- } catch (err) {
- this.error = String(err);
- }
- }
-
- getContexts(config: KubeConfig): Map {
- const contexts = new Map();
-
- splitConfig(config).forEach(config => {
- contexts.set(config.currentContext, config);
- });
-
- return contexts;
- }
+ this.kubeContexts.replace(getContexts(config));
+ this.errorText = error?.toString();
+ }, 500);
@action
- addClusters = (): void => {
+ addClusters = async () => {
+ this.isWaiting = true;
+ appEventBus.emit({ name: "cluster-add", action: "click" });
+
try {
+ const absPath = ClusterStore.getCustomKubeConfigPath();
- this.error = "";
- this.isWaiting = true;
- appEventBus.emit({ name: "cluster-add", action: "click" });
- const newClusters = Array.from(this.kubeContexts.keys()).filter(context => {
- const kubeConfig = this.kubeContexts.get(context);
- const error = validateKubeConfig(kubeConfig, context);
+ await fse.ensureDir(path.dirname(absPath));
+ await fse.writeFile(absPath, this.customConfig.trim(), { encoding: "utf-8", mode: 0o600 });
- if (error) {
- this.error = error.toString();
+ Notifications.ok(`Successfully added ${this.kubeContexts.size} new cluster(s)`);
- if (error instanceof ExecValidationNotFoundError) {
- Notifications.error(<>Error while adding cluster(s): {this.error}>);
- }
- }
-
- return Boolean(!error);
- }).map(context => {
- const clusterId = uuid();
- const kubeConfig = this.kubeContexts.get(context);
- const kubeConfigPath = ClusterStore.embedCustomKubeConfig(clusterId, kubeConfig); // save in app-files folder
-
- return {
- id: clusterId,
- kubeConfigPath,
- contextName: kubeConfig.currentContext,
- preferences: {
- clusterName: kubeConfig.currentContext,
- httpsProxy: this.proxyServer || undefined,
- },
- };
- });
-
- runInAction(() => {
- ClusterStore.getInstance().addClusters(...newClusters);
-
- Notifications.ok(
- <>Successfully imported {newClusters.length} cluster(s)>
- );
-
- navigate(catalogURL());
- });
- this.refreshContexts();
- } catch (err) {
- this.error = String(err);
- Notifications.error(<>Error while adding cluster(s): {this.error}>);
- } finally {
- this.isWaiting = false;
+ return navigate(catalogURL());
+ } catch (error) {
+ Notifications.error(`Failed to add clusters: ${error}`);
}
};
- renderInfo() {
+ render() {
return (
-
- Paste kubeconfig as a text from the clipboard to the textarea below.
- If you want to add clusters from kubeconfigs that exists on filesystem, please add those files (or folders) to kubeconfig sync via navigate(preferencesURL())}>Preferences .
- Read more about adding clusters here .
-
- );
- }
-
- renderKubeConfigSource() {
- return (
- <>
+
+ Add Clusters from Kubeconfig
+
+ Clusters added here are not merged into the ~/.kube/config file.
+ Read more about adding clusters here .
+
{
this.customConfig = value;
+ this.errorText = "";
this.refreshContexts();
}}
/>
- >
- );
- }
-
- render() {
- const submitDisabled = this.kubeContexts.size === 0;
-
- return (
-
- Add Clusters from Kubeconfig
- {this.renderInfo()}
- {this.renderKubeConfigSource()}
-
- {this.showSettings && (
-
-
HTTP Proxy server. Used for communicating with Kubernetes API.
-
this.proxyServer = value}
- theme="round-black"
- />
-
- {"A HTTP proxy server URL (format: http://:)."}
-
-
+ {this.allErrors.length > 0 && (
+ <>
+ KubeConfig Yaml Validation Errors:
+ {...this.allErrors.map(error => {error}
)}
+ >
)}
- {this.error && (
- {this.error}
- )}
-
diff --git a/src/renderer/components/+apps-helm-charts/helm-charts.tsx b/src/renderer/components/+apps-helm-charts/helm-charts.tsx
index d8cb43a98d..0bf80577bd 100644
--- a/src/renderer/components/+apps-helm-charts/helm-charts.tsx
+++ b/src/renderer/components/+apps-helm-charts/helm-charts.tsx
@@ -30,7 +30,6 @@ import type { HelmChart } from "../../api/endpoints/helm-charts.api";
import { HelmChartDetails } from "./helm-chart-details";
import { navigation } from "../../navigation";
import { ItemListLayout } from "../item-object-list/item-list-layout";
-import { SearchInputUrl } from "../input";
enum columnId {
name = "name",
@@ -92,9 +91,12 @@ export class HelmCharts extends Component {
(chart: HelmChart) => chart.getAppVersion(),
(chart: HelmChart) => chart.getKeywords(),
]}
- customizeHeader={() => (
-
- )}
+ customizeHeader={({ searchProps }) => ({
+ searchProps: {
+ ...searchProps,
+ placeholder: "Search Helm Charts...",
+ },
+ })}
renderTableHeader={[
{ className: "icon", showWithColumn: columnId.name },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
diff --git a/src/renderer/components/+apps-releases/releases.tsx b/src/renderer/components/+apps-releases/releases.tsx
index 7465ad16b5..bb16a4e723 100644
--- a/src/renderer/components/+apps-releases/releases.tsx
+++ b/src/renderer/components/+apps-releases/releases.tsx
@@ -34,6 +34,7 @@ import { navigation } from "../../navigation";
import { ItemListLayout } from "../item-object-list/item-list-layout";
import { HelmReleaseMenu } from "./release-menu";
import { secretsStore } from "../+config-secrets/secrets.store";
+import { NamespaceSelectFilter } from "../+namespaces/namespace-select-filter";
enum columnId {
name = "name",
@@ -116,6 +117,19 @@ export class HelmReleases extends Component {
(release: HelmRelease) => release.getStatus(),
(release: HelmRelease) => release.getVersion(),
]}
+ customizeHeader={({ filters, searchProps, ...headerPlaceholders }) => ({
+ filters: (
+ <>
+ {filters}
+
+ >
+ ),
+ searchProps: {
+ ...searchProps,
+ placeholder: "Search Releases...",
+ },
+ ...headerPlaceholders,
+ })}
renderHeaderTitle="Releases"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
diff --git a/src/renderer/components/+catalog/catalog-entity-details.scss b/src/renderer/components/+catalog/catalog-entity-details.scss
new file mode 100644
index 0000000000..f63e7c3ba3
--- /dev/null
+++ b/src/renderer/components/+catalog/catalog-entity-details.scss
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2021 OpenLens Authors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+ .CatalogEntityDetails {
+ .EntityMetadata {
+ margin-right: $margin;
+ }
+ .EntityIcon.box.top.left {
+ margin-right: $margin * 2;
+
+ .IconHint {
+ text-align: center;
+ font-size: var(--font-size-small);
+ text-transform: uppercase;
+ margin-top: $margin;
+ cursor: default;
+ user-select: none;
+ opacity: 0.5;
+ }
+
+ div * {
+ font-size: 1.5em;
+ }
+ }
+ }
diff --git a/src/renderer/components/+catalog/catalog-entity-details.tsx b/src/renderer/components/+catalog/catalog-entity-details.tsx
new file mode 100644
index 0000000000..8837920de4
--- /dev/null
+++ b/src/renderer/components/+catalog/catalog-entity-details.tsx
@@ -0,0 +1,129 @@
+/**
+ * Copyright (c) 2021 OpenLens Authors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+import "./catalog-entity-details.scss";
+import React, { Component } from "react";
+import { observer } from "mobx-react";
+import { Drawer, DrawerItem, DrawerItemLabels } from "../drawer";
+import { CatalogEntity, catalogEntityRunContext } from "../../api/catalog-entity";
+import type { CatalogCategory } from "../../../common/catalog";
+import { Icon } from "../icon";
+import { KubeObject } from "../../api/kube-object";
+import { CatalogEntityDrawerMenu } from "./catalog-entity-drawer-menu";
+import { catalogEntityDetailRegistry } from "../../../extensions/registries";
+import { HotbarIcon } from "../hotbar/hotbar-icon";
+
+interface Props {
+ entity: CatalogEntity;
+ hideDetails(): void;
+}
+
+@observer
+export class CatalogEntityDetails extends Component {
+ private abortController?: AbortController;
+
+ constructor(props: Props) {
+ super(props);
+ }
+
+ componentWillUnmount() {
+ this.abortController?.abort();
+ }
+
+ categoryIcon(category: CatalogCategory) {
+ if (category.metadata.icon.includes(" ;
+ } else {
+ return ;
+ }
+ }
+
+ openEntity() {
+ this.props.entity.onRun(catalogEntityRunContext);
+ }
+
+ renderContent() {
+ const { entity } = this.props;
+ const labels = KubeObject.stringifyLabels(entity.metadata.labels);
+ const detailItems = catalogEntityDetailRegistry.getItemsForKind(entity.kind, entity.apiVersion);
+ const details = detailItems.map((item, index) => {
+ return ;
+ });
+
+ const showDetails = detailItems.find((item) => item.priority > 999) === undefined;
+
+ return (
+ <>
+ {showDetails && (
+
+
+
this.openEntity()}
+ size={128} />
+
+ Click to open
+
+
+
+
+ {entity.metadata.name}
+
+
+ {entity.kind}
+
+
+ {entity.metadata.source}
+
+
+
+
+ )}
+
+ {details}
+
+ >
+ );
+ }
+
+ render() {
+ const { entity, hideDetails } = this.props;
+ const title = `${entity.kind}: ${entity.metadata.name}`;
+
+ return (
+ }
+ onClose={hideDetails}
+ >
+ {this.renderContent()}
+
+ );
+ }
+}
diff --git a/src/renderer/components/+catalog/catalog-entity-drawer-menu.tsx b/src/renderer/components/+catalog/catalog-entity-drawer-menu.tsx
new file mode 100644
index 0000000000..77c9df5d47
--- /dev/null
+++ b/src/renderer/components/+catalog/catalog-entity-drawer-menu.tsx
@@ -0,0 +1,127 @@
+/**
+ * Copyright (c) 2021 OpenLens Authors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+import React from "react";
+import { cssNames } from "../../utils";
+import { MenuActions, MenuActionsProps } from "../menu/menu-actions";
+import type { CatalogEntity, CatalogEntityContextMenu, CatalogEntityContextMenuContext } from "../../api/catalog-entity";
+import { observer } from "mobx-react";
+import { makeObservable, observable } from "mobx";
+import { navigate } from "../../navigation";
+import { MenuItem } from "../menu";
+import { ConfirmDialog } from "../confirm-dialog";
+import { HotbarStore } from "../../../common/hotbar-store";
+import { Icon } from "../icon";
+
+export interface CatalogEntityDrawerMenuProps extends MenuActionsProps {
+ entity: T | null | undefined;
+}
+
+@observer
+export class CatalogEntityDrawerMenu extends React.Component> {
+ @observable private contextMenu: CatalogEntityContextMenuContext;
+
+ constructor(props: CatalogEntityDrawerMenuProps) {
+ super(props);
+ makeObservable(this);
+ }
+
+ componentDidMount() {
+ this.contextMenu = {
+ menuItems: [],
+ navigate: (url: string) => navigate(url)
+ };
+ this.props.entity?.onContextMenuOpen(this.contextMenu);
+ }
+
+ onMenuItemClick(menuItem: CatalogEntityContextMenu) {
+ if (menuItem.confirm) {
+ ConfirmDialog.open({
+ okButtonProps: {
+ primary: false,
+ accent: true,
+ },
+ ok: () => {
+ menuItem.onClick();
+ },
+ message: menuItem.confirm.message
+ });
+ } else {
+ menuItem.onClick();
+ }
+ }
+
+ addToHotbar(entity: CatalogEntity): void {
+ HotbarStore.getInstance().addToHotbar(entity);
+ }
+
+ getMenuItems(entity: T): React.ReactChild[] {
+ if (!entity) {
+ return [];
+ }
+
+ const menuItems = this.contextMenu.menuItems.filter((menuItem) => {
+ return menuItem.icon && !menuItem.onlyVisibleForSource || menuItem.onlyVisibleForSource === entity.metadata.source;
+ });
+
+ const items = menuItems.map((menuItem, index) => {
+ const props = menuItem.icon.includes(" this.onMenuItemClick(menuItem)}>
+
+
+ );
+
+ });
+
+ items.unshift(
+ this.addToHotbar(entity) }>
+
+
+ );
+
+ items.reverse();
+
+ return items;
+ }
+
+ render() {
+ if (!this.contextMenu) {
+ return null;
+ }
+
+ const { className, entity, ...menuProps } = this.props;
+
+ return (
+
+ {this.getMenuItems(entity)}
+
+ );
+ }
+}
diff --git a/src/renderer/components/+catalog/catalog.module.css b/src/renderer/components/+catalog/catalog.module.css
new file mode 100644
index 0000000000..937195aa8f
--- /dev/null
+++ b/src/renderer/components/+catalog/catalog.module.css
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2021 OpenLens Authors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+.iconCell {
+ max-width: 40px;
+ display: flex;
+ align-items: center;
+}
+
+.nameCell {
+}
+
+.sourceCell {
+ max-width: 100px;
+}
+
+.statusCell {
+ max-width: 100px;
+}
+
+.connected {
+ color: var(--colorSuccess);
+}
+
+.disconnected {
+ color: var(--halfGray);
+}
+
+.labelsCell {
+ overflow-x: scroll;
+ text-overflow: unset;
+}
+
+.labelsCell::-webkit-scrollbar {
+ display: none;
+}
+
+.badge {
+ overflow: unset;
+ text-overflow: unset;
+ max-width: unset;
+}
+
+.badge:not(:first-child) {
+ margin-left: 0.5em;
+}
+
+.catalogIcon {
+ font-size: 10px;
+ -webkit-font-smoothing: auto;
+}
+
+.tabs {
+ @apply flex flex-grow flex-col;
+}
+
+.tab {
+ @apply px-8 py-4;
+}
+
+.tab:hover {
+ background-color: var(--sidebarItemHoverBackground);
+ --color-active: var(--textColorTertiary);
+}
+
+.tab::after {
+ display: none;
+}
+
+.activeTab, .activeTab:hover {
+ background-color: var(--blue);
+ --color-active: white;
+}
\ No newline at end of file
diff --git a/src/renderer/components/+catalog/catalog.scss b/src/renderer/components/+catalog/catalog.scss
deleted file mode 100644
index a0afd8c08c..0000000000
--- a/src/renderer/components/+catalog/catalog.scss
+++ /dev/null
@@ -1,120 +0,0 @@
-/**
- * Copyright (c) 2021 OpenLens Authors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-.CatalogPage {
- --width: 100%;
- --height: 100%;
- --nav-column-width: 200px;
-
- .sidebarRegion {
- justify-content: flex-start;
- background-color: var(--sidebarBackground);
-
- .sidebarHeader {
- background: var(--sidebarLogoBackground);
- height: var(--main-layout-header);
- padding: 4px;
- color: var(--textColorAccent);
- font-weight: bold;
- font-size: 14px;
- display: flex;
- align-items: center;
- padding-left: 10px;
- }
-
- > .sidebar {
- width: 100%;
- padding: 0;
-
- .sidebarTabs {
- margin-top: 5px;
-
- .Tab {
- padding: 7px 10px;
- font-weight: normal;
- font-size: 14px;
- border-radius: 0;
- height: 36px;
-
- &.active {
- background-color: var(--blue);
- color: white;
- }
- }
- }
- }
- }
-
- .contentRegion {
- > .content {
- padding: 20px 20px;
- }
- }
-
- .TableCell.icon {
- max-width: 40px;
- display: flex;
- align-items: center;
- }
-
- .TableCell.kind {
- max-width: 150px;
- }
-
- .TableCell.source {
- max-width: 100px;
- }
-
- .TableCell.status {
- max-width: 100px;
- &.connected {
- color: var(--colorSuccess);
- }
-
- &.disconnected {
- color: var(--halfGray);
- }
- }
-
- .TableCell.labels {
- overflow-x: scroll;
- text-overflow: unset;
-
- &::-webkit-scrollbar {
- display: none;
- }
-
- .Badge {
- overflow: unset;
- text-overflow: unset;
- max-width: unset;
-
- &:not(:first-child) {
- margin-left: 0.5em;
- }
- }
- }
-
- .catalogIcon {
- font-size: 10px;
- -webkit-font-smoothing: auto;
- }
-}
diff --git a/src/renderer/components/+catalog/catalog.tsx b/src/renderer/components/+catalog/catalog.tsx
index 066295b864..2414d90a49 100644
--- a/src/renderer/components/+catalog/catalog.tsx
+++ b/src/renderer/components/+catalog/catalog.tsx
@@ -19,7 +19,8 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-import "./catalog.scss";
+import styles from "./catalog.module.css";
+
import React from "react";
import { disposeOnUnmount, observer } from "mobx-react";
import { ItemListLayout } from "../item-object-list";
@@ -27,9 +28,8 @@ import { action, makeObservable, observable, reaction, when } from "mobx";
import { CatalogEntityItem, CatalogEntityStore } from "./catalog-entity.store";
import { navigate } from "../../navigation";
import { kebabCase } from "lodash";
-import { PageLayout } from "../layout/page-layout";
import { MenuItem, MenuActions } from "../menu";
-import { CatalogEntityContextMenu, CatalogEntityContextMenuContext, catalogEntityRunContext } from "../../api/catalog-entity";
+import type { CatalogEntityContextMenu, CatalogEntityContextMenuContext } from "../../api/catalog-entity";
import { Badge } from "../badge";
import { HotbarStore } from "../../../common/hotbar-store";
import { ConfirmDialog } from "../confirm-dialog";
@@ -40,6 +40,13 @@ import type { RouteComponentProps } from "react-router";
import type { ICatalogViewRouteParam } from "./catalog.route";
import { Notifications } from "../notifications";
import { Avatar } from "../avatar/avatar";
+import { MainLayout } from "../layout/main-layout";
+import { cssNames } from "../../utils";
+import { TopBar } from "../layout/topbar";
+import { welcomeURL } from "../+welcome";
+import { Icon } from "../icon";
+import { MaterialTooltip } from "../material-tooltip/material-tooltip";
+import { CatalogEntityDetails } from "./catalog-entity-details";
enum sortBy {
name = "name",
@@ -55,6 +62,7 @@ export class Catalog extends React.Component {
@observable private catalogEntityStore?: CatalogEntityStore;
@observable private contextMenu: CatalogEntityContextMenuContext;
@observable activeTab?: string;
+ @observable selectedItem?: CatalogEntityItem;
constructor(props: Props) {
super(props);
@@ -103,7 +111,7 @@ export class Catalog extends React.Component {
}
onDetails(item: CatalogEntityItem) {
- item.onRun(catalogEntityRunContext);
+ this.selectedItem = item;
}
onMenuItemClick(menuItem: CatalogEntityContextMenu) {
@@ -137,14 +145,14 @@ export class Catalog extends React.Component {
renderNavigation() {
return (
-
- Catalog
-
+
+
{
this.categories.map(category => (
@@ -153,6 +161,7 @@ export class Catalog extends React.Component
{
key={category.getId()}
label={category.metadata.name}
data-testid={`${category.getId()}-tab`}
+ className={cssNames(styles.tab, { [styles.activeTab]: this.activeTab == category.getId() })}
/>
))
}
@@ -181,19 +190,13 @@ export class Catalog extends React.Component {
};
renderIcon(item: CatalogEntityItem) {
- const category = catalogCategoryRegistry.getCategoryForEntity(item.entity);
-
- if (!category) {
- return null;
- }
-
return (
);
}
@@ -202,7 +205,6 @@ export class Catalog extends React.Component {
return (
{
(entity: CatalogEntityItem) => entity.searchFields,
]}
renderTableHeader={[
- { title: "", className: "icon" },
- { title: "Name", className: "name", sortBy: sortBy.name },
- { title: "Source", className: "source", sortBy: sortBy.source },
- { title: "Labels", className: "labels" },
- { title: "Status", className: "status", sortBy: sortBy.status },
+ { title: "", className: styles.iconCell },
+ { title: "Name", className: styles.nameCell, sortBy: sortBy.name },
+ { title: "Source", className: styles.sourceCell, sortBy: sortBy.source },
+ { title: "Labels", className: styles.labelsCell },
+ { title: "Status", className: styles.statusCell, sortBy: sortBy.status },
]}
renderTableContents={(item: CatalogEntityItem) => [
this.renderIcon(item),
@@ -239,7 +241,6 @@ export class Catalog extends React.Component {
return (
{
(entity: CatalogEntityItem) => entity.searchFields,
]}
renderTableHeader={[
- { title: "", className: "icon" },
- { title: "Name", className: "name", sortBy: sortBy.name },
- { title: "Kind", className: "kind", sortBy: sortBy.kind },
- { title: "Source", className: "source", sortBy: sortBy.source },
- { title: "Labels", className: "labels" },
- { title: "Status", className: "status", sortBy: sortBy.status },
+ { title: "", className: styles.iconCell },
+ { title: "Name", className: styles.nameCell, sortBy: sortBy.name },
+ { title: "Source", className: styles.sourceCell, sortBy: sortBy.source },
+ { title: "Labels", className: styles.labelsCell },
+ { title: "Status", className: styles.statusCell, sortBy: sortBy.status },
]}
renderTableContents={(item: CatalogEntityItem) => [
this.renderIcon(item),
@@ -269,6 +269,7 @@ export class Catalog extends React.Component {
item.labels.map((label) => ),
{ title: item.phase, className: kebabCase(item.phase) }
]}
+ detailsItem={this.selectedItem}
onDetails={(item: CatalogEntityItem) => this.onDetails(item) }
renderItemMenu={this.renderItemMenu}
/>
@@ -281,14 +282,29 @@ export class Catalog extends React.Component {
}
return (
-
- { this.catalogEntityStore.activeCategory ? this.renderSingleCategoryList() : this.renderAllCategoriesList() }
-
-
+ <>
+
+
+
+ navigate(welcomeURL())}/>
+
+
+
+
+
+ { this.catalogEntityStore.activeCategory ? this.renderSingleCategoryList() : this.renderAllCategoriesList() }
+
+ { !this.selectedItem && (
+
+ )}
+ { this.selectedItem && (
+ this.selectedItem = null}
+ />
+ )}
+
+ >
);
}
}
diff --git a/src/renderer/components/+custom-resources/crd-list.scss b/src/renderer/components/+custom-resources/crd-list.scss
index a1f50fb976..eed31b8f7c 100644
--- a/src/renderer/components/+custom-resources/crd-list.scss
+++ b/src/renderer/components/+custom-resources/crd-list.scss
@@ -42,4 +42,8 @@
}
}
}
-}
\ No newline at end of file
+
+ .SearchInput {
+ width: 300px;
+ }
+}
diff --git a/src/renderer/components/+custom-resources/crd-list.tsx b/src/renderer/components/+custom-resources/crd-list.tsx
index 5e44782476..822eff575f 100644
--- a/src/renderer/components/+custom-resources/crd-list.tsx
+++ b/src/renderer/components/+custom-resources/crd-list.tsx
@@ -95,7 +95,7 @@ export class CrdList extends React.Component {
sortingCallbacks={sortingCallbacks}
searchFilters={Object.values(sortingCallbacks)}
renderHeaderTitle="Custom Resources"
- customizeHeader={() => {
+ customizeHeader={({ filters, ...headerPlaceholders }) => {
let placeholder = <>All groups>;
if (selectedGroups.length == 1) placeholder = <>Group: {selectedGroups[0]}>;
@@ -104,26 +104,30 @@ export class CrdList extends React.Component {
return {
// todo: move to global filters
filters: (
- this.toggleSelection(group)}
- closeMenuOnSelect={false}
- controlShouldRenderValue={false}
- formatOptionLabel={({ value: group }: SelectOption) => {
- const isSelected = selectedGroups.includes(group);
-
- return (
-
-
- {group}
- {isSelected && }
-
- );
- }}
- />
- )
+ <>
+ {filters}
+ this.toggleSelection(group)}
+ closeMenuOnSelect={false}
+ controlShouldRenderValue={false}
+ formatOptionLabel={({ value: group }: SelectOption) => {
+ const isSelected = selectedGroups.includes(group);
+
+ return (
+
+
+ {group}
+ {isSelected && }
+
+ );
+ }}
+ />
+ >
+ ),
+ ...headerPlaceholders,
};
}}
renderTableHeader={[
diff --git a/src/renderer/components/+custom-resources/crd-resources.tsx b/src/renderer/components/+custom-resources/crd-resources.tsx
index b42703aa33..76ea8607b5 100644
--- a/src/renderer/components/+custom-resources/crd-resources.tsx
+++ b/src/renderer/components/+custom-resources/crd-resources.tsx
@@ -101,6 +101,13 @@ export class CrdResources extends React.Component {
(item: KubeObject) => item.getSearchFields(),
]}
renderHeaderTitle={crd.getResourceTitle()}
+ customizeHeader={({ searchProps, ...headerPlaceholders }) => ({
+ searchProps: {
+ ...searchProps,
+ placeholder: `Search ${crd.getResourceTitle()}...`,
+ },
+ ...headerPlaceholders
+ })}
renderTableHeader={[
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
isNamespaced && { title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
diff --git a/src/renderer/components/+events/events.tsx b/src/renderer/components/+events/events.tsx
index adf7b2d105..aa0ba475a9 100644
--- a/src/renderer/components/+events/events.tsx
+++ b/src/renderer/components/+events/events.tsx
@@ -30,7 +30,7 @@ import { EventStore, eventStore } from "./event.store";
import { getDetailsUrl, KubeObjectListLayout, KubeObjectListLayoutProps } from "../kube-object";
import type { KubeEvent } from "../../api/endpoints/events.api";
import type { TableSortCallbacks, TableSortParams, TableProps } from "../table";
-import type { IHeaderPlaceholders } from "../item-object-list";
+import type { HeaderCustomizer } from "../item-object-list";
import { Tooltip } from "../tooltip";
import { Link } from "react-router-dom";
import { cssNames, IClassName, stopPropagation } from "../../utils";
@@ -112,19 +112,21 @@ export class Events extends React.Component {
return this.items;
}
- customizeHeader = ({ info, title }: IHeaderPlaceholders) => {
+ customizeHeader: HeaderCustomizer = ({ info, title, ...headerPlaceholders }) => {
const { compact } = this.props;
const { store, items, visibleItems } = this;
const allEventsAreShown = visibleItems.length === items.length;
// handle "compact"-mode header
if (compact) {
- if (allEventsAreShown) return title; // title == "Events"
+ if (allEventsAreShown) {
+ return { title };
+ }
- return <>
- {title}
- ({visibleItems.length} of {items.length})
- >;
+ return {
+ title,
+ info: ({visibleItems.length} of {items.length}) ,
+ };
}
return {
@@ -136,7 +138,9 @@ export class Events extends React.Component {
className="help-icon"
tooltip={`Limited to ${store.limit}`}
/>
- >
+ >,
+ title,
+ ...headerPlaceholders
};
};
diff --git a/src/renderer/components/+namespaces/namespace-select-filter.tsx b/src/renderer/components/+namespaces/namespace-select-filter.tsx
index 25b14ae9e6..8ae2e97958 100644
--- a/src/renderer/components/+namespaces/namespace-select-filter.tsx
+++ b/src/renderer/components/+namespaces/namespace-select-filter.tsx
@@ -26,8 +26,6 @@ import { observer } from "mobx-react";
import { components, PlaceholderProps } from "react-select";
import { Icon } from "../icon";
-import { FilterIcon } from "../item-object-list/filter-icon";
-import { FilterType } from "../item-object-list/page-filters.store";
import { NamespaceSelect } from "./namespace-select";
import { namespaceStore } from "./namespace.store";
@@ -63,7 +61,7 @@ export class NamespaceSelectFilter extends React.Component {
return (
-
+
{namespace}
{isSelected && }
diff --git a/src/renderer/components/+welcome/welcome.scss b/src/renderer/components/+welcome/welcome.scss
index f74e135f70..6141f9f517 100644
--- a/src/renderer/components/+welcome/welcome.scss
+++ b/src/renderer/components/+welcome/welcome.scss
@@ -22,6 +22,7 @@
.Welcome {
text-align: center;
width: 100%;
+ height: 100%;
z-index: 1;
.box {
diff --git a/src/renderer/components/app.scss b/src/renderer/components/app.scss
index b4c15b89fd..e1d002c8f7 100755
--- a/src/renderer/components/app.scss
+++ b/src/renderer/components/app.scss
@@ -39,7 +39,7 @@
--font-weight-normal: 400;
--font-weight-bold: 500;
--main-layout-header: 40px;
- --drag-region-height: 22px
+ --drag-region-height: 22px;
}
*, *:before, *:after {
diff --git a/src/renderer/components/app.tsx b/src/renderer/components/app.tsx
index 5b68b56e2e..cde061b1aa 100755
--- a/src/renderer/components/app.tsx
+++ b/src/renderer/components/app.tsx
@@ -70,6 +70,8 @@ import { CommandContainer } from "./command-palette/command-container";
import { KubeObjectStore } from "../kube-object.store";
import { clusterContext } from "./context";
import { namespaceStore } from "./+namespaces/namespace.store";
+import { Sidebar } from "./layout/sidebar";
+import { Dock } from "./dock";
@observer
export class App extends React.Component {
@@ -175,7 +177,7 @@ export class App extends React.Component {
return (
-
+ } footer={ }>
diff --git a/src/renderer/components/cluster-manager/cluster-manager.scss b/src/renderer/components/cluster-manager/cluster-manager.scss
index 0c7c450f1b..16f77051c9 100644
--- a/src/renderer/components/cluster-manager/cluster-manager.scss
+++ b/src/renderer/components/cluster-manager/cluster-manager.scss
@@ -32,6 +32,7 @@
grid-area: main;
position: relative;
display: flex;
+ flex-direction: column;
}
.HotbarMenu {
@@ -45,7 +46,7 @@
#lens-views {
position: absolute;
left: 0;
- top: 0;
+ top: var(--main-layout-header); // Move below the TopBar
right: 0;
bottom: 0;
display: flex;
diff --git a/src/renderer/components/cluster-manager/cluster-status.tsx b/src/renderer/components/cluster-manager/cluster-status.tsx
index 2d4ccf3a38..c821f2874e 100644
--- a/src/renderer/components/cluster-manager/cluster-status.tsx
+++ b/src/renderer/components/cluster-manager/cluster-status.tsx
@@ -19,21 +19,23 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-import type { KubeAuthProxyLog } from "../../../main/kube-auth-proxy";
-
import "./cluster-status.scss";
-import React from "react";
-import { observer } from "mobx-react";
+
import { ipcRenderer } from "electron";
import { computed, observable, makeObservable } from "mobx";
-import { requestMain, subscribeToBroadcast } from "../../../common/ipc";
-import { Icon } from "../icon";
-import { Button } from "../button";
-import { cssNames, IClassName } from "../../utils";
-import type { Cluster } from "../../../main/cluster";
-import { ClusterId, ClusterStore } from "../../../common/cluster-store";
-import { CubeSpinner } from "../spinner";
+import { observer } from "mobx-react";
+import React from "react";
import { clusterActivateHandler } from "../../../common/cluster-ipc";
+import { ClusterId, ClusterStore } from "../../../common/cluster-store";
+import { requestMain, subscribeToBroadcast } from "../../../common/ipc";
+import type { Cluster } from "../../../main/cluster";
+import { cssNames, IClassName } from "../../utils";
+import { Button } from "../button";
+import { Icon } from "../icon";
+import { CubeSpinner } from "../spinner";
+import type { KubeAuthProxyLog } from "../../../main/kube-auth-proxy";
+import { navigate } from "../../navigation";
+import { entitySettingsURL } from "../+entity-settings";
interface Props {
className?: IClassName;
@@ -82,6 +84,15 @@ export class ClusterStatus extends React.Component {
this.isReconnecting = false;
};
+ manageProxySettings = () => {
+ navigate(entitySettingsURL({
+ params: {
+ entityId: this.props.clusterId,
+ },
+ fragment: "http-proxy",
+ }));
+ };
+
renderContent() {
const { authOutput, cluster, hasErrors } = this;
const failureReason = cluster.failureReason;
@@ -89,7 +100,7 @@ export class ClusterStatus extends React.Component {
if (!hasErrors || this.isReconnecting) {
return (
<>
-
+
{this.isReconnecting ? "Reconnecting..." : "Connecting..."}
{authOutput.map(({ data, error }, index) => {
@@ -102,7 +113,7 @@ export class ClusterStatus extends React.Component {
return (
<>
-
+
{cluster.preferences.clusterName}
@@ -121,6 +132,12 @@ export class ClusterStatus extends React.Component {
onClick={this.reconnect}
waiting={this.isReconnecting}
/>
+
>
);
}
diff --git a/src/renderer/components/cluster-manager/cluster-topbar.tsx b/src/renderer/components/cluster-manager/cluster-topbar.tsx
new file mode 100644
index 0000000000..af49194056
--- /dev/null
+++ b/src/renderer/components/cluster-manager/cluster-topbar.tsx
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2021 OpenLens Authors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+import React from "react";
+import { catalogURL } from "../+catalog";
+import type { Cluster } from "../../../main/cluster";
+import { navigate } from "../../navigation";
+import { Icon } from "../icon";
+import { TopBar } from "../layout/topbar";
+import { MaterialTooltip } from "../material-tooltip/material-tooltip";
+
+interface Props {
+ cluster: Cluster
+}
+
+export function ClusterTopbar({ cluster }: Props) {
+ return (
+
+
+
+ navigate(catalogURL())}/>
+
+
+
+ );
+}
diff --git a/src/renderer/components/cluster-manager/cluster-view.tsx b/src/renderer/components/cluster-manager/cluster-view.tsx
index fc9ba90807..f1530032e3 100644
--- a/src/renderer/components/cluster-manager/cluster-view.tsx
+++ b/src/renderer/components/cluster-manager/cluster-view.tsx
@@ -32,13 +32,13 @@ import { clusterActivateHandler } from "../../../common/cluster-ipc";
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
import { navigate } from "../../navigation";
import { catalogURL } from "../+catalog/catalog.route";
+import { ClusterTopbar } from "./cluster-topbar";
import type { RouteComponentProps } from "react-router-dom";
import type { IClusterViewRouteParams } from "./cluster-view.route";
interface Props extends RouteComponentProps {
}
-
@observer
export class ClusterView extends React.Component {
private store = ClusterStore.getInstance();
@@ -103,7 +103,8 @@ export class ClusterView extends React.Component {
render() {
return (
-
+
+ {this.cluster && }
{this.renderStatus()}
);
diff --git a/src/renderer/components/cluster-settings/components/cluster-proxy-setting.tsx b/src/renderer/components/cluster-settings/components/cluster-proxy-setting.tsx
index 55278cd9ae..054f8444ea 100644
--- a/src/renderer/components/cluster-settings/components/cluster-proxy-setting.tsx
+++ b/src/renderer/components/cluster-settings/components/cluster-proxy-setting.tsx
@@ -58,7 +58,7 @@ export class ClusterProxySetting extends React.Component
{
render() {
return (
<>
-
+
{
errorClass?: IClassName;
add: (item: CatalogEntity, index: number) => void;
remove: (uid: string) => void;
+ size?: number;
}
@observer
diff --git a/src/renderer/components/hotbar/hotbar-icon.scss b/src/renderer/components/hotbar/hotbar-icon.scss
index d573e86eb5..d890f622f8 100644
--- a/src/renderer/components/hotbar/hotbar-icon.scss
+++ b/src/renderer/components/hotbar/hotbar-icon.scss
@@ -71,7 +71,7 @@
&:hover {
&:not(.active) {
- box-shadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px #ffffff30;
+ box-shadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px #ffffff50;
}
}
}
diff --git a/src/renderer/components/hotbar/hotbar-icon.tsx b/src/renderer/components/hotbar/hotbar-icon.tsx
index 6dd86414e7..dd74a944de 100644
--- a/src/renderer/components/hotbar/hotbar-icon.tsx
+++ b/src/renderer/components/hotbar/hotbar-icon.tsx
@@ -31,7 +31,7 @@ import { MaterialTooltip } from "../material-tooltip/material-tooltip";
import { observer } from "mobx-react";
import { Avatar } from "../avatar/avatar";
-interface Props extends DOMAttributes {
+export interface HotbarIconProps extends DOMAttributes {
uid: string;
title: string;
source: string;
@@ -40,6 +40,7 @@ interface Props extends DOMAttributes {
active?: boolean;
menuItems?: CatalogEntityContextMenu[];
disabled?: boolean;
+ size?: number;
}
function onMenuItemClick(menuItem: CatalogEntityContextMenu) {
@@ -59,7 +60,7 @@ function onMenuItemClick(menuItem: CatalogEntityContextMenu) {
}
}
-export const HotbarIcon = observer(({menuItems = [], ...props}: Props) => {
+export const HotbarIcon = observer(({menuItems = [], size = 40, ...props}: HotbarIconProps) => {
const { uid, title, active, className, source, disabled, onMenuOpen, children, ...rest } = props;
const id = `hotbarIcon-${uid}`;
const [menuOpen, setMenuOpen] = useState(false);
@@ -77,8 +78,8 @@ export const HotbarIcon = observer(({menuItems = [], ...props}: Props) => {
title={title}
colorHash={`${title}-${source}`}
className={active ? "active" : "default"}
- width={40}
- height={40}
+ width={size}
+ height={size}
/>
{children}
diff --git a/src/renderer/components/hotbar/hotbar-menu.scss b/src/renderer/components/hotbar/hotbar-menu.scss
index 5f0eaddc3c..3b7300507a 100644
--- a/src/renderer/components/hotbar/hotbar-menu.scss
+++ b/src/renderer/components/hotbar/hotbar-menu.scss
@@ -62,7 +62,7 @@
height: var(--cellHeight);
min-height: var(--cellHeight);
margin: 12px;
- background: var(--layoutBackground);
+ background: var(--clusterMenuCellBackground);
border-radius: 6px;
position: relative;
@@ -136,4 +136,4 @@
100% {
margin-top: 2px;
}
-}
\ No newline at end of file
+}
diff --git a/src/renderer/components/hotbar/hotbar-menu.tsx b/src/renderer/components/hotbar/hotbar-menu.tsx
index d3bb838ac7..68d93b1675 100644
--- a/src/renderer/components/hotbar/hotbar-menu.tsx
+++ b/src/renderer/components/hotbar/hotbar-menu.tsx
@@ -157,6 +157,7 @@ export class HotbarMenu extends React.Component {
className={cssNames({ isDragging: snapshot.isDragging })}
remove={this.removeItem}
add={this.addItem}
+ size={40}
/>
) : (
{
source={item.entity.source}
menuItems={disabledMenuItems}
disabled
+ size={40}
/>
)}
diff --git a/src/renderer/components/icon/icon.scss b/src/renderer/components/icon/icon.scss
index 124e2c1cb9..b10eb3708b 100644
--- a/src/renderer/components/icon/icon.scss
+++ b/src/renderer/components/icon/icon.scss
@@ -135,7 +135,7 @@
&.interactive {
cursor: pointer;
transition: 250ms color, 250ms opacity, 150ms background-color, 150ms box-shadow;
- border-radius: 50%;
+ border-radius: var(--border-radius);
&.focusable:focus:not(:hover) {
box-shadow: 0 0 0 2px var(--focus-color);
diff --git a/src/renderer/components/input/search-input-url.tsx b/src/renderer/components/input/search-input-url.tsx
index 131f17d383..328f189d6d 100644
--- a/src/renderer/components/input/search-input-url.tsx
+++ b/src/renderer/components/input/search-input-url.tsx
@@ -32,12 +32,12 @@ export const searchUrlParam = createPageParam({
defaultValue: "",
});
-interface Props extends InputProps {
+export interface SearchInputUrlProps extends InputProps {
compact?: boolean; // show only search-icon when not focused
}
@observer
-export class SearchInputUrl extends React.Component {
+export class SearchInputUrl extends React.Component {
@observable inputVal = ""; // fix: use empty string on init to avoid react warnings
@disposeOnUnmount
@@ -62,7 +62,7 @@ export class SearchInputUrl extends React.Component {
}
};
- constructor(props: Props) {
+ constructor(props: SearchInputUrlProps) {
super(props);
makeObservable(this);
}
diff --git a/src/renderer/components/item-object-list/filter-icon.tsx b/src/renderer/components/item-object-list/filter-icon.tsx
index f5534b2f71..87f41c524f 100644
--- a/src/renderer/components/item-object-list/filter-icon.tsx
+++ b/src/renderer/components/item-object-list/filter-icon.tsx
@@ -31,9 +31,6 @@ export function FilterIcon(props: Props) {
const { type, ...iconProps } = props;
switch (type) {
- case FilterType.NAMESPACE:
- return ;
-
case FilterType.SEARCH:
return ;
diff --git a/src/renderer/components/item-object-list/item-list-layout.scss b/src/renderer/components/item-object-list/item-list-layout.scss
index a91e2a2a18..2609d0b323 100644
--- a/src/renderer/components/item-object-list/item-list-layout.scss
+++ b/src/renderer/components/item-object-list/item-list-layout.scss
@@ -28,7 +28,7 @@
padding: var(--flex-gap);
.title {
- color: $textColorPrimary;
+ color: var(--textColorTertiary);
}
.info-panel {
diff --git a/src/renderer/components/item-object-list/item-list-layout.tsx b/src/renderer/components/item-object-list/item-list-layout.tsx
index f894f90a4a..72dafbd90e 100644
--- a/src/renderer/components/item-object-list/item-list-layout.tsx
+++ b/src/renderer/components/item-object-list/item-list-layout.tsx
@@ -32,31 +32,30 @@ import { AddRemoveButtons, AddRemoveButtonsProps } from "../add-remove-buttons";
import { NoItems } from "../no-items";
import { Spinner } from "../spinner";
import type { ItemObject, ItemStore } from "../../item.store";
-import { SearchInputUrl } from "../input";
+import { SearchInputUrlProps, SearchInputUrl } from "../input";
import { Filter, FilterType, pageFilters } from "./page-filters.store";
import { PageFiltersList } from "./page-filters-list";
-import { PageFiltersSelect } from "./page-filters-select";
import { ThemeStore } from "../../theme.store";
import { MenuActions } from "../menu/menu-actions";
import { MenuItem } from "../menu";
import { Checkbox } from "../checkbox";
import { UserStore } from "../../../common/user-store";
import { namespaceStore } from "../+namespaces/namespace.store";
-import { KubeObjectStore } from "../../kube-object.store";
-import { NamespaceSelectFilter } from "../+namespaces/namespace-select-filter";
-// todo: refactor, split to small re-usable components
+
export type SearchFilter = (item: T) => string | number | (string | number)[];
export type ItemsFilter = (items: T[]) => T[];
-export interface IHeaderPlaceholders {
- title: ReactNode;
- search: ReactNode;
- filters: ReactNode;
- info: ReactNode;
+export interface HeaderPlaceholders {
+ title?: ReactNode;
+ searchProps?: SearchInputUrlProps;
+ filters?: ReactNode;
+ info?: ReactNode;
}
+export type HeaderCustomizer = (placeholders: HeaderPlaceholders) => HeaderPlaceholders;
+
export interface ItemListLayoutProps {
tableId?: string;
className: IClassName;
@@ -73,12 +72,11 @@ export interface ItemListLayoutProps {
showHeader?: boolean;
headerClassName?: IClassName;
renderHeaderTitle?: ReactNode | ((parent: ItemListLayout) => ReactNode);
- customizeHeader?: (placeholders: IHeaderPlaceholders, content: ReactNode) => Partial | ReactNode;
+ customizeHeader?: HeaderCustomizer | HeaderCustomizer[];
// items list configuration
isReady?: boolean; // show loading indicator while not ready
isSelectable?: boolean; // show checkbox in rows for selecting items
- isSearchable?: boolean; // apply search-filter & add search-input
isConfigurable?: boolean;
copyClassNameFromHeadCells?: boolean;
sortingCallbacks?: { [sortBy: string]: TableSortCallback };
@@ -102,12 +100,13 @@ export interface ItemListLayoutProps {
const defaultProps: Partial = {
showHeader: true,
- isSearchable: true,
isSelectable: true,
isConfigurable: false,
copyClassNameFromHeadCells: true,
preloadStores: true,
dependentStores: [],
+ searchFilters: [],
+ customizeHeader: [],
filterItems: [],
hasDetailsView: true,
onDetails: noop,
@@ -161,10 +160,10 @@ export class ItemListLayout extends React.Component {
private filterCallbacks: { [type: string]: ItemsFilter } = {
[FilterType.SEARCH]: items => {
- const { searchFilters, isSearchable } = this.props;
+ const { searchFilters } = this.props;
const search = pageFilters.getValues(FilterType.SEARCH)[0] || "";
- if (search && isSearchable && searchFilters) {
+ if (search && searchFilters.length) {
const normalizeText = (text: string) => String(text).toLowerCase();
const searchTexts = [search].map(normalizeText);
@@ -179,16 +178,6 @@ export class ItemListLayout extends React.Component {
return items;
},
-
- [FilterType.NAMESPACE]: items => {
- const filterValues = pageFilters.getValues(FilterType.NAMESPACE);
-
- if (filterValues.length > 0) {
- return items.filter(item => filterValues.includes(item.getNs()));
- }
-
- return items;
- },
};
@computed get isReady() {
@@ -201,9 +190,9 @@ export class ItemListLayout extends React.Component {
@computed get filters() {
let { activeFilters } = pageFilters;
- const { isSearchable, searchFilters } = this.props;
+ const { searchFilters } = this.props;
- if (!(isSearchable && searchFilters)) {
+ if (searchFilters.length === 0) {
activeFilters = activeFilters.filter(({ type }) => type !== FilterType.SEARCH);
}
@@ -359,18 +348,22 @@ export class ItemListLayout extends React.Component {
return this.items.map(item => this.getRow(item.getId()));
}
- renderHeaderContent(placeholders: IHeaderPlaceholders): ReactNode {
- const { isSearchable, searchFilters } = this.props;
- const { title, filters, search, info } = placeholders;
+ renderHeaderContent(placeholders: HeaderPlaceholders): ReactNode {
+ const { searchFilters } = this.props;
+ const { title, filters, searchProps, info } = placeholders;
return (
<>
{title}
-
- {info}
-
+ {
+ info && (
+
+ {info}
+
+ )
+ }
{filters}
- {isSearchable && searchFilters && search}
+ {searchFilters.length > 0 && searchProps && }
>
);
}
@@ -396,35 +389,15 @@ export class ItemListLayout extends React.Component {
return null;
}
- const showNamespaceSelectFilter = this.props.store instanceof KubeObjectStore && this.props.store.api.isNamespaced;
const title = typeof renderHeaderTitle === "function" ? renderHeaderTitle(this) : renderHeaderTitle;
- const placeholders: IHeaderPlaceholders = {
+ const customizeHeaders = [customizeHeader].flat().filter(Boolean);
+ const initialPlaceholders: HeaderPlaceholders = {
title: {title} ,
info: this.renderInfo(),
- filters: (
- <>
- {showNamespaceSelectFilter && }
-
- >
- ),
- search: ,
+ searchProps: {},
};
- let header = this.renderHeaderContent(placeholders);
-
- if (customizeHeader) {
- const modifiedHeader = customizeHeader(placeholders, header) ?? {};
-
- if (isReactNode(modifiedHeader)) {
- header = modifiedHeader;
- } else {
- header = this.renderHeaderContent({
- ...placeholders,
- ...modifiedHeader as IHeaderPlaceholders,
- });
- }
- }
+ const headerPlaceholders = customizeHeaders.reduce((prevPlaceholders, customizer) => customizer(prevPlaceholders), initialPlaceholders);
+ const header = this.renderHeaderContent(headerPlaceholders);
return (
diff --git a/src/renderer/components/item-object-list/page-filters-select.tsx b/src/renderer/components/item-object-list/page-filters-select.tsx
deleted file mode 100644
index 418c82045b..0000000000
--- a/src/renderer/components/item-object-list/page-filters-select.tsx
+++ /dev/null
@@ -1,136 +0,0 @@
-/**
- * Copyright (c) 2021 OpenLens Authors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-import React from "react";
-import { observer } from "mobx-react";
-import { computed, makeObservable } from "mobx";
-import { GroupSelectOption, Select, SelectOption, SelectProps } from "../select";
-import { FilterType, pageFilters } from "./page-filters.store";
-import { namespaceStore } from "../+namespaces/namespace.store";
-import { Icon } from "../icon";
-import { FilterIcon } from "./filter-icon";
-
-export interface SelectOptionFilter extends SelectOption {
- type: FilterType;
- selected?: boolean;
-}
-
-interface Props extends SelectProps {
- allowEmpty?: boolean;
- disableFilters?: {
- [filterType: string]: boolean;
- };
-}
-
-@observer
-export class PageFiltersSelect extends React.Component
{
- static defaultProps: Props = {
- allowEmpty: true,
- disableFilters: {},
- };
-
- constructor(props: Props) {
- super(props);
- makeObservable(this);
- }
-
- @computed get groupedOptions() {
- const options: GroupSelectOption[] = [];
- const { disableFilters } = this.props;
-
- if (!disableFilters[FilterType.NAMESPACE]) {
- const selectedValues = pageFilters.getValues(FilterType.NAMESPACE);
-
- options.push({
- label: "Namespace",
- options: namespaceStore.items.map(ns => {
- const name = ns.getName();
-
- return {
- type: FilterType.NAMESPACE,
- value: name,
- icon: ,
- selected: selectedValues.includes(name),
- };
- })
- });
- }
-
- return options;
- }
-
- @computed get options(): SelectOptionFilter[] {
- return this.groupedOptions.reduce((options, optGroup) => {
- options.push(...optGroup.options);
-
- return options;
- }, []);
- }
-
- private formatLabel = (option: SelectOptionFilter) => {
- const { label, value, type, selected } = option;
-
- return (
-
-
- {label || String(value)}
- {selected && }
-
- );
- };
-
- private onSelect = (option: SelectOptionFilter) => {
- const { type, value, selected } = option;
- const { addFilter, removeFilter } = pageFilters;
- const filter = { type, value };
-
- if (!selected) {
- addFilter(filter);
- }
- else {
- removeFilter(filter);
- }
- };
-
- render() {
- const { groupedOptions, formatLabel, onSelect, options } = this;
-
- if (!options.length && this.props.allowEmpty) {
- return null;
- }
- const { allowEmpty, disableFilters, ...selectProps } = this.props;
- const selectedOptions = options.filter(opt => opt.selected);
-
- return (
- `No filters available.`}
- autoConvertOptions={false}
- tabSelectsValue={false}
- controlShouldRenderValue={false}
- options={groupedOptions}
- formatOptionLabel={formatLabel}
- onChange={onSelect}
- />
- );
- }
-}
diff --git a/src/renderer/components/item-object-list/page-filters.store.ts b/src/renderer/components/item-object-list/page-filters.store.ts
index 4abccb8585..f2d36a0da8 100644
--- a/src/renderer/components/item-object-list/page-filters.store.ts
+++ b/src/renderer/components/item-object-list/page-filters.store.ts
@@ -25,7 +25,6 @@ import { searchUrlParam } from "../input/search-input-url";
export enum FilterType {
SEARCH = "search",
- NAMESPACE = "namespace",
}
export interface Filter {
diff --git a/src/renderer/components/kube-object/kube-object-list-layout.tsx b/src/renderer/components/kube-object/kube-object-list-layout.tsx
index 52c886f6a2..39b0ee5019 100644
--- a/src/renderer/components/kube-object/kube-object-list-layout.tsx
+++ b/src/renderer/components/kube-object/kube-object-list-layout.tsx
@@ -30,6 +30,8 @@ import { KubeObjectMenu } from "./kube-object-menu";
import { kubeSelectedUrlParam, showDetails } from "./kube-object-details";
import { kubeWatchApi } from "../../api/kube-watch-api";
import { clusterContext } from "../context";
+import { NamespaceSelectFilter } from "../+namespaces/namespace-select-filter";
+import { ResourceKindMap, ResourceNames } from "../../utils/rbac";
export interface KubeObjectListLayoutProps extends ItemListLayoutProps {
store: KubeObjectStore;
@@ -66,7 +68,8 @@ export class KubeObjectListLayout extends React.Component ({
+ filters: (
+ <>
+ {filters}
+ {store.api.isNamespaced && }
+ >
+ ),
+ searchProps: {
+ ...searchProps,
+ placeholder: `Search ${placeholderString}...`,
+ },
+ ...headerPlaceHolders,
+ }),
+ ...[customizeHeader].flat(),
+ ]}
renderItemMenu={(item: KubeObject) => } // safe because we are dealing with KubeObjects here
/>
);
diff --git a/src/renderer/components/layout/__test__/main-layout-header.test.tsx b/src/renderer/components/layout/__test__/main-layout-header.test.tsx
deleted file mode 100644
index ad50d77fe8..0000000000
--- a/src/renderer/components/layout/__test__/main-layout-header.test.tsx
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * Copyright (c) 2021 OpenLens Authors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-jest.mock("../../../../common/ipc");
-
-import React from "react";
-import { render } from "@testing-library/react";
-import "@testing-library/jest-dom/extend-expect";
-
-import { MainLayoutHeader } from "../main-layout-header";
-import { Cluster } from "../../../../main/cluster";
-import { ClusterStore } from "../../../../common/cluster-store";
-import mockFs from "mock-fs";
-import { ThemeStore } from "../../../theme.store";
-import { UserStore } from "../../../../common/user-store";
-
-jest.mock("electron", () => {
- return {
- app: {
- getVersion: () => "99.99.99",
- getPath: () => "tmp",
- getLocale: () => "en",
- setLoginItemSettings: jest.fn(),
- },
- };
-});
-
-describe(" ", () => {
- let cluster: Cluster;
-
- beforeEach(() => {
- const mockOpts = {
- "minikube-config.yml": JSON.stringify({
- apiVersion: "v1",
- clusters: [{
- name: "minikube",
- cluster: {
- server: "https://192.168.64.3:8443",
- },
- }],
- contexts: [{
- context: {
- cluster: "minikube",
- user: "minikube",
- },
- name: "minikube",
- }],
- users: [{
- name: "minikube",
- }],
- kind: "Config",
- preferences: {},
- })
- };
-
- mockFs(mockOpts);
-
- UserStore.createInstance();
- ThemeStore.createInstance();
- ClusterStore.createInstance();
-
- cluster = new Cluster({
- id: "foo",
- contextName: "minikube",
- kubeConfigPath: "minikube-config.yml",
- });
- });
-
- afterEach(() => {
- ClusterStore.resetInstance();
- ThemeStore.resetInstance();
- UserStore.resetInstance();
- mockFs.restore();
- });
-
- it("renders w/o errors", () => {
- const { container } = render( );
-
- expect(container).toBeInstanceOf(HTMLElement);
- });
-
- it("renders cluster name", () => {
- const { getByText } = render( );
-
- expect(getByText("minikube")).toBeInTheDocument();
- });
-});
diff --git a/src/renderer/components/layout/main-layout.module.css b/src/renderer/components/layout/main-layout.module.css
new file mode 100644
index 0000000000..abee3c0258
--- /dev/null
+++ b/src/renderer/components/layout/main-layout.module.css
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2021 OpenLens Authors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+.mainLayout {
+ display: grid;
+ grid-template-areas:
+ "sidebar contents"
+ "sidebar footer";
+ grid-template-rows: [contents] 1fr [footer] auto;
+ grid-template-columns: [sidebar] var(--sidebar-width) [contents] 1fr;
+ width: 100%;
+ z-index: 1;
+ height: calc(100% - var(--main-layout-header));
+}
+
+.sidebar {
+ grid-area: sidebar;
+ display: flex;
+ position: relative;
+ background: var(--sidebarBackground);
+}
+
+.contents {
+ grid-area: contents;
+ overflow: auto;
+}
+
+.footer {
+ position: relative;
+ grid-area: footer;
+ min-width: 0; /* restrict size when overflow content (e.g. tabs scrolling) */
+}
\ No newline at end of file
diff --git a/src/renderer/components/layout/main-layout.scss b/src/renderer/components/layout/main-layout.scss
deleted file mode 100755
index a2deeea392..0000000000
--- a/src/renderer/components/layout/main-layout.scss
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * Copyright (c) 2021 OpenLens Authors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-.MainLayout {
- display: grid;
- grid-template-areas:
- "aside header"
- "aside tabs"
- "aside main"
- "aside footer";
- grid-template-rows: [header] var(--main-layout-header) [tabs] min-content [main] 1fr [footer] auto;
- grid-template-columns: [sidebar] minmax(var(--main-layout-header), min-content) [main] 1fr;
- height: 100%;
-
- > header {
- grid-area: header;
- background: $layoutBackground;
- padding: $padding $padding * 2;
- }
-
- > aside {
- grid-area: aside;
- position: relative;
- background: $sidebarBackground;
- white-space: nowrap;
- transition: width 150ms cubic-bezier(0.4, 0, 0.2, 1);
- width: var(--sidebar-width);
-
- &.compact {
- position: absolute;
- width: var(--main-layout-header);
- height: 100%;
- overflow: hidden;
-
- &:hover {
- width: var(--sidebar-width);
- transition-delay: 750ms;
- box-shadow: 3px 3px 16px rgba(0, 0, 0, 0.35);
- z-index: $zIndex-sidebar-hover;
- }
- }
- }
-
- > main {
- display: contents;
-
- > * {
- grid-area: main;
- overflow: auto;
- }
- }
-
- footer {
- position: relative;
- grid-area: footer;
- min-width: 0; // restrict size when overflow content (e.g. tabs scrolling)
- }
-}
diff --git a/src/renderer/components/layout/main-layout.tsx b/src/renderer/components/layout/main-layout.tsx
index 455f0dfdfc..a85e90b158 100755
--- a/src/renderer/components/layout/main-layout.tsx
+++ b/src/renderer/components/layout/main-layout.tsx
@@ -19,73 +19,53 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-import "./main-layout.scss";
+import styles from "./main-layout.module.css";
import React from "react";
import { observer } from "mobx-react";
-import { getHostedCluster } from "../../../common/cluster-store";
import { cssNames } from "../../utils";
-import { Dock } from "../dock";
import { ErrorBoundary } from "../error-boundary";
import { ResizeDirection, ResizeGrowthDirection, ResizeSide, ResizingAnchor } from "../resizing-anchor";
-import { MainLayoutHeader } from "./main-layout-header";
-import { Sidebar } from "./sidebar";
import { sidebarStorage } from "./sidebar-storage";
-export interface MainLayoutProps {
- className?: any;
+interface Props {
+ sidebar: React.ReactNode;
+ className?: string;
footer?: React.ReactNode;
- headerClass?: string;
- footerClass?: string;
}
@observer
-export class MainLayout extends React.Component {
- onSidebarCompactModeChange = () => {
- sidebarStorage.merge(draft => {
- draft.compact = !draft.compact;
- });
- };
-
+export class MainLayout extends React.Component {
onSidebarResize = (width: number) => {
sidebarStorage.merge({ width });
};
render() {
- const cluster = getHostedCluster();
- const { onSidebarCompactModeChange, onSidebarResize } = this;
- const { className, headerClass, footer, footerClass, children } = this.props;
- const { compact, width: sidebarWidth } = sidebarStorage.get();
+ const { onSidebarResize } = this;
+ const { className, footer, children, sidebar } = this.props;
+ const { width: sidebarWidth } = sidebarStorage.get();
const style = { "--sidebar-width": `${sidebarWidth}px` } as React.CSSProperties;
- if (!cluster) {
- return null; // fix: skip render when removing active (visible) cluster
- }
-
return (
-
-
-
-
-
+
+
+ {sidebar}
sidebarWidth}
onDrag={onSidebarResize}
- onDoubleClick={onSidebarCompactModeChange}
- disabled={compact}
minExtent={120}
maxExtent={400}
/>
-
+
-
+
{children}
-
+
-
+ {footer}
);
}
diff --git a/src/renderer/components/layout/sidebar-item.tsx b/src/renderer/components/layout/sidebar-item.tsx
index 61957a61a3..113cef6634 100644
--- a/src/renderer/components/layout/sidebar-item.tsx
+++ b/src/renderer/components/layout/sidebar-item.tsx
@@ -62,10 +62,6 @@ export class SidebarItem extends React.Component {
return this.props.id;
}
- @computed get compact(): boolean {
- return Boolean(sidebarStorage.get().compact);
- }
-
@computed get expanded(): boolean {
return Boolean(sidebarStorage.get().expanded[this.id]);
}
@@ -78,8 +74,6 @@ export class SidebarItem extends React.Component {
}
@computed get isExpandable(): boolean {
- if (this.compact) return false; // not available in compact-mode currently
-
return Boolean(this.props.children);
}
@@ -108,10 +102,8 @@ export class SidebarItem extends React.Component {
if (isHidden) return null;
- const { isActive, id, compact, expanded, isExpandable, toggleExpand } = this;
- const classNames = cssNames(SidebarItem.displayName, className, {
- compact,
- });
+ const { isActive, id, expanded, isExpandable, toggleExpand } = this;
+ const classNames = cssNames(SidebarItem.displayName, className);
return (
diff --git a/src/renderer/components/layout/sidebar-storage.ts b/src/renderer/components/layout/sidebar-storage.ts
index 976f40b31c..663cb7c177 100644
--- a/src/renderer/components/layout/sidebar-storage.ts
+++ b/src/renderer/components/layout/sidebar-storage.ts
@@ -23,14 +23,12 @@ import { createStorage } from "../../utils";
export interface SidebarStorageState {
width: number;
- compact: boolean;
expanded: {
[itemId: string]: boolean;
}
}
export const sidebarStorage = createStorage
("sidebar", {
- width: 200, // sidebar size in non-compact mode
- compact: false, // compact-mode (icons only)
+ width: 200,
expanded: {},
});
diff --git a/src/renderer/components/layout/sidebar.scss b/src/renderer/components/layout/sidebar.scss
index 6212758905..f0d777fadd 100644
--- a/src/renderer/components/layout/sidebar.scss
+++ b/src/renderer/components/layout/sidebar.scss
@@ -23,49 +23,9 @@
$iconSize: 24px;
$itemSpacing: floor($unit / 2.6) floor($unit / 1.6);
- &.compact {
- .sidebar-nav {
- @include hidden-scrollbar; // fix: scrollbar overlaps icons
- }
- }
-
- .header {
- background: $sidebarLogoBackground;
- padding: $padding / 2;
- height: var(--main-layout-header);
-
- a {
- font-size: 18.5px;
- text-decoration: none;
- }
-
- div.logo-text {
- position: absolute;
- left: 42px;
- top: 11px;
- }
-
- .logo-icon {
- width: 28px;
- height: 28px;
- margin-left: 2px;
- margin-top: 2px;
- margin-right: 10px;
-
- svg {
- --size: 28px;
- padding: 2px;
- }
- }
-
- .pin-icon {
- margin: auto;
- margin-right: $padding / 2;
- }
- }
-
.sidebar-nav {
- padding: $padding / 1.5 0;
+ width: var(--sidebar-width);
+ padding-bottom: calc(var(--padding) * 3);
overflow: auto;
.Icon {
diff --git a/src/renderer/components/layout/sidebar.tsx b/src/renderer/components/layout/sidebar.tsx
index 30b14919e9..6ecc9b8df9 100644
--- a/src/renderer/components/layout/sidebar.tsx
+++ b/src/renderer/components/layout/sidebar.tsx
@@ -24,7 +24,6 @@ import type { TabLayoutRoute } from "./tab-layout";
import React from "react";
import { observer } from "mobx-react";
-import { NavLink } from "react-router-dom";
import { cssNames } from "../../utils";
import { Icon } from "../icon";
import { workloadsRoute, workloadsURL } from "../+workloads/workloads.route";
@@ -52,8 +51,6 @@ import { SidebarItem } from "./sidebar-item";
interface Props {
className?: string;
- compact?: boolean; // compact-mode view: show only icons and expand on :hover
- toggle(): void; // compact-mode updater
}
@observer
@@ -173,24 +170,11 @@ export class Sidebar extends React.Component {
}
render() {
- const { toggle, compact, className } = this.props;
+ const { className } = this.props;
return (
-
-
-
+
+
.Tabs {
- grid-area: tabs;
background: $layoutTabsBackground;
+ min-height: 32px;
}
-
main {
$spacing: $margin * 2;
- grid-area: main;
+ flex-grow: 1;
overflow-y: scroll; // always reserve space for scrollbar (17px)
overflow-x: auto;
margin: $spacing;
diff --git a/src/common/utils/saveToAppFiles.ts b/src/renderer/components/layout/topbar.module.css
similarity index 66%
rename from src/common/utils/saveToAppFiles.ts
rename to src/renderer/components/layout/topbar.module.css
index b957cdb38e..08378bb1d4 100644
--- a/src/common/utils/saveToAppFiles.ts
+++ b/src/renderer/components/layout/topbar.module.css
@@ -19,17 +19,27 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-// Save file to electron app directory (e.g. "/Users/$USER/Library/Application Support/Lens" for MacOS)
-import path from "path";
-import { app, remote } from "electron";
-import { ensureDirSync, writeFileSync } from "fs-extra";
-import type { WriteFileOptions } from "fs";
-
-export function saveToAppFiles(filePath: string, contents: any, options?: WriteFileOptions): string {
- const absPath = path.resolve((app || remote.app).getPath("userData"), filePath);
-
- ensureDirSync(path.dirname(absPath));
- writeFileSync(absPath, contents, options);
-
- return absPath;
+.topBar {
+ display: grid;
+ grid-template-columns: [title] 1fr [controls] auto;
+ grid-template-rows: var(--main-layout-header);
+ grid-template-areas: "title controls";
+ background-color: var(--layoutBackground);
+ z-index: 1;
+ width: 100%;
}
+
+.title {
+ @apply font-bold px-6;
+ color: var(--textColorAccent);
+ align-items: center;
+ display: flex;
+}
+
+.controls {
+ align-self: flex-end;
+ padding-right: 1.5rem;
+ align-items: center;
+ display: flex;
+ height: 100%;
+}
\ No newline at end of file
diff --git a/src/renderer/components/layout/main-layout-header.tsx b/src/renderer/components/layout/topbar.tsx
similarity index 75%
rename from src/renderer/components/layout/main-layout-header.tsx
rename to src/renderer/components/layout/topbar.tsx
index 354794e363..2fe302ce55 100644
--- a/src/renderer/components/layout/main-layout-header.tsx
+++ b/src/renderer/components/layout/topbar.tsx
@@ -19,20 +19,19 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+import styles from "./topbar.module.css";
import React from "react";
import { observer } from "mobx-react";
-import type { Cluster } from "../../../main/cluster";
-import { cssNames } from "../../utils";
-interface Props {
- cluster: Cluster
- className?: string
+interface Props extends React.HTMLAttributes {
+ label: React.ReactNode;
}
-export const MainLayoutHeader = observer(({ cluster, className }: Props) => {
+export const TopBar = observer(({ label, children, ...rest }: Props) => {
return (
-
+
);
});
diff --git a/src/renderer/components/resizing-anchor/resizing-anchor.scss b/src/renderer/components/resizing-anchor/resizing-anchor.scss
index 0896a9ee62..024a83105b 100644
--- a/src/renderer/components/resizing-anchor/resizing-anchor.scss
+++ b/src/renderer/components/resizing-anchor/resizing-anchor.scss
@@ -31,6 +31,23 @@ body.resizing {
position: absolute;
z-index: 10;
+ &::after {
+ content: " ";
+ display: block;
+ width: 3px;
+ height: 100%;
+ margin-left: 50%;
+ background: transparent;
+ transition: all 0.2s 0s;
+ }
+
+ &:hover {
+ &::after {
+ background: var(--blue);
+ transition: all 0.2s 0.5s;
+ }
+ }
+
&.disabled {
display: none;
}
@@ -56,6 +73,17 @@ body.resizing {
cursor: col-resize;
width: $dimension;
+ // Expand hoverable area while resizing to keep highlighting resizer.
+ // Otherwise, cursor can move far away dropping hover indicator.
+ .resizing & {
+ $expandedWidth: 200px;
+ width: $expandedWidth;
+
+ &.trailing {
+ right: -$expandedWidth / 2;
+ }
+ }
+
&.leading {
left: -$dimension / 2;
}
diff --git a/src/renderer/kube-object.store.ts b/src/renderer/kube-object.store.ts
index ec26f0e2dc..f869d131d4 100644
--- a/src/renderer/kube-object.store.ts
+++ b/src/renderer/kube-object.store.ts
@@ -27,7 +27,7 @@ import { KubeObject, KubeStatus } from "./api/kube-object";
import type { IKubeWatchEvent } from "./api/kube-watch-api";
import { ItemStore } from "./item.store";
import { apiManager } from "./api/api-manager";
-import { IKubeApiQueryParams, KubeApi, parseKubeApi } from "./api/kube-api";
+import { ensureObjectSelfLink, IKubeApiQueryParams, KubeApi, parseKubeApi } from "./api/kube-api";
import type { KubeJsonApiData } from "./api/kube-json-api";
import { Notifications } from "./components/notifications";
@@ -280,6 +280,9 @@ export abstract class KubeObjectStore extends ItemSt
async update(item: T, data: Partial): Promise {
const newItem = await item.update(data);
+
+ ensureObjectSelfLink(this.api, newItem);
+
const index = this.items.findIndex(item => item.getId() === newItem.getId());
this.items.splice(index, 1, newItem);
diff --git a/src/renderer/lens-app.tsx b/src/renderer/lens-app.tsx
index c58845fe23..35151dcee2 100644
--- a/src/renderer/lens-app.tsx
+++ b/src/renderer/lens-app.tsx
@@ -49,6 +49,9 @@ export class LensApp extends React.Component {
window.addEventListener("online", () => broadcastMessage("network:online"));
registerIpcHandlers();
+ }
+
+ componentDidMount() {
ipcRenderer.send(IpcRendererNavigationEvents.LOADED);
}
@@ -57,11 +60,11 @@ export class LensApp extends React.Component {
-
+
-
-
+
+
);
diff --git a/src/renderer/themes/lens-dark.json b/src/renderer/themes/lens-dark.json
index f96eb81453..fff229699b 100644
--- a/src/renderer/themes/lens-dark.json
+++ b/src/renderer/themes/lens-dark.json
@@ -26,6 +26,7 @@
"sidebarLogoBackground": "#414448",
"sidebarActiveColor": "#ffffff",
"sidebarSubmenuActiveColor": "#ffffff",
+ "sidebarItemHoverBackground": "#3a3e44",
"buttonPrimaryBackground": "#3d90ce",
"buttonDefaultBackground": "#414448",
"buttonLightBackground": "#f1f1f1",
@@ -105,11 +106,12 @@
"drawerItemValueColor": "#a0a0a0",
"clusterMenuBackground": "#252729",
"clusterMenuBorderColor": "#252729",
+ "clusterMenuCellBackground": "#2e3136",
"clusterSettingsBackground": "#1e2124",
"addClusterIconColor": "#252729",
"boxShadow": "#0000003a",
"iconActiveColor": "#ffffff",
- "iconActiveBackground": "#ffffff22",
+ "iconActiveBackground": "#ffffff18",
"filterAreaBackground": "#23272b",
"chartLiveBarBackgound": "#00000033",
"chartStripesColor": "#ffffff08",
diff --git a/src/renderer/themes/lens-light.json b/src/renderer/themes/lens-light.json
index d3b5938de3..5084b63c52 100644
--- a/src/renderer/themes/lens-light.json
+++ b/src/renderer/themes/lens-light.json
@@ -27,6 +27,7 @@
"sidebarActiveColor": "#ffffff",
"sidebarSubmenuActiveColor": "#3d90ce",
"sidebarBackground": "#e8e8e8",
+ "sidebarItemHoverBackground": "#f0f2f5",
"buttonPrimaryBackground": "#3d90ce",
"buttonDefaultBackground": "#414448",
"buttonLightBackground": "#f1f1f1",
@@ -104,8 +105,9 @@
"drawerSubtitleBackground": "#f1f1f1",
"drawerItemNameColor": "#727272",
"drawerItemValueColor": "#555555",
- "clusterMenuBackground": "#e8e8e8",
+ "clusterMenuBackground": "#d7d8da",
"clusterMenuBorderColor": "#c9cfd3",
+ "clusterMenuCellBackground": "#bbbbbb",
"clusterSettingsBackground": "#ffffff",
"addClusterIconColor": "#8d8d8d",
"boxShadow": "#0000003a",
diff --git a/src/renderer/utils/rbac.ts b/src/renderer/utils/rbac.ts
index ca264f050c..da167541fc 100644
--- a/src/renderer/utils/rbac.ts
+++ b/src/renderer/utils/rbac.ts
@@ -19,7 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-import type { KubeResource } from "../../common/rbac";
+import { apiResourceRecord, KubeResource } from "../../common/rbac";
export const ResourceNames: Record = {
"namespaces": "Namespaces",
@@ -53,3 +53,8 @@ export const ResourceNames: Record = {
"clusterroles": "Cluster Roles",
"serviceaccounts": "Service Accounts"
};
+
+export const ResourceKindMap: Record = Object.fromEntries(
+ Object.entries(apiResourceRecord)
+ .map(([resource, { kind }]) => [kind, resource as KubeResource])
+);
diff --git a/typedoc.json b/typedoc.json
new file mode 100644
index 0000000000..bad7697c4f
--- /dev/null
+++ b/typedoc.json
@@ -0,0 +1,11 @@
+{
+ "readme": "docs/extensions/typedoc-readme.md.tpl",
+ "name": "@k8slens/extensions",
+ "out": "docs/extensions/api",
+ "excludePrivate": true,
+ "includes": [
+ "src/"
+ ],
+ "hideBreadcrumbs": true,
+ "disableSources": true
+}
diff --git a/yarn.lock b/yarn.lock
index 4526d78f67..78491269c1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -789,14 +789,16 @@
"@types/yargs" "^15.0.0"
chalk "^4.0.0"
-"@kubernetes/client-node@^0.12.0":
- version "0.12.0"
- resolved "https://registry.yarnpkg.com/@kubernetes/client-node/-/client-node-0.12.0.tgz#79120311bced206ac8fa36435fb4cc2c1828fff2"
- integrity sha512-u57q5IaZl91f7YZoZOsgCa31hHyowHxFG88XZXd8arI8heSxbdHWHineo/8mLZbeSbHkge9Awae1stQZzuTnjg==
+"@kubernetes/client-node@^0.14.3":
+ version "0.14.3"
+ resolved "https://registry.yarnpkg.com/@kubernetes/client-node/-/client-node-0.14.3.tgz#5ed9b88873419080547f22cb74eb502bf6671fca"
+ integrity sha512-9hHGDNm2JEFQcRTpDxVoAVr0fowU+JH/l5atCXY9VXwvFM18pW5wr2LzLP+Q2Rh+uQv7Moz4gEjEKSCgVKykEQ==
dependencies:
"@types/js-yaml" "^3.12.1"
"@types/node" "^10.12.0"
"@types/request" "^2.47.1"
+ "@types/stream-buffers" "^3.0.3"
+ "@types/tar" "^4.0.3"
"@types/underscore" "^1.8.9"
"@types/ws" "^6.0.1"
byline "^5.0.0"
@@ -804,13 +806,16 @@
isomorphic-ws "^4.0.1"
js-yaml "^3.13.1"
jsonpath-plus "^0.19.0"
- openid-client "2.5.0"
+ openid-client "^4.1.1"
request "^2.88.0"
rfc4648 "^1.3.0"
shelljs "^0.8.2"
+ stream-buffers "^3.0.2"
+ tar "^6.0.2"
+ tmp-promise "^3.0.2"
tslib "^1.9.3"
underscore "^1.9.1"
- ws "^6.1.0"
+ ws "^7.3.1"
"@malept/cross-spawn-promise@^1.1.0":
version "1.1.1"
@@ -961,10 +966,10 @@
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
-"@sindresorhus/is@^0.7.0":
- version "0.7.0"
- resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd"
- integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==
+"@sindresorhus/is@^4.0.0":
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.1.tgz#d26729db850fa327b7cacc5522252194404226f5"
+ integrity sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==
"@sinonjs/commons@^1.7.0":
version "1.8.0"
@@ -987,6 +992,13 @@
dependencies:
defer-to-connect "^1.0.1"
+"@szmarczak/http-timer@^4.0.5":
+ version "4.0.5"
+ resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152"
+ integrity sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==
+ dependencies:
+ defer-to-connect "^2.0.0"
+
"@testing-library/dom@>=7", "@testing-library/dom@^7.28.1":
version "7.30.3"
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-7.30.3.tgz#779ea9bbb92d63302461800a388a5a890ac22519"
@@ -1086,6 +1098,16 @@
dependencies:
"@types/node" "*"
+"@types/cacheable-request@^6.0.1":
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976"
+ integrity sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==
+ dependencies:
+ "@types/http-cache-semantics" "*"
+ "@types/keyv" "*"
+ "@types/node" "*"
+ "@types/responselike" "*"
+
"@types/caseless@*":
version "0.12.2"
resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8"
@@ -1300,6 +1322,11 @@
"@types/tapable" "*"
"@types/webpack" "*"
+"@types/http-cache-semantics@*":
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a"
+ integrity sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==
+
"@types/http-proxy-middleware@*":
version "0.19.3"
resolved "https://registry.yarnpkg.com/@types/http-proxy-middleware/-/http-proxy-middleware-0.19.3.tgz#b2eb96fbc0f9ac7250b5d9c4c53aade049497d03"
@@ -1408,6 +1435,13 @@
resolved "https://registry.yarnpkg.com/@types/jsonpath/-/jsonpath-0.2.0.tgz#13c62db22a34d9c411364fac79fd374d63445aa1"
integrity sha512-v7qlPA0VpKUlEdhghbDqRoKMxFB3h3Ch688TApBJ6v+XLDdvWCGLJIYiPKGZnS6MAOie+IorCfNYVHOPIHSWwQ==
+"@types/keyv@*":
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7"
+ integrity sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==
+ dependencies:
+ "@types/node" "*"
+
"@types/lodash@^4.14.155":
version "4.14.155"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.155.tgz#e2b4514f46a261fd11542e47519c20ebce7bc23a"
@@ -1447,7 +1481,7 @@
dependencies:
"@types/webpack" "*"
-"@types/minimatch@*", "@types/minimatch@3.0.3":
+"@types/minimatch@*":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
@@ -1476,16 +1510,16 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.41.tgz#d0b939d94c1d7bd53d04824af45f1139b8c45615"
integrity sha512-dueRKfaJL4RTtSa7bWeTK1M+VH+Gns73oCgzvYfHZywRCoPSd8EkXBL0mZ9unPTveBn+D9phZBaxuzpwjWkW0g==
+"@types/node@12.20", "@types/node@^12.0.12":
+ version "12.20.11"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.11.tgz#980832cd56efafff8c18aa148c4085eb02a483f4"
+ integrity sha512-gema+apZ6qLQK7k7F0dGkGCWQYsL0qqKORWOQO6tq46q+x+1C0vbOiOqOwRVlh4RAdbQwV/j/ryr3u5NOG1fPQ==
+
"@types/node@^10.12.0":
version "10.17.24"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.24.tgz#c57511e3a19c4b5e9692bb2995c40a3a52167944"
integrity sha512-5SCfvCxV74kzR3uWgTYiGxrd69TbT1I6+cMx1A5kEly/IVveJBimtAMlXiEyVFn5DvUFewQWxOOiJhlxeQwxgA==
-"@types/node@^12.0.12", "@types/node@^12.12.45":
- version "12.12.45"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.45.tgz#33d550d6da243652004b00cbf4f15997456a38e3"
- integrity sha512-9w50wqeS0qQH9bo1iIRcQhDXRxoDzyAqCL5oJG+Nuu7cAoe6omGo+YDE0spAGK5sPrdLDhQLbQxq0DnxyndPKA==
-
"@types/normalize-package-data@^2.4.0":
version "2.4.0"
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
@@ -1575,17 +1609,10 @@
dependencies:
"@types/react" "*"
-"@types/react-dom@*":
- version "16.9.8"
- resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.8.tgz#fe4c1e11dfc67155733dfa6aa65108b4971cb423"
- integrity sha512-ykkPQ+5nFknnlU6lDd947WbQ6TE3NNzbQAkInC2EKY1qeYdTKp7onFusmYZb+ityzx2YviqT6BXSu+LyWWJwcA==
- dependencies:
- "@types/react" "*"
-
-"@types/react-dom@^17.0.0":
- version "17.0.0"
- resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.0.tgz#b3b691eb956c4b3401777ee67b900cb28415d95a"
- integrity sha512-lUqY7OlkF/RbNtD5nIq7ot8NquXrdFrjSOR6+w9a9RFQevGi1oZO1dcJbXMeONAPKtZ2UrZOEJ5UOCVsxbLk/g==
+"@types/react-dom@*", "@types/react-dom@^17.0.6":
+ version "17.0.6"
+ resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.6.tgz#c158325cf91b196270bc0f4af73463f149e7eafe"
+ integrity sha512-MGTI+TudxAnGTj8aco8mogaPSJGK2Whje7OZh1CxNLRyhJpTZg/pGQpIbCT0eCVFQyH7UFpdvCqQEThHIp/gsA==
dependencies:
"@types/react" "*"
@@ -1646,15 +1673,7 @@
dependencies:
"@types/react" "*"
-"@types/react@*":
- version "16.9.35"
- resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.35.tgz#a0830d172e8aadd9bd41709ba2281a3124bbd368"
- integrity sha512-q0n0SsWcGc8nDqH2GJfWQWUOmZSJhXV64CjVN5SvcNti3TdEaA3AH0D8DwNmMdzjMAC/78tB8nAZIlV8yTz+zQ==
- dependencies:
- "@types/prop-types" "*"
- csstype "^2.2.0"
-
-"@types/react@^17.0.0":
+"@types/react@*", "@types/react@^17.0.0":
version "17.0.0"
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.0.tgz#5af3eb7fad2807092f0046a1302b7823e27919b8"
integrity sha512-aj/L7RIMsRlWML3YB6KZiXB3fV2t41+5RBGYF8z+tAKU43Px8C3cYUZsDvf1/+Bm4FK21QWBrDutu8ZJ/70qOw==
@@ -1692,6 +1711,13 @@
"@types/tough-cookie" "*"
form-data "^2.5.0"
+"@types/responselike@*", "@types/responselike@^1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29"
+ integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==
+ dependencies:
+ "@types/node" "*"
+
"@types/retry@*":
version "0.12.0"
resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d"
@@ -1717,10 +1743,10 @@
"@types/mime" "*"
"@types/node" "*"
-"@types/sharp@^0.26.0":
- version "0.26.0"
- resolved "https://registry.yarnpkg.com/@types/sharp/-/sharp-0.26.0.tgz#2fa8419dbdaca8dd38f73888b27b207f188a8669"
- integrity sha512-oJrR8eiwpL7qykn2IeFRduXM4za7z+7yOUEbKVtuDQ/F6htDLHYO6IbzhaJQHV5n6O3adIh4tJvtgPyLyyydqg==
+"@types/sharp@^0.28.3":
+ version "0.28.3"
+ resolved "https://registry.yarnpkg.com/@types/sharp/-/sharp-0.28.3.tgz#0e57ede34d3e334632ab7a68a6af070aa0f51ceb"
+ integrity sha512-y3mxUj3jukIWgdu9CrSTSCo5HruTzDxdjn5SqdIEALdTszkcot9r8HX/7q9FMx3YjuXifTD0OI+d4wA6Pogqmw==
dependencies:
"@types/node" "*"
@@ -1756,12 +1782,19 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==
+"@types/stream-buffers@^3.0.3":
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/@types/stream-buffers/-/stream-buffers-3.0.3.tgz#34e565bf64e3e4bdeee23fd4aa58d4636014a02b"
+ integrity sha512-NeFeX7YfFZDYsCfbuaOmFQ0OjSmHreKBpp7MQ4alWQBHeh2USLsj7qyMyn9t82kjqIX516CR/5SRHnARduRtbQ==
+ dependencies:
+ "@types/node" "*"
+
"@types/tapable@*", "@types/tapable@^1.0.5":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.5.tgz#9adbc12950582aa65ead76bffdf39fe0c27a3c02"
integrity sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==
-"@types/tar@^4.0.4":
+"@types/tar@^4.0.3", "@types/tar@^4.0.4":
version "4.0.4"
resolved "https://registry.yarnpkg.com/@types/tar/-/tar-4.0.4.tgz#d680de60855e7778a51c672b755869a3b8d2889f"
integrity sha512-0Xv+xcmkTsOZdIF4yCnd7RkOOyfyqPaqJ7RZFKnwdxfDbkN3eAAE9sHl8zJFqBz4VhxolW9EErbjR1oyH7jK2A==
@@ -2279,14 +2312,6 @@ agentkeepalive@^3.4.1:
dependencies:
humanize-ms "^1.2.1"
-aggregate-error@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-1.0.0.tgz#888344dad0220a72e3af50906117f48771925fac"
- integrity sha1-iINE2tAiCnLjr1CQYRf0h3GSX6w=
- dependencies:
- clean-stack "^1.0.0"
- indent-string "^3.0.0"
-
aggregate-error@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0"
@@ -2295,6 +2320,14 @@ aggregate-error@^3.0.0:
clean-stack "^2.0.0"
indent-string "^4.0.0"
+aggregate-error@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
+ integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==
+ dependencies:
+ clean-stack "^2.0.0"
+ indent-string "^4.0.0"
+
ajv-errors@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d"
@@ -2850,13 +2883,6 @@ babel-runtime@^6.26.0:
core-js "^2.4.0"
regenerator-runtime "^0.11.0"
-backbone@^1.4.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/backbone/-/backbone-1.4.0.tgz#54db4de9df7c3811c3f032f34749a4cd27f3bd12"
- integrity sha512-RLmDrRXkVdouTg38jcgHhyQ/2zjg7a8E6sz2zxfz21Hh17xDJYUHBZimVIt5fUyS8vbfpeSmTL3gUjTEvUV3qQ==
- dependencies:
- underscore ">=1.8.3"
-
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
@@ -2872,7 +2898,7 @@ base64-js@^1.5.1:
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
-base64url@^3.0.0, base64url@^3.0.1:
+base64url@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d"
integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==
@@ -3341,18 +3367,10 @@ cache-base@^1.0.1:
union-value "^1.0.0"
unset-value "^1.0.0"
-cacheable-request@^2.1.1:
- version "2.1.4"
- resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d"
- integrity sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=
- dependencies:
- clone-response "1.0.2"
- get-stream "3.0.0"
- http-cache-semantics "3.8.1"
- keyv "3.0.0"
- lowercase-keys "1.0.0"
- normalize-url "2.0.1"
- responselike "1.0.2"
+cacheable-lookup@^5.0.3:
+ version "5.0.4"
+ resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005"
+ integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==
cacheable-request@^6.0.0:
version "6.1.0"
@@ -3367,6 +3385,19 @@ cacheable-request@^6.0.0:
normalize-url "^4.1.0"
responselike "^1.0.2"
+cacheable-request@^7.0.1:
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.1.tgz#062031c2856232782ed694a257fa35da93942a58"
+ integrity sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==
+ dependencies:
+ clone-response "^1.0.2"
+ get-stream "^5.1.0"
+ http-cache-semantics "^4.0.0"
+ keyv "^4.0.0"
+ lowercase-keys "^2.0.0"
+ normalize-url "^4.1.0"
+ responselike "^2.0.0"
+
call-bind@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.0.tgz#24127054bb3f9bdcb4b1fb82418186072f77b8ce"
@@ -3669,11 +3700,6 @@ clean-css@^4.2.3:
dependencies:
source-map "~0.6.0"
-clean-stack@^1.0.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-1.3.0.tgz#9e821501ae979986c46b1d66d2d432db2fd4ae31"
- integrity sha1-noIVAa6XmYbEax1m0tQy2y/UrjE=
-
clean-stack@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
@@ -3777,7 +3803,7 @@ clone-deep@^4.0.1:
kind-of "^6.0.2"
shallow-clone "^3.0.0"
-clone-response@1.0.2, clone-response@^1.0.2:
+clone-response@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=
@@ -4455,7 +4481,7 @@ cssstyle@^2.2.0:
dependencies:
cssom "~0.3.6"
-csstype@^2.2.0, csstype@^2.5.2, csstype@^2.5.7, csstype@^2.6.7:
+csstype@^2.5.2, csstype@^2.5.7, csstype@^2.6.7:
version "2.6.10"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.10.tgz#e63af50e66d7c266edb6b32909cfd0aabe03928b"
integrity sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w==
@@ -4660,6 +4686,11 @@ defer-to-connect@^1.0.1:
resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591"
integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==
+defer-to-connect@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587"
+ integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==
+
define-properties@^1.1.2, define-properties@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
@@ -5398,7 +5429,7 @@ es6-error@^4.1.1:
resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
-es6-promise@^4.0.3, es6-promise@^4.2.8:
+es6-promise@^4.0.3:
version "4.2.8"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
@@ -6282,7 +6313,7 @@ from2@^1.3.0:
inherits "~2.0.1"
readable-stream "~1.1.10"
-from2@^2.1.0, from2@^2.1.1:
+from2@^2.1.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af"
integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=
@@ -6497,7 +6528,7 @@ get-stdin@^4.0.1:
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=
-get-stream@3.0.0, get-stream@^3.0.0:
+get-stream@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=
@@ -6706,6 +6737,23 @@ globule@^1.0.0:
lodash "~4.17.10"
minimatch "~3.0.2"
+got@^11.8.0:
+ version "11.8.2"
+ resolved "https://registry.yarnpkg.com/got/-/got-11.8.2.tgz#7abb3959ea28c31f3576f1576c1effce23f33599"
+ integrity sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==
+ dependencies:
+ "@sindresorhus/is" "^4.0.0"
+ "@szmarczak/http-timer" "^4.0.5"
+ "@types/cacheable-request" "^6.0.1"
+ "@types/responselike" "^1.0.0"
+ cacheable-lookup "^5.0.3"
+ cacheable-request "^7.0.1"
+ decompress-response "^6.0.0"
+ http2-wrapper "^1.0.0-beta.5.2"
+ lowercase-keys "^2.0.0"
+ p-cancelable "^2.0.0"
+ responselike "^2.0.0"
+
got@^6.7.1:
version "6.7.1"
resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0"
@@ -6723,29 +6771,6 @@ got@^6.7.1:
unzip-response "^2.0.1"
url-parse-lax "^1.0.0"
-got@^8.3.2:
- version "8.3.2"
- resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937"
- integrity sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==
- dependencies:
- "@sindresorhus/is" "^0.7.0"
- cacheable-request "^2.1.1"
- decompress-response "^3.3.0"
- duplexer3 "^0.1.4"
- get-stream "^3.0.0"
- into-stream "^3.1.0"
- is-retry-allowed "^1.1.0"
- isurl "^1.0.0-alpha5"
- lowercase-keys "^1.0.0"
- mimic-response "^1.0.0"
- p-cancelable "^0.4.0"
- p-timeout "^2.0.1"
- pify "^3.0.0"
- safe-buffer "^5.1.1"
- timed-out "^4.0.1"
- url-parse-lax "^3.0.0"
- url-to-options "^1.0.1"
-
got@^9.6.0:
version "9.6.0"
resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85"
@@ -6793,7 +6818,7 @@ handle-thing@^2.0.0:
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e"
integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==
-handlebars@^4.7.2, handlebars@^4.7.6, handlebars@^4.7.7:
+handlebars@^4.7.7:
version "4.7.7"
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1"
integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==
@@ -6845,23 +6870,11 @@ has-flag@^4.0.0:
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
-has-symbol-support-x@^1.4.1:
- version "1.4.2"
- resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455"
- integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==
-
has-symbols@^1.0.0, has-symbols@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
-has-to-string-tag-x@^1.2.0:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d"
- integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==
- dependencies:
- has-symbol-support-x "^1.4.1"
-
has-unicode@^2.0.0, has-unicode@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@@ -6932,11 +6945,6 @@ he@^1.2.0:
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
-highlight.js@^9.18.0:
- version "9.18.3"
- resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.3.tgz#a1a0a2028d5e3149e2380f8a865ee8516703d634"
- integrity sha512-zBZAmhSupHIl5sITeMqIJnYCDfAEc3Gdkqj65wC1lpI468MMQeeQkhcIAvk+RylAkxrCcI9xy9piHiXeQ1BdzQ==
-
history@^4.10.1, history@^4.9.0:
version "4.10.1"
resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3"
@@ -7063,7 +7071,7 @@ htmlparser2@^3.3.0:
inherits "^2.0.1"
readable-stream "^3.1.1"
-http-cache-semantics@3.8.1, http-cache-semantics@^3.8.1:
+http-cache-semantics@^3.8.1:
version "3.8.1"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2"
integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==
@@ -7151,6 +7159,14 @@ http-signature@~1.2.0:
jsprim "^1.2.2"
sshpk "^1.7.0"
+http2-wrapper@^1.0.0-beta.5.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d"
+ integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==
+ dependencies:
+ quick-lru "^5.1.1"
+ resolve-alpn "^1.0.0"
+
https-browserify@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
@@ -7364,11 +7380,6 @@ indent-string@^2.1.0:
dependencies:
repeating "^2.0.0"
-indent-string@^3.0.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289"
- integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=
-
indent-string@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251"
@@ -7478,14 +7489,6 @@ interpret@^1.0.0:
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
-into-stream@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6"
- integrity sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=
- dependencies:
- from2 "^2.1.1"
- p-is-promise "^1.1.0"
-
invert-kv@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
@@ -7807,11 +7810,6 @@ is-obj@^2.0.0:
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982"
integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==
-is-object@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470"
- integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA=
-
is-path-cwd@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb"
@@ -7848,11 +7846,6 @@ is-path-inside@^3.0.2:
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
-is-plain-obj@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
- integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4=
-
is-plain-object@^2.0.3, is-plain-object@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
@@ -7884,7 +7877,7 @@ is-regex@^1.0.5:
dependencies:
has-symbols "^1.0.1"
-is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0:
+is-retry-allowed@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==
@@ -8049,14 +8042,6 @@ istextorbinary@^5.12.0:
editions "^6.1.0"
textextensions "^5.11.0"
-isurl@^1.0.0-alpha5:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67"
- integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==
- dependencies:
- has-to-string-tag-x "^1.2.0"
- is-object "^1.0.1"
-
jake@^10.6.1:
version "10.8.1"
resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.1.tgz#0f6f5ef13ebe014104527fb4b1b24f44cd1f04d6"
@@ -8503,6 +8488,17 @@ joi@^17.3.0:
"@sideway/formula" "^3.0.0"
"@sideway/pinpoint" "^2.0.0"
+joi@^17.4.0:
+ version "17.4.0"
+ resolved "https://registry.yarnpkg.com/joi/-/joi-17.4.0.tgz#b5c2277c8519e016316e49ababd41a1908d9ef20"
+ integrity sha512-F4WiW2xaV6wc1jxete70Rw4V/VuMd6IN+a5ilZsxG4uYtUXWu2kq9W5P2dz30e7Gmw8RCbY/u/uk+dMPma9tAg==
+ dependencies:
+ "@hapi/hoek" "^9.0.0"
+ "@hapi/topo" "^5.0.0"
+ "@sideway/address" "^4.1.0"
+ "@sideway/formula" "^3.0.0"
+ "@sideway/pinpoint" "^2.0.0"
+
jose@^1.27.1:
version "1.27.1"
resolved "https://registry.yarnpkg.com/jose/-/jose-1.27.1.tgz#a1de2ecb5b3ae1ae28f0d9d0cc536349ada27ec8"
@@ -8510,10 +8506,12 @@ jose@^1.27.1:
dependencies:
"@panva/asn1.js" "^1.0.0"
-jquery@^3.4.1:
- version "3.5.1"
- resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.1.tgz#d7b4d08e1bfdb86ad2f1a3d039ea17304717abb5"
- integrity sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg==
+jose@^2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/jose/-/jose-2.0.5.tgz#29746a18d9fff7dcf9d5d2a6f62cb0c7cd27abd3"
+ integrity sha512-BAiDNeDKTMgk4tvD0BbxJ8xHEHBZgpeRZ1zGPPsitSyMgjoMWiLGYAE7H7NpP5h0lPppQajQs871E8NHUrzVPA==
+ dependencies:
+ "@panva/asn1.js" "^1.0.0"
js-base64@^2.1.8:
version "2.5.2"
@@ -8530,7 +8528,7 @@ js-sha3@^0.8.0:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
-js-yaml@^3.13.1:
+js-yaml@^3.13.1, js-yaml@^3.14.0:
version "3.14.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537"
integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
@@ -8538,14 +8536,6 @@ js-yaml@^3.13.1:
argparse "^1.0.7"
esprima "^4.0.0"
-js-yaml@^3.14.0:
- version "3.14.0"
- resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482"
- integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==
- dependencies:
- argparse "^1.0.7"
- esprima "^4.0.0"
-
js-yaml@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.0.0.tgz#f426bc0ff4b4051926cd588c71113183409a121f"
@@ -8632,6 +8622,11 @@ json-buffer@3.0.0:
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=
+json-buffer@3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
+ integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
+
json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
@@ -8825,13 +8820,6 @@ jszip@^3.1.0:
readable-stream "~2.3.6"
set-immediate-shim "~1.0.1"
-keyv@3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373"
- integrity sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==
- dependencies:
- json-buffer "3.0.0"
-
keyv@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9"
@@ -8839,6 +8827,13 @@ keyv@^3.0.0:
dependencies:
json-buffer "3.0.0"
+keyv@^4.0.0:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254"
+ integrity sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==
+ dependencies:
+ json-buffer "3.0.1"
+
killable@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
@@ -9311,11 +9306,6 @@ loglevel@^1.6.8:
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.0.tgz#728166855a740d59d38db01cf46f042caa041bb0"
integrity sha512-i2sY04nal5jDcagM3FMfG++T69GEEM8CYuOfeOIvmXzOIcwE9a/CJPR0MFM97pYMj/u10lzz7/zd7+qwhrBTqQ==
-long@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
- integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
-
loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
@@ -9338,11 +9328,6 @@ lower-case@^2.0.1:
dependencies:
tslib "^1.10.0"
-lowercase-keys@1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306"
- integrity sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=
-
lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
@@ -9375,7 +9360,7 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
-lunr@^2.3.8:
+lunr@^2.3.9:
version "2.3.9"
resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1"
integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==
@@ -9472,16 +9457,16 @@ map-visit@^1.0.0:
dependencies:
object-visit "^1.0.0"
-marked@^0.8.0:
- version "0.8.2"
- resolved "https://registry.yarnpkg.com/marked/-/marked-0.8.2.tgz#4faad28d26ede351a7a1aaa5fec67915c869e355"
- integrity sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw==
-
marked@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/marked/-/marked-2.0.3.tgz#3551c4958c4da36897bda2a16812ef1399c8d6b0"
integrity sha512-5otztIIcJfPc2qGTN8cVtOJEjNJZ0jwa46INMagrYfk0EvqtRuEHLsEe0LrFS0/q+ZRKT0+kXK7P2T1AN5lWRA==
+marked@^2.0.7:
+ version "2.0.7"
+ resolved "https://registry.yarnpkg.com/marked/-/marked-2.0.7.tgz#bc5b857a09071b48ce82a1f7304913a993d4b7d1"
+ integrity sha512-BJXxkuIfJchcXOJWTT2DOL+yFWifFv2yGYOUzvXg8Qz610QKw+sHCvTMYwA+qWGhlA2uivBezChZ/pBy1tWdkQ==
+
matcher@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca"
@@ -9853,16 +9838,11 @@ moment-timezone@^0.5.33:
dependencies:
moment ">= 2.9.0"
-"moment@>= 2.9.0", moment@^2.14.1, moment@^2.22.1:
+"moment@>= 2.9.0", moment@^2.10.2, moment@^2.14.1, moment@^2.22.1, moment@^2.29.1:
version "2.29.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
-moment@^2.10.2, moment@^2.26.0:
- version "2.26.0"
- resolved "https://registry.yarnpkg.com/moment/-/moment-2.26.0.tgz#5e1f82c6bafca6e83e808b30c8705eed0dcbd39a"
- integrity sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw==
-
moo-color@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/moo-color/-/moo-color-1.0.2.tgz#837c40758d2d58763825d1359a84e330531eca64"
@@ -10040,7 +10020,7 @@ node-forge@^0.7.5:
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.6.tgz#fdf3b418aee1f94f0ef642cd63486c77ca9724ac"
integrity sha512-sol30LUpz1jQFBjOKwbjxijiE3b6pjd74YwfD0fJOKPjF+fONKb2Yg8rYgS6+bK6VDl+/wfr4IYpC7jDzLUIfw==
-node-forge@^0.8.2, node-forge@^0.8.5:
+node-forge@^0.8.2:
version "0.8.5"
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.8.5.tgz#57906f07614dc72762c84cef442f427c0e1b86ee"
integrity sha512-vFMQIWt+J/7FLNyKouZ9TazT74PRV3wgv9UT4cRjC8BffxFbKXkgIWR42URCPSnHm/QDz6BOlb2Q0U4+VQT67Q==
@@ -10085,22 +10065,6 @@ node-int64@^0.4.0:
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=
-node-jose@^1.1.0:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/node-jose/-/node-jose-1.1.4.tgz#af3f44a392e586d26b123b0e12dc09bef1e9863b"
- integrity sha512-L31IFwL3pWWcMHxxidCY51ezqrDXMkvlT/5pLTfNw5sXmmOLJuN6ug7txzF/iuZN55cRpyOmoJrotwBQIoo5Lw==
- dependencies:
- base64url "^3.0.1"
- browserify-zlib "^0.2.0"
- buffer "^5.5.0"
- es6-promise "^4.2.8"
- lodash "^4.17.15"
- long "^4.0.0"
- node-forge "^0.8.5"
- process "^0.11.10"
- react-zlib-js "^1.0.4"
- uuid "^3.3.3"
-
node-libs-browser@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425"
@@ -10130,10 +10094,13 @@ node-libs-browser@^2.2.1:
util "^0.11.0"
vm-browserify "^1.0.1"
-node-loader@^0.6.0:
- version "0.6.0"
- resolved "https://registry.yarnpkg.com/node-loader/-/node-loader-0.6.0.tgz#c797ef51095ed5859902b157f6384f6361e05ae8"
- integrity sha1-x5fvUQle1YWZArFX9jhPY2HgWug=
+node-loader@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/node-loader/-/node-loader-1.0.3.tgz#ed8f4a8a75928575a5a2dab0e73c9f6386b2353e"
+ integrity sha512-8c9ef5q24F0AjrPxUjdX7qdTlsU1zZCPeqYvSBCH1TJko3QW4qu1uA1C9KbOPdaRQwREDdbSYZgltBAlbV7l5g==
+ dependencies:
+ loader-utils "^2.0.0"
+ schema-utils "^3.0.0"
node-modules-regexp@^1.0.0:
version "1.0.0"
@@ -10257,15 +10224,6 @@ normalize-path@^3.0.0, normalize-path@~3.0.0:
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
-normalize-url@2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6"
- integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==
- dependencies:
- prepend-http "^2.0.0"
- query-string "^5.0.1"
- sort-keys "^2.0.0"
-
normalize-url@^4.1.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129"
@@ -10571,11 +10529,6 @@ object-copy@^0.1.0:
define-property "^0.2.5"
kind-of "^3.0.3"
-object-hash@^1.3.1:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df"
- integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==
-
object-hash@^2.0.1:
version "2.0.3"
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.0.3.tgz#d12db044e03cd2ca3d77c0570d87225b02e1e6ea"
@@ -10685,16 +10638,16 @@ obuf@^1.0.0, obuf@^1.1.2:
resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e"
integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==
-oidc-token-hash@^3.0.1:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/oidc-token-hash/-/oidc-token-hash-3.0.2.tgz#5bd4716cc48ad433f4e4e99276811019b165697e"
- integrity sha512-dTzp80/y/da+um+i+sOucNqiPpwRL7M/xPwj7pH1TFA2/bqQ+OK2sJahSXbemEoLtPkHcFLyhLhLWZa9yW5+RA==
-
oidc-token-hash@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/oidc-token-hash/-/oidc-token-hash-5.0.0.tgz#acdfb1f4310f58e64d5d74a4e8671a426986e888"
integrity sha512-8Yr4CZSv+Tn8ZkN3iN2i2w2G92mUKClp4z7EGUfdsERiYSbj7P4i/NHm72ft+aUdsiFx9UdIPSTwbyzQ6C4URg==
+oidc-token-hash@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/oidc-token-hash/-/oidc-token-hash-5.0.1.tgz#ae6beec3ec20f0fd885e5400d175191d6e2f10c6"
+ integrity sha512-EvoOtz6FIEBzE+9q253HsLCVRiK/0doEJ2HCvvqMQb3dHZrP3WlJKYtJ55CRTw4jmYomzH4wkPuCj/I3ZvpKxQ==
+
on-finished@~2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
@@ -10733,6 +10686,13 @@ onetime@^5.1.0:
dependencies:
mimic-fn "^2.1.0"
+onigasm@^2.2.5:
+ version "2.2.5"
+ resolved "https://registry.yarnpkg.com/onigasm/-/onigasm-2.2.5.tgz#cc4d2a79a0fa0b64caec1f4c7ea367585a676892"
+ integrity sha512-F+th54mPc0l1lp1ZcFMyL/jTs2Tlq4SqIHKIXGZOR/VkHkF9A7Fr5rRr5+ZG/lWeRsyrClLYRq7s/yFQ/XhWCA==
+ dependencies:
+ lru-cache "^5.1.1"
+
open@^7.3.1:
version "7.3.1"
resolved "https://registry.yarnpkg.com/open/-/open-7.3.1.tgz#111119cb919ca1acd988f49685c4fdd0f4755356"
@@ -10746,20 +10706,6 @@ opener@^1.5.2:
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598"
integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==
-openid-client@2.5.0:
- version "2.5.0"
- resolved "https://registry.yarnpkg.com/openid-client/-/openid-client-2.5.0.tgz#7d4cf552b30dbad26917d7e2722422eda057ea93"
- integrity sha512-t3hFD7xEoW1U25RyBcRFaL19fGGs6hNVTysq9pgmiltH0IVUPzH/bQV9w24pM5Q7MunnGv2/5XjIru6BQcWdxg==
- dependencies:
- base64url "^3.0.0"
- got "^8.3.2"
- lodash "^4.17.11"
- lru-cache "^5.1.1"
- node-jose "^1.1.0"
- object-hash "^1.3.1"
- oidc-token-hash "^3.0.1"
- p-any "^1.1.0"
-
openid-client@^3.15.2:
version "3.15.2"
resolved "https://registry.yarnpkg.com/openid-client/-/openid-client-3.15.2.tgz#d48a6d7991d5d6117f4598bb1d19399262164128"
@@ -10776,6 +10722,19 @@ openid-client@^3.15.2:
oidc-token-hash "^5.0.0"
p-any "^3.0.0"
+openid-client@^4.1.1:
+ version "4.7.4"
+ resolved "https://registry.yarnpkg.com/openid-client/-/openid-client-4.7.4.tgz#bd9978456d53d38adb89856b14a8fbd094f7732e"
+ integrity sha512-n+RURXYuR0bBZo9i0pn+CXZSyg5JYQ1nbwEwPQvLE7EcJt/vMZ2iIMjLehl5DvCN53XUoPVZs9KAE5r6d9fxsw==
+ dependencies:
+ aggregate-error "^3.1.0"
+ got "^11.8.0"
+ jose "^2.0.5"
+ lru-cache "^6.0.0"
+ make-error "^1.3.6"
+ object-hash "^2.0.1"
+ oidc-token-hash "^5.0.1"
+
opn@^5.5.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc"
@@ -10863,13 +10822,6 @@ osenv@0, osenv@^0.1.4, osenv@^0.1.5:
os-homedir "^1.0.0"
os-tmpdir "^1.0.0"
-p-any@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/p-any/-/p-any-1.1.0.tgz#1d03835c7eed1e34b8e539c47b7b60d0d015d4e1"
- integrity sha512-Ef0tVa4CZ5pTAmKn+Cg3w8ABBXh+hHO1aV8281dKOoUHfX+3tjG2EaFcC+aZyagg9b4EYGsHEjz21DnEE8Og2g==
- dependencies:
- p-some "^2.0.0"
-
p-any@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/p-any/-/p-any-3.0.0.tgz#79847aeed70b5d3a10ea625296c0c3d2e90a87b9"
@@ -10878,11 +10830,6 @@ p-any@^3.0.0:
p-cancelable "^2.0.0"
p-some "^5.0.0"
-p-cancelable@^0.4.0:
- version "0.4.1"
- resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0"
- integrity sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==
-
p-cancelable@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc"
@@ -10908,11 +10855,6 @@ p-finally@^1.0.0:
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
-p-is-promise@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e"
- integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=
-
p-is-promise@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e"
@@ -10972,13 +10914,6 @@ p-retry@^3.0.1:
dependencies:
retry "^0.12.0"
-p-some@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/p-some/-/p-some-2.0.1.tgz#65d87c8b154edbcf5221d167778b6d2e150f6f06"
- integrity sha1-Zdh8ixVO289SIdFnd4ttLhUPbwY=
- dependencies:
- aggregate-error "^1.0.0"
-
p-some@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/p-some/-/p-some-5.0.0.tgz#8b730c74b4fe5169d7264a240ad010b6ebc686a4"
@@ -10987,13 +10922,6 @@ p-some@^5.0.0:
aggregate-error "^3.0.0"
p-cancelable "^2.0.0"
-p-timeout@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038"
- integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==
- dependencies:
- p-finally "^1.0.0"
-
p-try@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
@@ -11857,15 +11785,6 @@ qs@~6.5.2:
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
-query-string@^5.0.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb"
- integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==
- dependencies:
- decode-uri-component "^0.2.0"
- object-assign "^4.1.0"
- strict-uri-encode "^1.0.0"
-
query-string@^6.8.2:
version "6.14.1"
resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a"
@@ -12088,11 +12007,6 @@ react-window@^1.8.5:
"@babel/runtime" "^7.0.0"
memoize-one ">=3.1.1 <6"
-react-zlib-js@^1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/react-zlib-js/-/react-zlib-js-1.0.4.tgz#dd2b9fbf56d5ab224fa7a99affbbedeba9aa3dc7"
- integrity sha512-ynXD9DFxpE7vtGoa3ZwBtPmZrkZYw2plzHGbanUjBOSN4RtuXdektSfABykHtTiWEHMh7WdYj45LHtp228ZF1A==
-
react@^16.8.0:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"
@@ -12504,6 +12418,11 @@ reserved-words@^0.1.2:
resolved "https://registry.yarnpkg.com/reserved-words/-/reserved-words-0.1.2.tgz#00a0940f98cd501aeaaac316411d9adc52b31ab1"
integrity sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE=
+resolve-alpn@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.1.2.tgz#30b60cfbb0c0b8dc897940fe13fe255afcdd4d28"
+ integrity sha512-8OyfzhAtA32LVUsJSke3auIyINcwdh5l3cvYKdKO0nvsYSKuiLfTM5i78PJswFPT8y6cPW+L1v6/hE95chcpDA==
+
resolve-cwd@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
@@ -12574,13 +12493,20 @@ resolve@^1.20.0:
is-core-module "^2.2.0"
path-parse "^1.0.6"
-responselike@1.0.2, responselike@^1.0.2:
+responselike@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=
dependencies:
lowercase-keys "^1.0.0"
+responselike@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723"
+ integrity sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==
+ dependencies:
+ lowercase-keys "^2.0.0"
+
restore-cursor@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
@@ -13052,7 +12978,7 @@ shell-env@^3.0.1:
execa "^1.0.0"
strip-ansi "^5.2.0"
-shelljs@^0.8.2, shelljs@^0.8.3:
+shelljs@^0.8.2:
version "0.8.4"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2"
integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==
@@ -13066,6 +12992,14 @@ shellwords@^0.1.1:
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
+shiki@^0.9.3:
+ version "0.9.3"
+ resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.9.3.tgz#7bf7bcf3ed50ca525ec89cc09254abce4264d5ca"
+ integrity sha512-NEjg1mVbAUrzRv2eIcUt3TG7X9svX7l3n3F5/3OdFq+/BxUdmBOeKGiH4icZJBLHy354Shnj6sfBTemea2e7XA==
+ dependencies:
+ onigasm "^2.2.5"
+ vscode-textmate "^5.2.0"
+
side-channel@^1.0.2, side-channel@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.3.tgz#cdc46b057550bbab63706210838df5d4c19519c3"
@@ -13217,13 +13151,6 @@ socks@~2.3.2:
ip "1.1.5"
smart-buffer "^4.1.0"
-sort-keys@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128"
- integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=
- dependencies:
- is-plain-obj "^1.0.0"
-
sorted-object@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/sorted-object/-/sorted-object-2.0.1.tgz#7d631f4bd3a798a24af1dffcfbfe83337a5df5fc"
@@ -13475,6 +13402,11 @@ stream-browserify@^2.0.1:
inherits "~2.0.1"
readable-stream "^2.0.2"
+stream-buffers@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-3.0.2.tgz#5249005a8d5c2d00b3a32e6e0a6ea209dc4f3521"
+ integrity sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==
+
stream-each@^1.1.0:
version "1.2.3"
resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae"
@@ -13507,11 +13439,6 @@ stream-shift@^1.0.0:
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==
-strict-uri-encode@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
- integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=
-
strict-uri-encode@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546"
@@ -13922,10 +13849,10 @@ tar@^4.4.10, tar@^4.4.12, tar@^4.4.13:
safe-buffer "^5.1.2"
yallist "^3.0.3"
-tar@^6.0.5:
- version "6.0.5"
- resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.5.tgz#bde815086e10b39f1dcd298e89d596e1535e200f"
- integrity sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==
+tar@^6.0.2, tar@^6.0.5:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83"
+ integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==
dependencies:
chownr "^2.0.0"
fs-minipass "^2.0.0"
@@ -14056,7 +13983,7 @@ thunky@^1.0.2:
resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d"
integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==
-timed-out@^4.0.0, timed-out@^4.0.1:
+timed-out@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=
@@ -14083,6 +14010,13 @@ tiny-warning@^1.0.0, tiny-warning@^1.0.2, tiny-warning@^1.0.3:
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
+tmp-promise@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-3.0.2.tgz#6e933782abff8b00c3119d63589ca1fb9caaa62a"
+ integrity sha512-OyCLAKU1HzBjL6Ev3gxUeraJNlbNingmi8IrHHEsYH8LTmEuhvYfqvhn2F/je+mjf4N58UmZ96OMEy1JanSCpA==
+ dependencies:
+ tmp "^0.2.0"
+
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
@@ -14090,6 +14024,13 @@ tmp@^0.0.33:
dependencies:
os-tmpdir "~1.0.2"
+tmp@^0.2.0:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14"
+ integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==
+ dependencies:
+ rimraf "^3.0.0"
+
tmpl@1.0.x:
version "1.0.4"
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"
@@ -14273,12 +14214,7 @@ tsconfig-paths@^3.9.0:
minimist "^1.2.0"
strip-bom "^3.0.0"
-tslib@^1.10.0, tslib@^1.9.0, tslib@^1.9.3:
- version "1.13.0"
- resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043"
- integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==
-
-tslib@^1.8.1:
+tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
@@ -14391,39 +14327,32 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
-typedoc-default-themes@0.8.0-0:
- version "0.8.0-0"
- resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.8.0-0.tgz#80b7080837b2c9eba36c2fe06601ebe01973a0cd"
- integrity sha512-blFWppm5aKnaPOa1tpGO9MLu+njxq7P3rtkXK4QxJBNszA+Jg7x0b+Qx0liXU1acErur6r/iZdrwxp5DUFdSXw==
- dependencies:
- backbone "^1.4.0"
- jquery "^3.4.1"
- lunr "^2.3.8"
- underscore "^1.9.1"
+typedoc-default-themes@^0.12.10:
+ version "0.12.10"
+ resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.12.10.tgz#614c4222fe642657f37693ea62cad4dafeddf843"
+ integrity sha512-fIS001cAYHkyQPidWXmHuhs8usjP5XVJjWB8oZGqkTowZaz3v7g3KDZeeqE82FBrmkAnIBOY3jgy7lnPnqATbA==
-typedoc-plugin-markdown@^2.4.0:
- version "2.4.2"
- resolved "https://registry.yarnpkg.com/typedoc-plugin-markdown/-/typedoc-plugin-markdown-2.4.2.tgz#2d83fe4f279643436ebc44ca2f937855b0fd9f12"
- integrity sha512-BBH+9/Uq5XbsqfzCDl8Jq4iaLXRMXRuAHZRFarAZX7df8+F3vUjDx/WHWoWqbZ/XUFzduLC2Iuy2qwsJX8SQ7A==
+typedoc-plugin-markdown@^3.9.0:
+ version "3.9.0"
+ resolved "https://registry.yarnpkg.com/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.9.0.tgz#d9c0390b8ddeeda56fdbf01264521ef04b3c19c7"
+ integrity sha512-s445YeUe8bH7me15T+hsHZgNmAvvF7QIpX02vFgseLGtghAwmtdZYVOqPneWoKqRv/JNpPSuyZb3CeblML9jOg==
dependencies:
- fs-extra "^9.0.1"
- handlebars "^4.7.6"
+ handlebars "^4.7.7"
-typedoc@0.17.0-3:
- version "0.17.0-3"
- resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.17.0-3.tgz#91996e77427ff3a208ab76595a927ee11b75e9e8"
- integrity sha512-DO2djkR4NHgzAWfNbJb2eQKsFMs+gOuYBXlQ8dOSCjkAK5DRI7ZywDufBGPUw7Ue9Qwi2Cw1DxLd3reDq8wFuQ==
+typedoc@0.21.0-beta.2:
+ version "0.21.0-beta.2"
+ resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.21.0-beta.2.tgz#e26927bf9c55c691f5401cd1608d99e4e7852ada"
+ integrity sha512-oCjdueR4glcSHT6ynR2q5HTpBkBM1ihf3/Wfpl0qriDJutrSg4idZovN+1jx66s+p9QmJE7yzDCXPrZ2GW/Xbw==
dependencies:
- "@types/minimatch" "3.0.3"
- fs-extra "^8.1.0"
- handlebars "^4.7.2"
- highlight.js "^9.18.0"
- lodash "^4.17.15"
- marked "^0.8.0"
+ glob "^7.1.6"
+ handlebars "^4.7.7"
+ lodash "^4.17.21"
+ lunr "^2.3.9"
+ marked "^2.0.7"
minimatch "^3.0.0"
progress "^2.0.3"
- shelljs "^0.8.3"
- typedoc-default-themes "0.8.0-0"
+ shiki "^0.9.3"
+ typedoc-default-themes "^0.12.10"
typeface-roboto@^0.0.75:
version "0.0.75"
@@ -14488,11 +14417,6 @@ underscore@1.7.0:
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209"
integrity sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=
-underscore@>=1.8.3:
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.11.0.tgz#dd7c23a195db34267186044649870ff1bab5929e"
- integrity sha512-xY96SsN3NA461qIRKZ/+qox37YXPtSBswMGfiNptr+wrt6ds4HaMw23TP612fEyGekRE6LNRiLYr/aqbHXNedw==
-
underscore@^1.9.1:
version "1.10.2"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.10.2.tgz#73d6aa3668f3188e4adb0f1943bd12cfd7efaaaf"
@@ -14688,11 +14612,6 @@ url-parse@^1.4.3, url-parse@^1.5.1:
querystringify "^2.1.1"
requires-port "^1.0.0"
-url-to-options@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9"
- integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=
-
url@^0.11.0, url@~0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
@@ -14850,6 +14769,11 @@ vm-browserify@^1.0.1:
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
+vscode-textmate@^5.2.0:
+ version "5.4.0"
+ resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.4.0.tgz#4b25ffc1f14ac3a90faf9a388c67a01d24257cd7"
+ integrity sha512-c0Q4zYZkcLizeYJ3hNyaVUM2AA8KDhNCA3JvXY8CeZSJuBdAy3bAvSbv46RClC4P3dSO9BdwhnKEx2zOo6vP/w==
+
w3c-hr-time@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"
@@ -15289,14 +15213,14 @@ write@1.0.3:
dependencies:
mkdirp "^0.5.1"
-ws@^6.1.0, ws@^6.2.1:
+ws@^6.2.1:
version "6.2.1"
resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb"
integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==
dependencies:
async-limiter "~1.0.0"
-ws@^7.2.3, ws@^7.4.6:
+ws@^7.2.3, ws@^7.3.1, ws@^7.4.6:
version "7.4.6"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==