UNPKG

@r-delfino/mux-sync-engine

Version:

Mux Sync Engine to sync Mux data based on webhooks to Postgres

148 lines (141 loc) 5.06 kB
import { Mux } from '@mux/mux-node'; import pg, { QueryResult } from 'pg'; import { HeadersLike } from '@mux/mux-node/core'; interface EntitySchema$1 { readonly properties: string[]; } type PostgresConfig = { databaseUrl: string; schema: string; maxConnections?: number; }; declare class PostgresClient { private config; pool: pg.Pool; constructor(config: PostgresConfig); deleteByField(table: string, field: string, value: string): Promise<boolean>; query(text: string, params?: any[]): Promise<QueryResult>; upsertMany<T extends { [Key: string]: any; }>(entries: T[], table: string, tableSchema: EntitySchema$1, options?: { conflict?: string; }): Promise<T[]>; findMissingEntries(idField: string | undefined, table: string, ids: string[]): Promise<string[]>; /** * Returns an (yesql formatted) upsert function based on the key/vals of an object. * eg, * insert into customers ("id", "name") * values (:id, :name) * on conflict (id) * do update set ( * "id" = :id, * "name" = :name * ) */ private constructUpsertSql; /** * For array object field * ex: [{"name":"Project name","value":"Test Project"}] * * we need to stringify it first cos passing array object directly will end up with * { * invalid input syntax for type json * detail: 'Expected ":", but found "}".', * where: 'JSON data, line 1: ...\\":\\"Project name\\",\\"value\\":\\"Test Project\\"}"}', * } */ private cleanseArrayField; } type Logger = Pick<globalThis.Console, 'info' | 'error' | 'warn' | 'debug'>; type MuxSyncConfig = { /** Postgres database URL including authentication */ databaseUrl: string; /** Mux token ID used to authenticate requests to the Mux API. */ muxTokenId: string; /** Mux token secret used to authenticate requests to the Mux API. */ muxTokenSecret: string; /** Mux webhook secret used to verify the signature of webhook events. */ muxWebhookSecret: string; /** * If true, the sync engine will backfill related entities, i.e. when a Upload webhook comes in, it ensures that the asset is present and synced. * This ensures foreign key integrity, but comes at the cost of additional queries to the database (and added latency for Mux calls if the entity is actually missing). */ backfillRelatedEntities?: boolean; /** * If true, the webhook data is not used and instead the webhook is just a trigger to fetch the entity from Mux again. This ensures that a race condition with failed webhooks can never accidentally overwrite the data with an older state. * * Default: false */ revalidateEntityViaMuxApi?: boolean; maxPostgresConnections?: number; /** Optional logger. If not provided, `console` will be used. */ logger?: Logger; }; type SyncObject = 'all' | 'mux_assets' | 'mux_live_streams' | 'mux_uploads'; interface Sync { synced: number; } interface SyncBackfill { muxAssets?: Sync; muxLiveStreams?: Sync; muxUploads?: Sync; } interface SyncBackfillParams { object?: SyncObject; } interface MuxListResponse<T> { data: T[]; next_cursor?: string; } interface SimulcastTargetData { live_stream_id?: string; id?: string; [key: string]: unknown; } interface StaticRenditionData { asset_id?: string; id?: string; [key: string]: unknown; } interface TrackData extends Record<string, unknown> { asset_id?: string; id?: string; } type TransformFunction<T, R = Record<string, unknown>> = (entity: T) => R; interface UpsertResult { id: string; [key: string]: unknown; } type EntitySchema = EntitySchema$1; declare class MuxSync { private config; mux: Mux; postgresClient: PostgresClient; private logger; constructor(config: MuxSyncConfig); processWebhook(payload: string, headers: HeadersLike): Promise<void>; syncBackfill(params?: SyncBackfillParams): Promise<SyncBackfill>; private fetchOrUseWebhookData; private upsertAssets; private genericSync; private syncMuxAssets; private upsertEntitiesWithRelatedAssets; private upsertLiveStreams; private upsertUploads; private syncMuxLiveStreams; private syncMuxUploads; private handleAssetUpdateEvent; private handleAssetTrackEvent; private handleLiveStreamUpdateEvent; private handleLiveStreamSimulcastTargetEvent; private handleAssetStaticRenditionEvent; private deleteAsset; private deleteLiveStream; private upsertWebhookEvent; } type MigrationConfig = { databaseUrl: string; logger?: Logger; }; declare function runMigrations(config: MigrationConfig): Promise<void>; export { type EntitySchema, type Logger, type MuxListResponse, MuxSync, type MuxSyncConfig, type SimulcastTargetData, type StaticRenditionData, type Sync, type SyncBackfill, type SyncBackfillParams, type SyncObject, type TrackData, type TransformFunction, type UpsertResult, runMigrations };