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

add no-unused-vars and no-unused-imports

added quotes: double, and remove ignore pattern

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2020-11-25 09:12:20 -05:00
parent 238756be72
commit 4ab4ccfc8c
196 changed files with 1167 additions and 799 deletions

View File

@ -1,62 +1,92 @@
const packageJson = require("./package.json");
module.exports = {
ignorePatterns: [
"**/node_modules/**/*",
"**/dist/**/*",
],
settings: {
react: {
version: packageJson.devDependencies.react || "detect",
}
},
overrides: [
{
files: [
"src/renderer/**/*.js",
"build/**/*.js",
"extensions/**/*.js"
"**/*.js"
],
extends: [
'eslint:recommended',
"eslint:recommended",
],
env: {
node: true
},
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
sourceType: "module",
},
plugins: [
"unused-imports"
],
rules: {
"indent": ["error", 2, {
"SwitchCase": 1,
}],
"no-unused-vars": "off",
"unused-imports/no-unused-imports": "error",
"unused-imports/no-unused-vars": [
"warn", {
"vars": "all",
"args": "after-used",
"ignoreRestSiblings": true,
}
],
"quotes": ["error", "double", {
"avoidEscape": true,
"allowTemplateLiterals": true,
}],
"semi": ["error", "always"],
"object-shorthand": "error",
}
},
{
files: [
"build/*.ts",
"src/**/*.ts",
"integration/**/*.ts",
"src/extensions/**/*.ts*",
"extensions/**/*.ts*",
"__mocks__/*.ts",
"**/*.ts",
],
parser: "@typescript-eslint/parser",
extends: [
'plugin:@typescript-eslint/recommended',
"plugin:@typescript-eslint/recommended",
],
plugins: [
"unused-imports"
],
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
sourceType: "module",
},
rules: {
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-empty-interface": "off",
"@typescript-eslint/no-unused-vars": "off",
"unused-imports/no-unused-imports-ts": "error",
"unused-imports/no-unused-vars-ts": [
"warn", {
"vars": "all",
"args": "after-used",
"ignoreRestSiblings": true,
}
],
"indent": ["error", 2, {
"SwitchCase": 1,
}],
"quotes": ["error", "double", {
"avoidEscape": true,
"allowTemplateLiterals": true,
}],
"semi": "off",
"@typescript-eslint/semi": ["error"],
"object-shorthand": "error",
@ -64,21 +94,24 @@ module.exports = {
},
{
files: [
"src/renderer/**/*.tsx",
"**/*.tsx",
],
parser: "@typescript-eslint/parser",
plugins: [
"unused-imports"
],
extends: [
'plugin:@typescript-eslint/recommended',
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
],
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
sourceType: "module",
jsx: true,
},
rules: {
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/interface-name-prefix": "off",
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/no-empty-interface": "off",
@ -87,9 +120,23 @@ module.exports = {
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/no-empty-function": "off",
"react/display-name": "off",
"@typescript-eslint/no-unused-vars": "off",
"unused-imports/no-unused-imports-ts": "error",
"unused-imports/no-unused-vars-ts": [
"warn", {
"vars": "all",
"args": "after-used",
"ignoreRestSiblings": true,
}
],
"indent": ["error", 2, {
"SwitchCase": 1,
}],
"quotes": ["error", "double", {
"avoidEscape": true,
"allowTemplateLiterals": true,
}],
"semi": "off",
"@typescript-eslint/semi": ["error"],
"object-shorthand": "error",

View File

@ -4,9 +4,7 @@ module.exports = {
app: {
getVersion: jest.fn().mockReturnValue("3.0.0"),
getLocale: jest.fn().mockRejectedValue("en"),
getPath: jest.fn((name: string) => {
return "tmp";
}),
getPath: jest.fn(() => "tmp"),
},
remote: {
app: {

View File

@ -92,12 +92,12 @@ class KubectlDownloader {
}
const downloadVersion = packageInfo.config.bundledKubectlVersion;
const baseDir = path.join(process.env.INIT_CWD, 'binaries', 'client');
const baseDir = path.join(process.env.INIT_CWD, "binaries", "client");
const downloads = [
{ platform: 'linux', arch: 'amd64', target: path.join(baseDir, 'linux', 'x64', 'kubectl') },
{ platform: 'darwin', arch: 'amd64', target: path.join(baseDir, 'darwin', 'x64', 'kubectl') },
{ platform: 'windows', arch: 'amd64', target: path.join(baseDir, 'windows', 'x64', 'kubectl.exe') },
{ platform: 'windows', arch: '386', target: path.join(baseDir, 'windows', 'ia32', 'kubectl.exe') }
{ platform: "linux", arch: "amd64", target: path.join(baseDir, "linux", "x64", "kubectl") },
{ platform: "darwin", arch: "amd64", target: path.join(baseDir, "darwin", "x64", "kubectl") },
{ platform: "windows", arch: "amd64", target: path.join(baseDir, "windows", "x64", "kubectl.exe") },
{ platform: "windows", arch: "386", target: path.join(baseDir, "windows", "ia32", "kubectl.exe") }
];
downloads.forEach((dlOpts) => {

View File

@ -1,8 +1,8 @@
const { notarize } = require('electron-notarize');
const { notarize } = require("electron-notarize");
exports.default = async function notarizing(context) {
const { electronPlatformName, appOutDir } = context;
if (electronPlatformName !== 'darwin') {
if (electronPlatformName !== "darwin") {
return;
}
if (!process.env.APPLEID || !process.env.APPLEIDPASS) {
@ -12,7 +12,7 @@ exports.default = async function notarizing(context) {
const appName = context.packager.appInfo.productFilename;
return await notarize({
appBundleId: 'io.kontena.lens-app',
appBundleId: "io.kontena.lens-app",
appPath: `${appOutDir}/${appName}.app`,
appleId: process.env.APPLEID,
appleIdPassword: process.env.APPLEIDPASS,

View File

@ -2,10 +2,10 @@ import { LensMainExtension } from "@k8slens/extensions";
export default class ExampleExtensionMain extends LensMainExtension {
onActivate() {
console.log('EXAMPLE EXTENSION MAIN: ACTIVATED', this.name, this.id);
console.log("EXAMPLE EXTENSION MAIN: ACTIVATED", this.name, this.id);
}
onDeactivate() {
console.log('EXAMPLE EXTENSION MAIN: DEACTIVATED', this.name, this.id);
console.log("EXAMPLE EXTENSION MAIN: DEACTIVATED", this.name, this.id);
}
}

View File

@ -1,8 +1,8 @@
const path = require('path');
const path = require("path");
module.exports = [
{
entry: './main.ts',
entry: "./main.ts",
context: __dirname,
target: "electron-main",
mode: "production",
@ -10,7 +10,7 @@ module.exports = [
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
use: "ts-loader",
exclude: /node_modules/,
},
],
@ -23,16 +23,16 @@ module.exports = [
}
],
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
extensions: [ ".tsx", ".ts", ".js" ],
},
output: {
libraryTarget: "commonjs2",
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
filename: "main.js",
path: path.resolve(__dirname, "dist"),
},
},
{
entry: './renderer.tsx',
entry: "./renderer.tsx",
context: __dirname,
target: "electron-renderer",
mode: "production",
@ -40,7 +40,7 @@ module.exports = [
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
use: "ts-loader",
exclude: /node_modules/,
},
],
@ -53,13 +53,13 @@ module.exports = [
}
],
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
extensions: [ ".tsx", ".ts", ".js" ],
},
output: {
libraryTarget: "commonjs2",
globalObject: "this",
filename: 'renderer.js',
path: path.resolve(__dirname, 'dist'),
filename: "renderer.js",
path: path.resolve(__dirname, "dist"),
},
},
];

View File

@ -1,8 +1,8 @@
const path = require('path');
const path = require("path");
module.exports = [
{
entry: './renderer.tsx',
entry: "./renderer.tsx",
context: __dirname,
target: "electron-renderer",
mode: "production",
@ -10,7 +10,7 @@ module.exports = [
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
use: "ts-loader",
exclude: /node_modules/,
},
],
@ -23,13 +23,13 @@ module.exports = [
}
],
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
extensions: [ ".tsx", ".ts", ".js" ],
},
output: {
libraryTarget: "commonjs2",
globalObject: "this",
filename: 'renderer.js',
path: path.resolve(__dirname, 'dist'),
filename: "renderer.js",
path: path.resolve(__dirname, "dist"),
},
},
];

View File

@ -1,10 +1,10 @@
import path from "path";
const outputPath = path.resolve(__dirname, 'dist');
const outputPath = path.resolve(__dirname, "dist");
export default [
{
entry: './main.ts',
entry: "./main.ts",
context: __dirname,
target: "electron-main",
mode: "production",
@ -12,7 +12,7 @@ export default [
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
use: "ts-loader",
exclude: /node_modules/,
},
],
@ -22,12 +22,12 @@ export default [
"mobx": "var global.Mobx",
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
extensions: [".tsx", ".ts", ".js"],
},
output: {
libraryTarget: "commonjs2",
globalObject: "this",
filename: 'main.js',
filename: "main.js",
path: outputPath,
},
},

View File

@ -7,15 +7,13 @@ export default class ClusterMetricsFeatureExtension extends LensRendererExtensio
{
title: "Metrics Stack",
components: {
Description: () => {
return (
<span>
Enable timeseries data visualization (Prometheus stack) for your cluster.
Install this only if you don't have existing Prometheus stack installed.
You can see preview of manifests <a href="https://github.com/lensapp/lens/tree/master/extensions/lens-metrics/resources" target="_blank">here</a>.
</span>
);
}
Description: () => (
<span>
Enable timeseries data visualization (Prometheus stack) for your cluster.
Install this only if you don&apos;t have existing Prometheus stack installed.
You can see preview of manifests <a href="https://github.com/lensapp/lens/tree/master/extensions/lens-metrics/resources" rel="noreferrer" target="_blank">here</a>.
</span>
)
},
feature: new MetricsFeature()
}

View File

@ -54,8 +54,8 @@ export class MetricsFeature extends ClusterFeature.Feature {
const storageClassApi = K8sApi.forCluster(cluster, K8sApi.StorageClass);
const scs = await storageClassApi.list();
this.templateContext.persistence.enabled = scs.some(sc => (
sc.metadata?.annotations?.['storageclass.kubernetes.io/is-default-class'] === 'true' ||
sc.metadata?.annotations?.['storageclass.beta.kubernetes.io/is-default-class'] === 'true'
sc.metadata?.annotations?.["storageclass.kubernetes.io/is-default-class"] === "true" ||
sc.metadata?.annotations?.["storageclass.beta.kubernetes.io/is-default-class"] === "true"
));
super.applyResources(cluster, path.join(__dirname, "../resources/"));

View File

@ -1,8 +1,8 @@
const path = require('path');
const path = require("path");
module.exports = [
{
entry: './renderer.tsx',
entry: "./renderer.tsx",
context: __dirname,
target: "electron-renderer",
mode: "production",
@ -10,7 +10,7 @@ module.exports = [
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
use: "ts-loader",
exclude: /node_modules/,
},
],
@ -23,13 +23,13 @@ module.exports = [
}
],
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
extensions: [ ".tsx", ".ts", ".js" ],
},
output: {
libraryTarget: "commonjs2",
globalObject: "this",
filename: 'renderer.js',
path: path.resolve(__dirname, 'dist'),
filename: "renderer.js",
path: path.resolve(__dirname, "dist"),
},
node: {
__dirname: false

View File

@ -1,8 +1,8 @@
const path = require('path');
const path = require("path");
module.exports = [
{
entry: './renderer.tsx',
entry: "./renderer.tsx",
context: __dirname,
target: "electron-renderer",
mode: "production",
@ -10,7 +10,7 @@ module.exports = [
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
use: "ts-loader",
exclude: /node_modules/,
},
],
@ -23,13 +23,13 @@ module.exports = [
}
],
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
extensions: [ ".tsx", ".ts", ".js" ],
},
output: {
libraryTarget: "commonjs2",
globalObject: "this",
filename: 'renderer.js',
path: path.resolve(__dirname, 'dist'),
filename: "renderer.js",
path: path.resolve(__dirname, "dist"),
},
},
];

View File

@ -1,8 +1,8 @@
const path = require('path');
const path = require("path");
module.exports = [
{
entry: './renderer.tsx',
entry: "./renderer.tsx",
context: __dirname,
target: "electron-renderer",
mode: "production",
@ -10,7 +10,7 @@ module.exports = [
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
use: "ts-loader",
exclude: /node_modules/,
},
],
@ -23,13 +23,13 @@ module.exports = [
}
],
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
extensions: [ ".tsx", ".ts", ".js" ],
},
output: {
libraryTarget: "commonjs2",
globalObject: "this",
filename: 'renderer.js',
path: path.resolve(__dirname, 'dist'),
filename: "renderer.js",
path: path.resolve(__dirname, "dist"),
},
},
];

View File

@ -1,8 +1,8 @@
const path = require('path');
const path = require("path");
module.exports = [
{
entry: './main.ts',
entry: "./main.ts",
context: __dirname,
target: "electron-main",
mode: "production",
@ -10,7 +10,7 @@ module.exports = [
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
use: "ts-loader",
exclude: /node_modules/,
},
],
@ -23,17 +23,17 @@ module.exports = [
}
],
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
extensions: [ ".tsx", ".ts", ".js" ],
},
output: {
libraryTarget: "commonjs2",
globalObject: "this",
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
filename: "main.js",
path: path.resolve(__dirname, "dist"),
},
},
{
entry: './renderer.tsx',
entry: "./renderer.tsx",
context: __dirname,
target: "electron-renderer",
mode: "production",
@ -41,7 +41,7 @@ module.exports = [
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
use: "ts-loader",
exclude: /node_modules/,
},
],
@ -55,13 +55,13 @@ module.exports = [
}
],
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
extensions: [ ".tsx", ".ts", ".js" ],
},
output: {
libraryTarget: "commonjs2",
globalObject: "this",
filename: 'renderer.js',
path: path.resolve(__dirname, 'dist'),
filename: "renderer.js",
path: path.resolve(__dirname, "dist"),
},
},
];

