Extension {displayName} successfully uninstalled!
); this.extensionState.delete(id); }); this.addedInstalling.forEach(({ id, displayName }) => { Notifications.ok(Extension {displayName} successfully installed!
); this.extensionState.delete(id); this.installPath = ""; }); }) ); } @computed get extensions() { const searchText = this.search.toLowerCase(); return Array.from(extensionLoader.userExtensions.values()).filter(ext => { const { name, description } = ext.manifest; return [ name.toLowerCase().includes(searchText), description?.toLowerCase().includes(searchText), ].some(value => value); }); } get extensionsPath() { return extensionDiscovery.localFolderPath; } getExtensionPackageTemp(fileName = "") { return path.join(os.tmpdir(), "lens-extensions", fileName); } getExtensionDestFolder(name: string) { return path.join(this.extensionsPath, sanitizeExtensionName(name)); } installFromSelectFileDialog = async () => { const { dialog, BrowserWindow, app } = remote; const { canceled, filePaths } = await dialog.showOpenDialog(BrowserWindow.getFocusedWindow(), { defaultPath: app.getPath("downloads"), properties: ["openFile", "multiSelections"], message: _i18n._(t`Select extensions to install (formats: ${this.supportedFormats.join(", ")}), `), buttonLabel: _i18n._(t`Use configuration`), filters: [ { name: "tarball", extensions: this.supportedFormats } ] }); if (!canceled && filePaths.length) { this.requestInstall( filePaths.map(filePath => ({ fileName: path.basename(filePath), filePath, })) ); } }; installFromUrlOrPath = async () => { const { installPath } = this; if (!installPath) return; const fileName = path.basename(installPath); try { // install via url // fixme: improve error messages for non-tar-file URLs if (InputValidators.isUrl.validate(installPath)) { const { promise: filePromise } = downloadFile({ url: installPath, timeout: 60000 /*1m*/ }); const data = await filePromise; this.requestInstall({ fileName, data }); } // otherwise installing from system path else if (InputValidators.isPath.validate(installPath)) { this.requestInstall({ fileName, filePath: installPath }); } } catch (error) { Notifications.error(Installation has failed: {String(error)}
); } }; installOnDrop = (files: File[]) => { logger.info("Install from D&D"); return this.requestInstall( files.map(file => ({ fileName: path.basename(file.path), filePath: file.path, })) ); }; async preloadExtensions(requests: InstallRequest[], { showError = true } = {}) { const preloadedRequests = requests.filter(req => req.data); await Promise.all( requests .filter(req => !req.data && req.filePath) .map(request => { return fse.readFile(request.filePath).then(data => { request.data = data; preloadedRequests.push(request); }).catch(error => { if (showError) { Notifications.error(`Error while reading "${request.filePath}": ${String(error)}`); } }); }) ); return preloadedRequests as InstallRequestPreloaded[]; } async validatePackage(filePath: string): PromiseInstalling {req.fileName} has failed, skipping.
Reason: {String(error)}
Install extension {name}@{version}?
Description: {description}
{extensionFolder} will be removed before installation.
Installing extension {displayName} has failed: {error}
); // Remove install state on install failure if (this.extensionState.get(extensionId)?.state === "installing") { this.extensionState.delete(extensionId); } } finally { // clean up fse.remove(unpackingTempFolder).catch(Function); fse.unlink(tempFile).catch(Function); } } confirmUninstallExtension = (extension: InstalledExtension) => { const displayName = extensionDisplayName(extension.manifest.name, extension.manifest.version); ConfirmDialog.open({ message:Are you sure you want to uninstall extension {displayName}?
, labelOk:Uninstalling extension {displayName} has failed: {error?.message ?? ""}
); // Remove uninstall state on uninstall failure if (this.extensionState.get(extension.id)?.state === "uninstalling") { this.extensionState.delete(extension.id); } } } renderExtensions() { const { extensions, search } = this; if (!extensions.length) { return (No search results found
:There are no installed extensions. See list of available extensions.
}{name}