@better-s3/react 3.1045.1 → 3.1045.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/helpers.ts","../src/upload/retry.ts","../src/upload/simple.ts","../src/upload/part.ts","../src/upload/multipart.ts","../src/upload/upload-file.ts","../src/upload/upload-files.ts","../src/use-upload.ts","../src/use-multi-upload.ts","../src/use-upload-controls.ts","../src/use-download.ts","../src/use-fetch-download.ts","../src/use-delete.ts"],"names":["parseContentDispositionFilename","header","fallback","starMatch","match","formatFileSize","bytes","units","i","withRetry","fn","retries","signal","lastError","attempt","err","delay","r","uploadSimple","file","url","fields","onProgress","resolve","reject","xhr","onAbort","e","formData","k","v","uploadPut","headers","uploadPart","blob","presignedUrl","partLoaded","totalSize","reportProgress","uploadMultipart","api","objectKey","partSize","concurrentParts","requestOptions","contentType","uploadId","key","totalParts","parts","partProgress","loaded","sum","p","batchStart","batchEnd","batch","start","end","partNumber","batchResults","a","b","result","uploadFile","config","callbacks","threshold","useMultipart","eTag","presign","uploadFiles","items","getRequestOptions","results","item","reportTotalProgress","total","nextIndex","processNext","idx","progress","message","concurrentFiles","workers","INITIAL_PROGRESS","INITIAL_STATE","useUpload","options","state","setState","useState","optionsRef","useRef","abortRef","upload","useCallback","opts","validationError","validateFile","s","controller","phase","cancel","reset","nextId","generateId","useMultiUpload","fileMapRef","files","resolveKey","fileStates","fileMap","msg","id","f","error","perFile","hasErrors","successResults","useUploadControls","isMulti","singleOpts","multiOpts","single","multi","inputRef","fileInfo","setFileInfo","handleFiles","openFilePicker","isUploading","useDownload","downloadName","download","useFetchDownload","res","contentLength","name","reader","chunks","done","value","percent","blobUrl","anchor","useDelete","pendingKey","setPendingKey","requestDelete","confirmDelete","cancelDelete"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Parses the filename from a `Content-Disposition` header value.\n * Prefers `filename*` (RFC 5987, full Unicode) over `filename`.\n * Returns `fallback` if no filename is found.\n */\nexport function parseContentDispositionFilename(\n header: string | null,\n fallback: string,\n): string {\n if (!header) return fallback;\n const starMatch = header.match(/filename\\*=UTF-8''([^;,\\s]+)/i);\n if (starMatch) {\n try {\n return decodeURIComponent(starMatch[1]);\n } catch {\n // fall through\n }\n }\n const match = header.match(/filename=\"([^\"]+)\"/i);\n if (match) return match[1];\n return fallback;\n}\n\nexport function formatFileSize(bytes: number): string {\n if (bytes === 0) return \"0 B\";\n const units = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(1024));\n const size = bytes / Math.pow(1024, i);\n return `${size.toFixed(i === 0 ? 0 : 1)} ${units[i]}`;\n}\n","import { RETRY_BASE_DELAY } from \"./constants\";\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n retries: number,\n signal?: AbortSignal,\n): Promise<T> {\n let lastError: unknown;\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n return await fn();\n } catch (err) {\n if ((err as Error).name === \"AbortError\") throw err;\n lastError = err;\n if (attempt < retries) {\n const delay = RETRY_BASE_DELAY * 2 ** attempt;\n await new Promise((r) => setTimeout(r, delay));\n if (signal?.aborted)\n throw new DOMException(\"Upload aborted\", \"AbortError\");\n }\n }\n }\n throw lastError;\n}\n","import type { UploadProgress } from \"../types\";\n\n/**\n * Uploads a file directly to S3 using a presigned POST form.\n *\n * All policy fields (acl, Content-Type, content-length-range, signature, etc.)\n * are embedded in `fields` and must be appended to the FormData **before** the\n * file — this is an S3 requirement. The size constraint is enforced by S3 at\n * the storage layer, so the server never needs to re-validate it.\n */\nexport function uploadSimple(\n file: File,\n url: string,\n fields: Record<string, string>,\n onProgress?: (progress: UploadProgress) => void,\n signal?: AbortSignal,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n\n const onAbort = () => {\n xhr.abort();\n reject(new DOMException(\"Upload aborted\", \"AbortError\"));\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n xhr.upload.addEventListener(\"progress\", (e) => {\n if (e.lengthComputable) {\n onProgress?.({\n loaded: e.loaded,\n total: e.total,\n percent: Math.round((e.loaded / e.total) * 100),\n });\n }\n });\n\n xhr.addEventListener(\"load\", () => {\n signal?.removeEventListener(\"abort\", onAbort);\n if (xhr.status >= 200 && xhr.status < 300) {\n onProgress?.({ loaded: file.size, total: file.size, percent: 100 });\n resolve();\n } else {\n reject(new Error(`Upload failed: ${xhr.status} ${xhr.statusText}`));\n }\n });\n\n xhr.addEventListener(\"error\", () => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(new Error(\"Upload failed: network error\"));\n });\n\n xhr.addEventListener(\"abort\", () => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(new DOMException(\"Upload aborted\", \"AbortError\"));\n });\n\n // S3 presigned POST: policy fields must come before the file field.\n const formData = new FormData();\n for (const [k, v] of Object.entries(fields)) {\n formData.append(k, v);\n }\n formData.append(\"file\", file);\n\n xhr.open(\"POST\", url);\n xhr.send(formData);\n });\n}\n\n/**\n * Uploads a file directly to S3 using a presigned PUT URL.\n *\n * Use this when the server is configured with `upload.method = \"put\"` — for\n * example with Cloudflare R2 which does not support presigned POST.\n * The `headers` object must match exactly what was signed on the server\n * (Content-Type, Content-Disposition, x-amz-meta-*, etc.).\n */\nexport function uploadPut(\n file: File,\n url: string,\n headers: Record<string, string>,\n onProgress?: (progress: UploadProgress) => void,\n signal?: AbortSignal,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n\n const onAbort = () => {\n xhr.abort();\n reject(new DOMException(\"Upload aborted\", \"AbortError\"));\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n xhr.upload.addEventListener(\"progress\", (e) => {\n if (e.lengthComputable) {\n onProgress?.({\n loaded: e.loaded,\n total: e.total,\n percent: Math.round((e.loaded / e.total) * 100),\n });\n }\n });\n\n xhr.addEventListener(\"load\", () => {\n signal?.removeEventListener(\"abort\", onAbort);\n if (xhr.status >= 200 && xhr.status < 300) {\n onProgress?.({ loaded: file.size, total: file.size, percent: 100 });\n resolve();\n } else {\n reject(new Error(`Upload failed: ${xhr.status} ${xhr.statusText}`));\n }\n });\n\n xhr.addEventListener(\"error\", () => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(new Error(\"Upload failed: network error\"));\n });\n\n xhr.addEventListener(\"abort\", () => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(new DOMException(\"Upload aborted\", \"AbortError\"));\n });\n\n xhr.open(\"PUT\", url);\n for (const [k, v] of Object.entries(headers)) {\n xhr.setRequestHeader(k, v);\n }\n xhr.send(file);\n });\n}\n","export function uploadPart(\n blob: Blob,\n presignedUrl: string,\n partLoaded: { bytes: number },\n totalSize: number,\n reportProgress: () => void,\n signal?: AbortSignal,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n\n const onAbort = () => {\n xhr.abort();\n reject(new DOMException(\"Upload aborted\", \"AbortError\"));\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n xhr.upload.addEventListener(\"progress\", (e) => {\n if (e.lengthComputable) {\n partLoaded.bytes = e.loaded;\n reportProgress();\n }\n });\n\n xhr.addEventListener(\"load\", () => {\n signal?.removeEventListener(\"abort\", onAbort);\n if (xhr.status >= 200 && xhr.status < 300) {\n partLoaded.bytes = blob.size;\n reportProgress();\n resolve();\n } else {\n reject(new Error(`Part upload failed: ${xhr.status}`));\n }\n });\n\n xhr.addEventListener(\"error\", () => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(new Error(\"Part upload failed: network error\"));\n });\n\n xhr.addEventListener(\"abort\", () => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(new DOMException(\"Upload aborted\", \"AbortError\"));\n });\n\n xhr.open(\"PUT\", presignedUrl);\n xhr.send(blob);\n });\n}\n","import type { UploadProgress, UploadRequestOptions } from \"../types\";\nimport type { S3Api } from \"@better-s3/server\";\nimport { MAX_RETRIES } from \"./constants\";\nimport { withRetry } from \"./retry\";\nimport { uploadPart } from \"./part\";\n\nexport async function uploadMultipart(\n api: S3Api,\n file: File,\n objectKey: string,\n partSize: number,\n concurrentParts: number,\n onProgress?: (progress: UploadProgress) => void,\n signal?: AbortSignal,\n requestOptions?: UploadRequestOptions,\n): Promise<string | undefined> {\n const contentType = requestOptions?.contentType ?? file.type;\n const { uploadId, key } = await api.multipart.init({\n key: objectKey,\n contentType,\n fileSize: file.size,\n fileName:\n requestOptions?.fileName !== null\n ? (requestOptions?.fileName ?? file.name)\n : undefined,\n metadata: requestOptions?.metadata,\n bucket: requestOptions?.bucket,\n acl: requestOptions?.acl,\n });\n\n const totalParts = Math.ceil(file.size / partSize);\n const parts: Array<{ partNumber: number }> = [];\n\n const partProgress: Array<{ bytes: number }> = Array.from(\n { length: totalParts },\n () => ({ bytes: 0 }),\n );\n\n const reportProgress = () => {\n const loaded = partProgress.reduce((sum, p) => sum + p.bytes, 0);\n onProgress?.({\n loaded,\n total: file.size,\n percent: Math.round((loaded / file.size) * 100),\n });\n };\n\n try {\n for (\n let batchStart = 0;\n batchStart < totalParts;\n batchStart += concurrentParts\n ) {\n if (signal?.aborted) {\n throw new DOMException(\"Upload aborted\", \"AbortError\");\n }\n\n const batchEnd = Math.min(batchStart + concurrentParts, totalParts);\n const batch: Array<Promise<{ partNumber: number }>> = [];\n\n for (let i = batchStart; i < batchEnd; i++) {\n const start = i * partSize;\n const end = Math.min(start + partSize, file.size);\n const blob = file.slice(start, end);\n const partNumber = i + 1;\n\n batch.push(\n withRetry(\n async () => {\n const { presignedUrl } = await api.multipart.signPart({\n key,\n uploadId,\n partNumber,\n // Pass the exact byte count so the server binds Content-Length\n // into the HMAC signature. S3 will then reject any PUT whose\n // body size differs from blob.size with SignatureDoesNotMatch.\n partSize: blob.size,\n bucket: requestOptions?.bucket,\n });\n\n partProgress[i].bytes = 0;\n\n await uploadPart(\n blob,\n presignedUrl,\n partProgress[i],\n file.size,\n reportProgress,\n signal,\n );\n\n return { partNumber };\n },\n MAX_RETRIES,\n signal,\n ),\n );\n }\n\n const batchResults = await Promise.all(batch);\n parts.push(...batchResults);\n }\n\n parts.sort((a, b) => a.partNumber - b.partNumber);\n\n const result = await api.multipart.complete({\n key,\n uploadId,\n parts,\n bucket: requestOptions?.bucket,\n });\n onProgress?.({ loaded: file.size, total: file.size, percent: 100 });\n return result.eTag;\n } catch (err) {\n api.multipart\n .abort({ key, uploadId, bucket: requestOptions?.bucket })\n .catch(() => {});\n throw err;\n }\n}\n","import type {\n UploadConfig,\n UploadProgress,\n UploadResult,\n UploadRequestOptions,\n} from \"../types\";\nimport type { S3Api } from \"@better-s3/server\";\nimport {\n DEFAULT_MULTIPART_THRESHOLD,\n DEFAULT_CONCURRENT_PARTS,\n DEFAULT_PART_SIZE,\n MAX_RETRIES,\n} from \"./constants\";\nimport { withRetry } from \"./retry\";\nimport { uploadSimple, uploadPut } from \"./simple\";\nimport { uploadMultipart } from \"./multipart\";\n\nexport type UploadEngineCallbacks = {\n onProgress?: (progress: UploadProgress) => void;\n /** Called when the upload transitions between internal phases. */\n onPhaseChange?: (phase: \"presigning\" | \"uploading\" | \"finalizing\") => void;\n};\n\nexport async function uploadFile(\n api: S3Api,\n file: File,\n objectKey: string,\n config: UploadConfig = {},\n callbacks: UploadEngineCallbacks = {},\n signal?: AbortSignal,\n requestOptions?: UploadRequestOptions,\n): Promise<UploadResult> {\n const threshold = config.multipartThreshold ?? DEFAULT_MULTIPART_THRESHOLD;\n const useMultipart = config.multipart === true && file.size >= threshold;\n const concurrentParts = config.concurrentParts ?? DEFAULT_CONCURRENT_PARTS;\n const contentType = requestOptions?.contentType ?? file.type;\n\n let eTag: string | undefined;\n\n if (useMultipart) {\n callbacks.onPhaseChange?.(\"uploading\");\n eTag = await uploadMultipart(\n api,\n file,\n objectKey,\n DEFAULT_PART_SIZE,\n concurrentParts,\n callbacks.onProgress,\n signal,\n requestOptions,\n );\n } else {\n await withRetry(\n async () => {\n callbacks.onPhaseChange?.(\"presigning\");\n const presign = await api.upload({\n key: objectKey,\n contentType,\n fileSize: file.size,\n fileName:\n requestOptions?.fileName !== null\n ? (requestOptions?.fileName ?? file.name)\n : undefined,\n metadata: requestOptions?.metadata,\n bucket: requestOptions?.bucket,\n acl: requestOptions?.acl,\n });\n callbacks.onPhaseChange?.(\"uploading\");\n if (presign.method === \"put\") {\n await uploadPut(\n file,\n presign.url,\n presign.headers ?? {},\n callbacks.onProgress,\n signal,\n );\n } else {\n await uploadSimple(\n file,\n presign.url,\n presign.fields ?? {},\n callbacks.onProgress,\n signal,\n );\n }\n },\n MAX_RETRIES,\n signal,\n );\n\n callbacks.onPhaseChange?.(\"finalizing\");\n const confirmed = await api.confirm({\n key: objectKey,\n bucket: requestOptions?.bucket,\n });\n eTag = confirmed.eTag;\n }\n\n return { key: objectKey, eTag };\n}\n","import type {\n UploadConfig,\n UploadProgress,\n UploadResult,\n UploadRequestOptions,\n} from \"../types\";\nimport type { S3Api } from \"@better-s3/server\";\nimport { DEFAULT_CONCURRENT_FILES } from \"./constants\";\nimport { uploadFile } from \"./upload-file\";\n\nexport type FileItemStatus = \"pending\" | \"uploading\" | \"success\" | \"error\";\n\nexport type FileItem = {\n id: string;\n file: File;\n objectKey: string;\n status: FileItemStatus;\n progress: UploadProgress;\n result: UploadResult | null;\n error: string | null;\n};\n\nexport type MultiUploadCallbacks = {\n onFileProgress?: (id: string, progress: UploadProgress) => void;\n onFileSuccess?: (id: string, result: UploadResult) => void;\n onFileError?: (id: string, error: string) => void;\n onTotalProgress?: (progress: UploadProgress) => void;\n};\n\nexport async function uploadFiles(\n api: S3Api,\n items: Array<{ id: string; file: File; objectKey: string }>,\n config: UploadConfig = {},\n callbacks: MultiUploadCallbacks = {},\n signal?: AbortSignal,\n getRequestOptions?: (file: File) => UploadRequestOptions,\n): Promise<FileItem[]> {\n const results: FileItem[] = items.map((item) => ({\n ...item,\n status: \"pending\" as FileItemStatus,\n progress: { loaded: 0, total: item.file.size, percent: 0 },\n result: null,\n error: null,\n }));\n\n const reportTotalProgress = () => {\n const loaded = results.reduce((sum, r) => sum + r.progress.loaded, 0);\n const total = results.reduce((sum, r) => sum + r.progress.total, 0);\n callbacks.onTotalProgress?.({\n loaded,\n total,\n percent: total > 0 ? Math.round((loaded / total) * 100) : 0,\n });\n };\n\n let nextIndex = 0;\n\n const processNext = async (): Promise<void> => {\n while (nextIndex < results.length) {\n if (signal?.aborted) return;\n const idx = nextIndex++;\n const item = results[idx];\n\n item.status = \"uploading\";\n\n try {\n const result = await uploadFile(\n api,\n item.file,\n item.objectKey,\n config,\n {\n onProgress: (progress) => {\n item.progress = progress;\n callbacks.onFileProgress?.(item.id, progress);\n reportTotalProgress();\n },\n },\n signal,\n getRequestOptions?.(item.file),\n );\n item.status = \"success\";\n item.result = result;\n item.progress = {\n loaded: item.file.size,\n total: item.file.size,\n percent: 100,\n };\n callbacks.onFileSuccess?.(item.id, result);\n reportTotalProgress();\n } catch (err) {\n if ((err as Error).name === \"AbortError\") {\n item.status = \"error\";\n item.error = \"Upload cancelled\";\n return;\n }\n const message = err instanceof Error ? err.message : \"Upload failed\";\n item.status = \"error\";\n item.error = message;\n callbacks.onFileError?.(item.id, message);\n reportTotalProgress();\n }\n }\n };\n\n const concurrentFiles = config.concurrentFiles ?? DEFAULT_CONCURRENT_FILES;\n const workers = Array.from(\n { length: Math.min(concurrentFiles, items.length) },\n () => processNext(),\n );\n await Promise.all(workers);\n\n return results;\n}\n","\"use client\";\n\nimport { useCallback, useRef, useState } from \"react\";\nimport type { S3Api } from \"@better-s3/server\";\nimport { validateFile } from \"@better-s3/server\";\nimport type {\n UploadConfig,\n UploadHooks,\n UploadPhase,\n UploadProgress,\n UploadResult,\n UploadRequestOptions,\n} from \"./types\";\nimport { uploadFile } from \"./upload\";\n\nexport type UseUploadOptions = UploadConfig &\n UploadHooks & {\n api: S3Api;\n };\n\nexport type UseUploadState = {\n phase: UploadPhase;\n progress: UploadProgress;\n error: string | null;\n result: UploadResult | null;\n fileName: string | null;\n fileSize: number | null;\n};\n\nexport type UseUploadReturn = UseUploadState & {\n upload: (\n file: File,\n objectKey: string,\n requestOptions?: UploadRequestOptions,\n ) => Promise<void>;\n cancel: () => void;\n reset: () => void;\n};\n\nconst INITIAL_PROGRESS: UploadProgress = { loaded: 0, total: 0, percent: 0 };\n\nconst INITIAL_STATE: UseUploadState = {\n phase: \"idle\",\n progress: INITIAL_PROGRESS,\n error: null,\n result: null,\n fileName: null,\n fileSize: null,\n};\n\nexport function useUpload(options: UseUploadOptions): UseUploadReturn {\n const [state, setState] = useState<UseUploadState>(INITIAL_STATE);\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const abortRef = useRef<AbortController | null>(null);\n\n const upload = useCallback(\n async (\n file: File,\n objectKey: string,\n requestOptions?: UploadRequestOptions,\n ) => {\n setState({\n ...INITIAL_STATE,\n phase: \"validating\",\n fileName: file.name,\n fileSize: file.size,\n });\n const opts = optionsRef.current;\n\n const validationError = validateFile(file, {\n accept: opts.accept,\n maxFileSize: opts.maxFileSize,\n });\n if (validationError) {\n setState((s) => ({ ...s, phase: \"error\", error: validationError }));\n opts.onError?.(file, new Error(validationError), \"validating\");\n return;\n }\n\n if (opts.beforeUpload) {\n const allowed = await opts.beforeUpload(file);\n if (!allowed) {\n setState((s) => ({\n ...s,\n phase: \"error\",\n error: \"Upload blocked by beforeUpload hook\",\n }));\n opts.onError?.(file, new Error(\"blocked\"), \"validating\");\n return;\n }\n }\n\n setState((s) => ({ ...s, phase: \"presigning\" }));\n opts.onUploadStart?.(file, objectKey);\n\n const controller = new AbortController();\n abortRef.current = controller;\n\n try {\n const result = await uploadFile(\n opts.api,\n file,\n objectKey,\n {\n multipart: opts.multipart,\n multipartThreshold: opts.multipartThreshold,\n concurrentParts: opts.concurrentParts,\n },\n {\n onProgress: (progress) => {\n setState((s) => ({ ...s, progress }));\n opts.onProgress?.(file, progress);\n },\n onPhaseChange: (phase) => setState((s) => ({ ...s, phase })),\n },\n controller.signal,\n requestOptions,\n );\n\n setState((s) => ({\n ...s,\n phase: \"success\",\n result,\n progress: { loaded: file.size, total: file.size, percent: 100 },\n }));\n await opts.onSuccess?.(file, result);\n } catch (err) {\n if ((err as Error).name === \"AbortError\") {\n opts.onCancel?.(file);\n setState(INITIAL_STATE);\n return;\n }\n const message = err instanceof Error ? err.message : \"Upload failed\";\n setState((s) => ({ ...s, phase: \"error\", error: message }));\n opts.onError?.(file, err, \"uploading\");\n } finally {\n abortRef.current = null;\n }\n },\n [],\n );\n\n const cancel = useCallback(() => {\n abortRef.current?.abort();\n setState(INITIAL_STATE);\n }, []);\n\n const reset = useCallback(() => {\n abortRef.current?.abort();\n setState(INITIAL_STATE);\n }, []);\n\n return { ...state, upload, cancel, reset };\n}\n","\"use client\";\n\nimport { useCallback, useRef, useState } from \"react\";\nimport type { S3Api } from \"@better-s3/server\";\nimport { validateFile } from \"@better-s3/server\";\nimport type {\n UploadConfig,\n UploadProgress,\n UploadResult,\n UploadRequestOptions,\n MultiUploadPhase,\n MultiUploadFileState,\n MultiUploadHooks,\n} from \"./types\";\nimport { uploadFiles } from \"./upload\";\n\nexport type UseMultiUploadOptions = UploadConfig &\n MultiUploadHooks & {\n api: S3Api;\n /** Static request options applied to all files */\n uploadOptions?: UploadRequestOptions;\n /** Per-file request options (overrides uploadOptions) */\n getUploadOptions?: (file: File) => UploadRequestOptions;\n };\n\nexport type UseMultiUploadState = {\n phase: MultiUploadPhase;\n files: MultiUploadFileState[];\n totalProgress: UploadProgress;\n error: string | null;\n};\n\nexport type UseMultiUploadReturn = UseMultiUploadState & {\n upload: (files: File[], resolveKey: (file: File) => string) => Promise<void>;\n cancel: () => void;\n reset: () => void;\n};\n\nconst INITIAL_PROGRESS: UploadProgress = { loaded: 0, total: 0, percent: 0 };\n\nconst INITIAL_STATE: UseMultiUploadState = {\n phase: \"idle\",\n files: [],\n totalProgress: INITIAL_PROGRESS,\n error: null,\n};\n\nlet nextId = 0;\nfunction generateId() {\n return `file-${++nextId}`;\n}\n\nexport function useMultiUpload(\n options: UseMultiUploadOptions,\n): UseMultiUploadReturn {\n const [state, setState] = useState<UseMultiUploadState>(INITIAL_STATE);\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const abortRef = useRef<AbortController | null>(null);\n const fileMapRef = useRef<Map<string, File>>(new Map());\n\n const upload = useCallback(\n async (files: File[], resolveKey: (file: File) => string) => {\n const opts = optionsRef.current;\n\n const items: Array<{\n id: string;\n file: File;\n objectKey: string;\n }> = [];\n const fileStates: MultiUploadFileState[] = [];\n const fileMap = new Map<string, File>();\n\n setState((s) => ({ ...s, phase: \"validating\", error: null }));\n\n if (opts.maxFiles && files.length > opts.maxFiles) {\n const msg = `Too many files. Maximum is ${opts.maxFiles}.`;\n setState((s) => ({ ...s, phase: \"error\", error: msg }));\n opts.onError?.(new Error(msg));\n return;\n }\n\n for (const file of files) {\n const validationError = validateFile(file, {\n accept: opts.accept,\n maxFileSize: opts.maxFileSize,\n });\n if (validationError) {\n const msg = `${file.name}: ${validationError}`;\n setState((s) => ({ ...s, phase: \"error\", error: msg }));\n opts.onError?.(new Error(msg));\n return;\n }\n }\n\n if (opts.beforeUpload) {\n const allowed = await opts.beforeUpload(files);\n if (!allowed) {\n setState((s) => ({\n ...s,\n phase: \"error\",\n error: \"Upload blocked by beforeUpload hook\",\n }));\n opts.onError?.(new Error(\"blocked\"));\n return;\n }\n }\n\n for (const file of files) {\n const id = generateId();\n const objectKey = resolveKey(file);\n items.push({ id, file, objectKey });\n fileMap.set(id, file);\n fileStates.push({\n id,\n fileName: file.name,\n fileSize: file.size,\n status: \"pending\",\n progress: { loaded: 0, total: file.size, percent: 0 },\n error: null,\n });\n }\n\n fileMapRef.current = fileMap;\n\n setState({\n phase: \"uploading\",\n files: fileStates,\n totalProgress: {\n loaded: 0,\n total: files.reduce((s, f) => s + f.size, 0),\n percent: 0,\n },\n error: null,\n });\n\n opts.onUploadStart?.(files);\n\n const controller = new AbortController();\n abortRef.current = controller;\n\n try {\n const results = await uploadFiles(\n opts.api,\n items,\n {\n multipart: opts.multipart,\n multipartThreshold: opts.multipartThreshold,\n concurrentParts: opts.concurrentParts,\n concurrentFiles: opts.concurrentFiles,\n },\n {\n onFileProgress: (id, progress) => {\n setState((s) => ({\n ...s,\n files: s.files.map((f) =>\n f.id === id ? { ...f, status: \"uploading\", progress } : f,\n ),\n }));\n const file = fileMap.get(id);\n if (file) opts.onFileProgress?.(file, progress);\n },\n onFileSuccess: (id, result) => {\n setState((s) => ({\n ...s,\n files: s.files.map((f) =>\n f.id === id\n ? {\n ...f,\n status: \"success\",\n progress: {\n loaded: f.fileSize,\n total: f.fileSize,\n percent: 100,\n },\n }\n : f,\n ),\n }));\n const file = fileMap.get(id);\n if (file) opts.onFileSuccess?.(file, result);\n },\n onFileError: (id, error) => {\n setState((s) => ({\n ...s,\n files: s.files.map((f) =>\n f.id === id ? { ...f, status: \"error\", error } : f,\n ),\n }));\n const file = fileMap.get(id);\n if (file) opts.onFileError?.(file, error);\n },\n onTotalProgress: (progress) => {\n setState((s) => ({ ...s, totalProgress: progress }));\n opts.onProgress?.(progress);\n },\n },\n controller.signal,\n (file) => {\n const perFile = opts.getUploadOptions?.(file);\n if (!opts.uploadOptions) return perFile ?? {};\n return { ...opts.uploadOptions, ...perFile };\n },\n );\n\n const hasErrors = results.some((r) => r.status === \"error\");\n const successResults = results\n .filter((r) => r.result !== null)\n .map((r) => r.result!);\n\n setState((s) => ({\n ...s,\n phase: hasErrors ? \"error\" : \"success\",\n error: hasErrors\n ? `${results.filter((r) => r.status === \"error\").length} file(s) failed`\n : null,\n totalProgress: hasErrors\n ? s.totalProgress\n : {\n loaded: s.totalProgress.total,\n total: s.totalProgress.total,\n percent: 100,\n },\n }));\n\n if (!hasErrors) {\n await opts.onSuccess?.(successResults);\n }\n } catch (err) {\n if ((err as Error).name === \"AbortError\") {\n opts.onCancel?.();\n setState(INITIAL_STATE);\n return;\n }\n const message = err instanceof Error ? err.message : \"Upload failed\";\n setState((s) => ({ ...s, phase: \"error\", error: message }));\n opts.onError?.(err);\n } finally {\n abortRef.current = null;\n }\n },\n [],\n );\n\n const cancel = useCallback(() => {\n abortRef.current?.abort();\n setState(INITIAL_STATE);\n }, []);\n\n const reset = useCallback(() => {\n abortRef.current?.abort();\n setState(INITIAL_STATE);\n }, []);\n\n return { ...state, upload, cancel, reset };\n}\n","\"use client\";\n\nimport { useRef, useState } from \"react\";\nimport type {\n UploadPhase,\n UploadProgress,\n UploadResult,\n UploadRequestOptions,\n MultiUploadFileState,\n MultiUploadPhase,\n} from \"./types\";\nimport { useUpload, type UseUploadOptions } from \"./use-upload\";\nimport { useMultiUpload, type UseMultiUploadOptions } from \"./use-multi-upload\";\nimport type { S3Api } from \"@better-s3/server\";\nimport type { UploadConfig } from \"./types\";\n\nconst INITIAL_PROGRESS: UploadProgress = { loaded: 0, total: 0, percent: 0 };\n\nexport type UseUploadControlsOptions = UploadConfig & {\n api: S3Api;\n objectKey: string | ((file: File) => string);\n /**\n * Maximum number of files. When > 1 the hook switches to multi-upload mode\n * and the native file picker allows selecting multiple files.\n * @default 1\n */\n maxFiles?: number;\n /** Static request options applied to all files (multi mode) */\n uploadOptions?: UploadRequestOptions;\n /** Per-file request options */\n getUploadOptions?: (file: File) => UploadRequestOptions;\n // Callbacks – typed as a union to support both single and multi modes\n beforeUpload?:\n | ((file: File) => boolean | Promise<boolean>)\n | ((files: File[]) => boolean | Promise<boolean>);\n onUploadStart?:\n | ((file: File, key: string) => void)\n | ((files: File[]) => void);\n onProgress?:\n | ((file: File, progress: UploadProgress) => void)\n | ((progress: UploadProgress) => void);\n onSuccess?:\n | ((file: File, result: UploadResult) => void | Promise<void>)\n | ((results: UploadResult[]) => void | Promise<void>);\n onError?:\n | ((file: File | null, error: unknown, phase: UploadPhase) => void)\n | ((error: unknown) => void);\n onCancel?: ((file: File | null) => void) | (() => void);\n // Multi-only callbacks\n onFileProgress?: (file: File, progress: UploadProgress) => void;\n onFileSuccess?: (file: File, result: UploadResult) => void;\n onFileError?: (file: File, error: string) => void;\n};\n\nexport type UseUploadControlsReturn = {\n /** Whether the hook is in single-file or multi-file mode */\n mode: \"single\" | \"multi\";\n phase: UploadPhase | MultiUploadPhase;\n /** Info about the selected file (single mode only) */\n fileInfo: { name: string; size: number } | null;\n /** Upload progress (single mode) */\n progress: UploadProgress;\n /** Per-file states (multi mode only) */\n files: MultiUploadFileState[];\n /** Aggregated progress across all files (multi mode) */\n totalProgress: UploadProgress;\n error: string | null;\n isUploading: boolean;\n handleFiles: (files: FileList | null) => void;\n openFilePicker: () => void;\n cancel: () => void;\n reset: () => void;\n /** Spread on a hidden `<input>` element */\n inputProps: {\n ref: React.RefObject<HTMLInputElement | null>;\n type: \"file\";\n multiple?: true;\n accept?: string;\n hidden: true;\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\n };\n /** Spread on a container to enable drag-and-drop */\n dropHandlers: {\n onDragOver: (e: React.DragEvent) => void;\n onDrop: (e: React.DragEvent) => void;\n };\n};\n\nexport function useUploadControls(\n options: UseUploadControlsOptions,\n): UseUploadControlsReturn {\n const isMulti = (options.maxFiles ?? 1) > 1;\n\n // Build per-mode options. Both hooks are called unconditionally (React rules).\n const singleOpts: UseUploadOptions = {\n api: options.api,\n accept: options.accept,\n maxFileSize: options.maxFileSize,\n multipart: options.multipart,\n multipartThreshold: options.multipartThreshold,\n concurrentParts: options.concurrentParts,\n beforeUpload: options.beforeUpload as UseUploadOptions[\"beforeUpload\"],\n onUploadStart: options.onUploadStart as UseUploadOptions[\"onUploadStart\"],\n onProgress: options.onProgress as UseUploadOptions[\"onProgress\"],\n onSuccess: options.onSuccess as UseUploadOptions[\"onSuccess\"],\n onError: options.onError as UseUploadOptions[\"onError\"],\n onCancel: options.onCancel as UseUploadOptions[\"onCancel\"],\n };\n\n const multiOpts: UseMultiUploadOptions = {\n api: options.api,\n accept: options.accept,\n maxFileSize: options.maxFileSize,\n maxFiles: options.maxFiles,\n multipart: options.multipart,\n multipartThreshold: options.multipartThreshold,\n concurrentParts: options.concurrentParts,\n concurrentFiles: options.concurrentFiles,\n uploadOptions: options.uploadOptions,\n getUploadOptions: options.getUploadOptions,\n beforeUpload: options.beforeUpload as UseMultiUploadOptions[\"beforeUpload\"],\n onUploadStart:\n options.onUploadStart as UseMultiUploadOptions[\"onUploadStart\"],\n onProgress: options.onProgress as UseMultiUploadOptions[\"onProgress\"],\n onSuccess: options.onSuccess as UseMultiUploadOptions[\"onSuccess\"],\n onError: options.onError as UseMultiUploadOptions[\"onError\"],\n onCancel: options.onCancel as UseMultiUploadOptions[\"onCancel\"],\n onFileProgress: options.onFileProgress,\n onFileSuccess: options.onFileSuccess,\n onFileError: options.onFileError,\n };\n\n const single = useUpload(singleOpts);\n const multi = useMultiUpload(multiOpts);\n\n const inputRef = useRef<HTMLInputElement>(null);\n const [fileInfo, setFileInfo] = useState<{\n name: string;\n size: number;\n } | null>(null);\n\n const resolveKey = (file: File): string =>\n typeof options.objectKey === \"function\"\n ? options.objectKey(file)\n : options.objectKey;\n\n const handleFiles = async (files: FileList | null) => {\n if (isMulti) {\n if (!files?.length) return;\n await multi.upload(Array.from(files), resolveKey);\n } else {\n const file = files?.[0];\n if (!file) return;\n setFileInfo({ name: file.name, size: file.size });\n await single.upload(file, resolveKey(file), {\n ...options.uploadOptions,\n ...options.getUploadOptions?.(file),\n });\n }\n };\n\n const openFilePicker = () => inputRef.current?.click();\n const isUploading = isMulti\n ? multi.phase === \"uploading\"\n : single.phase === \"uploading\";\n\n return {\n mode: isMulti ? \"multi\" : \"single\",\n phase: isMulti ? multi.phase : single.phase,\n fileInfo: isMulti ? null : fileInfo,\n progress: isMulti ? INITIAL_PROGRESS : single.progress,\n files: isMulti ? multi.files : [],\n totalProgress: isMulti ? multi.totalProgress : INITIAL_PROGRESS,\n error: isMulti ? multi.error : single.error,\n isUploading,\n handleFiles,\n openFilePicker,\n cancel: isMulti ? multi.cancel : single.cancel,\n reset: isMulti\n ? multi.reset\n : () => {\n single.reset();\n setFileInfo(null);\n },\n inputProps: {\n ref: inputRef,\n type: \"file\",\n ...(isMulti && { multiple: true as const }),\n accept: options.accept?.join(\",\"),\n hidden: true,\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => {\n handleFiles(e.target.files);\n e.target.value = \"\";\n },\n },\n dropHandlers: {\n onDragOver: (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n },\n onDrop: (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n if (!isUploading) handleFiles(e.dataTransfer.files);\n },\n },\n };\n}\n","\"use client\";\n\nimport { useCallback, useRef, useState } from \"react\";\nimport type { S3Api } from \"@better-s3/server\";\n\n/** \"presigning\" = fetching the presigned URL from the server; download itself is native */\nexport type DownloadPhase = \"idle\" | \"presigning\" | \"error\";\n\nexport type DownloadHooks = {\n beforeDownload?: (key: string) => Promise<boolean> | boolean;\n /** Fires as soon as the browser has been handed the URL — not when download completes. */\n onInitiated?: (key: string) => void;\n onError?: (key: string, error: unknown) => void;\n};\n\nexport type UseDownloadOptions = DownloadHooks & {\n api: S3Api;\n /** Target bucket (overrides server default) */\n bucket?: string;\n};\n\nexport type UseDownloadState = {\n phase: DownloadPhase;\n error: string | null;\n /** Presigned URL — set after a successful presign, cleared on reset */\n url: string | null;\n /** Validity window in seconds for the presigned URL */\n expiresIn: number | null;\n};\n\nexport type UseDownloadReturn = UseDownloadState & {\n download: (key: string, downloadName?: string) => Promise<void>;\n /** Fetch the presigned URL without triggering a browser download — for headless use */\n presign: (\n key: string,\n downloadName?: string,\n ) => Promise<{ url: string; expiresIn: number } | null>;\n reset: () => void;\n};\n\nconst INITIAL_STATE: UseDownloadState = {\n phase: \"idle\",\n error: null,\n url: null,\n expiresIn: null,\n};\n\nexport function useDownload(options: UseDownloadOptions): UseDownloadReturn {\n const [state, setState] = useState<UseDownloadState>(INITIAL_STATE);\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const presign = useCallback(async (key: string, downloadName?: string) => {\n const opts = optionsRef.current;\n setState({ phase: \"presigning\", error: null, url: null, expiresIn: null });\n try {\n const result = await opts.api.download(key, {\n fileName: downloadName,\n bucket: opts.bucket,\n });\n setState({\n phase: \"idle\",\n error: null,\n url: result.url,\n expiresIn: result.expiresIn,\n });\n return { url: result.url, expiresIn: result.expiresIn };\n } catch (err) {\n const message = err instanceof Error ? err.message : \"Download failed\";\n setState({ phase: \"error\", error: message, url: null, expiresIn: null });\n opts.onError?.(key, err);\n return null;\n }\n }, []);\n\n const download = useCallback(\n async (key: string, downloadName?: string) => {\n const opts = optionsRef.current;\n\n if (opts.beforeDownload) {\n const allowed = await opts.beforeDownload(key);\n if (!allowed) {\n setState({\n phase: \"error\",\n error: \"Download blocked by beforeDownload hook\",\n url: null,\n expiresIn: null,\n });\n opts.onError?.(key, new Error(\"blocked\"));\n return;\n }\n }\n\n const result = await presign(key, downloadName);\n if (!result) return; // presign already set error state\n\n // Native browser download via location — server sets Content-Disposition: attachment.\n window.location.href = result.url;\n\n opts.onInitiated?.(key);\n },\n [presign],\n );\n\n const reset = useCallback(() => {\n setState(INITIAL_STATE);\n }, []);\n\n return { ...state, download, presign, reset };\n}\n","\"use client\";\n\nimport { useCallback, useRef, useState } from \"react\";\nimport type { S3Api } from \"@better-s3/server\";\nimport { parseContentDispositionFilename } from \"./helpers\";\n\nexport type FetchDownloadPhase =\n | \"idle\"\n | \"presigning\"\n | \"downloading\"\n | \"success\"\n | \"error\";\n\nexport type FetchDownloadProgress = {\n loaded: number;\n total: number;\n percent: number;\n};\n\nexport type FetchDownloadHooks = {\n beforeDownload?: (key: string) => Promise<boolean> | boolean;\n onDownloadStart?: (key: string) => void;\n onProgress?: (key: string, progress: FetchDownloadProgress) => void;\n onSuccess?: (key: string, fileName: string) => Promise<void> | void;\n onError?: (key: string, error: unknown, phase: FetchDownloadPhase) => void;\n onCancel?: (key: string) => void;\n};\n\nexport type UseFetchDownloadOptions = FetchDownloadHooks & {\n api: S3Api;\n /** Target bucket (overrides server default) */\n bucket?: string;\n};\n\nexport type UseFetchDownloadState = {\n phase: FetchDownloadPhase;\n progress: FetchDownloadProgress;\n error: string | null;\n fileName: string | null;\n fileSize: number | null;\n};\n\nexport type UseFetchDownloadReturn = UseFetchDownloadState & {\n download: (key: string, downloadName?: string) => Promise<void>;\n cancel: () => void;\n reset: () => void;\n};\n\nconst INITIAL_PROGRESS: FetchDownloadProgress = {\n loaded: 0,\n total: 0,\n percent: 0,\n};\n\nconst INITIAL_STATE: UseFetchDownloadState = {\n phase: \"idle\",\n progress: INITIAL_PROGRESS,\n error: null,\n fileName: null,\n fileSize: null,\n};\n\nexport function useFetchDownload(\n options: UseFetchDownloadOptions,\n): UseFetchDownloadReturn {\n const [state, setState] = useState<UseFetchDownloadState>(INITIAL_STATE);\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const abortRef = useRef<AbortController | null>(null);\n\n const download = useCallback(async (key: string, downloadName?: string) => {\n const fallback = key.split(\"/\").pop() ?? key;\n const opts = optionsRef.current;\n\n if (opts.beforeDownload) {\n const allowed = await opts.beforeDownload(key);\n if (!allowed) {\n setState((s) => ({\n ...s,\n phase: \"error\",\n error: \"Download blocked by beforeDownload hook\",\n }));\n opts.onError?.(key, new Error(\"blocked\"), \"presigning\");\n return;\n }\n }\n\n setState({\n phase: \"presigning\",\n progress: INITIAL_PROGRESS,\n error: null,\n fileName: downloadName ?? null,\n fileSize: null,\n });\n\n try {\n const { url } = await opts.api.download(key, {\n fileName: downloadName,\n bucket: opts.bucket,\n });\n\n setState((s) => ({ ...s, phase: \"downloading\" }));\n opts.onDownloadStart?.(key);\n\n const controller = new AbortController();\n abortRef.current = controller;\n\n const res = await fetch(url, { signal: controller.signal });\n if (!res.ok) {\n throw new Error(\n res.status === 404\n ? \"File not found\"\n : `Download failed (${res.status})`,\n );\n }\n\n const contentLength = Number(res.headers.get(\"content-length\") || 0);\n const name =\n downloadName ??\n parseContentDispositionFilename(\n res.headers.get(\"content-disposition\"),\n fallback,\n );\n setState((s) => ({\n ...s,\n fileName: name,\n fileSize: contentLength || null,\n }));\n\n const reader = res.body?.getReader();\n if (!reader) throw new Error(\"ReadableStream not supported\");\n\n const chunks: BlobPart[] = [];\n let loaded = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n loaded += value.byteLength;\n const percent =\n contentLength > 0 ? Math.round((loaded / contentLength) * 100) : 0;\n const progress: FetchDownloadProgress = {\n loaded,\n total: contentLength,\n percent,\n };\n setState((s) => ({ ...s, progress }));\n opts.onProgress?.(key, progress);\n }\n\n const blob = new Blob(chunks);\n const blobUrl = URL.createObjectURL(blob);\n const anchor = document.createElement(\"a\");\n anchor.href = blobUrl;\n anchor.download = name ?? fallback;\n anchor.click();\n URL.revokeObjectURL(blobUrl);\n\n setState((s) => ({\n ...s,\n phase: \"success\",\n fileSize: blob.size,\n progress: { loaded: blob.size, total: blob.size, percent: 100 },\n }));\n await opts.onSuccess?.(key, name ?? fallback);\n } catch (err) {\n if ((err as Error).name === \"AbortError\") {\n opts.onCancel?.(key);\n setState(INITIAL_STATE);\n return;\n }\n const message = err instanceof Error ? err.message : \"Download failed\";\n setState((s) => ({ ...s, phase: \"error\", error: message }));\n opts.onError?.(key, err, \"downloading\");\n } finally {\n abortRef.current = null;\n }\n }, []);\n\n const cancel = useCallback(() => {\n abortRef.current?.abort();\n setState(INITIAL_STATE);\n }, []);\n\n const reset = useCallback(() => {\n abortRef.current?.abort();\n setState(INITIAL_STATE);\n }, []);\n\n return { ...state, download, cancel, reset };\n}\n","\"use client\";\n\nimport { useCallback, useRef, useState } from \"react\";\nimport type { S3Api } from \"@better-s3/server\";\nimport type { DeletePhase, DeleteHooks } from \"./types\";\n\nexport type UseDeleteOptions = DeleteHooks & {\n api: S3Api;\n /** Target bucket (overrides server default) */\n bucket?: string;\n};\n\nexport type UseDeleteState = {\n phase: DeletePhase;\n error: string | null;\n};\n\nexport type UseDeleteReturn = UseDeleteState & {\n requestDelete: (key: string) => void;\n confirmDelete: () => Promise<void>;\n cancelDelete: () => void;\n reset: () => void;\n pendingKey: string | null;\n};\n\nconst INITIAL_STATE: UseDeleteState = {\n phase: \"idle\",\n error: null,\n};\n\nexport function useDelete(options: UseDeleteOptions): UseDeleteReturn {\n const [state, setState] = useState<UseDeleteState>(INITIAL_STATE);\n const [pendingKey, setPendingKey] = useState<string | null>(null);\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const requestDelete = useCallback((key: string) => {\n setPendingKey(key);\n setState({ phase: \"confirming\", error: null });\n }, []);\n\n const confirmDelete = useCallback(async () => {\n if (!pendingKey) return;\n const opts = optionsRef.current;\n\n if (opts.beforeDelete) {\n const allowed = await opts.beforeDelete(pendingKey);\n if (!allowed) {\n setState({\n phase: \"error\",\n error: \"Delete blocked by beforeDelete hook\",\n });\n opts.onError?.(pendingKey, new Error(\"blocked\"), \"confirming\");\n setPendingKey(null);\n return;\n }\n }\n\n setState({ phase: \"deleting\", error: null });\n opts.onDeleteStart?.(pendingKey);\n\n try {\n await opts.api.delete(pendingKey, { bucket: opts.bucket });\n\n setState({ phase: \"success\", error: null });\n await opts.onSuccess?.(pendingKey);\n setPendingKey(null);\n } catch (err) {\n const message = err instanceof Error ? err.message : \"Delete failed\";\n setState({ phase: \"error\", error: message });\n opts.onError?.(pendingKey, err, \"deleting\");\n }\n }, [pendingKey]);\n\n const cancelDelete = useCallback(() => {\n setPendingKey(null);\n setState(INITIAL_STATE);\n }, []);\n\n const reset = useCallback(() => {\n setPendingKey(null);\n setState(INITIAL_STATE);\n }, []);\n\n return {\n ...state,\n pendingKey,\n requestDelete,\n confirmDelete,\n cancelDelete,\n reset,\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/helpers.ts","../src/upload/constants.ts","../src/upload/retry.ts","../src/upload/simple.ts","../src/upload/part.ts","../src/upload/multipart.ts","../src/upload/upload-file.ts","../src/upload/upload-files.ts","../src/use-upload.ts","../src/use-multi-upload.ts","../src/use-upload-controls.ts","../src/use-download.ts","../src/use-fetch-download.ts","../src/use-delete.ts"],"names":["INITIAL_PROGRESS","INITIAL_STATE","useState","useRef","useCallback","validateFile"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Parses the filename from a `Content-Disposition` header value.\n * Prefers `filename*` (RFC 5987, full Unicode) over `filename`.\n * Returns `fallback` if no filename is found.\n */\nexport function parseContentDispositionFilename(\n header: string | null,\n fallback: string,\n): string {\n if (!header) return fallback;\n const starMatch = header.match(/filename\\*=UTF-8''([^;,\\s]+)/i);\n if (starMatch) {\n try {\n return decodeURIComponent(starMatch[1]);\n } catch {\n // fall through\n }\n }\n const match = header.match(/filename=\"([^\"]+)\"/i);\n if (match) return match[1];\n return fallback;\n}\n\nexport function formatFileSize(bytes: number): string {\n if (bytes === 0) return \"0 B\";\n const units = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(1024));\n const size = bytes / Math.pow(1024, i);\n return `${size.toFixed(i === 0 ? 0 : 1)} ${units[i]}`;\n}\n","export const DEFAULT_MULTIPART_THRESHOLD = 30 * 1024 * 1024; // 30 MB\nexport const DEFAULT_PART_SIZE = 10 * 1024 * 1024; // 10 MB\nexport const MAX_RETRIES = 3;\nexport const RETRY_BASE_DELAY = 1_000; // ms\nexport const DEFAULT_CONCURRENT_PARTS = 3;\nexport const DEFAULT_CONCURRENT_FILES = 2;\n","import { RETRY_BASE_DELAY } from \"./constants\";\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n retries: number,\n signal?: AbortSignal,\n): Promise<T> {\n let lastError: unknown;\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n return await fn();\n } catch (err) {\n if ((err as Error).name === \"AbortError\") throw err;\n lastError = err;\n if (attempt < retries) {\n const delay = RETRY_BASE_DELAY * 2 ** attempt;\n await new Promise((r) => setTimeout(r, delay));\n if (signal?.aborted)\n throw new DOMException(\"Upload aborted\", \"AbortError\");\n }\n }\n }\n throw lastError;\n}\n","import type { UploadProgress } from \"../types\";\n\n/**\n * Uploads a file directly to S3 using a presigned POST form.\n *\n * All policy fields (acl, Content-Type, content-length-range, signature, etc.)\n * are embedded in `fields` and must be appended to the FormData **before** the\n * file — this is an S3 requirement. The size constraint is enforced by S3 at\n * the storage layer, so the server never needs to re-validate it.\n */\nexport function uploadSimple(\n file: File,\n url: string,\n fields: Record<string, string>,\n onProgress?: (progress: UploadProgress) => void,\n signal?: AbortSignal,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n\n const onAbort = () => {\n xhr.abort();\n reject(new DOMException(\"Upload aborted\", \"AbortError\"));\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n xhr.upload.addEventListener(\"progress\", (e) => {\n if (e.lengthComputable) {\n onProgress?.({\n loaded: e.loaded,\n total: e.total,\n percent: Math.round((e.loaded / e.total) * 100),\n });\n }\n });\n\n xhr.addEventListener(\"load\", () => {\n signal?.removeEventListener(\"abort\", onAbort);\n if (xhr.status >= 200 && xhr.status < 300) {\n onProgress?.({ loaded: file.size, total: file.size, percent: 100 });\n resolve();\n } else {\n reject(new Error(`Upload failed: ${xhr.status} ${xhr.statusText}`));\n }\n });\n\n xhr.addEventListener(\"error\", () => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(new Error(\"Upload failed: network error\"));\n });\n\n xhr.addEventListener(\"abort\", () => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(new DOMException(\"Upload aborted\", \"AbortError\"));\n });\n\n // S3 presigned POST: policy fields must come before the file field.\n const formData = new FormData();\n for (const [k, v] of Object.entries(fields)) {\n formData.append(k, v);\n }\n formData.append(\"file\", file);\n\n xhr.open(\"POST\", url);\n xhr.send(formData);\n });\n}\n\n/**\n * Uploads a file directly to S3 using a presigned PUT URL.\n *\n * Use this when the server is configured with `upload.method = \"put\"` — for\n * example with Cloudflare R2 which does not support presigned POST.\n * The `headers` object must match exactly what was signed on the server\n * (Content-Type, Content-Disposition, x-amz-meta-*, etc.).\n */\nexport function uploadPut(\n file: File,\n url: string,\n headers: Record<string, string>,\n onProgress?: (progress: UploadProgress) => void,\n signal?: AbortSignal,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n\n const onAbort = () => {\n xhr.abort();\n reject(new DOMException(\"Upload aborted\", \"AbortError\"));\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n xhr.upload.addEventListener(\"progress\", (e) => {\n if (e.lengthComputable) {\n onProgress?.({\n loaded: e.loaded,\n total: e.total,\n percent: Math.round((e.loaded / e.total) * 100),\n });\n }\n });\n\n xhr.addEventListener(\"load\", () => {\n signal?.removeEventListener(\"abort\", onAbort);\n if (xhr.status >= 200 && xhr.status < 300) {\n onProgress?.({ loaded: file.size, total: file.size, percent: 100 });\n resolve();\n } else {\n reject(new Error(`Upload failed: ${xhr.status} ${xhr.statusText}`));\n }\n });\n\n xhr.addEventListener(\"error\", () => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(new Error(\"Upload failed: network error\"));\n });\n\n xhr.addEventListener(\"abort\", () => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(new DOMException(\"Upload aborted\", \"AbortError\"));\n });\n\n xhr.open(\"PUT\", url);\n for (const [k, v] of Object.entries(headers)) {\n xhr.setRequestHeader(k, v);\n }\n xhr.send(file);\n });\n}\n","export function uploadPart(\n blob: Blob,\n presignedUrl: string,\n partLoaded: { bytes: number },\n totalSize: number,\n reportProgress: () => void,\n signal?: AbortSignal,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n\n const onAbort = () => {\n xhr.abort();\n reject(new DOMException(\"Upload aborted\", \"AbortError\"));\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n xhr.upload.addEventListener(\"progress\", (e) => {\n if (e.lengthComputable) {\n partLoaded.bytes = e.loaded;\n reportProgress();\n }\n });\n\n xhr.addEventListener(\"load\", () => {\n signal?.removeEventListener(\"abort\", onAbort);\n if (xhr.status >= 200 && xhr.status < 300) {\n partLoaded.bytes = blob.size;\n reportProgress();\n resolve();\n } else {\n reject(new Error(`Part upload failed: ${xhr.status}`));\n }\n });\n\n xhr.addEventListener(\"error\", () => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(new Error(\"Part upload failed: network error\"));\n });\n\n xhr.addEventListener(\"abort\", () => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(new DOMException(\"Upload aborted\", \"AbortError\"));\n });\n\n xhr.open(\"PUT\", presignedUrl);\n xhr.send(blob);\n });\n}\n","import type { UploadProgress, UploadRequestOptions } from \"../types\";\nimport type { S3Api } from \"@better-s3/server\";\nimport { MAX_RETRIES } from \"./constants\";\nimport { withRetry } from \"./retry\";\nimport { uploadPart } from \"./part\";\n\nexport async function uploadMultipart(\n api: S3Api,\n file: File,\n objectKey: string,\n partSize: number,\n concurrentParts: number,\n onProgress?: (progress: UploadProgress) => void,\n signal?: AbortSignal,\n requestOptions?: UploadRequestOptions,\n): Promise<string | undefined> {\n const contentType = requestOptions?.contentType ?? file.type;\n const { uploadId, key } = await api.multipart.init({\n key: objectKey,\n contentType,\n fileSize: file.size,\n fileName:\n requestOptions?.fileName !== null\n ? (requestOptions?.fileName ?? file.name)\n : undefined,\n metadata: requestOptions?.metadata,\n bucket: requestOptions?.bucket,\n acl: requestOptions?.acl,\n });\n\n const totalParts = Math.ceil(file.size / partSize);\n const parts: Array<{ partNumber: number }> = [];\n\n const partProgress: Array<{ bytes: number }> = Array.from(\n { length: totalParts },\n () => ({ bytes: 0 }),\n );\n\n const reportProgress = () => {\n const loaded = partProgress.reduce((sum, p) => sum + p.bytes, 0);\n onProgress?.({\n loaded,\n total: file.size,\n percent: Math.round((loaded / file.size) * 100),\n });\n };\n\n try {\n for (\n let batchStart = 0;\n batchStart < totalParts;\n batchStart += concurrentParts\n ) {\n if (signal?.aborted) {\n throw new DOMException(\"Upload aborted\", \"AbortError\");\n }\n\n const batchEnd = Math.min(batchStart + concurrentParts, totalParts);\n const batch: Array<Promise<{ partNumber: number }>> = [];\n\n for (let i = batchStart; i < batchEnd; i++) {\n const start = i * partSize;\n const end = Math.min(start + partSize, file.size);\n const blob = file.slice(start, end);\n const partNumber = i + 1;\n\n batch.push(\n withRetry(\n async () => {\n const { presignedUrl } = await api.multipart.signPart({\n key,\n uploadId,\n partNumber,\n // Pass the exact byte count so the server binds Content-Length\n // into the HMAC signature. S3 will then reject any PUT whose\n // body size differs from blob.size with SignatureDoesNotMatch.\n partSize: blob.size,\n bucket: requestOptions?.bucket,\n });\n\n partProgress[i].bytes = 0;\n\n await uploadPart(\n blob,\n presignedUrl,\n partProgress[i],\n file.size,\n reportProgress,\n signal,\n );\n\n return { partNumber };\n },\n MAX_RETRIES,\n signal,\n ),\n );\n }\n\n const batchResults = await Promise.all(batch);\n parts.push(...batchResults);\n }\n\n parts.sort((a, b) => a.partNumber - b.partNumber);\n\n const result = await api.multipart.complete({\n key,\n uploadId,\n parts,\n bucket: requestOptions?.bucket,\n });\n onProgress?.({ loaded: file.size, total: file.size, percent: 100 });\n return result.eTag;\n } catch (err) {\n api.multipart\n .abort({ key, uploadId, bucket: requestOptions?.bucket })\n .catch(() => {});\n throw err;\n }\n}\n","import type {\n UploadConfig,\n UploadProgress,\n UploadResult,\n UploadRequestOptions,\n} from \"../types\";\nimport type { S3Api } from \"@better-s3/server\";\nimport {\n DEFAULT_MULTIPART_THRESHOLD,\n DEFAULT_CONCURRENT_PARTS,\n DEFAULT_PART_SIZE,\n MAX_RETRIES,\n} from \"./constants\";\nimport { withRetry } from \"./retry\";\nimport { uploadSimple, uploadPut } from \"./simple\";\nimport { uploadMultipart } from \"./multipart\";\n\nexport type UploadEngineCallbacks = {\n onProgress?: (progress: UploadProgress) => void;\n /** Called when the upload transitions between internal phases. */\n onPhaseChange?: (phase: \"presigning\" | \"uploading\" | \"finalizing\") => void;\n};\n\nexport async function uploadFile(\n api: S3Api,\n file: File,\n objectKey: string,\n config: UploadConfig = {},\n callbacks: UploadEngineCallbacks = {},\n signal?: AbortSignal,\n requestOptions?: UploadRequestOptions,\n): Promise<UploadResult> {\n const threshold = config.multipartThreshold ?? DEFAULT_MULTIPART_THRESHOLD;\n const useMultipart = config.multipart === true && file.size >= threshold;\n const concurrentParts = config.concurrentParts ?? DEFAULT_CONCURRENT_PARTS;\n const contentType = requestOptions?.contentType ?? file.type;\n\n let eTag: string | undefined;\n\n if (useMultipart) {\n callbacks.onPhaseChange?.(\"uploading\");\n eTag = await uploadMultipart(\n api,\n file,\n objectKey,\n DEFAULT_PART_SIZE,\n concurrentParts,\n callbacks.onProgress,\n signal,\n requestOptions,\n );\n } else {\n await withRetry(\n async () => {\n callbacks.onPhaseChange?.(\"presigning\");\n const presign = await api.upload({\n key: objectKey,\n contentType,\n fileSize: file.size,\n fileName:\n requestOptions?.fileName !== null\n ? (requestOptions?.fileName ?? file.name)\n : undefined,\n metadata: requestOptions?.metadata,\n bucket: requestOptions?.bucket,\n acl: requestOptions?.acl,\n });\n callbacks.onPhaseChange?.(\"uploading\");\n if (presign.method === \"put\") {\n await uploadPut(\n file,\n presign.url,\n presign.headers ?? {},\n callbacks.onProgress,\n signal,\n );\n } else {\n await uploadSimple(\n file,\n presign.url,\n presign.fields ?? {},\n callbacks.onProgress,\n signal,\n );\n }\n },\n MAX_RETRIES,\n signal,\n );\n\n callbacks.onPhaseChange?.(\"finalizing\");\n const confirmed = await api.confirm({\n key: objectKey,\n bucket: requestOptions?.bucket,\n });\n eTag = confirmed.eTag;\n }\n\n return { key: objectKey, eTag };\n}\n","import type {\n UploadConfig,\n UploadProgress,\n UploadResult,\n UploadRequestOptions,\n} from \"../types\";\nimport type { S3Api } from \"@better-s3/server\";\nimport { DEFAULT_CONCURRENT_FILES } from \"./constants\";\nimport { uploadFile } from \"./upload-file\";\n\nexport type FileItemStatus = \"pending\" | \"uploading\" | \"success\" | \"error\";\n\nexport type FileItem = {\n id: string;\n file: File;\n objectKey: string;\n status: FileItemStatus;\n progress: UploadProgress;\n result: UploadResult | null;\n error: string | null;\n};\n\nexport type MultiUploadCallbacks = {\n onFileProgress?: (id: string, progress: UploadProgress) => void;\n onFileSuccess?: (id: string, result: UploadResult) => void;\n onFileError?: (id: string, error: string) => void;\n onTotalProgress?: (progress: UploadProgress) => void;\n};\n\nexport async function uploadFiles(\n api: S3Api,\n items: Array<{ id: string; file: File; objectKey: string }>,\n config: UploadConfig = {},\n callbacks: MultiUploadCallbacks = {},\n signal?: AbortSignal,\n getRequestOptions?: (file: File) => UploadRequestOptions,\n): Promise<FileItem[]> {\n const results: FileItem[] = items.map((item) => ({\n ...item,\n status: \"pending\" as FileItemStatus,\n progress: { loaded: 0, total: item.file.size, percent: 0 },\n result: null,\n error: null,\n }));\n\n const reportTotalProgress = () => {\n const loaded = results.reduce((sum, r) => sum + r.progress.loaded, 0);\n const total = results.reduce((sum, r) => sum + r.progress.total, 0);\n callbacks.onTotalProgress?.({\n loaded,\n total,\n percent: total > 0 ? Math.round((loaded / total) * 100) : 0,\n });\n };\n\n let nextIndex = 0;\n\n const processNext = async (): Promise<void> => {\n while (nextIndex < results.length) {\n if (signal?.aborted) return;\n const idx = nextIndex++;\n const item = results[idx];\n\n item.status = \"uploading\";\n\n try {\n const result = await uploadFile(\n api,\n item.file,\n item.objectKey,\n config,\n {\n onProgress: (progress) => {\n item.progress = progress;\n callbacks.onFileProgress?.(item.id, progress);\n reportTotalProgress();\n },\n },\n signal,\n getRequestOptions?.(item.file),\n );\n item.status = \"success\";\n item.result = result;\n item.progress = {\n loaded: item.file.size,\n total: item.file.size,\n percent: 100,\n };\n callbacks.onFileSuccess?.(item.id, result);\n reportTotalProgress();\n } catch (err) {\n if ((err as Error).name === \"AbortError\") {\n item.status = \"error\";\n item.error = \"Upload cancelled\";\n return;\n }\n const message = err instanceof Error ? err.message : \"Upload failed\";\n item.status = \"error\";\n item.error = message;\n callbacks.onFileError?.(item.id, message);\n reportTotalProgress();\n }\n }\n };\n\n const concurrentFiles = config.concurrentFiles ?? DEFAULT_CONCURRENT_FILES;\n const workers = Array.from(\n { length: Math.min(concurrentFiles, items.length) },\n () => processNext(),\n );\n await Promise.all(workers);\n\n return results;\n}\n","\"use client\";\n\nimport { useCallback, useRef, useState } from \"react\";\nimport type { S3Api } from \"@better-s3/server\";\nimport { validateFile } from \"@better-s3/server\";\nimport type {\n UploadConfig,\n UploadHooks,\n UploadPhase,\n UploadProgress,\n UploadResult,\n UploadRequestOptions,\n} from \"./types\";\nimport { uploadFile } from \"./upload\";\n\nexport type UseUploadOptions = UploadConfig &\n UploadHooks & {\n api: S3Api;\n };\n\nexport type UseUploadState = {\n phase: UploadPhase;\n progress: UploadProgress;\n error: string | null;\n result: UploadResult | null;\n fileName: string | null;\n fileSize: number | null;\n};\n\nexport type UseUploadReturn = UseUploadState & {\n upload: (\n file: File,\n objectKey: string,\n requestOptions?: UploadRequestOptions,\n ) => Promise<void>;\n cancel: () => void;\n reset: () => void;\n};\n\nconst INITIAL_PROGRESS: UploadProgress = { loaded: 0, total: 0, percent: 0 };\n\nconst INITIAL_STATE: UseUploadState = {\n phase: \"idle\",\n progress: INITIAL_PROGRESS,\n error: null,\n result: null,\n fileName: null,\n fileSize: null,\n};\n\nexport function useUpload(options: UseUploadOptions): UseUploadReturn {\n const [state, setState] = useState<UseUploadState>(INITIAL_STATE);\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const abortRef = useRef<AbortController | null>(null);\n\n const upload = useCallback(\n async (\n file: File,\n objectKey: string,\n requestOptions?: UploadRequestOptions,\n ) => {\n setState({\n ...INITIAL_STATE,\n phase: \"validating\",\n fileName: file.name,\n fileSize: file.size,\n });\n const opts = optionsRef.current;\n\n const validationError = validateFile(file, {\n accept: opts.accept,\n maxFileSize: opts.maxFileSize,\n });\n if (validationError) {\n setState((s) => ({ ...s, phase: \"error\", error: validationError }));\n opts.onError?.(file, new Error(validationError), \"validating\");\n return;\n }\n\n if (opts.beforeUpload) {\n const allowed = await opts.beforeUpload(file);\n if (!allowed) {\n setState((s) => ({\n ...s,\n phase: \"error\",\n error: \"Upload blocked by beforeUpload hook\",\n }));\n opts.onError?.(file, new Error(\"blocked\"), \"validating\");\n return;\n }\n }\n\n setState((s) => ({ ...s, phase: \"presigning\" }));\n opts.onUploadStart?.(file, objectKey);\n\n const controller = new AbortController();\n abortRef.current = controller;\n\n try {\n const result = await uploadFile(\n opts.api,\n file,\n objectKey,\n {\n multipart: opts.multipart,\n multipartThreshold: opts.multipartThreshold,\n concurrentParts: opts.concurrentParts,\n },\n {\n onProgress: (progress) => {\n setState((s) => ({ ...s, progress }));\n opts.onProgress?.(file, progress);\n },\n onPhaseChange: (phase) => setState((s) => ({ ...s, phase })),\n },\n controller.signal,\n requestOptions,\n );\n\n setState((s) => ({\n ...s,\n phase: \"success\",\n result,\n progress: { loaded: file.size, total: file.size, percent: 100 },\n }));\n await opts.onSuccess?.(file, result);\n } catch (err) {\n if ((err as Error).name === \"AbortError\") {\n opts.onCancel?.(file);\n setState(INITIAL_STATE);\n return;\n }\n const message = err instanceof Error ? err.message : \"Upload failed\";\n setState((s) => ({ ...s, phase: \"error\", error: message }));\n opts.onError?.(file, err, \"uploading\");\n } finally {\n abortRef.current = null;\n }\n },\n [],\n );\n\n const cancel = useCallback(() => {\n abortRef.current?.abort();\n setState(INITIAL_STATE);\n }, []);\n\n const reset = useCallback(() => {\n abortRef.current?.abort();\n setState(INITIAL_STATE);\n }, []);\n\n return { ...state, upload, cancel, reset };\n}\n","\"use client\";\n\nimport { useCallback, useRef, useState } from \"react\";\nimport type { S3Api } from \"@better-s3/server\";\nimport { validateFile } from \"@better-s3/server\";\nimport type {\n UploadConfig,\n UploadProgress,\n UploadResult,\n UploadRequestOptions,\n MultiUploadPhase,\n MultiUploadFileState,\n MultiUploadHooks,\n} from \"./types\";\nimport { uploadFiles } from \"./upload\";\n\nexport type UseMultiUploadOptions = UploadConfig &\n MultiUploadHooks & {\n api: S3Api;\n /** Static request options applied to all files */\n uploadOptions?: UploadRequestOptions;\n /** Per-file request options (overrides uploadOptions) */\n getUploadOptions?: (file: File) => UploadRequestOptions;\n };\n\nexport type UseMultiUploadState = {\n phase: MultiUploadPhase;\n files: MultiUploadFileState[];\n totalProgress: UploadProgress;\n error: string | null;\n};\n\nexport type UseMultiUploadReturn = UseMultiUploadState & {\n upload: (files: File[], resolveKey: (file: File) => string) => Promise<void>;\n cancel: () => void;\n reset: () => void;\n};\n\nconst INITIAL_PROGRESS: UploadProgress = { loaded: 0, total: 0, percent: 0 };\n\nconst INITIAL_STATE: UseMultiUploadState = {\n phase: \"idle\",\n files: [],\n totalProgress: INITIAL_PROGRESS,\n error: null,\n};\n\nlet nextId = 0;\nfunction generateId() {\n return `file-${++nextId}`;\n}\n\nexport function useMultiUpload(\n options: UseMultiUploadOptions,\n): UseMultiUploadReturn {\n const [state, setState] = useState<UseMultiUploadState>(INITIAL_STATE);\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const abortRef = useRef<AbortController | null>(null);\n const fileMapRef = useRef<Map<string, File>>(new Map());\n\n const upload = useCallback(\n async (files: File[], resolveKey: (file: File) => string) => {\n const opts = optionsRef.current;\n\n const items: Array<{\n id: string;\n file: File;\n objectKey: string;\n }> = [];\n const fileStates: MultiUploadFileState[] = [];\n const fileMap = new Map<string, File>();\n\n setState((s) => ({ ...s, phase: \"validating\", error: null }));\n\n if (opts.maxFiles && files.length > opts.maxFiles) {\n const msg = `Too many files. Maximum is ${opts.maxFiles}.`;\n setState((s) => ({ ...s, phase: \"error\", error: msg }));\n opts.onError?.(new Error(msg));\n return;\n }\n\n for (const file of files) {\n const validationError = validateFile(file, {\n accept: opts.accept,\n maxFileSize: opts.maxFileSize,\n });\n if (validationError) {\n const msg = `${file.name}: ${validationError}`;\n setState((s) => ({ ...s, phase: \"error\", error: msg }));\n opts.onError?.(new Error(msg));\n return;\n }\n }\n\n if (opts.beforeUpload) {\n const allowed = await opts.beforeUpload(files);\n if (!allowed) {\n setState((s) => ({\n ...s,\n phase: \"error\",\n error: \"Upload blocked by beforeUpload hook\",\n }));\n opts.onError?.(new Error(\"blocked\"));\n return;\n }\n }\n\n for (const file of files) {\n const id = generateId();\n const objectKey = resolveKey(file);\n items.push({ id, file, objectKey });\n fileMap.set(id, file);\n fileStates.push({\n id,\n fileName: file.name,\n fileSize: file.size,\n status: \"pending\",\n progress: { loaded: 0, total: file.size, percent: 0 },\n error: null,\n });\n }\n\n fileMapRef.current = fileMap;\n\n setState({\n phase: \"uploading\",\n files: fileStates,\n totalProgress: {\n loaded: 0,\n total: files.reduce((s, f) => s + f.size, 0),\n percent: 0,\n },\n error: null,\n });\n\n opts.onUploadStart?.(files);\n\n const controller = new AbortController();\n abortRef.current = controller;\n\n try {\n const results = await uploadFiles(\n opts.api,\n items,\n {\n multipart: opts.multipart,\n multipartThreshold: opts.multipartThreshold,\n concurrentParts: opts.concurrentParts,\n concurrentFiles: opts.concurrentFiles,\n },\n {\n onFileProgress: (id, progress) => {\n setState((s) => ({\n ...s,\n files: s.files.map((f) =>\n f.id === id ? { ...f, status: \"uploading\", progress } : f,\n ),\n }));\n const file = fileMap.get(id);\n if (file) opts.onFileProgress?.(file, progress);\n },\n onFileSuccess: (id, result) => {\n setState((s) => ({\n ...s,\n files: s.files.map((f) =>\n f.id === id\n ? {\n ...f,\n status: \"success\",\n progress: {\n loaded: f.fileSize,\n total: f.fileSize,\n percent: 100,\n },\n }\n : f,\n ),\n }));\n const file = fileMap.get(id);\n if (file) opts.onFileSuccess?.(file, result);\n },\n onFileError: (id, error) => {\n setState((s) => ({\n ...s,\n files: s.files.map((f) =>\n f.id === id ? { ...f, status: \"error\", error } : f,\n ),\n }));\n const file = fileMap.get(id);\n if (file) opts.onFileError?.(file, error);\n },\n onTotalProgress: (progress) => {\n setState((s) => ({ ...s, totalProgress: progress }));\n opts.onProgress?.(progress);\n },\n },\n controller.signal,\n (file) => {\n const perFile = opts.getUploadOptions?.(file);\n if (!opts.uploadOptions) return perFile ?? {};\n return { ...opts.uploadOptions, ...perFile };\n },\n );\n\n const hasErrors = results.some((r) => r.status === \"error\");\n const successResults = results\n .filter((r) => r.result !== null)\n .map((r) => r.result!);\n\n setState((s) => ({\n ...s,\n phase: hasErrors ? \"error\" : \"success\",\n error: hasErrors\n ? `${results.filter((r) => r.status === \"error\").length} file(s) failed`\n : null,\n totalProgress: hasErrors\n ? s.totalProgress\n : {\n loaded: s.totalProgress.total,\n total: s.totalProgress.total,\n percent: 100,\n },\n }));\n\n if (!hasErrors) {\n await opts.onSuccess?.(successResults);\n }\n } catch (err) {\n if ((err as Error).name === \"AbortError\") {\n opts.onCancel?.();\n setState(INITIAL_STATE);\n return;\n }\n const message = err instanceof Error ? err.message : \"Upload failed\";\n setState((s) => ({ ...s, phase: \"error\", error: message }));\n opts.onError?.(err);\n } finally {\n abortRef.current = null;\n }\n },\n [],\n );\n\n const cancel = useCallback(() => {\n abortRef.current?.abort();\n setState(INITIAL_STATE);\n }, []);\n\n const reset = useCallback(() => {\n abortRef.current?.abort();\n setState(INITIAL_STATE);\n }, []);\n\n return { ...state, upload, cancel, reset };\n}\n","\"use client\";\n\nimport { useRef, useState } from \"react\";\nimport type {\n UploadPhase,\n UploadProgress,\n UploadResult,\n UploadRequestOptions,\n MultiUploadFileState,\n MultiUploadPhase,\n} from \"./types\";\nimport { useUpload, type UseUploadOptions } from \"./use-upload\";\nimport { useMultiUpload, type UseMultiUploadOptions } from \"./use-multi-upload\";\nimport type { S3Api } from \"@better-s3/server\";\nimport type { UploadConfig } from \"./types\";\n\nconst INITIAL_PROGRESS: UploadProgress = { loaded: 0, total: 0, percent: 0 };\n\nexport type UseUploadControlsOptions = UploadConfig & {\n api: S3Api;\n objectKey: string | ((file: File) => string);\n /**\n * Maximum number of files. When > 1 the hook switches to multi-upload mode\n * and the native file picker allows selecting multiple files.\n * @default 1\n */\n maxFiles?: number;\n /** Static request options applied to all files (multi mode) */\n uploadOptions?: UploadRequestOptions;\n /** Per-file request options */\n getUploadOptions?: (file: File) => UploadRequestOptions;\n // Callbacks – typed as a union to support both single and multi modes\n beforeUpload?:\n | ((file: File) => boolean | Promise<boolean>)\n | ((files: File[]) => boolean | Promise<boolean>);\n onUploadStart?:\n | ((file: File, key: string) => void)\n | ((files: File[]) => void);\n onProgress?:\n | ((file: File, progress: UploadProgress) => void)\n | ((progress: UploadProgress) => void);\n onSuccess?:\n | ((file: File, result: UploadResult) => void | Promise<void>)\n | ((results: UploadResult[]) => void | Promise<void>);\n onError?:\n | ((file: File | null, error: unknown, phase: UploadPhase) => void)\n | ((error: unknown) => void);\n onCancel?: ((file: File | null) => void) | (() => void);\n // Multi-only callbacks\n onFileProgress?: (file: File, progress: UploadProgress) => void;\n onFileSuccess?: (file: File, result: UploadResult) => void;\n onFileError?: (file: File, error: string) => void;\n};\n\nexport type UseUploadControlsReturn = {\n /** Whether the hook is in single-file or multi-file mode */\n mode: \"single\" | \"multi\";\n phase: UploadPhase | MultiUploadPhase;\n /** Info about the selected file (single mode only) */\n fileInfo: { name: string; size: number } | null;\n /** Upload progress (single mode) */\n progress: UploadProgress;\n /** Per-file states (multi mode only) */\n files: MultiUploadFileState[];\n /** Aggregated progress across all files (multi mode) */\n totalProgress: UploadProgress;\n error: string | null;\n isUploading: boolean;\n handleFiles: (files: FileList | null) => void;\n openFilePicker: () => void;\n cancel: () => void;\n reset: () => void;\n /** Spread on a hidden `<input>` element */\n inputProps: {\n ref: React.RefObject<HTMLInputElement | null>;\n type: \"file\";\n multiple?: true;\n accept?: string;\n hidden: true;\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\n };\n /** Spread on a container to enable drag-and-drop */\n dropHandlers: {\n onDragOver: (e: React.DragEvent) => void;\n onDrop: (e: React.DragEvent) => void;\n };\n};\n\nexport function useUploadControls(\n options: UseUploadControlsOptions,\n): UseUploadControlsReturn {\n const isMulti = (options.maxFiles ?? 1) > 1;\n\n // Build per-mode options. Both hooks are called unconditionally (React rules).\n const singleOpts: UseUploadOptions = {\n api: options.api,\n accept: options.accept,\n maxFileSize: options.maxFileSize,\n multipart: options.multipart,\n multipartThreshold: options.multipartThreshold,\n concurrentParts: options.concurrentParts,\n beforeUpload: options.beforeUpload as UseUploadOptions[\"beforeUpload\"],\n onUploadStart: options.onUploadStart as UseUploadOptions[\"onUploadStart\"],\n onProgress: options.onProgress as UseUploadOptions[\"onProgress\"],\n onSuccess: options.onSuccess as UseUploadOptions[\"onSuccess\"],\n onError: options.onError as UseUploadOptions[\"onError\"],\n onCancel: options.onCancel as UseUploadOptions[\"onCancel\"],\n };\n\n const multiOpts: UseMultiUploadOptions = {\n api: options.api,\n accept: options.accept,\n maxFileSize: options.maxFileSize,\n maxFiles: options.maxFiles,\n multipart: options.multipart,\n multipartThreshold: options.multipartThreshold,\n concurrentParts: options.concurrentParts,\n concurrentFiles: options.concurrentFiles,\n uploadOptions: options.uploadOptions,\n getUploadOptions: options.getUploadOptions,\n beforeUpload: options.beforeUpload as UseMultiUploadOptions[\"beforeUpload\"],\n onUploadStart:\n options.onUploadStart as UseMultiUploadOptions[\"onUploadStart\"],\n onProgress: options.onProgress as UseMultiUploadOptions[\"onProgress\"],\n onSuccess: options.onSuccess as UseMultiUploadOptions[\"onSuccess\"],\n onError: options.onError as UseMultiUploadOptions[\"onError\"],\n onCancel: options.onCancel as UseMultiUploadOptions[\"onCancel\"],\n onFileProgress: options.onFileProgress,\n onFileSuccess: options.onFileSuccess,\n onFileError: options.onFileError,\n };\n\n const single = useUpload(singleOpts);\n const multi = useMultiUpload(multiOpts);\n\n const inputRef = useRef<HTMLInputElement>(null);\n const [fileInfo, setFileInfo] = useState<{\n name: string;\n size: number;\n } | null>(null);\n\n const resolveKey = (file: File): string =>\n typeof options.objectKey === \"function\"\n ? options.objectKey(file)\n : options.objectKey;\n\n const handleFiles = async (files: FileList | null) => {\n if (isMulti) {\n if (!files?.length) return;\n await multi.upload(Array.from(files), resolveKey);\n } else {\n const file = files?.[0];\n if (!file) return;\n setFileInfo({ name: file.name, size: file.size });\n await single.upload(file, resolveKey(file), {\n ...options.uploadOptions,\n ...options.getUploadOptions?.(file),\n });\n }\n };\n\n const openFilePicker = () => inputRef.current?.click();\n const isUploading = isMulti\n ? multi.phase === \"uploading\"\n : single.phase === \"uploading\";\n\n return {\n mode: isMulti ? \"multi\" : \"single\",\n phase: isMulti ? multi.phase : single.phase,\n fileInfo: isMulti ? null : fileInfo,\n progress: isMulti ? INITIAL_PROGRESS : single.progress,\n files: isMulti ? multi.files : [],\n totalProgress: isMulti ? multi.totalProgress : INITIAL_PROGRESS,\n error: isMulti ? multi.error : single.error,\n isUploading,\n handleFiles,\n openFilePicker,\n cancel: isMulti ? multi.cancel : single.cancel,\n reset: isMulti\n ? multi.reset\n : () => {\n single.reset();\n setFileInfo(null);\n },\n inputProps: {\n ref: inputRef,\n type: \"file\",\n ...(isMulti && { multiple: true as const }),\n accept: options.accept?.join(\",\"),\n hidden: true,\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => {\n handleFiles(e.target.files);\n e.target.value = \"\";\n },\n },\n dropHandlers: {\n onDragOver: (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n },\n onDrop: (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n if (!isUploading) handleFiles(e.dataTransfer.files);\n },\n },\n };\n}\n","\"use client\";\n\nimport { useCallback, useRef, useState } from \"react\";\nimport type { S3Api } from \"@better-s3/server\";\n\n/** \"presigning\" = fetching the presigned URL from the server; download itself is native */\nexport type DownloadPhase = \"idle\" | \"presigning\" | \"error\";\n\nexport type DownloadHooks = {\n beforeDownload?: (key: string) => Promise<boolean> | boolean;\n /** Fires as soon as the browser has been handed the URL — not when download completes. */\n onInitiated?: (key: string) => void;\n onError?: (key: string, error: unknown) => void;\n};\n\nexport type UseDownloadOptions = DownloadHooks & {\n api: S3Api;\n /** Target bucket (overrides server default) */\n bucket?: string;\n};\n\nexport type UseDownloadState = {\n phase: DownloadPhase;\n error: string | null;\n /** Presigned URL — set after a successful presign, cleared on reset */\n url: string | null;\n /** Validity window in seconds for the presigned URL */\n expiresIn: number | null;\n};\n\nexport type UseDownloadReturn = UseDownloadState & {\n download: (key: string, downloadName?: string) => Promise<void>;\n /** Fetch the presigned URL without triggering a browser download — for headless use */\n presign: (\n key: string,\n downloadName?: string,\n ) => Promise<{ url: string; expiresIn: number } | null>;\n reset: () => void;\n};\n\nconst INITIAL_STATE: UseDownloadState = {\n phase: \"idle\",\n error: null,\n url: null,\n expiresIn: null,\n};\n\nexport function useDownload(options: UseDownloadOptions): UseDownloadReturn {\n const [state, setState] = useState<UseDownloadState>(INITIAL_STATE);\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const presign = useCallback(async (key: string, downloadName?: string) => {\n const opts = optionsRef.current;\n setState({ phase: \"presigning\", error: null, url: null, expiresIn: null });\n try {\n const result = await opts.api.download(key, {\n fileName: downloadName,\n bucket: opts.bucket,\n });\n setState({\n phase: \"idle\",\n error: null,\n url: result.url,\n expiresIn: result.expiresIn,\n });\n return { url: result.url, expiresIn: result.expiresIn };\n } catch (err) {\n const message = err instanceof Error ? err.message : \"Download failed\";\n setState({ phase: \"error\", error: message, url: null, expiresIn: null });\n opts.onError?.(key, err);\n return null;\n }\n }, []);\n\n const download = useCallback(\n async (key: string, downloadName?: string) => {\n const opts = optionsRef.current;\n\n if (opts.beforeDownload) {\n const allowed = await opts.beforeDownload(key);\n if (!allowed) {\n setState({\n phase: \"error\",\n error: \"Download blocked by beforeDownload hook\",\n url: null,\n expiresIn: null,\n });\n opts.onError?.(key, new Error(\"blocked\"));\n return;\n }\n }\n\n const result = await presign(key, downloadName);\n if (!result) return; // presign already set error state\n\n // Native browser download via location — server sets Content-Disposition: attachment.\n window.location.href = result.url;\n\n opts.onInitiated?.(key);\n },\n [presign],\n );\n\n const reset = useCallback(() => {\n setState(INITIAL_STATE);\n }, []);\n\n return { ...state, download, presign, reset };\n}\n","\"use client\";\n\nimport { useCallback, useRef, useState } from \"react\";\nimport type { S3Api } from \"@better-s3/server\";\nimport { parseContentDispositionFilename } from \"./helpers\";\n\nexport type FetchDownloadPhase =\n | \"idle\"\n | \"presigning\"\n | \"downloading\"\n | \"success\"\n | \"error\";\n\nexport type FetchDownloadProgress = {\n loaded: number;\n total: number;\n percent: number;\n};\n\nexport type FetchDownloadHooks = {\n beforeDownload?: (key: string) => Promise<boolean> | boolean;\n onDownloadStart?: (key: string) => void;\n onProgress?: (key: string, progress: FetchDownloadProgress) => void;\n onSuccess?: (key: string, fileName: string) => Promise<void> | void;\n onError?: (key: string, error: unknown, phase: FetchDownloadPhase) => void;\n onCancel?: (key: string) => void;\n};\n\nexport type UseFetchDownloadOptions = FetchDownloadHooks & {\n api: S3Api;\n /** Target bucket (overrides server default) */\n bucket?: string;\n};\n\nexport type UseFetchDownloadState = {\n phase: FetchDownloadPhase;\n progress: FetchDownloadProgress;\n error: string | null;\n fileName: string | null;\n fileSize: number | null;\n};\n\nexport type UseFetchDownloadReturn = UseFetchDownloadState & {\n download: (key: string, downloadName?: string) => Promise<void>;\n cancel: () => void;\n reset: () => void;\n};\n\nconst INITIAL_PROGRESS: FetchDownloadProgress = {\n loaded: 0,\n total: 0,\n percent: 0,\n};\n\nconst INITIAL_STATE: UseFetchDownloadState = {\n phase: \"idle\",\n progress: INITIAL_PROGRESS,\n error: null,\n fileName: null,\n fileSize: null,\n};\n\nexport function useFetchDownload(\n options: UseFetchDownloadOptions,\n): UseFetchDownloadReturn {\n const [state, setState] = useState<UseFetchDownloadState>(INITIAL_STATE);\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const abortRef = useRef<AbortController | null>(null);\n\n const download = useCallback(async (key: string, downloadName?: string) => {\n const fallback = key.split(\"/\").pop() ?? key;\n const opts = optionsRef.current;\n\n if (opts.beforeDownload) {\n const allowed = await opts.beforeDownload(key);\n if (!allowed) {\n setState((s) => ({\n ...s,\n phase: \"error\",\n error: \"Download blocked by beforeDownload hook\",\n }));\n opts.onError?.(key, new Error(\"blocked\"), \"presigning\");\n return;\n }\n }\n\n setState({\n phase: \"presigning\",\n progress: INITIAL_PROGRESS,\n error: null,\n fileName: downloadName ?? null,\n fileSize: null,\n });\n\n try {\n const { url } = await opts.api.download(key, {\n fileName: downloadName,\n bucket: opts.bucket,\n });\n\n setState((s) => ({ ...s, phase: \"downloading\" }));\n opts.onDownloadStart?.(key);\n\n const controller = new AbortController();\n abortRef.current = controller;\n\n const res = await fetch(url, { signal: controller.signal });\n if (!res.ok) {\n throw new Error(\n res.status === 404\n ? \"File not found\"\n : `Download failed (${res.status})`,\n );\n }\n\n const contentLength = Number(res.headers.get(\"content-length\") || 0);\n const name =\n downloadName ??\n parseContentDispositionFilename(\n res.headers.get(\"content-disposition\"),\n fallback,\n );\n setState((s) => ({\n ...s,\n fileName: name,\n fileSize: contentLength || null,\n }));\n\n const reader = res.body?.getReader();\n if (!reader) throw new Error(\"ReadableStream not supported\");\n\n const chunks: BlobPart[] = [];\n let loaded = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n loaded += value.byteLength;\n const percent =\n contentLength > 0 ? Math.round((loaded / contentLength) * 100) : 0;\n const progress: FetchDownloadProgress = {\n loaded,\n total: contentLength,\n percent,\n };\n setState((s) => ({ ...s, progress }));\n opts.onProgress?.(key, progress);\n }\n\n const blob = new Blob(chunks);\n const blobUrl = URL.createObjectURL(blob);\n const anchor = document.createElement(\"a\");\n anchor.href = blobUrl;\n anchor.download = name ?? fallback;\n anchor.click();\n URL.revokeObjectURL(blobUrl);\n\n setState((s) => ({\n ...s,\n phase: \"success\",\n fileSize: blob.size,\n progress: { loaded: blob.size, total: blob.size, percent: 100 },\n }));\n await opts.onSuccess?.(key, name ?? fallback);\n } catch (err) {\n if ((err as Error).name === \"AbortError\") {\n opts.onCancel?.(key);\n setState(INITIAL_STATE);\n return;\n }\n const message = err instanceof Error ? err.message : \"Download failed\";\n setState((s) => ({ ...s, phase: \"error\", error: message }));\n opts.onError?.(key, err, \"downloading\");\n } finally {\n abortRef.current = null;\n }\n }, []);\n\n const cancel = useCallback(() => {\n abortRef.current?.abort();\n setState(INITIAL_STATE);\n }, []);\n\n const reset = useCallback(() => {\n abortRef.current?.abort();\n setState(INITIAL_STATE);\n }, []);\n\n return { ...state, download, cancel, reset };\n}\n","\"use client\";\n\nimport { useCallback, useRef, useState } from \"react\";\nimport type { S3Api } from \"@better-s3/server\";\nimport type { DeletePhase, DeleteHooks } from \"./types\";\n\nexport type UseDeleteOptions = DeleteHooks & {\n api: S3Api;\n /** Target bucket (overrides server default) */\n bucket?: string;\n};\n\nexport type UseDeleteState = {\n phase: DeletePhase;\n error: string | null;\n};\n\nexport type UseDeleteReturn = UseDeleteState & {\n requestDelete: (key: string) => void;\n confirmDelete: () => Promise<void>;\n cancelDelete: () => void;\n reset: () => void;\n pendingKey: string | null;\n};\n\nconst INITIAL_STATE: UseDeleteState = {\n phase: \"idle\",\n error: null,\n};\n\nexport function useDelete(options: UseDeleteOptions): UseDeleteReturn {\n const [state, setState] = useState<UseDeleteState>(INITIAL_STATE);\n const [pendingKey, setPendingKey] = useState<string | null>(null);\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const requestDelete = useCallback((key: string) => {\n setPendingKey(key);\n setState({ phase: \"confirming\", error: null });\n }, []);\n\n const confirmDelete = useCallback(async () => {\n if (!pendingKey) return;\n const opts = optionsRef.current;\n\n if (opts.beforeDelete) {\n const allowed = await opts.beforeDelete(pendingKey);\n if (!allowed) {\n setState({\n phase: \"error\",\n error: \"Delete blocked by beforeDelete hook\",\n });\n opts.onError?.(pendingKey, new Error(\"blocked\"), \"confirming\");\n setPendingKey(null);\n return;\n }\n }\n\n setState({ phase: \"deleting\", error: null });\n opts.onDeleteStart?.(pendingKey);\n\n try {\n await opts.api.delete(pendingKey, { bucket: opts.bucket });\n\n setState({ phase: \"success\", error: null });\n await opts.onSuccess?.(pendingKey);\n setPendingKey(null);\n } catch (err) {\n const message = err instanceof Error ? err.message : \"Delete failed\";\n setState({ phase: \"error\", error: message });\n opts.onError?.(pendingKey, err, \"deleting\");\n }\n }, [pendingKey]);\n\n const cancelDelete = useCallback(() => {\n setPendingKey(null);\n setState(INITIAL_STATE);\n }, []);\n\n const reset = useCallback(() => {\n setPendingKey(null);\n setState(INITIAL_STATE);\n }, []);\n\n return {\n ...state,\n pendingKey,\n requestDelete,\n confirmDelete,\n cancelDelete,\n reset,\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@better-s3/react",
3
- "version": "3.1045.1",
3
+ "version": "3.1045.2",
4
4
  "description": "React hooks for S3-compatible file uploads, downloads, and deletes",
5
5
  "keywords": [
6
6
  "s3",
@@ -33,7 +33,7 @@
33
33
  "dist"
34
34
  ],
35
35
  "dependencies": {
36
- "@better-s3/server": "3.1045.1"
36
+ "@better-s3/server": "3.1045.2"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "react": ">=18"