amazon-sp-api
Advanced tools
Comparing version 0.3.7 to 0.4.0
@@ -1,27 +0,15 @@ | ||
// For a list of required and optional body, query or path parameters for resources please see official references: | ||
// --> https://github.com/amzn/selling-partner-api-docs/tree/main/references | ||
module.exports = { | ||
...require('./resources/aplusContent'), | ||
...require('./resources/authorization'), | ||
...require('./resources/catalogItems'), | ||
...require('./resources/fbaInboundEligibility'), | ||
...require('./resources/fbaInventory'), | ||
...require('./resources/fbaSmallAndLight'), | ||
...require('./resources/feeds'), | ||
...require('./resources/finances'), | ||
...require('./resources/fulfillmentInbound'), | ||
...require('./resources/fulfillmentOutbound'), | ||
...require('./resources/merchantFulfillment'), | ||
...require('./resources/messaging'), | ||
...require('./resources/notifications'), | ||
...require('./resources/orders'), | ||
...require('./resources/productFees'), | ||
...require('./resources/productPricing'), | ||
...require('./resources/reports'), | ||
...require('./resources/sales'), | ||
...require('./resources/sellers'), | ||
...require('./resources/services'), | ||
...require('./resources/shipping'), | ||
...require('./resources/solicitations'), | ||
...require('./resources/uploads') | ||
// As the original design of the module (<= v0.3.7) didn't keep in mind the possibility of having more versions of the same endpoints | ||
// and as a result different versions of the same operation, we had to replace original operation-only based calls to the API | ||
// with a new concept that includes endpoints and version-specific operation calls | ||
// In order to prevent breaking changes we need this operation to endpoint mapping | ||
module.exports = (endpoints) => { | ||
// Map the correct endpoint to the operation and return as key/value | ||
return { | ||
...Object.keys(endpoints).reduce((eps, ep) => { | ||
return Object.assign(eps, { | ||
...require('./resources/' + ep)[ep].__operations.reduce((ops, op) => {ops[op] = ep; return ops;}, {}) | ||
}); | ||
}, {}) | ||
}; | ||
}; |
@@ -1,117 +0,20 @@ | ||
const utils = require('../utils'); | ||
// TODO: Restore rates may vary for aplus content operations --> x-amzn-RateLimit-Limit header is returned and should be respected | ||
module.exports = { | ||
searchContentDocuments:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/aplus/2020-11-01/contentDocuments', | ||
restore_rate:0.1 | ||
}); | ||
}, | ||
createContentDocument:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/aplus/2020-11-01/contentDocuments', | ||
restore_rate:0.1 | ||
}); | ||
}, | ||
getContentDocument:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
contentReferenceKey:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/aplus/2020-11-01/contentDocuments/' + req_params.path.contentReferenceKey, | ||
restore_rate:0.1 | ||
}); | ||
}, | ||
updateContentDocument:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
contentReferenceKey:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/aplus/2020-11-01/contentDocuments/' + req_params.path.contentReferenceKey, | ||
restore_rate:0.1 | ||
}); | ||
}, | ||
listContentDocumentAsinRelations:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
contentReferenceKey:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/aplus/2020-11-01/contentDocuments/' + req_params.path.contentReferenceKey + '/asins', | ||
restore_rate:0.1 | ||
}); | ||
}, | ||
postContentDocumentAsinRelations:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
contentReferenceKey:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/aplus/2020-11-01/contentDocuments/' + req_params.path.contentReferenceKey + '/asins', | ||
restore_rate:0.1 | ||
}); | ||
}, | ||
validateContentDocumentAsinRelations:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/aplus/2020-11-01/contentAsinValidations', | ||
restore_rate:0.1 | ||
}); | ||
}, | ||
searchContentPublishRecords:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/aplus/2020-11-01/contentPublishRecords', | ||
restore_rate:0.1 | ||
}); | ||
}, | ||
postContentDocumentApprovalSubmission:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
contentReferenceKey:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/aplus/2020-11-01/contentDocuments/' + req_params.path.contentReferenceKey + '/approvalSubmissions', | ||
restore_rate:0.1 | ||
}); | ||
}, | ||
postContentDocumentSuspendSubmission:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
contentReferenceKey:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/aplus/2020-11-01/contentDocuments/' + req_params.path.contentReferenceKey + '/suspendSubmissions', | ||
restore_rate:0.1 | ||
}); | ||
aplusContent:{ | ||
__versions:[ | ||
'2020-11-01' | ||
], | ||
__operations:[ | ||
'searchContentDocuments', | ||
'createContentDocument', | ||
'getContentDocument', | ||
'updateContentDocument', | ||
'listContentDocumentAsinRelations', | ||
'postContentDocumentAsinRelations', | ||
'validateContentDocumentAsinRelations', | ||
'searchContentPublishRecords', | ||
'postContentDocumentApprovalSubmission', | ||
'postContentDocumentSuspendSubmission' | ||
], | ||
...require('./versions/aplus_content/aplusContent_2020-11-01') | ||
} | ||
}; |
module.exports = { | ||
getAuthorizationCode:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/authorization/v1/authorizationCode', | ||
restore_rate:1, | ||
is_grantless:true, | ||
scope:'sellingpartnerapi::migration' | ||
}); | ||
authorization:{ | ||
__versions:[ | ||
'v1' | ||
], | ||
__operations:[ | ||
'getAuthorizationCode', | ||
], | ||
...require('./versions/authorization/authorization_v1') | ||
} | ||
}; |
@@ -1,32 +0,15 @@ | ||
const utils = require('../utils'); | ||
module.exports = { | ||
listCatalogItems:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/catalog/v0/items', | ||
restore_rate:0.167 | ||
}); | ||
}, | ||
getCatalogItem:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
asin:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/catalog/v0/items/' + req_params.path.asin, | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
listCatalogCategories:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/catalog/v0/categories', | ||
restore_rate:1 | ||
}); | ||
catalogItems:{ | ||
__versions:[ | ||
'v0', | ||
'2020-12-01' | ||
], | ||
__operations:[ | ||
'listCatalogItems', | ||
'getCatalogItem', | ||
'listCatalogCategories' | ||
], | ||
...require('./versions/catalog_items/catalogItems_v0'), | ||
...require('./versions/catalog_items/catalogItems_2020-12-01') | ||
} | ||
}; |
module.exports = { | ||
getItemEligibilityPreview:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/inbound/v1/eligibility/itemPreview', | ||
restore_rate:1 | ||
}); | ||
fbaInboundEligibility:{ | ||
__versions:[ | ||
'v1' | ||
], | ||
__operations:[ | ||
'getItemEligibilityPreview' | ||
], | ||
...require('./versions/fba_inbound_eligibility/fbaInboundEligibility_v1') | ||
} | ||
}; |
module.exports = { | ||
// getInventorySummaries seems to be available in "NA" region only --> comparable to ListInventorySupply in MWS API | ||
// May return a pagination value that includes a nextToken --> this pagination will be added to the returned payload | ||
getInventorySummaries:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/inventory/v1/summaries', | ||
restore_rate:0.012 | ||
}); | ||
fbaInventory:{ | ||
__versions:[ | ||
'v1' | ||
], | ||
__operations:[ | ||
'getInventorySummaries' | ||
], | ||
...require('./versions/fba_inventory/fbaInventory_v1') | ||
} | ||
}; |
@@ -1,67 +0,15 @@ | ||
const utils = require('../utils'); | ||
module.exports = { | ||
getSmallAndLightEnrollmentBySellerSKU:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
sellerSKU:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/smallAndLight/v1/enrollments/' + req_params.path.sellerSKU, | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
putSmallAndLightEnrollmentBySellerSKU:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
sellerSKU:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'PUT', | ||
api_path:'/fba/smallAndLight/v1/enrollments/' + req_params.path.sellerSKU, | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
deleteSmallAndLightEnrollmentBySellerSKU:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
sellerSKU:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'DELETE', | ||
api_path:'/fba/smallAndLight/v1/enrollments/' + req_params.path.sellerSKU, | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
getSmallAndLightEligibilityBySellerSKU:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
sellerSKU:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/smallAndLight/v1/eligibilities/' + req_params.path.sellerSKU, | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
getSmallAndLightFeePreview:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/fba/smallAndLight/v1/feePreviews', | ||
restore_rate:1 | ||
}); | ||
fbaSmallAndLight:{ | ||
__versions:[ | ||
'v1' | ||
], | ||
__operations:[ | ||
'getSmallAndLightEnrollmentBySellerSKU', | ||
'putSmallAndLightEnrollmentBySellerSKU', | ||
'deleteSmallAndLightEnrollmentBySellerSKU', | ||
'getSmallAndLightEligibilityBySellerSKU', | ||
'getSmallAndLightFeePreview' | ||
], | ||
...require('./versions/fba_small_and_light/fbaSmallAndLight_v1') | ||
} | ||
}; |
@@ -1,67 +0,18 @@ | ||
const utils = require('../utils'); | ||
module.exports = { | ||
getFeeds:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/feeds/2020-09-04/feeds', | ||
restore_rate:45 | ||
}); | ||
}, | ||
createFeed:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/feeds/2020-09-04/feeds', | ||
restore_rate:120 | ||
}); | ||
}, | ||
getFeed:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
feedId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/feeds/2020-09-04/feeds/' + req_params.path.feedId, | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
cancelFeed:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
feedId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'DELETE', | ||
api_path:'/feeds/2020-09-04/feeds/' + req_params.path.feedId, | ||
restore_rate:45 | ||
}); | ||
}, | ||
createFeedDocument:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/feeds/2020-09-04/documents', | ||
restore_rate:120 | ||
}); | ||
}, | ||
getFeedDocument:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
feedDocumentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/feeds/2020-09-04/documents/' + req_params.path.feedDocumentId, | ||
restore_rate:45 | ||
}); | ||
feeds:{ | ||
__versions:[ | ||
'2020-09-04', | ||
'2021-06-30' | ||
], | ||
__operations:[ | ||
'getFeeds', | ||
'createFeed', | ||
'getFeed', | ||
'cancelFeed', | ||
'createFeedDocument', | ||
'getFeedDocument' | ||
], | ||
...require('./versions/feeds/feeds_2020-09-04'), | ||
...require('./versions/feeds/feeds_2021-06-30') | ||
} | ||
}; |
@@ -1,46 +0,14 @@ | ||
const utils = require('../utils'); | ||
module.exports = { | ||
listFinancialEventGroups:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/finances/v0/financialEventGroups', | ||
restore_rate:2 | ||
}); | ||
}, | ||
listFinancialEventsByGroupId:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
eventGroupId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/finances/v0/financialEventGroups/' + req_params.path.eventGroupId + '/financialEvents', | ||
restore_rate:2 | ||
}); | ||
}, | ||
listFinancialEventsByOrderId:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
orderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/finances/v0/orders/' + req_params.path.orderId + '/financialEvents', | ||
restore_rate:2 | ||
}); | ||
}, | ||
listFinancialEvents:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/finances/v0/financialEvents', | ||
restore_rate:2 | ||
}); | ||
finances:{ | ||
__versions:[ | ||
'v0' | ||
], | ||
__operations:[ | ||
'listFinancialEventGroups', | ||
'listFinancialEventsByGroupId', | ||
'listFinancialEventsByOrderId', | ||
'listFinancialEvents' | ||
], | ||
...require('./versions/finances/finances_v0') | ||
} | ||
}; |
@@ -1,207 +0,27 @@ | ||
const utils = require('../utils'); | ||
module.exports = { | ||
getInboundGuidance:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/inbound/v0/itemsGuidance', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
createInboundShipmentPlan:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/fba/inbound/v0/plans', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
updateInboundShipment:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
shipmentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'PUT', | ||
api_path:'/fba/inbound/v0/shipments/' + req_params.path.shipmentId, | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
createInboundShipment:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
shipmentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/fba/inbound/v0/shipments/' + req_params.path.shipmentId, | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
getPreorderInfo:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
shipmentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/inbound/v0/shipments/' + req_params.path.shipmentId + '/preorder', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
confirmPreorder:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
shipmentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'PUT', | ||
api_path:'/fba/inbound/v0/shipments/' + req_params.path.shipmentId + '/preorder/confirm', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
getPrepInstructions:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/inbound/v0/prepInstructions', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
getTransportDetails:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
shipmentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/inbound/v0/shipments/' + req_params.path.shipmentId + '/transport', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
putTransportDetails:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
shipmentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'PUT', | ||
api_path:'/fba/inbound/v0/shipments/' + req_params.path.shipmentId + '/transport', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
voidTransport:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
shipmentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/fba/inbound/v0/shipments/' + req_params.path.shipmentId + '/transport/void', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
estimateTransport:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
shipmentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/fba/inbound/v0/shipments/' + req_params.path.shipmentId + '/transport/estimate', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
confirmTransport:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
shipmentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/fba/inbound/v0/shipments/' + req_params.path.shipmentId + '/transport/confirm', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
getLabels:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
shipmentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/inbound/v0/shipments/' + req_params.path.shipmentId + '/labels', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
getBillOfLading:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
shipmentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/inbound/v0/shipments/' + req_params.path.shipmentId + '/billOfLading', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
getShipments:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/inbound/v0/shipments', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
getShipmentItemsByShipmentId:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
shipmentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/inbound/v0/shipments/' + req_params.path.shipmentId + '/items', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
getShipmentItems:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/inbound/v0/shipmentItems', | ||
restore_rate:0.5 | ||
}); | ||
fulfillmentInbound:{ | ||
__versions:[ | ||
'v0' | ||
], | ||
__operations:[ | ||
'getInboundGuidance', | ||
'createInboundShipmentPlan', | ||
'updateInboundShipment', | ||
'createInboundShipment', | ||
'getPreorderInfo', | ||
'confirmPreorder', | ||
'getPrepInstructions', | ||
'getTransportDetails', | ||
'putTransportDetails', | ||
'voidTransport', | ||
'estimateTransport', | ||
'confirmTransport', | ||
'getLabels', | ||
'getBillOfLading', | ||
'getShipments', | ||
'getShipmentItemsByShipmentId', | ||
'getShipmentItems' | ||
], | ||
...require('./versions/fulfillment_inbound/fulfillmentInbound_v0') | ||
} | ||
}; |
@@ -1,133 +0,22 @@ | ||
const utils = require('../utils'); | ||
module.exports = { | ||
getFulfillmentPreview:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/fba/outbound/2020-07-01/fulfillmentOrders/preview', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
listAllFulfillmentOrders:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/outbound/2020-07-01/fulfillmentOrders', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
createFulfillmentOrder:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/fba/outbound/2020-07-01/fulfillmentOrders', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
getPackageTrackingDetails:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/outbound/2020-07-01/tracking', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
listReturnReasonCodes:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/outbound/2020-07-01/returnReasonCodes', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
createFulfillmentReturn:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
sellerFulfillmentOrderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'PUT', | ||
api_path:'/fba/outbound/2020-07-01/fulfillmentOrders/' + req_params.path.sellerFulfillmentOrderId + '/return', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
getFulfillmentOrder:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
sellerFulfillmentOrderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/outbound/2020-07-01/fulfillmentOrders/' + req_params.path.sellerFulfillmentOrderId, | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
updateFulfillmentOrder:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
sellerFulfillmentOrderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/outbound/2020-07-01/fulfillmentOrders/' + req_params.path.sellerFulfillmentOrderId, | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
cancelFulfillmentOrder:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
sellerFulfillmentOrderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'PUT', | ||
api_path:'/fba/outbound/2020-07-01/fulfillmentOrders/' + req_params.path.sellerFulfillmentOrderId + '/cancel', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
getFeatures:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/outbound/2020-07-01/features', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
getFeatureInventory:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
featureName:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/outbound/2020-07-01/features/inventory/' + req_params.path.featureName, | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
getFeatureSKU:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
featureName:{ | ||
type:'string' | ||
}, | ||
sellerSku:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/fba/outbound/2020-07-01/features/inventory/' + req_params.path.featureName + '/' + req_params.path.sellerSku, | ||
restore_rate:0.5 | ||
}); | ||
fulfillmentOutbound:{ | ||
__versions:[ | ||
'2020-07-01' | ||
], | ||
__operations:[ | ||
'getFulfillmentPreview', | ||
'listAllFulfillmentOrders', | ||
'createFulfillmentOrder', | ||
'getPackageTrackingDetails', | ||
'listReturnReasonCodes', | ||
'createFulfillmentReturn', | ||
'getFulfillmentOrder', | ||
'updateFulfillmentOrder', | ||
'cancelFulfillmentOrder', | ||
'getFeatures', | ||
'getFeatureInventory', | ||
'getFeatureSKU' | ||
], | ||
...require('./versions/fulfillment_outbound/fulfillmentOutbound_2020-07-01') | ||
} | ||
}; |
@@ -1,81 +0,18 @@ | ||
const utils = require('../utils'); | ||
module.exports = { | ||
getEligibleShipmentServicesOld:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/mfn/v0/eligibleServices', | ||
restore_rate:1 | ||
}); | ||
}, | ||
getEligibleShipmentServices:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/mfn/v0/eligibleShippingServices', | ||
restore_rate:1 | ||
}); | ||
}, | ||
getShipment:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
shipmentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/mfn/v0/shipments/' + req_params.path.shipmentId, | ||
restore_rate:1 | ||
}); | ||
}, | ||
cancelShipment:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
shipmentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'DELETE', | ||
api_path:'/mfn/v0/shipments/' + req_params.path.shipmentId, | ||
restore_rate:1 | ||
}); | ||
}, | ||
cancelShipmentOld:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
shipmentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'PUT', | ||
api_path:'/mfn/v0/shipments/' + req_params.path.shipmentId + '/cancel', | ||
restore_rate:1 | ||
}); | ||
}, | ||
createShipment:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/mfn/v0/shipments', | ||
restore_rate:1 | ||
}); | ||
}, | ||
getAdditionalSellerInputsOld:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/mfn/v0/sellerInputs', | ||
restore_rate:1 | ||
}); | ||
}, | ||
getAdditionalSellerInputs:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/mfn/v0/additionalSellerInputs', | ||
restore_rate:1 | ||
}); | ||
merchantFulfillment:{ | ||
__versions:[ | ||
'v0' | ||
], | ||
__operations:[ | ||
'getEligibleShipmentServicesOld', | ||
'getEligibleShipmentServices', | ||
'getShipment', | ||
'cancelShipment', | ||
'cancelShipmentOld', | ||
'createShipment', | ||
'getAdditionalSellerInputsOld', | ||
'getAdditionalSellerInputs' | ||
], | ||
...require('./versions/merchant_fulfillment/merchantFulfillment_v0') | ||
} | ||
}; |
@@ -1,172 +0,22 @@ | ||
const utils = require('../utils'); | ||
module.exports = { | ||
getMessagingActionsForOrder:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
amazonOrderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/messaging/v1/orders/' + req_params.path.amazonOrderId, | ||
restore_rate:1 | ||
}); | ||
}, | ||
confirmCustomizationDetails:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
amazonOrderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/messaging/v1/orders/' + req_params.path.amazonOrderId + '/messages/confirmCustomizationDetails', | ||
restore_rate:1 | ||
}); | ||
}, | ||
createConfirmDeliveryDetails:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
amazonOrderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/messaging/v1/orders/' + req_params.path.amazonOrderId + '/messages/confirmDeliveryDetails', | ||
restore_rate:1 | ||
}); | ||
}, | ||
createLegalDisclosure:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
amazonOrderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/messaging/v1/orders/' + req_params.path.amazonOrderId + '/messages/legalDisclosure', | ||
restore_rate:1 | ||
}); | ||
}, | ||
createNegativeFeedbackRemoval:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
amazonOrderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/messaging/v1/orders/' + req_params.path.amazonOrderId + '/messages/negativeFeedbackRemoval', | ||
restore_rate:1 | ||
}); | ||
}, | ||
createConfirmOrderDetails:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
amazonOrderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/messaging/v1/orders/' + req_params.path.amazonOrderId + '/messages/confirmOrderDetails', | ||
restore_rate:1 | ||
}); | ||
}, | ||
createConfirmServiceDetails:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
amazonOrderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/messaging/v1/orders/' + req_params.path.amazonOrderId + '/messages/confirmServiceDetails', | ||
restore_rate:1 | ||
}); | ||
}, | ||
CreateAmazonMotors:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
amazonOrderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/messaging/v1/orders/' + req_params.path.amazonOrderId + '/messages/amazonMotors', | ||
restore_rate:1 | ||
}); | ||
}, | ||
CreateWarranty:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
amazonOrderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/messaging/v1/orders/' + req_params.path.amazonOrderId + '/messages/warranty', | ||
restore_rate:1 | ||
}); | ||
}, | ||
GetAttributes:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
amazonOrderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/messaging/v1/orders/' + req_params.path.amazonOrderId + '/attributes', | ||
restore_rate:1 | ||
}); | ||
}, | ||
createDigitalAccessKey:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
amazonOrderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/messaging/v1/orders/' + req_params.path.amazonOrderId + '/messages/digitalAccessKey', | ||
restore_rate:1 | ||
}); | ||
}, | ||
createUnexpectedProblem:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
amazonOrderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/messaging/v1/orders/' + req_params.path.amazonOrderId + '/messages/unexpectedProblem', | ||
restore_rate:1 | ||
}); | ||
messaging:{ | ||
__versions:[ | ||
'v1' | ||
], | ||
__operations:[ | ||
'getMessagingActionsForOrder', | ||
'confirmCustomizationDetails', | ||
'createConfirmDeliveryDetails', | ||
'createLegalDisclosure', | ||
'createNegativeFeedbackRemoval', | ||
'createConfirmOrderDetails', | ||
'createConfirmServiceDetails', | ||
'CreateAmazonMotors', | ||
'CreateWarranty', | ||
'GetAttributes', | ||
'createDigitalAccessKey', | ||
'createUnexpectedProblem' | ||
], | ||
...require('./versions/messaging/messaging_v1') | ||
} | ||
}; |
@@ -1,128 +0,18 @@ | ||
const utils = require('../utils'); | ||
let notificationTypeEnum = ['ANY_OFFER_CHANGED', 'FEED_PROCESSING_FINISHED', 'FBA_OUTBOUND_SHIPMENT_STATUS', 'FEE_PROMOTION', | ||
'FULFILLMENT_ORDER_STATUS', 'REPORT_PROCESSING_FINISHED', 'BRANDED_ITEM_CONTENT_CHANGE', 'ITEM_PRODUCT_TYPE_CHANGE', | ||
'MFN_ORDER_STATUS_CHANGE', 'B2B_ANY_OFFER_CHANGED']; | ||
module.exports = { | ||
getSubscription:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
notificationType:{ | ||
type:'enum', | ||
enum:notificationTypeEnum | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/notifications/v1/subscriptions/' + req_params.path.notificationType, | ||
restore_rate:1 | ||
}); | ||
}, | ||
createSubscription:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
notificationType:{ | ||
type:'enum', | ||
enum:notificationTypeEnum | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/notifications/v1/subscriptions/' + req_params.path.notificationType, | ||
restore_rate:1 | ||
}); | ||
}, | ||
getSubscriptionById:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
subscriptionId:{ | ||
type:'string' | ||
}, | ||
notificationType:{ | ||
type:'enum', | ||
enum:notificationTypeEnum | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/notifications/v1/subscriptions/' + req_params.path.notificationType + '/' + req_params.path.subscriptionId, | ||
restore_rate:1, | ||
is_grantless:true, | ||
scope:'sellingpartnerapi::notifications' | ||
}); | ||
}, | ||
deleteSubscriptionById:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
subscriptionId:{ | ||
type:'string' | ||
}, | ||
notificationType:{ | ||
type:'enum', | ||
enum:notificationTypeEnum | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'DELETE', | ||
api_path:'/notifications/v1/subscriptions/' + req_params.path.notificationType + '/' + req_params.path.subscriptionId, | ||
restore_rate:1, | ||
is_grantless:true, | ||
scope:'sellingpartnerapi::notifications' | ||
}); | ||
}, | ||
getDestinations:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/notifications/v1/destinations', | ||
restore_rate:1, | ||
is_grantless:true, | ||
scope:'sellingpartnerapi::notifications' | ||
}); | ||
}, | ||
createDestination:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/notifications/v1/destinations', | ||
restore_rate:1, | ||
is_grantless:true, | ||
scope:'sellingpartnerapi::notifications' | ||
}); | ||
}, | ||
getDestination:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
destinationId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/notifications/v1/destinations/' + req_params.path.destinationId, | ||
restore_rate:1, | ||
is_grantless:true, | ||
scope:'sellingpartnerapi::notifications' | ||
}); | ||
}, | ||
deleteDestination:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
destinationId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'DELETE', | ||
api_path:'/notifications/v1/destinations/' + req_params.path.destinationId, | ||
restore_rate:1, | ||
is_grantless:true, | ||
scope:'sellingpartnerapi::notifications' | ||
}); | ||
notifications:{ | ||
__versions:[ | ||
'v1' | ||
], | ||
__operations:[ | ||
'getSubscription', | ||
'createSubscription', | ||
'getSubscriptionById', | ||
'deleteSubscriptionById', | ||
'getDestinations', | ||
'createDestination', | ||
'getDestination', | ||
'deleteDestination' | ||
], | ||
...require('./versions/notifications/notifications_v1') | ||
} | ||
}; |
@@ -1,81 +0,16 @@ | ||
const utils = require('../utils'); | ||
module.exports = { | ||
getOrders:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/orders/v0/orders', | ||
restore_rate:1 | ||
}); | ||
}, | ||
getOrder:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
orderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/orders/v0/orders/' + req_params.path.orderId, | ||
restore_rate:1 | ||
}); | ||
}, | ||
getOrderBuyerInfo:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
orderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/orders/v0/orders/' + req_params.path.orderId + '/buyerInfo', | ||
restore_rate:1 | ||
}); | ||
}, | ||
getOrderAddress:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
orderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/orders/v0/orders/' + req_params.path.orderId + '/address', | ||
restore_rate:1 | ||
}); | ||
}, | ||
getOrderItems:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
orderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/orders/v0/orders/' + req_params.path.orderId + '/orderItems', | ||
restore_rate:1 | ||
}); | ||
}, | ||
getOrderItemsBuyerInfo:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
orderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/orders/v0/orders/' + req_params.path.orderId + '/orderItems/buyerInfo', | ||
restore_rate:1 | ||
}); | ||
orders:{ | ||
__versions:[ | ||
'v0' | ||
], | ||
__operations:[ | ||
'getOrders', | ||
'getOrder', | ||
'getOrderBuyerInfo', | ||
'getOrderAddress', | ||
'getOrderItems', | ||
'getOrderItemsBuyerInfo' | ||
], | ||
...require('./versions/orders/orders_v0') | ||
} | ||
}; |
@@ -1,33 +0,12 @@ | ||
const utils = require('../utils'); | ||
// TODO: Restore rates may vary for product fees operations --> x-amzn-RateLimit-Limit header is returned and should be respected | ||
module.exports = { | ||
getMyFeesEstimateForSKU:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
SellerSKU:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/products/fees/v0/listings/' + req_params.path.SellerSKU + '/feesEstimate', | ||
restore_rate:1 | ||
}); | ||
}, | ||
getMyFeesEstimateForASIN:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
Asin:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/products/fees/v0/items/' + req_params.path.Asin + '/feesEstimate', | ||
restore_rate:1 | ||
}); | ||
}, | ||
productFees:{ | ||
__versions:[ | ||
'v0' | ||
], | ||
__operations:[ | ||
'getMyFeesEstimateForSKU', | ||
'getMyFeesEstimateForASIN' | ||
], | ||
...require('./versions/product_fees/productFees_v0') | ||
} | ||
}; |
@@ -1,46 +0,14 @@ | ||
const utils = require('../utils'); | ||
module.exports = { | ||
getPricing:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/products/pricing/v0/price', | ||
restore_rate:1 | ||
}); | ||
}, | ||
getCompetitivePricing:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/products/pricing/v0/competitivePrice', | ||
restore_rate:1 | ||
}); | ||
}, | ||
getListingOffers:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
SellerSKU:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/products/pricing/v0/listings/' + req_params.path.SellerSKU + '/offers', | ||
restore_rate:1 | ||
}); | ||
}, | ||
getItemOffers:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
Asin:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/products/pricing/v0/items/' + req_params.path.Asin + '/offers', | ||
restore_rate:1 | ||
}); | ||
productPricing:{ | ||
__versions:[ | ||
'v0' | ||
], | ||
__operations:[ | ||
'getPricing', | ||
'getCompetitivePricing', | ||
'getListingOffers', | ||
'getItemOffers' | ||
], | ||
...require('./versions/product_pricing/productPricing_v0') | ||
} | ||
}; |
@@ -1,102 +0,21 @@ | ||
const utils = require('../utils'); | ||
module.exports = { | ||
getReports:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/reports/2020-09-04/reports', | ||
restore_rate:45 | ||
}); | ||
}, | ||
createReport:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/reports/2020-09-04/reports', | ||
restore_rate:60 | ||
}); | ||
}, | ||
getReport:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
reportId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/reports/2020-09-04/reports/' + req_params.path.reportId, | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
cancelReport:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
reportId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'DELETE', | ||
api_path:'/reports/2020-09-04/reports/' + req_params.path.reportId, | ||
restore_rate:45 | ||
}); | ||
}, | ||
getReportSchedules:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/reports/2020-09-04/schedules', | ||
restore_rate:0.5 | ||
}); | ||
}, | ||
createReportSchedule:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/reports/2020-09-04/schedules', | ||
restore_rate:45 | ||
}); | ||
}, | ||
getReportSchedule:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
reportScheduleId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/reports/2020-09-04/schedules/' + req_params.path.reportScheduleId, | ||
restore_rate:45 | ||
}); | ||
}, | ||
cancelReportSchedule:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
reportScheduleId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'DELETE', | ||
api_path:'/reports/2020-09-04/schedules/' + req_params.path.reportScheduleId, | ||
restore_rate:45 | ||
}); | ||
}, | ||
getReportDocument:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
reportDocumentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/reports/2020-09-04/documents/' + req_params.path.reportDocumentId, | ||
restore_rate:45 | ||
}); | ||
reports:{ | ||
__versions:[ | ||
'2020-09-04', | ||
'2021-06-30' | ||
], | ||
__operations:[ | ||
'getReports', | ||
'createReport', | ||
'getReport', | ||
'cancelReport', | ||
'getReportSchedules', | ||
'createReportSchedule', | ||
'getReportSchedule', | ||
'cancelReportSchedule', | ||
'getReportDocument' | ||
], | ||
...require('./versions/reports/reports_2020-09-04'), | ||
...require('./versions/reports/reports_2021-06-30') | ||
} | ||
}; |
module.exports = { | ||
getOrderMetrics:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/sales/v1/orderMetrics', | ||
restore_rate:2 | ||
}); | ||
sales:{ | ||
__versions:[ | ||
'v1' | ||
], | ||
__operations:[ | ||
'getOrderMetrics' | ||
], | ||
...require('./versions/sales/sales_v1') | ||
} | ||
}; |
module.exports = { | ||
getMarketplaceParticipations:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/sellers/v1/marketplaceParticipations', | ||
restore_rate:60 | ||
}); | ||
sellers:{ | ||
__versions:[ | ||
'v1' | ||
], | ||
__operations:[ | ||
'getMarketplaceParticipations' | ||
], | ||
...require('./versions/sellers/sellers_v1.js') | ||
} | ||
}; |
@@ -1,84 +0,16 @@ | ||
const utils = require('../utils'); | ||
module.exports = { | ||
getServiceJobByServiceJobId:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
serviceJobId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/service/v1/serviceJobs/' + req_params.path.serviceJobId, | ||
restore_rate:0.05 | ||
}); | ||
}, | ||
cancelServiceJobByServiceJobId:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
serviceJobId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'PUT', | ||
api_path:'/service/v1/serviceJobs/' + req_params.path.serviceJobId + '/cancellations', | ||
restore_rate:0.2 | ||
}); | ||
}, | ||
completeServiceJobByServiceJobId:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
serviceJobId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'PUT', | ||
api_path:'/service/v1/serviceJobs/' + req_params.path.serviceJobId + '/completions', | ||
restore_rate:0.2 | ||
}); | ||
}, | ||
getServiceJobs:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/service/v1/serviceJobs', | ||
restore_rate:0.1 | ||
}); | ||
}, | ||
addAppointmentForServiceJobByServiceJobId:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
serviceJobId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/service/v1/serviceJobs/' + req_params.path.serviceJobId + '/appointments', | ||
restore_rate:0.2 | ||
}); | ||
}, | ||
rescheduleAppointmentForServiceJobByServiceJobId:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
serviceJobId:{ | ||
type:'string' | ||
}, | ||
appointmentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/service/v1/serviceJobs/' + req_params.path.serviceJobId + '/appointments/' + req_params.path.appointmentId, | ||
restore_rate:0.2 | ||
}); | ||
services:{ | ||
__versions:[ | ||
'v1' | ||
], | ||
__operations:[ | ||
'getServiceJobByServiceJobId', | ||
'cancelServiceJobByServiceJobId', | ||
'completeServiceJobByServiceJobId', | ||
'getServiceJobs', | ||
'addAppointmentForServiceJobByServiceJobId', | ||
'rescheduleAppointmentForServiceJobByServiceJobId' | ||
], | ||
...require('./versions/services/services_v1') | ||
} | ||
}; |
@@ -1,105 +0,19 @@ | ||
const utils = require('../utils'); | ||
module.exports = { | ||
createShipment:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/shipping/v1/shipments', | ||
restore_rate:0.2 | ||
}); | ||
}, | ||
getShipment:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
shipmentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/shipping/v1/shipments/' + req_params.path.shipmentId, | ||
restore_rate:0.2 | ||
}); | ||
}, | ||
cancelShipment:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
shipmentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/shipping/v1/shipments/' + req_params.path.shipmentId + '/cancel', | ||
restore_rate:0.2 | ||
}); | ||
}, | ||
purchaseLabels:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
shipmentId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/shipping/v1/shipments/' + req_params.path.shipmentId + '/purchaseLabels', | ||
restore_rate:0.2 | ||
}); | ||
}, | ||
retrieveShippingLabel:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
shipmentId:{ | ||
type:'string' | ||
}, | ||
trackingId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/shipping/v1/shipments/' + req_params.path.shipmentId + '/containers/' + req_params.path.trackingId + '/label', | ||
restore_rate:0.2 | ||
}); | ||
}, | ||
purchaseShipment:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/shipping/v1/purchaseShipment', | ||
restore_rate:0.2 | ||
}); | ||
}, | ||
getRates:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/shipping/v1/rates', | ||
restore_rate:0.2 | ||
}); | ||
}, | ||
getAccount:(req_params) => { | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/shipping/v1/account', | ||
restore_rate:0.2 | ||
}); | ||
}, | ||
getTrackingInformation:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
trackingId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/shipping/v1/tracking/' + req_params.path.trackingId, | ||
restore_rate:1 | ||
}); | ||
shipping:{ | ||
__versions:[ | ||
'v1' | ||
], | ||
__operations:[ | ||
'createShipment', | ||
'getShipment', | ||
'cancelShipment', | ||
'purchaseLabels', | ||
'retrieveShippingLabel', | ||
'purchaseShipment', | ||
'getRates', | ||
'getAccount', | ||
'getTrackingInformation' | ||
], | ||
...require('./versions/shipping/shipping_v1') | ||
} | ||
}; |
@@ -1,32 +0,12 @@ | ||
const utils = require('../utils'); | ||
module.exports = { | ||
getSolicitationActionsForOrder:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
amazonOrderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'GET', | ||
api_path:'/solicitations/v1/orders/' + req_params.path.amazonOrderId, | ||
restore_rate:1 | ||
}); | ||
}, | ||
createProductReviewAndSellerFeedbackSolicitation:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
amazonOrderId:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/solicitations/v1/orders/' + req_params.path.amazonOrderId + '/solicitations/productReviewAndSellerFeedback', | ||
restore_rate:60 | ||
}); | ||
solicitations:{ | ||
__versions:[ | ||
'v1' | ||
], | ||
__operations:[ | ||
'getSolicitationActionsForOrder', | ||
'createProductReviewAndSellerFeedbackSolicitation' | ||
], | ||
...require('./versions/solicitations/solicitations_v1') | ||
} | ||
}; |
@@ -1,18 +0,11 @@ | ||
const utils = require('../utils'); | ||
module.exports = { | ||
createUploadDestinationForResource:(req_params) => { | ||
utils.checkParams(req_params, { | ||
path:{ | ||
resource:{ | ||
type:'string' | ||
} | ||
} | ||
}); | ||
return Object.assign(req_params, { | ||
method:'POST', | ||
api_path:'/uploads/2020-11-01/uploadDestinations/' + req_params.path.resource, | ||
restore_rate:10 | ||
}); | ||
uploads:{ | ||
__versions:[ | ||
'2020-11-01' | ||
], | ||
__operations:[ | ||
'createUploadDestinationForResource' | ||
], | ||
...require('./versions/uploads/uploads_2020-11-01') | ||
} | ||
}; |
@@ -6,3 +6,4 @@ const CustomError = require('./CustomError'); | ||
const credentials = require('./credentials'); | ||
const operations = require('./operations'); | ||
const endpoints = require('./endpoints'); | ||
const operations = require('./operations')(endpoints); | ||
const crypto = require('crypto'); | ||
@@ -22,23 +23,27 @@ const csv = require('csvtojson'); | ||
// config object params: | ||
// region:'eu', // Required: The region of the selling partner API endpoint ("eu", "na" or "fe") | ||
// refresh_token:'<YOUR_REFRESH_TOKEN>', // Optional: The refresh token of your app user, required if "only_grantless_operations" option is not explicity set to true | ||
// access_token:'<YOUR_ACCESS_TOKEN>', // Optional: The access token requested with the refresh token of the app user | ||
// role_credentials:{ | ||
// id:'<YOUR_TEMPORARY_ROLE_ACCESS_ID>', // Optional: The temporary access id for the sp api role of the iam user | ||
// secret:'<YOUR_TEMPORARY_ROLE_ACCESS_SECRET>', // Optional: The temporary access secret for the sp api role of the iam user | ||
// security_token:'<YOUR_TEMPORARY_ROLE_SECURITY_TOKEN>' // Optional: The temporary security token for the sp api role of the iam user | ||
// region:'<REGION>', // Required: The region to use for the SP-API endpoints. Must be one of: "eu", "na" or "fe" | ||
// refresh_token:'<REFRESH_TOKEN>', // Optional: The refresh token of your app user. Required if "only_grantless_operations" option is set to "false". | ||
// access_token:'<ACCESS_TOKEN>', // Optional: The temporary access token requested with the refresh token of the app user. | ||
// role_credentials:{ // Optional: The temporary role credentials for the sellingpartner api role of the iam user. | ||
// id:'<TEMPORARY_ROLE_ACCESS_ID>', | ||
// secret:'<TEMPORARY_ROLE_ACCESS_SECRET>', | ||
// security_token:'<TEMPORARY_ROLE_SECURITY_TOKEN>' | ||
// }, | ||
// endpoints_versions:{ // Optional: Defines the version to use for an endpoint as key/value pairs, i.e. "reports":"2021-06-30". | ||
// ... | ||
// }, | ||
// credentials:{ // Optional: The app client and aws user credentials. Should only be used if you have no means of using environment vars or credentials file! | ||
// SELLING_PARTNER_APP_CLIENT_ID:'<APP_CLIENT_ID>', | ||
// SELLING_PARTNER_APP_CLIENT_SECRET:'<APP_CLIENT_SECRET>', | ||
// AWS_ACCESS_KEY_ID:'<AWS_USER_ID>', | ||
// AWS_SECRET_ACCESS_KEY:'<AWS_USER_SECRET>', | ||
// AWS_SELLING_PARTNER_ROLE:'<AWS_SELLING_PARTNER_API_ROLE>' | ||
// }, | ||
// options:{ | ||
// credentials_path:'<YOUR_CUSTOM_ABSOLUTE_PATH', // Optional: A custom absolute path to your credentials file location | ||
// auto_request_tokens:true|false, // Optional: Whether or not the client should retrieve new access and role credentials if non given or expired. Default is true | ||
// auto_request_throttled:true|false, // Optional: Whether or not the client should automatically retry a request when throttled. Default is true | ||
// use_sandbox:true|false, // Optional: Whether or not to use the sandbox endpoint. Default is false | ||
// only_grantless_operations:true|false // Optional: Whether or not to only use grantless operations. Default is false | ||
// }, | ||
// credentials:{ // Optional: Your app client and aws user credentials, should only be used if you have no means of using environment vars or credentials file | ||
// SELLING_PARTNER_APP_CLIENT_ID:'<YOUR_APP_CLIENT_ID>', | ||
// SELLING_PARTNER_APP_CLIENT_SECRET:'<YOUR_APP_CLIENT_SECRET>', | ||
// AWS_ACCESS_KEY_ID:'<YOUR_AWS_USER_ID>', | ||
// AWS_SECRET_ACCESS_KEY:'<YOUR_AWS_USER_SECRET>', | ||
// AWS_SELLING_PARTNER_ROLE:'<YOUR_AWS_SELLING_PARTNER_API_ROLE>' | ||
// credentials_path:'~/.amzspapi/credentials', // Optional: A custom absolute path to your credentials file location. | ||
// auto_request_tokens:true, // Optional: Whether or not the client should retrieve new access and role credentials if non given or expired. | ||
// auto_request_throttled:true, // Optional: Whether or not the client should automatically retry a request when throttled. | ||
// version_fallback:true, // Optional: Whether or not the client should try to use an older version of an endpoint if the operation is not defined for the desired version. | ||
// use_sandbox:false, // Optional: Whether or not to use the sandbox endpoint. | ||
// only_grantless_operations:false // Optional: Whether or not to only use grantless operations. | ||
// } | ||
@@ -57,4 +62,6 @@ // TODO: We could add something like a debug option, that will enable included info logs, i.e. sandbox activated, credentials load type (env, file, config), etc. | ||
use_sandbox:false, | ||
only_grantless_operations:false | ||
only_grantless_operations:false, | ||
version_fallback:true | ||
}, config.options); | ||
this._endpoints_versions = this._validateEndpointsVersions(Object.assign({}, config.endpoints_versions)); | ||
this._credentials = credentials.load(config.credentials, this._options.credentials_path); | ||
@@ -84,2 +91,29 @@ | ||
get endpoints(){ | ||
return endpoints; | ||
} | ||
// Make sure that all defined endpoints and its defined versions exist | ||
_validateEndpointsVersions(endpoints_versions){ | ||
let invalid_endpoints = Object.keys(endpoints_versions).filter((endpoint) => { | ||
return !endpoints[endpoint]; | ||
}); | ||
if (invalid_endpoints.length){ | ||
throw new CustomError({ | ||
code:'VERSION_DEFINED_FOR_INVALID_ENDPOINTS', | ||
message:'One or more endpoints are not valid. These endpoints don\'t exist: "' + invalid_endpoints.join('","') + '"' | ||
}); | ||
} | ||
let invalid_endpoints_versions = Object.keys(endpoints_versions).filter((endpoint) => { | ||
return !endpoints[endpoint].__versions.includes(endpoints_versions[endpoint]); | ||
}); | ||
if (invalid_endpoints_versions.length){ | ||
throw new CustomError({ | ||
code:'INVALID_VERSION_FOR_ENDPOINTS', | ||
message:'The provided version for the following endpoint(s) is not valid: "' + invalid_endpoints_versions.join('","') + '"' | ||
}); | ||
} | ||
return endpoints_versions; | ||
} | ||
async _wait(restore_rate){ | ||
@@ -226,2 +260,12 @@ return new Promise((resolve, reject) => { | ||
_validateMethod(method){ | ||
if (!method || !/^(GET|POST|PUT|DELETE)$/.test(method.toUpperCase())){ | ||
throw new CustomError({ | ||
code:'NO_VALID_METHOD_PROVIDED', | ||
message:'Please provide a valid HTTP Method ("GET","POST","PUT" or "DELETE") when using "api_path"' | ||
}); | ||
} | ||
return method.toUpperCase(); | ||
} | ||
_validateOperation(operation){ | ||
@@ -242,2 +286,63 @@ if (!operation){ | ||
_getFallbackVersion(operation, version){ | ||
let endpoint = operations[operation]; | ||
// Make sure to only look for the operation in older versions | ||
// --> we don't want to break stuff by accidently calling a newer version than expected! | ||
let version_index = endpoints[endpoint].__versions.indexOf(version); | ||
let fallback_version = endpoints[endpoint].__versions.slice(0, version_index).reverse().find((__version) => { | ||
return endpoints[endpoint][__version][operation]; | ||
}); | ||
// Throw error if version_fallback is disabled or no fallback version was found | ||
if (!this._options.version_fallback || !fallback_version){ | ||
throw new CustomError({ | ||
code:'OPERATION_NOT_FOUND_FOR_VERSION', | ||
message:'Operation "' + operation + '" not found for version "' + version + '"' | ||
}); | ||
} | ||
return fallback_version; | ||
} | ||
// Logic if version was explicitly set in .callAPI options | ||
_validateLocallySetVersion(operation, version){ | ||
let endpoint = operations[operation]; | ||
// Throw error if the explicitly specified version in .callAPI can't be found for the endpoint | ||
if (!endpoints[endpoint].__versions.includes(version)){ | ||
throw new CustomError({ | ||
code:'INVALID_VERSION', | ||
message:'Invalid version "' + version + '" for endpoint "' + endpoint + '" and operation "' + operation + '". Should be one of: "' + endpoints[endpoint].__versions.join('","') + '"' | ||
}); | ||
} | ||
// If operation is not supported for the version: | ||
// --> try to find an older version of the endpoint that supports the operation | ||
if (!endpoints[endpoint][version][operation]){ | ||
return this._getFallbackVersion(operation, version); | ||
} | ||
return version; | ||
} | ||
// Logic if version was NOT explicitly set in .callAPI options | ||
_validateGloballySetVersion(operation){ | ||
let endpoint = operations[operation]; | ||
// If no version for the endpoint was set in constructor config: | ||
// --> find the oldest version that supports the operation | ||
if (!this._endpoints_versions[endpoint]){ | ||
// We can directly return the version as its impossible for a valid operation to have no version | ||
return endpoints[endpoint].__versions.find((__version) => { | ||
return endpoints[endpoint][__version][operation]; | ||
}); | ||
} | ||
// Get the version specified for the endpoint in constructor config | ||
let version = this._endpoints_versions[endpoint]; | ||
// If operation is not supported for the version: | ||
// --> try to find an older version of the endpoint that supports the operation | ||
if (!endpoints[endpoint][version][operation]){ | ||
return this._getFallbackVersion(operation, version); | ||
} | ||
return version; | ||
} | ||
_validateAndGetVersion(operation, version){ | ||
return version ? this._validateLocallySetVersion(operation, version) : this._validateGloballySetVersion(operation); | ||
} | ||
_validateOperationAllowance(scope){ | ||
@@ -324,10 +429,29 @@ if (this._options.only_grantless_operations && !scope){ | ||
// req_params object: | ||
// * operation: Required, the operation you want to request [see SP API References](https://github.com/amzn/selling-partner-api-docs/tree/main/references) | ||
// * path: Optional, the input paramaters added to the path of the operation | ||
// * query: Optional, the input parameters added to the query string of the operation | ||
// * body: Optional, the input parameters added to the body of the operation | ||
// * options: Optional, additional options, currently only supports `raw_result:true` as key/value, see examples for more information | ||
// operation:'<OPERATION_TO_CALL>', // Optional: The operation you want to request. Required if "api_path" is not defined. | ||
// path:{ // Optional: The input paramaters added to the path of the operation. | ||
// ... | ||
// } | ||
// query:{ // Optional: The input paramaters added to the query string of the operation. | ||
// ... | ||
// }, | ||
// body:{ // Optional: The input paramaters added to the body of the operation. | ||
// ... | ||
// }, | ||
// api_path:'<FULL_PATH_OF_OPERATION>', // Optional: The full path of an operation. Required if "operation" is not defined. | ||
// method:'GET' // The HTTP method to use. Required only if "api_path" is defined. Must be one of: "GET", "POST", "PUT" or "DELETE". | ||
// restricted_data_token:'<RESTRICTED_DATA_TOKEN>' // Optional: A token received from a "createRestrictedDataToken" operation for receiving PII from a restricted operation. | ||
// options:{ | ||
// version:'<OPERATION_ENDPOINT_VERSION>', // Optional: The endpoint’s version that should be used when calling the operation. Will be preferred over an "endpoints_versions" setting. | ||
// raw_result:false // Whether or not the client should return the "raw" result, which will include the raw body, buffer chunks, statuscode and headers of the result. | ||
// } | ||
async callAPI(req_params){ | ||
this._validateOperation(req_params.operation); | ||
req_params = operations[req_params.operation](req_params); | ||
let options = Object.assign({}, req_params.options); | ||
if (req_params.api_path){ | ||
req_params.method = this._validateMethod(req_params.method); | ||
} else { | ||
let operation = req_params.operation; | ||
this._validateOperation(operation); | ||
let version = this._validateAndGetVersion(operation, options.version); | ||
req_params = endpoints[operations[operation]][version][operation](req_params); | ||
} | ||
// Scope will only be defined for grantless operations | ||
@@ -337,6 +461,12 @@ let scope = req_params.scope; | ||
await this._validateAccessTokenAndRoleCredentials(scope); | ||
let token_for_request = scope ? this._grantless_tokens[scope] : this._access_token; | ||
// Make sure to use the correct token for the request | ||
let token_for_request = this._access_token; | ||
if (scope){ | ||
token_for_request = this._grantless_tokens[scope]; | ||
} else if (req_params.restricted_data_token){ | ||
token_for_request = req_params.restricted_data_token; | ||
} | ||
let signed_request = new Signer(this._region, this._options.use_sandbox).signAPIRequest(token_for_request, this._role_credentials, req_params); | ||
let res = await request(signed_request); | ||
if (req_params.options && req_params.options.raw_result){ | ||
if (options.raw_result){ | ||
return res; | ||
@@ -393,10 +523,8 @@ } | ||
// Will be a tab-delimited flat file or an xml document | ||
// Download a report or feed result | ||
// Options object: | ||
// * json: Optional (true|false), whether or not the content should be transformed to json before returning it (from tab delimited flat-file or XML). Defaults to false. | ||
// --> IMPORTANT: is ignored when unzip is set to false. | ||
// * unzip: Optional (true|false), whether or not the content should be unzipped before returning it. Defaults to true. | ||
// * file: Optional, the absolute file path to save the report to. Defaults to not saving to disk. | ||
// --> IMPORTANT: Even when saved to disk the report content is still returned. | ||
// * charset: Optional, the charset to use for decoding the content. | ||
// json:false, // Optional: Whether or not the content should be transformed to json before returning it (from tab delimited flat-file or XML). | ||
// unzip:true, // Optional: Whether or not the content should be unzipped before returning it. | ||
// file:'<FILE_PATH>', // Optional: The absolute file path to save the report to. Even when saved to disk the report content is still returned. | ||
// charset:'utf8' // Optional: The charset to use for decoding the content. Is ignored when content is compressed and unzip is set to false. | ||
async download(details, options = {}){ | ||
@@ -407,2 +535,3 @@ options = Object.assign({ | ||
this._validateEncryptionDetails(details); | ||
// Result will be a tab-delimited flat file or an xml document | ||
let res = await request({ | ||
@@ -466,8 +595,6 @@ url:details.url | ||
// Upload a tab-delimited flat file or an xml document | ||
// feed object: | ||
// * content: Required if "file" is not provided, the content to upload as a string | ||
// * file: Required if "content" is not provided, the absolute file path of the document to upload | ||
// --> IMPORTANT: Is ignored if "content" is provided | ||
// * contentType: Required, the contentType of the content to upload | ||
// --> (should be one of "text/xml" or "text/tab-separated-values" and the charset of the content, i.e. "text/xml; charset=utf-8") | ||
// Feed object: | ||
// content:'<CONTENT>', // Optional: The content to upload as a string. Required if "file" is not provided. | ||
// file:'<FILE_PATH>', // Optional: The absolute file path to the feed content document to upload. Required if "content" is not provided. | ||
// contentType:'<CONTENT_TYPE>' // Optional: The contentType of the content to upload. Should be one of "text/xml" or "text/tab-separated-values" and the charset of the content, i.e. "text/xml; charset=utf-8". | ||
async upload(details, feed){ | ||
@@ -474,0 +601,0 @@ this._validateEncryptionDetails(details); |
{ | ||
"name": "amazon-sp-api", | ||
"version": "0.3.7", | ||
"version": "0.4.0", | ||
"description": "Amazon Selling Partner API client", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
312
README.md
# amazon-sp-api (client for the Amazon Selling Partner API) | ||
The client handles calls to the Amazon Selling Partner API. It wraps up all the necessary stuff such as requesting access token, security token and signing requests with AWS4 signature. | ||
@@ -17,6 +18,12 @@ | ||
* [Examples](#examples) | ||
* [Versions](#versions) | ||
* [Version specific operation implementations](#version-specific-operation-implementations) | ||
* [Defining endpoints versions on class level](#defining-endpoints-versions-on-class-level) | ||
* [Fallback](#fallback) | ||
* [Grantless operations](#grantless-operations) | ||
* [Restore rates](#restore-rates) | ||
* [Unsupported endpoints/versions/operations](#unsupported-endpointsversionsoperations) | ||
* [Download, decrypt and unzip reports](#download-decrypt-and-unzip-reports) | ||
* [Encrypt and upload feeds](#encrypt-and-upload-feeds) | ||
* [TypeScript Support](#typescript-support) | ||
* [Sandbox mode](#sandbox-mode) | ||
@@ -27,4 +34,5 @@ * [Known Issues](#known-issues) | ||
## Prerequisites | ||
Make sure that you followed the [Selling Partner API Developer Guide](https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md) and have successfully completed the steps [Registering as a developer](https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#registering-as-a-developer), [Registering your Selling Partner API application](https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#registering-your-selling-partner-api-application) and have a valid refresh_token (if you use the client only for your own seller account the easiest way is using the self authorization as described in the developer guide). | ||
Make sure that you followed the [Selling Partner API Developer Guide](https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md) and have successfully completed the steps [Registering as a developer](https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#registering-as-a-developer), [Registering your Selling Partner API application](https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#registering-your-selling-partner-api-application) and have a valid refresh token (if you use the client only for your own seller account the easiest way is using the self authorization as described in the developer guide). | ||
## Installation | ||
@@ -36,5 +44,7 @@ ```bash | ||
## Getting Started | ||
Before you can use the client you need to add your app client and aws user credentials. | ||
### Setting credentials from environment variables | ||
* `SELLING_PARTNER_APP_CLIENT_ID`=<YOUR_APP_CLIENT_ID> ([see SP Developer Guide "Viewing your developer information"](https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#viewing-your-developer-information)) | ||
@@ -47,3 +57,4 @@ * `SELLING_PARTNER_APP_CLIENT_SECRET`=<YOUR_APP_CLIENT_SECRET> ([see SP Developer Guide "Viewing your developer information"](https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#viewing-your-developer-information)) | ||
### Setting credentials from file | ||
Instead of setting the credentials via environment variables you may load them from a credentials file. The default path to the file is ~/.amzspapi/credentials (path can be changed when creating a client) and you add the credentials one per line: | ||
Instead of setting the credentials via environment variables you may load them from a credentials file. The default path to the file is `~/.amzspapi/credentials` (path can be changed when creating a client) and you add the credentials one per line: | ||
```bash | ||
@@ -58,5 +69,7 @@ SELLING_PARTNER_APP_CLIENT_ID=<YOUR_APP_CLIENT_ID> | ||
### Setting credentials from constructor config object | ||
Although the most convenient and recommended way of setting the credentials is via environment variables or config file it is also possible to pass the credentials inside the config object when creating an instance of the client (i.e. if you have no means of using env vars or a config file). The structure of the constructor config object will be explained below. | ||
## Usage | ||
Require library: | ||
@@ -72,4 +85,4 @@ ```javascript | ||
let sellingPartner = new SellingPartnerAPI({ | ||
region:'eu', // The region of the selling partner API endpoint ("eu", "na" or "fe") | ||
refresh_token:'<YOUR_REFRESH_TOKEN>' // The refresh token of your app user | ||
region:'eu', // The region to use for the SP-API endpoints ("eu", "na" or "fe") | ||
refresh_token:'<REFRESH_TOKEN>' // The refresh token of your app user | ||
}); | ||
@@ -88,32 +101,57 @@ let res = await sellingPartner.callAPI({ | ||
The class constructor takes a config object as input: | ||
The class constructor takes a config object with the following structure as input: | ||
```javascript | ||
{ | ||
region:'eu', // Required: The region of the selling partner API endpoint ("eu", "na" or "fe") | ||
refresh_token:'<YOUR_REFRESH_TOKEN>', // Optional: The refresh token of your app user. Required if "only_grantless_operations" option is set to false | ||
access_token:'<YOUR_ACCESS_TOKEN>', // Optional: The access token requested with the refresh token of the app user | ||
region:'<REGION>', | ||
refresh_token:'<REFRESH_TOKEN>', | ||
access_token:'<ACCESS_TOKEN>', | ||
role_credentials:{ | ||
id:'<YOUR_TEMPORARY_ROLE_ACCESS_ID>', // Optional: The temporary access id for the sp api role of the iam user | ||
secret:'<YOUR_TEMPORARY_ROLE_ACCESS_SECRET>', // Optional: The temporary access secret for the sp api role of the iam user | ||
security_token:'<YOUR_TEMPORARY_ROLE_SECURITY_TOKEN>' // Optional: The temporary security token for the sp api role of the iam user | ||
id:'<TEMPORARY_ROLE_ACCESS_ID>', | ||
secret:'<TEMPORARY_ROLE_ACCESS_SECRET>', | ||
security_token:'<TEMPORARY_ROLE_SECURITY_TOKEN>' | ||
}, | ||
options:{ | ||
credentials_path:'<YOUR_CUSTOM_ABSOLUTE_PATH>', // Optional: A custom absolute path to your credentials file location | ||
auto_request_tokens:true, // Optional: Whether or not the client should retrieve new access and role credentials if non given or expired. Default is true | ||
auto_request_throttled:true, // Optional: Whether or not the client should automatically retry a request when throttled. Default is true | ||
use_sandbox:false, // Optional: Whether or not to use the sandbox endpoint. Default is false | ||
only_grantless_operations:false // Optional: Whether or not to only use grantless operations. Default is false | ||
endpoints_versions:{ | ||
... | ||
}, | ||
// Optional: Your app client and aws user credentials | ||
// --> should only be used if you have no means of using environment vars or credentials file | ||
credentials:{ | ||
SELLING_PARTNER_APP_CLIENT_ID:'<YOUR_APP_CLIENT_ID>', | ||
SELLING_PARTNER_APP_CLIENT_SECRET:'<YOUR_APP_CLIENT_SECRET>', | ||
AWS_ACCESS_KEY_ID:'<YOUR_AWS_USER_ID>', | ||
AWS_SECRET_ACCESS_KEY:'<YOUR_AWS_USER_SECRET>', | ||
AWS_SELLING_PARTNER_ROLE:'<YOUR_AWS_SELLING_PARTNER_API_ROLE>' | ||
SELLING_PARTNER_APP_CLIENT_ID:'<APP_CLIENT_ID>', | ||
SELLING_PARTNER_APP_CLIENT_SECRET:'<APP_CLIENT_SECRET>', | ||
AWS_ACCESS_KEY_ID:'<AWS_USER_ID>', | ||
AWS_SECRET_ACCESS_KEY:'<AWS_USER_SECRET>', | ||
AWS_SELLING_PARTNER_ROLE:'<AWS_SELLING_PARTNER_API_ROLE>' | ||
}, | ||
options:{ | ||
credentials_path:'~/.amzspapi/credentials', | ||
auto_request_tokens:true, | ||
auto_request_throttled:true, | ||
version_fallback:true, | ||
use_sandbox:false, | ||
only_grantless_operations:false | ||
} | ||
} | ||
``` | ||
If you only provide the "region" and "refresh_token" parameters the client will automatically request access_token and role_credentials for you (with a TTL of 1 hour) and reuse these for future api calls for the class instance. | ||
Valid properties of the config object: | ||
| Name | Type | Default | Description | | ||
|:--|:--:|:--:|:--| | ||
| **region**<br>*required* | string | - | The region to use for the SP-API endpoints.<br>Must be one of: `eu`, `na` or `fe` | | ||
| **refresh_token**<br>*optional* | string | - | The refresh token of your app user.<br>Required if `only_grantless_operations` option is set to `false`. | | ||
| **access_token**<br>*optional* | string | - | The temporary access token requested with the refresh token of the app user. | | ||
| **role_credentials**<br>*optional* | object | - | The temporary role credentials for the sellingpartner api role of the iam user. Must include the three properties `id`, `secret` and `security_token` with their corresponding values. | | ||
| **endpoints_versions**<br>*optional* | object | - | Defines the version to use for an endpoint as key/value pairs, i.e. `"reports":"2021-06-30"`. If none given the client is using the first (meaning the oldest) version for an endpoint.<br>Call `.endpoints` on class instance to retrieve a complete list of all endpoints, versions and operations supported by the client. | | ||
| **credentials**<br>*optional* | object | - | The app client and aws user credentials. Must include the five credentials properties `SELLING_PARTNER_APP_CLIENT_ID`, `SELLING_PARTNER_APP_CLIENT_SECRET`, `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_SELLING_PARTNER_ROLE` with their corresponding values.<br>NOTE: Should only be used if you have no means of using environment vars or credentials file! | | ||
| **options**<br>*optional* | object | - | Additional options, see table below for all possible options properties. | | ||
Valid properties of the config options: | ||
| Name | Type | Default | Description | | ||
|:--|:--:|:--:|--| | ||
| **credentials_path**<br>*optional* | string | ~/.amzspapi/credentials | A custom absolute path to your credentials file location. | | ||
| **auto_request_tokens**<br>*optional* | boolean | true | Whether or not the client should retrieve new access and role credentials if non given or expired. | | ||
| **auto_request_throttled**<br>*optional* | boolean | true | Whether or not the client should automatically retry a request when throttled. | | ||
| **version_fallback**<br>*optional* | boolean | true | Whether or not the client should try to use an older version of an endpoint if the operation is not defined for the desired version. | | ||
| **use_sandbox**<br>*optional* | boolean | false | Whether or not to use the sandbox endpoint. | | ||
| **only_grantless_operations**<br>*optional* | boolean | false | Whether or not to only use grantless operations. | | ||
If you only provide the `region` and `refresh_token` parameters the client will automatically request `access_token` and `role_credentials` for you (with a TTL of 1 hour) and reuse these for future api calls for the class instance. | ||
If you want to use the same credentials for multiple instances you can retrieve them via getters and use them as input for a new instance: | ||
@@ -126,3 +164,3 @@ ```javascript | ||
region:'eu', | ||
refresh_token:'<YOUR_REFRESH_TOKEN>', | ||
refresh_token:'<REFRESH_TOKEN>', | ||
access_token:access_token, | ||
@@ -135,7 +173,7 @@ role_credentials:role_credentials | ||
Instead of having the client handle the access token and role credentials requests automatically, you may also refresh them manually: | ||
Instead of having the client handle the `access_token` and `role_credentials` requests automatically, you may also refresh them manually: | ||
```javascript | ||
let sellingPartner = new SellingPartnerAPI({ | ||
region:'eu', | ||
refresh_token:'<YOUR_REFRESH_TOKEN>', | ||
refresh_token:'<REFRESH_TOKEN>', | ||
options:{ | ||
@@ -151,10 +189,46 @@ auto_request_tokens:false | ||
The **.callAPI()** function takes an object as input: | ||
* `operation`: Required, the operation you want to request [see SP API References](https://github.com/amzn/selling-partner-api-docs/tree/main/references) | ||
* `path`: Optional, the input paramaters added to the path of the operation | ||
* `query`: Optional, the input parameters added to the query string of the operation | ||
* `body`: Optional, the input parameters added to the body of the operation | ||
* `options`: Optional, additional options, currently only supports `raw_result:true` as key/value, see examples for more information | ||
All calls to the SP-API will be triggered by using the `.callAPI()` function, which takes an object with the following structure as input: | ||
```javascript | ||
{ | ||
operation:'<OPERATION_TO_CALL>', | ||
path:{ | ||
... | ||
} | ||
query:{ | ||
... | ||
}, | ||
body:{ | ||
... | ||
}, | ||
api_path:'<FULL_PATH_OF_OPERATION>', | ||
method:'GET', | ||
restricted_data_token:'<RESTRICTED_DATA_TOKEN>' | ||
options:{ | ||
version:'<OPERATION_ENDPOINT_VERSION>', | ||
raw_result:false | ||
} | ||
} | ||
``` | ||
Valid properties of the object: | ||
| Name | Type | Default | Description | | ||
|:--|:--:|:--:|:--| | ||
| **operation**<br>*optional* | string | - | The operation you want to request, [see SP API References](https://github.com/amzn/selling-partner-api-docs/tree/main/references).<br>Call `.endpoints` on class instance to retrieve a complete list of all endpoints, versions and operations supported by the client.<br>Required if `api_path` is not defined. | | ||
| **path**<br>*optional* | object | - | The input paramaters added to the path of the operation. | | ||
| **query**<br>*optional* | object | - | The input paramaters added to the query string of the operation. | | ||
| **body**<br>*optional* | object | - | The input paramaters added to the body of the operation. | | ||
| **api_path**<br>*optional* | string | - | The full api path of an operation. Can be used to call operations that are not yet supported or have a new version that is not yet supported by the client.<br>Required if `operation` is not defined. | | ||
| **method**<br>*optional* | string | - | The HTTP method to use.<br>Required only if `api_path` is defined.<br>Must be one of: `GET`, `POST`, `PUT` or `DELETE`. | | ||
| **restricted_data_token**<br>*optional* | string | - | A token received from a `createRestrictedDataToken` operation. Neccessary to include PII (Personally Identifiable Informaton) for some restricted operations, [see Tokens API use case guide](https://github.com/amzn/selling-partner-api-docs/blob/main/guides/en-US/use-case-guides/tokens-api-use-case-guide/tokens-API-use-case-guide-2021-03-01.md#restricted-operations) for a list of restricted operations.<br>NOTE: Your developer account must be approved for PII by Amazon in order to be able to receive PII, otherwise the token will have no effect, meaning the result of restricted operations will not include PII. | | ||
| **options**<br>*optional* | object | - | Additional options, see table below for all possible options properties. | | ||
Valid properties of the config options: | ||
| Name | Type | Default | Description | | ||
|:--|:--:|:--:|--| | ||
| **version**<br>*optional* | string | - | The endpoint's version that should be used when calling the operation. Will be preferred over an `endpoints_versions` setting.<br>NOTE: The call might still use an older version of the endpoint if the operation is not available for the specified version and `version_fallback` is set to `true`. | | ||
| **raw_result**<br>*optional* | boolean | false | Whether or not the client should return the "raw" result, which will include the raw body, buffer chunks, statuscode and headers of the result. This will skip the internal formatting or error checking, but might be helpful when you need additional information besides the payload or when the client encounters JSON.parse errors such as the ones already encountered with old finance documents ([see Known Issues](#known-issues)). | | ||
### Examples | ||
```javascript | ||
@@ -190,3 +264,2 @@ let res = await sellingPartner.callAPI({ | ||
``` | ||
Instead of having the client handle the result and error parsing you may also have the client return the "raw" result, which will include the raw body, buffer chunks, statusCode and headers of the result. I.e. this might be helpful when the client encounters JSON.parse errors such as the ones already encountered with old finance documents ([see Known Issues](#known-issues)). To do so you pass in an options object with the key `raw_result` to `true` to the .callAPI() function: | ||
```javascript | ||
@@ -205,13 +278,85 @@ let res = await sellingPartner.callAPI({ | ||
### Versions | ||
Every operation belongs to an endpoint that consists of one or more versions and each version consists of one or more operations. You will find a complete list of the endpoints with all versions and operations [here in the Selling Partner API Docs](https://github.com/amzn/selling-partner-api-docs/tree/main/references). For a complete list of all currently by the client supported endpoints with versions and operations you can just call `sellingPartner.endpoints`. | ||
NOTE: As the original design of the client (< v0.4.0) didn't keep in mind the possibility of having more versions of the same endpoint (and as such multiple versions of the same operation), we had to replace original operation-only based calls to the API with a new concept that includes endpoints and version-specific operation calls. However this concept comes without any breaking changes, so you can still safely upgrade from any version below 0.4.0 to the latest version. | ||
#### Version specific operation implementations | ||
The client uses the first (in fact the oldest) endpoint version if no version is provided since new versions of some operations are not backward compatible. So in order to prevent breaking changes we can't enable latest endpoint versions by default. I.e. the two different implementations of the `getCatalogItem` operation (see [catalogItemsV0](https://github.com/amzn/selling-partner-api-docs/blob/main/references/catalog-items-api/catalogItemsV0.md#getcatalogitem) vs. [catalogItems_2020-12-01](https://github.com/amzn/selling-partner-api-docs/blob/main/references/catalog-items-api/catalogItems_2020-12-01.md#getcatalogitem)) expect different input parameters and return different results. | ||
The implementation of the `getCatalogItem` operation in the `v0` version expects an `asin` and a `MarketplaceId` as input: | ||
```javascript | ||
let res = await sellingPartner.callAPI({ | ||
operation:'getCatalogItem', | ||
query:{ | ||
MarketplaceId:'A1PA6795UKMFR9' | ||
}, | ||
path:{ | ||
asin:'B084DWG2VQ' | ||
}, | ||
options:{ | ||
version:'v0' | ||
} | ||
}); | ||
``` | ||
In contrast, the implementation of the `getCatalogItem` operation in the `2021-12-01` version expects an `asin`, a `marketplaceIds` array and an `includedData` array as input: | ||
```javascript | ||
let res = await sellingPartner.callAPI({ | ||
operation:'getCatalogItem', | ||
query:{ | ||
marketplaceIds:['A1PA6795UKMFR9'], | ||
includedData:['identifiers', 'images', 'productTypes', 'salesRanks', 'summaries', 'variations'] | ||
}, | ||
path:{ | ||
asin:'B084DWG2VQ' | ||
}, | ||
options:{ | ||
version:'2020-12-01' | ||
} | ||
}); | ||
``` | ||
Trying to call the new `2020-12-01` version without explicitly setting it would result in an `InvalidInput` error as the required `MarketplaceId` parameter is missing. | ||
#### Defining endpoints versions on class level | ||
There are different ways of specifying the version to use for endpoints and their corresponding operations. You can specify the `version` directly inside the `options` object of the `.callAPI()` function as seen in the examples above. But you can also enable a newer version for all operations of an endpoint by using the `endpoints_versions` setting in the constructor config object. | ||
I.e. you can tell the class instance to use the new `2020-12-01` version for the `catalogItems` endpoint and thus enabling it for all operations of the endpoint throughout the class instance like this: | ||
```javascript | ||
let sellingPartner = new SellingPartnerAPI({ | ||
region:'eu', | ||
refresh_token:'<REFRESH_TOKEN>', | ||
endpoints_versions:{ | ||
'catalogItems':'2020-12-01' | ||
} | ||
}); | ||
``` | ||
By doing so you can skip setting the `version` inside the `options` object each time when you are using `.callAPI()` with the new version of the `getCatalogItem` operation. | ||
#### Fallback | ||
If trying to call an operation that is not part of the endpoint's version you specified, the client will automatically try to find the operation in an earlier endpoint's version and use that implementation if `version_fallback` is set to `true` (which is the default). | ||
I.e. the `listCatalogCategories` operation is not part of the new `catalogItems` endpoint version. So if the new version was set as in the example code above, the following call would still work, because it will automatically fallback to the operation's implementation in version `v0`: | ||
```javascript | ||
let res = await sellingPartner.callAPI({ | ||
operation:'listCatalogCategories', | ||
query:{ | ||
MarketplaceId:'A1PA6795UKMFR9', | ||
ASIN:'B084DWG2VQ' | ||
} | ||
}); | ||
``` | ||
### Grantless operations | ||
Some operations don't require an explicit authorization by a seller ([list of grantless operations](https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#grantless-operations-1)). A grantless operation needs another access_token than other operations and as such a grantless token is NOT the access_token you can provide in the constructor config object. However if you set "auto_request_tokens" option to true the client should handle everything for you. | ||
Some operations don't require an explicit authorization by a seller, [see list of grantless operations](https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#grantless-operations-1). A grantless operation needs another access token than other operations and as such a grantless token is NOT the `access_token` you can provide in the constructor config object. However if the `auto_request_tokens` option is set to `true` the client should handle everything for you. | ||
If you do the token request manually you need to create a grantless token by calling "refreshAccessToken" with the scope of the corresponding endpoint. Currently there are only two different scopes: "sellingpartnerapi::migration" for authorization endpoint and "sellingpartnerapi::notifications" for notifications endpoint. | ||
If you do the token request manually you need to create a grantless token by calling `refreshAccessToken` with the scope of the corresponding endpoint. Currently there are only two different scopes: `sellingpartnerapi::migration` for authorization endpoint and `sellingpartnerapi::notifications` for notifications endpoint. | ||
If you don't need or have a refresh_token (i.e. because you want to retrieve an SP API authorization code of an already via MWS authorized seller) you may use the client with the "only_grantless_operations" option set to true which allows you to create an instance of the client without a refresh_token. | ||
If you don't need or have a refresh token (i.e. because you want to retrieve an SP API authorization code of an already via MWS authorized seller) you may use the client with the `only_grantless_operations` option set to `true` which allows you to create an instance of the client without a `refresh_token`. | ||
To sum up, please see the following example that will request an auth code for an authorized MWS seller account. | ||
First create a client instance that only allows to call grantless operations (no refresh_token included): | ||
First create a class instance that only allows to call grantless operations (no `refresh_token` included): | ||
```javascript | ||
@@ -244,10 +389,27 @@ let sellingPartner = new SellingPartnerAPI({ | ||
### Restore rates | ||
If you set the `auto_request_throttled` option in the class constructor config object to `true` (which is the default), the client will automatically retry the call if its throttled. It will either use the restore rate from the result header field `x-amzn-ratelimit-limit` if given [see Usage Plans and Rate Limits](https://github.com/amzn/selling-partner-api-docs/blob/main/guides/en-US/usage-plans-rate-limits/Usage-Plans-and-Rate-Limits.md) or otherwise use the default restore rate of the operation. If you set `auto_request_throttled` to `false` the client will throw a "QuoatExceeded" error when a request is throttled. | ||
IMPORTANT:If you are using the same operation with the same seller account across multiple class instances the restore rate logic might NOT work correct or, even worse, result in an infinite quota exceeded loop. So if you're planning to do that you should probalby set `auto_request_throttled` to `false`, catch the "QuotaExceeded" errors and handle the restore rate logic on your own. | ||
If you set the `auto_request_throttled` option in the class constructor config object to `true` (which is the default), the client will automatically retry the call if its throttled. It will either use the restore rate from the result header field `x-amzn-ratelimit-limit` if given ([see Usage Plans and Rate Limits](https://github.com/amzn/selling-partner-api-docs/blob/main/guides/en-US/usage-plans-rate-limits/Usage-Plans-and-Rate-Limits.md)) or otherwise use the default restore rate of the operation. If you set `auto_request_throttled` to `false` the client will throw a `QuotaExceeded` error when a request is throttled. | ||
NOTE: If you are using the same operation with the same seller account across multiple class instances the restore rate logic might NOT work correct or, even worse, result in an infinite quota exceeded loop. So if you're planning to do that you should probably set `auto_request_throttled` to `false`, catch the `QuotaExceeded` errors and handle the restore rate logic on your own. | ||
### Unsupported endpoints/versions/operations | ||
The newest client version should have full support for all endpoints, versions and operations on release, however it might lack support for very recently added new endpoints, versions or operations. If you need an endpoint/version/operation that is not yet supported you can still call it by using the `api_path` parameter. I.e. if the new `catalogItems` version `2020-12-01` would not be supported yet we could still use the new implementation of the `getCatalogItem` operation by using the `api_path` and `method` properties: | ||
```javascript | ||
let res = await sellingPartner.callAPI({ | ||
api_path:'/catalog/2020-12-01/items/B084DWG2VQ', | ||
method:'GET', | ||
query:{ | ||
marketplaceIds:['A1PA6795UKMFR9'], | ||
includedData:['identifiers', 'images', 'productTypes', 'salesRanks', 'summaries', 'variations'] | ||
} | ||
}); | ||
``` | ||
## Download, decrypt and unzip reports | ||
The **.download()** function takes the download details (url and encryption details) received from a "getReportDocument" operation as input, downloads the content, unzips it (if result is compressed), decrypts it and returns it. | ||
You may also include an options object to enable a json result or to additionally save the report to a file. | ||
Retrieve the download details from a "getReportDocument" operation: | ||
The `.download()` function takes the download details (url and encryption details) received from a `getReportDocument` operation as input, downloads the content, unzips it (if result is compressed), decrypts it and returns it. | ||
Retrieve the download details from a `getReportDocument` operation: | ||
```javascript | ||
@@ -261,3 +423,3 @@ let report_document = await sellingPartner.callAPI({ | ||
``` | ||
The structure of the returned report_document should look like this: | ||
The structure of the returned `report_document` should look like this: | ||
```javascript | ||
@@ -275,12 +437,15 @@ { | ||
``` | ||
Call the .download() function to receive the content of the report. The default without any config options will download, decrypt and unzip the content and return it without reformatting or saving it to the disk: | ||
Call the `.download()` function to receive the content of the report. The default without any config options will download, decrypt and unzip the content and return it without reformatting or saving it to the disk: | ||
```javascript | ||
let report = await sellingPartner.download(report_document); | ||
``` | ||
The options object has three optional properties: | ||
* `json`: Optional (true|false), whether or not the content should be transformed to json before returning it (from tab delimited flat-file or XML). Defaults to false. IMPORTANT: is ignored when content is compressed and unzip is set to false. | ||
* `unzip`: Optional (true|false), whether or not the content should be unzipped before returning it. Defaults to true. | ||
* `file`: Optional, absolute file path to save the report to. Defaults to not saving to disk. IMPORTANT: Even when saved to disk the report content is still returned. | ||
* `charset`: Optional, the charset to use for decoding the content. IMPORTANT: is ignored when content is compressed and unzip is set to false. | ||
You may also include an options object as a 2nd parameter to the `.download()` function, i.e. to enable a json result or to additionally save the report to a file. It supports four optional properties: | ||
| Name | Type | Default | Description | | ||
|:--|:--:|:--:|--| | ||
| **json**<br>*optional* | boolean | false | Whether or not the content should be transformed to json before returning it (from tab delimited flat-file or XML). | | ||
| **unzip**<br>*optional* | boolean | true | Whether or not the content should be unzipped before returning it. | | ||
| **file**<br>*optional* | string | - | The absolute file path to save the report to.<br>NOTE: Even when saved to disk the report content is still returned. | | ||
| **charset**<br>*optional* | string | utf8 | The charset to use for decoding the content.<br>NOTE: Is ignored when content is compressed and `unzip` is set to `false`.| | ||
The following call will download the report, transform it to json and save it to disk: | ||
@@ -290,7 +455,7 @@ ```javascript | ||
json:true, | ||
file:'<YOUR_ABSOLUTE_FILE_PATH>/report.json' | ||
file:'<ABSOLUTE_FILE_PATH>/report.json' | ||
}); | ||
``` | ||
Some reports may have an encoding other than UTF-8 and require special decoding with a different charset, i.e. the "GET_MERCHANT_LISTINGS_ALL_DATA" report is encoded as "cp1252". Proper decoding is possible with passing in the optional charset property: | ||
Some reports may have an encoding other than UTF-8 and require special decoding with a different charset, i.e. the `GET_MERCHANT_LISTINGS_ALL_DATA` report is encoded as `cp1252`. Proper decoding is possible with passing in the optional charset property: | ||
```javascript | ||
@@ -304,9 +469,13 @@ let report = await sellingPartner.download(report_document, { | ||
The **.upload()** function takes the feed upload details (url and encryption details) received from a "createFeedDocument" operation, the feed content and its content type to upload as input, encrypts the content and uploads it. | ||
Start by creating a feed object with the following properties: | ||
* `content`: Required if "file" is not provided, the content to upload as a string. | ||
* `file`: Required if "content" is not provided, the absolute file path of the document to upload. IMPORTANT: Is ignored if "content" is provided | ||
* `contentType`: Required, the contentType of the content to upload (should be one of "text/xml" or "text/tab-separated-values" and the charset of the content, i.e. "text/xml; charset=utf-8"). | ||
The `.upload()` function takes the feed upload details (url and encryption details) received from a `createFeedDocument` operation, the feed content and its content type to upload as input, encrypts the content and uploads it. | ||
This will create an inventory feed ("POST_INVENTORY_AVAILABILITY_DATA") that will update the quantity of a given SKU to 10: | ||
Start by creating a feed object with a contentType and the content either as a string or a file path to a document: | ||
| Name | Type | Default | Description | | ||
|:--|:--:|:--:|--| | ||
| **content**<br>*optional* | string | - | The content to upload as a string.<br>Required if `file` is not provided. | | ||
| **file**<br>*optional* | string | - | The absolute file path to the feed content document to upload.<br>Required if `content` is not provided. | | ||
| **contentType**<br>*required* | string | - | The contentType of the content to upload.<br>Should be one of `text/xml` or `text/tab-separated-values` and the charset of the content, i.e. `text/xml; charset=utf-8`. | | ||
This will create an inventory feed (`POST_INVENTORY_AVAILABILITY_DATA`) that will update the quantity of a given SKU to 10: | ||
```javascript | ||
@@ -332,3 +501,3 @@ let feed = { | ||
``` | ||
Before you can upload the feed you need to retrieve the feed upload details from a "createFeedDocument" operation: | ||
Before you can upload the feed you need to retrieve the feed upload details from a `createFeedDocument` operation: | ||
```javascript | ||
@@ -342,7 +511,7 @@ let feed_upload_details = await sellingPartner.callAPI({ | ||
``` | ||
Call the .upload() function to encrypt and upload the content of the feed: | ||
Call the `.upload()` function to encrypt and upload the content of the feed: | ||
```javascript | ||
let res = await sellingPartner.upload(feed_upload_details, feed); | ||
``` | ||
After uploading the feed you have to trigger the processing of the feed by calling the "createFeed" operation with the necessary params (marketplaceIds, feedType and inputFeedDocumentId): | ||
After uploading the feed you have to trigger the processing of the feed by calling the `createFeed` operation with the necessary params (`marketplaceIds`, `feedType` and `inputFeedDocumentId`): | ||
```javascript | ||
@@ -358,7 +527,12 @@ let feed_creation_infos = await sellingPartner.callAPI({ | ||
``` | ||
IMPORTANT: Although uploading and creating the feed was successful it doesn't mean that the processing of the feed itself was also successful. You can check the result of the feed once it has been processed by downloading the processing result with the **.download()** function quite similar as how to download reports. Use the feedId returned by the "createFeed" operation and call the "getFeed" operation, which will include a resultFeedDocumentId if feed processing is already done. The resultFeedDocumentId can be used with a "getFeedDocument" operation that will return the feed download details needed for the feed result download. | ||
NOTE: Although uploading and creating the feed was successful it doesn't mean that the processing of the feed itself was also successful. You can check the result of the feed once it has been processed by downloading the processing result with the `.download()` function quite similar as how to download reports. Use the `feedId` returned by the `createFeed` operation and call the `getFeed` operation, which will include a `resultFeedDocumentId` if feed processing is already done. The `resultFeedDocumentId` can be used with a `getFeedDocument` operation that will return the feed download details needed for the feed result download. | ||
## TypeScript Support | ||
All TypeScript related information can be found in [lib/typings](https://github.com/amz-tools/amazon-sp-api/tree/main/lib/typings). Currently types are not yet defined for all operations and/or params, so feel free to add new types following the readme. You are also welcome to create a pull request. | ||
## Sandbox mode | ||
You can easily enable sandbox mode by setting the use_sandbox in the constructor config options to true. When using the sandbox you have to make sure to use the correct request parameters for the operation you want to test. You can find these inside the [api models definitions](https://github.com/amzn/selling-partner-api-models/tree/main/models) by searching the corresponding json file for "x-amazon-spds-sandbox-behaviors". | ||
For example, this will test the "listCatalogItems" operation in sandbox mode: | ||
You can easily enable sandbox mode by setting `use_sandbox` in the constructor config options to `true`. When using the sandbox you have to make sure to use the correct request parameters for the operation you want to test. You can find these inside the [api models definitions](https://github.com/amzn/selling-partner-api-models/tree/main/models) by searching the corresponding json file for `x-amazon-spds-sandbox-behaviors`. | ||
For example, this will test the `listCatalogItems` operation in sandbox mode: | ||
```javascript | ||
@@ -375,9 +549,11 @@ let res = await sellingPartner.callAPI({ | ||
## Known Issues | ||
Since the Selling Partner API is still pretty new, not all API paths and endpoints have been tested for full functionality. If you find any calls not working please open up a new issue. | ||
Some operations don't seem to be heavy-use resistant yet, i.e. the "listCatalogItems" operation throws an "InteralFailure" error (statusCode 500) if used repetitive (although restore rate of operation is respected). | ||
Some operations don't seem to be heavy-use resistant yet, i.e. the `listCatalogItems` operation throws an `InteralFailure` error (statusCode 500) if used repetitive (although restore rate of operation is respected). | ||
Some endpoints might have issues with special charsets like UTF-8. I.e. the finances operations return invalid UTF-8 encodings for all data prior to May 2020 resulting in JSON parse errors. | ||
Some endpoints might have issues with special charsets like UTF-8. I.e. the `finances` operations return invalid UTF-8 encodings for all data prior to May 2020 resulting in JSON parse errors. | ||
## Seller Support | ||
If you're a european seller we might be able to support you with everything else that can't be done with the API, i.e. review management, product sourcing or sales and revenue estimations for products. Feel free to visit us at [amz.tools](https://amz.tools). | ||
If you are selling on the european market we might be able to support you with everything else that can't be done with the API, i.e. review management, product sourcing or sales and revenue estimations for products. Feel free to visit us at [https://amz.tools](https://amz.tools). |
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
172572
77
4617
539
5