Commit 64ec25ee by Alex MacCaw

merge

parents 40b36f2a 2a1f3759
...@@ -17,7 +17,4 @@ deploy: ...@@ -17,7 +17,4 @@ deploy:
on: on:
tags: true tags: true
all_branches: true all_branches: true
repo: bendrucker/clearbit-node repo: clearbit/clearbit-node
env:
global:
secure: CHoeYn6R9p4vQ96KkysrCSIiN7J0EU1x1jNuevgYVgVol+b5ukvDVUBTaSEzeSznuCotrZdhPp6/CQNELMDJowTXUgbwdp7FUPss5Bp5WjMJHt+YIUw3vjaeucPawX2uzVyNjFY2pCG2IDl13LAvDEWuqMvB6NboX9uBFpW8ah0=
clearbit-node [![Build Status](https://travis-ci.org/bendrucker/clearbit-node.svg?branch=master)](https://travis-ci.org/bendrucker/clearbit-node) [![Code Climate](https://codeclimate.com/github/bendrucker/clearbit-node/badges/gpa.svg)](https://codeclimate.com/github/bendrucker/clearbit-node) [![Test Coverage](https://codeclimate.com/github/bendrucker/clearbit-node/badges/coverage.svg)](https://codeclimate.com/github/bendrucker/clearbit-node) clearbit-node [![Build Status](https://travis-ci.org/clearbit/clearbit-node.svg?branch=master)](https://travis-ci.org/clearbit/clearbit-node) [![Code Climate](https://codeclimate.com/github/clearbit/clearbit-node/badges/gpa.svg)](https://codeclimate.com/github/clearbit/clearbit-node) [![Test Coverage](https://codeclimate.com/github/clearbit/clearbit-node/badges/coverage.svg)](https://codeclimate.com/github/clearbit/clearbit-node)
============= =============
Node library for querying the [Clearbit](https://clearbit.com) business intelligence APIs. Currently supports: Node library for querying the [Clearbit](https://clearbit.com) business intelligence APIs. Currently supports:
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/bendrucker/clearbit-node.git" "url": "https://github.com/clearbit/clearbit-node.git"
}, },
"keywords": [ "keywords": [
"clearbit", "clearbit",
...@@ -18,9 +18,9 @@ ...@@ -18,9 +18,9 @@
"author": "Ben Drucker <bvdrucker@gmail.com> (http://www.bendrucker.me)", "author": "Ben Drucker <bvdrucker@gmail.com> (http://www.bendrucker.me)",
"license": "MIT", "license": "MIT",
"bugs": { "bugs": {
"url": "https://github.com/bendrucker/clearbit-node/issues" "url": "https://github.com/clearbit/clearbit-node/issues"
}, },
"homepage": "https://github.com/bendrucker/clearbit-node", "homepage": "https://github.com/clearbit/clearbit-node",
"dependencies": { "dependencies": {
"bluebird": "2", "bluebird": "2",
"create-error": "0.3", "create-error": "0.3",
......
...@@ -15,9 +15,9 @@ function ClearbitClient (config) { ...@@ -15,9 +15,9 @@ function ClearbitClient (config) {
assert(!!config.key, 'An API key must be provided'); assert(!!config.key, 'An API key must be provided');
this.key = config.key; this.key = config.key;
this.Person = require('./person')(this); this.Person = require('./person').Person(this);
this.PersonCompany = require('./person').PersonCompany(this);
this.Company = require('./company')(this); this.Company = require('./company')(this);
this.PersonCompany = require('./person_company')(this);
} }
var base = 'https://%s%s.clearbit.com/v%s'; var base = 'https://%s%s.clearbit.com/v%s';
...@@ -48,7 +48,7 @@ function generateQuery () { ...@@ -48,7 +48,7 @@ function generateQuery () {
} }
ClearbitClient.prototype.request = function (options) { ClearbitClient.prototype.request = function (options) {
options = _.defaults(options || /* istanbul ignore next */ {}, { options = _.defaults(options, {
method: 'get', method: 'get',
query: {} query: {}
}); });
......
'use strict'; 'use strict';
var assert = require('assert'); var assert = require('assert');
var _ = require('lodash'); var resource = require('./resource');
var Promise = require('bluebird');
var utils = require('./utils'); module.exports = resource.create('Company', {
api: 'company',
module.exports = function (client) { path: '/companies/domain/<%= domain %>'
function Company (data) { })
_.extend(this, data); .on('preFind', function (options) {
} assert(options.domain, 'A domain must be provided');
});
Company.find = Promise.method(function (options) {
assert(options && options.domain, 'A domain must be provided');
return this.client.request(_.extend({
api: 'company',
path: '/companies/domain/' + options.domain
}, options))
.bind(this)
.then(utils.cast)
.catch(utils.isQueued, function () {
throw new this.QueuedError('Company lookup queued');
})
.catch(utils.isUnknownRecord, function () {
throw new this.NotFoundError('Company not found');
});
});
Company.prototype.client = Company.client = client;
Company.NotFoundError = utils.NotFoundError;
Company.QueuedError = utils.QueuedError;
return Company;
};
'use strict'; 'use strict';
var assert = require('assert'); var assert = require('assert');
var _ = require('lodash'); var resource = require('./resource');
var Promise = require('bluebird');
var utils = require('./utils');
module.exports = function (client) { function requireEmail (options) {
function Person (data) { assert(options.email, 'An email must be provided');
_.extend(this, data); }
}
Person.find = Promise.method(function (options) { exports.Person = resource.create('Person', {
assert(options && options.email, 'An email must be provided'); api: 'person',
return this.client.request(_.extend({ path: '/people/email/<%= email %>',
api: 'person', queryKeys: 'subscribe'
path: '/people/email/' + options.email, })
query: _.pick(options, 'subscribe', 'company') .on('preFind', requireEmail);
}, options))
.bind(this)
.then(utils.cast)
.catch(utils.isQueued, function () {
throw new this.QueuedError('Person lookup queued');
})
.catch(utils.isUnknownRecord, function () {
throw new this.NotFoundError('Person not found');
});
});
Person.prototype.client = Person.client = client; exports.PersonCompany = resource.create('PersonCompany', {
Person.NotFoundError = utils.NotFoundError; api: 'person',
Person.QueuedError = utils.QueuedError; path: '/combined/email/<%= email %>',
queryKeys: 'subscribe'
return Person; })
}; .on('preFind', requireEmail);
'use strict';
var assert = require('assert');
var _ = require('lodash');
var Promise = require('bluebird');
var utils = require('./utils');
module.exports = function (client) {
function PersonCompany (data) {
_.extend(this, data);
}
PersonCompany.find = Promise.method(function (options) {
assert(options && options.email, 'An email must be provided');
return this.client.request(_.extend({
api: 'person',
path: '/combined/email/' + options.email,
query: _.pick(options, 'subscribe', 'webhook_id')
}, options))
.bind(this)
.then(utils.cast)
.catch(utils.isQueued, function () {
throw new this.QueuedError('PersonCompany lookup queued');
})
.catch(utils.isUnknownRecord, function () {
throw new this.NotFoundError('PersonCompany not found');
});
});
PersonCompany.prototype.client = PersonCompany.client = client;
PersonCompany.NotFoundError = utils.NotFoundError;
PersonCompany.QueuedError = utils.QueuedError;
return PersonCompany;
};
'use strict';
var createError = require('create-error');
var EventEmitter = require('events').EventEmitter;
var _ = require('lodash');
var Promise = require('bluebird');
function isQueued (err) {
return err.type === 'queued';
}
function isUnknownRecord (err) {
return err.type === 'unknown_record';
}
function ClearbitResource (data) {
_.extend(this, data);
}
ClearbitResource.find = Promise.method(function (options) {
options = options || /* istanbul ignore next */ {};
this.emit('preFind', options);
return this.client.request(_.extend({
api: this._options.api,
path: this._options.template(options),
query: _.pick(options, this._options.queryKeys)
}, options))
.bind(this)
.then(function (data) {
return new this(data);
})
.catch(isQueued, function () {
throw new this.QueuedError(this._name + ' lookup queued');
})
.catch(isUnknownRecord, function () {
throw new this.NotFoundError(this._name + ' not found');
});
});
function createErrors (name) {
return {
NotFoundError: createError(name + 'NotFoundError'),
QueuedError: createError(name + 'QueuedError')
};
}
exports.create = function (name, options) {
var Resource = function () {
ClearbitResource.apply(this, arguments);
};
_.extend(Resource, new EventEmitter(), EventEmitter.prototype, ClearbitResource, createErrors(name), {
_name: name,
_options: _.extend({}, options, {
template: _.template(options.path)
})
});
return _.extend(function (client) {
return _.extend(Resource, {
client: client
});
},
{
on: function () {
Resource.on.apply(Resource, arguments);
return this;
}
});
};
'use strict';
var createError = require('create-error');
exports.cast = function (data) {
return new this(data);
};
exports.NotFoundError = createError('NotFoundError');
exports.QueuedError = createError('QueuedError');
exports.isUnknownRecord = function (err) {
return err.type === 'unknown_record';
};
exports.isQueued = function (err) {
return err.type === 'queued';
};
\ No newline at end of file
'use strict'; 'use strict';
var expect = require('chai').use(require('chai-as-promised')).expect; var expect = require('chai').use(require('chai-as-promised')).expect;
var nock = require('nock'); var nock = require('nock');
var Person = require('../')('k').Person; var Person = require('../')('k').Person;
var PersonCompany = require('../')('k').PersonCompany;
describe('Person', function () { describe('Person', function () {
...@@ -15,9 +16,10 @@ describe('Person', function () { ...@@ -15,9 +16,10 @@ describe('Person', function () {
mock.done(); mock.done();
}); });
describe('Person#find', function () { var alex = require('./fixtures/person');
var company = require('./fixtures/company');
var alex = require('./fixtures/person'); describe('Person#find', function () {
it('can find a person by email', function () { it('can find a person by email', function () {
mock mock
...@@ -38,13 +40,6 @@ describe('Person', function () { ...@@ -38,13 +40,6 @@ describe('Person', function () {
return Person.find({email: 'alex@alexmaccaw.com', subscribe: true}); return Person.find({email: 'alex@alexmaccaw.com', subscribe: true});
}); });
it('can override the company setting', function () {
mock
.get('/v1/people/email/alex@alexmaccaw.com?company=false')
.reply(200, alex);
return Person.find({email: 'alex@alexmaccaw.com', company: false});
});
it('can handle queued requests', function () { it('can handle queued requests', function () {
mock mock
.get('/v1/people/email/alex@alexmaccaw.com') .get('/v1/people/email/alex@alexmaccaw.com')
...@@ -71,4 +66,37 @@ describe('Person', function () { ...@@ -71,4 +66,37 @@ describe('Person', function () {
}); });
describe('PersonCompany#find', function () {
it('can find a person by email', function () {
mock
.get('/v1/combined/email/alex@alexmaccaw.com')
.reply(200, {
person: alex,
company: company
});
return PersonCompany.find({email: 'alex@alexmaccaw.com'})
.then(function (personCompany) {
expect(personCompany)
.to.be.an.instanceOf(PersonCompany)
.and.have.have.keys('person', 'company')
.and.have.deep.property('person.id', alex.id);
});
});
it('can handle queued requests', function () {
mock
.get('/v1/combined/email/alex@alexmaccaw.com')
.reply(202, {
error: {
type: 'queued'
}
});
return expect(PersonCompany.find({email: 'alex@alexmaccaw.com'}))
.to.be.rejectedWith(PersonCompany.QueuedError);
});
});
}); });
'use strict';
var expect = require('chai').use(require('chai-as-promised')).expect;
var nock = require('nock');
var PersonCompany = require('../')('k').PersonCompany;
describe('PersonCompany', function () {
var mock;
before(function () {
mock = nock('https://person.clearbit.com');
});
after(nock.cleanAll);
afterEach(function () {
mock.done();
});
describe('PersonCompany#find', function () {
var alex = require('./fixtures/person');
it('can find a person by email', function () {
mock
.get('/v1/combined/email/alex@alexmaccaw.com')
.reply(200, alex);
return PersonCompany.find({email: 'alex@alexmaccaw.com'})
.then(function (person) {
expect(person)
.to.be.an.instanceOf(PersonCompany)
.and.have.property('id', alex.id);
});
});
it('can handle queued requests', function () {
mock
.get('/v1/combined/email/alex@alexmaccaw.com')
.reply(202, {
error: {
type: 'queued'
}
});
return expect(PersonCompany.find({email: 'alex@alexmaccaw.com'}))
.to.be.rejectedWith(PersonCompany.QueuedError);
});
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment