@whitebox-co/walmart-marketplace-api
Version:
A fully typed TypeScript, Javascript, and Node.js API library for the Walmart Marketplace API
170 lines • 7.93 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WalmartApi = void 0;
const configuration_1 = require("./apis/configuration");
const auth_1 = require("./apis/auth");
const uuid_1 = require("uuid");
const interceptors_1 = require("./util/interceptors");
const constants_1 = require("./constants");
const form_data_1 = __importDefault(require("form-data"));
const buffer_1 = require("buffer/");
const credentialsCache = {};
/**
* Converts a credential into a defaultParam object used in all api calls.
*
* @param {WalmartApiCredentials} credentials The credentials to transform into a DefaultParam.
* @returns {DefaultParams} The default parameters with information from credentials object.
*/
const getDefaultParams = (credentials) => {
const { accessToken, clientId, clientSecret, serviceName, consumerChannelType } = credentials;
return {
...constants_1.defaultParams,
authorization: 'Basic ' + buffer_1.Buffer.from(clientId + ':' + clientSecret).toString('base64'),
wMSECACCESSTOKEN: accessToken === null || accessToken === void 0 ? void 0 : accessToken.token,
wMQOSCORRELATIONID: (0, uuid_1.v4)(),
wMSVCNAME: serviceName ? serviceName : '@whitebox-co/walmart-marketplace-api',
wMCONSUMERCHANNELTYPE: consumerChannelType,
};
};
/**
* Uses the clientId and clientSecret to get an access token from Walmart's Token API.
*
* Checks for cached credentials and against Walmart's tokenDetail endpoint to see if
* the found cached token is valid.
*
* @param {WalmartApiCredentials} credentials credentials without authorized token.
* @returns {Promise<WalmartApiCredentials>} cached or new credentials.
*/
const authorize = async (credentials) => {
var _a, _b, _c, _d;
const { clientId } = credentials;
const authApi = new auth_1.AuthenticationApi();
// lets first check if credentials are cached and make sure the expiration has not been hit.
let cachedCredentials = credentialsCache[clientId];
const isValid = credentials && credentials.accessToken && new Date() < credentials.accessToken.expiration;
// Even though the cached credentials are valid lets double check with walmart
// to make sure the token is still active.
let tokenDetailResponse;
if (isValid) {
const defaultParams = getDefaultParams(cachedCredentials);
tokenDetailResponse = await authApi.getTokenDetail(defaultParams);
}
// get new token if cached credentials were invalid or walmart tell us it's not valid.
if (!isValid || !((_a = tokenDetailResponse === null || tokenDetailResponse === void 0 ? void 0 : tokenDetailResponse.data) === null || _a === void 0 ? void 0 : _a.is_valid)) {
const defaultParams = getDefaultParams(credentials);
const tokenResponse = await authApi.tokenAPI({
...defaultParams,
grantType: 'client_credentials',
});
if (tokenResponse.status !== 200) {
throw new Error(`Walmart Marketplace API Authorization failed for clientId ${clientId}`);
}
// TODO: remove when the auto generated interface type is correct.
const tokenData = tokenResponse;
cachedCredentials = {
...credentials,
accessToken: tokenData && {
token: (_b = tokenData.data) === null || _b === void 0 ? void 0 : _b.access_token,
expiration: (_c = tokenData.data) === null || _c === void 0 ? void 0 : _c.expires_in,
type: (_d = tokenData.data) === null || _d === void 0 ? void 0 : _d.token_type,
},
};
}
// cache credentials.
credentialsCache[clientId] = cachedCredentials;
// return cached or new credentials
return cachedCredentials;
};
/**
* Authorizes against the Walmart token endpoint and returns a configured Configuration object.
*
* This is the main object passed in to all api's and must have a valid token.
*
* @example
* import marketplaceApi, {InventoryApi} from '@whitebox-co/walmart-marketplace-api';
*
* const credentials: WalmartApiCredentials = {clientID: 'abcd', clientSecret: 'efg', consumerChannelType: 'channelId'};
* const defaultParams = marketplaceApi.getDefaultParams(credentials);
* const authorizedCredentials = marketplaceApi.getAuthorizedConfiguration(credentials);
* const inventoryApi = new InventoryApi(authorizedCredentials);
* const inventory = inventoryApi.getInventory({...defaultParams, sku: 'abcd'})
*
* @param {WalmartApiCredentials} credentials input params, some are optional.
* @returns {Promise<Configuration>} A Configuration object with an authorized and valid access_token.
*/
const getAuthorizedConfiguration = async (credentials) => {
const authorizedCredentials = await authorize(credentials);
return new configuration_1.Configuration({
accessToken: authorizedCredentials.accessToken.token,
});
};
/**
* Generates a fully instantiated and configured Walmart Marketplace Api.
*
* @example
* import marketplaceApi, {InventoryApi} from '@whitebox-co/walmart-marketplace-api';
*
* const credentials: WalmartApiCredentials = {clientID: 'abcd', clientSecret: 'efg', consumerChannelType: 'channelId'};
* const defaultParams = marketplaceApi.getDefaultParams(credentials);
* const inventoryApi = marketplaceApi.getConfiguredApi(InventoryApi, credentials);
* const inventory = inventoryApi.getInventory({...defaultParams, sku: 'abcd'})
*
* @param {T} Api WalmartMarketplaceApi
* - Should be one of the many Apis from the './api' exports.
* - This should be the Class itself and not an instance.
*
* @param {WalmartApiCredentials} credentials input params, some are optional.
*
* @returns {Promise<T>} A fully instantiated Api from the './api' exports.
*/
const getConfiguredApi = async (Api, credentials) => {
const authorizedConfiguration = await getAuthorizedConfiguration(credentials);
authorizedConfiguration.formDataCtor = form_data_1.default;
authorizedConfiguration.baseOptions = {
headers: {
Accept: 'application/json',
},
};
const api = new Api(authorizedConfiguration);
// run an apiInterceptor in order to fill in defaultParams necessary for each call.
return (0, interceptors_1.apiInterceptor)(api, (fnName, fnArgs) => {
const defaultParams = getDefaultParams(credentialsCache[credentials.clientId]);
// apply default params to first arg which is always a request object.
fnArgs[0] = { ...fnArgs[0], ...defaultParams };
// run function with args.
api[fnName](...fnArgs);
});
};
class WalmartApi {
constructor(credentials) {
this.credentials = credentials;
this.getConfiguredApi = async (Api) => {
return await getConfiguredApi(Api, this.credentials);
};
}
}
exports.WalmartApi = WalmartApi;
__exportStar(require("./apis"), exports);
__exportStar(require("./apis/configuration"), exports);
__exportStar(require("./constants"), exports);
exports.default = {
getConfiguredApi,
};
//# sourceMappingURL=index.js.map