Skip to content
This repository has been archived by the owner on Jan 25, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1 from ericblade/master
Browse files Browse the repository at this point in the history
Pull from Eric Blade
  • Loading branch information
pwrnrd committed Jun 20, 2018
2 parents cbfd26b + 2620802 commit 52b7187
Show file tree
Hide file tree
Showing 20 changed files with 141 additions and 88 deletions.
36 changes: 14 additions & 22 deletions lib/callEndpoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ const init = ({
return mws;
};

const { flattenResult } = require('./flatten-result');
const { flattenResult } = require('./util/flatten-result');

const { validateAndTransformParameters } = require('./validation');
const { digResponseResult } = require('./dig-response-result.js');
const { validateAndTransformParameters } = require('./util/validation');
const { digResponseResult } = require('./util/dig-response-result.js');

// TODO: add Subscriptions and Recommendations categories
const {
Expand Down Expand Up @@ -169,9 +169,18 @@ async function callEndpoint(name, callOptions = {}, opt = { maxThrottleRetries:
return digResult;
} catch (err) {
if (err instanceof mws.ServerError) {
if (err.code === 503 && opt.maxThrottleRetries > 0 && throttleRetries <= opt.maxThrottleRetries) {
if (
err.code === 503 &&
opt.maxThrottleRetries > 0 &&
throttleRetries <= opt.maxThrottleRetries
) {
throttleRetries += 1;
console.warn('***** Error 503 .. throttling?', name, throttleRetries, opt.maxThrottleRetries);
console.warn(
'***** Error 503 .. throttling?',
name,
throttleRetries,
opt.maxThrottleRetries,
);
let ms = 2000;
if (!endpoint.throttle) {
console.warn(`***** throttle information missing for API ${name}`);
Expand Down Expand Up @@ -202,24 +211,7 @@ async function callEndpoint(name, callOptions = {}, opt = { maxThrottleRetries:
}
}

// experimental
const parseEndpoint = (name, callOptions, opt) => async (parser) => {
try {
const res = await callEndpoint(name, callOptions, opt);
return parser(res);
} catch (err) {
console.warn('**** caught parseEndpoint error');
throw err;
}
};

// experimental
const parseEndpoint2 = (outParser, inParser = x => x) => name => async (callOptions, opt) =>
outParser(await callEndpoint(name, inParser(callOptions), opt));

module.exports = {
init,
callEndpoint,
parseEndpoint,
parseEndpoint2,
};
4 changes: 2 additions & 2 deletions lib/get-lowest-priced-offers.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
const { parseEndpoint2 } = require('./callEndpoint');
const { parseEndpoint } = require('./parseEndpoint');

const parseLowestPricedOffers = require('./parsers/lowestPricedOffers');

// TODO: perhaps we should merge ForASIN and ForSKU varities into a single call, with either
// a parameter to say which to get, or intelligent determination based on the contents? ... probably
// better to go with a parameter, since a user could use something that looks like an ASIN as a SKU

const getLowestPricedOffersBase = parseEndpoint2(parseLowestPricedOffers);
const getLowestPricedOffersBase = parseEndpoint(parseLowestPricedOffers);
/**
* getLowestPricedOffersForASIN
*
Expand Down
4 changes: 2 additions & 2 deletions lib/get-marketplaces.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { parseEndpoint2 } = require('./callEndpoint');
const { parseEndpoint } = require('./parseEndpoint');
const parseMarketplaceData = require('./parsers/marketplaceData');

// TODO: upgrade to call ListMarketplaceParticipationsByNextToken when a NextToken
Expand Down Expand Up @@ -33,7 +33,7 @@ const parseMarketplaceData = require('./parsers/marketplaceData');
* @return {MarketDetail}
*/

const getMarketplaces = parseEndpoint2(parseMarketplaceData)('ListMarketplaceParticipations');
const getMarketplaces = parseEndpoint(parseMarketplaceData)('ListMarketplaceParticipations');

module.exports = {
getMarketplaces,
Expand Down
10 changes: 5 additions & 5 deletions lib/get-matching-product.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { parseEndpoint2 } = require('./callEndpoint');
const { parseEndpoint } = require('./parseEndpoint');
const errors = require('./errors');

const parseMatchingProduct = require('./parsers/matchingProduct');
Expand All @@ -21,14 +21,14 @@ const outputParser = (out) => {
* EAN, ISBN, or JAN values
*
* @param {Object} options see https://docs.developer.amazonservices.com/en_UK/products/Products_GetMatchingProductForId.html
* @param {string} options.MarketplaceId Identifier for marketplace (see getMarketplaces)
* @param {string} options.IdType Type of lookup to perform: ASIN, GCID, SellerSKU, UPC, EAN, ISBN, JAN
* @param {string[]} options.IdList List of codes to perform lookup on
* @param {string} options.marketplaceId Identifier for marketplace (see getMarketplaces)
* @param {string} options.idType Type of lookup to perform: ASIN, GCID, SellerSKU, UPC, EAN, ISBN, JAN
* @param {string[]} options.idList List of codes to perform lookup on
* @public
* @returns {Product[]}
*/
const getMatchingProductForId =
parseEndpoint2(outputParser, inputParser)('GetMatchingProductForId');
parseEndpoint(outputParser, inputParser)('GetMatchingProductForId');

module.exports = {
getMatchingProductForId,
Expand Down
5 changes: 3 additions & 2 deletions lib/get-my-fees-estimate.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { parseEndpoint2 } = require('./callEndpoint');
const { parseEndpoint } = require('./parseEndpoint');
const parseFeesEstimate = require('./parsers/feesEstimate');
const { forceArray } = require('./util/transformers');

Expand Down Expand Up @@ -68,7 +68,8 @@ const estimateRequestParser = estimates => (
* @param {EstimateRequest[]} - Array of EstimateRequest items to get fees for
* @returns {Object} - Object of Estimate items, indexed by EstimateRequest Identifier
*/
const getMyFeesEstimate = parseEndpoint2(parseFeesEstimate, estimateRequestParser)('GetMyFeesEstimate');
const getMyFeesEstimate =
parseEndpoint(parseFeesEstimate, estimateRequestParser)('GetMyFeesEstimate');

module.exports = {
getMyFeesEstimate,
Expand Down
6 changes: 4 additions & 2 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

// http://s3.amazonaws.com/devo.docs.developer.amazonservices.com/en_US/sellers/Sellers_ListMarketplaceParticipations.html

const { init, callEndpoint, parseEndpoint } = require('./callEndpoint');
const { init, callEndpoint } = require('./callEndpoint');
const { parseEndpoint } = require('./parseEndpoint');
const { getMarketplaces } = require('./get-marketplaces');
const { listOrderItems } = require('./list-order-items');
const { listOrders } = require('./list-orders');
Expand All @@ -18,7 +19,8 @@ const {
getLowestPricedOffersForASIN,
getLowestPricedOffersForSKU,
} = require('./get-lowest-priced-offers');
const { getProductCategoriesForAsins, getProductCategoriesForSkus } = require('./get-product-categories');
const { getProductCategoriesForAsins, getProductCategoriesForSkus } =
require('./get-product-categories');
const { getMyFeesEstimate } = require('./get-my-fees-estimate');
const { listMatchingProducts } = require('./list-matching-products');
const constants = require('./constants');
Expand Down
14 changes: 7 additions & 7 deletions lib/list-financial-events.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { parseEndpoint2 } = require('./callEndpoint');
const { parseEndpoint } = require('./parseEndpoint');
const { forceArray } = require('./util/transformers');

// TODO: probably needs to handle nextToken
Expand Down Expand Up @@ -30,13 +30,13 @@ const outputParser = (out) => {
* https://docs.developer.amazonservices.com/en_UK/finances/Finances_ListFinancialEvents.html
*
* @param {object} options
* @param {number} options.MaxResultsPerPage Maximum number of results to return (1 <=> 100)
* @param {string} options.AmazonOrderId An order number to search for
* @param {string} options.FinancialEventGroupId Type of Financial Event to search for
* @param {Date} options.PostedAfter When to search for events after
* @param {Date} options.PostedBefore When to search for events prior to
* @param {number} options.maxResultsPerPage Maximum number of results to return (1 <=> 100)
* @param {string} options.amazonOrderId An order number to search for
* @param {string} options.financialEventGroupId Type of Financial Event to search for
* @param {Date} options.postedAfter When to search for events after
* @param {Date} options.postedBefore When to search for events prior to
* @returns {object}
*/
const listFinancialEvents = parseEndpoint2(outputParser, inputParser)('ListFinancialEvents');
const listFinancialEvents = parseEndpoint(outputParser, inputParser)('ListFinancialEvents');

module.exports = { listFinancialEvents };
12 changes: 6 additions & 6 deletions lib/list-inventory-supply.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { parseEndpoint2 } = require('./callEndpoint');
const { parseEndpoint } = require('./parseEndpoint');

/*
[ { Condition: 'NewItem',
Expand Down Expand Up @@ -26,13 +26,13 @@ const outputParser = out => ({
* Return information about the availability of a seller's FBA inventory
*
* @param {object} options
* @param {String[]} options.SellerSkus A list of SKUs for items to get inventory info for
* @param {Date} options.QueryStartDateTime Date to begin searching at
* @param {string} options.ResponseGroup 'Basic' = Do not include SupplyDetail, 'Detailed' = Do
* @param {string} options.MarketplaceId Marketplace ID to search
* @param {String[]} options.sellerSkus A list of SKUs for items to get inventory info for
* @param {Date} options.queryStartDateTime Date to begin searching at
* @param {string} options.responseGroup 'Basic' = Do not include SupplyDetail, 'Detailed' = Do
* @param {string} options.marketplaceId Marketplace ID to search
*
* @returns {{ nextToken: string, supplyList: object[] }}
*/
const listInventorySupply = parseEndpoint2(outputParser, inputParser)('ListInventorySupply');
const listInventorySupply = parseEndpoint(outputParser, inputParser)('ListInventorySupply');

module.exports = { listInventorySupply };
4 changes: 2 additions & 2 deletions lib/list-matching-products.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { parseEndpoint2 } = require('./callEndpoint');
const { parseEndpoint } = require('./parseEndpoint');
const parseMatchingProduct = require('./parsers/matchingProduct');

const inputParser = opt => ({
Expand All @@ -19,7 +19,7 @@ const outputParser = out => parseMatchingProduct(out)[0].results;
* @returns {Product[]} - Array of product information
*/

const listMatchingProducts = parseEndpoint2(outputParser, inputParser)('ListMatchingProducts');
const listMatchingProducts = parseEndpoint(outputParser, inputParser)('ListMatchingProducts');

module.exports = {
listMatchingProducts,
Expand Down
4 changes: 2 additions & 2 deletions lib/list-order-items.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @module mws-advanced
*/
const { parseEndpoint2 } = require('./callEndpoint');
const { parseEndpoint } = require('./parseEndpoint');
const parseOrderItems = require('./parsers/orderItems');

// TODO: make a typedef for OrderItem and document it correctly
Expand Down Expand Up @@ -40,7 +40,7 @@ const parseOrderItems = require('./parsers/orderItems');
*/

const listOrderItems =
parseEndpoint2(parseOrderItems, AmazonOrderId => ({ AmazonOrderId }))('ListOrderItems');
parseEndpoint(parseOrderItems, AmazonOrderId => ({ AmazonOrderId }))('ListOrderItems');

module.exports = {
listOrderItems,
Expand Down
4 changes: 2 additions & 2 deletions lib/list-orders.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { parseEndpoint2 } = require('./callEndpoint');
const { parseEndpoint } = require('./parseEndpoint');

// returns
/*
Expand Down Expand Up @@ -37,6 +37,6 @@ const { parseEndpoint2 } = require('./callEndpoint');
* @returns {object}
*/

const listOrders = parseEndpoint2(out => out.Orders.Order)('ListOrders');
const listOrders = parseEndpoint(out => out.Orders.Order)('ListOrders');

module.exports = { listOrders };
11 changes: 11 additions & 0 deletions lib/parseEndpoint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const { callEndpoint } = require('./callEndpoint');

const parseEndpoint =
(outParser, inParser = x => x) =>
name =>
async (callOptions, opt) =>
outParser(await callEndpoint(name, inParser(callOptions), opt));

module.exports = {
parseEndpoint,
};
25 changes: 15 additions & 10 deletions lib/parsers/lowestPricedOffers.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,20 @@ const reformatOfferCount = offerCount => ({
fulfillmentChannel: offerCount.$.fulfillmentChannel,
});

/** @typedef SellerFeedbackRating
/**
* @typedef SellerFeedbackRating
* @param {string} unknown
*/
/** @typedef DetailedShippingTime
/**
* @typedef DetailedShippingTime
* @param {string} unknown
*/
/** @typedef Money
/**
* @typedef Money
* @param {string} unknown
*/
/** @typedef ShipsFrom
/**
* @typedef ShipsFrom
* @param {string} unknown
*/

Expand Down Expand Up @@ -184,12 +188,13 @@ function parseLowestPricedOffers(offerData) {

const offers = forceArray(offerData.Offers.Offer);

const ret = {};
ret.asin = identifier.ASIN;
ret.marketplace = identifier.MarketplaceId;
ret.itemCondition = identifier.ItemCondition;
ret.summary = reformatSummary(summary);
ret.lowestOffers = offers.map(reformatOffer);
const ret = {
asin: identifier.ASIN,
marketplace: identifier.MarketplaceId,
itemCondition: identifier.ItemCondition,
summary: reformatSummary(summary),
lowestOffers: offers.map(reformatOffer),
};
return ret;
}

Expand Down
21 changes: 15 additions & 6 deletions lib/parsers/orderItems.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
const { forceArray, transformObjectKeys } = require('../util/transformers');
const {
forceArray,
transformObjectKeys,
stringToBool,
stringToInt,
} = require('../util/transformers');

/**
* @typedef OrderItem - see https://docs.developer.amazonservices.com/en_UK/orders-2013-09-01/Orders_Datatypes.html#OrderItem
Expand Down Expand Up @@ -31,19 +36,23 @@ function transformIntsAndBools(item) {
productInfo,
...restItem
} = item;
const { numberOfItems, ...restProductInfo } = productInfo;
const {
numberOfItems,
...restProductInfo
} = productInfo;

return {
...restItem,
isGift: !!(isGift === 'true'),
quantityOrdered: parseInt(quantityOrdered, 10),
quantityShipped: parseInt(quantityShipped, 10),
isGift: stringToBool(isGift),
quantityOrdered: stringToInt(quantityOrdered),
quantityShipped: stringToInt(quantityShipped),
productInfo: {
...restProductInfo,
numberOfItems: parseInt(numberOfItems, 10),
numberOfItems: stringToInt(numberOfItems),
},
};
}

/**
* Transform MWS OrderItemsList
*
Expand Down
12 changes: 6 additions & 6 deletions lib/reports.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const errors = require('./errors');
*/
const writeFile = promisify(fs.writeFile);

const { parseEndpoint2 } = require('./callEndpoint');
const { parseEndpoint } = require('./parseEndpoint');
const sleep = require('./util/sleep');

/**
Expand Down Expand Up @@ -45,7 +45,7 @@ const sleep = require('./util/sleep');
* @param {string[]} [MarketplaceId] Array of marketplace IDs to generate reports covering
* @returns {ReportRequestInfo}
*/
const requestReport = parseEndpoint2(out => out.ReportRequestInfo)('RequestReport');
const requestReport = parseEndpoint(out => out.ReportRequestInfo)('RequestReport');

// interesting note: there are tons of reports returned by this API,
// apparently Amazon auto pulls reports, and many reports pulled in the Seller Central
Expand Down Expand Up @@ -92,7 +92,7 @@ const reportRequestListParser = (out) => {
* @param {Date} [RequestedToDate=Now] Newest date to search for
* @returns {GetReportRequestListResult[]}
*/
const getReportRequestList = parseEndpoint2(reportRequestListParser)('GetReportRequestList');
const getReportRequestList = parseEndpoint(reportRequestListParser)('GetReportRequestList');

/**
* Returns the contents of a report
Expand All @@ -101,7 +101,7 @@ const getReportRequestList = parseEndpoint2(reportRequestListParser)('GetReportR
* @param {string} options.ReportId Report number from @see {@link GetReportList} or GeneratedReportId from @see {@link GetReportRequestListResult}
* @return {Array|object} Contents of the report to return (format may vary WIDELY between different reports generated, see [ReportType](https://docs.developer.amazonservices.com/en_US/reports/Reports_ReportType.html))
*/
const getReport = parseEndpoint2(x => x)('GetReport');
const getReport = parseEndpoint(x => x)('GetReport');

const getReportListParser = (out) => {
try {
Expand All @@ -118,14 +118,14 @@ const getReportListParser = (out) => {
/**
* TODO: write documentation for getReportList
*/
const getReportList = parseEndpoint2(getReportListParser)('GetReportList');
const getReportList = parseEndpoint(getReportListParser)('GetReportList');

/**
* TODO: write documentation for getReportListByNextToken
* (or just roll getReportList and getReportListByNextToken into the same wrapper)
* (that wrapper might be getReportListAll, and just rename it)
*/
const getReportListByNextToken = parseEndpoint2(getReportListParser)('GetReportListByNextToken');
const getReportListByNextToken = parseEndpoint(getReportListParser)('GetReportListByNextToken');

/**
* TODO: write documentation for getReportListAll (or see comment on getReportListByNextToken)
Expand Down
Loading

0 comments on commit 52b7187

Please sign in to comment.