Skip to content
← Public packages

@kody/notion

Search, read, query, and safely write Notion pages and databases through the saved notion OAuth integration.

src/query-database.ts

44 lines · 1.5 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 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))

  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 },
  )

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