Initial commit with Advoware proxy

This commit is contained in:
root
2025-10-19 14:57:07 +00:00
commit 273aa8b549
45771 changed files with 5534555 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Amplitude Analytics
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.

View File

@@ -0,0 +1,215 @@
class ApplicationContextProviderImpl {
getApplicationContext() {
return {
versionName: this.versionName,
language: getLanguage(),
platform: 'Web',
os: undefined,
deviceModel: undefined,
};
}
}
const getLanguage = () => {
return ((typeof navigator !== 'undefined' &&
((navigator.languages && navigator.languages[0]) ||
navigator.language)) ||
'');
};
class EventBridgeImpl {
constructor() {
this.queue = [];
}
logEvent(event) {
if (!this.receiver) {
if (this.queue.length < 512) {
this.queue.push(event);
}
}
else {
this.receiver(event);
}
}
setEventReceiver(receiver) {
this.receiver = receiver;
if (this.queue.length > 0) {
this.queue.forEach((event) => {
receiver(event);
});
this.queue = [];
}
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const isEqual = (obj1, obj2) => {
const primitive = ['string', 'number', 'boolean', 'undefined'];
const typeA = typeof obj1;
const typeB = typeof obj2;
if (typeA !== typeB) {
return false;
}
for (const p of primitive) {
if (p === typeA) {
return obj1 === obj2;
}
}
// check null
if (obj1 == null && obj2 == null) {
return true;
}
else if (obj1 == null || obj2 == null) {
return false;
}
// if got here - objects
if (obj1.length !== obj2.length) {
return false;
}
//check if arrays
const isArrayA = Array.isArray(obj1);
const isArrayB = Array.isArray(obj2);
if (isArrayA !== isArrayB) {
return false;
}
if (isArrayA && isArrayB) {
//arrays
for (let i = 0; i < obj1.length; i++) {
if (!isEqual(obj1[i], obj2[i])) {
return false;
}
}
}
else {
//objects
const sorted1 = Object.keys(obj1).sort();
const sorted2 = Object.keys(obj2).sort();
if (!isEqual(sorted1, sorted2)) {
return false;
}
//compare object values
let result = true;
Object.keys(obj1).forEach((key) => {
if (!isEqual(obj1[key], obj2[key])) {
result = false;
}
});
return result;
}
return true;
};
const ID_OP_SET = '$set';
const ID_OP_UNSET = '$unset';
const ID_OP_CLEAR_ALL = '$clearAll';
// Polyfill for Object.entries
if (!Object.entries) {
Object.entries = function (obj) {
const ownProps = Object.keys(obj);
let i = ownProps.length;
const resArray = new Array(i);
while (i--) {
resArray[i] = [ownProps[i], obj[ownProps[i]]];
}
return resArray;
};
}
class IdentityStoreImpl {
constructor() {
this.identity = { userProperties: {} };
this.listeners = new Set();
}
editIdentity() {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const self = this;
const actingUserProperties = Object.assign({}, this.identity.userProperties);
const actingIdentity = Object.assign(Object.assign({}, this.identity), { userProperties: actingUserProperties });
return {
setUserId: function (userId) {
actingIdentity.userId = userId;
return this;
},
setDeviceId: function (deviceId) {
actingIdentity.deviceId = deviceId;
return this;
},
setUserProperties: function (userProperties) {
actingIdentity.userProperties = userProperties;
return this;
},
setOptOut(optOut) {
actingIdentity.optOut = optOut;
return this;
},
updateUserProperties: function (actions) {
let actingProperties = actingIdentity.userProperties || {};
for (const [action, properties] of Object.entries(actions)) {
switch (action) {
case ID_OP_SET:
for (const [key, value] of Object.entries(properties)) {
actingProperties[key] = value;
}
break;
case ID_OP_UNSET:
for (const key of Object.keys(properties)) {
delete actingProperties[key];
}
break;
case ID_OP_CLEAR_ALL:
actingProperties = {};
break;
}
}
actingIdentity.userProperties = actingProperties;
return this;
},
commit: function () {
self.setIdentity(actingIdentity);
return this;
},
};
}
getIdentity() {
return Object.assign({}, this.identity);
}
setIdentity(identity) {
const originalIdentity = Object.assign({}, this.identity);
this.identity = Object.assign({}, identity);
if (!isEqual(originalIdentity, this.identity)) {
this.listeners.forEach((listener) => {
listener(identity);
});
}
}
addIdentityListener(listener) {
this.listeners.add(listener);
}
removeIdentityListener(listener) {
this.listeners.delete(listener);
}
}
const safeGlobal = typeof globalThis !== 'undefined'
? globalThis
: typeof global !== 'undefined'
? global
: self;
class AnalyticsConnector {
constructor() {
this.identityStore = new IdentityStoreImpl();
this.eventBridge = new EventBridgeImpl();
this.applicationContextProvider = new ApplicationContextProviderImpl();
}
static getInstance(instanceName) {
if (!safeGlobal['analyticsConnectorInstances']) {
safeGlobal['analyticsConnectorInstances'] = {};
}
if (!safeGlobal['analyticsConnectorInstances'][instanceName]) {
safeGlobal['analyticsConnectorInstances'][instanceName] =
new AnalyticsConnector();
}
return safeGlobal['analyticsConnectorInstances'][instanceName];
}
}
export { AnalyticsConnector };

View File

@@ -0,0 +1,330 @@
var ApplicationContextProviderImpl = /** @class */ (function () {
function ApplicationContextProviderImpl() {
}
ApplicationContextProviderImpl.prototype.getApplicationContext = function () {
return {
versionName: this.versionName,
language: getLanguage(),
platform: 'Web',
os: undefined,
deviceModel: undefined,
};
};
return ApplicationContextProviderImpl;
}());
var getLanguage = function () {
return ((typeof navigator !== 'undefined' &&
((navigator.languages && navigator.languages[0]) ||
navigator.language)) ||
'');
};
var EventBridgeImpl = /** @class */ (function () {
function EventBridgeImpl() {
this.queue = [];
}
EventBridgeImpl.prototype.logEvent = function (event) {
if (!this.receiver) {
if (this.queue.length < 512) {
this.queue.push(event);
}
}
else {
this.receiver(event);
}
};
EventBridgeImpl.prototype.setEventReceiver = function (receiver) {
this.receiver = receiver;
if (this.queue.length > 0) {
this.queue.forEach(function (event) {
receiver(event);
});
this.queue = [];
}
};
return EventBridgeImpl;
}());
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
var __assign = function () {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __values(o) {
var s = typeof Symbol === "function" && Symbol.iterator,
m = s && o[s],
i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return {
value: o && o[i++],
done: !o
};
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o),
r,
ar = [],
e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
} catch (error) {
e = {
error: error
};
} finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
} finally {
if (e) throw e.error;
}
}
return ar;
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var isEqual = function (obj1, obj2) {
var e_1, _a;
var primitive = ['string', 'number', 'boolean', 'undefined'];
var typeA = typeof obj1;
var typeB = typeof obj2;
if (typeA !== typeB) {
return false;
}
try {
for (var primitive_1 = __values(primitive), primitive_1_1 = primitive_1.next(); !primitive_1_1.done; primitive_1_1 = primitive_1.next()) {
var p = primitive_1_1.value;
if (p === typeA) {
return obj1 === obj2;
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (primitive_1_1 && !primitive_1_1.done && (_a = primitive_1.return)) _a.call(primitive_1);
}
finally { if (e_1) throw e_1.error; }
}
// check null
if (obj1 == null && obj2 == null) {
return true;
}
else if (obj1 == null || obj2 == null) {
return false;
}
// if got here - objects
if (obj1.length !== obj2.length) {
return false;
}
//check if arrays
var isArrayA = Array.isArray(obj1);
var isArrayB = Array.isArray(obj2);
if (isArrayA !== isArrayB) {
return false;
}
if (isArrayA && isArrayB) {
//arrays
for (var i = 0; i < obj1.length; i++) {
if (!isEqual(obj1[i], obj2[i])) {
return false;
}
}
}
else {
//objects
var sorted1 = Object.keys(obj1).sort();
var sorted2 = Object.keys(obj2).sort();
if (!isEqual(sorted1, sorted2)) {
return false;
}
//compare object values
var result_1 = true;
Object.keys(obj1).forEach(function (key) {
if (!isEqual(obj1[key], obj2[key])) {
result_1 = false;
}
});
return result_1;
}
return true;
};
var ID_OP_SET = '$set';
var ID_OP_UNSET = '$unset';
var ID_OP_CLEAR_ALL = '$clearAll';
// Polyfill for Object.entries
if (!Object.entries) {
Object.entries = function (obj) {
var ownProps = Object.keys(obj);
var i = ownProps.length;
var resArray = new Array(i);
while (i--) {
resArray[i] = [ownProps[i], obj[ownProps[i]]];
}
return resArray;
};
}
var IdentityStoreImpl = /** @class */ (function () {
function IdentityStoreImpl() {
this.identity = { userProperties: {} };
this.listeners = new Set();
}
IdentityStoreImpl.prototype.editIdentity = function () {
// eslint-disable-next-line @typescript-eslint/no-this-alias
var self = this;
var actingUserProperties = __assign({}, this.identity.userProperties);
var actingIdentity = __assign(__assign({}, this.identity), { userProperties: actingUserProperties });
return {
setUserId: function (userId) {
actingIdentity.userId = userId;
return this;
},
setDeviceId: function (deviceId) {
actingIdentity.deviceId = deviceId;
return this;
},
setUserProperties: function (userProperties) {
actingIdentity.userProperties = userProperties;
return this;
},
setOptOut: function (optOut) {
actingIdentity.optOut = optOut;
return this;
},
updateUserProperties: function (actions) {
var e_1, _a, e_2, _b, e_3, _c;
var actingProperties = actingIdentity.userProperties || {};
try {
for (var _d = __values(Object.entries(actions)), _e = _d.next(); !_e.done; _e = _d.next()) {
var _f = __read(_e.value, 2), action = _f[0], properties = _f[1];
switch (action) {
case ID_OP_SET:
try {
for (var _g = (e_2 = void 0, __values(Object.entries(properties))), _h = _g.next(); !_h.done; _h = _g.next()) {
var _j = __read(_h.value, 2), key = _j[0], value = _j[1];
actingProperties[key] = value;
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
}
finally { if (e_2) throw e_2.error; }
}
break;
case ID_OP_UNSET:
try {
for (var _k = (e_3 = void 0, __values(Object.keys(properties))), _l = _k.next(); !_l.done; _l = _k.next()) {
var key = _l.value;
delete actingProperties[key];
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (_l && !_l.done && (_c = _k.return)) _c.call(_k);
}
finally { if (e_3) throw e_3.error; }
}
break;
case ID_OP_CLEAR_ALL:
actingProperties = {};
break;
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
}
finally { if (e_1) throw e_1.error; }
}
actingIdentity.userProperties = actingProperties;
return this;
},
commit: function () {
self.setIdentity(actingIdentity);
return this;
},
};
};
IdentityStoreImpl.prototype.getIdentity = function () {
return __assign({}, this.identity);
};
IdentityStoreImpl.prototype.setIdentity = function (identity) {
var originalIdentity = __assign({}, this.identity);
this.identity = __assign({}, identity);
if (!isEqual(originalIdentity, this.identity)) {
this.listeners.forEach(function (listener) {
listener(identity);
});
}
};
IdentityStoreImpl.prototype.addIdentityListener = function (listener) {
this.listeners.add(listener);
};
IdentityStoreImpl.prototype.removeIdentityListener = function (listener) {
this.listeners.delete(listener);
};
return IdentityStoreImpl;
}());
var safeGlobal = typeof globalThis !== 'undefined'
? globalThis
: typeof global !== 'undefined'
? global
: self;
var AnalyticsConnector = /** @class */ (function () {
function AnalyticsConnector() {
this.identityStore = new IdentityStoreImpl();
this.eventBridge = new EventBridgeImpl();
this.applicationContextProvider = new ApplicationContextProviderImpl();
}
AnalyticsConnector.getInstance = function (instanceName) {
if (!safeGlobal['analyticsConnectorInstances']) {
safeGlobal['analyticsConnectorInstances'] = {};
}
if (!safeGlobal['analyticsConnectorInstances'][instanceName]) {
safeGlobal['analyticsConnectorInstances'][instanceName] =
new AnalyticsConnector();
}
return safeGlobal['analyticsConnectorInstances'][instanceName];
};
return AnalyticsConnector;
}());
export { AnalyticsConnector };

View File

@@ -0,0 +1,340 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Experiment = {}));
})(this, (function (exports) { 'use strict';
var ApplicationContextProviderImpl = /** @class */ (function () {
function ApplicationContextProviderImpl() {
}
ApplicationContextProviderImpl.prototype.getApplicationContext = function () {
return {
versionName: this.versionName,
language: getLanguage(),
platform: 'Web',
os: undefined,
deviceModel: undefined,
};
};
return ApplicationContextProviderImpl;
}());
var getLanguage = function () {
return ((typeof navigator !== 'undefined' &&
((navigator.languages && navigator.languages[0]) ||
navigator.language)) ||
'');
};
var EventBridgeImpl = /** @class */ (function () {
function EventBridgeImpl() {
this.queue = [];
}
EventBridgeImpl.prototype.logEvent = function (event) {
if (!this.receiver) {
if (this.queue.length < 512) {
this.queue.push(event);
}
}
else {
this.receiver(event);
}
};
EventBridgeImpl.prototype.setEventReceiver = function (receiver) {
this.receiver = receiver;
if (this.queue.length > 0) {
this.queue.forEach(function (event) {
receiver(event);
});
this.queue = [];
}
};
return EventBridgeImpl;
}());
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
var __assign = function () {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __values(o) {
var s = typeof Symbol === "function" && Symbol.iterator,
m = s && o[s],
i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return {
value: o && o[i++],
done: !o
};
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o),
r,
ar = [],
e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
} catch (error) {
e = {
error: error
};
} finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
} finally {
if (e) throw e.error;
}
}
return ar;
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var isEqual = function (obj1, obj2) {
var e_1, _a;
var primitive = ['string', 'number', 'boolean', 'undefined'];
var typeA = typeof obj1;
var typeB = typeof obj2;
if (typeA !== typeB) {
return false;
}
try {
for (var primitive_1 = __values(primitive), primitive_1_1 = primitive_1.next(); !primitive_1_1.done; primitive_1_1 = primitive_1.next()) {
var p = primitive_1_1.value;
if (p === typeA) {
return obj1 === obj2;
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (primitive_1_1 && !primitive_1_1.done && (_a = primitive_1.return)) _a.call(primitive_1);
}
finally { if (e_1) throw e_1.error; }
}
// check null
if (obj1 == null && obj2 == null) {
return true;
}
else if (obj1 == null || obj2 == null) {
return false;
}
// if got here - objects
if (obj1.length !== obj2.length) {
return false;
}
//check if arrays
var isArrayA = Array.isArray(obj1);
var isArrayB = Array.isArray(obj2);
if (isArrayA !== isArrayB) {
return false;
}
if (isArrayA && isArrayB) {
//arrays
for (var i = 0; i < obj1.length; i++) {
if (!isEqual(obj1[i], obj2[i])) {
return false;
}
}
}
else {
//objects
var sorted1 = Object.keys(obj1).sort();
var sorted2 = Object.keys(obj2).sort();
if (!isEqual(sorted1, sorted2)) {
return false;
}
//compare object values
var result_1 = true;
Object.keys(obj1).forEach(function (key) {
if (!isEqual(obj1[key], obj2[key])) {
result_1 = false;
}
});
return result_1;
}
return true;
};
var ID_OP_SET = '$set';
var ID_OP_UNSET = '$unset';
var ID_OP_CLEAR_ALL = '$clearAll';
// Polyfill for Object.entries
if (!Object.entries) {
Object.entries = function (obj) {
var ownProps = Object.keys(obj);
var i = ownProps.length;
var resArray = new Array(i);
while (i--) {
resArray[i] = [ownProps[i], obj[ownProps[i]]];
}
return resArray;
};
}
var IdentityStoreImpl = /** @class */ (function () {
function IdentityStoreImpl() {
this.identity = { userProperties: {} };
this.listeners = new Set();
}
IdentityStoreImpl.prototype.editIdentity = function () {
// eslint-disable-next-line @typescript-eslint/no-this-alias
var self = this;
var actingUserProperties = __assign({}, this.identity.userProperties);
var actingIdentity = __assign(__assign({}, this.identity), { userProperties: actingUserProperties });
return {
setUserId: function (userId) {
actingIdentity.userId = userId;
return this;
},
setDeviceId: function (deviceId) {
actingIdentity.deviceId = deviceId;
return this;
},
setUserProperties: function (userProperties) {
actingIdentity.userProperties = userProperties;
return this;
},
setOptOut: function (optOut) {
actingIdentity.optOut = optOut;
return this;
},
updateUserProperties: function (actions) {
var e_1, _a, e_2, _b, e_3, _c;
var actingProperties = actingIdentity.userProperties || {};
try {
for (var _d = __values(Object.entries(actions)), _e = _d.next(); !_e.done; _e = _d.next()) {
var _f = __read(_e.value, 2), action = _f[0], properties = _f[1];
switch (action) {
case ID_OP_SET:
try {
for (var _g = (e_2 = void 0, __values(Object.entries(properties))), _h = _g.next(); !_h.done; _h = _g.next()) {
var _j = __read(_h.value, 2), key = _j[0], value = _j[1];
actingProperties[key] = value;
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
}
finally { if (e_2) throw e_2.error; }
}
break;
case ID_OP_UNSET:
try {
for (var _k = (e_3 = void 0, __values(Object.keys(properties))), _l = _k.next(); !_l.done; _l = _k.next()) {
var key = _l.value;
delete actingProperties[key];
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (_l && !_l.done && (_c = _k.return)) _c.call(_k);
}
finally { if (e_3) throw e_3.error; }
}
break;
case ID_OP_CLEAR_ALL:
actingProperties = {};
break;
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
}
finally { if (e_1) throw e_1.error; }
}
actingIdentity.userProperties = actingProperties;
return this;
},
commit: function () {
self.setIdentity(actingIdentity);
return this;
},
};
};
IdentityStoreImpl.prototype.getIdentity = function () {
return __assign({}, this.identity);
};
IdentityStoreImpl.prototype.setIdentity = function (identity) {
var originalIdentity = __assign({}, this.identity);
this.identity = __assign({}, identity);
if (!isEqual(originalIdentity, this.identity)) {
this.listeners.forEach(function (listener) {
listener(identity);
});
}
};
IdentityStoreImpl.prototype.addIdentityListener = function (listener) {
this.listeners.add(listener);
};
IdentityStoreImpl.prototype.removeIdentityListener = function (listener) {
this.listeners.delete(listener);
};
return IdentityStoreImpl;
}());
var safeGlobal = typeof globalThis !== 'undefined'
? globalThis
: typeof global !== 'undefined'
? global
: self;
var AnalyticsConnector = /** @class */ (function () {
function AnalyticsConnector() {
this.identityStore = new IdentityStoreImpl();
this.eventBridge = new EventBridgeImpl();
this.applicationContextProvider = new ApplicationContextProviderImpl();
}
AnalyticsConnector.getInstance = function (instanceName) {
if (!safeGlobal['analyticsConnectorInstances']) {
safeGlobal['analyticsConnectorInstances'] = {};
}
if (!safeGlobal['analyticsConnectorInstances'][instanceName]) {
safeGlobal['analyticsConnectorInstances'][instanceName] =
new AnalyticsConnector();
}
return safeGlobal['analyticsConnectorInstances'][instanceName];
};
return AnalyticsConnector;
}());
exports.AnalyticsConnector = AnalyticsConnector;
Object.defineProperty(exports, '__esModule', { value: true });
}));

View File

@@ -0,0 +1,9 @@
import { ApplicationContextProviderImpl } from './applicationContextProvider';
import { EventBridgeImpl } from './eventBridge';
import { IdentityStoreImpl } from './identityStore';
export declare class AnalyticsConnector {
readonly identityStore: IdentityStoreImpl;
readonly eventBridge: EventBridgeImpl;
readonly applicationContextProvider: ApplicationContextProviderImpl;
static getInstance(instanceName: string): AnalyticsConnector;
}

View File

@@ -0,0 +1,15 @@
export type ApplicationContext = {
versionName?: string;
language?: string;
platform?: string;
os?: string;
deviceModel?: string;
};
export interface ApplicationContextProvider {
versionName: string;
getApplicationContext(): ApplicationContext;
}
export declare class ApplicationContextProviderImpl implements ApplicationContextProvider {
versionName: string;
getApplicationContext(): ApplicationContext;
}

View File

@@ -0,0 +1,16 @@
export type AnalyticsEvent = {
eventType: string;
eventProperties?: Record<string, unknown>;
userProperties?: Record<string, unknown>;
};
export type AnalyticsEventReceiver = (event: AnalyticsEvent) => void;
export interface EventBridge {
logEvent(event: AnalyticsEvent): void;
setEventReceiver(listener: AnalyticsEventReceiver): void;
}
export declare class EventBridgeImpl implements EventBridge {
private receiver;
private queue;
logEvent(event: AnalyticsEvent): void;
setEventReceiver(receiver: AnalyticsEventReceiver): void;
}

View File

@@ -0,0 +1,31 @@
export type Identity = {
userId?: string;
deviceId?: string;
userProperties?: Record<string, unknown>;
optOut?: boolean;
};
export type IdentityListener = (identity: Identity) => void;
export interface IdentityStore {
editIdentity(): IdentityEditor;
getIdentity(): Identity;
setIdentity(identity: Identity): void;
addIdentityListener(listener: IdentityListener): void;
removeIdentityListener(listener: IdentityListener): void;
}
export interface IdentityEditor {
setUserId(userId: string): IdentityEditor;
setDeviceId(deviceId: string): IdentityEditor;
setUserProperties(userProperties: Record<string, unknown>): IdentityEditor;
setOptOut(optOut: boolean): IdentityEditor;
updateUserProperties(actions: Record<string, Record<string, unknown>>): IdentityEditor;
commit(): void;
}
export declare class IdentityStoreImpl implements IdentityStore {
private identity;
private listeners;
editIdentity(): IdentityEditor;
getIdentity(): Identity;
setIdentity(identity: Identity): void;
addIdentityListener(listener: IdentityListener): void;
removeIdentityListener(listener: IdentityListener): void;
}

View File

@@ -0,0 +1,4 @@
export { AnalyticsConnector } from './analyticsConnector';
export { EventBridge, AnalyticsEvent, AnalyticsEventReceiver, } from './eventBridge';
export { ApplicationContext, ApplicationContextProvider, } from './applicationContextProvider';
export { Identity, IdentityStore, IdentityListener, IdentityEditor, } from './identityStore';

View File

@@ -0,0 +1 @@
export declare const isEqual: (obj1: any, obj2: any) => boolean;

View File

@@ -0,0 +1 @@
export declare const safeGlobal: typeof globalThis;

View File

@@ -0,0 +1,38 @@
{
"name": "@amplitude/analytics-connector",
"version": "1.6.4",
"description": "Connector package for Amplitude SDKs",
"author": "Amplitude",
"homepage": "https://github.com/amplitude/experiment-js-client",
"license": "MIT",
"main": "dist/analytics-connector.umd.js",
"module": "dist/analytics-connector.esm.js",
"es2015": "dist/analytics-connector.es2015.js",
"types": "dist/types/src/index.d.ts",
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/amplitude/experiment-js-client.git",
"directory": "packages/analytics-connector"
},
"scripts": {
"build": "rm -rf dist && rollup -c",
"clean": "rimraf node_modules dist",
"lint": "eslint . --ignore-path ../../.eslintignore && prettier -c . --ignore-path ../../.prettierignore",
"test": "jest",
"prepublish": "yarn build"
},
"bugs": {
"url": "https://github.com/amplitude/experiment-js-client/issues"
},
"devDependencies": {
"@types/amplitude-js": "^8.0.2",
"amplitude-js": "^8.12.0"
},
"files": [
"dist"
],
"gitHead": "ccdcdca446bab61bf2fc615751e0933653c12307"
}

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Amplitude Analytics
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.

View File

@@ -0,0 +1,10 @@
<p align="center">
<a href="https://amplitude.com" target="_blank" align="center">
<img src="https://static.amplitude.com/lightning/46c85bfd91905de8047f1ee65c7c93d6fa9ee6ea/static/media/amplitude-logo-with-text.4fb9e463.svg" width="280">
</a>
<br />
</p>
# @amplitude/analytics-core
Internal Node package for Amplitude

View File

@@ -0,0 +1,8 @@
export declare class Logger {
disable(): void;
enable(): void;
log(): void;
warn(): void;
error(): void;
}
//# sourceMappingURL=logger.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/__mocks__/logger.ts"],"names":[],"mappings":"AAAA,qBAAa,MAAM;IACjB,OAAO,IAAI,IAAI;IAIf,MAAM,IAAI,IAAI;IAId,GAAG,IAAI,IAAI;IAIX,IAAI,IAAI,IAAI;IAIZ,KAAK,IAAI,IAAI;CAGd"}

View File

@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Logger = void 0;
var Logger = /** @class */ (function () {
function Logger() {
}
Logger.prototype.disable = function () {
return undefined;
};
Logger.prototype.enable = function () {
return undefined;
};
Logger.prototype.log = function () {
return undefined;
};
Logger.prototype.warn = function () {
return undefined;
};
Logger.prototype.error = function () {
return undefined;
};
return Logger;
}());
exports.Logger = Logger;
//# sourceMappingURL=logger.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/__mocks__/logger.ts"],"names":[],"mappings":";;;AAAA;IAAA;IAoBA,CAAC;IAnBC,wBAAO,GAAP;QACE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,uBAAM,GAAN;QACE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,oBAAG,GAAH;QACE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,qBAAI,GAAJ;QACE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,sBAAK,GAAL;QACE,OAAO,SAAS,CAAC;IACnB,CAAC;IACH,aAAC;AAAD,CAAC,AApBD,IAoBC;AApBY,wBAAM","sourcesContent":["export class Logger {\n disable(): void {\n return undefined;\n }\n\n enable(): void {\n return undefined;\n }\n\n log(): void {\n return undefined;\n }\n\n warn(): void {\n return undefined;\n }\n\n error(): void {\n return undefined;\n }\n}\n"]}

View File

@@ -0,0 +1,5 @@
import { AnalyticsConnector } from '@amplitude/analytics-connector';
export declare const getAnalyticsConnector: (instanceName?: string) => AnalyticsConnector;
export declare const setConnectorUserId: (userId: string | undefined, instanceName?: string) => void;
export declare const setConnectorDeviceId: (deviceId: string, instanceName?: string) => void;
//# sourceMappingURL=analytics-connector.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"analytics-connector.d.ts","sourceRoot":"","sources":["../../src/analytics-connector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGpE,eAAO,MAAM,qBAAqB,6BAA2C,kBAE5E,CAAC;AAEF,eAAO,MAAM,kBAAkB,WAAY,MAAM,GAAG,SAAS,iBAAiB,MAAM,KAAG,IAItF,CAAC;AAEF,eAAO,MAAM,oBAAoB,aAAc,MAAM,iBAAiB,MAAM,KAAG,IAE9E,CAAC"}

