@muhgholy/next-drive 4.23.8 → 4.23.11

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.
Files changed (37) hide show
  1. package/README.md +152 -1
  2. package/dist/{chunk-RBSFEEJJ.js → chunk-26KZWPCF.js} +131 -25
  3. package/dist/chunk-26KZWPCF.js.map +1 -0
  4. package/dist/{chunk-OU5TKLHV.cjs → chunk-NDHVF2IB.cjs} +132 -24
  5. package/dist/chunk-NDHVF2IB.cjs.map +1 -0
  6. package/dist/client/file-chooser.d.ts +1 -0
  7. package/dist/client/file-chooser.d.ts.map +1 -1
  8. package/dist/client/hooks/use-upload.d.ts +1 -1
  9. package/dist/client/hooks/use-upload.d.ts.map +1 -1
  10. package/dist/client/index.cjs +88 -42
  11. package/dist/client/index.cjs.map +1 -1
  12. package/dist/client/index.js +87 -41
  13. package/dist/client/index.js.map +1 -1
  14. package/dist/server/actions/drive.d.ts +1 -0
  15. package/dist/server/actions/drive.d.ts.map +1 -1
  16. package/dist/server/config.d.ts.map +1 -1
  17. package/dist/server/controllers/drive.d.ts +26 -0
  18. package/dist/server/controllers/drive.d.ts.map +1 -1
  19. package/dist/server/database/mongoose/schema/drive.d.ts +1 -0
  20. package/dist/server/database/mongoose/schema/drive.d.ts.map +1 -1
  21. package/dist/server/express.cjs +11 -11
  22. package/dist/server/express.js +2 -2
  23. package/dist/server/hono.cjs +11 -11
  24. package/dist/server/hono.js +2 -2
  25. package/dist/server/index.cjs +24 -16
  26. package/dist/server/index.d.ts +1 -1
  27. package/dist/server/index.d.ts.map +1 -1
  28. package/dist/server/index.js +1 -1
  29. package/dist/server/zod/schemas.d.ts +5 -0
  30. package/dist/server/zod/schemas.d.ts.map +1 -1
  31. package/dist/types/lib/database/drive.d.ts +1 -0
  32. package/dist/types/lib/database/drive.d.ts.map +1 -1
  33. package/dist/types/server/config.d.ts +17 -0
  34. package/dist/types/server/config.d.ts.map +1 -1
  35. package/package.json +2 -1
  36. package/dist/chunk-OU5TKLHV.cjs.map +0 -1
  37. package/dist/chunk-RBSFEEJJ.js.map +0 -1
@@ -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: () => setIsOpen(true),
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: () => setIsOpen(true), disabled, children: "Change" }),
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: () => setIsOpen(true), disabled, children: "Add more" }),
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, {}),