Skip to content

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

Package listing

@kody/trello

src/comments.ts

101 lines · 2.9 KB · TypeScript
import { isDryRunResult, trelloRequest } from './client.ts'
import { parseAuthInput } from './auth.ts'
import { commentSummary, mapMany, requireMapped } from './models.ts'
import type {
	DryRunResult,
	MutationInput,
	TrelloAuthInput,
	TrelloCommentSummary,
} from './types.ts'
import { clampInt, compactRecord, optionalBoolean, optionalString, requireRecord, requireString } from './types.ts'

export type ListCommentsInput = TrelloAuthInput & {
	cardId: string
	limit?: number
}

export type AddCommentInput = TrelloAuthInput &
	MutationInput & {
		cardId: string
		text: string
	}

/**
 * List commentCard actions on a caller-supplied card id.
 * @example
 * import { listComments } from 'kody:@kody/trello/comments'
 * const comments = await listComments({ cardId, limit: 25 })
 */
export async function listComments(
	input: ListCommentsInput,
): Promise<Array<TrelloCommentSummary>> {
	const cardId = requireString(input.cardId, 'cardId')
	const limit = clampInt(input.limit, 1, 1000, 25)
	const result = await trelloRequest<unknown>({
		...input,
		method: 'GET',
		path: `/cards/${cardId}/actions`,
		query: compactRecord({
			filter: 'commentCard',
			limit,
		}),
	})
	if (isDryRunResult(result)) return []
	return mapMany(result.data, commentSummary).slice(0, limit)
}

/**
 * Add a comment to a Trello card. Requires `confirm: true`, or use `dryRun: true`.
 * @example
 * import { addComment } from 'kody:@kody/trello/comments'
 * const preview = await addComment({ cardId, text: 'Looks good', dryRun: true })
 */
export async function addComment(
	input: AddCommentInput,
): Promise<TrelloCommentSummary | DryRunResult> {
	const cardId = requireString(input.cardId, 'cardId')
	const body = {
		text: requireString(input.text, 'text'),
	}
	const result = await trelloRequest<Record<string, unknown>>({
		...input,
		method: 'POST',
		path: `/cards/${cardId}/actions/comments`,
		query: body,
		body,
	})
	if (isDryRunResult(result)) return result
	return requireMapped(commentSummary(result.data), 'addComment')
}

export { commentSummary }

/**
 * Comment helpers dispatcher.
 * @example
 * import comments from 'kody:@kody/trello/comments'
 * const items = await comments({ action: 'list', cardId })
 */
export default async function commentsEntrypoint(params: Record<string, unknown> = {}) {
	const input = requireRecord(params, 'comments')
	const auth = parseAuthInput(input)
	const action = optionalString(input.action, 'action') ?? 'list'
	switch (action) {
		case 'list':
			return listComments({
				...auth,
				cardId: requireString(input.cardId, 'cardId'),
				limit: input.limit as number | undefined,
			})
		case 'add':
			return addComment({
				...auth,
				cardId: requireString(input.cardId, 'cardId'),
				text: requireString(input.text, 'text'),
				confirm: optionalBoolean(input.confirm, 'confirm'),
				dryRun: optionalBoolean(input.dryRun, 'dryRun'),
			})
		default:
			throw new Error('comments action must be one of: list, add.')
	}
}