View File

@@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.setConnectorDeviceId = exports.setConnectorUserId = exports.getAnalyticsConnector = void 0;
var analytics_connector_1 = require("@amplitude/analytics-connector");
var constants_1 = require("./types/constants");
var getAnalyticsConnector = function (instanceName) {
if (instanceName === void 0) { instanceName = constants_1.DEFAULT_INSTANCE_NAME; }
return analytics_connector_1.AnalyticsConnector.getInstance(instanceName);
};
exports.getAnalyticsConnector = getAnalyticsConnector;
var setConnectorUserId = function (userId, instanceName) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
(0, exports.getAnalyticsConnector)(instanceName).identityStore.editIdentity().setUserId(userId).commit();
};
exports.setConnectorUserId = setConnectorUserId;
var setConnectorDeviceId = function (deviceId, instanceName) {
(0, exports.getAnalyticsConnector)(instanceName).identityStore.editIdentity().setDeviceId(deviceId).commit();
};
exports.setConnectorDeviceId = setConnectorDeviceId;
//# sourceMappingURL=analytics-connector.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"analytics-connector.js","sourceRoot":"","sources":["../../src/analytics-connector.ts"],"names":[],"mappings":";;;AAAA,sEAAoE;AACpE,+CAA0D;AAEnD,IAAM,qBAAqB,GAAG,UAAC,YAAoC;IAApC,6BAAA,EAAA,eAAe,iCAAqB;IACxE,OAAO,wCAAkB,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;AACtD,CAAC,CAAC;AAFW,QAAA,qBAAqB,yBAEhC;AAEK,IAAM,kBAAkB,GAAG,UAAC,MAA0B,EAAE,YAAqB;IAClF,6DAA6D;IAC7D,aAAa;IACb,IAAA,6BAAqB,EAAC,YAAY,CAAC,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;AAC9F,CAAC,CAAC;AAJW,QAAA,kBAAkB,sBAI7B;AAEK,IAAM,oBAAoB,GAAG,UAAC,QAAgB,EAAE,YAAqB;IAC1E,IAAA,6BAAqB,EAAC,YAAY,CAAC,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC;AAClG,CAAC,CAAC;AAFW,QAAA,oBAAoB,wBAE/B","sourcesContent":["import { AnalyticsConnector } from '@amplitude/analytics-connector';\nimport { DEFAULT_INSTANCE_NAME } from './types/constants';\n\nexport const getAnalyticsConnector = (instanceName = DEFAULT_INSTANCE_NAME): AnalyticsConnector => {\n return AnalyticsConnector.getInstance(instanceName);\n};\n\nexport const setConnectorUserId = (userId: string | undefined, instanceName?: string): void => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n getAnalyticsConnector(instanceName).identityStore.editIdentity().setUserId(userId).commit();\n};\n\nexport const setConnectorDeviceId = (deviceId: string, instanceName?: string): void => {\n getAnalyticsConnector(instanceName).identityStore.editIdentity().setDeviceId(deviceId).commit();\n};\n"]}

View File

@@ -0,0 +1,8 @@
import { Campaign, ICampaignParser, ClickIdParameters, ReferrerParameters, UTMParameters } from '../types/campaign';
export declare class CampaignParser implements ICampaignParser {
parse(): Promise<Campaign>;
getUtmParam(): UTMParameters;
getReferrer(): ReferrerParameters;
getClickIds(): ClickIdParameters;
}
//# sourceMappingURL=campaign-parser.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"campaign-parser.d.ts","sourceRoot":"","sources":["../../../src/campaign/campaign-parser.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEpH,qBAAa,cAAe,YAAW,eAAe;IAC9C,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC;IAShC,WAAW,IAAI,aAAa;IAoB5B,WAAW,IAAI,kBAAkB;IAcjC,WAAW,IAAI,iBAAiB;CAgBjC"}

View File

@@ -0,0 +1,69 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CampaignParser = void 0;
var tslib_1 = require("tslib");
var query_params_1 = require("../query-params");
var constants_1 = require("../types/constants");
var CampaignParser = /** @class */ (function () {
function CampaignParser() {
}
CampaignParser.prototype.parse = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
return [2 /*return*/, tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, constants_1.BASE_CAMPAIGN), this.getUtmParam()), this.getReferrer()), this.getClickIds())];
});
});
};
CampaignParser.prototype.getUtmParam = function () {
var params = (0, query_params_1.getQueryParams)();
var utmCampaign = params[constants_1.UTM_CAMPAIGN];
var utmContent = params[constants_1.UTM_CONTENT];
var utmId = params[constants_1.UTM_ID];
var utmMedium = params[constants_1.UTM_MEDIUM];
var utmSource = params[constants_1.UTM_SOURCE];
var utmTerm = params[constants_1.UTM_TERM];
return {
utm_campaign: utmCampaign,
utm_content: utmContent,
utm_id: utmId,
utm_medium: utmMedium,
utm_source: utmSource,
utm_term: utmTerm,
};
};
CampaignParser.prototype.getReferrer = function () {
var _a, _b;
var data = {
referrer: undefined,
referring_domain: undefined,
};
try {
data.referrer = document.referrer || undefined;
data.referring_domain = (_b = (_a = data.referrer) === null || _a === void 0 ? void 0 : _a.split('/')[2]) !== null && _b !== void 0 ? _b : undefined;
}
catch (_c) {
// nothing to track
}
return data;
};
CampaignParser.prototype.getClickIds = function () {
var _a;
var params = (0, query_params_1.getQueryParams)();
return _a = {},
_a[constants_1.DCLID] = params[constants_1.DCLID],
_a[constants_1.FBCLID] = params[constants_1.FBCLID],
_a[constants_1.GBRAID] = params[constants_1.GBRAID],
_a[constants_1.GCLID] = params[constants_1.GCLID],
_a[constants_1.KO_CLICK_ID] = params[constants_1.KO_CLICK_ID],
_a[constants_1.LI_FAT_ID] = params[constants_1.LI_FAT_ID],
_a[constants_1.MSCLKID] = params[constants_1.MSCLKID],
_a[constants_1.RDT_CID] = params[constants_1.RDT_CID],
_a[constants_1.TTCLID] = params[constants_1.TTCLID],
_a[constants_1.TWCLID] = params[constants_1.TWCLID],
_a[constants_1.WBRAID] = params[constants_1.WBRAID],
_a;
};
return CampaignParser;
}());
exports.CampaignParser = CampaignParser;
//# sourceMappingURL=campaign-parser.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"campaign-parser.js","sourceRoot":"","sources":["../../../src/campaign/campaign-parser.ts"],"names":[],"mappings":";;;;AAAA,gDAAiD;AACjD,gDAmB4B;AAG5B;IAAA;IA4DA,CAAC;IA3DO,8BAAK,GAAX;;;gBACE,sBAAO,wEACF,yBAAa,GACb,IAAI,CAAC,WAAW,EAAE,GAClB,IAAI,CAAC,WAAW,EAAE,GAClB,IAAI,CAAC,WAAW,EAAE,CACV,EAAC;;;KACf;IAED,oCAAW,GAAX;QACE,IAAM,MAAM,GAAG,IAAA,6BAAc,GAAE,CAAC;QAEhC,IAAM,WAAW,GAAG,MAAM,CAAC,wBAAY,CAAC,CAAC;QACzC,IAAM,UAAU,GAAG,MAAM,CAAC,uBAAW,CAAC,CAAC;QACvC,IAAM,KAAK,GAAG,MAAM,CAAC,kBAAM,CAAC,CAAC;QAC7B,IAAM,SAAS,GAAG,MAAM,CAAC,sBAAU,CAAC,CAAC;QACrC,IAAM,SAAS,GAAG,MAAM,CAAC,sBAAU,CAAC,CAAC;QACrC,IAAM,OAAO,GAAG,MAAM,CAAC,oBAAQ,CAAC,CAAC;QAEjC,OAAO;YACL,YAAY,EAAE,WAAW;YACzB,WAAW,EAAE,UAAU;YACvB,MAAM,EAAE,KAAK;YACb,UAAU,EAAE,SAAS;YACrB,UAAU,EAAE,SAAS;YACrB,QAAQ,EAAE,OAAO;SAClB,CAAC;IACJ,CAAC;IAED,oCAAW,GAAX;;QACE,IAAM,IAAI,GAAuB;YAC/B,QAAQ,EAAE,SAAS;YACnB,gBAAgB,EAAE,SAAS;SAC5B,CAAC;QACF,IAAI;YACF,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,IAAI,SAAS,CAAC;YAC/C,IAAI,CAAC,gBAAgB,GAAG,MAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,mCAAI,SAAS,CAAC;SACnE;QAAC,WAAM;YACN,mBAAmB;SACpB;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,oCAAW,GAAX;;QACE,IAAM,MAAM,GAAG,IAAA,6BAAc,GAAE,CAAC;QAChC;YACE,GAAC,iBAAK,IAAG,MAAM,CAAC,iBAAK,CAAC;YACtB,GAAC,kBAAM,IAAG,MAAM,CAAC,kBAAM,CAAC;YACxB,GAAC,kBAAM,IAAG,MAAM,CAAC,kBAAM,CAAC;YACxB,GAAC,iBAAK,IAAG,MAAM,CAAC,iBAAK,CAAC;YACtB,GAAC,uBAAW,IAAG,MAAM,CAAC,uBAAW,CAAC;YAClC,GAAC,qBAAS,IAAG,MAAM,CAAC,qBAAS,CAAC;YAC9B,GAAC,mBAAO,IAAG,MAAM,CAAC,mBAAO,CAAC;YAC1B,GAAC,mBAAO,IAAG,MAAM,CAAC,mBAAO,CAAC;YAC1B,GAAC,kBAAM,IAAG,MAAM,CAAC,kBAAM,CAAC;YACxB,GAAC,kBAAM,IAAG,MAAM,CAAC,kBAAM,CAAC;YACxB,GAAC,kBAAM,IAAG,MAAM,CAAC,kBAAM,CAAC;eACxB;IACJ,CAAC;IACH,qBAAC;AAAD,CAAC,AA5DD,IA4DC;AA5DY,wCAAc","sourcesContent":["import { getQueryParams } from '../query-params';\nimport {\n UTM_CAMPAIGN,\n UTM_CONTENT,\n UTM_MEDIUM,\n UTM_SOURCE,\n UTM_TERM,\n GCLID,\n FBCLID,\n BASE_CAMPAIGN,\n DCLID,\n MSCLKID,\n RDT_CID,\n TWCLID,\n TTCLID,\n KO_CLICK_ID,\n LI_FAT_ID,\n GBRAID,\n WBRAID,\n UTM_ID,\n} from '../types/constants';\nimport { Campaign, ICampaignParser, ClickIdParameters, ReferrerParameters, UTMParameters } from '../types/campaign';\n\nexport class CampaignParser implements ICampaignParser {\n async parse(): Promise<Campaign> {\n return {\n ...BASE_CAMPAIGN,\n ...this.getUtmParam(),\n ...this.getReferrer(),\n ...this.getClickIds(),\n } as Campaign;\n }\n\n getUtmParam(): UTMParameters {\n const params = getQueryParams();\n\n const utmCampaign = params[UTM_CAMPAIGN];\n const utmContent = params[UTM_CONTENT];\n const utmId = params[UTM_ID];\n const utmMedium = params[UTM_MEDIUM];\n const utmSource = params[UTM_SOURCE];\n const utmTerm = params[UTM_TERM];\n\n return {\n utm_campaign: utmCampaign,\n utm_content: utmContent,\n utm_id: utmId,\n utm_medium: utmMedium,\n utm_source: utmSource,\n utm_term: utmTerm,\n };\n }\n\n getReferrer(): ReferrerParameters {\n const data: ReferrerParameters = {\n referrer: undefined,\n referring_domain: undefined,\n };\n try {\n data.referrer = document.referrer || undefined;\n data.referring_domain = data.referrer?.split('/')[2] ?? undefined;\n } catch {\n // nothing to track\n }\n return data;\n }\n\n getClickIds(): ClickIdParameters {\n const params = getQueryParams();\n return {\n [DCLID]: params[DCLID],\n [FBCLID]: params[FBCLID],\n [GBRAID]: params[GBRAID],\n [GCLID]: params[GCLID],\n [KO_CLICK_ID]: params[KO_CLICK_ID],\n [LI_FAT_ID]: params[LI_FAT_ID],\n [MSCLKID]: params[MSCLKID],\n [RDT_CID]: params[RDT_CID],\n [TTCLID]: params[TTCLID],\n [TWCLID]: params[TWCLID],\n [WBRAID]: params[WBRAID],\n };\n }\n}\n"]}

View File

@@ -0,0 +1,71 @@
import { OfflineDisabled } from './types/offline';
import { ServerZoneType } from './types/server-zone';
import { Transport } from './types/transport';
import { Event } from './types/event/event';
import { Plan } from './types/event/plan';
import { IngestionMetadata } from './types/event/ingestion-metadata';
import { Storage } from './types/storage';
import { Logger, ILogger } from './logger';
import { LogLevel } from './types/loglevel';
import { ConfigOptions, IRequestMetadata, IHistogramOptions, HistogramKey } from './types/config/core-config';
import { IConfig } from './types/config/core-config';
export declare const getDefaultConfig: () => {
flushMaxRetries: number;
flushQueueSize: number;
flushIntervalMillis: number;
instanceName: string;
logLevel: LogLevel;
loggerProvider: Logger;
offline: boolean;
optOut: boolean;
serverUrl: string;
serverZone: ServerZoneType;
useBatch: boolean;
};
export declare class Config implements IConfig {
apiKey: string;
flushIntervalMillis: number;
flushMaxRetries: number;
flushQueueSize: number;
instanceName?: string;
loggerProvider: ILogger;
logLevel: LogLevel;
minIdLength?: number;
offline?: boolean | typeof OfflineDisabled;
plan?: Plan;
ingestionMetadata?: IngestionMetadata;
serverUrl: string | undefined;
serverZone?: ServerZoneType;
transportProvider: Transport;
storageProvider?: Storage<Event[]>;
useBatch: boolean;
requestMetadata?: RequestMetadata;
protected _optOut: boolean;
get optOut(): boolean;
set optOut(optOut: boolean);
constructor(options: ConfigOptions);
}
export declare const getServerUrl: (serverZone: ServerZoneType, useBatch: boolean) => "https://api2.amplitude.com/2/httpapi" | "https://api.eu.amplitude.com/2/httpapi" | "https://api2.amplitude.com/batch" | "https://api.eu.amplitude.com/batch";
export declare const createServerConfig: (serverUrl?: string, serverZone?: ServerZoneType, useBatch?: boolean) => {
serverUrl: string;
serverZone: undefined;
} | {
serverZone: ServerZoneType;
serverUrl: string;
};
export declare class RequestMetadata implements IRequestMetadata {
sdk: {
metrics: {
histogram: HistogramOptions;
};
};
constructor();
recordHistogram<T extends HistogramKey>(key: T, value: HistogramOptions[T]): void;
}
declare class HistogramOptions implements IHistogramOptions {
remote_config_fetch_time_IDB?: number;
remote_config_fetch_time_API_success?: number;
remote_config_fetch_time_API_fail?: number;
}
export {};
//# sourceMappingURL=config.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAS1C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC9G,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAErD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;CAY3B,CAAC;AACH,qBAAa,MAAO,YAAW,OAAO;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,eAAe,CAAC;IAC3C,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,iBAAiB,EAAE,SAAS,CAAC;IAC7B,eAAe,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACnC,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC,SAAS,CAAC,OAAO,UAAS;IAC1B,IAAI,MAAM,IAGS,OAAO,CADzB;IACD,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,EAEzB;gBAEW,OAAO,EAAE,aAAa;CAyBnC;AAED,eAAO,MAAM,YAAY,eAAgB,cAAc,YAAY,OAAO,kKAKzE,CAAC;AAEF,eAAO,MAAM,kBAAkB,oCAEjB,cAAc,aAChB,OAAO;;;;;;CAUlB,CAAC;AAEF,qBAAa,eAAgB,YAAW,gBAAgB;IACtD,GAAG,EAAE;QACH,OAAO,EAAE;YACP,SAAS,EAAE,gBAAgB,CAAC;SAC7B,CAAC;KACH,CAAC;;IAUF,eAAe,CAAC,CAAC,SAAS,YAAY,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC;CAG3E;AAED,cAAM,gBAAiB,YAAW,iBAAiB;IACjD,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,oCAAoC,CAAC,EAAE,MAAM,CAAC;IAC9C,iCAAiC,CAAC,EAAE,MAAM,CAAC;CAC5C"}

View File

@@ -0,0 +1,101 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RequestMetadata = exports.createServerConfig = exports.getServerUrl = exports.Config = exports.getDefaultConfig = void 0;
var constants_1 = require("./types/constants");
var logger_1 = require("./logger");
var loglevel_1 = require("./types/loglevel");
var getDefaultConfig = function () { return ({
flushMaxRetries: 12,
flushQueueSize: 200,
flushIntervalMillis: 10000,
instanceName: constants_1.DEFAULT_INSTANCE_NAME,
logLevel: loglevel_1.LogLevel.Warn,
loggerProvider: new logger_1.Logger(),
offline: false,
optOut: false,
serverUrl: constants_1.AMPLITUDE_SERVER_URL,
serverZone: 'US',
useBatch: false,
}); };
exports.getDefaultConfig = getDefaultConfig;
var Config = /** @class */ (function () {
function Config(options) {
var _a, _b, _c, _d;
this._optOut = false;
var defaultConfig = (0, exports.getDefaultConfig)();
this.apiKey = options.apiKey;
this.flushIntervalMillis = (_a = options.flushIntervalMillis) !== null && _a !== void 0 ? _a : defaultConfig.flushIntervalMillis;
this.flushMaxRetries = options.flushMaxRetries || defaultConfig.flushMaxRetries;
this.flushQueueSize = options.flushQueueSize || defaultConfig.flushQueueSize;
this.instanceName = options.instanceName || defaultConfig.instanceName;
this.loggerProvider = options.loggerProvider || defaultConfig.loggerProvider;
this.logLevel = (_b = options.logLevel) !== null && _b !== void 0 ? _b : defaultConfig.logLevel;
this.minIdLength = options.minIdLength;
this.plan = options.plan;
this.ingestionMetadata = options.ingestionMetadata;
this.offline = options.offline !== undefined ? options.offline : defaultConfig.offline;
this.optOut = (_c = options.optOut) !== null && _c !== void 0 ? _c : defaultConfig.optOut;
this.serverUrl = options.serverUrl;
this.serverZone = options.serverZone || defaultConfig.serverZone;
this.storageProvider = options.storageProvider;
this.transportProvider = options.transportProvider;
this.useBatch = (_d = options.useBatch) !== null && _d !== void 0 ? _d : defaultConfig.useBatch;
this.loggerProvider.enable(this.logLevel);
var serverConfig = (0, exports.createServerConfig)(options.serverUrl, options.serverZone, options.useBatch);
this.serverZone = serverConfig.serverZone;
this.serverUrl = serverConfig.serverUrl;
}
Object.defineProperty(Config.prototype, "optOut", {
get: function () {
return this._optOut;
},
set: function (optOut) {
this._optOut = optOut;
},
enumerable: false,
configurable: true
});
return Config;
}());
exports.Config = Config;
var getServerUrl = function (serverZone, useBatch) {
if (serverZone === 'EU') {
return useBatch ? constants_1.EU_AMPLITUDE_BATCH_SERVER_URL : constants_1.EU_AMPLITUDE_SERVER_URL;
}
return useBatch ? constants_1.AMPLITUDE_BATCH_SERVER_URL : constants_1.AMPLITUDE_SERVER_URL;
};
exports.getServerUrl = getServerUrl;
var createServerConfig = function (serverUrl, serverZone, useBatch) {
if (serverUrl === void 0) { serverUrl = ''; }
if (serverZone === void 0) { serverZone = (0, exports.getDefaultConfig)().serverZone; }
if (useBatch === void 0) { useBatch = (0, exports.getDefaultConfig)().useBatch; }
if (serverUrl) {
return { serverUrl: serverUrl, serverZone: undefined };
}
var _serverZone = ['US', 'EU'].includes(serverZone) ? serverZone : (0, exports.getDefaultConfig)().serverZone;
return {
serverZone: _serverZone,
serverUrl: (0, exports.getServerUrl)(_serverZone, useBatch),
};
};
exports.createServerConfig = createServerConfig;
var RequestMetadata = /** @class */ (function () {
function RequestMetadata() {
this.sdk = {
metrics: {
histogram: {},
},
};
}
RequestMetadata.prototype.recordHistogram = function (key, value) {
this.sdk.metrics.histogram[key] = value;
};
return RequestMetadata;
}());
exports.RequestMetadata = RequestMetadata;
var HistogramOptions = /** @class */ (function () {
function HistogramOptions() {
}
return HistogramOptions;
}());
//# sourceMappingURL=config.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
export declare const getCookieName: (apiKey: string, postKey?: string, limit?: number) => string;
export declare const getOldCookieName: (apiKey: string) => string;
//# sourceMappingURL=cookie-name.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"cookie-name.d.ts","sourceRoot":"","sources":["../../src/cookie-name.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,WAAY,MAAM,6CAE3C,CAAC;AAEF,eAAO,MAAM,gBAAgB,WAAY,MAAM,WAE9C,CAAC"}

View File

@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getOldCookieName = exports.getCookieName = void 0;
var constants_1 = require("./types/constants");
var getCookieName = function (apiKey, postKey, limit) {
if (postKey === void 0) { postKey = ''; }
if (limit === void 0) { limit = 10; }
return [constants_1.AMPLITUDE_PREFIX, postKey, apiKey.substring(0, limit)].filter(Boolean).join('_');
};
exports.getCookieName = getCookieName;
var getOldCookieName = function (apiKey) {
return "".concat(constants_1.AMPLITUDE_PREFIX.toLowerCase(), "_").concat(apiKey.substring(0, 6));
};
exports.getOldCookieName = getOldCookieName;
//# sourceMappingURL=cookie-name.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"cookie-name.js","sourceRoot":"","sources":["../../src/cookie-name.ts"],"names":[],"mappings":";;;AAAA,+CAAqD;AAE9C,IAAM,aAAa,GAAG,UAAC,MAAc,EAAE,OAAY,EAAE,KAAU;IAAxB,wBAAA,EAAA,YAAY;IAAE,sBAAA,EAAA,UAAU;IACpE,OAAO,CAAC,4BAAgB,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3F,CAAC,CAAC;AAFW,QAAA,aAAa,iBAExB;AAEK,IAAM,gBAAgB,GAAG,UAAC,MAAc;IAC7C,OAAO,UAAG,4BAAgB,CAAC,WAAW,EAAE,cAAI,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,CAAC;AACvE,CAAC,CAAC;AAFW,QAAA,gBAAgB,oBAE3B","sourcesContent":["import { AMPLITUDE_PREFIX } from './types/constants';\n\nexport const getCookieName = (apiKey: string, postKey = '', limit = 10) => {\n return [AMPLITUDE_PREFIX, postKey, apiKey.substring(0, limit)].filter(Boolean).join('_');\n};\n\nexport const getOldCookieName = (apiKey: string) => {\n return `${AMPLITUDE_PREFIX.toLowerCase()}_${apiKey.substring(0, 6)}`;\n};\n"]}

View File

