avo-inspector 3.2.3-alpha.1 → 3.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/index.js +1 -1
  2. package/package.json +1 -1
  3. package/dist/AvoBatcher.js +0 -87
  4. package/dist/AvoDeduplicator.js +0 -142
  5. package/dist/AvoEncryption.js +0 -176
  6. package/dist/AvoInspector.js +0 -435
  7. package/dist/AvoNetworkCallsHandler.js +0 -229
  8. package/dist/AvoSchemaParser.js +0 -95
  9. package/dist/AvoStreamId.js +0 -82
  10. package/dist/__mocks__/xhr.js +0 -14
  11. package/dist/__mocks__/xhrError.js +0 -14
  12. package/dist/__tests__/AvoEncryption.d.ts +0 -1
  13. package/dist/__tests__/AvoEncryption.js +0 -272
  14. package/dist/__tests__/AvoEncryptionIntegration.d.ts +0 -1
  15. package/dist/__tests__/AvoEncryptionIntegration.js +0 -191
  16. package/dist/__tests__/AvoEventSpecFetcher.d.ts +0 -1
  17. package/dist/__tests__/AvoEventSpecFetcher.js +0 -377
  18. package/dist/__tests__/AvoInspector.d.ts +0 -1
  19. package/dist/__tests__/AvoInspector.js +0 -335
  20. package/dist/__tests__/Batcher.d.ts +0 -1
  21. package/dist/__tests__/Batcher.js +0 -214
  22. package/dist/__tests__/BatcherPublic.d.ts +0 -1
  23. package/dist/__tests__/BatcherPublic.js +0 -139
  24. package/dist/__tests__/Deduplicator.d.ts +0 -1
  25. package/dist/__tests__/Deduplicator.js +0 -190
  26. package/dist/__tests__/EnableLoggingLite_test.d.ts +0 -1
  27. package/dist/__tests__/EnableLogging_test.d.ts +0 -1
  28. package/dist/__tests__/EventSpecCache.d.ts +0 -1
  29. package/dist/__tests__/EventSpecCache.js +0 -143
  30. package/dist/__tests__/EventValidator.d.ts +0 -1
  31. package/dist/__tests__/EventValidator.js +0 -543
  32. package/dist/__tests__/InstallationId.d.ts +0 -1
  33. package/dist/__tests__/InstallationId.js +0 -60
  34. package/dist/__tests__/NetworkCallsHandler.d.ts +0 -1
  35. package/dist/__tests__/NetworkCallsHandler.js +0 -222
  36. package/dist/__tests__/NetworkCallsHandlerModelA.d.ts +0 -1
  37. package/dist/__tests__/NetworkCallsHandlerModelA.js +0 -206
  38. package/dist/__tests__/Parsing.d.ts +0 -1
  39. package/dist/__tests__/Parsing.js +0 -115
  40. package/dist/__tests__/Sessions.d.ts +0 -1
  41. package/dist/__tests__/Sessions.js +0 -10
  42. package/dist/__tests__/Storage.d.ts +0 -1
  43. package/dist/__tests__/Storage.js +0 -173
  44. package/dist/__tests__/StreamId.d.ts +0 -1
  45. package/dist/__tests__/StreamId.js +0 -153
  46. package/dist/__tests__/constants.js +0 -48
  47. package/dist/browser.js +0 -2
  48. package/dist/esm/AvoBatcher.js +0 -75
  49. package/dist/esm/AvoDeduplicator.js +0 -137
  50. package/dist/esm/AvoEncryption.js +0 -277
  51. package/dist/esm/AvoGuid.js +0 -9
  52. package/dist/esm/AvoInspector.js +0 -470
  53. package/dist/esm/AvoInspectorEnv.js +0 -5
  54. package/dist/esm/AvoNetworkCallsHandler.js +0 -181
  55. package/dist/esm/AvoSchemaParser.js +0 -128
  56. package/dist/esm/AvoStorage.js +0 -176
  57. package/dist/esm/AvoStreamId.js +0 -140
  58. package/dist/esm/eventSpec/AvoEventSpecCache.js +0 -165
  59. package/dist/esm/eventSpec/AvoEventSpecFetchTypes.js +0 -6
  60. package/dist/esm/eventSpec/AvoEventSpecFetcher.js +0 -203
  61. package/dist/esm/eventSpec/EventValidator.js +0 -687
  62. package/dist/esm/eventSpec/index.js +0 -4
  63. package/dist/esm/index.js +0 -3
  64. package/dist/esm/utils.js +0 -38
  65. package/dist/esm/version.js +0 -2
  66. package/dist/eventSpec/AvoEventSpecCache.js +0 -181
  67. package/dist/eventSpec/AvoEventSpecFetcher.js +0 -290
  68. package/dist/eventSpec/EventValidator.js +0 -846
  69. package/dist/eventSpec/index.js +0 -20
  70. package/dist/version.d.ts +0 -1
  71. package/dist/version.js +0 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "avo-inspector",