View File

@ -8,8 +8,9 @@ import { Application } from "spectron";
import * as util from "../helpers/utils";
import { spawnSync } from "child_process";
const describeif = (condition: boolean) => condition ? describe : describe.skip;
// eslint-disable-next-line unused-imports/no-unused-vars-ts
const itif = (condition: boolean) => condition ? it : it.skip;
const describeif = (condition: boolean) => condition ? describe : describe.skip;
jest.setTimeout(60000);
@ -82,18 +83,18 @@ describe("Lens integration tests", () => {
});
it('shows "add cluster"', async () => {
await app.electron.ipcRenderer.send('test-menu-item-click', "File", "Add Cluster");
await app.electron.ipcRenderer.send("test-menu-item-click", "File", "Add Cluster");
await app.client.waitUntilTextExists("h2", "Add Cluster");
});
describe("preferences page", () => {
it('shows "preferences"', async () => {
const appName: string = process.platform === "darwin" ? "Lens" : "File";
await app.electron.ipcRenderer.send('test-menu-item-click', appName, "Preferences");
await app.electron.ipcRenderer.send("test-menu-item-click", appName, "Preferences");
await app.client.waitUntilTextExists("h2", "Preferences");
});
it('ensures helm repos', async () => {
it("ensures helm repos", async () => {
await app.client.waitUntilTextExists("div.repos #message-bitnami", "bitnami"); // wait for the helm-cli to fetch the bitnami repo
await app.client.click("#HelmRepoSelect"); // click the repo select to activate the drop-down
await app.client.waitUntilTextExists("div.Select__option", ""); // wait for at least one option to appear (any text)
@ -101,8 +102,8 @@ describe("Lens integration tests", () => {
});
it.skip('quits Lens"', async () => {
await app.client.keys(['Meta', 'Q']);
await app.client.keys('Meta');
await app.client.keys(["Meta", "Q"]);
await app.client.keys("Meta");
});
});
@ -115,27 +116,27 @@ describe("Lens integration tests", () => {
}
});
it('creates new workspace', async () => {
it("creates new workspace", async () => {
await clickWhatsNew(app);
await app.client.click('#current-workspace .Icon');
await app.client.click("#current-workspace .Icon");
await app.client.click('a[href="/workspaces"]');
await app.client.click('.Workspaces button.Button');
await app.client.click(".Workspaces button.Button");
await app.client.keys("test-workspace");
await app.client.click('.Workspaces .Input.description input');
await app.client.click(".Workspaces .Input.description input");
await app.client.keys("test description");
await app.client.click('.Workspaces .workspace.editing .Icon');
await app.client.click(".Workspaces .workspace.editing .Icon");
await app.client.waitUntilTextExists(".workspace .name a", "test-workspace");
});
it('adds cluster in default workspace', async () => {
it("adds cluster in default workspace", async () => {
await addMinikubeCluster(app);
await app.client.waitUntilTextExists("pre.kube-auth-out", "Authentication proxy started");
await app.client.waitForExist(`iframe[name="minikube"]`);
await app.client.waitForVisible(".ClustersMenu .ClusterIcon.active");
});
it('adds cluster in test-workspace', async () => {
await app.client.click('#current-workspace .Icon');
it("adds cluster in test-workspace", async () => {
await app.client.click("#current-workspace .Icon");
await app.client.waitForVisible('.WorkspaceMenu li[title="test description"]');
await app.client.click('.WorkspaceMenu li[title="test description"]');
await addMinikubeCluster(app);
@ -143,10 +144,10 @@ describe("Lens integration tests", () => {
await app.client.waitForExist(`iframe[name="minikube"]`);
});
it('checks if default workspace has active cluster', async () => {
await app.client.click('#current-workspace .Icon');
await app.client.waitForVisible('.WorkspaceMenu > li:first-of-type');
await app.client.click('.WorkspaceMenu > li:first-of-type');
it("checks if default workspace has active cluster", async () => {
await app.client.click("#current-workspace .Icon");
await app.client.waitForVisible(".WorkspaceMenu > li:first-of-type");
await app.client.click(".WorkspaceMenu > li:first-of-type");
await app.client.waitForVisible(".ClustersMenu .ClusterIcon.active");
});
});
@ -190,7 +191,7 @@ describe("Lens integration tests", () => {
}
});
it('allows to add a cluster', async () => {
it("allows to add a cluster", async () => {
await addCluster();
clusterAdded = true;
});
@ -515,7 +516,7 @@ describe("Lens integration tests", () => {
}
});
it('shows default namespace', async () => {
it("shows default namespace", async () => {
expect(clusterAdded).toBe(true);
await app.client.click('a[href="/namespaces"]');
await app.client.waitUntilTextExists("div.TableCell", "default");
@ -539,7 +540,7 @@ describe("Lens integration tests", () => {
await app.client.waitUntilTextExists('a[href^="/pods"]', "Pods");
await app.client.click('a[href^="/pods"]');
await app.client.waitUntilTextExists("div.TableCell", "kube-apiserver");
await app.client.click('.Icon.new-dock-tab');
await app.client.click(".Icon.new-dock-tab");
await app.client.waitUntilTextExists("li.MenuItem.create-resource-tab", "Create resource");
await app.client.click("li.MenuItem.create-resource-tab");
await app.client.waitForVisible(".CreateResource div.ace_content");

View File

@ -342,6 +342,8 @@
"electron-builder": "^22.7.0",
"electron-notarize": "^0.3.0",
"eslint": "^7.7.0",
"eslint-plugin-react": "^7.21.5",
"eslint-plugin-unused-imports": "^1.0.0",
"file-loader": "^6.0.0",
"flex.box": "^3.4.4",
"fork-ts-checker-webpack-plugin": "^5.0.0",

View File

@ -15,8 +15,8 @@ describe("empty config", () => {
beforeEach(() => {
ClusterStore.resetInstance();
const mockOpts = {
'tmp': {
'lens-cluster-store.json': JSON.stringify({})
"tmp": {
"lens-cluster-store.json": JSON.stringify({})
}
};
mockFs(mockOpts);
@ -146,8 +146,8 @@ describe("config with existing clusters", () => {
beforeEach(() => {
ClusterStore.resetInstance();
const mockOpts = {
'tmp': {
'lens-cluster-store.json': JSON.stringify({
"tmp": {
"lens-cluster-store.json": JSON.stringify({
__internal__: {
migrations: {
version: "99.99.99"
@ -155,24 +155,24 @@ describe("config with existing clusters", () => {
},
clusters: [
{
id: 'cluster1',
kubeConfig: 'foo',
contextName: 'foo',
preferences: { terminalCWD: '/foo' },
workspace: 'default'
id: "cluster1",
kubeConfig: "foo",
contextName: "foo",
preferences: { terminalCWD: "/foo" },
workspace: "default"
},
{
id: 'cluster2',
kubeConfig: 'foo2',
contextName: 'foo2',
preferences: { terminalCWD: '/foo2' }
id: "cluster2",
kubeConfig: "foo2",
contextName: "foo2",
preferences: { terminalCWD: "/foo2" }
},
{
id: 'cluster3',
kubeConfig: 'foo',
contextName: 'foo',
preferences: { terminalCWD: '/foo' },
workspace: 'foo'
id: "cluster3",
kubeConfig: "foo",
contextName: "foo",
preferences: { terminalCWD: "/foo" },
workspace: "foo"
},
]
})
@ -188,27 +188,27 @@ describe("config with existing clusters", () => {
});
it("allows to retrieve a cluster", () => {
const storedCluster = clusterStore.getById('cluster1');
expect(storedCluster.id).toBe('cluster1');
expect(storedCluster.preferences.terminalCWD).toBe('/foo');
const storedCluster = clusterStore.getById("cluster1");
expect(storedCluster.id).toBe("cluster1");
expect(storedCluster.preferences.terminalCWD).toBe("/foo");
});
it("allows to delete a cluster", () => {
clusterStore.removeById('cluster2');
const storedCluster = clusterStore.getById('cluster1');
clusterStore.removeById("cluster2");
const storedCluster = clusterStore.getById("cluster1");
expect(storedCluster).toBeTruthy();
const storedCluster2 = clusterStore.getById('cluster2');
const storedCluster2 = clusterStore.getById("cluster2");
expect(storedCluster2).toBeUndefined();
});
it("allows getting all of the clusters", async () => {
const storedClusters = clusterStore.clustersList;
expect(storedClusters.length).toBe(3);
expect(storedClusters[0].id).toBe('cluster1');
expect(storedClusters[0].preferences.terminalCWD).toBe('/foo');
expect(storedClusters[1].id).toBe('cluster2');
expect(storedClusters[1].preferences.terminalCWD).toBe('/foo2');
expect(storedClusters[2].id).toBe('cluster3');
expect(storedClusters[0].id).toBe("cluster1");
expect(storedClusters[0].preferences.terminalCWD).toBe("/foo");
expect(storedClusters[1].id).toBe("cluster2");
expect(storedClusters[1].preferences.terminalCWD).toBe("/foo2");
expect(storedClusters[2].id).toBe("cluster3");
});
});
@ -216,14 +216,14 @@ describe("pre 2.0 config with an existing cluster", () => {
beforeEach(() => {
ClusterStore.resetInstance();
const mockOpts = {
'tmp': {
'lens-cluster-store.json': JSON.stringify({
"tmp": {
"lens-cluster-store.json": JSON.stringify({
__internal__: {
migrations: {
version: "1.0.0"
}
},
cluster1: 'kubeconfig content'
cluster1: "kubeconfig content"
})
}
};
@ -246,8 +246,8 @@ describe("pre 2.6.0 config with a cluster that has arrays in auth config", () =>
beforeEach(() => {
ClusterStore.resetInstance();
const mockOpts = {
'tmp': {
'lens-cluster-store.json': JSON.stringify({
"tmp": {
"lens-cluster-store.json": JSON.stringify({
__internal__: {
migrations: {
version: "2.4.1"
@ -272,8 +272,8 @@ describe("pre 2.6.0 config with a cluster that has arrays in auth config", () =>
const file = clusterStore.clustersList[0].kubeConfigPath;
const config = fs.readFileSync(file, "utf8");
const kc = yaml.safeLoad(config);
expect(kc.users[0].user['auth-provider'].config['access-token']).toBe("should be string");
expect(kc.users[0].user['auth-provider'].config['expiry']).toBe("should be string");
expect(kc.users[0].user["auth-provider"].config["access-token"]).toBe("should be string");
expect(kc.users[0].user["auth-provider"].config["expiry"]).toBe("should be string");
});
});
@ -281,8 +281,8 @@ describe("pre 2.6.0 config with a cluster icon", () => {
beforeEach(() => {
ClusterStore.resetInstance();
const mockOpts = {
'tmp': {
'lens-cluster-store.json': JSON.stringify({
"tmp": {
"lens-cluster-store.json": JSON.stringify({
__internal__: {
migrations: {
version: "2.4.1"
@ -310,8 +310,8 @@ describe("pre 2.6.0 config with a cluster icon", () => {
it("moves the icon into preferences", async () => {
const storedClusterData = clusterStore.clustersList[0];
expect(storedClusterData.hasOwnProperty('icon')).toBe(false);
expect(storedClusterData.preferences.hasOwnProperty('icon')).toBe(true);
expect(storedClusterData.hasOwnProperty("icon")).toBe(false);
expect(storedClusterData.preferences.hasOwnProperty("icon")).toBe(true);
expect(storedClusterData.preferences.icon.startsWith("data:;base64,")).toBe(true);
});
});
@ -320,8 +320,8 @@ describe("for a pre 2.7.0-beta.0 config without a workspace", () => {
beforeEach(() => {
ClusterStore.resetInstance();
const mockOpts = {
'tmp': {
'lens-cluster-store.json': JSON.stringify({
"tmp": {
"lens-cluster-store.json": JSON.stringify({
__internal__: {
migrations: {
version: "2.6.6"
@ -347,7 +347,7 @@ describe("for a pre 2.7.0-beta.0 config without a workspace", () => {
it("adds cluster to default workspace", async () => {
const storedClusterData = clusterStore.clustersList[0];
expect(storedClusterData.workspace).toBe('default');
expect(storedClusterData.workspace).toBe("default");
});
});
@ -355,8 +355,8 @@ describe("pre 3.6.0-beta.1 config with an existing cluster", () => {
beforeEach(() => {
ClusterStore.resetInstance();
const mockOpts = {
'tmp': {
'lens-cluster-store.json': JSON.stringify({
"tmp": {
"lens-cluster-store.json": JSON.stringify({
__internal__: {
migrations: {
version: "3.5.0"
@ -364,9 +364,9 @@ describe("pre 3.6.0-beta.1 config with an existing cluster", () => {
},
clusters: [
{
id: 'cluster1',
kubeConfig: 'kubeconfig content',
contextName: 'cluster',
id: "cluster1",
kubeConfig: "kubeconfig content",
contextName: "cluster",
preferences: {
icon: "store://icon_path",
}

View File

@ -3,9 +3,9 @@ import mockFs from "mock-fs";
jest.mock("electron", () => {
return {
app: {
getVersion: () => '99.99.99',
getPath: () => 'tmp',
getLocale: () => 'en'
getVersion: () => "99.99.99",
getPath: () => "tmp",
getLocale: () => "en"
}
};
});
@ -18,7 +18,7 @@ describe("user store tests", () => {
describe("for an empty config", () => {
beforeEach(() => {
UserStore.resetInstance();
mockFs({ tmp: { 'config.json': "{}" } });
mockFs({ tmp: { "config.json": "{}" } });
});
afterEach(() => {
@ -35,26 +35,26 @@ describe("user store tests", () => {
it("allows adding and listing seen contexts", () => {
const us = UserStore.getInstance<UserStore>();
us.seenContexts.add('foo');
us.seenContexts.add("foo");
expect(us.seenContexts.size).toBe(1);
us.seenContexts.add('foo');
us.seenContexts.add('bar');
us.seenContexts.add("foo");
us.seenContexts.add("bar");
expect(us.seenContexts.size).toBe(2); // check 'foo' isn't added twice
expect(us.seenContexts.has('foo')).toBe(true);
expect(us.seenContexts.has('bar')).toBe(true);
expect(us.seenContexts.has("foo")).toBe(true);
expect(us.seenContexts.has("bar")).toBe(true);
});
it("allows setting and getting preferences", () => {
const us = UserStore.getInstance<UserStore>();
us.preferences.httpsProxy = 'abcd://defg';
us.preferences.httpsProxy = "abcd://defg";
expect(us.preferences.httpsProxy).toBe('abcd://defg');
expect(us.preferences.httpsProxy).toBe("abcd://defg");
expect(us.preferences.colorTheme).toBe(UserStore.defaultTheme);
us.preferences.colorTheme = "light";
expect(us.preferences.colorTheme).toBe('light');
expect(us.preferences.colorTheme).toBe("light");
});
it("correctly resets theme to default value", async () => {
@ -80,11 +80,11 @@ describe("user store tests", () => {
beforeEach(() => {
UserStore.resetInstance();
mockFs({
'tmp': {
'config.json': JSON.stringify({
user: { username: 'foobar' },
preferences: { colorTheme: 'light' },
lastSeenAppVersion: '1.2.3'
"tmp": {
"config.json": JSON.stringify({
user: { username: "foobar" },
preferences: { colorTheme: "light" },
lastSeenAppVersion: "1.2.3"
})
}
});
@ -97,7 +97,7 @@ describe("user store tests", () => {
it("sets last seen app version to 0.0.0", () => {
const us = UserStore.getInstance<UserStore>();
expect(us.lastSeenAppVersion).toBe('0.0.0');
expect(us.lastSeenAppVersion).toBe("0.0.0");
});
});
});

View File

@ -3,9 +3,9 @@ import mockFs from "mock-fs";
jest.mock("electron", () => {
return {
app: {
getVersion: () => '99.99.99',
getPath: () => 'tmp',
getLocale: () => 'en'
getVersion: () => "99.99.99",
getPath: () => "tmp",
getLocale: () => "en"
}
};
});
@ -16,7 +16,7 @@ describe("workspace store tests", () => {
describe("for an empty config", () => {
beforeEach(async () => {
WorkspaceStore.resetInstance();
mockFs({ tmp: { 'lens-workspace-store.json': "{}" } });
mockFs({ tmp: { "lens-workspace-store.json": "{}" } });
await WorkspaceStore.getInstance<WorkspaceStore>().load();
});
@ -146,7 +146,7 @@ describe("workspace store tests", () => {
WorkspaceStore.resetInstance();
mockFs({
tmp: {
'lens-workspace-store.json': JSON.stringify({
"lens-workspace-store.json": JSON.stringify({
currentWorkspace: "abc",
workspaces: [{
id: "abc",

View File

@ -2,7 +2,7 @@ import path from "path";
import Config from "conf";
import { Options as ConfOptions } from "conf/dist/source/types";
import { app, ipcMain, IpcMainEvent, ipcRenderer, IpcRendererEvent, remote } from "electron";
import { action, IReactionOptions, observable, reaction, runInAction, toJS, when } from "mobx";
import { IReactionOptions, observable, reaction, runInAction, when } from "mobx";
import Singleton from "./utils/singleton";
import { getAppVersion } from "./utils/app-version";
import logger from "../main/logger";

View File

@ -16,7 +16,7 @@ export async function requestMain(channel: string, ...args: any[]) {
async function getSubFrames(): Promise<number[]> {
const subFrames: number[] = [];
clusterFrameMap.forEach((frameId, _) => {
clusterFrameMap.forEach(frameId => {
subFrames.push(frameId);
});
return subFrames;

View File

@ -7,7 +7,7 @@ import logger from "../main/logger";
import commandExists from "command-exists";
import { ExecValidationNotFoundError } from "./custom-errors";
export const kubeConfigDefaultPath = path.join(os.homedir(), '.kube', 'config');
export const kubeConfigDefaultPath = path.join(os.homedir(), ".kube", "config");
function resolveTilde(filePath: string) {
if (filePath[0] === "~" && (filePath[1] === "/" || filePath.length === 1)) {
@ -78,15 +78,15 @@ export function dumpConfigYaml(kubeConfig: Partial<KubeConfig>): string {
apiVersion: "v1",
kind: "Config",
preferences: {},
'current-context': kubeConfig.currentContext,
"current-context": kubeConfig.currentContext,
clusters: kubeConfig.clusters.map(cluster => {
return {
name: cluster.name,
cluster: {
'certificate-authority-data': cluster.caData,
'certificate-authority': cluster.caFile,
"certificate-authority-data": cluster.caData,
"certificate-authority": cluster.caFile,
server: cluster.server,
'insecure-skip-tls-verify': cluster.skipTLSVerify
"insecure-skip-tls-verify": cluster.skipTLSVerify
}
};
}),
@ -104,11 +104,11 @@ export function dumpConfigYaml(kubeConfig: Partial<KubeConfig>): string {
return {
name: user.name,
user: {
'client-certificate-data': user.certData,
'client-certificate': user.certFile,
'client-key-data': user.keyData,
'client-key': user.keyFile,
'auth-provider': user.authProvider,
"client-certificate-data": user.certData,
"client-certificate": user.certFile,
"client-key-data": user.keyData,
"client-key": user.keyFile,
"auth-provider": user.authProvider,
exec: user.exec,
token: user.token,
username: user.username,

View File

@ -1,5 +1,5 @@
import type { ThemeId } from "../renderer/theme.store";
import { app, remote } from 'electron';
import { app, remote } from "electron";
import semver from "semver";
import { readFile } from "fs-extra";
import { action, observable, reaction, toJS } from "mobx";
@ -9,7 +9,7 @@ import { getAppVersion } from "./utils/app-version";
import { kubeConfigDefaultPath, loadConfig } from "./kube-helpers";
import { appEventBus } from "./event-bus";
import logger from "../main/logger";
import path from 'path';
import path from "path";
export interface UserStoreModel {
kubeConfigPath: string;

View File

@ -2,7 +2,7 @@
export function debouncePromise<T, F extends any[]>(func: (...args: F) => T | Promise<T>, timeout = 0): (...args: F) => Promise<T> {
let timer: NodeJS.Timeout;
return (...params: any[]) => new Promise((resolve, reject) => {
return (...params: any[]) => new Promise(resolve => {
clearTimeout(timer);
timer = global.setTimeout(() => resolve(func.apply(this, params)), timeout);
});

View File

@ -1,5 +1,5 @@
// Helper to sanitize / escape special chars for passing to RegExp-constructor
export function escapeRegExp(str: string) {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}

View File

@ -112,7 +112,7 @@ export abstract class ClusterFeature {
fs.readdirSync(folderPath).forEach(filename => {
const file = path.join(folderPath, filename);
const raw = fs.readFileSync(file);
if (filename.endsWith('.hb')) {
if (filename.endsWith(".hb")) {
const template = hb.compile(raw.toString());
resources.push(template(this.templateContext));
} else {

View File

@ -160,7 +160,7 @@ export class ExtensionDiscovery {
if (path.relative(this.localFolderPath, filePath) === extensionFolderName) {
const extensionName: string | undefined = Object
.entries(this.packagesJson.dependencies)
.find(([_name, extensionFolder]) => filePath === extensionFolder)?.[0];
.find(([, extensionFolder]) => filePath === extensionFolder)?.[0];
if (extensionName !== undefined) {
delete this.packagesJson.dependencies[extensionName];
@ -242,7 +242,6 @@ export class ExtensionDiscovery {
isBundled?: boolean;
} = {}): Promise<InstalledExtension | null> {
let manifestJson: LensExtensionManifest;
let isEnabled: boolean;
try {
// check manifest file for existence

View File

@ -1,4 +1,4 @@
import AwaitLock from 'await-lock';
import AwaitLock from "await-lock";
import child_process from "child_process";
import fs from "fs-extra";
import path from "path";
@ -27,7 +27,7 @@ export class ExtensionInstaller {
}
get npmPath() {
return __non_webpack_require__.resolve('npm/bin/npm-cli');
return __non_webpack_require__.resolve("npm/bin/npm-cli");
}
installDependencies(): Promise<void> {

View File

@ -21,13 +21,9 @@ export class ExtensionsStore extends BaseStore<LensExtensionsStoreModel> {
@computed
get enabledExtensions() {
const extensions: string[] = [];
this.state.forEach((state, id) => {
if (state.enabled) {
extensions.push(state.name);
}
});
return extensions;
return Array.from(this.state.values())
.filter(({enabled}) => enabled)
.map(({name}) => name);
}
protected state = observable.map<LensExtensionId, LensExtensionState>();

View File

@ -1,5 +1,4 @@
import type { MenuRegistration } from "./registries/menu-registry";
import { observable } from "mobx";
import { LensExtension } from "./lens-extension";
import { WindowManager } from "../main/window-manager";
import { getExtensionPageUrl } from "./registries/page-registry";

View File

@ -1,6 +1,5 @@
import type { AppPreferenceRegistration, ClusterFeatureRegistration, KubeObjectDetailRegistration, KubeObjectMenuRegistration, KubeObjectStatusRegistration, PageMenuRegistration, PageRegistration, StatusBarRegistration, } from "./registries";
import type { Cluster } from "../main/cluster";
import { observable } from "mobx";
import { LensExtension } from "./lens-extension";
import { getExtensionPageUrl } from "./registries/page-registry";
@ -30,6 +29,7 @@ export class LensRendererExtension extends LensExtension {
/**
* Defines if extension is enabled for a given cluster. Defaults to `true`.
*/
// eslint-disable-next-line unused-imports/no-unused-vars-ts
async isEnabledForCluster(cluster: Cluster): Promise<Boolean> {
return true;
}

View File

@ -1,4 +1,4 @@
import { getExtensionPageUrl, globalPageRegistry, PageRegistration } from "../page-registry";
import { getExtensionPageUrl, globalPageRegistry } from "../page-registry";
import { LensExtension } from "../../lens-extension";
import React from "react";
@ -51,18 +51,18 @@ describe("globalPageRegistry", () => {
{
id: "test-page",
components: {
Page: () => React.createElement('Text')
Page: () => React.createElement("Text")
}
},
{
id: "another-page",
components: {
Page: () => React.createElement('Text')
Page: () => React.createElement("Text")
},
},
{
components: {
Page: () => React.createElement('Default')
Page: () => React.createElement("Default")
}
},
], ext);

View File

@ -1,7 +1,7 @@
// Extensions-api -> Register page menu items
import type { IconProps } from "../../renderer/components/icon";
import type React from "react";
import { action, computed } from "mobx";
import { action } from "mobx";
import { BaseRegistry } from "./base-registry";
import { LensExtension } from "../lens-extension";
import { RegisteredPage } from "./page-registry";

View File

@ -146,7 +146,7 @@ describe("create clusters", () => {
}
}));
mockedRequest.mockImplementationOnce(((uri: any, _options: any) => {
mockedRequest.mockImplementationOnce(((uri: any) => {
expect(uri).toBe(`http://localhost:${port}/api-kube/version`);
return Promise.resolve({ gitVersion: "1.2.3" });
}) as any);

View File

@ -31,10 +31,10 @@ import { Cluster } from "../cluster";
import { KubeAuthProxy } from "../kube-auth-proxy";
import { getFreePort } from "../port";
import { broadcastMessage } from "../../common/ipc";
import { ChildProcess, spawn, SpawnOptions } from "child_process";
import { ChildProcess, spawn } from "child_process";
import { bundledKubectlPath, Kubectl } from "../kubectl";
import { mock, MockProxy } from 'jest-mock-extended';
import { waitUntilUsed } from 'tcp-port-used';
import { mock, MockProxy } from "jest-mock-extended";
import { waitUntilUsed } from "tcp-port-used";
import { Readable } from "stream";
const mockBroadcastIpc = broadcastMessage as jest.MockedFunction<typeof broadcastMessage>;
@ -81,7 +81,7 @@ describe("kube auth proxy tests", () => {
listeners[`stdout/${event}`] = listener;
return mockedCP.stdout;
});
mockSpawn.mockImplementationOnce((command: string, args: readonly string[], options: SpawnOptions): ChildProcess => {
mockSpawn.mockImplementationOnce((command: string): ChildProcess => {
expect(command).toBe(bundledKubectlPath());
return mockedCP;
});

View File

@ -9,7 +9,7 @@ import { ContextHandler } from "./context-handler";
import { AuthorizationV1Api, CoreV1Api, KubeConfig, V1ResourceAttributes } from "@kubernetes/client-node";
import { Kubectl } from "./kubectl";
import { KubeconfigManager } from "./kubeconfig-manager";
import { getNodeWarningConditions, loadConfig, podHasIssues } from "../common/kube-helpers";
import { loadConfig } from "../common/kube-helpers";
import request, { RequestPromiseOptions } from "request-promise-native";
import { apiResources } from "../common/rbac";
import logger from "./logger";

View File

@ -3,8 +3,8 @@
* The dependency is not bundled to the production build.
*/
export const installDeveloperTools = async () => {
if (process.env.NODE_ENV === 'development') {
const { default: devToolsInstaller, REACT_DEVELOPER_TOOLS } = await import('electron-devtools-installer');
if (process.env.NODE_ENV === "development") {
const { default: devToolsInstaller, REACT_DEVELOPER_TOOLS } = await import("electron-devtools-installer");
return devToolsInstaller([REACT_DEVELOPER_TOOLS]);
}

View File

@ -11,7 +11,7 @@ export function exitApp() {
appEventBus.emit({ name: "service", action: "close" });
windowManager.hide();
clusterManager.stop();
logger.info('SERVICE:QUIT');
logger.info("SERVICE:QUIT");
setTimeout(() => {
app.exit();
}, 1000);

View File

@ -36,10 +36,10 @@ export class HelmChartManager {
public async getReadme(name: string, version = "") {
const helm = await helmCli.binaryPath();
if(version && version != "") {
const { stdout, stderr} = await promiseExec(`"${helm}" show readme ${this.repo.name}/${name} --version ${version}`).catch((error) => { throw(error.stderr);});
const { stdout } = await promiseExec(`"${helm}" show readme ${this.repo.name}/${name} --version ${version}`).catch((error) => { throw(error.stderr);});
return stdout;
} else {
const { stdout, stderr} = await promiseExec(`"${helm}" show readme ${this.repo.name}/${name}`).catch((error) => { throw(error.stderr);});
const { stdout } = await promiseExec(`"${helm}" show readme ${this.repo.name}/${name}`).catch((error) => { throw(error.stderr);});
return stdout;
}
}
@ -47,11 +47,11 @@ export class HelmChartManager {
public async getValues(name: string, version = "") {
const helm = await helmCli.binaryPath();
if(version && version != "") {
const { stdout, stderr} = await promiseExec(`"${helm}" show values ${this.repo.name}/${name} --version ${version}`).catch((error) => { throw(error.stderr);});
const { stdout } = await promiseExec(`"${helm}" show values ${this.repo.name}/${name} --version ${version}`).catch((error) => { throw(error.stderr);});
return stdout;
} else {
const { stdout, stderr} = await promiseExec(`"${helm}" show values ${this.repo.name}/${name}`).catch((error) => { throw(error.stderr);});
const { stdout } = await promiseExec(`"${helm}" show values ${this.repo.name}/${name}`).catch((error) => { throw(error.stderr);});
return stdout;
}
@ -59,12 +59,12 @@ export class HelmChartManager {
protected async cachedYaml(): Promise<CachedYaml> {
if (!(this.repo.name in this.cache)) {
const cacheFile = await fs.promises.readFile(this.repo.cacheFilePath, 'utf-8');
const cacheFile = await fs.promises.readFile(this.repo.cacheFilePath, "utf-8");
const data = yaml.safeLoad(cacheFile);
for(const key in data["entries"]) {
data["entries"][key].forEach((version: any) => {
version['repo'] = this.repo.name;
version['created'] = Date.parse(version.created).toString();
version["repo"] = this.repo.name;
version["created"] = Date.parse(version.created).toString();
});
}
this.cache[this.repo.name] = Buffer.from(JSON.stringify(data));

View File

@ -34,8 +34,8 @@ export class HelmReleaseManager {
generateName = "--generate-name";
name = "";
}
const { stdout, stderr } = await promiseExec(`"${helm}" install ${name} ${chart} --version ${version} -f ${fileName} --namespace ${namespace} --kubeconfig ${pathToKubeconfig} ${generateName}`).catch((error) => { throw(error.stderr);});
const releaseName = stdout.split("\n")[0].split(' ')[1].trim();
const { stdout } = await promiseExec(`"${helm}" install ${name} ${chart} --version ${version} -f ${fileName} --namespace ${namespace} --kubeconfig ${pathToKubeconfig} ${generateName}`).catch((error) => { throw(error.stderr);});
const releaseName = stdout.split("\n")[0].split(" ")[1].trim();
return {
log: stdout,
release: {
@ -54,7 +54,7 @@ export class HelmReleaseManager {
await fs.promises.writeFile(fileName, yaml.safeDump(values));
try {
const { stdout, stderr } = await promiseExec(`"${helm}" upgrade ${name} ${chart} --version ${version} -f ${fileName} --namespace ${namespace} --kubeconfig ${cluster.getProxyKubeconfigPath()}`).catch((error) => { throw(error.stderr);});
const { stdout } = await promiseExec(`"${helm}" upgrade ${name} ${chart} --version ${version} -f ${fileName} --namespace ${namespace} --kubeconfig ${cluster.getProxyKubeconfigPath()}`).catch((error) => { throw(error.stderr);});
return {
log: stdout,
release: this.getRelease(name, namespace, cluster)
@ -66,7 +66,7 @@ export class HelmReleaseManager {
public async getRelease(name: string, namespace: string, cluster: Cluster) {
const helm = await helmCli.binaryPath();
const {stdout, stderr} = await promiseExec(`"${helm}" status ${name} --output json --namespace ${namespace} --kubeconfig ${cluster.getProxyKubeconfigPath()}`).catch((error) => { throw(error.stderr);});
const { stdout } = await promiseExec(`"${helm}" status ${name} --output json --namespace ${namespace} --kubeconfig ${cluster.getProxyKubeconfigPath()}`).catch((error) => { throw(error.stderr);});
const release = JSON.parse(stdout);
release.resources = await this.getResources(name, namespace, cluster);
return release;
@ -74,26 +74,26 @@ export class HelmReleaseManager {
public async deleteRelease(name: string, namespace: string, pathToKubeconfig: string) {
const helm = await helmCli.binaryPath();
const { stdout, stderr } = await promiseExec(`"${helm}" delete ${name} --namespace ${namespace} --kubeconfig ${pathToKubeconfig}`).catch((error) => { throw(error.stderr);});
const { stdout } = await promiseExec(`"${helm}" delete ${name} --namespace ${namespace} --kubeconfig ${pathToKubeconfig}`).catch((error) => { throw(error.stderr);});
return stdout;
}
public async getValues(name: string, namespace: string, pathToKubeconfig: string) {
const helm = await helmCli.binaryPath();
const { stdout, stderr } = await promiseExec(`"${helm}" get values ${name} --all --output yaml --namespace ${namespace} --kubeconfig ${pathToKubeconfig}`).catch((error) => { throw(error.stderr);});
const { stdout, } = await promiseExec(`"${helm}" get values ${name} --all --output yaml --namespace ${namespace} --kubeconfig ${pathToKubeconfig}`).catch((error) => { throw(error.stderr);});
return stdout;
}
public async getHistory(name: string, namespace: string, pathToKubeconfig: string) {
const helm = await helmCli.binaryPath();
const {stdout, stderr} = await promiseExec(`"${helm}" history ${name} --output json --namespace ${namespace} --kubeconfig ${pathToKubeconfig}`).catch((error) => { throw(error.stderr);});
const { stdout } = await promiseExec(`"${helm}" history ${name} --output json --namespace ${namespace} --kubeconfig ${pathToKubeconfig}`).catch((error) => { throw(error.stderr);});
return JSON.parse(stdout);
}
public async rollback(name: string, namespace: string, revision: number, pathToKubeconfig: string) {
const helm = await helmCli.binaryPath();
const {stdout, stderr} = await promiseExec(`"${helm}" rollback ${name} ${revision} --namespace ${namespace} --kubeconfig ${pathToKubeconfig}`).catch((error) => { throw(error.stderr);});
const { stdout } = await promiseExec(`"${helm}" rollback ${name} ${revision} --namespace ${namespace} --kubeconfig ${pathToKubeconfig}`).catch((error) => { throw(error.stderr);});
return stdout;
}
@ -101,7 +101,7 @@ export class HelmReleaseManager {
const helm = await helmCli.binaryPath();
const kubectl = await cluster.kubeCtl.getPath();
const pathToKubeconfig = cluster.getProxyKubeconfigPath();
const { stdout } = await promiseExec(`"${helm}" get manifest ${name} --namespace ${namespace} --kubeconfig ${pathToKubeconfig} | "${kubectl}" get -n ${namespace} --kubeconfig ${pathToKubeconfig} -f - -o=json`).catch((error) => {
const { stdout } = await promiseExec(`"${helm}" get manifest ${name} --namespace ${namespace} --kubeconfig ${pathToKubeconfig} | "${kubectl}" get -n ${namespace} --kubeconfig ${pathToKubeconfig} -f - -o=json`).catch(() => {
return { stdout: JSON.stringify({items: []})};
});
return stdout;

View File

@ -77,7 +77,7 @@ export class HelmRepoManager extends Singleton {
}
try {
const repoConfigFile = this.helmEnv.HELM_REPOSITORY_CONFIG;
const { repositories }: HelmRepoConfig = await readFile(repoConfigFile, 'utf8')
const { repositories }: HelmRepoConfig = await readFile(repoConfigFile, "utf8")
.then((yamlContent: string) => yaml.safeLoad(yamlContent))
.catch(() => ({
repositories: []
@ -121,7 +121,7 @@ export class HelmRepoManager extends Singleton {
public async removeRepo({ name, url }: HelmRepo): Promise<string> {
logger.info(`[HELM]: removing repo "${name}" from ${url}`);
const helm = await helmCli.binaryPath();
const { stdout, stderr } = await promiseExec(`"${helm}" repo remove ${name}`).catch((error) => {
const { stdout } = await promiseExec(`"${helm}" repo remove ${name}`).catch((error) => {
throw(error.stderr);
});
return stdout;

View File

@ -85,7 +85,7 @@ class HelmService {
for (const key in entries) {
entries[key] = entries[key].filter((entry: any) => {
if (Array.isArray(entry)) {
return entry[0]['deprecated'] != true;
return entry[0]["deprecated"] != true;
}
return entry["deprecated"] != true;
});

View File

@ -77,6 +77,7 @@ app.on("ready", async () => {
// run proxy
try {
// eslint-disable-next-line unused-imports/no-unused-vars-ts
proxyServer = LensProxy.create(proxyPort, clusterManager);
} catch (error) {
logger.error(`Could not start proxy (127.0.0:${proxyPort}): ${error.message}`);
@ -108,7 +109,7 @@ app.on("ready", async () => {
});
app.on("activate", (event, hasVisibleWindows) => {
logger.info('APP:ACTIVATE', { hasVisibleWindows });
logger.info("APP:ACTIVATE", { hasVisibleWindows });
if (!hasVisibleWindows) {
windowManager.initMainWindow();
}
@ -116,7 +117,7 @@ app.on("activate", (event, hasVisibleWindows) => {
// Quit app on Cmd+Q (MacOS)
app.on("will-quit", (event) => {
logger.info('APP:QUIT');
logger.info("APP:QUIT");
appEventBus.emit({name: "app", action: "close"});
event.preventDefault(); // prevent app's default shutdown (e.g. required for telemetry, etc.)
clusterManager?.stop(); // close cluster connections

View File

@ -60,7 +60,7 @@ export class KubeAuthProxy {
this.exit();
});
this.proxyProcess.stdout.on('data', (data) => {
this.proxyProcess.stdout.on("data", (data) => {
let logItem = data.toString();
if (logItem.startsWith("Starting to serve on")) {
logItem = "Authentication proxy started\n";
@ -68,7 +68,7 @@ export class KubeAuthProxy {
this.sendIpcLogMessage({ data: logItem });
});
this.proxyProcess.stderr.on('data', (data) => {
this.proxyProcess.stderr.on("data", (data) => {
this.lastError = this.parseError(data.toString());
this.sendIpcLogMessage({ data: data.toString(), error: true });
});

View File

@ -41,7 +41,7 @@ export class KubeconfigManager {
* This way any user of the config does not need to know anything about the auth etc. details.
*/
protected async createProxyKubeconfig(): Promise<string> {
const { configDir, cluster, contextHandler } = this;
const { configDir, cluster } = this;
const { contextName, kubeConfigPath, id } = cluster;
const tempFile = path.join(configDir, `kubeconfig-${id}`);
const kubeConfig = loadConfig(kubeConfigPath);
@ -81,7 +81,7 @@ export class KubeconfigManager {
return;
}
logger.info('Deleting temporary kubeconfig: ' + this.tempFile);
logger.info("Deleting temporary kubeconfig: " + this.tempFile);
await fs.unlink(this.tempFile);
this.tempFile = undefined;
}

View File

@ -123,6 +123,10 @@ export class Kubectl {
}
public async getPath(bundled = false): Promise<string> {
if (bundled) {
return this.getBundledPath();
}
if (userStore.preferences?.downloadKubectlBinaries === false) {
return this.getPathFromPreferences();
}
@ -167,7 +171,7 @@ export class Kubectl {
return true;
}
let version: string = output.clientVersion.gitVersion;
if (version[0] === 'v') {
if (version[0] === "v") {
version = version.slice(1);
}
if (version === this.kubectlVersion) {
@ -274,7 +278,7 @@ export class Kubectl {
const kubectlPath = userStore.preferences?.downloadKubectlBinaries ? this.dirname : path.dirname(this.getPathFromPreferences());
const helmPath = helmCli.getBinaryDir();
const fsPromises = fs.promises;
const bashScriptPath = path.join(this.dirname, '.bash_set_path');
const bashScriptPath = path.join(this.dirname, ".bash_set_path");
let bashScript = "" + initScriptVersionString;
bashScript += "tempkubeconfig=\"$KUBECONFIG\"\n";
@ -297,7 +301,7 @@ export class Kubectl {
bashScript += "unset tempkubeconfig\n";
await fsPromises.writeFile(bashScriptPath, bashScript.toString(), { mode: 0o644 });
const zshScriptPath = path.join(this.dirname, '.zlogin');
const zshScriptPath = path.join(this.dirname, ".zlogin");
let zshScript = "" + initScriptVersionString;

View File

@ -121,12 +121,12 @@ export class LensBinary {
}
protected async untarBinary() {
return new Promise<void>((resolve, reject) => {
return new Promise<void>(resolve => {
this.logger.debug(`Extracting ${this.originalBinaryName} binary`);
tar.x({
file: this.tarPath,
cwd: this.dirname
}).then((_ => {
}).then((() => {
resolve();
}));
});

View File

@ -88,23 +88,23 @@ export class LensProxy {
proxySocket.setTimeout(0);
socket.setTimeout(0);
proxySocket.on('data', function (chunk) {
proxySocket.on("data", function (chunk) {
socket.write(chunk);
});
proxySocket.on('end', function () {
proxySocket.on("end", function () {
socket.end();
});
proxySocket.on('error', function (err) {
proxySocket.on("error", function () {
socket.write("HTTP/" + req.httpVersion + " 500 Connection error\r\n\r\n");
socket.end();
});
socket.on('data', function (chunk) {
socket.on("data", function (chunk) {
proxySocket.write(chunk);
});
socket.on('end', function () {
socket.on("end", function () {
proxySocket.end();
});
socket.on('error', function () {
socket.on("error", function () {
proxySocket.end();
});
}

View File

@ -65,31 +65,31 @@ export function buildMenu(windowManager: WindowManager) {
showAbout(browserWindow);
}
},
{ type: 'separator' },
{ type: "separator" },
{
label: 'Preferences',
accelerator: 'CmdOrCtrl+,',
label: "Preferences",
accelerator: "CmdOrCtrl+,",
click() {
navigate(preferencesURL());
}
},
{
label: 'Extensions',
accelerator: 'CmdOrCtrl+Shift+E',
label: "Extensions",
accelerator: "CmdOrCtrl+Shift+E",
click() {
navigate(extensionsURL());
}
},
{ type: 'separator' },
{ role: 'services' },
{ type: 'separator' },
{ role: 'hide' },
{ role: 'hideOthers' },
{ role: 'unhide' },
{ type: 'separator' },
{ type: "separator" },
{ role: "services" },
{ type: "separator" },
{ role: "hide" },
{ role: "hideOthers" },
{ role: "unhide" },
{ type: "separator" },
{
label: 'Quit',
accelerator: 'Cmd+Q',
label: "Quit",
accelerator: "Cmd+Q",
click() {
exitApp();
}
@ -101,16 +101,16 @@ export function buildMenu(windowManager: WindowManager) {
label: "File",
submenu: [
{
label: 'Add Cluster',
accelerator: 'CmdOrCtrl+Shift+A',
label: "Add Cluster",
accelerator: "CmdOrCtrl+Shift+A",
click() {
navigate(addClusterURL());
}
},
...activeClusterOnly([
{
label: 'Cluster Settings',
accelerator: 'CmdOrCtrl+Shift+S',
label: "Cluster Settings",
accelerator: "CmdOrCtrl+Shift+S",
click() {
navigate(clusterSettingsURL({
params: {
@ -121,32 +121,32 @@ export function buildMenu(windowManager: WindowManager) {
}
]),
...ignoreOnMac([
{ type: 'separator' },
{ type: "separator" },
{
label: 'Preferences',
accelerator: 'Ctrl+,',
label: "Preferences",
accelerator: "Ctrl+,",
click() {
navigate(preferencesURL());
}
},
{
label: 'Extensions',
accelerator: 'Ctrl+Shift+E',
label: "Extensions",
accelerator: "Ctrl+Shift+E",
click() {
navigate(extensionsURL());
}
}
]),
{ type: 'separator' },
{ type: "separator" },
{
role: 'close',
role: "close",
label: "Close Window"
},
...ignoreOnMac([
{ type: 'separator' },
{ type: "separator" },
{
label: 'Exit',
accelerator: 'Alt+F4',
label: "Exit",
accelerator: "Alt+F4",
click() {
exitApp();
}
@ -156,56 +156,56 @@ export function buildMenu(windowManager: WindowManager) {
};
const editMenu: MenuItemConstructorOptions = {
label: 'Edit',
label: "Edit",
submenu: [
{ role: 'undo' },
{ role: 'redo' },
{ type: 'separator' },
{ role: 'cut' },
{ role: 'copy' },
{ role: 'paste' },
{ role: 'delete' },
{ type: 'separator' },
{ role: 'selectAll' },
{ role: "undo" },
{ role: "redo" },
{ type: "separator" },
{ role: "cut" },
{ role: "copy" },
{ role: "paste" },
{ role: "delete" },
{ type: "separator" },
{ role: "selectAll" },
]
};
const viewMenu: MenuItemConstructorOptions = {
label: 'View',
label: "View",
submenu: [
{
label: 'Back',
accelerator: 'CmdOrCtrl+[',
label: "Back",
accelerator: "CmdOrCtrl+[",
click() {
webContents.getFocusedWebContents()?.goBack();
}
},
{
label: 'Forward',
accelerator: 'CmdOrCtrl+]',
label: "Forward",
accelerator: "CmdOrCtrl+]",
click() {
webContents.getFocusedWebContents()?.goForward();
}
},
{
label: 'Reload',
accelerator: 'CmdOrCtrl+R',
label: "Reload",
accelerator: "CmdOrCtrl+R",
click() {
windowManager.reload();
}
},
{ role: 'toggleDevTools' },
{ type: 'separator' },
{ role: 'resetZoom' },
{ role: 'zoomIn' },
{ role: 'zoomOut' },
{ type: 'separator' },
{ role: 'togglefullscreen' }
{ role: "toggleDevTools" },
{ type: "separator" },
{ role: "resetZoom" },
{ role: "zoomIn" },
{ role: "zoomOut" },
{ type: "separator" },
{ role: "togglefullscreen" }
]
};
const helpMenu: MenuItemConstructorOptions = {
role: 'help',
role: "help",
submenu: [
{
label: "What's new?",
@ -265,7 +265,7 @@ export function buildMenu(windowManager: WindowManager) {
if (isTestEnv) {
// this is a workaround for the test environment (spectron) not being able to directly access
// the application menus (https://github.com/electron-userland/spectron/issues/21)
ipcMain.on('test-menu-item-click', (event: IpcMainEvent, ...names: string[]) => {
ipcMain.on("test-menu-item-click", (event: IpcMainEvent, ...names: string[]) => {
let menu: Menu = Menu.getApplicationMenu();
const parentLabels: string[] = [];
let menuItem: MenuItem;
@ -286,7 +286,7 @@ export function buildMenu(windowManager: WindowManager) {
}
const { enabled, visible, click } = menuItem;
if (enabled === false || visible === false || typeof click !== 'function') {
if (enabled === false || visible === false || typeof click !== "function") {
logger.info(`[MENU:test-menu-item-click] Menu item ${menuPath} not clickable`);
return;
}

View File

@ -24,7 +24,7 @@ export class NodeShellSession extends ShellSession {
const shell = await this.kubectl.getPath();
let args = [];
if (this.createNodeShellPod(this.podId, this.nodeName)) {
await this.waitForRunningPod(this.podId).catch((error) => {
await this.waitForRunningPod(this.podId).catch(() => {
this.exit(1001);
});
}
@ -108,7 +108,7 @@ export class NodeShellSession extends ShellSession {
const req = await watch.watch(`/api/v1/namespaces/kube-system/pods`, {},
// callback is called for each received object.
(_type, obj) => {
(type, obj) => {
if (obj.metadata.name == podId && obj.status.phase === "Running") {
resolve(true);
}

View File

@ -1,4 +1,4 @@
import { EventEmitter } from 'events';
import { EventEmitter } from "events";
import { getFreePort } from "./port";
let newPort = 0;
@ -8,7 +8,7 @@ jest.mock("net", () => {
createServer() {
return new class MockServer extends EventEmitter {
listen = jest.fn(() => {
this.emit('listening');
this.emit("listening");
return this;
});
address = () => {

View File

@ -24,7 +24,7 @@ export class PrometheusLens implements PrometheusProvider {
public getQueries(opts: PrometheusQueryOpts): PrometheusQuery {
switch(opts.category) {
case 'cluster':
case "cluster":
return {
memoryUsage: `
sum(
@ -43,7 +43,7 @@ export class PrometheusLens implements PrometheusProvider {
fsSize: `sum(node_filesystem_size_bytes{kubernetes_node=~"${opts.nodes}", mountpoint="/"}) by (kubernetes_node)`,
fsUsage: `sum(node_filesystem_size_bytes{kubernetes_node=~"${opts.nodes}", mountpoint="/"} - node_filesystem_avail_bytes{kubernetes_node=~"${opts.nodes}", mountpoint="/"}) by (kubernetes_node)`
};
case 'nodes':
case "nodes":
return {
memoryUsage: `sum (node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes)) by (kubernetes_node)`,
memoryCapacity: `sum(kube_node_status_capacity{resource="memory"}) by (node)`,
@ -52,7 +52,7 @@ export class PrometheusLens implements PrometheusProvider {
fsSize: `sum(node_filesystem_size_bytes{mountpoint="/"}) by (kubernetes_node)`,
fsUsage: `sum(node_filesystem_size_bytes{mountpoint="/"} - node_filesystem_avail_bytes{mountpoint="/"}) by (kubernetes_node)`
};
case 'pods':
case "pods":
return {
cpuUsage: `sum(rate(container_cpu_usage_seconds_total{container!="POD",container!="",pod=~"${opts.pods}",namespace="${opts.namespace}"}[${this.rateAccuracy}])) by (${opts.selector})`,
cpuRequests: `sum(kube_pod_container_resource_requests{pod=~"${opts.pods}",resource="cpu",namespace="${opts.namespace}"}) by (${opts.selector})`,
@ -64,12 +64,12 @@ export class PrometheusLens implements PrometheusProvider {
networkReceive: `sum(rate(container_network_receive_bytes_total{pod=~"${opts.pods}",namespace="${opts.namespace}"}[${this.rateAccuracy}])) by (${opts.selector})`,
networkTransmit: `sum(rate(container_network_transmit_bytes_total{pod=~"${opts.pods}",namespace="${opts.namespace}"}[${this.rateAccuracy}])) by (${opts.selector})`
};
case 'pvc':
case "pvc":
return {
diskUsage: `sum(kubelet_volume_stats_used_bytes{persistentvolumeclaim="${opts.pvc}"}) by (persistentvolumeclaim, namespace)`,
diskCapacity: `sum(kubelet_volume_stats_capacity_bytes{persistentvolumeclaim="${opts.pvc}"}) by (persistentvolumeclaim, namespace)`
};
case 'ingress':
case "ingress":
const bytesSent = (ingress: string, statuses: string) =>
`sum(rate(nginx_ingress_controller_bytes_sent_sum{ingress="${ingress}", status=~"${statuses}"}[${this.rateAccuracy}])) by (ingress)`;
return {

View File

@ -32,7 +32,7 @@ export class PrometheusOperator implements PrometheusProvider {
public getQueries(opts: PrometheusQueryOpts): PrometheusQuery {
switch(opts.category) {
case 'cluster':
case "cluster":
return {
memoryUsage: `
sum(
@ -51,7 +51,7 @@ export class PrometheusOperator implements PrometheusProvider {
fsSize: `sum(node_filesystem_size_bytes{mountpoint="/"} * on (pod,namespace) group_left(node) kube_pod_info{node=~"${opts.nodes}"})`,
fsUsage: `sum(node_filesystem_size_bytes{mountpoint="/"} * on (pod,namespace) group_left(node) kube_pod_info{node=~"${opts.nodes}"} - node_filesystem_avail_bytes{mountpoint="/"} * on (pod,namespace) group_left(node) kube_pod_info{node=~"${opts.nodes}"})`
};
case 'nodes':
case "nodes":
return {
memoryUsage: `sum((node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes)) * on (pod,namespace) group_left(node) kube_pod_info) by (node)`,
memoryCapacity: `sum(kube_node_status_capacity{resource="memory"}) by (node)`,
@ -60,7 +60,7 @@ export class PrometheusOperator implements PrometheusProvider {
fsSize: `sum(node_filesystem_size_bytes{mountpoint="/"} * on (pod,namespace) group_left(node) kube_pod_info) by (node)`,
fsUsage: `sum((node_filesystem_size_bytes{mountpoint="/"} - node_filesystem_avail_bytes{mountpoint="/"}) * on (pod,namespace) group_left(node) kube_pod_info) by (node)`
};
case 'pods':
case "pods":
return {
cpuUsage: `sum(rate(container_cpu_usage_seconds_total{container!="POD",container!="",image!="",pod=~"${opts.pods}",namespace="${opts.namespace}"}[${this.rateAccuracy}])) by (${opts.selector})`,
cpuRequests: `sum(kube_pod_container_resource_requests{pod=~"${opts.pods}",resource="cpu",namespace="${opts.namespace}"}) by (${opts.selector})`,
@ -72,12 +72,12 @@ export class PrometheusOperator implements PrometheusProvider {
networkReceive: `sum(rate(container_network_receive_bytes_total{pod=~"${opts.pods}",namespace="${opts.namespace}"}[${this.rateAccuracy}])) by (${opts.selector})`,
networkTransmit: `sum(rate(container_network_transmit_bytes_total{pod=~"${opts.pods}",namespace="${opts.namespace}"}[${this.rateAccuracy}])) by (${opts.selector})`
};
case 'pvc':
case "pvc":
return {
diskUsage: `sum(kubelet_volume_stats_used_bytes{persistentvolumeclaim="${opts.pvc}"}) by (persistentvolumeclaim, namespace)`,
diskCapacity: `sum(kubelet_volume_stats_capacity_bytes{persistentvolumeclaim="${opts.pvc}"}) by (persistentvolumeclaim, namespace)`
};
case 'ingress':
case "ingress":
const bytesSent = (ingress: string, statuses: string) =>
`sum(rate(nginx_ingress_controller_bytes_sent_sum{ingress="${ingress}", status=~"${statuses}"}[${this.rateAccuracy}])) by (ingress)`;
return {

View File

@ -24,7 +24,7 @@ export class PrometheusStacklight implements PrometheusProvider {
public getQueries(opts: PrometheusQueryOpts): PrometheusQuery {
switch(opts.category) {
case 'cluster':
case "cluster":
return {
memoryUsage: `
sum(
@ -43,7 +43,7 @@ export class PrometheusStacklight implements PrometheusProvider {
fsSize: `sum(node_filesystem_size_bytes{node=~"${opts.nodes}", mountpoint="/"}) by (node)`,
fsUsage: `sum(node_filesystem_size_bytes{node=~"${opts.nodes}", mountpoint="/"} - node_filesystem_avail_bytes{node=~"${opts.nodes}", mountpoint="/"}) by (node)`
};
case 'nodes':
case "nodes":
return {
memoryUsage: `sum (node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes)) by (node)`,
memoryCapacity: `sum(kube_node_status_capacity{resource="memory"}) by (node)`,
@ -52,7 +52,7 @@ export class PrometheusStacklight implements PrometheusProvider {
fsSize: `sum(node_filesystem_size_bytes{mountpoint="/"}) by (node)`,
fsUsage: `sum(node_filesystem_size_bytes{mountpoint="/"} - node_filesystem_avail_bytes{mountpoint="/"}) by (node)`
};
case 'pods':
case "pods":
return {
cpuUsage: `sum(rate(container_cpu_usage_seconds_total{container!="POD",container!="",pod=~"${opts.pods}",namespace="${opts.namespace}"}[${this.rateAccuracy}])) by (${opts.selector})`,
cpuRequests: `sum(kube_pod_container_resource_requests{pod=~"${opts.pods}",resource="cpu",namespace="${opts.namespace}"}) by (${opts.selector})`,
@ -64,12 +64,12 @@ export class PrometheusStacklight implements PrometheusProvider {
networkReceive: `sum(rate(container_network_receive_bytes_total{pod=~"${opts.pods}",namespace="${opts.namespace}"}[${this.rateAccuracy}])) by (${opts.selector})`,
networkTransmit: `sum(rate(container_network_transmit_bytes_total{pod=~"${opts.pods}",namespace="${opts.namespace}"}[${this.rateAccuracy}])) by (${opts.selector})`
};
case 'pvc':
case "pvc":
return {
diskUsage: `sum(kubelet_volume_stats_used_bytes{persistentvolumeclaim="${opts.pvc}"}) by (persistentvolumeclaim, namespace)`,
diskCapacity: `sum(kubelet_volume_stats_capacity_bytes{persistentvolumeclaim="${opts.pvc}"}) by (persistentvolumeclaim, namespace)`
};
case 'ingress':
case "ingress":
const bytesSent = (ingress: string, statuses: string) =>
`sum(rate(nginx_ingress_controller_bytes_sent_sum{ingress="${ingress}", status=~"${statuses}"}[${this.rateAccuracy}])) by (ingress)`;
return {

View File

@ -75,7 +75,7 @@ export class ResourceApplier {
delete resource.metadata?.resourceVersion;
const annotations = resource.metadata?.annotations;
if (annotations) {
delete annotations['kubectl.kubernetes.io/last-applied-configuration'];
delete annotations["kubectl.kubernetes.io/last-applied-configuration"];
}
return resource;
}

View File

@ -100,11 +100,11 @@ export class Router {
try {
const filename = path.basename(req.url);
// redirect requests to [appName].js, [appName].html /sockjs-node/ to webpack-dev-server (for hot-reload support)
const toWebpackDevServer = filename.includes(appName) || filename.includes('hot-update') || req.url.includes('sockjs-node');
const toWebpackDevServer = filename.includes(appName) || filename.includes("hot-update") || req.url.includes("sockjs-node");
if (isDevelopment && toWebpackDevServer) {
const redirectLocation = `http://localhost:${webpackDevServerPort}` + req.url;
res.statusCode = 307;
res.setHeader('Location', redirectLocation);
res.setHeader("Location", redirectLocation);
res.end();
return;
}
@ -126,8 +126,8 @@ export class Router {
protected addRoutes() {
// Static assets
this.router.add(
{ method: 'get', path: '/{path*}' },
({ params, response, path, raw: { req } }: LensApiRequest) => {
{ method: "get", path: "/{path*}" },
({ params, response, raw: { req } }: LensApiRequest) => {
this.handleStaticFile(params.path, response, req);
});

View File

@ -6,36 +6,36 @@ import { CoreV1Api, V1Secret } from "@kubernetes/client-node";
function generateKubeConfig(username: string, secret: V1Secret, cluster: Cluster) {
const tokenData = Buffer.from(secret.data["token"], "base64");
return {
'apiVersion': 'v1',
'kind': 'Config',
'clusters': [
"apiVersion": "v1",
"kind": "Config",
"clusters": [
{
'name': cluster.contextName,
'cluster': {
'server': cluster.apiUrl,
'certificate-authority-data': secret.data["ca.crt"]
"name": cluster.contextName,
"cluster": {
"server": cluster.apiUrl,
"certificate-authority-data": secret.data["ca.crt"]
}
}
],
'users': [
"users": [
{
'name': username,
'user': {
'token': tokenData.toString("utf8"),
"name": username,
"user": {
"token": tokenData.toString("utf8"),
}
}
],
'contexts': [
"contexts": [
{
'name': cluster.contextName,
'context': {
'user': username,
'cluster': cluster.contextName,
'namespace': secret.metadata.namespace,
"name": cluster.contextName,
"context": {
"user": username,
"cluster": cluster.contextName,
"namespace": secret.metadata.namespace,
}
}
],
'current-context': cluster.contextName
"current-context": cluster.contextName
};
}

View File

@ -72,7 +72,7 @@ class ApiWatcher {
class WatchRoute extends LensApi {
public async routeWatch(request: LensApiRequest) {
const { params, response, cluster} = request;
const { response, cluster} = request;
const apis: string[] = request.query.getAll("api");
const watchers: ApiWatcher[] = [];

View File

@ -73,7 +73,7 @@ export class ShellSession extends EventEmitter {
case "powershell.exe":
return ["-NoExit", "-command", `& {Set-Location $Env:USERPROFILE; $Env:PATH="${this.helmBinDir};${this.kubectlPathDir};$Env:PATH"}`];
case "bash":
return ["--init-file", path.join(this.kubectlBinDir, '.bash_set_path')];
return ["--init-file", path.join(this.kubectlBinDir, ".bash_set_path")];
case "fish":
return ["--login", "--init-command", `export PATH="${this.helmBinDir}:${this.kubectlPathDir}:$PATH"; export KUBECONFIG="${this.kubeconfigPath}"`];
case "zsh":
@ -156,7 +156,7 @@ export class ShellSession extends EventEmitter {
this.shellProcess.resize(resizeMsgObj["Width"], resizeMsgObj["Height"]);
break;
case "9":
this.emit('newToken', message);
this.emit("newToken", message);
break;
}
});
@ -164,7 +164,7 @@ export class ShellSession extends EventEmitter {
protected exit(code = 1000) {
if (this.websocket.readyState == this.websocket.OPEN) this.websocket.close(code);
this.emit('exit');
this.emit("exit");
}
protected closeWebsocketOnProcessExit() {

View File

@ -25,7 +25,7 @@ export async function shellSync() {
const env: Env = JSON.parse(JSON.stringify(envVars));
if (!env.LANG) {
// the LANG env var expects an underscore instead of electron's dash
env.LANG = `${app.getLocale().replace('-', '_')}.UTF-8`;
env.LANG = `${app.getLocale().replace("-", "_")}.UTF-8`;
} else if (!env.LANG.endsWith(".UTF-8")) {
env.LANG += ".UTF-8";
}

View File

@ -66,7 +66,7 @@ export function createTrayMenu(windowManager: WindowManager): Menu {
showAbout(browserWindow);
},
},
{ type: 'separator' },
{ type: "separator" },
{
label: "Open Lens",
async click() {
@ -91,7 +91,7 @@ export function createTrayMenu(windowManager: WindowManager): Menu {
submenu: clusters.map(cluster => {
const { id: clusterId, name: label, online, workspace } = cluster;
return {
label: `${online ? '✓' : '\x20'.repeat(3)/*offset*/}${label}`,
label: `${online ? "✓" : "\x20".repeat(3)/*offset*/}${label}`,
toolTip: clusterId,
async click() {
workspaceStore.setActive(workspace);
@ -115,9 +115,9 @@ export function createTrayMenu(windowManager: WindowManager): Menu {
}
},
},
{ type: 'separator' },
{ type: "separator" },
{
label: 'Quit App',
label: "Quit App",
click() {
exitApp();
}

View File

@ -5,12 +5,12 @@ import { migration } from "../migration-wrapper";
export default migration({
version: "2.0.0-beta.2",
run(store, log) {
run(store) {
for (const value of store) {
const contextName = value[0];
// Looping all the keys gives out the store internal stuff too...
if (contextName === "__internal__" || value[1].hasOwnProperty('kubeConfig')) continue;
if (contextName === "__internal__" || value[1].hasOwnProperty("kubeConfig")) continue;
store.set(contextName, { kubeConfig: value[1] });
}
}
});
});

View File

@ -3,7 +3,7 @@ import { migration } from "../migration-wrapper";
export default migration({
version: "2.4.1",
run(store, log) {
run(store) {
for (const value of store) {
const contextName = value[0];
if (contextName === "__internal__") continue;

View File

@ -3,7 +3,7 @@ import { migration } from "../migration-wrapper";
export default migration({
version: "2.6.0-beta.2",
run(store, log) {
run(store) {
for (const value of store) {
const clusterKey = value[0];
if (clusterKey === "__internal__") continue;

View File

@ -10,7 +10,7 @@ export default migration({
const cluster = value[1];
if (!cluster.kubeConfig) continue;
const kubeConfig = yaml.safeLoad(cluster.kubeConfig);
if (!kubeConfig.hasOwnProperty('users')) continue;
if (!kubeConfig.hasOwnProperty("users")) continue;
const userObj = kubeConfig.users[0];
if (userObj) {
const user = userObj.user;

View File

@ -3,7 +3,7 @@ import { migration } from "../migration-wrapper";
export default migration({
version: "2.7.0-beta.0",
run(store, log) {
run(store) {
for (const value of store) {
const clusterKey = value[0];
if (clusterKey === "__internal__") continue;

View File

@ -4,7 +4,7 @@ import { v4 as uuid } from "uuid";
export default migration({
version: "2.7.0-beta.1",
run(store, log) {
run(store) {
const clusters: any[] = [];
for (const value of store) {
const clusterKey = value[0];

View File

@ -44,7 +44,7 @@ export default migration({
const iconPath = cluster.preferences.icon.replace("store://", "");
const fileData = fse.readFileSync(path.join(userDataPath, iconPath));
cluster.preferences.icon = `data:;base64,${fileData.toString('base64')}`;
cluster.preferences.icon = `data:;base64,${fileData.toString("base64")}`;
} else {
delete cluster.preferences?.icon;
}

View File

@ -1,7 +1,7 @@
// Fix embedded kubeconfig paths under snap config
import { migration } from "../migration-wrapper";
import { ClusterModel, ClusterStore } from "../../common/cluster-store";
import { ClusterModel } from "../../common/cluster-store";
import { getAppVersion } from "../../common/utils/app-version";
import fs from "fs";

View File

@ -14,7 +14,7 @@ export class ApiManager {
return this.apis.get(pathOrCallback) || this.apis.get(KubeApi.parseApi(pathOrCallback).apiBase);
}
return Array.from(this.apis.values()).find(pathOrCallback ?? ((api: KubeApi) => true));
return Array.from(this.apis.values()).find(pathOrCallback ?? (() => true));
}
registerApi(apiBase: string, api: KubeApi) {

View File

@ -40,7 +40,7 @@ export class DeploymentApi extends KubeApi<Deployment> {
},
{
headers: {
'content-type': 'application/strategic-merge-patch+json'
"content-type": "application/strategic-merge-patch+json"
}
});
}

View File

@ -40,7 +40,7 @@ export const metricsApi = {
if (!start && !end) {
const timeNow = Date.now() / 1000;
const now = moment.unix(timeNow).startOf('minute').unix(); // round date to minutes
const now = moment.unix(timeNow).startOf("minute").unix(); // round date to minutes
start = now - range;
end = now;
}

View File

@ -7,8 +7,8 @@ import { KubeApi } from "../kube-api";
export class PersistentVolumeClaimsApi extends KubeApi<PersistentVolumeClaim> {
getMetrics(pvcName: string, namespace: string): Promise<IPvcMetrics> {
return metricsApi.getMetrics({
diskUsage: { category: 'pvc', pvc: pvcName },
diskCapacity: { category: 'pvc', pvc: pvcName }
diskUsage: { category: "pvc", pvc: pvcName },
diskCapacity: { category: "pvc", pvc: pvcName }
}, {
namespace
});

View File

@ -34,7 +34,7 @@ export interface JsonApiConfig {
export class JsonApi<D = JsonApiData, P extends JsonApiParams = JsonApiParams> {
static reqInitDefault: RequestInit = {
headers: {
'content-type': 'application/json'
"content-type": "application/json"
}
};
@ -132,9 +132,9 @@ export class JsonApi<D = JsonApiData, P extends JsonApiParams = JsonApiParams> {
protected writeLog(log: JsonApiLog) {
if (!this.config.debug) return;
const { method, reqUrl, ...params } = log;
let textStyle = 'font-weight: bold;';
if (params.data) textStyle += 'background: green; color: white;';
if (params.error) textStyle += 'background: red; color: white;';
let textStyle = "font-weight: bold;";
if (params.data) textStyle += "background: green; color: white;";
if (params.error) textStyle += "background: red; color: white;";
console.log(`%c${method} ${reqUrl}`, textStyle, params);
}
}

View File

@ -77,7 +77,7 @@ export function parseKubeApi(path: string): IKubeApiParsed {
* 3. otherwise assume apiVersion <- left[0]
* 4. always resource, name <- left[(0 or 1)+1..]
*/
if (left[0].includes('.') || left[1].match(/^v[0-9]/)) {
if (left[0].includes(".") || left[1].match(/^v[0-9]/)) {
[apiGroup, apiVersion] = left;
resource = left.slice(2).join("/");
} else {

View File

@ -142,7 +142,7 @@ export class KubeWatchApi {
protected writeLog(...data: any[]) {
if (isDevelopment) {
console.log('%cKUBE-WATCH-API:', `font-weight: bold`, ...data);
console.log("%cKUBE-WATCH-API:", `font-weight: bold`, ...data);
}
}

View File

@ -91,7 +91,6 @@ export class TerminalApi extends WebSocketApi {
}
reconnect() {
const { reconnectDelaySeconds } = this.params;
super.reconnect();
}

View File

@ -88,7 +88,7 @@ export class WebSocketApi {
reconnect() {
const { reconnectDelaySeconds } = this.params;
if (!reconnectDelaySeconds) return;
this.writeLog('reconnect after', reconnectDelaySeconds + "ms");
this.writeLog("reconnect after", reconnectDelaySeconds + "ms");
this.reconnectTimer = setTimeout(() => this.connect(), reconnectDelaySeconds * 1000);
this.readyState = WebSocketApiState.RECONNECTING;
}
@ -136,17 +136,17 @@ export class WebSocketApi {
this.onOpen.emit();
if (this.params.flushOnOpen) this.flush();
this.readyState = WebSocketApiState.OPEN;
this.writeLog('%cOPEN', 'color:green;font-weight:bold;', evt);
this.writeLog("%cOPEN", "color:green;font-weight:bold;", evt);
}
protected _onMessage(evt: MessageEvent) {
const data = this.parseMessage(evt.data);
this.onData.emit(data);
this.writeLog('%cMESSAGE', 'color:black;font-weight:bold;', data);
this.writeLog("%cMESSAGE", "color:black;font-weight:bold;", data);
}
protected _onError(evt: Event) {
this.writeLog('%cERROR', 'color:red;font-weight:bold;', evt);
this.writeLog("%cERROR", "color:red;font-weight:bold;", evt);
}
protected _onClose(evt: CloseEvent) {
@ -158,7 +158,7 @@ export class WebSocketApi {
this.readyState = WebSocketApiState.CLOSED;
this.onClose.emit();
}
this.writeLog('%cCLOSE', `color:${error ? "red" : "black"};font-weight:bold;`, evt);
this.writeLog("%cCLOSE", `color:${error ? "red" : "black"};font-weight:bold;`, evt);
}
protected writeLog(...data: any[]) {

View File

@ -12,7 +12,6 @@ import { DropFileInput, Input } from "../input";
import { AceEditor } from "../ace-editor";
import { Button } from "../button";
import { Icon } from "../icon";
import { WizardLayout } from "../layout/wizard-layout";
import { kubeConfigDefaultPath, loadConfig, splitConfig, validateConfig, validateKubeConfig } from "../../../common/kube-helpers";
import { ClusterModel, ClusterStore, clusterStore } from "../../../common/cluster-store";
import { workspaceStore } from "../../../common/workspace-store";
@ -67,7 +66,7 @@ export class AddCluster extends React.Component {
userStore.kubeConfigPath = filePath; // save to store
} catch (err) {
Notifications.error(
<div>Can't setup <code>{filePath}</code> as kubeconfig: {String(err)}</div>
<div>Can&apos;t setup <code>{filePath}</code> as kubeconfig: {String(err)}</div>
);
if (throwError) {
throw err;
@ -197,9 +196,9 @@ export class AddCluster extends React.Component {
return (
<p>
Add clusters by clicking the <span className="text-primary">Add Cluster</span> button.
You'll need to obtain a working kubeconfig for the cluster you want to add.
You&apos;ll need to obtain a working kubeconfig for the cluster you want to add.
You can either browse it from the file system or paste it as a text from the clipboard.
Read more about adding clusters <a href={`${docsUrl}/latest/clusters/adding-clusters/`} target="_blank">here</a>.
Read more about adding clusters <a href={`${docsUrl}/latest/clusters/adding-clusters/`} rel="noreferrer" target="_blank">here</a>.
</p>
);
}
@ -301,7 +300,7 @@ export class AddCluster extends React.Component {
);
}
onKubeConfigInputBlur = (evt: React.FocusEvent<HTMLInputElement>) => {
onKubeConfigInputBlur = () => {
const isChanged = this.kubeConfigPath !== userStore.kubeConfigPath;
if (isChanged) {
this.kubeConfigPath = this.kubeConfigPath.replace("~", os.homedir());
@ -357,7 +356,7 @@ export class AddCluster extends React.Component {
theme="round-black"
/>
<small className="hint">
{'A HTTP proxy server URL (format: http://<address>:<port>).'}
{"A HTTP proxy server URL (format: http://<address>:<port>)."}
</small>
</div>
)}

View File

@ -93,11 +93,11 @@ export class HelmChartDetails extends Component<Props> {
/>
</DrawerItem>
<DrawerItem name={_i18n._(t`Home`)}>
<a href={selectedChart.getHome()} target="_blank">{selectedChart.getHome()}</a>
<a href={selectedChart.getHome()} target="_blank" rel="noreferrer">{selectedChart.getHome()}</a>
</DrawerItem>
<DrawerItem name={_i18n._(t`Maintainers`)} className="maintainers">
{selectedChart.getMaintainers().map(({ name, email, url }) =>
<a key={name} href={url || `mailto:${email}`} target="_blank">{name}</a>
<a key={name} href={url || `mailto:${email}`} target="_blank" rel="noreferrer">{name}</a>
)}
</DrawerItem>
{selectedChart.getKeywords().length > 0 && (

View File

@ -84,7 +84,7 @@ export class HelmCharts extends Component<Props> {
]}
renderTableContents={(chart: HelmChart) => [
<figure>
<figure key="image">
<img
src={chart.getIcon() || require("./helm-placeholder.svg")}
onLoad={evt => evt.currentTarget.classList.add("visible")}

View File

@ -56,8 +56,9 @@ export class HelmReleaseMenu extends React.Component<Props> {
{...menuProps}
className={cssNames("HelmReleaseMenu", className)}
removeAction={this.remove}
children={this.renderContent()}
/>
>
{this.renderContent()}
</MenuActions>
);
}
}

View File

@ -70,7 +70,7 @@ export class HelmReleases extends Component<Props> {
<div>
<Trans>Remove <b>{releaseNames}</b>?</Trans>
<p className="warning">
<Trans>Note: StatefulSet Volumes won't be deleted automatically</Trans>
<Trans>Note: StatefulSet Volumes won&apos;t be deleted automatically</Trans>
</p>
</div>
);
@ -146,4 +146,4 @@ export class HelmReleases extends Component<Props> {
</>
);
}
}
}

View File

@ -19,7 +19,7 @@ export class ClusterAccessibleNamespaces extends React.Component<Props> {
return (
<>
<SubTitle title="Accessible Namespaces" />
<p><Trans>This setting is useful for manually specifying which namespaces you have access to. This is useful when you don't have permissions to list namespaces.</Trans></p>
<p><Trans>This setting is useful for manually specifying which namespaces you have access to. This is useful when you don&apos;t have permissions to list namespaces.</Trans></p>
<EditableList
placeholder={_i18n._("Add new namespace...")}
add={(newNamespace) => {

View File

@ -28,7 +28,7 @@ export class ClusterIconSetting extends React.Component<Props> {
try {
if (file) {
const buf = Buffer.from(await file.arrayBuffer());
cluster.preferences.icon = `data:${file.type};base64,${buf.toString('base64')}`;
cluster.preferences.icon = `data:${file.type};base64,${buf.toString("base64")}`;
} else {
// this has to be done as a seperate branch (and not always) because `cluster`
// is observable and triggers an update loop.

View File

@ -78,7 +78,7 @@ export class ClusterPrometheusSetting extends React.Component<Props> {
<SubTitle title="Prometheus"/>
<p>
Use pre-installed Prometheus service for metrics. Please refer to the{" "}
<a href="https://github.com/lensapp/lens/blob/master/troubleshooting/custom-prometheus.md" target="_blank">guide</a>{" "}
<a href="https://github.com/lensapp/lens/blob/master/troubleshooting/custom-prometheus.md" target="_blank" rel="noreferrer">guide</a>{" "}
for possible configuration changes.
</p>
<p>Prometheus installation method.</p>
@ -103,11 +103,11 @@ export class ClusterPrometheusSetting extends React.Component<Props> {
/>
<small className="hint">
An address to an existing Prometheus installation{" "}
({'<namespace>/<service>:<port>'}). Lens tries to auto-detect address if left empty.
({"<namespace>/<service>:<port>"}). Lens tries to auto-detect address if left empty.
</small>
</>
)}
</>
);
}
}
}

View File

@ -14,16 +14,18 @@ export class Features extends React.Component<Props> {
return (
<div>
<h2>Features</h2>
{ clusterFeatureRegistry.getItems().map((f) => {
return (
<InstallFeature cluster={cluster} feature={f.feature}>
<>
<SubTitle title={f.title}/>
<p><f.components.Description /></p>
</>
</InstallFeature>
);
})}
{
clusterFeatureRegistry
.getItems()
.map((f) => (
<InstallFeature key={f.title} cluster={cluster} feature={f.feature}>
<>
<SubTitle title={f.title} />
<p><f.components.Description /></p>
</>
</InstallFeature>
))
}
</div>
);
}

View File

@ -62,7 +62,7 @@ export class HorizontalPodAutoscalers extends React.Component<Props> {
]}
renderTableContents={(hpa: HorizontalPodAutoscaler) => [
hpa.getName(),
<KubeObjectStatusIcon object={hpa} />,
<KubeObjectStatusIcon key="icon" object={hpa} />,
hpa.getNs(),
this.getTargets(hpa),
hpa.getMinPods(),
@ -85,4 +85,3 @@ export class HorizontalPodAutoscalers extends React.Component<Props> {
);
}
}

View File

@ -5,11 +5,9 @@ import { observer } from "mobx-react";
import { Trans } from "@lingui/macro";
import { RouteComponentProps } from "react-router";
import { configMapsStore } from "./config-maps.store";
import { ConfigMap, configMapApi } from "../../api/endpoints/configmap.api";
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
import { ConfigMap } from "../../api/endpoints/configmap.api";
import { KubeObjectListLayout } from "../kube-object";
import { IConfigMapsRouteParams } from "./config-maps.route";
import { apiManager } from "../../api/api-manager";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
@ -48,7 +46,7 @@ export class ConfigMaps extends React.Component<Props> {
]}
renderTableContents={(configMap: ConfigMap) => [
configMap.getName(),
<KubeObjectStatusIcon object={configMap}/>,
<KubeObjectStatusIcon key="icon" object={configMap}/>,
configMap.getNs(),
configMap.getKeys().join(", "),
configMap.getAge(),
@ -57,4 +55,3 @@ export class ConfigMaps extends React.Component<Props> {
);
}
}

View File

@ -19,18 +19,17 @@ export class PodDisruptionBudgetDetails extends React.Component<Props> {
render() {
const { object: pdb } = this.props;
if (!pdb) return null;
const { status, spec } = pdb;
const selectors = pdb.getSelectors();
return (
<div className="PdbDetails">
<KubeObjectMeta object={pdb}/>
{selectors.length > 0 &&
<DrawerItem name={<Trans>Selector</Trans>} labelsOnly>
{
selectors.map(label => <Badge key={label} label={label}/>)
}
</DrawerItem>
<DrawerItem name={<Trans>Selector</Trans>} labelsOnly>
{
selectors.map(label => <Badge key={label} label={label}/>)
}
</DrawerItem>
}
<DrawerItem name={<Trans>Min Available</Trans>}>

View File

@ -3,13 +3,9 @@ import "./pod-disruption-budgets.scss";
import * as React from "react";
import { observer } from "mobx-react";
import { Trans } from "@lingui/macro";
import { RouteComponentProps } from "react-router";
import { podDisruptionBudgetsStore } from "./pod-disruption-budgets.store";
import { PodDisruptionBudget, pdbApi } from "../../api/endpoints/poddisruptionbudget.api";
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
import { PodDisruptionBudget } from "../../api/endpoints/poddisruptionbudget.api";
import { KubeObjectDetailsProps, KubeObjectListLayout } from "../kube-object";
import { IPodDisruptionBudgetsRouteParams } from "./pod-disruption-budgets.route";
import { apiManager } from "../../api/api-manager";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
@ -58,7 +54,7 @@ export class PodDisruptionBudgets extends React.Component<Props> {
renderTableContents={(pdb: PodDisruptionBudget) => {
return [
pdb.getName(),
<KubeObjectStatusIcon object={pdb} />,
<KubeObjectStatusIcon key="icon" object={pdb} />,
pdb.getNs(),
pdb.getMinAvailable(),
pdb.getMaxUnavailable(),

View File

@ -63,7 +63,7 @@ export class AddQuotaDialog extends React.Component<Props> {
@computed get quotaEntries() {
return Object.entries(this.quotas)
.filter(([type, value]) => !!value.trim());
.filter(([, value]) => !!value.trim());
}
@computed get quotaOptions() {
@ -201,4 +201,4 @@ export class AddQuotaDialog extends React.Component<Props> {
</Dialog>
);
}
}
}

View File

@ -16,8 +16,6 @@ import { ReplicaSetDetails } from "../+workloads-replicasets";
interface Props extends KubeObjectDetailsProps<ResourceQuota> {
}
const onlyNumbers = /$[0-9]*^/g;
function transformUnit(name: string, value: string): number {
if (name.includes("memory") || name.includes("storage")) {
return unitsToBytes(value);

View File

@ -4,13 +4,11 @@ import React from "react";
import { observer } from "mobx-react";
import { Trans } from "@lingui/macro";
import { RouteComponentProps } from "react-router";
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
import { KubeObjectListLayout } from "../kube-object";
import { ResourceQuota, resourceQuotaApi } from "../../api/endpoints/resource-quota.api";
import { ResourceQuota } from "../../api/endpoints/resource-quota.api";
import { AddQuotaDialog } from "./add-quota-dialog";
import { resourceQuotaStore } from "./resource-quotas.store";
import { IResourceQuotaRouteParams } from "./resource-quotas.route";
import { apiManager } from "../../api/api-manager";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
@ -47,7 +45,7 @@ export class ResourceQuotas extends React.Component<Props> {
]}
renderTableContents={(resourceQuota: ResourceQuota) => [
resourceQuota.getName(),
<KubeObjectStatusIcon object={resourceQuota}/>,
<KubeObjectStatusIcon key="icon" object={resourceQuota}/>,
resourceQuota.getNs(),
resourceQuota.getAge(),
]}

View File

@ -4,14 +4,12 @@ import React from "react";
import { observer } from "mobx-react";
import { Trans } from "@lingui/macro";
import { RouteComponentProps } from "react-router";
import { Secret, secretsApi } from "../../api/endpoints";
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
import { Secret } from "../../api/endpoints";
import { AddSecretDialog } from "./add-secret-dialog";
import { ISecretsRouteParams } from "./secrets.route";
import { KubeObjectListLayout } from "../kube-object";
import { Badge } from "../badge";
import { secretsStore } from "./secrets.store";
import { apiManager } from "../../api/api-manager";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
@ -57,7 +55,7 @@ export class Secrets extends React.Component<Props> {
]}
renderTableContents={(secret: Secret) => [
secret.getName(),
<KubeObjectStatusIcon object={secret} />,
<KubeObjectStatusIcon key="icon" object={secret} />,
secret.getNs(),
secret.getLabels().map(label => <Badge key={label} label={label}/>),
secret.getKeys().join(", "),

View File

@ -4,8 +4,7 @@ import React from "react";
import { Trans } from "@lingui/macro";
import { Link } from "react-router-dom";
import { observer } from "mobx-react";
import { apiManager } from "../../api/api-manager";
import { crdApi, CustomResourceDefinition } from "../../api/endpoints/crd.api";
import { CustomResourceDefinition } from "../../api/endpoints/crd.api";
import { cssNames } from "../../utils";
import { AceEditor } from "../ace-editor";
import { Badge } from "../badge";

View File

@ -90,19 +90,16 @@ export class CrdList extends React.Component {
{ title: <Trans>Scope</Trans>, className: "scope", sortBy: sortBy.scope },
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
]}
renderTableContents={(crd: CustomResourceDefinition) => {
return [
<Link to={crd.getResourceUrl()} onClick={stopPropagation}>
{crd.getResourceTitle()}
</Link>,
crd.getGroup(),
crd.getVersion(),
crd.getScope(),
crd.getAge(),
];
}}
renderTableContents={(crd: CustomResourceDefinition) => [
<Link key="link" to={crd.getResourceUrl()} onClick={stopPropagation}>
{crd.getResourceTitle()}
</Link>,
crd.getGroup(),
crd.getVersion(),
crd.getScope(),
crd.getAge(),
]}
/>
);
}
}

View File

@ -102,7 +102,7 @@ export class Events extends React.Component<Props> {
},
event.getNs(),
kind,
<Link to={detailsUrl} title={name} onClick={stopPropagation}>{name}</Link>,
<Link key="link" to={detailsUrl} title={name} onClick={stopPropagation}>{name}</Link>,
event.getSource(),
event.count,
event.getAge(),

View File

@ -120,7 +120,7 @@ export class Extensions extends React.Component {
};
installOnDrop = (files: File[]) => {
logger.info('Install from D&D');
logger.info("Install from D&D");
return this.requestInstall(
files.map(file => ({
fileName: path.basename(file.path),
@ -345,7 +345,7 @@ export class Extensions extends React.Component {
The features that Lens includes out-of-the-box are just the start.
Lens extensions let you add new features to your installation to support your workflow.
Rich extensibility model lets extension authors plug directly into the Lens UI and contribute functionality through the same APIs used by Lens itself.
Check out documentation to <a href={`${docsUrl}/latest/extensions/usage/`} target="_blank">learn more</a>.
Check out documentation to <a href={`${docsUrl}/latest/extensions/usage/`} target="_blank" rel="noreferrer">learn more</a>.
</div>
<div className="install-extension flex column gaps">
@ -378,7 +378,7 @@ export class Extensions extends React.Component {
onClick={this.installFromUrlOrPath}
/>
<small className="hint">
<Trans><b>Pro-Tip</b>: you can drag & drop extension's tarball-file to install</Trans>
<Trans><b>Pro-Tip</b>: you can drag & drop extension&apos;s tarball-file to install</Trans>
</small>
</div>

View File

@ -49,7 +49,7 @@ export class Namespaces extends React.Component<Props> {
]}
renderTableContents={(item: Namespace) => [
item.getName(),
<KubeObjectStatusIcon object={item} />,
<KubeObjectStatusIcon key="icon" object={item} />,
item.getLabels().map(label => <Badge key={label} label={label}/>),
item.getAge(),
{ title: item.getStatus(), className: item.getStatus().toLowerCase() },

Some files were not shown because too many files have changed in this diff Show More