Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@global-savings-group/caa-engine

Package Overview
Dependencies
Maintainers
0
Versions
52
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@global-savings-group/caa-engine - npm Package Compare versions

Comparing version 4.1.2 to 4.2.0

dist/content/utils/send-log-to-background.d.ts

5

dist/background/code.d.ts

@@ -6,2 +6,7 @@ import { type ParsedAmount } from '../content';

}
/**
* Record includes meta fields from the extension,
* which will be unknown for the libriary and not used,
* but still need in the extenstion(id for analytics).
*/
export interface Code extends Record<string | number, unknown> {

@@ -8,0 +13,0 @@ code: string;

5

dist/background/config.d.ts
import { type UnifiedConfig } from '@src/interfaces/unified-config.interfaces';
type MerchantDomain = string;
export type GetUnifiedConfigUrl = (domain: MerchantDomain) => Promise<string>;
export type GetUnifiedConfigUrl = (domain: MerchantDomain) => string;
/**
* @throws Error if no config is found
*/
export declare function getConfig(tabUrl: string, getUnifiedConfigUrl: GetUnifiedConfigUrl): Promise<UnifiedConfig>;
export {};

1

dist/background/constants.d.ts
export declare const DEFAULT_TIMEOUT = 10000;
export declare const PAGE_STATE_DELAY = 200;
export declare const DEFAULT_GET_CONFIG_URL: (domain: string) => string;
import { type LoggerImplementation } from '@src/common/logger';
import { type GetUnifiedConfigUrl } from './config';
export interface BackgroundConfig {
getUnifiedConfigUrl: GetUnifiedConfigUrl;
/** @deprecated Used for e2e tests only */
getUnifiedConfigUrl?: GetUnifiedConfigUrl;
logger?: (tabId: number) => LoggerImplementation;
}
export declare function setupBackgroundListeners({ getUnifiedConfigUrl, logger, }: BackgroundConfig): void;

@@ -0,1 +1,2 @@

import { type ErrorLog, type InfoLog, type PerformanceLog } from '@src/common/logger';
import { type UnifiedConfig } from '@src/interfaces/unified-config.interfaces';

@@ -6,2 +7,3 @@ import { type Code, type TestedCode } from './code';

Stop = "caa-stop",
GetLog = "caa-get-log",
GetPageState = "caa-get-page-state"

@@ -24,3 +26,7 @@ }

}
export type ClientToBackgroundMessage = TryCodes | Stop | GetPageState;
export interface GetLog {
log: ErrorLog | PerformanceLog | InfoLog;
type: ClientToBackgroundMessageType.GetLog;
}
export type ClientToBackgroundMessage = TryCodes | Stop | GetPageState | GetLog;
export declare enum BackgroundToClientMessageType {

@@ -27,0 +33,0 @@ CodeTested = "caa-code-tested"

@@ -1,2 +0,7 @@

declare const LOG_LEVEL: {
/**
* To provide more control and transparency over side-effects, the actual implementation
* of the logging is implemented outside of the engine.
* Here we provide the interface of the logged data the client application should expect to receive.
*/
export declare const LOG_LEVEL: {
readonly ERROR: "ERROR";

@@ -33,2 +38,3 @@ readonly INFO: "INFO";

};
export declare function generateErrorStackTrace(error?: unknown): string;
export {};

@@ -0,1 +1,4 @@

/**
* Extract the main domain from a URL.
*/
export declare function getMainDomain(value: string): string;

@@ -0,1 +1,4 @@

/**
* Results of a code application/removal process UI controller should expect and handle.
*/
export declare enum CodeActionResultType {

@@ -6,4 +9,3 @@ Reloading = "Reloading",

Timeout = "Timeout",
NoRequiredSelectorsProvided = "NoRequiredSelectorsProvided",
ApplyAndRemoveButtonsHaveSameSelector = "ApplyAndRemoveButtonsHaveSameSelector"
NoRequiredSelectorsProvided = "NoRequiredSelectorsProvided"
}
import { type PageState } from '@src/interfaces/page-state.interfaces';
import { type UnifiedConfig } from '@src/interfaces/unified-config.interfaces';
/**
* Constructor function for parsing the checkout page.
* Returns a function which is used in the public API of the Engine.
*/
export declare function getPageState(config: UnifiedConfig): Promise<PageState>;

@@ -0,1 +1,4 @@

/**
* Type of a currency
*/
export declare enum AmountType {

@@ -6,6 +9,9 @@ Dollar = "$",

Pound = "\u00A3",
Real = "R$",
Zloty = "z\u0142",
Real = "R$",// https://en.wikipedia.org/wiki/Brazilian_real
Zloty = "z\u0142",// https://en.wikipedia.org/wiki/Polish_z%C5%82oty
Krona = "kr"
}
/**
* Output of a price parsing
*/
export interface ParsedAmount {

@@ -12,0 +18,0 @@ type?: AmountType;

@@ -1,1 +0,1 @@

(()=>{"use strict";var e={d:(t,n)=>{for(var o in n)e.o(n,o)&&!e.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:n[o]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{AmountType:()=>a,BackgroundToClientMessageType:()=>te,ClientToBackgroundMessageType:()=>ee,TestedCodeType:()=>Y,getElements:()=>v,getGeneratedSelector:()=>g,getMainDomain:()=>H,setupBackgroundListeners:()=>me,setupContentListeners:()=>X});let n=()=>{};function o(e){n=e}const r={error:(e,t)=>n({level:"ERROR",message:e,stack:t instanceof Error&&t.stack||(new Error).stack||""}),info:e=>n({details:JSON.stringify(e),level:"INFO"}),perf:(e,t)=>n({label:e,level:"PERF",meta:t})};var a;function i(e){if(!e)throw new Error("Cannot parse amount from empty value");if("string"!=typeof e)throw new Error(`Cannot parse amount from "${typeof e}"`);if(!e.match(/\d/))throw new Error(`Amount not found in "${e}"`);let t=e.replace(/[^0-9,.]/g,"");t.match(/^\d{1,3}(?:\.\d{3})*(?:,\d{2})?$/)&&(t=t.replaceAll(".","").replace(",",".")),t.match(/^\d{1,3}(?:,\d{3})*(?:.\d{2})?$/)&&(t=t.replaceAll(",","")),(t.match(/^\d*(?:,\d{2})?$/)||t.match(/^\d*(?:,\d{1})?$/))&&(t=t.replaceAll(",","."));const n=parseFloat(t.replace(/([^0-9.])/g,"")),o=function(e){let t=null;function n(e){null!==t&&t!==e?r.error(`Amount has conflicting types: ${t} and ${e}`):t=e}return(e.includes("€")||e.includes("EUR"))&&n(a.Euro),e.includes("$")&&(e.includes("R$")?n(a.Real):n(a.Dollar)),e.includes("£")&&n(a.Pound),e.includes("%")&&n(a.Percent),(e.includes("zł")||e.includes("PLN"))&&n(a.Zloty),(e.match(/\b\d*(kr)\d*\b/)||e.includes("SEK"))&&n(a.Krona),t}(e);return null!==o?{type:o,value:n}:{value:n}}!function(e){e.Dollar="$",e.Euro="€",e.Percent="%",e.Pound="£",e.Real="R$",e.Zloty="zł",e.Krona="kr"}(a||(a={}));const l="data-caa-text";function c(e){try{const[,t=""]=e.split('"');return Object(JSON.parse(decodeURI(t)))}catch{return{}}}function s(e){return c(e)}const u=/[0-9.,]+/g;function d(e){return e?e.normalize("NFC").replaceAll(u,""):null}function f({innerText:e,tagName:t}){return function(e){try{return encodeURI(JSON.stringify(e))}catch(e){return r.error("Cannot encode a custom cssSelector: ",e),""}}({innerText:e,tagName:t})}function p(e){const{tagName:t,innerText:n}=c(e);return e.includes(l)&&"string"==typeof t&&"string"==typeof n}function m(e){return p(e)}function y(e){const t=Array.from(document.querySelectorAll(e));return p(e)?t.length>0?t.filter((n=e,function(e){const{tagName:t,innerText:o}=s(n);return e.tagName===t&&d(e.innerText)===d(o)})):function(e){const{tagName:t,innerText:n}=s(e);return Array.from(document.getElementsByTagName(t)).filter((e=>e instanceof HTMLElement)).filter((e=>d(e.innerText)===d(n))).map((e=>(e.setAttribute(l,f(e)),e)))}(e):[];var n}function h(e){try{if(m(e)){const[t=null]=y(e);return t}return document.querySelector(e)}catch(t){return r.error(`Cannot find the element in the DOM with the selector="${e}":`,t),null}}function v(e){try{return m(e)?y(e):Array.from(document.querySelectorAll(e))}catch(t){return r.error(`Cannot find elements in the DOM with the selector="${e}":`,t),[]}}function g(e){const t=function(e){return`[${l}="${f(e)}"]`}(e);return 1===v(t).length?t:null}const b=function(){try{return"object"==typeof browser&&null!==browser&&"runtime"in browser?browser:chrome}catch{return console.warn("[CAA-ENGINE]: not running in a DOM environment, the browser object is not defined."),{}}}();var w,E;async function S(e=500){return new Promise((t=>setTimeout(t,e)))}function C(e,t){return"object"==typeof e&&null!==e&&t in e}function P(e){return!C(e,"disabled")||!e.disabled}function T(e){return!!P(e)&&"none"!==window.getComputedStyle(e).getPropertyValue("pointer-events")}function B(e){if(e.hidden)return!1;const t=window.getComputedStyle(e);return"hidden"!==t.getPropertyValue("visibility")&&"0"!==t.getPropertyValue("opacity")&&"none"!==t.getPropertyValue("display")&&0!==e.offsetWidth&&0!==e.offsetHeight}function A(e){return P(e)&&T(e)&&B(e)}function M(e){return"INPUT"!==e.tagName&&!e.innerHTML.length}!function(e){e.GetPageState="caa-get-page-state",e.ApplyCode="caa-apply-code",e.RemoveCode="caa-remove-code"}(w||(w={})),function(e){e.Reloading="Reloading",e.Done="Done",e.UnhandledError="UnhandledError",e.Timeout="Timeout",e.NoRequiredSelectorsProvided="NoRequiredSelectorsProvided",e.ApplyAndRemoveButtonsHaveSameSelector="ApplyAndRemoveButtonsHaveSameSelector"}(E||(E={}));const I=1e3;function $(e=.5){return new Promise((t=>setTimeout(t,e*I)))}function N(e){e.dispatchEvent(new PointerEvent("pointerdown",{bubbles:!0,pointerType:"mouse"})),e.dispatchEvent(new MouseEvent("mousedown",{bubbles:!0})),e.dispatchEvent(new PointerEvent("pointerup",{bubbles:!0,pointerType:"mouse"})),e.dispatchEvent(new MouseEvent("mouseup",{bubbles:!0})),e.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0}))}async function R(e,t=0,n=0){if(!e.closeModal)return;if(t>=4)throw E.Timeout;const o=h(e.closeModal);if(!o||!A(o)){if(t>0||n>=4)return;return await S(),R(e,t,n+1)}return r.info("Trying to close modal"),N(o),await S(),R(e,t+1)}function k(e){const t=e&&h(e);return!!t&&B(t)}const F=4;function L(e){return e.loading?function(e){const t={bodyObserver:null,isLoading:k(e)};return[new Promise((n=>{t.bodyObserver=new MutationObserver((()=>{k(e)?t.isLoading=!0:t.isLoading&&n()})),t.bodyObserver.observe(document.body,{attributes:!0,childList:!0,subtree:!0})})),()=>t.bodyObserver?.disconnect()]}(e.loading):[void 0,()=>{}]}function V(e){const[t,n]=function(e){const t={pending:!0};return[(async()=>{for(let n=0;n<F;n++){const n=[e.error,e.removeButton,e.appliedCode];if(!t.pending||n.some(k))break;r.info("Waiting for feedback"),await $()}})(),()=>{t.pending=!1}]}(e),[o,a]=L(e),i=[t,o].filter(Boolean),l=[n,a];return Promise.race(i).finally((()=>{l.forEach((e=>e()))}))}function U(e,t){const n=h(e);return!!(n&&(o=n,C(o,"value")&&A(o)))&&(r.info("Trying to fill in the code"),function(e,t){const{value:n}=e;if(e.value=t,C(e,"_valueTracker")&&e._valueTracker){const t=e._valueTracker;C(t,"setValue")&&"function"==typeof t.setValue&&t.setValue(n)}e.dispatchEvent(new KeyboardEvent("keydown",{bubbles:!0})),e.dispatchEvent(new KeyboardEvent("keypress",{bubbles:!0})),e.dispatchEvent(new KeyboardEvent("input",{bubbles:!0})),e.dispatchEvent(new KeyboardEvent("keyup",{bubbles:!0})),e.dispatchEvent(new Event("change",{bubbles:!0}))}(n,t),!0);var o}function D(e){const t=h(e);return!(!t||!A(t)||(r.info("Trying to submit the code"),N(t),0))}async function O(e,t){for(let n=0;n<10&&!(e.couponInput&&U(e.couponInput,t)&&(await S(),e.applyButton&&D(e.applyButton)));n++);}function x(e){switch(e){case E.Reloading:return E.Reloading;case E.Timeout:return E.Timeout;case E.NoRequiredSelectorsProvided:return E.NoRequiredSelectorsProvided;default:return E.UnhandledError}}function H(e){const t=e.toLowerCase().replace(/^https?:\/\//,"").replace(/:\d+.*/,"").replace(/(:|\/|\?|#).*/,"");if(!/[a-z0-9-.]+/.test(t))throw new Error(`Cannot get main domain from ${e}`);const[n,o,r]=t.split(".").reverse();if("localhost"===n)return n;if(!n||n.length<2)throw new Error(`Wrong root domain "${n}" in ${e}`);if(!o)throw new Error(`Unknown main domain "${o}" in ${e}`);if(!["co.uk","co.za","com.au","com.de","org.uk","uk.com","com.br","com.pl","com.nl","com.mx","com.at","co.at","com.se"].includes(`${o}.${n}`))return`${o}.${n}`;if(!r)throw new Error(`Unknown main domain "${r}" in ${e}`);return`${r}.${o}.${n}`}var q;function j(e){try{if(!e)return{html:"",isClickable:!1,isEmpty:!0,isEnabled:!1,isVisible:!1,multipleMatches:!1,result:q.NoSelectorProvided};const t=v(e),[n]=t;return n?{html:n.outerHTML,isClickable:Boolean(t.filter(T).length),isEmpty:M(n),isEnabled:Boolean(t.filter(P).length),isVisible:Boolean(t.filter(B).length),multipleMatches:t.length>1,result:q.ElementFound}:{html:"",isClickable:!1,isEmpty:!0,isEnabled:!1,isVisible:!1,multipleMatches:!1,result:q.NoElementsFound}}catch(e){return e instanceof Error&&"SyntaxError"===e.name?(r.error(q.InvalidCSSSelector,e),{html:"",isClickable:!1,isEmpty:!0,isEnabled:!1,isVisible:!1,multipleMatches:!1,result:q.InvalidCSSSelector}):(r.error(q.Unhandled,e),{html:"",isClickable:!1,isEmpty:!0,isEnabled:!1,isVisible:!1,multipleMatches:!1,result:q.Unhandled})}}function G(e){if(!e)return!1;const t=e.totalAmount?v(e.totalAmount):[],n=e.couponInput?v(e.couponInput).filter(A):[],o=e.applyButton?v(e.applyButton).filter(B):[],r=e.showFormButton?v(e.showFormButton).filter(A):[];return Boolean(n.length)&&Boolean(o.length)&&Boolean(t.length)||Boolean(t.length)&&Boolean(r.length)}function K(e){if(!e||!e.removeButton)return!1;const t=v(e.removeButton).filter(A);return Boolean(t.length)}function z(e){try{if(!e)return{html:"",isEmpty:!0,isVisible:!1,multipleMatches:!1,result:q.NoSelectorProvided};const t=v(e),[n]=t;return n?{amount:i(n.innerText),html:n.outerHTML,isEmpty:M(n),isVisible:Boolean(t.filter(B).length),multipleMatches:t.length>1,result:q.ElementFound}:{html:"",isEmpty:!0,isVisible:!1,multipleMatches:!1,result:q.NoElementsFound}}catch(e){return e instanceof Error&&"SyntaxError"===e.name?(r.error(q.InvalidCSSSelector,e),{html:"",isEmpty:!0,isVisible:!1,multipleMatches:!1,result:q.InvalidCSSSelector}):(r.error(q.Unhandled,e),{html:"",isEmpty:!0,isVisible:!1,multipleMatches:!1,result:q.Unhandled})}}function W(e){try{if(!e)return{html:"",isEmpty:!0,isVisible:!1,multipleMatches:!1,result:q.NoSelectorProvided,value:""};const t=v(e),[n]=t;return n?{html:n.outerHTML,isEmpty:M(n),isVisible:Boolean(t.filter(B).length),multipleMatches:t.length>1,result:q.ElementFound,value:n.innerHTML}:{html:"",isEmpty:!0,isVisible:!1,multipleMatches:!1,result:q.NoElementsFound,value:""}}catch(e){return e instanceof Error&&"SyntaxError"===e.name?(r.error(q.InvalidCSSSelector,e),{html:"",isEmpty:!0,isVisible:!1,multipleMatches:!1,result:q.InvalidCSSSelector,value:""}):(r.error(q.Unhandled,e),{html:"",isEmpty:!0,isVisible:!1,multipleMatches:!1,result:q.Unhandled,value:""})}}function _(){return window.location.href}!function(e){e.ElementFound="ElementFound",e.NoSelectorProvided="NoSelectorProvided",e.Unhandled="Unhandled",e.NoElementsFound="NoElementsFound",e.InvalidCSSSelector="InvalidCSSSelector",e.NoConfigProvided="NoConfigProvided"}(q||(q={}));const J={applyCode:async function(e,t){return new Promise((n=>{const o=()=>{r.info("Page is about to reload."),n({type:E.Reloading})};(async()=>{try{if(!e.couponInput||!e.applyButton)throw E.NoRequiredSelectorsProvided;r.info(`Preparing to apply code: ${t}`),window.addEventListener("beforeunload",o),await async function(e){if(e.showFormButton){for(let t=0;t<4;t++){const t=e.couponInput&&h(e.couponInput);if(t&&A(t))return;const n=h(e.showFormButton);n&&A(n)&&(r.info("Trying to show the coupon form"),N(n)),await S()}throw E.Timeout}}(e),await O(e,t),await V(e),await R(e),r.info(`Code: ${t} applied.`),n({type:E.Done})}catch(e){const o=x(e);r.error(`Failed to apply code: ${t} -- ${o}`,e),n({type:o})}finally{window.removeEventListener("beforeunload",o),r.info("beforeunload listener removed.")}})()}))},getPageState:async function(e){return{amounts:{discount:z(e.discountAmount),subtotal:z(e.subtotalAmount),total:z(e.totalAmount)},coupon:{appliedCode:W(e.appliedCode),canApply:G(e),canRemove:K(e)},currentUrl:_(),elements:{applyButton:j(e.applyButton),closeModal:j(e.closeModal),couponInput:j(e.couponInput),error:j(e.error),loading:j(e.loading),removeButton:j(e.removeButton),showFormButton:j(e.showFormButton)},mainDomain:H(_())}},removeCode:async function(e){let t=!1;try{if(!e.removeButton)throw E.NoRequiredSelectorsProvided;if(e.removeButton===e.applyButton)throw E.ApplyAndRemoveButtonsHaveSameSelector;return r.info("Trying to remove applied code."),window.addEventListener("beforeunload",n),await async function n(o=0){if(o>=4)throw E.Timeout;if(t)throw E.Reloading;if(!e.removeButton)return;const a=h(e.removeButton);return a&&A(a)?(N(a),r.info("Waiting for coupon is removed"),await S(),n(o+1)):void 0}(),r.info("Code removed."),{type:E.Done}}catch(e){let t;switch(r.error("Failed to remove the code",e),e){case E.Reloading:t=E.Reloading;break;case E.ApplyAndRemoveButtonsHaveSameSelector:t=E.ApplyAndRemoveButtonsHaveSameSelector;break;default:t=E.UnhandledError}return{type:t}}finally{window.removeEventListener("beforeunload",n),r.info("beforeunload listener removed.")}function n(){r.info("Page is about to reload."),t=!0}}};const Z={applyCode:async function(e,t){return new Promise((n=>{const o=()=>{r.info("Page is about to reload."),n({type:E.Reloading})};(async()=>{try{if(!e.couponInput||!e.applyButton)throw E.NoRequiredSelectorsProvided;r.info(`Preparing to apply code: ${t}`),window.addEventListener("beforeunload",o),await function(e,t){return"/br/checkout/"===e.urlPattern?async function(e,t){await O(e,t),await V(e)}(e,t):function(e,t){const[n,o]=L(e);for(let r=0;r<10;r++)if(e.couponInput&&U(e.couponInput,t)){const t=[n,S(2e3)].filter(Boolean);return Promise.race(t).then((()=>{e.applyButton&&D(e.applyButton)})).finally((()=>{o()}))}return Promise.resolve()}(e,t)}(e,t),r.info(`Code: ${t} applied.`),n({type:E.Done})}catch(e){const o=x(e);r.error(`Failed to apply code: ${t} -- ${o}`,e),n({type:o})}finally{window.removeEventListener("beforeunload",o),r.info("beforeunload listener removed.")}})()}))},getPageState:J.getPageState,removeCode:J.removeCode};function Q(e){return"samsung.com"===e.domain?Z:J}function X({logger:e=(()=>{})}={}){b.runtime.onMessage.addListener(((t,n,r)=>{switch(o(e),t.type){case w.GetPageState:{const{getPageState:e}=Q(t.config);return e(t.config).then(r),!0}case w.ApplyCode:{const{applyCode:e}=Q(t.config);return e(t.config,t.code).then(r),!0}case w.RemoveCode:{const{removeCode:e}=Q(t.config);return e(t.config).then(r),!0}}}))}var Y,ee,te,ne;!function(e){e.Discount="Discount",e.Invalid="Invalid"}(Y||(Y={})),function(e){e.TryCodes="caa-try-codes",e.Stop="caa-stop",e.GetPageState="caa-get-page-state"}(ee||(ee={})),function(e){e.CodeTested="caa-code-tested"}(te||(te={})),function(e){e.PageLoaded="caa-page-loaded"}(ne||(ne={}));const oe=1e4,re=200;async function ae(e,t,n){return new Promise((async o=>{let a=!1;const i=setTimeout((()=>{a=!0,o(null)}),oe);for(;!a;){try{const r=await b.tabs.sendMessage(e,{config:t,type:w.GetPageState});if(r&&(!n||n(r)))return clearTimeout(i),void o(r)}catch(e){r.error("get caa page state",e)}await S(re)}}))}async function ie(e,t,n){const o=await ae(e,n,(e=>!!e?.amounts.total.amount));if(!o)return{...t,type:Y.Invalid};let a=o.amounts.total.amount;if(o.elements.removeButton.isClickable){try{await async function(e,t){let n=10;try{await b.tabs.sendMessage(e,{config:t,type:w.RemoveCode})}catch(e){r.error("remove caa-engine error",e)}for(;n>0;){n--;const o=await ae(e,t);if(o){if(!o.elements.removeButton.isVisible)return;await S(200)}}if(!n)throw new Error("remove code is not removed")}(e,n)}catch(e){return r.error("remove code caa-background",e),{...t,type:Y.Invalid}}const o=await ae(e,n);if(!o)return{...t,type:Y.Invalid};!o.elements.removeButton.isVisible&&o.amounts.total.amount&&(a=o.amounts.total.amount)}try{const o=await b.tabs.sendMessage(e,{code:t.code,config:n,type:w.ApplyCode});r.info({codeApplicationResult:o})}catch(e){r.error("apply code caa-from-content",e)}let i=10;for(;i>0;){i--;const o=await ae(e,n,(e=>!!e?.amounts.total.amount));if(!o){await S(re);continue}const r=o.amounts.total.amount;if(a&&r&&r.value<a.value)return{...t,initialTotal:a,totalWithDiscount:r,type:Y.Discount};await S(re)}return r.info("timeout handleApplyProcess"),{...t,type:Y.Invalid}}const le=new Map;async function ce(e,t){const n=H(e),o=new URL(e).pathname,r=await t(n),a=await async function(e,t){const n=le.get(e);if(n?.length)return n;const o=await fetch(t).then((e=>e.json())).then(se).catch((()=>[]));return le.set(e,o),o}(n,r).then(ue);let i=null,l=null;for(const e of a)e.urlPattern?new RegExp(e.urlPattern).test(o)&&(l=e):i=e;if(l)return l;if(i)return i;throw new Error(`No config found for ${n}`)}function se(e){const t=e,n=[];for(const e of t.configs){const t=e;t.data&&(t.disabled||n.push({appliedCode:t.data.appliedCode||void 0,applyButton:t.data.applyButton||void 0,applyType:t.data.applyType||void 0,closeModal:t.data.closeModal||void 0,couponInput:t.data.couponInput||void 0,discountAmount:t.data.discountAmount||void 0,domain:t.data.domain||"",error:t.data.error||void 0,loading:t.data.loading||void 0,removeButton:t.data.removeButton||void 0,showFormButton:t.data.showFormButton||void 0,subtotalAmount:t.data.subtotalAmount||void 0,totalAmount:t.data.totalAmount||void 0,urlPattern:t.data.urlPattern||void 0}))}return n}function ue(e){return e.sort(((e,t)=>e.urlPattern?t.urlPattern?e.urlPattern.length-t.urlPattern.length:1:-1))}class de{active;testedCodes=new Map;constructor(){this.active=!0}get isActive(){return this.active}stop(){this.active=!1}addTestedCode(e,t){this.testedCodes.set(e,t)}getTestedCode(e){return this.testedCodes.get(e)}}function fe(e){return e.code.trim().length&&!/\s/.test(e.code.trim())}const pe=new Map;function me({getUnifiedConfigUrl:e,logger:t=(()=>()=>{})}){b.runtime.onMessage.addListener(((n,a,i)=>{const l=a.tab?.id,c=a.tab?.url;if(void 0!==l)if(o(t(l)),void 0!==c)switch(n.type){case ne.PageLoaded:return void r.info({message:n,tabId:l});case ee.Stop:return r.info({message:n,tabId:l}),pe.get(l)?.stop(),void r.info("stopping CAA for tab"+l);case ee.TryCodes:return r.info({message:n,tabId:l}),void async function(e,t,n,{codes:o,cacheDuplicates:a=!1,validateCodes:i=!1,minDelay:l=1e3,config:c}){let s;try{s=c||await ce(t,n)}catch(e){return void r.error("Cannot get config for "+t,e)}r.info("starting CAA for tab "+e);const u=new de;pe.set(e,u);for(const t of o){if(!u.isActive)break;const n=u.getTestedCode(t.code);if(a&&n){await S(l),await ye(e,{...n,...t});continue}if(i&&!fe(t)){await S(l),await ye(e,{...t,type:Y.Invalid});continue}const o=(new Date).getTime(),c=await ie(e,t,s);r.perf(t.code+" tested in: ",{code:t.code,timeSpent:(new Date).getTime()-o}),u.addTestedCode(t.code,c),await ye(e,c)}pe.delete(e)}(l,c,e,n);case ee.GetPageState:return r.info({message:n,tabId:l}),async function(e,t,n,o){let a;if(o)a=o;else try{a=await ce(t,n)}catch(e){return void r.error("No config exists for: "+t,e)}const i=await ae(e,a);return r.info({pageState:i,tabId:e}),i}(l,c,e,n.config).then(i),!0}else r.error("No tabUrl provided for "+l);else console.warn("No tabId provided")}))}async function ye(e,t){r.info({code:t,info:"sending tried code",tabId:e});const n={code:t,type:te.CodeTested};let o=!1;for(let a=0;a<10;a++){try{await he(e),o=await b.tabs.sendMessage(e,n)}catch(n){r.info({code:t,info:"Tried code not received by the tab.",tabId:e})}if(o)break;await S(200)}if(!o)throw new Error(`Cannot send tried code to the browser tab. code: ${t.code} , tabId: ${e}`)}async function he(e){let t=10;for(;t--;){if("complete"===(await b.tabs.get(e)).status)return;await S(100)}}module.exports=t})();
(()=>{"use strict";var e={d:(t,n)=>{for(var o in n)e.o(n,o)&&!e.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:n[o]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{AmountType:()=>l,BackgroundToClientMessageType:()=>P,ClientToBackgroundMessageType:()=>C,TestedCodeType:()=>ie,getElements:()=>b,getGeneratedSelector:()=>w,getMainDomain:()=>W,setupBackgroundListeners:()=>he,setupContentListeners:()=>re});const n={ERROR:"ERROR",INFO:"INFO",PERF:"PERF"};let o=()=>{};function r(e){o=e}const i={error:(e,t)=>o({level:n.ERROR,message:e,stack:a(t)}),info:e=>o({details:JSON.stringify(e),level:n.INFO}),perf:(e,t)=>o({label:e,level:n.PERF,meta:t})};function a(e){const t=e instanceof Error?e:new Error("string"==typeof e?e:void 0),{stack:n=""}=t;return n}var l;function s(e){if(!e)throw new Error("Cannot parse amount from empty value");if("string"!=typeof e)throw new Error(`Cannot parse amount from "${typeof e}"`);if(!e.match(/\d/))throw new Error(`Amount not found in "${e}"`);let t=e.replace(/[^0-9,.]/g,"");t.match(/^\d{1,3}(?:\.\d{3})*(?:,\d{2})?$/)&&(t=t.replaceAll(".","").replace(",",".")),t.match(/^\d{1,3}(?:,\d{3})*(?:.\d{2})?$/)&&(t=t.replaceAll(",","")),(t.match(/^\d*(?:,\d{2})?$/)||t.match(/^\d*(?:,\d{1})?$/))&&(t=t.replaceAll(",","."));const n=parseFloat(t.replace(/([^0-9.])/g,"")),o=function(e){let t=null;function n(e){null!==t&&t!==e?i.error(`Amount has conflicting types: ${t} and ${e}`):t=e}return(e.includes("€")||e.includes("EUR"))&&n(l.Euro),e.includes("$")&&(e.includes("R$")?n(l.Real):n(l.Dollar)),e.includes("£")&&n(l.Pound),e.includes("%")&&n(l.Percent),(e.includes("zł")||e.includes("PLN"))&&n(l.Zloty),(e.match(/\b\d*(kr)\d*\b/)||e.includes("SEK"))&&n(l.Krona),t}(e);return null!==o?{type:o,value:n}:{value:n}}!function(e){e.Dollar="$",e.Euro="€",e.Percent="%",e.Pound="£",e.Real="R$",e.Zloty="zł",e.Krona="kr"}(l||(l={}));const c="data-caa-text";function u(e){try{const[,t=""]=e.split('"');return Object(JSON.parse(decodeURI(t)))}catch{return{}}}function d(e){return u(e)}const f=/[0-9.,]+/g;function m(e){return e?e.normalize("NFC").replaceAll(f,""):null}function p({innerText:e,tagName:t}){return function(e){try{return encodeURI(JSON.stringify(e))}catch(e){return i.error("Cannot encode a custom cssSelector: ",e),""}}({innerText:e,tagName:t})}function g(e){const{tagName:t,innerText:n}=u(e);return e.includes(c)&&"string"==typeof t&&"string"==typeof n}function v(e){return g(e)}function y(e){const t=Array.from(document.querySelectorAll(e));return g(e)?t.length>0?t.filter((n=e,function(e){const{tagName:t,innerText:o}=d(n);return e.tagName===t&&m(e.innerText)===m(o)})):function(e){const{tagName:t,innerText:n}=d(e);return Array.from(document.getElementsByTagName(t)).filter((e=>e instanceof HTMLElement)).filter((e=>m(e.innerText)===m(n))).map((e=>(e.setAttribute(c,p(e)),e)))}(e):[];var n}function h(e){try{if(v(e)){const[t=null]=y(e);return t}return document.querySelector(e)}catch(t){return i.error(`Cannot find the element in the DOM with the selector="${e}":`,t),null}}function b(e){try{return v(e)?y(e):Array.from(document.querySelectorAll(e))}catch(t){return i.error(`Cannot find elements in the DOM with the selector="${e}":`,t),[]}}function w(e){const t=function(e){return`[${c}="${p(e)}"]`}(e);return 1===b(t).length?t:null}const E=function(){try{return"object"==typeof browser&&null!==browser&&"runtime"in browser?browser:chrome}catch{return console.warn("[CAA-ENGINE]: not running in a DOM environment, the browser object is not defined."),{}}}();var R,C,P,S,I;function N(e){E.runtime.sendMessage({log:e,type:C.GetLog})}async function T(e=500){return new Promise((t=>setTimeout(t,e)))}function O(e,t){return"object"==typeof e&&null!==e&&t in e}function B(e){return!O(e,"disabled")||!e.disabled}function F(e){return!!B(e)&&"none"!==window.getComputedStyle(e).getPropertyValue("pointer-events")}function M(e){if(e.hidden)return!1;const t=window.getComputedStyle(e);return"hidden"!==t.getPropertyValue("visibility")&&"0"!==t.getPropertyValue("opacity")&&"none"!==t.getPropertyValue("display")&&0!==e.offsetWidth&&0!==e.offsetHeight}function $(e){return B(e)&&F(e)&&M(e)}function k(e){return"INPUT"!==e.tagName&&!e.innerHTML.length}!function(e){e.GetPageState="caa-get-page-state",e.ApplyCode="caa-apply-code",e.RemoveCode="caa-remove-code"}(R||(R={})),function(e){e.TryCodes="caa-try-codes",e.Stop="caa-stop",e.GetLog="caa-get-log",e.GetPageState="caa-get-page-state"}(C||(C={})),function(e){e.CodeTested="caa-code-tested"}(P||(P={})),function(e){e.PageLoaded="caa-page-loaded"}(S||(S={})),function(e){e.Reloading="Reloading",e.Done="Done",e.UnhandledError="UnhandledError",e.Timeout="Timeout",e.NoRequiredSelectorsProvided="NoRequiredSelectorsProvided"}(I||(I={}));const A=1e3;function L(e=.5){return new Promise((t=>setTimeout(t,e*A)))}function V(e){e.dispatchEvent(new PointerEvent("pointerdown",{bubbles:!0,pointerType:"mouse"})),e.dispatchEvent(new MouseEvent("mousedown",{bubbles:!0})),e.dispatchEvent(new PointerEvent("pointerup",{bubbles:!0,pointerType:"mouse"})),e.dispatchEvent(new MouseEvent("mouseup",{bubbles:!0})),e.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0}))}async function U(e,t=0,o=0){if(!e.closeModal)return;if(t>=4)throw I.Timeout;const r=h(e.closeModal);if(!r||!$(r)){if(t>0||o>=4)return;return await T(),U(e,t,o+1)}return N({details:"Trying to close modal",level:n.INFO}),V(r),await T(),U(e,t+1)}function D(e){const t=e&&h(e);return!!t&&M(t)}const x=4;function j(e){return e.loading?function(e){const t={bodyObserver:null,isLoading:D(e)};return[new Promise((n=>{t.bodyObserver=new MutationObserver((()=>{D(e)?t.isLoading=!0:t.isLoading&&n()})),t.bodyObserver.observe(document.body,{attributes:!0,childList:!0,subtree:!0})})),()=>t.bodyObserver?.disconnect()]}(e.loading):[void 0,()=>{}]}function q(e){const[t,o]=function(e){const t={pending:!0};return[(async()=>{for(let o=0;o<x;o++){const o=[e.error,e.removeButton,e.appliedCode];if(!t.pending||o.some(D))break;N({details:"Waiting for feedback",level:n.INFO}),await L()}})(),()=>{t.pending=!1}]}(e),[r,i]=j(e),a=[t,r].filter(Boolean),l=[o,i];return Promise.race(a).finally((()=>{l.forEach((e=>e()))}))}function G(e,t){const o=h(e);return!!(o&&(r=o,O(r,"value")&&$(r)))&&(N({details:"Trying to fill in the code",level:n.INFO}),function(e,t){const{value:n}=e;if(e.value=t,O(e,"_valueTracker")&&e._valueTracker){const t=e._valueTracker;O(t,"setValue")&&"function"==typeof t.setValue&&t.setValue(n)}e.dispatchEvent(new KeyboardEvent("keydown",{bubbles:!0})),e.dispatchEvent(new KeyboardEvent("keypress",{bubbles:!0})),e.dispatchEvent(new KeyboardEvent("input",{bubbles:!0})),e.dispatchEvent(new KeyboardEvent("keyup",{bubbles:!0})),e.dispatchEvent(new Event("change",{bubbles:!0}))}(o,t),!0);var r}function H(e){const t=h(e);return!(!t||!$(t)||(N({details:"Trying to submit the code",level:n.INFO}),V(t),0))}async function K(e,t){for(let n=0;n<10&&!(e.couponInput&&G(e.couponInput,t)&&(await T(),e.applyButton&&H(e.applyButton)));n++);}function z(e){switch(e){case I.Reloading:return I.Reloading;case I.Timeout:return I.Timeout;case I.NoRequiredSelectorsProvided:return I.NoRequiredSelectorsProvided;default:return I.UnhandledError}}function W(e){const t=e.toLowerCase().replace(/^https?:\/\//,"").replace(/:\d+.*/,"").replace(/(:|\/|\?|#).*/,"");if(!/[a-z0-9-.]+/.test(t))throw new Error(`Cannot get main domain from ${e}`);const[n,o,r]=t.split(".").reverse();if("localhost"===n)return n;if(!n||n.length<2)throw new Error(`Wrong root domain "${n}" in ${e}`);if(!o)throw new Error(`Unknown main domain "${o}" in ${e}`);if(!["co.uk","co.za","com.au","com.de","org.uk","uk.com","com.br","com.pl","com.nl","com.mx","com.at","co.at","com.se"].includes(`${o}.${n}`))return`${o}.${n}`;if(!r)throw new Error(`Unknown main domain "${r}" in ${e}`);return`${r}.${o}.${n}`}var _;function J(e){try{if(!e)return{html:"",isClickable:!1,isEmpty:!0,isEnabled:!1,isVisible:!1,multipleMatches:!1,result:_.NoSelectorProvided};const t=b(e),[n]=t;return n?{html:n.outerHTML,isClickable:Boolean(t.filter(F).length),isEmpty:k(n),isEnabled:Boolean(t.filter(B).length),isVisible:Boolean(t.filter(M).length),multipleMatches:t.length>1,result:_.ElementFound}:{html:"",isClickable:!1,isEmpty:!0,isEnabled:!1,isVisible:!1,multipleMatches:!1,result:_.NoElementsFound}}catch(e){return e instanceof Error&&"SyntaxError"===e.name?(N({level:n.ERROR,message:_.InvalidCSSSelector,stack:a(e)}),{html:"",isClickable:!1,isEmpty:!0,isEnabled:!1,isVisible:!1,multipleMatches:!1,result:_.InvalidCSSSelector}):(N({level:n.ERROR,message:_.Unhandled,stack:a(e)}),{html:"",isClickable:!1,isEmpty:!0,isEnabled:!1,isVisible:!1,multipleMatches:!1,result:_.Unhandled})}}function Z(e){if(!e)return!1;const t=e.totalAmount?b(e.totalAmount):[],n=e.couponInput?b(e.couponInput).filter($):[],o=e.applyButton?b(e.applyButton).filter(M):[],r=e.showFormButton?b(e.showFormButton).filter($):[];return Boolean(n.length)&&Boolean(o.length)&&Boolean(t.length)||Boolean(t.length)&&Boolean(r.length)}function Q(e){if(!e||!e.removeButton)return!1;const t=b(e.removeButton).filter($);return Boolean(t.length)}function X(e){try{if(!e)return{html:"",isEmpty:!0,isVisible:!1,multipleMatches:!1,result:_.NoSelectorProvided};const t=b(e),[n]=t;return n?{amount:s(n.innerText),html:n.outerHTML,isEmpty:k(n),isVisible:Boolean(t.filter(M).length),multipleMatches:t.length>1,result:_.ElementFound}:{html:"",isEmpty:!0,isVisible:!1,multipleMatches:!1,result:_.NoElementsFound}}catch(e){return e instanceof Error&&"SyntaxError"===e.name?(N({level:n.ERROR,message:_.InvalidCSSSelector,stack:a(e)}),{html:"",isEmpty:!0,isVisible:!1,multipleMatches:!1,result:_.InvalidCSSSelector}):(N({level:n.ERROR,message:_.Unhandled,stack:a(e)}),{html:"",isEmpty:!0,isVisible:!1,multipleMatches:!1,result:_.Unhandled})}}function Y(e){try{if(!e)return{html:"",isEmpty:!0,isVisible:!1,multipleMatches:!1,result:_.NoSelectorProvided,value:""};const t=b(e),[n]=t;return n?{html:n.outerHTML,isEmpty:k(n),isVisible:Boolean(t.filter(M).length),multipleMatches:t.length>1,result:_.ElementFound,value:n.innerHTML}:{html:"",isEmpty:!0,isVisible:!1,multipleMatches:!1,result:_.NoElementsFound,value:""}}catch(e){return e instanceof Error&&"SyntaxError"===e.name?(N({level:n.ERROR,message:_.InvalidCSSSelector,stack:a(e)}),{html:"",isEmpty:!0,isVisible:!1,multipleMatches:!1,result:_.InvalidCSSSelector,value:""}):(N({level:n.ERROR,message:_.Unhandled,stack:a(e)}),{html:"",isEmpty:!0,isVisible:!1,multipleMatches:!1,result:_.Unhandled,value:""})}}function ee(){return window.location.href}!function(e){e.ElementFound="ElementFound",e.NoSelectorProvided="NoSelectorProvided",e.Unhandled="Unhandled",e.NoElementsFound="NoElementsFound",e.InvalidCSSSelector="InvalidCSSSelector",e.NoConfigProvided="NoConfigProvided"}(_||(_={}));const te={applyCode:async function(e,t){return new Promise((o=>{const r=()=>{N({details:"Page is about to reload.",level:n.INFO}),o({type:I.Reloading})};(async()=>{try{if(!e.couponInput||!e.applyButton)throw I.NoRequiredSelectorsProvided;N({details:`Preparing to apply code: ${t}`,level:n.INFO}),window.addEventListener("beforeunload",r),await async function(e){if(e.showFormButton){for(let t=0;t<4;t++){const t=e.couponInput&&h(e.couponInput);if(t&&$(t))return;const o=h(e.showFormButton);o&&$(o)&&(N({details:"Trying to show the coupon form",level:n.INFO}),V(o)),await T()}throw I.Timeout}}(e),await K(e,t),await q(e),await U(e),N({details:`Code: ${t} applied.`,level:n.INFO}),o({type:I.Done})}catch(e){const r=z(e);N({level:n.ERROR,message:`Failed to apply code: ${t} -- ${r}`,stack:a(e)}),o({type:r})}finally{window.removeEventListener("beforeunload",r),N({details:"beforeunload listener removed.",level:n.INFO})}})()}))},getPageState:async function(e){return{amounts:{discount:X(e.discountAmount),subtotal:X(e.subtotalAmount),total:X(e.totalAmount)},coupon:{appliedCode:Y(e.appliedCode),canApply:Z(e),canRemove:Q(e)},currentUrl:ee(),elements:{applyButton:J(e.applyButton),closeModal:J(e.closeModal),couponInput:J(e.couponInput),error:J(e.error),loading:J(e.loading),removeButton:J(e.removeButton),showFormButton:J(e.showFormButton)},mainDomain:W(ee())}},removeCode:async function(e){let t=!1;try{if(!e.removeButton)throw I.NoRequiredSelectorsProvided;return N({details:"Trying to remove applied code.",level:n.INFO}),window.addEventListener("beforeunload",o),await async function o(r=0){if(r>=4)throw I.Timeout;if(t)throw I.Reloading;if(!e.removeButton)return;const i=h(e.removeButton);return i&&$(i)?(V(i),N({details:"Waiting for coupon is removed",level:n.INFO}),await T(),o(r+1)):void 0}(),N({details:"Code removed.",level:n.INFO}),{type:I.Done}}catch(e){let t;return N({level:n.ERROR,message:"Failed to remove the code",stack:a(e)}),t=e===I.Reloading?I.Reloading:I.UnhandledError,{type:t}}finally{window.removeEventListener("beforeunload",o),N({details:"beforeunload listener removed.",level:n.INFO})}function o(){N({details:"Page is about to reload.",level:n.INFO}),t=!0}}};const ne={applyCode:async function(e,t){return new Promise((o=>{const r=()=>{N({details:"Page is about to reload.",level:n.INFO}),o({type:I.Reloading})};(async()=>{try{if(!e.couponInput||!e.applyButton)throw I.NoRequiredSelectorsProvided;N({details:`Preparing to apply code: ${t}`,level:n.INFO}),window.addEventListener("beforeunload",r),await function(e,t){return"/br/"===e.urlPattern?async function(e,t){await K(e,t),await q(e)}(e,t):function(e,t){const[n,o]=j(e);for(let r=0;r<10;r++)if(e.couponInput&&G(e.couponInput,t)){const t=[n,T(2e3)].filter(Boolean);return Promise.race(t).then((()=>{e.applyButton&&H(e.applyButton)})).finally((()=>{o()}))}return Promise.resolve()}(e,t)}(e,t),N({details:`Code: ${t} applied.`,level:n.INFO}),o({type:I.Done})}catch(e){const r=z(e);N({level:n.ERROR,message:`Failed to apply code: ${t} -- ${r}`,stack:a(e)}),o({type:r})}finally{window.removeEventListener("beforeunload",r),N({details:"beforeunload listener removed.",level:n.INFO})}})()}))},getPageState:te.getPageState,removeCode:te.removeCode};function oe(e){return"samsung.com"===e.domain?ne:te}function re({logger:e=(()=>{})}={}){E.runtime.onMessage.addListener(((t,n,o)=>{switch(r(e),t.type){case R.GetPageState:{const{getPageState:e}=oe(t.config);return e(t.config).then(o),!0}case R.ApplyCode:{const{applyCode:e}=oe(t.config);return e(t.config,t.code).then(o),!0}case R.RemoveCode:{const{removeCode:e}=oe(t.config);return e(t.config).then(o),!0}}}))}var ie;!function(e){e.Discount="Discount",e.Invalid="Invalid"}(ie||(ie={}));const ae=1e4,le=200,se=e=>`https://caa-configurations.gsg-extension.com/${e}.json`;async function ce(e,t,n){return new Promise((async o=>{let r=!1;const a=setTimeout((()=>{r=!0,o(null)}),ae);for(;!r;){try{const r=await E.tabs.sendMessage(e,{config:t,type:R.GetPageState});if(r&&(!n||n(r)))return clearTimeout(a),void o(r)}catch(e){i.info("can`t get page state")}await T(le)}}))}async function ue(e,t,n){const o=await ce(e,n,(e=>!!e?.amounts.total.amount));if(!o)return{...t,type:ie.Invalid};let r=o.amounts.total.amount;if(o.elements.removeButton.isClickable){try{await async function(e,t){let n=10;try{await E.tabs.sendMessage(e,{config:t,type:R.RemoveCode})}catch(e){i.error("remove caa-engine error",e)}for(;n>0;){n--;const o=await ce(e,t);if(o){if(!o.elements.removeButton.isVisible)return;await T(200)}}if(!n)throw new Error("remove code is not removed")}(e,n)}catch(e){return i.error("remove code caa-background",e),{...t,type:ie.Invalid}}const o=await ce(e,n);if(!o)return{...t,type:ie.Invalid};!o.elements.removeButton.isVisible&&o.amounts.total.amount&&(r=o.amounts.total.amount)}try{const o=await E.tabs.sendMessage(e,{code:t.code,config:n,type:R.ApplyCode});i.info({codeApplicationResult:o})}catch(e){i.error("apply code caa-from-content",e)}let a=10;for(;a>0;){a--;const o=await ce(e,n,(e=>!!e?.amounts.total.amount));if(!o){await T(le);continue}const i=o.amounts.total.amount;if(r&&i&&i.value<r.value)return{...t,initialTotal:r,totalWithDiscount:i,type:ie.Discount};await T(le)}return i.info("timeout handleApplyProcess"),{...t,type:ie.Invalid}}const de=new Map;async function fe(e,t){const n=W(e),o=new URL(e).pathname,r=t(n),i=await async function(e,t){const n=de.get(e);if(n?.length)return n;const o=await fetch(t).then((e=>e.json())).then(me).catch((()=>[]));return de.set(e,o),o}(n,r).then(pe);let a=null,l=null;for(const e of i)e.urlPattern?new RegExp(e.urlPattern).test(o)&&(l=e):a=e;if(l)return l;if(a)return a;throw new Error(`No config found for ${n}`)}function me(e){const t=e,n=[];for(const e of t.configs){const t=e;n.push({appliedCode:t.appliedCode||void 0,applyButton:t.applyButton||void 0,applyType:t.applyType||void 0,closeModal:t.closeModal||void 0,couponInput:t.couponInput||void 0,discountAmount:t.discountAmount||void 0,domain:t.domain||"",error:t.error||void 0,loading:t.loading||void 0,removeButton:t.removeButton||void 0,showFormButton:t.showFormButton||void 0,subtotalAmount:t.subtotalAmount||void 0,totalAmount:t.totalAmount||void 0,urlPattern:t.urlPattern||void 0})}return n}function pe(e){return e.sort(((e,t)=>e.urlPattern?t.urlPattern?e.urlPattern.length-t.urlPattern.length:1:-1))}class ge{active;testedCodes=new Map;constructor(){this.active=!0}get isActive(){return this.active}stop(){this.active=!1}addTestedCode(e,t){this.testedCodes.set(e,t)}getTestedCode(e){return this.testedCodes.get(e)}}function ve(e){return e.code.trim().length&&!/\s/.test(e.code.trim())}const ye=new Map;function he({getUnifiedConfigUrl:e=se,logger:t=(()=>()=>{})}){E.runtime.onMessage.addListener(((o,a,l)=>{const s=a.tab?.id,c=a.tab?.url;if(void 0!==s)if(r(t(s)),void 0!==c)switch(o.type){case S.PageLoaded:return void i.info({message:o,tabId:s});case C.Stop:return i.info({message:o,tabId:s}),ye.get(s)?.stop(),void i.info("stopping CAA for tab"+s);case C.TryCodes:return i.info({message:o,tabId:s}),void async function(e,t,n,{codes:o,cacheDuplicates:r=!1,validateCodes:a=!1,minDelay:l=1e3,config:s}){let c;try{c=s||await fe(t,n)}catch(e){return void i.error("Cannot get config for "+t,e)}i.info("starting CAA for tab "+e);const u=new ge;ye.set(e,u);for(const t of o){if(!u.isActive)break;const n=u.getTestedCode(t.code);if(r&&n){await T(l),await be(e,{...n,...t});continue}if(a&&!ve(t)){await T(l),await be(e,{...t,type:ie.Invalid});continue}const o=(new Date).getTime(),s=await ue(e,t,c);i.perf(t.code+" tested in: ",{code:t.code,timeSpent:(new Date).getTime()-o}),u.addTestedCode(t.code,s),await be(e,s)}ye.delete(e)}(s,c,e,o);case C.GetPageState:return i.info({message:o,tabId:s}),async function(e,t,n,o){let r;if(o)r=o;else try{r=await fe(t,n)}catch(e){return void i.info("No config exists for: "+t)}const a=await ce(e,r);return i.info({pageState:a,tabId:e}),a}(s,c,e,o.config).then(l),!0;case C.GetLog:return function(e){switch(e.level){case n.INFO:i.info(e.details);break;case n.ERROR:i.error(e.message);break;case n.PERF:i.perf(e.label,e.meta)}}(o.log),!1}else i.error("No tabUrl provided for "+s);else console.warn("No tabId provided")}))}async function be(e,t){i.info({code:t,info:"sending tried code",tabId:e});const n={code:t,type:P.CodeTested};let o=!1;for(let r=0;r<10;r++){try{await we(e),o=await E.tabs.sendMessage(e,n)}catch(n){i.info({code:t,info:"Tried code not received by the tab.",tabId:e})}if(o)break;await T(200)}if(!o)throw new Error(`Cannot send tried code to the browser tab. code: ${t.code} , tabId: ${e}`)}async function we(e){let t=10;for(;t--;){if("complete"===(await E.tabs.get(e)).status)return;await T(100)}}module.exports=t})();
import { type ParsedAmount } from '@src/content';
/**
* Result of a DOM element query
*/
export declare enum FieldQueryResultType {

@@ -10,2 +13,5 @@ ElementFound = "ElementFound",

}
/**
* We parse amounts for numeric values to define copuon value
*/
export interface AmountField {

@@ -19,2 +25,5 @@ amount?: ParsedAmount;

}
/**
* State of an applied coupon
*/
export interface CouponField {

@@ -28,2 +37,5 @@ html: string;

}
/**
* Elements are everything we check for or interact with to apply / remove coupon code
*/
export interface ElementField {

@@ -38,4 +50,9 @@ html: string;

}
/**
* Representation of a parsed checkout page on retailer's website.
* Shall be used for getting the current situation and make further decisions.
*/
export interface PageState {
amounts: {
/** @deprecated This field will be removed as it is deprecated from the UnifiedConfig interface */
discount: AmountField;

@@ -42,0 +59,0 @@ subtotal: AmountField;

@@ -10,11 +10,15 @@ export declare const TEXT_SELECTOR = "data-caa-text";

applyButton?: CssSelector;
/** @deprecated The caa-engine shouldn't rely on this selector */
applyType?: PageSubmitType;
closeModal?: CssSelector;
couponInput?: CssSelector;
/** @deprecated The selector is not used by the engine */
discountAmount?: CssSelector;
domain: string;
error?: CssSelector;
/** @deprecated The mutation observer object should be used instead of watching for a loader */
loading?: CssSelector;
removeButton?: CssSelector;
showFormButton?: CssSelector;
/** @deprecated The selector is not used by the engine */
subtotalAmount?: CssSelector;

@@ -21,0 +25,0 @@ totalAmount?: CssSelector;

@@ -15,3 +15,3 @@ {

"name": "@global-savings-group/caa-engine",
"version": "4.1.2"
"version": "4.2.0"
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc