@muhgholy/next-drive 1.3.0 → 1.4.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/README.md +107 -59
- package/dist/client/components/dialog.d.ts +21 -0
- package/dist/client/components/dialog.d.ts.map +1 -0
- package/dist/client/components/drive/explorer.d.ts +10 -0
- package/dist/client/components/drive/explorer.d.ts.map +1 -0
- package/dist/client/components/drive/header.d.ts +3 -0
- package/dist/client/components/drive/header.d.ts.map +1 -0
- package/dist/client/components/drive/path-bar.d.ts +3 -0
- package/dist/client/components/drive/path-bar.d.ts.map +1 -0
- package/dist/client/components/drive/sidebar.d.ts +3 -0
- package/dist/client/components/drive/sidebar.d.ts.map +1 -0
- package/dist/client/components/drive/storage/indicator.d.ts +6 -0
- package/dist/client/components/drive/storage/indicator.d.ts.map +1 -0
- package/dist/client/components/drive/upload.d.ts +6 -0
- package/dist/client/components/drive/upload.d.ts.map +1 -0
- package/dist/client/components/ui/alert-dialog.d.ts +21 -0
- package/dist/client/components/ui/alert-dialog.d.ts.map +1 -0
- package/dist/client/components/ui/alert.d.ts +10 -0
- package/dist/client/components/ui/alert.d.ts.map +1 -0
- package/dist/client/components/ui/button.d.ts +11 -0
- package/dist/client/components/ui/button.d.ts.map +1 -0
- package/dist/client/components/ui/context-menu.d.ts +28 -0
- package/dist/client/components/ui/context-menu.d.ts.map +1 -0
- package/dist/client/components/ui/dialog.d.ts +16 -0
- package/dist/client/components/ui/dialog.d.ts.map +1 -0
- package/dist/client/components/ui/dropdown-menu.d.ts +28 -0
- package/dist/client/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/client/components/ui/input.d.ts +4 -0
- package/dist/client/components/ui/input.d.ts.map +1 -0
- package/dist/client/components/ui/label.d.ts +5 -0
- package/dist/client/components/ui/label.d.ts.map +1 -0
- package/dist/client/components/ui/progress.d.ts +7 -0
- package/dist/client/components/ui/progress.d.ts.map +1 -0
- package/dist/client/components/ui/separator.d.ts +5 -0
- package/dist/client/components/ui/separator.d.ts.map +1 -0
- package/dist/client/components/ui/sheet.d.ts +26 -0
- package/dist/client/components/ui/sheet.d.ts.map +1 -0
- package/dist/client/components/ui/tooltip.d.ts +8 -0
- package/dist/client/components/ui/tooltip.d.ts.map +1 -0
- package/dist/client/context.d.ts +87 -0
- package/dist/client/context.d.ts.map +1 -0
- package/dist/client/file-chooser.d.ts +14 -0
- package/dist/client/file-chooser.d.ts.map +1 -0
- package/dist/client/hooks/useUpload.d.ts +8 -0
- package/dist/client/hooks/useUpload.d.ts.map +1 -0
- package/dist/client/index.d.ts +13 -133
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +401 -602
- package/dist/client/index.js.map +1 -1
- package/dist/client/utils.d.ts +16 -0
- package/dist/client/utils.d.ts.map +1 -0
- package/dist/schemas.d.ts +3 -5
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +5 -4
- package/dist/schemas.js.map +1 -1
- package/dist/server/config.d.ts +6 -0
- package/dist/server/config.d.ts.map +1 -0
- package/dist/server/controllers/drive.d.ts +55 -0
- package/dist/server/controllers/drive.d.ts.map +1 -0
- package/dist/server/database/mongoose/schema/drive.d.ts +19 -0
- package/dist/server/database/mongoose/schema/drive.d.ts.map +1 -0
- package/dist/server/database/mongoose/schema/storage/account.d.ts +12 -0
- package/dist/server/database/mongoose/schema/storage/account.d.ts.map +1 -0
- package/dist/server/express.d.ts +10 -0
- package/dist/server/express.d.ts.map +1 -0
- package/dist/server/express.js +1384 -0
- package/dist/server/express.js.map +1 -0
- package/dist/server/index.d.ts +10 -156
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +68 -110
- package/dist/server/index.js.map +1 -1
- package/dist/server/providers/google.d.ts +3 -0
- package/dist/server/providers/google.d.ts.map +1 -0
- package/dist/server/providers/local.d.ts +3 -0
- package/dist/server/providers/local.d.ts.map +1 -0
- package/dist/server/security/cryptoUtils.d.ts +13 -0
- package/dist/server/security/cryptoUtils.d.ts.map +1 -0
- package/dist/server/security/mimeFilter.d.ts +6 -0
- package/dist/server/security/mimeFilter.d.ts.map +1 -0
- package/dist/server/utils/ffmpeg.d.ts +14 -0
- package/dist/server/utils/ffmpeg.d.ts.map +1 -0
- package/dist/server/utils/folderValidation.d.ts +9 -0
- package/dist/server/utils/folderValidation.d.ts.map +1 -0
- package/dist/server/utils/imageConvert.d.ts +15 -0
- package/dist/server/utils/imageConvert.d.ts.map +1 -0
- package/dist/server/utils/metadata.d.ts +23 -0
- package/dist/server/utils/metadata.d.ts.map +1 -0
- package/dist/server/utils.d.ts +14 -0
- package/dist/server/utils.d.ts.map +1 -0
- package/dist/server/zod/schemas.d.ts +207 -0
- package/dist/server/zod/schemas.d.ts.map +1 -0
- package/dist/types/client/index.d.ts +32 -0
- package/dist/types/client/index.d.ts.map +1 -0
- package/dist/types/lib/database/drive.d.ts +41 -0
- package/dist/types/lib/database/drive.d.ts.map +1 -0
- package/dist/types/lib/database/index.d.ts +3 -0
- package/dist/types/lib/database/index.d.ts.map +1 -0
- package/dist/types/lib/database/storage/account.d.ts +15 -0
- package/dist/types/lib/database/storage/account.d.ts.map +1 -0
- package/dist/types/server/api.d.ts +16 -0
- package/dist/types/server/api.d.ts.map +1 -0
- package/dist/types/server/config.d.ts +41 -0
- package/dist/types/server/config.d.ts.map +1 -0
- package/dist/types/server/drive.d.ts +2 -0
- package/dist/types/server/drive.d.ts.map +1 -0
- package/dist/types/server/express.d.ts +37 -0
- package/dist/types/server/express.d.ts.map +1 -0
- package/dist/types/server/index.d.ts +4 -0
- package/dist/types/server/index.d.ts.map +1 -0
- package/dist/types/server/storage.d.ts +29 -0
- package/dist/types/server/storage.d.ts.map +1 -0
- package/package.json +102 -96
- package/dist/index-CUS76o75.d.ts +0 -90
package/dist/server/index.js
CHANGED
|
@@ -1,20 +1,26 @@
|
|
|
1
|
+
import formidable from 'formidable';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs2 from 'fs';
|
|
4
|
+
import mongoose2, { Schema, isValidObjectId } from 'mongoose';
|
|
5
|
+
import crypto2 from 'crypto';
|
|
6
|
+
import sharp from 'sharp';
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
import ffmpeg from 'fluent-ffmpeg';
|
|
9
|
+
import { google } from 'googleapis';
|
|
10
|
+
import 'clsx';
|
|
11
|
+
import 'tailwind-merge';
|
|
12
|
+
import 'lucide-react';
|
|
13
|
+
import 'react/jsx-runtime';
|
|
14
|
+
|
|
1
15
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
16
|
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
17
|
}) : x)(function(x) {
|
|
4
18
|
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
19
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
20
|
});
|
|
7
|
-
|
|
8
|
-
// src/server/index.ts
|
|
9
|
-
import formidable from "formidable";
|
|
10
|
-
import path4 from "path";
|
|
11
|
-
import fs5 from "fs";
|
|
12
|
-
|
|
13
|
-
// src/server/config.ts
|
|
14
|
-
import mongoose from "mongoose";
|
|
15
21
|
var globalConfig = null;
|
|
16
22
|
var driveConfiguration = (config) => {
|
|
17
|
-
if (
|
|
23
|
+
if (mongoose2.connection.readyState !== 1) {
|
|
18
24
|
throw new Error("Database not connected. Please connect to Mongoose before initializing next-drive.");
|
|
19
25
|
}
|
|
20
26
|
const mergedConfig = {
|
|
@@ -45,9 +51,6 @@ var getDriveInformation = async (req) => {
|
|
|
45
51
|
const config = getDriveConfig();
|
|
46
52
|
return config.information(req);
|
|
47
53
|
};
|
|
48
|
-
|
|
49
|
-
// src/server/database/mongoose/schema/drive.ts
|
|
50
|
-
import mongoose2, { Schema } from "mongoose";
|
|
51
54
|
var informationSchema = new Schema({
|
|
52
55
|
type: { type: String, enum: ["FILE", "FOLDER"], required: true },
|
|
53
56
|
sizeInBytes: { type: Number, default: 0 },
|
|
@@ -102,18 +105,15 @@ DriveSchema.method("toClient", async function() {
|
|
|
102
105
|
});
|
|
103
106
|
var Drive = mongoose2.models.Drive || mongoose2.model("Drive", DriveSchema);
|
|
104
107
|
var drive_default = Drive;
|
|
105
|
-
|
|
106
|
-
// src/server/database/mongoose/schema/storage/account.ts
|
|
107
|
-
import mongoose3, { Schema as Schema2 } from "mongoose";
|
|
108
|
-
var StorageAccountSchema = new Schema2(
|
|
108
|
+
var StorageAccountSchema = new Schema(
|
|
109
109
|
{
|
|
110
|
-
owner: { type:
|
|
110
|
+
owner: { type: Schema.Types.Mixed, default: null },
|
|
111
111
|
name: { type: String, required: true },
|
|
112
112
|
metadata: {
|
|
113
113
|
provider: { type: String, enum: ["GOOGLE"], required: true },
|
|
114
114
|
google: {
|
|
115
115
|
email: { type: String, required: true },
|
|
116
|
-
credentials: { type:
|
|
116
|
+
credentials: { type: Schema.Types.Mixed, required: true }
|
|
117
117
|
}
|
|
118
118
|
},
|
|
119
119
|
createdAt: { type: Date, default: Date.now }
|
|
@@ -132,13 +132,8 @@ StorageAccountSchema.method("toClient", async function() {
|
|
|
132
132
|
createdAt: data.createdAt
|
|
133
133
|
};
|
|
134
134
|
});
|
|
135
|
-
var StorageAccount =
|
|
135
|
+
var StorageAccount = mongoose2.models.StorageAccount || mongoose2.model("StorageAccount", StorageAccountSchema);
|
|
136
136
|
var account_default = StorageAccount;
|
|
137
|
-
|
|
138
|
-
// src/server/utils.ts
|
|
139
|
-
import fs from "fs";
|
|
140
|
-
import crypto2 from "crypto";
|
|
141
|
-
import sharp from "sharp";
|
|
142
137
|
var validateMimeType = (mime, allowedTypes) => {
|
|
143
138
|
if (allowedTypes.includes("*/*")) return true;
|
|
144
139
|
return allowedTypes.some((pattern) => {
|
|
@@ -152,7 +147,7 @@ var validateMimeType = (mime, allowedTypes) => {
|
|
|
152
147
|
};
|
|
153
148
|
var computeFileHash = (filePath) => new Promise((resolve, reject) => {
|
|
154
149
|
const hash = crypto2.createHash("sha256");
|
|
155
|
-
const stream =
|
|
150
|
+
const stream = fs2.createReadStream(filePath);
|
|
156
151
|
stream.on("data", (data) => hash.update(data));
|
|
157
152
|
stream.on("end", () => resolve(hash.digest("hex")));
|
|
158
153
|
stream.on("error", reject);
|
|
@@ -165,10 +160,6 @@ var extractImageMetadata = async (filePath) => {
|
|
|
165
160
|
return null;
|
|
166
161
|
}
|
|
167
162
|
};
|
|
168
|
-
|
|
169
|
-
// src/server/zod/schemas.ts
|
|
170
|
-
import { z } from "zod";
|
|
171
|
-
import { isValidObjectId } from "mongoose";
|
|
172
163
|
var objectIdSchema = z.string().refine((val) => isValidObjectId(val), {
|
|
173
164
|
message: "Invalid ObjectId format"
|
|
174
165
|
});
|
|
@@ -216,7 +207,7 @@ var renameBodySchema = z.object({
|
|
|
216
207
|
var deleteQuerySchema = z.object({
|
|
217
208
|
id: objectIdSchema
|
|
218
209
|
});
|
|
219
|
-
|
|
210
|
+
z.object({
|
|
220
211
|
ids: z.array(objectIdSchema).min(1).max(1e3)
|
|
221
212
|
});
|
|
222
213
|
var createFolderBodySchema = z.object({
|
|
@@ -227,7 +218,7 @@ var moveBodySchema = z.object({
|
|
|
227
218
|
ids: z.array(objectIdSchema).min(1).max(1e3),
|
|
228
219
|
targetFolderId: z.union([z.literal("root"), objectIdSchema, z.undefined()]).optional()
|
|
229
220
|
});
|
|
230
|
-
|
|
221
|
+
z.object({
|
|
231
222
|
ids: z.array(objectIdSchema).min(1).max(1e3)
|
|
232
223
|
});
|
|
233
224
|
var searchQuerySchema = z.object({
|
|
@@ -239,13 +230,13 @@ var searchQuerySchema = z.object({
|
|
|
239
230
|
}),
|
|
240
231
|
trashed: z.string().optional().transform((val) => val === "true")
|
|
241
232
|
});
|
|
242
|
-
|
|
233
|
+
z.object({
|
|
243
234
|
id: objectIdSchema
|
|
244
235
|
});
|
|
245
|
-
|
|
236
|
+
z.object({
|
|
246
237
|
id: objectIdSchema
|
|
247
238
|
});
|
|
248
|
-
|
|
239
|
+
z.object({
|
|
249
240
|
days: z.number().int().min(1).max(365).optional()
|
|
250
241
|
});
|
|
251
242
|
var driveFileSchemaZod = z.object({
|
|
@@ -262,13 +253,6 @@ function sanitizeContentDispositionFilename(filename) {
|
|
|
262
253
|
const basename = filename.replace(/^.*[\\\/]/, "");
|
|
263
254
|
return basename.replace(/["\r\n]/g, "").replace(/[^\x20-\x7E]/g, "").slice(0, 255);
|
|
264
255
|
}
|
|
265
|
-
|
|
266
|
-
// src/server/providers/local.ts
|
|
267
|
-
import fs2 from "fs";
|
|
268
|
-
import path from "path";
|
|
269
|
-
import mongoose4 from "mongoose";
|
|
270
|
-
import ffmpeg from "fluent-ffmpeg";
|
|
271
|
-
import sharp2 from "sharp";
|
|
272
256
|
var STORAGE_PATH = path.join(process.cwd(), "storage");
|
|
273
257
|
var LocalStorageProvider = {
|
|
274
258
|
name: "LOCAL",
|
|
@@ -282,7 +266,7 @@ var LocalStorageProvider = {
|
|
|
282
266
|
{ $group: { _id: null, total: { $sum: "$information.sizeInBytes" } } }
|
|
283
267
|
]);
|
|
284
268
|
const usedInBytes = result[0]?.total || 0;
|
|
285
|
-
|
|
269
|
+
getDriveConfig();
|
|
286
270
|
return { usedInBytes, quotaInBytes: 10 * 1024 * 1024 * 1024 };
|
|
287
271
|
},
|
|
288
272
|
openStream: async (item, accountId) => {
|
|
@@ -309,7 +293,7 @@ var LocalStorageProvider = {
|
|
|
309
293
|
}
|
|
310
294
|
if (!fs2.existsSync(path.dirname(thumbPath))) fs2.mkdirSync(path.dirname(thumbPath), { recursive: true });
|
|
311
295
|
if (item.information.mime.startsWith("image/")) {
|
|
312
|
-
await
|
|
296
|
+
await sharp(originalPath).resize(300, 300, { fit: "inside" }).toFormat("webp", { quality: 80 }).toFile(thumbPath);
|
|
313
297
|
} else if (item.information.mime.startsWith("video/")) {
|
|
314
298
|
await new Promise((resolve, reject) => {
|
|
315
299
|
ffmpeg(originalPath).screenshots({
|
|
@@ -400,21 +384,15 @@ var LocalStorageProvider = {
|
|
|
400
384
|
move: async (id, newParentId, owner, accountId) => {
|
|
401
385
|
const item = await drive_default.findOne({ _id: id, owner });
|
|
402
386
|
if (!item) throw new Error("Item not found");
|
|
403
|
-
|
|
404
|
-
item.parentId = newParentId === "root" || !newParentId ? null : new
|
|
387
|
+
item.parentId;
|
|
388
|
+
item.parentId = newParentId === "root" || !newParentId ? null : new mongoose2.Types.ObjectId(newParentId);
|
|
405
389
|
await item.save();
|
|
406
390
|
return item.toClient();
|
|
407
391
|
},
|
|
408
392
|
revokeToken: async (owner, accountId) => {
|
|
409
393
|
}
|
|
410
394
|
};
|
|
411
|
-
|
|
412
|
-
// src/server/providers/google.ts
|
|
413
|
-
import fs3 from "fs";
|
|
414
|
-
import path2 from "path";
|
|
415
|
-
import { google } from "googleapis";
|
|
416
|
-
import mongoose5 from "mongoose";
|
|
417
|
-
var STORAGE_PATH2 = path2.join(process.cwd(), "storage");
|
|
395
|
+
path.join(process.cwd(), "storage");
|
|
418
396
|
var createAuthClient = async (owner, accountId) => {
|
|
419
397
|
const query = { owner, "metadata.provider": "GOOGLE" };
|
|
420
398
|
if (accountId) query._id = accountId;
|
|
@@ -694,7 +672,7 @@ var GoogleDriveProvider = {
|
|
|
694
672
|
},
|
|
695
673
|
media: {
|
|
696
674
|
mimeType: drive.information.mime,
|
|
697
|
-
body:
|
|
675
|
+
body: fs2.createReadStream(filePath)
|
|
698
676
|
},
|
|
699
677
|
fields: "id, name, mimeType, webViewLink, iconLink, thumbnailLink, size"
|
|
700
678
|
});
|
|
@@ -813,7 +791,7 @@ var GoogleDriveProvider = {
|
|
|
813
791
|
removeParents: previousGoogleParentId,
|
|
814
792
|
fields: "id, parents"
|
|
815
793
|
});
|
|
816
|
-
item.parentId = newParentId === "root" || !newParentId ? null : new
|
|
794
|
+
item.parentId = newParentId === "root" || !newParentId ? null : new mongoose2.Types.ObjectId(newParentId);
|
|
817
795
|
await item.save();
|
|
818
796
|
return item.toClient();
|
|
819
797
|
},
|
|
@@ -829,11 +807,6 @@ var GoogleDriveProvider = {
|
|
|
829
807
|
}
|
|
830
808
|
}
|
|
831
809
|
};
|
|
832
|
-
|
|
833
|
-
// src/server/controllers/drive.ts
|
|
834
|
-
import fs4 from "fs";
|
|
835
|
-
import path3 from "path";
|
|
836
|
-
import crypto3 from "crypto";
|
|
837
810
|
var driveGetUrl = (fileId, options) => {
|
|
838
811
|
const config = getDriveConfig();
|
|
839
812
|
if (!config.security.signedUrls?.enabled) {
|
|
@@ -848,7 +821,7 @@ var driveGetUrl = (fileId, options) => {
|
|
|
848
821
|
} else {
|
|
849
822
|
expiryTimestamp = Math.floor(Date.now() / 1e3) + expiresIn;
|
|
850
823
|
}
|
|
851
|
-
const signature =
|
|
824
|
+
const signature = crypto2.createHmac("sha256", secret).update(`${fileId}:${expiryTimestamp}`).digest("hex");
|
|
852
825
|
const token = Buffer.from(`${expiryTimestamp}:${signature}`).toString("base64url");
|
|
853
826
|
return `/api/drive?action=serve&id=${fileId}&token=${token}`;
|
|
854
827
|
};
|
|
@@ -888,8 +861,8 @@ var driveFilePath = async (file) => {
|
|
|
888
861
|
const STORAGE_PATH3 = config.storage.path;
|
|
889
862
|
const providerType = drive.provider?.type || "LOCAL";
|
|
890
863
|
if (providerType === "LOCAL") {
|
|
891
|
-
const filePath =
|
|
892
|
-
if (!
|
|
864
|
+
const filePath = path.join(STORAGE_PATH3, drive.information.path);
|
|
865
|
+
if (!fs2.existsSync(filePath)) {
|
|
893
866
|
throw new Error(`Local file not found on disk: ${filePath}`);
|
|
894
867
|
}
|
|
895
868
|
return Object.freeze({
|
|
@@ -901,11 +874,11 @@ var driveFilePath = async (file) => {
|
|
|
901
874
|
});
|
|
902
875
|
}
|
|
903
876
|
if (providerType === "GOOGLE") {
|
|
904
|
-
const libraryDir =
|
|
905
|
-
const fileName = `${drive._id}${
|
|
906
|
-
const cachedFilePath =
|
|
907
|
-
if (
|
|
908
|
-
const stats =
|
|
877
|
+
const libraryDir = path.join(STORAGE_PATH3, "library", "google");
|
|
878
|
+
const fileName = `${drive._id}${path.extname(drive.name)}`;
|
|
879
|
+
const cachedFilePath = path.join(libraryDir, fileName);
|
|
880
|
+
if (fs2.existsSync(cachedFilePath)) {
|
|
881
|
+
const stats = fs2.statSync(cachedFilePath);
|
|
909
882
|
if (stats.size === drive.information.sizeInBytes) {
|
|
910
883
|
return Object.freeze({
|
|
911
884
|
path: cachedFilePath,
|
|
@@ -915,22 +888,22 @@ var driveFilePath = async (file) => {
|
|
|
915
888
|
provider: "GOOGLE"
|
|
916
889
|
});
|
|
917
890
|
}
|
|
918
|
-
|
|
891
|
+
fs2.unlinkSync(cachedFilePath);
|
|
919
892
|
}
|
|
920
893
|
const accountId = drive.storageAccountId?.toString();
|
|
921
894
|
const { stream } = await GoogleDriveProvider.openStream(drive, accountId);
|
|
922
|
-
if (!
|
|
923
|
-
|
|
895
|
+
if (!fs2.existsSync(libraryDir)) {
|
|
896
|
+
fs2.mkdirSync(libraryDir, { recursive: true });
|
|
924
897
|
}
|
|
925
898
|
const tempPath = `${cachedFilePath}.tmp`;
|
|
926
|
-
const writeStream =
|
|
899
|
+
const writeStream = fs2.createWriteStream(tempPath);
|
|
927
900
|
await new Promise((resolve, reject) => {
|
|
928
901
|
stream.pipe(writeStream);
|
|
929
902
|
writeStream.on("finish", resolve);
|
|
930
903
|
writeStream.on("error", reject);
|
|
931
904
|
stream.on("error", reject);
|
|
932
905
|
});
|
|
933
|
-
|
|
906
|
+
fs2.renameSync(tempPath, cachedFilePath);
|
|
934
907
|
return Object.freeze({
|
|
935
908
|
path: cachedFilePath,
|
|
936
909
|
name: drive.name,
|
|
@@ -941,12 +914,6 @@ var driveFilePath = async (file) => {
|
|
|
941
914
|
}
|
|
942
915
|
throw new Error(`Unsupported provider: ${providerType}`);
|
|
943
916
|
};
|
|
944
|
-
|
|
945
|
-
// src/client/utils.tsx
|
|
946
|
-
import { clsx } from "clsx";
|
|
947
|
-
import { twMerge } from "tailwind-merge";
|
|
948
|
-
import { File, Folder, Image, Video, Music, FileText, FileCode, FileArchive } from "lucide-react";
|
|
949
|
-
import { jsx } from "react/jsx-runtime";
|
|
950
917
|
var driveCreateUrl = (driveFile, apiEndpoint, options) => {
|
|
951
918
|
const params = new URLSearchParams({
|
|
952
919
|
action: "serve",
|
|
@@ -1143,10 +1110,10 @@ var driveAPIHandler = async (req, res) => {
|
|
|
1143
1110
|
const form = formidable({
|
|
1144
1111
|
multiples: false,
|
|
1145
1112
|
maxFileSize: config.security.maxUploadSizeInBytes * 2,
|
|
1146
|
-
uploadDir:
|
|
1113
|
+
uploadDir: path.join(STORAGE_PATH3, "temp"),
|
|
1147
1114
|
keepExtensions: true
|
|
1148
1115
|
});
|
|
1149
|
-
if (!
|
|
1116
|
+
if (!fs2.existsSync(path.join(STORAGE_PATH3, "temp"))) fs2.mkdirSync(path.join(STORAGE_PATH3, "temp"), { recursive: true });
|
|
1150
1117
|
const [fields, files] = await new Promise((resolve, reject) => {
|
|
1151
1118
|
form.parse(req, (err, fields2, files2) => {
|
|
1152
1119
|
if (err) reject(err);
|
|
@@ -1155,7 +1122,7 @@ var driveAPIHandler = async (req, res) => {
|
|
|
1155
1122
|
});
|
|
1156
1123
|
const cleanupTempFiles = (files2) => {
|
|
1157
1124
|
Object.values(files2).flat().forEach((file) => {
|
|
1158
|
-
if (file &&
|
|
1125
|
+
if (file && fs2.existsSync(file.filepath)) fs2.rmSync(file.filepath, { force: true });
|
|
1159
1126
|
});
|
|
1160
1127
|
};
|
|
1161
1128
|
const getString = (f) => Array.isArray(f) ? f[0] : f || "";
|
|
@@ -1175,7 +1142,7 @@ var driveAPIHandler = async (req, res) => {
|
|
|
1175
1142
|
}
|
|
1176
1143
|
const { chunkIndex, totalChunks, driveId, fileName, fileSize: fileSizeInBytes, fileType, folderId } = uploadData.data;
|
|
1177
1144
|
let currentUploadId = driveId;
|
|
1178
|
-
const tempBaseDir =
|
|
1145
|
+
const tempBaseDir = path.join(STORAGE_PATH3, "temp", "uploads");
|
|
1179
1146
|
if (!currentUploadId) {
|
|
1180
1147
|
if (chunkIndex !== 0) return res.status(400).json({ message: "Missing upload ID for non-zero chunk" });
|
|
1181
1148
|
if (fileType && !validateMimeType(fileType, config.security.allowedMimeTypes)) {
|
|
@@ -1188,8 +1155,8 @@ var driveAPIHandler = async (req, res) => {
|
|
|
1188
1155
|
return res.status(413).json({ status: 413, message: "Storage quota exceeded" });
|
|
1189
1156
|
}
|
|
1190
1157
|
currentUploadId = crypto.randomUUID();
|
|
1191
|
-
const uploadDir =
|
|
1192
|
-
|
|
1158
|
+
const uploadDir = path.join(tempBaseDir, currentUploadId);
|
|
1159
|
+
fs2.mkdirSync(uploadDir, { recursive: true });
|
|
1193
1160
|
const metadata = {
|
|
1194
1161
|
owner,
|
|
1195
1162
|
accountId,
|
|
@@ -1200,28 +1167,28 @@ var driveAPIHandler = async (req, res) => {
|
|
|
1200
1167
|
mimeType: fileType,
|
|
1201
1168
|
totalChunks
|
|
1202
1169
|
};
|
|
1203
|
-
|
|
1170
|
+
fs2.writeFileSync(path.join(uploadDir, "metadata.json"), JSON.stringify(metadata));
|
|
1204
1171
|
}
|
|
1205
1172
|
if (currentUploadId) {
|
|
1206
|
-
const uploadDir =
|
|
1207
|
-
if (!
|
|
1173
|
+
const uploadDir = path.join(tempBaseDir, currentUploadId);
|
|
1174
|
+
if (!fs2.existsSync(uploadDir)) {
|
|
1208
1175
|
cleanupTempFiles(files);
|
|
1209
1176
|
return res.status(404).json({ status: 404, message: "Upload session not found or expired" });
|
|
1210
1177
|
}
|
|
1211
1178
|
try {
|
|
1212
1179
|
const chunkFile = Array.isArray(files.chunk) ? files.chunk[0] : files.chunk;
|
|
1213
1180
|
if (!chunkFile) throw new Error("No chunk file received");
|
|
1214
|
-
const partPath =
|
|
1215
|
-
|
|
1216
|
-
const uploadedParts =
|
|
1181
|
+
const partPath = path.join(uploadDir, `part_${chunkIndex}`);
|
|
1182
|
+
fs2.renameSync(chunkFile.filepath, partPath);
|
|
1183
|
+
const uploadedParts = fs2.readdirSync(uploadDir).filter((f) => f.startsWith("part_"));
|
|
1217
1184
|
if (uploadedParts.length === totalChunks) {
|
|
1218
|
-
const metaPath =
|
|
1219
|
-
const meta = JSON.parse(
|
|
1220
|
-
const finalTempPath =
|
|
1221
|
-
const writeStream =
|
|
1185
|
+
const metaPath = path.join(uploadDir, "metadata.json");
|
|
1186
|
+
const meta = JSON.parse(fs2.readFileSync(metaPath, "utf-8"));
|
|
1187
|
+
const finalTempPath = path.join(uploadDir, "final.bin");
|
|
1188
|
+
const writeStream = fs2.createWriteStream(finalTempPath);
|
|
1222
1189
|
for (let i = 0; i < totalChunks; i++) {
|
|
1223
|
-
const pPath =
|
|
1224
|
-
const data =
|
|
1190
|
+
const pPath = path.join(uploadDir, `part_${i}`);
|
|
1191
|
+
const data = fs2.readFileSync(pPath);
|
|
1225
1192
|
writeStream.write(data);
|
|
1226
1193
|
}
|
|
1227
1194
|
writeStream.end();
|
|
@@ -1239,12 +1206,12 @@ var driveAPIHandler = async (req, res) => {
|
|
|
1239
1206
|
totalChunks
|
|
1240
1207
|
});
|
|
1241
1208
|
if (meta.providerName === "LOCAL" && drive.information.type === "FILE") {
|
|
1242
|
-
drive.information.path =
|
|
1209
|
+
drive.information.path = path.join("drive", String(drive._id), "data.bin");
|
|
1243
1210
|
}
|
|
1244
1211
|
await drive.save();
|
|
1245
1212
|
try {
|
|
1246
1213
|
const item = await provider.uploadFile(drive, finalTempPath, meta.accountId);
|
|
1247
|
-
|
|
1214
|
+
fs2.rmSync(uploadDir, { recursive: true, force: true });
|
|
1248
1215
|
const newQuota = await provider.getQuota(meta.owner, meta.accountId);
|
|
1249
1216
|
res.status(200).json({ status: 200, message: "Upload complete", data: { type: "UPLOAD_COMPLETE", driveId: String(drive._id), item }, statistic: { storage: newQuota } });
|
|
1250
1217
|
} catch (err) {
|
|
@@ -1432,16 +1399,7 @@ var driveAPIHandler = async (req, res) => {
|
|
|
1432
1399
|
res.status(500).json({ status: 500, message: error instanceof Error ? error.message : "Unknown error" });
|
|
1433
1400
|
}
|
|
1434
1401
|
};
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
driveCreateSrcSet,
|
|
1439
|
-
driveCreateUrl,
|
|
1440
|
-
driveFilePath,
|
|
1441
|
-
driveFileSchemaZod,
|
|
1442
|
-
driveGetUrl,
|
|
1443
|
-
driveReadFile,
|
|
1444
|
-
getDriveConfig,
|
|
1445
|
-
getDriveInformation
|
|
1446
|
-
};
|
|
1402
|
+
|
|
1403
|
+
export { driveAPIHandler, driveConfiguration, driveCreateSrcSet, driveCreateUrl, driveFilePath, driveFileSchemaZod, driveGetUrl, driveReadFile, getDriveConfig, getDriveInformation };
|
|
1404
|
+
//# sourceMappingURL=index.js.map
|
|
1447
1405
|
//# sourceMappingURL=index.js.map
|