@absmartly/sdk-plugins 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1101 -0
- package/dist/absmartly-cookie.min.js +1 -0
- package/dist/absmartly-dom-changes-core.min.js +1 -0
- package/dist/absmartly-dom-changes-lite.min.js +1 -0
- package/dist/absmartly-overrides-full.min.js +1 -0
- package/dist/absmartly-overrides-lite.min.js +1 -0
- package/dist/absmartly-sdk-plugins.min.js +1 -0
- package/dist/absmartly-vitals.min.js +1 -0
- package/es/cookies/CookiePlugin.js +410 -0
- package/es/cookies/CookiePlugin.js.map +1 -0
- package/es/cookies/index.js +2 -0
- package/es/cookies/index.js.map +1 -0
- package/es/core/DOMChangesPluginLite.js +1124 -0
- package/es/core/DOMChangesPluginLite.js.map +1 -0
- package/es/core/DOMManipulatorLite.js +410 -0
- package/es/core/DOMManipulatorLite.js.map +1 -0
- package/es/core/ExposureTracker.js +501 -0
- package/es/core/ExposureTracker.js.map +1 -0
- package/es/core/HTMLInjector.js +333 -0
- package/es/core/HTMLInjector.js.map +1 -0
- package/es/core/PendingChangeManager.js +440 -0
- package/es/core/PendingChangeManager.js.map +1 -0
- package/es/core/StyleSheetManager.js +78 -0
- package/es/core/StyleSheetManager.js.map +1 -0
- package/es/entries/cookie-only.js +10 -0
- package/es/entries/cookie-only.js.map +1 -0
- package/es/entries/dom-only.js +13 -0
- package/es/entries/dom-only.js.map +1 -0
- package/es/entries/dom-with-overrides-full.js +19 -0
- package/es/entries/dom-with-overrides-full.js.map +1 -0
- package/es/entries/dom-with-overrides-lite.js +15 -0
- package/es/entries/dom-with-overrides-lite.js.map +1 -0
- package/es/entries/overrides-full-only.js +15 -0
- package/es/entries/overrides-full-only.js.map +1 -0
- package/es/entries/overrides-lite-only.js +12 -0
- package/es/entries/overrides-lite-only.js.map +1 -0
- package/es/entries/vitals-only.js +10 -0
- package/es/entries/vitals-only.js.map +1 -0
- package/es/index.js +17 -0
- package/es/index.js.map +1 -0
- package/es/overrides/BrowserCookieAdapter.js +76 -0
- package/es/overrides/BrowserCookieAdapter.js.map +1 -0
- package/es/overrides/OverridesPlugin.js +903 -0
- package/es/overrides/OverridesPlugin.js.map +1 -0
- package/es/overrides/OverridesPluginFull.js +32 -0
- package/es/overrides/OverridesPluginFull.js.map +1 -0
- package/es/overrides/OverridesPluginLite.js +352 -0
- package/es/overrides/OverridesPluginLite.js.map +1 -0
- package/es/overrides/index.js +4 -0
- package/es/overrides/index.js.map +1 -0
- package/es/overrides/types.js +2 -0
- package/es/overrides/types.js.map +1 -0
- package/es/parsers/VariantExtractor.js +570 -0
- package/es/parsers/VariantExtractor.js.map +1 -0
- package/es/types/index.js +2 -0
- package/es/types/index.js.map +1 -0
- package/es/utils/URLMatcher.js +114 -0
- package/es/utils/URLMatcher.js.map +1 -0
- package/es/utils/debug.js +184 -0
- package/es/utils/debug.js.map +1 -0
- package/es/vitals/WebVitalsPlugin.js +379 -0
- package/es/vitals/WebVitalsPlugin.js.map +1 -0
- package/es/vitals/index.js +2 -0
- package/es/vitals/index.js.map +1 -0
- package/lib/cookies/CookiePlugin.d.ts +55 -0
- package/lib/cookies/CookiePlugin.js +413 -0
- package/lib/cookies/CookiePlugin.js.map +1 -0
- package/lib/cookies/index.d.ts +2 -0
- package/lib/cookies/index.js +6 -0
- package/lib/cookies/index.js.map +1 -0
- package/lib/core/DOMChangesPluginLite.d.ts +89 -0
- package/lib/core/DOMChangesPluginLite.js +1127 -0
- package/lib/core/DOMChangesPluginLite.js.map +1 -0
- package/lib/core/DOMManipulatorLite.d.ts +21 -0
- package/lib/core/DOMManipulatorLite.js +413 -0
- package/lib/core/DOMManipulatorLite.js.map +1 -0
- package/lib/core/ExposureTracker.d.ts +81 -0
- package/lib/core/ExposureTracker.js +504 -0
- package/lib/core/ExposureTracker.js.map +1 -0
- package/lib/core/HTMLInjector.d.ts +19 -0
- package/lib/core/HTMLInjector.js +336 -0
- package/lib/core/HTMLInjector.js.map +1 -0
- package/lib/core/PendingChangeManager.d.ts +31 -0
- package/lib/core/PendingChangeManager.js +443 -0
- package/lib/core/PendingChangeManager.js.map +1 -0
- package/lib/core/StyleSheetManager.d.ts +16 -0
- package/lib/core/StyleSheetManager.js +81 -0
- package/lib/core/StyleSheetManager.js.map +1 -0
- package/lib/entries/cookie-only.d.ts +8 -0
- package/lib/entries/cookie-only.js +12 -0
- package/lib/entries/cookie-only.js.map +1 -0
- package/lib/entries/dom-only.d.ts +9 -0
- package/lib/entries/dom-only.js +29 -0
- package/lib/entries/dom-only.js.map +1 -0
- package/lib/entries/dom-with-overrides-full.d.ts +15 -0
- package/lib/entries/dom-with-overrides-full.js +39 -0
- package/lib/entries/dom-with-overrides-full.js.map +1 -0
- package/lib/entries/dom-with-overrides-lite.d.ts +11 -0
- package/lib/entries/dom-with-overrides-lite.js +32 -0
- package/lib/entries/dom-with-overrides-lite.js.map +1 -0
- package/lib/entries/overrides-full-only.d.ts +11 -0
- package/lib/entries/overrides-full-only.js +33 -0
- package/lib/entries/overrides-full-only.js.map +1 -0
- package/lib/entries/overrides-lite-only.d.ts +8 -0
- package/lib/entries/overrides-lite-only.js +28 -0
- package/lib/entries/overrides-lite-only.js.map +1 -0
- package/lib/entries/vitals-only.d.ts +8 -0
- package/lib/entries/vitals-only.js +12 -0
- package/lib/entries/vitals-only.js.map +1 -0
- package/lib/index.d.ts +13 -0
- package/lib/index.js +34 -0
- package/lib/index.js.map +1 -0
- package/lib/overrides/BrowserCookieAdapter.d.ts +6 -0
- package/lib/overrides/BrowserCookieAdapter.js +79 -0
- package/lib/overrides/BrowserCookieAdapter.js.map +1 -0
- package/lib/overrides/OverridesPlugin.d.ts +33 -0
- package/lib/overrides/OverridesPlugin.js +906 -0
- package/lib/overrides/OverridesPlugin.js.map +1 -0
- package/lib/overrides/OverridesPluginFull.d.ts +9 -0
- package/lib/overrides/OverridesPluginFull.js +35 -0
- package/lib/overrides/OverridesPluginFull.js.map +1 -0
- package/lib/overrides/OverridesPluginLite.d.ts +27 -0
- package/lib/overrides/OverridesPluginLite.js +355 -0
- package/lib/overrides/OverridesPluginLite.js.map +1 -0
- package/lib/overrides/index.d.ts +3 -0
- package/lib/overrides/index.js +23 -0
- package/lib/overrides/index.js.map +1 -0
- package/lib/overrides/types.d.ts +43 -0
- package/lib/overrides/types.js +3 -0
- package/lib/overrides/types.js.map +1 -0
- package/lib/parsers/VariantExtractor.d.ts +49 -0
- package/lib/parsers/VariantExtractor.js +573 -0
- package/lib/parsers/VariantExtractor.js.map +1 -0
- package/lib/types/index.d.ts +177 -0
- package/lib/types/index.js +3 -0
- package/lib/types/index.js.map +1 -0
- package/lib/utils/URLMatcher.d.ts +20 -0
- package/lib/utils/URLMatcher.js +117 -0
- package/lib/utils/URLMatcher.js.map +1 -0
- package/lib/utils/debug.d.ts +41 -0
- package/lib/utils/debug.js +195 -0
- package/lib/utils/debug.js.map +1 -0
- package/lib/vitals/WebVitalsPlugin.d.ts +37 -0
- package/lib/vitals/WebVitalsPlugin.js +382 -0
- package/lib/vitals/WebVitalsPlugin.js.map +1 -0
- package/lib/vitals/index.d.ts +2 -0
- package/lib/vitals/index.js +6 -0
- package/lib/vitals/index.js.map +1 -0
- package/package.json +94 -0
- package/types/cookies/CookiePlugin.d.ts +55 -0
- package/types/cookies/index.d.ts +2 -0
- package/types/core/DOMChangesPluginLite.d.ts +89 -0
- package/types/core/DOMManipulatorLite.d.ts +21 -0
- package/types/core/ExposureTracker.d.ts +81 -0
- package/types/core/HTMLInjector.d.ts +19 -0
- package/types/core/PendingChangeManager.d.ts +31 -0
- package/types/core/StyleSheetManager.d.ts +16 -0
- package/types/entries/cookie-only.d.ts +8 -0
- package/types/entries/dom-only.d.ts +9 -0
- package/types/entries/dom-with-overrides-full.d.ts +15 -0
- package/types/entries/dom-with-overrides-lite.d.ts +11 -0
- package/types/entries/overrides-full-only.d.ts +11 -0
- package/types/entries/overrides-lite-only.d.ts +8 -0
- package/types/entries/vitals-only.d.ts +8 -0
- package/types/index.d.ts +13 -0
- package/types/overrides/BrowserCookieAdapter.d.ts +6 -0
- package/types/overrides/OverridesPlugin.d.ts +33 -0
- package/types/overrides/OverridesPluginFull.d.ts +9 -0
- package/types/overrides/OverridesPluginLite.d.ts +27 -0
- package/types/overrides/index.d.ts +3 -0
- package/types/overrides/types.d.ts +43 -0
- package/types/parsers/VariantExtractor.d.ts +49 -0
- package/types/types/index.d.ts +177 -0
- package/types/utils/URLMatcher.d.ts +20 -0
- package/types/utils/debug.d.ts +41 -0
- package/types/vitals/WebVitalsPlugin.d.ts +37 -0
- package/types/vitals/index.d.ts +2 -0
|
@@ -0,0 +1,903 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
/**
|
|
3
|
+
* Full-featured version of OverridesPlugin
|
|
4
|
+
* Extends OverridesPluginLite with API fetching for non-running experiments
|
|
5
|
+
* Supports server-side rendering, cookie adapters, and dev environments
|
|
6
|
+
*/
|
|
7
|
+
var __extends = (this && this.__extends) || (function () {
|
|
8
|
+
var extendStatics = function (d, b) {
|
|
9
|
+
extendStatics = Object.setPrototypeOf ||
|
|
10
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
11
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
12
|
+
return extendStatics(d, b);
|
|
13
|
+
};
|
|
14
|
+
return function (d, b) {
|
|
15
|
+
if (typeof b !== "function" && b !== null)
|
|
16
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
17
|
+
extendStatics(d, b);
|
|
18
|
+
function __() { this.constructor = d; }
|
|
19
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
20
|
+
};
|
|
21
|
+
})();
|
|
22
|
+
var __assign = (this && this.__assign) || function () {
|
|
23
|
+
__assign = Object.assign || function(t) {
|
|
24
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
25
|
+
s = arguments[i];
|
|
26
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
27
|
+
t[p] = s[p];
|
|
28
|
+
}
|
|
29
|
+
return t;
|
|
30
|
+
};
|
|
31
|
+
return __assign.apply(this, arguments);
|
|
32
|
+
};
|
|
33
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
34
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
35
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
36
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
37
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
38
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
39
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
43
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
44
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
45
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
46
|
+
function step(op) {
|
|
47
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
48
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
49
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
50
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
51
|
+
switch (op[0]) {
|
|
52
|
+
case 0: case 1: t = op; break;
|
|
53
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
54
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
55
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
56
|
+
default:
|
|
57
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
58
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
59
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
60
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
61
|
+
if (t[2]) _.ops.pop();
|
|
62
|
+
_.trys.pop(); continue;
|
|
63
|
+
}
|
|
64
|
+
op = body.call(thisArg, _);
|
|
65
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
66
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
var __values = (this && this.__values) || function(o) {
|
|
70
|
+
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
71
|
+
if (m) return m.call(o);
|
|
72
|
+
if (o && typeof o.length === "number") return {
|
|
73
|
+
next: function () {
|
|
74
|
+
if (o && i >= o.length) o = void 0;
|
|
75
|
+
return { value: o && o[i++], done: !o };
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
79
|
+
};
|
|
80
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
81
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
82
|
+
if (!m) return o;
|
|
83
|
+
var i = m.call(o), r, ar = [], e;
|
|
84
|
+
try {
|
|
85
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
86
|
+
}
|
|
87
|
+
catch (error) { e = { error: error }; }
|
|
88
|
+
finally {
|
|
89
|
+
try {
|
|
90
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
91
|
+
}
|
|
92
|
+
finally { if (e) throw e.error; }
|
|
93
|
+
}
|
|
94
|
+
return ar;
|
|
95
|
+
};
|
|
96
|
+
import { OverridesPluginLite } from './OverridesPluginLite';
|
|
97
|
+
import { logDebug } from '../utils/debug';
|
|
98
|
+
var OverridesPlugin = /** @class */ (function (_super) {
|
|
99
|
+
__extends(OverridesPlugin, _super);
|
|
100
|
+
function OverridesPlugin(config) {
|
|
101
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
|
|
102
|
+
// Pass a simplified config to the base class
|
|
103
|
+
var _this = _super.call(this, {
|
|
104
|
+
context: config.context,
|
|
105
|
+
cookieName: config.cookieName,
|
|
106
|
+
useQueryString: (_a = config.useQueryString) !== null && _a !== void 0 ? _a : typeof window !== 'undefined',
|
|
107
|
+
queryPrefix: (_b = config.queryPrefix) !== null && _b !== void 0 ? _b : '_exp_',
|
|
108
|
+
persistQueryToCookie: (_c = config.persistQueryToCookie) !== null && _c !== void 0 ? _c : false,
|
|
109
|
+
debug: (_d = config.debug) !== null && _d !== void 0 ? _d : false,
|
|
110
|
+
}) || this;
|
|
111
|
+
_this.onExperimentsAddedCallbacks = [];
|
|
112
|
+
if (!config.context) {
|
|
113
|
+
throw new Error('[OverridesPlugin] Context is required');
|
|
114
|
+
}
|
|
115
|
+
// Detect environment
|
|
116
|
+
_this.isServerSide = typeof window === 'undefined';
|
|
117
|
+
// Get SDK endpoint from context if not provided
|
|
118
|
+
var sdkEndpoint = config.sdkEndpoint;
|
|
119
|
+
if (!sdkEndpoint) {
|
|
120
|
+
var contextInternal = config.context;
|
|
121
|
+
if (contextInternal._endpoint) {
|
|
122
|
+
sdkEndpoint = contextInternal._endpoint;
|
|
123
|
+
}
|
|
124
|
+
else if ((_e = contextInternal._config) === null || _e === void 0 ? void 0 : _e.endpoint) {
|
|
125
|
+
sdkEndpoint = contextInternal._config.endpoint;
|
|
126
|
+
}
|
|
127
|
+
else if ((_f = contextInternal._dataProvider) === null || _f === void 0 ? void 0 : _f._endpoint) {
|
|
128
|
+
sdkEndpoint = contextInternal._dataProvider._endpoint;
|
|
129
|
+
}
|
|
130
|
+
else if ((_g = contextInternal._options) === null || _g === void 0 ? void 0 : _g.endpoint) {
|
|
131
|
+
sdkEndpoint = contextInternal._options.endpoint.replace('/v1', '');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// For the full plugin, we should have an endpoint available
|
|
135
|
+
if (!sdkEndpoint && !config.absmartlyEndpoint) {
|
|
136
|
+
// Try one more time to get from context
|
|
137
|
+
var contextInternal = config.context;
|
|
138
|
+
if (!contextInternal._endpoint &&
|
|
139
|
+
!((_h = contextInternal._config) === null || _h === void 0 ? void 0 : _h.endpoint) &&
|
|
140
|
+
!((_j = contextInternal._dataProvider) === null || _j === void 0 ? void 0 : _j._endpoint) &&
|
|
141
|
+
!((_k = contextInternal._options) === null || _k === void 0 ? void 0 : _k.endpoint)) {
|
|
142
|
+
throw new Error('[OverridesPlugin] SDK endpoint must be provided if not available from context');
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Setup full configuration
|
|
146
|
+
_this.fullConfig = {
|
|
147
|
+
context: config.context,
|
|
148
|
+
cookieName: config.cookieName,
|
|
149
|
+
cookieAdapter: config.cookieAdapter,
|
|
150
|
+
cookieOptions: (_l = config.cookieOptions) !== null && _l !== void 0 ? _l : { path: '/' },
|
|
151
|
+
useQueryString: (_m = config.useQueryString) !== null && _m !== void 0 ? _m : !_this.isServerSide,
|
|
152
|
+
queryPrefix: (_o = config.queryPrefix) !== null && _o !== void 0 ? _o : '_exp_',
|
|
153
|
+
envParam: (_p = config.envParam) !== null && _p !== void 0 ? _p : 'env',
|
|
154
|
+
persistQueryToCookie: (_q = config.persistQueryToCookie) !== null && _q !== void 0 ? _q : false,
|
|
155
|
+
url: config.url,
|
|
156
|
+
absmartlyEndpoint: (_r = config.absmartlyEndpoint) !== null && _r !== void 0 ? _r : '',
|
|
157
|
+
sdkEndpoint: sdkEndpoint || '',
|
|
158
|
+
domChangesFieldName: (_s = config.domChangesFieldName) !== null && _s !== void 0 ? _s : '__dom_changes',
|
|
159
|
+
sdkApiKey: (_t = config.sdkApiKey) !== null && _t !== void 0 ? _t : '',
|
|
160
|
+
application: (_u = config.application) !== null && _u !== void 0 ? _u : '',
|
|
161
|
+
environment: (_v = config.environment) !== null && _v !== void 0 ? _v : '',
|
|
162
|
+
debug: (_w = config.debug) !== null && _w !== void 0 ? _w : false,
|
|
163
|
+
};
|
|
164
|
+
if (_this.fullConfig.debug) {
|
|
165
|
+
logDebug('[OverridesPlugin] Initialized with config:', {
|
|
166
|
+
isServerSide: _this.isServerSide,
|
|
167
|
+
cookieName: _this.fullConfig.cookieName,
|
|
168
|
+
useQueryString: _this.fullConfig.useQueryString,
|
|
169
|
+
queryPrefix: _this.fullConfig.queryPrefix,
|
|
170
|
+
envParam: _this.fullConfig.envParam,
|
|
171
|
+
persistQueryToCookie: _this.fullConfig.persistQueryToCookie,
|
|
172
|
+
sdkEndpoint: _this.fullConfig.sdkEndpoint,
|
|
173
|
+
absmartlyEndpoint: _this.fullConfig.absmartlyEndpoint,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
return _this;
|
|
177
|
+
}
|
|
178
|
+
OverridesPlugin.prototype.ready = function () {
|
|
179
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
180
|
+
var overridesData;
|
|
181
|
+
return __generator(this, function (_a) {
|
|
182
|
+
switch (_a.label) {
|
|
183
|
+
case 0:
|
|
184
|
+
// Check if already initialized (use base class property)
|
|
185
|
+
if (this.initialized) {
|
|
186
|
+
if (this.fullConfig.debug) {
|
|
187
|
+
logDebug('[OverridesPlugin] Already initialized, skipping re-initialization');
|
|
188
|
+
}
|
|
189
|
+
return [2 /*return*/];
|
|
190
|
+
}
|
|
191
|
+
// Mark as initialized immediately to prevent concurrent calls
|
|
192
|
+
this.initialized = true;
|
|
193
|
+
// Register with context
|
|
194
|
+
this.registerWithContext();
|
|
195
|
+
overridesData = this.getOverrides();
|
|
196
|
+
if (Object.keys(overridesData.overrides).length === 0) {
|
|
197
|
+
if (this.fullConfig.debug) {
|
|
198
|
+
logDebug('[OverridesPlugin] No overrides found');
|
|
199
|
+
}
|
|
200
|
+
return [2 /*return*/];
|
|
201
|
+
}
|
|
202
|
+
// Apply overrides with API fetching
|
|
203
|
+
return [4 /*yield*/, this.applyOverridesWithFetching(overridesData.overrides, overridesData.devEnv)];
|
|
204
|
+
case 1:
|
|
205
|
+
// Apply overrides with API fetching
|
|
206
|
+
_a.sent();
|
|
207
|
+
return [2 /*return*/];
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
};
|
|
212
|
+
// Alias for backwards compatibility
|
|
213
|
+
OverridesPlugin.prototype.initialize = function () {
|
|
214
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
215
|
+
return __generator(this, function (_a) {
|
|
216
|
+
return [2 /*return*/, this.ready()];
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
};
|
|
220
|
+
OverridesPlugin.prototype.getOverrides = function () {
|
|
221
|
+
var overridesData = { overrides: {}, devEnv: null };
|
|
222
|
+
// First get cookie overrides if enabled
|
|
223
|
+
if (this.fullConfig.cookieName) {
|
|
224
|
+
var cookieData = this.getEnhancedCookieOverrides();
|
|
225
|
+
overridesData.overrides = __assign({}, cookieData.overrides);
|
|
226
|
+
overridesData.devEnv = cookieData.devEnv;
|
|
227
|
+
}
|
|
228
|
+
// Then check query string and merge/override if enabled
|
|
229
|
+
if (this.fullConfig.useQueryString) {
|
|
230
|
+
var queryData = this.getEnhancedQueryStringOverrides();
|
|
231
|
+
// Query string overrides take precedence over cookies
|
|
232
|
+
if (Object.keys(queryData.overrides).length > 0) {
|
|
233
|
+
// Merge overrides, with query string taking precedence
|
|
234
|
+
overridesData.overrides = __assign(__assign({}, overridesData.overrides), queryData.overrides);
|
|
235
|
+
// Query string env takes precedence if specified
|
|
236
|
+
if (queryData.devEnv !== null) {
|
|
237
|
+
overridesData.devEnv = queryData.devEnv;
|
|
238
|
+
}
|
|
239
|
+
// Persist merged overrides to cookie if requested
|
|
240
|
+
if (this.fullConfig.persistQueryToCookie && this.fullConfig.cookieName) {
|
|
241
|
+
this.persistEnhancedOverridesToCookie(overridesData);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return overridesData;
|
|
246
|
+
};
|
|
247
|
+
OverridesPlugin.prototype.getEnhancedQueryStringOverrides = function () {
|
|
248
|
+
var e_1, _a;
|
|
249
|
+
try {
|
|
250
|
+
var urlParams = void 0;
|
|
251
|
+
if (this.isServerSide) {
|
|
252
|
+
// Server-side: use provided URL
|
|
253
|
+
if (!this.fullConfig.url) {
|
|
254
|
+
return { overrides: {}, devEnv: null };
|
|
255
|
+
}
|
|
256
|
+
var url = typeof this.fullConfig.url === 'string'
|
|
257
|
+
? new URL(this.fullConfig.url)
|
|
258
|
+
: this.fullConfig.url;
|
|
259
|
+
urlParams = new URLSearchParams(url.search);
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
// Client-side: use window.location
|
|
263
|
+
urlParams = new URLSearchParams(window.location.search);
|
|
264
|
+
}
|
|
265
|
+
var overrides = {};
|
|
266
|
+
var devEnv = null;
|
|
267
|
+
// Get environment from query param
|
|
268
|
+
if (this.fullConfig.envParam) {
|
|
269
|
+
var env = urlParams.get(this.fullConfig.envParam);
|
|
270
|
+
if (env) {
|
|
271
|
+
devEnv = env;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
// Check for experiment parameters with prefix
|
|
275
|
+
var prefix = this.fullConfig.queryPrefix;
|
|
276
|
+
try {
|
|
277
|
+
for (var _b = __values(urlParams.entries()), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
278
|
+
var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
|
|
279
|
+
if (key.startsWith(prefix)) {
|
|
280
|
+
var experimentName = key.substring(prefix.length);
|
|
281
|
+
if (experimentName) {
|
|
282
|
+
var parts = value.split(',');
|
|
283
|
+
var variant = parseInt(parts[0], 10);
|
|
284
|
+
if (!isNaN(variant)) {
|
|
285
|
+
if (parts.length === 1) {
|
|
286
|
+
overrides[experimentName] = variant;
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
overrides[experimentName] = {
|
|
290
|
+
variant: variant,
|
|
291
|
+
env: parts[1] ? parseInt(parts[1], 10) : undefined,
|
|
292
|
+
id: parts[2] ? parseInt(parts[2], 10) : undefined,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
301
|
+
finally {
|
|
302
|
+
try {
|
|
303
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
304
|
+
}
|
|
305
|
+
finally { if (e_1) throw e_1.error; }
|
|
306
|
+
}
|
|
307
|
+
if (this.fullConfig.debug && Object.keys(overrides).length > 0) {
|
|
308
|
+
logDebug('[OverridesPlugin] Query string overrides:', overrides, 'env:', devEnv);
|
|
309
|
+
}
|
|
310
|
+
return { overrides: overrides, devEnv: devEnv };
|
|
311
|
+
}
|
|
312
|
+
catch (error) {
|
|
313
|
+
logDebug('[OverridesPlugin] Error parsing query string:', error);
|
|
314
|
+
return { overrides: {}, devEnv: null };
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
OverridesPlugin.prototype.getEnhancedCookieOverrides = function () {
|
|
318
|
+
var e_2, _a;
|
|
319
|
+
if (!this.fullConfig.cookieName) {
|
|
320
|
+
return { overrides: {}, devEnv: null };
|
|
321
|
+
}
|
|
322
|
+
var cookieValue = null;
|
|
323
|
+
if (this.fullConfig.cookieAdapter) {
|
|
324
|
+
// Server-side or custom adapter
|
|
325
|
+
cookieValue = this.fullConfig.cookieAdapter.get(this.fullConfig.cookieName);
|
|
326
|
+
}
|
|
327
|
+
else if (typeof document !== 'undefined') {
|
|
328
|
+
// Client-side: read directly from document.cookie
|
|
329
|
+
var nameEQ = this.fullConfig.cookieName + '=';
|
|
330
|
+
var cookies = document.cookie.split(';');
|
|
331
|
+
try {
|
|
332
|
+
for (var cookies_1 = __values(cookies), cookies_1_1 = cookies_1.next(); !cookies_1_1.done; cookies_1_1 = cookies_1.next()) {
|
|
333
|
+
var cookie = cookies_1_1.value;
|
|
334
|
+
cookie = cookie.trim();
|
|
335
|
+
if (cookie.indexOf(nameEQ) === 0) {
|
|
336
|
+
cookieValue = decodeURIComponent(cookie.substring(nameEQ.length));
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
342
|
+
finally {
|
|
343
|
+
try {
|
|
344
|
+
if (cookies_1_1 && !cookies_1_1.done && (_a = cookies_1.return)) _a.call(cookies_1);
|
|
345
|
+
}
|
|
346
|
+
finally { if (e_2) throw e_2.error; }
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
if (this.fullConfig.debug && cookieValue) {
|
|
350
|
+
logDebug('[OverridesPlugin] Raw cookie value:', cookieValue);
|
|
351
|
+
}
|
|
352
|
+
var parsed = this.parseEnhancedCookieValue(cookieValue);
|
|
353
|
+
if (this.fullConfig.debug && Object.keys(parsed.overrides).length > 0) {
|
|
354
|
+
logDebug('[OverridesPlugin] Parsed cookie overrides:', parsed);
|
|
355
|
+
}
|
|
356
|
+
return parsed;
|
|
357
|
+
};
|
|
358
|
+
OverridesPlugin.prototype.parseEnhancedCookieValue = function (value) {
|
|
359
|
+
var e_3, _a;
|
|
360
|
+
if (!value)
|
|
361
|
+
return { overrides: {}, devEnv: null };
|
|
362
|
+
try {
|
|
363
|
+
var devEnv = null;
|
|
364
|
+
var experimentsStr = value;
|
|
365
|
+
// Check if dev environment is included
|
|
366
|
+
if (value.startsWith('devEnv=')) {
|
|
367
|
+
var parts = value.split('|');
|
|
368
|
+
devEnv = decodeURIComponent(parts[0].substring(7));
|
|
369
|
+
experimentsStr = parts[1] || '';
|
|
370
|
+
}
|
|
371
|
+
var overrides = {};
|
|
372
|
+
if (experimentsStr) {
|
|
373
|
+
var experiments = experimentsStr.split(',');
|
|
374
|
+
try {
|
|
375
|
+
for (var experiments_1 = __values(experiments), experiments_1_1 = experiments_1.next(); !experiments_1_1.done; experiments_1_1 = experiments_1.next()) {
|
|
376
|
+
var exp = experiments_1_1.value;
|
|
377
|
+
var _b = __read(exp.split(':'), 2), name_1 = _b[0], values = _b[1];
|
|
378
|
+
if (!name_1 || !values)
|
|
379
|
+
continue;
|
|
380
|
+
var decodedName = decodeURIComponent(name_1);
|
|
381
|
+
var parts = values.split('.');
|
|
382
|
+
var variant = parseInt(parts[0], 10);
|
|
383
|
+
// Skip if variant is not a valid number
|
|
384
|
+
if (isNaN(variant))
|
|
385
|
+
continue;
|
|
386
|
+
if (parts.length === 1) {
|
|
387
|
+
overrides[decodedName] = variant;
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
overrides[decodedName] = {
|
|
391
|
+
variant: variant,
|
|
392
|
+
env: parts[1] ? parseInt(parts[1], 10) : undefined,
|
|
393
|
+
id: parts[2] ? parseInt(parts[2], 10) : undefined,
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
399
|
+
finally {
|
|
400
|
+
try {
|
|
401
|
+
if (experiments_1_1 && !experiments_1_1.done && (_a = experiments_1.return)) _a.call(experiments_1);
|
|
402
|
+
}
|
|
403
|
+
finally { if (e_3) throw e_3.error; }
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
return { overrides: overrides, devEnv: devEnv };
|
|
407
|
+
}
|
|
408
|
+
catch (error) {
|
|
409
|
+
logDebug('[OverridesPlugin] Error parsing overrides:', error);
|
|
410
|
+
return { overrides: {}, devEnv: null };
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
OverridesPlugin.prototype.persistEnhancedOverridesToCookie = function (data) {
|
|
414
|
+
var e_4, _a;
|
|
415
|
+
if (!this.fullConfig.cookieName)
|
|
416
|
+
return;
|
|
417
|
+
var parts = [];
|
|
418
|
+
// Add dev environment if present
|
|
419
|
+
if (data.devEnv) {
|
|
420
|
+
parts.push("devEnv=".concat(encodeURIComponent(data.devEnv)));
|
|
421
|
+
}
|
|
422
|
+
// Add experiments
|
|
423
|
+
var expParts = [];
|
|
424
|
+
try {
|
|
425
|
+
for (var _b = __values(Object.entries(data.overrides)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
426
|
+
var _d = __read(_c.value, 2), name_2 = _d[0], value = _d[1];
|
|
427
|
+
var encodedName = encodeURIComponent(name_2);
|
|
428
|
+
if (typeof value === 'number') {
|
|
429
|
+
expParts.push("".concat(encodedName, ":").concat(value));
|
|
430
|
+
}
|
|
431
|
+
else {
|
|
432
|
+
var v = value;
|
|
433
|
+
var str = "".concat(encodedName, ":").concat(v.variant);
|
|
434
|
+
if (v.env !== undefined)
|
|
435
|
+
str += ".".concat(v.env);
|
|
436
|
+
if (v.id !== undefined)
|
|
437
|
+
str += ".".concat(v.id);
|
|
438
|
+
expParts.push(str);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
443
|
+
finally {
|
|
444
|
+
try {
|
|
445
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
446
|
+
}
|
|
447
|
+
finally { if (e_4) throw e_4.error; }
|
|
448
|
+
}
|
|
449
|
+
var cookieValue = parts.length > 0 ? "".concat(parts.join('|'), "|").concat(expParts.join(',')) : expParts.join(',');
|
|
450
|
+
if (this.fullConfig.cookieAdapter) {
|
|
451
|
+
// Server-side or custom adapter
|
|
452
|
+
var options = __assign({}, this.fullConfig.cookieOptions);
|
|
453
|
+
// Server-side defaults
|
|
454
|
+
if (this.isServerSide) {
|
|
455
|
+
if (options.httpOnly === undefined) {
|
|
456
|
+
options.httpOnly = true;
|
|
457
|
+
}
|
|
458
|
+
if (options.secure === undefined) {
|
|
459
|
+
options.secure = true;
|
|
460
|
+
}
|
|
461
|
+
if (options.sameSite === undefined) {
|
|
462
|
+
options.sameSite = 'lax';
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
this.fullConfig.cookieAdapter.set(this.fullConfig.cookieName, cookieValue, options);
|
|
466
|
+
}
|
|
467
|
+
else if (typeof document !== 'undefined') {
|
|
468
|
+
// Client-side: write directly to document.cookie
|
|
469
|
+
var options = this.fullConfig.cookieOptions || {};
|
|
470
|
+
var cookieString = "".concat(this.fullConfig.cookieName, "=").concat(encodeURIComponent(cookieValue));
|
|
471
|
+
if (options.path)
|
|
472
|
+
cookieString += ";path=".concat(options.path);
|
|
473
|
+
if (options.maxAge)
|
|
474
|
+
cookieString += ";max-age=".concat(options.maxAge);
|
|
475
|
+
var optionsWithExpires = options;
|
|
476
|
+
if (optionsWithExpires.expires) {
|
|
477
|
+
var expiresDate = optionsWithExpires.expires instanceof Date
|
|
478
|
+
? optionsWithExpires.expires.toUTCString()
|
|
479
|
+
: optionsWithExpires.expires;
|
|
480
|
+
cookieString += ";expires=".concat(expiresDate);
|
|
481
|
+
}
|
|
482
|
+
if (options.domain)
|
|
483
|
+
cookieString += ";domain=".concat(options.domain);
|
|
484
|
+
if (options.secure)
|
|
485
|
+
cookieString += ';secure';
|
|
486
|
+
if (options.sameSite)
|
|
487
|
+
cookieString += ";samesite=".concat(options.sameSite);
|
|
488
|
+
document.cookie = cookieString;
|
|
489
|
+
}
|
|
490
|
+
if (this.fullConfig.debug) {
|
|
491
|
+
logDebug('[OverridesPlugin] Persisted to cookie:', cookieValue);
|
|
492
|
+
}
|
|
493
|
+
};
|
|
494
|
+
OverridesPlugin.prototype.applyOverridesWithFetching = function (overrides, devEnv) {
|
|
495
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
496
|
+
var devExperiments, apiExperimentIds, _a, _b, _c, name_3, value, override, effectiveDevEnv, _d, _e, _f, experimentName, value, variant;
|
|
497
|
+
var e_5, _g, e_6, _h;
|
|
498
|
+
return __generator(this, function (_j) {
|
|
499
|
+
switch (_j.label) {
|
|
500
|
+
case 0:
|
|
501
|
+
// Log all overrides at initialization
|
|
502
|
+
logDebug('[OverridesPlugin] Initializing with overrides:', overrides);
|
|
503
|
+
logDebug('[OverridesPlugin] Dev environment:', devEnv);
|
|
504
|
+
devExperiments = [];
|
|
505
|
+
apiExperimentIds = new Set();
|
|
506
|
+
try {
|
|
507
|
+
// Categorize experiments
|
|
508
|
+
for (_a = __values(Object.entries(overrides)), _b = _a.next(); !_b.done; _b = _a.next()) {
|
|
509
|
+
_c = __read(_b.value, 2), name_3 = _c[0], value = _c[1];
|
|
510
|
+
override = typeof value === 'number' ? { variant: value } : value;
|
|
511
|
+
if (override.env === 1) {
|
|
512
|
+
// Development environment experiment
|
|
513
|
+
logDebug("[OverridesPlugin] ".concat(name_3, " categorized as DEV experiment (env=1)"));
|
|
514
|
+
devExperiments.push([name_3, override]);
|
|
515
|
+
}
|
|
516
|
+
else if (override.env === 2 && override.id) {
|
|
517
|
+
// Draft experiment with ID
|
|
518
|
+
logDebug("[OverridesPlugin] ".concat(name_3, " categorized as DRAFT experiment (env=2, id=").concat(override.id, ")"));
|
|
519
|
+
apiExperimentIds.add(override.id);
|
|
520
|
+
}
|
|
521
|
+
else {
|
|
522
|
+
// Running experiment (env=0 or undefined)
|
|
523
|
+
logDebug("[OverridesPlugin] ".concat(name_3, " categorized as RUNNING experiment (env=").concat(override.env || 0, ")"));
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
528
|
+
finally {
|
|
529
|
+
try {
|
|
530
|
+
if (_b && !_b.done && (_g = _a.return)) _g.call(_a);
|
|
531
|
+
}
|
|
532
|
+
finally { if (e_5) throw e_5.error; }
|
|
533
|
+
}
|
|
534
|
+
// Log summary
|
|
535
|
+
logDebug('[OverridesPlugin] Categorization summary:', {
|
|
536
|
+
total_overrides: Object.keys(overrides).length,
|
|
537
|
+
dev_experiments: devExperiments.length,
|
|
538
|
+
draft_experiments: apiExperimentIds.size,
|
|
539
|
+
running_experiments: Object.keys(overrides).length - devExperiments.length - apiExperimentIds.size,
|
|
540
|
+
dev_environment: devEnv,
|
|
541
|
+
});
|
|
542
|
+
if (!(apiExperimentIds.size > 0)) return [3 /*break*/, 2];
|
|
543
|
+
logDebug("[OverridesPlugin] Will fetch ".concat(apiExperimentIds.size, " DRAFT experiments from API"));
|
|
544
|
+
return [4 /*yield*/, this.fetchFromAPI(Array.from(apiExperimentIds))];
|
|
545
|
+
case 1:
|
|
546
|
+
_j.sent();
|
|
547
|
+
_j.label = 2;
|
|
548
|
+
case 2:
|
|
549
|
+
effectiveDevEnv = devEnv || this.fullConfig.environment || null;
|
|
550
|
+
if (!(devExperiments.length > 0 && effectiveDevEnv)) return [3 /*break*/, 4];
|
|
551
|
+
logDebug("[OverridesPlugin] Will fetch ".concat(devExperiments.length, " DEV experiments for environment: ").concat(effectiveDevEnv));
|
|
552
|
+
return [4 /*yield*/, this.fetchFromDevSDK(devExperiments, effectiveDevEnv)];
|
|
553
|
+
case 3:
|
|
554
|
+
_j.sent();
|
|
555
|
+
return [3 /*break*/, 5];
|
|
556
|
+
case 4:
|
|
557
|
+
if (devExperiments.length > 0) {
|
|
558
|
+
logDebug("[OverridesPlugin] Have ".concat(devExperiments.length, " DEV experiments but NO devEnv specified - NOT fetching"));
|
|
559
|
+
}
|
|
560
|
+
_j.label = 5;
|
|
561
|
+
case 5:
|
|
562
|
+
try {
|
|
563
|
+
// Apply all overrides to context
|
|
564
|
+
for (_d = __values(Object.entries(overrides)), _e = _d.next(); !_e.done; _e = _d.next()) {
|
|
565
|
+
_f = __read(_e.value, 2), experimentName = _f[0], value = _f[1];
|
|
566
|
+
variant = typeof value === 'number' ? value : value.variant;
|
|
567
|
+
this.fullConfig.context.override(experimentName, variant);
|
|
568
|
+
if (this.fullConfig.debug) {
|
|
569
|
+
logDebug("[OverridesPlugin] Override: ".concat(experimentName, " -> variant ").concat(variant));
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
574
|
+
finally {
|
|
575
|
+
try {
|
|
576
|
+
if (_e && !_e.done && (_h = _d.return)) _h.call(_d);
|
|
577
|
+
}
|
|
578
|
+
finally { if (e_6) throw e_6.error; }
|
|
579
|
+
}
|
|
580
|
+
return [2 /*return*/];
|
|
581
|
+
}
|
|
582
|
+
});
|
|
583
|
+
});
|
|
584
|
+
};
|
|
585
|
+
OverridesPlugin.prototype.fetchFromAPI = function (experimentIds) {
|
|
586
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
587
|
+
var apiEndpoint, apiUrl, headers, response, data, error_1;
|
|
588
|
+
return __generator(this, function (_a) {
|
|
589
|
+
switch (_a.label) {
|
|
590
|
+
case 0:
|
|
591
|
+
if (experimentIds.length === 0) {
|
|
592
|
+
if (this.fullConfig.debug) {
|
|
593
|
+
logDebug('[OverridesPlugin] No experiment IDs to fetch from API');
|
|
594
|
+
}
|
|
595
|
+
return [2 /*return*/];
|
|
596
|
+
}
|
|
597
|
+
apiEndpoint = this.fullConfig.absmartlyEndpoint;
|
|
598
|
+
if (!apiEndpoint) {
|
|
599
|
+
// Default: convert SDK endpoint to API endpoint
|
|
600
|
+
apiEndpoint = this.fullConfig.sdkEndpoint.replace('.absmartly.io', '.absmartly.com');
|
|
601
|
+
}
|
|
602
|
+
// Remove trailing /v1 if it exists to avoid double /v1/v1
|
|
603
|
+
if (apiEndpoint.endsWith('/v1')) {
|
|
604
|
+
apiEndpoint = apiEndpoint.slice(0, -3);
|
|
605
|
+
}
|
|
606
|
+
// Ensure https protocol
|
|
607
|
+
if (!apiEndpoint.startsWith('http')) {
|
|
608
|
+
apiEndpoint = "https://".concat(apiEndpoint);
|
|
609
|
+
}
|
|
610
|
+
apiUrl = "".concat(apiEndpoint, "/v1/experiments?ids=").concat(experimentIds.join(','));
|
|
611
|
+
if (this.fullConfig.debug) {
|
|
612
|
+
logDebug('[OverridesPlugin] Fetching non-running experiments from API:', apiUrl);
|
|
613
|
+
}
|
|
614
|
+
_a.label = 1;
|
|
615
|
+
case 1:
|
|
616
|
+
_a.trys.push([1, 4, , 5]);
|
|
617
|
+
headers = {
|
|
618
|
+
'Content-Type': 'application/json',
|
|
619
|
+
};
|
|
620
|
+
if (this.fullConfig.sdkApiKey) {
|
|
621
|
+
headers['Authorization'] = "ApiKey ".concat(this.fullConfig.sdkApiKey);
|
|
622
|
+
}
|
|
623
|
+
return [4 /*yield*/, fetch(apiUrl, {
|
|
624
|
+
method: 'GET',
|
|
625
|
+
credentials: 'include',
|
|
626
|
+
headers: headers,
|
|
627
|
+
mode: 'cors',
|
|
628
|
+
})];
|
|
629
|
+
case 2:
|
|
630
|
+
response = _a.sent();
|
|
631
|
+
logDebug('[OverridesPlugin] API Response status:', response.status, response.statusText);
|
|
632
|
+
if (!response.ok) {
|
|
633
|
+
logDebug("[OverridesPlugin] API request failed with status ".concat(response.status));
|
|
634
|
+
if (response.status === 401) {
|
|
635
|
+
logDebug('[OverridesPlugin] Check if you need to log in to the ABsmartly console first');
|
|
636
|
+
}
|
|
637
|
+
return [2 /*return*/];
|
|
638
|
+
}
|
|
639
|
+
return [4 /*yield*/, response.json()];
|
|
640
|
+
case 3:
|
|
641
|
+
data = _a.sent();
|
|
642
|
+
if (data.experiments) {
|
|
643
|
+
// Inject experiments into context data
|
|
644
|
+
this.injectExperimentsIntoContext(data.experiments);
|
|
645
|
+
// Notify listeners
|
|
646
|
+
this.notifyExperimentsAdded();
|
|
647
|
+
}
|
|
648
|
+
return [3 /*break*/, 5];
|
|
649
|
+
case 4:
|
|
650
|
+
error_1 = _a.sent();
|
|
651
|
+
logDebug('[OverridesPlugin] Failed to fetch experiments from API:', error_1);
|
|
652
|
+
return [3 /*break*/, 5];
|
|
653
|
+
case 5: return [2 /*return*/];
|
|
654
|
+
}
|
|
655
|
+
});
|
|
656
|
+
});
|
|
657
|
+
};
|
|
658
|
+
OverridesPlugin.prototype.fetchFromDevSDK = function (_experiments, devEnv) {
|
|
659
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
660
|
+
var sdkEndpoint, devSdkUrl, headers, response, data, experimentsArray, error_2;
|
|
661
|
+
return __generator(this, function (_a) {
|
|
662
|
+
switch (_a.label) {
|
|
663
|
+
case 0:
|
|
664
|
+
sdkEndpoint = this.fullConfig.sdkEndpoint;
|
|
665
|
+
// Ensure https protocol
|
|
666
|
+
if (!sdkEndpoint.startsWith('http')) {
|
|
667
|
+
sdkEndpoint = "https://".concat(sdkEndpoint);
|
|
668
|
+
}
|
|
669
|
+
// Normalize: strip trailing /v1 if present to avoid /v1/v1
|
|
670
|
+
if (sdkEndpoint.endsWith('/v1')) {
|
|
671
|
+
sdkEndpoint = sdkEndpoint.slice(0, -3);
|
|
672
|
+
}
|
|
673
|
+
devSdkUrl = "".concat(sdkEndpoint, "/v1/context?environment=").concat(encodeURIComponent(devEnv));
|
|
674
|
+
if (this.fullConfig.application) {
|
|
675
|
+
devSdkUrl += "&application=".concat(encodeURIComponent(this.fullConfig.application));
|
|
676
|
+
}
|
|
677
|
+
if (this.fullConfig.debug) {
|
|
678
|
+
logDebug('[OverridesPlugin] Fetching development experiments from SDK:', devSdkUrl);
|
|
679
|
+
}
|
|
680
|
+
_a.label = 1;
|
|
681
|
+
case 1:
|
|
682
|
+
_a.trys.push([1, 4, , 5]);
|
|
683
|
+
headers = {};
|
|
684
|
+
if (this.fullConfig.sdkApiKey) {
|
|
685
|
+
headers['Authorization'] = "ApiKey ".concat(this.fullConfig.sdkApiKey);
|
|
686
|
+
}
|
|
687
|
+
return [4 /*yield*/, fetch(devSdkUrl, {
|
|
688
|
+
method: 'GET',
|
|
689
|
+
headers: headers,
|
|
690
|
+
})];
|
|
691
|
+
case 2:
|
|
692
|
+
response = _a.sent();
|
|
693
|
+
logDebug('[OverridesPlugin] DEV Response status:', response.status, response.statusText);
|
|
694
|
+
if (!response.ok) {
|
|
695
|
+
logDebug("[OverridesPlugin] DEV SDK request failed with status ".concat(response.status));
|
|
696
|
+
return [2 /*return*/];
|
|
697
|
+
}
|
|
698
|
+
return [4 /*yield*/, response.json()];
|
|
699
|
+
case 3:
|
|
700
|
+
data = _a.sent();
|
|
701
|
+
if (data.experiments) {
|
|
702
|
+
experimentsArray = Object.entries(data.experiments).map(function (_a) {
|
|
703
|
+
var _b = __read(_a, 2), name = _b[0], exp = _b[1];
|
|
704
|
+
return (__assign(__assign({}, exp), { name: name }));
|
|
705
|
+
});
|
|
706
|
+
this.injectExperimentsIntoContext(experimentsArray);
|
|
707
|
+
// Notify listeners
|
|
708
|
+
this.notifyExperimentsAdded();
|
|
709
|
+
}
|
|
710
|
+
return [3 /*break*/, 5];
|
|
711
|
+
case 4:
|
|
712
|
+
error_2 = _a.sent();
|
|
713
|
+
logDebug('[OverridesPlugin] Failed to fetch experiments from dev SDK:', error_2);
|
|
714
|
+
return [3 /*break*/, 5];
|
|
715
|
+
case 5: return [2 /*return*/];
|
|
716
|
+
}
|
|
717
|
+
});
|
|
718
|
+
});
|
|
719
|
+
};
|
|
720
|
+
OverridesPlugin.prototype.injectExperimentsIntoContext = function (experiments) {
|
|
721
|
+
var e_7, _a, _b;
|
|
722
|
+
var _c, _d;
|
|
723
|
+
// Get original context data
|
|
724
|
+
var originalData = this.fullConfig.context.data.bind(this.fullConfig.context);
|
|
725
|
+
// Create a map of experiment names to new experiment data
|
|
726
|
+
var newExperimentsMap = new Map();
|
|
727
|
+
try {
|
|
728
|
+
for (var experiments_2 = __values(experiments), experiments_2_1 = experiments_2.next(); !experiments_2_1.done; experiments_2_1 = experiments_2.next()) {
|
|
729
|
+
var experiment = experiments_2_1.value;
|
|
730
|
+
// Transform API experiment format to context format
|
|
731
|
+
var contextExperiment = {
|
|
732
|
+
id: experiment.id,
|
|
733
|
+
name: experiment.name,
|
|
734
|
+
unitType: ((_c = experiment.unit_type) === null || _c === void 0 ? void 0 : _c.name) || 'user_id',
|
|
735
|
+
iteration: experiment.iteration || 1,
|
|
736
|
+
seedHi: 0,
|
|
737
|
+
seedLo: 0,
|
|
738
|
+
split: experiment.split || [],
|
|
739
|
+
trafficSeedHi: 0,
|
|
740
|
+
trafficSeedLo: 0,
|
|
741
|
+
trafficSplit: [0, 1],
|
|
742
|
+
fullOnVariant: 0,
|
|
743
|
+
applications: ((_d = experiment.applications) === null || _d === void 0 ? void 0 : _d.map(function (app) {
|
|
744
|
+
var _a;
|
|
745
|
+
return ({
|
|
746
|
+
name: ((_a = app.application) === null || _a === void 0 ? void 0 : _a.name) || app.name,
|
|
747
|
+
});
|
|
748
|
+
})) || [],
|
|
749
|
+
variants: [],
|
|
750
|
+
audience: experiment.audience || '',
|
|
751
|
+
audienceStrict: experiment.audience_strict || false,
|
|
752
|
+
};
|
|
753
|
+
// Process variants
|
|
754
|
+
if (experiment.variants && Array.isArray(experiment.variants)) {
|
|
755
|
+
for (var i = 0; i < experiment.variants.length; i++) {
|
|
756
|
+
var variant = experiment.variants[i];
|
|
757
|
+
var variantData = {
|
|
758
|
+
name: variant.name || "Variant ".concat(i),
|
|
759
|
+
config: typeof variant.config === 'string'
|
|
760
|
+
? variant.config
|
|
761
|
+
: JSON.stringify(variant.config || {}),
|
|
762
|
+
};
|
|
763
|
+
// Check if variant already has variables (from dev SDK)
|
|
764
|
+
if (variant.variables) {
|
|
765
|
+
variantData.variables = variant.variables;
|
|
766
|
+
}
|
|
767
|
+
// Otherwise try to parse from config (from API)
|
|
768
|
+
else if (variant.config) {
|
|
769
|
+
try {
|
|
770
|
+
var config = typeof variant.config === 'string' ? JSON.parse(variant.config) : variant.config;
|
|
771
|
+
var domChangesField = this.fullConfig.domChangesFieldName;
|
|
772
|
+
if (config[domChangesField]) {
|
|
773
|
+
// Store in variables format that VariantExtractor expects
|
|
774
|
+
variantData.variables = (_b = {},
|
|
775
|
+
_b[domChangesField] = config[domChangesField],
|
|
776
|
+
_b);
|
|
777
|
+
logDebug("[OverridesPlugin] Variant ".concat(i, " has DOM changes field '").concat(domChangesField, "'"));
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
catch (e) {
|
|
781
|
+
logDebug("[OverridesPlugin] Failed to parse variant config:", e);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
contextExperiment.variants[i] = variantData;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
newExperimentsMap.set(experiment.name, contextExperiment);
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
catch (e_7_1) { e_7 = { error: e_7_1 }; }
|
|
791
|
+
finally {
|
|
792
|
+
try {
|
|
793
|
+
if (experiments_2_1 && !experiments_2_1.done && (_a = experiments_2.return)) _a.call(experiments_2);
|
|
794
|
+
}
|
|
795
|
+
finally { if (e_7) throw e_7.error; }
|
|
796
|
+
}
|
|
797
|
+
// Override the context.data() method to include our experiments
|
|
798
|
+
this.fullConfig.context.data = function () {
|
|
799
|
+
var e_8, _a;
|
|
800
|
+
var data = originalData();
|
|
801
|
+
if (!data)
|
|
802
|
+
return data;
|
|
803
|
+
// Merge experiments
|
|
804
|
+
var existingExperiments = data.experiments || [];
|
|
805
|
+
var existingNames = new Set(existingExperiments.map(function (exp) { return exp.name; }));
|
|
806
|
+
var _loop_1 = function (name_4, experiment) {
|
|
807
|
+
if (!existingNames.has(name_4)) {
|
|
808
|
+
existingExperiments.push(experiment);
|
|
809
|
+
}
|
|
810
|
+
else {
|
|
811
|
+
// Replace existing experiment with fetched one
|
|
812
|
+
var index = existingExperiments.findIndex(function (exp) { return exp.name === name_4; });
|
|
813
|
+
if (index >= 0) {
|
|
814
|
+
existingExperiments[index] = experiment;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
};
|
|
818
|
+
try {
|
|
819
|
+
// Add new experiments that don't exist
|
|
820
|
+
for (var newExperimentsMap_1 = __values(newExperimentsMap), newExperimentsMap_1_1 = newExperimentsMap_1.next(); !newExperimentsMap_1_1.done; newExperimentsMap_1_1 = newExperimentsMap_1.next()) {
|
|
821
|
+
var _b = __read(newExperimentsMap_1_1.value, 2), name_4 = _b[0], experiment = _b[1];
|
|
822
|
+
_loop_1(name_4, experiment);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
catch (e_8_1) { e_8 = { error: e_8_1 }; }
|
|
826
|
+
finally {
|
|
827
|
+
try {
|
|
828
|
+
if (newExperimentsMap_1_1 && !newExperimentsMap_1_1.done && (_a = newExperimentsMap_1.return)) _a.call(newExperimentsMap_1);
|
|
829
|
+
}
|
|
830
|
+
finally { if (e_8) throw e_8.error; }
|
|
831
|
+
}
|
|
832
|
+
return __assign(__assign({}, data), { experiments: existingExperiments });
|
|
833
|
+
};
|
|
834
|
+
if (this.fullConfig.debug) {
|
|
835
|
+
logDebug("[OverridesPlugin] Injected ".concat(experiments.length, " experiments into context"));
|
|
836
|
+
}
|
|
837
|
+
};
|
|
838
|
+
// Register a callback to be called when experiments are added
|
|
839
|
+
OverridesPlugin.prototype.onExperimentsAdded = function (callback) {
|
|
840
|
+
this.onExperimentsAddedCallbacks.push(callback);
|
|
841
|
+
};
|
|
842
|
+
OverridesPlugin.prototype.notifyExperimentsAdded = function () {
|
|
843
|
+
var e_9, _a;
|
|
844
|
+
if (this.fullConfig.debug) {
|
|
845
|
+
logDebug("[OverridesPlugin] Notifying ".concat(this.onExperimentsAddedCallbacks.length, " listeners about new experiments"));
|
|
846
|
+
}
|
|
847
|
+
try {
|
|
848
|
+
for (var _b = __values(this.onExperimentsAddedCallbacks), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
849
|
+
var callback = _c.value;
|
|
850
|
+
try {
|
|
851
|
+
callback();
|
|
852
|
+
}
|
|
853
|
+
catch (error) {
|
|
854
|
+
logDebug('[OverridesPlugin] Error in experiments added callback:', error);
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
catch (e_9_1) { e_9 = { error: e_9_1 }; }
|
|
859
|
+
finally {
|
|
860
|
+
try {
|
|
861
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
862
|
+
}
|
|
863
|
+
finally { if (e_9) throw e_9.error; }
|
|
864
|
+
}
|
|
865
|
+
};
|
|
866
|
+
OverridesPlugin.prototype.registerWithContext = function () {
|
|
867
|
+
if (this.fullConfig.context) {
|
|
868
|
+
// Ensure __plugins object exists
|
|
869
|
+
if (!this.fullConfig.context.__plugins) {
|
|
870
|
+
this.fullConfig.context.__plugins = {};
|
|
871
|
+
}
|
|
872
|
+
// Register under standardized __plugins structure
|
|
873
|
+
this.fullConfig.context.__plugins.overridesPlugin = {
|
|
874
|
+
name: 'OverridesPlugin',
|
|
875
|
+
version: '1.0.0',
|
|
876
|
+
initialized: true,
|
|
877
|
+
capabilities: ['cookie-overrides', 'query-overrides', 'api-fetch', 'dev-environments'],
|
|
878
|
+
instance: this,
|
|
879
|
+
timestamp: Date.now(),
|
|
880
|
+
};
|
|
881
|
+
if (this.fullConfig.debug) {
|
|
882
|
+
logDebug('[OverridesPlugin] Registered with context at __plugins.overridesPlugin');
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
};
|
|
886
|
+
OverridesPlugin.prototype.unregisterFromContext = function () {
|
|
887
|
+
var _a, _b;
|
|
888
|
+
if ((_b = (_a = this.fullConfig.context) === null || _a === void 0 ? void 0 : _a.__plugins) === null || _b === void 0 ? void 0 : _b.overridesPlugin) {
|
|
889
|
+
delete this.fullConfig.context.__plugins.overridesPlugin;
|
|
890
|
+
if (this.fullConfig.debug) {
|
|
891
|
+
logDebug('[OverridesPlugin] Unregistered from context');
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
};
|
|
895
|
+
OverridesPlugin.prototype.destroy = function () {
|
|
896
|
+
_super.prototype.destroy.call(this);
|
|
897
|
+
this.unregisterFromContext();
|
|
898
|
+
this.onExperimentsAddedCallbacks = [];
|
|
899
|
+
};
|
|
900
|
+
return OverridesPlugin;
|
|
901
|
+
}(OverridesPluginLite));
|
|
902
|
+
export { OverridesPlugin };
|
|
903
|
+
//# sourceMappingURL=OverridesPlugin.js.map
|