import { dropboxRpc } from './request.ts'
import type { JsonRecord } from './types.ts'
import {
optionalBoolean,
optionalNumber,
optionalString,
requireDropboxPath,
requireRecord,
} from './types.ts'
export type ListFolderInput = {
path?: string
cursor?: string
recursive?: boolean
includeDeleted?: boolean
includeMediaInfo?: boolean
includeNonDownloadableFiles?: boolean
limit?: number
}
export type ListFolderResult = {
entries: JsonRecord[]
cursor: string
has_more: boolean
}
export async function listFolder(input: ListFolderInput = {}): Promise<ListFolderResult> {
const cursor = optionalString(input.cursor, 'cursor')
if (cursor) {
return dropboxRpc<ListFolderResult>('files/list_folder/continue', { cursor })
}
const path = requireDropboxPath(input.path ?? '', 'path', { allowRoot: true })
const limit = optionalNumber(input.limit, 'limit')
if (limit !== undefined && (!Number.isInteger(limit) || limit < 1 || limit > 2000)) {
throw new Error('limit must be an integer from 1 through 2000.')
}
return dropboxRpc<ListFolderResult>('files/list_folder', {
path,
recursive: optionalBoolean(input.recursive, 'recursive') ?? false,
include_deleted: optionalBoolean(input.includeDeleted, 'includeDeleted') ?? false,
include_media_info: optionalBoolean(input.includeMediaInfo, 'includeMediaInfo') ?? false,
include_non_downloadable_files:
optionalBoolean(input.includeNonDownloadableFiles, 'includeNonDownloadableFiles') ??
true,
...(limit === undefined ? {} : { limit }),
})
}
/**
* List a Dropbox folder or continue a previous page with `cursor`.
* Use an empty path for the account root.
* @example
* import listFolder from 'kody:@kentcdodds/dropbox/list-folder'
* const page = await listFolder({ path: '', limit: 100 })
*/
export default async function listFolderEntrypoint(
params: Partial<ListFolderInput> & Record<string, unknown> = {},
) {
return listFolder(requireRecord(params, 'list-folder') as ListFolderInput)
}