Extension {displayName} successfully uninstalled!
); }); removedUninstalling.forEach(({ id }) => { this.extensionState.delete(id); }); }) ); } @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(req => { return fse.readFile(req.filePath).then(data => { req.data = data; preloadedRequests.push(req); }).catch(error => { if (showError) { Notifications.error(`Error while reading "${req.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.
Extension {extName} successfully installed!
); } catch (error) { Notifications.error(Installing extension {extName} has failed: {error}
); } finally { // clean up fse.remove(unpackingTempFolder).catch(Function); fse.unlink(tempFile).catch(Function); } } async uninstallExtension(extension: InstalledExtension) { const displayName = extensionDisplayName(extension.manifest.name, extension.manifest.version); try { this.extensionState.set(extension.id, { state: "uninstalling", displayName }); await extensionDiscovery.uninstallExtension(extension.absolutePath); } catch (error) { Notifications.error(Uninstalling extension {displayName} has failed: {error?.message ?? ""}
); // Remove uninstall state on uninstall failure this.extensionState.delete(extension.id); } } renderExtensions() { const { extensions, extensionsPath, search } = this; if (!extensions.length) { return (No search results found
} {!search &&There are no extensions in {extensionsPath}
{name}