@lorenstuff/amazon-selling-partner-api
Version:
A package for interacting with the Amazon Selling Partner API.
108 lines • 3.9 kB
JavaScript
//
// Imports
//
import { formatDate } from "../utilities/format-date.js";
/** The core client that handles actually connecting to the Selling Partner API. */
export class AmazonSellingPartnerAPIClient {
/** The refresh token from an Amazon Seller Central app. */
refreshToken;
/** The client identifier from an Amazon Seller Central app. */
clientIdentifier;
/** The client secret from an Amazon Seller Central app. */
clientSecret;
/** The Amazon Seller Partner API Endpoint to use. */
apiEndpoint;
/** The AWS region to use. */
awsRegion;
/** The current access tokens this client has. */
accessTokens;
/** Constructs a new client. */
constructor(options) {
this.refreshToken = options.refreshToken;
this.clientIdentifier = options.clientIdentifier;
this.clientSecret = options.clientSecret;
this.apiEndpoint = options.apiEndpoint;
this.awsRegion = options.awsRegion;
this.accessTokens = [];
}
/**
* Adds an access token to the client.
*
* This is intended to be used to add a restricted data token.
*/
addAccessToken(accessToken) {
this.accessTokens.unshift(accessToken);
return accessToken;
}
/** Removes an access token from the client, if it is still present. */
removeAccessToken(accessToken) {
const index = this.accessTokens.indexOf(accessToken);
if (index === -1) {
return;
}
this.accessTokens.splice(index, 1);
}
/**
* Fetches a fresh access token.
*
* @returns A promise that resolves to the access token.
*/
async getCurrentAccessToken() {
//
// Try Existing Tokens
//
while (this.accessTokens[0] != null) {
const accessToken = this.accessTokens[0];
if (accessToken.expiresTimestamp > (Date.now() / 1000)) {
return accessToken;
}
this.accessTokens.shift();
}
//
// Request New Token
//
const headers = new Headers();
headers.set("Content-Type", "application/x-www-form-urlencoded");
const body = new URLSearchParams();
body.set("grant_type", "refresh_token");
body.set("refresh_token", this.refreshToken);
body.set("client_id", this.clientIdentifier);
body.set("client_secret", this.clientSecret);
const rawAccessTokenResponse = await fetch("https://api.amazon.com/auth/o2/token", {
method: "POST",
headers,
body,
});
const accessTokenResponse = await rawAccessTokenResponse.json();
if (accessTokenResponse.access_token == null) {
throw new Error("Failed to fetch access token.");
}
//
// Add & Return Access Token
//
return this.addAccessToken({
accessToken: accessTokenResponse.access_token,
expiresTimestamp: (Date.now() / 1000) + accessTokenResponse.expires_in,
});
}
/** Performs a request to the Selling Partner API. */
async request(options) {
const accessToken = await this.getCurrentAccessToken();
const dateTime = formatDate(new Date());
const headers = new Headers();
headers.set("host", this.apiEndpoint);
headers.set("user-agent", "Amazon SP API Node.js Client");
headers.set("x-amz-access-token", accessToken.accessToken);
headers.set("x-amz-date", dateTime);
let uri = this.apiEndpoint + options.path;
if (options.searchParams != null) {
uri += "?" + options.searchParams.toString();
}
return await fetch(uri, {
method: options.method,
headers,
body: options.body ?? null,
});
}
}
//# sourceMappingURL=AmazonSellingPartnerAPIClient.js.map