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

Merge remote-tracking branch 'origin/master' into eliminate-gst-from-app-paths

This commit is contained in:
Janne Savolainen 2022-01-10 17:13:20 +02:00
commit e1a6d4c4a9
No known key found for this signature in database
GPG Key ID: 5F465B5672372402
56 changed files with 379 additions and 224 deletions

View File

@ -54,6 +54,7 @@ module.exports = {
"react-hooks", "react-hooks",
], ],
rules: { rules: {
"no-constant-condition": ["error", { "checkLoops": false }],
"header/header": [2, "./license-header"], "header/header": [2, "./license-header"],
"comma-dangle": ["error", "always-multiline"], "comma-dangle": ["error", "always-multiline"],
"comma-spacing": "error", "comma-spacing": "error",
@ -107,7 +108,10 @@ module.exports = {
], ],
parser: "@typescript-eslint/parser", parser: "@typescript-eslint/parser",
extends: [ extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended", "plugin:@typescript-eslint/recommended",
"plugin:import/recommended",
"plugin:import/typescript",
], ],
plugins: [ plugins: [
"header", "header",
@ -118,7 +122,7 @@ module.exports = {
sourceType: "module", sourceType: "module",
}, },
rules: { rules: {
"no-irregular-whitespace": "error", "no-constant-condition": ["error", { "checkLoops": false }],
"header/header": [2, "./license-header"], "header/header": [2, "./license-header"],
"no-invalid-this": "off", "no-invalid-this": "off",
"@typescript-eslint/no-invalid-this": ["error"], "@typescript-eslint/no-invalid-this": ["error"],
@ -191,8 +195,11 @@ module.exports = {
"unused-imports", "unused-imports",
], ],
extends: [ extends: [
"eslint:recommended",
"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,
@ -200,8 +207,9 @@ module.exports = {
jsx: true, jsx: true,
}, },
rules: { rules: {
"no-irregular-whitespace": "error", "no-constant-condition": ["error", { "checkLoops": false }],
"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 +254,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": "3.1.1", "@ogre-tools/injectable-react": "3.1.1",
"@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",
@ -214,7 +214,7 @@
"filehound": "^1.17.5", "filehound": "^1.17.5",
"fs-extra": "^9.0.1", "fs-extra": "^9.0.1",
"glob-to-regexp": "^0.4.1", "glob-to-regexp": "^0.4.1",
"got": "^11.8.2", "got": "^11.8.3",
"grapheme-splitter": "^1.0.4", "grapheme-splitter": "^1.0.4",
"handlebars": "^4.7.7", "handlebars": "^4.7.7",
"http-proxy": "^1.18.1", "http-proxy": "^1.18.1",
@ -333,7 +333,7 @@
"concurrently": "^5.3.0", "concurrently": "^5.3.0",
"css-loader": "^5.2.7", "css-loader": "^5.2.7",
"deepdash": "^5.3.9", "deepdash": "^5.3.9",
"dompurify": "^2.3.3", "dompurify": "^2.3.4",
"electron": "^13.6.1", "electron": "^13.6.1",
"electron-builder": "^22.14.5", "electron-builder": "^22.14.5",
"electron-notarize": "^0.3.0", "electron-notarize": "^0.3.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

@ -493,42 +493,9 @@ users:
it("moves the icon into preferences", async () => { it("moves the icon into preferences", async () => {
const storedClusterData = clusterStore.clustersList[0]; const storedClusterData = clusterStore.clustersList[0];
expect(storedClusterData.hasOwnProperty("icon")).toBe(false); expect(Object.prototype.hasOwnProperty.call(storedClusterData, "icon")).toBe(false);
expect(storedClusterData.preferences.hasOwnProperty("icon")).toBe(true); expect(Object.prototype.hasOwnProperty.call(storedClusterData.preferences, "icon")).toBe(true);
expect( expect(storedClusterData.preferences.icon.startsWith("data:;base64,")).toBe(true);
storedClusterData.preferences.icon.startsWith("data:;base64,"),
).toBe(true);
});
});
describe("for a pre 2.7.0-beta.0 config without a workspace", () => {
beforeEach(() => {
ClusterStore.resetInstance();
const mockOpts = {
"some-directory-for-user-data": {
"lens-cluster-store.json": JSON.stringify({
__internal__: {
migrations: {
version: "2.6.6",
},
},
cluster1: {
kubeConfig: minimalValidKubeConfig,
preferences: {
terminalCWD: "/some-directory-for-user-data",
},
},
}),
},
};
mockFs(mockOpts);
clusterStore = mainDi.inject(clusterStoreInjectable);
});
afterEach(() => {
mockFs.restore();
}); });
}); });
@ -580,6 +547,7 @@ users:
}); });
}); });
}); });
const minimalValidKubeConfig = JSON.stringify({ const minimalValidKubeConfig = JSON.stringify({
apiVersion: "v1", apiVersion: "v1",
clusters: [ clusters: [

View File

@ -42,12 +42,12 @@ 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/cluster-store";
import { getDisForUnitTesting } from "../../test-utils/get-dis-for-unit-testing"; import { getDisForUnitTesting } from "../../test-utils/get-dis-for-unit-testing";
import userStoreInjectable from "../user-store/user-store.injectable"; import userStoreInjectable from "../user-store/user-store.injectable";
import type { DependencyInjectionContainer } from "@ogre-tools/injectable"; import type { DependencyInjectionContainer } from "@ogre-tools/injectable";
import directoryForUserDataInjectable from "../app-paths/directory-for-user-data/directory-for-user-data.injectable"; import directoryForUserDataInjectable from "../app-paths/directory-for-user-data/directory-for-user-data.injectable";
import type { ClusterStoreModel } from "../cluster-store/cluster-store";
import { defaultTheme } from "../vars";
console = new Console(stdout, stderr); console = new Console(stdout, stderr);
@ -92,7 +92,7 @@ describe("user store tests", () => {
userStore.httpsProxy = "abcd://defg"; userStore.httpsProxy = "abcd://defg";
expect(userStore.httpsProxy).toBe("abcd://defg"); expect(userStore.httpsProxy).toBe("abcd://defg");
expect(userStore.colorTheme).toBe(ThemeStore.defaultTheme); expect(userStore.colorTheme).toBe(defaultTheme);
userStore.colorTheme = "light"; userStore.colorTheme = "light";
expect(userStore.colorTheme).toBe("light"); expect(userStore.colorTheme).toBe("light");
@ -101,7 +101,7 @@ describe("user store tests", () => {
it("correctly resets theme to default value", async () => { it("correctly resets theme to default value", async () => {
userStore.colorTheme = "some other theme"; userStore.colorTheme = "some other theme";
userStore.resetTheme(); userStore.resetTheme();
expect(userStore.colorTheme).toBe(ThemeStore.defaultTheme); expect(userStore.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

@ -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/cluster-store"; import { ClusterStore } from "../cluster-store/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

@ -19,10 +19,10 @@
* 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 { CustomResourceDefinition } from "../endpoints"; import { CustomResourceDefinition, CustomResourceDefinitionSpec } from "../endpoints";
describe("Crds", () => { describe("Crds", () => {
describe("getVersion", () => { describe("getVersion()", () => {
it("should throw if none of the versions are served", () => { it("should throw if none of the versions are served", () => {
const crd = new CustomResourceDefinition({ const crd = new CustomResourceDefinition({
apiVersion: "apiextensions.k8s.io/v1", apiVersion: "apiextensions.k8s.io/v1",
@ -136,7 +136,7 @@ describe("Crds", () => {
expect(crd.getVersion()).toBe("123"); expect(crd.getVersion()).toBe("123");
}); });
it("should get the version name from the version field", () => { it("should get the version name from the version field, ignoring versions on v1beta", () => {
const crd = new CustomResourceDefinition({ const crd = new CustomResourceDefinition({
apiVersion: "apiextensions.k8s.io/v1beta1", apiVersion: "apiextensions.k8s.io/v1beta1",
kind: "CustomResourceDefinition", kind: "CustomResourceDefinition",
@ -147,7 +147,14 @@ describe("Crds", () => {
}, },
spec: { spec: {
version: "abc", version: "abc",
}, versions: [
{
name: "foobar",
served: true,
storage: true,
},
],
} as CustomResourceDefinitionSpec,
}); });
expect(crd.getVersion()).toBe("abc"); expect(crd.getVersion()).toBe("abc");

View File

@ -164,14 +164,14 @@ describe("KubeObject", () => {
describe("isJsonApiDataList", () => { describe("isJsonApiDataList", () => {
function isAny(val: unknown): val is any { function isAny(val: unknown): val is any {
return !Boolean(void val); return true;
} }
function isNotAny(val: unknown): val is any { function isNotAny(val: unknown): val is any {
return Boolean(void val); return false;
} }
function isBoolean(val: unknown): val is Boolean { function isBoolean(val: unknown): val is boolean {
return typeof val === "boolean"; return typeof val === "boolean";
} }

View File

@ -48,34 +48,36 @@ export interface CRDVersion {
additionalPrinterColumns?: AdditionalPrinterColumnsV1[]; additionalPrinterColumns?: AdditionalPrinterColumnsV1[];
} }
export interface CustomResourceDefinition { export interface CustomResourceDefinitionSpec {
spec: { group: string;
group: string; /**
/** * @deprecated for apiextensions.k8s.io/v1 but used in v1beta1
* @deprecated for apiextensions.k8s.io/v1 but used previously */
*/ version?: string;
version?: string; names: {
names: { plural: string;
plural: string; singular: string;
singular: string; kind: string;
kind: string; listKind: string;
listKind: string;
};
scope: "Namespaced" | "Cluster" | string;
/**
* @deprecated for apiextensions.k8s.io/v1 but used previously
*/
validation?: object;
versions?: CRDVersion[];
conversion: {
strategy?: string;
webhook?: any;
};
/**
* @deprecated for apiextensions.k8s.io/v1 but used previously
*/
additionalPrinterColumns?: AdditionalPrinterColumnsV1Beta[];
}; };
scope: "Namespaced" | "Cluster";
/**
* @deprecated for apiextensions.k8s.io/v1 but used in v1beta1
*/
validation?: object;
versions?: CRDVersion[];
conversion: {
strategy?: string;
webhook?: any;
};
/**
* @deprecated for apiextensions.k8s.io/v1 but used in v1beta1
*/
additionalPrinterColumns?: AdditionalPrinterColumnsV1Beta[];
}
export interface CustomResourceDefinition {
spec: CustomResourceDefinitionSpec;
status: { status: {
conditions: { conditions: {
lastTransitionTime: string; lastTransitionTime: string;
@ -150,27 +152,32 @@ export class CustomResourceDefinition extends KubeObject {
} }
getPreferedVersion(): CRDVersion { getPreferedVersion(): CRDVersion {
// Prefer the modern `versions` over the legacy `version` const { apiVersion } = this;
if (this.spec.versions) {
for (const version of this.spec.versions) {
if (version.storage) {
return version;
}
}
} else if (this.spec.version) {
const { additionalPrinterColumns: apc } = this.spec;
const additionalPrinterColumns = apc?.map(({ JSONPath, ...apc }) => ({ ...apc, jsonPath: JSONPath }));
return { switch (apiVersion) {
name: this.spec.version, case "apiextensions.k8s.io/v1":
served: true, for (const version of this.spec.versions) {
storage: true, if (version.storage) {
schema: this.spec.validation, return version;
additionalPrinterColumns, }
}; }
break;
case "apiextensions.k8s.io/v1beta1": {
const { additionalPrinterColumns: apc } = this.spec;
const additionalPrinterColumns = apc?.map(({ JSONPath, ...apc }) => ({ ...apc, jsonPath: JSONPath }));
return {
name: this.spec.version,
served: true,
storage: true,
schema: this.spec.validation,
additionalPrinterColumns,
};
}
} }
throw new Error(`Failed to find a version for CustomResourceDefinition ${this.metadata.name}`); throw new Error(`Unknown apiVersion=${apiVersion}: Failed to find a version for CustomResourceDefinition ${this.metadata.name}`);
} }
getVersion() { getVersion() {
@ -197,7 +204,7 @@ export class CustomResourceDefinition extends KubeObject {
const columns = this.getPreferedVersion().additionalPrinterColumns ?? []; const columns = this.getPreferedVersion().additionalPrinterColumns ?? [];
return columns return columns
.filter(column => column.name != "Age" && (ignorePriority || !column.priority)); .filter(column => column.name.toLowerCase() != "age" && (ignorePriority || !column.priority));
} }
getValidation() { getValidation() {

View File

@ -187,7 +187,7 @@ export class Ingress extends KubeObject {
const servicePort = defaultBackend?.service.port.number ?? backend?.servicePort; const servicePort = defaultBackend?.service.port.number ?? backend?.servicePort;
if (rules && rules.length > 0) { if (rules && rules.length > 0) {
if (rules.some(rule => rule.hasOwnProperty("http"))) { if (rules.some(rule => Object.prototype.hasOwnProperty.call(rule, "http"))) {
ports.push(httpPort); ports.push(httpPort);
} }
} else if (servicePort !== undefined) { } else if (servicePort !== undefined) {

View File

@ -184,7 +184,8 @@ export function getMetricLastPoints(metrics: Record<string, IMetrics>) {
if (metric.data.result.length) { if (metric.data.result.length) {
result[metricName] = +metric.data.result[0].values.slice(-1)[0][1]; result[metricName] = +metric.data.result[0].values.slice(-1)[0][1];
} }
} catch (e) { } catch {
// ignore error
} }
return result; return result;

View File

@ -34,6 +34,9 @@ import type { IKubeWatchEvent } from "./kube-watch-event";
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";
@ -698,21 +701,16 @@ export class KubeApi<T extends KubeObject> {
} }
protected modifyWatchEvent(event: IKubeWatchEvent<KubeJsonApiData>) { protected modifyWatchEvent(event: IKubeWatchEvent<KubeJsonApiData>) {
if (event.type === "ERROR") {
return;
switch (event.type) {
case "ADDED":
case "DELETED":
case "MODIFIED": {
ensureObjectSelfLink(this, event.object);
const { namespace, resourceVersion } = event.object.metadata;
this.setResourceVersion(namespace, resourceVersion);
this.setResourceVersion("", resourceVersion);
break;
}
} }
ensureObjectSelfLink(this, event.object);
const { namespace, resourceVersion } = event.object.metadata;
this.setResourceVersion(namespace, resourceVersion);
this.setResourceVersion("", resourceVersion);
} }
} }

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";
@ -469,7 +472,9 @@ export abstract class KubeObjectStore<T extends KubeObject> extends ItemStore<T>
switch (type) { switch (type) {
case "ADDED": case "ADDED":
case "MODIFIED":
// falls through
case "MODIFIED": {
const newItem = new this.api.objectConstructor(object); const newItem = new this.api.objectConstructor(object);
if (!item) { if (!item) {
@ -477,7 +482,9 @@ export abstract class KubeObjectStore<T extends KubeObject> extends ItemStore<T>
} else { } else {
items[index] = newItem; items[index] = newItem;
} }
break; break;
}
case "DELETED": case "DELETED":
if (item) { if (item) {
items.splice(index, 1); items.splice(index, 1);

View File

@ -89,7 +89,7 @@ export abstract class LensProtocolRouter {
public static readonly LoggingPrefix = "[PROTOCOL ROUTER]"; public static readonly LoggingPrefix = "[PROTOCOL ROUTER]";
static readonly ExtensionUrlSchema = `/:${EXTENSION_PUBLISHER_MATCH}(\@[A-Za-z0-9_]+)?/:${EXTENSION_NAME_MATCH}`; static readonly ExtensionUrlSchema = `/:${EXTENSION_PUBLISHER_MATCH}(@[A-Za-z0-9_]+)?/:${EXTENSION_NAME_MATCH}`;
constructor(protected dependencies: Dependencies) {} constructor(protected dependencies: Dependencies) {}

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

@ -26,7 +26,7 @@
export function defineGlobal(propName: string, descriptor: PropertyDescriptor) { export function defineGlobal(propName: string, descriptor: PropertyDescriptor) {
const scope = typeof global !== "undefined" ? global : window; const scope = typeof global !== "undefined" ? global : window;
if (scope.hasOwnProperty(propName)) { if (Object.prototype.hasOwnProperty.call(scope, propName)) {
return; return;
} }

View File

@ -25,6 +25,7 @@ export type Falsey = false | 0 | "" | null | undefined;
* Create a new type safe empty Iterable * Create a new type safe empty Iterable
* @returns An `Iterable` that yields 0 items * @returns An `Iterable` that yields 0 items
*/ */
// eslint-disable-next-line require-yield
export function* newEmpty<T>(): IterableIterator<T> { export function* newEmpty<T>(): IterableIterator<T> {
return; return;
} }

View File

@ -31,12 +31,13 @@ export interface ReadFileFromTarOpts {
} }
export function readFileFromTar<R = Buffer>({ tarPath, filePath, parseJson }: ReadFileFromTarOpts): Promise<R> { export function readFileFromTar<R = Buffer>({ tarPath, filePath, parseJson }: ReadFileFromTarOpts): Promise<R> {
return new Promise(async (resolve, reject) => { return new Promise((resolve, reject) => {
const fileChunks: Buffer[] = []; const fileChunks: Buffer[] = [];
await tar.list({ tar.list({
file: tarPath, file: tarPath,
filter: entryPath => path.normalize(entryPath) === filePath, filter: entryPath => path.normalize(entryPath) === filePath,
sync: true,
onentry(entry: FileStat) { onentry(entry: FileStat) {
entry.on("data", chunk => { entry.on("data", chunk => {
fileChunks.push(chunk); fileChunks.push(chunk);

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

@ -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

@ -119,7 +119,9 @@ export class HelmRepoManager extends Singleton {
if (typeof parsedConfig === "object" && parsedConfig) { if (typeof parsedConfig === "object" && parsedConfig) {
return parsedConfig as HelmRepoConfig; return parsedConfig as HelmRepoConfig;
} }
} catch { } } catch {
// ignore error
}
return { return {
repositories: [], repositories: [],

View File

@ -101,7 +101,9 @@ export const initIpcMainHandlers = ({ electronMenuItems, directoryForLensLocalSt
const localStorageFilePath = path.resolve(directoryForLensLocalStorage, `${cluster.id}.json`); const localStorageFilePath = path.resolve(directoryForLensLocalStorage, `${cluster.id}.json`);
await remove(localStorageFilePath); await remove(localStorageFilePath);
} catch {} } catch {
// ignore error
}
}); });
ipcMainHandle(clusterSetDeletingHandler, (event, clusterId: string) => { ipcMainHandle(clusterSetDeletingHandler, (event, clusterId: string) => {

View File

@ -356,10 +356,10 @@ export class Kubectl {
bashScript += `export PATH="${helmPath}:${kubectlPath}:$PATH"\n`; bashScript += `export PATH="${helmPath}:${kubectlPath}:$PATH"\n`;
bashScript += "export KUBECONFIG=\"$tempkubeconfig\"\n"; bashScript += "export KUBECONFIG=\"$tempkubeconfig\"\n";
bashScript += `NO_PROXY=\",\${NO_PROXY:-localhost},\"\n`; bashScript += `NO_PROXY=",\${NO_PROXY:-localhost},"\n`;
bashScript += `NO_PROXY=\"\${NO_PROXY//,localhost,/,}\"\n`; bashScript += `NO_PROXY="\${NO_PROXY//,localhost,/,}"\n`;
bashScript += `NO_PROXY=\"\${NO_PROXY//,127.0.0.1,/,}\"\n`; bashScript += `NO_PROXY="\${NO_PROXY//,127.0.0.1,/,}"\n`;
bashScript += `NO_PROXY=\"localhost,127.0.0.1\${NO_PROXY%,}\"\n`; bashScript += `NO_PROXY="localhost,127.0.0.1\${NO_PROXY%,}"\n`;
bashScript += "export NO_PROXY\n"; bashScript += "export NO_PROXY\n";
bashScript += "unset tempkubeconfig\n"; bashScript += "unset tempkubeconfig\n";
await fsPromises.writeFile(bashScriptPath, bashScript.toString(), { mode: 0o644 }); await fsPromises.writeFile(bashScriptPath, bashScript.toString(), { mode: 0o644 });
@ -377,18 +377,18 @@ export class Kubectl {
zshScript += "test -f \"$OLD_ZDOTDIR/.zshrc\" && . \"$OLD_ZDOTDIR/.zshrc\"\n"; zshScript += "test -f \"$OLD_ZDOTDIR/.zshrc\" && . \"$OLD_ZDOTDIR/.zshrc\"\n";
// voodoo to replace any previous occurrences of kubectl path in the PATH // voodoo to replace any previous occurrences of kubectl path in the PATH
zshScript += `kubectlpath=\"${kubectlPath}"\n`; zshScript += `kubectlpath="${kubectlPath}"\n`;
zshScript += `helmpath=\"${helmPath}"\n`; zshScript += `helmpath="${helmPath}"\n`;
zshScript += "p=\":$kubectlpath:\"\n"; zshScript += "p=\":$kubectlpath:\"\n";
zshScript += "d=\":$PATH:\"\n"; zshScript += "d=\":$PATH:\"\n";
zshScript += `d=\${d//$p/:}\n`; zshScript += `d=\${d//$p/:}\n`;
zshScript += `d=\${d/#:/}\n`; zshScript += `d=\${d/#:/}\n`;
zshScript += `export PATH=\"$helmpath:$kubectlpath:\${d/%:/}\"\n`; zshScript += `export PATH="$helmpath:$kubectlpath:\${d/%:/}"\n`;
zshScript += "export KUBECONFIG=\"$tempkubeconfig\"\n"; zshScript += "export KUBECONFIG=\"$tempkubeconfig\"\n";
zshScript += `NO_PROXY=\",\${NO_PROXY:-localhost},\"\n`; zshScript += `NO_PROXY=",\${NO_PROXY:-localhost},"\n`;
zshScript += `NO_PROXY=\"\${NO_PROXY//,localhost,/,}\"\n`; zshScript += `NO_PROXY="\${NO_PROXY//,localhost,/,}"\n`;
zshScript += `NO_PROXY=\"\${NO_PROXY//,127.0.0.1,/,}\"\n`; zshScript += `NO_PROXY="\${NO_PROXY//,127.0.0.1,/,}"\n`;
zshScript += `NO_PROXY=\"localhost,127.0.0.1\${NO_PROXY%,}\"\n`; zshScript += `NO_PROXY="localhost,127.0.0.1\${NO_PROXY%,}"\n`;
zshScript += "export NO_PROXY\n"; zshScript += "export NO_PROXY\n";
zshScript += "unset tempkubeconfig\n"; zshScript += "unset tempkubeconfig\n";
zshScript += "unset OLD_ZDOTDIR\n"; zshScript += "unset OLD_ZDOTDIR\n";

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/app-event-bus/event-bus"; import { appEventBus } from "../common/app-event-bus/event-bus";
import { cloneJsonObject } from "../common/utils"; import { cloneJsonObject } from "../common/utils";

View File

@ -73,6 +73,7 @@ export class NodeShellSession extends ShellSession {
switch (nodeOs) { switch (nodeOs) {
default: default:
logger.warn(`[NODE-SHELL-SESSION]: could not determine node OS, falling back with assumption of linux`); logger.warn(`[NODE-SHELL-SESSION]: could not determine node OS, falling back with assumption of linux`);
// fallthrough
case "linux": case "linux":
args.push("sh", "-c", "((clear && bash) || (clear && ash) || (clear && sh))"); args.push("sh", "-c", "((clear && bash) || (clear && ash) || (clear && sh))");
break; break;

View File

@ -134,7 +134,9 @@ export abstract class ShellSession {
for (const shellProcess of this.processes.values()) { for (const shellProcess of this.processes.values()) {
try { try {
process.kill(shellProcess.pid); process.kill(shellProcess.pid);
} catch {} } catch {
// ignore error
}
} }
this.processes.clear(); this.processes.clear();
@ -212,7 +214,9 @@ export abstract class ShellSession {
if (stats.isDirectory()) { if (stats.isDirectory()) {
return potentialCwd; return potentialCwd;
} }
} catch {} } catch {
// ignore error
}
} }
return "."; // Always valid return "."; // Always valid

View File

@ -33,7 +33,7 @@ export default {
const contextName = value[0]; const contextName = value[0];
// Looping all the keys gives out the store internal stuff too... // Looping all the keys gives out the store internal stuff too...
if (contextName === "__internal__" || value[1].hasOwnProperty("kubeConfig")) continue; if (contextName === "__internal__" || Object.prototype.hasOwnProperty.call(value[1], "kubeConfig")) continue;
store.set(contextName, { kubeConfig: value[1] }); store.set(contextName, { kubeConfig: value[1] });
} }
}, },

View File

@ -34,7 +34,7 @@ export default {
if (!cluster.kubeConfig) continue; if (!cluster.kubeConfig) continue;
const config = yaml.load(cluster.kubeConfig); const config = yaml.load(cluster.kubeConfig);
if (!config || typeof config !== "object" || !config.hasOwnProperty("users")) { if (!config || typeof config !== "object" || !Object.prototype.hasOwnProperty.call(config, "users")) {
continue; continue;
} }

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/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

@ -45,15 +45,17 @@ export class HpaDetails extends React.Component<HpaDetailsProps> {
const renderName = (metric: IHpaMetric) => { const renderName = (metric: IHpaMetric) => {
switch (metric.type) { switch (metric.type) {
case HpaMetricType.Resource: case HpaMetricType.Resource: {
const addition = metric.resource.targetAverageUtilization ? <>(as a percentage of request)</> : ""; const addition = metric.resource.targetAverageUtilization
? "(as a percentage of request)"
: "";
return <>Resource {metric.resource.name} on Pods {addition}</>; return <>Resource {metric.resource.name} on Pods {addition}</>;
}
case HpaMetricType.Pods: case HpaMetricType.Pods:
return <>{metric.pods.metricName} on Pods</>; return <>{metric.pods.metricName} on Pods</>;
case HpaMetricType.Object: case HpaMetricType.Object: {
const { target } = metric.object; const { target } = metric.object;
const { kind, name } = target; const { kind, name } = target;
const objectUrl = getDetailsUrl(apiManager.lookupApiLink(target, hpa)); const objectUrl = getDetailsUrl(apiManager.lookupApiLink(target, hpa));
@ -64,6 +66,7 @@ export class HpaDetails extends React.Component<HpaDetailsProps> {
<Link to={objectUrl}>{kind}/{name}</Link> <Link to={objectUrl}>{kind}/{name}</Link>
</> </>
); );
}
case HpaMetricType.External: case HpaMetricType.External:
return ( return (
<> <>

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";
import getExtensionDestFolderInjectable import getExtensionDestFolderInjectable

View File

@ -47,8 +47,8 @@ export const getBaseRegistryUrl = ({ getRegistryUrlPreference }: Dependencies) =
} catch (error) { } catch (error) {
Notifications.error(<p>Failed to get configured registry from <code>.npmrc</code>. Falling back to default registry</p>); Notifications.error(<p>Failed to get configured registry from <code>.npmrc</code>. Falling back to default registry</p>);
console.warn("[EXTENSIONS]: failed to get configured registry from .npmrc", error); console.warn("[EXTENSIONS]: failed to get configured registry from .npmrc", error);
// fallthrough
} }
// fallthrough
} }
default: default:
case ExtensionRegistryLocation.DEFAULT: case ExtensionRegistryLocation.DEFAULT:

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 type { Cluster } from "../../../../common/cluster/cluster"; import type { Cluster } from "../../../../common/cluster/cluster";
import { DeleteClusterDialog } from "../delete-cluster-dialog"; import { DeleteClusterDialog } from "../delete-cluster-dialog";

View File

@ -21,8 +21,7 @@
import React from "react"; import React from "react";
import "@testing-library/jest-dom/extend-expect"; import "@testing-library/jest-dom/extend-expect";
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";
import type { LogTabData } from "../log-tab-store/log-tab.store"; import type { LogTabData } from "../log-tab-store/log-tab.store";
@ -33,8 +32,7 @@ import mockFs from "mock-fs";
import { getDiForUnitTesting } from "../../getDiForUnitTesting"; import { getDiForUnitTesting } from "../../getDiForUnitTesting";
import type { DiRender } from "../../test-utils/renderFor"; import type { DiRender } from "../../test-utils/renderFor";
import { renderFor } from "../../test-utils/renderFor"; import { renderFor } from "../../test-utils/renderFor";
import directoryForUserDataInjectable import directoryForUserDataInjectable from "../../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
from "../../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
import callForLogsInjectable from "../log-store/call-for-logs/call-for-logs.injectable"; import callForLogsInjectable from "../log-store/call-for-logs/call-for-logs.injectable";
jest.mock("electron", () => ({ jest.mock("electron", () => ({

View File

@ -133,7 +133,8 @@ export class FilePicker extends React.Component<Props> {
switch (onOverSizeLimit) { switch (onOverSizeLimit) {
case OverSizeLimitStyle.FILTER: case OverSizeLimitStyle.FILTER:
return files.filter(file => file.size <= maxSize ); return files.filter(file => file.size <= maxSize );
case OverSizeLimitStyle.REJECT:
case OverSizeLimitStyle.REJECT: {
const firstFileToLarge = files.find(file => file.size > maxSize); const firstFileToLarge = files.find(file => file.size > maxSize);
if (firstFileToLarge) { if (firstFileToLarge) {
@ -141,6 +142,7 @@ export class FilePicker extends React.Component<Props> {
} }
return files; return files;
}
} }
} }
@ -156,7 +158,9 @@ export class FilePicker extends React.Component<Props> {
switch (onOverTotalSizeLimit) { switch (onOverTotalSizeLimit) {
case OverTotalSizeLimitStyle.FILTER_LARGEST: case OverTotalSizeLimitStyle.FILTER_LARGEST:
files = _.orderBy(files, ["size"]); files = _.orderBy(files, ["size"]);
case OverTotalSizeLimitStyle.FILTER_LAST:
// fallthrough
case OverTotalSizeLimitStyle.FILTER_LAST: {
let newTotalSize = totalSize; let newTotalSize = totalSize;
for (;files.length > 0;) { for (;files.length > 0;) {
@ -168,6 +172,7 @@ export class FilePicker extends React.Component<Props> {
} }
return files; return files;
}
case OverTotalSizeLimitStyle.REJECT: case OverTotalSizeLimitStyle.REJECT:
throw `Total file size to upload is too large. Expected at most ${maxTotalSize}. Found ${totalSize}.`; throw `Total file size to upload is too large. Expected at most ${maxTotalSize}. Found ${totalSize}.`;
} }

View File

@ -73,6 +73,7 @@ export class Icon extends React.PureComponent<IconProps> {
switch (evt.nativeEvent.code) { switch (evt.nativeEvent.code) {
case "Space": case "Space":
// fallthrough
case "Enter": { case "Enter": {
// eslint-disable-next-line react/no-find-dom-node // eslint-disable-next-line react/no-find-dom-node
const icon = findDOMNode(this) as HTMLElement; const icon = findDOMNode(this) as HTMLElement;

View File

@ -39,7 +39,7 @@ export const isRequired: InputValidator = {
export const isEmail: InputValidator = { export const isEmail: InputValidator = {
condition: ({ type }) => type === "email", condition: ({ type }) => type === "email",
message: () => `Wrong email format`, message: () => `Wrong email format`,
validate: value => !!value.match(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/), validate: value => !!value.match(/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/),
}; };
export const isNumber: InputValidator = { export const isNumber: InputValidator = {

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

@ -243,7 +243,9 @@ export class Menu extends React.Component<MenuProps, State> {
break; break;
case "Space": case "Space":
case "Enter": // fallthrough
case "Enter": {
const focusedItem = this.focusedItem; const focusedItem = this.focusedItem;
if (focusedItem) { if (focusedItem) {
@ -251,10 +253,12 @@ export class Menu extends React.Component<MenuProps, State> {
evt.preventDefault(); evt.preventDefault();
} }
break; break;
}
case "ArrowUp": case "ArrowUp":
this.focusNextItem(true); this.focusNextItem(true);
break; break;
case "ArrowDown": case "ArrowDown":
this.focusNextItem(); this.focusNextItem();
break; break;

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 { getPortForwards } from "./port-forward-store/port-forward-store"; import { getPortForwards } from "./port-forward-store/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";
import { withInjectables } from "@ogre-tools/injectable-react"; import { withInjectables } from "@ogre-tools/injectable-react";
import modifyPortForwardInjectable from "./port-forward-store/modify-port-forward/modify-port-forward.injectable"; import modifyPortForwardInjectable from "./port-forward-store/modify-port-forward/modify-port-forward.injectable";

View File

@ -33,7 +33,7 @@ export class SearchStore {
* @param value Unescaped string * @param value Unescaped string
*/ */
public static escapeRegex(value?: string): string { public static escapeRegex(value?: string): string {
return value ? value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&") : ""; return value ? value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") : "";
} }
/** /**

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

@ -20,16 +20,8 @@
*/ */
// 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 { import { action, comparer, computed, makeObservable, observable, toJS, when } from "mobx";
action, import { produce, Draft, isDraft } from "immer";
comparer,
computed,
makeObservable,
observable,
toJS,
when,
} from "mobx";
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";

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",
}), }),

137
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"
@ -3415,17 +3431,17 @@ cacheable-request@^6.0.0:
normalize-url "^4.1.0" normalize-url "^4.1.0"
responselike "^1.0.2" responselike "^1.0.2"
cacheable-request@^7.0.1: cacheable-request@^7.0.2:
version "7.0.1" version "7.0.2"
resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.1.tgz#062031c2856232782ed694a257fa35da93942a58" resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27"
integrity sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw== integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==
dependencies: dependencies:
clone-response "^1.0.2" clone-response "^1.0.2"
get-stream "^5.1.0" get-stream "^5.1.0"
http-cache-semantics "^4.0.0" http-cache-semantics "^4.0.0"
keyv "^4.0.0" keyv "^4.0.0"
lowercase-keys "^2.0.0" lowercase-keys "^2.0.0"
normalize-url "^4.1.0" normalize-url "^6.0.1"
responselike "^2.0.0" responselike "^2.0.0"
call-bind@^1.0.0: call-bind@^1.0.0:
@ -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==
@ -4853,10 +4876,10 @@ domhandler@^2.3.0:
dependencies: dependencies:
domelementtype "1" domelementtype "1"
dompurify@^2.3.3: dompurify@^2.3.4:
version "2.3.3" version "2.3.4"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.3.tgz#c1af3eb88be47324432964d8abc75cf4b98d634c" resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.4.tgz#1cf5cf0105ccb4debdf6db162525bd41e6ddacc6"
integrity sha512-dqnqRkPMAjOZE0FogZ+ceJNM2dZ3V/yNOuFB7+39qpO93hHhfRpHw3heYQC7DPK9FqbQTfBKUJhiSfz4MvXYwg== integrity sha512-6BVcgOAVFXjI0JTjEvZy901Rghm+7fDQOrNIcxB4+gdhj6Kwp6T9VBhBY/AbagKHJocRkDYGd6wvI+p4/10xtQ==
domutils@1.5.1: domutils@1.5.1:
version "1.5.1" version "1.5.1"
@ -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=
@ -6593,17 +6652,17 @@ globby@^6.1.0:
pify "^2.0.0" pify "^2.0.0"
pinkie-promise "^2.0.0" pinkie-promise "^2.0.0"
got@^11.8.0, got@^11.8.2: got@^11.8.0, got@^11.8.3:
version "11.8.2" version "11.8.3"
resolved "https://registry.yarnpkg.com/got/-/got-11.8.2.tgz#7abb3959ea28c31f3576f1576c1effce23f33599" resolved "https://registry.yarnpkg.com/got/-/got-11.8.3.tgz#f496c8fdda5d729a90b4905d2b07dbd148170770"
integrity sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ== integrity sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==
dependencies: dependencies:
"@sindresorhus/is" "^4.0.0" "@sindresorhus/is" "^4.0.0"
"@szmarczak/http-timer" "^4.0.5" "@szmarczak/http-timer" "^4.0.5"
"@types/cacheable-request" "^6.0.1" "@types/cacheable-request" "^6.0.1"
"@types/responselike" "^1.0.0" "@types/responselike" "^1.0.0"
cacheable-lookup "^5.0.3" cacheable-lookup "^5.0.3"
cacheable-request "^7.0.1" cacheable-request "^7.0.2"
decompress-response "^6.0.0" decompress-response "^6.0.0"
http2-wrapper "^1.0.0-beta.5.2" http2-wrapper "^1.0.0-beta.5.2"
lowercase-keys "^2.0.0" lowercase-keys "^2.0.0"
@ -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"
@ -9885,6 +9951,11 @@ normalize-url@^4.1.0:
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a"
integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==
normalize-url@^6.0.1:
version "6.1.0"
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
npm-audit-report@^1.3.3: npm-audit-report@^1.3.3:
version "1.3.3" version "1.3.3"
resolved "https://registry.yarnpkg.com/npm-audit-report/-/npm-audit-report-1.3.3.tgz#8226deeb253b55176ed147592a3995442f2179ed" resolved "https://registry.yarnpkg.com/npm-audit-report/-/npm-audit-report-1.3.3.tgz#8226deeb253b55176ed147592a3995442f2179ed"
@ -10823,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"
@ -13527,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"
@ -13576,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"
@ -13674,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==