File Management
Manage your uploaded files with list, get, and delete operations.
List Files
Retrieve a paginated list of files with filtering and sorting options.
Basic Listing
import { DropperClient } from '@dropper/core'
const client = new DropperClient({
publishableKey: 'pk_dropper_test_xxx',
})
const response = await client.listFiles()
console.log(`Total files: ${response.total}`)
response.data.forEach((file) => {
console.log(`- ${file.originalFilename} (${file.size} bytes)`)
})
ListFilesParams
interface ListFilesParams {
folderId?: string // Filter by folder
search?: string // Search by filename
mimeType?: string // Filter by MIME type
sortBy?: 'name' | 'size' | 'createdAt' | 'updatedAt' // Sort field
sortOrder?: 'asc' | 'desc' // Sort direction
page?: number // Page number (default: 1)
limit?: number // Items per page (default: 20)
}
ListFilesResponse
interface ListFilesResponse {
data: FileResponseDto[] // Array of files
total: number // Total number of files
page: number // Current page
limit: number // Items per page
}
Filtering Files
By Folder
List files in a specific folder:
const response = await client.listFiles({
folderId: 'folder_abc123',
})
By MIME Type
Filter files by type:
// Images only
const images = await client.listFiles({
mimeType: 'image/*',
})
// PDFs only
const pdfs = await client.listFiles({
mimeType: 'application/pdf',
})
// Videos only
const videos = await client.listFiles({
mimeType: 'video/*',
})
By Search Query
Search files by filename:
const response = await client.listFiles({
search: 'invoice',
})
Sorting Files
Sort by Name
const response = await client.listFiles({
sortBy: 'name',
sortOrder: 'asc',
})
Sort by Size
const response = await client.listFiles({
sortBy: 'size',
sortOrder: 'desc', // Largest first
})
Sort by Date
// Most recent first
const response = await client.listFiles({
sortBy: 'createdAt',
sortOrder: 'desc',
})
// Oldest first
const response = await client.listFiles({
sortBy: 'updatedAt',
sortOrder: 'asc',
})
Pagination
Handle large file lists with pagination:
const page = 1
const limit = 20
const response = await client.listFiles({
page,
limit,
})
console.log(`Showing ${response.data.length} of ${response.total} files`)
console.log(`Page ${response.page} of ${Math.ceil(response.total / response.limit)}`)
Load More Pattern
let page = 1
const limit = 20
const allFiles: FileResponseDto[] = []
while (true) {
const response = await client.listFiles({ page, limit })
allFiles.push(...response.data)
if (allFiles.length >= response.total) {
break
}
page++
}
console.log(`Loaded ${allFiles.length} files`)
Get Single File
Retrieve details for a specific file:
const file = await client.getFile('file_abc123')
console.log('File details:')
console.log(`- Name: ${file.originalFilename}`)
console.log(`- Size: ${file.size} bytes`)
console.log(`- Type: ${file.mimeType}`)
console.log(`- URL: ${file.url}`)
console.log(`- Created: ${file.createdAt}`)
Delete File
Remove a file from storage:
await client.deleteFile('file_abc123')
console.log('File deleted successfully')
With Error Handling
try {
await client.deleteFile('file_abc123')
console.log('File deleted successfully')
} catch (error) {
if (error.statusCode === 404) {
console.error('File not found')
} else if (error.statusCode === 403) {
console.error('Permission denied')
} else {
console.error('Delete failed:', error.message)
}
}
FileResponseDto
The file object returned by the API:
interface FileResponseDto {
id: string // Unique file ID
originalFilename: string // Original filename
mimeType: string // MIME type (e.g., "image/jpeg")
size: number // File size in bytes
storagePath: string // Storage path
isPublic: boolean // Public access flag
extension?: string // File extension (e.g., "jpg")
virtualPath?: string // Virtual path
width?: number // Image width (if image)
height?: number // Image height (if image)
duration?: number // Video duration (if video)
url: string // Public URL
thumbnailUrl?: string // Thumbnail URL (if image/video)
folderId?: string // Parent folder ID
appId: string // App ID
metadata?: Record<string, unknown> // Custom metadata
createdAt: string // ISO timestamp
updatedAt: string // ISO timestamp
}
Complete Examples
File Gallery
import { DropperClient, formatFileSize } from '@dropper/core'
const client = new DropperClient({
publishableKey: process.env.DROPPER_KEY!,
})
async function loadImageGallery() {
const response = await client.listFiles({
mimeType: 'image/*',
sortBy: 'createdAt',
sortOrder: 'desc',
limit: 50,
})
console.log(`Found ${response.total} images`)
response.data.forEach((file) => {
console.log(`Image: ${file.originalFilename}`)
console.log(` Size: ${formatFileSize(file.size)}`)
console.log(` Dimensions: ${file.width}x${file.height}`)
console.log(` URL: ${file.url}`)
console.log(` Thumbnail: ${file.thumbnailUrl}`)
console.log()
})
}
File Search
async function searchFiles(query: string) {
const response = await client.listFiles({
search: query,
sortBy: 'name',
sortOrder: 'asc',
})
if (response.total === 0) {
console.log(`No files found for "${query}"`)
return []
}
console.log(`Found ${response.total} files matching "${query}"`)
return response.data
}
Bulk Delete
async function deleteMultipleFiles(fileIds: string[]) {
const results = await Promise.allSettled(
fileIds.map((id) => client.deleteFile(id))
)
const successful = results.filter((r) => r.status === 'fulfilled').length
const failed = results.filter((r) => r.status === 'rejected').length
console.log(`Deleted ${successful} files`)
if (failed > 0) {
console.error(`Failed to delete ${failed} files`)
}
}
File Statistics
async function getFileStatistics() {
const response = await client.listFiles({
limit: 1000, // Get more files for accurate stats
})
const totalSize = response.data.reduce((sum, file) => sum + file.size, 0)
const avgSize = totalSize / response.data.length
const byType = response.data.reduce((acc, file) => {
const category = file.mimeType.split('/')[0]
acc[category] = (acc[category] || 0) + 1
return acc
}, {} as Record<string, number>)
console.log('File Statistics:')
console.log(`Total files: ${response.total}`)
console.log(`Total size: ${formatFileSize(totalSize)}`)
console.log(`Average size: ${formatFileSize(avgSize)}`)
console.log('By type:', byType)
}
Best Practices
1. Use Pagination
Always use pagination for large file lists:
const response = await client.listFiles({
page: 1,
limit: 20,
})
2. Filter Early
Apply filters to reduce data transfer:
// Good: Filter on server
const images = await client.listFiles({
mimeType: 'image/*',
})
// Bad: Filter on client
const all = await client.listFiles()
const images = all.data.filter(f => f.mimeType.startsWith('image/'))
3. Cache Results
Cache file lists to reduce API calls:
let cachedFiles: FileResponseDto[] | null = null
let cacheTime: number = 0
const CACHE_DURATION = 60000 // 1 minute
async function getFiles() {
const now = Date.now()
if (cachedFiles && now - cacheTime < CACHE_DURATION) {
return cachedFiles
}
const response = await client.listFiles()
cachedFiles = response.data
cacheTime = now
return cachedFiles
}
4. Handle Errors
Always handle errors when deleting files:
try {
await client.deleteFile(fileId)
showSuccess('File deleted')
} catch (error) {
showError(`Failed to delete: ${error.message}`)
}
Next Steps
- File Upload - Upload new files
- Folder Management - Organize files in folders
- Utilities - Helper functions for file operations