diff --git a/src/sections/products.ts b/src/sections/products.ts index 7e0b5212..e38441a6 100644 --- a/src/sections/products.ts +++ b/src/sections/products.ts @@ -156,7 +156,7 @@ interface ListMatchingProductsRequestParameters { const Product = record(string, unknown) -const SingleProductCodec = Codec.interface({ +const SingleProductInterface = Codec.interface({ Product, }) @@ -178,7 +178,7 @@ interface GetMatchingProductParameters { [key: string]: string[] | string } -const GetMatchingProductResult = ensureArray('GetMatchingProductResult', SingleProductCodec) +const GetMatchingProductResult = ensureArray('GetMatchingProductResult', SingleProductInterface) const GetMatchingProductResponse = Codec.interface({ GetMatchingProductResponse: GetMatchingProductResult, @@ -216,7 +216,7 @@ interface GetCompetitivePricingForSkuParameters { const GetCompetitivePricingForSKUResult = ensureArray( 'GetCompetitivePricingForSKUResult', - SingleProductCodec, + SingleProductInterface, ) type GetCompetitivePricingForSKUResult = GetInterface @@ -227,7 +227,7 @@ const GetCompetitivePricingForSKUResponse = Codec.interface({ const GetCompetitivePricingForASINResult = ensureArray( 'GetCompetitivePricingForASINResult', - SingleProductCodec, + SingleProductInterface, ) type GetCompetitivePricingForASINResult = GetInterface @@ -264,6 +264,26 @@ const GetLowestOfferListingsForSKUResponse = Codec.interface({ type GetLowestOfferListingsForSKUResult = GetInterface +interface GetLowestOfferListingsForAsinParameters { + ASINList: string[] + MarketplaceId: string + ItemCondition?: ItemCondition +} + +const GetLowestOfferListingsForASINResult = ensureArray( + 'GetLowestOfferListingsForASINResult', + Codec.interface({ + AllOfferListingsConsidered: boolean, + Product, + }), +) + +type GetLowestOfferListingsForASINResult = GetInterface + +const GetLowestOfferListingsForASINResponse = Codec.interface({ + GetLowestOfferListingsForASINResponse: GetLowestOfferListingsForASINResult, +}) + export class Products { constructor(private httpClient: HttpClient) {} @@ -409,4 +429,26 @@ export class Products { }, }) } + + async getLowestOfferListingsForAsin( + parameters: GetLowestOfferListingsForAsinParameters, + ): Promise<[GetLowestOfferListingsForASINResult, RequestMeta]> { + const [response, meta] = await this.httpClient.request('POST', { + resource: Resource.Products, + version: PRODUCTS_API_VERSION, + action: 'GetLowestOfferListingsForASIN', + parameters: { + 'ASINList.ASIN': parameters.ASINList, + MarketplaceId: parameters.MarketplaceId, + ItemCondition: parameters.ItemCondition, + }, + }) + + return GetLowestOfferListingsForASINResponse.decode(response).caseOf({ + Right: (x) => [x.GetLowestOfferListingsForASINResponse, meta], + Left: (error) => { + throw new ParsingError(error) + }, + }) + } } diff --git a/test/unit/__snapshots__/products.test.ts.snap b/test/unit/__snapshots__/products.test.ts.snap index 196ab62c..a386c66e 100644 --- a/test/unit/__snapshots__/products.test.ts.snap +++ b/test/unit/__snapshots__/products.test.ts.snap @@ -153,6 +153,122 @@ Array [ ] `; +exports[`products getLowestOfferListingsForAsin returns product and lowest offer listings when response is valid 1`] = ` +Array [ + Array [ + Object { + "AllOfferListingsConsidered": true, + "Product": Object { + "Identifiers": Object { + "MarketplaceASIN": Object { + "ASIN": "B002KT3XQM", + "MarketplaceId": "ATVPDKIKX0DER", + }, + }, + "LowestOfferListings": Object { + "LowestOfferListing": Array [ + Object { + "MultipleOffersAtLowestPrice": "False", + "NumberOfOfferListingsConsidered": 1, + "Price": Object { + "LandedPrice": Object { + "Amount": 32.99, + "CurrencyCode": "USD", + }, + "ListingPrice": Object { + "Amount": 28, + "CurrencyCode": "USD", + }, + "Shipping": Object { + "Amount": 4.99, + "CurrencyCode": "USD", + }, + }, + "Qualifiers": Object { + "FulfillmentChannel": "Merchant", + "ItemCondition": "Used", + "ItemSubcondition": "VeryGood", + "SellerPositiveFeedbackRating": "90-94%", + "ShippingTime": Object { + "Max": "0-2 days", + }, + "ShipsDomestically": "True", + }, + "SellerFeedbackCount": 762, + }, + Object { + "MultipleOffersAtLowestPrice": "False", + "NumberOfOfferListingsConsidered": 1, + "Price": Object { + "LandedPrice": Object { + "Amount": 34.27, + "CurrencyCode": "USD", + }, + "ListingPrice": Object { + "Amount": 34.27, + "CurrencyCode": "USD", + }, + "Shipping": Object { + "Amount": 0, + "CurrencyCode": "USD", + }, + }, + "Qualifiers": Object { + "FulfillmentChannel": "Amazon", + "ItemCondition": "New", + "ItemSubcondition": "New", + "SellerPositiveFeedbackRating": "98-100%", + "ShippingTime": Object { + "Max": "0-2 days", + }, + "ShipsDomestically": "True", + }, + "SellerFeedbackCount": 181744, + }, + Object { + "MultipleOffersAtLowestPrice": "False", + "NumberOfOfferListingsConsidered": 1, + "Price": Object { + "LandedPrice": Object { + "Amount": 41.18, + "CurrencyCode": "USD", + }, + "ListingPrice": Object { + "Amount": 41.18, + "CurrencyCode": "USD", + }, + "Shipping": Object { + "Amount": 0, + "CurrencyCode": "USD", + }, + }, + "Qualifiers": Object { + "FulfillmentChannel": "Amazon", + "ItemCondition": "New", + "ItemSubcondition": "New", + "SellerPositiveFeedbackRating": "95-97%", + "ShippingTime": Object { + "Max": "0-2 days", + }, + "ShipsDomestically": "True", + }, + "SellerFeedbackCount": 13213, + }, + ], + }, + }, + }, + ], + Object { + "quotaMax": 1000, + "quotaRemaining": 999, + "quotaResetOn": "2020-04-06T10:22:23.582Z", + "requestId": "0", + "timestamp": "2020-05-06T09:22:23.582Z", + }, +] +`; + exports[`products getLowestOfferListingsForSku returns product and lowest offer listings when response is valid 1`] = ` Array [ Array [ diff --git a/test/unit/products.test.ts b/test/unit/products.test.ts index 54680c0f..ba20b643 100644 --- a/test/unit/products.test.ts +++ b/test/unit/products.test.ts @@ -114,9 +114,9 @@ describe('products', () => { it("throws an error when the response isn't valid", async () => { expect.assertions(1) - await expect(() => { - mockMwsFail.products.getLowestOfferListingsForAsin(parameters) - }).rejects.toStrictEqual(new ParsingError(parsingError)) + await expect(() => + mockMwsFail.products.getLowestOfferListingsForAsin(parameters), + ).rejects.toStrictEqual(new ParsingError(parsingError)) }) })