Comparing version 1.0.0 to 1.0.1
@@ -1,1 +0,1 @@ | ||
module.exports = require('./lib'); | ||
module.exports = require('./lib'); |
@@ -5,3 +5,5 @@ ## 1.0.0 (2015-11-04) | ||
- Callbacks were changed to correctly implement 'error first' pattern. | ||
- Initialization method must be invoked even when setting environment variables<br> | ||
`var bby = require('bestbuy')();` | ||
- Callbacks were changed to correctly implement 'error first' pattern.<br> | ||
@@ -8,0 +10,0 @@ Features: |
@@ -9,24 +9,26 @@ // Initialize with your Best Buy developer API key - if it is present as a | ||
bby.products('customerReviewAverage=4', { | ||
show: 'name,sku' | ||
}, function(err, data) { | ||
console.log('Product Search result number one:'); | ||
console.log(data.products[0]); | ||
console.log(''); | ||
show: 'name,sku' | ||
}, function (err, data) { | ||
if (err) console.error(err); | ||
console.log('Product Search result number one:'); | ||
console.log(data.products[0]); | ||
console.log(''); | ||
}); | ||
// Do a search which emits an error | ||
bby.products('gurgleflats????4', function(err, data) { | ||
console.log('Here is what an error looks like:'); | ||
console.log('HTTP Status Code: ' + err.statusCode); | ||
console.log(err.message); | ||
console.log('There are %d examples of how to do it right', | ||
bby.products('gurgleflats????4', function (err, data) { | ||
console.log('Here is what an error looks like:'); | ||
console.log('HTTP Status Code: ' + err.statusCode); | ||
console.log(err.message); | ||
console.log('There are %d examples of how to do it right', | ||
err.error.error.examples.length); | ||
console.log(''); | ||
console.log(''); | ||
}); | ||
bby.products('manufacturer=canon&salePrice<1000', { | ||
format: 'json', | ||
show: 'sku,name,salePrice' | ||
}, function(err, data) { | ||
console.log(data.products[0]); | ||
}); | ||
format: 'json', | ||
show: 'sku,name,salePrice' | ||
}, function (err, data) { | ||
if (err) console.error(err); | ||
console.log(data.products[0]); | ||
}); |
@@ -7,17 +7,19 @@ // Initialize with your Best Buy developer API key - if it is present as a | ||
var bby = BBY({ | ||
key: process.env.BBY_API_KEY, | ||
url: 'https://api.bestbuy.com/v1', | ||
debug: true, | ||
headers: { | ||
'User-Agent': 'recommendations example' | ||
} | ||
key: process.env.BBY_API_KEY, | ||
url: 'https://api.bestbuy.com/v1', | ||
debug: true, | ||
headers: { | ||
'User-Agent': 'recommendations example' | ||
} | ||
}); | ||
// Figure out the current top trending product | ||
bby.recommendations('trendingViewed', function(err, data) { | ||
var topTrendingSku = data.results[0].sku; | ||
bby.products(+topTrendingSku, function(err, data) { | ||
console.log('This is the top trending product right now:'); | ||
console.log(data); | ||
}); | ||
}); | ||
bby.recommendations('trendingViewed', function (err, data) { | ||
if (err) console.error(err); | ||
var topTrendingSku = data.results[0].sku; | ||
bby.products(+topTrendingSku, function (err, data) { | ||
if (err) console.error(err); | ||
console.log('This is the top trending product right now:'); | ||
console.log(data); | ||
}); | ||
}); |
@@ -8,14 +8,16 @@ // Initialize with your Best Buy developer API key - if it is present as a | ||
// Do a query for stores | ||
bby.stores('area(55119,25)&storeType=BigBox', function(err, data) { | ||
console.log('Store Search:'); | ||
console.log('found %d stores.', data.stores.length); | ||
console.log(''); | ||
bby.stores('area(55119,25)&storeType=BigBox', function (err, data) { | ||
if (err) console.error(err); | ||
console.log('Store Search:'); | ||
console.log('found %d stores.', data.stores.length); | ||
console.log(''); | ||
}); | ||
// Show details for one store | ||
bby.stores(1443, function(err, data) { | ||
console.log('Store Details:'); | ||
console.log(data.longName); | ||
console.log(data.address); | ||
console.log(''); | ||
}); | ||
bby.stores(1443, function (err, data) { | ||
if (err) console.error(err); | ||
console.log('Store Details:'); | ||
console.log(data.longName); | ||
console.log(data.address); | ||
console.log(''); | ||
}); |
'use strict'; | ||
var AvailabilityStrategy = function() { | ||
var AvailabilityStrategy = function () { | ||
return function (sku, storeIds) { | ||
var options = { | ||
path: '/', | ||
qs: {} | ||
}; | ||
return function(sku, storeIds) { | ||
var options = { | ||
path: '/', | ||
qs: {} | ||
}; | ||
if (typeof sku !== 'number' && typeof sku !== 'string') { | ||
return new Error('First parameter of "availability" must be the SKU, and it must be either a number or a string'); | ||
} | ||
if (typeof sku !== 'number' && typeof sku !== 'string') { | ||
return new Error('First parameter of "availability" must be the SKU, and it must be either a number or a string'); | ||
} | ||
if (typeof storeIds !== 'number' && Array.isArray(storeIds) === false) { | ||
return new Error('Second parameter of "availability" must be store id(s), and it must be either a number or array of numbers'); | ||
} else if (Array.isArray(storeIds)) { | ||
storeIds = storeIds.join(','); | ||
} | ||
if (typeof storeIds !== 'number' && Array.isArray(storeIds) === false) { | ||
return new Error('Second parameter of "availability" must be store id(s), and it must be either a number or array of numbers'); | ||
} else if (Array.isArray(storeIds)) { | ||
storeIds = storeIds.join(','); | ||
} | ||
if (arguments.length === 3) { | ||
options.qs = arguments[2]; | ||
} | ||
if (arguments.length > 3) { | ||
return new Error('Unrecognized parameter length when calling "availability" method'); | ||
} | ||
if (arguments.length === 3) { | ||
options.qs = arguments[2]; | ||
} | ||
if (arguments.length > 3) { | ||
return new Error('Unrecognized parameter length when calling "availability" method'); | ||
} | ||
if (!options.qs.show) { | ||
options.qs.show = 'name,sku,stores'; | ||
} | ||
if (!options.qs.show) { | ||
options.qs.show = 'name,sku,stores'; | ||
} | ||
options.path = '/products(sku=' + sku + ')+stores(storeId in(' + storeIds + '))'; | ||
options.path = '/products(sku=' + sku + ')+stores(storeId in(' + storeIds + '))'; | ||
// Execute request | ||
return options; | ||
}; | ||
return options; | ||
}; | ||
}; | ||
module.exports = AvailabilityStrategy; | ||
module.exports = AvailabilityStrategy; |
'use strict'; | ||
var DefaultStrategy = function(resourceName) { | ||
var DefaultStrategy = function (resourceName) { | ||
return function () { | ||
var options = { | ||
path: '/' + resourceName | ||
}; | ||
return function() { | ||
var options = { | ||
path: '/' + resourceName | ||
}; | ||
// process arguments | ||
for (var i = 0; i < arguments.length; i++) { | ||
var arg = arguments[i]; | ||
if (typeof arg === 'string') { | ||
for (var i = 0; i < arguments.length; i++) { | ||
var arg = arguments[i]; | ||
if (typeof arg === 'string') { | ||
// The BBY query language string for this request | ||
options.query = arg; | ||
} else if (!isNaN(arg) && typeof arg === 'number') { | ||
options.query = arg; | ||
} else if (!isNaN(arg) && typeof arg === 'number') { | ||
// Resource ID | ||
options.id = arg; | ||
} else if (typeof arg === 'function') { | ||
options.id = arg; | ||
} else if (typeof arg === 'function') { | ||
// Result callback | ||
return new Error('Unhandled parameter type'); | ||
} else if (arg !== null && arg !== undefined) { | ||
return new Error('Unhandled parameter type'); | ||
} else if (arg !== null && arg !== undefined) { | ||
// Assume any object literal is a set of query params | ||
options.qs = arg; | ||
} | ||
} | ||
options.qs = arg; | ||
} | ||
} | ||
// Execute request | ||
return options; | ||
}; | ||
return options; | ||
}; | ||
}; | ||
module.exports = DefaultStrategy; | ||
module.exports = DefaultStrategy; |
'use strict'; | ||
var _ = require('lodash'); | ||
var assign = require('lodash.assign'); | ||
var Resource = require('./Resource'); | ||
@@ -12,45 +12,45 @@ var Default = require('./DefaultStrategy'); | ||
var BBY = { | ||
init: function(options) { | ||
this.options = { | ||
key: process.env.BBY_API_KEY, | ||
url: 'https://api.bestbuy.com/v1', | ||
debug: false, | ||
headers: { | ||
'User-Agent': 'bestbuy-sdk-js/' + pkg.version + ';nodejs' | ||
} | ||
}; | ||
init: function (options) { | ||
this.options = { | ||
key: process.env.BBY_API_KEY, | ||
url: 'https://api.bestbuy.com/v1', | ||
debug: false, | ||
headers: { | ||
'User-Agent': 'bestbuy-sdk-js/' + pkg.version + ';nodejs' | ||
} | ||
}; | ||
// As an effort to support the v0.0.1 functionality, if initialized with just | ||
// a string, we assume that string is the key | ||
if (typeof options === 'string') { | ||
this.options.key = options; | ||
} else if (typeof options === 'object') { | ||
this.options = _.extend(this.options, options); | ||
} | ||
this.availability = Resource(Availability(), this.options); | ||
this.openBox = Resource(OpenBox(), { | ||
key: this.options.key, | ||
debug: this.options.debug, | ||
url: 'https://api.bestbuy.com/beta', | ||
headers: this.options.headers | ||
}); | ||
this.categories = Resource(Default('categories'), this.options); | ||
this.products = Resource(Default('products'), this.options); | ||
this.recommendations = Resource(Recommendations(), { | ||
key: this.options.key, | ||
debug: this.options.debug, | ||
url: 'https://api.bestbuy.com/beta', | ||
headers: this.options.headers | ||
}); | ||
this.reviews = Resource(Default('reviews'), this.options); | ||
this.stores = Resource(Default('stores'), this.options); | ||
return this; | ||
if (typeof options === 'string') { | ||
this.options.key = options; | ||
} else if (typeof options === 'object') { | ||
this.options = assign(this.options, options); | ||
} | ||
this.availability = Resource(Availability(), this.options); | ||
this.openBox = Resource(OpenBox(), { | ||
key: this.options.key, | ||
debug: this.options.debug, | ||
url: 'https://api.bestbuy.com/beta', | ||
headers: this.options.headers | ||
}); | ||
this.categories = Resource(Default('categories'), this.options); | ||
this.products = Resource(Default('products'), this.options); | ||
this.recommendations = Resource(Recommendations(), { | ||
key: this.options.key, | ||
debug: this.options.debug, | ||
url: 'https://api.bestbuy.com/beta', | ||
headers: this.options.headers | ||
}); | ||
this.reviews = Resource(Default('reviews'), this.options); | ||
this.stores = Resource(Default('stores'), this.options); | ||
return this; | ||
} | ||
}; | ||
function newInstance(options) { | ||
var bby = Object.create(BBY); | ||
return bby.init(options); | ||
function newInstance (options) { | ||
var bby = Object.create(BBY); | ||
return bby.init(options); | ||
} | ||
// Module config + REST resources is the public module interface | ||
module.exports = newInstance; | ||
module.exports = newInstance; |
'use strict'; | ||
var OpenBoxStrategy = function() { | ||
var OpenBoxStrategy = function () { | ||
return function (search) { | ||
var options = { | ||
path: '/products/openBox' | ||
}; | ||
return function(search) { | ||
var options = { | ||
path: '/products/openBox' | ||
}; | ||
if (typeof search === 'number') { | ||
options.path = '/products/' + search + '/openBox'; | ||
} else if (typeof search === 'string' && search.length > 0) { | ||
// Search is still a "sku", but was passed as a string | ||
if (!isNaN(parseInt(search))) { | ||
options.path = '/products/' + search + '/openBox'; | ||
} else { | ||
options.path += '(' + search + ')'; | ||
} | ||
} | ||
if (typeof search === 'number') { | ||
options.path = '/products/' + search + '/openBox'; | ||
} else if (typeof search === 'string' && search.length > 0) { | ||
//Search is still a "sku", but was passed as a string | ||
if (!isNaN(parseInt(search))) { | ||
options.path = '/products/' + search + '/openBox'; | ||
} else { | ||
options.path += '(' + search + ')'; | ||
} | ||
} | ||
if (typeof arguments[1] !== 'undefined') { | ||
options.qs = arguments[1]; | ||
} | ||
if (typeof arguments[1] !== 'undefined') { | ||
options.qs = arguments[1]; | ||
} | ||
// Execute request | ||
return options; | ||
}; | ||
return options; | ||
}; | ||
}; | ||
module.exports = OpenBoxStrategy; | ||
module.exports = OpenBoxStrategy; |
'use strict'; | ||
var RecommendationsStrategy = function() { | ||
var RecommendationsStrategy = function () { | ||
return function (path, criteria) { | ||
var options = { | ||
path: '/products' | ||
}; | ||
return function(path, criteria) { | ||
var options = { | ||
path: '/products' | ||
}; | ||
if (path === 'mostViewed' || path === 'trendingViewed') { | ||
options.path += '/' + path; | ||
if (typeof criteria === 'string') { | ||
options.path += '(categoryId=' + criteria + ')'; | ||
} | ||
} else if (path === 'alsoViewed' || path === 'similar') { | ||
if (typeof criteria !== 'string' && typeof criteria !== 'number') { | ||
return new Error('Recommendations endpoint requires 2nd parameter to be a SKU for the "' + path + '" method'); | ||
} | ||
options.path += '/' + criteria + '/' + path; | ||
} else { | ||
return new Error('Unrecognized path "' + path + '"'); | ||
} | ||
if (path === 'mostViewed' || path === 'trendingViewed') { | ||
options.path += '/' + path; | ||
if (typeof criteria === 'string') { | ||
options.path += '(categoryId=' + criteria + ')'; | ||
} | ||
} else if (path === 'alsoViewed' || path === 'similar') { | ||
if (typeof criteria !== 'string' && typeof criteria !== 'number') { | ||
return new Error('Recommendations endpoint requires 2nd parameter to be a SKU for the "' + path + '" method'); | ||
} | ||
options.path += '/' + criteria + '/' + path; | ||
} else { | ||
return new Error('Unrecognized path "' + path + '"'); | ||
} | ||
if (typeof arguments[arguments.length - 1] === 'object') { | ||
options.qs = arguments[arguments.length - 1]; | ||
} | ||
if (typeof arguments[arguments.length - 1] === 'function') { | ||
return new Error('Unhandled parameter type'); | ||
} | ||
if (typeof arguments[arguments.length - 1] === 'object') { | ||
options.qs = arguments[arguments.length - 1]; | ||
} | ||
if (typeof arguments[arguments.length - 1] === 'function') { | ||
return new Error('Unhandled parameter type'); | ||
} | ||
// Execute request | ||
return options; | ||
}; | ||
return options; | ||
}; | ||
}; | ||
module.exports = RecommendationsStrategy; | ||
module.exports = RecommendationsStrategy; |
'use strict'; | ||
var request = require('request-promise'); | ||
var _ = require('lodash'); | ||
var assign = require('lodash.assign'); | ||
var Promise = require('bluebird'); | ||
var Resource = function(strategy, config) { | ||
var Resource = function (_strategy, _config) { | ||
var config = _config; | ||
var strategy = _strategy; | ||
var config = config; | ||
var strategy = strategy; | ||
return function () { | ||
var requestOptions; | ||
var callback; | ||
var handleErr = function (err) { | ||
if (callback) { | ||
callback(err); | ||
return; | ||
} else { | ||
return Promise.reject(err); | ||
} | ||
}; | ||
return function() { | ||
// find callback | ||
var args = Array.prototype.slice.call(arguments); | ||
if (args !== null && typeof args[args.length - 1] === 'function') { | ||
callback = args.pop(); | ||
} | ||
var requestOptions; | ||
var callback; | ||
var handleErr = function(err) { | ||
if (callback) { | ||
callback(err); | ||
return; | ||
} else { | ||
return Promise.reject(err); | ||
} | ||
}; | ||
try { | ||
requestOptions = strategy.apply(null, args); | ||
} catch (err) { | ||
return handleErr(err); | ||
} | ||
//find callback | ||
var args = Array.prototype.slice.call(arguments); | ||
if (args !== null && typeof args[args.length - 1] === 'function') { | ||
callback = args.pop(); | ||
} | ||
if (requestOptions instanceof Error) { | ||
return handleErr(requestOptions.message); | ||
} | ||
try { | ||
requestOptions = strategy.apply(null, args); | ||
} catch (err) { | ||
return handleErr(err); | ||
} | ||
if (requestOptions instanceof Error) { | ||
return handleErr(requestOptions.message); | ||
} | ||
// Throw if BBY API key has not been specified | ||
if (!config.key) { | ||
throw new Error('A Best Buy developer API key is required. Register for one at ' + | ||
if (!config.key) { | ||
throw new Error('A Best Buy developer API key is required. Register for one at ' + | ||
'developer.bestbuy.com, call bestbuy(YOUR_API_KEY), or ' + | ||
'specify a BBY_API_KEY system environment variable.'); | ||
} | ||
} | ||
if (config.debug) { | ||
require('request-debug')(request); | ||
} | ||
if (config.debug) { | ||
require('request-debug')(request); | ||
} | ||
// set up query string defaults | ||
var qs = _.extend({ | ||
apiKey: config.key, | ||
format: 'json' | ||
}, requestOptions.qs); | ||
// set up query string defaults | ||
var qs = assign({ | ||
apiKey: config.key, | ||
format: 'json' | ||
}, requestOptions.qs); | ||
// Assemble request URL | ||
var url = config.url + requestOptions.path; | ||
if (requestOptions.query) { | ||
url = url + '(' + requestOptions.query + ')'; | ||
} | ||
if (requestOptions.id) { | ||
url = url + '/' + requestOptions.id + '.json'; | ||
var url = config.url + requestOptions.path; | ||
if (requestOptions.query) { | ||
url = url + '(' + requestOptions.query + ')'; | ||
} | ||
if (requestOptions.id) { | ||
url = url + '/' + requestOptions.id + '.json'; | ||
// sending a format for a specific resource results in a 400 :/ | ||
delete qs.format; | ||
} | ||
delete qs.format; | ||
} | ||
var headers = {}; | ||
if (config.headers instanceof Object) | ||
headers = config.headers; | ||
var headers = {}; | ||
if (config.headers instanceof Object) { | ||
headers = config.headers; | ||
} | ||
var options = { | ||
uri: url, | ||
qs: qs, | ||
headers: headers, | ||
json: true | ||
}; | ||
var options = { | ||
uri: url, | ||
qs: qs, | ||
headers: headers, | ||
json: true | ||
}; | ||
return request(options) | ||
.then(function(body) { | ||
if (callback) { | ||
callback(null, body); | ||
} else | ||
return body; | ||
}) | ||
.catch(function(err) { | ||
if (callback) { | ||
callback(err); | ||
} else | ||
return err; | ||
}); | ||
}; | ||
return request(options) | ||
.then(function (body) { | ||
if (callback) { | ||
callback(null, body); | ||
} else { | ||
return body; | ||
} | ||
}) | ||
.catch(function (err) { | ||
if (callback) { | ||
callback(err); | ||
} else { throw err; } | ||
}); | ||
}; | ||
}; | ||
module.exports = Resource; | ||
module.exports = Resource; |
{ | ||
"name": "bestbuy", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "High level node.js client for the Best Buy API.", | ||
"main": "bestbuy.js", | ||
"scripts": { | ||
"test": "jasmine-node spec", | ||
"coverage": "istanbul cover jasmine-node --captureExceptions spec", | ||
"coveralls": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage", | ||
"pretty": "fixmyjs --legacy *.js */*.js && js-beautify -r *.js */*.js" | ||
"record": "rm -rf test/fixtures/*.json && NOCK_BACK_MODE=record npm test", | ||
"test-live": "NOCK_BACK_MODE=wild npm test", | ||
"test": "tape test/*.test.js | tap-spec && semistandard ", | ||
"coverage": "istanbul cover tape test/*.test.js", | ||
"coveralls": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage" | ||
}, | ||
@@ -26,3 +27,3 @@ "repository": { | ||
"Eric Caron <eric.caron@gmail.com> (http://ericcaron.com/)", | ||
"Dan Flettre <fletd01@yahoo.com>" | ||
"Dan Flettre <flettre@gmail.com>" | ||
], | ||
@@ -36,14 +37,15 @@ "license": "MIT", | ||
"bluebird": "^3.0.5", | ||
"lodash": ">2 <4", | ||
"request": "^2.40.0", | ||
"lodash.assign": "^4.2.0", | ||
"request": "^2.79.0", | ||
"request-debug": "^0.2.0", | ||
"request-promise": "^1.0.2" | ||
"request-promise": "^4.1.1" | ||
}, | ||
"devDependencies": { | ||
"coveralls": "^2.11.4", | ||
"fixmyjs": "^1.0.3", | ||
"istanbul": "^0.4.0", | ||
"jasmine-node": "^1.14.5", | ||
"js-beautify": "^1.5.10" | ||
"semistandard": "^9.2.1", | ||
"tap-spec": "^4.1.1", | ||
"tape": "^4.6.3", | ||
"tape-nock": "^1.4.0" | ||
} | ||
} |
@@ -28,3 +28,4 @@ # Best Buy API | ||
3. The library requires an API key to be provided before it can be used. You can set that in one of three ways: | ||
* Set an environment variable of `BBY_API_KEY` to your key | ||
* Set an environment variable of `BBY_API_KEY` to your key and invoke the method<br> | ||
`var bby = require('bestbuy')();` | ||
* Send the key in as a string when invoking the method<br> | ||
@@ -40,3 +41,3 @@ `var bby = require('bestbuy')('YOURKEY');` | ||
- [`categories`](#categories) | ||
- [`openBox`](#openBox) | ||
- [`openBox`](#openbox) | ||
- [`products`](#products) | ||
@@ -261,3 +262,16 @@ - [`recommendations`](#recommendations) | ||
``` | ||
Note that this uses nock fixtures to mock all network calls. | ||
Run tests against the live API (BBY_API_KEY env var needs to be set): | ||
```bash | ||
npm run test-live | ||
``` | ||
If tests are added, re-record the mock fixtures: | ||
``` | ||
npm run record | ||
# tests will run against the live API and their output will be saved in test/fixtures | ||
``` | ||
## Online Resources | ||
@@ -264,0 +278,0 @@ - [Best Buy Developer Portal](https://developer.bestbuy.com) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
447030
66
9700
282
6
14
2
+ Addedlodash.assign@^4.2.0
+ Addedlodash@4.17.21(transitive)
+ Addedlodash.assign@4.2.0(transitive)
+ Addedrequest-promise@4.2.6(transitive)
+ Addedrequest-promise-core@1.1.4(transitive)
+ Addedstealthy-require@1.1.1(transitive)
- Removedlodash@>2 <4
- Removedbluebird@2.11.0(transitive)
- Removedcls-bluebird@1.1.3(transitive)
- Removedis-bluebird@1.0.2(transitive)
- Removedlodash@3.10.1(transitive)
- Removedrequest-promise@1.0.2(transitive)
- Removedshimmer@1.2.1(transitive)
Updatedrequest@^2.79.0
Updatedrequest-promise@^4.1.1