Skip to content

Built for people who want to own their automations. Join the waitlist for an invite.

Package listing

@kody/sessionize

src/find-session.ts

65 lines · 1.8 KB · TypeScript
import { assertEndpointId, fetchSessionizeView } from './client.ts'
import { flattenSessionGroups, matchSession } from './project.ts'
import type {
	EndpointInput,
	SessionizeListedSession,
	SessionizeSessionGroup,
	SlimSession,
} from './types.ts'

export type FindSessionInput = EndpointInput & {
	/** Session id, exact title, or a case-insensitive title/speaker fragment. */
	query: string
}

export type FoundSession = SlimSession & {
	description: string | null
}

/**
 * Find one Sessionize session by id, title, or speaker name.
 *
 * @example
 * import findSession from 'kody:@kody/sessionize/find-session'
 * const result = await findSession({ endpointId: 'jl4ktls0', query: 'Aiden' })
 * // => { matchCount: 1, session: { title: "Aiden's Keynote", description: '...' } }
 */
export default async function findSession(input: FindSessionInput): Promise<{
	endpointId: string
	query: string
	matchCount: number
	session: FoundSession | null
	matches: Array<SlimSession>
}> {
	const endpointId = assertEndpointId(input.endpointId)
	const query = input.query.trim()
	if (!query) {
		throw new Error('findSession requires a non-empty query.')
	}

	const groups = await fetchSessionizeView<Array<SessionizeSessionGroup>>({
		endpointId,
		view: 'Sessions',
	})
	const listedById = new Map<string, SessionizeListedSession>()
	for (const group of groups) {
		for (const session of group.sessions) {
			listedById.set(String(session.id), session)
		}
	}

	const items = flattenSessionGroups(groups)
	const matches = items.filter((session) => matchSession(session, query))
	const top = matches[0] ?? null
	const listed = top ? listedById.get(top.id) : null

	return {
		endpointId,
		query,
		matchCount: matches.length,
		session: top
			? { ...top, description: listed?.description ?? null }
			: null,
		matches,
	}
}