Skip to content
← Public packages

@kentcdodds/transistor

Authenticated Transistor.fm helpers for shows, episodes, episode metadata, and morning-briefing-ready podcast analytics.

src/index.d.ts

363 lines · 8.4 KB · TypeScript
export type TransistorShow = {
	id: string
	type: string
	title?: string
	slug?: string
	description?: string
	status?: string
	feedUrl?: string
	siteUrl?: string
	private?: boolean
	author?: string
	keywords?: string
	category?: string
	language?: string
	showType?: string
	timeZone?: string
	explicit?: boolean
	imageUrl?: string
	raw?: unknown
}

export type TransistorEpisode = {
	id: string
	type: string
	title?: string
	number?: number
	season?: number
	episodeType?: string
	status?: string
	publishedAt?: string
	duration?: number
	mediaUrl?: string
	shareUrl?: string
	alternateUrl?: string
	videoUrl?: string
	imageUrl?: string
	slug?: string
	raw?: unknown
}

export type TransistorEpisodeAnalytics = {
	id: string
	title?: string
	publishedAt?: string
	downloads: Array<{ date?: string; downloads?: number }>
	downloadCount: number
}

export type TransistorPaginationMeta = Record<string, unknown>

export type ListShowsInput = {
	query?: string
	private?: boolean
	page?: number
	per?: number
}

export type ListShowsResult = {
	shows: TransistorShow[]
	meta: TransistorPaginationMeta
	raw: unknown
}

export type ListEpisodesInput = {
	/** Required show id (also accepts `show_id`). */
	showId?: string
	show_id?: string
	query?: string
	status?: string
	order?: 'asc' | 'desc' | string
	page?: number
	per?: number
}

export type ListEpisodesResult = {
	episodes: TransistorEpisode[]
	meta: TransistorPaginationMeta
	raw: unknown
}

export type GetEpisodeInput = {
	/** Required episode id (also accepts `id`). */
	episodeId?: string
	id?: string
}

export type GetShowInput = {
	/** Show id or slug. */
	showId?: string
	id?: string
	slug?: string
}

export type ShowWriteFields = {
	title?: string
	author?: string
	website?: string
	description?: string
	keywords?: string
	category?: string
	secondary_category?: string
	language?: string
	show_type?: 'episodic' | 'serial' | string
	time_zone?: string
	explicit?: boolean | string
	copyright?: string
	owner_email?: string
	image_url?: string
	multiple_seasons?: boolean | string
}

export type PatchShowInput = ShowWriteFields & {
	showId?: string
	id?: string
	slug?: string
	show?: ShowWriteFields
	/** Required — mutating. */
	confirm: true
}

export type EpisodeWriteFields = {
	audio_url?: string
	transcript_text?: string
	author?: string
	description?: string
	explicit?: boolean | string
	image_url?: string
	keywords?: string
	number?: number
	season?: number
	/** Only `""` is allowed (clears a legacy summary). Non-empty values throw. */
	summary?: ''
	type?: 'full' | 'trailer' | 'bonus' | string
	title?: string
	alternate_url?: string
	video_url?: string
	email_notifications?: boolean
	increment_number?: boolean
	show_id?: string
	showId?: string
}

export type CreateEpisodeInput = EpisodeWriteFields & {
	/** Nested episode payload (fields may also be top-level). */
	episode?: EpisodeWriteFields
	showId?: string
	show_id?: string
	increment_number?: boolean
}

export type UpdateEpisodeInput = EpisodeWriteFields & {
	/** Required episode id (also accepts `id`). */
	episodeId?: string
	id?: string
	episode?: EpisodeWriteFields
}

export type PublishEpisodeInput = {
	episodeId?: string
	id?: string
	status: 'published' | 'scheduled' | 'draft'
	publishedAt?: string
	published_at?: string
	/** Required — mutating. */
	confirm: true
}

export type ClearEpisodeSummaryInput = {
	episodeId?: string
	id?: string
}

export type AnalyticsDateInput = {
	showId?: string
	id?: string
	startDate?: string
	endDate?: string
	timeZone?: string
}

export type EpisodesAnalyticsResult = {
	id?: string
	type?: string
	startDate?: string
	endDate?: string
	episodes: TransistorEpisodeAnalytics[]
	totalDownloads: number
	raw: unknown
}

export type MorningBriefingSnapshotInput = {
	days?: number
	/** When true (default), the window ends on the last completed local day. */
	completedDays?: boolean
	startDate?: string
	endDate?: string
	timeZone?: string
	showIds?: Array<string | number>
	showLimit?: number
	minLiveRequestGapMs?: number
}

export type MorningBriefingSnapshot = {
	window: {
		timeZone: string
		startDate: string
		endDate: string
		label: string
	}
	podcasts: Array<{
		podcast: TransistorShow
		downloads: {
			total: number
			startDate?: string
			endDate?: string
		}
		topEpisodes: TransistorEpisodeAnalytics[]
		episodeCount: number
		episodeCountWithDownloads: number
	}>
	totals: {
		downloads: number
		podcastCount: number
		podcastCountWithDownloads: number
		episodeCount: number
		episodeCountWithDownloads: number
	}
}

