/** * Build PublishEvent payloads from the publish-flow output. * * `executePlan` returns a list of `{name, version}` for each * published package. Each entry becomes a PublishEvent. The event's * `registry` and `tag` flow from the publish mode (alpha/normal/ * promote) so subscribers can filter accurately — an alpha * subscriber doesn't fire on real publishes. */ import { randomUUID } from 'node:crypto'; import type { PublishEvent } from '@celilo/event-bus/build-bus'; export interface PublishedItem { name: string; version: string; } export interface EventFactoryInput { published: PublishedItem[]; /** Per the publish mode: `latest` for normal, `alpha` for alpha. Promote ships under `latest`. */ tag: 'latest' | 'alpha'; /** Current git HEAD at publish time. Optional. */ gitHead?: string; /** Defaults to "npm". The cross-machine event flow doesn't care. */ registry?: string; /** * Time + UUID injection for deterministic tests. Production * omits, uses Date.now + crypto.randomUUID. */ now?: () => Date; newId?: () => string; } /** * Build one PublishEvent per published package. Pure given the * injectables — same input + same `now`/`newId` produces the same * events. */ export function eventsForPublished(input: EventFactoryInput): PublishEvent[] { const tag = input.tag; const registry = input.registry ?? 'npm'; const now = input.now ?? (() => new Date()); const newId = input.newId ?? (() => randomUUID()); return input.published.map(({ name, version }) => ({ eventId: newId(), timestamp: now().toISOString(), registry, tag, package: { name, version }, gitHead: input.gitHead, })); }