From f40cabbd2d1b0ad250efdeed07616158d301b829 Mon Sep 17 00:00:00 2001 From: Bob Corsaro Date: Wed, 4 May 2016 14:37:37 -0400 Subject: [PATCH] Remove constructor callback --- README.rst | 81 +++++++++++++--------------- index.js | 135 +++++++++++++++++++++++++--------------------- package.json | 2 +- test/responses.js | 25 ++++----- 4 files changed, 126 insertions(+), 117 deletions(-) diff --git a/README.rst b/README.rst index df47792..5e3aaaa 100644 --- a/README.rst +++ b/README.rst @@ -7,6 +7,9 @@ visit http://embed.ly. News ^^^^ +* 05/04/2016 - The callback on object creation has been removed. Initialization +is now lazy and happens on the first API call. This is a breaking change if you +used a callback style constructor. * The embedly-node modules has been updated and simplified. It is not backward compatible. If you want to stick with the old API, use a verion < 1.0. @@ -40,59 +43,51 @@ Here are some examples *hint* replace xxxxxxxxxxx with real key:: var embedly = require('embedly'), util = require('util'); - new embedly({key: EMBEDLY_KEY}, function(err, api) { + var api = new embedly({key: EMBEDLY_KEY}); + // call single url + var url = 'http://www.youtube.com/watch?v=Zk7dDekYej0'; + api.oembed({url: url}, function(err, objs) { if (!!err) { - console.error('Error creating Embedly api'); - console.error(err.stack, api); + console.error('request #1 failed'); + console.error(err.stack, objs); return; } - - // call single url - var url = 'http://www.youtube.com/watch?v=Zk7dDekYej0'; - api.oembed({url: url}, function(err, objs) { - if (!!err) { - console.error('request #1 failed'); - console.error(err.stack, objs); - return; - } - console.log('---------------------------------------------------------'); - console.log('1. '); - console.log(util.inspect(objs[0])); - }); - - // call multiple urls with parameters - var urls = ['http://www.youtube.com/watch?v=Zk7dDekYej0', - 'http://plixi.com/p/16044847'], - opts = { urls: urls, - maxWidth: 450, - wmode: 'transparent', - method: 'after' }; - - api.oembed(opts, function(err, objs) { - if (!!err) { - console.error('request #2 failed'); - console.error(err.stack, objs); - return; - } - console.log('-------------------------------------------------------'); - console.log('2. '); - console.log(util.inspect(objs)); - }); + console.log('---------------------------------------------------------'); + console.log('1. '); + console.log(util.inspect(objs[0])); }); - new embedly({key: EMBEDLY_KEY}, function(err, api) { - var url = ('http://www.guardian.co.uk/media/2011/jan' + - '/21/andy-coulson-phone-hacking-statement'); - api.preview({url: url}, function(err, objs) { + // call multiple urls with parameters + var urls = ['http://www.youtube.com/watch?v=Zk7dDekYej0', + 'http://plixi.com/p/16044847'], + opts = { urls: urls, + maxWidth: 450, + wmode: 'transparent', + method: 'after' }; + + api.oembed(opts, function(err, objs) { if (!!err) { console.error('request #2 failed'); console.error(err.stack, objs); return; } - console.log('---------------------------------------------------------'); - console.log('3. '); - console.log(util.inspect(objs[0])); - }); + console.log('-------------------------------------------------------'); + console.log('2. '); + console.log(util.inspect(objs)); + }); + + var api = new embedly({key: EMBEDLY_KEY}); + var url = ('http://www.guardian.co.uk/media/2011/jan' + + '/21/andy-coulson-phone-hacking-statement'); + api.preview({url: url}, function(err, objs) { + if (!!err) { + console.error('request #2 failed'); + console.error(err.stack, objs); + return; + } + console.log('---------------------------------------------------------'); + console.log('3. '); + console.log(util.inspect(objs[0])); }); Authentication diff --git a/index.js b/index.js index b27553a..0b5f399 100644 --- a/index.js +++ b/index.js @@ -58,6 +58,8 @@ function embedly(opts, callback) { logger: null, servicesRegExp: null }, opts); + this.initDone = false; + this.initError = null; if (!this.config.logger) { this.config.logger = defaultLogger(); @@ -72,34 +74,44 @@ function embedly(opts, callback) { return embedly.prototype.apiCall.apply(self, args); }; }); + return self; +} - if (!this.config.key && !this.config.servicesRegExp) { - var url = this.url('services/javascript', '1'), - errorMsg = 'Failed to fetch /1/services/javascript during init.'; - - request - .get(url) - .set('User-Agent', this.config.userAgent) - .set('Accept', 'application/json') - .end(function(e, res) { - if (!!e) return callback(e); - if (res.status >= 400) { - return callback(new Error(errorMsg), res); - } - try { - var services = JSON.parse(res.text), - regExpText = services.map(function(service) { - return service.regex.join("|"); - }).join("|"); - self.config.servicesRegExp = new RegExp(regExpText) - } catch(e) { - return callback(new Error(errorMsg), res); - } - callback(null, self); - }) +embedly.prototype._init = function(ctx, fn) { + if (!this.initDone) { + this.initDone = true; + if (!this.config.key && !this.config.servicesRegExp) { + var url = this.url('services/javascript', '1'), + errorMsg = 'Failed to fetch /1/services/javascript during init.'; + + request + .get(url) + .set('User-Agent', this.config.userAgent) + .set('Accept', 'application/json') + .end(function(e, res) { + if (!!e) return fn(ctx, e); + if (res.status >= 400) { + self.initError = new Error(errorMsg); + return fn(ctx, self.initError, res); + } + try { + var services = JSON.parse(res.text), + regExpText = services.map(function(service) { + return service.regex.join("|"); + }).join("|"); + self.config.servicesRegExp = new RegExp(regExpText) + } catch(e) { + self.initError = new Error(errorMsg); + return fn(ctx, self.initError, res); + } + return fn(ctx, null, self); + }) + } else { + return fn(ctx, null, this); + } } else { - callback(null, this); + return fn(ctx, this.initError, this); } }; @@ -152,44 +164,45 @@ embedly.prototype.serializeResponse = function(urls, resText) { }); }; -embedly.prototype.apiCall = function(endpoint, version, params, callback) { - if (!params.key) { - params.key = this.config.key; - } - - var url = this.url(endpoint, version), - params = this.canonizeParams(params), - origUrls = params.urls.slice(0); - - params.urls = this.matchUrls(params.urls); +embedly.prototype.apiCall = function(endpoint, version, q, fn) { + // The first parameter to _init is the context. For some reason wrapping + // them in a closure wasn't working. I gave up do to frustration, but this + // works. + this._init({endpoint: endpoint, version: version, q: q, fn: fn}, function(ctx, err, self) { + if (err) { + return ctx.fn(err); + } - var query = '?' + querystring.stringify(params), - self = this; + if (!ctx.q.key) { + ctx.q.key = self.config.key; + } - if (params.urls.length > 0) { - this.config.logger.debug('calling: ' + url + '?' + query); - // Appending our own querystring this way is complete and utter bullshit - // caused by this bug that is VERY VERY old (not to mention many others - // related to this braindamaged behavior). Since visionmedia has - // abandoned js, we should probably use a different http client lib. - // - // https://github.com/visionmedia/superagent/issues/128 - var req = request - .get(url) - .set('User-Agent', this.config.userAgent) - .set('Accept', 'application/json'); - req.request().path += query; - req.end(function(e, res) { - if (!!e) return callback(e) - if (res.status >= 400) { - self.config.logger.error(String(res.status), res.text); - return callback(new Error('Invalid response'), res.text); - } - callback(null, self.serializeResponse(origUrls, res.text)) - }); - } else { - callback(null, self.serializeResponse(origUrls, '[]')); - } + var url = self.url(ctx.endpoint, ctx.version), + q = self.canonizeParams(ctx.q), + origUrls = q.urls.slice(0); + + q.urls = self.matchUrls(q.urls); + + if (q.urls.length > 0) { + self.config.logger.debug('calling: ' + url + '?' + querystring.stringify(q)); + var req = request + .get(url) + .set('User-Agent', self.config.userAgent) + .set('Accept', 'application/json'); + req.query(querystring.stringify(q)); + req.end(function(e, res) { + if (!!e) return ctx.fn(e) + if (res.status >= 400) { + self.config.logger.error(String(res.status), res.text); + return ctx.fn(new Error('Invalid response'), res.text); + } + return ctx.fn(null, self.serializeResponse(origUrls, res.text)) + }); + } else { + return ctx.fn(null, self.serializeResponse(origUrls, '[]')); + } + }); + return q; }; exports = module.exports = embedly diff --git a/package.json b/package.json index ab3724c..2c5b9c2 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ }, "dependencies": { "batbelt": "0.0.2", - "superagent": "0.21.0", + "superagent": "1.8.3", "sprintf": "0.1.1", "hashish": "0.0.4" }, diff --git a/test/responses.js b/test/responses.js index 5bb740f..be1a0c5 100644 --- a/test/responses.js +++ b/test/responses.js @@ -7,23 +7,24 @@ var embedly = require('../index.js'), describe('embedly', function() { describe('oembed', function() { it('should call the oembed endpoint', function(done) { - new embedly({key: process.env.EMBEDLY_KEY, logger: logger}, function(err, api) { + var api = new embedly({key: process.env.EMBEDLY_KEY, logger: logger}), + params = { + urls: [ + 'www.google.com', + 'www.yahoo.com', + 'http://www.youtube.com/watch?v=-ywcu1rzPik' + ] + }; + api.oembed(params, function(err, res) { if (!!err) { + console.error("Make sure you set environmental variable EMBEDLY_KEY to a valid api key"); console.error(err.stack); - console.error(api.text); + console.error(res && res.text); } else { - api.oembed({urls: ['www.google.com', 'www.yahoo.com', 'http://www.youtube.com/watch?v=-ywcu1rzPik']}, function(err, res) { - if (!!err) { - console.error(err.stack); - console.error(res.text); - } else { - console.log(res); - } - done(err); - }); + console.log(res); } + done(err); }); }); }); }); -