@@ -0,0 +1,71 @@
import { Plugin } from './types/plugin';
import { IConfig } from './types/config/core-config';
import { BaseEvent, EventOptions } from './types/event/base-event';
import { Result } from './types/result';
import { Event, UserProperties } from './types/event/event';
import { IIdentify } from './identify';
import { IRevenue } from './revenue';
import { Timeline } from './timeline';
import { returnWrapper } from './utils/return-wrapper';
import { CoreClient, PluginHost } from './types/client/core-client';
export declare class AmplitudeCore implements CoreClient, PluginHost {
protected initializing: boolean;
protected name: string;
config: IConfig;
timeline: Timeline;
isReady: boolean;
protected q: Array<CallableFunction | typeof returnWrapper>;
protected dispatchQ: Array<CallableFunction>;
constructor(name?: string);
protected _init(config: IConfig): Promise<void>;
runQueuedFunctions(queueName: 'q' | 'dispatchQ'): Promise<void>;
track(eventInput: BaseEvent | string, eventProperties?: Record<string, any>, eventOptions?: EventOptions): import("./utils/return-wrapper").AmplitudeReturn<Result>;
logEvent: (eventInput: BaseEvent | string, eventProperties?: Record<string, any>, eventOptions?: EventOptions) => import("./utils/return-wrapper").AmplitudeReturn<Result>;
identify(identify: IIdentify, eventOptions?: EventOptions): import("./utils/return-wrapper").AmplitudeReturn<Result>;
groupIdentify(groupType: string, groupName: string | string[], identify: IIdentify, eventOptions?: EventOptions): import("./utils/return-wrapper").AmplitudeReturn<Result>;
setGroup(groupType: string, groupName: string | string[], eventOptions?: EventOptions): import("./utils/return-wrapper").AmplitudeReturn<Result>;
revenue(revenue: IRevenue, eventOptions?: EventOptions): import("./utils/return-wrapper").AmplitudeReturn<Result>;
add(plugin: Plugin): import("./utils/return-wrapper").AmplitudeReturn<void>;
_addPlugin(plugin: Plugin): import("./utils/return-wrapper").AmplitudeReturn<void>;
remove(pluginName: string): import("./utils/return-wrapper").AmplitudeReturn<void>;
_removePlugin(pluginName: string): import("./utils/return-wrapper").AmplitudeReturn<void>;
dispatchWithCallback(event: Event, callback: (result: Result) => void): void;
dispatch(event: Event): Promise<Result>;
/**
*
* This method applies identify operations to user properties and
* returns a single object representing the final user property state.
*
* This is a best-effort api that only supports $set, $clearAll, and $unset.
* Other operations are not supported and are ignored.
*
*
* @param userProperties The `event.userProperties` object from an Identify event.
* @returns A key-value object user properties without operations.
*
* @example
* Input:
* {
* $set: { plan: 'premium' },
* custom_flag: true
* }
*
* Output:
* {
* plan: 'premium',
* custom_flag: true
* }
*/
getOperationAppliedUserProperties(userProperties: UserProperties | undefined): {
[key: string]: any;
};
process(event: Event): Promise<Result>;
setOptOut(optOut: boolean): void;
_setOptOut(optOut: boolean): void;
flush(): import("./utils/return-wrapper").AmplitudeReturn<void>;
plugin(name: string): Plugin | undefined;
plugins<T extends Plugin>(pluginClass: {
new (...args: any[]): T;
}): T[];
}
//# sourceMappingURL=core-client.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"core-client.d.ts","sourceRoot":"","sources":["../../src/core-client.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,286 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AmplitudeCore = void 0;
var tslib_1 = require("tslib");
var event_1 = require("./types/event/event");
var identify_1 = require("./identify");
var messages_1 = require("./types/messages");
var timeline_1 = require("./timeline");
var event_builder_1 = require("./utils/event-builder");
var result_builder_1 = require("./utils/result-builder");
var return_wrapper_1 = require("./utils/return-wrapper");
var AmplitudeCore = /** @class */ (function () {
function AmplitudeCore(name) {
if (name === void 0) { name = '$default'; }
this.initializing = false;
this.isReady = false;
this.q = [];
this.dispatchQ = [];
this.logEvent = this.track.bind(this);
this.timeline = new timeline_1.Timeline(this);
this.name = name;
}
AmplitudeCore.prototype._init = function (config) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
this.config = config;
this.timeline.reset(this);
this.timeline.loggerProvider = this.config.loggerProvider;
return [4 /*yield*/, this.runQueuedFunctions('q')];
case 1:
_a.sent();
this.isReady = true;
return [2 /*return*/];
}
});
});
};
AmplitudeCore.prototype.runQueuedFunctions = function (queueName) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var queuedFunctions, queuedFunctions_1, queuedFunctions_1_1, queuedFunction, val, e_1_1;
var e_1, _a;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
queuedFunctions = this[queueName];
this[queueName] = [];
_b.label = 1;
case 1:
_b.trys.push([1, 8, 9, 10]);
queuedFunctions_1 = tslib_1.__values(queuedFunctions), queuedFunctions_1_1 = queuedFunctions_1.next();
_b.label = 2;
case 2:
if (!!queuedFunctions_1_1.done) return [3 /*break*/, 7];
queuedFunction = queuedFunctions_1_1.value;
val = queuedFunction();
if (!(val && 'promise' in val)) return [3 /*break*/, 4];
return [4 /*yield*/, val.promise];
case 3:
_b.sent();
return [3 /*break*/, 6];
case 4: return [4 /*yield*/, val];
case 5:
_b.sent();
_b.label = 6;
case 6:
queuedFunctions_1_1 = queuedFunctions_1.next();
return [3 /*break*/, 2];
case 7: return [3 /*break*/, 10];
case 8:
e_1_1 = _b.sent();
e_1 = { error: e_1_1 };
return [3 /*break*/, 10];
case 9:
try {
if (queuedFunctions_1_1 && !queuedFunctions_1_1.done && (_a = queuedFunctions_1.return)) _a.call(queuedFunctions_1);
}
finally { if (e_1) throw e_1.error; }
return [7 /*endfinally*/];
case 10:
if (!this[queueName].length) return [3 /*break*/, 12];
return [4 /*yield*/, this.runQueuedFunctions(queueName)];
case 11:
_b.sent();
_b.label = 12;
case 12: return [2 /*return*/];
}
});
});
};
AmplitudeCore.prototype.track = function (eventInput, eventProperties, eventOptions) {
var event = (0, event_builder_1.createTrackEvent)(eventInput, eventProperties, eventOptions);
return (0, return_wrapper_1.returnWrapper)(this.dispatch(event));
};
AmplitudeCore.prototype.identify = function (identify, eventOptions) {
var event = (0, event_builder_1.createIdentifyEvent)(identify, eventOptions);
return (0, return_wrapper_1.returnWrapper)(this.dispatch(event));
};
AmplitudeCore.prototype.groupIdentify = function (groupType, groupName, identify, eventOptions) {
var event = (0, event_builder_1.createGroupIdentifyEvent)(groupType, groupName, identify, eventOptions);
return (0, return_wrapper_1.returnWrapper)(this.dispatch(event));
};
AmplitudeCore.prototype.setGroup = function (groupType, groupName, eventOptions) {
var event = (0, event_builder_1.createGroupEvent)(groupType, groupName, eventOptions);
return (0, return_wrapper_1.returnWrapper)(this.dispatch(event));
};
AmplitudeCore.prototype.revenue = function (revenue, eventOptions) {
var event = (0, event_builder_1.createRevenueEvent)(revenue, eventOptions);
return (0, return_wrapper_1.returnWrapper)(this.dispatch(event));
};
AmplitudeCore.prototype.add = function (plugin) {
if (!this.isReady) {
this.q.push(this._addPlugin.bind(this, plugin));
return (0, return_wrapper_1.returnWrapper)();
}
return this._addPlugin(plugin);
};
AmplitudeCore.prototype._addPlugin = function (plugin) {
return (0, return_wrapper_1.returnWrapper)(this.timeline.register(plugin, this.config));
};
AmplitudeCore.prototype.remove = function (pluginName) {
if (!this.isReady) {
this.q.push(this._removePlugin.bind(this, pluginName));
return (0, return_wrapper_1.returnWrapper)();
}
return this._removePlugin(pluginName);
};
AmplitudeCore.prototype._removePlugin = function (pluginName) {
return (0, return_wrapper_1.returnWrapper)(this.timeline.deregister(pluginName, this.config));
};
AmplitudeCore.prototype.dispatchWithCallback = function (event, callback) {
if (!this.isReady) {
return callback((0, result_builder_1.buildResult)(event, 0, messages_1.CLIENT_NOT_INITIALIZED));
}
void this.process(event).then(callback);
};
AmplitudeCore.prototype.dispatch = function (event) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _this = this;
return tslib_1.__generator(this, function (_a) {
if (!this.isReady) {
return [2 /*return*/, new Promise(function (resolve) {
_this.dispatchQ.push(_this.dispatchWithCallback.bind(_this, event, resolve));
})];
}
return [2 /*return*/, this.process(event)];
});
});
};
/**
*
* This method applies identify operations to user properties and
* returns a single object representing the final user property state.
*
* This is a best-effort api that only supports $set, $clearAll, and $unset.
* Other operations are not supported and are ignored.
*
*
* @param userProperties The `event.userProperties` object from an Identify event.
* @returns A key-value object user properties without operations.
*
* @example
* Input:
* {
* $set: { plan: 'premium' },
* custom_flag: true
* }
*
* Output:
* {
* plan: 'premium',
* custom_flag: true
* }
*/
AmplitudeCore.prototype.getOperationAppliedUserProperties = function (userProperties) {
var updatedProperties = {};
if (userProperties === undefined) {
return updatedProperties;
}
// Keep non-operation keys for later merge
var nonOpProperties = {};
Object.keys(userProperties).forEach(function (key) {
if (!Object.values(event_1.IdentifyOperation).includes(key)) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
nonOpProperties[key] = userProperties[key];
}
});
identify_1.OrderedIdentifyOperations.forEach(function (operation) {
// Skip when key is an operation.
if (!Object.keys(userProperties).includes(operation))
return;
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
var opProperties = userProperties[operation];
switch (operation) {
case event_1.IdentifyOperation.CLEAR_ALL:
// Due to operation order, the following line will never execute.
/* istanbul ignore next */
Object.keys(updatedProperties).forEach(function (prop) {
delete updatedProperties[prop];
});
break;
case event_1.IdentifyOperation.UNSET:
Object.keys(opProperties).forEach(function (prop) {
delete updatedProperties[prop];
});
break;
case event_1.IdentifyOperation.SET:
Object.assign(updatedProperties, opProperties);
break;
}
});
// Merge non-operation properties.
// Custom properties should not be affected by operations.
// https://github.com/amplitude/nova/blob/343f678ded83c032e83b189796b3c2be161b48f5/src/main/java/com/amplitude/userproperty/model/ModifyUserPropertiesIdent.java#L79-L83
Object.assign(updatedProperties, nonOpProperties);
return updatedProperties;
};
AmplitudeCore.prototype.process = function (event) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var userProperties, result, e_2, message, result;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
// skip event processing if opt out
if (this.config.optOut) {
return [2 /*return*/, (0, result_builder_1.buildResult)(event, 0, messages_1.OPT_OUT_MESSAGE)];
}
if (event.event_type === event_1.SpecialEventType.IDENTIFY) {
userProperties = this.getOperationAppliedUserProperties(event.user_properties);
this.timeline.onIdentityChanged({ userProperties: userProperties });
}
return [4 /*yield*/, this.timeline.push(event)];
case 1:
result = _a.sent();
result.code === 200
? this.config.loggerProvider.log(result.message)
: result.code === 100
? this.config.loggerProvider.warn(result.message)
: this.config.loggerProvider.error(result.message);
return [2 /*return*/, result];
case 2:
e_2 = _a.sent();
message = String(e_2);
this.config.loggerProvider.error(message);
result = (0, result_builder_1.buildResult)(event, 0, message);
return [2 /*return*/, result];
case 3: return [2 /*return*/];
}
});
});
};
AmplitudeCore.prototype.setOptOut = function (optOut) {
if (!this.isReady) {
this.q.push(this._setOptOut.bind(this, Boolean(optOut)));
return;
}
this._setOptOut(optOut);
};
AmplitudeCore.prototype._setOptOut = function (optOut) {
if (this.config.optOut !== optOut) {
this.timeline.onOptOutChanged(optOut);
this.config.optOut = Boolean(optOut);
}
};
AmplitudeCore.prototype.flush = function () {
return (0, return_wrapper_1.returnWrapper)(this.timeline.flush());
};
AmplitudeCore.prototype.plugin = function (name) {
var plugin = this.timeline.plugins.find(function (plugin) { return plugin.name === name; });
if (plugin === undefined) {
this.config.loggerProvider.debug("Cannot find plugin with name ".concat(name));
return undefined;
}
return plugin;
};
AmplitudeCore.prototype.plugins = function (pluginClass) {
return this.timeline.plugins.filter(function (plugin) { return plugin instanceof pluginClass; });
};
return AmplitudeCore;
}());
exports.AmplitudeCore = AmplitudeCore;
//# sourceMappingURL=core-client.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,187 @@
import { ILogger } from '../logger';
import { IDiagnosticsStorage } from './diagnostics-storage';
import { ServerZoneType } from '../types/server-zone';
export declare const SAVE_INTERVAL_MS = 1000;
export declare const FLUSH_INTERVAL_MS: number;
export declare const DIAGNOSTICS_US_SERVER_URL = "https://diagnostics.prod.us-west-2.amplitude.com/v1/capture";
export declare const DIAGNOSTICS_EU_SERVER_URL = "https://diagnostics.prod.eu-central-1.amplitude.com/v1/capture";
export declare const MAX_MEMORY_STORAGE_COUNT = 10000;
export declare const MAX_MEMORY_STORAGE_EVENTS_COUNT = 10;
/**
* Key-value pairs for environment/context information
*/
type DiagnosticsTags = Record<string, string>;
/**
* Numeric counters that can be incremented
*/
type DiagnosticsCounters = Record<string, number>;
/**
* Properties for diagnostic events
*/
type EventProperties = Record<string, any>;
/**
* Individual diagnostic event
*/
interface DiagnosticsEvent {
readonly event_name: string;
readonly time: number;
readonly event_properties: EventProperties;
}
/**
* Computed histogram statistics for final payload
*/
interface HistogramResult {
readonly count: number;
readonly min: number;
readonly max: number;
readonly avg: number;
}
/**
* Internal histogram statistics with sum for efficient incremental updates
*/
export interface HistogramStats {
count: number;
min: number;
max: number;
sum: number;
}
/**
* Collection of histogram results keyed by histogram name
*/
type DiagnosticsHistograms = Record<string, HistogramResult>;
/**
* Collection of histogram stats keyed by histogram name (internal use for memory + persistence storage)
*/
type DiagnosticsHistogramStats = Record<string, HistogramStats>;
/**
* Complete diagnostics payload sent to backend
*/
interface FlushPayload {
readonly tags: DiagnosticsTags;
readonly histogram: DiagnosticsHistograms;
readonly counters: DiagnosticsCounters;
readonly events: readonly DiagnosticsEvent[];
}
/**
* Amplitude Diagnostics Client
*
* A client for collecting and managing diagnostics data including tags, counters,
* histograms, and events. Data is stored persistently using IndexedDB to survive browser restarts and offline scenarios.
*
* Key Features:
* - IndexedDB storage
* - Time-based persistent storage flush interval (5 minutes since last flush)
* - 1 second time-based memory storage flush to persistent storage
* - Histogram statistics calculation (min, max, avg)
*/
export interface IDiagnosticsClient {
/**
* Set or update a tag
*
* @example
* ```typescript
* // Set environment tags
* diagnostics.setTag('library', 'amplitude-typescript/2.0.0');
* diagnostics.setTag('user_agent', navigator.userAgent);
* ```
*/
setTag(name: string, value: string): void;
/**
* Increment a counter. If doesn't exist, create a counter and set value to 1
*
* @example
* ```typescript
* // Track counters
* diagnostics.increment('analytics.fileNotFound');
* diagnostics.increment('network.retry', 3);
* ```
*/
increment(name: string, size?: number): void;
/**
* Record a histogram value
*
* @example
* ```typescript
* // Record performance metrics
* diagnostics.recordHistogram('sr.time', 5.2);
* diagnostics.recordHistogram('network.latency', 150);
* ```
*/
recordHistogram(name: string, value: number): void;
/**
* Record an event
*
* @example
* ```typescript
* // Record diagnostic events
* diagnostics.recordEvent('error', {
* stack_trace: '...',
* });
* ```
*/
recordEvent(name: string, properties: EventProperties): void;
_flush(): void;
/**
* Sets the sample rate for diagnostics.
*
* @example
* ```typescript
* diagnostics.setSampleRate(0.5);
* ```
*/
_setSampleRate(sampleRate: number): void;
}
export declare class DiagnosticsClient implements IDiagnosticsClient {
storage?: IDiagnosticsStorage;
logger: ILogger;
serverUrl: string;
apiKey: string;
shouldTrack: boolean;
config: {
enabled: boolean;
sampleRate: number;
};
/**
* The timestamp when the diagnostics client was initialized.
* Save in memory to keep lifecycle sample rate calculation consistency.
*/
startTimestamp: number;
inMemoryTags: DiagnosticsTags;
inMemoryCounters: DiagnosticsCounters;
inMemoryHistograms: DiagnosticsHistogramStats;
inMemoryEvents: DiagnosticsEvent[];
saveTimer: ReturnType<typeof setTimeout> | null;
flushTimer: ReturnType<typeof setTimeout> | null;
constructor(apiKey: string, logger: ILogger, serverZone?: ServerZoneType, options?: {
enabled?: boolean;
sampleRate?: number;
});
/**
* Check if storage is available and tracking is enabled
*/
isStorageAndTrackEnabled(): boolean;
setTag(name: string, value: string): void;
increment(name: string, size?: number): void;
recordHistogram(name: string, value: number): void;
recordEvent(name: string, properties: EventProperties): void;
startTimersIfNeeded(): void;
saveAllDataToStorage(): Promise<void>;
_flush(): Promise<void>;
/**
* Send diagnostics data to the server
*/
fetch(payload: FlushPayload): Promise<void>;
/**
* Initialize flush interval logic.
* Check if 5 minutes has passed since last flush, if so flush immediately.
* Otherwise set a timer to flush when the interval is reached.
*/
initializeFlushInterval(): Promise<void>;
/**
* Helper method to set flush timer with consistent error handling
*/
private _setFlushTimer;
_setSampleRate(sampleRate: number): void;
}
export {};
//# sourceMappingURL=diagnostics-client.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"diagnostics-client.d.ts","sourceRoot":"","sources":["../../../src/diagnostics/diagnostics-client.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,330 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DiagnosticsClient = exports.MAX_MEMORY_STORAGE_EVENTS_COUNT = exports.MAX_MEMORY_STORAGE_COUNT = exports.DIAGNOSTICS_EU_SERVER_URL = exports.DIAGNOSTICS_US_SERVER_URL = exports.FLUSH_INTERVAL_MS = exports.SAVE_INTERVAL_MS = void 0;
var tslib_1 = require("tslib");
var diagnostics_storage_1 = require("./diagnostics-storage");
var global_scope_1 = require("../global-scope");
var sampling_1 = require("../utils/sampling");
exports.SAVE_INTERVAL_MS = 1000; // 1 second
exports.FLUSH_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes
exports.DIAGNOSTICS_US_SERVER_URL = 'https://diagnostics.prod.us-west-2.amplitude.com/v1/capture';
exports.DIAGNOSTICS_EU_SERVER_URL = 'https://diagnostics.prod.eu-central-1.amplitude.com/v1/capture';
// In-memory storage limits
exports.MAX_MEMORY_STORAGE_COUNT = 10000; // for tags, counters, histograms separately
exports.MAX_MEMORY_STORAGE_EVENTS_COUNT = 10;
var DiagnosticsClient = /** @class */ (function () {
function DiagnosticsClient(apiKey, logger, serverZone, options) {
if (serverZone === void 0) { serverZone = 'US'; }
// In-memory storages
this.inMemoryTags = {};
this.inMemoryCounters = {};
this.inMemoryHistograms = {};
this.inMemoryEvents = [];
// Timer for 1-second persistence
this.saveTimer = null;
// Timer for flush interval
this.flushTimer = null;
this.apiKey = apiKey;
this.logger = logger;
this.serverUrl = serverZone === 'US' ? exports.DIAGNOSTICS_US_SERVER_URL : exports.DIAGNOSTICS_EU_SERVER_URL;
this.logger.debug('DiagnosticsClient: Initializing with options', JSON.stringify(options, null, 2));
// Diagnostics is enabled by default with sample rate of 0 (no sampling)
this.config = tslib_1.__assign({ enabled: true, sampleRate: 0 }, options);
this.startTimestamp = Date.now();
this.shouldTrack = (0, sampling_1.isTimestampInSample)(this.startTimestamp, this.config.sampleRate) && this.config.enabled;
if (diagnostics_storage_1.DiagnosticsStorage.isSupported()) {
this.storage = new diagnostics_storage_1.DiagnosticsStorage(apiKey, logger);
}
else {
this.logger.debug('DiagnosticsClient: IndexedDB is not supported');
}
void this.initializeFlushInterval();
}
/**
* Check if storage is available and tracking is enabled
*/
DiagnosticsClient.prototype.isStorageAndTrackEnabled = function () {
return Boolean(this.storage) && Boolean(this.shouldTrack);
};
DiagnosticsClient.prototype.setTag = function (name, value) {
if (!this.isStorageAndTrackEnabled()) {
return;
}
if (Object.keys(this.inMemoryTags).length >= exports.MAX_MEMORY_STORAGE_COUNT) {
this.logger.debug('DiagnosticsClient: Early return setTags as reaching memory limit');
return;
}
this.inMemoryTags[name] = value;
this.startTimersIfNeeded();
};
DiagnosticsClient.prototype.increment = function (name, size) {
if (size === void 0) { size = 1; }
if (!this.isStorageAndTrackEnabled()) {
return;
}
if (Object.keys(this.inMemoryCounters).length >= exports.MAX_MEMORY_STORAGE_COUNT) {
this.logger.debug('DiagnosticsClient: Early return increment as reaching memory limit');
return;
}
this.inMemoryCounters[name] = (this.inMemoryCounters[name] || 0) + size;
this.startTimersIfNeeded();
};
DiagnosticsClient.prototype.recordHistogram = function (name, value) {
if (!this.isStorageAndTrackEnabled()) {
return;
}
if (Object.keys(this.inMemoryHistograms).length >= exports.MAX_MEMORY_STORAGE_COUNT) {
this.logger.debug('DiagnosticsClient: Early return recordHistogram as reaching memory limit');
return;
}
var existing = this.inMemoryHistograms[name];
if (existing) {
// Update existing stats incrementally
existing.count += 1;
existing.min = Math.min(existing.min, value);
existing.max = Math.max(existing.max, value);
existing.sum += value;
}
else {
// Create new stats
this.inMemoryHistograms[name] = {
count: 1,
min: value,
max: value,
sum: value,
};
}
this.startTimersIfNeeded();
};
DiagnosticsClient.prototype.recordEvent = function (name, properties) {
if (!this.isStorageAndTrackEnabled()) {
return;
}
if (this.inMemoryEvents.length >= exports.MAX_MEMORY_STORAGE_EVENTS_COUNT) {
this.logger.debug('DiagnosticsClient: Early return recordEvent as reaching memory limit');
return;
}
this.inMemoryEvents.push({
event_name: name,
time: Date.now(),
event_properties: properties,
});
this.startTimersIfNeeded();
};
DiagnosticsClient.prototype.startTimersIfNeeded = function () {
var _this = this;
if (!this.saveTimer) {
this.saveTimer = setTimeout(function () {
_this.saveAllDataToStorage()
.catch(function (error) {
_this.logger.debug('DiagnosticsClient: Failed to save all data to storage', error);
})
.finally(function () {
_this.saveTimer = null;
});
}, exports.SAVE_INTERVAL_MS);
}
if (!this.flushTimer) {
this.flushTimer = setTimeout(function () {
_this._flush()
.catch(function (error) {
_this.logger.debug('DiagnosticsClient: Failed to flush', error);
})
.finally(function () {
_this.flushTimer = null;
});
}, exports.FLUSH_INTERVAL_MS);
}
};
DiagnosticsClient.prototype.saveAllDataToStorage = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var tagsToSave, countersToSave, histogramsToSave, eventsToSave;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!this.storage) {
return [2 /*return*/];
}
tagsToSave = tslib_1.__assign({}, this.inMemoryTags);
countersToSave = tslib_1.__assign({}, this.inMemoryCounters);
histogramsToSave = tslib_1.__assign({}, this.inMemoryHistograms);
eventsToSave = tslib_1.__spreadArray([], tslib_1.__read(this.inMemoryEvents), false);
this.inMemoryEvents = [];
this.inMemoryTags = {};
this.inMemoryCounters = {};
this.inMemoryHistograms = {};
return [4 /*yield*/, Promise.all([
this.storage.setTags(tagsToSave),
this.storage.incrementCounters(countersToSave),
this.storage.setHistogramStats(histogramsToSave),
this.storage.addEventRecords(eventsToSave),
])];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
};
DiagnosticsClient.prototype._flush = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _a, tagRecords, counterRecords, histogramStatsRecords, eventRecords, tags, counters, histogram, events, payload;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!this.storage) {
return [2 /*return*/];
}
return [4 /*yield*/, this.saveAllDataToStorage()];
case 1:
_b.sent();
this.saveTimer = null;
this.flushTimer = null;
return [4 /*yield*/, this.storage.getAllAndClear()];
case 2:
_a = _b.sent(), tagRecords = _a.tags, counterRecords = _a.counters, histogramStatsRecords = _a.histogramStats, eventRecords = _a.events;
// Update the last flush timestamp
void this.storage.setLastFlushTimestamp(Date.now());
tags = {};
tagRecords.forEach(function (record) {
tags[record.key] = record.value;
});
counters = {};
counterRecords.forEach(function (record) {
counters[record.key] = record.value;
});
histogram = {};
histogramStatsRecords.forEach(function (stats) {
histogram[stats.key] = {
count: stats.count,
min: stats.min,
max: stats.max,
avg: Math.round((stats.sum / stats.count) * 100) / 100, // round the average to 2 decimal places.
};
});
events = eventRecords.map(function (record) { return ({
event_name: record.event_name,
time: record.time,
event_properties: record.event_properties,
}); });
// Early return if all data collections are empty
if (Object.keys(counters).length === 0 && Object.keys(histogram).length === 0 && events.length === 0) {
return [2 /*return*/];
}
payload = {
tags: tags,
histogram: histogram,
counters: counters,
events: events,
};
// Send payload to diagnostics server
void this.fetch(payload);
return [2 /*return*/];
}
});
});
};
/**
* Send diagnostics data to the server
*/
DiagnosticsClient.prototype.fetch = function (payload) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var response, error_1;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
if (!(0, global_scope_1.getGlobalScope)()) {
throw new Error('DiagnosticsClient: Fetch is not supported');
}
return [4 /*yield*/, fetch(this.serverUrl, {
method: 'POST',
headers: {
'X-ApiKey': this.apiKey,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
})];
case 1:
response = _a.sent();
if (!response.ok) {
this.logger.debug('DiagnosticsClient: Failed to send diagnostics data.');
return [2 /*return*/];
}
this.logger.debug('DiagnosticsClient: Successfully sent diagnostics data');
return [3 /*break*/, 3];
case 2:
error_1 = _a.sent();
this.logger.debug('DiagnosticsClient: Failed to send diagnostics data. ', error_1);
return [3 /*break*/, 3];
case 3: return [2 /*return*/];
}
});
});
};
/**
* Initialize flush interval logic.
* Check if 5 minutes has passed since last flush, if so flush immediately.
* Otherwise set a timer to flush when the interval is reached.
*/
DiagnosticsClient.prototype.initializeFlushInterval = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var now, lastFlushTimestamp, timeSinceLastFlush;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!this.storage) {
return [2 /*return*/];
}
now = Date.now();
return [4 /*yield*/, this.storage.getLastFlushTimestamp()];
case 1:
lastFlushTimestamp = (_a.sent()) || -1;
// If last flush timestamp is -1, it means this is a new client
// Save current timestamp as the initial "last flush timestamp"
// and schedule the flush timer
if (lastFlushTimestamp === -1) {
void this.storage.setLastFlushTimestamp(now);
this._setFlushTimer(exports.FLUSH_INTERVAL_MS);
return [2 /*return*/];
}
timeSinceLastFlush = now - lastFlushTimestamp;
if (timeSinceLastFlush >= exports.FLUSH_INTERVAL_MS) {
// More than 5 minutes has passed, flush immediately
void this._flush();
return [2 /*return*/];
}
else {
// Set timer for remaining time
this._setFlushTimer(exports.FLUSH_INTERVAL_MS - timeSinceLastFlush);
}
return [2 /*return*/];
}
});
});
};
/**
* Helper method to set flush timer with consistent error handling
*/
DiagnosticsClient.prototype._setFlushTimer = function (delay) {
var _this = this;
this.flushTimer = setTimeout(function () {
_this._flush()
.catch(function (error) {
_this.logger.debug('DiagnosticsClient: Failed to flush', error);
})
.finally(function () {
_this.flushTimer = null;
});
}, delay);
};
DiagnosticsClient.prototype._setSampleRate = function (sampleRate) {
this.logger.debug('DiagnosticsClient: Setting sample rate to', sampleRate);
this.config.sampleRate = sampleRate;
this.shouldTrack = (0, sampling_1.isTimestampInSample)(this.startTimestamp, this.config.sampleRate) && this.config.enabled;
this.logger.debug('DiagnosticsClient: Should track is', this.shouldTrack);
};
return DiagnosticsClient;
}());
exports.DiagnosticsClient = DiagnosticsClient;
//# sourceMappingURL=diagnostics-client.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,123 @@
import { ILogger } from '../logger';
import { HistogramStats } from './diagnostics-client';
export declare const TABLE_NAMES: {
readonly TAGS: "tags";
readonly COUNTERS: "counters";
readonly HISTOGRAMS: "histograms";
readonly EVENTS: "events";
readonly INTERNAL: "internal";
};
export declare const INTERNAL_KEYS: {
readonly LAST_FLUSH_TIMESTAMP: "last_flush_timestamp";
};
export interface TagRecord {
key: string;
value: string;
}
export interface CounterRecord {
key: string;
value: number;
}
export interface HistogramRecord {
key: string;
count: number;
min: number;
max: number;
sum: number;
}
export interface EventRecord {
id?: number;
event_name: string;
time: number;
event_properties: Record<string, any>;
}
export interface InternalRecord {
key: string;
value: string;
}
export interface IDiagnosticsStorage {
/**
* Set multiple tags in a single transaction (batch operation)
* Promise never rejects - errors are logged and operation continues gracefully
*/
setTags(tags: Record<string, string>): Promise<void>;
/**
* Increment multiple counters in a single transaction (batch operation)
* Uses read-modify-write pattern to accumulate with existing values
* Promise never rejects - errors are logged and operation continues gracefully
*/
incrementCounters(counters: Record<string, number>): Promise<void>;
/**
* Set multiple histogram stats in a single transaction (batch operation)
* Uses read-modify-write pattern to accumulate count/sum and update min/max with existing values
* Promise never rejects - errors are logged and operation continues gracefully
*/
setHistogramStats(histogramStats: Record<string, {
count: number;
min: number;
max: number;
sum: number;
}>): Promise<void>;
/**
* Add multiple event records in a single transaction (batch operation)
* Promise never rejects - errors are logged and operation continues gracefully
*/
addEventRecords(events: Array<{
event_name: string;
time: number;
event_properties: Record<string, any>;
}>): Promise<void>;
setLastFlushTimestamp(timestamp: number): Promise<void>;
getLastFlushTimestamp(): Promise<number | undefined>;
/**
* Get all data except internal data from storage and clear it
*/
getAllAndClear(): Promise<{
tags: TagRecord[];
counters: CounterRecord[];
histogramStats: HistogramRecord[];
events: EventRecord[];
}>;
}
/**
* Purpose-specific IndexedDB storage for diagnostics data
* Provides optimized methods for each type of diagnostics data
*/
export declare class DiagnosticsStorage implements IDiagnosticsStorage {
dbPromise: Promise<IDBDatabase> | null;
dbName: string;
logger: ILogger;
constructor(apiKey: string, logger: ILogger);
/**
* Check if IndexedDB is supported in the current environment
* @returns true if IndexedDB is available, false otherwise
*/
static isSupported(): boolean;
getDB(): Promise<IDBDatabase>;
openDB(): Promise<IDBDatabase>;
createTables(db: IDBDatabase): void;
setTags(tags: Record<string, string>): Promise<void>;
incrementCounters(counters: Record<string, number>): Promise<void>;
setHistogramStats(histogramStats: Record<string, HistogramStats>): Promise<void>;
addEventRecords(events: Array<{
event_name: string;
time: number;
event_properties: Record<string, any>;
}>): Promise<void>;
setInternal(key: string, value: string): Promise<void>;
getInternal(key: string): Promise<InternalRecord | undefined>;
getLastFlushTimestamp(): Promise<number | undefined>;
setLastFlushTimestamp(timestamp: number): Promise<void>;
clearTable(transaction: IDBTransaction, tableName: string): Promise<void>;
getAllAndClear(): Promise<{
tags: TagRecord[];
counters: CounterRecord[];
histogramStats: HistogramRecord[];
events: EventRecord[];
}>;
/**
* Helper method to get all records from a store within a transaction
*/
private getAllFromStore;
}
//# sourceMappingURL=diagnostics-storage.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"diagnostics-storage.d.ts","sourceRoot":"","sources":["../../../src/diagnostics/diagnostics-storage.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,492 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DiagnosticsStorage = exports.INTERNAL_KEYS = exports.TABLE_NAMES = void 0;
var tslib_1 = require("tslib");
var global_scope_1 = require("../global-scope");
var MAX_PERSISTENT_STORAGE_EVENTS_COUNT = 10;
// Database configuration
var DB_VERSION = 1;
// Table names for different diagnostics types
exports.TABLE_NAMES = {
TAGS: 'tags',
COUNTERS: 'counters',
HISTOGRAMS: 'histograms',
EVENTS: 'events',
INTERNAL: 'internal', // New table for internal storage like flush timestamps
};
// Keys for internal storage table
exports.INTERNAL_KEYS = {
LAST_FLUSH_TIMESTAMP: 'last_flush_timestamp',
};
/**
* Purpose-specific IndexedDB storage for diagnostics data
* Provides optimized methods for each type of diagnostics data
*/
var DiagnosticsStorage = /** @class */ (function () {
function DiagnosticsStorage(apiKey, logger) {
this.dbPromise = null;
this.logger = logger;
this.dbName = "AMP_diagnostics_".concat(apiKey.substring(0, 10));
}
/**
* Check if IndexedDB is supported in the current environment
* @returns true if IndexedDB is available, false otherwise
*/
DiagnosticsStorage.isSupported = function () {
var _a;
return ((_a = (0, global_scope_1.getGlobalScope)()) === null || _a === void 0 ? void 0 : _a.indexedDB) !== undefined;
};
DiagnosticsStorage.prototype.getDB = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
if (!this.dbPromise) {
this.dbPromise = this.openDB();
}
return [2 /*return*/, this.dbPromise];
});
});
};
DiagnosticsStorage.prototype.openDB = function () {
var _this = this;
return new Promise(function (resolve, reject) {
var request = indexedDB.open(_this.dbName, DB_VERSION);
request.onerror = function () {
// Clear dbPromise when it rejects for the first time
_this.dbPromise = null;
reject(new Error('Failed to open IndexedDB'));
};
request.onsuccess = function () {
var db = request.result;
// Clear dbPromise when connection was on but went off later
db.onclose = function () {
_this.dbPromise = null;
_this.logger.debug('DiagnosticsStorage: DB connection closed.');
};
db.onerror = function (event) {
_this.logger.debug('DiagnosticsStorage: A global database error occurred.', event);
db.close();
};
resolve(db);
};
request.onupgradeneeded = function (event) {
var db = event.target.result;
_this.createTables(db);
};
});
};
DiagnosticsStorage.prototype.createTables = function (db) {
// Create tags table
if (!db.objectStoreNames.contains(exports.TABLE_NAMES.TAGS)) {
db.createObjectStore(exports.TABLE_NAMES.TAGS, { keyPath: 'key' });
}
// Create counters table
if (!db.objectStoreNames.contains(exports.TABLE_NAMES.COUNTERS)) {
db.createObjectStore(exports.TABLE_NAMES.COUNTERS, { keyPath: 'key' });
}
// Create histograms table for storing histogram stats (count, min, max, sum)
if (!db.objectStoreNames.contains(exports.TABLE_NAMES.HISTOGRAMS)) {
db.createObjectStore(exports.TABLE_NAMES.HISTOGRAMS, {
keyPath: 'key',
});
}
// Create events table
if (!db.objectStoreNames.contains(exports.TABLE_NAMES.EVENTS)) {
var eventsStore = db.createObjectStore(exports.TABLE_NAMES.EVENTS, {
keyPath: 'id',
autoIncrement: true,
});
// Create index on time for chronological queries
eventsStore.createIndex('time_idx', 'time', { unique: false });
}
// Create internal table for storing internal data like flush timestamps
if (!db.objectStoreNames.contains(exports.TABLE_NAMES.INTERNAL)) {
db.createObjectStore(exports.TABLE_NAMES.INTERNAL, { keyPath: 'key' });
}
};
DiagnosticsStorage.prototype.setTags = function (tags) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var db, transaction_1, store_1, error_1;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
if (Object.entries(tags).length === 0) {
return [2 /*return*/];
}
return [4 /*yield*/, this.getDB()];
case 1:
db = _a.sent();
transaction_1 = db.transaction([exports.TABLE_NAMES.TAGS], 'readwrite');
store_1 = transaction_1.objectStore(exports.TABLE_NAMES.TAGS);
return [2 /*return*/, new Promise(function (resolve) {
var entries = Object.entries(tags);
transaction_1.oncomplete = function () {
resolve();
};
transaction_1.onabort = function (event) {
_this.logger.debug('DiagnosticsStorage: Failed to set tags', event);
resolve();
};
entries.forEach(function (_a) {
var _b = tslib_1.__read(_a, 2), key = _b[0], value = _b[1];
var putRequest = store_1.put({ key: key, value: value });
putRequest.onerror = function (event) {
_this.logger.debug('DiagnosticsStorage: Failed to set tag', key, value, event);
};
});
})];
case 2:
error_1 = _a.sent();
this.logger.debug('DiagnosticsStorage: Failed to set tags', error_1);
return [3 /*break*/, 3];
case 3: return [2 /*return*/];
}
});
});
};
DiagnosticsStorage.prototype.incrementCounters = function (counters) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var db, transaction_2, store_2, error_2;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
if (Object.entries(counters).length === 0) {
return [2 /*return*/];
}
return [4 /*yield*/, this.getDB()];
case 1:
db = _a.sent();
transaction_2 = db.transaction([exports.TABLE_NAMES.COUNTERS], 'readwrite');
store_2 = transaction_2.objectStore(exports.TABLE_NAMES.COUNTERS);
return [2 /*return*/, new Promise(function (resolve) {
var entries = Object.entries(counters);
transaction_2.oncomplete = function () {
resolve();
};
transaction_2.onabort = function (event) {
_this.logger.debug('DiagnosticsStorage: Failed to increment counters', event);
resolve();
};
// Read existing values and update them
entries.forEach(function (_a) {
var _b = tslib_1.__read(_a, 2), key = _b[0], incrementValue = _b[1];
var getRequest = store_2.get(key);
getRequest.onsuccess = function () {
var existingRecord = getRequest.result;
/* istanbul ignore next */
var existingValue = existingRecord ? existingRecord.value : 0;
var putRequest = store_2.put({ key: key, value: existingValue + incrementValue });
putRequest.onerror = function (event) {
_this.logger.debug('DiagnosticsStorage: Failed to update counter', key, event);
};
};
getRequest.onerror = function (event) {
_this.logger.debug('DiagnosticsStorage: Failed to read existing counter', key, event);
};
});
})];
case 2:
error_2 = _a.sent();
this.logger.debug('DiagnosticsStorage: Failed to increment counters', error_2);
return [3 /*break*/, 3];
case 3: return [2 /*return*/];
}
});
});
};
DiagnosticsStorage.prototype.setHistogramStats = function (histogramStats) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var db, transaction_3, store_3, error_3;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
if (Object.entries(histogramStats).length === 0) {
return [2 /*return*/];
}
return [4 /*yield*/, this.getDB()];
case 1:
db = _a.sent();
transaction_3 = db.transaction([exports.TABLE_NAMES.HISTOGRAMS], 'readwrite');
store_3 = transaction_3.objectStore(exports.TABLE_NAMES.HISTOGRAMS);
return [2 /*return*/, new Promise(function (resolve) {
var entries = Object.entries(histogramStats);
transaction_3.oncomplete = function () {
resolve();
};
transaction_3.onabort = function (event) {
_this.logger.debug('DiagnosticsStorage: Failed to set histogram stats', event);
resolve();
};
// Read existing values and update them
entries.forEach(function (_a) {
var _b = tslib_1.__read(_a, 2), key = _b[0], newStats = _b[1];
var getRequest = store_3.get(key);
getRequest.onsuccess = function () {
var existingRecord = getRequest.result;
var updatedStats;
/* istanbul ignore next */
if (existingRecord) {
// Accumulate with existing stats
updatedStats = {
key: key,
count: existingRecord.count + newStats.count,
min: Math.min(existingRecord.min, newStats.min),
max: Math.max(existingRecord.max, newStats.max),
sum: existingRecord.sum + newStats.sum,
};
}
else {
// Create new stats
updatedStats = {
key: key,
count: newStats.count,
min: newStats.min,
max: newStats.max,
sum: newStats.sum,
};
}
var putRequest = store_3.put(updatedStats);
putRequest.onerror = function (event) {
_this.logger.debug('DiagnosticsStorage: Failed to set histogram stats', key, event);
};
};
getRequest.onerror = function (event) {
_this.logger.debug('DiagnosticsStorage: Failed to read existing histogram stats', key, event);
};
});
})];
case 2:
error_3 = _a.sent();
this.logger.debug('DiagnosticsStorage: Failed to set histogram stats', error_3);
return [3 /*break*/, 3];
case 3: return [2 /*return*/];
}
});
});
};
DiagnosticsStorage.prototype.addEventRecords = function (events) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var db, transaction_4, store_4, error_4;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
if (events.length === 0) {
return [2 /*return*/];
}
return [4 /*yield*/, this.getDB()];
case 1:
db = _a.sent();
transaction_4 = db.transaction([exports.TABLE_NAMES.EVENTS], 'readwrite');
store_4 = transaction_4.objectStore(exports.TABLE_NAMES.EVENTS);
return [2 /*return*/, new Promise(function (resolve) {
transaction_4.oncomplete = function () {
resolve();
};
/* istanbul ignore next */
transaction_4.onabort = function (event) {
_this.logger.debug('DiagnosticsStorage: Failed to add event records', event);
resolve();
};
// First, check how many events are currently stored
var countRequest = store_4.count();
countRequest.onsuccess = function () {
var currentCount = countRequest.result;
// Calculate how many events we can add
var availableSlots = Math.max(0, MAX_PERSISTENT_STORAGE_EVENTS_COUNT - currentCount);
if (availableSlots < events.length) {
_this.logger.debug("DiagnosticsStorage: Only added ".concat(availableSlots, " of ").concat(events.length, " events due to storage limit"));
}
// Only add events up to the available slots (take the least recent ones)
events.slice(0, availableSlots).forEach(function (event) {
var request = store_4.add(event);
request.onerror = function (event) {
_this.logger.debug('DiagnosticsStorage: Failed to add event record', event);
};
});
};
countRequest.onerror = function (event) {
_this.logger.debug('DiagnosticsStorage: Failed to count existing events', event);
};
})];
case 2:
error_4 = _a.sent();
this.logger.debug('DiagnosticsStorage: Failed to add event records', error_4);
return [3 /*break*/, 3];
case 3: return [2 /*return*/];
}
});
});
};
DiagnosticsStorage.prototype.setInternal = function (key, value) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var db, transaction_5, store_5, error_5;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4 /*yield*/, this.getDB()];
case 1:
db = _a.sent();
transaction_5 = db.transaction([exports.TABLE_NAMES.INTERNAL], 'readwrite');
store_5 = transaction_5.objectStore(exports.TABLE_NAMES.INTERNAL);
return [2 /*return*/, new Promise(function (resolve, reject) {
/* istanbul ignore next */
transaction_5.onabort = function () { return reject(new Error('Failed to set internal value')); };
var request = store_5.put({ key: key, value: value });
request.onsuccess = function () { return resolve(); };
/* istanbul ignore next */
request.onerror = function () { return reject(new Error('Failed to set internal value')); };
})];
case 2:
error_5 = _a.sent();
/* istanbul ignore next */
this.logger.debug('DiagnosticsStorage: Failed to set internal value', error_5);
return [3 /*break*/, 3];
case 3: return [2 /*return*/];
}
});
});
};
DiagnosticsStorage.prototype.getInternal = function (key) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var db, transaction_6, store_6, error_6;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4 /*yield*/, this.getDB()];
case 1:
db = _a.sent();
transaction_6 = db.transaction([exports.TABLE_NAMES.INTERNAL], 'readonly');
store_6 = transaction_6.objectStore(exports.TABLE_NAMES.INTERNAL);
return [2 /*return*/, new Promise(function (resolve, reject) {
/* istanbul ignore next */
transaction_6.onabort = function () { return reject(new Error('Failed to get internal value')); };
var request = store_6.get(key);
request.onsuccess = function () { return resolve(request.result); };
/* istanbul ignore next */
request.onerror = function () { return reject(new Error('Failed to get internal value')); };
})];
case 2:
error_6 = _a.sent();
this.logger.debug('DiagnosticsStorage: Failed to get internal value', error_6);
return [2 /*return*/, undefined];
case 3: return [2 /*return*/];
}
});
});
};
DiagnosticsStorage.prototype.getLastFlushTimestamp = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var record, error_7;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4 /*yield*/, this.getInternal(exports.INTERNAL_KEYS.LAST_FLUSH_TIMESTAMP)];
case 1:
record = _a.sent();
return [2 /*return*/, record ? parseInt(record.value, 10) : undefined];
case 2:
error_7 = _a.sent();
/* istanbul ignore next */
this.logger.debug('DiagnosticsStorage: Failed to get last flush timestamp', error_7);
/* istanbul ignore next */
return [2 /*return*/, undefined];
case 3: return [2 /*return*/];
}
});
});
};
DiagnosticsStorage.prototype.setLastFlushTimestamp = function (timestamp) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var error_8;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4 /*yield*/, this.setInternal(exports.INTERNAL_KEYS.LAST_FLUSH_TIMESTAMP, timestamp.toString())];
case 1:
_a.sent();
return [3 /*break*/, 3];
case 2:
error_8 = _a.sent();
/* istanbul ignore next */
this.logger.debug('DiagnosticsStorage: Failed to set last flush timestamp', error_8);
return [3 /*break*/, 3];
case 3: return [2 /*return*/];
}
});
});
};
/* istanbul ignore next */
DiagnosticsStorage.prototype.clearTable = function (transaction, tableName) {
return new Promise(function (resolve, reject) {
var store = transaction.objectStore(tableName);
var request = store.clear();
request.onsuccess = function () { return resolve(); };
request.onerror = function () { return reject(new Error("Failed to clear table ".concat(tableName))); };
});
};
/* istanbul ignore next */
DiagnosticsStorage.prototype.getAllAndClear = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var db, transaction, _a, tags, counters, histogramStats, events, error_9;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 4, , 5]);
return [4 /*yield*/, this.getDB()];
case 1:
db = _b.sent();
transaction = db.transaction([exports.TABLE_NAMES.TAGS, exports.TABLE_NAMES.COUNTERS, exports.TABLE_NAMES.HISTOGRAMS, exports.TABLE_NAMES.EVENTS], 'readwrite');
return [4 /*yield*/, Promise.all([
this.getAllFromStore(transaction, exports.TABLE_NAMES.TAGS),
this.getAllFromStore(transaction, exports.TABLE_NAMES.COUNTERS),
this.getAllFromStore(transaction, exports.TABLE_NAMES.HISTOGRAMS),
this.getAllFromStore(transaction, exports.TABLE_NAMES.EVENTS),
])];
case 2:
_a = tslib_1.__read.apply(void 0, [_b.sent(), 4]), tags = _a[0], counters = _a[1], histogramStats = _a[2], events = _a[3];
// Clear all data in the same transaction
return [4 /*yield*/, Promise.all([
this.clearTable(transaction, exports.TABLE_NAMES.COUNTERS),
this.clearTable(transaction, exports.TABLE_NAMES.HISTOGRAMS),
this.clearTable(transaction, exports.TABLE_NAMES.EVENTS),
])];
case 3:
// Clear all data in the same transaction
_b.sent();
return [2 /*return*/, { tags: tags, counters: counters, histogramStats: histogramStats, events: events }];
case 4:
error_9 = _b.sent();
this.logger.debug('DiagnosticsStorage: Failed to get all and clear data', error_9);
return [2 /*return*/, { tags: [], counters: [], histogramStats: [], events: [] }];
case 5: return [2 /*return*/];
}
});
});
};
/**
* Helper method to get all records from a store within a transaction
*/
/* istanbul ignore next */
DiagnosticsStorage.prototype.getAllFromStore = function (transaction, tableName) {
return new Promise(function (resolve, reject) {
var store = transaction.objectStore(tableName);
var request = store.getAll();
request.onsuccess = function () { return resolve(request.result); };
request.onerror = function () { return reject(new Error("Failed to get all from ".concat(tableName))); };
});
};
return DiagnosticsStorage;
}());
exports.DiagnosticsStorage = DiagnosticsStorage;
//# sourceMappingURL=diagnostics-storage.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,11 @@
import { IEventBridgeReceiver } from './event-bridge';
import { Event } from '../types/event/event';
export declare class EventBridgeChannel {
channel: string;
queue: Event[];
receiver: IEventBridgeReceiver | undefined;
constructor(channel: string);
sendEvent(event: Event): void;
setReceiver(receiver: IEventBridgeReceiver): void;
}
//# sourceMappingURL=event-bridge-channel.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"event-bridge-channel.d.ts","sourceRoot":"","sources":["../../../src/event-bridge/event-bridge-channel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAI7C,qBAAa,kBAAkB;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,KAAK,EAAE,CAAM;IACpB,QAAQ,EAAE,oBAAoB,GAAG,SAAS,CAAC;gBAE/B,OAAO,EAAE,MAAM;IAI3B,SAAS,CAAC,KAAK,EAAE,KAAK;IAQtB,WAAW,CAAC,QAAQ,EAAE,oBAAoB;CAW3C"}

