Giter Site home page Giter Site logo

ericblade / mws-advanced Goto Github PK

View Code? Open in Web Editor NEW
41.0 10.0 12.0 4.59 MB

Javascript (node) Amazon Merchant Web Services (MWS) code with mws-simple as it's underpinnings

License: Apache License 2.0

JavaScript 88.69% Batchfile 0.07% TypeScript 11.23%
mws amazon-api javascript market promise amazon-mws node node-js nodejs hacktoberfest

mws-advanced's Introduction

ARCHIVED - DEPRECATION ALERT

Over the last year, Amazon has shutdown most of the MWS API, and it has not been available to new users for quite some time. The new Amazon SP API is a replacement for it. You can find suitable libraries for using SP API in several places on github.

As the MWS API is effectively no longer available, this repository has now been deprecated, and moved to archive status. There will be no more updates of any kind to this code. If you depend on it still, for the last few months of the last few sections of MWS that remain, go ahead and fork it.

Have a great day, and BE AWESOME.

Thank you for all your support over the years.

-Eric

Build Status codebeat badge Greenkeeper badge Documentation badge Coverage Status

mws-advanced -- A modern Amazon Merchant Web Services API Interface for Javascript

Join the chat at https://gitter.im/mws-advanced/Lobby

What does it do?

mws-advanced provides a modern, fast, and hopefully sensible APIs to connect your Javascript application (node or browser) to the Amazon Merchant Web Services API.

Nice-to-have features:

  • Automatic throttle-retry mechanism
  • Automatic parameter validation
  • Transform Javascript Arrays into MWS List format
  • Transform Date objects into ISO-8601 date stamps

mws-advanced uses the straight-forward and very basic functionality provided by mws-simple to provide a much more advanced library for accessing MWS, than what has previously been available in the past.

Discussions

Hey, everyone! :-) This is by far my most popular repo on github at the moment, based on the number of clones and amount of traffic I'm seeing in the stats. If you think you might have a good use for this library, drop a line at Discussion :-)

Documentation / Quick-Start (I've heard enough, let's write some code)

Automatically generated documentation is available at Documentation.

Why a new mws library?

Although there are a whole lot of MWS libraries out there on the npm repository, few are actively maintained, and even fewer are written using modern Javascript. Some use Promises, but none are written to take advantage of the newest features of the language. Still fewer have documentation that doesn't just assume you are intimately familiar with the Amazon MWS API already.

I am writing this to change that. I am writing a project that needs access to the MWS API, and to do that, I needed code that interfaces well with modern code. I need code that is documented well, is intuitive to use, and doesn't leave my primary application stuck having to figure out all the vagaries of an XML response transformed into a JSON result. Or worse.

Most of all, though, this library is here to give you the pieces that I am using to build my internal project with. Enjoy! :-)

Requirements

This requires node.js v9.0+ to run. If that's not your environment, you can setup Babel or some other transpiler to make it work in older versions. I'd be happy to accept pulls for this, or any other reason, but it is not something I am at all concerned with. Let's move the ecosystem forward!

Development

This library is under heavy development. Pull requests from all are welcome. Since I am writing a system that makes use of this library, my primary priority is to make it work for my specific use- cases. Your use cases may not match mine, so let's work together to create a fantastic library for all of us :-)

mws-advanced's People

Contributors

aflansburg avatar dependabot[bot] avatar ericblade avatar greenkeeper[bot] avatar imgbotapp avatar pwrnrd avatar semantic-release-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mws-advanced's Issues

validateAndTransform should trim whitespace on both sides of string parameters

Otherwise you have to hit the server just to get back a "Extraneous Whitespace" error.

<?xml version="1.0"?>\n<ErrorResponse xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01"><Error><Type>Sender</Type><Code>InvalidRequest</Code><Message>parameter ASINList.ASIN.1 failed a validation check: Extraneous whitespace for input value: "142210284X "</Message><Detail/></Error><RequestID>8a0f16d9-8a95-4935-be96-2a8f409e4685</RequestID></ErrorResponse>

Version 10 of node.js has been released

Version 10 of Node.js (code name Dubnium) has been released! 🎊

To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:

  • Added the new Node.js version to your .travis.yml

If you’re interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.

More information on this issue

