avo-inspector 2.2.0 → 2.2.2-alpha.2

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 (108) hide show
  1. package/CHANGELOG.md +34 -1
  2. package/README.md +130 -0
  3. package/bin/avo-inspector.js +97 -0
  4. package/dist/AvoBatcher.d.ts +4 -11
  5. package/dist/AvoEncryption.d.ts +33 -0
  6. package/dist/AvoInspector.d.ts +35 -6
  7. package/dist/AvoNetworkCallsHandler.d.ts +42 -12
  8. package/dist/AvoSchemaParser.d.ts +12 -5
  9. package/dist/browser.js.LICENSE.txt +5 -0
  10. package/dist/eventSpec/AvoEventSpecCache.d.ts +73 -0
  11. package/dist/eventSpec/AvoEventSpecFetchTypes.d.ts +141 -0
  12. package/dist/eventSpec/AvoEventSpecFetcher.d.ts +54 -0
  13. package/dist/eventSpec/EventValidator.d.ts +34 -0
  14. package/dist/eventSpec/cache.d.ts +73 -0
  15. package/dist/eventSpec/index.d.ts +4 -0
  16. package/dist/eventSpec/types.d.ts +74 -0
  17. package/dist/index.js +2 -1
  18. package/dist/index.js.LICENSE.txt +5 -0
  19. package/dist-browser/AvoAnonymousId.d.ts +26 -0
  20. package/dist-browser/AvoBatcher.d.ts +26 -0
  21. package/dist-browser/AvoDeduplicator.d.ts +20 -0
  22. package/dist-browser/AvoEncryption.d.ts +33 -0
  23. package/dist-browser/AvoGuid.d.ts +3 -0
  24. package/dist-browser/AvoInspector.d.ts +78 -0
  25. package/dist-browser/AvoInspectorEnv.d.ts +7 -0
  26. package/dist-browser/AvoNetworkCallsHandler.d.ts +74 -0
  27. package/dist-browser/AvoSchemaParser.d.ts +20 -0
  28. package/dist-browser/AvoStorage.d.ts +22 -0
  29. package/dist-browser/__mocks__/xhr.d.ts +12 -0
  30. package/dist-browser/__mocks__/xhrError.d.ts +12 -0
  31. package/dist-browser/__tests__/AnonymousId_test.d.ts +1 -0
  32. package/dist-browser/__tests__/AvoEncryption_test.d.ts +1 -0
  33. package/dist-browser/__tests__/AvoInspectorEventSpec_test.d.ts +1 -0
  34. package/dist-browser/__tests__/AvoInspector_test.d.ts +1 -0
  35. package/dist-browser/__tests__/BatcherPublic_test.d.ts +1 -0
  36. package/dist-browser/__tests__/Batcher_test.d.ts +1 -0
  37. package/dist-browser/__tests__/Deduplicator_test.d.ts +1 -0
  38. package/dist-browser/__tests__/EncryptedPropertyTracking_test.d.ts +1 -0
  39. package/dist-browser/__tests__/EventSpecCache_test.d.ts +1 -0
  40. package/dist-browser/__tests__/EventSpecFetcher_test.d.ts +1 -0
  41. package/dist-browser/__tests__/EventValidator_test.d.ts +1 -0
  42. package/dist-browser/__tests__/NetworkCallsHandler_test.d.ts +1 -0
  43. package/dist-browser/__tests__/Parsing_test.d.ts +1 -0
  44. package/dist-browser/__tests__/Storage_test.d.ts +1 -0
  45. package/dist-browser/__tests__/ValidationIntegration_test.d.ts +1 -0
  46. package/dist-browser/__tests__/constants.d.ts +36 -0
  47. package/dist-browser/__tests__/helpers/encryptionHelpers.d.ts +13 -0
  48. package/dist-browser/__tests__/helpers/mockFactories.d.ts +49 -0
  49. package/dist-browser/eventSpec/AvoEventSpecCache.d.ts +73 -0
  50. package/dist-browser/eventSpec/AvoEventSpecFetchTypes.d.ts +109 -0
  51. package/dist-browser/eventSpec/AvoEventSpecFetcher.d.ts +55 -0
  52. package/dist-browser/eventSpec/EventValidator.d.ts +90 -0
  53. package/dist-browser/eventSpec/index.d.ts +4 -0
  54. package/dist-browser/index.d.ts +2 -0
  55. package/dist-browser/utils.d.ts +3 -0
  56. package/dist-native/AvoBatcher.d.ts +24 -0
  57. package/dist-native/AvoBatcher.js +82 -0
  58. package/dist-native/AvoDeduplicator.d.ts +36 -0
  59. package/dist-native/AvoDeduplicator.js +142 -0
  60. package/dist-native/AvoGuid.d.ts +3 -0
  61. package/dist-native/AvoGuid.js +14 -0
  62. package/dist-native/AvoInspector.d.ts +52 -0
  63. package/dist-native/AvoInspector.js +220 -0
  64. package/dist-native/AvoInspectorEnv.d.ts +7 -0
  65. package/dist-native/AvoInspectorEnv.js +8 -0
  66. package/dist-native/AvoInstallationId.d.ts +5 -0
  67. package/dist-native/AvoInstallationId.js +36 -0
  68. package/dist-native/AvoNetworkCallsHandler.d.ts +48 -0
  69. package/dist-native/AvoNetworkCallsHandler.js +142 -0
  70. package/dist-native/AvoSchemaParser.d.ts +11 -0
  71. package/dist-native/AvoSchemaParser.js +95 -0
  72. package/dist-native/AvoSessionTracker.d.ts +15 -0
  73. package/dist-native/AvoSessionTracker.js +104 -0
  74. package/dist-native/AvoStorage.d.ts +22 -0
  75. package/dist-native/AvoStorage.js +336 -0
  76. package/dist-native/__mocks__/xhr.d.ts +12 -0
  77. package/dist-native/__mocks__/xhr.js +14 -0
  78. package/dist-native/__mocks__/xhrError.d.ts +12 -0
  79. package/dist-native/__mocks__/xhrError.js +14 -0
  80. package/dist-native/__tests__/AvoInspector.d.ts +1 -0
  81. package/dist-native/__tests__/AvoInspector.js +207 -0
  82. package/dist-native/__tests__/Batcher.d.ts +1 -0
  83. package/dist-native/__tests__/Batcher.js +280 -0
  84. package/dist-native/__tests__/BatcherPublic.d.ts +1 -0
  85. package/dist-native/__tests__/BatcherPublic.js +82 -0
  86. package/dist-native/__tests__/Deduplicator.d.ts +1 -0
  87. package/dist-native/__tests__/Deduplicator.js +111 -0
  88. package/dist-native/__tests__/InstallationId.d.ts +1 -0
  89. package/dist-native/__tests__/InstallationId.js +40 -0
  90. package/dist-native/__tests__/NetworkCallsHandler.d.ts +1 -0
  91. package/dist-native/__tests__/NetworkCallsHandler.js +132 -0
  92. package/dist-native/__tests__/Parsing.d.ts +1 -0
  93. package/dist-native/__tests__/Parsing.js +115 -0
  94. package/dist-native/__tests__/Sessions.d.ts +1 -0
  95. package/dist-native/__tests__/Sessions.js +179 -0
  96. package/dist-native/__tests__/Storage.d.ts +1 -0
  97. package/dist-native/__tests__/Storage.js +173 -0
  98. package/dist-native/__tests__/constants.d.ts +36 -0
  99. package/dist-native/__tests__/constants.js +47 -0
  100. package/dist-native/index.d.ts +2 -0
  101. package/dist-native/index.js +7 -0
  102. package/dist-native/utils.d.ts +3 -0
  103. package/dist-native/utils.js +42 -0
  104. package/jest.config.js +6 -0
  105. package/package.json +8 -2
  106. package/webpack.browserConfig.js +1 -1
  107. package/webpack.config.js +1 -1
  108. package/.claude/settings.local.json +0 -9
