Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

amazon-sp-api

Package Overview
Dependencies
Maintainers
1
Versions
61
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

amazon-sp-api - npm Package Compare versions

Comparing version 0.2.0 to 0.2.1

6

lib/request.js

@@ -19,5 +19,7 @@ const https = require('https');

let req = https.request(options, (res) => {
let chunks = [];
let body = '';
res.on('data', (chunk) => {
body += chunk;
chunks.push(chunk);
});

@@ -27,3 +29,5 @@ res.on('end', () => {

body:body,
statusCode:res.statusCode
chunks:chunks,
statusCode:res.statusCode,
headers:res.headers
});

@@ -30,0 +34,0 @@ });

@@ -7,2 +7,6 @@ const CustomError = require('./CustomError');

const operations = require('./operations');
const crypto = require('crypto');
const csv = require('csvtojson');
const fs = require('fs/promises');
const zlib = require('zlib');

@@ -69,2 +73,13 @@ // Provide credentials as environment variables OR create a path and file ~/.amzspapi/credentials (located in your user folder)

async _unzip(buffer){
return new Promise((resolve, reject) => {
zlib.gunzip(buffer, (err, unzipped_buffer) => {
if (err){
reject(err);
}
resolve(unzipped_buffer);
});
});
}
async refreshAccessToken(){

@@ -211,4 +226,99 @@ let res = await request({

// Will be a tab-delimited flat file or an xml document
// Options object:
// * json: 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: true/false, whether or not the content should be unzipped before returning it. Defaults to true.
// * file: 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.
async download(details, options = {}){
options = Object.assign({
unzip:true
}, options);
if (!details || !details.encryptionDetails || !details.url){
throw new CustomError({
code:'DOWNLOAD_INFORMATION_MISSING',
message:'Please provide encryptionDetails and url'
});
}
// Docs state that no other encryption standards should be possible, but check if its correct anyway
if (details.encryptionDetails.standard !== 'AES'){
throw new CustomError({
code:'UNKNOWN_ENCRYPTION_STANDARD',
message:'Cannot decrypt ' + details.encryptionDetails.standard + ', expecting AES'
});
}
let compression = details.compressionAlgorithm;
// Docs state that no other zip standards should be possible, but check if its correct anyway
if (compression && compression !== 'GZIP'){
throw new CustomError({
code:'UNKNOWN_ZIP_STANDARD',
message:'Cannot unzip ' + compression + ', expecting GZIP'
});
}
let res = await request({
url:details.url
});
if (res.statusCode !== 200){
let json_res;
try {
json_res = xml_parser.parse(res.body);
} catch(e){
throw new CustomError({
code:'DOWNLOAD_ERROR',
message:res.body
});
}
if (json_res && json_res.Error){
throw new CustomError({
code:json_res.Error.Code,
message:json_res.Error.Message
});
} else {
throw new CustomError({
code:'DOWNLOAD_ERROR',
message:json_res
});
}
} else {
// Decrypt buffer
let encrypted_buffer = Buffer.concat(res.chunks);
let decipher = crypto.createDecipheriv(
'aes-256-cbc',
Buffer.from(details.encryptionDetails.key, 'base64'),
Buffer.from(details.encryptionDetails.initializationVector, 'base64')
);
let decrypted_buffer = Buffer.concat([decipher.update(encrypted_buffer), decipher.final()]);
// Decompress if content is compressed and unzip option is true
if (compression && options.unzip){
decrypted_buffer = await this._unzip(decrypted_buffer);
}
let decrypted = (!compression || options.unzip) ? decrypted_buffer.toString() : decrypted_buffer;
if ((options.unzip || !compression) && options.json){
// Transform content to json --> take content type from which to transform to json from result header
try {
if (res.headers['content-type'].includes('xml')){
decrypted = xml_parser.parse(decrypted);
} else if (res.headers['content-type'].includes('plain')){
decrypted = await csv({
delimiter:'\t'
}).fromString(decrypted);
}
} catch(e){
throw new CustomError({
code:'PARSE_ERROR',
message:'Could not parse result to JSON.',
details:decrypted
});
}
}
if (options.file){
options.json ? await fs.writeFile(options.file, JSON.stringify(decrypted)) : await fs.writeFile(options.file, decrypted);
}
return decrypted;
}
}
};
module.exports = SellingPartner;

3

package.json
{
"name": "amazon-sp-api",
"version": "0.2.0",
"version": "0.2.1",
"description": "Amazon Selling Partner API client",

@@ -24,2 +24,3 @@ "main": "index.js",

"crypto-js": "^4.0.0",
"csvtojson": "^2.0.10",
"fast-xml-parser": "^3.17.4",

@@ -26,0 +27,0 @@ "qs": "^6.9.4"

@@ -71,3 +71,3 @@ # amazon-sp-api (client for the Amazon Selling Partner API)

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
auto_request_throttled:true // Optional, whether or not the client should automatically retry a request when throttled. Default is true
}

@@ -107,3 +107,3 @@ }

The .callAPI() function takes an object as input:
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)

@@ -114,3 +114,3 @@ * path: The input paramaters added to the path of the operation

## Examples
#### Examples
```javascript

@@ -147,3 +147,46 @@ let res = await sellingPartner.callAPI({

### 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 with a "getReportDocument" operation:
```javascript
let report_document = await sellingPartner.callAPI({
operation:'getReportDocument',
path:{
reportDocumentId:'<REPORT_DOCUMENT_ID>' // retrieve the reportDocumentId from a "getReport" operation (when processingStatus of report is "DONE")
}
});
```
The structure of the returned report_document should look like this:
```javascript
{
reportDocumentId:'<REPORT_DOCUMENT_ID>',
compressionAlgorithm:'GZIP', // Only included if report is compressed
encryptionDetails:{
standard:'AES',
initializationVector:'<INITIALIZATION_VECTOR>',
key:'<KEY>'
},
url: '<REPORT_DOWNLOAD_URL>' // Expires after 5 minutes!
}
```
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 parameters:
* json: 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: true/false, whether or not the content should be unzipped before returning it. Defaults to true.
* file: 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.
The following call will download the report, transform it to json and save it to disk:
```javascript
let report = await sellingPartner.download(report_document, {
json:true,
file:'<YOUR_ABSOLUTE_FILE_PATH>/report.json'
});
```
## 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.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc