@better-s3/react 3.1045.2 → 3.1046.0
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/api.d.ts +30 -0
- package/dist/helpers/build-object-key.d.ts +20 -0
- package/dist/helpers/format-eta.d.ts +12 -0
- package/dist/helpers/format-file-size.d.ts +11 -0
- package/dist/helpers/format-speed.d.ts +8 -0
- package/dist/helpers/format-upload-progress.d.ts +17 -0
- package/dist/helpers/get-file-extension.d.ts +13 -0
- package/dist/helpers/index.d.ts +10 -0
- package/dist/helpers/parse-content-disposition.d.ts +18 -0
- package/dist/helpers/speed-tracker.d.ts +17 -0
- package/dist/helpers/truncate-filename.d.ts +9 -0
- package/dist/helpers/validate-file.d.ts +22 -0
- package/dist/hooks/index.d.ts +7 -0
- package/dist/{use-delete.d.ts → hooks/use-delete.d.ts} +4 -3
- package/dist/{use-download.d.ts → hooks/use-download.d.ts} +5 -10
- package/dist/hooks/use-fetch-download.d.ts +23 -0
- package/dist/hooks/use-multi-upload-controls.d.ts +33 -0
- package/dist/{use-multi-upload.d.ts → hooks/use-multi-upload.d.ts} +4 -3
- package/dist/hooks/use-upload-controls.d.ts +44 -0
- package/dist/hooks/use-upload.d.ts +75 -0
- package/dist/index.d.ts +13 -8
- package/dist/index.js +581 -186
- package/dist/index.js.map +1 -1
- package/dist/internal-helpers.d.ts +9 -0
- package/dist/s3-provider.d.ts +47 -0
- package/dist/store/index.d.ts +3 -0
- package/dist/store/local-storage-store.d.ts +9 -0
- package/dist/store/memory-store.d.ts +14 -0
- package/dist/types/download.d.ts +19 -2
- package/dist/types/error.d.ts +14 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/s3-api.d.ts +158 -0
- package/dist/types/upload-store.d.ts +54 -0
- package/dist/types/upload.d.ts +56 -0
- package/dist/upload/constants.d.ts +1 -1
- package/dist/upload/multipart.d.ts +4 -3
- package/dist/upload/retry.d.ts +2 -1
- package/dist/upload/upload-file.d.ts +5 -1
- package/dist/upload/upload-files.d.ts +1 -1
- package/package.json +1 -4
- package/dist/helpers.d.ts +0 -7
- package/dist/use-fetch-download.d.ts +0 -33
- package/dist/use-upload-controls.d.ts +0 -63
- package/dist/use-upload.d.ts +0 -19
package/dist/types/download.d.ts
CHANGED
|
@@ -1,2 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
export type
|
|
1
|
+
import type { UploadProgress } from "./upload";
|
|
2
|
+
export type DownloadPhase = "idle" | "presigning" | "error";
|
|
3
|
+
export type DownloadHooks = {
|
|
4
|
+
beforeDownload?: (key: string) => Promise<boolean> | boolean;
|
|
5
|
+
/** Fires as soon as the browser has been handed the URL — not when download completes. */
|
|
6
|
+
onInitiated?: (key: string) => void;
|
|
7
|
+
onError?: (key: string, error: unknown) => void;
|
|
8
|
+
};
|
|
9
|
+
export type FetchDownloadPhase = "idle" | "presigning" | "downloading" | "success" | "error";
|
|
10
|
+
/** Identical shape to {@link UploadProgress}. */
|
|
11
|
+
export type FetchDownloadProgress = UploadProgress;
|
|
12
|
+
export type FetchDownloadHooks = {
|
|
13
|
+
beforeDownload?: (key: string) => Promise<boolean> | boolean;
|
|
14
|
+
onDownloadStart?: (key: string) => void;
|
|
15
|
+
onProgress?: (key: string, progress: UploadProgress) => void;
|
|
16
|
+
onSuccess?: (key: string, fileName: string) => Promise<void> | void;
|
|
17
|
+
onError?: (key: string, error: unknown, phase: FetchDownloadPhase) => void;
|
|
18
|
+
onCancel?: (key: string) => void;
|
|
19
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { UploadPhase } from "./upload";
|
|
2
|
+
/**
|
|
3
|
+
* Structured error thrown by the upload engine.
|
|
4
|
+
*
|
|
5
|
+
* - `code` — machine-readable error code (e.g. `"VALIDATION_ERROR"`, `"NETWORK_ERROR"`)
|
|
6
|
+
* - `statusCode` — HTTP status code when the error originated from a server response
|
|
7
|
+
* - `phase` — upload phase in which the error occurred
|
|
8
|
+
*/
|
|
9
|
+
export declare class S3UploadError extends Error {
|
|
10
|
+
readonly code: string;
|
|
11
|
+
readonly statusCode: number | undefined;
|
|
12
|
+
readonly phase: UploadPhase | undefined;
|
|
13
|
+
constructor(message: string, code: string, statusCode?: number, phase?: UploadPhase);
|
|
14
|
+
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
export type PresignResponse = {
|
|
2
|
+
key: string;
|
|
3
|
+
bucket: string;
|
|
4
|
+
url: string;
|
|
5
|
+
expiresIn: number;
|
|
6
|
+
};
|
|
7
|
+
export type UploadPresignResponse = {
|
|
8
|
+
key: string;
|
|
9
|
+
bucket: string;
|
|
10
|
+
url: string;
|
|
11
|
+
expiresIn: number;
|
|
12
|
+
method: "post" | "put";
|
|
13
|
+
/** Present when `method` is `"post"`. Must be appended to FormData before the file. */
|
|
14
|
+
fields?: Record<string, string>;
|
|
15
|
+
/** Present when `method` is `"put"`. Must be set as request headers on the PUT request. */
|
|
16
|
+
headers?: Record<string, string>;
|
|
17
|
+
};
|
|
18
|
+
/** @deprecated Use {@link UploadPresignResponse} instead. */
|
|
19
|
+
export type PresignedPostResponse = UploadPresignResponse;
|
|
20
|
+
export type MultipartInitResponse = {
|
|
21
|
+
key: string;
|
|
22
|
+
bucket: string;
|
|
23
|
+
uploadId: string;
|
|
24
|
+
};
|
|
25
|
+
export type MultipartPartResponse = {
|
|
26
|
+
presignedUrl: string;
|
|
27
|
+
partNumber: number;
|
|
28
|
+
uploadId: string;
|
|
29
|
+
bucket: string;
|
|
30
|
+
expiresIn: number;
|
|
31
|
+
/** Exact byte size locked into this part's presigned URL signature. */
|
|
32
|
+
partSize?: number;
|
|
33
|
+
};
|
|
34
|
+
export type MultipartListPartsResponse = {
|
|
35
|
+
parts: Array<{
|
|
36
|
+
partNumber: number;
|
|
37
|
+
/** Byte size of the uploaded part. */
|
|
38
|
+
size: number;
|
|
39
|
+
/** ETag of the uploaded part. */
|
|
40
|
+
eTag: string;
|
|
41
|
+
}>;
|
|
42
|
+
};
|
|
43
|
+
export type UploadConfirmResponse = {
|
|
44
|
+
key: string;
|
|
45
|
+
bucket: string;
|
|
46
|
+
contentType?: string;
|
|
47
|
+
contentLength: number;
|
|
48
|
+
eTag?: string;
|
|
49
|
+
/** S3 object metadata (x-amz-meta-*). Always present; empty object when no metadata was stored. */
|
|
50
|
+
metadata: Record<string, string>;
|
|
51
|
+
/** Resolved ACL. Omitted when ACL lookup is disabled or unsupported. */
|
|
52
|
+
acl?: "private" | "public-read";
|
|
53
|
+
/** Display file name parsed from the object's Content-Disposition header. */
|
|
54
|
+
fileName?: string;
|
|
55
|
+
/** Object version ID. Only present when bucket versioning is enabled. */
|
|
56
|
+
versionId?: string;
|
|
57
|
+
/** Last-modified timestamp from HeadObject (ISO 8601 string). */
|
|
58
|
+
lastModified?: string;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Protocol interface for the presign API consumed by `@better-s3/react` hooks.
|
|
62
|
+
*
|
|
63
|
+
* The default implementation is `createS3Api()` from `@better-s3/server`, but
|
|
64
|
+
* any backend that satisfies this interface can be used instead.
|
|
65
|
+
*/
|
|
66
|
+
export type S3Api = {
|
|
67
|
+
upload: (payload: {
|
|
68
|
+
key: string;
|
|
69
|
+
contentType?: string;
|
|
70
|
+
/**
|
|
71
|
+
* Exact byte size of the file. When provided the presigned POST policy
|
|
72
|
+
* locks `content-length-range` to `[fileSize, fileSize]` so S3 rejects
|
|
73
|
+
* uploads of any other size at the storage layer.
|
|
74
|
+
*/
|
|
75
|
+
fileSize?: number;
|
|
76
|
+
metadata?: Record<string, string>;
|
|
77
|
+
bucket?: string;
|
|
78
|
+
acl?: "private" | "public-read";
|
|
79
|
+
/** Original file name. Stored as `Content-Disposition` on the S3 object. */
|
|
80
|
+
fileName?: string;
|
|
81
|
+
}) => Promise<UploadPresignResponse>;
|
|
82
|
+
confirm: (payload: {
|
|
83
|
+
key: string;
|
|
84
|
+
bucket?: string;
|
|
85
|
+
}) => Promise<UploadConfirmResponse>;
|
|
86
|
+
download: (key: string, options?: {
|
|
87
|
+
fileName?: string;
|
|
88
|
+
bucket?: string;
|
|
89
|
+
}) => Promise<PresignResponse>;
|
|
90
|
+
delete: (key: string, options?: {
|
|
91
|
+
bucket?: string;
|
|
92
|
+
}) => Promise<{
|
|
93
|
+
success: boolean;
|
|
94
|
+
bucket: string;
|
|
95
|
+
key: string;
|
|
96
|
+
}>;
|
|
97
|
+
multipart: {
|
|
98
|
+
init: (payload: {
|
|
99
|
+
key: string;
|
|
100
|
+
contentType?: string;
|
|
101
|
+
/** Declared total byte size of the file. */
|
|
102
|
+
fileSize?: number;
|
|
103
|
+
metadata?: Record<string, string>;
|
|
104
|
+
bucket?: string;
|
|
105
|
+
acl?: "private" | "public-read";
|
|
106
|
+
/** Original file name. Stored as `Content-Disposition` on the S3 object. */
|
|
107
|
+
fileName?: string;
|
|
108
|
+
}) => Promise<MultipartInitResponse>;
|
|
109
|
+
signPart: (payload: {
|
|
110
|
+
key: string;
|
|
111
|
+
uploadId: string;
|
|
112
|
+
partNumber: number;
|
|
113
|
+
/**
|
|
114
|
+
* Exact byte size of the part. When provided, Content-Length is included
|
|
115
|
+
* in the HMAC signature so S3 rejects any part body of a different size.
|
|
116
|
+
*/
|
|
117
|
+
partSize?: number;
|
|
118
|
+
bucket?: string;
|
|
119
|
+
}) => Promise<MultipartPartResponse>;
|
|
120
|
+
/**
|
|
121
|
+
* List already-uploaded parts for an in-progress multipart upload.
|
|
122
|
+
* Used by the resumable upload flow to skip already-completed parts.
|
|
123
|
+
*/
|
|
124
|
+
listParts: (payload: {
|
|
125
|
+
key: string;
|
|
126
|
+
uploadId: string;
|
|
127
|
+
bucket?: string;
|
|
128
|
+
}) => Promise<MultipartListPartsResponse>;
|
|
129
|
+
complete: (payload: {
|
|
130
|
+
key: string;
|
|
131
|
+
uploadId: string;
|
|
132
|
+
parts: Array<{
|
|
133
|
+
partNumber: number;
|
|
134
|
+
}>;
|
|
135
|
+
bucket?: string;
|
|
136
|
+
}) => Promise<{
|
|
137
|
+
key: string;
|
|
138
|
+
bucket: string;
|
|
139
|
+
uploadId: string;
|
|
140
|
+
contentLength: number;
|
|
141
|
+
contentType?: string;
|
|
142
|
+
eTag?: string;
|
|
143
|
+
/** S3 object metadata (x-amz-meta-*). Always present; empty object when no metadata was stored. */
|
|
144
|
+
metadata: Record<string, string>;
|
|
145
|
+
/** Object version ID. Only present when bucket versioning is enabled. */
|
|
146
|
+
versionId?: string;
|
|
147
|
+
/** Last-modified timestamp from HeadObject (ISO 8601 string). */
|
|
148
|
+
lastModified?: string;
|
|
149
|
+
}>;
|
|
150
|
+
abort: (payload: {
|
|
151
|
+
key: string;
|
|
152
|
+
uploadId: string;
|
|
153
|
+
bucket?: string;
|
|
154
|
+
}) => Promise<{
|
|
155
|
+
aborted: boolean;
|
|
156
|
+
}>;
|
|
157
|
+
};
|
|
158
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal state that must be persisted to resume a multipart upload.
|
|
3
|
+
*/
|
|
4
|
+
export type StoredUpload = {
|
|
5
|
+
/** S3 multipart `UploadId` returned by `CreateMultipartUpload`. */
|
|
6
|
+
uploadId: string;
|
|
7
|
+
/** S3 object key. */
|
|
8
|
+
key: string;
|
|
9
|
+
/** Total file size in bytes — used to verify the same file is being resumed. */
|
|
10
|
+
fileSize: number;
|
|
11
|
+
/** Bucket override, if any. */
|
|
12
|
+
bucket?: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Storage backend for resumable multipart uploads.
|
|
16
|
+
*
|
|
17
|
+
* Implement this interface to persist `uploadId` state in any storage system
|
|
18
|
+
* (database, Redis, IndexedDB, etc.). The default implementation uses
|
|
19
|
+
* `localStorage` via `createLocalStorageStore()`.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* // Custom database-backed store
|
|
24
|
+
* const dbStore: UploadStore = {
|
|
25
|
+
* async get(key, fileSize) {
|
|
26
|
+
* const row = await db.uploads.findFirst({ where: { key, fileSize } });
|
|
27
|
+
* return row ? { uploadId: row.uploadId, key, fileSize, bucket: row.bucket } : null;
|
|
28
|
+
* },
|
|
29
|
+
* async set(upload) {
|
|
30
|
+
* await db.uploads.upsert({ where: { key: upload.key }, data: upload });
|
|
31
|
+
* },
|
|
32
|
+
* async delete(key) {
|
|
33
|
+
* await db.uploads.deleteMany({ where: { key } });
|
|
34
|
+
* },
|
|
35
|
+
* };
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export type UploadStore = {
|
|
39
|
+
/**
|
|
40
|
+
* Look up a pending upload by its S3 object key and file size.
|
|
41
|
+
* Returns `null` if no matching upload is found.
|
|
42
|
+
*/
|
|
43
|
+
get: (key: string, fileSize: number) => StoredUpload | null | Promise<StoredUpload | null>;
|
|
44
|
+
/**
|
|
45
|
+
* Persist a new upload state after `CreateMultipartUpload` succeeds.
|
|
46
|
+
* Called once per upload, before any parts are sent.
|
|
47
|
+
*/
|
|
48
|
+
set: (upload: StoredUpload) => void | Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Remove the upload state after the upload completes or is explicitly
|
|
51
|
+
* abandoned. Should be a no-op if the key is not found.
|
|
52
|
+
*/
|
|
53
|
+
delete: (key: string) => void | Promise<void>;
|
|
54
|
+
};
|
package/dist/types/upload.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { UploadStore } from "./upload-store";
|
|
1
2
|
export type UploadResult = {
|
|
2
3
|
key: string;
|
|
3
4
|
url?: string;
|
|
@@ -7,6 +8,8 @@ export type UploadProgress = {
|
|
|
7
8
|
loaded: number;
|
|
8
9
|
total: number;
|
|
9
10
|
percent: number;
|
|
11
|
+
/** Instantaneous transfer speed in bytes/second. `undefined` until measurable. */
|
|
12
|
+
speed?: number;
|
|
10
13
|
};
|
|
11
14
|
export type UploadPhase = "idle" | "validating" | "presigning" | "uploading" | "finalizing" | "success" | "error";
|
|
12
15
|
export type UploadRequestOptions = {
|
|
@@ -24,21 +27,74 @@ export type UploadRequestOptions = {
|
|
|
24
27
|
* Pass `null` to omit Content-Disposition entirely.
|
|
25
28
|
*/
|
|
26
29
|
fileName?: string | null;
|
|
30
|
+
/**
|
|
31
|
+
* Per-upload multipart part size in bytes. Overrides `UploadConfig.partSize`.
|
|
32
|
+
* Minimum 5 MB; ignored for non-multipart uploads.
|
|
33
|
+
*/
|
|
34
|
+
partSize?: number;
|
|
27
35
|
};
|
|
28
36
|
export type UploadHooks = {
|
|
37
|
+
/** Runs before the upload starts. Return `false` to block it. */
|
|
29
38
|
beforeUpload?: (file: File) => Promise<boolean> | boolean;
|
|
39
|
+
/** Fires after validation passes and the upload begins. */
|
|
30
40
|
onUploadStart?: (file: File, key: string) => void;
|
|
41
|
+
/** Fires continuously while bytes are transferred. */
|
|
31
42
|
onProgress?: (file: File, progress: UploadProgress) => void;
|
|
43
|
+
/**
|
|
44
|
+
* Fires after each part is successfully uploaded to S3.
|
|
45
|
+
* Only called during multipart uploads (files above `multipartThreshold`).
|
|
46
|
+
*/
|
|
47
|
+
onPartUpload?: (file: File, partNumber: number, totalParts: number) => void;
|
|
48
|
+
/**
|
|
49
|
+
* Fires once after `CreateMultipartUpload` succeeds.
|
|
50
|
+
* Only called during multipart uploads.
|
|
51
|
+
* Receives the S3-assigned `uploadId` — useful for server-side tracking.
|
|
52
|
+
*/
|
|
53
|
+
onMultipartInit?: (file: File, uploadId: string) => void;
|
|
54
|
+
/** Fires when the upload finishes successfully. */
|
|
32
55
|
onSuccess?: (file: File, result: UploadResult) => Promise<void> | void;
|
|
56
|
+
/** Fires when the upload fails with an unrecoverable error. */
|
|
33
57
|
onError?: (file: File | null, error: unknown, phase: UploadPhase) => void;
|
|
58
|
+
/** Fires when the upload is cancelled via `cancel()`. */
|
|
34
59
|
onCancel?: (file: File | null) => void;
|
|
35
60
|
};
|
|
61
|
+
export type RetryConfig = {
|
|
62
|
+
/** Maximum number of retry attempts per request. @default 3 */
|
|
63
|
+
maxRetries?: number;
|
|
64
|
+
/** Base delay in ms for exponential backoff. @default 1000 */
|
|
65
|
+
baseDelay?: number;
|
|
66
|
+
};
|
|
36
67
|
export type UploadConfig = {
|
|
37
68
|
multipart?: boolean;
|
|
38
69
|
accept?: string[];
|
|
39
70
|
maxFileSize?: number;
|
|
40
71
|
maxFiles?: number;
|
|
41
72
|
multipartThreshold?: number;
|
|
73
|
+
/**
|
|
74
|
+
* Multipart part size in bytes. Minimum 5 MB.
|
|
75
|
+
* Can be overridden per-upload via `UploadRequestOptions.partSize`.
|
|
76
|
+
* @default 5 MB
|
|
77
|
+
*/
|
|
78
|
+
partSize?: number;
|
|
42
79
|
concurrentParts?: number;
|
|
43
80
|
concurrentFiles?: number;
|
|
81
|
+
/** Retry configuration for failed network requests. */
|
|
82
|
+
retry?: RetryConfig;
|
|
83
|
+
/**
|
|
84
|
+
* Store for resumable multipart uploads.
|
|
85
|
+
*
|
|
86
|
+
* - Omit / `undefined` — resumability disabled; abort immediately on cancel or error.
|
|
87
|
+
* - `false` — same as omitting; abort immediately on cancel or error.
|
|
88
|
+
* - Custom `UploadStore` — persist `uploadId` across sessions (localStorage, database, IndexedDB, etc.).
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```ts
|
|
92
|
+
* // Enable localStorage-based resumability
|
|
93
|
+
* useUpload({ api, uploadStore: createLocalStorageStore() });
|
|
94
|
+
*
|
|
95
|
+
* // Custom backend
|
|
96
|
+
* useUpload({ api, uploadStore: myDbStore });
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
uploadStore?: UploadStore | false;
|
|
44
100
|
};
|
|
@@ -2,5 +2,5 @@ export declare const DEFAULT_MULTIPART_THRESHOLD: number;
|
|
|
2
2
|
export declare const DEFAULT_PART_SIZE: number;
|
|
3
3
|
export declare const MAX_RETRIES = 3;
|
|
4
4
|
export declare const RETRY_BASE_DELAY = 1000;
|
|
5
|
-
export declare const DEFAULT_CONCURRENT_PARTS =
|
|
5
|
+
export declare const DEFAULT_CONCURRENT_PARTS = 2;
|
|
6
6
|
export declare const DEFAULT_CONCURRENT_FILES = 2;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import type { UploadProgress, UploadRequestOptions } from "../types";
|
|
2
|
-
import type { S3Api } from "
|
|
3
|
-
|
|
1
|
+
import type { UploadProgress, UploadRequestOptions, RetryConfig } from "../types";
|
|
2
|
+
import type { S3Api } from "../types/s3-api";
|
|
3
|
+
import type { UploadStore } from "../types/upload-store";
|
|
4
|
+
export declare function uploadMultipart(api: S3Api, file: File, objectKey: string, partSize: number, concurrentParts: number, onProgress?: (progress: UploadProgress) => void, signal?: AbortSignal, requestOptions?: UploadRequestOptions, retryConfig?: RetryConfig, uploadStore?: UploadStore | false, onPartUpload?: (partNumber: number, totalParts: number) => void, onMultipartInit?: (uploadId: string, key: string) => void): Promise<string | undefined>;
|
package/dist/upload/retry.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import type { RetryConfig } from "../types";
|
|
2
|
+
export declare function withRetry<T>(fn: () => Promise<T>, retryConfig: RetryConfig | undefined, signal?: AbortSignal): Promise<T>;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import type { UploadConfig, UploadProgress, UploadResult, UploadRequestOptions } from "../types";
|
|
2
|
-
import type { S3Api } from "
|
|
2
|
+
import type { S3Api } from "../types/s3-api";
|
|
3
3
|
export type UploadEngineCallbacks = {
|
|
4
4
|
onProgress?: (progress: UploadProgress) => void;
|
|
5
5
|
/** Called when the upload transitions between internal phases. */
|
|
6
6
|
onPhaseChange?: (phase: "presigning" | "uploading" | "finalizing") => void;
|
|
7
|
+
/** Called after each individual multipart part is successfully uploaded. */
|
|
8
|
+
onPartUpload?: (partNumber: number, totalParts: number) => void;
|
|
9
|
+
/** Called once after `CreateMultipartUpload` succeeds with the S3-assigned `uploadId` and final object `key`. */
|
|
10
|
+
onMultipartInit?: (uploadId: string, key: string) => void;
|
|
7
11
|
};
|
|
8
12
|
export declare function uploadFile(api: S3Api, file: File, objectKey: string, config?: UploadConfig, callbacks?: UploadEngineCallbacks, signal?: AbortSignal, requestOptions?: UploadRequestOptions): Promise<UploadResult>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { UploadConfig, UploadProgress, UploadResult, UploadRequestOptions } from "../types";
|
|
2
|
-
import type { S3Api } from "
|
|
2
|
+
import type { S3Api } from "../types/s3-api";
|
|
3
3
|
export type FileItemStatus = "pending" | "uploading" | "success" | "error";
|
|
4
4
|
export type FileItem = {
|
|
5
5
|
id: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-s3/react",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1046.0",
|
|
4
4
|
"description": "React hooks for S3-compatible file uploads, downloads, and deletes",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"s3",
|
|
@@ -32,9 +32,6 @@
|
|
|
32
32
|
"files": [
|
|
33
33
|
"dist"
|
|
34
34
|
],
|
|
35
|
-
"dependencies": {
|
|
36
|
-
"@better-s3/server": "3.1045.2"
|
|
37
|
-
},
|
|
38
35
|
"peerDependencies": {
|
|
39
36
|
"react": ">=18"
|
|
40
37
|
},
|
package/dist/helpers.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Parses the filename from a `Content-Disposition` header value.
|
|
3
|
-
* Prefers `filename*` (RFC 5987, full Unicode) over `filename`.
|
|
4
|
-
* Returns `fallback` if no filename is found.
|
|
5
|
-
*/
|
|
6
|
-
export declare function parseContentDispositionFilename(header: string | null, fallback: string): string;
|
|
7
|
-
export declare function formatFileSize(bytes: number): string;
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import type { S3Api } from "@better-s3/server";
|
|
2
|
-
export type FetchDownloadPhase = "idle" | "presigning" | "downloading" | "success" | "error";
|
|
3
|
-
export type FetchDownloadProgress = {
|
|
4
|
-
loaded: number;
|
|
5
|
-
total: number;
|
|
6
|
-
percent: number;
|
|
7
|
-
};
|
|
8
|
-
export type FetchDownloadHooks = {
|
|
9
|
-
beforeDownload?: (key: string) => Promise<boolean> | boolean;
|
|
10
|
-
onDownloadStart?: (key: string) => void;
|
|
11
|
-
onProgress?: (key: string, progress: FetchDownloadProgress) => void;
|
|
12
|
-
onSuccess?: (key: string, fileName: string) => Promise<void> | void;
|
|
13
|
-
onError?: (key: string, error: unknown, phase: FetchDownloadPhase) => void;
|
|
14
|
-
onCancel?: (key: string) => void;
|
|
15
|
-
};
|
|
16
|
-
export type UseFetchDownloadOptions = FetchDownloadHooks & {
|
|
17
|
-
api: S3Api;
|
|
18
|
-
/** Target bucket (overrides server default) */
|
|
19
|
-
bucket?: string;
|
|
20
|
-
};
|
|
21
|
-
export type UseFetchDownloadState = {
|
|
22
|
-
phase: FetchDownloadPhase;
|
|
23
|
-
progress: FetchDownloadProgress;
|
|
24
|
-
error: string | null;
|
|
25
|
-
fileName: string | null;
|
|
26
|
-
fileSize: number | null;
|
|
27
|
-
};
|
|
28
|
-
export type UseFetchDownloadReturn = UseFetchDownloadState & {
|
|
29
|
-
download: (key: string, downloadName?: string) => Promise<void>;
|
|
30
|
-
cancel: () => void;
|
|
31
|
-
reset: () => void;
|
|
32
|
-
};
|
|
33
|
-
export declare function useFetchDownload(options: UseFetchDownloadOptions): UseFetchDownloadReturn;
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import type { UploadPhase, UploadProgress, UploadResult, UploadRequestOptions, MultiUploadFileState, MultiUploadPhase } from "./types";
|
|
2
|
-
import type { S3Api } from "@better-s3/server";
|
|
3
|
-
import type { UploadConfig } from "./types";
|
|
4
|
-
export type UseUploadControlsOptions = UploadConfig & {
|
|
5
|
-
api: S3Api;
|
|
6
|
-
objectKey: string | ((file: File) => string);
|
|
7
|
-
/**
|
|
8
|
-
* Maximum number of files. When > 1 the hook switches to multi-upload mode
|
|
9
|
-
* and the native file picker allows selecting multiple files.
|
|
10
|
-
* @default 1
|
|
11
|
-
*/
|
|
12
|
-
maxFiles?: number;
|
|
13
|
-
/** Static request options applied to all files (multi mode) */
|
|
14
|
-
uploadOptions?: UploadRequestOptions;
|
|
15
|
-
/** Per-file request options */
|
|
16
|
-
getUploadOptions?: (file: File) => UploadRequestOptions;
|
|
17
|
-
beforeUpload?: ((file: File) => boolean | Promise<boolean>) | ((files: File[]) => boolean | Promise<boolean>);
|
|
18
|
-
onUploadStart?: ((file: File, key: string) => void) | ((files: File[]) => void);
|
|
19
|
-
onProgress?: ((file: File, progress: UploadProgress) => void) | ((progress: UploadProgress) => void);
|
|
20
|
-
onSuccess?: ((file: File, result: UploadResult) => void | Promise<void>) | ((results: UploadResult[]) => void | Promise<void>);
|
|
21
|
-
onError?: ((file: File | null, error: unknown, phase: UploadPhase) => void) | ((error: unknown) => void);
|
|
22
|
-
onCancel?: ((file: File | null) => void) | (() => void);
|
|
23
|
-
onFileProgress?: (file: File, progress: UploadProgress) => void;
|
|
24
|
-
onFileSuccess?: (file: File, result: UploadResult) => void;
|
|
25
|
-
onFileError?: (file: File, error: string) => void;
|
|
26
|
-
};
|
|
27
|
-
export type UseUploadControlsReturn = {
|
|
28
|
-
/** Whether the hook is in single-file or multi-file mode */
|
|
29
|
-
mode: "single" | "multi";
|
|
30
|
-
phase: UploadPhase | MultiUploadPhase;
|
|
31
|
-
/** Info about the selected file (single mode only) */
|
|
32
|
-
fileInfo: {
|
|
33
|
-
name: string;
|
|
34
|
-
size: number;
|
|
35
|
-
} | null;
|
|
36
|
-
/** Upload progress (single mode) */
|
|
37
|
-
progress: UploadProgress;
|
|
38
|
-
/** Per-file states (multi mode only) */
|
|
39
|
-
files: MultiUploadFileState[];
|
|
40
|
-
/** Aggregated progress across all files (multi mode) */
|
|
41
|
-
totalProgress: UploadProgress;
|
|
42
|
-
error: string | null;
|
|
43
|
-
isUploading: boolean;
|
|
44
|
-
handleFiles: (files: FileList | null) => void;
|
|
45
|
-
openFilePicker: () => void;
|
|
46
|
-
cancel: () => void;
|
|
47
|
-
reset: () => void;
|
|
48
|
-
/** Spread on a hidden `<input>` element */
|
|
49
|
-
inputProps: {
|
|
50
|
-
ref: React.RefObject<HTMLInputElement | null>;
|
|
51
|
-
type: "file";
|
|
52
|
-
multiple?: true;
|
|
53
|
-
accept?: string;
|
|
54
|
-
hidden: true;
|
|
55
|
-
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
56
|
-
};
|
|
57
|
-
/** Spread on a container to enable drag-and-drop */
|
|
58
|
-
dropHandlers: {
|
|
59
|
-
onDragOver: (e: React.DragEvent) => void;
|
|
60
|
-
onDrop: (e: React.DragEvent) => void;
|
|
61
|
-
};
|
|
62
|
-
};
|
|
63
|
-
export declare function useUploadControls(options: UseUploadControlsOptions): UseUploadControlsReturn;
|
package/dist/use-upload.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { S3Api } from "@better-s3/server";
|
|
2
|
-
import type { UploadConfig, UploadHooks, UploadPhase, UploadProgress, UploadResult, UploadRequestOptions } from "./types";
|
|
3
|
-
export type UseUploadOptions = UploadConfig & UploadHooks & {
|
|
4
|
-
api: S3Api;
|
|
5
|
-
};
|
|
6
|
-
export type UseUploadState = {
|
|
7
|
-
phase: UploadPhase;
|
|
8
|
-
progress: UploadProgress;
|
|
9
|
-
error: string | null;
|
|
10
|
-
result: UploadResult | null;
|
|
11
|
-
fileName: string | null;
|
|
12
|
-
fileSize: number | null;
|
|
13
|
-
};
|
|
14
|
-
export type UseUploadReturn = UseUploadState & {
|
|
15
|
-
upload: (file: File, objectKey: string, requestOptions?: UploadRequestOptions) => Promise<void>;
|
|
16
|
-
cancel: () => void;
|
|
17
|
-
reset: () => void;
|
|
18
|
-
};
|
|
19
|
-
export declare function useUpload(options: UseUploadOptions): UseUploadReturn;
|