mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
responding to comments, fixed package validation
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
1c17420e6c
commit
55c284f8ef
@ -17,3 +17,4 @@ export * from "./openExternal";
|
|||||||
export * from "./rectify-array";
|
export * from "./rectify-array";
|
||||||
export * from "./downloadFile";
|
export * from "./downloadFile";
|
||||||
export * from "./escapeRegExp";
|
export * from "./escapeRegExp";
|
||||||
|
export * from "./tar";
|
||||||
|
|||||||
@ -99,5 +99,5 @@ export class LensExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function sanitizeExtensionName(name: string) {
|
export function sanitizeExtensionName(name: string) {
|
||||||
return name.replace("@", "").replace("/", "-");
|
return name.replace("@", "").replace("/", "--");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,8 +20,7 @@ import { extensionLoader } from "../../../extensions/extension-loader";
|
|||||||
import { extensionDiscovery, manifestFilename } from "../../../extensions/extension-discovery";
|
import { extensionDiscovery, manifestFilename } from "../../../extensions/extension-discovery";
|
||||||
import { LensExtensionManifest, sanitizeExtensionName } from "../../../extensions/lens-extension";
|
import { LensExtensionManifest, sanitizeExtensionName } from "../../../extensions/lens-extension";
|
||||||
import { Notifications } from "../notifications";
|
import { Notifications } from "../notifications";
|
||||||
import { downloadFile } from "../../../common/utils";
|
import { downloadFile, extractTar, listTarEntries, readFileFromTar } from "../../../common/utils";
|
||||||
import { extractTar, listTarEntries, readFileFromTar } from "../../../common/utils/tar";
|
|
||||||
import { docsUrl } from "../../../common/vars";
|
import { docsUrl } from "../../../common/vars";
|
||||||
|
|
||||||
interface InstallRequest {
|
interface InstallRequest {
|
||||||
@ -36,7 +35,7 @@ interface InstallRequestPreloaded extends InstallRequest {
|
|||||||
|
|
||||||
interface InstallRequestValidated extends InstallRequestPreloaded {
|
interface InstallRequestValidated extends InstallRequestPreloaded {
|
||||||
manifest: LensExtensionManifest;
|
manifest: LensExtensionManifest;
|
||||||
tmpFile: string; // temp file for unpacking
|
tempFile: string; // temp system path to packed extension for unpacking
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
@ -145,11 +144,12 @@ export class Extensions extends React.Component {
|
|||||||
const tarFiles = await listTarEntries(filePath);
|
const tarFiles = await listTarEntries(filePath);
|
||||||
|
|
||||||
// tarball from npm contains single root folder "package/*"
|
// tarball from npm contains single root folder "package/*"
|
||||||
const hasSingleRootFolder = tarFiles.every(entry => entry.startsWith(tarFiles[0]));
|
const rootFolder = tarFiles[0].split("/")[0];
|
||||||
const manifestLocation = hasSingleRootFolder ? path.join(tarFiles[0], manifestFilename) : manifestFilename;
|
const packedInRootFolder = tarFiles.every(entry => entry.startsWith(rootFolder));
|
||||||
|
const manifestLocation = packedInRootFolder ? path.join(rootFolder, manifestFilename) : manifestFilename;
|
||||||
|
|
||||||
if(!tarFiles.includes(manifestLocation)) {
|
if (!tarFiles.includes(manifestLocation)) {
|
||||||
throw `invalid package, ${manifestFilename} not found`;
|
throw new Error(`invalid extension bundle, ${manifestFilename} not found`);
|
||||||
}
|
}
|
||||||
const manifest = await readFileFromTar<LensExtensionManifest>({
|
const manifest = await readFileFromTar<LensExtensionManifest>({
|
||||||
tarPath: filePath,
|
tarPath: filePath,
|
||||||
@ -157,7 +157,7 @@ export class Extensions extends React.Component {
|
|||||||
parseJson: true,
|
parseJson: true,
|
||||||
});
|
});
|
||||||
if (!manifest.lens && !manifest.renderer) {
|
if (!manifest.lens && !manifest.renderer) {
|
||||||
throw `${manifestFilename} must specify "main" and/or "renderer" fields`;
|
throw new Error(`${manifestFilename} must specify "main" and/or "renderer" fields`);
|
||||||
}
|
}
|
||||||
return manifest;
|
return manifest;
|
||||||
}
|
}
|
||||||
@ -181,7 +181,7 @@ export class Extensions extends React.Component {
|
|||||||
validatedRequests.push({
|
validatedRequests.push({
|
||||||
...req,
|
...req,
|
||||||
manifest,
|
manifest,
|
||||||
tmpFile: tempFile,
|
tempFile,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
fse.unlink(tempFile).catch(() => null); // remove invalid temp package
|
fse.unlink(tempFile).catch(() => null); // remove invalid temp package
|
||||||
@ -231,16 +231,16 @@ export class Extensions extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async unpackExtension({ fileName, tmpFile, manifest: { name, version } }: InstallRequestValidated) {
|
async unpackExtension({ fileName, tempFile, manifest: { name, version } }: InstallRequestValidated) {
|
||||||
const extName = `${name}@${version}`;
|
const extName = `${name}@${version}`;
|
||||||
logger.info(`Unpacking extension ${extName}`, { fileName, tmpFile });
|
logger.info(`Unpacking extension ${extName}`, { fileName, tempFile });
|
||||||
const unpackingTempFolder = path.join(path.dirname(tmpFile), path.basename(tmpFile) + "-unpacked");
|
const unpackingTempFolder = path.join(path.dirname(tempFile), path.basename(tempFile) + "-unpacked");
|
||||||
const extensionFolder = this.getExtensionDestFolder(name);
|
const extensionFolder = this.getExtensionDestFolder(name);
|
||||||
try {
|
try {
|
||||||
// extract to temp folder first
|
// extract to temp folder first
|
||||||
await fse.remove(unpackingTempFolder).catch(Function);
|
await fse.remove(unpackingTempFolder).catch(Function);
|
||||||
await fse.ensureDir(unpackingTempFolder);
|
await fse.ensureDir(unpackingTempFolder);
|
||||||
await extractTar(tmpFile, { cwd: unpackingTempFolder });
|
await extractTar(tempFile, { cwd: unpackingTempFolder });
|
||||||
|
|
||||||
// move contents to extensions folder
|
// move contents to extensions folder
|
||||||
const unpackedFiles = await fse.readdir(unpackingTempFolder);
|
const unpackedFiles = await fse.readdir(unpackingTempFolder);
|
||||||
@ -262,7 +262,7 @@ export class Extensions extends React.Component {
|
|||||||
} finally {
|
} finally {
|
||||||
// clean up
|
// clean up
|
||||||
fse.remove(unpackingTempFolder).catch(Function);
|
fse.remove(unpackingTempFolder).catch(Function);
|
||||||
fse.unlink(tmpFile).catch(Function);
|
fse.unlink(tempFile).catch(Function);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -34,7 +34,7 @@ export class NotificationsStore {
|
|||||||
const notification = this.getById(id);
|
const notification = this.getById(id);
|
||||||
if (!notification) return;
|
if (!notification) return;
|
||||||
this.removeAutoHideTimer(id);
|
this.removeAutoHideTimer(id);
|
||||||
if (notification.timeout) {
|
if (notification?.timeout) {
|
||||||
const timer = window.setTimeout(() => this.remove(id), notification.timeout);
|
const timer = window.setTimeout(() => this.remove(id), notification.timeout);
|
||||||
this.autoHideTimers.set(id, timer);
|
this.autoHideTimers.set(id, timer);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user