Skip to content

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

Package listing

@kentcdodds/notion

src/query-database.ts

48 lines · 1.7 KB · TypeScript
import { nextCursor, notionRequest, resolveDataSourceId, type JsonRecord } from './request.ts'
import { boundedPageSize, inputRecord, optionalArray, optionalRecord, optionalString } from './validation.ts'

type QueryResponse = {
  results?: unknown[]
  has_more?: boolean
  next_cursor?: string | null
  [key: string]: unknown
}

/**
 * Query a Notion database's rows with optional filter and sorts.
 *
 * Pass `dataSourceId` directly, or `databaseId` to auto-resolve the database's
 * single data source (errors if the database has multiple data sources).
 */
export default async function queryDatabase(params: Record<string, unknown>) {
  const input = inputRecord(params)
  const account = optionalString(input, 'account')
  const integration = optionalString(input, 'integration')
  const explicitDataSourceId = optionalString(input, 'dataSourceId')
  const databaseId = optionalString(input, 'databaseId')
  if (!explicitDataSourceId && !databaseId) {
    throw new Error('dataSourceId or databaseId is required.')
  }
  const dataSourceId =
    explicitDataSourceId ??
    (await resolveDataSourceId(databaseId as string, { account, integration }))

  const body: JsonRecord = {
    filter: optionalRecord(input, 'filter'),
    sorts: optionalArray(input, 'sorts'),
    page_size: boundedPageSize(input.pageSize),
    start_cursor: optionalString(input, 'startCursor'),
  }

  const result = await notionRequest<QueryResponse>(
    '/data_sources/' + encodeURIComponent(dataSourceId) + '/query',
    { method: 'POST', body, account, integration },
  )

  return {
    dataSourceId,
    results: result.results ?? [],
    hasMore: result.has_more === true,
    nextCursor: nextCursor(result),
  }
}