Greenkeeper has checked the engines key in any package.json file, the .nvmrc file, and the .travis.yml file, if present.

  • engines was only updated if it defined a single version, not a range.
  • .nvmrc was updated to Node.js 10
  • .travis.yml was only changed if there was a root-level node_js that didn’t already include Node.js 10, such as node or lts/*. In this case, the new version was appended to the list. We didn’t touch job or matrix configurations because these tend to be quite specific and complex, and it’s difficult to infer what the intentions were.

For many simpler .travis.yml configurations, this PR should suffice as-is, but depending on what you’re doing it may require additional work or may not be applicable at all. We’re also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, I’m a humble robot and won’t feel rejected 🤖


FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Multiple instances of MWSAdvanced overwrite one another

I'm trying to fetch a report in multiple regions. I do this by creating multiple MWS objects. However, the MWS objects seem to overwrite eachother when I create them using an asynchronous function.

Below I wrote some code to give you an example of what I try to do.

const MWS = require('mws-advanced).MWSAdvanced;

function getKeys(region) {
    switch (region) {
        case "JP":
            return {
               //some keys for JP
            }
        default:
            return {
                 //some keys for US
            }
    }
}


async function createMWSConnection ({accessKeyId, secretAccessKey, merchantId}) {
    const mws = new MWS({
        accessKeyId,
        secretAccessKey,
        merchantId,
    });

  // some async stuff here..

  return mws;
};

const requestedReports = ["JP", "NA"].map(regionCode => {
    const keys = getKeys(regionCode);
    const mws = await createMWSConnection(keys);
    return mws.requestReport( .... SOME OPTIONS HERE .... );
}    

Does this code make sense? I think the problem could be here:

function requestPromise(requestData, opt = {}) {
	return new Promise((resolve, reject) => {
		// eslint-disable-line prefer-arrow-callback
		const mwsInterface = this && this.mws ? this.mws : mws;
                .....
                .....
      }
}

If I console.log the "this" object, then "this" is undefined. So 'mwsInterface' is set equal to 'mws'. I think that by running my code, the global mws object get overwritten by the second request. Hence, when I try to fetch data from one marketplace I try to do that using the mws object of the second marketplace. What do you think? What else could have caused the behaviour that I'm describing? Is this a bug or is this my own codes wrong doing?

should emit status updates for reports?

I'm not sure if this goes against any established patterns or not, but according to my TODO right above "requestAndDownloadReport()" I was considering the idea of making the MWS object also an Emitter, so that one could easily pick up status updates from functions that may take a very long time to complete asynchronously.

mws-simple does not work with /Products/GetLowestPricedOffersForASIN

As per this thread: https://stackoverflow.com/questions/36293752/getlowestpricedoffersforsku-failed-processing-arguments

I was just attempting to implement this call, and sure enough, I get the exact same problem, an error 400, followed by

Failed processing arguments of org.jboss.resteasy.spi.metadata.ResourceMethod@1f3d6bd9

There are a few things needed to be done here:

1- Trapping the error 400 -- I had to go all the way back to mws-simple, just to get the dump of the data. So, no data other than a blank Array is coming back to mws-advanced. I'm not sure if ultimately, this means forking and patching mws-simple, which hasn't been updated in a year, monkey patching it, or just absorbing it so that we can add proper functionality to it for the above call, per th e stack overflow answer. In any case, we need to capture the error, and treat it AS an error. Checking response 'body.statusCode < 200 || body.statusCode > 299' should give us some valid reasonable error checking, right around line 96 or so of mws-simple. Then we should also treat that as an error going back to line 99-ish in request.post() . . at which point then the clients will know that something has seriously broken.

2- actually writing a new method to handle this. We need to review the above link to Stack Overflow, and then determine if that is a thing that we can add to every call, and it will make them all "Just Work"(tm), or if this call method only works with the functions that the existing one does not (the one referenced here, and the additional one(s) referenced in the Stack thread.

3- Before we fix this, we should make sure that we have a way of replicating it, so that we can write a test that checks that everyone handles exceptions like they should. Like, by calling this specific endpoint in raw mode, and checking it's returns, etc. If we can generate a 400 error from Amazon's end, then we should be able to write a test that can show it, so that maybe they can fix it, or something like that.

Proposal: parseEndpoint without logging

Personally I like to catch parseEndpoint myself without error logging. My implementation:

const parseEndpoint = (name, callOptions, opt) => async (parser) => {
    return parser(await callEndpoint(name, callOptions, opt));
};

The reason for this is that I use mws.getMarketplaces() to validate my API keys. If the call to getMarketplaces is unsuccesfull I get the warnings message **** caught parseEndpoint error. However, in the case where the API keys are invalid, the parseEndpoint error is not an error but the expected result. The console.warn call pollutes the console in that case.

misc parameter validation enhancements

Some of these might be pretty tricky to pull off given the current architecture, but here goes:

ListOrders, for example, requires one of either LastUpdatedAfter or CreatedAfter. If BOTH are specified, then it is an error. So, need to allow "one of" in validation. Perhaps 'required' should be some sort of data structure outside of the individual parameters, that allows to specify conditional requirements, such as this OR that. Also could handle a list of parameters that are incompatible with each other to throw on.

ListOrders also has some complementary xs:dateTime parameters -- CreatedBefore must be a Date that is newer than CreatedAfter if both are supplied. LastUpdatedBefore must be a Date that is newer than LastUpdatedAfter if both are supplied.

Support a "MarketplaceType" validation? GetMatchingProductForId refers to it in the MarketplaceId parameter. See https://docs.developer.amazonservices.com/en_UK/products/Products_Datatypes.html#MarketplaceType . Amazon provides a complete list of valid MarketplaceIds, we could probably validate against that list.. implementing MarketplaceType as an alias for xs:string with values: [ 'array of marketplaceids' ]

Whenever we get to implementing return parameter validation, we'll need a way to handle xs:boolean .. either that, or we implement return parameter validation using the .XSD schema files that Amazon links to, in which case we can completely undo our custom home rolled version of it.

listOrderItems returns object instead of an array

The API call to listOrderItems returns an object if there are multiple items in an order.

Output:

{
   "0" : {
       OrderItem_ 1
    },
    "1": {
        OrderItem_2 
    }
    isGift: "someval"
    quantityOrdered: "someval"
    quantityShipped: "someval"
    productInfo: "someval"
}

Where OrderItem_1 and OrderItem_2 are objects in line with the MWS documentation regarding OrderItem: https://docs.developer.amazonservices.com/en_UK/orders-2013-09-01/Orders_Datatypes.html#OrderItem .

Expected:

[ {OrderItem_1}, {OrderItem_2}]

I did some digging and I found that the input to the function parseOrderItems in orderItems.js does not meet the expected input. The argument orderItemsList of this function retrieves the following:

const parseOrderItems = orderItemsList => {
	const { NextToken: nextToken, AmazonOrderId: orderId } = orderItemsList;
	console.log(JSON.stringify(orderItemsList, null, 4));
        ....
        ....

The above outputs:

{
    "OrderItems": {
        "OrderItem": [
            {OrderItem_1},
            {OrderItem_2}
         ]
    }
}

Perhaps this should be/expected:

{
    "OrderItems": [{
        "OrderItem": OrderItem_1,
        "OrderItem": OrderItem_2
    }]
}

OR: 

{
    "OrderItems": [
        OrderItem_1,
        OrderItem_2
    ]
}


I think I found where the error arises, but I don't know how to fix this... Where should I dig next in order to solve this issue? How could this issue be solved?

Discussion: What are you wanting to do with mws ?

Hi all! Just noticed that there's been a few clones of this repo, and thought I'd ask what other people are wanting to do with this?

Personally, I'm a part time Amazon merchant, and I have wanted to build a system that can locally store a list of all of my products, and keep tabs on orders and shipments automatically, without having to go and hit Seller Central .. and something that will help make sense out of the huge quantity of reports that are available.

Lately, when I've had time to work on this, I've been playing with the report downloading functions, as that seems to be where the bulk of everything is. The real time APIs are interesting, but don't seem to be geared towards the sort of information that I'm looking to get in touch with.

A far out there goal, is that I'd like to build something that can replace the Seller Central FBA shipment workflow, and play with ways to make that much easier for me.

listOrderItems TypeError

I'm trying to load the products that belogn to a certain order using listOrderItems. For most orders the function listOrderItems seems to work. However, in some cases, I get the following error:

TypeError: Cannot read property  'numberOfItems' of undefined
     at transformIntsAndBools (parsers/orderItems.js:40:9)

The function:


function transformIntsAndBools(item) {
    const {
        quantityOrdered,
        quantityShipped,
        isGift,
        productInfo,
        ...restItem
    } = item;
    const {
        numberOfItems,
        ...restProductInfo
    } = productInfo;

    return {
        ...restItem,
        isGift: stringToBool(isGift),
        quantityOrdered: stringToInt(quantityOrdered),
        quantityShipped: stringToInt(quantityShipped),
        productInfo: {
            ...restProductInfo,
            numberOfItems: stringToInt(numberOfItems),
        },
    };
}

How could I fix this?

travis builds failing because testing is taking too long

... there's some info on the failed build logs about how to deal with it taking longer than 10 minutes to do something... but i suspect it might be best to just remove the reports api testing from travis, if reports are going to be taking this huge length of time to come out.

need to find a new doc generator

esdoc had decent looking output, but is very opinionated -- it required a 3rd party plugin to work with require(), which is kind of ridiculous, and it treated everything as if it was an ES module. After the recent structural changes to this library, it no longer fits our needs at all -- and I had to make code changes to even get the files to parse. esdoc does not receive updates in a timely fashion. Therefore, I conclude, that either we maintain our own esdoc-plugin to deal with things, or we find a better generator.

Seems there are a pretty fair number of them out there. jsdoc has reasonably styled output, but doesn't seem to understand very well that the primary interface to this library is through the MwsAdvanced class. I'm not sure if there's a possible way to get it to give me the MwsAdvanced docs in one set, and the rest of the docs (internal stuff) as a second set -- then we could have "public" and "internal/private" docs, one set for users, one set for people who want to hack on the lib.

There might be other generators out there that might more naturally understand this.

add ability to "get all" of every type of function that provides a *ByNextToken equivalent

We should add a parameter to all the base functions that also have *ByNextToken versions, that will allow the MWS lib to go and gather up ALL of the data before accepting the promise.

So, you could potentially call something like

    callEndpoint('ListFinancialEvents', { GetAll: true })

and if you receive a NextToken with the initial result, then automatically call ListFinancialEventsByNextToken, and add that data to the original result. Re-run until there are no more NextTokens returned.

This is essentially what getReportListAll() does already.

getMatchingProductForId weirdness (strings? turning into objects?!)

"materialType" field in some items is turning into:

                      "materialType": [
                            {
                                "0": "M",
                                "1": "e",
                                "2": "t",
                                "3": "a",
                                "4": "l"
                            },
                            {
                                "0": "P",
                                "1": "l",
                                "2": "a",
                                "3": "s",
                                "4": "t",
                                "5": "i",
                                "6": "c"
                            }
                        ],

during the call to transformObjectKeys in lib/get-matching-products

This may affect other fields, but I haven't seen one yet.

To demonstrate, call as follows, and the messed up result will be about halfway down the results:

        const results = await mws.getMatchingProductForId({
            MarketplaceId: 'ATVPDKIKX0DER',
            IdType: 'UPC',
            IdList: ['746775298494'],
        });

getMatchingProductForId returns extremely long floats that look wrong in packageDimensions and itemDimensions

Sometimes, getMatchingProductForId returns itemDimensions in extremely long floats-as-strings.

It's unclear if this is coming from Amazon directly, or if it's something that is occurring as the data gets handed between amazon, mws-simple, and mws-advanced. It is clear now, as per #54 (comment) that the actual Amazon MWS output is bad.

        const results = await mws.getMatchingProductForId({
            MarketplaceId: 'ATVPDKIKX0DER',
            IdType: 'ASIN',
            IdList: ['B0026HM31E' ],
        });

occasionally exhibits this. Sometimes I get ...attributeSets.itemAttributes.packageDimensions as

{ height: { value: "0.69999999999999...", ... }, ... }

sometimes i get it as 0.70. So, they are badly rounded strings.

Ultimately: I don't know who's screwing these up. There's no parseFloat() usage in either mws-advanced or mws-simple. It could be occurring in xmlParser inside mws-simple, or it could be occurring before it even gets to us. Since it's not happening 100% of the time, I'm wondering if it's at the MWS server side.

Is it a valid solution, if it's occurring server side, to String(parseFloat(height.value).toFixed(2)) at a layer in between? That could break legit data, potentially. I feel like if I bring it up to MWS, i'll never really get a resolution as to if it's their end, or if it's fixed or not. :-S

warning of breaking change coming: getMatchingProductForId

Although it may have been obvious that the wrapper getMatchingProductForId was not completed, I am fleshing this function out quite a bit, as I write this.

the new return format will have all it's keys camelCased (and I may choose to go back through other things that are done, and do this, because it's far more javascript-y), and returns everything without a "ns2:" prefix on it's keys. Objects that once contained a "_" and a "$" field are simplified:

{ 
    $: {
        "xml:Lang": "en-US"
    }
}

becomes

{ "xml:Lang": "en-US" }

and

{
    _: "1.20",
    "$": {
        units: "inches"
    }
}

becomes

{
    value: "1.20",
    units: "inches"
}

there may be other changes.

Discussion/Q&A: JS version, Node version, -harmony

I must admit, I'm a bit new to working on a project such as this with other people - so I'm equally as excited, but I did have a couple of questions. As far as JS (ECMAScript) version - I'm assuming ES6. I'm currently running Node 8.9.0 and haven't had issues, but I am completely clueless regarding the '-harmony' switch and finding info on it has been difficult and what I have found was slightly confusing.

Also - I ditched the README edit PR since you mentioned some overall changes needed to be made there anyways - I meant to include the Promise post-action (.then, .catch) when I originally suggested edits, but forgot and wasn't sure how active the project was!

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on all branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please delete the greenkeeper/initial branch in this repository, and then remove and re-add this repository to the Greenkeeper App’s white list on Github. You'll find this list on your repo or organization’s settings page, under Installed GitHub Apps.

Discussion: Dynamic feed generation

With Feed support now functioning at the most basic level, this leaves a lot of possibilities for dynamic feed generation.

What I'm toying with right now, is creating a class that matches a feed type -- such as ListingLoader, that contains class fields for each of the parameters in the feed, and has a static method for getting the header for the feed. (this is for a flat-file feed, by the way, I haven't even begun to investigate XML feeds)

So, what you could do is something like

    let newListings = [];
    const x = new ListingLoader();
    ... code to load data into a ListingLoader, such as from a database, or from user input ...
    const feedContent = `${x.getFeedHeader()}${x.getFeedData()}`;
    mws.callEndpoint('SubmitFeed', { ...params, feedContent });

it seems easy and simple, but I suspect there may be better ways of doing it. This is just my first gut thought.

Perhaps the class should store an array of objects (or of other classes) that stores the required data, and has a method to retrieve the raw data objects, or the feeddata for submission. Or even has a method to actually submit the feed once it's been loaded full of data. Sounds like a nice improvement to what I'm toying with right now.

Datatype: requestReports param MarketplaceIdList

The MWS API allows to request a report for a specific marketplace using "MarketplaceIdList". According to the MWS API documentation (https://docs.developer.amazonservices.com/en_ES/reports/Reports_RequestReport.html) the type should be: List of Type: xs:string.

In mws-advanced the variable MarketplaceIdList is specified to be of type: xs:string. How should MarketplaceIDList be specified?

I tried all of the following, but none of these specifications seem to work...

MarketplaceIdList: 'ATVPDKIKX0DER'
MarketplaceIdList: '[ATVPDKIKX0DER]'
MarketplaceIdList: 'MarketplaceIdList.Id.1=ATVPDKIKX0DER'
MarketplaceIdList: '[MarketplaceIdList.Id.1=ATVPDKIKX0DER]' 

Feature Request: allow getOrder to take more than 50 order IDs

Current behaviour:
When passing an array of more than 50 elements to mws.getOrder() the following Error occurs:

ValidationError: List parameter AmazonOrderId can only take up to 50 items

Preferred behaviour
Allow mws.getOrder() to retrieve an array of more than 50 elements, then cut the array into chunks of less then 50 elements and make a getOrder request. It would be nice if, when making a lot of requests, these requests also automatically deal with throtteling (perhaps that's already the case given #98 .

Disadvantage
This is a clear deviation from the behaviour described by the MWS API.

Advantage
Allow users to work with getOrder() as if there were no limits.

Alternative
Perhaps we can create a another function (e.g. getMultipleOrders()) to meet the preferred behaviour.

Error with this binding

I'm trying to do the following:

export default async function () {
    mws.init({
        accessKeyId: '',
        secretAccessKey: '',
        merchantId: ''
    });
    const startDate = new Date('2018-05-24');
    const query = {       
        CreatedAfter: startDate,
        MarketplaceId: ["ATVPDKIKX0DER"],
    }
    let orders = await mws.listOrders(query);
    return orders;
}

This code throws the following error: TypeError: Cannot read property 'mws' of undefined .

The error is related to the following function.

function requestPromise(requestData, opt = {}) {
    return new Promise((function reqPromise(resolve, reject) { // eslint-disable-line prefer-arrow-callback
        const mwsInterface = this.mws || mws;
        mwsInterface.request(requestData, (err, result) => {
            if (err) {
                reject(err);
            } else {
                resolve(opt.noFlatten ? result : flattenResult(result));
            }
        });
    }).bind(this));
}

By running my code, the "this"-object is undefined.

I'm not sure whether this is a bug or whether I'm doing something wrong...

callEndpoint saveRaw and saveParsed options are never hit if the server errors

I would sort of expect that they would probably both hit, saving the error data to the file. There's some inconsistency here, particularly when dealing with parseEndpoint vs callEndpoint -- tests from getMatchingProductForId expose that parseEndpoint is not currently as robust at dealing with errors as it should? be? and that there is some inconsistency in how errors are dealt with -- so far, I've only dealt with errors in functions where I've actually received them, rather than make an attempt to deal with the Known Unknowns and the Unknown Unknowns. :-D

The inconsistency is that errors that bypass saveRaw and saveParsed would also not be parseable by any of the data parsers that i'm currently creating.

SO, we need to take the mostly re-architected getMatchingProductForId, which has easily repeatable error conditions, and make sure that we clean up the error handling, so that we know exactly what to expect whenever an API call throws an error, whether we are using callEndpoint or parseEndpoint.

multi-user support could probably use separate objects

When using this on a client that can accept multiple users, with different MWS credentials, you should be able to get a new mws-advanced() object to be able to do that with. This wasn't an initial design goal for me, but now I need it to get worked in.

Discussion: documentation

Although I originally set out to try really hard to keep the documentation up to date, and useful, inspiration and coding outstripped the pace of documentation updating. Also, I'm really not at all happy with the documentation that I've found in almost every project out there, so keeping up on the documentation has absolutely been a chore, rather than enjoyable.

That said, I discovered a project that I think has really great documentation: http://docs.sequelizejs.com/

I'm switching to using sequelize for my main project, that incorporates mws-advanced, and other than some nitpicks as to not being able to quickly locate certain pieces in it, Sequelize's documentation seems to be quite a bit better than most everything else out there. It really has a whole lot of what I want in a documentation for anything -- quick information for those with the ability to dive right in, great examples, pretty decent in depth info, and it's really easy to read through. In fact, I enjoyed reading the documentation for it. My only complaint about it is that there's a little bit less of the "what is this useful for?" in some places, and I tried to search for some ability that seemed completely obvious to me, but took some search-fu to figure out how to do it. (namely, how to create a database index on a model, that used the relationships to other models)

I'm looking into how they build their documentation right now. Looks like they are using something to build html from .md files.

Feature Request: ManageReportSchedule

TODO: document using authToken

For those who want to use this as a client for 3rd-party account operations, you'll want to use the authToken parameter that was just added to init(). Need to document how to use that correctly.

Handling rate throttling

I've baked in throttling restore rate to the metadata that we keep about the functions, so it shouldn't be extremely difficult to add throttle handling to the package here. What we probably do need to do is grab an example of a Throttling error, so that we can detect when we're being throttled, and then back off and retry based on the meta-data throttle restore.

seems MarketplaceId isn't getting auto populated? is that new?

Having a bit of trouble getting back into this after a few months away. I don't recall (nor do any of my samples include) having to provide MarketplaceId before to live data APIs such as listOrders, and I'm not sure if it's now complaining about it because of my previous change to monkey-patch the mws-simple api, or if it's something on my MWS account that has changed.

create a mock mws server code to test mws-advanced (and mws-simple) without live data

We should be able to use the example outputs from the MWS documentation to put together a library of data to test many things without going live.

We can also use that to validate that completely unexpected things like server 503's or whatever, don't completely blow up the libraries.

This probably actually should be filed into mws-simple, then both libs can take advantage of it.
I posted it to mws-advanced since there are more people visiting this repo than that repo.

warning of breaking change coming: getMarketplaces

Yes, yes, I know if any of you have written something, you've probably used getMarketplaces. Maintaining the same data structure that it had in the earliest revisions of this lib, as well as the updates to it that added the "marketDetail" sub-object, is just kind of silly. Now that I'm staring at it in the new Documentation page, it's even sillier looking.

So, in a day or two, I'm going to push a change that is going to make it just return the internal "marketDetail", so the return results will look like this, instead:

{
        "A2EUQ1WTGCTBG2": {
            "MarketplaceId": "A2EUQ1WTGCTBG2",
            "DefaultCountryCode": "CA",
            "DomainName": "www.amazon.ca",
            "Name": "Amazon.ca",
            "DefaultCurrencyCode": "CAD",
            "DefaultLanguageCode": "en_CA",
            "SellerId": "A3VRRE5P0AL2IX",
            "HasSellerSuspendedListings": "No"
        },
        "ATVPDKIKX0DER": {
            "MarketplaceId": "ATVPDKIKX0DER",
            "DefaultCountryCode": "US",
            "DomainName": "www.amazon.com",
            "Name": "Amazon.com",
            "DefaultCurrencyCode": "USD",
            "DefaultLanguageCode": "en_US",
            "SellerId": "A3VRRE5P0AL2IX",
            "HasSellerSuspendedListings": "No"
        }
}

It'll be an object hash indexed by the marketplaceId. That should be a ton easier to work with. If you have code that depends on the existing structure, and you're keeping up to date with changes made here, this will serve as your warning. I will also update the new version of the documentation to reflect that change at that time.

My apologies up front if that breaks anything. :) I don't intend to start using the version number field until things are really into a state that i'm willing to call 1.0.0. Perhaps it's ok to use pre-1.0.0 numbers these days, though. not sure. i guess i should anyway. that's a debate for a different thread, though.

note: there are probably node libraries that can read the XSD files and do something useful

... i'm not 100% sure where I'm going with this thought -- it's probably safe to assume that Amazon will always send valid data, and even if they didn't, we'd have to handle it gracefully anyway.

Which leads me to several thoughts:

1- Entering validation data for responses from MWS, in our own definition, is probably futile -- using it would really only give us the ability to log when unexpected responses come in. That might well be valuable, for when new fields are added but no one is informed about them.

2- Actually validating the data from MWS is even more futile -- we can't really do anything about it if MWS sends junk data, anyway, other than file a bug with them.

3- However, are there XSD files that describe the inputs to the API? If so, then we might be able to parse those down and use them for generating the validation parameters for function calls.

4- If there are not, then that question is pretty much moot -- building an XSD looks significantly more painful than the mindnumbing boredom that is involved with entering the parameter validation data by hand while reading the MWS documentation. And re-entering it in Javascript from the documentation, also provides me with more study of how each function call works, and what it can be useful for.

5- I may spend too much time thinking about things that will make this project more automated and/or self-maintaining, at the expense of actually using this project. :-D

cache: replace with a middleware-type solution

So, in hindsight, while I needed the functionality of the cache system that was implemented, implementing it in the way that I did was pretty dumb. So, this is a note to remind me that I need to un-do it, and allow a method for taking care of it in whatever application uses mws-advanced, instead of doing it inside mws-advanced.

improve handling in requestAndDownloadReport()

I seem to have lost where in the official MWS documentation this is described, but inside requestAndDownloadReport() I have noted an area where checkReportComplete() does not receive a ReportId (this is intentional, or at least known, per the MWS docs) and therefore, the function can receive a positive response from checkReportComplete, but not know what ReportId to download.

if ReportId is not received, then we need to call getReportList() and handle it properly. There is code currently there right now that calls getReportList() but it is not known if getReportList() is currently completely functional. If it is, then we need to analyze the data output from getReportList() and issue a proper getReport() call afterwards.

Additionally, we probably also need to properly handle if checkReportComplete() fails. Does checkReportComplete() even know how to fail?

supporting validation for GetMyFeesEstimate requires support for object parameters

GetMyFeesEstimate is expecting a list of keys that would look a bit in code like:

                // FeesEstimateRequestList.FeesEstimateRequest.1=
                // {
                //     IdType: 'ASIN', // type: 'MarketplaceType', values: ['ASIN', 'SellerSKU'],
                //     IdValue: 'B002KT3XQM', // type: 'xs:string'
                //     IsAmazonFulled: true, // type: 'xs:boolean',
                //     Identifier: 'request1', // type: 'xs:string'
                //     PriceToEstimateFees: {
                //         ListingPrice: {
                //             CurrencyCode: 'USD',
                //             Amount: '30.00',
                //         },
                //         Shipping: {
                //             CurrencyCode: 'USD',
                //             Amount: '3.99',
                //         },
                //         Points: {
                //             PointsNumber: 0,
                //         },
                //     },
                // }

... this taken from comments i've made in products.js.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.