UNPKG

@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
"use strict"; 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