From 70ef242b50d007f68ed5c890ff78539df462b25e Mon Sep 17 00:00:00 2001 From: Martin Zagora Date: Sun, 8 Mar 2015 02:03:21 +1100 Subject: [PATCH] download extension information from the npm --- .travis.yml | 5 +++ README.md | 2 +- gulpfile.js | 7 ++++ package.json | 16 ++++++-- src/npm-domain.js | 93 +++++++++++++++++++++++++++++++++++++++++++++++ test/index.js | 21 +++++++++++ 6 files changed, 140 insertions(+), 4 deletions(-) create mode 100644 .travis.yml create mode 100644 src/npm-domain.js create mode 100644 test/index.js diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..c90feef --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - 0.12 +before_install: + - npm install -g gulp-cli mocha diff --git a/README.md b/README.md index 71b20c3..f79a2a6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# brackets-npm-registry +# brackets-npm-registry [![Build Status](https://travis-ci.org/zaggino/brackets-npm-registry.svg?branch=master)](https://travis-ci.org/zaggino/brackets-npm-registry) Extension to install other extensions with npm ## gulp tasks diff --git a/gulpfile.js b/gulpfile.js index 4d823de..2fd0f64 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -31,6 +31,12 @@ function logPipe(str) { }); } +// prevents watch from crashing on errors +function swallowError (error) { + console.log(error.toString()); + this.emit('end'); +} + // helper for transpiling es6 files to es5 function doBabel(globs, singleFile) { if (singleFile) { @@ -40,6 +46,7 @@ function doBabel(globs, singleFile) { var task = gulp.src(globs, {base: path.resolve(__dirname, 'src')}) .pipe(sourcemaps.init()) .pipe(babel(babelOptions)) + .on('error', swallowError) .pipe(sourcemaps.write('.')) .pipe(gulp.dest(DIST_DIR)); diff --git a/package.json b/package.json index 8567715..abb98e1 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,11 @@ "name": "brackets-npm-registry", "version": "0.0.2", "description": "Boilerplate for a Brackets extension written in ES6", - "keywords": ["brackets-extension", "boilerplate", "hello-world"], + "keywords": [ + "brackets-extension", + "boilerplate", + "hello-world" + ], "homepage": "https://github.com/zaggino/brackets-npm-registry", "bugs": "https://github.com/zaggino/brackets-npm-registry/issues", "license": "MIT", @@ -16,12 +20,12 @@ "url": "https://github.com/zaggino/brackets-npm-registry.git" }, "scripts": { - "test": "gulp test", + "test": "mocha", "install": "gulp build" }, "dependencies": { - "bluebird": "^2.9.13", "babel-core": "^4.6.6", + "bluebird": "^2.9.13", "eslint": "^0.15.1", "esprima-fb": "^13001.1.0-dev-harmony-fb", "gulp": "^3.8.11", @@ -29,9 +33,15 @@ "gulp-eslint": "^0.5.0", "gulp-sourcemaps": "^1.5.0", "gulp-util": "^3.0.4", + "npm": "^2.7.0", + "request": "^2.53.0", "through2": "^0.6.3" }, "engines": { "brackets": ">=1.2.0" + }, + "devDependencies": { + "chai": "^2.1.1", + "mocha": "^2.2.0" } } diff --git a/src/npm-domain.js b/src/npm-domain.js new file mode 100644 index 0000000..b282d1e --- /dev/null +++ b/src/npm-domain.js @@ -0,0 +1,93 @@ +(function () { + 'use strict'; + + let npm = require('npm'); + let domainName = 'brackets-npm-registry-domain'; + let domainManager = null; + let Promise = require('bluebird'); + let request = require('request'); + + let getExtensions = exports.getExtensions = function (callback) { + + let npmLoad = Promise.promisify(npm.load, npm); + npmLoad() + .then(() => { + // get all entries tagged 'brackets-extension' + let npmSearch = Promise.promisify(npm.commands.search, npm.commands); + return npmSearch(['brackets-extension'], true); + }) + .then(searchResults => { + // call view for all potential extensions + let npmView = Promise.promisify(npm.commands.view, npm.commands); + return Promise.all(Object.keys(searchResults).map( + extensionId => + npmView([extensionId + '@latest'], true).then(result => + result[Object.keys(result)[0]] + ) + )); + }) + .then(viewResults => { + // filter out those, which doesn't have brackets engine specified + return viewResults.filter(result => result.engines && result.engines.brackets); + }) + .then(extensionInfos => { + // get download counts for the extensions + let extensionIds = extensionInfos.map(i => i.name); + let from = '2015-01-01'; + let to = new Date().toISOString().substring(0,10); + return new Promise((resolve, reject) => { + request(`https://api.npmjs.org/downloads/range/${from}:${to}/${extensionIds.join(',')}`, (error, response, body) => { + + if (error) { + return reject(error); + } + + if (response.statusCode !== 200) { + return reject(body); + } + + if (typeof body === 'string') { + try { + body = JSON.parse(body); + } catch (err) { + return reject(err); + } + } + + if (extensionIds.length === 1) { + extensionInfos[0].downloads = body.downloads; + } else { + extensionInfos.forEach(extensionInfo => { + extensionInfo.downloads = body[extensionInfo.name].downloads; + }); + } + + resolve(extensionInfos); + + }); + }); + }) + .nodeify(callback); + + }; + + exports.init = function (_domainManager) { + domainManager = _domainManager; + + if (!domainManager.hasDomain(domainName)) { + domainManager.registerDomain(domainName, {major: 0, minor: 1}); + } + + domainManager.registerCommand( + domainName, + 'getExtensions', // command name + getExtensions, // handler function + true, // is async + 'get a list of extensions from npm', // description + [ + {name: 'extensions', type: 'array'} + ] + ); + }; + +}()); diff --git a/test/index.js b/test/index.js new file mode 100644 index 0000000..c205b95 --- /dev/null +++ b/test/index.js @@ -0,0 +1,21 @@ +var expect = require("chai").expect; +var npmDomain = require('../dist/npm-domain'); + +describe('npm-domain', function () { + + describe('getExtensions()', function () { + + it('should return a list of extensions', function (done) { + + this.timeout(100000); + + npmDomain.getExtensions(function (err, response) { + // console.log(JSON.stringify(response, null, 4)); + done(err); + }); + + }); + + }); + +});