@muhgholy/next-drive 4.9.0 → 4.10.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/dist/{chunk-WZWJYN64.cjs → chunk-IE2Y7DG4.cjs} +43 -18
- package/dist/chunk-IE2Y7DG4.cjs.map +1 -0
- package/dist/{chunk-C5CORNPP.js → chunk-MHRLZQBV.js} +42 -17
- package/dist/chunk-MHRLZQBV.js.map +1 -0
- package/dist/server/express.cjs +11 -11
- package/dist/server/express.js +2 -2
- package/dist/server/index.cjs +13 -13
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/providers/local.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-C5CORNPP.js.map +0 -1
- package/dist/chunk-WZWJYN64.cjs.map +0 -1
|
@@ -6,7 +6,7 @@ var fs = require('fs');
|
|
|
6
6
|
var os2 = require('os');
|
|
7
7
|
var crypto2 = require('crypto');
|
|
8
8
|
var mongoose = require('mongoose');
|
|
9
|
-
var
|
|
9
|
+
var sharp2 = require('sharp');
|
|
10
10
|
var zod = require('zod');
|
|
11
11
|
var ffmpeg = require('fluent-ffmpeg');
|
|
12
12
|
var googleapis = require('googleapis');
|
|
@@ -19,7 +19,7 @@ var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
|
19
19
|
var os2__default = /*#__PURE__*/_interopDefault(os2);
|
|
20
20
|
var crypto2__default = /*#__PURE__*/_interopDefault(crypto2);
|
|
21
21
|
var mongoose__default = /*#__PURE__*/_interopDefault(mongoose);
|
|
22
|
-
var
|
|
22
|
+
var sharp2__default = /*#__PURE__*/_interopDefault(sharp2);
|
|
23
23
|
var ffmpeg__default = /*#__PURE__*/_interopDefault(ffmpeg);
|
|
24
24
|
|
|
25
25
|
// src/server/index.ts
|
|
@@ -363,7 +363,7 @@ var computeFileHash = (filePath) => new Promise((resolve, reject) => {
|
|
|
363
363
|
});
|
|
364
364
|
var extractImageMetadata = async (filePath) => {
|
|
365
365
|
try {
|
|
366
|
-
const { width = 0, height = 0, exif } = await
|
|
366
|
+
const { width = 0, height = 0, exif } = await sharp2__default.default(filePath).metadata();
|
|
367
367
|
return { width, height, ...exif && { exif: { raw: exif.toString("base64") } } };
|
|
368
368
|
} catch {
|
|
369
369
|
return null;
|
|
@@ -374,7 +374,7 @@ var DISPLAY_PRESETS = {
|
|
|
374
374
|
"article-image": { ratio: [16, 9], baseWidth: 800, qualityFactor: 0.85, defaultFit: "inside" },
|
|
375
375
|
"thumbnail": { ratio: [1, 1], baseWidth: 150, qualityFactor: 0.7, defaultFit: "cover" },
|
|
376
376
|
"avatar": { ratio: [1, 1], baseWidth: 128, qualityFactor: 0.8, defaultFit: "cover" },
|
|
377
|
-
"logo": { ratio: [2, 1], baseWidth: 200, qualityFactor: 0.95, defaultFit: "
|
|
377
|
+
"logo": { ratio: [2, 1], baseWidth: 200, qualityFactor: 0.95, defaultFit: "inside" },
|
|
378
378
|
"card": { ratio: [4, 3], baseWidth: 400, qualityFactor: 0.8, defaultFit: "cover" },
|
|
379
379
|
"gallery": { ratio: [1, 1], baseWidth: 600, qualityFactor: 0.85, defaultFit: "cover" },
|
|
380
380
|
"og": { ratio: [1200, 630], baseWidth: 1200, qualityFactor: 0.9, defaultFit: "cover" },
|
|
@@ -597,6 +597,19 @@ function sanitizeContentDispositionFilename(filename) {
|
|
|
597
597
|
const basename = filename.replace(/^.*[\\\/]/, "");
|
|
598
598
|
return basename.replace(/["\r\n]/g, "").replace(/[^\x20-\x7E]/g, "").slice(0, 255);
|
|
599
599
|
}
|
|
600
|
+
var generatePlaceholderThumbnail = async (outputPath, mimeType) => {
|
|
601
|
+
const typeParts = mimeType.split("/");
|
|
602
|
+
const subtype = typeParts[1] || "file";
|
|
603
|
+
const label = subtype.replace(/^x-/, "").toUpperCase().slice(0, 6);
|
|
604
|
+
const svg = `
|
|
605
|
+
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg">
|
|
606
|
+
<rect width="300" height="300" fill="#e5e7eb"/>
|
|
607
|
+
<text x="150" y="140" text-anchor="middle" font-family="system-ui, sans-serif" font-size="48" fill="#6b7280">${label}</text>
|
|
608
|
+
<text x="150" y="180" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#9ca3af">Preview unavailable</text>
|
|
609
|
+
</svg>
|
|
610
|
+
`;
|
|
611
|
+
await sharp2__default.default(Buffer.from(svg)).resize(300, 300).toFormat("webp", { quality: 80 }).toFile(outputPath);
|
|
612
|
+
};
|
|
600
613
|
var LocalStorageProvider = {
|
|
601
614
|
name: "LOCAL",
|
|
602
615
|
sync: async (folderId, owner, accountId) => {
|
|
@@ -653,18 +666,28 @@ var LocalStorageProvider = {
|
|
|
653
666
|
}
|
|
654
667
|
if (!fs__default.default.existsSync(thumbDir)) fs__default.default.mkdirSync(thumbDir, { recursive: true });
|
|
655
668
|
if (item.information.mime.startsWith("image/")) {
|
|
656
|
-
|
|
669
|
+
try {
|
|
670
|
+
await sharp2__default.default(originalPath).resize(300, 300, { fit: "inside" }).toFormat("webp", { quality: 80 }).toFile(thumbPath);
|
|
671
|
+
} catch (err) {
|
|
672
|
+
console.warn(`[next-drive] Thumbnail generation failed for ${item.information.mime}, using placeholder`);
|
|
673
|
+
await generatePlaceholderThumbnail(thumbPath, item.information.mime);
|
|
674
|
+
}
|
|
657
675
|
} else if (item.information.mime.startsWith("video/")) {
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
676
|
+
try {
|
|
677
|
+
await new Promise((resolve, reject) => {
|
|
678
|
+
ffmpeg__default.default(originalPath).screenshots({
|
|
679
|
+
count: 1,
|
|
680
|
+
folder: path__default.default.dirname(thumbPath),
|
|
681
|
+
filename: path__default.default.basename(thumbPath),
|
|
682
|
+
size: "300x?"
|
|
683
|
+
}).on("end", resolve).on("error", reject);
|
|
684
|
+
});
|
|
685
|
+
} catch (err) {
|
|
686
|
+
console.warn(`[next-drive] Video thumbnail generation failed, using placeholder`);
|
|
687
|
+
await generatePlaceholderThumbnail(thumbPath, item.information.mime);
|
|
688
|
+
}
|
|
666
689
|
} else {
|
|
667
|
-
|
|
690
|
+
await generatePlaceholderThumbnail(thumbPath, item.information.mime);
|
|
668
691
|
}
|
|
669
692
|
return fs__default.default.createReadStream(thumbPath);
|
|
670
693
|
},
|
|
@@ -1784,12 +1807,14 @@ var driveAPIHandler = async (req, res) => {
|
|
|
1784
1807
|
return;
|
|
1785
1808
|
}
|
|
1786
1809
|
if (!fs__default.default.existsSync(cacheDir)) fs__default.default.mkdirSync(cacheDir, { recursive: true });
|
|
1787
|
-
let pipeline =
|
|
1810
|
+
let pipeline = sharp2__default.default();
|
|
1788
1811
|
if (settings.width && settings.height) {
|
|
1789
1812
|
pipeline = pipeline.resize(settings.width, settings.height, {
|
|
1790
1813
|
fit: settings.fit || "inside",
|
|
1791
1814
|
position: settings.position || "center",
|
|
1792
|
-
withoutEnlargement: true
|
|
1815
|
+
withoutEnlargement: true,
|
|
1816
|
+
// Use transparent background for 'contain' fit to preserve transparency
|
|
1817
|
+
background: { r: 0, g: 0, b: 0, alpha: 0 }
|
|
1793
1818
|
});
|
|
1794
1819
|
}
|
|
1795
1820
|
if (targetFormat === "jpeg") {
|
|
@@ -2364,5 +2389,5 @@ exports.driveReadFile = driveReadFile;
|
|
|
2364
2389
|
exports.driveUpload = driveUpload;
|
|
2365
2390
|
exports.getDriveConfig = getDriveConfig;
|
|
2366
2391
|
exports.getDriveInformation = getDriveInformation;
|
|
2367
|
-
//# sourceMappingURL=chunk-
|
|
2368
|
-
//# sourceMappingURL=chunk-
|
|
2392
|
+
//# sourceMappingURL=chunk-IE2Y7DG4.cjs.map
|
|
2393
|
+
//# sourceMappingURL=chunk-IE2Y7DG4.cjs.map
|