mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
project restructuring and initial refactoring
This commit is contained in:
1 parent
5af12bdbbd
commit
aa0eca2dc4
807 files changed
+11848
-22947
No files matched your search
Whitespace-only changes.
@@ -0,0 +1,112 @@
|
||||
import ElectronStore from "electron-store"
|
||||
import { Cluster, ClusterBaseInfo } from "../main/cluster";
|
||||
import * as version200Beta2 from "../migrations/cluster-store/2.0.0-beta.2"
|
||||
import * as version241 from "../migrations/cluster-store/2.4.1"
|
||||
import * as version260Beta2 from "../migrations/cluster-store/2.6.0-beta.2"
|
||||
import * as version260Beta3 from "../migrations/cluster-store/2.6.0-beta.3"
|
||||
import * as version270Beta0 from "../migrations/cluster-store/2.7.0-beta.0"
|
||||
import * as version270Beta1 from "../migrations/cluster-store/2.7.0-beta.1"
|
||||
|
||||
export class ClusterStore {
|
||||
private static instance: ClusterStore;
|
||||
public store: ElectronStore;
|
||||
|
||||
private constructor() {
|
||||
this.store = new ElectronStore({
|
||||
name: "lens-cluster-store",
|
||||
accessPropertiesByDotNotation: false, // To make dots safe in cluster context names
|
||||
migrations: {
|
||||
"2.0.0-beta.2": version200Beta2.migration,
|
||||
"2.4.1": version241.migration,
|
||||
"2.6.0-beta.2": version260Beta2.migration,
|
||||
"2.6.0-beta.3": version260Beta3.migration,
|
||||
"2.7.0-beta.0": version270Beta0.migration,
|
||||
"2.7.0-beta.1": version270Beta1.migration
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
public getAllClusterObjects(): Array<Cluster> {
|
||||
return this.store.get("clusters", []).map((clusterInfo: ClusterBaseInfo) => {
|
||||
return new Cluster(clusterInfo)
|
||||
})
|
||||
}
|
||||
|
||||
public getAllClusters(): Array<ClusterBaseInfo> {
|
||||
return this.store.get("clusters", [])
|
||||
}
|
||||
|
||||
public removeCluster(id: string): void {
|
||||
this.store.delete(id);
|
||||
const clusterBaseInfos = this.getAllClusters()
|
||||
const index = clusterBaseInfos.findIndex((cbi) => cbi.id === id)
|
||||
if (index !== -1) {
|
||||
clusterBaseInfos.splice(index, 1)
|
||||
this.store.set("clusters", clusterBaseInfos)
|
||||
}
|
||||
}
|
||||
|
||||
public removeClustersByWorkspace(workspace: string) {
|
||||
this.getAllClusters().forEach((cluster) => {
|
||||
if (cluster.workspace === workspace) {
|
||||
this.removeCluster(cluster.id)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
public getCluster(id: string): Cluster {
|
||||
const cluster = this.getAllClusterObjects().find((cluster) => cluster.id === id)
|
||||
if (cluster) {
|
||||
return cluster
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
public storeCluster(cluster: ClusterBaseInfo) {
|
||||
const clusters = this.getAllClusters();
|
||||
const index = clusters.findIndex((cl) => cl.id === cluster.id)
|
||||
const storable = {
|
||||
id: cluster.id,
|
||||
kubeConfig: cluster.kubeConfig,
|
||||
preferences: cluster.preferences,
|
||||
workspace: cluster.workspace
|
||||
}
|
||||
if (index === -1) {
|
||||
clusters.push(storable)
|
||||
}
|
||||
else {
|
||||
clusters[index] = storable
|
||||
}
|
||||
this.store.set("clusters", clusters)
|
||||
}
|
||||
|
||||
public storeClusters(clusters: ClusterBaseInfo[]) {
|
||||
clusters.forEach((cluster: ClusterBaseInfo) => {
|
||||
this.removeCluster(cluster.id)
|
||||
this.storeCluster(cluster)
|
||||
})
|
||||
}
|
||||
|
||||
public reloadCluster(cluster: ClusterBaseInfo): void {
|
||||
const storedCluster = this.getCluster(cluster.id);
|
||||
if (storedCluster) {
|
||||
cluster.kubeConfig = storedCluster.kubeConfig
|
||||
cluster.preferences = storedCluster.preferences
|
||||
cluster.workspace = storedCluster.workspace
|
||||
}
|
||||
}
|
||||
|
||||
static getInstance(): ClusterStore {
|
||||
if (!ClusterStore.instance) {
|
||||
ClusterStore.instance = new ClusterStore();
|
||||
}
|
||||
return ClusterStore.instance;
|
||||
}
|
||||
|
||||
static resetInstance() {
|
||||
ClusterStore.instance = null
|
||||
}
|
||||
}
|
||||
|
||||
export const clusterStore = ClusterStore.getInstance();
|
||||
@@ -0,0 +1,11 @@
|
||||
import { PrometheusLens } from "../main/prometheus/lens";
|
||||
import { PrometheusHelm } from "../main/prometheus/helm";
|
||||
import { PrometheusOperator } from "../main/prometheus/operator";
|
||||
import { PrometheusProviderRegistry } from "../main/prometheus/provider-registry";
|
||||
|
||||
[PrometheusLens, PrometheusHelm, PrometheusOperator].forEach(providerClass => {
|
||||
const provider = new providerClass()
|
||||
PrometheusProviderRegistry.registerProvider(provider.id, provider)
|
||||
});
|
||||
|
||||
export const prometheusProviders = PrometheusProviderRegistry.getProviders()
|
||||
@@ -0,0 +1,12 @@
|
||||
import request from "request"
|
||||
import { userStore } from "../common/user-store"
|
||||
|
||||
export function globalRequestOpts(requestOpts: request.Options ) {
|
||||
const userPrefs = userStore.getPreferences()
|
||||
if (userPrefs.httpsProxy) {
|
||||
requestOpts.proxy = userPrefs.httpsProxy
|
||||
}
|
||||
requestOpts.rejectUnauthorized = !userPrefs.allowUntrustedCAs;
|
||||
|
||||
return requestOpts
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import "mac-ca"
|
||||
import winca from "win-ca/api"
|
||||
import { isWindows } from "./vars";
|
||||
|
||||
if (isWindows) {
|
||||
winca.inject("+") // see: https://github.com/ukoloff/win-ca#caveats
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import ua from "universal-analytics"
|
||||
import { machineIdSync } from "node-machine-id"
|
||||
import { userStore } from "../common/user-store"
|
||||
|
||||
const GA_ID = "UA-159377374-1"
|
||||
|
||||
export class Tracker {
|
||||
protected visitor: ua.Visitor
|
||||
protected machineId: string = null;
|
||||
protected ip: string = null;
|
||||
protected appVersion: string;
|
||||
protected locale: string;
|
||||
protected electronUA: string;
|
||||
|
||||
constructor(app: Electron.App) {
|
||||
try {
|
||||
this.visitor = ua(GA_ID, machineIdSync(), {strictCidFormat: false})
|
||||
} catch (error) {
|
||||
this.visitor = ua(GA_ID)
|
||||
}
|
||||
this.visitor.set("dl", "https://lensapptelemetry.lakendlabs.com")
|
||||
}
|
||||
|
||||
public async event(eventCategory: string, eventAction: string) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
if (!this.telemetryAllowed()) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
this.visitor.event({
|
||||
ec: eventCategory,
|
||||
ea: eventAction
|
||||
}).send()
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
|
||||
protected telemetryAllowed() {
|
||||
const userPrefs = userStore.getPreferences()
|
||||
return !!userPrefs.allowTelemetry
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
import ElectronStore from "electron-store"
|
||||
import * as version210Beta4 from "../migrations/user-store/2.1.0-beta.4"
|
||||
|
||||
export interface User {
|
||||
id?: string;
|
||||
}
|
||||
|
||||
export interface UserPreferences {
|
||||
httpsProxy?: string;
|
||||
colorTheme?: string;
|
||||
allowUntrustedCAs?: boolean;
|
||||
allowTelemetry?: boolean;
|
||||
downloadMirror?: string;
|
||||
}
|
||||
|
||||
export class UserStore {
|
||||
private static instance: UserStore;
|
||||
public store: ElectronStore;
|
||||
|
||||
private constructor() {
|
||||
this.store = new ElectronStore({
|
||||
migrations: {
|
||||
"2.1.0-beta.4": version210Beta4.migration,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public lastSeenAppVersion() {
|
||||
return this.store.get('lastSeenAppVersion', "0.0.0")
|
||||
}
|
||||
|
||||
public setLastSeenAppVersion(version: string) {
|
||||
this.store.set('lastSeenAppVersion', version)
|
||||
}
|
||||
|
||||
public getSeenContexts(): Array<string> {
|
||||
return this.store.get("seenContexts", [])
|
||||
}
|
||||
|
||||
public storeSeenContext(newContexts: string[]) {
|
||||
const seenContexts = this.getSeenContexts().concat(newContexts)
|
||||
// store unique contexts by casting array to set first
|
||||
const newContextSet = new Set(seenContexts)
|
||||
const allContexts = [...newContextSet]
|
||||
this.store.set("seenContexts", allContexts)
|
||||
return allContexts
|
||||
}
|
||||
|
||||
public setPreferences(preferences: UserPreferences) {
|
||||
this.store.set('preferences', preferences)
|
||||
}
|
||||
|
||||
public getPreferences(): UserPreferences {
|
||||
const prefs = this.store.get("preferences", {})
|
||||
if (!prefs.colorTheme) {
|
||||
prefs.colorTheme = "dark"
|
||||
}
|
||||
if (!prefs.downloadMirror) {
|
||||
prefs.downloadMirror = "default"
|
||||
}
|
||||
if (prefs.allowTelemetry === undefined) {
|
||||
prefs.allowTelemetry = true
|
||||
}
|
||||
|
||||
return prefs
|
||||
}
|
||||
|
||||
static getInstance(): UserStore {
|
||||
if (!UserStore.instance) {
|
||||
UserStore.instance = new UserStore();
|
||||
}
|
||||
return UserStore.instance;
|
||||
}
|
||||
|
||||
static resetInstance() {
|
||||
UserStore.instance = null
|
||||
}
|
||||
}
|
||||
|
||||
const userStore: UserStore = UserStore.getInstance();
|
||||
|
||||
export { userStore };
|
||||
@@ -0,0 +1,9 @@
|
||||
import { app, remote } from "electron"
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns app version correctly regardless of dev/prod mode and main/renderer differences
|
||||
*/
|
||||
export function getAppVersion(): string {
|
||||
return (app || remote.app).getVersion();
|
||||
}
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
// Encode/decode utf-8 base64 string
|
||||
import * as Base64 from "crypto-js/enc-base64";
|
||||
import * as Utf8 from "crypto-js/enc-utf8";
|
||||
|
||||
export const base64 = {
|
||||
decode(data: string) {
|
||||
return Base64.parse(data).toString(Utf8);
|
||||
},
|
||||
encode(data: string) {
|
||||
return Utf8.parse(data).toString(Base64);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
// Convert object's keys to camelCase format
|
||||
import { camelCase, isPlainObject } from "lodash";
|
||||
|
||||
export function toCamelCase(obj: Record<string, any>): any {
|
||||
if (Array.isArray(obj)) {
|
||||
return obj.map(toCamelCase);
|
||||
}
|
||||
else if (isPlainObject(obj)) {
|
||||
return Object.keys(obj).reduce((result, key) => {
|
||||
const value = obj[key];
|
||||
result[camelCase(key)] = typeof value === "object" ? toCamelCase(value) : value;
|
||||
return result;
|
||||
}, {} as any);
|
||||
}
|
||||
else {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// Common utils bundle
|
||||
|
||||
export * from "./app-version"
|
||||
export * from "./base64"
|
||||
export * from "./camelCase"
|
||||
@@ -0,0 +1,24 @@
|
||||
// App's common paths/flags/etc. for any process
|
||||
import packageInfo from "../package.json"
|
||||
import path from "path";
|
||||
|
||||
const { main, renderer } = packageInfo.electronWebpack;
|
||||
|
||||
export const outDir = path.resolve(__dirname, "../dist");
|
||||
export const mainDir = path.resolve(__dirname, "../", main.sourceDirectory);
|
||||
export const rendererDir = path.resolve(__dirname, "../", renderer.sourceDirectory);
|
||||
|
||||
export const isMac = process.platform === "darwin"
|
||||
export const isWindows = process.platform === "win32"
|
||||
export const isProduction = process.env.NODE_ENV === "production"
|
||||
export const isDevelopment = !isProduction;
|
||||
export const buildVersion = process.env.BUILD_VERSION;
|
||||
|
||||
export const apiPrefix = {
|
||||
BASE: '/api',
|
||||
TERMINAL: '/api-terminal', // terminal api
|
||||
KUBE_BASE: '/api-kube', // kubernetes cluster api
|
||||
KUBE_USERS: '/api-users', // users & groups api
|
||||
KUBE_HELM: '/api-helm', // helm charts api
|
||||
KUBE_RESOURCE_APPLIER: "/api-resource",
|
||||
};
|
||||
@@ -0,0 +1,78 @@
|
||||
import ElectronStore from "electron-store"
|
||||
import { clusterStore } from "./cluster-store"
|
||||
|
||||
export interface WorkspaceData {
|
||||
id: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export class Workspace implements WorkspaceData {
|
||||
public id: string
|
||||
public name: string
|
||||
public description?: string
|
||||
|
||||
public constructor(data: WorkspaceData) {
|
||||
Object.assign(this, data)
|
||||
}
|
||||
}
|
||||
|
||||
export class WorkspaceStore {
|
||||
public static defaultId = "default"
|
||||
private static instance: WorkspaceStore;
|
||||
public store: ElectronStore;
|
||||
|
||||
private constructor() {
|
||||
this.store = new ElectronStore({
|
||||
name: "lens-workspace-store"
|
||||
})
|
||||
}
|
||||
|
||||
public storeWorkspace(workspace: WorkspaceData) {
|
||||
const workspaces = this.getAllWorkspaces()
|
||||
const index = workspaces.findIndex((w) => w.id === workspace.id)
|
||||
if (index !== -1) {
|
||||
workspaces[index] = workspace
|
||||
} else {
|
||||
workspaces.push(workspace)
|
||||
}
|
||||
this.store.set("workspaces", workspaces)
|
||||
}
|
||||
|
||||
public removeWorkspace(workspace: Workspace) {
|
||||
if (workspace.id === WorkspaceStore.defaultId) {
|
||||
throw new Error("Cannot remove default workspace")
|
||||
}
|
||||
const workspaces = this.getAllWorkspaces()
|
||||
const index = workspaces.findIndex((w) => w.id === workspace.id)
|
||||
if (index !== -1) {
|
||||
clusterStore.removeClustersByWorkspace(workspace.id)
|
||||
workspaces.splice(index, 1)
|
||||
this.store.set("workspaces", workspaces)
|
||||
}
|
||||
}
|
||||
|
||||
public getAllWorkspaces(): Array<Workspace> {
|
||||
const workspacesData: WorkspaceData[] = this.store.get("workspaces", [])
|
||||
|
||||
return workspacesData.map((wsd) => new Workspace(wsd))
|
||||
}
|
||||
|
||||
static getInstance(): WorkspaceStore {
|
||||
if (!WorkspaceStore.instance) {
|
||||
WorkspaceStore.instance = new WorkspaceStore()
|
||||
}
|
||||
return WorkspaceStore.instance
|
||||
}
|
||||
}
|
||||
|
||||
const workspaceStore: WorkspaceStore = WorkspaceStore.getInstance()
|
||||
|
||||
if (!workspaceStore.getAllWorkspaces().find( ws => ws.id === WorkspaceStore.defaultId)) {
|
||||
workspaceStore.storeWorkspace({
|
||||
id: WorkspaceStore.defaultId,
|
||||
name: "default"
|
||||
})
|
||||
}
|
||||
|
||||
export { workspaceStore }
|
||||
Reference in new issue
Block a user