View File

@@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EventBridgeChannel = void 0;
var tslib_1 = require("tslib");
var QUEUE_CAPACITY = 512;
var EventBridgeChannel = /** @class */ (function () {
function EventBridgeChannel(channel) {
this.queue = [];
this.channel = channel;
}
EventBridgeChannel.prototype.sendEvent = function (event) {
if (!this.receiver) {
this.queue = tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(this.queue.slice(0, QUEUE_CAPACITY)), false), [event], false);
return;
}
this.receiver.receive(this.channel, event);
};
EventBridgeChannel.prototype.setReceiver = function (receiver) {
var _this = this;
if (this.receiver) {
return;
}
this.receiver = receiver;
var events = this.queue;
this.queue = [];
events.forEach(function (event) {
_this.receiver.receive(_this.channel, event);
});
};
return EventBridgeChannel;
}());
exports.EventBridgeChannel = EventBridgeChannel;
//# sourceMappingURL=event-bridge-channel.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"event-bridge-channel.js","sourceRoot":"","sources":["../../../src/event-bridge/event-bridge-channel.ts"],"names":[],"mappings":";;;;AAGA,IAAM,cAAc,GAAG,GAAG,CAAC;AAE3B;IAKE,4BAAY,OAAe;QAH3B,UAAK,GAAY,EAAE,CAAC;QAIlB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,sCAAS,GAAT,UAAU,KAAY;QACpB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YAClB,IAAI,CAAC,KAAK,kEAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,YAAE,KAAK,SAAC,CAAC;YAC7D,OAAO;SACR;QACD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC7C,CAAC;IAED,wCAAW,GAAX,UAAY,QAA8B;QAA1C,iBAUC;QATC,IAAI,IAAI,CAAC,QAAQ,EAAE;YACjB,OAAO;SACR;QACD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAChB,MAAM,CAAC,OAAO,CAAC,UAAC,KAAK;YAClB,KAAI,CAAC,QAAiC,CAAC,OAAO,CAAC,KAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;IACL,CAAC;IACH,yBAAC;AAAD,CAAC,AA5BD,IA4BC;AA5BY,gDAAkB","sourcesContent":["import { IEventBridgeReceiver } from './event-bridge';\nimport { Event } from '../types/event/event';\n\nconst QUEUE_CAPACITY = 512;\n\nexport class EventBridgeChannel {\n channel: string;\n queue: Event[] = [];\n receiver: IEventBridgeReceiver | undefined;\n\n constructor(channel: string) {\n this.channel = channel;\n }\n\n sendEvent(event: Event) {\n if (!this.receiver) {\n this.queue = [...this.queue.slice(0, QUEUE_CAPACITY), event];\n return;\n }\n this.receiver.receive(this.channel, event);\n }\n\n setReceiver(receiver: IEventBridgeReceiver) {\n if (this.receiver) {\n return;\n }\n this.receiver = receiver;\n const events = this.queue;\n this.queue = [];\n events.forEach((event) => {\n (this.receiver as IEventBridgeReceiver).receive(this.channel, event);\n });\n }\n}\n"]}

View File

@@ -0,0 +1,6 @@
import { IEventBridge } from './event-bridge';
export declare class EventBridgeContainer {
static instances: Record<string, IEventBridge>;
static getInstance(instanceName: string): IEventBridge;
}
//# sourceMappingURL=event-bridge-container.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"event-bridge-container.d.ts","sourceRoot":"","sources":["../../../src/event-bridge/event-bridge-container.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE3D,qBAAa,oBAAoB;IAC/B,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAM;IACpD,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,YAAY;CAMvD"}

View File

@@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EventBridgeContainer = void 0;
var event_bridge_1 = require("./event-bridge");
var EventBridgeContainer = /** @class */ (function () {
function EventBridgeContainer() {
}
EventBridgeContainer.getInstance = function (instanceName) {
if (!this.instances[instanceName]) {
this.instances[instanceName] = new event_bridge_1.EventBridge();
}
return this.instances[instanceName];
};
EventBridgeContainer.instances = {};
return EventBridgeContainer;
}());
exports.EventBridgeContainer = EventBridgeContainer;
//# sourceMappingURL=event-bridge-container.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"event-bridge-container.js","sourceRoot":"","sources":["../../../src/event-bridge/event-bridge-container.ts"],"names":[],"mappings":";;;AAAA,+CAA2D;AAE3D;IAAA;IAQA,CAAC;IANQ,gCAAW,GAAlB,UAAmB,YAAoB;QACrC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE;YACjC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,GAAG,IAAI,0BAAW,EAAE,CAAC;SAClD;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IACtC,CAAC;IANM,8BAAS,GAAiC,EAAE,CAAC;IAOtD,2BAAC;CAAA,AARD,IAQC;AARY,oDAAoB","sourcesContent":["import { EventBridge, IEventBridge } from './event-bridge';\n\nexport class EventBridgeContainer {\n static instances: Record<string, IEventBridge> = {};\n static getInstance(instanceName: string): IEventBridge {\n if (!this.instances[instanceName]) {\n this.instances[instanceName] = new EventBridge();\n }\n return this.instances[instanceName];\n }\n}\n"]}

View File

@@ -0,0 +1,15 @@
import { Event } from '../types/event/event';
import { EventBridgeChannel } from './event-bridge-channel';
export interface IEventBridge {
sendEvent(channel: string, event: Event): void;
setReceiver(channel: string, receiver: IEventBridgeReceiver): void;
}
export interface IEventBridgeReceiver {
receive(channel: string, event: Event): void;
}
export declare class EventBridge implements IEventBridge {
eventBridgeChannels: Record<string, EventBridgeChannel | undefined>;
sendEvent(channel: string, event: Event): void;
setReceiver(channel: string, receiver: IEventBridgeReceiver): void;
}
//# sourceMappingURL=event-bridge.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"event-bridge.d.ts","sourceRoot":"","sources":["../../../src/event-bridge/event-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAC/C,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAAC;CACpE;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CAC9C;AAED,qBAAa,WAAY,YAAW,YAAY;IAC9C,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,GAAG,SAAS,CAAC,CAAM;IAEzE,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK;IAOvC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,oBAAoB;CAM5D"}

