import { dropboxRpc } from './request.ts'
import type { JsonRecord } from './types.ts'
import {
optionalBoolean,
optionalNumber,
optionalString,
requireDropboxPath,
requireRecord,
requireString,
} from './types.ts'
export type SearchDropboxInput = {
query?: string
cursor?: string
path?: string
maxResults?: number
filenameOnly?: boolean
}
export type SearchDropboxResult = {
matches: JsonRecord[]
has_more: boolean
cursor?: string
}
export async function searchDropbox(
input: SearchDropboxInput,
): Promise<SearchDropboxResult> {
const cursor = optionalString(input.cursor, 'cursor')
if (cursor) {
return dropboxRpc<SearchDropboxResult>('files/search/continue_v2', { cursor })
}
const query = requireString(input.query, 'query')
const path = requireDropboxPath(input.path ?? '', 'path', { allowRoot: true })
const maxResults = optionalNumber(input.maxResults, 'maxResults')
if (
maxResults !== undefined &&
(!Number.isInteger(maxResults) || maxResults < 1 || maxResults > 1000)
) {
throw new Error('maxResults must be an integer from 1 through 1000.')
}
return dropboxRpc<SearchDropboxResult>('files/search_v2', {
query,
options: {
path,
filename_only: optionalBoolean(input.filenameOnly, 'filenameOnly') ?? false,
...(maxResults === undefined ? {} : { max_results: maxResults }),
},
})
}
/**
* Search Dropbox file and folder names, or continue with a previous cursor.
* @example
* import search from 'kody:@kentcdodds/dropbox/search'
* const results = await search({ query: 'invoice', path: '/documents' })
*/
export default async function searchDropboxEntrypoint(
params: Partial<SearchDropboxInput> & Record<string, unknown> = {},
) {
return searchDropbox(requireRecord(params, 'search') as SearchDropboxInput)
}