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

Ban circular dependencies (#3547)

This commit is contained in:
Sebastian Malton 2022-01-05 11:35:44 -05:00 committed by GitHub
parent b227a86711
commit 4f75acf2b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 209 additions and 59 deletions

View File

@ -108,6 +108,8 @@ module.exports = {
parser: "@typescript-eslint/parser", parser: "@typescript-eslint/parser",
extends: [ extends: [
"plugin:@typescript-eslint/recommended", "plugin:@typescript-eslint/recommended",
"plugin:import/recommended",
"plugin:import/typescript",
], ],
plugins: [ plugins: [
"header", "header",
@ -193,6 +195,8 @@ module.exports = {
extends: [ extends: [
"plugin:@typescript-eslint/recommended", "plugin:@typescript-eslint/recommended",
"plugin:react/recommended", "plugin:react/recommended",
"plugin:import/recommended",
"plugin:import/typescript",
], ],
parserOptions: { parserOptions: {
ecmaVersion: 2018, ecmaVersion: 2018,
@ -202,6 +206,7 @@ module.exports = {
rules: { rules: {
"no-irregular-whitespace": "error", "no-irregular-whitespace": "error",
"header/header": [2, "./license-header"], "header/header": [2, "./license-header"],
"react/prop-types": "off",
"no-invalid-this": "off", "no-invalid-this": "off",
"@typescript-eslint/no-invalid-this": ["error"], "@typescript-eslint/no-invalid-this": ["error"],
"@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/explicit-function-return-type": "off",
@ -246,7 +251,6 @@ module.exports = {
"objectsInObjects": false, "objectsInObjects": false,
"arraysInObjects": true, "arraysInObjects": true,
}], }],
"react/prop-types": "off",
"semi": "off", "semi": "off",
"@typescript-eslint/semi": ["error"], "@typescript-eslint/semi": ["error"],
"linebreak-style": ["error", "unix"], "linebreak-style": ["error", "unix"],

36
extensions/.eslintrc.js Normal file
View File

@ -0,0 +1,36 @@
/**
* 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.
*/
module.exports = {
"overrides": [
{
files: [
"**/*.ts",
"**/*.tsx",
],
rules: {
"import/no-unresolved": ["error", {
ignore: ["@k8slens/extensions"],
}],
},
},
],
};

View File

@ -62,8 +62,7 @@
}, },
"moduleNameMapper": { "moduleNameMapper": {
"\\.(css|scss)$": "<rootDir>/__mocks__/styleMock.ts", "\\.(css|scss)$": "<rootDir>/__mocks__/styleMock.ts",
"\\.(svg)$": "<rootDir>/__mocks__/imageMock.ts", "\\.(svg)$": "<rootDir>/__mocks__/imageMock.ts"
"src/(.*)": "<rootDir>/__mocks__/windowMock.ts"
}, },
"modulePathIgnorePatterns": [ "modulePathIgnorePatterns": [
"<rootDir>/dist", "<rootDir>/dist",
@ -200,6 +199,7 @@
"@ogre-tools/injectable-react": "2.0.0", "@ogre-tools/injectable-react": "2.0.0",
"@sentry/electron": "^2.5.4", "@sentry/electron": "^2.5.4",
"@sentry/integrations": "^6.15.0", "@sentry/integrations": "^6.15.0",
"@types/circular-dependency-plugin": "5.0.4",
"abort-controller": "^3.0.0", "abort-controller": "^3.0.0",
"auto-bind": "^4.0.0", "auto-bind": "^4.0.0",
"autobind-decorator": "^2.4.0", "autobind-decorator": "^2.4.0",
@ -341,6 +341,7 @@
"esbuild-loader": "^2.16.0", "esbuild-loader": "^2.16.0",
"eslint": "^7.32.0", "eslint": "^7.32.0",
"eslint-plugin-header": "^3.1.1", "eslint-plugin-header": "^3.1.1",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-react": "^7.27.1", "eslint-plugin-react": "^7.27.1",
"eslint-plugin-react-hooks": "^4.3.0", "eslint-plugin-react-hooks": "^4.3.0",
"eslint-plugin-unused-imports": "^1.1.5", "eslint-plugin-unused-imports": "^1.1.5",

View File

@ -42,9 +42,9 @@ import { Console } from "console";
import { SemVer } from "semver"; import { SemVer } from "semver";
import electron from "electron"; import electron from "electron";
import { stdout, stderr } from "process"; import { stdout, stderr } from "process";
import { ThemeStore } from "../../renderer/theme.store";
import type { ClusterStoreModel } from "../cluster-store"; import type { ClusterStoreModel } from "../cluster-store";
import { AppPaths } from "../app-paths"; import { AppPaths } from "../app-paths";
import { defaultTheme } from "../vars";
console = new Console(stdout, stderr); console = new Console(stdout, stderr);
AppPaths.init(); AppPaths.init();
@ -75,7 +75,7 @@ describe("user store tests", () => {
us.httpsProxy = "abcd://defg"; us.httpsProxy = "abcd://defg";
expect(us.httpsProxy).toBe("abcd://defg"); expect(us.httpsProxy).toBe("abcd://defg");
expect(us.colorTheme).toBe(ThemeStore.defaultTheme); expect(us.colorTheme).toBe(defaultTheme);
us.colorTheme = "light"; us.colorTheme = "light";
expect(us.colorTheme).toBe("light"); expect(us.colorTheme).toBe("light");
@ -86,7 +86,7 @@ describe("user store tests", () => {
us.colorTheme = "some other theme"; us.colorTheme = "some other theme";
us.resetTheme(); us.resetTheme();
expect(us.colorTheme).toBe(ThemeStore.defaultTheme); expect(us.colorTheme).toBe(defaultTheme);
}); });
it("correctly calculates if the last seen version is an old release", () => { it("correctly calculates if the last seen version is an old release", () => {

View File

@ -23,7 +23,8 @@ import { app, ipcMain, ipcRenderer } from "electron";
import { observable, when } from "mobx"; import { observable, when } from "mobx";
import path from "path"; import path from "path";
import logger from "./logger"; import logger from "./logger";
import { fromEntries, toJS } from "./utils"; import { fromEntries } from "./utils/objects";
import { toJS } from "./utils/toJS";
import { isWindows } from "./vars"; import { isWindows } from "./vars";
export type PathName = Parameters<typeof app["getPath"]>[0]; export type PathName = Parameters<typeof app["getPath"]>[0];

View File

@ -20,11 +20,10 @@
*/ */
import { catalogCategoryRegistry } from "../catalog/catalog-category-registry"; import { catalogCategoryRegistry } from "../catalog/catalog-category-registry";
import { CatalogEntity, CatalogEntityActionContext, CatalogEntityContextMenuContext, CatalogEntityMetadata, CatalogEntityStatus } from "../catalog"; import { CatalogEntity, CatalogEntityActionContext, CatalogEntityContextMenuContext, CatalogEntityMetadata, CatalogEntityStatus, CatalogCategory, CatalogCategorySpec } from "../catalog";
import { clusterActivateHandler, clusterDisconnectHandler } from "../cluster-ipc"; import { clusterActivateHandler, clusterDisconnectHandler } from "../cluster-ipc";
import { ClusterStore } from "../cluster-store"; import { ClusterStore } from "../cluster-store";
import { broadcastMessage, requestMain } from "../ipc"; import { broadcastMessage, requestMain } from "../ipc";
import { CatalogCategory, CatalogCategorySpec } from "../catalog";
import { app } from "electron"; import { app } from "electron";
import type { CatalogEntitySpec } from "../catalog/catalog-entity"; import type { CatalogEntitySpec } from "../catalog/catalog-entity";
import { IpcRendererNavigationEvents } from "../../renderer/navigation/events"; import { IpcRendererNavigationEvents } from "../../renderer/navigation/events";

View File

@ -30,7 +30,15 @@ import { ClusterFrameInfo, clusterFrameMap } from "../cluster-frames";
import type { Disposer } from "../utils"; import type { Disposer } from "../utils";
import type remote from "@electron/remote"; import type remote from "@electron/remote";
const electronRemote = ipcMain ? null : require("@electron/remote"); const electronRemote = (() => {
if (ipcRenderer) {
try {
return require("@electron/remote");
} catch {}
}
return null;
})();
const subFramesChannel = "ipc:get-sub-frames"; const subFramesChannel = "ipc:get-sub-frames";

View File

@ -34,6 +34,9 @@ import type { IKubeWatchEvent } from "./kube-watch-api";
import { KubeJsonApi, KubeJsonApiData } from "./kube-json-api"; import { KubeJsonApi, KubeJsonApiData } from "./kube-json-api";
import { noop } from "../utils"; import { noop } from "../utils";
import type { RequestInit } from "node-fetch"; import type { RequestInit } from "node-fetch";
// BUG: https://github.com/mysticatea/abort-controller/pull/22
// eslint-disable-next-line import/no-named-as-default
import AbortController from "abort-controller"; import AbortController from "abort-controller";
import { Agent, AgentOptions } from "https"; import { Agent, AgentOptions } from "https";
import type { Patch } from "rfc6902"; import type { Patch } from "rfc6902";

View File

@ -30,6 +30,9 @@ import { ensureObjectSelfLink, IKubeApiQueryParams, KubeApi } from "./kube-api";
import { parseKubeApi } from "./kube-api-parse"; import { parseKubeApi } from "./kube-api-parse";
import type { KubeJsonApiData } from "./kube-json-api"; import type { KubeJsonApiData } from "./kube-json-api";
import type { RequestInit } from "node-fetch"; import type { RequestInit } from "node-fetch";
// BUG: https://github.com/mysticatea/abort-controller/pull/22
// eslint-disable-next-line import/no-named-as-default
import AbortController from "abort-controller"; import AbortController from "abort-controller";
import type { Patch } from "rfc6902"; import type { Patch } from "rfc6902";

View File

@ -22,11 +22,11 @@
import moment from "moment-timezone"; import moment from "moment-timezone";
import path from "path"; import path from "path";
import os from "os"; import os from "os";
import { ThemeStore } from "../../renderer/theme.store";
import { getAppVersion, ObservableToggleSet } from "../utils"; import { getAppVersion, ObservableToggleSet } from "../utils";
import type { editor } from "monaco-editor"; import type { editor } from "monaco-editor";
import merge from "lodash/merge"; import merge from "lodash/merge";
import { SemVer } from "semver"; import { SemVer } from "semver";
import { defaultTheme } from "../vars";
export interface KubeconfigSyncEntry extends KubeconfigSyncValue { export interface KubeconfigSyncEntry extends KubeconfigSyncValue {
filePath: string; filePath: string;
@ -72,10 +72,10 @@ const shell: PreferenceDescription<string | undefined> = {
const colorTheme: PreferenceDescription<string> = { const colorTheme: PreferenceDescription<string> = {
fromStore(val) { fromStore(val) {
return val || ThemeStore.defaultTheme; return val || defaultTheme;
}, },
toStore(val) { toStore(val) {
if (!val || val === ThemeStore.defaultTheme) { if (!val || val === defaultTheme) {
return undefined; return undefined;
} }

View File

@ -19,7 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
import { array } from "../utils"; import * as array from "../utils/array";
/** /**
* A strict N-tuple of type T * A strict N-tuple of type T

View File

@ -41,6 +41,7 @@ export const isIntegrationTesting = process.argv.includes(integrationTestingArg)
export const productName = packageInfo.productName; export const productName = packageInfo.productName;
export const appName = `${packageInfo.productName}${isDevelopment ? "Dev" : ""}`; export const appName = `${packageInfo.productName}${isDevelopment ? "Dev" : ""}`;
export const publicPath = "/build/" as string; export const publicPath = "/build/" as string;
export const defaultTheme = "lens-dark" as string;
// Webpack build paths // Webpack build paths
export const contextDir = process.cwd(); export const contextDir = process.cwd();

View File

@ -18,8 +18,7 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * 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. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
import { lifecycleEnum } from "@ogre-tools/injectable";
import { ExtensionLoader } from "./extension-loader"; import { ExtensionLoader } from "./extension-loader";
const extensionLoaderInjectable = getInjectable({ const extensionLoaderInjectable = getInjectable({

View File

@ -22,7 +22,7 @@
// Base class for extensions-api registries // Base class for extensions-api registries
import { action, observable, makeObservable } from "mobx"; import { action, observable, makeObservable } from "mobx";
import { Singleton } from "../../common/utils"; import { Singleton } from "../../common/utils";
import { LensExtension } from "../lens-extension"; import type { LensExtension } from "../lens-extension";
export class BaseRegistry<T, I = T> extends Singleton { export class BaseRegistry<T, I = T> extends Singleton {
private items = observable.map<T, I>([], { deep: false }); private items = observable.map<T, I>([], { deep: false });

View File

@ -25,10 +25,9 @@ import { isLinux, isMac, isPublishConfigured, isTestEnv } from "../common/vars";
import { delay } from "../common/utils"; import { delay } from "../common/utils";
import { areArgsUpdateAvailableToBackchannel, AutoUpdateChecking, AutoUpdateLogPrefix, AutoUpdateNoUpdateAvailable, broadcastMessage, onceCorrect, UpdateAvailableChannel, UpdateAvailableToBackchannel } from "../common/ipc"; import { areArgsUpdateAvailableToBackchannel, AutoUpdateChecking, AutoUpdateLogPrefix, AutoUpdateNoUpdateAvailable, broadcastMessage, onceCorrect, UpdateAvailableChannel, UpdateAvailableToBackchannel } from "../common/ipc";
import { once } from "lodash"; import { once } from "lodash";
import { ipcMain } from "electron"; import { ipcMain, autoUpdater as electronAutoUpdater } from "electron";
import { nextUpdateChannel } from "./utils/update-channel"; import { nextUpdateChannel } from "./utils/update-channel";
import { UserStore } from "../common/user-store"; import { UserStore } from "../common/user-store";
import { autoUpdater as electronAutoUpdater } from "electron";
let installVersion: null | string = null; let installVersion: null | string = null;

View File

@ -19,7 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
import * as tempy from "tempy"; import tempy from "tempy";
import fse from "fs-extra"; import fse from "fs-extra";
import * as yaml from "js-yaml"; import * as yaml from "js-yaml";
import { promiseExecFile } from "../../common/utils/promise-exec"; import { promiseExecFile } from "../../common/utils/promise-exec";

View File

@ -25,7 +25,7 @@ import { exec } from "child_process";
import fs from "fs-extra"; import fs from "fs-extra";
import * as yaml from "js-yaml"; import * as yaml from "js-yaml";
import path from "path"; import path from "path";
import * as tempy from "tempy"; import tempy from "tempy";
import logger from "./logger"; import logger from "./logger";
import { appEventBus } from "../common/event-bus"; import { appEventBus } from "../common/event-bus";
import { cloneJsonObject } from "../common/utils"; import { cloneJsonObject } from "../common/utils";

View File

@ -20,7 +20,6 @@
*/ */
import { CatalogEntityRegistry } from "../catalog-entity-registry"; import { CatalogEntityRegistry } from "../catalog-entity-registry";
import "../../../common/catalog-entities";
import { catalogCategoryRegistry } from "../../../common/catalog/catalog-category-registry"; import { catalogCategoryRegistry } from "../../../common/catalog/catalog-category-registry";
import { CatalogCategory, CatalogEntityData, CatalogEntityKindData } from "../catalog-entity"; import { CatalogCategory, CatalogEntityData, CatalogEntityKindData } from "../catalog-entity";
import { KubernetesCluster, WebLink } from "../../../common/catalog-entities"; import { KubernetesCluster, WebLink } from "../../../common/catalog-entities";

View File

@ -28,14 +28,21 @@ import { ClusterStore } from "../../common/cluster-store";
import { Disposer, iter } from "../utils"; import { Disposer, iter } from "../utils";
import { once } from "lodash"; import { once } from "lodash";
import logger from "../../common/logger"; import logger from "../../common/logger";
import { catalogEntityRunContext } from "./catalog-entity";
import { CatalogRunEvent } from "../../common/catalog/catalog-run-event"; import { CatalogRunEvent } from "../../common/catalog/catalog-run-event";
import { ipcRenderer } from "electron"; import { ipcRenderer } from "electron";
import { CatalogIpcEvents } from "../../common/ipc/catalog"; import { CatalogIpcEvents } from "../../common/ipc/catalog";
import { navigate } from "../navigation";
export type EntityFilter = (entity: CatalogEntity) => any; export type EntityFilter = (entity: CatalogEntity) => any;
export type CatalogEntityOnBeforeRun = (event: CatalogRunEvent) => void | Promise<void>; export type CatalogEntityOnBeforeRun = (event: CatalogRunEvent) => void | Promise<void>;
export const catalogEntityRunContext = {
navigate: (url: string) => navigate(url),
setCommandPaletteContext: (entity?: CatalogEntity) => {
catalogEntityRegistry.activeEntity = entity;
},
};
export class CatalogEntityRegistry { export class CatalogEntityRegistry {
@observable protected activeEntityId: string | undefined = undefined; @observable protected activeEntityId: string | undefined = undefined;
protected _entities = observable.map<string, CatalogEntity>([], { deep: true }); protected _entities = observable.map<string, CatalogEntity>([], { deep: true });

View File

@ -19,10 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
import { navigate } from "../navigation"; export { catalogEntityRunContext } from "./catalog-entity-registry";
import type { CatalogEntity } from "../../common/catalog";
import { catalogEntityRegistry } from "./catalog-entity-registry";
export { CatalogCategory, CatalogEntity } from "../../common/catalog"; export { CatalogCategory, CatalogEntity } from "../../common/catalog";
export type { export type {
CatalogEntityData, CatalogEntityData,
@ -33,10 +30,3 @@ export type {
CatalogEntityContextMenu, CatalogEntityContextMenu,
CatalogEntityContextMenuContext, CatalogEntityContextMenuContext,
} from "../../common/catalog"; } from "../../common/catalog";
export const catalogEntityRunContext = {
navigate: (url: string) => navigate(url),
setCommandPaletteContext: (entity?: CatalogEntity) => {
catalogEntityRegistry.activeEntity = entity;
},
};

View File

@ -18,8 +18,7 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * 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. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
import { lifecycleEnum } from "@ogre-tools/injectable";
import { unpackExtension } from "./unpack-extension"; import { unpackExtension } from "./unpack-extension";
import extensionLoaderInjectable from "../../../../../extensions/extension-loader/extension-loader.injectable"; import extensionLoaderInjectable from "../../../../../extensions/extension-loader/extension-loader.injectable";

View File

@ -21,11 +21,10 @@
import React from "react"; import React from "react";
import { boundMethod, cssNames } from "../../utils"; import { boundMethod, cssNames } from "../../utils";
import { openPortForward, PortForwardItem, removePortForward } from "../../port-forward"; import { openPortForward, PortForwardItem, removePortForward, PortForwardDialog } from "../../port-forward";
import { MenuActions, MenuActionsProps } from "../menu/menu-actions"; import { MenuActions, MenuActionsProps } from "../menu/menu-actions";
import { MenuItem } from "../menu"; import { MenuItem } from "../menu";
import { Icon } from "../icon"; import { Icon } from "../icon";
import { PortForwardDialog } from "../../port-forward";
import { Notifications } from "../notifications"; import { Notifications } from "../notifications";
interface Props extends MenuActionsProps { interface Props extends MenuActionsProps {

View File

@ -23,7 +23,7 @@ import { KubeConfig } from "@kubernetes/client-node";
import { fireEvent, render } from "@testing-library/react"; import { fireEvent, render } from "@testing-library/react";
import mockFs from "mock-fs"; import mockFs from "mock-fs";
import React from "react"; import React from "react";
import selectEvent from "react-select-event"; import * as selectEvent from "react-select-event";
import { Cluster } from "../../../../main/cluster"; import { Cluster } from "../../../../main/cluster";
import { DeleteClusterDialog } from "../delete-cluster-dialog"; import { DeleteClusterDialog } from "../delete-cluster-dialog";

View File

@ -22,7 +22,7 @@
import React from "react"; import React from "react";
import "@testing-library/jest-dom/extend-expect"; import "@testing-library/jest-dom/extend-expect";
import { render } from "@testing-library/react"; import { render } from "@testing-library/react";
import selectEvent from "react-select-event"; import * as selectEvent from "react-select-event";
import { Pod } from "../../../../common/k8s-api/endpoints"; import { Pod } from "../../../../common/k8s-api/endpoints";
import { LogResourceSelector } from "../log-resource-selector"; import { LogResourceSelector } from "../log-resource-selector";

View File

@ -31,7 +31,6 @@ import { apiManager } from "../../../common/k8s-api/api-manager";
import { crdStore } from "../+custom-resources/crd.store"; import { crdStore } from "../+custom-resources/crd.store";
import { KubeObjectMenu } from "../kube-object-menu"; import { KubeObjectMenu } from "../kube-object-menu";
import { KubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; import { KubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
import logger from "../../../main/logger";
import { CrdResourceDetails } from "../+custom-resources"; import { CrdResourceDetails } from "../+custom-resources";
import { KubeObjectMeta } from "../kube-object-meta"; import { KubeObjectMeta } from "../kube-object-meta";
import { hideDetails, kubeDetailsUrlParam } from "../kube-detail-params"; import { hideDetails, kubeDetailsUrlParam } from "../kube-detail-params";
@ -62,7 +61,7 @@ export class KubeObjectDetails extends React.Component {
.getStore(this.path) .getStore(this.path)
?.getByPath(this.path); ?.getByPath(this.path);
} catch (error) { } catch (error) {
logger.error(`[KUBE-OBJECT-DETAILS]: failed to get store or object: ${error}`, { path: this.path }); console.error(`[KUBE-OBJECT-DETAILS]: failed to get store or object: ${error}`, { path: this.path });
return undefined; return undefined;
} }

View File

@ -21,7 +21,7 @@
import { hideDetails } from "../../kube-detail-params"; import { hideDetails } from "../../kube-detail-params";
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
export const hideDetailsInjectable = getInjectable({ const hideDetailsInjectable = getInjectable({
instantiate: () => hideDetails, instantiate: () => hideDetails,
lifecycle: lifecycleEnum.singleton, lifecycle: lifecycleEnum.singleton,
}); });

View File

@ -27,7 +27,7 @@ import { observer } from "mobx-react";
import { boundMethod, cssNames } from "../../utils"; import { boundMethod, cssNames } from "../../utils";
import { ConfirmDialog } from "../confirm-dialog"; import { ConfirmDialog } from "../confirm-dialog";
import { Icon, IconProps } from "../icon"; import { Icon, IconProps } from "../icon";
import { Menu, MenuItem, MenuProps } from "../menu"; import { Menu, MenuItem, MenuProps } from "./menu";
import uniqueId from "lodash/uniqueId"; import uniqueId from "lodash/uniqueId";
import isString from "lodash/isString"; import isString from "lodash/isString";

View File

@ -24,7 +24,8 @@ import React from "react";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import { action, computed, makeObservable, observable, reaction } from "mobx"; import { action, computed, makeObservable, observable, reaction } from "mobx";
import { editor, Uri } from "monaco-editor"; import { editor, Uri } from "monaco-editor";
import { MonacoTheme, MonacoValidator, monacoValidators } from "./index"; import type { MonacoTheme } from "./monaco-themes";
import { MonacoValidator, monacoValidators } from "./monaco-validators";
import { debounce, merge } from "lodash"; import { debounce, merge } from "lodash";
import { cssNames, disposer } from "../../utils"; import { cssNames, disposer } from "../../utils";
import { UserStore } from "../../../common/user-store"; import { UserStore } from "../../../common/user-store";

View File

@ -20,8 +20,7 @@
*/ */
import styles from "./react-table.module.scss"; import styles from "./react-table.module.scss";
import React from "react"; import React, { useCallback, useMemo } from "react";
import { useCallback, useMemo } from "react";
import { useFlexLayout, useSortBy, useTable, UseTableOptions } from "react-table"; import { useFlexLayout, useSortBy, useTable, UseTableOptions } from "react-table";
import { Icon } from "../icon"; import { Icon } from "../icon";
import { cssNames } from "../../utils"; import { cssNames } from "../../utils";

View File

@ -31,7 +31,8 @@ import { Notifications } from "../components/notifications";
import { cssNames } from "../utils"; import { cssNames } from "../utils";
import { addPortForward, getPortForwards, modifyPortForward } from "./port-forward.store"; import { addPortForward, getPortForwards, modifyPortForward } from "./port-forward.store";
import type { ForwardedPort } from "./port-forward-item"; import type { ForwardedPort } from "./port-forward-item";
import { aboutPortForwarding, openPortForward } from "."; import { openPortForward } from "./port-forward-utils";
import { aboutPortForwarding } from "./port-forward-notify";
import { Checkbox } from "../components/checkbox"; import { Checkbox } from "../components/checkbox";
interface Props extends Partial<DialogProps> { interface Props extends Partial<DialogProps> {

View File

@ -27,6 +27,7 @@ import lensDarkThemeJson from "./themes/lens-dark.json";
import lensLightThemeJson from "./themes/lens-light.json"; import lensLightThemeJson from "./themes/lens-light.json";
import type { SelectOption } from "./components/select"; import type { SelectOption } from "./components/select";
import type { MonacoEditorProps } from "./components/monaco-editor"; import type { MonacoEditorProps } from "./components/monaco-editor";
import { defaultTheme } from "../common/vars";
export type ThemeId = string; export type ThemeId = string;
@ -40,7 +41,6 @@ export interface Theme {
} }
export class ThemeStore extends Singleton { export class ThemeStore extends Singleton {
static readonly defaultTheme = "lens-dark";
protected styles: HTMLStyleElement; protected styles: HTMLStyleElement;
// bundled themes from `themes/${themeId}.json` // bundled themes from `themes/${themeId}.json`
@ -54,7 +54,7 @@ export class ThemeStore extends Singleton {
} }
@computed get activeTheme(): Theme { @computed get activeTheme(): Theme {
return this.themes.get(this.activeThemeId) ?? this.themes.get(ThemeStore.defaultTheme); return this.themes.get(this.activeThemeId) ?? this.themes.get(defaultTheme);
} }
@computed get themeOptions(): SelectOption<string>[] { @computed get themeOptions(): SelectOption<string>[] {

View File

@ -21,7 +21,7 @@
// Helper for working with storages (e.g. window.localStorage, NodeJS/file-system, etc.) // Helper for working with storages (e.g. window.localStorage, NodeJS/file-system, etc.)
import { action, comparer, makeObservable, observable, toJS, when } from "mobx"; import { action, comparer, makeObservable, observable, toJS, when } from "mobx";
import produce, { Draft, isDraft } from "immer"; import { produce, Draft, isDraft } from "immer";
import { isEqual, isPlainObject } from "lodash"; import { isEqual, isPlainObject } from "lodash";
import logger from "../../main/logger"; import logger from "../../main/logger";
import { getHostedClusterId } from "../../common/utils"; import { getHostedClusterId } from "../../common/utils";

View File

@ -27,6 +27,7 @@ import nodeExternals from "webpack-node-externals";
import ProgressBarPlugin from "progress-bar-webpack-plugin"; import ProgressBarPlugin from "progress-bar-webpack-plugin";
import * as vars from "./src/common/vars"; import * as vars from "./src/common/vars";
import getTSLoader from "./src/common/getTSLoader"; import getTSLoader from "./src/common/getTSLoader";
import CircularDependencyPlugin from "circular-dependency-plugin";
const configs: { (): webpack.Configuration }[] = []; const configs: { (): webpack.Configuration }[] = [];
@ -64,6 +65,12 @@ configs.push((): webpack.Configuration => {
plugins: [ plugins: [
new ProgressBarPlugin(), new ProgressBarPlugin(),
new ForkTsCheckerPlugin(), new ForkTsCheckerPlugin(),
new CircularDependencyPlugin({
cwd: __dirname,
exclude: /node_modules/,
failOnError: true,
}),
].filter(Boolean), ].filter(Boolean),
}; };
}); });

View File

@ -30,6 +30,7 @@ import ProgressBarPlugin from "progress-bar-webpack-plugin";
import ReactRefreshWebpackPlugin from "@pmmmwh/react-refresh-webpack-plugin"; import ReactRefreshWebpackPlugin from "@pmmmwh/react-refresh-webpack-plugin";
import MonacoWebpackPlugin from "monaco-editor-webpack-plugin"; import MonacoWebpackPlugin from "monaco-editor-webpack-plugin";
import getTSLoader from "./src/common/getTSLoader"; import getTSLoader from "./src/common/getTSLoader";
import CircularDependencyPlugin from "circular-dependency-plugin";
export default [ export default [
webpackLensRenderer, webpackLensRenderer,
@ -173,6 +174,12 @@ export function webpackLensRenderer({ showVars = true } = {}): webpack.Configura
inject: true, inject: true,
}), }),
new CircularDependencyPlugin({
cwd: __dirname,
exclude: /node_modules/,
failOnError: true,
}),
new MiniCssExtractPlugin({ new MiniCssExtractPlugin({
filename: "[name].css", filename: "[name].css",
}), }),

104
yarn.lock
View File

@ -1358,6 +1358,13 @@
dependencies: dependencies:
moment "^2.10.2" moment "^2.10.2"
"@types/circular-dependency-plugin@5.0.4":
version "5.0.4"
resolved "https://registry.yarnpkg.com/@types/circular-dependency-plugin/-/circular-dependency-plugin-5.0.4.tgz#c5ccbd1d2bbb39b60e9859b39c6b826f60567ef2"
integrity sha512-J4XkMJfkGv3o3q2Ca821cufIBNBFms45fz+xD9tEESR0YqL5BlwETOwm2desSCdki2zdcPRhG9ZQCm/WITCEPQ==
dependencies:
"@types/webpack" "^4"
"@types/clean-css@*": "@types/clean-css@*":
version "4.2.1" version "4.2.1"
resolved "https://registry.yarnpkg.com/@types/clean-css/-/clean-css-4.2.1.tgz#cb0134241ec5e6ede1b5344bc829668fd9871a8d" resolved "https://registry.yarnpkg.com/@types/clean-css/-/clean-css-4.2.1.tgz#cb0134241ec5e6ede1b5344bc829668fd9871a8d"
@ -2711,6 +2718,15 @@ array-unique@^0.3.2:
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
array.prototype.flat@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13"
integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"
es-abstract "^1.19.0"
array.prototype.flatmap@^1.2.5: array.prototype.flatmap@^1.2.5:
version "1.2.5" version "1.2.5"
resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz#908dc82d8a406930fdf38598d51e7411d18d4446" resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz#908dc82d8a406930fdf38598d51e7411d18d4446"
@ -4431,21 +4447,28 @@ debug@3.1.0, debug@~3.1.0:
dependencies: dependencies:
ms "2.0.0" ms "2.0.0"
debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2: debug@4, debug@^4.3.2:
version "4.3.2" version "4.3.2"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
dependencies: dependencies:
ms "2.1.2" ms "2.1.2"
debug@4.3.1: debug@4.3.1, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1:
version "4.3.1" version "4.3.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
dependencies: dependencies:
ms "2.1.2" ms "2.1.2"
debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.6: debug@^3.0.0, debug@^3.1.1, debug@^3.2.6:
version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
dependencies:
ms "^2.1.1"
debug@^3.1.0, debug@^3.2.7:
version "3.2.7" version "3.2.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
@ -5436,11 +5459,47 @@ escodegen@^2.0.0:
optionalDependencies: optionalDependencies:
source-map "~0.6.1" source-map "~0.6.1"
eslint-import-resolver-node@^0.3.6:
version "0.3.6"
resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd"
integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==
dependencies:
debug "^3.2.7"
resolve "^1.20.0"
eslint-module-utils@^2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz#b435001c9f8dd4ab7f6d0efcae4b9696d4c24b7c"
integrity sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==
dependencies:
debug "^3.2.7"
find-up "^2.1.0"
pkg-dir "^2.0.0"
eslint-plugin-header@^3.1.1: eslint-plugin-header@^3.1.1:
version "3.1.1" version "3.1.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-header/-/eslint-plugin-header-3.1.1.tgz#6ce512432d57675265fac47292b50d1eff11acd6" resolved "https://registry.yarnpkg.com/eslint-plugin-header/-/eslint-plugin-header-3.1.1.tgz#6ce512432d57675265fac47292b50d1eff11acd6"
integrity sha512-9vlKxuJ4qf793CmeeSrZUvVClw6amtpghq3CuWcB5cUNnWHQhgcqy5eF8oVKFk1G3Y/CbchGfEaw3wiIJaNmVg== integrity sha512-9vlKxuJ4qf793CmeeSrZUvVClw6amtpghq3CuWcB5cUNnWHQhgcqy5eF8oVKFk1G3Y/CbchGfEaw3wiIJaNmVg==
eslint-plugin-import@^2.25.3:
version "2.25.3"
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.3.tgz#a554b5f66e08fb4f6dc99221866e57cfff824766"
integrity sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg==
dependencies:
array-includes "^3.1.4"
array.prototype.flat "^1.2.5"
debug "^2.6.9"
doctrine "^2.1.0"
eslint-import-resolver-node "^0.3.6"
eslint-module-utils "^2.7.1"
has "^1.0.3"
is-core-module "^2.8.0"
is-glob "^4.0.3"
minimatch "^3.0.4"
object.values "^1.1.5"
resolve "^1.20.0"
tsconfig-paths "^3.11.0"
eslint-plugin-react-hooks@^4.3.0: eslint-plugin-react-hooks@^4.3.0:
version "4.3.0" version "4.3.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz#318dbf312e06fab1c835a4abef00121751ac1172" resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz#318dbf312e06fab1c835a4abef00121751ac1172"
@ -6039,7 +6098,7 @@ find-root@^1.1.0:
resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==
find-up@^2.0.0: find-up@^2.0.0, find-up@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c=
@ -7439,6 +7498,13 @@ is-core-module@^2.2.0:
dependencies: dependencies:
has "^1.0.3" has "^1.0.3"
is-core-module@^2.8.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548"
integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==
dependencies:
has "^1.0.3"
is-data-descriptor@^0.1.4: is-data-descriptor@^0.1.4:
version "0.1.4" version "0.1.4"
resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56"
@ -10828,6 +10894,13 @@ pirates@^4.0.1:
dependencies: dependencies:
node-modules-regexp "^1.0.0" node-modules-regexp "^1.0.0"
pkg-dir@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b"
integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=
dependencies:
find-up "^2.1.0"
pkg-dir@^3.0.0: pkg-dir@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3"
@ -13532,9 +13605,9 @@ truncate-utf8-bytes@^1.0.0:
utf8-byte-length "^1.0.1" utf8-byte-length "^1.0.1"
ts-essentials@^7.0.2: ts-essentials@^7.0.2:
version "7.0.3" version "7.0.2"
resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38" resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.2.tgz#e21142df8034dbd444cb9573ed204d0b85fc64fb"
integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ== integrity sha512-qWPVC1xZGdefbsgFP7tPo+bsgSA2ZIXL1XeEe5M2WoMZxIOr/HbsHxP/Iv75IFhiMHMDGL7cOOwi5SXcgx9mHw==
ts-jest@26.5.6: ts-jest@26.5.6:
version "26.5.6" version "26.5.6"
@ -13581,6 +13654,16 @@ ts-node@^10.4.0:
make-error "^1.1.1" make-error "^1.1.1"
yn "3.1.1" yn "3.1.1"
tsconfig-paths@^3.11.0:
version "3.12.0"
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz#19769aca6ee8f6a1a341e38c8fa45dd9fb18899b"
integrity sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==
dependencies:
"@types/json5" "^0.0.29"
json5 "^1.0.1"
minimist "^1.2.0"
strip-bom "^3.0.0"
tsconfig-paths@^3.9.0: tsconfig-paths@^3.9.0:
version "3.9.0" version "3.9.0"
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b"
@ -13679,7 +13762,12 @@ type-fest@^0.8.1:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
type-fest@^1.0.2, type-fest@^1.4.0: type-fest@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.0.2.tgz#3f9c39982859f385c77c38b7e5f1432b8a3661c6"
integrity sha512-a720oz3Kjbp3ll0zkeN9qjRhO7I34MKMhPGQiQJAmaZQZQ1lo+NWThK322f7sXV+kTg9B1Ybt16KgBXWgteT8w==
type-fest@^1.4.0:
version "1.4.0" version "1.4.0"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1"
integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==