diff --git a/src/common/user-store/preferences-helpers.ts b/src/common/user-store/preferences-helpers.ts index 59f201f55f..d23f9a89dd 100644 --- a/src/common/user-store/preferences-helpers.ts +++ b/src/common/user-store/preferences-helpers.ts @@ -200,6 +200,19 @@ const openAtLogin: PreferenceDescription = { }, }; +const extensionRegistryUrl: PreferenceDescription = { + fromStore(val) { + return val ?? false; + }, + toStore(val) { + if (val === false) { + return undefined; + } + + return val; + } +}; + const hiddenTableColumns: PreferenceDescription<[string, string[]][], Map>> = { fromStore(val) { return new Map( @@ -271,6 +284,7 @@ export const DESCRIPTORS = { downloadBinariesPath, kubectlBinariesPath, openAtLogin, + extensionRegistryUrl, hiddenTableColumns, syncKubeconfigEntries, editorConfiguration, diff --git a/src/common/user-store/user-store.ts b/src/common/user-store/user-store.ts index ee0022da1b..ad85065b9d 100644 --- a/src/common/user-store/user-store.ts +++ b/src/common/user-store/user-store.ts @@ -71,6 +71,22 @@ export class UserStore extends BaseStore /* implements UserStore @observable downloadBinariesPath?: string; @observable kubectlBinariesPath?: string; + /** + * The extension registry URL + * - If `true` then used the registry configured in the `~/.npmrc` + * - If `false` then the default location + * - If a string, then use that + */ + @observable extensionRegistryUrl: boolean | string; + + @computed get getUseConfiguredExtensionRegistryUrl(): boolean { + if (typeof this.extensionRegistryUrl === "boolean") { + return this.extensionRegistryUrl; + } + + return false; + } + /** * Download kubectl binaries matching cluster version */ @@ -209,6 +225,7 @@ export class UserStore extends BaseStore /* implements UserStore this.downloadBinariesPath = DESCRIPTORS.downloadBinariesPath.fromStore(preferences?.downloadBinariesPath); this.kubectlBinariesPath = DESCRIPTORS.kubectlBinariesPath.fromStore(preferences?.kubectlBinariesPath); this.openAtLogin = DESCRIPTORS.openAtLogin.fromStore(preferences?.openAtLogin); + this.extensionRegistryUrl = DESCRIPTORS.extensionRegistryUrl.fromStore(preferences?.extensionRegistryUrl); this.hiddenTableColumns.replace(DESCRIPTORS.hiddenTableColumns.fromStore(preferences?.hiddenTableColumns)); this.syncKubeconfigEntries.replace(DESCRIPTORS.syncKubeconfigEntries.fromStore(preferences?.syncKubeconfigEntries)); this.editorConfiguration = DESCRIPTORS.editorConfiguration.fromStore(preferences?.editorConfiguration); @@ -230,6 +247,7 @@ export class UserStore extends BaseStore /* implements UserStore downloadBinariesPath: DESCRIPTORS.downloadBinariesPath.toStore(this.downloadBinariesPath), kubectlBinariesPath: DESCRIPTORS.kubectlBinariesPath.toStore(this.kubectlBinariesPath), openAtLogin: DESCRIPTORS.openAtLogin.toStore(this.openAtLogin), + extensionRegistryUrl: DESCRIPTORS.extensionRegistryUrl.toStore(this.extensionRegistryUrl), hiddenTableColumns: DESCRIPTORS.hiddenTableColumns.toStore(this.hiddenTableColumns), syncKubeconfigEntries: DESCRIPTORS.syncKubeconfigEntries.toStore(this.syncKubeconfigEntries), editorConfiguration: DESCRIPTORS.editorConfiguration.toStore(this.editorConfiguration), diff --git a/src/renderer/components/+extensions/extensions.tsx b/src/renderer/components/+extensions/extensions.tsx index 97c9aa9e82..e40b5f08d2 100644 --- a/src/renderer/components/+extensions/extensions.tsx +++ b/src/renderer/components/+extensions/extensions.tsx @@ -47,6 +47,7 @@ import { Notice } from "./notice"; import { SettingLayout } from "../layout/setting-layout"; import { docsUrl } from "../../../common/vars"; import { dialog } from "../../remote-helpers"; +import { UserStore } from "../../../common/user-store"; function getMessageFromError(error: any): string { if (!error || typeof error !== "object") { @@ -299,9 +300,19 @@ async function unpackExtension(request: InstallRequestValidated, disposeDownload } } -const defaultBaseRegistryUrl = "https://registry.npmjs.com"; +export const defaultBaseRegistryUrl = "https://registry.npmjs.com"; async function getBaseRegistryUrl(): Promise { + const userStore = UserStore.getInstance(); + + if (userStore.extensionRegistryUrl === false) { + return defaultBaseRegistryUrl; + } + + if (typeof userStore.extensionRegistryUrl === "string") { + return userStore.extensionRegistryUrl; + } + try { const filteredEnv = Object.fromEntries( Object.entries(process.env) diff --git a/src/renderer/components/+preferences/application.tsx b/src/renderer/components/+preferences/application.tsx index ac05012f2f..60aa794f0a 100644 --- a/src/renderer/components/+preferences/application.tsx +++ b/src/renderer/components/+preferences/application.tsx @@ -29,6 +29,8 @@ import { Input } from "../input"; import { isWindows } from "../../../common/vars"; import { FormSwitch, Switcher } from "../switch"; import moment from "moment-timezone"; +import { defaultBaseRegistryUrl } from "../+extensions"; +import { Checkbox } from "../mui/checkbox"; const timezoneOptions: SelectOption[] = moment.tz.names().map(zone => ({ label: zone, @@ -43,8 +45,13 @@ export const Application = observer(() => { ? "powershell.exe" : "System default shell" ); - - const [shell, setShell] = React.useState(UserStore.getInstance().shell || ""); + const userStore = UserStore.getInstance(); + const [shell, setShell] = React.useState(userStore.shell || ""); + const [extensionRegistryUrl, setExtensionRegistryUrl] = React.useState( + typeof userStore.extensionRegistryUrl === "string" + ? userStore.extensionRegistryUrl + : "" + ); return (
@@ -53,8 +60,8 @@ export const Application = observer(() => { userStore.extensionRegistryUrl = extensionRegistryUrl} + /> + + The registry URL for installing extensions by name. +

@@ -79,8 +113,8 @@ export const Application = observer(() => { UserStore.getInstance().openAtLogin = v.target.checked} + checked={userStore.openAtLogin} + onChange={v => userStore.openAtLogin = v.target.checked} name="startup" /> } @@ -94,8 +128,8 @@ export const Application = observer(() => {