81 lines
1.9 KiB
TypeScript
81 lines
1.9 KiB
TypeScript
export const INVALIDATION_TYPES = [
|
|
"directory.updated",
|
|
"page.updated",
|
|
"admin.updated",
|
|
] as const;
|
|
|
|
export type InvalidationType = (typeof INVALIDATION_TYPES)[number];
|
|
|
|
export interface InvalidationEvent {
|
|
type: InvalidationType;
|
|
id: string;
|
|
version: number;
|
|
}
|
|
|
|
export interface OutboxEventLike {
|
|
aggregateId: string;
|
|
eventType: string;
|
|
payload: Record<string, unknown>;
|
|
topic: string;
|
|
}
|
|
|
|
function isInvalidationType(value: string): value is InvalidationType {
|
|
return INVALIDATION_TYPES.some((type) => type === value);
|
|
}
|
|
|
|
export function expectedTopic(event: InvalidationEvent): string {
|
|
switch (event.type) {
|
|
case "directory.updated":
|
|
return "directory";
|
|
case "page.updated":
|
|
return `page:${event.id}`;
|
|
case "admin.updated":
|
|
return "admin";
|
|
}
|
|
}
|
|
|
|
export function toInvalidationEvent(
|
|
record: OutboxEventLike,
|
|
): InvalidationEvent | null {
|
|
if (!isInvalidationType(record.eventType)) return null;
|
|
const id = record.payload.id;
|
|
const version = record.payload.version;
|
|
if (
|
|
typeof id !== "string" ||
|
|
id !== record.aggregateId ||
|
|
typeof version !== "number" ||
|
|
!Number.isSafeInteger(version) ||
|
|
version < 0
|
|
) {
|
|
return null;
|
|
}
|
|
const event: InvalidationEvent = {
|
|
type: record.eventType,
|
|
id,
|
|
version,
|
|
};
|
|
return expectedTopic(event) === record.topic ? event : null;
|
|
}
|
|
|
|
export function parseInvalidationEvent(value: string): InvalidationEvent | null {
|
|
try {
|
|
const parsed = JSON.parse(value) as Record<string, unknown>;
|
|
const type = parsed.type;
|
|
const id = parsed.id;
|
|
const version = parsed.version;
|
|
if (
|
|
typeof type !== "string" ||
|
|
!isInvalidationType(type) ||
|
|
typeof id !== "string" ||
|
|
typeof version !== "number" ||
|
|
!Number.isSafeInteger(version) ||
|
|
version < 0
|
|
) {
|
|
return null;
|
|
}
|
|
return { type, id, version };
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|