Skip to content

Instantly share code, notes, and snippets.

@valotas
Last active September 18, 2017 20:40
Show Gist options
  • Save valotas/83d0588f9270c6423393c3212086c5bc to your computer and use it in GitHub Desktop.
Save valotas/83d0588f9270c6423393c3212086c5bc to your computer and use it in GitHub Desktop.
download vscode vsix files
const { JSDOM } = require("jsdom");
const semver = require("semver");
const Listr = require("listr");
const { Observable } = require("rxjs");
const http = require("https");
const fs = require("fs");
function fetchPluginInfo(plugin) {
return JSDOM.fromURL(
`https://marketplace.visualstudio.com/items?itemName=${plugin}`
)
.then(dom => dom.window.document.querySelector(".vss-item-data script"))
.then(script => script.innerHTML)
.then(jsonText => JSON.parse(jsonText))
.then(createPluginInfo)
.then(info => {
if (!info.vsix) {
throw new Error("No vsix asset found");
}
return info;
});
}
function createPluginInfo(json) {
json.versions.sort((v1, v2) => {
return semver.gt(v1.version, v2.version) ? 1 : -1;
});
const v = json.versions[0];
return {
name: json.extensionName,
version: v.version,
vsix: v.files.filter(
({ assetType }) =>
assetType == "Microsoft.VisualStudio.Services.VSIXPackage"
)[0]
};
}
const tasks = [
"EditorConfig.editorconfig",
"dbaeumer.vscode-eslint",
"eamodio.gitlens",
"k--kato.intellij-idea-keybindings",
"esbenp.prettier-vscode",
"donjayamanne.githistory"
].map(plugin => ({
title: `Downloading ${plugin}`,
task: (ctx, task) =>
new Observable(ob => {
ob.next("Fetching info");
fetchPluginInfo(plugin)
.then(info => {
ob.next(`Found version ${info.version}`);
const dest = `${info.name}-${info.version}.vsix`;
return { info, dest };
ob.next(`Downloading to ${dest}`);
return download(info, dest);
})
.then(({ info, dest }) => {
return exists(dest).then(exists => {
if (exists) {
task.skip(`${dest} exists no need to download`);
return;
} else {
ob.next(`Downloading ${dest}`);
return download(info, dest);
}
});
})
.then(() => {
ob.complete();
})
.catch(err => {
ob.error(`Failed to download: ${err.message}`);
ob.complete();
});
})
}));
function exists(dest) {
return new Promise(resolve => {
fs.access(`${dest}`, fs.constants.F_OK, err => {
const exists = !err;
resolve(exists);
});
});
}
function download({ name, version, vsix }, dest) {
return new Promise((resolve, reject) => {
const file = fs.createWriteStream(dest);
const request = http.get(vsix.source, response => {
// check if response is success
if (response.statusCode !== 200) {
reject("Response status was " + response.statusCode);
return;
}
response.pipe(file);
file.on("finish", function() {
file.close(err => {
if (err) {
reject("Could not close");
} else {
resolve();
}
});
});
});
// check for request error too
request.on("error", err => {
fs.unlink(dest);
reject(err.message);
});
file.on("error", err => {
// Handle errors
fs.unlink(dest); // Delete the file async. (But we don't check the result)
reject(err.message);
});
});
}
new Listr(tasks, { concurrent: true }).run().catch(err => {
console.log("Oups!", err);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment