@muhgholy/next-drive 4.23.14 → 4.23.19
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/README.md +81 -0
- package/dist/client/components/drive/upload.d.ts.map +1 -1
- package/dist/client/hooks/use-upload.d.ts +1 -1
- package/dist/client/hooks/use-upload.d.ts.map +1 -1
- package/dist/client/index.cjs +284 -122
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +283 -123
- package/dist/client/index.js.map +1 -1
- package/dist/client/upload.d.ts +18 -0
- package/dist/client/upload.d.ts.map +1 -0
- package/dist/server/zod/schemas.d.ts +6 -6
- package/dist/types/client/index.d.ts +62 -0
- package/dist/types/client/index.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -193,6 +193,87 @@ function MyForm() {
|
|
|
193
193
|
|
|
194
194
|
---
|
|
195
195
|
|
|
196
|
+
## Headless Uploads
|
|
197
|
+
|
|
198
|
+
Need to build your own upload UI? Use the framework-agnostic `uploadFile` / `uploadFiles` functions. They run the same chunked, retrying upload engine that powers the built-in components — without any React or UI — so you control the markup, loading states, and cancel buttons.
|
|
199
|
+
|
|
200
|
+
Capabilities:
|
|
201
|
+
|
|
202
|
+
- 📈 **Byte-level progress** – smooth percentage, even for small single-chunk files
|
|
203
|
+
- 🪵 **Logs** – the same per-step log stream shown by `DriveFileChooser`
|
|
204
|
+
- ✋ **Cancellation** – every call returns a `cancel()` function
|
|
205
|
+
- 🔓 **Anonymous** – just omit `accountId` (works with `unauthenticated` server config)
|
|
206
|
+
- 📦 **Consistent result** – returns a normalized `TDriveFile` on completion
|
|
207
|
+
|
|
208
|
+
### Single File
|
|
209
|
+
|
|
210
|
+
```tsx
|
|
211
|
+
import { uploadFile } from "@muhgholy/next-drive/client";
|
|
212
|
+
|
|
213
|
+
const { id, promise, cancel } = uploadFile({
|
|
214
|
+
apiEndpoint: "/api/drive",
|
|
215
|
+
file, // a File from an <input type="file" />
|
|
216
|
+
folderId: null, // optional: target folder id (defaults to root)
|
|
217
|
+
accountId: null, // optional: omit/null = anonymous upload
|
|
218
|
+
withCredentials: false, // optional: send cookies cross-origin
|
|
219
|
+
onProgress: ({ percent, uploadedBytes, totalBytes }) => {
|
|
220
|
+
setProgress(percent); // 0–100
|
|
221
|
+
},
|
|
222
|
+
onLog: ({ type, message, timestamp }) => {
|
|
223
|
+
console.log(`[${type}] ${message}`);
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// Call cancel() any time to abort (e.g. a Cancel button)
|
|
228
|
+
// <button onClick={cancel}>Cancel</button>
|
|
229
|
+
|
|
230
|
+
const result = await promise;
|
|
231
|
+
if (result.status === "complete") {
|
|
232
|
+
result.file; // TDriveFile — same shape as DriveFileChooser's onChange
|
|
233
|
+
result.driveId; // server drive item id
|
|
234
|
+
result.item; // raw item (signed URL, full metadata, etc.)
|
|
235
|
+
} else if (result.status === "cancelled") {
|
|
236
|
+
// upload was aborted
|
|
237
|
+
} else {
|
|
238
|
+
result.error; // failure message
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Multiple Files (with concurrency)
|
|
243
|
+
|
|
244
|
+
```tsx
|
|
245
|
+
import { uploadFiles } from "@muhgholy/next-drive/client";
|
|
246
|
+
|
|
247
|
+
const { uploads, cancelAll, promise } = uploadFiles(files, {
|
|
248
|
+
apiEndpoint: "/api/drive",
|
|
249
|
+
concurrency: 2, // optional: max parallel uploads (default 2)
|
|
250
|
+
onProgress: ({ id, percent }) => updateRow(id, percent),
|
|
251
|
+
onFileComplete: (result) => {
|
|
252
|
+
if (result.status === "complete") addFile(result.file);
|
|
253
|
+
},
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// uploads: one handle per file — each has its own { id, promise, cancel }
|
|
257
|
+
// cancelAll(): abort everything
|
|
258
|
+
|
|
259
|
+
const results = await promise; // resolves once all files settle
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Result Type
|
|
263
|
+
|
|
264
|
+
The result is a discriminated union (no optional fields — narrow by `status`):
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
type TDriveUploadResult =
|
|
268
|
+
| { id: string; status: "complete"; driveId: string; file: TDriveFile; item: unknown }
|
|
269
|
+
| { id: string; status: "cancelled"; driveId: string | null }
|
|
270
|
+
| { id: string; status: "error"; driveId: string | null; error: string };
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
> Prefer React state management? The `useUpload` hook wraps the same engine and exposes a reactive `uploads` array — see the source for `DriveUpload` for a reference implementation.
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
196
277
|
## Express Integration
|
|
197
278
|
|
|
198
279
|
Use the Express adapter instead of Next.js API routes:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../../src/client/components/drive/upload.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAwC,MAAM,OAAO,CAAC;AA8G7D,eAAO,MAAM,WAAW,GAAI,OAAO,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../../src/client/components/drive/upload.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAwC,MAAM,OAAO,CAAC;AA8G7D,eAAO,MAAM,WAAW,GAAI,OAAO,QAAQ,CAAC;IACvC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC,sBAoQD,CAAC"}
|
|
@@ -2,7 +2,7 @@ import type { TDriveUploadState } from '../../types/client';
|
|
|
2
2
|
export declare const useUpload: (apiEndpoint: string, activeAccountId: string | null, withCredentials?: boolean, onUploadComplete?: (item: unknown) => void) => {
|
|
3
3
|
uploads: TDriveUploadState[];
|
|
4
4
|
uploadFiles: (files: File[], folderId: string | null) => Promise<void>;
|
|
5
|
-
cancelUpload: (id: string) =>
|
|
5
|
+
cancelUpload: (id: string) => void;
|
|
6
6
|
cancelAllUploads: () => Promise<void>;
|
|
7
7
|
};
|
|
8
8
|
//# sourceMappingURL=use-upload.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-upload.d.ts","sourceRoot":"","sources":["../../../src/client/hooks/use-upload.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"use-upload.d.ts","sourceRoot":"","sources":["../../../src/client/hooks/use-upload.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAMxD,eAAO,MAAM,SAAS,GAAI,aAAa,MAAM,EAAE,iBAAiB,MAAM,GAAG,IAAI,EAAE,kBAAiB,OAAe,EAAE,mBAAmB,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI;;yBA0DzG,IAAI,EAAE,YAAY,MAAM,GAAG,IAAI;uBAsBpE,MAAM;;CA6BlB,CAAC"}
|