avo-inspector 2.2.2-alpha → 2.2.2-alpha.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.
- package/.claude/settings.local.json +18 -0
- package/README.md +38 -3
- package/bin/avo-inspector.js +78 -26
- package/dist/AvoBatcher.d.ts +3 -12
- package/dist/AvoInspector.d.ts +13 -7
- package/dist/AvoNetworkCallsHandler.d.ts +28 -21
- package/dist/AvoSchemaParser.d.ts +2 -6
- package/dist/AvoStreamId.d.ts +58 -0
- package/dist/eventSpec/AvoEventSpecCache.d.ts +2 -1
- package/dist/eventSpec/AvoEventSpecFetchTypes.d.ts +103 -65
- package/dist/eventSpec/AvoEventSpecFetcher.d.ts +11 -5
- package/dist/eventSpec/EventValidator.d.ts +16 -72
- package/dist/eventSpec/fetcher.d.ts +52 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/browser.js.LICENSE.txt +0 -5
- package/dist-browser/AvoAnonymousId.d.ts +0 -26
- package/dist-browser/AvoBatcher.d.ts +0 -26
- package/dist-browser/AvoDeduplicator.d.ts +0 -20
- package/dist-browser/AvoEncryption.d.ts +0 -33
- package/dist-browser/AvoGuid.d.ts +0 -3
- package/dist-browser/AvoInspector.d.ts +0 -78
- package/dist-browser/AvoInspectorEnv.d.ts +0 -7
- package/dist-browser/AvoNetworkCallsHandler.d.ts +0 -74
- package/dist-browser/AvoSchemaParser.d.ts +0 -20
- package/dist-browser/AvoStorage.d.ts +0 -22
- package/dist-browser/__mocks__/xhr.d.ts +0 -12
- package/dist-browser/__mocks__/xhrError.d.ts +0 -12
- package/dist-browser/__tests__/AnonymousId_test.d.ts +0 -1
- package/dist-browser/__tests__/AvoEncryption_test.d.ts +0 -1
- package/dist-browser/__tests__/AvoInspectorEventSpec_test.d.ts +0 -1
- package/dist-browser/__tests__/AvoInspector_test.d.ts +0 -1
- package/dist-browser/__tests__/BatcherPublic_test.d.ts +0 -1
- package/dist-browser/__tests__/Batcher_test.d.ts +0 -1
- package/dist-browser/__tests__/Deduplicator_test.d.ts +0 -1
- package/dist-browser/__tests__/EncryptedPropertyTracking_test.d.ts +0 -1
- package/dist-browser/__tests__/EventSpecCache_test.d.ts +0 -1
- package/dist-browser/__tests__/EventSpecFetcher_test.d.ts +0 -1
- package/dist-browser/__tests__/EventValidator_test.d.ts +0 -1
- package/dist-browser/__tests__/NetworkCallsHandler_test.d.ts +0 -1
- package/dist-browser/__tests__/Parsing_test.d.ts +0 -1
- package/dist-browser/__tests__/Storage_test.d.ts +0 -1
- package/dist-browser/__tests__/ValidationIntegration_test.d.ts +0 -1
- package/dist-browser/__tests__/constants.d.ts +0 -36
- package/dist-browser/__tests__/helpers/encryptionHelpers.d.ts +0 -13
- package/dist-browser/__tests__/helpers/mockFactories.d.ts +0 -49
- package/dist-browser/eventSpec/AvoEventSpecCache.d.ts +0 -73
- package/dist-browser/eventSpec/AvoEventSpecFetchTypes.d.ts +0 -109
- package/dist-browser/eventSpec/AvoEventSpecFetcher.d.ts +0 -55
- package/dist-browser/eventSpec/EventValidator.d.ts +0 -90
- package/dist-browser/eventSpec/index.d.ts +0 -4
- package/dist-browser/index.d.ts +0 -2
- package/dist-browser/utils.d.ts +0 -3
- package/dist-native/AvoBatcher.d.ts +0 -24
- package/dist-native/AvoBatcher.js +0 -82
- package/dist-native/AvoDeduplicator.d.ts +0 -36
- package/dist-native/AvoDeduplicator.js +0 -142
- package/dist-native/AvoGuid.d.ts +0 -3
- package/dist-native/AvoGuid.js +0 -14
- package/dist-native/AvoInspector.d.ts +0 -52
- package/dist-native/AvoInspector.js +0 -220
- package/dist-native/AvoInspectorEnv.d.ts +0 -7
- package/dist-native/AvoInspectorEnv.js +0 -8
- package/dist-native/AvoInstallationId.d.ts +0 -5
- package/dist-native/AvoInstallationId.js +0 -36
- package/dist-native/AvoNetworkCallsHandler.d.ts +0 -48
- package/dist-native/AvoNetworkCallsHandler.js +0 -142
- package/dist-native/AvoSchemaParser.d.ts +0 -11
- package/dist-native/AvoSchemaParser.js +0 -95
- package/dist-native/AvoSessionTracker.d.ts +0 -15
- package/dist-native/AvoSessionTracker.js +0 -104
- package/dist-native/AvoStorage.d.ts +0 -22
- package/dist-native/AvoStorage.js +0 -336
- package/dist-native/__mocks__/xhr.d.ts +0 -12
- package/dist-native/__mocks__/xhr.js +0 -14
- package/dist-native/__mocks__/xhrError.d.ts +0 -12
- package/dist-native/__mocks__/xhrError.js +0 -14
- package/dist-native/__tests__/AvoInspector.d.ts +0 -1
- package/dist-native/__tests__/AvoInspector.js +0 -207
- package/dist-native/__tests__/Batcher.d.ts +0 -1
- package/dist-native/__tests__/Batcher.js +0 -280
- package/dist-native/__tests__/BatcherPublic.d.ts +0 -1
- package/dist-native/__tests__/BatcherPublic.js +0 -82
- package/dist-native/__tests__/Deduplicator.d.ts +0 -1
- package/dist-native/__tests__/Deduplicator.js +0 -111
- package/dist-native/__tests__/InstallationId.d.ts +0 -1
- package/dist-native/__tests__/InstallationId.js +0 -40
- package/dist-native/__tests__/NetworkCallsHandler.d.ts +0 -1
- package/dist-native/__tests__/NetworkCallsHandler.js +0 -132
- package/dist-native/__tests__/Parsing.d.ts +0 -1
- package/dist-native/__tests__/Parsing.js +0 -115
- package/dist-native/__tests__/Sessions.d.ts +0 -1
- package/dist-native/__tests__/Sessions.js +0 -179
- package/dist-native/__tests__/Storage.d.ts +0 -1
- package/dist-native/__tests__/Storage.js +0 -173
- package/dist-native/__tests__/constants.d.ts +0 -36
- package/dist-native/__tests__/constants.js +0 -47
- package/dist-native/index.d.ts +0 -2
- package/dist-native/index.js +0 -7
- package/dist-native/utils.d.ts +0 -3
- package/dist-native/utils.js +0 -42
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(npm test)",
|
|
5
|
+
"Bash(npm test:*)",
|
|
6
|
+
"Bash(npm run build:*)",
|
|
7
|
+
"Bash(yarn typecheck:*)",
|
|
8
|
+
"Bash(yarn test:*)",
|
|
9
|
+
"Bash(yarn build)",
|
|
10
|
+
"WebSearch",
|
|
11
|
+
"Bash(node -e:*)",
|
|
12
|
+
"Bash(git add:*)",
|
|
13
|
+
"mcp__linear__list_issues"
|
|
14
|
+
],
|
|
15
|
+
"deny": [],
|
|
16
|
+
"ask": []
|
|
17
|
+
}
|
|
18
|
+
}
|
package/README.md
CHANGED
|
@@ -123,7 +123,7 @@ This will output:
|
|
|
123
123
|
|
|
124
124
|
## Using Encryption
|
|
125
125
|
|
|
126
|
-
Pass the `
|
|
126
|
+
Pass the `publicEncryptionKey` parameter when initializing Inspector:
|
|
127
127
|
|
|
128
128
|
```javascript
|
|
129
129
|
import * as Inspector from "avo-inspector";
|
|
@@ -148,7 +148,7 @@ When encryption is enabled:
|
|
|
148
148
|
|
|
149
149
|
# Client-Side Validation (Dev/Staging Only)
|
|
150
150
|
|
|
151
|
-
When initialized with a `
|
|
151
|
+
When initialized with a `publicEncryptionKey` in dev or staging environments, Inspector performs client-side validation of your events against your Avo Tracking Plan.
|
|
152
152
|
|
|
153
153
|
## How It Works
|
|
154
154
|
|
|
@@ -186,13 +186,48 @@ inspector.trackSchemaFromEvent("User Signed Up", { name: "John" });
|
|
|
186
186
|
The `trackSchema` method only sends pre-extracted schemas and **does not perform client-side validation** - it goes through the normal batching flow.
|
|
187
187
|
|
|
188
188
|
```javascript
|
|
189
|
-
// ✅ Validates against tracking plan (when
|
|
189
|
+
// ✅ Validates against tracking plan (when publicEncryptionKey is provided)
|
|
190
190
|
inspector.trackSchemaFromEvent("Event Name", { prop: "value" });
|
|
191
191
|
|
|
192
192
|
// ❌ Does NOT validate - only sends schema, uses batching
|
|
193
193
|
inspector.trackSchema("Event Name", [{ propertyName: "prop", propertyType: "string" }]);
|
|
194
194
|
```
|
|
195
195
|
|
|
196
|
+
## Accessing Validation Results
|
|
197
|
+
|
|
198
|
+
`trackSchemaFromEvent` returns a `Promise<EventProperty[]>` that resolves with the validated properties. You can use this in two ways:
|
|
199
|
+
|
|
200
|
+
### Fire-and-Forget (Default)
|
|
201
|
+
|
|
202
|
+
Call without `await` for non-blocking behavior. The event is tracked asynchronously and validation happens in the background:
|
|
203
|
+
|
|
204
|
+
```javascript
|
|
205
|
+
// Non-blocking - validation runs in background
|
|
206
|
+
inspector.trackSchemaFromEvent("Event Name", { prop: "value" });
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Await for Validation Results
|
|
210
|
+
|
|
211
|
+
If you need to access validation results (e.g., for testing or debugging), you can `await` the call:
|
|
212
|
+
|
|
213
|
+
```javascript
|
|
214
|
+
// Blocking - wait for validation to complete
|
|
215
|
+
const validatedProperties = await inspector.trackSchemaFromEvent("Event Name", {
|
|
216
|
+
email: "user@example.com",
|
|
217
|
+
age: 25
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Each property includes validation results:
|
|
221
|
+
// {
|
|
222
|
+
// propertyName: "email",
|
|
223
|
+
// propertyType: "string",
|
|
224
|
+
// failedEventIds: [], // Event IDs where this property failed validation
|
|
225
|
+
// passedEventIds: ["abc123"] // Event IDs where this property passed validation
|
|
226
|
+
// }
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**Note:** Awaiting will block until the event spec is fetched (if not cached) and validation completes. For production use, fire-and-forget is recommended to avoid impacting your application's performance.
|
|
230
|
+
|
|
196
231
|
# Batching control
|
|
197
232
|
|
|
198
233
|
In order to ensure our SDK doesn't have a large impact on performance or battery life it supports event schemas batching.
|
package/bin/avo-inspector.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
// Use eciesjs directly for ECC key generation
|
|
4
4
|
const { PrivateKey } = require('eciesjs');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
5
7
|
|
|
6
8
|
function generateKeyPair() {
|
|
7
9
|
// Generate a new random private key (32 bytes / 256 bits)
|
|
@@ -17,6 +19,7 @@ function generateKeyPair() {
|
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
const command = process.argv[2];
|
|
22
|
+
const outputFlag = process.argv[3];
|
|
20
23
|
|
|
21
24
|
function showHelp() {
|
|
22
25
|
console.log(`
|
|
@@ -25,18 +28,24 @@ function showHelp() {
|
|
|
25
28
|
╚═══════════════════════════════════════════════════════════════╝
|
|
26
29
|
|
|
27
30
|
Usage:
|
|
28
|
-
npx avo-inspector <command>
|
|
31
|
+
npx avo-inspector <command> [options]
|
|
29
32
|
|
|
30
33
|
Commands:
|
|
31
|
-
generate-keys
|
|
32
|
-
help
|
|
34
|
+
generate-keys Generate ECC key pair for property encryption
|
|
35
|
+
help Show this help message
|
|
36
|
+
|
|
37
|
+
Options:
|
|
38
|
+
--output, -o Write keys to files instead of stdout
|
|
39
|
+
Creates: avo-public.key and avo-private.key
|
|
33
40
|
|
|
34
41
|
Examples:
|
|
35
|
-
npx avo-inspector generate-keys
|
|
42
|
+
npx avo-inspector generate-keys # Print keys to console
|
|
43
|
+
npx avo-inspector generate-keys --output # Write keys to files
|
|
44
|
+
npx avo-inspector generate-keys -o # Write keys to files (short form)
|
|
36
45
|
`);
|
|
37
46
|
}
|
|
38
47
|
|
|
39
|
-
function generateKeys() {
|
|
48
|
+
function generateKeys(writeToFiles = false) {
|
|
40
49
|
console.log(`
|
|
41
50
|
╔═══════════════════════════════════════════════════════════════╗
|
|
42
51
|
║ Generating ECC Key Pair (secp256k1)... ║
|
|
@@ -46,26 +55,68 @@ function generateKeys() {
|
|
|
46
55
|
try {
|
|
47
56
|
const { publicKey, privateKey } = generateKeyPair();
|
|
48
57
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
58
|
+
if (writeToFiles) {
|
|
59
|
+
// Write keys to files instead of printing to console
|
|
60
|
+
const publicKeyPath = path.join(process.cwd(), 'avo-public.key');
|
|
61
|
+
const privateKeyPath = path.join(process.cwd(), 'avo-private.key');
|
|
62
|
+
|
|
63
|
+
// Check if files already exist
|
|
64
|
+
if (fs.existsSync(publicKeyPath) || fs.existsSync(privateKeyPath)) {
|
|
65
|
+
console.error('❌ Error: Key files already exist in current directory.');
|
|
66
|
+
console.error(' Delete avo-public.key and avo-private.key first, or use a different directory.\n');
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Write public key
|
|
71
|
+
fs.writeFileSync(publicKeyPath, publicKey + '\n', { mode: 0o644 });
|
|
72
|
+
console.log(`✅ Public key written to: ${publicKeyPath}`);
|
|
73
|
+
|
|
74
|
+
// Write private key with restrictive permissions (owner read/write only)
|
|
75
|
+
fs.writeFileSync(privateKeyPath, privateKey + '\n', { mode: 0o600 });
|
|
76
|
+
console.log(`✅ Private key written to: ${privateKeyPath}`);
|
|
77
|
+
|
|
78
|
+
console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
79
|
+
console.log('⚠️ IMPORTANT: Add avo-private.key to your .gitignore!\n');
|
|
80
|
+
console.log(' echo "avo-private.key" >> .gitignore\n');
|
|
81
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
82
|
+
console.log('📝 Next Steps:\n');
|
|
83
|
+
console.log('1. Use the PUBLIC KEY in your SDK initialization:\n');
|
|
84
|
+
console.log(' const inspector = new AvoInspector({');
|
|
85
|
+
console.log(' apiKey: "your-api-key",');
|
|
86
|
+
console.log(' env: AvoInspectorEnv.Dev,');
|
|
87
|
+
console.log(' version: "1.0.0",');
|
|
88
|
+
console.log(' publicKey: fs.readFileSync("avo-public.key", "utf8").trim()');
|
|
89
|
+
console.log(' });\n');
|
|
90
|
+
console.log('2. Store avo-private.key securely (password manager, vault, etc.)');
|
|
91
|
+
console.log(' - The SDK never uses the private key');
|
|
92
|
+
console.log(' - You only need it to decrypt values in Avo\'s dashboard\n');
|
|
93
|
+
} else {
|
|
94
|
+
// Print keys to console (original behavior)
|
|
95
|
+
console.log('✅ Key pair generated successfully!\n');
|
|
96
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
97
|
+
console.log('📋 PUBLIC KEY (safe to share with Avo SDK):\n');
|
|
98
|
+
console.log(publicKey);
|
|
99
|
+
console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
100
|
+
console.log('🔐 PRIVATE KEY (⚠️ KEEP SECURE - DO NOT COMMIT TO GIT):\n');
|
|
101
|
+
console.log(privateKey);
|
|
102
|
+
console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
103
|
+
console.log('💡 TIP: Use --output flag to write keys to files instead:\n');
|
|
104
|
+
console.log(' npx avo-inspector generate-keys --output\n');
|
|
105
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
106
|
+
console.log('📝 Next Steps:\n');
|
|
107
|
+
console.log('1. Use the PUBLIC KEY in your SDK initialization:\n');
|
|
108
|
+
console.log(' const inspector = new AvoInspector({');
|
|
109
|
+
console.log(' apiKey: "your-api-key",');
|
|
110
|
+
console.log(' env: AvoInspectorEnv.Dev,');
|
|
111
|
+
console.log(' version: "1.0.0",');
|
|
112
|
+
console.log(' publicKey: "<paste public key above>"');
|
|
113
|
+
console.log(' });\n');
|
|
114
|
+
console.log(' 💡 The public key is not a secret - you can hardcode it or use .env\n');
|
|
115
|
+
console.log('2. Save the PRIVATE KEY externally (password manager, secure notes)');
|
|
116
|
+
console.log(' - The SDK never uses the private key');
|
|
117
|
+
console.log(' - You only need it to decrypt values in Avo\'s dashboard\n');
|
|
118
|
+
}
|
|
119
|
+
|
|
69
120
|
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
70
121
|
console.log('ℹ️ Note: Property encryption only works in dev/staging environments.');
|
|
71
122
|
console.log(' Production data is never encrypted for performance.\n');
|
|
@@ -78,7 +129,8 @@ function generateKeys() {
|
|
|
78
129
|
// Main command router
|
|
79
130
|
switch (command) {
|
|
80
131
|
case 'generate-keys':
|
|
81
|
-
|
|
132
|
+
const writeToFiles = outputFlag === '--output' || outputFlag === '-o';
|
|
133
|
+
generateKeys(writeToFiles);
|
|
82
134
|
break;
|
|
83
135
|
case 'help':
|
|
84
136
|
case '--help':
|
package/dist/AvoBatcher.d.ts
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
import { type AvoNetworkCallsHandler } from "./AvoNetworkCallsHandler";
|
|
1
|
+
import { type AvoNetworkCallsHandler, type EventProperty } from "./AvoNetworkCallsHandler";
|
|
2
2
|
import type { EventSpecMetadata } from "./eventSpec/AvoEventSpecFetchTypes";
|
|
3
|
-
import type { ValidationIssue } from "./eventSpec/EventValidator";
|
|
4
3
|
export interface AvoBatcherType {
|
|
5
4
|
handleSessionStarted: () => void;
|
|
6
|
-
handleTrackSchema: (eventName: string, schema:
|
|
7
|
-
propertyName: string;
|
|
8
|
-
propertyType: string;
|
|
9
|
-
children?: any;
|
|
10
|
-
}>, eventId: string | null, eventHash: string | null, variantId?: string | null, eventSpecMetadata?: EventSpecMetadata, validationErrors?: ValidationIssue[]) => void;
|
|
5
|
+
handleTrackSchema: (eventName: string, schema: EventProperty[], eventId: string | null, eventHash: string | null, eventSpecMetadata?: EventSpecMetadata) => void;
|
|
11
6
|
}
|
|
12
7
|
export declare class AvoBatcher implements AvoBatcherType {
|
|
13
8
|
private events;
|
|
@@ -15,11 +10,7 @@ export declare class AvoBatcher implements AvoBatcherType {
|
|
|
15
10
|
private readonly networkCallsHandler;
|
|
16
11
|
constructor(networkCallsHandler: AvoNetworkCallsHandler);
|
|
17
12
|
handleSessionStarted(): void;
|
|
18
|
-
handleTrackSchema(eventName: string, schema:
|
|
19
|
-
propertyName: string;
|
|
20
|
-
propertyType: string;
|
|
21
|
-
children?: any;
|
|
22
|
-
}>, eventId: string | null, eventHash: string | null, variantId?: string | null, eventSpecMetadata?: EventSpecMetadata, validationErrors?: ValidationIssue[]): void;
|
|
13
|
+
handleTrackSchema(eventName: string, schema: EventProperty[], eventId: string | null, eventHash: string | null, eventSpecMetadata?: EventSpecMetadata): void;
|
|
23
14
|
private checkIfBatchNeedsToBeSent;
|
|
24
15
|
private saveEvents;
|
|
25
16
|
static get cacheKey(): string;
|
package/dist/AvoInspector.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type AvoInspectorEnvValueType } from "./AvoInspectorEnv";
|
|
2
2
|
import { AvoBatcher } from "./AvoBatcher";
|
|
3
|
+
import { type EventProperty } from "./AvoNetworkCallsHandler";
|
|
3
4
|
import { AvoStorage } from "./AvoStorage";
|
|
4
5
|
import { AvoDeduplicator } from "./AvoDeduplicator";
|
|
5
6
|
export declare class AvoInspector {
|
|
@@ -33,12 +34,7 @@ export declare class AvoInspector {
|
|
|
33
34
|
suffix?: string;
|
|
34
35
|
publicEncryptionKey?: string;
|
|
35
36
|
});
|
|
36
|
-
trackSchemaFromEvent(eventName: string, eventProperties: Record<string, any>): Promise<
|
|
37
|
-
propertyName: string;
|
|
38
|
-
propertyType: string;
|
|
39
|
-
encryptedPropertyValue?: string;
|
|
40
|
-
children?: any;
|
|
41
|
-
}>>;
|
|
37
|
+
trackSchemaFromEvent(eventName: string, eventProperties: Record<string, any>): Promise<EventProperty[]>;
|
|
42
38
|
private _avoFunctionTrackSchemaFromEvent;
|
|
43
39
|
trackSchema(eventName: string, eventSchema: Array<{
|
|
44
40
|
propertyName: string;
|
|
@@ -70,9 +66,19 @@ export declare class AvoInspector {
|
|
|
70
66
|
* Note: EventSpec fetching and validation only happens in dev/staging environments.
|
|
71
67
|
*/
|
|
72
68
|
private fetchAndValidateEvent;
|
|
69
|
+
/**
|
|
70
|
+
* Merges validation results into the event schema.
|
|
71
|
+
* Adds failedEventIds or passedEventIds to each property based on validation.
|
|
72
|
+
* Recursively merges validation results for nested children.
|
|
73
|
+
*/
|
|
74
|
+
private mergeValidationResults;
|
|
75
|
+
/**
|
|
76
|
+
* Merges validation result into a single property, recursively handling children.
|
|
77
|
+
*/
|
|
78
|
+
private mergePropertyValidation;
|
|
73
79
|
/**
|
|
74
80
|
* Sends an event immediately with validation data (bypasses batching).
|
|
75
|
-
* Logs validation
|
|
81
|
+
* Logs validation info if shouldLog is true.
|
|
76
82
|
*/
|
|
77
83
|
private sendEventWithValidation;
|
|
78
84
|
}
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
import type { EventSpecMetadata } from "./eventSpec/AvoEventSpecFetchTypes";
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Recursive type for schema children.
|
|
4
|
+
* - For object properties: array of EventProperty objects
|
|
5
|
+
* - For list properties: array of strings (primitive types) or nested structures
|
|
6
|
+
*/
|
|
7
|
+
export type SchemaChild = string | EventProperty | SchemaChild[];
|
|
8
|
+
/**
|
|
9
|
+
* Property schema with optional validation results.
|
|
10
|
+
*/
|
|
11
|
+
export interface EventProperty {
|
|
12
|
+
propertyName: string;
|
|
13
|
+
propertyType: string;
|
|
14
|
+
encryptedPropertyValue?: string;
|
|
15
|
+
children?: SchemaChild[];
|
|
16
|
+
/** Event/variant IDs that FAILED validation (present if smaller or equal to passed) */
|
|
17
|
+
failedEventIds?: string[];
|
|
18
|
+
/** Event/variant IDs that PASSED validation (present if smaller than failed) */
|
|
19
|
+
passedEventIds?: string[];
|
|
20
|
+
}
|
|
3
21
|
export interface BaseBody {
|
|
4
22
|
apiKey: string;
|
|
5
23
|
appName: string;
|
|
@@ -11,32 +29,25 @@ export interface BaseBody {
|
|
|
11
29
|
trackingId: string;
|
|
12
30
|
createdAt: string;
|
|
13
31
|
sessionId: string;
|
|
14
|
-
|
|
32
|
+
streamId: string;
|
|
15
33
|
samplingRate: number;
|
|
34
|
+
/** Event spec metadata from EventSpecResponse (moved from EventSchemaBody) */
|
|
35
|
+
eventSpecMetadata?: EventSpecMetadata;
|
|
16
36
|
}
|
|
17
37
|
export interface SessionStartedBody extends BaseBody {
|
|
18
38
|
type: "sessionStarted";
|
|
19
39
|
}
|
|
20
40
|
export interface EventSchemaBody extends BaseBody {
|
|
21
41
|
type: "event";
|
|
22
|
-
/** ID of the
|
|
42
|
+
/** ID of the base event from spec (null if no spec available) */
|
|
23
43
|
eventId: string | null;
|
|
24
|
-
/** ID of the matched variant (if any) */
|
|
25
|
-
variantId?: string | null;
|
|
26
44
|
/** Name seen in code */
|
|
27
45
|
eventName?: string;
|
|
28
|
-
|
|
29
|
-
eventSpecMetadata?: EventSpecMetadata;
|
|
30
|
-
/** Array of validation issues found during validation */
|
|
31
|
-
validationErrors?: ValidationIssue[];
|
|
32
|
-
eventProperties: Array<{
|
|
33
|
-
propertyName: string;
|
|
34
|
-
propertyType: string;
|
|
35
|
-
encryptedPropertyValue?: string;
|
|
36
|
-
children?: any;
|
|
37
|
-
}>;
|
|
46
|
+
eventProperties: EventProperty[];
|
|
38
47
|
avoFunction: boolean;
|
|
39
48
|
eventHash: string | null;
|
|
49
|
+
/** Branch ID from getEventSpec response when value validation was performed */
|
|
50
|
+
validatedBranchId?: string;
|
|
40
51
|
}
|
|
41
52
|
export declare class AvoNetworkCallsHandler {
|
|
42
53
|
private readonly apiKey;
|
|
@@ -49,13 +60,9 @@ export declare class AvoNetworkCallsHandler {
|
|
|
49
60
|
private static readonly trackingEndpoint;
|
|
50
61
|
constructor(apiKey: string, envName: string, appName: string, appVersion: string, libVersion: string);
|
|
51
62
|
callInspectorWithBatchBody(inEvents: Array<SessionStartedBody | EventSchemaBody>, onCompleted: (error: Error | null) => any): void;
|
|
52
|
-
private
|
|
63
|
+
private fixStreamIds;
|
|
53
64
|
bodyForSessionStartedCall(): SessionStartedBody;
|
|
54
|
-
bodyForEventSchemaCall(eventName: string, eventProperties:
|
|
55
|
-
propertyName: string;
|
|
56
|
-
propertyType: string;
|
|
57
|
-
children?: any;
|
|
58
|
-
}>, eventId: string | null, eventHash: string | null, variantId?: string | null, eventSpecMetadata?: EventSpecMetadata, validationErrors?: ValidationIssue[]): EventSchemaBody;
|
|
65
|
+
bodyForEventSchemaCall(eventName: string, eventProperties: EventProperty[], eventId: string | null, eventHash: string | null, eventSpecMetadata?: EventSpecMetadata, validatedBranchId?: string): EventSchemaBody;
|
|
59
66
|
private createBaseCallBody;
|
|
60
67
|
/**
|
|
61
68
|
* Calls Inspector API immediately with a single event (bypasses batching).
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { EventProperty } from "./AvoNetworkCallsHandler";
|
|
1
2
|
export declare class AvoSchemaParser {
|
|
2
3
|
/**
|
|
3
4
|
* Returns true only if we have a valid encryption key and can send encrypted values.
|
|
@@ -9,12 +10,7 @@ export declare class AvoSchemaParser {
|
|
|
9
10
|
* Never returns unencrypted values - only encrypted or nothing.
|
|
10
11
|
*/
|
|
11
12
|
private static getEncryptedPropertyValueIfEnabled;
|
|
12
|
-
static extractSchema(eventProperties: Record<string, any>, publicEncryptionKey?: string, env?: string):
|
|
13
|
-
propertyName: string;
|
|
14
|
-
propertyType: string;
|
|
15
|
-
encryptedPropertyValue?: string;
|
|
16
|
-
children?: any;
|
|
17
|
-
}>;
|
|
13
|
+
static extractSchema(eventProperties: Record<string, any>, publicEncryptionKey?: string, env?: string): EventProperty[];
|
|
18
14
|
private static removeDuplicates;
|
|
19
15
|
private static getPropValueType;
|
|
20
16
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AvoStreamId manages an ephemeral stream identifier.
|
|
3
|
+
*
|
|
4
|
+
* The stream ID is generated and stored persistently, but resets after:
|
|
5
|
+
* - 4 hours of total age AND
|
|
6
|
+
* - 2 hours of idle time (no activity)
|
|
7
|
+
*
|
|
8
|
+
* This ensures the ID is truly anonymous by not persisting indefinitely,
|
|
9
|
+
* while still maintaining session continuity during active usage.
|
|
10
|
+
*/
|
|
11
|
+
export declare class AvoStreamId {
|
|
12
|
+
private static _streamId;
|
|
13
|
+
private static _createdAt;
|
|
14
|
+
private static _lastActivityAt;
|
|
15
|
+
private static readonly MAX_AGE_MS;
|
|
16
|
+
private static readonly IDLE_THRESHOLD_MS;
|
|
17
|
+
private static readonly STREAM_ID_KEY;
|
|
18
|
+
private static readonly CREATED_AT_KEY;
|
|
19
|
+
private static readonly LAST_ACTIVITY_KEY;
|
|
20
|
+
/**
|
|
21
|
+
* Get the stream ID. If it doesn't exist or has expired, generates a new one.
|
|
22
|
+
* Returns "unknown" if storage is not initialized.
|
|
23
|
+
*/
|
|
24
|
+
static get streamId(): string;
|
|
25
|
+
/**
|
|
26
|
+
* Check if the stream ID should be reset based on age and idle time.
|
|
27
|
+
*/
|
|
28
|
+
private static shouldReset;
|
|
29
|
+
/**
|
|
30
|
+
* Load stream ID and timestamps from storage into cache.
|
|
31
|
+
*/
|
|
32
|
+
private static loadFromStorage;
|
|
33
|
+
/**
|
|
34
|
+
* Generate a new stream ID and store it with timestamps.
|
|
35
|
+
*/
|
|
36
|
+
private static generateAndStoreNew;
|
|
37
|
+
/**
|
|
38
|
+
* Update the last activity timestamp.
|
|
39
|
+
*/
|
|
40
|
+
private static updateLastActivity;
|
|
41
|
+
/**
|
|
42
|
+
* The storage key used to persist the stream ID.
|
|
43
|
+
*/
|
|
44
|
+
static get storageKey(): string;
|
|
45
|
+
/**
|
|
46
|
+
* The storage key for created at timestamp.
|
|
47
|
+
*/
|
|
48
|
+
static get createdAtKey(): string;
|
|
49
|
+
/**
|
|
50
|
+
* The storage key for last activity timestamp.
|
|
51
|
+
*/
|
|
52
|
+
static get lastActivityKey(): string;
|
|
53
|
+
/**
|
|
54
|
+
* Clear the cached stream ID. The next access will reload from storage.
|
|
55
|
+
* This is primarily useful for testing.
|
|
56
|
+
*/
|
|
57
|
+
static clearCache(): void;
|
|
58
|
+
}
|
|
@@ -46,7 +46,7 @@ export declare class EventSpecCache {
|
|
|
46
46
|
*/
|
|
47
47
|
private shouldEvict;
|
|
48
48
|
/**
|
|
49
|
-
* Evicts the
|
|
49
|
+
* Evicts the least recently used cache entry based on lastAccessed timestamp.
|
|
50
50
|
* This implements the LRU (Least Recently Used) eviction policy.
|
|
51
51
|
*/
|
|
52
52
|
private evictOldest;
|
|
@@ -67,6 +67,7 @@ export declare class EventSpecCache {
|
|
|
67
67
|
entries: Array<{
|
|
68
68
|
key: string;
|
|
69
69
|
age: number;
|
|
70
|
+
lastAccessedAgo: number;
|
|
70
71
|
eventCount: number;
|
|
71
72
|
}>;
|
|
72
73
|
};
|