← Public packages
@charlesmatte/granola
Search and read Granola meeting notes, summaries and transcripts from any agent; manage webhooks and legal holds safely.
src/lib/api.ts
28 lines · 1.8 KB · TypeScriptimport { resolveAccount, type Account } from './account.ts'
import { granolaRequest, type Query } from './client.ts'
import { paginate } from './paginate.ts'
import { authSpec, mutationSpec, pageSpec, parseInput, type Spec } from './validate.ts'
/** Parse input with the shared `account` / `secretName` fields plus export-specific fields. */
export function parseWithAccount<T extends Record<string, unknown>>(raw: unknown, spec: Spec, exportName: string): T & { acct: Account } {
const params = parseInput<T & { account: string; secretName?: string }>(raw, { ...authSpec, ...spec }, exportName)
return { ...params, acct: resolveAccount(params) }
}
export { mutationSpec, pageSpec }
type ListOptions = { path: string; itemsKey: string; query?: Query; limit: number; maxPageSize: number; cursor?: string; paginate: boolean }
/** Run a cursor-paginated Granola list endpoint and return `{ items, count, hasMore, cursor, pages, truncated }`. */
export async function listEndpoint<T = Record<string, unknown>>(a: Account, o: ListOptions, wrap: <R>(fn: () => Promise<R>) => Promise<R> = (fn) => fn()) {
const result = await paginate<T>(
async (cursor, pageSize) => {
const res = await wrap(() => granolaRequest<Record<string, unknown>>(a, { path: o.path, query: { ...o.query, cursor, page_size: pageSize } }))
const data = res.data ?? {}
const items = Array.isArray(data[o.itemsKey]) ? (data[o.itemsKey] as Array<T>) : []
return { items, hasMore: Boolean(data.hasMore), cursor: typeof data.cursor === 'string' ? data.cursor : null }
},
{ limit: o.limit, maxPageSize: o.maxPageSize, cursor: o.cursor, paginate: o.paginate },
)
return { count: result.items.length, items: result.items, hasMore: result.hasMore, cursor: result.cursor, pages: result.pages, truncated: result.truncated }
}