View File

@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EventBridge = void 0;
var event_bridge_channel_1 = require("./event-bridge-channel");
var EventBridge = /** @class */ (function () {
function EventBridge() {
this.eventBridgeChannels = {};
}
EventBridge.prototype.sendEvent = function (channel, event) {
if (!this.eventBridgeChannels[channel]) {
this.eventBridgeChannels[channel] = new event_bridge_channel_1.EventBridgeChannel(channel);
}
this.eventBridgeChannels[channel].sendEvent(event);
};
EventBridge.prototype.setReceiver = function (channel, receiver) {
if (!this.eventBridgeChannels[channel]) {
this.eventBridgeChannels[channel] = new event_bridge_channel_1.EventBridgeChannel(channel);
}
this.eventBridgeChannels[channel].setReceiver(receiver);
};
return EventBridge;
}());
exports.EventBridge = EventBridge;
//# sourceMappingURL=event-bridge.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"event-bridge.js","sourceRoot":"","sources":["../../../src/event-bridge/event-bridge.ts"],"names":[],"mappings":";;;AACA,+DAA4D;AAW5D;IAAA;QACE,wBAAmB,GAAmD,EAAE,CAAC;IAe3E,CAAC;IAbC,+BAAS,GAAT,UAAU,OAAe,EAAE,KAAY;QACrC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,EAAE;YACtC,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,GAAG,IAAI,yCAAkB,CAAC,OAAO,CAAC,CAAC;SACrE;QACA,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAwB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC7E,CAAC;IAED,iCAAW,GAAX,UAAY,OAAe,EAAE,QAA8B;QACzD,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,EAAE;YACtC,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,GAAG,IAAI,yCAAkB,CAAC,OAAO,CAAC,CAAC;SACrE;QACA,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAwB,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAClF,CAAC;IACH,kBAAC;AAAD,CAAC,AAhBD,IAgBC;AAhBY,kCAAW","sourcesContent":["import { Event } from '../types/event/event';\nimport { EventBridgeChannel } from './event-bridge-channel';\n\nexport interface IEventBridge {\n sendEvent(channel: string, event: Event): void;\n setReceiver(channel: string, receiver: IEventBridgeReceiver): void;\n}\n\nexport interface IEventBridgeReceiver {\n receive(channel: string, event: Event): void;\n}\n\nexport class EventBridge implements IEventBridge {\n eventBridgeChannels: Record<string, EventBridgeChannel | undefined> = {};\n\n sendEvent(channel: string, event: Event) {\n if (!this.eventBridgeChannels[channel]) {\n this.eventBridgeChannels[channel] = new EventBridgeChannel(channel);\n }\n (this.eventBridgeChannels[channel] as EventBridgeChannel).sendEvent(event);\n }\n\n setReceiver(channel: string, receiver: IEventBridgeReceiver) {\n if (!this.eventBridgeChannels[channel]) {\n this.eventBridgeChannels[channel] = new EventBridgeChannel(channel);\n }\n (this.eventBridgeChannels[channel] as EventBridgeChannel).setReceiver(receiver);\n }\n}\n"]}

View File

@@ -0,0 +1,2 @@
export declare const getGlobalScope: () => typeof globalThis | undefined;
//# sourceMappingURL=global-scope.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"global-scope.d.ts","sourceRoot":"","sources":["../../src/global-scope.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,cAAc,QAAO,iBAAiB,GAAG,SAoBrD,CAAC"}

View File

@@ -0,0 +1,28 @@
"use strict";
/* eslint-disable no-restricted-globals */
/* Only file allowed to access to globalThis, window, self */
Object.defineProperty(exports, "__esModule", { value: true });
exports.getGlobalScope = void 0;
var getGlobalScope = function () {
// This should only be used for integrations with Amplitude that are not running in a browser environment
// We need to specify the name of the global variable as a string to prevent it from being minified
var ampIntegrationContextName = 'ampIntegrationContext';
if (typeof globalThis !== 'undefined' && typeof globalThis[ampIntegrationContextName] !== 'undefined') {
return globalThis[ampIntegrationContextName];
}
if (typeof globalThis !== 'undefined') {
return globalThis;
}
if (typeof window !== 'undefined') {
return window;
}
if (typeof self !== 'undefined') {
return self;
}
if (typeof global !== 'undefined') {
return global;
}
return undefined;
};
exports.getGlobalScope = getGlobalScope;
//# sourceMappingURL=global-scope.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"global-scope.js","sourceRoot":"","sources":["../../src/global-scope.ts"],"names":[],"mappings":";AAAA,0CAA0C;AAC1C,6DAA6D;;;AAEtD,IAAM,cAAc,GAAG;IAC5B,yGAAyG;IACzG,qGAAqG;IACrG,IAAM,yBAAyB,GAAG,uBAAkD,CAAC;IACrF,IAAI,OAAO,UAAU,KAAK,WAAW,IAAI,OAAO,UAAU,CAAC,yBAAyB,CAAC,KAAK,WAAW,EAAE;QACrG,OAAO,UAAU,CAAC,yBAAyB,CAAsB,CAAC;KACnE;IACD,IAAI,OAAO,UAAU,KAAK,WAAW,EAAE;QACrC,OAAO,UAAU,CAAC;KACnB;IACD,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACjC,OAAO,MAAM,CAAC;KACf;IACD,IAAI,OAAO,IAAI,KAAK,WAAW,EAAE;QAC/B,OAAO,IAAI,CAAC;KACb;IACD,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACjC,OAAO,MAAM,CAAC;KACf;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AApBW,QAAA,cAAc,kBAoBzB","sourcesContent":["/* eslint-disable no-restricted-globals */\n/* Only file allowed to access to globalThis, window, self */\n\nexport const getGlobalScope = (): typeof globalThis | undefined => {\n // This should only be used for integrations with Amplitude that are not running in a browser environment\n // We need to specify the name of the global variable as a string to prevent it from being minified\n const ampIntegrationContextName = 'ampIntegrationContext' as keyof typeof globalThis;\n if (typeof globalThis !== 'undefined' && typeof globalThis[ampIntegrationContextName] !== 'undefined') {\n return globalThis[ampIntegrationContextName] as typeof globalThis;\n }\n if (typeof globalThis !== 'undefined') {\n return globalThis;\n }\n if (typeof window !== 'undefined') {\n return window;\n }\n if (typeof self !== 'undefined') {\n return self;\n }\n if (typeof global !== 'undefined') {\n return global;\n }\n return undefined;\n};\n"]}

View File

@@ -0,0 +1,70 @@
export interface IIdentify {
getUserProperties(): IdentifyUserProperties;
set(property: string, value: ValidPropertyType): IIdentify;
setOnce(property: string, value: ValidPropertyType): IIdentify;
append(property: string, value: ValidPropertyType): IIdentify;
prepend(property: string, value: ValidPropertyType): IIdentify;
postInsert(property: string, value: ValidPropertyType): IIdentify;
preInsert(property: string, value: ValidPropertyType): IIdentify;
remove(property: string, value: ValidPropertyType): IIdentify;
add(property: string, value: number): IIdentify;
unset(property: string): IIdentify;
clearAll(): IIdentify;
}
export declare class Identify implements IIdentify {
protected readonly _propertySet: Set<string>;
protected _properties: IdentifyUserProperties;
getUserProperties(): IdentifyUserProperties;
set(property: string, value: ValidPropertyType): Identify;
setOnce(property: string, value: ValidPropertyType): Identify;
append(property: string, value: ValidPropertyType): Identify;
prepend(property: string, value: ValidPropertyType): Identify;
postInsert(property: string, value: ValidPropertyType): Identify;
preInsert(property: string, value: ValidPropertyType): Identify;
remove(property: string, value: ValidPropertyType): Identify;
add(property: string, value: number): Identify;
unset(property: string): Identify;
clearAll(): Identify;
private _safeSet;
private _validate;
}
export type ValidPropertyType = number | string | boolean | Array<string | number> | {
[key: string]: ValidPropertyType;
} | Array<{
[key: string]: ValidPropertyType;
}>;
interface BaseOperationConfig {
[key: string]: ValidPropertyType;
}
export interface IdentifyUserProperties {
[IdentifyOperation.ADD]?: {
[key: string]: number;
};
[IdentifyOperation.UNSET]?: BaseOperationConfig;
[IdentifyOperation.CLEAR_ALL]?: any;
[IdentifyOperation.SET]?: BaseOperationConfig;
[IdentifyOperation.SET_ONCE]?: BaseOperationConfig;
[IdentifyOperation.APPEND]?: BaseOperationConfig;
[IdentifyOperation.PREPEND]?: BaseOperationConfig;
[IdentifyOperation.POSTINSERT]?: BaseOperationConfig;
[IdentifyOperation.PREINSERT]?: BaseOperationConfig;
[IdentifyOperation.REMOVE]?: BaseOperationConfig;
}
export declare enum IdentifyOperation {
SET = "$set",
SET_ONCE = "$setOnce",
ADD = "$add",
APPEND = "$append",
PREPEND = "$prepend",
REMOVE = "$remove",
PREINSERT = "$preInsert",
POSTINSERT = "$postInsert",
UNSET = "$unset",
CLEAR_ALL = "$clearAll"
}
/**
* Note that the order of operations should align with https://github.com/amplitude/nova/blob/7701b5986b565d4b2fb53b99a9f2175df055dea8/src/main/java/com/amplitude/ingestion/core/UserPropertyUtils.java#L210
*/
export declare const OrderedIdentifyOperations: IdentifyOperation[];
export {};
//# sourceMappingURL=identify.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"identify.d.ts","sourceRoot":"","sources":["../../src/identify.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,126 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OrderedIdentifyOperations = exports.IdentifyOperation = exports.Identify = void 0;
var tslib_1 = require("tslib");
var constants_1 = require("./types/constants");
var valid_properties_1 = require("./utils/valid-properties");
var Identify = /** @class */ (function () {
function Identify() {
this._propertySet = new Set();
this._properties = {};
}
Identify.prototype.getUserProperties = function () {
return tslib_1.__assign({}, this._properties);
};
Identify.prototype.set = function (property, value) {
this._safeSet(IdentifyOperation.SET, property, value);
return this;
};
Identify.prototype.setOnce = function (property, value) {
this._safeSet(IdentifyOperation.SET_ONCE, property, value);
return this;
};
Identify.prototype.append = function (property, value) {
this._safeSet(IdentifyOperation.APPEND, property, value);
return this;
};
Identify.prototype.prepend = function (property, value) {
this._safeSet(IdentifyOperation.PREPEND, property, value);
return this;
};
Identify.prototype.postInsert = function (property, value) {
this._safeSet(IdentifyOperation.POSTINSERT, property, value);
return this;
};
Identify.prototype.preInsert = function (property, value) {
this._safeSet(IdentifyOperation.PREINSERT, property, value);
return this;
};
Identify.prototype.remove = function (property, value) {
this._safeSet(IdentifyOperation.REMOVE, property, value);
return this;
};
Identify.prototype.add = function (property, value) {
this._safeSet(IdentifyOperation.ADD, property, value);
return this;
};
Identify.prototype.unset = function (property) {
this._safeSet(IdentifyOperation.UNSET, property, constants_1.UNSET_VALUE);
return this;
};
Identify.prototype.clearAll = function () {
// When clear all happens, all properties are unset. Reset the entire object.
this._properties = {};
this._properties[IdentifyOperation.CLEAR_ALL] = constants_1.UNSET_VALUE;
return this;
};
// Returns whether or not this set actually worked.
Identify.prototype._safeSet = function (operation, property, value) {
if (this._validate(operation, property, value)) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
var userPropertyMap = this._properties[operation];
if (userPropertyMap === undefined) {
userPropertyMap = {};
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
this._properties[operation] = userPropertyMap;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
userPropertyMap[property] = value;
this._propertySet.add(property);
return true;
}
return false;
};
Identify.prototype._validate = function (operation, property, value) {
if (this._properties[IdentifyOperation.CLEAR_ALL] !== undefined) {
// clear all already set. Skipping operation;
return false;
}
if (this._propertySet.has(property)) {
// Property already used. Skipping operation
return false;
}
if (operation === IdentifyOperation.ADD) {
return typeof value === 'number';
}
if (operation !== IdentifyOperation.UNSET && operation !== IdentifyOperation.REMOVE) {
return (0, valid_properties_1.isValidProperties)(property, value);
}
return true;
};
return Identify;
}());
exports.Identify = Identify;
var IdentifyOperation;
(function (IdentifyOperation) {
// Base Operations to set values
IdentifyOperation["SET"] = "$set";
IdentifyOperation["SET_ONCE"] = "$setOnce";
// Operations around modifying existing values
IdentifyOperation["ADD"] = "$add";
IdentifyOperation["APPEND"] = "$append";
IdentifyOperation["PREPEND"] = "$prepend";
IdentifyOperation["REMOVE"] = "$remove";
// Operations around appending values *if* they aren't present
IdentifyOperation["PREINSERT"] = "$preInsert";
IdentifyOperation["POSTINSERT"] = "$postInsert";
// Operations around removing properties/values
IdentifyOperation["UNSET"] = "$unset";
IdentifyOperation["CLEAR_ALL"] = "$clearAll";
})(IdentifyOperation = exports.IdentifyOperation || (exports.IdentifyOperation = {}));
/**
* Note that the order of operations should align with https://github.com/amplitude/nova/blob/7701b5986b565d4b2fb53b99a9f2175df055dea8/src/main/java/com/amplitude/ingestion/core/UserPropertyUtils.java#L210
*/
exports.OrderedIdentifyOperations = [
IdentifyOperation.CLEAR_ALL,
IdentifyOperation.UNSET,
IdentifyOperation.SET,
IdentifyOperation.SET_ONCE,
IdentifyOperation.ADD,
IdentifyOperation.APPEND,
IdentifyOperation.PREPEND,
IdentifyOperation.PREINSERT,
IdentifyOperation.POSTINSERT,
IdentifyOperation.REMOVE,
];
//# sourceMappingURL=identify.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,65 @@
export { AmplitudeCore } from './core-client';
export { CoreClient, PluginHost } from './types/client/core-client';
export { AnalyticsClient } from './types/client/analytics-client';
export { AmplitudeContext } from './types/amplitude-context';
export { Identify, IIdentify } from './identify';
export { Revenue, IRevenue, RevenueProperty } from './revenue';
export { Destination } from './plugins/destination';
export { IdentityEventSender } from './plugins/identity';
export { Config, RequestMetadata } from './config';
export { IConfig } from './types/config/core-config';
export { Logger, ILogger, LogConfig } from './logger';
export { getGlobalScope } from './global-scope';
export { getAnalyticsConnector, setConnectorDeviceId, setConnectorUserId } from './analytics-connector';
export { isNewSession } from './session';
export { getCookieName, getOldCookieName } from './cookie-name';
export { getLanguage } from './language';
export { getQueryParams } from './query-params';
export { returnWrapper, AmplitudeReturn } from './utils/return-wrapper';
export { debugWrapper, getClientLogConfig, getClientStates } from './utils/debug';
export { UUID } from './utils/uuid';
export { createIdentifyEvent } from './utils/event-builder';
export { isUrlMatchAllowlist, getDecodeURI } from './utils/url-utils';
export { generateHashCode, isTimestampInSample } from './utils/sampling';
export { MemoryStorage } from './storage/memory';
export { CookieStorage } from './storage/cookie';
export { getStorageKey } from './storage/helpers';
export { BrowserStorage } from './storage/browser-storage';
export { DiagnosticsClient, IDiagnosticsClient } from './diagnostics/diagnostics-client';
export { BaseTransport } from './transports/base';
export { FetchTransport } from './transports/fetch';
export { RemoteConfigClient, IRemoteConfigClient, RemoteConfig, Source } from './remote-config/remote-config';
export { LogLevel } from './types/loglevel';
export { AMPLITUDE_PREFIX, STORAGE_PREFIX } from './types/constants';
export { Storage, IdentityStorageType } from './types/storage';
export { Event, IdentifyOperation, SpecialEventType, IdentifyEvent, GroupIdentifyEvent } from './types/event/event';
export { EventOptions, BaseEvent } from './types/event/base-event';
export { IngestionMetadata } from './types/event/ingestion-metadata';
export { ServerZoneType, ServerZone } from './types/server-zone';
export { OfflineDisabled } from './types/offline';
export { Plan } from './types/event/plan';
export { TransportType, Transport } from './types/transport';
export { Payload } from './types/payload';
export { Response } from './types/response';
export { UserSession } from './types/user-session';
export { Plugin, BeforePlugin, DestinationPlugin, EnrichmentPlugin, PluginType, AnalyticsIdentity, } from './types/plugin';
export { Result } from './types/result';
export { ElementInteractionsOptions, Messenger, ActionType, DEFAULT_CSS_SELECTOR_ALLOWLIST, DEFAULT_DATA_ATTRIBUTE_PREFIX, DEFAULT_ACTION_CLICK_ALLOWLIST, } from './types/element-interactions';
export { FrustrationInteractionsOptions, DEFAULT_DEAD_CLICK_ALLOWLIST, DEFAULT_RAGE_CLICK_ALLOWLIST, DEFAULT_RAGE_CLICK_THRESHOLD, DEFAULT_RAGE_CLICK_WINDOW_MS, DEFAULT_RAGE_CLICK_OUT_OF_BOUNDS_THRESHOLD, DEFAULT_DEAD_CLICK_WINDOW_MS, } from './types/frustration-interactions';
export { PageTrackingOptions, PageTrackingTrackOn, PageTrackingHistoryChanges } from './types/page-view-tracking';
export { Status } from './types/status';
export { NetworkEventCallback, networkObserver } from './network-observer';
export { NetworkRequestEvent, IRequestWrapper, JsonObject, JsonValue, JsonArray } from './network-request-event';
export { NetworkTrackingOptions, NetworkCaptureRule } from './types/network-tracking';
export { SAFE_HEADERS, FORBIDDEN_HEADERS } from './types/constants';
export { PageUrlEnrichmentOptions } from './types/page-url-enrichment';
export { Campaign, UTMParameters, ReferrerParameters, ClickIdParameters, ICampaignParser } from './types/campaign';
export { EMPTY_VALUE, BASE_CAMPAIGN, MKTG } from './types/constants';
export { CampaignParser } from './campaign/campaign-parser';
export { BrowserConfig, BrowserOptions, DefaultTrackingOptions, TrackingOptions, AutocaptureOptions, CookieOptions, AttributionOptions, } from './types/config/browser-config';
export { BrowserClient } from './types/client/browser-client';
export { NodeClient } from './types/client/node-client';
export { NodeConfig, NodeOptions } from './types/config/node-config';
export { ReactNativeConfig, ReactNativeTrackingOptions, ReactNativeOptions, ReactNativeAttributionOptions, } from './types/config/react-native-config';
export { ReactNativeClient } from './types/client/react-native-client';
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,107 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DEFAULT_RAGE_CLICK_WINDOW_MS = exports.DEFAULT_RAGE_CLICK_THRESHOLD = exports.DEFAULT_RAGE_CLICK_ALLOWLIST = exports.DEFAULT_DEAD_CLICK_ALLOWLIST = exports.DEFAULT_ACTION_CLICK_ALLOWLIST = exports.DEFAULT_DATA_ATTRIBUTE_PREFIX = exports.DEFAULT_CSS_SELECTOR_ALLOWLIST = exports.OfflineDisabled = exports.ServerZone = exports.SpecialEventType = exports.IdentifyOperation = exports.STORAGE_PREFIX = exports.AMPLITUDE_PREFIX = exports.LogLevel = exports.RemoteConfigClient = exports.FetchTransport = exports.BaseTransport = exports.DiagnosticsClient = exports.BrowserStorage = exports.getStorageKey = exports.CookieStorage = exports.MemoryStorage = exports.isTimestampInSample = exports.generateHashCode = exports.getDecodeURI = exports.isUrlMatchAllowlist = exports.createIdentifyEvent = exports.UUID = exports.getClientStates = exports.getClientLogConfig = exports.debugWrapper = exports.returnWrapper = exports.getQueryParams = exports.getLanguage = exports.getOldCookieName = exports.getCookieName = exports.isNewSession = exports.setConnectorUserId = exports.setConnectorDeviceId = exports.getAnalyticsConnector = exports.getGlobalScope = exports.Logger = exports.RequestMetadata = exports.Config = exports.IdentityEventSender = exports.Destination = exports.RevenueProperty = exports.Revenue = exports.Identify = exports.AmplitudeCore = void 0;
exports.CampaignParser = exports.MKTG = exports.BASE_CAMPAIGN = exports.EMPTY_VALUE = exports.FORBIDDEN_HEADERS = exports.SAFE_HEADERS = exports.NetworkRequestEvent = exports.networkObserver = exports.NetworkEventCallback = exports.Status = exports.DEFAULT_DEAD_CLICK_WINDOW_MS = exports.DEFAULT_RAGE_CLICK_OUT_OF_BOUNDS_THRESHOLD = void 0;
var core_client_1 = require("./core-client");
Object.defineProperty(exports, "AmplitudeCore", { enumerable: true, get: function () { return core_client_1.AmplitudeCore; } });
var identify_1 = require("./identify");
Object.defineProperty(exports, "Identify", { enumerable: true, get: function () { return identify_1.Identify; } });
var revenue_1 = require("./revenue");
Object.defineProperty(exports, "Revenue", { enumerable: true, get: function () { return revenue_1.Revenue; } });
Object.defineProperty(exports, "RevenueProperty", { enumerable: true, get: function () { return revenue_1.RevenueProperty; } });
var destination_1 = require("./plugins/destination");
Object.defineProperty(exports, "Destination", { enumerable: true, get: function () { return destination_1.Destination; } });
var identity_1 = require("./plugins/identity");
Object.defineProperty(exports, "IdentityEventSender", { enumerable: true, get: function () { return identity_1.IdentityEventSender; } });
var config_1 = require("./config");
Object.defineProperty(exports, "Config", { enumerable: true, get: function () { return config_1.Config; } });
Object.defineProperty(exports, "RequestMetadata", { enumerable: true, get: function () { return config_1.RequestMetadata; } });
var logger_1 = require("./logger");
Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return logger_1.Logger; } });
var global_scope_1 = require("./global-scope");
Object.defineProperty(exports, "getGlobalScope", { enumerable: true, get: function () { return global_scope_1.getGlobalScope; } });
var analytics_connector_1 = require("./analytics-connector");
Object.defineProperty(exports, "getAnalyticsConnector", { enumerable: true, get: function () { return analytics_connector_1.getAnalyticsConnector; } });
Object.defineProperty(exports, "setConnectorDeviceId", { enumerable: true, get: function () { return analytics_connector_1.setConnectorDeviceId; } });
Object.defineProperty(exports, "setConnectorUserId", { enumerable: true, get: function () { return analytics_connector_1.setConnectorUserId; } });
var session_1 = require("./session");
Object.defineProperty(exports, "isNewSession", { enumerable: true, get: function () { return session_1.isNewSession; } });
var cookie_name_1 = require("./cookie-name");
Object.defineProperty(exports, "getCookieName", { enumerable: true, get: function () { return cookie_name_1.getCookieName; } });
Object.defineProperty(exports, "getOldCookieName", { enumerable: true, get: function () { return cookie_name_1.getOldCookieName; } });
var language_1 = require("./language");
Object.defineProperty(exports, "getLanguage", { enumerable: true, get: function () { return language_1.getLanguage; } });
var query_params_1 = require("./query-params");
Object.defineProperty(exports, "getQueryParams", { enumerable: true, get: function () { return query_params_1.getQueryParams; } });
var return_wrapper_1 = require("./utils/return-wrapper");
Object.defineProperty(exports, "returnWrapper", { enumerable: true, get: function () { return return_wrapper_1.returnWrapper; } });
var debug_1 = require("./utils/debug");
Object.defineProperty(exports, "debugWrapper", { enumerable: true, get: function () { return debug_1.debugWrapper; } });
Object.defineProperty(exports, "getClientLogConfig", { enumerable: true, get: function () { return debug_1.getClientLogConfig; } });
Object.defineProperty(exports, "getClientStates", { enumerable: true, get: function () { return debug_1.getClientStates; } });
var uuid_1 = require("./utils/uuid");
Object.defineProperty(exports, "UUID", { enumerable: true, get: function () { return uuid_1.UUID; } });
var event_builder_1 = require("./utils/event-builder");
Object.defineProperty(exports, "createIdentifyEvent", { enumerable: true, get: function () { return event_builder_1.createIdentifyEvent; } });
var url_utils_1 = require("./utils/url-utils");
Object.defineProperty(exports, "isUrlMatchAllowlist", { enumerable: true, get: function () { return url_utils_1.isUrlMatchAllowlist; } });
Object.defineProperty(exports, "getDecodeURI", { enumerable: true, get: function () { return url_utils_1.getDecodeURI; } });
var sampling_1 = require("./utils/sampling");
Object.defineProperty(exports, "generateHashCode", { enumerable: true, get: function () { return sampling_1.generateHashCode; } });
Object.defineProperty(exports, "isTimestampInSample", { enumerable: true, get: function () { return sampling_1.isTimestampInSample; } });
var memory_1 = require("./storage/memory");
Object.defineProperty(exports, "MemoryStorage", { enumerable: true, get: function () { return memory_1.MemoryStorage; } });
var cookie_1 = require("./storage/cookie");
Object.defineProperty(exports, "CookieStorage", { enumerable: true, get: function () { return cookie_1.CookieStorage; } });
var helpers_1 = require("./storage/helpers");
Object.defineProperty(exports, "getStorageKey", { enumerable: true, get: function () { return helpers_1.getStorageKey; } });
var browser_storage_1 = require("./storage/browser-storage");
Object.defineProperty(exports, "BrowserStorage", { enumerable: true, get: function () { return browser_storage_1.BrowserStorage; } });
var diagnostics_client_1 = require("./diagnostics/diagnostics-client");
Object.defineProperty(exports, "DiagnosticsClient", { enumerable: true, get: function () { return diagnostics_client_1.DiagnosticsClient; } });
var base_1 = require("./transports/base");
Object.defineProperty(exports, "BaseTransport", { enumerable: true, get: function () { return base_1.BaseTransport; } });
var fetch_1 = require("./transports/fetch");
Object.defineProperty(exports, "FetchTransport", { enumerable: true, get: function () { return fetch_1.FetchTransport; } });
var remote_config_1 = require("./remote-config/remote-config");
Object.defineProperty(exports, "RemoteConfigClient", { enumerable: true, get: function () { return remote_config_1.RemoteConfigClient; } });
var loglevel_1 = require("./types/loglevel");
Object.defineProperty(exports, "LogLevel", { enumerable: true, get: function () { return loglevel_1.LogLevel; } });
var constants_1 = require("./types/constants");
Object.defineProperty(exports, "AMPLITUDE_PREFIX", { enumerable: true, get: function () { return constants_1.AMPLITUDE_PREFIX; } });
Object.defineProperty(exports, "STORAGE_PREFIX", { enumerable: true, get: function () { return constants_1.STORAGE_PREFIX; } });
var event_1 = require("./types/event/event");
Object.defineProperty(exports, "IdentifyOperation", { enumerable: true, get: function () { return event_1.IdentifyOperation; } });
Object.defineProperty(exports, "SpecialEventType", { enumerable: true, get: function () { return event_1.SpecialEventType; } });
var server_zone_1 = require("./types/server-zone");
Object.defineProperty(exports, "ServerZone", { enumerable: true, get: function () { return server_zone_1.ServerZone; } });
var offline_1 = require("./types/offline");
Object.defineProperty(exports, "OfflineDisabled", { enumerable: true, get: function () { return offline_1.OfflineDisabled; } });
var element_interactions_1 = require("./types/element-interactions");
Object.defineProperty(exports, "DEFAULT_CSS_SELECTOR_ALLOWLIST", { enumerable: true, get: function () { return element_interactions_1.DEFAULT_CSS_SELECTOR_ALLOWLIST; } });
Object.defineProperty(exports, "DEFAULT_DATA_ATTRIBUTE_PREFIX", { enumerable: true, get: function () { return element_interactions_1.DEFAULT_DATA_ATTRIBUTE_PREFIX; } });
Object.defineProperty(exports, "DEFAULT_ACTION_CLICK_ALLOWLIST", { enumerable: true, get: function () { return element_interactions_1.DEFAULT_ACTION_CLICK_ALLOWLIST; } });
var frustration_interactions_1 = require("./types/frustration-interactions");
Object.defineProperty(exports, "DEFAULT_DEAD_CLICK_ALLOWLIST", { enumerable: true, get: function () { return frustration_interactions_1.DEFAULT_DEAD_CLICK_ALLOWLIST; } });
Object.defineProperty(exports, "DEFAULT_RAGE_CLICK_ALLOWLIST", { enumerable: true, get: function () { return frustration_interactions_1.DEFAULT_RAGE_CLICK_ALLOWLIST; } });
Object.defineProperty(exports, "DEFAULT_RAGE_CLICK_THRESHOLD", { enumerable: true, get: function () { return frustration_interactions_1.DEFAULT_RAGE_CLICK_THRESHOLD; } });
Object.defineProperty(exports, "DEFAULT_RAGE_CLICK_WINDOW_MS", { enumerable: true, get: function () { return frustration_interactions_1.DEFAULT_RAGE_CLICK_WINDOW_MS; } });
Object.defineProperty(exports, "DEFAULT_RAGE_CLICK_OUT_OF_BOUNDS_THRESHOLD", { enumerable: true, get: function () { return frustration_interactions_1.DEFAULT_RAGE_CLICK_OUT_OF_BOUNDS_THRESHOLD; } });
Object.defineProperty(exports, "DEFAULT_DEAD_CLICK_WINDOW_MS", { enumerable: true, get: function () { return frustration_interactions_1.DEFAULT_DEAD_CLICK_WINDOW_MS; } });
var status_1 = require("./types/status");
Object.defineProperty(exports, "Status", { enumerable: true, get: function () { return status_1.Status; } });
var network_observer_1 = require("./network-observer");
Object.defineProperty(exports, "NetworkEventCallback", { enumerable: true, get: function () { return network_observer_1.NetworkEventCallback; } });
Object.defineProperty(exports, "networkObserver", { enumerable: true, get: function () { return network_observer_1.networkObserver; } });
var network_request_event_1 = require("./network-request-event");
Object.defineProperty(exports, "NetworkRequestEvent", { enumerable: true, get: function () { return network_request_event_1.NetworkRequestEvent; } });
var constants_2 = require("./types/constants");
Object.defineProperty(exports, "SAFE_HEADERS", { enumerable: true, get: function () { return constants_2.SAFE_HEADERS; } });
Object.defineProperty(exports, "FORBIDDEN_HEADERS", { enumerable: true, get: function () { return constants_2.FORBIDDEN_HEADERS; } });
var constants_3 = require("./types/constants");
Object.defineProperty(exports, "EMPTY_VALUE", { enumerable: true, get: function () { return constants_3.EMPTY_VALUE; } });
Object.defineProperty(exports, "BASE_CAMPAIGN", { enumerable: true, get: function () { return constants_3.BASE_CAMPAIGN; } });
Object.defineProperty(exports, "MKTG", { enumerable: true, get: function () { return constants_3.MKTG; } });
var campaign_parser_1 = require("./campaign/campaign-parser");
Object.defineProperty(exports, "CampaignParser", { enumerable: true, get: function () { return campaign_parser_1.CampaignParser; } });
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,2 @@
export declare const getLanguage: () => string;
//# sourceMappingURL=language.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"language.d.ts","sourceRoot":"","sources":["../../src/language.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,QAAO,MAM9B,CAAC"}

