@muhgholy/next-drive 4.23.8 → 4.23.10
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 +152 -1
- package/dist/{chunk-OU5TKLHV.cjs → chunk-V75PCJHT.cjs} +116 -24
- package/dist/chunk-V75PCJHT.cjs.map +1 -0
- package/dist/{chunk-RBSFEEJJ.js → chunk-XUPDNN2U.js} +115 -25
- package/dist/chunk-XUPDNN2U.js.map +1 -0
- package/dist/client/file-chooser.d.ts +1 -0
- package/dist/client/file-chooser.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 +88 -42
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.js +87 -41
- package/dist/client/index.js.map +1 -1
- package/dist/server/actions/drive.d.ts.map +1 -1
- package/dist/server/config.d.ts.map +1 -1
- package/dist/server/controllers/drive.d.ts +26 -0
- package/dist/server/controllers/drive.d.ts.map +1 -1
- package/dist/server/database/mongoose/schema/drive.d.ts +1 -0
- package/dist/server/database/mongoose/schema/drive.d.ts.map +1 -1
- package/dist/server/express.cjs +11 -11
- package/dist/server/express.js +2 -2
- package/dist/server/hono.cjs +11 -11
- package/dist/server/hono.js +2 -2
- package/dist/server/index.cjs +24 -16
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/zod/schemas.d.ts +5 -0
- package/dist/server/zod/schemas.d.ts.map +1 -1
- package/dist/types/lib/database/drive.d.ts +1 -0
- package/dist/types/lib/database/drive.d.ts.map +1 -1
- package/dist/types/server/config.d.ts +17 -0
- package/dist/types/server/config.d.ts.map +1 -1
- package/package.json +2 -1
- package/dist/chunk-OU5TKLHV.cjs.map +0 -1
- package/dist/chunk-RBSFEEJJ.js.map +0 -1
package/dist/client/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import React3__default, { createContext, useContext, useState, useCallback, useR
|
|
|
5
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
6
|
import { Slot } from '@radix-ui/react-slot';
|
|
7
7
|
import { cva } from 'class-variance-authority';
|
|
8
|
+
import * as ProgressPrimitive from '@radix-ui/react-progress';
|
|
8
9
|
import * as SheetPrimitive from '@radix-ui/react-dialog';
|
|
9
10
|
import { X, ChevronRight, Check, Circle, Loader2, Folder, FolderPlus, Menu, RotateCcw, Trash2, Group, Search, ArrowUpDown, Calendar, ArrowDownAZ, ArrowUpAZ, ArrowDown01, ArrowUp01, LayoutGrid, List, RefreshCw, Upload, CheckCircle2, Cloud, AlertCircle, Pencil, FileText, HardDrive, Database, ChevronsUpDown, Plus, Settings2, Trash, FolderOpen, Clock } from 'lucide-react';
|
|
10
11
|
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
@@ -12,7 +13,6 @@ import * as LabelPrimitive from '@radix-ui/react-label';
|
|
|
12
13
|
import { useForm } from 'react-hook-form';
|
|
13
14
|
import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, pointerWithin, closestCenter, useDroppable } from '@dnd-kit/core';
|
|
14
15
|
import { sortableKeyboardCoordinates, arrayMove, SortableContext, rectSortingStrategy, useSortable } from '@dnd-kit/sortable';
|
|
15
|
-
import * as ProgressPrimitive from '@radix-ui/react-progress';
|
|
16
16
|
import { startOfWeek, subWeeks, isToday, isYesterday, isAfter } from 'date-fns';
|
|
17
17
|
import * as ContextMenuPrimitive from '@radix-ui/react-context-menu';
|
|
18
18
|
import { CSS } from '@dnd-kit/utilities';
|
|
@@ -296,7 +296,7 @@ var getChunkSize = (fileSize) => {
|
|
|
296
296
|
if (fileSize < 1024 * 1024 * 1024) return 8 * 1024 * 1024;
|
|
297
297
|
return 16 * 1024 * 1024;
|
|
298
298
|
};
|
|
299
|
-
var useUpload = (apiEndpoint, activeAccountId, withCredentials = false, onUploadComplete) => {
|
|
299
|
+
var useUpload = (apiEndpoint, activeAccountId, withCredentials = false, onUploadComplete, unauthenticated = false) => {
|
|
300
300
|
const [uploads, setUploads] = useState([]);
|
|
301
301
|
const abortControllers = useRef(/* @__PURE__ */ new Map());
|
|
302
302
|
const filesRef = useRef(/* @__PURE__ */ new Map());
|
|
@@ -380,6 +380,7 @@ var useUpload = (apiEndpoint, activeAccountId, withCredentials = false, onUpload
|
|
|
380
380
|
formData.append("fileType", file.type);
|
|
381
381
|
formData.append("folderId", folderId || "root");
|
|
382
382
|
if (driveId) formData.append("driveId", driveId);
|
|
383
|
+
if (unauthenticated) formData.append("unauthenticated", "true");
|
|
383
384
|
let attempts = 0;
|
|
384
385
|
let success = false;
|
|
385
386
|
while (!success && attempts < 3 && !controller.signal.aborted) {
|
|
@@ -539,6 +540,39 @@ function Button({
|
|
|
539
540
|
}
|
|
540
541
|
);
|
|
541
542
|
}
|
|
543
|
+
function Progress({
|
|
544
|
+
className,
|
|
545
|
+
value,
|
|
546
|
+
indicatorClassName,
|
|
547
|
+
indeterminate = false,
|
|
548
|
+
...props
|
|
549
|
+
}) {
|
|
550
|
+
const isIndeterminate = indeterminate || value === void 0;
|
|
551
|
+
return /* @__PURE__ */ jsx(
|
|
552
|
+
ProgressPrimitive.Root,
|
|
553
|
+
{
|
|
554
|
+
"data-slot": "progress",
|
|
555
|
+
className: cn(
|
|
556
|
+
"nd:bg-primary/20 nd:relative nd:h-2 nd:w-full nd:overflow-hidden nd:rounded-full",
|
|
557
|
+
className
|
|
558
|
+
),
|
|
559
|
+
...props,
|
|
560
|
+
children: /* @__PURE__ */ jsx(
|
|
561
|
+
ProgressPrimitive.Indicator,
|
|
562
|
+
{
|
|
563
|
+
"data-slot": "progress-indicator",
|
|
564
|
+
className: cn(
|
|
565
|
+
"nd:bg-primary nd:h-full nd:flex-1 nd:transition-all",
|
|
566
|
+
isIndeterminate && "nd:w-1/3 nd:animate-[indeterminate_1.5s_ease-in-out_infinite]",
|
|
567
|
+
!isIndeterminate && "nd:w-full",
|
|
568
|
+
indicatorClassName
|
|
569
|
+
),
|
|
570
|
+
style: isIndeterminate ? void 0 : { transform: `translateX(-${100 - (value || 0)}%)` }
|
|
571
|
+
}
|
|
572
|
+
)
|
|
573
|
+
}
|
|
574
|
+
);
|
|
575
|
+
}
|
|
542
576
|
function Dialog2({ ...props }) {
|
|
543
577
|
return /* @__PURE__ */ jsx(SheetPrimitive.Root, { "data-slot": "dialog2", ...props });
|
|
544
578
|
}
|
|
@@ -1362,39 +1396,6 @@ var DriveDndProvider = (props) => {
|
|
|
1362
1396
|
}
|
|
1363
1397
|
) : children });
|
|
1364
1398
|
};
|
|
1365
|
-
function Progress({
|
|
1366
|
-
className,
|
|
1367
|
-
value,
|
|
1368
|
-
indicatorClassName,
|
|
1369
|
-
indeterminate = false,
|
|
1370
|
-
...props
|
|
1371
|
-
}) {
|
|
1372
|
-
const isIndeterminate = indeterminate || value === void 0;
|
|
1373
|
-
return /* @__PURE__ */ jsx(
|
|
1374
|
-
ProgressPrimitive.Root,
|
|
1375
|
-
{
|
|
1376
|
-
"data-slot": "progress",
|
|
1377
|
-
className: cn(
|
|
1378
|
-
"nd:bg-primary/20 nd:relative nd:h-2 nd:w-full nd:overflow-hidden nd:rounded-full",
|
|
1379
|
-
className
|
|
1380
|
-
),
|
|
1381
|
-
...props,
|
|
1382
|
-
children: /* @__PURE__ */ jsx(
|
|
1383
|
-
ProgressPrimitive.Indicator,
|
|
1384
|
-
{
|
|
1385
|
-
"data-slot": "progress-indicator",
|
|
1386
|
-
className: cn(
|
|
1387
|
-
"nd:bg-primary nd:h-full nd:flex-1 nd:transition-all",
|
|
1388
|
-
isIndeterminate && "nd:w-1/3 nd:animate-[indeterminate_1.5s_ease-in-out_infinite]",
|
|
1389
|
-
!isIndeterminate && "nd:w-full",
|
|
1390
|
-
indicatorClassName
|
|
1391
|
-
),
|
|
1392
|
-
style: isIndeterminate ? void 0 : { transform: `translateX(-${100 - (value || 0)}%)` }
|
|
1393
|
-
}
|
|
1394
|
-
)
|
|
1395
|
-
}
|
|
1396
|
-
);
|
|
1397
|
-
}
|
|
1398
1399
|
var ContextMenu = ContextMenuPrimitive.Root;
|
|
1399
1400
|
var ContextMenuTrigger = ContextMenuPrimitive.Trigger;
|
|
1400
1401
|
var ContextMenuSubTrigger = React3.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
@@ -3100,11 +3101,46 @@ var DriveFileChooser = (props) => {
|
|
|
3100
3101
|
className,
|
|
3101
3102
|
disabled = false,
|
|
3102
3103
|
error,
|
|
3103
|
-
helperText
|
|
3104
|
+
helperText,
|
|
3105
|
+
allowUnauthenticated = false
|
|
3104
3106
|
} = props;
|
|
3105
|
-
const { items, selectedFileIds, setSelectedFileIds, createUrl, triggerFetch } = useDrive();
|
|
3107
|
+
const { items, selectedFileIds, setSelectedFileIds, createUrl, triggerFetch, apiEndpoint, activeAccountId, withCredentials, callAPI } = useDrive();
|
|
3106
3108
|
useStyleInjector();
|
|
3107
3109
|
const [isOpen, setIsOpen] = useState(false);
|
|
3110
|
+
const fileInputRef = useRef(null);
|
|
3111
|
+
const valueRef = useRef(value);
|
|
3112
|
+
valueRef.current = value;
|
|
3113
|
+
const [authed, setAuthed] = useState(allowUnauthenticated ? null : true);
|
|
3114
|
+
useEffect(() => {
|
|
3115
|
+
if (!allowUnauthenticated) return;
|
|
3116
|
+
callAPI("information").then((res) => setAuthed(res.status === 200 ? !!res.data?.authenticated : false));
|
|
3117
|
+
}, [allowUnauthenticated, callAPI]);
|
|
3118
|
+
const unauthenticatedMode = allowUnauthenticated && authed === false;
|
|
3119
|
+
const handleUploaded = useCallback((item) => {
|
|
3120
|
+
const isFile = item?.information?.type === "FILE";
|
|
3121
|
+
const uploaded = {
|
|
3122
|
+
id: item.id,
|
|
3123
|
+
file: { name: item.name, mime: isFile ? item.information.mime : "", size: isFile ? item.information.sizeInBytes : 0 }
|
|
3124
|
+
};
|
|
3125
|
+
const current = valueRef.current;
|
|
3126
|
+
if (multiple) {
|
|
3127
|
+
const arr = Array.isArray(current) ? current : current ? [current] : [];
|
|
3128
|
+
onChange([...arr, uploaded]);
|
|
3129
|
+
} else {
|
|
3130
|
+
onChange(uploaded);
|
|
3131
|
+
}
|
|
3132
|
+
}, [multiple, onChange]);
|
|
3133
|
+
const { uploads, uploadFiles } = useUpload(apiEndpoint, activeAccountId, withCredentials, handleUploaded, unauthenticatedMode);
|
|
3134
|
+
const openPicker = useCallback(() => {
|
|
3135
|
+
if (unauthenticatedMode) fileInputRef.current?.click();
|
|
3136
|
+
else setIsOpen(true);
|
|
3137
|
+
}, [unauthenticatedMode]);
|
|
3138
|
+
const handleFilePick = useCallback((e) => {
|
|
3139
|
+
const picked = Array.from(e.target.files ?? []);
|
|
3140
|
+
if (picked.length) uploadFiles(multiple ? picked : [picked[0]], null);
|
|
3141
|
+
e.target.value = "";
|
|
3142
|
+
}, [uploadFiles, multiple]);
|
|
3143
|
+
const activeUploads = unauthenticatedMode ? uploads.filter((u) => ["queued", "uploading", "error"].includes(u.status)) : [];
|
|
3108
3144
|
useEffect(() => {
|
|
3109
3145
|
if (isOpen) {
|
|
3110
3146
|
triggerFetch();
|
|
@@ -3138,8 +3174,8 @@ var DriveFileChooser = (props) => {
|
|
|
3138
3174
|
{
|
|
3139
3175
|
type: "button",
|
|
3140
3176
|
variant: "outline",
|
|
3141
|
-
onClick:
|
|
3142
|
-
disabled,
|
|
3177
|
+
onClick: openPicker,
|
|
3178
|
+
disabled: disabled || allowUnauthenticated && authed === null,
|
|
3143
3179
|
className: cn(
|
|
3144
3180
|
"nd:w-full nd:h-auto nd:justify-start nd:gap-3 nd:px-3 nd:py-2.5 nd:border-dashed",
|
|
3145
3181
|
error && "nd:border-destructive"
|
|
@@ -3168,7 +3204,7 @@ var DriveFileChooser = (props) => {
|
|
|
3168
3204
|
] })
|
|
3169
3205
|
] }),
|
|
3170
3206
|
/* @__PURE__ */ jsxs("div", { className: "nd:flex nd:items-center nd:gap-1 nd:shrink-0", children: [
|
|
3171
|
-
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick:
|
|
3207
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: openPicker, disabled, children: "Change" }),
|
|
3172
3208
|
!disabled && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon", className: "nd:size-8", onClick: () => handleRemove(displayFiles[0].id), children: /* @__PURE__ */ jsx(X, { className: "nd:size-4" }) })
|
|
3173
3209
|
] })
|
|
3174
3210
|
] }),
|
|
@@ -3181,7 +3217,7 @@ var DriveFileChooser = (props) => {
|
|
|
3181
3217
|
" selected"
|
|
3182
3218
|
] }),
|
|
3183
3219
|
/* @__PURE__ */ jsxs("div", { className: "nd:flex nd:items-center nd:gap-1", children: [
|
|
3184
|
-
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "nd:h-7 nd:text-xs", onClick:
|
|
3220
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "nd:h-7 nd:text-xs", onClick: openPicker, disabled, children: "Add more" }),
|
|
3185
3221
|
!disabled && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "nd:h-7 nd:text-xs nd:text-muted-foreground", onClick: () => onChange([]), children: "Clear" })
|
|
3186
3222
|
] })
|
|
3187
3223
|
] }),
|
|
@@ -3200,6 +3236,16 @@ var DriveFileChooser = (props) => {
|
|
|
3200
3236
|
] })
|
|
3201
3237
|
),
|
|
3202
3238
|
error && helperText && /* @__PURE__ */ jsx("p", { className: "nd:text-xs nd:text-destructive nd:mt-1.5", children: helperText }),
|
|
3239
|
+
unauthenticatedMode && /* @__PURE__ */ jsx("input", { ref: fileInputRef, type: "file", accept, multiple, className: "nd:hidden", onChange: handleFilePick }),
|
|
3240
|
+
activeUploads.length > 0 && /* @__PURE__ */ jsx("div", { className: "nd:mt-2 nd:space-y-2", children: activeUploads.map((u) => /* @__PURE__ */ jsxs("div", { className: "nd:rounded-lg nd:border nd:px-3 nd:py-2", children: [
|
|
3241
|
+
/* @__PURE__ */ jsxs("div", { className: "nd:flex nd:items-center nd:gap-2", children: [
|
|
3242
|
+
u.status === "error" ? /* @__PURE__ */ jsx(X, { className: "nd:size-4 nd:text-destructive nd:shrink-0" }) : /* @__PURE__ */ jsx(Loader2, { className: "nd:size-4 nd:animate-spin nd:text-muted-foreground nd:shrink-0" }),
|
|
3243
|
+
/* @__PURE__ */ jsx("span", { className: "nd:text-sm nd:truncate nd:flex-1", children: u.name }),
|
|
3244
|
+
/* @__PURE__ */ jsx("span", { className: "nd:text-xs nd:text-muted-foreground nd:shrink-0", children: u.status === "error" ? "Failed" : `${Math.round(u.currentChunk / Math.max(1, u.totalChunks) * 100)}%` })
|
|
3245
|
+
] }),
|
|
3246
|
+
u.status !== "error" && /* @__PURE__ */ jsx(Progress, { value: Math.round(u.currentChunk / Math.max(1, u.totalChunks) * 100), className: "nd:mt-1.5" }),
|
|
3247
|
+
u.status === "error" && u.error && /* @__PURE__ */ jsx("p", { className: "nd:text-xs nd:text-destructive nd:mt-1", children: u.error })
|
|
3248
|
+
] }, u.id)) }),
|
|
3203
3249
|
/* @__PURE__ */ jsx(Dialog2, { open: isOpen, onOpenChange: setIsOpen, children: /* @__PURE__ */ jsxs(Dialog2Content, { showCloseButton: false, className: "nd-drive-root", children: [
|
|
3204
3250
|
/* @__PURE__ */ jsxs(Dialog2Header, { className: "nd:gap-2", children: [
|
|
3205
3251
|
/* @__PURE__ */ jsx(MobileSidebarSheet, {}),
|