UNPKG

@apite/magento2-utility

Version:

Shopgate WebCheckout utility for Magento 2 extensions

154 lines (134 loc) 4.32 kB
'use strict' const get = require('lodash.get') const axios = require('axios') const { getCartId, getCustomerAuthToken } = require('./contextManager') const { getEndpoint, getStoreCode } = require('./configManager') const { GraphQLError } = require('../lib/errorList') const { formatAxiosResponse, formatAxiosRequest } = require('./logDecorator')() /** * @param {ApiteM2Utility.PipelineContext} context * @returns {Promise<AxiosInstance>} */ const createMageGraphQLApi = async context => { return addAxiosInterceptors( axios.create({ baseURL: new URL('graphql', getEndpoint(context)).toString(), headers: { Accept: 'application/json', 'Content-Type': 'application/json', Store: getStoreCode(context) } }), context) } /** * @param {AxiosInstance} axiosClient * @param {ApiteM2Utility.PipelineContext} context * @returns {Promise<AxiosInstance>} */ const addAxiosInterceptors = async (axiosClient, context) => { const isLoggedIn = context.meta.userId const token = await getCustomerAuthToken(context) if (isLoggedIn && token) { axiosClient.defaults.headers.Authorization = `Bearer ${token}` } axiosClient.interceptors.request.use(async config => { const newConfig = config const cartId = await getCartId(context) // records all queries to debug context.log.debug(formatAxiosRequest(config), 'request-catch-all') if (!cartId) { return newConfig } if (config.url) { newConfig.url = config.url.replace(':cartId', encodeURIComponent(cartId)) } const hasQuery = get(config, 'data.query', null) !== null if (hasQuery) { newConfig.data.query = config.data.query.replace(':cartId', encodeURIComponent(cartId)) } return newConfig }) // when this check is present, our module extends login tokens' TTL axiosClient.defaults.headers.common['shopgate-check'] = 'true' if (process.env.XDEBUG) { axiosClient.defaults.headers.common.Cookie = `XDEBUG_SESSION=${process.env.XDEBUG};` axiosClient.defaults.withCredentials = true } // responds with data instead of response axiosClient.interceptors.response.use(resp => { if (resp.data.errors && resp.data.errors.length > 0) { const error = new GraphQLError(resp) context.log.error(error.getFormattedError(), 'gql-error-catch-all') throw error } return resp.data }) return axiosClient } /** * @param {ApiteM2Utility.PipelineContext} context * @returns {AxiosInstance} */ const createMageApi = async context => { const urlPath = `rest/${getStoreCode(context)}/V1` const baseURL = new URL(urlPath, getEndpoint(context)).toString() const axiosClient = await addAxiosInterceptors( axios.create({ baseURL, headers: { Accept: 'application/json', 'Content-Type': 'application/json' } }), context) axiosClient.interceptors.response.use(null, async err => { if (err.response) { context.log.debug(formatAxiosResponse(err.response), 'rest-error-catch-all') } else { context.log.error({ message: err.message }, 'rest-non-api-error') } return Promise.reject(err) }) return axiosClient } /** * Retrieves customer, guest or anonymous (no cart) token * * @param {AxiosInstance} client * @param {'me'|'anonymous'|':cartId'} param * @returns {Promise<WebCheckoutAPI.LoginTokenResponse>} */ const getLoginToken = async (client, param) => { return client.post(`sgwebcheckout/${param}/token`) } /** * Retrieves product ID to SKU map * * @param {AxiosInstance} client * @param {ApiteM2Utility.PipelineContext} context * @param {string[]} ids * @returns {Promise<WebCheckoutAPI.ProductMapResponse>} */ const getProductMap = async (client, context, ids) => { return client.get('sgwebcheckout/products', { params: { ids } }) } /** * Retrieves product SKU to ID map * * @param {AxiosInstance} client * @param {ApiteM2Utility.PipelineContext} context * @param {string[]} skus * @returns {Promise<WebCheckoutAPI.ProductMapResponse>} */ const getProductBySkuMap = async (client, context, skus) => { return client.get('sgwebcheckout/productsBySku', { params: { skus } }) } module.exports = { createMageApi, createMageGraphQLApi, getLoginToken, getProductMap, getProductBySkuMap }