View File

@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getLanguage = void 0;
var getLanguage = function () {
var _a, _b, _c, _d;
if (typeof navigator === 'undefined')
return '';
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
var userLanguage = navigator.userLanguage;
return (_d = (_c = (_b = (_a = navigator.languages) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : navigator.language) !== null && _c !== void 0 ? _c : userLanguage) !== null && _d !== void 0 ? _d : '';
};
exports.getLanguage = getLanguage;
//# sourceMappingURL=language.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"language.js","sourceRoot":"","sources":["../../src/language.ts"],"names":[],"mappings":";;;AAAO,IAAM,WAAW,GAAG;;IACzB,IAAI,OAAO,SAAS,KAAK,WAAW;QAAE,OAAO,EAAE,CAAC;IAChD,sEAAsE;IACtE,IAAM,YAAY,GAAI,SAAiB,CAAC,YAAkC,CAAC;IAE3E,OAAO,MAAA,MAAA,MAAA,MAAA,SAAS,CAAC,SAAS,0CAAG,CAAC,CAAC,mCAAI,SAAS,CAAC,QAAQ,mCAAI,YAAY,mCAAI,EAAE,CAAC;AAC9E,CAAC,CAAC;AANW,QAAA,WAAW,eAMtB","sourcesContent":["export const getLanguage = (): string => {\n if (typeof navigator === 'undefined') return '';\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const userLanguage = (navigator as any).userLanguage as string | undefined;\n\n return navigator.languages?.[0] ?? navigator.language ?? userLanguage ?? '';\n};\n"]}

View File

@@ -0,0 +1,38 @@
import { LogLevel } from './types/loglevel';
export interface ILogger {
disable(): void;
enable(logLevel: LogLevel): void;
log(...args: any[]): void;
warn(...args: any[]): void;
error(...args: any[]): void;
debug(...args: any[]): void;
}
export interface LogConfig {
logger: ILogger;
logLevel: LogLevel;
}
type TimeKey = 'start' | 'end';
export interface DebugContext {
type: string;
name: string;
args: string[] | string;
stacktrace?: string[] | string;
time?: {
[key in TimeKey]?: string;
};
states?: {
[key: string]: any;
};
}
export declare class Logger implements ILogger {
logLevel: LogLevel;
constructor();
disable(): void;
enable(logLevel?: LogLevel): void;
log(...args: any[]): void;
warn(...args: any[]): void;
error(...args: any[]): void;
debug(...args: any[]): void;
}
export {};
//# sourceMappingURL=logger.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAI5C,MAAM,WAAW,OAAO;IACtB,OAAO,IAAI,IAAI,CAAC;IAChB,MAAM,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IACjC,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC1B,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC3B,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,KAAK,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;AAE/B,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAC/B,IAAI,CAAC,EAAE;SAAG,GAAG,IAAI,OAAO,CAAC,CAAC,EAAE,MAAM;KAAE,CAAC;IACrC,MAAM,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;CACjC;AAED,qBAAa,MAAO,YAAW,OAAO;IACpC,QAAQ,EAAE,QAAQ,CAAC;;IAMnB,OAAO,IAAI,IAAI;IAIf,MAAM,CAAC,QAAQ,GAAE,QAAwB,GAAG,IAAI;IAIhD,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAOzB,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAO1B,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAO3B,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;CAO5B"}

View File

@@ -0,0 +1,61 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Logger = void 0;
var loglevel_1 = require("./types/loglevel");
var PREFIX = 'Amplitude Logger ';
var Logger = /** @class */ (function () {
function Logger() {
this.logLevel = loglevel_1.LogLevel.None;
}
Logger.prototype.disable = function () {
this.logLevel = loglevel_1.LogLevel.None;
};
Logger.prototype.enable = function (logLevel) {
if (logLevel === void 0) { logLevel = loglevel_1.LogLevel.Warn; }
this.logLevel = logLevel;
};
Logger.prototype.log = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (this.logLevel < loglevel_1.LogLevel.Verbose) {
return;
}
console.log("".concat(PREFIX, "[Log]: ").concat(args.join(' ')));
};
Logger.prototype.warn = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (this.logLevel < loglevel_1.LogLevel.Warn) {
return;
}
console.warn("".concat(PREFIX, "[Warn]: ").concat(args.join(' ')));
};
Logger.prototype.error = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (this.logLevel < loglevel_1.LogLevel.Error) {
return;
}
console.error("".concat(PREFIX, "[Error]: ").concat(args.join(' ')));
};
Logger.prototype.debug = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (this.logLevel < loglevel_1.LogLevel.Debug) {
return;
}
// console.debug output is hidden by default in chrome
console.log("".concat(PREFIX, "[Debug]: ").concat(args.join(' ')));
};
return Logger;
}());
exports.Logger = Logger;
//# sourceMappingURL=logger.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":";;;AAAA,6CAA4C;AAE5C,IAAM,MAAM,GAAG,mBAAmB,CAAC;AA2BnC;IAGE;QACE,IAAI,CAAC,QAAQ,GAAG,mBAAQ,CAAC,IAAI,CAAC;IAChC,CAAC;IAED,wBAAO,GAAP;QACE,IAAI,CAAC,QAAQ,GAAG,mBAAQ,CAAC,IAAI,CAAC;IAChC,CAAC;IAED,uBAAM,GAAN,UAAO,QAAkC;QAAlC,yBAAA,EAAA,WAAqB,mBAAQ,CAAC,IAAI;QACvC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,oBAAG,GAAH;QAAI,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,yBAAc;;QAChB,IAAI,IAAI,CAAC,QAAQ,GAAG,mBAAQ,CAAC,OAAO,EAAE;YACpC,OAAO;SACR;QACD,OAAO,CAAC,GAAG,CAAC,UAAG,MAAM,oBAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC;IACnD,CAAC;IAED,qBAAI,GAAJ;QAAK,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,yBAAc;;QACjB,IAAI,IAAI,CAAC,QAAQ,GAAG,mBAAQ,CAAC,IAAI,EAAE;YACjC,OAAO;SACR;QACD,OAAO,CAAC,IAAI,CAAC,UAAG,MAAM,qBAAW,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC;IACrD,CAAC;IAED,sBAAK,GAAL;QAAM,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,yBAAc;;QAClB,IAAI,IAAI,CAAC,QAAQ,GAAG,mBAAQ,CAAC,KAAK,EAAE;YAClC,OAAO;SACR;QACD,OAAO,CAAC,KAAK,CAAC,UAAG,MAAM,sBAAY,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC;IACvD,CAAC;IAED,sBAAK,GAAL;QAAM,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,yBAAc;;QAClB,IAAI,IAAI,CAAC,QAAQ,GAAG,mBAAQ,CAAC,KAAK,EAAE;YAClC,OAAO;SACR;QACD,sDAAsD;QACtD,OAAO,CAAC,GAAG,CAAC,UAAG,MAAM,sBAAY,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC;IACrD,CAAC;IACH,aAAC;AAAD,CAAC,AA3CD,IA2CC;AA3CY,wBAAM","sourcesContent":["import { LogLevel } from './types/loglevel';\n\nconst PREFIX = 'Amplitude Logger ';\n\nexport interface ILogger {\n disable(): void;\n enable(logLevel: LogLevel): void;\n log(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n debug(...args: any[]): void;\n}\n\nexport interface LogConfig {\n logger: ILogger;\n logLevel: LogLevel;\n}\n\ntype TimeKey = 'start' | 'end';\n\nexport interface DebugContext {\n type: string;\n name: string;\n args: string[] | string;\n stacktrace?: string[] | string;\n time?: { [key in TimeKey]?: string };\n states?: { [key: string]: any };\n}\n\nexport class Logger implements ILogger {\n logLevel: LogLevel;\n\n constructor() {\n this.logLevel = LogLevel.None;\n }\n\n disable(): void {\n this.logLevel = LogLevel.None;\n }\n\n enable(logLevel: LogLevel = LogLevel.Warn): void {\n this.logLevel = logLevel;\n }\n\n log(...args: any[]): void {\n if (this.logLevel < LogLevel.Verbose) {\n return;\n }\n console.log(`${PREFIX}[Log]: ${args.join(' ')}`);\n }\n\n warn(...args: any[]): void {\n if (this.logLevel < LogLevel.Warn) {\n return;\n }\n console.warn(`${PREFIX}[Warn]: ${args.join(' ')}`);\n }\n\n error(...args: any[]): void {\n if (this.logLevel < LogLevel.Error) {\n return;\n }\n console.error(`${PREFIX}[Error]: ${args.join(' ')}`);\n }\n\n debug(...args: any[]): void {\n if (this.logLevel < LogLevel.Debug) {\n return;\n }\n // console.debug output is hidden by default in chrome\n console.log(`${PREFIX}[Debug]: ${args.join(' ')}`);\n }\n}\n"]}

View File

@@ -0,0 +1,41 @@
import { ILogger } from './logger';
import { IRequestWrapper, NetworkRequestEvent, IResponseWrapper } from './network-request-event';
export type NetworkEventCallbackFn = (event: NetworkRequestEvent) => void;
export declare class NetworkEventCallback {
readonly callback: (event: NetworkRequestEvent) => void;
readonly id: string;
constructor(callback: (event: NetworkRequestEvent) => void, id?: string);
}
type RequestUrlAndMethod = {
url: string | URL | undefined;
method: string | undefined;
};
export declare class NetworkObserver {
private eventCallbacks;
private globalScope?;
private logger?;
private isObserving;
constructor(logger?: ILogger);
static isSupported(): boolean;
subscribe(eventCallback: NetworkEventCallback, logger?: ILogger): void;
unsubscribe(eventCallback: NetworkEventCallback): void;
protected triggerEventCallbacks(event: NetworkRequestEvent): void;
handleNetworkRequestEvent(requestType: 'fetch' | 'xhr', requestInfo: RequestInfo | URL | RequestUrlAndMethod | undefined, requestWrapper: IRequestWrapper | undefined, responseWrapper: IResponseWrapper | undefined, typedError: Error | undefined, startTime?: number, durationStart?: number): void;
private getTimestamps;
private observeFetch;
/**
* Creates a function that parses the response of an XMLHttpRequest as JSON.
*
* Returns function instead of JSON object to avoid unnecessary parsing if the
* body is not being captured.
*
* @param xhrSafe - The XMLHttpRequest object.
* @param context - The NetworkObserver instance.
* @returns A function that parses the response of an XMLHttpRequest as JSON.
*/
static createXhrJsonParser(xhrUnsafe: XMLHttpRequest, context: NetworkObserver): () => any;
private observeXhr;
}
export declare const networkObserver: NetworkObserver;
export {};
//# sourceMappingURL=network-observer.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"network-observer.d.ts","sourceRoot":"","sources":["../../src/network-observer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EACL,eAAe,EACf,mBAAmB,EAKnB,gBAAgB,EAGjB,MAAM,yBAAyB,CAAC;AAoBjC,MAAM,MAAM,sBAAsB,GAAG,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;AAE1E,qBAAa,oBAAoB;aACH,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI;aAAkB,EAAE,EAAE,MAAM;gBAA1E,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,EAAkB,EAAE,GAAE,MAAe;CAChH;AAED,KAAK,mBAAmB,GAAG;IACzB,GAAG,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,CAAC;IAC9B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B,CAAC;AAgBF,qBAAa,eAAe;IAC1B,OAAO,CAAC,cAAc,CAAgD;IAEtE,OAAO,CAAC,WAAW,CAAC,CAAoB;IACxC,OAAO,CAAC,MAAM,CAAC,CAAU;IACzB,OAAO,CAAC,WAAW,CAAS;gBAChB,MAAM,CAAC,EAAE,OAAO;IAU5B,MAAM,CAAC,WAAW,IAAI,OAAO;IAK7B,SAAS,CAAC,aAAa,EAAE,oBAAoB,EAAE,MAAM,CAAC,EAAE,OAAO;IA+B/D,WAAW,CAAC,aAAa,EAAE,oBAAoB;IAI/C,SAAS,CAAC,qBAAqB,CAAC,KAAK,EAAE,mBAAmB;IAa1D,yBAAyB,CACvB,WAAW,EAAE,OAAO,GAAG,KAAK,EAC5B,WAAW,EAAE,WAAW,GAAG,GAAG,GAAG,mBAAmB,GAAG,SAAS,EAChE,cAAc,EAAE,eAAe,GAAG,SAAS,EAC3C,eAAe,EAAE,gBAAgB,GAAG,SAAS,EAC7C,UAAU,EAAE,KAAK,GAAG,SAAS,EAC7B,SAAS,CAAC,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,MAAM;IA+DxB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,YAAY;IA8DpB;;;;;;;;;OASG;IACH,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,eAAe;IA8B9E,OAAO,CAAC,UAAU;CAqHnB;AAGD,eAAO,MAAM,eAAe,iBAAwB,CAAC"}

View File

