@muhgholy/next-drive 4.23.0 → 4.23.2
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 +74 -0
- package/dist/{chunk-CR3QW3QN.js → chunk-R43JCXQB.js} +130 -10
- package/dist/chunk-R43JCXQB.js.map +1 -0
- package/dist/{chunk-EUAHSB2J.cjs → chunk-RBLDH7CP.cjs} +133 -10
- package/dist/chunk-RBLDH7CP.cjs.map +1 -0
- package/dist/server/controllers/drive.d.ts +57 -0
- package/dist/server/controllers/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 +25 -13
- package/dist/server/index.d.ts +3 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-CR3QW3QN.js.map +0 -1
- package/dist/chunk-EUAHSB2J.cjs.map +0 -1
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var formidable = require('formidable');
|
|
4
4
|
var path = require('path');
|
|
5
5
|
var fs = require('fs');
|
|
6
|
-
var
|
|
6
|
+
var os2 = require('os');
|
|
7
7
|
var crypto2 = require('crypto');
|
|
8
8
|
var mongoose = require('mongoose');
|
|
9
9
|
var sharp2 = require('sharp');
|
|
@@ -16,7 +16,7 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
16
16
|
var formidable__default = /*#__PURE__*/_interopDefault(formidable);
|
|
17
17
|
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
18
18
|
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
19
|
-
var
|
|
19
|
+
var os2__default = /*#__PURE__*/_interopDefault(os2);
|
|
20
20
|
var crypto2__default = /*#__PURE__*/_interopDefault(crypto2);
|
|
21
21
|
var mongoose__default = /*#__PURE__*/_interopDefault(mongoose);
|
|
22
22
|
var sharp2__default = /*#__PURE__*/_interopDefault(sharp2);
|
|
@@ -273,7 +273,7 @@ var driveConfiguration = async (config) => {
|
|
|
273
273
|
if (g.migrationPromise) await g.migrationPromise;
|
|
274
274
|
return g.config;
|
|
275
275
|
}
|
|
276
|
-
const resolvedPath = config.storage?.path || path__default.default.join(
|
|
276
|
+
const resolvedPath = config.storage?.path || path__default.default.join(os2__default.default.tmpdir(), "next-drive-data");
|
|
277
277
|
const mode = config.mode || "NORMAL";
|
|
278
278
|
if (mode === "ROOT") {
|
|
279
279
|
g.config = {
|
|
@@ -1464,6 +1464,51 @@ var driveList = async (options) => {
|
|
|
1464
1464
|
const items = await drive_default.find(query, {}, { sort: { order: 1, _id: -1 }, limit });
|
|
1465
1465
|
return await Promise.all(items.map((item) => item.toClient()));
|
|
1466
1466
|
};
|
|
1467
|
+
var driveListFiles = async (options) => {
|
|
1468
|
+
const { key, folderId, accountId } = options;
|
|
1469
|
+
const page = Math.max(1, options.page ?? 1);
|
|
1470
|
+
const limit = Math.min(Math.max(1, options.limit ?? 50), 100);
|
|
1471
|
+
let providerName = "LOCAL";
|
|
1472
|
+
if (accountId && accountId !== "LOCAL") {
|
|
1473
|
+
const account = await drive_default.db.model("StorageAccount").findOne({ _id: accountId, owner: key });
|
|
1474
|
+
if (!account) {
|
|
1475
|
+
throw new Error("Invalid Storage Account");
|
|
1476
|
+
}
|
|
1477
|
+
if (account.metadata.provider === "GOOGLE") {
|
|
1478
|
+
providerName = "GOOGLE";
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
const query = {
|
|
1482
|
+
"provider.type": providerName,
|
|
1483
|
+
"information.type": "FILE",
|
|
1484
|
+
storageAccountId: accountId || null,
|
|
1485
|
+
trashedAt: null
|
|
1486
|
+
};
|
|
1487
|
+
if (key !== void 0) {
|
|
1488
|
+
query.owner = key;
|
|
1489
|
+
}
|
|
1490
|
+
if (folderId && folderId !== "root") {
|
|
1491
|
+
query.parentId = folderId;
|
|
1492
|
+
} else if (folderId === "root" || folderId === null) {
|
|
1493
|
+
query.parentId = null;
|
|
1494
|
+
}
|
|
1495
|
+
const skip = (page - 1) * limit;
|
|
1496
|
+
const [totalCount, items] = await Promise.all([
|
|
1497
|
+
drive_default.countDocuments(query),
|
|
1498
|
+
drive_default.find(query, {}, { sort: { createdAt: -1 }, skip, limit })
|
|
1499
|
+
]);
|
|
1500
|
+
const totalPages = Math.ceil(totalCount / limit);
|
|
1501
|
+
return {
|
|
1502
|
+
items: await Promise.all(items.map((item) => item.toClient())),
|
|
1503
|
+
pagination: {
|
|
1504
|
+
page,
|
|
1505
|
+
limit,
|
|
1506
|
+
totalCount,
|
|
1507
|
+
totalPages,
|
|
1508
|
+
hasMore: page < totalPages
|
|
1509
|
+
}
|
|
1510
|
+
};
|
|
1511
|
+
};
|
|
1467
1512
|
var driveDelete = async (source, options) => {
|
|
1468
1513
|
const { recurse = true } = options || {};
|
|
1469
1514
|
let drive;
|
|
@@ -1562,7 +1607,7 @@ var driveUpload = async (source, key, options) => {
|
|
|
1562
1607
|
const stats = fs__default.default.statSync(source);
|
|
1563
1608
|
fileSize = stats.size;
|
|
1564
1609
|
} else if (Buffer.isBuffer(source)) {
|
|
1565
|
-
const tempDir = path__default.default.join(
|
|
1610
|
+
const tempDir = path__default.default.join(os2__default.default.tmpdir(), "next-drive-uploads");
|
|
1566
1611
|
if (!fs__default.default.existsSync(tempDir)) {
|
|
1567
1612
|
fs__default.default.mkdirSync(tempDir, { recursive: true });
|
|
1568
1613
|
}
|
|
@@ -1571,7 +1616,7 @@ var driveUpload = async (source, key, options) => {
|
|
|
1571
1616
|
sourceFilePath = tempFilePath;
|
|
1572
1617
|
fileSize = source.length;
|
|
1573
1618
|
} else {
|
|
1574
|
-
const tempDir = path__default.default.join(
|
|
1619
|
+
const tempDir = path__default.default.join(os2__default.default.tmpdir(), "next-drive-uploads");
|
|
1575
1620
|
if (!fs__default.default.existsSync(tempDir)) {
|
|
1576
1621
|
fs__default.default.mkdirSync(tempDir, { recursive: true });
|
|
1577
1622
|
}
|
|
@@ -1671,6 +1716,81 @@ var driveUpload = async (source, key, options) => {
|
|
|
1671
1716
|
}
|
|
1672
1717
|
}
|
|
1673
1718
|
};
|
|
1719
|
+
var driveCleanup = async () => {
|
|
1720
|
+
const config = getDriveConfig();
|
|
1721
|
+
const fileDir = path__default.default.join(config.storage.path, "file");
|
|
1722
|
+
if (!fs__default.default.existsSync(fileDir)) {
|
|
1723
|
+
return { removed: [], totalFreedInBytes: 0 };
|
|
1724
|
+
}
|
|
1725
|
+
const folderNames = fs__default.default.readdirSync(fileDir).filter((name) => {
|
|
1726
|
+
const fullPath = path__default.default.join(fileDir, name);
|
|
1727
|
+
return fs__default.default.statSync(fullPath).isDirectory();
|
|
1728
|
+
});
|
|
1729
|
+
if (folderNames.length === 0) {
|
|
1730
|
+
return { removed: [], totalFreedInBytes: 0 };
|
|
1731
|
+
}
|
|
1732
|
+
const getDirSize = (dirPath) => {
|
|
1733
|
+
let size = 0;
|
|
1734
|
+
try {
|
|
1735
|
+
const entries = fs__default.default.readdirSync(dirPath, { withFileTypes: true });
|
|
1736
|
+
for (const entry of entries) {
|
|
1737
|
+
const entryPath = path__default.default.join(dirPath, entry.name);
|
|
1738
|
+
if (entry.isFile()) {
|
|
1739
|
+
size += fs__default.default.statSync(entryPath).size;
|
|
1740
|
+
} else if (entry.isDirectory()) {
|
|
1741
|
+
size += getDirSize(entryPath);
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
} catch {
|
|
1745
|
+
}
|
|
1746
|
+
return size;
|
|
1747
|
+
};
|
|
1748
|
+
const BATCH_SIZE = 500;
|
|
1749
|
+
const existingIds = /* @__PURE__ */ new Set();
|
|
1750
|
+
for (let i = 0; i < folderNames.length; i += BATCH_SIZE) {
|
|
1751
|
+
const batch = folderNames.slice(i, i + BATCH_SIZE);
|
|
1752
|
+
const docs = await drive_default.find(
|
|
1753
|
+
{ _id: { $in: batch } },
|
|
1754
|
+
{ _id: 1 }
|
|
1755
|
+
).lean();
|
|
1756
|
+
for (const doc of docs) {
|
|
1757
|
+
existingIds.add(doc._id.toString());
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
const removed = [];
|
|
1761
|
+
let totalFreedInBytes = 0;
|
|
1762
|
+
for (const name of folderNames) {
|
|
1763
|
+
if (!existingIds.has(name)) {
|
|
1764
|
+
const dirPath = path__default.default.join(fileDir, name);
|
|
1765
|
+
try {
|
|
1766
|
+
totalFreedInBytes += getDirSize(dirPath);
|
|
1767
|
+
fs__default.default.rmSync(dirPath, { recursive: true, force: true });
|
|
1768
|
+
removed.push(name);
|
|
1769
|
+
} catch (e) {
|
|
1770
|
+
console.error(`[next-drive] Failed to remove orphaned folder ${name}:`, e);
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
const tempDir = path__default.default.join(config.storage.path, "temp");
|
|
1775
|
+
if (fs__default.default.existsSync(tempDir)) {
|
|
1776
|
+
try {
|
|
1777
|
+
totalFreedInBytes += getDirSize(tempDir);
|
|
1778
|
+
fs__default.default.rmSync(tempDir, { recursive: true, force: true });
|
|
1779
|
+
} catch (e) {
|
|
1780
|
+
console.error("[next-drive] Failed to remove temp directory:", e);
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
const systemTmpDir = path__default.default.join(os2__default.default.tmpdir(), "next-drive-uploads");
|
|
1784
|
+
if (fs__default.default.existsSync(systemTmpDir)) {
|
|
1785
|
+
try {
|
|
1786
|
+
totalFreedInBytes += getDirSize(systemTmpDir);
|
|
1787
|
+
fs__default.default.rmSync(systemTmpDir, { recursive: true, force: true });
|
|
1788
|
+
} catch (e) {
|
|
1789
|
+
console.error("[next-drive] Failed to remove system temp directory:", e);
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
return { removed, totalFreedInBytes };
|
|
1793
|
+
};
|
|
1674
1794
|
|
|
1675
1795
|
// src/server/index.ts
|
|
1676
1796
|
var getProvider = async (req, owner) => {
|
|
@@ -2088,7 +2208,7 @@ var driveAPIHandler = async (req, res) => {
|
|
|
2088
2208
|
// ** 3. UPLOAD **
|
|
2089
2209
|
case "upload": {
|
|
2090
2210
|
if (req.method !== "POST") return res.status(405).json({ status: 405, message: "Only POST allowed" });
|
|
2091
|
-
const systemTmpDir = path__default.default.join(
|
|
2211
|
+
const systemTmpDir = path__default.default.join(os2__default.default.tmpdir(), "next-drive-uploads");
|
|
2092
2212
|
if (!fs__default.default.existsSync(systemTmpDir)) fs__default.default.mkdirSync(systemTmpDir, { recursive: true });
|
|
2093
2213
|
const form = formidable__default.default({
|
|
2094
2214
|
multiples: false,
|
|
@@ -2124,7 +2244,7 @@ var driveAPIHandler = async (req, res) => {
|
|
|
2124
2244
|
}
|
|
2125
2245
|
const { chunkIndex, totalChunks, driveId, fileName, fileSize: fileSizeInBytes, fileType, folderId } = uploadData.data;
|
|
2126
2246
|
let currentUploadId = driveId;
|
|
2127
|
-
const tempBaseDir = path__default.default.join(
|
|
2247
|
+
const tempBaseDir = path__default.default.join(os2__default.default.tmpdir(), "next-drive-uploads");
|
|
2128
2248
|
if (!currentUploadId) {
|
|
2129
2249
|
if (chunkIndex !== 0) return res.status(400).json({ message: "Missing upload ID for non-zero chunk" });
|
|
2130
2250
|
if (fileType && config.security) {
|
|
@@ -2272,7 +2392,7 @@ var driveAPIHandler = async (req, res) => {
|
|
|
2272
2392
|
const cancelData = cancelQuerySchema.safeParse(req.query);
|
|
2273
2393
|
if (!cancelData.success) return res.status(400).json({ status: 400, message: "Invalid ID" });
|
|
2274
2394
|
const { id } = cancelData.data;
|
|
2275
|
-
const tempUploadDir = path__default.default.join(
|
|
2395
|
+
const tempUploadDir = path__default.default.join(os2__default.default.tmpdir(), "next-drive-uploads", id);
|
|
2276
2396
|
if (fs__default.default.existsSync(tempUploadDir)) {
|
|
2277
2397
|
try {
|
|
2278
2398
|
fs__default.default.rmSync(tempUploadDir, { recursive: true, force: true });
|
|
@@ -2418,6 +2538,7 @@ var driveAPIHandler = async (req, res) => {
|
|
|
2418
2538
|
};
|
|
2419
2539
|
|
|
2420
2540
|
exports.driveAPIHandler = driveAPIHandler;
|
|
2541
|
+
exports.driveCleanup = driveCleanup;
|
|
2421
2542
|
exports.driveConfiguration = driveConfiguration;
|
|
2422
2543
|
exports.driveDelete = driveDelete;
|
|
2423
2544
|
exports.driveFilePath = driveFilePath;
|
|
@@ -2425,9 +2546,11 @@ exports.driveFileSchemaZod = driveFileSchemaZod;
|
|
|
2425
2546
|
exports.driveGetUrl = driveGetUrl;
|
|
2426
2547
|
exports.driveInfo = driveInfo;
|
|
2427
2548
|
exports.driveList = driveList;
|
|
2549
|
+
exports.driveListFiles = driveListFiles;
|
|
2428
2550
|
exports.driveReadFile = driveReadFile;
|
|
2429
2551
|
exports.driveUpload = driveUpload;
|
|
2552
|
+
exports.drive_default = drive_default;
|
|
2430
2553
|
exports.getDriveConfig = getDriveConfig;
|
|
2431
2554
|
exports.getDriveInformation = getDriveInformation;
|
|
2432
|
-
//# sourceMappingURL=chunk-
|
|
2433
|
-
//# sourceMappingURL=chunk-
|
|
2555
|
+
//# sourceMappingURL=chunk-RBLDH7CP.cjs.map
|
|
2556
|
+
//# sourceMappingURL=chunk-RBLDH7CP.cjs.map
|