@koempf/shopgate-utility
Version:
Shopgate WebCheckout utility for Kömpf
218 lines (176 loc) • 6.16 kB
JavaScript
const { getSessionContext } = require('./contextManager')
const { getEndpoint, getClientId, getClientSecret, getSentryDsn } = require('./configManager')
const { login, refreshLogin } = require('../client/apiClient')
const customerService = require('./customerService')
const cartService = require('./cartService')
const guestCartService = require('./guestCartService')
const checkoutService = require('./checkoutService')
const { UnknownError, InvalidCredentialsError, UnauthorizedError } = require('./errors')
const createApiConfig = async (context, config = {}) => {
const endpoint = getEndpoint(context)
const clientId = getClientId(context)
const clientSecret = getClientSecret(context)
const sentryDsn = getSentryDsn(context)
const sessionContext = await getSessionContext(context)
const isGuest = !context.meta.userId
return Object.assign({
endpoint,
clientId,
clientSecret,
sentryDsn,
context: {
guestToken: isGuest ? context.meta.deviceId : null,
accessToken: sessionContext && sessionContext.accessToken ? sessionContext.accessToken : null,
expires: sessionContext && sessionContext.expires ? sessionContext.expires : null,
refreshToken: sessionContext && sessionContext.refreshToken ? sessionContext.refreshToken : null
},
tracedRequest: context.tracedRequest('koempf-spryker')
}, config)
}
const apiLogin = async ({ parameters }, config) => {
const response = await login({ username: parameters.login, password: parameters.password }, config)
if (response.statusCode !== 200) {
throw new InvalidCredentialsError()
}
const { access_token: accessToken, expires_in: expires, refresh_token: refreshToken } = response.body
return {
guestToken: null,
accessToken,
expires,
refreshToken
}
}
const checkSessionContext = async (config) => {
try {
await customerService.getCustomer(config)
return {
sessionContext: config.context,
refresh: false
}
} catch (error) {
const response = await refreshLogin(config)
if (response.statusCode !== 200) {
return {
sessionContext: null,
refresh: false
}
}
const { access_token: accessToken, expires_in: expires, refresh_token: refreshToken } = response.body
return {
sessionContext: {
guestToken: null,
accessToken,
expires,
refreshToken
},
refresh: true
}
}
}
const getCustomer = async (config) => {
if (!config.context || !config.context.accessToken) throw new UnauthorizedError()
return customerService.getCustomer(config)
}
const getCartById = async (id, config) => {
if (config.context.guestToken) {
return await guestCartService.getGuestCart({ cartId: id }, config)
}
return await cartService.getCart({ cartId: id }, config)
}
const getCart = async (config) => {
let cart = null
if (config.context.guestToken) {
cart = await guestCartService.getGuestCarts(config)
} else {
cart = await cartService.getCarts(config).catch(() => null)
if (!cart || cart.length === 0) cart = await cartService.createCart(config)
}
return cart || null
}
const getCarId = async (config) => {
const cart = await getCart(config)
if (!cart) return null
return cart.id
}
const mergeGuestCartToCart = async (context, config) => {
const guestConfig = {
...config,
context: {
guestToken: context.meta.deviceId,
accessToken: null,
expires: null,
refreshToken: null
}
}
const guestCartId = await getCarId(guestConfig)
if (!guestCartId) return null
const guestCart = await getCartById(guestCartId, guestConfig)
if (!guestCart) return
const cartItems = guestCart.included || []
const items = cartItems.filter(item => item.type === 'items') || []
items.forEach(async item => {
await addCartItem({ sku: item.attributes.sku, quantity: item.attributes.quantity }, config)
await deleteCartItem(item.attributes.sku, guestConfig)
})
}
const addCartItem = async ({ sku, quantity }, config) => {
const cartId = await getCarId(config)
if (config.context.guestToken) {
return await guestCartService.addGuestCartItem({ cartId, sku, quantity }, config)
}
return await cartService.addCartItem({ cartId, sku, quantity }, config)
}
const updateCartItemQuantity = async (itemGroupKey, quantity, config) => {
const cartId = await getCarId(config)
if (config.context.guestToken) {
return await guestCartService.updateGuestCartItem({ cartId, itemGroupKey, quantity }, config)
}
return await cartService.updateCartItem({ cartId, itemGroupKey, quantity }, config)
}
const deleteCartItem = async (itemGroupKey, config) => {
const cartId = await getCarId(config)
if (config.context.guestToken) {
return await guestCartService.deleteGuestCartItem({ cartId, itemGroupKey }, config)
}
return await cartService.deleteCartItem({ cartId, itemGroupKey }, config)
}
const addCouponCode = async (code, config) => {
const cartId = await getCarId(config)
if (config.context.guestToken) {
return await guestCartService.addCartCodes({ cartId, code }, config)
}
return await cartService.addCartCodes({ cartId, code }, config)
}
const removeCouponCode = async (code, config) => {
const cartId = await getCarId(config)
if (config.context.guestToken) {
return await guestCartService.deleteCartCodes({ cartId, code }, config)
}
return await cartService.deleteCartCodes({ cartId, code }, config)
}
const checkoutUrl = async (config) => {
const cartId = await getCarId(config)
return await checkoutService.getCheckoutUrl({ cartId }, config)
}
const getCustomerUrl = async (path, config) => {
const customer = await getCustomer(config)
if (!customer) throw new UnknownError()
return await customerService.getCustomerUrl({ customerId: customer.id, path }, config)
}
module.exports = {
createApiConfig,
apiLogin,
checkSessionContext,
getCustomer,
getCart,
getCartById,
addCartItem,
updateCartItemQuantity,
deleteCartItem,
addCouponCode,
removeCouponCode,
checkoutUrl,
getCustomerUrl,
mergeGuestCartToCart
}