@@ -0,0 +1,345 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.networkObserver = exports.NetworkObserver = exports.NetworkEventCallback = void 0;
var tslib_1 = require("tslib");
var _1 = require("./");
var uuid_1 = require("./utils/uuid");
var network_request_event_1 = require("./network-request-event");
/**
* Typeguard function checks if an input is a Request object.
*/
function isRequest(requestInfo) {
return typeof requestInfo === 'object' && requestInfo !== null && 'url' in requestInfo && 'method' in requestInfo;
}
var NetworkEventCallback = /** @class */ (function () {
function NetworkEventCallback(callback, id) {
if (id === void 0) { id = (0, uuid_1.UUID)(); }
this.callback = callback;
this.id = id;
}
return NetworkEventCallback;
}());
exports.NetworkEventCallback = NetworkEventCallback;
var NetworkObserver = /** @class */ (function () {
function NetworkObserver(logger) {
this.eventCallbacks = new Map();
this.isObserving = false;
this.logger = logger;
var globalScope = (0, _1.getGlobalScope)();
if (!NetworkObserver.isSupported()) {
/* istanbul ignore next */
return;
}
this.globalScope = globalScope;
}
NetworkObserver.isSupported = function () {
var globalScope = (0, _1.getGlobalScope)();
return !!globalScope && !!globalScope.fetch;
};
NetworkObserver.prototype.subscribe = function (eventCallback, logger) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
if (!this.logger) {
this.logger = logger;
}
this.eventCallbacks.set(eventCallback.id, eventCallback);
if (!this.isObserving) {
/* istanbul ignore next */
// eslint-disable-next-line @typescript-eslint/unbound-method
var originalXhrOpen = (_c = (_b = (_a = this.globalScope) === null || _a === void 0 ? void 0 : _a.XMLHttpRequest) === null || _b === void 0 ? void 0 : _b.prototype) === null || _c === void 0 ? void 0 : _c.open;
/* istanbul ignore next */
// eslint-disable-next-line @typescript-eslint/unbound-method
var originalXhrSend = (_f = (_e = (_d = this.globalScope) === null || _d === void 0 ? void 0 : _d.XMLHttpRequest) === null || _e === void 0 ? void 0 : _e.prototype) === null || _f === void 0 ? void 0 : _f.send;
/* istanbul ignore next */
// eslint-disable-next-line @typescript-eslint/unbound-method
var originalXhrSetRequestHeader = (_j = (_h = (_g = this.globalScope) === null || _g === void 0 ? void 0 : _g.XMLHttpRequest) === null || _h === void 0 ? void 0 : _h.prototype) === null || _j === void 0 ? void 0 : _j.setRequestHeader;
if (originalXhrOpen && originalXhrSend && originalXhrSetRequestHeader) {
this.observeXhr(originalXhrOpen, originalXhrSend, originalXhrSetRequestHeader);
}
/* istanbul ignore next */
var originalFetch = (_k = this.globalScope) === null || _k === void 0 ? void 0 : _k.fetch;
/* istanbul ignore next */
if (originalFetch) {
this.observeFetch(originalFetch);
}
/* istanbul ignore next */
this.isObserving = true;
}
};
NetworkObserver.prototype.unsubscribe = function (eventCallback) {
this.eventCallbacks.delete(eventCallback.id);
};
NetworkObserver.prototype.triggerEventCallbacks = function (event) {
var _this = this;
this.eventCallbacks.forEach(function (callback) {
var _a;
try {
callback.callback(event);
}
catch (err) {
// if the callback throws an error, we should catch it
// to avoid breaking the fetch promise chain
/* istanbul ignore next */
(_a = _this.logger) === null || _a === void 0 ? void 0 : _a.debug('an unexpected error occurred while triggering event callbacks', err);
}
});
};
NetworkObserver.prototype.handleNetworkRequestEvent = function (requestType, requestInfo, requestWrapper, responseWrapper, typedError, startTime, durationStart) {
var _a;
/* istanbul ignore next */
if (startTime === undefined || durationStart === undefined) {
// if we reach this point, it means that the performance API is not supported
// so we can't construct a NetworkRequestEvent
return;
}
// parse the URL and Method
var url;
var method = 'GET';
if (isRequest(requestInfo)) {
url = requestInfo['url'];
method = requestInfo['method'];
}
else {
url = (_a = requestInfo === null || requestInfo === void 0 ? void 0 : requestInfo.toString) === null || _a === void 0 ? void 0 : _a.call(requestInfo);
}
// strip basic auth from the URL
if (url) {
try {
var parsedUrl = new URL(url);
// reconstruct the URL without the basic auth
url = "".concat(parsedUrl.protocol, "//").concat(parsedUrl.host).concat(parsedUrl.pathname).concat(parsedUrl.search).concat(parsedUrl.hash);
// eslint-disable-next-line no-empty
}
catch (err) { }
}
method = (requestWrapper === null || requestWrapper === void 0 ? void 0 : requestWrapper.method) || method;
var status, error;
if (responseWrapper) {
status = responseWrapper.status;
}
if (typedError) {
error = {
name: typedError.name || 'UnknownError',
message: typedError.message || 'An unknown error occurred',
};
status = 0;
}
var duration = Math.floor(performance.now() - durationStart);
var endTime = Math.floor(startTime + duration);
var requestEvent = new network_request_event_1.NetworkRequestEvent(requestType, method, startTime, // timestamp and startTime are aliases
startTime, url, requestWrapper, status, duration, responseWrapper, error, endTime);
this.triggerEventCallbacks(requestEvent);
};
NetworkObserver.prototype.getTimestamps = function () {
var _a, _b;
/* istanbul ignore next */
return {
startTime: (_a = Date.now) === null || _a === void 0 ? void 0 : _a.call(Date),
durationStart: (_b = performance === null || performance === void 0 ? void 0 : performance.now) === null || _b === void 0 ? void 0 : _b.call(performance),
};
};
NetworkObserver.prototype.observeFetch = function (originalFetch) {
var _this = this;
/* istanbul ignore next */
if (!this.globalScope || !originalFetch) {
return;
}
/**
* IMPORTANT: This overrides window.fetch in browsers.
* You probably never need to make changes to this function.
* If you do, please be careful to preserve the original functionality of fetch
* and make sure another developer who is an expert reviews this change throughly
*/
this.globalScope.fetch = function (requestInfo, requestInit) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var timestamps, originalResponse, originalError, err_1;
var _a, _b;
return tslib_1.__generator(this, function (_c) {
switch (_c.label) {
case 0:
try {
timestamps = this.getTimestamps();
}
catch (error) {
/* istanbul ignore next */
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.debug('an unexpected error occurred while retrieving timestamps', error);
}
_c.label = 1;
case 1:
_c.trys.push([1, 3, , 4]);
return [4 /*yield*/, originalFetch(requestInfo, requestInit)];
case 2:
originalResponse = _c.sent();
return [3 /*break*/, 4];
case 3:
err_1 = _c.sent();
// Capture error information
originalError = err_1;
return [3 /*break*/, 4];
case 4:
// 3. call the handler after the fetch call is done
try {
this.handleNetworkRequestEvent('fetch', requestInfo, requestInit ? new network_request_event_1.RequestWrapperFetch(requestInit) : undefined, originalResponse ? new network_request_event_1.ResponseWrapperFetch(originalResponse) : undefined, originalError,
/* istanbul ignore next */
timestamps === null || timestamps === void 0 ? void 0 : timestamps.startTime,
/* istanbul ignore next */
timestamps === null || timestamps === void 0 ? void 0 : timestamps.durationStart);
}
catch (err) {
// this catch shouldn't be reachable, but keep it here for safety
// because we're overriding the fetch function and better to be safe than sorry
/* istanbul ignore next */
(_b = this.logger) === null || _b === void 0 ? void 0 : _b.debug('an unexpected error occurred while handling fetch', err);
}
// 4. return the original response or throw the original error
if (originalResponse) {
// if the response is not undefined, return it
return [2 /*return*/, originalResponse];
}
else {
throw originalError;
}
return [2 /*return*/];
}
});
}); };
};
/**
* Creates a function that parses the response of an XMLHttpRequest as JSON.
*
* Returns function instead of JSON object to avoid unnecessary parsing if the
* body is not being captured.
*
* @param xhrSafe - The XMLHttpRequest object.
* @param context - The NetworkObserver instance.
* @returns A function that parses the response of an XMLHttpRequest as JSON.
*/
NetworkObserver.createXhrJsonParser = function (xhrUnsafe, context) {
return function () {
var _a, _b;
try {
if (xhrUnsafe.responseType === 'json') {
// if response is a JS object, clone it so that subscribers can't mutate it
if ((_a = context.globalScope) === null || _a === void 0 ? void 0 : _a.structuredClone) {
/* eslint-disable-next-line @typescript-eslint/no-unsafe-return */
return context.globalScope.structuredClone(xhrUnsafe.response);
}
}
else if (['text', ''].includes(xhrUnsafe.responseType)) {
// if response is a string, parse it as JSON
/* eslint-disable-next-line @typescript-eslint/no-unsafe-return */
return JSON.parse(xhrUnsafe.responseText);
}
}
catch (err) {
/* istanbul ignore if */
if (err instanceof Error && err.name === 'InvalidStateError') {
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseText#exceptions
// if we reach here, it means we don't handle responseType correctly
(_b = context.logger) === null || _b === void 0 ? void 0 : _b.error("unexpected error when retrieving responseText. responseType='".concat(xhrUnsafe.responseType, "'"));
}
// the other possible error is Json Parse error which we fail silently
return null;
}
return null;
};
};
NetworkObserver.prototype.observeXhr = function (originalXhrOpen, originalXhrSend, originalXhrSetRequestHeader) {
/* istanbul ignore next */
if (!this.globalScope || !originalXhrOpen || !originalXhrSend) {
return;
}
var xhrProto = this.globalScope.XMLHttpRequest.prototype;
var networkObserverContext = this;
/**
* IMPORTANT: This overrides window.XMLHttpRequest.prototype.open
* You probably never need to make changes to this function.
* If you do, please be careful to preserve the original functionality of xhr.open
* and make sure another developer who is an expert reviews this change throughly
*/
xhrProto.open = function () {
var _a, _b;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var xhrSafe = this;
var _c = tslib_1.__read(args, 2), method = _c[0], url = _c[1];
try {
/* istanbul ignore next */
xhrSafe.$$AmplitudeAnalyticsEvent = tslib_1.__assign({ method: method, url: (_a = url === null || url === void 0 ? void 0 : url.toString) === null || _a === void 0 ? void 0 : _a.call(url), headers: {} }, networkObserverContext.getTimestamps());
}
catch (err) {
/* istanbul ignore next */
(_b = networkObserverContext.logger) === null || _b === void 0 ? void 0 : _b.error('an unexpected error occurred while calling xhr open', err);
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
return originalXhrOpen.apply(xhrSafe, args);
};
/**
* IMPORTANT: This overrides window.XMLHttpRequest.prototype.send
* You probably never need to make changes to this function.
* If you do, please be careful to preserve the original functionality of xhr.send
* and make sure another developer who is an expert reviews this change throughly
*/
// allow "any" type for args to reflect how it's used in the browser
/* eslint-disable-next-line @typescript-eslint/no-unsafe-argument */
xhrProto.send = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
// eslint-disable-next-line @typescript-eslint/no-this-alias
var xhrUnsafe = this;
var xhrSafe = xhrUnsafe;
var getJson = NetworkObserver.createXhrJsonParser(xhrUnsafe, networkObserverContext);
var body = args[0];
var requestEvent = xhrSafe.$$AmplitudeAnalyticsEvent;
xhrSafe.addEventListener('loadend', function () {
var _a;
try {
var responseHeaders = xhrSafe.getAllResponseHeaders();
var responseBodySize = xhrSafe.getResponseHeader('content-length');
var responseWrapper = new network_request_event_1.ResponseWrapperXhr(xhrSafe.status, responseHeaders,
/* istanbul ignore next */
responseBodySize ? parseInt(responseBodySize, 10) : undefined, getJson);
var requestHeaders = xhrSafe.$$AmplitudeAnalyticsEvent.headers;
var requestWrapper = new network_request_event_1.RequestWrapperXhr(body, requestHeaders);
requestEvent.status = xhrSafe.status;
networkObserverContext.handleNetworkRequestEvent('xhr', { url: requestEvent.url, method: requestEvent.method }, requestWrapper, responseWrapper, undefined, requestEvent.startTime, requestEvent.durationStart);
}
catch (err) {
/* istanbul ignore next */
(_a = networkObserverContext.logger) === null || _a === void 0 ? void 0 : _a.error('an unexpected error occurred while handling xhr send', err);
}
});
/* eslint-disable-next-line @typescript-eslint/no-unsafe-argument */
return originalXhrSend.apply(xhrSafe, args);
};
/**
* IMPORTANT: This overrides window.XMLHttpRequest.prototype.setRequestHeader
* You probably never need to make changes to this function.
* If you do, please be careful to preserve the original functionality of xhr.setRequestHeader
* and make sure another developer who is an expert reviews this change throughly
*/
// allow "any" type for args to reflect how it's used in the browser
/* eslint-disable-next-line @typescript-eslint/no-unsafe-argument */
xhrProto.setRequestHeader = function (headerName, headerValue) {
var _a;
var xhrSafe = this;
try {
/* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment */
xhrSafe.$$AmplitudeAnalyticsEvent.headers[headerName] = headerValue;
}
catch (err) {
/* istanbul ignore next */
(_a = networkObserverContext.logger) === null || _a === void 0 ? void 0 : _a.error('an unexpected error occurred while calling xhr setRequestHeader', err);
}
/* eslint-disable-next-line @typescript-eslint/no-unsafe-argument */
originalXhrSetRequestHeader.apply(xhrSafe, [headerName, headerValue]);
};
};
return NetworkObserver;
}());
exports.NetworkObserver = NetworkObserver;
// singleton instance of NetworkObserver
exports.networkObserver = new NetworkObserver();
//# sourceMappingURL=network-observer.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,192 @@
type BlobSafe = {
size: number;
};
type ArrayBufferSafe = {
byteLength: number;
};
type ArrayBufferViewSafe = {
byteLength: number;
};
type URLSearchParamsSafe = {
toString(): string;
};
type FormDataEntryValueSafe = string | BlobSafe | null;
type BodyInitSafe = string | Blob | ArrayBufferSafe | FormDataSafe | URLSearchParamsSafe | ArrayBufferViewSafe | null | undefined;
type HeadersRequestSafe = {
entries(): IterableIterator<[string, string]>;
forEach(callbackfn: (value: string, key: string) => void): void;
};
type HeadersResponseSafe = {
get(name: string): string | null;
forEach(callbackfn: (value: string, key: string) => void): void;
};
type HeadersInitSafe = HeadersRequestSafe | Record<string, string> | string[][];
type ResponseSafe = {
status: number;
headers: HeadersResponseSafe | undefined;
clone(): ResponseCloneSafe;
};
type ResponseCloneSafe = {
text(): Promise<string>;
};
export type RequestInitSafe = {
method?: string;
headers?: HeadersInitSafe;
body?: BodyInitSafe;
};
export interface FormDataSafe {
entries(): IterableIterator<[string, FormDataEntryValueSafe]>;
}
export type XMLHttpRequestBodyInitSafe = BlobSafe | FormDataSafe | URLSearchParamsSafe | string;
export type FetchRequestBody = string | BlobSafe | ArrayBufferSafe | FormDataSafe | URLSearchParamsSafe | ArrayBufferViewSafe | null | undefined;
export interface IRequestWrapper {
/**
* Get the headers of the request.
* @param allow - The headers to allow.
* @returns The pruned headers
*/
headers(allow?: string[]): Record<string, string> | undefined;
bodySize?: number;
method?: string;
body?: FetchRequestBody | XMLHttpRequestBodyInitSafe | null;
json: (allow?: string[], exclude?: string[]) => Promise<JsonObject | null>;
}
export declare const MAXIMUM_ENTRIES = 100;
/**
* This class encapsulates the RequestInit (https://developer.mozilla.org/en-US/docs/Web/API/RequestInit)
* object so that the consumer can only get access to the headers, method and body size.
*
* This is to prevent consumers from directly accessing the Request object
* and mutating it or running costly operations on it.
*
* IMPORTANT:
* * Do not make changes to this class without careful consideration
* of performance implications, memory usage and potential to mutate the customer's
* request.
* * NEVER .clone() the RequestInit object. This will 2x's the memory overhead of the request
* * NEVER: call .arrayBuffer(), text(), json() or any other method on the body that
* consumes the body's stream. This will cause the response to be consumed
* meaning the body will be empty when the customer tries to access it.
* (ie: if the body is an instanceof https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream
* never call any of the methods on it)
*/
export declare class RequestWrapperFetch implements IRequestWrapper {
private request;
private _bodySize;
constructor(request: RequestInitSafe);
headers(allow?: string[]): Record<string, string> | undefined;
get bodySize(): number | undefined;
get method(): string | undefined;
get body(): string | null;
json(allow?: string[], exclude?: string[]): Promise<JsonObject | null>;
}
export declare class RequestWrapperXhr implements IRequestWrapper {
readonly bodyRaw: XMLHttpRequestBodyInitSafe | null;
readonly requestHeaders: Record<string, string>;
constructor(bodyRaw: XMLHttpRequestBodyInitSafe | null, requestHeaders: Record<string, string>);
headers(allow?: string[]): Record<string, string> | undefined;
get bodySize(): number | undefined;
get body(): string | null;
json(allow?: string[], exclude?: string[]): Promise<JsonObject | null>;
}
export type JsonObject = {
[key: string]: JsonValue;
};
export type JsonValue = string | number | boolean | null | JsonObject | JsonArray;
export type JsonArray = Array<JsonValue>;
export interface IResponseWrapper {
/**
* Get the headers of the response.
* @param allow - The headers to allow.
* @returns The pruned headers
*/
headers(allow?: string[]): Record<string, string> | undefined;
bodySize?: number;
status?: number;
body?: string | Blob | ReadableStream | ArrayBuffer | FormDataSafe | URLSearchParams | ArrayBufferView | null;
json: (allow?: string[], exclude?: string[]) => Promise<JsonObject | null>;
}
/**
* This class encapsulates the Fetch API Response object
* (https://developer.mozilla.org/en-US/docs/Web/API/Response) so that the consumer can
* only get access to the headers and body size.
*
* This is to prevent consumers from directly accessing the Response object
* and mutating it or running costly operations on it.
*
* IMPORTANT:
* * Do not make changes to this class without careful consideration
* of performance implications, memory usage and potential to mutate the customer's
* response.
* * Do not .clone() the Response object unless you need to access the body.
* Cloning will 2x the memory overhead of the response.
* * NEVER consume the body's stream. This will cause the response to be consumed
* meaning the body will be empty when the customer tries to access it.
* (ie: if the body is an instanceof https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream
* never call any of the methods on it)
*/
export declare class ResponseWrapperFetch implements IResponseWrapper {
private response;
private _bodySize;
private clonedResponse?;
constructor(response: ResponseSafe);
headers(allow?: string[]): Record<string, string> | undefined;
get bodySize(): number | undefined;
get status(): number;
text(): Promise<string | null>;
json(allow?: string[], exclude?: string[]): Promise<JsonObject | null>;
}
export declare class ResponseWrapperXhr implements IResponseWrapper {
readonly statusCode: number;
readonly headersString: string;
readonly size: number | undefined;
readonly getJson: () => any | null;
constructor(statusCode: number, headersString: string, size: number | undefined, getJson: () => any | null);
get bodySize(): number | undefined;
get status(): number;
headers(allow?: string[]): Record<string, string> | undefined;
json(allow?: string[], exclude?: string[]): Promise<JsonObject | null>;
}
export declare enum PRUNE_STRATEGY {
REDACT = "redact",
REMOVE = "remove"
}
/**
* Prune headers from a headers record object.
* @param headers - The headers to prune.
* @param options - The options to prune the headers.
* @param options.exclude - List of headers to delete from headers
* @param options.include - List of headers to keep in headers, if not provided, all headers are kept by default
* @returns The pruned headers.
*/
export declare const pruneHeaders: (headers: Record<string, string>, options: {
allow?: string[] | undefined;
strategy?: PRUNE_STRATEGY | undefined;
}) => Record<string, string>;
export declare class NetworkRequestEvent {
readonly type: 'xhr' | 'fetch';
readonly method: string;
readonly timestamp: number;
readonly startTime: number;
readonly url?: string | undefined;
readonly requestWrapper?: IRequestWrapper | undefined;
readonly status: number;
readonly duration?: number | undefined;
readonly responseWrapper?: IResponseWrapper | undefined;
readonly error?: {
name: string;
message: string;
} | undefined;
readonly endTime?: number | undefined;
requestHeaders?: Record<string, string>;
responseHeaders?: Record<string, string>;
requestBodyJson?: Promise<JsonObject | null>;
responseBodyJson?: Promise<JsonObject | null>;
constructor(type: 'xhr' | 'fetch', method: string, timestamp: number, startTime: number, url?: string | undefined, requestWrapper?: IRequestWrapper | undefined, status?: number, duration?: number | undefined, responseWrapper?: IResponseWrapper | undefined, error?: {
name: string;
message: string;
} | undefined, endTime?: number | undefined);
toSerializable(): Record<string, any>;
}
export {};
//# sourceMappingURL=network-request-event.d.ts.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,519 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NetworkRequestEvent = exports.pruneHeaders = exports.PRUNE_STRATEGY = exports.ResponseWrapperXhr = exports.ResponseWrapperFetch = exports.RequestWrapperXhr = exports.RequestWrapperFetch = exports.MAXIMUM_ENTRIES = void 0;
var tslib_1 = require("tslib");
var global_scope_1 = require("./global-scope");
var json_query_1 = require("./utils/json-query");
var _1 = require("./");
var TEXT_READ_TIMEOUT = 500;
exports.MAXIMUM_ENTRIES = 100;
/**
* This class encapsulates the RequestInit (https://developer.mozilla.org/en-US/docs/Web/API/RequestInit)
* object so that the consumer can only get access to the headers, method and body size.
*
* This is to prevent consumers from directly accessing the Request object
* and mutating it or running costly operations on it.
*
* IMPORTANT:
* * Do not make changes to this class without careful consideration
* of performance implications, memory usage and potential to mutate the customer's
* request.
* * NEVER .clone() the RequestInit object. This will 2x's the memory overhead of the request
* * NEVER: call .arrayBuffer(), text(), json() or any other method on the body that
* consumes the body's stream. This will cause the response to be consumed
* meaning the body will be empty when the customer tries to access it.
* (ie: if the body is an instanceof https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream
* never call any of the methods on it)
*/
var RequestWrapperFetch = /** @class */ (function () {
function RequestWrapperFetch(request) {
this.request = request;
}
RequestWrapperFetch.prototype.headers = function (allow) {
var e_1, _a;
if (allow === void 0) { allow = []; }
var headersUnsafe = this.request.headers;
// copy the headers into a new object
var headersSafeCopy = {};
if (Array.isArray(headersUnsafe)) {
headersUnsafe.forEach(function (_a) {
var _b = tslib_1.__read(_a, 2), headerName = _b[0], headerValue = _b[1];
headersSafeCopy[headerName] = headerValue;
});
}
else if (headersUnsafe instanceof Headers) {
headersUnsafe.forEach(function (value, key) {
headersSafeCopy[key] = value;
});
}
else if (typeof headersUnsafe === 'object' && headersUnsafe !== null) {
try {
for (var _b = tslib_1.__values(Object.entries(headersUnsafe)), _c = _b.next(); !_c.done; _c = _b.next()) {
var _d = tslib_1.__read(_c.value, 2), key = _d[0], value = _d[1];
headersSafeCopy[key] = value;
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
}
return (0, exports.pruneHeaders)(headersSafeCopy, { allow: allow });
};
Object.defineProperty(RequestWrapperFetch.prototype, "bodySize", {
get: function () {
if (typeof this._bodySize === 'number')
return this._bodySize;
var global = (0, global_scope_1.getGlobalScope)();
/* istanbul ignore if */
if (!(global === null || global === void 0 ? void 0 : global.TextEncoder)) {
return;
}
var body = this.request.body;
this._bodySize = getBodySize(body, exports.MAXIMUM_ENTRIES);
return this._bodySize;
},
enumerable: false,
configurable: true
});
Object.defineProperty(RequestWrapperFetch.prototype, "method", {
get: function () {
return this.request.method;
},
enumerable: false,
configurable: true
});
Object.defineProperty(RequestWrapperFetch.prototype, "body", {
get: function () {
if (typeof this.request.body === 'string') {
return this.request.body;
}
return null;
},
enumerable: false,
configurable: true
});
RequestWrapperFetch.prototype.json = function (allow, exclude) {
if (allow === void 0) { allow = []; }
if (exclude === void 0) { exclude = []; }
return tslib_1.__awaiter(this, void 0, void 0, function () {
var text;
return tslib_1.__generator(this, function (_a) {
if (allow.length === 0) {
return [2 /*return*/, null];
}
text = this.body;
return [2 /*return*/, safeParseAndPruneBody(text, allow, exclude)];
});
});
};
return RequestWrapperFetch;
}());
exports.RequestWrapperFetch = RequestWrapperFetch;
var RequestWrapperXhr = /** @class */ (function () {
function RequestWrapperXhr(bodyRaw, requestHeaders) {
this.bodyRaw = bodyRaw;
this.requestHeaders = requestHeaders;
}
RequestWrapperXhr.prototype.headers = function (allow) {
if (allow === void 0) { allow = []; }
return (0, exports.pruneHeaders)(this.requestHeaders, { allow: allow });
};
Object.defineProperty(RequestWrapperXhr.prototype, "bodySize", {
get: function () {
return getBodySize(this.bodyRaw, exports.MAXIMUM_ENTRIES);
},
enumerable: false,
configurable: true
});
Object.defineProperty(RequestWrapperXhr.prototype, "body", {
get: function () {
if (typeof this.bodyRaw === 'string') {
return this.bodyRaw;
}
return null;
},
enumerable: false,
configurable: true
});
RequestWrapperXhr.prototype.json = function (allow, exclude) {
if (allow === void 0) { allow = []; }
if (exclude === void 0) { exclude = []; }
return tslib_1.__awaiter(this, void 0, void 0, function () {
var text;
return tslib_1.__generator(this, function (_a) {
if (allow.length === 0) {
return [2 /*return*/, null];
}
text = this.body;
return [2 /*return*/, safeParseAndPruneBody(text, allow, exclude)];
});
});
};
return RequestWrapperXhr;
}());
exports.RequestWrapperXhr = RequestWrapperXhr;
function getBodySize(bodyUnsafe, maxEntries) {
var e_2, _a;
var bodySize;
var global = (0, global_scope_1.getGlobalScope)();
/* istanbul ignore next */
var TextEncoder = global === null || global === void 0 ? void 0 : global.TextEncoder;
/* istanbul ignore next */
if (!TextEncoder) {
return;
}
var bodySafe;
if (typeof bodyUnsafe === 'string') {
bodySafe = bodyUnsafe;
bodySize = new TextEncoder().encode(bodySafe).length;
}
else if (bodyUnsafe instanceof Blob) {
bodySafe = bodyUnsafe;
bodySize = bodySafe.size;
}
else if (bodyUnsafe instanceof URLSearchParams) {
bodySafe = bodyUnsafe;
bodySize = new TextEncoder().encode(bodySafe.toString()).length;
}
else if (ArrayBuffer.isView(bodyUnsafe)) {
bodySafe = bodyUnsafe;
bodySize = bodySafe.byteLength;
}
else if (bodyUnsafe instanceof ArrayBuffer) {
bodySafe = bodyUnsafe;
bodySize = bodySafe.byteLength;
}
else if (bodyUnsafe instanceof FormData) {
// Estimating only for text parts; not accurate for files
var formData = bodyUnsafe;
var total = 0;
var count = 0;
try {
for (var _b = tslib_1.__values(formData.entries()), _c = _b.next(); !_c.done; _c = _b.next()) {
var _d = tslib_1.__read(_c.value, 2), key = _d[0], value = _d[1];
total += key.length;
if (typeof value === 'string') {
total += new TextEncoder().encode(value).length;
}
else if (value instanceof Blob) {
total += value.size;
}
else {
// encountered an unknown type
// we can't estimate the size of this entry
return;
}
// terminate if we reach the maximum number of entries
// to avoid performance issues in case of very large FormData
if (++count >= maxEntries) {
return;
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_2) throw e_2.error; }
}
bodySize = total;
}
else if (bodyUnsafe instanceof ReadableStream) {
// If bodyUnsafe is an instanceof ReadableStream, we can't determine the size,
// without consuming it, so we return undefined.
// Never ever consume ReadableStream! DO NOT DO IT!!!
// eslint-disable-next-line @typescript-eslint/no-unused-vars
bodySafe = bodyUnsafe;
return;
}
return bodySize;
}
/**
* This class encapsulates the Fetch API Response object
* (https://developer.mozilla.org/en-US/docs/Web/API/Response) so that the consumer can
* only get access to the headers and body size.
*
* This is to prevent consumers from directly accessing the Response object
* and mutating it or running costly operations on it.
*
* IMPORTANT:
* * Do not make changes to this class without careful consideration
* of performance implications, memory usage and potential to mutate the customer's
* response.
* * Do not .clone() the Response object unless you need to access the body.
* Cloning will 2x the memory overhead of the response.
* * NEVER consume the body's stream. This will cause the response to be consumed
* meaning the body will be empty when the customer tries to access it.
* (ie: if the body is an instanceof https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream
* never call any of the methods on it)
*/
var ResponseWrapperFetch = /** @class */ (function () {
function ResponseWrapperFetch(response) {
this.response = response;
}
ResponseWrapperFetch.prototype.headers = function (allow) {
var _a;
if (allow === void 0) { allow = []; }
if (this.response.headers instanceof Headers) {
var headersSafe = this.response.headers;
var headersOut_1 = {};
/* istanbul ignore next */
(_a = headersSafe === null || headersSafe === void 0 ? void 0 : headersSafe.forEach) === null || _a === void 0 ? void 0 : _a.call(headersSafe, function (value, key) {
headersOut_1[key] = value;
});
return (0, exports.pruneHeaders)(headersOut_1, { allow: allow });
}
return;
};
Object.defineProperty(ResponseWrapperFetch.prototype, "bodySize", {
get: function () {
var _a, _b;
if (this._bodySize !== undefined)
return this._bodySize;
/* istanbul ignore next */
var contentLength = (_b = (_a = this.response.headers) === null || _a === void 0 ? void 0 : _a.get) === null || _b === void 0 ? void 0 : _b.call(_a, 'content-length');
var bodySize = contentLength ? parseInt(contentLength, 10) : undefined;
this._bodySize = bodySize;
return bodySize;
},
enumerable: false,
configurable: true
});
Object.defineProperty(ResponseWrapperFetch.prototype, "status", {
get: function () {
return this.response.status;
},
enumerable: false,
configurable: true
});
ResponseWrapperFetch.prototype.text = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var textPromise, timer, text, error_1;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
// !!!IMPORTANT: we clone the response to avoid mutating the original response
// never call .text(), .json(), etc.. on the original response always clone it first
if (!this.clonedResponse) {
this.clonedResponse = this.response.clone();
}
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
textPromise = this.clonedResponse.text();
timer = new Promise(function (resolve) {
return setTimeout(
/* istanbul ignore next */
function () { return resolve(null); }, TEXT_READ_TIMEOUT);
});
return [4 /*yield*/, Promise.race([textPromise, timer])];
case 2:
text = _a.sent();
return [2 /*return*/, text];
case 3:
error_1 = _a.sent();
return [2 /*return*/, null];
case 4: return [2 /*return*/];
}
});
});
};
ResponseWrapperFetch.prototype.json = function (allow, exclude) {
if (allow === void 0) { allow = []; }
if (exclude === void 0) { exclude = []; }
return tslib_1.__awaiter(this, void 0, void 0, function () {
var text;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (allow.length === 0) {
return [2 /*return*/, null];
}
return [4 /*yield*/, this.text()];
case 1:
text = _a.sent();
return [2 /*return*/, safeParseAndPruneBody(text, allow, exclude)];
}
});
});
};
return ResponseWrapperFetch;
}());
exports.ResponseWrapperFetch = ResponseWrapperFetch;
var ResponseWrapperXhr = /** @class */ (function () {
function ResponseWrapperXhr(statusCode, headersString, size, getJson) {
this.statusCode = statusCode;
this.headersString = headersString;
this.size = size;
this.getJson = getJson;
}
Object.defineProperty(ResponseWrapperXhr.prototype, "bodySize", {
get: function () {
return this.size;
},
enumerable: false,
configurable: true
});
Object.defineProperty(ResponseWrapperXhr.prototype, "status", {
get: function () {
return this.statusCode;
},
enumerable: false,
configurable: true
});
ResponseWrapperXhr.prototype.headers = function (allow) {
var e_3, _a;
if (allow === void 0) { allow = []; }
if (!this.headersString) {
return {};
}
var headers = {};
var headerLines = this.headersString.split('\r\n');
try {
for (var headerLines_1 = tslib_1.__values(headerLines), headerLines_1_1 = headerLines_1.next(); !headerLines_1_1.done; headerLines_1_1 = headerLines_1.next()) {
var line = headerLines_1_1.value;
var _b = tslib_1.__read(line.split(': '), 2), key = _b[0], value = _b[1];
if (key && value) {
headers[key] = value;
}
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (headerLines_1_1 && !headerLines_1_1.done && (_a = headerLines_1.return)) _a.call(headerLines_1);
}
finally { if (e_3) throw e_3.error; }
}
return (0, exports.pruneHeaders)(headers, { allow: allow });
};
ResponseWrapperXhr.prototype.json = function (allow, exclude) {
if (allow === void 0) { allow = []; }
if (exclude === void 0) { exclude = []; }
return tslib_1.__awaiter(this, void 0, void 0, function () {
var jsonBody;
return tslib_1.__generator(this, function (_a) {
if (allow.length === 0) {
return [2 /*return*/, null];
}
jsonBody = this.getJson();
if (jsonBody) {
(0, json_query_1.pruneJson)(jsonBody, allow, exclude);
return [2 /*return*/, jsonBody];
}
return [2 /*return*/, null];
});
});
};
return ResponseWrapperXhr;
}());
exports.ResponseWrapperXhr = ResponseWrapperXhr;
function safeParseAndPruneBody(text, allow, exclude) {
if (!text)
return null;
try {
var json = JSON.parse(text);
(0, json_query_1.pruneJson)(json, allow, exclude);
return json;
}
catch (error) {
return null;
}
}
var PRUNE_STRATEGY;
(function (PRUNE_STRATEGY) {
PRUNE_STRATEGY["REDACT"] = "redact";
PRUNE_STRATEGY["REMOVE"] = "remove";
})(PRUNE_STRATEGY = exports.PRUNE_STRATEGY || (exports.PRUNE_STRATEGY = {}));
var REDACTED_VALUE = '[REDACTED]';
/**
* Prune headers from a headers record object.
* @param headers - The headers to prune.
* @param options - The options to prune the headers.
* @param options.exclude - List of headers to delete from headers
* @param options.include - List of headers to keep in headers, if not provided, all headers are kept by default
* @returns The pruned headers.
*/
var pruneHeaders = function (headers, options) {
var e_4, _a;
var _b = options.allow, allow = _b === void 0 ? [] : _b, _c = options.strategy, strategy = _c === void 0 ? PRUNE_STRATEGY.REMOVE : _c;
var exclude = tslib_1.__spreadArray([], tslib_1.__read(_1.FORBIDDEN_HEADERS), false);
var headersPruned = {};
var _loop_1 = function (key) {
var lowerKey = key.toLowerCase();
if (exclude.find(function (e) { return e.toLowerCase() === lowerKey; })) {
if (strategy === PRUNE_STRATEGY.REDACT) {
headersPruned[key] = REDACTED_VALUE;
}
}
else if (!allow.find(function (i) { return i.toLowerCase() === lowerKey; })) {
if (strategy === PRUNE_STRATEGY.REDACT) {
headersPruned[key] = REDACTED_VALUE;
}
}
else {
headersPruned[key] = headers[key];
}
};
try {
for (var _d = tslib_1.__values(Object.keys(headers)), _e = _d.next(); !_e.done; _e = _d.next()) {
var key = _e.value;
_loop_1(key);
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
}
finally { if (e_4) throw e_4.error; }
}
return headersPruned;
};
exports.pruneHeaders = pruneHeaders;
var NetworkRequestEvent = /** @class */ (function () {
function NetworkRequestEvent(type, method, timestamp, startTime, url, requestWrapper, status, duration, responseWrapper, error, endTime) {
if (status === void 0) { status = 0; }
this.type = type;
this.method = method;
this.timestamp = timestamp;
this.startTime = startTime;
this.url = url;
this.requestWrapper = requestWrapper;
this.status = status;
this.duration = duration;
this.responseWrapper = responseWrapper;
this.error = error;
this.endTime = endTime;
}
NetworkRequestEvent.prototype.toSerializable = function () {
var _a, _b, _c, _d;
var serialized = {
type: this.type,
method: this.method,
url: this.url,
timestamp: this.timestamp,
status: this.status,
duration: this.duration,
error: this.error,
startTime: this.startTime,
endTime: this.endTime,
requestHeaders: (_a = this.requestWrapper) === null || _a === void 0 ? void 0 : _a.headers(tslib_1.__spreadArray([], tslib_1.__read(_1.SAFE_HEADERS), false)),
requestBodySize: (_b = this.requestWrapper) === null || _b === void 0 ? void 0 : _b.bodySize,
responseHeaders: (_c = this.responseWrapper) === null || _c === void 0 ? void 0 : _c.headers(tslib_1.__spreadArray([], tslib_1.__read(_1.SAFE_HEADERS), false)),
responseBodySize: (_d = this.responseWrapper) === null || _d === void 0 ? void 0 : _d.bodySize,
};
return Object.fromEntries(Object.entries(serialized).filter(function (_a) {
var _b = tslib_1.__read(_a, 2), _ = _b[0], v = _b[1];
return v !== undefined;
}));
};
return NetworkRequestEvent;
}());
exports.NetworkRequestEvent = NetworkRequestEvent;
//# sourceMappingURL=network-request-event.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,53 @@
import { DestinationPlugin } from '../types/plugin';
import { Event } from '../types/event/event';
import { Result } from '../types/result';
import { Response, InvalidResponse, PayloadTooLargeResponse, RateLimitResponse, SuccessResponse } from '../types/response';
import { IConfig } from '../types/config/core-config';
import { EventCallback } from '../types/event-callback';
export interface Context {
event: Event;
attempts: number;
callback: EventCallback;
timeout: number;
}
export declare function getResponseBodyString(res: Response): string;
export declare class Destination implements DestinationPlugin {
name: string;
type: "destination";
retryTimeout: number;
throttleTimeout: number;
storageKey: string;
config: IConfig;
scheduleId: ReturnType<typeof setTimeout> | null;
scheduledTimeout: number;
flushId: ReturnType<typeof setTimeout> | null;
queue: Context[];
setup(config: IConfig): Promise<undefined>;
execute(event: Event): Promise<Result>;
removeEventsExceedFlushMaxRetries(list: Context[]): Context[];
scheduleEvents(list: Context[]): void;
schedule(timeout: number): void;
resetSchedule(): void;
flush(useRetry?: boolean): Promise<void>;
send(list: Context[], useRetry?: boolean): Promise<void>;
handleResponse(res: Response, list: Context[]): void;
handleSuccessResponse(res: SuccessResponse, list: Context[]): void;
handleInvalidResponse(res: InvalidResponse, list: Context[]): void;
handlePayloadTooLargeResponse(res: PayloadTooLargeResponse, list: Context[]): void;
handleRateLimitResponse(res: RateLimitResponse, list: Context[]): void;
handleOtherResponse(list: Context[]): void;
fulfillRequest(list: Context[], code: number, message: string): void;
/**
* This is called on
* 1) new events are added to queue; or
* 2) response comes back for a request
*
* Update the event storage based on the queue
*/
saveEvents(): void;
/**
* This is called on response comes back for a request
*/
removeEvents(eventsToRemove: Context[]): void;
}
//# sourceMappingURL=destination.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"destination.d.ts","sourceRoot":"","sources":["../../../src/plugins/destination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,OAAO,EACL,QAAQ,EACR,eAAe,EACf,uBAAuB,EACvB,iBAAiB,EACjB,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAa3B,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB;AAOD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,QAAQ,UAUlD;AAED,qBAAa,WAAY,YAAW,iBAAiB;IACnD,IAAI,SAAe;IACnB,IAAI,gBAA0B;IAE9B,YAAY,SAAQ;IACpB,eAAe,SAAS;IACxB,UAAU,SAAM;IAIhB,MAAM,EAAE,OAAO,CAAC;IAKhB,UAAU,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG,IAAI,CAAQ;IAExD,gBAAgB,SAAK;IAGrB,OAAO,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG,IAAI,CAAQ;IACrD,KAAK,EAAE,OAAO,EAAE,CAAM;IAEhB,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC;IAYhD,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC;IAmBtC,iCAAiC,CAAC,IAAI,EAAE,OAAO,EAAE;IAWjD,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE;IAU9B,QAAQ,CAAC,OAAO,EAAE,MAAM;IAsBxB,aAAa;IAMP,KAAK,CAAC,QAAQ,UAAQ;IAoCtB,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,QAAQ,UAAO;IA2C3C,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE;IA6B7C,qBAAqB,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,OAAO,EAAE;IAI3D,qBAAqB,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,OAAO,EAAE;IA+B3D,6BAA6B,CAAC,GAAG,EAAE,uBAAuB,EAAE,IAAI,EAAE,OAAO,EAAE;IAe3E,uBAAuB,CAAC,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,OAAO,EAAE;IA+B/D,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE;IAUnC,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAK7D;;;;;;OAMG;IACH,UAAU;IASV;;OAEG;IACH,YAAY,CAAC,cAAc,EAAE,OAAO,EAAE;CAOvC"}

