@apite/magento2-utility
Version:
Shopgate WebCheckout utility for Magento 2 extensions
154 lines (134 loc) • 4.32 kB
JavaScript
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
}