Last active
September 18, 2017 20:40
-
-
Save valotas/83d0588f9270c6423393c3212086c5bc to your computer and use it in GitHub Desktop.
download vscode vsix files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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