View File

@@ -0,0 +1,368 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Destination = exports.getResponseBodyString = void 0;
var tslib_1 = require("tslib");
var status_1 = require("../types/status");
var messages_1 = require("../types/messages");
var constants_1 = require("../types/constants");
var chunk_1 = require("../utils/chunk");
var result_builder_1 = require("../utils/result-builder");
var config_1 = require("../config");
var uuid_1 = require("../utils/uuid");
function getErrorMessage(error) {
if (error instanceof Error)
return error.message;
return String(error);
}
function getResponseBodyString(res) {
var responseBodyString = '';
try {
if ('body' in res) {
responseBodyString = JSON.stringify(res.body, null, 2);
}
}
catch (_a) {
// to avoid crash, but don't care about the error, add comment to avoid empty block lint error
}
return responseBodyString;
}
exports.getResponseBodyString = getResponseBodyString;
var Destination = /** @class */ (function () {
function Destination() {
this.name = 'amplitude';
this.type = 'destination';
this.retryTimeout = 1000;
this.throttleTimeout = 30000;
this.storageKey = '';
// Indicator of whether events that are scheduled (but not flushed yet).
// When flush:
// 1. assign `scheduleId` to `flushId`
// 2. set `scheduleId` to null
this.scheduleId = null;
// Timeout in milliseconds of current schedule
this.scheduledTimeout = 0;
// Indicator of whether current flush resolves.
// When flush resolves, set `flushId` to null
this.flushId = null;
this.queue = [];
}
Destination.prototype.setup = function (config) {
var _a;
return tslib_1.__awaiter(this, void 0, void 0, function () {
var unsent;
var _this = this;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
this.config = config;
this.storageKey = "".concat(constants_1.STORAGE_PREFIX, "_").concat(this.config.apiKey.substring(0, 10));
return [4 /*yield*/, ((_a = this.config.storageProvider) === null || _a === void 0 ? void 0 : _a.get(this.storageKey))];
case 1:
unsent = _b.sent();
if (unsent && unsent.length > 0) {
void Promise.all(unsent.map(function (event) { return _this.execute(event); })).catch();
}
return [2 /*return*/, Promise.resolve(undefined)];
}
});
});
};
Destination.prototype.execute = function (event) {
var _this = this;
// Assign insert_id for dropping invalid event later
if (!event.insert_id) {
event.insert_id = (0, uuid_1.UUID)();
}
return new Promise(function (resolve) {
var context = {
event: event,
attempts: 0,
callback: function (result) { return resolve(result); },
timeout: 0,
};
_this.queue.push(context);
_this.schedule(_this.config.flushIntervalMillis);
_this.saveEvents();
});
};
Destination.prototype.removeEventsExceedFlushMaxRetries = function (list) {
var _this = this;
return list.filter(function (context) {
context.attempts += 1;
if (context.attempts < _this.config.flushMaxRetries) {
return true;
}
void _this.fulfillRequest([context], 500, messages_1.MAX_RETRIES_EXCEEDED_MESSAGE);
return false;
});
};
Destination.prototype.scheduleEvents = function (list) {
var _this = this;
list.forEach(function (context) {
_this.schedule(context.timeout === 0 ? _this.config.flushIntervalMillis : context.timeout);
});
};
// Schedule a flush in timeout when
// 1. No schedule
// 2. Timeout greater than existing timeout.
// This makes sure that when throttled, no flush when throttle timeout expires.
Destination.prototype.schedule = function (timeout) {
var _this = this;
if (this.config.offline) {
return;
}
if (this.scheduleId === null || (this.scheduleId && timeout > this.scheduledTimeout)) {
if (this.scheduleId) {
clearTimeout(this.scheduleId);
}
this.scheduledTimeout = timeout;
this.scheduleId = setTimeout(function () {
_this.queue = _this.queue.map(function (context) {
context.timeout = 0;
return context;
});
void _this.flush(true);
}, timeout);
return;
}
};
// Mark current schedule is flushed.
Destination.prototype.resetSchedule = function () {
this.scheduleId = null;
this.scheduledTimeout = 0;
};
// Flush all events regardless of their timeout
Destination.prototype.flush = function (useRetry) {
if (useRetry === void 0) { useRetry = false; }
return tslib_1.__awaiter(this, void 0, void 0, function () {
var list, later, batches;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
// Skip flush if offline
if (this.config.offline) {
this.resetSchedule();
this.config.loggerProvider.debug('Skipping flush while offline.');
return [2 /*return*/];
}
if (this.flushId) {
this.resetSchedule();
this.config.loggerProvider.debug('Skipping flush because previous flush has not resolved.');
return [2 /*return*/];
}
this.flushId = this.scheduleId;
this.resetSchedule();
list = [];
later = [];
this.queue.forEach(function (context) { return (context.timeout === 0 ? list.push(context) : later.push(context)); });
batches = (0, chunk_1.chunk)(list, this.config.flushQueueSize);
// Promise.all() doesn't guarantee resolve order.
// Sequentially resolve to make sure backend receives events in order
return [4 /*yield*/, batches.reduce(function (promise, batch) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, promise];
case 1:
_a.sent();
return [4 /*yield*/, this.send(batch, useRetry)];
case 2: return [2 /*return*/, _a.sent()];
}
});
}); }, Promise.resolve())];
case 1:
// Promise.all() doesn't guarantee resolve order.
// Sequentially resolve to make sure backend receives events in order
_a.sent();
// Mark current flush is done
this.flushId = null;
this.scheduleEvents(this.queue);
return [2 /*return*/];
}
});
});
};
Destination.prototype.send = function (list, useRetry) {
if (useRetry === void 0) { useRetry = true; }
return tslib_1.__awaiter(this, void 0, void 0, function () {
var payload, serverUrl, res, e_1, errorMessage;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!this.config.apiKey) {
return [2 /*return*/, this.fulfillRequest(list, 400, messages_1.MISSING_API_KEY_MESSAGE)];
}
payload = {
api_key: this.config.apiKey,
events: list.map(function (context) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
var _a = context.event, extra = _a.extra, eventWithoutExtra = tslib_1.__rest(_a, ["extra"]);
return eventWithoutExtra;
}),
options: {
min_id_length: this.config.minIdLength,
},
client_upload_time: new Date().toISOString(),
request_metadata: this.config.requestMetadata,
};
this.config.requestMetadata = new config_1.RequestMetadata();
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
serverUrl = (0, config_1.createServerConfig)(this.config.serverUrl, this.config.serverZone, this.config.useBatch).serverUrl;
return [4 /*yield*/, this.config.transportProvider.send(serverUrl, payload)];
case 2:
res = _a.sent();
if (res === null) {
this.fulfillRequest(list, 0, messages_1.UNEXPECTED_ERROR_MESSAGE);
return [2 /*return*/];
}
if (!useRetry) {
if ('body' in res) {
this.fulfillRequest(list, res.statusCode, "".concat(res.status, ": ").concat(getResponseBodyString(res)));
}
else {
this.fulfillRequest(list, res.statusCode, res.status);
}
return [2 /*return*/];
}
this.handleResponse(res, list);
return [3 /*break*/, 4];
case 3:
e_1 = _a.sent();
errorMessage = getErrorMessage(e_1);
this.config.loggerProvider.error(errorMessage);
this.handleResponse({ status: status_1.Status.Failed, statusCode: 0 }, list);
return [3 /*break*/, 4];
case 4: return [2 /*return*/];
}
});
});
};
Destination.prototype.handleResponse = function (res, list) {
var status = res.status;
switch (status) {
case status_1.Status.Success: {
this.handleSuccessResponse(res, list);
break;
}
case status_1.Status.Invalid: {
this.handleInvalidResponse(res, list);
break;
}
case status_1.Status.PayloadTooLarge: {
this.handlePayloadTooLargeResponse(res, list);
break;
}
case status_1.Status.RateLimit: {
this.handleRateLimitResponse(res, list);
break;
}
default: {
// log intermediate event status before retry
this.config.loggerProvider.warn("{code: 0, error: \"Status '".concat(status, "' provided for ").concat(list.length, " events\"}"));
this.handleOtherResponse(list);
break;
}
}
};
Destination.prototype.handleSuccessResponse = function (res, list) {
this.fulfillRequest(list, res.statusCode, messages_1.SUCCESS_MESSAGE);
};
Destination.prototype.handleInvalidResponse = function (res, list) {
var _this = this;
if (res.body.missingField || res.body.error.startsWith(messages_1.INVALID_API_KEY)) {
this.fulfillRequest(list, res.statusCode, res.body.error);
return;
}
var dropIndex = tslib_1.__spreadArray(tslib_1.__spreadArray(tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(Object.values(res.body.eventsWithInvalidFields)), false), tslib_1.__read(Object.values(res.body.eventsWithMissingFields)), false), tslib_1.__read(Object.values(res.body.eventsWithInvalidIdLengths)), false), tslib_1.__read(res.body.silencedEvents), false).flat();
var dropIndexSet = new Set(dropIndex);
var retry = list.filter(function (context, index) {
if (dropIndexSet.has(index)) {
_this.fulfillRequest([context], res.statusCode, res.body.error);
return;
}
return true;
});
if (retry.length > 0) {
// log intermediate event status before retry
this.config.loggerProvider.warn(getResponseBodyString(res));
}
var tryable = this.removeEventsExceedFlushMaxRetries(retry);
this.scheduleEvents(tryable);
};
Destination.prototype.handlePayloadTooLargeResponse = function (res, list) {
if (list.length === 1) {
this.fulfillRequest(list, res.statusCode, res.body.error);
return;
}
// log intermediate event status before retry
this.config.loggerProvider.warn(getResponseBodyString(res));
this.config.flushQueueSize /= 2;
var tryable = this.removeEventsExceedFlushMaxRetries(list);
this.scheduleEvents(tryable);
};
Destination.prototype.handleRateLimitResponse = function (res, list) {
var _this = this;
var dropUserIds = Object.keys(res.body.exceededDailyQuotaUsers);
var dropDeviceIds = Object.keys(res.body.exceededDailyQuotaDevices);
var throttledIndex = res.body.throttledEvents;
var dropUserIdsSet = new Set(dropUserIds);
var dropDeviceIdsSet = new Set(dropDeviceIds);
var throttledIndexSet = new Set(throttledIndex);
var retry = list.filter(function (context, index) {
if ((context.event.user_id && dropUserIdsSet.has(context.event.user_id)) ||
(context.event.device_id && dropDeviceIdsSet.has(context.event.device_id))) {
_this.fulfillRequest([context], res.statusCode, res.body.error);
return;
}
if (throttledIndexSet.has(index)) {
context.timeout = _this.throttleTimeout;
}
return true;
});
if (retry.length > 0) {
// log intermediate event status before retry
this.config.loggerProvider.warn(getResponseBodyString(res));
}
var tryable = this.removeEventsExceedFlushMaxRetries(retry);
this.scheduleEvents(tryable);
};
Destination.prototype.handleOtherResponse = function (list) {
var _this = this;
var later = list.map(function (context) {
context.timeout = context.attempts * _this.retryTimeout;
return context;
});
var tryable = this.removeEventsExceedFlushMaxRetries(later);
this.scheduleEvents(tryable);
};
Destination.prototype.fulfillRequest = function (list, code, message) {
this.removeEvents(list);
list.forEach(function (context) { return context.callback((0, result_builder_1.buildResult)(context.event, code, message)); });
};
/**
* This is called on
* 1) new events are added to queue; or
* 2) response comes back for a request
*
* Update the event storage based on the queue
*/
Destination.prototype.saveEvents = function () {
if (!this.config.storageProvider) {
return;
}
var updatedEvents = this.queue.map(function (context) { return context.event; });
void this.config.storageProvider.set(this.storageKey, updatedEvents);
};
/**
* This is called on response comes back for a request
*/
Destination.prototype.removeEvents = function (eventsToRemove) {
this.queue = this.queue.filter(function (queuedContext) { return !eventsToRemove.some(function (context) { return context.event.insert_id === queuedContext.event.insert_id; }); });
this.saveEvents();
};
return Destination;
}());
exports.Destination = Destination;
//# sourceMappingURL=destination.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,11 @@
import { BeforePlugin } from '../types/plugin';
import { IConfig } from '../types/config/core-config';
import { Event } from '../types/event/event';
export declare class IdentityEventSender implements BeforePlugin {
name: string;
type: "before";
identityStore: import("@amplitude/analytics-connector/dist/types/src/identityStore").IdentityStoreImpl;
execute(context: Event): Promise<Event>;
setup(config: IConfig): Promise<void>;
}
//# sourceMappingURL=identity.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../../src/plugins/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAG7C,qBAAa,mBAAoB,YAAW,YAAY;IACtD,IAAI,SAAc;IAClB,IAAI,WAAqB;IAEzB,aAAa,0FAAyC;IAEhD,OAAO,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAQvC,KAAK,CAAC,MAAM,EAAE,OAAO;CAK5B"}

View File

@@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IdentityEventSender = void 0;
var tslib_1 = require("tslib");
var analytics_connector_1 = require("../analytics-connector");
var IdentityEventSender = /** @class */ (function () {
function IdentityEventSender() {
this.name = 'identity';
this.type = 'before';
this.identityStore = (0, analytics_connector_1.getAnalyticsConnector)().identityStore;
}
IdentityEventSender.prototype.execute = function (context) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var userProperties;
return tslib_1.__generator(this, function (_a) {
userProperties = context.user_properties;
if (userProperties) {
this.identityStore.editIdentity().updateUserProperties(userProperties).commit();
}
return [2 /*return*/, context];
});
});
};
IdentityEventSender.prototype.setup = function (config) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
if (config.instanceName) {
this.identityStore = (0, analytics_connector_1.getAnalyticsConnector)(config.instanceName).identityStore;
}
return [2 /*return*/];
});
});
};
return IdentityEventSender;
}());
exports.IdentityEventSender = IdentityEventSender;
//# sourceMappingURL=identity.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../src/plugins/identity.ts"],"names":[],"mappings":";;;;AAGA,8DAA+D;AAE/D;IAAA;QACE,SAAI,GAAG,UAAU,CAAC;QAClB,SAAI,GAAG,QAAiB,CAAC;QAEzB,kBAAa,GAAG,IAAA,2CAAqB,GAAE,CAAC,aAAa,CAAC;IAexD,CAAC;IAbO,qCAAO,GAAb,UAAc,OAAc;;;;gBACpB,cAAc,GAAG,OAAO,CAAC,eAAsC,CAAC;gBACtE,IAAI,cAAc,EAAE;oBAClB,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC,MAAM,EAAE,CAAC;iBACjF;gBACD,sBAAO,OAAO,EAAC;;;KAChB;IAEK,mCAAK,GAAX,UAAY,MAAe;;;gBACzB,IAAI,MAAM,CAAC,YAAY,EAAE;oBACvB,IAAI,CAAC,aAAa,GAAG,IAAA,2CAAqB,EAAC,MAAM,CAAC,YAAY,CAAC,CAAC,aAAa,CAAC;iBAC/E;;;;KACF;IACH,0BAAC;AAAD,CAAC,AAnBD,IAmBC;AAnBY,kDAAmB","sourcesContent":["import { BeforePlugin } from '../types/plugin';\nimport { IConfig } from '../types/config/core-config';\nimport { Event } from '../types/event/event';\nimport { getAnalyticsConnector } from '../analytics-connector';\n\nexport class IdentityEventSender implements BeforePlugin {\n name = 'identity';\n type = 'before' as const;\n\n identityStore = getAnalyticsConnector().identityStore;\n\n async execute(context: Event): Promise<Event> {\n const userProperties = context.user_properties as Record<string, any>;\n if (userProperties) {\n this.identityStore.editIdentity().updateUserProperties(userProperties).commit();\n }\n return context;\n }\n\n async setup(config: IConfig) {\n if (config.instanceName) {\n this.identityStore = getAnalyticsConnector(config.instanceName).identityStore;\n }\n }\n}\n"]}

View File

@@ -0,0 +1,3 @@
export declare const getQueryParams: () => Record<string, string | undefined>;
export declare const tryDecodeURIComponent: (value?: string) => string;
//# sourceMappingURL=query-params.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"query-params.d.ts","sourceRoot":"","sources":["../../src/query-params.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,QAAO,OAAO,MAAM,EAAE,MAAM,GAAG,SAAS,CAkBlE,CAAC;AAEF,eAAO,MAAM,qBAAqB,4BAMjC,CAAC"}

View File

@@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.tryDecodeURIComponent = exports.getQueryParams = void 0;
var global_scope_1 = require("./global-scope");
var getQueryParams = function () {
var _a;
var globalScope = (0, global_scope_1.getGlobalScope)();
/* istanbul ignore if */
if (!((_a = globalScope === null || globalScope === void 0 ? void 0 : globalScope.location) === null || _a === void 0 ? void 0 : _a.search)) {
return {};
}
var pairs = globalScope.location.search.substring(1).split('&').filter(Boolean);
var params = pairs.reduce(function (acc, curr) {
var query = curr.split('=', 2);
var key = (0, exports.tryDecodeURIComponent)(query[0]);
var value = (0, exports.tryDecodeURIComponent)(query[1]);
if (!value) {
return acc;
}
acc[key] = value;
return acc;
}, {});
return params;
};
exports.getQueryParams = getQueryParams;
var tryDecodeURIComponent = function (value) {
if (value === void 0) { value = ''; }
try {
return decodeURIComponent(value);
}
catch (_a) {
return '';
}
};
exports.tryDecodeURIComponent = tryDecodeURIComponent;
//# sourceMappingURL=query-params.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"query-params.js","sourceRoot":"","sources":["../../src/query-params.ts"],"names":[],"mappings":";;;AAAA,+CAAgD;AAEzC,IAAM,cAAc,GAAG;;IAC5B,IAAM,WAAW,GAAG,IAAA,6BAAc,GAAE,CAAC;IACrC,wBAAwB;IACxB,IAAI,CAAC,CAAA,MAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,QAAQ,0CAAE,MAAM,CAAA,EAAE;QAClC,OAAO,EAAE,CAAC;KACX;IACD,IAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClF,IAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAqC,UAAC,GAAG,EAAE,IAAI;QACxE,IAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACjC,IAAM,GAAG,GAAG,IAAA,6BAAqB,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,IAAM,KAAK,GAAG,IAAA,6BAAqB,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,KAAK,EAAE;YACV,OAAO,GAAG,CAAC;SACZ;QACD,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACjB,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAlBW,QAAA,cAAc,kBAkBzB;AAEK,IAAM,qBAAqB,GAAG,UAAC,KAAU;IAAV,sBAAA,EAAA,UAAU;IAC9C,IAAI;QACF,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;KAClC;IAAC,WAAM;QACN,OAAO,EAAE,CAAC;KACX;AACH,CAAC,CAAC;AANW,QAAA,qBAAqB,yBAMhC","sourcesContent":["import { getGlobalScope } from './global-scope';\n\nexport const getQueryParams = (): Record<string, string | undefined> => {\n const globalScope = getGlobalScope();\n /* istanbul ignore if */\n if (!globalScope?.location?.search) {\n return {};\n }\n const pairs = globalScope.location.search.substring(1).split('&').filter(Boolean);\n const params = pairs.reduce<Record<string, string | undefined>>((acc, curr) => {\n const query = curr.split('=', 2);\n const key = tryDecodeURIComponent(query[0]);\n const value = tryDecodeURIComponent(query[1]);\n if (!value) {\n return acc;\n }\n acc[key] = value;\n return acc;\n }, {});\n return params;\n};\n\nexport const tryDecodeURIComponent = (value = '') => {\n try {\n return decodeURIComponent(value);\n } catch {\n return '';\n }\n};\n"]}

View File

@@ -0,0 +1,10 @@
import { RemoteConfigStorage, RemoteConfigInfo } from './remote-config';
import { ILogger } from '../logger';
export declare class RemoteConfigLocalStorage implements RemoteConfigStorage {
private readonly key;
private readonly logger;
constructor(apiKey: string, logger: ILogger);
fetchConfig(): Promise<RemoteConfigInfo>;
setConfig(config: RemoteConfigInfo): Promise<boolean>;
}
//# sourceMappingURL=remote-config-localstorage.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"remote-config-localstorage.d.ts","sourceRoot":"","sources":["../../../src/remote-config/remote-config-localstorage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,qBAAa,wBAAyB,YAAW,mBAAmB;IAClE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;gBAErB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;IAK3C,WAAW,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAiCxC,SAAS,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;CAUtD"}

Some files were not shown because too many files have changed in this diff Show More