3
- "version": "3.2.3-alpha.1",
3
+ "version": "3.2.3",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "browser": "dist/index.js",
@@ -1,87 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AvoBatcher = void 0;
4
- var AvoInspector_1 = require("./AvoInspector");
5
- var AvoBatcher = /** @class */ (function () {
6
- function AvoBatcher(networkCallsHandler) {
7
- var _this = this;
8
- this.events = [];
9
- this.networkCallsHandler = networkCallsHandler;
10
- this.batchFlushAttemptTimestamp = Date.now();
11
- AvoInspector_1.AvoInspector.avoStorage
12
- .getItemAsync(AvoBatcher.cacheKey)
13
- .then(function (savedEvents) {
14
- if (savedEvents !== null) {
15
- var nonNullSavedEvents = savedEvents.filter(function (event) { return event !== null; });
16
- _this.events = _this.events.concat(nonNullSavedEvents);
17
- _this.checkIfBatchNeedsToBeSent();
18
- }
19
- })
20
- .catch(function (error) {
21
- if (AvoInspector_1.AvoInspector.shouldLog) {
22
- console.error("Avo Inspector: failed to load cached events.", error);
23
- }
24
- });
25
- }
26
- AvoBatcher.prototype.handleTrackSchema = function (eventName, schema, eventId, eventHash, eventProps) {
27
- var _this = this;
28
- this.networkCallsHandler.bodyForEventSchemaCall(eventName, schema, eventId, eventHash, eventProps).then(function (eventBody) {
29
- _this.events.push(eventBody);
30
- _this.saveEvents();
31
- if (AvoInspector_1.AvoInspector.shouldLog) {
32
- console.log("Avo Inspector: saved event " +
33
- eventName +
34
- " with schema " +
35
- JSON.stringify(schema));
36
- }
37
- _this.checkIfBatchNeedsToBeSent();
38
- }).catch(function (error) {
39
- console.error("Avo Inspector: failed to prepare event body for " + eventName + ".", error);
40
- });
41
- };
42
- AvoBatcher.prototype.checkIfBatchNeedsToBeSent = function () {
43
- var batchSize = this.events.length;
44
- var now = Date.now();
45
- var timeSinceLastFlushAttempt = now - this.batchFlushAttemptTimestamp;
46
- var sendBySize = batchSize % AvoInspector_1.AvoInspector.batchSize == 0;
47
- var sendByTime = timeSinceLastFlushAttempt >= AvoInspector_1.AvoInspector.batchFlushSeconds * 1000;
48
- var avoBatcher = this;
49
- if (sendBySize || sendByTime) {
50
- this.batchFlushAttemptTimestamp = now;
51
- var sendingEvents_1 = avoBatcher.events;
52
- avoBatcher.events = [];
53
- this.networkCallsHandler.callInspectorWithBatchBody(sendingEvents_1, function (error) {
54
- if (error != null) {
55
- avoBatcher.events = avoBatcher.events.concat(sendingEvents_1);
56
- if (AvoInspector_1.AvoInspector.shouldLog) {
57
- console.log("Avo Inspector: batch sending failed: " +
58
- error +
59
- ". We will attempt to send your schemas with next batch");
60
- }
61
- }
62
- else {
63
- if (AvoInspector_1.AvoInspector.shouldLog) {
64
- console.log("Avo Inspector: batch sent successfully.");
65
- }
66
- }
67
- avoBatcher.saveEvents();
68
- });
69
- }
70
- };
71
- AvoBatcher.prototype.saveEvents = function () {
72
- if (this.events.length > 1000) {
73
- var extraElements = this.events.length - 1000;
74
- this.events.splice(0, extraElements);
75
- }
76
- AvoInspector_1.AvoInspector.avoStorage.setItem(AvoBatcher.cacheKey, this.events);
77
- };
78
- Object.defineProperty(AvoBatcher, "cacheKey", {
79
- get: function () {
80
- return "AvoInspectorEvents";
81
- },
82
- enumerable: false,
83
- configurable: true
84
- });
85
- return AvoBatcher;
86
- }());
87
- exports.AvoBatcher = AvoBatcher;
@@ -1,142 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AvoDeduplicator = void 0;
4
- var AvoSchemaParser_1 = require("./AvoSchemaParser");
5
- var utils_1 = require("./utils");
6
- var AvoDeduplicator = /** @class */ (function () {
7
- function AvoDeduplicator() {
8
- this.avoFunctionsEvents = {};
9
- this.manualEvents = {};
10
- this.avoFunctionsEventsParams = {};
11
- this.manualEventsParams = {};
12
- }
13
- AvoDeduplicator.prototype.shouldRegisterEvent = function (eventName, params, fromAvoFunction) {
14
- this.clearOldEvents();
15
- if (fromAvoFunction) {
16
- this.avoFunctionsEvents[Date.now()] = eventName;
17
- this.avoFunctionsEventsParams[eventName] = params;
18
- }
19
- else {
20
- this.manualEvents[Date.now()] = eventName;
21
- this.manualEventsParams[eventName] = params;
22
- }
23
- var checkInAvoFunctions = !fromAvoFunction;
24
- return !this.hasSameEventAs(eventName, params, checkInAvoFunctions);
25
- };
26
- AvoDeduplicator.prototype.hasSameEventAs = function (eventName, params, checkInAvoFunctions) {
27
- var result = false;
28
- if (checkInAvoFunctions) {
29
- if (this.lookForEventIn(eventName, params, this.avoFunctionsEventsParams)) {
30
- result = true;
31
- }
32
- }
33
- else {
34
- if (this.lookForEventIn(eventName, params, this.manualEventsParams)) {
35
- result = true;
36
- }
37
- }
38
- if (result) {
39
- delete this.avoFunctionsEventsParams[eventName];
40
- delete this.manualEventsParams[eventName];
41
- }
42
- return result;
43
- };
44
- AvoDeduplicator.prototype.lookForEventIn = function (eventName, params, eventsStorage) {
45
- for (var otherEventName in eventsStorage) {
46
- if (eventsStorage.hasOwnProperty(otherEventName)) {
47
- if (otherEventName === eventName) {
48
- var otherParams = eventsStorage[eventName];
49
- if (otherParams && (0, utils_1.deepEquals)(params, otherParams)) {
50
- return true;
51
- }
52
- }
53
- }
54
- }
55
- return false;
56
- };
57
- AvoDeduplicator.prototype.hasSeenEventParams = function (params, checkInAvoFunctions) {
58
- var result = false;
59
- if (checkInAvoFunctions) {
60
- if (this.lookForEventParamsIn(params, this.avoFunctionsEventsParams)) {
61
- result = true;
62
- }
63
- }
64
- else {
65
- if (this.lookForEventParamsIn(params, this.manualEventsParams)) {
66
- result = true;
67
- }
68
- }
69
- return result;
70
- };
71
- AvoDeduplicator.prototype.lookForEventParamsIn = function (params, eventsStorage) {
72
- for (var otherEventName in eventsStorage) {
73
- if (eventsStorage.hasOwnProperty(otherEventName)) {
74
- var otherParams = eventsStorage[otherEventName];
75
- if (otherParams && (0, utils_1.deepEquals)(params, otherParams)) {
76
- return true;
77
- }
78
- }
79
- }
80
- return false;
81
- };
82
- AvoDeduplicator.prototype.shouldRegisterSchemaFromManually = function (eventName, eventSchema) {
83
- this.clearOldEvents();
84
- return !this.hasSameShapeInAvoFunctionsAs(eventName, eventSchema);
85
- };
86
- AvoDeduplicator.prototype.hasSameShapeInAvoFunctionsAs = function (eventName, eventSchema) {
87
- var result = false;
88
- if (this.lookForEventSchemaIn(eventName, eventSchema, this.avoFunctionsEventsParams)) {
89
- result = true;
90
- }
91
- if (result) {
92
- delete this.avoFunctionsEventsParams[eventName];
93
- }
94
- return result;
95
- };
96
- AvoDeduplicator.prototype.lookForEventSchemaIn = function (eventName, eventSchema, eventsStorage) {
97
- for (var otherEventName in eventsStorage) {
98
- if (eventsStorage.hasOwnProperty(otherEventName)) {
99
- if (otherEventName === eventName) {
100
- var otherSchema = AvoSchemaParser_1.AvoSchemaParser.extractSchema(eventsStorage[eventName]);
101
- if (otherSchema && (0, utils_1.deepEquals)(eventSchema, otherSchema)) {
102
- return true;
103
- }
104
- }
105
- }
106
- }
107
- return false;
108
- };
109
- AvoDeduplicator.prototype.clearOldEvents = function () {
110
- var now = Date.now();
111
- var msToConsiderOld = 300;
112
- for (var time in this.avoFunctionsEvents) {
113
- if (this.avoFunctionsEvents.hasOwnProperty(time)) {
114
- var timestamp = Number(time) || 0;
115
- if (now - timestamp > msToConsiderOld) {
116
- var eventName = this.avoFunctionsEvents[time];
117
- delete this.avoFunctionsEvents[time];
118
- delete this.avoFunctionsEventsParams[eventName];
119
- }
120
- }
121
- }
122
- for (var time in this.manualEvents) {
123
- if (this.manualEvents.hasOwnProperty(time)) {
124
- var timestamp = Number(time) || 0;
125
- if (now - timestamp > msToConsiderOld) {
126
- var eventName = this.manualEvents[time];
127
- delete this.manualEvents[time];
128
- delete this.manualEventsParams[eventName];
129
- }
130
- }
131
- }
132
- };
133
- // used in tests
134
- AvoDeduplicator.prototype._clearEvents = function () {
135
- this.avoFunctionsEvents = {};
136
- this.manualEvents = {};
137
- this.avoFunctionsEventsParams = {};
138
- this.manualEventsParams = {};
139
- };
140
- return AvoDeduplicator;
141
- }());
142
- exports.AvoDeduplicator = AvoDeduplicator;
@@ -1,176 +0,0 @@
1
- "use strict";
2
- /**
3
- * AvoEncryption — React Native ECIES encryption using @noble/ciphers.
4
- *
5
- * CRITICAL: React Native's Hermes runtime does NOT have crypto.subtle.
6
- * This module uses @noble/ciphers/aes gcm() for AES-GCM instead — fully synchronous.
7
- * Ephemeral key generation and ECDH use @noble/curves/p256.
8
- *
9
- * Wire format (MUST match all SDKs):
10
- * [0x00][65-byte ephemeral pubkey (uncompressed)][16-byte IV][16-byte auth tag][ciphertext]
11
- * → base64
12
- *
13
- * Algorithm:
14
- * 1. Generate ephemeral P-256 key pair
15
- * 2. ECDH: ephemeral private key + recipient public key → shared secret (X-coordinate)
16
- * 3. KDF: SHA-256(shared secret) → 32-byte AES key
17
- * 4. AES-256-GCM encrypt with random 16-byte IV
18
- * 5. Serialize: version(1) + ephemeralPubKey(65) + IV(16) + authTag(16) + ciphertext
19
- * 6. Base64 encode
20
- */
21
- Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.shouldEncrypt = shouldEncrypt;
23
- exports.encryptValue = encryptValue;
24
- exports.encryptEventProperties = encryptEventProperties;
25
- var p256_1 = require("@noble/curves/p256");
26
- var aes_1 = require("@noble/ciphers/aes");
27
- var sha256_1 = require("@noble/hashes/sha256");
28
- var webcrypto_1 = require("@noble/ciphers/webcrypto");
29
- /**
30
- * Converts a hex string to a Uint8Array.
31
- * Strips optional 0x/0X prefix (matching Android SDK behavior).
32
- */
33
- function hexToBytes(hex) {
34
- if (hex.startsWith("0x") || hex.startsWith("0X")) {
35
- hex = hex.substring(2);
36
- }
37
- var bytes = new Uint8Array(hex.length / 2);
38
- for (var i = 0; i < hex.length; i += 2) {
39
- bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);
40
- }
41
- return bytes;
42
- }
43
- /**
44
- * Determines whether encryption should be performed.
45
- *
46
- * Truth table:
47
- * dev + key → true
48
- * staging + key → true
49
- * prod + key → false
50
- * dev + null → false
51
- * dev + empty → false
52
- */
53
- function shouldEncrypt(env, publicEncryptionKey) {
54
- if (env === "prod")
55
- return false;
56
- if (publicEncryptionKey === null ||
57
- publicEncryptionKey === undefined ||
58
- publicEncryptionKey.trim().length === 0) {
59
- return false;
60
- }
61
- return true;
62
- }
63
- /**
64
- * Encrypts a value using ECIES (P-256 ECDH + AES-256-GCM).
65
- * Fully synchronous — no async/await.
66
- *
67
- * @param value - The plaintext string to encrypt (already JSON-stringified by caller if needed)
68
- * @param publicKeyHex - The recipient's P-256 public key as a hex string (uncompressed, 04...)
69
- * @returns Base64-encoded ciphertext in Avo ECIES wire format
70
- */
71
- function encryptValue(value, publicKeyHex) {
72
- // Fail fast with a helpful message when running in React Native without the polyfill.
73
- // Node.js and browsers provide crypto natively; only Hermes (RN) lacks it.
74
- if (!process.env.BROWSER &&
75
- typeof navigator !== "undefined" && navigator.product === "ReactNative" &&
76
- (typeof globalThis.crypto === "undefined" || typeof globalThis.crypto.getRandomValues !== "function")) {
77
- throw new Error("crypto.getRandomValues is not available. " +
78
- "If you are using React Native, add 'react-native-get-random-values' to your project " +
79
- "and import it at the top of your entry file (index.js) before any other imports: " +
80
- "import 'react-native-get-random-values';");
81
- }
82
- // 1. Parse recipient public key from hex
83
- var recipientPublicKeyBytes = hexToBytes(publicKeyHex);
84
- // 2. Generate ephemeral P-256 key pair
85
- var ephemeralPrivateKeyBytes = p256_1.p256.utils.randomPrivateKey();
86
- var ephemeralPublicKeyBytes = p256_1.p256.getPublicKey(ephemeralPrivateKeyBytes, false // uncompressed = 65 bytes (0x04 + 32-byte X + 32-byte Y)
87
- );
88
- // 3. ECDH: compute shared secret
89
- // getSharedSecret returns the full point; extract X-coordinate (last 32 bytes)
90
- var sharedSecretPoint = p256_1.p256.getSharedSecret(ephemeralPrivateKeyBytes, recipientPublicKeyBytes);
91
- var sharedSecret = sharedSecretPoint.slice(-32);
92
- // 4. KDF: SHA-256(sharedSecret) → 32-byte AES key
93
- var aesKey = (0, sha256_1.sha256)(sharedSecret);
94
- // 5. Generate random 16-byte IV
95
- var iv = (0, webcrypto_1.randomBytes)(16);
96
- // 6. AES-256-GCM encrypt
97
- var plaintext = new TextEncoder().encode(value);
98
- var aes = (0, aes_1.gcm)(aesKey, iv);
99
- var ciphertextWithTag = aes.encrypt(plaintext);
100
- // @noble/ciphers gcm() returns ciphertext + authTag concatenated
101
- // Split the LAST 16 bytes as the auth tag
102
- var authTagLength = 16;
103
- var ciphertextLength = ciphertextWithTag.length - authTagLength;
104
- var ciphertext = ciphertextWithTag.slice(0, ciphertextLength);
105
- var authTag = ciphertextWithTag.slice(ciphertextLength);
106
- // 7. Serialize: [Version 0x00 (1B)] + [EphemeralPubKey (65B)] + [IV (16B)] + [AuthTag (16B)] + [Ciphertext]
107
- var resultLength = 1 + ephemeralPublicKeyBytes.length + 16 + 16 + ciphertext.length;
108
- var result = new Uint8Array(resultLength);
109
- var offset = 0;
110
- result[0] = 0x00; // Version byte
111
- offset += 1;
112
- result.set(ephemeralPublicKeyBytes, offset);
113
- offset += ephemeralPublicKeyBytes.length;
114
- result.set(iv, offset);
115
- offset += 16;
116
- result.set(authTag, offset);
117
- offset += 16;
118
- result.set(ciphertext, offset);
119
- // 8. Base64 encode (platform-safe: avoids Buffer which is unavailable in Hermes/React Native)
120
- var binary = "";
121
- for (var i = 0; i < result.length; i++) {
122
- binary += String.fromCharCode(result[i]);
123
- }
124
- return btoa(binary);
125
- }
126
- /**
127
- * Encrypts event property values for transmission.
128
- *
129
- * Rules:
130
- * - List-type properties are omitted entirely
131
- * - On encryption failure: console.warn, omit the property, continue
132
- * - Returns new array with encryptedPropertyValue set (propertyType/propertyName preserved)
133
- */
134
- function encryptEventProperties(properties, eventProps, publicKeyHex) {
135
- var result = [];
136
- var encryptionFailed = false;
137
- for (var _i = 0, properties_1 = properties; _i < properties_1.length; _i++) {
138
- var prop = properties_1[_i];
139
- // Omit list-type properties entirely
140
- if (prop.propertyType === "list") {
141
- continue;
142
- }
143
- // If encryption already failed for this batch, skip remaining properties
144
- // to avoid spamming the console with the same error
145
- if (encryptionFailed) {
146
- continue;
147
- }
148
- try {
149
- var value = eventProps[prop.propertyName];
150
- var jsonValue = JSON.stringify(value === undefined ? null : value);
151
- var encrypted = encryptValue(jsonValue, publicKeyHex);
152
- var entry = {
153
- propertyName: prop.propertyName,
154
- propertyType: prop.propertyType,
155
- encryptedPropertyValue: encrypted,
156
- };
157
- // Preserve children if present
158
- if (prop.children !== undefined) {
159
- entry.children = prop.children;
160
- }
161
- // Preserve validation fields if present
162
- if (prop.failedEventIds !== undefined) {
163
- entry.failedEventIds = prop.failedEventIds;
164
- }
165
- if (prop.passedEventIds !== undefined) {
166
- entry.passedEventIds = prop.passedEventIds;
167
- }
168
- result.push(entry);
169
- }
170
- catch (e) {
171
- encryptionFailed = true;
172
- console.warn("[Avo Inspector] Encryption failed: ".concat(e instanceof Error ? e.message : String(e), ". Remaining event properties will be omitted from the encrypted payload."));
173
- }
174
- }
175
- return result;
176
- }