Skip to content

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

Package listing

@kody/trello

src/viewer.ts

62 lines · 2.1 KB · TypeScript
import { trelloRequestWithAuth } from './client.ts'
import { parseAuthInput, resolveTrelloAuth } from './auth.ts'
import { MEMBER_FIELDS, ORG_FIELDS, memberSummary, mapMany, organizationSummary } from './models.ts'
import type { TrelloAuthInput, TrelloMemberSummary, TrelloOrganizationSummary } from './types.ts'
import { clampInt, optionalString, requireRecord } from './types.ts'

export type ViewerInput = TrelloAuthInput & {
	includeOrganizations?: boolean
	organizationLimit?: number
}

export type ViewerResult = TrelloMemberSummary & {
	organizations?: Array<TrelloOrganizationSummary>
}

/**
 * Return the authenticated Trello member (no email).
 * @example
 * import { getViewer } from 'kody:@kody/trello/viewer'
 * const me = await getViewer()
 */
export async function getViewer(input: ViewerInput = {}): Promise<ViewerResult> {
	const auth = await resolveTrelloAuth(input)
	const result = await trelloRequestWithAuth<Record<string, unknown>>(auth, {
		method: 'GET',
		path: '/members/me',
		query: { fields: MEMBER_FIELDS },
	})
	const member = memberSummary(result.data)
	if (!member) throw new Error('Trello /members/me returned no member.')

	if (input.includeOrganizations !== true) return member

	const orgs = await trelloRequestWithAuth<unknown>(auth, {
		method: 'GET',
		path: '/members/me/organizations',
		query: { fields: ORG_FIELDS },
	})
	const limit = clampInt(input.organizationLimit, 1, 100, 25, 'organizationLimit')
	return {
		...member,
		organizations: mapMany(orgs.data, organizationSummary).slice(0, limit),
	}
}

/**
 * Return the authenticated Trello member (no email).
 * @example
 * import getViewer from 'kody:@kody/trello/viewer'
 * const me = await getViewer({ account: 'work' })
 */
export default async function viewerEntrypoint(
	params: ViewerInput & Record<string, unknown> = {},
) {
	const input = requireRecord(params, 'viewer')
	return getViewer({
		...parseAuthInput(input),
		includeOrganizations: input.includeOrganizations === true,
		organizationLimit: input.organizationLimit as number | undefined,
		account: optionalString(input.account, 'account'),
	})
}