PageSourceSearch

https://www.americaneagle.ae/scripts/configs.js

js americaneagle.ae collected 2026-10-02 13:25:25 UTC 12,727 bytes, 424 lines download raw bytes

1export const PROD_ENV = 'prod';
2export const PPROD_ENV = 'pprod';
3export const EDS_ENV = 'aem';
4export const STAGE_ENV = 'stage';
5export const DEV_ENV = 'dev';
6export const PREVIEW_ENV = 'preview';
7const ALLOWED_CONFIGS = [PROD_ENV, PPROD_ENV, EDS_ENV, DEV_ENV, PREVIEW_ENV];
8const SEPARATE_CONFIG_FILES = [STAGE_ENV, PREVIEW_ENV, PPROD_ENV];
9
10export const REG_DATE_KEY = 'registration_date';
11export const LOGOUT_SOURCE = 'logout';
12export const CARTID_STORE = 'M2_VENIA_BROWSER_PERSISTENCE__cartId';
13const REACT_DEPENDENCIES = ['/scripts/vendor.js', '/scripts/react-bridge.js'];
14export const BLOCK_DEPENDENCIES = {
15  cart: REACT_DEPENDENCIES,
16  'cart-login': REACT_DEPENDENCIES,
17  'cart-register': REACT_DEPENDENCIES,
18  checkout: REACT_DEPENDENCIES,
19  'order-confirmation': REACT_DEPENDENCIES,
20  'payment-success': REACT_DEPENDENCIES,
21  'payment-error': REACT_DEPENDENCIES,
22  'shared-cart': REACT_DEPENDENCIES,
23};
24export default BLOCK_DEPENDENCIES;
25
26const IMAGES = {
27  ICON: { name: 'imagesize-icon', size: '120', mobile: '120' },
28  XSMALL: { name: 'imagesize-xsmall', size: '250', mobile: '250' },
29  SMALL: { name: 'imagesize-small', size: '400', mobile: '400' },
30  XMEDIUM: { name: 'imagesize-xmedium', size: '550', mobile: '550' },
31  MEDIUM: { name: 'imagesize-medium', size: '750', mobile: '750' },
32  LARGE: { name: 'imagesize-large', size: '1024', mobile: '750' },
33  XLARGE: { name: 'imagesize-xlarge', size: '1600', mobile: '750' },
34  XXLARGE: { name: 'imagesize-xxlarge', size: '2000', mobile: '750' },
35};
36
37export const COUNTRY_LIST = [
38  {
39    code: 'AE', label: 'United Arab Emirates', phone: '971', phoneLength: 9,
40  },
41  {
42    code: 'BH', label: 'Bahrain', phone: '973', phoneLength: 8,
43  },
44  {
45    code: 'EG', label: 'Egypt', phone: '20', phoneLength: 10,
46  },
47  {
48    code: 'JO', label: 'Jordan', phone: '962', phoneLength: 9,
49  },
50  {
51    code: 'KW', label: 'Kuwait', phone: '965', phoneLength: 8,
52  },
53  {
54    code: 'QA', label: 'Qatar', phone: '974', phoneLength: 8,
55  },
56  {
57    code: 'SA', label: 'Saudi Arabia', phone: '966', phoneLength: 9,
58  },
59];
60
61export const CACHE_KEYS = {
62  VERSION: 'version',
63  KEYS: 'keys',
64  CONFIGS: 'configs',
65  BRAND_CONFIGS: 'brand_configs',
66  PLACEHOLDERS: 'placeholders',
67  COMMERCE_CATEGORIES: 'categories',
68  CATEGORIES_BY_URL: 'cat_byurl',
69  TRENDING_SEARCH: 'tsearch',
70  PLP_FILTERS: 'plp_filters',
71  FILTERS: 'filter',
72  CHECKOUT_ORDER_DETAILS: 'order_info',
73  STORES: 'stores',
74  AURA_INFO: 'aura',
75  AURA_EARLY_ACCESS_SALE: 'aura_early_access',
76  IS_ITEM_ON_SALE: 'is_item_on_sale',
77  FINDATON_SELECTED_SHADES: 'kSavedShades',
78  BANNER_LIST: 'banner_list',
79  BANNER_TYPOGRAPHY: 'banner_typography',
80  HEADER_SECOUNDRY_NAV: 'sec_nav',
81  EXPRESS_DELIVERY_LOCATIONS: 'express_del_loc',
82  COUPONS_DATA: 'coupons',
83};
84
85const CACHE_KEYS_IGNORE = [
86  CACHE_KEYS.AURA_INFO,
87];
88
89// store configs globally to avoid multiple requests
90if (!window.axp) window.axp = {};
91
92/*
93 * Returns the true origin of the current page in the browser.
94 * If the page is running in a iframe with srcdoc, the ancestor origin is returned.
95 * @returns {String} The true origin
96 */
97function getOrigin() {
98  const { location } = window;
99  return location.href === 'about:srcdoc' ? window.parent.location.origin : location.origin;
100}
101
102export function getHref() {
103  if (window.location.href !== 'about:srcdoc') return window.location.href;
104
105  const { location: parentLocation } = window.parent;
106  const urlParams = new URLSearchParams(parentLocation.search);
107  return `${parentLocation.origin}${urlParams.get('path')}`;
108}
109
110/**
111 * Returns the document language attribute value
112 *
113 * @returns String language value
114 */
115export function getLanguageAttr() {
116  const path = getHref();
117  if (path.includes('/ar/')) {
118    return 'ar';
119  }
120  return document.documentElement.lang || 'en';
121}
122
123/**
124 * This function calculates the environment in which the site is running based on the URL.
125 * It defaults to 'prod'. In non 'prod' environments, the value can be overwritten using
126 * the 'environment' key in sessionStorage.
127 *
128 * @returns {string} - environment identifier (dev, stage or prod'.
129 */
130export const calcEnvironment = () => {
131  const { href } = window.location;
132  let environment = PROD_ENV;
133  if (href.includes('.hlx.page') || href.includes('.aem.page')) {
134    environment = EDS_ENV;
135  } else if (href.includes('-stage.factory.alshayauat.com')) {
136    environment = STAGE_ENV;
137  } else if (href.includes('localhost')) {
138    environment = DEV_ENV;
139  } else if (href.includes('-eds.factory.alshayauat.com')) {
140    environment = PREVIEW_ENV;
141  } else if (href.includes('-pprod.factory.alshayauat.com')) {
142    environment = PPROD_ENV;
143  }
144
145  const environmentFromConfig = window.sessionStorage.getItem('environment');
146  if (environmentFromConfig
147    && ALLOWED_CONFIGS.includes(environmentFromConfig)
148    && environment !== PROD_ENV) {
149    return environmentFromConfig;
150  }
151
152  return environment;
153};
154
155/**
156 * Localstorage caching based on ttl (in seconds)
157 *
158 */
159export const LocalStorageCache = (() => {
160  const PREFIX = '_axp_';
161
162  function getExpiry(ttl) {
163    return ttl > 0 ? Date.now() + (ttl * 1000) : null;
164  }
165
166  // Helper to build stored object with ttl in seconds
167  function buildItem(value, ttl) {
168    return JSON.stringify({
169      v: value,
170      exp: ttl,
171    });
172  }
173
174  // Helper to parse/store
175  function parseItem(item) {
176    try {
177      return JSON.parse(item);
178    } catch {
179      return null;
180    }
181  }
182
183  function getCacheKey(key, lang) {
184    let cacheKey = PREFIX + key;
185    if (lang) {
186      cacheKey += `_${getLanguageAttr()}`;
187    }
188
189    return cacheKey;
190  }
191
192  return {
193    /**
194     * Store an object or string value in localstorage
195     *
196     * @param {string} key unique key
197     * @param {object} value string or object
198     * @param {Integer} ttl Time in seconds, default is 600 sec (10 min)
199     * @param {boolean} lang language option, to create cache with local, false as default
200     */
201    set(key, value, ttl = 600, lang = false) {
202      // ttl in hours, 0 or negative means never expires
203      const cacheKey = getCacheKey(key, lang);
204      const cacheExp = getExpiry(ttl);
205      localStorage.setItem(cacheKey, buildItem(value, cacheExp));
206
207      const cacheObjectKeys = this.get(CACHE_KEYS.KEYS, false) || { };
208      cacheObjectKeys[cacheKey] = cacheExp;
209      localStorage.setItem(getCacheKey(CACHE_KEYS.KEYS, false), buildItem(cacheObjectKeys, 0));
210    },
211
212    /**
213     * Get the cached object from localstorage, using key and language option
214     * This function also check expiry of cache.
215     *
216     * @param {string} key unique key
217     * @param {boolean} lang language option, to return cached object with local, false as default
218     * @returns Cached object if valid (not expired) object is cached, otherwise null
219     */
220    get(key, lang = false) {
221      const itemStr = localStorage.getItem(getCacheKey(key, lang));
222      if (!itemStr) return null;
223
224      const item = parseItem(itemStr);
225      if (!item) return null;
226
227      if (item.exp && Date.now() > item.exp) {
228        this.remove(key, lang);
229        return null;
230      }
231      return item.v;
232    },
233
234    /**
235     * Remove the object from localstorage cache
236     *
237     * @param {string} key unique key
238     * @param {boolean} lang language option, to use cached object with local, false as default
239     */
240    remove(key, lang = false) {
241      localStorage.removeItem(getCacheKey(key, lang));
242    },
243
244    /**
245     * Clear all objects of axp localstorage
246     */
247    clear(full = false) {
248      const cacheKeys = this.get(CACHE_KEYS.KEYS, false);
249      Object.keys(localStorage).forEach((key) => {
250        if (key.startsWith(PREFIX)) {
251          if (full && !CACHE_KEYS_IGNORE.includes(key)) localStorage.removeItem(key);
252          else {
253            const itemExp = cacheKeys[key];
254            if (itemExp && Date.now() > itemExp) {
255              localStorage.removeItem(key);
256              delete cacheKeys[key];
257            }
258          }
259        }
260      });
261      localStorage.setItem(getCacheKey(CACHE_KEYS.KEYS, false), buildItem(cacheKeys, 0));
262    },
263  };
264})();
265
266function buildConfigURL(env, locale) {
267  const origin = getOrigin();
268  const localePath = locale ? `${locale}/` : '';
269  let configFileName = 'configs.json';
270  if (SEPARATE_CONFIG_FILES.includes(env)) {
271    configFileName = `configs-${env}.json`;
272  }
273  const configURL = new URL(`${origin}/${localePath}${configFileName}`);
274  return configURL;
275}
276
277async function getConfig() {
278  const language = getLanguageAttr();
279  const env = calcEnvironment();
280  const configs = {};
281
282  const fetchGlobalConfig = fetch(buildConfigURL(env));
283  const fetchLocalConfig = fetch(buildConfigURL(env, language));
284  try {
285    const responses = await Promise.all([fetchGlobalConfig, fetchLocalConfig]);
286
287    // Extract JSON data from responses
288    const [configJSON, configLocaleJSON] = await Promise.all(responses
289      .map((response) => response.text()));
290
291    // merge config and locale config
292    if (configJSON && configLocaleJSON) {
293      const config = JSON.parse(configJSON);
294      const configLocal = JSON.parse(configLocaleJSON);
295      configLocal.data.forEach((localeConfig) => {
296        const existing = config.data.find((c) => c.key === localeConfig.key);
297        if (existing) {
298          existing.value = localeConfig.value;
299        } else {
300          config.data.push(localeConfig);
301        }
302      });
303
304      config.data?.forEach((c) => {
305        configs[c.key] = c.value;
306      });
307    }
308  } catch (e) {
309    console.error('no config loaded', e);
310  }
311
312  return configs;
313}
314
315/**
316 * This function retrieves all configuration values for a given environment.
317 *
318 * @returns {Object} - All configuration values
319 */
320export async function getAllConfigs() {
321  let configs = window.axp?.configs;
322
323  if (!configs) {
324    configs = LocalStorageCache.get(CACHE_KEYS.CONFIGS, true);
325    if (typeof (configs) !== 'object') {
326      configs = null;
327    }
328    window.axp.configs = configs;
329  }
330
331  if (!configs) {
332    configs = await getConfig();
333
334    window.axp.configs = configs;
335    LocalStorageCache.set(CACHE_KEYS.CONFIGS, configs, 18000, true);
336  }
337
338  return window.axp.configs;
339}
340
341/**
342 * This function retrieves a configuration value for a given environment.
343 *
344 * @param {string} configParam - The configuration parameter to retrieve.
345 * @returns {string} - The value of the configuration parameter, or undefined.
346 */
347export async function getConfigValue(configParam) {
348  const configs = await getAllConfigs();
349
350  return configs?.[configParam];
351}
352
353export const formatDate = (dateString) => {
354  const language = getLanguageAttr();
355  const date = new Date(dateString);
356  const day = date.getDate().toString().padStart(2, '0');
357  const month = date.toLocaleString(language, { month: 'short' });
358  const year = date.getFullYear();
359
360  return `${day} ${month} ${year}`;
361};
362
363/**
364 * Load band config file to check which all brand level overridden files needs to be loaded.
365 *
366 * @param {string} brand Brand code
367 *
368 * @returns brand config object
369 */
370export async function getBrandConfigs() {
371  let bConfig = window?.axp?.brandConfig || LocalStorageCache.get(CACHE_KEYS.BRAND_CONFIGS, false);
372
373  if (!bConfig) {
374    const [config] = await Promise.all([
375      import(`/scripts/configs/${window.axp.brandCode}.js`).catch((e) => {
376        console.warn('Error loading brand config:', e);
377        return { BRAND_CONFIGS: { noconfig: true } };
378      }),
379    ]);
380
381    bConfig = config?.BRAND_CONFIGS;
382    LocalStorageCache.set(CACHE_KEYS.BRAND_CONFIGS, bConfig, 86400, false);
383  }
384  if (!window?.axp?.brandConfig) window.axp.brandConfig = bConfig;
385
386  return bConfig;
387}
388
389/**
390 * Get maximum phone length by country code
391 *
392 * @param {*} countryCode
393 * @returns phoneLength
394 */
395export async function getMaxLengthByCountryCode(countryCode) {
396  const countryByCode = COUNTRY_LIST.find((c) => c.code === countryCode);
397  return countryByCode.phoneLength;
398}
399
400/**
401 * Get country ISO code
402 * @param {*} countryCode
403 * @returns Phone ISO code
404 */
405export async function getCountryIso(countryCode) {
406  const countryIso = COUNTRY_LIST.find((c) => c.code === countryCode);
407  return countryIso.phone;
408}
409
410/**
411 * Return the correct image size based on block configuration, otherwise default size is returned
412 * @param {*} blockClasses - Block class list
413 * @param {*} defaultSize - default image size
414 * @returns imageSize
415 */
416export function getImageSize(blockClasses, defaultSize = '750', isMobile = false) {
417  const filteredImg = Object.values(IMAGES).filter(
418    (img) => blockClasses?.contains(img.name),
419  );
420  if (isMobile) {
421    return filteredImg?.length > 0 ? filteredImg[0]?.mobile : defaultSize;
422  }
423  return filteredImg?.length > 0 ? filteredImg[0]?.size : defaultSize;
424}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.