export type SmokeTestResult = {
	user: {
		id?: string
		name?: string
	}
	showCount: number
	shows: Array<{
		id: string
		title?: string
		slug?: string
		feedUrl?: string
	}>
}

export type OverviewResult = {
	name: string
	description: string
	commonActions: string[]
	notes: string[]
}

export type RequestOptions = {
	method?: string
	query?: Record<string, unknown>
	body?: unknown
	headers?: Record<string, string>
	maxAttempts?: number
}

export type TransistorAction =
	| 'overview'
	| 'smokeTest'
	| 'request'
	| 'listShows'
	| 'getShow'
	| 'patchShow'
	| 'listEpisodes'
	| 'getEpisode'
	| 'createEpisode'
	| 'updateEpisode'
	| 'publishEpisode'
	| 'clearEpisodeSummary'
	| 'getShowAnalytics'
	| 'getEpisodesAnalytics'
	| 'morningBriefingSnapshot'
	| 'getMorningBriefingSnapshot'

/**
 * Compatibility dispatcher input. Prefer named typed exports
 * (`listShows`, `listEpisodes`, `getMorningBriefingSnapshot`, …).
 */
export type TransistorInput =
	| { action?: 'overview' }
	| { action: 'smokeTest' }
	| {
			action: 'request'
			path?: string
			method?: string
			query?: Record<string, unknown>
			body?: unknown
			headers?: Record<string, string>
			options?: RequestOptions
	  }
	| ({ action: 'listShows' } & ListShowsInput)
	| ({ action: 'getShow' } & GetShowInput)
	| ({ action: 'patchShow' } & PatchShowInput)
	| ({ action: 'listEpisodes' } & ListEpisodesInput)
	| ({ action: 'getEpisode' } & GetEpisodeInput)
	| ({ action: 'createEpisode' } & CreateEpisodeInput)
	| ({ action: 'updateEpisode' } & UpdateEpisodeInput)
	| ({ action: 'publishEpisode' } & PublishEpisodeInput)
	| ({ action: 'clearEpisodeSummary' } & ClearEpisodeSummaryInput)
	| ({ action: 'getShowAnalytics' } & AnalyticsDateInput)
	| ({ action: 'getEpisodesAnalytics' } & AnalyticsDateInput)
	| ({
			action: 'morningBriefingSnapshot' | 'getMorningBriefingSnapshot'
	  } & MorningBriefingSnapshotInput)

/**
 * Dispatch Transistor.fm podcast helpers. Prefer named exports such as
 * `listShows` / `getMorningBriefingSnapshot` for typed call sites.
 * @param input.action One of the known actions; defaults to `overview`.
 * @example
 * import { listShows } from 'kody:@kentcdodds/transistor'
 * const result = await listShows()
 * // => { shows: [{ id: '78601', title: '...', slug: '...' }], ... }
 */
export default function transistor(
	input?: TransistorInput,
): Promise<
	| OverviewResult
	| SmokeTestResult
	| ListShowsResult
	| ListEpisodesResult
	| TransistorShow
	| TransistorEpisode
	| EpisodesAnalyticsResult
	| MorningBriefingSnapshot
	| unknown
>

export function request(
	path: string,
	options?: RequestOptions,
): Promise<unknown>

/** @deprecated Prefer `request`. */
export function transistorRequest(
	pathOrInput: string | { path?: string; method?: string; query?: Record<string, unknown>; body?: unknown; headers?: Record<string, string> },
	options?: RequestOptions,
): Promise<unknown>

export function getCurrentUser(): Promise<unknown>

export function listShows(input?: ListShowsInput): Promise<ListShowsResult>
export function getShow(input: GetShowInput): Promise<TransistorShow>
export function patchShow(input: PatchShowInput): Promise<TransistorShow>
export function listEpisodes(input: ListEpisodesInput): Promise<ListEpisodesResult>
export function getEpisode(input: GetEpisodeInput): Promise<TransistorEpisode>
export function createEpisode(input: CreateEpisodeInput): Promise<TransistorEpisode>
export function updateEpisode(input: UpdateEpisodeInput): Promise<TransistorEpisode>
export function publishEpisode(input: PublishEpisodeInput): Promise<TransistorEpisode>
export function clearEpisodeSummary(
	input: ClearEpisodeSummaryInput,
): Promise<TransistorEpisode>
export function getShowAnalytics(input: AnalyticsDateInput): Promise<unknown>
export function getEpisodesAnalytics(
	input: AnalyticsDateInput,
): Promise<EpisodesAnalyticsResult>
export function getMorningBriefingSnapshot(
	input?: MorningBriefingSnapshotInput,
): Promise<MorningBriefingSnapshot>
export function smokeTest(): Promise<SmokeTestResult>
export function getOverview(): OverviewResult