/** * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ import moment from "moment-timezone"; import path from "path"; import os from "os"; import type { editor } from "monaco-editor"; import merge from "lodash/merge"; import { defaultThemeId, defaultEditorFontFamily, defaultFontSize, defaultTerminalFontFamily } from "../vars"; import type { ObservableMap } from "mobx"; import { observable } from "mobx"; export interface KubeconfigSyncEntry extends KubeconfigSyncValue { filePath: string; } export interface KubeconfigSyncValue { } export interface TerminalConfig { fontSize: number; fontFamily: string; } export const defaultTerminalConfig: TerminalConfig = { fontSize: defaultFontSize, fontFamily: defaultTerminalFontFamily, }; interface BaseEditorConfiguration extends Required> { lineNumbers: NonNullable>; } export type EditorConfiguration = Required; export const defaultEditorConfig: EditorConfiguration = { tabSize: 2, lineNumbers: "on", fontSize: defaultFontSize, fontFamily: defaultEditorFontFamily, minimap: { enabled: true, side: "right", }, }; export type StoreType

= P extends PreferenceDescription ? Store : never; export interface PreferenceDescription { fromStore(val: T | undefined): R; toStore(val: R): T | undefined; } const httpsProxy: PreferenceDescription = { fromStore(val) { return val; }, toStore(val) { return val || undefined; }, }; const shell: PreferenceDescription = { fromStore(val) { return val; }, toStore(val) { return val || undefined; }, }; const colorTheme: PreferenceDescription = { fromStore(val) { return val || defaultThemeId; }, toStore(val) { if (!val || val === defaultThemeId) { return undefined; } return val; }, }; const terminalTheme: PreferenceDescription = { fromStore(val) { return val || ""; }, toStore(val) { return val || undefined; }, }; export const defaultLocaleTimezone = "UTC"; const localeTimezone: PreferenceDescription = { fromStore(val) { return val || moment.tz.guess(true) || defaultLocaleTimezone; }, toStore(val) { if (!val || val === moment.tz.guess(true) || val === defaultLocaleTimezone) { return undefined; } return val; }, }; const allowUntrustedCAs: PreferenceDescription = { fromStore(val) { return val ?? false; }, toStore(val) { if (!val) { return undefined; } return val; }, }; const allowErrorReporting: PreferenceDescription = { fromStore(val) { return val ?? true; }, toStore(val) { if (val === true) { return undefined; } return val; }, }; export interface DownloadMirror { url: string; label: string; platforms: Set; } export const defaultPackageMirror = "default"; const defaultDownloadMirrorData: DownloadMirror = { url: "https://storage.googleapis.com/kubernetes-release/release", label: "Default (Google)", platforms: new Set(["darwin", "win32", "linux"]), }; export const packageMirrors = new Map([ [defaultPackageMirror, defaultDownloadMirrorData], ["china", { url: "https://mirror.azure.cn/kubernetes/kubectl", label: "China (Azure)", platforms: new Set(["win32", "linux"]), }], ]); const downloadMirror: PreferenceDescription = { fromStore(val) { return !val || !packageMirrors.has(val) ? defaultPackageMirror : val; }, toStore(val) { if (!val || val === defaultPackageMirror) { return undefined; } return val; }, }; const downloadKubectlBinaries: PreferenceDescription = { fromStore(val) { return val ?? true; }, toStore(val) { if (val === true) { return undefined; } return val; }, }; const downloadBinariesPath: PreferenceDescription = { fromStore(val) { return val; }, toStore(val) { if (!val) { return undefined; } return val; }, }; const kubectlBinariesPath: PreferenceDescription = { fromStore(val) { return val; }, toStore(val) { if (!val) { return undefined; } return val; }, }; const openAtLogin: PreferenceDescription = { fromStore(val) { return val ?? false; }, toStore(val) { if (!val) { return undefined; } return val; }, }; const terminalCopyOnSelect: PreferenceDescription = { fromStore(val) { return val ?? false; }, toStore(val) { if (!val) { return undefined; } return val; }, }; const hiddenTableColumns: PreferenceDescription<[string, string[]][], Map>> = { fromStore(val) { return new Map( (val ?? []).map(([tableId, columnIds]) => [tableId, new Set(columnIds)]), ); }, toStore(val) { const res: [string, string[]][] = []; for (const [table, columns] of val) { if (columns.size) { res.push([table, Array.from(columns)]); } } return res.length ? res : undefined; }, }; const mainKubeFolder = path.join(os.homedir(), ".kube"); const syncKubeconfigEntries: PreferenceDescription> = { fromStore(val) { return observable.map( val ?.map(({ filePath, ...rest }) => [filePath, rest]) ?? [[mainKubeFolder, {}]], ); }, toStore(val) { if (val.size === 1 && val.has(mainKubeFolder)) { return undefined; } return Array.from(val, ([filePath, rest]) => ({ filePath, ...rest })); }, }; const editorConfiguration: PreferenceDescription | undefined, EditorConfiguration> = { fromStore(val) { return merge(defaultEditorConfig, val); }, toStore(val) { return val; }, }; const terminalConfig: PreferenceDescription = { fromStore(val) { return merge(defaultTerminalConfig, val); }, toStore(val) { return val; }, }; export type ExtensionRegistryLocation = "default" | "npmrc" | "custom"; export type ExtensionRegistry = { location: "default" | "npmrc"; customUrl?: undefined; } | { location: "custom"; customUrl: string; }; export const defaultExtensionRegistryUrlLocation = "default"; export const defaultExtensionRegistryUrl = "https://registry.npmjs.org"; const extensionRegistryUrl: PreferenceDescription = { fromStore(val) { return val ?? { location: defaultExtensionRegistryUrlLocation, }; }, toStore(val) { if (val.location === defaultExtensionRegistryUrlLocation) { return undefined; } return val; }, }; type PreferencesModelType = typeof DESCRIPTORS[field] extends PreferenceDescription ? T : never; type UserStoreModelType = typeof DESCRIPTORS[field] extends PreferenceDescription ? T : never; export type UserStoreFlatModel = { [field in keyof typeof DESCRIPTORS]: UserStoreModelType; }; export type UserPreferencesModel = { [field in keyof typeof DESCRIPTORS]: PreferencesModelType; } & { updateChannel: string }; export const DESCRIPTORS = { httpsProxy, shell, colorTheme, terminalTheme, localeTimezone, allowUntrustedCAs, allowErrorReporting, downloadMirror, downloadKubectlBinaries, downloadBinariesPath, kubectlBinariesPath, openAtLogin, hiddenTableColumns, syncKubeconfigEntries, editorConfiguration, terminalCopyOnSelect, terminalConfig, extensionRegistryUrl, };