UNPKG

@flagship.io/js-sdk

Version:
1,375 lines (1,266 loc) 282 kB
/******/ var __webpack_modules__ = ({ /***/ 7: /***/ ((module) => { // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. var R = typeof Reflect === 'object' ? Reflect : null var ReflectApply = R && typeof R.apply === 'function' ? R.apply : function ReflectApply(target, receiver, args) { return Function.prototype.apply.call(target, receiver, args); } var ReflectOwnKeys if (R && typeof R.ownKeys === 'function') { ReflectOwnKeys = R.ownKeys } else if (Object.getOwnPropertySymbols) { ReflectOwnKeys = function ReflectOwnKeys(target) { return Object.getOwnPropertyNames(target) .concat(Object.getOwnPropertySymbols(target)); }; } else { ReflectOwnKeys = function ReflectOwnKeys(target) { return Object.getOwnPropertyNames(target); }; } function ProcessEmitWarning(warning) { if (console && console.warn) console.warn(warning); } var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) { return value !== value; } function EventEmitter() { EventEmitter.init.call(this); } module.exports = EventEmitter; module.exports.once = once; // Backwards-compat with node 0.10.x EventEmitter.EventEmitter = EventEmitter; EventEmitter.prototype._events = undefined; EventEmitter.prototype._eventsCount = 0; EventEmitter.prototype._maxListeners = undefined; // By default EventEmitters will print a warning if more than 10 listeners are // added to it. This is a useful default which helps finding memory leaks. var defaultMaxListeners = 10; function checkListener(listener) { if (typeof listener !== 'function') { throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); } } Object.defineProperty(EventEmitter, 'defaultMaxListeners', { enumerable: true, get: function() { return defaultMaxListeners; }, set: function(arg) { if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) { throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.'); } defaultMaxListeners = arg; } }); EventEmitter.init = function() { if (this._events === undefined || this._events === Object.getPrototypeOf(this)._events) { this._events = Object.create(null); this._eventsCount = 0; } this._maxListeners = this._maxListeners || undefined; }; // Obviously not all Emitters should be limited to 10. This function allows // that to be increased. Set to zero for unlimited. EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) { if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) { throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.'); } this._maxListeners = n; return this; }; function _getMaxListeners(that) { if (that._maxListeners === undefined) return EventEmitter.defaultMaxListeners; return that._maxListeners; } EventEmitter.prototype.getMaxListeners = function getMaxListeners() { return _getMaxListeners(this); }; EventEmitter.prototype.emit = function emit(type) { var args = []; for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); var doError = (type === 'error'); var events = this._events; if (events !== undefined) doError = (doError && events.error === undefined); else if (!doError) return false; // If there is no 'error' event listener then throw. if (doError) { var er; if (args.length > 0) er = args[0]; if (er instanceof Error) { // Note: The comments on the `throw` lines are intentional, they show // up in Node's output if this results in an unhandled exception. throw er; // Unhandled 'error' event } // At least give some kind of context to the user var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : '')); err.context = er; throw err; // Unhandled 'error' event } var handler = events[type]; if (handler === undefined) return false; if (typeof handler === 'function') { ReflectApply(handler, this, args); } else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) ReflectApply(listeners[i], this, args); } return true; }; function _addListener(target, type, listener, prepend) { var m; var events; var existing; checkListener(listener); events = target._events; if (events === undefined) { events = target._events = Object.create(null); target._eventsCount = 0; } else { // To avoid recursion in the case that type === "newListener"! Before // adding it to the listeners, first emit "newListener". if (events.newListener !== undefined) { target.emit('newListener', type, listener.listener ? listener.listener : listener); // Re-assign `events` because a newListener handler could have caused the // this._events to be assigned to a new object events = target._events; } existing = events[type]; } if (existing === undefined) { // Optimize the case of one listener. Don't need the extra array object. existing = events[type] = listener; ++target._eventsCount; } else { if (typeof existing === 'function') { // Adding the second element, need to change to array. existing = events[type] = prepend ? [listener, existing] : [existing, listener]; // If we've already got an array, just append. } else if (prepend) { existing.unshift(listener); } else { existing.push(listener); } // Check for listener leak m = _getMaxListeners(target); if (m > 0 && existing.length > m && !existing.warned) { existing.warned = true; // No error code for this since it is a Warning // eslint-disable-next-line no-restricted-syntax var w = new Error('Possible EventEmitter memory leak detected. ' + existing.length + ' ' + String(type) + ' listeners ' + 'added. Use emitter.setMaxListeners() to ' + 'increase limit'); w.name = 'MaxListenersExceededWarning'; w.emitter = target; w.type = type; w.count = existing.length; ProcessEmitWarning(w); } } return target; } EventEmitter.prototype.addListener = function addListener(type, listener) { return _addListener(this, type, listener, false); }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.prependListener = function prependListener(type, listener) { return _addListener(this, type, listener, true); }; function onceWrapper() { if (!this.fired) { this.target.removeListener(this.type, this.wrapFn); this.fired = true; if (arguments.length === 0) return this.listener.call(this.target); return this.listener.apply(this.target, arguments); } } function _onceWrap(target, type, listener) { var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; var wrapped = onceWrapper.bind(state); wrapped.listener = listener; state.wrapFn = wrapped; return wrapped; } EventEmitter.prototype.once = function once(type, listener) { checkListener(listener); this.on(type, _onceWrap(this, type, listener)); return this; }; EventEmitter.prototype.prependOnceListener = function prependOnceListener(type, listener) { checkListener(listener); this.prependListener(type, _onceWrap(this, type, listener)); return this; }; // Emits a 'removeListener' event if and only if the listener was removed. EventEmitter.prototype.removeListener = function removeListener(type, listener) { var list, events, position, i, originalListener; checkListener(listener); events = this._events; if (events === undefined) return this; list = events[type]; if (list === undefined) return this; if (list === listener || list.listener === listener) { if (--this._eventsCount === 0) this._events = Object.create(null); else { delete events[type]; if (events.removeListener) this.emit('removeListener', type, list.listener || listener); } } else if (typeof list !== 'function') { position = -1; for (i = list.length - 1; i >= 0; i--) { if (list[i] === listener || list[i].listener === listener) { originalListener = list[i].listener; position = i; break; } } if (position < 0) return this; if (position === 0) list.shift(); else { spliceOne(list, position); } if (list.length === 1) events[type] = list[0]; if (events.removeListener !== undefined) this.emit('removeListener', type, originalListener || listener); } return this; }; EventEmitter.prototype.off = EventEmitter.prototype.removeListener; EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) { var listeners, events, i; events = this._events; if (events === undefined) return this; // not listening for removeListener, no need to emit if (events.removeListener === undefined) { if (arguments.length === 0) { this._events = Object.create(null); this._eventsCount = 0; } else if (events[type] !== undefined) { if (--this._eventsCount === 0) this._events = Object.create(null); else delete events[type]; } return this; } // emit removeListener for all listeners on all events if (arguments.length === 0) { var keys = Object.keys(events); var key; for (i = 0; i < keys.length; ++i) { key = keys[i]; if (key === 'removeListener') continue; this.removeAllListeners(key); } this.removeAllListeners('removeListener'); this._events = Object.create(null); this._eventsCount = 0; return this; } listeners = events[type]; if (typeof listeners === 'function') { this.removeListener(type, listeners); } else if (listeners !== undefined) { // LIFO order for (i = listeners.length - 1; i >= 0; i--) { this.removeListener(type, listeners[i]); } } return this; }; function _listeners(target, type, unwrap) { var events = target._events; if (events === undefined) return []; var evlistener = events[type]; if (evlistener === undefined) return []; if (typeof evlistener === 'function') return unwrap ? [evlistener.listener || evlistener] : [evlistener]; return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); } EventEmitter.prototype.listeners = function listeners(type) { return _listeners(this, type, true); }; EventEmitter.prototype.rawListeners = function rawListeners(type) { return _listeners(this, type, false); }; EventEmitter.listenerCount = function(emitter, type) { if (typeof emitter.listenerCount === 'function') { return emitter.listenerCount(type); } else { return listenerCount.call(emitter, type); } }; EventEmitter.prototype.listenerCount = listenerCount; function listenerCount(type) { var events = this._events; if (events !== undefined) { var evlistener = events[type]; if (typeof evlistener === 'function') { return 1; } else if (evlistener !== undefined) { return evlistener.length; } } return 0; } EventEmitter.prototype.eventNames = function eventNames() { return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : []; }; function arrayClone(arr, n) { var copy = new Array(n); for (var i = 0; i < n; ++i) copy[i] = arr[i]; return copy; } function spliceOne(list, index) { for (; index + 1 < list.length; index++) list[index] = list[index + 1]; list.pop(); } function unwrapListeners(arr) { var ret = new Array(arr.length); for (var i = 0; i < ret.length; ++i) { ret[i] = arr[i].listener || arr[i]; } return ret; } function once(emitter, name) { return new Promise(function (resolve, reject) { function errorListener(err) { emitter.removeListener(name, resolver); reject(err); } function resolver() { if (typeof emitter.removeListener === 'function') { emitter.removeListener('error', errorListener); } resolve([].slice.call(arguments)); }; eventTargetAgnosticAddListener(emitter, name, resolver, { once: true }); if (name !== 'error') { addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true }); } }); } function addErrorHandlerIfEventEmitter(emitter, handler, flags) { if (typeof emitter.on === 'function') { eventTargetAgnosticAddListener(emitter, 'error', handler, flags); } } function eventTargetAgnosticAddListener(emitter, name, listener, flags) { if (typeof emitter.on === 'function') { if (flags.once) { emitter.once(name, listener); } else { emitter.on(name, listener); } } else if (typeof emitter.addEventListener === 'function') { // EventTarget does not have `error` event semantics like Node // EventEmitters, we do not listen for `error` events here. emitter.addEventListener(name, function wrapListener(arg) { // IE does not have builtin `{ once: true }` support so we // have to do it manually. if (flags.once) { emitter.removeEventListener(name, wrapListener); } listener(arg); }); } else { throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter); } } /***/ }), /***/ 985: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const { EventEmitter } = __webpack_require__(7); class AbortSignal { constructor() { this.eventEmitter = new EventEmitter(); this.onabort = null; this.aborted = false; this.reason = undefined; } toString() { return "[object AbortSignal]"; } get [Symbol.toStringTag]() { return "AbortSignal"; } removeEventListener(name, handler) { this.eventEmitter.removeListener(name, handler); } addEventListener(name, handler) { this.eventEmitter.on(name, handler); } dispatchEvent(type) { const event = { type, target: this }; const handlerName = `on${type}`; if (typeof this[handlerName] === "function") this[handlerName](event); this.eventEmitter.emit(type, event); } throwIfAborted() { if (this.aborted) { throw this.reason; } } static abort(reason) { const controller = new AbortController(); controller.abort(); return controller.signal; } static timeout(time) { const controller = new AbortController(); setTimeout(() => controller.abort(new Error("TimeoutError")), time); return controller.signal; } } class AbortController { constructor() { this.signal = new AbortSignal(); } abort(reason) { if (this.signal.aborted) return; this.signal.aborted = true; if (reason) this.signal.reason = reason; else this.signal.reason = new Error("AbortError"); this.signal.dispatchEvent("abort"); } toString() { return "[object AbortController]"; } get [Symbol.toStringTag]() { return "AbortController"; } } module.exports = { AbortController, AbortSignal }; /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // EXPORTS __webpack_require__.d(__webpack_exports__, { ABTastyWebSDKPostMessageType: () => (/* reexport */ ABTastyWebSDKPostMessageType), APP_VERSION_CODE: () => (/* reexport */ APP_VERSION_CODE), APP_VERSION_NAME: () => (/* reexport */ APP_VERSION_NAME), CARRIER_NAME: () => (/* reexport */ CARRIER_NAME), CacheStrategy: () => (/* reexport */ CacheStrategy), DEVICE_LOCALE: () => (/* reexport */ DEVICE_LOCALE), DEVICE_MODEL: () => (/* reexport */ DEVICE_MODEL), DEVICE_TYPE: () => (/* reexport */ DEVICE_TYPE), DecisionApiConfig: () => (/* reexport */ DecisionApiConfig), DecisionMode: () => (/* reexport */ DecisionMode), EventCategory: () => (/* reexport */ EventCategory), FLAGSHIP_CLIENT: () => (/* reexport */ FLAGSHIP_CLIENT), FLAGSHIP_CONTEXT: () => (/* reexport */ FLAGSHIP_CONTEXT), FLAGSHIP_VERSION: () => (/* reexport */ FLAGSHIP_VERSION), FLAGSHIP_VISITOR: () => (/* reexport */ FLAGSHIP_VISITOR), FSFetchReasons: () => (/* reexport */ FSFetchReasons), FSFetchStatus: () => (/* reexport */ FSFetchStatus), FSFlag: () => (/* reexport */ FSFlag), FSFlagCollection: () => (/* reexport */ FSFlagCollection), FSFlagMetadata: () => (/* reexport */ FSFlagMetadata), FSFlagStatus: () => (/* reexport */ FSFlagStatus), FSSdkStatus: () => (/* reexport */ FSSdkStatus), Flagship: () => (/* reexport */ Flagship), HitType: () => (/* reexport */ HitType), INTERFACE_NAME: () => (/* reexport */ INTERFACE_NAME), INTERNET_CONNECTION: () => (/* reexport */ INTERNET_CONNECTION), IP: () => (/* reexport */ IP), LOCATION_CITY: () => (/* reexport */ LOCATION_CITY), LOCATION_COUNTRY: () => (/* reexport */ LOCATION_COUNTRY), LOCATION_LAT: () => (/* reexport */ LOCATION_LAT), LOCATION_LONG: () => (/* reexport */ LOCATION_LONG), LOCATION_REGION: () => (/* reexport */ LOCATION_REGION), LogLevel: () => (/* reexport */ LogLevel), OS_NAME: () => (/* reexport */ OS_NAME), OS_VERSION_CODE: () => (/* reexport */ OS_VERSION_CODE), OS_VERSION_NAME: () => (/* reexport */ OS_VERSION_NAME), TroubleshootingLabel: () => (/* reexport */ TroubleshootingLabel), Visitor: () => (/* reexport */ Visitor), VisitorCacheStatus: () => (/* reexport */ VisitorCacheStatus), "default": () => (/* binding */ src) }); // EXTERNAL MODULE: ./node_modules/events/events.js var events = __webpack_require__(7); ;// ./src/sdkVersion.ts // Generated by genversion. const sdkVersion_version = '5.1.5'; ;// ./src/enum/FlagshipConstant.ts /** * SDK language */ const SDK_INFO = { name: 'TypeScript', version: sdkVersion_version }; /** * Default request timeout in second */ const REQUEST_TIME_OUT = 2; const FETCH_FLAG_BUFFERING_DEFAULT_TIME = 2; const DEFAULT_DEDUPLICATION_TIME = 2.5; const DEFAULT_POLLING_INTERVAL = 5; const DEFAULT_SERVER_TIME_INTERVAL = 10; const DEFAULT_SERVER_POOL_MAX_SIZE = 100; const DEFAULT_BROWSER_TIME_INTERVAL = 5; const DEFAULT_BROWSER_POOL_MAX_SIZE = 10; const BATCH_MAX_SIZE = 2500000; const ANALYTIC_HIT_ALLOCATION = 1; const MAX_COLLECTING_TIME_MS = 30000; const MAX_LAST_COLLECTING_TIME_MS = 120000; const MAX_CLICK_PATH_LENGTH = 1900; const MAX_SCORING_POLLING_TIME = 120000; const SCROLL_END_DELAY_MS = 200; const CLICK_PATH_DELAY_MS = 500; const SCORING_INTERVAL = 5000; /** * Decision api base url */ const BASE_API_URL = 'https://decision.flagship.io/v2/'; const HIT_API_URL = 'https://ariane.abtasty.com'; const HIT_EVENT_URL = 'https://events.flagship.io'; const TROUBLESHOOTING_HIT_URL = 'https://events.flagship.io/troubleshooting'; const USAGE_HIT_URL = 'https://events.flagship.io/analytics'; const BUCKETING_API_URL = 'https://cdn.flagship.io/{0}/bucketing.json'; const BUCKETING_API_CONTEXT_URL = 'https://decision.flagship.io/v2/{0}/events'; const THIRD_PARTY_SEGMENT_URL = 'https://api-data-connector.flagship.io/accounts/{0}/segments/{1}'; const HIT_CONSENT_URL = 'https://ariane.abtasty.com'; const URL_CAMPAIGNS = '/campaigns'; const URL_ACTIVATE_MODIFICATION = 'activate'; const QA_ASSISTANT_PROD_URL = 'https://qa-assistant.flagship.io/bundle.js'; const QA_ASSISTANT_STAGING_URL = 'https://staging-qa-assistant.flagship.io/bundle.js'; const QA_ASSISTANT_LOCAL_URL = 'https://local-qa-assistant.flagship.io:5000/bundle.js'; const FS_QA_ASSISTANT = 'fs_qa_assistant'; const FS_QA_ASSISTANT_STAGING = 'fs_qa_assistant_staging'; const FS_QA_ASSISTANT_LOCAL = 'fs_qa_assistant_local'; const TAG_QA_ASSISTANT = 'abtasty_qa_assistant'; const TAG_QA_ASSISTANT_STAGING = 'abtasty_qa_assistant_staging'; const TAG_QA_ASSISTANT_LOCAL = 'abtasty_qa_assistant_local'; const TAG_QA_URL = 'qa-assistant.abtasty.com'; const FS_QA_URL = 'qa-assistant.flagship.io'; const EXPOSE_ALL_KEYS = 'exposeAllKeys'; const SEND_CONTEXT_EVENT = 'sendContextEvent'; const FS_CONSENT = 'fs_consent'; const FS_IS_QA_MODE_ENABLED = 'FS_IS_QA_MODE_ENABLED'; const FS_FORCED_VARIATIONS = 'FS_FORCED_VARIATIONS'; const FS_QA_ASSISTANT_SCRIPT_TAG_ID = 'FS_QA_ASSISTANT_SCRIPT_TAG_ID'; const EMOTION_AI_UC_URL = 'https://uc-info.flagship.io/v1/segments/clients/{0}/visitors/{1}'; const CDN_ACCOUNT_SETTINGS_URL = 'https://cdn.flagship.io/{0}/accountSettings.json'; const VISITOR_EAI_SCORE_KEY = '{0}_EAIScore'; const EMOTION_AI_EVENT_URL = 'https://events.flagship.io/emotionsai'; const SEND_EAI_EVENT = 'sendEAIEvent'; const SEND_EAI_EVENT_ERROR = 'Failed to send Emotion AI event: {0}'; const SEND_EAI_EVENT_SUCCESS = 'Emotion AI event sent: {0}'; const FETCH_EAI_SCORE = 'fetchEAIScore'; const FETCH_EAI_SCORE_ERROR = 'visitor {0}, Failed to fetch EAIScore: {1}'; const FETCH_EAI_SCORE_SUCCESS = 'visitor {0}, EAIScore fetched: {1}'; const EAI_SCORE_CONTEXT_KEY = 'eai::eas'; const CLIENT_CACHE_KEY = 'FS_CLIENT_VISITOR'; /** * SDK version */ const SDK_VERSION = (/* unused pure expression or super */ null && (version)); const VISITOR_CACHE_VERSION = 1; const HIT_CACHE_VERSION = 1; const DEFAULT_HIT_CACHE_TIME_MS = 14400000; const MAX_ACTIVATE_HIT_PER_BATCH = 100; /** * Message Info */ const SDK_STARTED_INFO = 'Flagship SDK (version: {0}) {1} in **{2}** mode'; const FLAGSHIP_SDK = 'Flagship SDK'; const EMIT_READY = 'ready'; const EMIT_STATUS = 'status'; const NO_BATCHING_WITH_CONTINUOUS_CACHING_STRATEGY = 3; const JS_DOC_URL = 'https://docs.developers.flagship.io/docs/js-v3'; const PANIC_MODE_DOC_URL = 'https://docs.developers.flagship.io/docs/glossary#panic-mode'; /** * Message Error */ const INITIALIZATION_PARAM_ERROR = `Params 'envId' and 'apiKey' must not be null or empty. Learn more: ${JS_DOC_URL}#initialization`; const ERROR = 'error'; const CONTEXT_NULL_ERROR = 'Context must not to be null'; const CONTEXT_PARAM_ERROR = "params {0} must be a non null String, and 'value' must be one of the following types , Number, Boolean"; const GET_MODIFICATION_CAST_ERROR = 'Modification for key {0} has a different type. Default value is returned.'; const GET_MODIFICATION_MISSING_ERROR = 'No modification for key {0}. Default value is returned.'; const GET_MODIFICATION_KEY_ERROR = 'Key {0} must not be null. Default value is returned.'; const ACTIVATE_MODIFICATION_KEY_ERROR = 'Key {0} must not be null, no activate will be sent.'; const GET_MODIFICATION_ERROR = 'No modification for key {0}.'; const GET_FLAG_ERROR = 'No flag for key {0}.'; const ACTIVATE_MODIFICATION_ERROR = 'No modification for key {0}, no activate will be sent.'; const DECISION_MANAGER_MISSING_ERROR = 'decisionManager must not be null.'; const TRACKER_MANAGER_MISSING_ERROR = 'trackerManager must not be null.'; const CURL_LIBRARY_IS_NOT_LOADED = 'curl library is not loaded'; const TYPE_ERROR = '{0} must be a {1}'; const TYPE_INTEGER_ERROR = 'value of {0} is not an {1}, it will be truncated to {1}'; const VISITOR_ID_ERROR = 'visitorId must not be null or empty'; const PANIC_MODE_ERROR = '{0} deactivated while panic mode is on.'; const METHOD_DEACTIVATED_CONSENT_ERROR = 'Method {0} is deactivated for visitor {1} : visitor did not consent.'; const METHOD_DEACTIVATED_ERROR = 'Visitor {0}, method {1} is deactivated while SDK status is: {2}.'; const METHOD_DEACTIVATED_SEND_CONSENT_ERROR = 'Send consent hit is deactivated while SDK status is: {1}.'; const TROUBLESHOOTING_HIT_ADDED_IN_QUEUE = 'The TROUBLESHOOTING HIT has been added to the pool queue : {0}'; const ANALYTICS_HIT_ADDED_IN_QUEUE = 'The USAGE HIT has been added to the pool queue : {0}'; const ACTIVATE_ADDED_IN_QUEUE = 'The ACTIVATE has been added to the pool queue : {0}'; const HIT_ADDED_IN_QUEUE = 'The HIT has been added into the pool queue : {0}'; const ADD_HIT = 'ADD HIT'; const ADD_TROUBLESHOOTING_HIT = 'ADD TROUBLESHOOTING HIT'; const ADD_USAGE_HIT = 'ADD USAGE HIT'; const ADD_ACTIVATE = 'ADD ACTIVATE'; const BATCH_SENT_SUCCESS = 'Batch hit has been sent : {0}'; const TROUBLESHOOTING_SENT_SUCCESS = 'Troubleshooting hit has been sent : {0}'; const ANALYTICS_HIT_SENT_SUCCESS = 'Usage hit has been sent : {0}'; const ACTIVATE_SENT_SUCCESS = 'Activate hit has been sent : {0}'; const SEND_BATCH = 'SEND BATCH'; const SEND_TROUBLESHOOTING = 'SEND TROUBLESHOOTING'; const SEND_USAGE_HIT = 'SEND USAGE HIT'; const SEND_ACTIVATE = 'SEND ACTIVATE'; const SEND_SEGMENT_HIT = 'SEND SEGMENT HIT'; const SEND_HIT = 'SEND HIT'; const EVENT_SUFFIX = 'events'; const FETCH_FLAGS_BUFFERING_MESSAGE = 'Visitor {0}, fetchFlags has been ignored and will continue to be ignored for the next {1}ms, this delay can be changed with `fetchFlagsBufferingTime` option in the SDK config'; const VISITOR_SYNC_FLAGS_MESSAGE = 'without calling `fetchFlags` method afterwards. So, the value of the flag `{1}` might be outdated'; const NEW_VISITOR_NOT_READY = `You can't create a new visitor without first calling the "Flagship.start" method. Learn more: ${JS_DOC_URL}#initialization `; const LOOKUP_HITS_JSON_OBJECT_ERROR = 'JSON DATA must fit the type HitCacheDTO'; const ACTIVATE_BATCH_LENGTH = 5; // Process const PROCESS = 'process'; const PROCESS_INITIALIZATION = 'INITIALIZATION'; const PROCESS_UPDATE_CONTEXT = 'UPDATE CONTEXT'; const PROCESS_GET_MODIFICATION = 'GET MODIFICATION'; const PROCESS_GET_MODIFICATION_INFO = 'GET MODIFICATION INFO'; const PROCESS_NEW_VISITOR = 'NEW VISITOR'; const PROCESS_ACTIVE_MODIFICATION = 'ACTIVE MODIFICATION'; const PROCESS_SYNCHRONIZED_MODIFICATION = 'SYNCHRONIZED MODIFICATION'; const PROCESS_SEND_HIT = 'ADD HIT'; const PROCESS_SEND_ACTIVATE = 'SEND ACTIVATE'; const PROCESS_GET_CAMPAIGNS = 'GET CAMPAIGNS'; const PROCESS_GET_ALL_MODIFICATION = 'GET ALL MODIFICATIONS'; const PROCESS_MODIFICATIONS_FOR_CAMPAIGN = 'GET MODIFICATION FOR CAMPAIGN'; const PROCESS_CACHE_HIT = 'CACHE HIT'; const PROCESS_FLUSH_HIT = 'FLUSH HIT'; const PROCESS_LOOKUP_HIT = 'LOOKUP HIT'; // Api items const BATCH = 'batch'; const CUSTOMER_ENV_ID_API_ITEM = 'cid'; const CUSTOMER_ENV_ID_API_ACTIVATE = 'cid'; const CUSTOMER_UID = 'cuid'; const ANONYMOUS_ID = 'aid'; const VISITOR_ID_API_ITEM = 'vid'; const VARIATION_GROUP_ID_API_ITEM = 'caid'; const VARIATION_GROUP_ID_API_ITEM_ACTIVATE = 'caid'; const VISITOR_CONSENT = 'vc'; const CAMPAIGN_ID = 'caid'; const VARIATION_ID_API_ITEM = 'vaid'; const DS_API_ITEM = 'ds'; const T_API_ITEM = 't'; const QT_API_ITEM = 'qt'; const QA_MODE_API_ITEM = 'qa'; const DL_API_ITEM = 'dl'; const SL_ITEM = 'sl'; const SDK_APP = 'APP'; const TID_API_ITEM = 'tid'; const TA_API_ITEM = 'ta'; const TT_API_ITEM = 'tt'; const TC_API_ITEM = 'tc'; const TCC_API_ITEM = 'tcc'; const ICN_API_ITEM = 'icn'; const SM_API_ITEM = 'sm'; const PM_API_ITEM = 'pm'; const TR_API_ITEM = 'tr'; const TS_API_ITEM = 'ts'; const IN_API_ITEM = 'in'; const IC_API_ITEM = 'ic'; const IP_API_ITEM = 'ip'; const IQ_API_ITEM = 'iq'; const IV_API_ITEM = 'iv'; const S_API_ITEM = 's'; const EVENT_CATEGORY_API_ITEM = 'ec'; const EVENT_ACTION_API_ITEM = 'ea'; const EVENT_LABEL_API_ITEM = 'el'; const EVENT_VALUE_API_ITEM = 'ev'; const USER_IP_API_ITEM = 'uip'; const SCREEN_RESOLUTION_API_ITEM = 'sr'; const USER_LANGUAGE = 'ul'; const SESSION_NUMBER = 'sn'; const HEADER_X_API_KEY = 'x-api-key'; const HEADER_X_ENV_ID = 'x-env-id'; const HEADER_CONTENT_TYPE = 'Content-Type'; const HEADER_X_SDK_CLIENT = 'x-sdk-client'; const HEADER_X_SDK_VERSION = 'x-sdk-version'; const HEADER_APPLICATION_JSON = 'application/json'; // Log const INITIALIZATION_STARTING = 'Flagship SDK version {0} is starting in {1} mode with config {2}'; const BUCKETING_POOLING_STARTED = 'Bucketing polling process has been started'; const BUCKETING_POOLING_STOPPED = 'Bucketing polling process has been stopped'; const PROCESS_BUCKETING = 'BUCKETING'; const POLLING_EVENT_200 = 'Polling event with code status 200 : {0}'; const POLLING_EVENT_300 = 'Polling event with code status 304'; const POLLING_EVENT_FAILED = 'Polling event failed with error'; const PROCESS_SDK_STATUS = 'SDK STATUS'; const SDK_STATUS_CHANGED = 'SDK status has changed: {0}'; const SAVE_VISITOR_INSTANCE = 'Visitor {0} has been saved in SDK instance'; const VISITOR_CREATED = 'Visitor {0} has been created with context {1}, isAuthenticated:{2} and hasConsented {3}'; const VISITOR_PROFILE_LOADED = 'Visitor profile has been loaded {0}'; const VISITOR_ID_FROM_AB_TASTY_TAG = "The visitor ID '{0}' has been retrieved from ABTasty tag"; const VISITOR_ID_GENERATED = 'Visitor identifier is empty. A UUID {0} has been generated.'; const PREDEFINED_CONTEXT_LOADED = 'Predefined Context have been loaded {0}'; const CONTEXT_KEY_ERROR = `Visitor {0}, the key '{1}' must be a non null String. Learn more: ${JS_DOC_URL}#updating-the-visitor-context`; const CONTEXT_VALUE_ERROR = `Visitor {0}, 'value' for key '{1}[], must be one of the following types : String, Number, Boolean Learn more: ${JS_DOC_URL}#updating-the-visitor-context`; const PREDEFINED_CONTEXT_TYPE_ERROR = `visitor {0}, Predefined Context {0} must be of type {1} Learn more: ${JS_DOC_URL}#predefined-user-context-keys-`; const CONTEXT_KEY_VALUE_UPDATE = 'visitor `{0}`, context have been updated: key {1}, value {2}, Context {3}'; const CONTEXT_OBJET_PARAM_UPDATE = 'visitor `{0}`, context have been updated: key/value {1}, Context {2}'; const CLEAR_CONTEXT = 'visitor `{0}`, context has been cleared cleared `{1}`'; const PROCESS_CLEAR_CONTEXT = 'CLEAR_CONTEXT'; const CONSENT_CHANGED = 'Visitor `{0}` consent has been changed : {1}'; const PROCESS_SET_CONSENT = 'SET_CONSENT'; const FETCH_CAMPAIGNS_SUCCESS = 'Visitor {0}, anonymousId {1} with context {2} has just fetched campaigns {3} in {4} ms'; const FETCH_CAMPAIGNS_FROM_CACHE = 'Visitor {0}, anonymousId {1} with context {2} has just fetched campaigns from cache {3} in {4} ms'; const FETCH_FLAGS_FROM_CAMPAIGNS = 'Visitor {0}, anonymousId {1} with context {2} has just fetched flags {3} from Campaigns'; const FETCH_FLAGS_STARTED = 'visitor `{0}` fetchFlags process is started'; const FETCH_FLAGS_PANIC_MODE = 'Panic mode is enabled : all feature are disabled except fetchFlags.'; const PROCESS_FETCHING_FLAGS = 'FETCH_FLAGS'; const GET_FLAG_MISSING_ERROR = 'For the visitor "{0}", no flags were found with the key "{1}". Therefore, the default value "{2}" has been returned.'; const GET_FLAG_NOT_FOUND = 'For the visitor "{0}", no flags were found with the key "{1}". Therefore, an empty flag has been returned.'; const FETCH_FLAGS_MISSING = 'Visitor {0} has {1} without calling fetchFlags method, '; const FLAG_VALUE = 'FLAG_VALUE'; const GET_FLAG = 'GET_FLAG'; const GET_FLAG_CAST_ERROR = 'For the visitor "{0}", the flag with key "{1}" has a different type compared to the default value. Therefore, the default value "{2}" has been returned.'; const GET_FLAG_VALUE = 'Visitor {0}, Flag for key {1} returns value {2}'; const USER_EXPOSED_FLAG_ERROR = 'For the visitor "{0}", no flags were found with the key "{1}". As a result, user exposure will not be sent.'; const VISITOR_EXPOSED_VALUE_NOT_CALLED = 'For the visitor `{0}`,assuming the getValue() method has not previously been invoked for the flag `{0}`. Therefore, the exposure is canceled'; const FLAG_VISITOR_EXPOSED = 'FLAG_VISITOR_EXPOSED'; const USER_EXPOSED_CAST_ERROR = 'For the visitor `{0}, the flag with the key `{0}` has a different type compared to the default value. Therefore, the exposure is interrupted'; const GET_METADATA_CAST_ERROR = 'Visitor {0}, Flag for key {1} has a different type with default value: Empty metadata object is returned {2}'; const FLAG_METADATA = 'FLAG_METADATA'; const NO_FLAG_METADATA = 'Visitor {0}, No Flags found for key {1}: Empty metadata object is returned'; const METADATA_SDK_NOT_READY = `Visitor {0}, Flag for key {1} Method Flag.metadata is deactivated while SDK status is NOT_READY: Empty metadata object is returned {2} Learn more: ${JS_DOC_URL}#getting-flags-campaigns-metadata`; const METADATA_PANIC_MODE = `Visitor {0}, Flag for key {1} Method Flag.metadata is deactivated while SDK status is PANIC: Empty metadata object is returned {2} Learn more: ${PANIC_MODE_DOC_URL}`; const AUTHENTICATE = 'AUTHENTICATE'; const VISITOR_AUTHENTICATE = 'The visitor is authenticated with new visitor ID {0} anonymous ID {1}'; const VISITOR_ALREADY_AUTHENTICATE = 'The visitor is already authenticated with visitor ID {0}'; const METHOD_DEACTIVATED_BUCKETING_ERROR = 'Visitor {0}, Method {1} is deactivated on Bucketing mode'; const VISITOR_AUTHENTICATE_VISITOR_ID_ERROR = `Visitor {0}, visitorId must not be null or empty Learn more: ${JS_DOC_URL}#authenticate`; const VISITOR_UNAUTHENTICATE = 'The visitor is unauthenticated with visitor ID {0}'; const UNAUTHENTICATE = 'UNAUTHENTICATE'; const FLAGSHIP_VISITOR_NOT_AUTHENTICATE = 'Visitor {0} is not authenticated yet'; const ALLOCATION = 'ALLOCATION'; const BUCKETING_VARIATION_CACHE = 'Visitor {0}, Variation {1} selected from cache.'; const BUCKETING_NEW_ALLOCATION = 'Visitor {0}, Variation {1} selected with allocation {2}.'; const LOOKUP_VISITOR_JSON_OBJECT_ERROR = `lookupVisitor method has loaded a bad format version ({0}) for visitor {1}. Learn more: ${JS_DOC_URL}#managing-visitor-cache`; const PROCESS_CACHE = 'CACHE'; const VISITOR_CACHE_ERROR = 'visitor {0}. {1} threw an exception {2}'; const HIT_CACHE_ERROR = '{0} threw an exception {1}'; const VISITOR_CACHE_LOADED = 'Visitor {0}, visitor cache has been loaded from database: {1}'; const VISITOR_CACHE_SAVED = 'Visitor {0}, visitor cache has been saved into database : {0}'; const VISITOR_CACHE_FLUSHED = 'Visitor {0}, visitor cache has been flushed from database.'; const HIT_CACHE_LOADED = 'Hits cache has been loaded from database: {0}'; const HIT_CACHE_SAVED = 'Hit cache has been saved into database : {0}'; const HIT_DATA_FLUSHED = 'The following hit keys have been flushed from database : {0}'; const ALL_HITS_FLUSHED = 'All hits cache has been flushed from database'; const BATCH_LOOP_STARTED = 'The Batch Loop has been started with a time interval of {0} ms'; const TRACKING_MANAGER = 'TRACKING_MANAGER'; const BATCH_LOOP_STOPPED = 'The Batch Loop has been stopped'; const TRACKING_MANAGER_ERROR = '{0} Unexpected Error occurred {1}'; const HIT_SENT_SUCCESS = '{0} has been sent : {1}'; const ACTIVATE_HIT = 'ACTIVATE HIT'; const BATCH_HIT = 'BATCH HIT'; const DIRECT_HIT = 'HIT'; const GET_THIRD_PARTY_SEGMENT = 'GET_THIRD_PARTY_SEGMENT'; const CONSENT_NOT_SPECIFY_WARNING = 'Consent has not been specified. By default, consent is set to false, which may result in some features being deactivated.'; const ACTION_TRACKING = 'Action Tracking'; const ACTION_TRACKING_HIT_RECEIVED = 'Hit received: {0}'; const ACTION_TRACKING_INVALID_HIT = 'Invalid hit data: {0}'; const ACTION_TRACKING_INVALID_NONCE = 'Invalid nonce: {0}'; const ACTION_TRACKING_SENDING_HIT = 'Sending hit: {0}'; const ACTION_TRACKING_SENDING_HIT_ERROR = 'Failed to send hit: {0}'; const ACTION_TRACKING_DISPATCHED = 'action tracking hits have been dispatched {0}'; const TRUSTED_QA_ORIGINS = (/* unused pure expression or super */ null && ([ 'https://local-qa-assistant.abtasty.com:5000', 'https://staging-qa-assistant.abtasty.com', 'https://qa-assistant.abtasty.com', 'https://qa-assistant.flagship.io', 'https://local-qa-assistant.flagship.io:5000', 'https://staging-qa-assistant.flagship.io' ])); ;// ./src/visitor/Visitor.ts /** * The `Visitor` class represents a unique user within your application. It aids in * managing the visitor's data and fetching the corresponding flags for the visitor * from the [Flagship platform](https://app.flagship.io/login) . */ class Visitor extends events.EventEmitter { visitorDelegate; // eslint-disable-next-line @typescript-eslint/no-explicit-any _onReady; constructor(visitorDelegate) { super(); this.visitorDelegate = visitorDelegate; // eslint-disable-next-line @typescript-eslint/no-explicit-any this._onReady = (err) => { this.emit(EMIT_READY, err); }; this.visitorDelegate.on(EMIT_READY, this._onReady); const instance = this; instance.sendEaiVisitorEvent = (event) => { this.visitorDelegate.sendEaiVisitorEvent(event); }; instance.sendEaiPageView = (pageView) => { this.visitorDelegate.sendEaiPageView(pageView); }; instance.onEAICollectStatusChange = (callback) => { this.visitorDelegate.onEAICollectStatusChange(callback); }; } /** * @inheritdoc */ get visitorId() { return this.visitorDelegate.visitorId; } /** * @inheritdoc */ set visitorId(v) { this.visitorDelegate.visitorId = v; } /** * @inheritdoc */ get anonymousId() { return this.visitorDelegate.anonymousId; } /** * @inheritdoc */ get config() { return this.visitorDelegate.config; } /** * @inheritdoc */ get context() { return this.visitorDelegate.context; } /** * @inheritdoc */ get flagsStatus() { return this.visitorDelegate.flagsStatus; } /** * @inheritdoc */ get hasConsented() { return this.visitorDelegate.hasConsented; } /** * @inheritdoc */ setConsent(hasConsented) { this.visitorDelegate.setConsent(hasConsented); } updateContext(context, value) { this.visitorDelegate.updateContext(context, value); } /** * @inheritdoc */ clearContext() { this.visitorDelegate.clearContext(); } /** * @inheritdoc */ getFlag(key) { return this.visitorDelegate.getFlag(key); } /** * @inheritdoc */ getFlags() { return this.visitorDelegate.getFlags(); } /** * @inheritdoc */ fetchFlags() { return this.visitorDelegate.fetchFlags(); } sendHit(hit) { return this.visitorDelegate.sendHit(hit); } sendHits(hits) { return this.visitorDelegate.sendHits(hits); } /** * @inheritdoc */ authenticate(visitorId) { this.visitorDelegate.authenticate(visitorId); } /** * @inheritdoc */ unauthenticate() { this.visitorDelegate.unauthenticate(); } /** * @inheritdoc */ collectEAIEventsAsync(...args) { let currentPage; if (args.length > 0) { currentPage = args[0]; } return this.visitorDelegate.collectEAIEventsAsync(currentPage); } /** * @inheritdoc */ cleanup() { this.visitorDelegate.cleanup(); this.visitorDelegate.off(EMIT_READY, this._onReady); } } ;// ./src/enum/FSSdkStatus.ts /** * Enum representing the status of the Flagship SDK. */ var FSSdkStatus; (function (FSSdkStatus) { /** * It is the default initial status. This status remains until the sdk has been initialized successfully. */ FSSdkStatus[FSSdkStatus["SDK_NOT_INITIALIZED"] = 0] = "SDK_NOT_INITIALIZED"; /** * The SDK is currently initializing. */ FSSdkStatus[FSSdkStatus["SDK_INITIALIZING"] = 1] = "SDK_INITIALIZING"; /** * Flagship SDK is ready but is running in Panic mode: All features are disabled except the one which refresh this status. */ FSSdkStatus[FSSdkStatus["SDK_PANIC"] = 2] = "SDK_PANIC"; /** * The Initialization is done, and Flagship SDK is ready to use. */ FSSdkStatus[FSSdkStatus["SDK_INITIALIZED"] = 3] = "SDK_INITIALIZED"; })(FSSdkStatus || (FSSdkStatus = {})); ;// ./src/config/DecisionMode.ts var DecisionMode; (function (DecisionMode) { /** * /** * Flagship SDK mode decision api */ DecisionMode["DECISION_API"] = "DECISION-API"; /** * Flagship SDK mode bucketing */ DecisionMode["BUCKETING"] = "BUCKETING"; DecisionMode["BUCKETING_EDGE"] = "BUCKETING_EDGE"; })(DecisionMode || (DecisionMode = {})); ;// ./src/enum/LogLevel.ts var LogLevel; (function (LogLevel) { /** * NONE = 0: Logging will be disabled. */ LogLevel[LogLevel["NONE"] = 0] = "NONE"; /** * EMERGENCY = 1: Only emergencies will be logged. */ LogLevel[LogLevel["EMERGENCY"] = 1] = "EMERGENCY"; /** * ALERT = 2: Only alerts and above will be logged. */ LogLevel[LogLevel["ALERT"] = 2] = "ALERT"; /** * CRITICAL = 3: Only critical and above will be logged. */ LogLevel[LogLevel["CRITICAL"] = 3] = "CRITICAL"; /** * ERROR = 4: Only errors and above will be logged. */ LogLevel[LogLevel["ERROR"] = 4] = "ERROR"; /** * WARNING = 5: Only warnings and above will be logged. */ LogLevel[LogLevel["WARNING"] = 5] = "WARNING"; /** * NOTICE = 6: Only notices and above will be logged. */ LogLevel[LogLevel["NOTICE"] = 6] = "NOTICE"; /** * INFO = 7: Only info logs and above will be logged. */ LogLevel[LogLevel["INFO"] = 7] = "INFO"; /** * DEBUG = 8: Only debug logs and above will be logged. */ LogLevel[LogLevel["DEBUG"] = 8] = "DEBUG"; /** * ALL = 9: All logs will be logged. */ LogLevel[LogLevel["ALL"] = 9] = "ALL"; })(LogLevel || (LogLevel = {})); ;// ./src/enum/FSFetchReasons.ts /** * Enum representing the reasons for fetching Flags. */ var FSFetchReasons; (function (FSFetchReasons) { /** * Indicates that a context has been updated or changed. */ FSFetchReasons["UPDATE_CONTEXT"] = "UPDATE_CONTEXT"; /** * Indicates that the XPC method 'authenticate' has been called. */ FSFetchReasons["AUTHENTICATE"] = "AUTHENTICATE"; /** * Indicates that the XPC method 'unauthenticate' has been called. */ FSFetchReasons["UNAUTHENTICATE"] = "UNAUTHENTICATE"; /** * Indicates that fetching flags has failed. */ FSFetchReasons["FLAGS_FETCHING_ERROR"] = "FLAGS_FETCHING_ERROR"; /** * Indicates that flags have been fetched from the cache. */ FSFetchReasons["FLAGS_FETCHED_FROM_CACHE"] = "FLAGS_FETCHED_FROM_CACHE"; /** * Indicates that the visitor has been created. */ FSFetchReasons["FLAGS_NEVER_FETCHED"] = "FLAGS_NEVER_FETCHED"; /** * Indicates that there is no specific reason for fetching flags. */ FSFetchReasons["NONE"] = "NONE"; })(FSFetchReasons || (FSFetchReasons = {})); ;// ./src/utils/utils.ts /** * Return a formatted string */ // eslint-disable-next-line @typescript-eslint/no-explicit-any function sprintf(format, ...value) { let formatted = format; for (let i = 0; i < value.length; i++) { const item = value[i]; const element = typeof item === 'string' ? item : JSON.stringify(item instanceof Map ? Array.from(item.values()) : item); formatted = formatted.replace(new RegExp(`\\{${i}\\}`, 'g'), element); } return formatted; } function logErrorSprintf(config, tag, message, ...arg) { if (!config || !config.logLevel || config.logLevel < LogLevel.ERROR) { return; } const customMessage = sprintf(message, ...arg); logError(config, customMessage, tag); } function logError(config, message, tag) { if (!config || !config.logLevel || config.logLevel < LogLevel.ERROR) { return; } if (typeof config.onLog === 'function') { config.onLog(LogLevel.ERROR, tag, message); } if (config.logManager && typeof config.logManager.error === 'function') { config.logManager.error(message, tag); } } function logWarningSprintf(config, tag, message, ...arg) { if (!config || !config.logLevel || config.logLevel < LogLevel.WARNING) { return; } const customMessage = sprintf(message, ...arg); logWarning(config, customMessage, tag); } function logWarning(config, message, tag) { if (!config || !config.logLevel || config.logLevel < LogLevel.WARNING) { return; } if (typeof config.onLog === 'function') { config.onLog(LogLevel.WARNING, tag, message); } if (config.logManager && typeof config.logManager.warning === 'function') { config.logManager.warning(message, tag); } } function logInfoSprintf(config, tag, message, ...arg) { if (!config || !config.logLevel || config.logLevel < LogLevel.INFO) { return; } const customMessage = sprintf(message, ...arg); logInfo(config, customMessage, tag); } function logInfo(config, message, tag) { if (!config || !config.logLevel || config.logLevel < LogLevel.INFO) { return; } if (typeof config.onLog === 'function') { config.onLog(LogLevel.INFO, tag, message); } if (config.logManager && typeof config.logManager.info === 'function') { config.logManager.info(message, tag); } } function logDebugSprintf(config, tag, message, ...arg) { if (!config || !config.logLevel || config.logLevel < LogLevel.DEBUG) { return; } const customMessage = sprintf(message, ...arg); logDebug(config, customMessage, tag); } function logDebug(config, message, tag) { if (!config || !config.logLevel || config.logLevel < LogLevel.DEBUG) { return; } if (typeof config.onLog === 'function') { config.onLog(LogLevel.DEBUG, tag, message); } if (config.logManager && typeof config.logManager.debug === 'function') { config.logManager.debug(message, tag); } } function isBrowser() { return typeof window !== 'undefined' && typeof window.document !== 'undefined'; } function hasSameType(flagValue, defaultValue) { if (typeof flagValue !== typeof defaultValue) { return false; } if (typeof flagValue === 'object' && typeof defaultValue === 'object' && Array.isArray(flagValue) !== Array.isArray(defaultValue)) { return false; } return true; } function uuidV4() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (char) { const rand = Math.random() * 16 | 0; const value = char === 'x' ? rand : (rand & 0x3 | 0x8); return value.toString(16); }); } function errorFormat(message, errorData) { return JSON.stringify({ message, data: errorData }); } function visitorFlagSyncStatusMessage(reason) { let message = ''; switch (reason) { case FSFetchReasons.FLAGS_NEVER_FETCHED: message = `Visitor \`{0}\` has been created ${VISITOR_SYNC_FLAGS_MESSAGE}`; break; case FSFetchReasons.UPDATE_CONTEXT: message = `Visitor context for visitor \`{0}\` has been updated ${VISITOR_SYNC_FLAGS_MESSAGE}`; break; case FSFetchReasons.AUTHENTICATE: message = `Visitor \`{0}\` has been auth