57 lines
1.8 KiB
TypeScript
57 lines
1.8 KiB
TypeScript
/**
|
|
* Value Object: EventName
|
|
* Validates and encapsulates a telemetry event name.
|
|
* Event names must be non-empty, max 64 characters, and follow snake_case convention.
|
|
*/
|
|
export class EventName {
|
|
private static readonly MAX_LENGTH = 64;
|
|
private static readonly PATTERN = /^[a-z][a-z0-9_]*$/;
|
|
|
|
private constructor(private readonly value: string) {}
|
|
|
|
static create(name: string): EventName {
|
|
if (!name || name.trim().length === 0) {
|
|
throw new Error('Event name cannot be empty');
|
|
}
|
|
if (name.length > EventName.MAX_LENGTH) {
|
|
throw new Error(`Event name must be at most ${EventName.MAX_LENGTH} characters, got ${name.length}`);
|
|
}
|
|
if (!EventName.PATTERN.test(name)) {
|
|
throw new Error(`Event name must be snake_case (lowercase letters, digits, underscores): "${name}"`);
|
|
}
|
|
return new EventName(name);
|
|
}
|
|
|
|
/**
|
|
* Create an EventName without strict pattern validation (for legacy/external events).
|
|
* Still enforces max length.
|
|
*/
|
|
static createLenient(name: string): EventName {
|
|
if (!name || name.trim().length === 0) {
|
|
throw new Error('Event name cannot be empty');
|
|
}
|
|
if (name.length > EventName.MAX_LENGTH) {
|
|
throw new Error(`Event name must be at most ${EventName.MAX_LENGTH} characters, got ${name.length}`);
|
|
}
|
|
return new EventName(name);
|
|
}
|
|
|
|
toString(): string {
|
|
return this.value;
|
|
}
|
|
|
|
equals(other: EventName): boolean {
|
|
return this.value === other.value;
|
|
}
|
|
|
|
/** Check if this is a session-related event */
|
|
isSessionEvent(): boolean {
|
|
return this.value === 'app_session_start' || this.value === 'app_session_end';
|
|
}
|
|
|
|
/** Check if this is a heartbeat-related event */
|
|
isHeartbeatEvent(): boolean {
|
|
return this.value === 'heartbeat' || this.value === 'app_heartbeat';
|
|
}
|
|
}
|