avo-inspector 2.2.0 → 2.2.2-alpha.10
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 -1
- package/CHANGELOG.md +34 -1
- package/README.md +130 -0
- package/bin/avo-inspector.js +149 -0
- package/dist/AvoBatcher.d.ts +4 -11
- package/dist/AvoEncryption.d.ts +33 -0
- package/dist/AvoInspector.d.ts +40 -6
- package/dist/AvoNetworkCallsHandler.d.ts +50 -15
- package/dist/AvoSchemaParser.d.ts +12 -5
- package/dist/AvoStreamId.d.ts +58 -0
- package/dist/eventSpec/AvoEventSpecCache.d.ts +74 -0
- package/dist/eventSpec/AvoEventSpecFetchTypes.d.ts +151 -0
- package/dist/eventSpec/AvoEventSpecFetcher.d.ts +60 -0
- package/dist/eventSpec/EventValidator.d.ts +34 -0
- package/dist/eventSpec/cache.d.ts +73 -0
- package/dist/eventSpec/fetcher.d.ts +52 -0
- package/dist/eventSpec/index.d.ts +4 -0
- package/dist/eventSpec/types.d.ts +74 -0
- package/dist/index.js +2 -1
- package/dist/index.js.LICENSE.txt +5 -0
- package/jest.config.js +6 -0
- package/package.json +7 -1
- package/rescript/AvoInspector.res +1 -0
- package/rescript/AvoInspector.resi +1 -1
- package/webpack.browserConfig.js +1 -1
- package/webpack.config.js +1 -1
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { EventSpecResponse } from "./AvoEventSpecFetchTypes";
|
|
2
|
+
/**
|
|
3
|
+
* EventSpecCache implements a dual-condition cache with LRU eviction.
|
|
4
|
+
*
|
|
5
|
+
* Cache Policy:
|
|
6
|
+
* - Entries expire after 5 minutes OR 50 cache hits, whichever comes first
|
|
7
|
+
* - When 50 cache hits occur globally, the oldest cached entry is evicted
|
|
8
|
+
* - Each cache entry tracks: spec, timestamp, and hit count
|
|
9
|
+
*
|
|
10
|
+
* Cache Key Format: ${apiKey}:${streamId}:${eventName}
|
|
11
|
+
*
|
|
12
|
+
* Note: Event count only increments on cache hits, not on every tracked event.
|
|
13
|
+
* This ensures the cache evicts based on actual usage, not overall tracking volume.
|
|
14
|
+
*/
|
|
15
|
+
export declare class EventSpecCache {
|
|
16
|
+
/** Cache storage: key -> CacheEntry */
|
|
17
|
+
private cache;
|
|
18
|
+
/** Time-to-live in milliseconds (5 minutes) */
|
|
19
|
+
private readonly TTL_MS;
|
|
20
|
+
/** Maximum cache hit count before rotating cache (50 hits) */
|
|
21
|
+
private readonly MAX_EVENT_COUNT;
|
|
22
|
+
/** Global cache hit counter to track when to rotate cache */
|
|
23
|
+
private globalEventCount;
|
|
24
|
+
/** Whether to log debug information */
|
|
25
|
+
private readonly shouldLog;
|
|
26
|
+
constructor(shouldLog?: boolean);
|
|
27
|
+
/**
|
|
28
|
+
* Generates a cache key from the provided parameters.
|
|
29
|
+
*/
|
|
30
|
+
private generateKey;
|
|
31
|
+
/**
|
|
32
|
+
* Retrieves an event spec response from the cache if it exists and is valid.
|
|
33
|
+
* Returns null if the entry is missing, expired, or has exceeded event count.
|
|
34
|
+
*
|
|
35
|
+
* On cache hit, increments the hit count for this entry and the global counter.
|
|
36
|
+
*/
|
|
37
|
+
get(apiKey: string, streamId: string, eventName: string): EventSpecResponse | null;
|
|
38
|
+
/**
|
|
39
|
+
* Stores an event spec response in the cache.
|
|
40
|
+
*/
|
|
41
|
+
set(apiKey: string, streamId: string, eventName: string, spec: EventSpecResponse): void;
|
|
42
|
+
/**
|
|
43
|
+
* Determines if a cache entry should be evicted based on:
|
|
44
|
+
* - Age (older than 5 minutes)
|
|
45
|
+
* - Hit count (50 or more cache hits)
|
|
46
|
+
*/
|
|
47
|
+
private shouldEvict;
|
|
48
|
+
/**
|
|
49
|
+
* Evicts the least recently used cache entry based on lastAccessed 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
|
+
lastAccessedAgo: number;
|
|
71
|
+
eventCount: number;
|
|
72
|
+
}>;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
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
|
+
/** List flag - true if this is an array/list of the type */
|
|
16
|
+
l?: boolean;
|
|
17
|
+
/** Pinned values: pinnedValue -> eventIds that require this exact value */
|
|
18
|
+
p?: Record<string, Array<string>>;
|
|
19
|
+
/** Allowed values: JSON array string -> eventIds that accept these values */
|
|
20
|
+
v?: Record<string, Array<string>>;
|
|
21
|
+
/** Regex patterns: pattern -> eventIds that require matching this regex */
|
|
22
|
+
rx?: Record<string, Array<string>>;
|
|
23
|
+
/** Min/max ranges: "min,max" -> eventIds that require value in this range */
|
|
24
|
+
minmax?: Record<string, Array<string>>;
|
|
25
|
+
/** Nested property constraints for object properties */
|
|
26
|
+
children?: Record<string, PropertyConstraintsWire>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Wire format - Event spec entry with short field names.
|
|
30
|
+
* A single event entry (base event + its variants).
|
|
31
|
+
* Multiple events can match the same name request due to name mapping.
|
|
32
|
+
*/
|
|
33
|
+
export interface EventSpecEntryWire {
|
|
34
|
+
/** Branch identifier */
|
|
35
|
+
b: string;
|
|
36
|
+
/** Base event ID */
|
|
37
|
+
id: string;
|
|
38
|
+
/** Variant IDs (baseEventId + variantIds = complete set) */
|
|
39
|
+
vids: Array<string>;
|
|
40
|
+
/** Property constraints keyed by property name */
|
|
41
|
+
p: Record<string, PropertyConstraintsWire>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Wire format - Response from getEventSpec endpoint.
|
|
45
|
+
* Contains array of events that match the requested name (due to name mapping).
|
|
46
|
+
*/
|
|
47
|
+
export interface EventSpecResponseWire {
|
|
48
|
+
/** Array of events matching the requested name */
|
|
49
|
+
events: Array<EventSpecEntryWire>;
|
|
50
|
+
/** Schema metadata (keeps long names - small, one per response) */
|
|
51
|
+
metadata: EventSpecMetadata;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Internal - Property constraints with meaningful field names.
|
|
55
|
+
* At most one constraint type will be present per property.
|
|
56
|
+
*/
|
|
57
|
+
export interface PropertyConstraints {
|
|
58
|
+
/** Type name (for reference only, not validated) */
|
|
59
|
+
type: string;
|
|
60
|
+
/** Required flag (for reference only, not validated) */
|
|
61
|
+
required: boolean;
|
|
62
|
+
/** List flag - true if this is an array/list of items */
|
|
63
|
+
isList?: boolean;
|
|
64
|
+
/** Pinned values: pinnedValue -> eventIds that require this exact value */
|
|
65
|
+
pinnedValues?: Record<string, Array<string>>;
|
|
66
|
+
/** Allowed values: JSON array string -> eventIds that accept these values */
|
|
67
|
+
allowedValues?: Record<string, Array<string>>;
|
|
68
|
+
/** Regex patterns: pattern -> eventIds that require matching this regex */
|
|
69
|
+
regexPatterns?: Record<string, Array<string>>;
|
|
70
|
+
/** Min/max ranges: "min,max" -> eventIds that require value in this range */
|
|
71
|
+
minMaxRanges?: Record<string, Array<string>>;
|
|
72
|
+
/** Nested property constraints for object properties (for objects or list of objects) */
|
|
73
|
+
children?: Record<string, PropertyConstraints>;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Internal - Event spec entry with meaningful field names.
|
|
77
|
+
* A single event entry (base event + its variants).
|
|
78
|
+
*/
|
|
79
|
+
export interface EventSpecEntry {
|
|
80
|
+
/** Branch identifier */
|
|
81
|
+
branchId: string;
|
|
82
|
+
/** Base event ID */
|
|
83
|
+
baseEventId: string;
|
|
84
|
+
/** Variant IDs (baseEventId + variantIds = complete set) */
|
|
85
|
+
variantIds: Array<string>;
|
|
86
|
+
/** Property constraints keyed by property name */
|
|
87
|
+
props: Record<string, PropertyConstraints>;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Internal - Parsed response from getEventSpec endpoint.
|
|
91
|
+
* Contains array of events that match the requested name (due to name mapping).
|
|
92
|
+
*/
|
|
93
|
+
export interface EventSpecResponse {
|
|
94
|
+
/** Array of events matching the requested name */
|
|
95
|
+
events: Array<EventSpecEntry>;
|
|
96
|
+
/** Schema metadata */
|
|
97
|
+
metadata: EventSpecMetadata;
|
|
98
|
+
}
|
|
99
|
+
/** Metadata returned with the event spec response. */
|
|
100
|
+
export interface EventSpecMetadata {
|
|
101
|
+
/** Schema identifier */
|
|
102
|
+
schemaId: string;
|
|
103
|
+
/** Branch identifier */
|
|
104
|
+
branchId: string;
|
|
105
|
+
/** Latest action identifier */
|
|
106
|
+
latestActionId: string;
|
|
107
|
+
/** Optional source identifier */
|
|
108
|
+
sourceId?: string;
|
|
109
|
+
}
|
|
110
|
+
/** Cache entry for storing event specs with metadata. */
|
|
111
|
+
export interface EventSpecCacheEntry {
|
|
112
|
+
/** The cached event specification response (internal format) */
|
|
113
|
+
spec: EventSpecResponse;
|
|
114
|
+
/** Timestamp when this entry was cached (used for TTL expiration) */
|
|
115
|
+
timestamp: number;
|
|
116
|
+
/** Timestamp when this entry was last accessed (used for LRU eviction) */
|
|
117
|
+
lastAccessed: number;
|
|
118
|
+
/** Number of cache hits since this entry was cached */
|
|
119
|
+
eventCount: number;
|
|
120
|
+
}
|
|
121
|
+
/** Parameters for fetching event specifications from the API. */
|
|
122
|
+
export interface FetchEventSpecParams {
|
|
123
|
+
/** The API key */
|
|
124
|
+
apiKey: string;
|
|
125
|
+
/** The stream ID */
|
|
126
|
+
streamId: string;
|
|
127
|
+
/** The name of the event */
|
|
128
|
+
eventName: string;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Result of validating a single property.
|
|
132
|
+
* Contains either failedEventIds or passedEventIds (whichever is smaller for bandwidth).
|
|
133
|
+
*/
|
|
134
|
+
export interface PropertyValidationResult {
|
|
135
|
+
/** Event/variant IDs that FAILED validation (present if smaller or equal to passed) */
|
|
136
|
+
failedEventIds?: Array<string>;
|
|
137
|
+
/** Event/variant IDs that PASSED validation (present if smaller than failed) */
|
|
138
|
+
passedEventIds?: Array<string>;
|
|
139
|
+
/** Nested validation results for child properties of object properties */
|
|
140
|
+
children?: Record<string, PropertyValidationResult>;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Result of validating all properties in an event.
|
|
144
|
+
* Maps property name to its validation result.
|
|
145
|
+
*/
|
|
146
|
+
export interface ValidationResult {
|
|
147
|
+
/** Event spec metadata */
|
|
148
|
+
metadata: EventSpecMetadata | null;
|
|
149
|
+
/** Validation results per property */
|
|
150
|
+
propertyResults: Record<string, PropertyValidationResult>;
|
|
151
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
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 /trackingPlan/eventSpec
|
|
11
|
+
* Base URL: https://api.avo.app
|
|
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, Phase 2 should skip validation 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
|
+
/** Parses the wire format response into internal format with meaningful field names. */
|
|
55
|
+
private static parseEventSpecResponse;
|
|
56
|
+
/** Parses a single event spec entry from wire format. */
|
|
57
|
+
private static parseEventSpecEntry;
|
|
58
|
+
/** Parses property constraints from wire format. */
|
|
59
|
+
private static parsePropertyConstraints;
|
|
60
|
+
}
|
|
@@ -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,52 @@
|
|
|
1
|
+
import type { EventSpec, FetchEventSpecParams } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* EventSpecFetcher handles fetching event specifications from the Avo API.
|
|
4
|
+
*
|
|
5
|
+
* Endpoint: GET /getEventSpec
|
|
6
|
+
* Base URL: https://api.avo.app/inspector/v1
|
|
7
|
+
*/
|
|
8
|
+
export declare class EventSpecFetcher {
|
|
9
|
+
/** Base URL for the event spec API */
|
|
10
|
+
private readonly baseUrl;
|
|
11
|
+
/** Network timeout in milliseconds */
|
|
12
|
+
private readonly timeout;
|
|
13
|
+
/** Whether to log debug information */
|
|
14
|
+
private readonly shouldLog;
|
|
15
|
+
/** In-flight requests to prevent duplicate fetches */
|
|
16
|
+
private inFlightRequests;
|
|
17
|
+
constructor(timeout?: number, shouldLog?: boolean, baseUrl?: string);
|
|
18
|
+
/**
|
|
19
|
+
* Generates a unique key for tracking in-flight requests.
|
|
20
|
+
*/
|
|
21
|
+
private generateRequestKey;
|
|
22
|
+
/**
|
|
23
|
+
* Fetches an event specification from the API.
|
|
24
|
+
*
|
|
25
|
+
* Returns null if:
|
|
26
|
+
* - The network request fails
|
|
27
|
+
* - The response has an invalid status code (non-200)
|
|
28
|
+
* - The response is invalid or malformed
|
|
29
|
+
* - The request times out
|
|
30
|
+
*
|
|
31
|
+
* This method gracefully degrades - failures do not throw errors.
|
|
32
|
+
* When null is returned, Phase 2 should skip validation for that event.
|
|
33
|
+
*/
|
|
34
|
+
fetch(params: FetchEventSpecParams): Promise<EventSpec | null>;
|
|
35
|
+
/**
|
|
36
|
+
* Internal fetch implementation.
|
|
37
|
+
*/
|
|
38
|
+
private fetchInternal;
|
|
39
|
+
/**
|
|
40
|
+
* Builds the complete URL with query parameters.
|
|
41
|
+
*/
|
|
42
|
+
private buildUrl;
|
|
43
|
+
/**
|
|
44
|
+
* Makes an HTTP GET request using XMLHttpRequest.
|
|
45
|
+
* Returns the parsed JSON response or null on failure.
|
|
46
|
+
*/
|
|
47
|
+
private makeRequest;
|
|
48
|
+
/**
|
|
49
|
+
* Validates that the response matches the EventSpec structure.
|
|
50
|
+
*/
|
|
51
|
+
private isValidEventSpec;
|
|
52
|
+
}
|
|
@@ -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
|
+
}
|