UNPKG

@shopgate/pwa-common

Version:

Common library for the Shopgate Connect PWA.

174 lines (156 loc) 5.38 kB
import "core-js/modules/es.string.replace.js"; import pck from "../../package.json"; import { buildThemeConfig } from "./theme"; import { assignObjectDeep } from "../data"; import { isObject } from "../validation"; /** * Provides a default app config as a fallback. * @mixin AppConfig */ const defaultAppConfig = { appId: 'shop_30177', browserConnector: false, colors: {}, forgotPasswordUrl: null, hasFavorites: false, hasReviews: true, showWriteReview: true, language: 'en-us', logo: 'https://example.com/logo', marketId: 'US', publicPath: 'https://example.com/public', shopName: 'Shopgate Connect', webCheckoutShopify: null, hasNoScanner: false, apiUrl: 'https://shop_30177.dev.connect.shopgate.com/', shopCNAME: null, currency: 'USD', showGmdMenuSubHeaders: false, benchmark: false, sentry: {}, theme: {}, cartShippingHideAnonymousLegacy: null, cartShippingTextAnonymousLegacy: null, variantSelectionMode: null, product: { variantPreselect: false }, cart: {}, scanner: {}, favorites: {}, tracking: { hasWebTrackingEngage: false, useSkuAsProductId: false }, webTrackingEngage: { android: '', ios: '' } }; /** * @type {string} package version from package.json */ export const pckVersion = pck.version; /** * Provides a default components config as a fallback. * @type {{portals: {}, widgets: {}}} */ const defaultComponentsConfig = { portals: {}, widgets: {} }; /** * The components.json config from the theme. * @type {Object} */ export const componentsConfig = { ...defaultComponentsConfig, ...process.env.COMPONENTS_CONFIG }; /** * The app.json config from the theme which will automatically be resolved. * Be careful when changing existing properties on the fly, reassignments should never be done! * @mixes AppConfig */ const appConfig = process.env.NODE_ENV !== 'test' ? process.env.APP_CONFIG : defaultAppConfig; /** * The theme name. * @type {string} */ export const themeName = process.env.THEME || 'theme'; /** * The resolved theme configuration. * @type {ThemeConfig} */ export const themeConfig = buildThemeConfig(appConfig); /** @mixes ThemeColors */ export const themeColors = themeConfig.colors; /** @mixes ThemeShadows */ export const themeShadows = themeConfig.shadows; /** @mixes ThemeVariables */ export const themeVariables = themeConfig.variables; /** @mixes ThemeIcons */ export const themeIcons = themeConfig.icons; // Fix theme config reference appConfig.theme = themeConfig; /** * A comparator for array items as they occur on different levels within the default app config. * It identifies items uniquely to avoid duplicates when merging configs. * Items identified as equal are merged together by the caller. Non-equals are added to the result. * * @type {ArrayItemComparator} Callback implementation for "assignObjectDeep" * @param {string} path Allows identification of the current elements to be compared * @param {*} prev Item that already exists in the config. * @param {*} next Item to be compared against. * @returns {boolean} Returns true if the items are considered equal and false if not */ export const appConfigArrayItemComparator = (path, prev, next) => { // Replaces object paths with array indices to a structure with easy comparisons // E.g. converts "prop.subprop.15.arrayitem.3" to "prop.subprop.N.arrayitem.N" const simplePath = path.replace(/\.[0-9]+/g, '.N'); // Simple types if (!isObject(prev) || !isObject(next)) { return prev === next; } // Identity of pages is defined by the page pattern if (simplePath === '$.theme.pages.N') { return prev.pattern === next.pattern; } // Identity of widgets is defined by the widget id if (simplePath === '$.theme.pages.N.widgets.N') { return prev.id === next.id; } // Assume everything else to be of different values (including sub-arrays) // => Arrays within arrays not defined in the default config => never equal. // => Custom defined array items must be handled using the given arrayComparator! return false; }; /** * Comparator which treats items to be equal arrays by the position of the item in the array. * @param {string} [path] Unused param * @param {*} [prev] Unused param * @param {*} [next] Unused param * @param {number} prevIndex Position of the prev item in the array which is currently compared * @param {number} nextIndex Position of the next item in the array which is currently compared * @returns {boolean} Returns true if the items are considered equal and false if not */ export const equalStructureComparator = (path, prev, next, prevIndex, nextIndex) => prevIndex === nextIndex; /** * Takes an object with app config values and safely injects it into the current app config. * @param {Object} newConfig Contains new config fields to inject into the existing destination. * @param {ArrayItemComparator|null} [arrayComparator] Defines how to compare array items. */ export function writeToConfig(newConfig, arrayComparator = null) { const comparator = arrayComparator || appConfigArrayItemComparator; assignObjectDeep(appConfig, newConfig, true, comparator, '$'); } /** * The shop number. * @type {string} */ const { appId } = appConfig; export const shopNumber = appId ? appId.replace('shop_', '') : ''; /** @mixes AppConfig */ export default appConfig;