#!/usr/bin/env node var semver = require('semver'); var fs = require('fs'); var path = require('path'); var shared = require('../lib/shared'); process.on('uncaughtException', function (err) { exitWithError(err); }); var engine = process.env.npm_package_engines_vscode; if (!engine) { exitWithError('Missing VSCode engine declaration in package.json.'); } var vscodeDtsTypescriptPath = path.join(path.dirname(__dirname), 'vscode.d.ts'); console.log('Detected VS Code engine version: ' + engine); getURLMatchingEngine(engine, function (_, data) { console.log('Fetching vscode.d.ts from: ' + data.url); shared.getUrlContents(data.url, process.env.GITHUB_TOKEN, null, function (error, contents) { if (error) { exitWithError(error); } if (contents === 'Not Found') { exitWithError(new Error('Could not find vscode.d.ts at the provided URL. Please report this to https://github.com/Microsoft/vscode/issues')); } if (data.version !== '*' && semver.lt(data.version, '1.7.0')) { // Older versions of vscode.d.ts need a massage to play nice. contents = vscodeDtsToTypescript(contents); } fs.writeFileSync(vscodeDtsTypescriptPath, contents); console.log('vscode.d.ts successfully installed!\n'); }); }); function vscodeDtsToTypescript(contents) { var markerHit = false; var lines = contents.split('\n').filter(function (line) { if (!markerHit && (line === '// when used for JS*' || line === 'declare module \'vscode\' {')) { markerHit = true; } return !markerHit; }); lines.unshift('/// '); lines.push('export = vscode;'); // this is to enable TS module resolution support return lines.join('\n'); } function getURLMatchingEngine(engine, callback) { if (engine === '*') { // master return callback(null, { url: 'https://raw.githubusercontent.com/Microsoft/vscode/master/src/vs/vscode.d.ts', version: '*' }); } shared.getUrlContents('https://update.code.visualstudio.com/api/releases/stable', null, { "X-API-Version": "2" }, function (error, tagsRaw) { if (error) { exitWithError(error); } var tagsAndCommits; try { tagsAndCommits = JSON.parse(tagsRaw); } catch (error) { exitWithError(error); } var mapTagsToCommits = Object.create(null); for (var i = 0; i < tagsAndCommits.length; i++) { var tagAndCommit = tagsAndCommits[i]; mapTagsToCommits[tagAndCommit.version] = tagAndCommit.id; } var tags = Object.keys(mapTagsToCommits); var tag = minSatisfying(tags, engine); // check if master is on the version specified if (!tag) { return shared.getUrlContents('https://raw.githubusercontent.com/Microsoft/vscode/master/package.json', process.env.GITHUB_TOKEN, null, function (error, packageJson) { if (error) { exitWithError(error); } var version = JSON.parse(packageJson).version; if (semver.satisfies(version, engine)) { // master return callback(null, { url: 'https://raw.githubusercontent.com/Microsoft/vscode/master/src/vs/vscode.d.ts', version: version }); } exitWithError('Could not find satifying VSCode for version ' + engine + ' in the tags: [' + tags.join(', ') + '] or on master: ' + version); }); } console.log('Found minimal version that qualifies engine range: ' + tag); return callback(null, { url: 'https://raw.githubusercontent.com/Microsoft/vscode/' + mapTagsToCommits[tag] + '/src/vs/vscode.d.ts', version: tag }); }); } function minSatisfying(versions, range) { return versions.filter(function (version) { try { return semver.satisfies(version, range); } catch (error) { return false; // version might be invalid so we return as not matching } }).sort(function (a, b) { return semver.compare(a, b); })[0] || null; } function exitWithError(error) { console.error('Error installing vscode.d.ts: ' + error.toString()); process.exit(1); }