ebay-api-async
Advanced tools
Comparing version 1.13.5 to 1.14.0
@@ -1,6 +0,4 @@ | ||
var | ||
_ = require('lodash'), | ||
debug = require('debug')('ebay:defaults'); | ||
var _ = require('lodash'), | ||
debug = require('debug')('ebay:defaults') | ||
/* | ||
@@ -11,3 +9,3 @@ default params per service type. | ||
exports.getDefaultHeaders = function(options) { | ||
if (!options || !options.serviceName) throw new Error("Need serviceName for default params"); | ||
if (!options || !options.serviceName) throw new Error('Need serviceName for default params') | ||
@@ -22,4 +20,4 @@ switch (options.serviceName) { | ||
'X-EBAY-SOA-SERVICE-VERSION': options.version ? options.version : '1.13.0', | ||
'X-EBAY-SOA-OPERATION-NAME': options.opType | ||
}; | ||
'X-EBAY-SOA-OPERATION-NAME': options.opType, | ||
} | ||
@@ -35,4 +33,4 @@ case 'Product': | ||
'RESPONSE-DATA-FORMAT': 'XML', | ||
'REST-PAYLOAD': null // (not sure what this does) | ||
}; | ||
'REST-PAYLOAD': null, // (not sure what this does) | ||
} | ||
@@ -48,3 +46,3 @@ case 'Merchandising': | ||
//'REST-PAYLOAD': null // (not sure what this does) | ||
}; | ||
} | ||
@@ -61,3 +59,3 @@ case 'Shopping': | ||
//'Accept': 'text/xml' | ||
}; | ||
} | ||
@@ -72,4 +70,13 @@ case 'Trading': | ||
'X-EBAY-API-CERT-NAME': options.certId, | ||
}; | ||
} | ||
case 'SellerProfilesManagement': | ||
return { | ||
'X-EBAY-SOA-GLOBAL-ID': 'EBAY-US', | ||
'X-EBAY-SOA-SERVICE-NAME': 'SellerProfilesManagementService', | ||
'X-EBAY-SOA-OPERATION-NAME': options.opType, | ||
'X-EBAY-SOA-SERVICE-VERSION': '1.0.0', | ||
'X-EBAY-SOA-SECURITY-TOKEN': options.authToken, | ||
} | ||
} | ||
}; | ||
} |
@@ -1,6 +0,4 @@ | ||
var | ||
_ = require('lodash'), | ||
debug = require('debug')('ebay:urls'); | ||
var _ = require('lodash'), | ||
debug = require('debug')('ebay:urls') | ||
/* | ||
@@ -11,7 +9,7 @@ build URL to API endpoints. | ||
exports.buildRequestUrl = function(options) { | ||
var url; | ||
var url | ||
options = options || {}; | ||
options = options || {} | ||
var serviceName = options.serviceName.replace(/Service$/, ''); | ||
var serviceName = options.serviceName.replace(/Service$/, '') | ||
@@ -22,26 +20,33 @@ // note: sandboxes do not all support SSL. | ||
case 'Finding': | ||
if (options.sandbox) url = 'http://svcs.sandbox.ebay.com/services/search/FindingService/v1'; | ||
else url = 'http://svcs.ebay.com/services/search/FindingService/v1'; // no HTTPS support, really?! | ||
break; | ||
if (options.sandbox) url = 'http://svcs.sandbox.ebay.com/services/search/FindingService/v1' | ||
else url = 'http://svcs.ebay.com/services/search/FindingService/v1' // no HTTPS support, really?! | ||
break | ||
case 'Product': | ||
if (options.sandbox) url = 'http://svcs.sandbox.ebay.com/services/marketplacecatalog/' + serviceName + '/v1'; | ||
else url = 'http://svcs.ebay.com/services/marketplacecatalog/' + serviceName + '/v1'; // no HTTPS support, really?! | ||
break; | ||
if (options.sandbox) | ||
url = 'http://svcs.sandbox.ebay.com/services/marketplacecatalog/' + serviceName + '/v1' | ||
else url = 'http://svcs.ebay.com/services/marketplacecatalog/' + serviceName + '/v1' // no HTTPS support, really?! | ||
break | ||
case 'Shopping': | ||
if (options.sandbox) url = 'http://open.api.sandbox.ebay.com/shopping'; | ||
else url = "http://open.api.ebay.com/shopping"; // no HTTPS support, really?! | ||
break; | ||
if (options.sandbox) url = 'http://open.api.sandbox.ebay.com/shopping' | ||
else url = 'http://open.api.ebay.com/shopping' // no HTTPS support, really?! | ||
break | ||
case 'Trading': | ||
if (options.sandbox) url = 'https://api.sandbox.ebay.com/ws/api.dll'; | ||
else url = 'https://api.ebay.com/ws/api.dll'; | ||
break; | ||
if (options.sandbox) url = 'https://api.sandbox.ebay.com/ws/api.dll' | ||
else url = 'https://api.ebay.com/ws/api.dll' | ||
break | ||
case 'Merchandising': | ||
if (options.sandbox) url = 'http://svcs.sandbox.ebay.com/MerchandisingService'; | ||
else url = "https://svcs.ebay.com/MerchandisingService"; | ||
break; | ||
if (options.sandbox) url = 'http://svcs.sandbox.ebay.com/MerchandisingService' | ||
else url = 'https://svcs.ebay.com/MerchandisingService' | ||
break | ||
case 'SellerProfilesManagement': | ||
if (options.sandbox) | ||
url = 'http://svcs.sandbox.ebay.com/services/selling/v1/SellerProfilesManagementService' | ||
else url = 'https://svcs.ebay.com/services/selling/v1/SellerProfilesManagementService' | ||
break | ||
// this is not a real service, it's more of a meta-service. the name is made up here. | ||
@@ -52,11 +57,12 @@ // it's also not really an API - it's used for HTML consent pages - | ||
case 'Signin': | ||
if (options.sandbox) url = 'https://signin.sandbox.ebay.com/ws/eBayISAPI.dll'; | ||
else url = 'https://signin.ebay.com/ws/eBayISAPI.dll'; | ||
break; | ||
if (options.sandbox) url = 'https://signin.sandbox.ebay.com/ws/eBayISAPI.dll' | ||
else url = 'https://signin.ebay.com/ws/eBayISAPI.dll' | ||
break | ||
default: | ||
if (options.sandbox) { | ||
throw new Error("Sandbox endpoint for " + serviceName + " service not yet implemented. Please add."); | ||
} | ||
else url = "https://svcs.ebay.com/" + serviceName + 'Service?'; | ||
throw new Error( | ||
'Sandbox endpoint for ' + serviceName + ' service not yet implemented. Please add.', | ||
) | ||
} else url = 'https://svcs.ebay.com/' + serviceName + 'Service?' | ||
} | ||
@@ -66,3 +72,3 @@ | ||
return url; | ||
}; | ||
return url | ||
} |
@@ -1,3 +0,2 @@ | ||
var | ||
_ = require('lodash'), | ||
var _ = require('lodash'), | ||
debug = require('debug')('ebay:request'), | ||
@@ -14,5 +13,4 @@ timer = require('debug')('ebay:timer'), | ||
deepToArray = require('./deep-to-array').deepToArray, | ||
EbayClientError = require('./errors').EbayClientError; | ||
EbayClientError = require('./errors').EbayClientError | ||
/* | ||
@@ -24,35 +22,32 @@ build XML input for XML requests (POST). | ||
function buildXmlInput(options) { | ||
debug('buildXmlInput', options); | ||
debug('buildXmlInput', options) | ||
var data = {}, root; | ||
var params = options.params || {}; | ||
var data = {}, | ||
root | ||
var params = options.params || {} | ||
root = data[options.opType + 'Request'] = []; // e.g. <GetOrdersRequest> | ||
root = data[options.opType + 'Request'] = [] // e.g. <GetOrdersRequest> | ||
if (options.serviceName === 'Finding') { | ||
root.push({'_attr': {'xmlns': 'http://www.ebay.com/marketplace/search/v1/services'}}); | ||
root.push({ _attr: { xmlns: 'http://www.ebay.com/marketplace/search/v1/services' } }) | ||
} else { | ||
root.push({ _attr: { xmlns: 'urn:ebay:apis:eBLBaseComponents' } }) | ||
} | ||
else { | ||
root.push({'_attr': {'xmlns': 'urn:ebay:apis:eBLBaseComponents'}}); | ||
} | ||
if (options.authToken) { | ||
root.push({ 'RequesterCredentials': [ { 'eBayAuthToken' : options.authToken } ] }); | ||
if (options.serviceName !== 'SellerProfilesManagement' && options.authToken) { | ||
root.push({ RequesterCredentials: [{ eBayAuthToken: options.authToken }] }) | ||
} | ||
// concat | ||
root.push.apply(root, deepToArray(params)); | ||
root.push.apply(root, deepToArray(params)) | ||
debug('Converting to XML', data); | ||
debug('Converting to XML', data) | ||
var xmlBody = | ||
'<?xml version="1.0" encoding="UTF-8"?>\n' + | ||
xmlBuilder([data], true); | ||
var xmlBody = '<?xml version="1.0" encoding="UTF-8"?>\n' + xmlBuilder([data], true) | ||
debug('XML body', xmlBody); | ||
debug('XML body', xmlBody) | ||
return xmlBody; | ||
return xmlBody | ||
} | ||
/* | ||
@@ -88,61 +83,66 @@ @param {object} @options: | ||
exports.xmlRequest = function(options, callback) { | ||
var _startTime = Date.now(); | ||
var _startTime = Date.now() | ||
debug('XML request', options); | ||
options = options || {}; | ||
debug('XML request', options) | ||
options = options || {} | ||
if (! options.serviceName) return callback(new Error("Missing serviceName")); | ||
if (! options.opType) return callback(new Error("Missing opType")); | ||
if (!options.serviceName) return callback(new Error('Missing serviceName')) | ||
if (!options.opType) return callback(new Error('Missing opType')) | ||
options.xmlConverter = options.xmlConverter || convertXmlToJson; | ||
options.parser = options.parser || parseResponseJson; | ||
options.xmlConverter = options.xmlConverter || convertXmlToJson | ||
options.parser = options.parser || parseResponseJson | ||
// for default parser | ||
options.parseDepth = options.parseDepth != null ? options.parseDepth : -1; // default parse all the way | ||
options.parseDepth = options.parseDepth != null ? options.parseDepth : -1 // default parse all the way | ||
options.reqOptions = options.reqOptions || {}; | ||
options.reqOptions.headers = options.reqOptions.headers || {}; | ||
_.defaults(options.reqOptions.headers, getDefaultHeaders(options)); | ||
options.reqOptions = options.reqOptions || {} | ||
options.reqOptions.headers = options.reqOptions.headers || {} | ||
_.defaults(options.reqOptions.headers, getDefaultHeaders(options)) | ||
// allow options to override default url (and body) if they want to. | ||
options.reqOptions = _.extend({ | ||
url: buildRequestUrl(options), | ||
body: buildXmlInput(options), | ||
// As of 3/22/2016, the eBay API has several servers that can only | ||
// negotiate TLS v1.0 sessions, and several servers that can negotiate TLS | ||
// v1.0, v1.1 and v1.2. Node/OpenSSL get confused by this, and occasionally | ||
// attempt to parse a v1.2 response using TLS v1.0 and vice versa. The | ||
// error you get back from the request looks something like this: | ||
// | ||
// { [Error: write EPROTO 140113357338496:error:1408F10B:SSL | ||
// routines:SSL3_GET_RECORD:wrong version number:../deps/openssl/openssl/ssl/s3_pkt.c:362: | ||
// ] code: 'EPROTO', | ||
// errno: 'EPROTO', | ||
// syscall: 'write' } | ||
// | ||
// As far as I can tell, this isn't patched yet, in Node or OpenSSL. But | ||
// setting the following options forces all connections to be negotiated | ||
// with TLS v1.0, effectively fixing the issue. | ||
// | ||
// More reading: | ||
// | ||
// https://github.com/aws/aws-sdk-js/issues/862 | ||
// https://github.com/nodejs/node/issues/3692 | ||
// https://www.ssllabs.com/ssltest/analyze.html?d=api.ebay.com | ||
agentOptions: { | ||
ciphers: 'ALL', | ||
secureProtocol: 'TLSv1_method', | ||
options.reqOptions = _.extend( | ||
{ | ||
url: buildRequestUrl(options), | ||
body: buildXmlInput(options), | ||
// As of 3/22/2016, the eBay API has several servers that can only | ||
// negotiate TLS v1.0 sessions, and several servers that can negotiate TLS | ||
// v1.0, v1.1 and v1.2. Node/OpenSSL get confused by this, and occasionally | ||
// attempt to parse a v1.2 response using TLS v1.0 and vice versa. The | ||
// error you get back from the request looks something like this: | ||
// | ||
// { [Error: write EPROTO 140113357338496:error:1408F10B:SSL | ||
// routines:SSL3_GET_RECORD:wrong version number:../deps/openssl/openssl/ssl/s3_pkt.c:362: | ||
// ] code: 'EPROTO', | ||
// errno: 'EPROTO', | ||
// syscall: 'write' } | ||
// | ||
// As far as I can tell, this isn't patched yet, in Node or OpenSSL. But | ||
// setting the following options forces all connections to be negotiated | ||
// with TLS v1.0, effectively fixing the issue. | ||
// | ||
// More reading: | ||
// | ||
// https://github.com/aws/aws-sdk-js/issues/862 | ||
// https://github.com/nodejs/node/issues/3692 | ||
// https://www.ssllabs.com/ssltest/analyze.html?d=api.ebay.com | ||
agentOptions: { | ||
ciphers: 'ALL', | ||
secureProtocol: 'TLSv1_method', | ||
}, | ||
}, | ||
}, options.reqOptions); | ||
options.reqOptions, | ||
) | ||
debug('XML request options', options.reqOptions); | ||
timer('time to initiate request', Date.now() - _startTime); | ||
debug('XML request options', options.reqOptions) | ||
timer('time to initiate request', Date.now() - _startTime) | ||
request.post(options.reqOptions, function(error, response) { | ||
debug( | ||
'response', | ||
error ? { error: error } : { statusCode: response.statusCode, body: response.body }, | ||
) | ||
timer('time to response', Date.now() - _startTime) | ||
debug('response', error ? {error: error} : {statusCode: response.statusCode, body: response.body}); | ||
timer('time to response', Date.now() - _startTime); | ||
if (error) { | ||
return callback(error); | ||
return callback(error) | ||
} | ||
@@ -154,5 +154,11 @@ | ||
if (response.statusCode !== 200) { | ||
return callback(new EbayClientError( | ||
util.format("Bad response status code", response.statusCode, (response.body ? response.body.toString() : null)) | ||
)); | ||
return callback( | ||
new EbayClientError( | ||
util.format( | ||
'Bad response status code', | ||
response.statusCode, | ||
response.body ? response.body.toString() : null, | ||
), | ||
), | ||
) | ||
} | ||
@@ -162,51 +168,50 @@ | ||
if (options.raw) { | ||
return callback(null, response.body); | ||
return callback(null, response.body) | ||
} | ||
async.waterfall([ | ||
// convert xml to json | ||
function _toJson(next) { | ||
options.xmlConverter(response.body, options, function(error, data) { | ||
if (error) return next(error); | ||
debug('Parsed XML', data); | ||
timer('time to parsed XML', Date.now() - _startTime); | ||
next(null, data); | ||
}); | ||
}, | ||
async.waterfall( | ||
[ | ||
// convert xml to json | ||
function _toJson(next) { | ||
options.xmlConverter(response.body, options, function(error, data) { | ||
if (error) return next(error) | ||
debug('Parsed XML', data) | ||
timer('time to parsed XML', Date.now() - _startTime) | ||
next(null, data) | ||
}) | ||
}, | ||
function _parseJson(data, next) { | ||
// will pass error if response includes an error message, | ||
// or if actually can't parse. | ||
// `options.parseDepth` is very important here. | ||
options.parser(data, options, next); | ||
} | ||
], | ||
function _done(error, data) { | ||
timer('time to parsed JSON', Date.now() - _startTime); | ||
var extraErrorProps = {}; | ||
function _parseJson(data, next) { | ||
// will pass error if response includes an error message, | ||
// or if actually can't parse. | ||
// `options.parseDepth` is very important here. | ||
options.parser(data, options, next) | ||
}, | ||
], | ||
function _done(error, data) { | ||
timer('time to parsed JSON', Date.now() - _startTime) | ||
var extraErrorProps = {} | ||
if (error) { | ||
// as much context as possible for forensic debugging. | ||
// (includes `serviceName`, `reqOptions`, etc; not functions.) | ||
extraErrorProps.requestContext = _.omit(options, _.functions(options)); | ||
extraErrorProps.requestContext.response = _.pick(response, ['statusCode', 'body']); | ||
if (error) { | ||
// as much context as possible for forensic debugging. | ||
// (includes `serviceName`, `reqOptions`, etc; not functions.) | ||
extraErrorProps.requestContext = _.omit(options, _.functions(options)) | ||
extraErrorProps.requestContext.response = _.pick(response, ['statusCode', 'body']) | ||
if (/Ebay/i.test(error.name)) { | ||
// already differentiated into custom error classes. | ||
_.extend(error, extraErrorProps); | ||
callback(error, data); | ||
if (/Ebay/i.test(error.name)) { | ||
// already differentiated into custom error classes. | ||
_.extend(error, extraErrorProps) | ||
callback(error, data) | ||
} else { | ||
// some other parsing error | ||
// @review - is the original stack trace lost here? | ||
error = new EbayClientError('Error parsing JSON: ' + error.message, extraErrorProps) | ||
callback(error, data) | ||
} | ||
} else { | ||
callback(null, data) | ||
} | ||
else { | ||
// some other parsing error | ||
// @review - is the original stack trace lost here? | ||
error = new EbayClientError("Error parsing JSON: " + error.message, extraErrorProps); | ||
callback(error, data); | ||
} | ||
} | ||
else { | ||
callback(null, data); | ||
} | ||
}); | ||
}); | ||
}; | ||
}, | ||
) | ||
}) | ||
} |
{ | ||
"name": "ebay-api-async", | ||
"description": "eBay API Client", | ||
"version": "1.13.5", | ||
"version": "1.14.0", | ||
"homepage": "https://github.com/notVitaliy/nodejs-ebay-api", | ||
"authors": [ | ||
"Ben Buckman", | ||
"Vitaliy Isikov (@notVitaliy)" | ||
], | ||
"authors": ["Ben Buckman", "Vitaliy Isikov (@notVitaliy)"], | ||
"repository": { | ||
@@ -11,0 +8,0 @@ "url": "git://github.com/notVitaliy/nodejs-ebay-api.git" |
117246
1664