@@ -0,0 +1,141 @@
1
+ /**
2
+ * This file is generated. Internal development changes should be made in the generator
3
+ * and the file should be re-generated. External contributions are welcome to submit
4
+ * changes directly to this file, and we'll apply them to the generator internally.
5
+ */
6
+ /**
7
+ * Wire format - Property constraints with short field names.
8
+ * At most one constraint type will be present per property.
9
+ */
10
+ export interface PropertyConstraintsWire {
11
+ /** Type name (for reference only, not validated) */
12
+ t: string;
13
+ /** Required flag (for reference only, not validated) */
14
+ r: boolean;
15
+ /** Pinned values: pinnedValue -> eventIds that require this exact value */
16
+ p?: Record<string, string[]>;
17
+ /** Allowed values: JSON array string -> eventIds that accept these values */
18
+ v?: Record<string, string[]>;
19
+ /** Regex patterns: pattern -> eventIds that require matching this regex */
20
+ rx?: Record<string, string[]>;
21
+ /** Min/max ranges: "min,max" -> eventIds that require value in this range */
22
+ minmax?: Record<string, string[]>;
23
+ }
24
+ /**
25
+ * Wire format - Event spec entry with short field names.
26
+ * A single event entry (base event + its variants).
27
+ * Multiple events can match the same name request due to name mapping.
28
+ */
29
+ export interface EventSpecEntryWire {
30
+ /** Branch identifier */
31
+ b: string;
32
+ /** Base event ID */
33
+ id: string;
34
+ /** Variant IDs (baseEventId + variantIds = complete set) */
35
+ vids: string[];
36
+ /** Property constraints keyed by property name */
37
+ p: Record<string, PropertyConstraintsWire>;
38
+ }
39
+ /**
40
+ * Wire format - Response from getEventSpec endpoint.
41
+ * Contains array of events that match the requested name (due to name mapping).
42
+ */
43
+ export interface EventSpecResponseWire {
44
+ /** Array of events matching the requested name */
45
+ events: EventSpecEntryWire[];
46
+ /** Schema metadata (keeps long names - small, one per response) */
47
+ metadata: EventSpecMetadata;
48
+ }
49
+ /**
50
+ * Internal - Property constraints with meaningful field names.
51
+ * At most one constraint type will be present per property.
52
+ */
53
+ export interface PropertyConstraints {
54
+ /** Type name (for reference only, not validated) */
55
+ type: string;
56
+ /** Required flag (for reference only, not validated) */
57
+ required: boolean;
58
+ /** Pinned values: pinnedValue -> eventIds that require this exact value */
59
+ pinnedValues?: Record<string, string[]>;
60
+ /** Allowed values: JSON array string -> eventIds that accept these values */
61
+ allowedValues?: Record<string, string[]>;
62
+ /** Regex patterns: pattern -> eventIds that require matching this regex */
63
+ regexPatterns?: Record<string, string[]>;
64
+ /** Min/max ranges: "min,max" -> eventIds that require value in this range */
65
+ minMaxRanges?: Record<string, string[]>;
66
+ }
67
+ /**
68
+ * Internal - Event spec entry with meaningful field names.
69
+ * A single event entry (base event + its variants).
70
+ */
71
+ export interface EventSpecEntry {
72
+ /** Branch identifier */
73
+ branchId: string;
74
+ /** Base event ID */
75
+ baseEventId: string;
76
+ /** Variant IDs (baseEventId + variantIds = complete set) */
77
+ variantIds: string[];
78
+ /** Property constraints keyed by property name */
79
+ props: Record<string, PropertyConstraints>;
80
+ }
81
+ /**
82
+ * Internal - Parsed response from getEventSpec endpoint.
83
+ * Contains array of events that match the requested name (due to name mapping).
84
+ */
85
+ export interface EventSpecResponse {
86
+ /** Array of events matching the requested name */
87
+ events: EventSpecEntry[];
88
+ /** Schema metadata */
89
+ metadata: EventSpecMetadata;
90
+ }
91
+ /**
92
+ * Metadata returned with the event spec response.
93
+ */
94
+ export interface EventSpecMetadata {
95
+ /** Schema identifier */
96
+ schemaId: string;
97
+ /** Branch identifier */
98
+ branchId: string;
99
+ /** Latest action identifier */
100
+ latestActionId: string;
101
+ /** Optional source identifier */
102
+ sourceId?: string;
103
+ }
104
+ /** Cache entry for storing event specs with metadata. */
105
+ export interface EventSpecCacheEntry {
106
+ /** The cached event specification response (internal format) */
107
+ spec: EventSpecResponse;
108
+ /** Timestamp when this entry was cached */
109
+ timestamp: number;
110
+ /** Number of cache hits since this entry was cached */
111
+ eventCount: number;
112
+ }
113
+ /** Parameters for fetching event specifications from the API. */
114
+ export interface FetchEventSpecParams {
115
+ /** The API key */
116
+ apiKey: string;
117
+ /** The stream ID */
118
+ streamId: string;
119
+ /** The name of the event */
120
+ eventName: string;
121
+ }
122
+ /**
123
+ * Result of validating a single property.
124
+ * Contains either failedEventIds or passedEventIds (whichever is smaller for bandwidth).
125
+ */
126
+ export interface PropertyValidationResult {
127
+ /** Event/variant IDs that FAILED validation (present if smaller or equal to passed) */
128
+ failedEventIds?: string[];
129
+ /** Event/variant IDs that PASSED validation (present if smaller than failed) */
130
+ passedEventIds?: string[];
131
+ }
132
+ /**
133
+ * Result of validating all properties in an event.
134
+ * Maps property name to its validation result.
135
+ */
136
+ export interface ValidationResult {
137
+ /** Event spec metadata */
138
+ metadata: EventSpecMetadata | null;
139
+ /** Validation results per property */
140
+ propertyResults: Record<string, PropertyValidationResult>;
141
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * This file is generated. Internal development changes should be made in the generator
3
+ * and the file should be re-generated. External contributions are welcome to submit
4
+ * changes directly to this file, and we'll apply them to the generator internally.
5
+ */
6
+ import type { EventSpecResponse, FetchEventSpecParams } from "./AvoEventSpecFetchTypes";
7
+ /**
8
+ * EventSpecFetcher handles fetching event specifications from the Avo API.
9
+ *
10
+ * Endpoint: GET /getEventSpec
11
+ * Base URL: https://us-central1-avo-web-app.cloudfunctions.net
12
+ */
13
+ export declare class AvoEventSpecFetcher {
14
+ /** Base URL for the event spec API */
15
+ private readonly baseUrl;
16
+ /** Network timeout in milliseconds */
17
+ private readonly timeout;
18
+ /** In-flight requests to prevent duplicate fetches */
19
+ private inFlightRequests;
20
+ /** Whether to log debug information */
21
+ private readonly shouldLog;
22
+ /** Environment name */
23
+ private readonly env;
24
+ constructor(timeout: number | undefined, shouldLog: boolean | undefined, env: string, baseUrl?: string);
25
+ /** Generates a unique key for tracking in-flight requests. */
26
+ private generateRequestKey;
27
+ /**
28
+ * Fetches an event specification from the API.
29
+ *
30
+ * Returns null if:
31
+ * - The network request fails
32
+ * - The response has an invalid status code (non-200)
33
+ * - The response is invalid or malformed
34
+ * - The request times out
35
+ *
36
+ * This method gracefully degrades - failures do not throw errors.
37
+ * When null is returned, validation should be skipped for that event.
38
+ */
39
+ fetch(params: FetchEventSpecParams): Promise<EventSpecResponse | null>;
40
+ /** Internal fetch implementation. */
41
+ private fetchInternal;
42
+ /** Builds the complete URL with query parameters. */
43
+ private buildUrl;
44
+ /**
45
+ * Makes an HTTP GET request using XMLHttpRequest.
46
+ * Returns the parsed JSON response or null on failure.
47
+ */
48
+ private makeRequest;
49
+ /**
50
+ * Basic shape check for wire format - ensures response has the minimum expected structure.
51
+ * Uses short field names from wire format.
52
+ */
53
+ private hasExpectedShape;
54
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * EventValidator - Client-side validation of tracking events against the Avo Tracking Plan.
3
+ *
4
+ * This module validates property values against constraints:
5
+ * - Pinned values (exact match required)
6
+ * - Allowed values (must be in list)
7
+ * - Regex patterns (must match pattern)
8
+ * - Min/max ranges (numeric values must be in range)
9
+ *
10
+ * No schema validation (types/required) is performed - only value constraints.
11
+ * Validation runs against ALL events/variants in the response.
12
+ */
13
+ import type { EventSpecResponse, ValidationResult } from "./AvoEventSpecFetchTypes";
14
+ /**
15
+ * Runtime property value - can be any JSON-compatible type
16
+ */
17
+ export type RuntimePropertyValue = string | number | boolean | null | undefined | object | Array<any>;
18
+ /**
19
+ * Runtime properties map
20
+ */
21
+ export type RuntimeProperties = Record<string, RuntimePropertyValue>;
22
+ /**
23
+ * Validates runtime properties against all events in the EventSpecResponse.
24
+ *
25
+ * For each property:
26
+ * - If property not in spec: no validation needed (empty result)
27
+ * - If property in spec: check constraints and collect failed/passed eventIds
28
+ * - Return whichever list is smaller for bandwidth optimization
29
+ *
30
+ * @param properties - The properties observed at runtime
31
+ * @param specResponse - The EventSpecResponse from the backend
32
+ * @returns ValidationResult with baseEventId, metadata, and per-property results
33
+ */
34
+ export declare function validateEvent(properties: RuntimeProperties, specResponse: EventSpecResponse): ValidationResult;
@@ -0,0 +1,73 @@
1
+ import type { EventSpec } from "./types";
2
+ /**
3
+ * EventSpecCache implements a dual-condition cache with LRU eviction.
4
+ *
5
+ * Cache Policy:
6
+ * - Entries expire after 5 minutes OR 50 events, whichever comes first
7
+ * - When 50 events are processed, the oldest cached entry is evicted
8
+ * - Each cache entry tracks: spec, timestamp, and eventCount
9
+ *
10
+ * Cache Key Format: ${schemaId}:${sourceId}:${eventName}:${branchId}
11
+ */
12
+ export declare class EventSpecCache {
13
+ /** Cache storage: key -> CacheEntry */
14
+ private cache;
15
+ /** Time-to-live in milliseconds (5 minutes) */
16
+ private readonly TTL_MS;
17
+ /** Maximum event count before rotating cache (50 events) */
18
+ private readonly MAX_EVENT_COUNT;
19
+ /** Global event counter to track when to rotate cache */
20
+ private globalEventCount;
21
+ /** Whether to log debug information */
22
+ private readonly shouldLog;
23
+ constructor(shouldLog?: boolean);
24
+ /**
25
+ * Generates a cache key from the provided parameters.
26
+ */
27
+ private generateKey;
28
+ /**
29
+ * Retrieves an event spec from the cache if it exists and is valid.
30
+ * Returns null if the entry is missing, expired, or has exceeded event count.
31
+ */
32
+ get(schemaId: string, sourceId: string, eventName: string, branchId: string): EventSpec | null;
33
+ /**
34
+ * Stores an event spec in the cache.
35
+ */
36
+ set(schemaId: string, sourceId: string, eventName: string, branchId: string, spec: EventSpec): void;
37
+ /**
38
+ * Increments the event count for all cached entries and triggers
39
+ * eviction if the global event count reaches MAX_EVENT_COUNT.
40
+ */
41
+ incrementEventCount(): void;
42
+ /**
43
+ * Determines if a cache entry should be evicted based on:
44
+ * - Age (older than 5 minutes)
45
+ * - Event count (50 or more events processed)
46
+ */
47
+ private shouldEvict;
48
+ /**
49
+ * Evicts the oldest cache entry based on timestamp.
50
+ * This implements the LRU (Least Recently Used) eviction policy.
51
+ */
52
+ private evictOldest;
53
+ /**
54
+ * Clears all cached entries. Useful for testing.
55
+ */
56
+ clear(): void;
57
+ /**
58
+ * Returns the current size of the cache.
59
+ */
60
+ size(): number;
61
+ /**
62
+ * Returns cache statistics for debugging.
63
+ */
64
+ getStats(): {
65
+ size: number;
66
+ globalEventCount: number;
67
+ entries: Array<{
68
+ key: string;
69
+ age: number;
70
+ eventCount: number;
71
+ }>;
72
+ };
73
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./AvoEventSpecFetchTypes";
2
+ export * from "./AvoEventSpecCache";
3
+ export * from "./AvoEventSpecFetcher";
4
+ export * from "./EventValidator";
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Represents the specification for a single property in an event.
3
+ * Supports recursive nesting for object types.
4
+ */
5
+ export interface PropertySpec {
6
+ /** Type - can be a primitive type string OR a nested object structure (recursive) */
7
+ t: string | Record<string, PropertySpec>;
8
+ /** Required flag */
9
+ r: boolean;
10
+ /** Is list (array) flag */
11
+ l?: boolean;
12
+ /** Minimum value (for numeric types) */
13
+ min?: number;
14
+ /** Maximum value (for numeric types) */
15
+ max?: number;
16
+ /** Enum values (allowed values for the property) */
17
+ v?: string[];
18
+ /** Regex pattern for string validation */
19
+ rx?: string;
20
+ }
21
+ /**
22
+ * Represents a variant of an event with additional or modified properties.
23
+ */
24
+ export interface EventVariant {
25
+ /** Unique identifier for this variant */
26
+ variantId: string;
27
+ /** Suffix to append to the base event name */
28
+ nameSuffix: string;
29
+ /** Event ID for this variant */
30
+ eventId: string;
31
+ /** Properties specific to this variant */
32
+ props: Record<string, PropertySpec>;
33
+ }
34
+ /**
35
+ * Represents the complete specification for an event, including base event
36
+ * and optional variants.
37
+ */
38
+ export interface EventSpec {
39
+ /** Base event specification */
40
+ baseEvent: {
41
+ /** Name of the event */
42
+ name: string;
43
+ /** Unique identifier for the event */
44
+ id: string;
45
+ /** Properties defined for the base event */
46
+ props: Record<string, PropertySpec>;
47
+ };
48
+ /** Optional variants of this event with additional/modified properties */
49
+ variants?: EventVariant[];
50
+ }
51
+ /**
52
+ * Cache entry for storing event specs with metadata.
53
+ */
54
+ export interface EventSpecCacheEntry {
55
+ /** The cached event specification */
56
+ spec: EventSpec;
57
+ /** Timestamp when this entry was cached */
58
+ timestamp: number;
59
+ /** Number of events processed since this entry was cached */
60
+ eventCount: number;
61
+ }
62
+ /**
63
+ * Parameters for fetching event specifications from the API.
64
+ */
65
+ export interface FetchEventSpecParams {
66
+ /** The workspace/schema ID */
67
+ schemaId: string;
68
+ /** The source ID */
69
+ sourceId: string;
70
+ /** The name of the event */
71
+ eventName: string;
72
+ /** The branch ID (defaults to "main") */
73
+ branchId?: string;
74
+ }