diff --git a/.eslintrc.json b/.eslintrc.json index a66a6c7b17e..d3f8867d778 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -55,6 +55,7 @@ "@typescript-eslint/await-thenable": "error", "@typescript-eslint/no-floating-promises": "error", "@typescript-eslint/no-misused-promises": "error", + "@typescript-eslint/prefer-optional-chain": "error", /** * Having a semicolon helps the optimizer interpret your code correctly. diff --git a/extensions/podman/src/podman-configuration.ts b/extensions/podman/src/podman-configuration.ts index 1d0c8696d15..48917db8374 100644 --- a/extensions/podman/src/podman-configuration.ts +++ b/extensions/podman/src/podman-configuration.ts @@ -55,7 +55,7 @@ export class PodmanConfiguration { const containersConfigFile = await this.readContainersConfigFile(); const tomlConfigFile = toml.parse(containersConfigFile); - if (tomlConfigFile && tomlConfigFile.engine) { + if (tomlConfigFile?.engine) { // eslint-disable-next-line @typescript-eslint/no-explicit-any const engineConf: any = tomlConfigFile.engine; diff --git a/extensions/podman/src/podman-install.ts b/extensions/podman/src/podman-install.ts index 3be4f96492e..0990a85d88b 100755 --- a/extensions/podman/src/podman-install.ts +++ b/extensions/podman/src/podman-install.ts @@ -149,11 +149,7 @@ export class PodmanInstall { const installer = this.getInstaller(); const bundledVersion = getBundledPodmanVersion(); - if ( - installer && - installer.requireUpdate(installedVersion) && - this.podmanInfo.ignoreVersionUpdate !== bundledVersion - ) { + if (installer?.requireUpdate(installedVersion) && this.podmanInfo.ignoreVersionUpdate !== bundledVersion) { return { installedVersion, hasUpdate: true, bundledVersion }; } return { installedVersion, hasUpdate: false, bundledVersion }; diff --git a/packages/main/src/mainWindow.ts b/packages/main/src/mainWindow.ts index 7b35aeb3f9a..2489e7b0a9c 100644 --- a/packages/main/src/mainWindow.ts +++ b/packages/main/src/mainWindow.ts @@ -193,7 +193,7 @@ async function createWindow() { // In development mode, show the "Open DevTools of Extension" menu item if (import.meta.env.DEV) { let extensionId = ''; - if (parameters.linkURL && parameters.linkURL.includes('/contribs')) { + if (parameters?.linkURL?.includes('/contribs')) { extensionId = parameters.linkURL.split('/contribs/')[1]; } return [ diff --git a/packages/main/src/plugin/authentication.ts b/packages/main/src/plugin/authentication.ts index fb675ca1a2d..889abc9c04e 100644 --- a/packages/main/src/plugin/authentication.ts +++ b/packages/main/src/plugin/authentication.ts @@ -215,10 +215,7 @@ export class AuthenticationImpl { if (!options.silent) { const providerRequests = this._signInRequests.get(providerId); const scopesList = sortedScopes.join(' '); - const extHasRequests = - providerRequests && - providerRequests[scopesList] && - providerRequests[scopesList].includes(requestingExtension.id); + const extHasRequests = providerRequests?.[scopesList]?.includes(requestingExtension.id); if (extHasRequests) { // request was added already by this extension return; diff --git a/packages/main/src/plugin/container-registry.ts b/packages/main/src/plugin/container-registry.ts index 66d44c3714c..5f2f4f2d335 100644 --- a/packages/main/src/plugin/container-registry.ts +++ b/packages/main/src/plugin/container-registry.ts @@ -584,10 +584,7 @@ export class ContainerProviderRegistry { containerProvider.connection.endpoint.socketPath === providerContainerConnectionInfo.endpoint.socketPath && containerProvider.connection.name === providerContainerConnectionInfo.name, ); - if (!matchingContainerProvider || !matchingContainerProvider.api) { - throw new Error('No provider with a running engine'); - } - if (!matchingContainerProvider.api) { + if (!matchingContainerProvider?.api) { throw new Error('no running provider for the matching container'); } return matchingContainerProvider.api; @@ -715,7 +712,7 @@ export class ContainerProviderRegistry { containerProvider.connection.endpoint.socketPath === selectedProvider.endpoint.socketPath && containerProvider.connection.name === selectedProvider.name, ); - if (!matchingContainerProvider || !matchingContainerProvider.libpodApi) { + if (!matchingContainerProvider?.libpodApi) { throw new Error('No provider with a running engine'); } const result = await matchingContainerProvider.libpodApi.createPod(podOptions); @@ -1029,7 +1026,7 @@ export class ContainerProviderRegistry { containerProvider.connection.endpoint.socketPath === selectedProvider.endpoint.socketPath && containerProvider.name === selectedProvider.name, ); - if (!matchingContainerProvider || !matchingContainerProvider.libpodApi) { + if (!matchingContainerProvider?.libpodApi) { throw new Error('No provider with a running engine'); } return matchingContainerProvider.libpodApi.playKube(kubernetesYamlFilePath); @@ -1050,7 +1047,7 @@ export class ContainerProviderRegistry { containerProvider.connection.name === selectedProvider.name && selectedProvider.status === 'started', ); - if (!matchingContainerProvider || !matchingContainerProvider.api) { + if (!matchingContainerProvider?.api) { throw new Error('No provider with a running engine'); } diff --git a/packages/main/src/plugin/docker-extension/docker-desktop-installation.ts b/packages/main/src/plugin/docker-extension/docker-desktop-installation.ts index b4cc5dc112d..f9d7a7555d7 100644 --- a/packages/main/src/plugin/docker-extension/docker-desktop-installation.ts +++ b/packages/main/src/plugin/docker-extension/docker-desktop-installation.ts @@ -64,7 +64,7 @@ export class DockerDesktopInstallation { // host binaries const hostFiles: string[] = []; - if (metadata.host && metadata.host.binaries) { + if (metadata?.host?.binaries) { // grab current platform let platform: string = process.platform; if (platform === 'win32') { diff --git a/packages/main/src/plugin/events/emitter.ts b/packages/main/src/plugin/events/emitter.ts index 40663d92c35..a8d16c68d09 100644 --- a/packages/main/src/plugin/events/emitter.ts +++ b/packages/main/src/plugin/events/emitter.ts @@ -24,7 +24,7 @@ class CallbackList implements Iterable { private _contexts: any[] | undefined; get length(): number { - return (this._callbacks && this._callbacks.length) || 0; + return this._callbacks?.length || 0; } public add(callback: Function, context: any = undefined, bucket?: IDisposable[]): void { @@ -146,7 +146,7 @@ export class Emitter { if (!this._callbacks) { this._callbacks = new CallbackList(); } - if (this._options && this._options.onFirstListenerAdd && this._callbacks.isEmpty()) { + if (this._options?.onFirstListenerAdd && this._callbacks.isEmpty()) { this._options.onFirstListenerAdd(this); } this._callbacks.add(listener, thisArgs); @@ -161,7 +161,7 @@ export class Emitter { if (!this._disposed) { this._callbacks?.remove(listener, thisArgs); result.dispose = Emitter._noop; - if (this._options && this._options.onLastListenerRemove && this._callbacks?.isEmpty()) { + if (this._options?.onLastListenerRemove && this._callbacks?.isEmpty()) { this._options.onLastListenerRemove(this); } } diff --git a/packages/main/src/plugin/extension-loader.ts b/packages/main/src/plugin/extension-loader.ts index 855e2ebf754..3fd3d5494fe 100644 --- a/packages/main/src/plugin/extension-loader.ts +++ b/packages/main/src/plugin/extension-loader.ts @@ -167,7 +167,7 @@ export class ExtensionLoader { const extension = Array.from(analyzedExtensions.values()).find(extension => path.normalize(parent.filename).startsWith(path.normalize(extension.path)), ); - if (extension && extension.api) { + if (extension?.api) { return extension.api; } throw new Error('Unable to find extension API'); @@ -763,7 +763,7 @@ export class ExtensionLoader { while (i--) { const childMod: NodeJS.Module | undefined = mod?.children[i]; // ensure the child module is not null, is in the plug-in folder, and is not a native module (see above) - if (childMod && childMod.id.startsWith(extension.path) && !childMod.id.endsWith('.node')) { + if (childMod?.id.startsWith(extension.path) && !childMod.id.endsWith('.node')) { // cleanup exports - note that some modules (e.g. ansi-styles) define their // exports in an immutable manner, so overwriting the exports throws an error delete childMod.exports; diff --git a/packages/main/src/plugin/image-registry.ts b/packages/main/src/plugin/image-registry.ts index c70bcf295b6..fc77f1da8f1 100644 --- a/packages/main/src/plugin/image-registry.ts +++ b/packages/main/src/plugin/image-registry.ts @@ -285,7 +285,7 @@ export class ImageRegistry { /(?Bearer|Basic) realm="(?[^"]+)"(,service="(?[^"]+)")?(,scope="(?[^"]+)")?/; const parsed = WWW_AUTH_REGEXP.exec(wwwAuthenticate); - if (parsed && parsed.groups) { + if (parsed?.groups) { const { realm, service, scope, scheme } = parsed.groups; return { authUrl: realm, service, scope, scheme }; } @@ -305,8 +305,8 @@ export class ImageRegistry { if (this.proxyEnabled) { // use proxy when performing got request const proxy = this.proxySettings; - const httpProxyUrl = proxy && proxy.httpProxy; - const httpsProxyUrl = proxy && proxy.httpsProxy; + const httpProxyUrl = proxy?.httpProxy; + const httpsProxyUrl = proxy?.httpsProxy; if (httpProxyUrl) { if (!options.agent) { diff --git a/packages/main/src/plugin/input-quickpick/input-quickpick-registry.ts b/packages/main/src/plugin/input-quickpick/input-quickpick-registry.ts index b66d85cf8c4..c7f9a30137b 100644 --- a/packages/main/src/plugin/input-quickpick/input-quickpick-registry.ts +++ b/packages/main/src/plugin/input-quickpick/input-quickpick-registry.ts @@ -137,7 +137,7 @@ export class InputQuickPickRegistry { const callback = this.callbacksInputBox.get(id); // if there is a callback - if (callback && callback.options?.validateInput) { + if (callback?.options?.validateInput) { return callback.options.validateInput(value); } return undefined; @@ -149,7 +149,7 @@ export class InputQuickPickRegistry { const callback = this.callbacksQuickPicks.get(id); // if there is a callback - if (callback && callback.options?.onDidSelectItem) { + if (callback?.options?.onDidSelectItem) { // grab item const item = callback.items[index]; diff --git a/packages/main/src/plugin/kubernetes-client.ts b/packages/main/src/plugin/kubernetes-client.ts index 23f6ffd096f..4002eb4efa5 100644 --- a/packages/main/src/plugin/kubernetes-client.ts +++ b/packages/main/src/plugin/kubernetes-client.ts @@ -383,7 +383,7 @@ export class KubernetesClient { fieldSelector, labelSelector, ); - if (res && res.body) { + if (res?.body) { return res.body; } else { return { @@ -434,7 +434,7 @@ export class KubernetesClient { const k8sApi = this.kubeConfig.makeApiClient(CoreV1Api); try { const res = await k8sApi.readNamespacedPod(name, namespace); - if (res && res.body) { + if (res?.body) { return res.body; } else { return undefined; @@ -448,7 +448,7 @@ export class KubernetesClient { const k8sApi = this.kubeConfig.makeApiClient(CoreV1Api); try { const res = await k8sApi.readNamespacedConfigMap(name, namespace); - if (res && res.body) { + if (res?.body) { return res.body; } else { return undefined; @@ -462,7 +462,7 @@ export class KubernetesClient { try { const k8sApi = this.kubeConfig.makeApiClient(CoreV1Api); const res = await k8sApi.listNamespace(); - if (res && res.body) { + if (res?.body) { return res.body; } else { return { @@ -489,7 +489,7 @@ export class KubernetesClient { // eslint-disable-next-line @typescript-eslint/no-explicit-any private wrapK8sClientError(e: any): Error { - if (e.response && e.response.body) { + if (e?.response?.body) { if (e.response.body.message) { return this.newError(e.response.body.message, e); } @@ -633,7 +633,7 @@ export class KubernetesClient { await this.createResources(context, manifests, namespace); // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { - if (error.response && error.response.body) { + if (error?.response?.body) { if (error.response.body.message) { throw new Error(error.response.body.message); } diff --git a/packages/main/src/plugin/provider-registry.ts b/packages/main/src/plugin/provider-registry.ts index 75438ef861e..0bba8322cea 100644 --- a/packages/main/src/plugin/provider-registry.ts +++ b/packages/main/src/plugin/provider-registry.ts @@ -442,7 +442,7 @@ export class ProviderRegistry { if (provider.containerConnections && provider.containerConnections.length > 0) { const connection = provider.containerConnections[0]; const lifecycle = connection.lifecycle; - if (!lifecycle || !lifecycle.start) { + if (!lifecycle?.start) { throw new Error('The container connection does not support start lifecycle'); } @@ -469,7 +469,7 @@ export class ProviderRegistry { return this.intializeProviderLifecycle(providerInternalId); } - if (provider.containerProviderConnectionFactory && provider.containerProviderConnectionFactory.initialize) { + if (provider?.containerProviderConnectionFactory?.initialize) { this.telemetryService .track('initializeProvider', { name: provider.name, @@ -479,7 +479,7 @@ export class ProviderRegistry { return provider.containerProviderConnectionFactory.initialize(); } - if (provider.kubernetesProviderConnectionFactory && provider.kubernetesProviderConnectionFactory.initialize) { + if (provider?.kubernetesProviderConnectionFactory?.initialize) { this.telemetryService .track('initializeProvider', { name: provider.name, @@ -549,13 +549,13 @@ export class ProviderRegistry { // container connection factory ? let containerProviderConnectionInitialization = false; - if (provider.containerProviderConnectionFactory && provider.containerProviderConnectionFactory.initialize) { + if (provider?.containerProviderConnectionFactory?.initialize) { containerProviderConnectionInitialization = true; } // kubernetes connection factory ? let kubernetesProviderConnectionCreation = false; - if (provider.kubernetesProviderConnectionFactory && provider.kubernetesProviderConnectionFactory.create) { + if (provider?.kubernetesProviderConnectionFactory?.create) { kubernetesProviderConnectionCreation = true; } @@ -576,7 +576,7 @@ export class ProviderRegistry { const kubernetesProviderConnectionCreationButtonTitle = provider.kubernetesProviderConnectionFactory?.creationButtonTitle; const emptyConnectionMarkdownDescription = provider.emptyConnectionMarkdownDescription; - if (provider.kubernetesProviderConnectionFactory && provider.kubernetesProviderConnectionFactory.initialize) { + if (provider?.kubernetesProviderConnectionFactory?.initialize) { kubernetesProviderConnectionInitialization = true; } @@ -780,7 +780,7 @@ export class ProviderRegistry { const connection = this.getMatchingConnectionFromProvider(internalProviderId, providerConnectionInfo); const lifecycle = connection.lifecycle; - if (!lifecycle || !lifecycle.start) { + if (!lifecycle?.start) { throw new Error('The container connection does not support start lifecycle'); } @@ -830,7 +830,7 @@ export class ProviderRegistry { const connection = this.getMatchingConnectionFromProvider(internalProviderId, providerConnectionInfo); const lifecycle = connection.lifecycle; - if (!lifecycle || !lifecycle.stop) { + if (!lifecycle?.stop) { throw new Error('The container connection does not support stop lifecycle'); } @@ -880,7 +880,7 @@ export class ProviderRegistry { const connection = this.getMatchingConnectionFromProvider(internalProviderId, providerConnectionInfo); const lifecycle = connection.lifecycle; - if (!lifecycle || !lifecycle.delete) { + if (!lifecycle?.delete) { throw new Error('The container connection does not support delete lifecycle'); } this.telemetryService diff --git a/packages/preload-docker-extension/src/index.ts b/packages/preload-docker-extension/src/index.ts index 69696780c0d..8dd2b97154e 100644 --- a/packages/preload-docker-extension/src/index.ts +++ b/packages/preload-docker-extension/src/index.ts @@ -184,7 +184,7 @@ export class DockerExtensionPreload { 'docker-plugin-adapter:execWithOptions-callback-stdout', (_event, callbackId: number, data: string) => { const streamOptions = this.onDockerPluginExecWithOptionsCallbacks.get(callbackId); - if (streamOptions && streamOptions.onOutput) { + if (streamOptions?.onOutput) { streamOptions.onOutput({ stdout: data }); } }, @@ -193,7 +193,7 @@ export class DockerExtensionPreload { 'docker-plugin-adapter:execWithOptions-callback-stderr', (_event, callbackId: number, data: string) => { const streamOptions = this.onDockerPluginExecWithOptionsCallbacks.get(callbackId); - if (streamOptions && streamOptions.onOutput) { + if (streamOptions?.onOutput) { streamOptions.onOutput({ stderr: data }); } }, @@ -202,14 +202,14 @@ export class DockerExtensionPreload { 'docker-plugin-adapter:execWithOptions-callback-close', (_event, callbackId: number, exitCode: number) => { const streamOptions = this.onDockerPluginExecWithOptionsCallbacks.get(callbackId); - if (streamOptions && streamOptions.onClose) { + if (streamOptions?.onClose) { streamOptions.onClose(exitCode); } }, ); ipcRenderer.on('docker-plugin-adapter:execWithOptions-callback-error', (_event, callbackId: number, error: any) => { const streamOptions = this.onDockerPluginExecWithOptionsCallbacks.get(callbackId); - if (streamOptions && streamOptions.onError) { + if (streamOptions?.onError) { streamOptions.onError(error); } }); diff --git a/packages/renderer/src/lib/container/container-utils.ts b/packages/renderer/src/lib/container/container-utils.ts index c1921d4b905..1773acbe0bd 100644 --- a/packages/renderer/src/lib/container/container-utils.ts +++ b/packages/renderer/src/lib/container/container-utils.ts @@ -25,9 +25,9 @@ import { filesize } from 'filesize'; export class ContainerUtils { getName(containerInfo: ContainerInfo) { // part of a compose ? - const composeService = (containerInfo.Labels || {})['com.docker.compose.service']; + const composeService = containerInfo.Labels?.['com.docker.compose.service']; if (composeService) { - const composeContainerNumber = (containerInfo.Labels || {})['com.docker.compose.container-number']; + const composeContainerNumber = containerInfo.Labels?.['com.docker.compose.container-number']; if (composeContainerNumber) { return `${composeService}-${composeContainerNumber}`; } @@ -139,7 +139,7 @@ export class ContainerUtils { getContainerGroup(containerInfo: ContainerInfo): ContainerGroupPartInfoUI { // compose metatadata ? - const composeProject = (containerInfo.Labels || {})['com.docker.compose.project']; + const composeProject = containerInfo.Labels?.['com.docker.compose.project']; if (composeProject) { return { name: composeProject, diff --git a/packages/renderer/src/lib/preferences/Util.ts b/packages/renderer/src/lib/preferences/Util.ts index 056a1419d8a..f1e197b61f5 100644 --- a/packages/renderer/src/lib/preferences/Util.ts +++ b/packages/renderer/src/lib/preferences/Util.ts @@ -49,7 +49,7 @@ export function writeToTerminal(xterm: any, data: string[], colorPrefix: string) // eslint-disable-next-line @typescript-eslint/no-explicit-any function writeMultilineString(xterm: any, data: string, colorPrefix: string): void { - if (data && data.includes && data.includes('\n')) { + if (data?.includes?.('\n')) { const toWrite = data.split('\n'); for (const s of toWrite) { xterm.write(colorPrefix + s + '\n\r'); diff --git a/website/src/components/TailWindThemeSelector/index.tsx b/website/src/components/TailWindThemeSelector/index.tsx index 65ab536bf6d..a15988ae73e 100644 --- a/website/src/components/TailWindThemeSelector/index.tsx +++ b/website/src/components/TailWindThemeSelector/index.tsx @@ -3,7 +3,7 @@ import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; function TailWindThemeSelector(): JSX.Element { function updadeTailwindDarkTheme() { - if (!document || !document.documentElement) { + if (!document?.documentElement) { return; }