@hdriel/aws-utils 1.2.1 → 1.2.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/dist/index.cjs +137 -20
- package/dist/index.d.cts +10 -6
- package/dist/index.d.ts +10 -6
- package/dist/index.js +135 -19
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -89,7 +89,8 @@ __export(index_exports, {
|
|
|
89
89
|
LambdaUtil: () => LambdaUtil,
|
|
90
90
|
S3LocalstackUtil: () => S3LocalstackUtil,
|
|
91
91
|
S3Util: () => S3Util,
|
|
92
|
-
SNSUtil: () => SNSUtil
|
|
92
|
+
SNSUtil: () => SNSUtil,
|
|
93
|
+
SUPPORTED_IFRAME_EXTENSIONS: () => SUPPORTED_IFRAME_EXTENSIONS
|
|
93
94
|
});
|
|
94
95
|
module.exports = __toCommonJS(index_exports);
|
|
95
96
|
|
|
@@ -289,6 +290,91 @@ var ACLs = /* @__PURE__ */ ((ACLs2) => {
|
|
|
289
290
|
ACLs2["publicReadWrite"] = "public-read-write";
|
|
290
291
|
return ACLs2;
|
|
291
292
|
})(ACLs || {});
|
|
293
|
+
var SUPPORTED_IFRAME_EXTENSIONS = [
|
|
294
|
+
// Images
|
|
295
|
+
"jpg",
|
|
296
|
+
"jpeg",
|
|
297
|
+
"png",
|
|
298
|
+
"gif",
|
|
299
|
+
"bmp",
|
|
300
|
+
"webp",
|
|
301
|
+
"svg",
|
|
302
|
+
"ico",
|
|
303
|
+
"tif",
|
|
304
|
+
"tiff",
|
|
305
|
+
"heic",
|
|
306
|
+
"heif",
|
|
307
|
+
"raw",
|
|
308
|
+
"cr2",
|
|
309
|
+
"nef",
|
|
310
|
+
"arw",
|
|
311
|
+
// Videos
|
|
312
|
+
"mp4",
|
|
313
|
+
"avi",
|
|
314
|
+
"mov",
|
|
315
|
+
"wmv",
|
|
316
|
+
"flv",
|
|
317
|
+
"mkv",
|
|
318
|
+
"webm",
|
|
319
|
+
"mpeg",
|
|
320
|
+
"mpg",
|
|
321
|
+
"m4v",
|
|
322
|
+
"3gp",
|
|
323
|
+
"ogv",
|
|
324
|
+
"ts",
|
|
325
|
+
"mts",
|
|
326
|
+
"m2ts",
|
|
327
|
+
// Documents
|
|
328
|
+
"pdf",
|
|
329
|
+
// Text
|
|
330
|
+
"txt",
|
|
331
|
+
"csv",
|
|
332
|
+
"json",
|
|
333
|
+
"xml",
|
|
334
|
+
"md",
|
|
335
|
+
"log",
|
|
336
|
+
"yaml",
|
|
337
|
+
"yml",
|
|
338
|
+
"ini",
|
|
339
|
+
"conf",
|
|
340
|
+
"cfg",
|
|
341
|
+
// Code
|
|
342
|
+
"js",
|
|
343
|
+
"ts",
|
|
344
|
+
"jsx",
|
|
345
|
+
"tsx",
|
|
346
|
+
"py",
|
|
347
|
+
"java",
|
|
348
|
+
"c",
|
|
349
|
+
"cpp",
|
|
350
|
+
"h",
|
|
351
|
+
"cs",
|
|
352
|
+
"php",
|
|
353
|
+
"rb",
|
|
354
|
+
"go",
|
|
355
|
+
"rs",
|
|
356
|
+
"swift",
|
|
357
|
+
"kt",
|
|
358
|
+
"scala",
|
|
359
|
+
// Audio
|
|
360
|
+
"mp3",
|
|
361
|
+
"wav",
|
|
362
|
+
"ogg",
|
|
363
|
+
"flac",
|
|
364
|
+
"aac",
|
|
365
|
+
"m4a",
|
|
366
|
+
"wma",
|
|
367
|
+
"aiff",
|
|
368
|
+
"ape",
|
|
369
|
+
"opus",
|
|
370
|
+
// Web
|
|
371
|
+
"html",
|
|
372
|
+
"htm",
|
|
373
|
+
"css",
|
|
374
|
+
"scss",
|
|
375
|
+
"sass",
|
|
376
|
+
"less"
|
|
377
|
+
];
|
|
292
378
|
|
|
293
379
|
// src/utils/helpers.ts
|
|
294
380
|
var import_bytes = __toESM(require("bytes"), 1);
|
|
@@ -1238,7 +1324,7 @@ var S3Stream = class _S3Stream extends S3File {
|
|
|
1238
1324
|
queryField = "file",
|
|
1239
1325
|
paramsField = "file",
|
|
1240
1326
|
headerField = "x-fileKey",
|
|
1241
|
-
|
|
1327
|
+
cachingAge: _cachingAge = "1y"
|
|
1242
1328
|
} = {}) => {
|
|
1243
1329
|
return (req, res, next) => __async(this, null, function* () {
|
|
1244
1330
|
var _a2, _b, _c, _d, _e, _f, _g, _h;
|
|
@@ -1263,8 +1349,10 @@ var S3Stream = class _S3Stream extends S3File {
|
|
|
1263
1349
|
const contentType = mimeTypeMap[ext] || "application/octet-stream";
|
|
1264
1350
|
res.setHeader("Content-Type", contentType);
|
|
1265
1351
|
res.setHeader("Content-Length", imageBuffer.length);
|
|
1266
|
-
const cachingAge = !
|
|
1267
|
-
if (cachingAge)
|
|
1352
|
+
const cachingAge = !_cachingAge || typeof _cachingAge === "number" ? _cachingAge : getTotalSeconds(_cachingAge);
|
|
1353
|
+
if (cachingAge) {
|
|
1354
|
+
res.setHeader("Cache-Control", `public, max-age=${cachingAge}`);
|
|
1355
|
+
}
|
|
1268
1356
|
res.status(200).send(imageBuffer);
|
|
1269
1357
|
} catch (error) {
|
|
1270
1358
|
(_h = this.logger) == null ? void 0 : _h.warn(req.id, "image fileKey not found", __spreadValues({
|
|
@@ -1274,19 +1362,20 @@ var S3Stream = class _S3Stream extends S3File {
|
|
|
1274
1362
|
}
|
|
1275
1363
|
});
|
|
1276
1364
|
});
|
|
1277
|
-
__publicField(this, "
|
|
1365
|
+
__publicField(this, "streamBufferFileCtrl", ({
|
|
1278
1366
|
fileKey: _fileKey,
|
|
1367
|
+
filename: _filename,
|
|
1279
1368
|
queryField = "file",
|
|
1280
1369
|
paramsField = "file",
|
|
1281
1370
|
headerField = "x-fileKey",
|
|
1282
|
-
|
|
1371
|
+
cachingAge: _cachingAge = "1h"
|
|
1283
1372
|
} = {}) => {
|
|
1284
1373
|
return (req, res, next) => __async(this, null, function* () {
|
|
1285
1374
|
var _a2, _b, _c, _d, _e, _f, _g, _h;
|
|
1286
1375
|
let fileKey = _fileKey || (((_a2 = req.params) == null ? void 0 : _a2[paramsField]) ? decodeURIComponent((_b = req.params) == null ? void 0 : _b[paramsField]) : void 0) || (((_c = req.query) == null ? void 0 : _c[queryField]) ? decodeURIComponent((_d = req.query) == null ? void 0 : _d[queryField]) : void 0) || (((_e = req.headers) == null ? void 0 : _e[headerField]) ? decodeURIComponent((_f = req.headers) == null ? void 0 : _f[headerField]) : void 0);
|
|
1287
1376
|
if (!fileKey) {
|
|
1288
|
-
(_g = this.logger) == null ? void 0 : _g.warn(req.id, "
|
|
1289
|
-
next(Error("
|
|
1377
|
+
(_g = this.logger) == null ? void 0 : _g.warn(req.id, "iframe fileKey is required");
|
|
1378
|
+
next(Error("iframe fileKey is required"));
|
|
1290
1379
|
return;
|
|
1291
1380
|
}
|
|
1292
1381
|
try {
|
|
@@ -1303,12 +1392,14 @@ var S3Stream = class _S3Stream extends S3File {
|
|
|
1303
1392
|
pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
|
1304
1393
|
};
|
|
1305
1394
|
const contentType = mimeTypeMap[ext] || "application/octet-stream";
|
|
1306
|
-
const filename = (0, import_pathe2.basename)(fileKey);
|
|
1395
|
+
const filename = _filename || (0, import_pathe2.basename)(fileKey);
|
|
1307
1396
|
res.setHeader("Content-Type", contentType);
|
|
1308
1397
|
res.setHeader("Content-Disposition", `inline; filename="${encodeURIComponent(filename)}"`);
|
|
1309
|
-
res.setHeader("Content-Length", fileBuffer.length);
|
|
1310
|
-
const cachingAge = !
|
|
1311
|
-
|
|
1398
|
+
res.setHeader("Content-Length", String(fileBuffer.length));
|
|
1399
|
+
const cachingAge = !_cachingAge || typeof _cachingAge === "number" ? _cachingAge : getTotalSeconds(_cachingAge);
|
|
1400
|
+
if (cachingAge) {
|
|
1401
|
+
res.setHeader("Cache-Control", `public, max-age=${cachingAge}`);
|
|
1402
|
+
}
|
|
1312
1403
|
res.status(200).send(fileBuffer);
|
|
1313
1404
|
} catch (error) {
|
|
1314
1405
|
(_h = this.logger) == null ? void 0 : _h.warn(req.id, "pdf fileKey not found", __spreadValues({
|
|
@@ -1512,11 +1603,13 @@ var S3Stream = class _S3Stream extends S3File {
|
|
|
1512
1603
|
forDownloading = false,
|
|
1513
1604
|
paramsField = "file",
|
|
1514
1605
|
queryField = "file",
|
|
1515
|
-
headerField = "x-fileKey"
|
|
1606
|
+
headerField = "x-fileKey",
|
|
1607
|
+
streamMethod,
|
|
1608
|
+
cachingAge: _cachingAge = "1h"
|
|
1516
1609
|
} = {}) {
|
|
1517
1610
|
return (req, res, next) => __async(this, null, function* () {
|
|
1518
1611
|
var _a2, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1519
|
-
|
|
1612
|
+
const fileKey = _fileKey || (((_a2 = req.params) == null ? void 0 : _a2[paramsField]) ? (_b = req.params) == null ? void 0 : _b[paramsField] : void 0) || (((_c = req.query) == null ? void 0 : _c[queryField]) ? (_d = req.query) == null ? void 0 : _d[queryField] : void 0) || (((_e = req.headers) == null ? void 0 : _e[headerField]) ? decodeURIComponent((_f = req.headers) == null ? void 0 : _f[headerField]) : void 0);
|
|
1520
1613
|
if (!fileKey || fileKey === "/") {
|
|
1521
1614
|
(_g = this.logger) == null ? void 0 : _g.warn(req.id, "fileKey stream is required");
|
|
1522
1615
|
next(Error("fileKey stream is required"));
|
|
@@ -1550,13 +1643,23 @@ var S3Stream = class _S3Stream extends S3File {
|
|
|
1550
1643
|
}
|
|
1551
1644
|
const fileInfo = yield this.fileInfo(normalizedKey);
|
|
1552
1645
|
const fileName = filename || normalizedKey.split("/").pop() || "download";
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1646
|
+
const contentType = fileInfo.ContentType || "application/octet-stream";
|
|
1647
|
+
const ext = (0, import_pathe2.extname)(fileKey).slice(1).toLowerCase();
|
|
1648
|
+
const inlineTypes = ["text/", "image/", "application/pdf", "video/", "audio/"];
|
|
1649
|
+
const canDisplayInline = SUPPORTED_IFRAME_EXTENSIONS.includes(ext) || inlineTypes.some((type) => contentType.startsWith(type));
|
|
1650
|
+
res.setHeader("Content-Type", contentType);
|
|
1557
1651
|
if (fileInfo.ContentLength) {
|
|
1558
1652
|
res.setHeader("Content-Length", String(fileInfo.ContentLength));
|
|
1559
1653
|
}
|
|
1654
|
+
if (forDownloading || !canDisplayInline) {
|
|
1655
|
+
res.setHeader("Content-Disposition", `attachment; filename="${encodeURIComponent(fileName)}"`);
|
|
1656
|
+
} else {
|
|
1657
|
+
res.setHeader("Content-Disposition", `inline; filename="${encodeURIComponent(fileName)}"`);
|
|
1658
|
+
}
|
|
1659
|
+
const cachingAge = !_cachingAge || typeof _cachingAge === "number" ? _cachingAge : getTotalSeconds(_cachingAge);
|
|
1660
|
+
if (cachingAge) {
|
|
1661
|
+
res.setHeader("Cache-Control", `public, max-age=${cachingAge}`);
|
|
1662
|
+
}
|
|
1560
1663
|
stream.on("error", (err) => {
|
|
1561
1664
|
var _a3, _b2;
|
|
1562
1665
|
(_a3 = this.logger) == null ? void 0 : _a3.warn(this.reqId, "Stream error", { fileKey: normalizedKey, error: err });
|
|
@@ -1568,7 +1671,12 @@ var S3Stream = class _S3Stream extends S3File {
|
|
|
1568
1671
|
(_a3 = stream == null ? void 0 : stream.destroy) == null ? void 0 : _a3.call(stream);
|
|
1569
1672
|
req.off("close", onClose);
|
|
1570
1673
|
});
|
|
1571
|
-
|
|
1674
|
+
streamMethod || (streamMethod = canDisplayInline ? "pipe" : "pipeline");
|
|
1675
|
+
if (streamMethod === "pipeline") {
|
|
1676
|
+
yield pump(stream, res);
|
|
1677
|
+
} else {
|
|
1678
|
+
stream.pipe(res);
|
|
1679
|
+
}
|
|
1572
1680
|
req.off("close", onClose);
|
|
1573
1681
|
} catch (error) {
|
|
1574
1682
|
abort.abort();
|
|
@@ -1896,6 +2004,14 @@ var S3Stream = class _S3Stream extends S3File {
|
|
|
1896
2004
|
* Middleware for uploading multiple files with different field names
|
|
1897
2005
|
* Adds the uploaded files info to req.s3FilesByField
|
|
1898
2006
|
*/
|
|
2007
|
+
/*
|
|
2008
|
+
example
|
|
2009
|
+
uploadFieldsFiles([
|
|
2010
|
+
{ name: 'cardPosterSrc', maxCount: 1 },
|
|
2011
|
+
{ name: 'sectionPosterSrc', maxCount: 1 },
|
|
2012
|
+
{ name: 'imageSrc', maxCount: 1 },
|
|
2013
|
+
]) as any,
|
|
2014
|
+
*/
|
|
1899
2015
|
// uploadFieldsFiles(
|
|
1900
2016
|
// fields: Array<{ name: string; directory: string; maxCount?: number; options?: S3UploadOptions }>
|
|
1901
2017
|
// ): RequestHandler {
|
|
@@ -2083,5 +2199,6 @@ var SNSUtil = class {
|
|
|
2083
2199
|
LambdaUtil,
|
|
2084
2200
|
S3LocalstackUtil,
|
|
2085
2201
|
S3Util,
|
|
2086
|
-
SNSUtil
|
|
2202
|
+
SNSUtil,
|
|
2203
|
+
SUPPORTED_IFRAME_EXTENSIONS
|
|
2087
2204
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -76,6 +76,7 @@ declare enum ACLs {
|
|
|
76
76
|
publicRead = "public-read",
|
|
77
77
|
publicReadWrite = "public-read-write"
|
|
78
78
|
}
|
|
79
|
+
declare const SUPPORTED_IFRAME_EXTENSIONS: string[];
|
|
79
80
|
|
|
80
81
|
interface ContentFile {
|
|
81
82
|
Key: string;
|
|
@@ -311,27 +312,30 @@ declare class S3Stream extends S3File {
|
|
|
311
312
|
headerField?: string;
|
|
312
313
|
streamTimeoutMS?: number | undefined;
|
|
313
314
|
}): Promise<(req: Request$1 & any, res: Response & any, next: NextFunction & any) => Promise<any>>;
|
|
314
|
-
streamImageFileCtrl: ({ fileKey: _fileKey, queryField, paramsField, headerField,
|
|
315
|
+
streamImageFileCtrl: ({ fileKey: _fileKey, queryField, paramsField, headerField, cachingAge: _cachingAge, }?: {
|
|
315
316
|
fileKey?: string;
|
|
316
317
|
queryField?: string;
|
|
317
318
|
paramsField?: string;
|
|
318
319
|
headerField?: string;
|
|
319
|
-
|
|
320
|
+
cachingAge?: null | number | StringValue;
|
|
320
321
|
}) => (req: Request$1 & any, res: Response & any, next: NextFunction & any) => Promise<void>;
|
|
321
|
-
|
|
322
|
+
streamBufferFileCtrl: ({ fileKey: _fileKey, filename: _filename, queryField, paramsField, headerField, cachingAge: _cachingAge, }?: {
|
|
322
323
|
fileKey?: string;
|
|
324
|
+
filename?: string;
|
|
323
325
|
queryField?: string;
|
|
324
326
|
paramsField?: string;
|
|
325
327
|
headerField?: string;
|
|
326
|
-
|
|
328
|
+
cachingAge?: null | number | StringValue;
|
|
327
329
|
}) => (req: Request$1 & any, res: Response & any, next: NextFunction & any) => Promise<void>;
|
|
328
|
-
streamFileCtrl({ fileKey: _fileKey, filename, forDownloading, paramsField, queryField, headerField, }?: {
|
|
330
|
+
streamFileCtrl({ fileKey: _fileKey, filename, forDownloading, paramsField, queryField, headerField, streamMethod, cachingAge: _cachingAge, }?: {
|
|
329
331
|
fileKey?: string;
|
|
330
332
|
filename?: string;
|
|
331
333
|
forDownloading?: boolean;
|
|
332
334
|
paramsField?: string;
|
|
333
335
|
queryField?: string;
|
|
334
336
|
headerField?: string;
|
|
337
|
+
cachingAge?: null | number | StringValue;
|
|
338
|
+
streamMethod?: 'pipe' | 'pipeline';
|
|
335
339
|
}): Promise<(req: Request$1 & any, res: Response & any, next: NextFunction & any) => Promise<void>>;
|
|
336
340
|
streamZipFileCtr({ fileKey: _fileKey, filename: _filename, queryField, paramsField, headerField, compressionLevel, }?: {
|
|
337
341
|
filename?: string;
|
|
@@ -422,4 +426,4 @@ declare class AWSConfigSharingUtil {
|
|
|
422
426
|
};
|
|
423
427
|
}
|
|
424
428
|
|
|
425
|
-
export { ACLs, AWSConfigSharingUtil, type BucketInfo, type FILE_EXT, type FILE_TYPE, IAMUtil, LambdaUtil, S3LocalstackUtil, S3Util, type S3UtilProps, SNSUtil, type TreeDirectoryItem, type TreeFileItem, type UploadedS3File };
|
|
429
|
+
export { ACLs, AWSConfigSharingUtil, type BucketInfo, type FILE_EXT, type FILE_TYPE, IAMUtil, LambdaUtil, S3LocalstackUtil, S3Util, type S3UtilProps, SNSUtil, SUPPORTED_IFRAME_EXTENSIONS, type TreeDirectoryItem, type TreeFileItem, type UploadedS3File };
|
package/dist/index.d.ts
CHANGED
|
@@ -76,6 +76,7 @@ declare enum ACLs {
|
|
|
76
76
|
publicRead = "public-read",
|
|
77
77
|
publicReadWrite = "public-read-write"
|
|
78
78
|
}
|
|
79
|
+
declare const SUPPORTED_IFRAME_EXTENSIONS: string[];
|
|
79
80
|
|
|
80
81
|
interface ContentFile {
|
|
81
82
|
Key: string;
|
|
@@ -311,27 +312,30 @@ declare class S3Stream extends S3File {
|
|
|
311
312
|
headerField?: string;
|
|
312
313
|
streamTimeoutMS?: number | undefined;
|
|
313
314
|
}): Promise<(req: Request$1 & any, res: Response & any, next: NextFunction & any) => Promise<any>>;
|
|
314
|
-
streamImageFileCtrl: ({ fileKey: _fileKey, queryField, paramsField, headerField,
|
|
315
|
+
streamImageFileCtrl: ({ fileKey: _fileKey, queryField, paramsField, headerField, cachingAge: _cachingAge, }?: {
|
|
315
316
|
fileKey?: string;
|
|
316
317
|
queryField?: string;
|
|
317
318
|
paramsField?: string;
|
|
318
319
|
headerField?: string;
|
|
319
|
-
|
|
320
|
+
cachingAge?: null | number | StringValue;
|
|
320
321
|
}) => (req: Request$1 & any, res: Response & any, next: NextFunction & any) => Promise<void>;
|
|
321
|
-
|
|
322
|
+
streamBufferFileCtrl: ({ fileKey: _fileKey, filename: _filename, queryField, paramsField, headerField, cachingAge: _cachingAge, }?: {
|
|
322
323
|
fileKey?: string;
|
|
324
|
+
filename?: string;
|
|
323
325
|
queryField?: string;
|
|
324
326
|
paramsField?: string;
|
|
325
327
|
headerField?: string;
|
|
326
|
-
|
|
328
|
+
cachingAge?: null | number | StringValue;
|
|
327
329
|
}) => (req: Request$1 & any, res: Response & any, next: NextFunction & any) => Promise<void>;
|
|
328
|
-
streamFileCtrl({ fileKey: _fileKey, filename, forDownloading, paramsField, queryField, headerField, }?: {
|
|
330
|
+
streamFileCtrl({ fileKey: _fileKey, filename, forDownloading, paramsField, queryField, headerField, streamMethod, cachingAge: _cachingAge, }?: {
|
|
329
331
|
fileKey?: string;
|
|
330
332
|
filename?: string;
|
|
331
333
|
forDownloading?: boolean;
|
|
332
334
|
paramsField?: string;
|
|
333
335
|
queryField?: string;
|
|
334
336
|
headerField?: string;
|
|
337
|
+
cachingAge?: null | number | StringValue;
|
|
338
|
+
streamMethod?: 'pipe' | 'pipeline';
|
|
335
339
|
}): Promise<(req: Request$1 & any, res: Response & any, next: NextFunction & any) => Promise<void>>;
|
|
336
340
|
streamZipFileCtr({ fileKey: _fileKey, filename: _filename, queryField, paramsField, headerField, compressionLevel, }?: {
|
|
337
341
|
filename?: string;
|
|
@@ -422,4 +426,4 @@ declare class AWSConfigSharingUtil {
|
|
|
422
426
|
};
|
|
423
427
|
}
|
|
424
428
|
|
|
425
|
-
export { ACLs, AWSConfigSharingUtil, type BucketInfo, type FILE_EXT, type FILE_TYPE, IAMUtil, LambdaUtil, S3LocalstackUtil, S3Util, type S3UtilProps, SNSUtil, type TreeDirectoryItem, type TreeFileItem, type UploadedS3File };
|
|
429
|
+
export { ACLs, AWSConfigSharingUtil, type BucketInfo, type FILE_EXT, type FILE_TYPE, IAMUtil, LambdaUtil, S3LocalstackUtil, S3Util, type S3UtilProps, SNSUtil, SUPPORTED_IFRAME_EXTENSIONS, type TreeDirectoryItem, type TreeFileItem, type UploadedS3File };
|
package/dist/index.js
CHANGED
|
@@ -250,6 +250,91 @@ var ACLs = /* @__PURE__ */ ((ACLs2) => {
|
|
|
250
250
|
ACLs2["publicReadWrite"] = "public-read-write";
|
|
251
251
|
return ACLs2;
|
|
252
252
|
})(ACLs || {});
|
|
253
|
+
var SUPPORTED_IFRAME_EXTENSIONS = [
|
|
254
|
+
// Images
|
|
255
|
+
"jpg",
|
|
256
|
+
"jpeg",
|
|
257
|
+
"png",
|
|
258
|
+
"gif",
|
|
259
|
+
"bmp",
|
|
260
|
+
"webp",
|
|
261
|
+
"svg",
|
|
262
|
+
"ico",
|
|
263
|
+
"tif",
|
|
264
|
+
"tiff",
|
|
265
|
+
"heic",
|
|
266
|
+
"heif",
|
|
267
|
+
"raw",
|
|
268
|
+
"cr2",
|
|
269
|
+
"nef",
|
|
270
|
+
"arw",
|
|
271
|
+
// Videos
|
|
272
|
+
"mp4",
|
|
273
|
+
"avi",
|
|
274
|
+
"mov",
|
|
275
|
+
"wmv",
|
|
276
|
+
"flv",
|
|
277
|
+
"mkv",
|
|
278
|
+
"webm",
|
|
279
|
+
"mpeg",
|
|
280
|
+
"mpg",
|
|
281
|
+
"m4v",
|
|
282
|
+
"3gp",
|
|
283
|
+
"ogv",
|
|
284
|
+
"ts",
|
|
285
|
+
"mts",
|
|
286
|
+
"m2ts",
|
|
287
|
+
// Documents
|
|
288
|
+
"pdf",
|
|
289
|
+
// Text
|
|
290
|
+
"txt",
|
|
291
|
+
"csv",
|
|
292
|
+
"json",
|
|
293
|
+
"xml",
|
|
294
|
+
"md",
|
|
295
|
+
"log",
|
|
296
|
+
"yaml",
|
|
297
|
+
"yml",
|
|
298
|
+
"ini",
|
|
299
|
+
"conf",
|
|
300
|
+
"cfg",
|
|
301
|
+
// Code
|
|
302
|
+
"js",
|
|
303
|
+
"ts",
|
|
304
|
+
"jsx",
|
|
305
|
+
"tsx",
|
|
306
|
+
"py",
|
|
307
|
+
"java",
|
|
308
|
+
"c",
|
|
309
|
+
"cpp",
|
|
310
|
+
"h",
|
|
311
|
+
"cs",
|
|
312
|
+
"php",
|
|
313
|
+
"rb",
|
|
314
|
+
"go",
|
|
315
|
+
"rs",
|
|
316
|
+
"swift",
|
|
317
|
+
"kt",
|
|
318
|
+
"scala",
|
|
319
|
+
// Audio
|
|
320
|
+
"mp3",
|
|
321
|
+
"wav",
|
|
322
|
+
"ogg",
|
|
323
|
+
"flac",
|
|
324
|
+
"aac",
|
|
325
|
+
"m4a",
|
|
326
|
+
"wma",
|
|
327
|
+
"aiff",
|
|
328
|
+
"ape",
|
|
329
|
+
"opus",
|
|
330
|
+
// Web
|
|
331
|
+
"html",
|
|
332
|
+
"htm",
|
|
333
|
+
"css",
|
|
334
|
+
"scss",
|
|
335
|
+
"sass",
|
|
336
|
+
"less"
|
|
337
|
+
];
|
|
253
338
|
|
|
254
339
|
// src/utils/helpers.ts
|
|
255
340
|
import bytes from "bytes";
|
|
@@ -1227,7 +1312,7 @@ var S3Stream = class _S3Stream extends S3File {
|
|
|
1227
1312
|
queryField = "file",
|
|
1228
1313
|
paramsField = "file",
|
|
1229
1314
|
headerField = "x-fileKey",
|
|
1230
|
-
|
|
1315
|
+
cachingAge: _cachingAge = "1y"
|
|
1231
1316
|
} = {}) => {
|
|
1232
1317
|
return (req, res, next) => __async(this, null, function* () {
|
|
1233
1318
|
var _a2, _b, _c, _d, _e, _f, _g, _h;
|
|
@@ -1252,8 +1337,10 @@ var S3Stream = class _S3Stream extends S3File {
|
|
|
1252
1337
|
const contentType = mimeTypeMap[ext] || "application/octet-stream";
|
|
1253
1338
|
res.setHeader("Content-Type", contentType);
|
|
1254
1339
|
res.setHeader("Content-Length", imageBuffer.length);
|
|
1255
|
-
const cachingAge = !
|
|
1256
|
-
if (cachingAge)
|
|
1340
|
+
const cachingAge = !_cachingAge || typeof _cachingAge === "number" ? _cachingAge : getTotalSeconds(_cachingAge);
|
|
1341
|
+
if (cachingAge) {
|
|
1342
|
+
res.setHeader("Cache-Control", `public, max-age=${cachingAge}`);
|
|
1343
|
+
}
|
|
1257
1344
|
res.status(200).send(imageBuffer);
|
|
1258
1345
|
} catch (error) {
|
|
1259
1346
|
(_h = this.logger) == null ? void 0 : _h.warn(req.id, "image fileKey not found", __spreadValues({
|
|
@@ -1263,19 +1350,20 @@ var S3Stream = class _S3Stream extends S3File {
|
|
|
1263
1350
|
}
|
|
1264
1351
|
});
|
|
1265
1352
|
});
|
|
1266
|
-
__publicField(this, "
|
|
1353
|
+
__publicField(this, "streamBufferFileCtrl", ({
|
|
1267
1354
|
fileKey: _fileKey,
|
|
1355
|
+
filename: _filename,
|
|
1268
1356
|
queryField = "file",
|
|
1269
1357
|
paramsField = "file",
|
|
1270
1358
|
headerField = "x-fileKey",
|
|
1271
|
-
|
|
1359
|
+
cachingAge: _cachingAge = "1h"
|
|
1272
1360
|
} = {}) => {
|
|
1273
1361
|
return (req, res, next) => __async(this, null, function* () {
|
|
1274
1362
|
var _a2, _b, _c, _d, _e, _f, _g, _h;
|
|
1275
1363
|
let fileKey = _fileKey || (((_a2 = req.params) == null ? void 0 : _a2[paramsField]) ? decodeURIComponent((_b = req.params) == null ? void 0 : _b[paramsField]) : void 0) || (((_c = req.query) == null ? void 0 : _c[queryField]) ? decodeURIComponent((_d = req.query) == null ? void 0 : _d[queryField]) : void 0) || (((_e = req.headers) == null ? void 0 : _e[headerField]) ? decodeURIComponent((_f = req.headers) == null ? void 0 : _f[headerField]) : void 0);
|
|
1276
1364
|
if (!fileKey) {
|
|
1277
|
-
(_g = this.logger) == null ? void 0 : _g.warn(req.id, "
|
|
1278
|
-
next(Error("
|
|
1365
|
+
(_g = this.logger) == null ? void 0 : _g.warn(req.id, "iframe fileKey is required");
|
|
1366
|
+
next(Error("iframe fileKey is required"));
|
|
1279
1367
|
return;
|
|
1280
1368
|
}
|
|
1281
1369
|
try {
|
|
@@ -1292,12 +1380,14 @@ var S3Stream = class _S3Stream extends S3File {
|
|
|
1292
1380
|
pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
|
1293
1381
|
};
|
|
1294
1382
|
const contentType = mimeTypeMap[ext] || "application/octet-stream";
|
|
1295
|
-
const filename = basename2(fileKey);
|
|
1383
|
+
const filename = _filename || basename2(fileKey);
|
|
1296
1384
|
res.setHeader("Content-Type", contentType);
|
|
1297
1385
|
res.setHeader("Content-Disposition", `inline; filename="${encodeURIComponent(filename)}"`);
|
|
1298
|
-
res.setHeader("Content-Length", fileBuffer.length);
|
|
1299
|
-
const cachingAge = !
|
|
1300
|
-
|
|
1386
|
+
res.setHeader("Content-Length", String(fileBuffer.length));
|
|
1387
|
+
const cachingAge = !_cachingAge || typeof _cachingAge === "number" ? _cachingAge : getTotalSeconds(_cachingAge);
|
|
1388
|
+
if (cachingAge) {
|
|
1389
|
+
res.setHeader("Cache-Control", `public, max-age=${cachingAge}`);
|
|
1390
|
+
}
|
|
1301
1391
|
res.status(200).send(fileBuffer);
|
|
1302
1392
|
} catch (error) {
|
|
1303
1393
|
(_h = this.logger) == null ? void 0 : _h.warn(req.id, "pdf fileKey not found", __spreadValues({
|
|
@@ -1501,11 +1591,13 @@ var S3Stream = class _S3Stream extends S3File {
|
|
|
1501
1591
|
forDownloading = false,
|
|
1502
1592
|
paramsField = "file",
|
|
1503
1593
|
queryField = "file",
|
|
1504
|
-
headerField = "x-fileKey"
|
|
1594
|
+
headerField = "x-fileKey",
|
|
1595
|
+
streamMethod,
|
|
1596
|
+
cachingAge: _cachingAge = "1h"
|
|
1505
1597
|
} = {}) {
|
|
1506
1598
|
return (req, res, next) => __async(this, null, function* () {
|
|
1507
1599
|
var _a2, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1508
|
-
|
|
1600
|
+
const fileKey = _fileKey || (((_a2 = req.params) == null ? void 0 : _a2[paramsField]) ? (_b = req.params) == null ? void 0 : _b[paramsField] : void 0) || (((_c = req.query) == null ? void 0 : _c[queryField]) ? (_d = req.query) == null ? void 0 : _d[queryField] : void 0) || (((_e = req.headers) == null ? void 0 : _e[headerField]) ? decodeURIComponent((_f = req.headers) == null ? void 0 : _f[headerField]) : void 0);
|
|
1509
1601
|
if (!fileKey || fileKey === "/") {
|
|
1510
1602
|
(_g = this.logger) == null ? void 0 : _g.warn(req.id, "fileKey stream is required");
|
|
1511
1603
|
next(Error("fileKey stream is required"));
|
|
@@ -1539,13 +1631,23 @@ var S3Stream = class _S3Stream extends S3File {
|
|
|
1539
1631
|
}
|
|
1540
1632
|
const fileInfo = yield this.fileInfo(normalizedKey);
|
|
1541
1633
|
const fileName = filename || normalizedKey.split("/").pop() || "download";
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1634
|
+
const contentType = fileInfo.ContentType || "application/octet-stream";
|
|
1635
|
+
const ext = extname(fileKey).slice(1).toLowerCase();
|
|
1636
|
+
const inlineTypes = ["text/", "image/", "application/pdf", "video/", "audio/"];
|
|
1637
|
+
const canDisplayInline = SUPPORTED_IFRAME_EXTENSIONS.includes(ext) || inlineTypes.some((type) => contentType.startsWith(type));
|
|
1638
|
+
res.setHeader("Content-Type", contentType);
|
|
1546
1639
|
if (fileInfo.ContentLength) {
|
|
1547
1640
|
res.setHeader("Content-Length", String(fileInfo.ContentLength));
|
|
1548
1641
|
}
|
|
1642
|
+
if (forDownloading || !canDisplayInline) {
|
|
1643
|
+
res.setHeader("Content-Disposition", `attachment; filename="${encodeURIComponent(fileName)}"`);
|
|
1644
|
+
} else {
|
|
1645
|
+
res.setHeader("Content-Disposition", `inline; filename="${encodeURIComponent(fileName)}"`);
|
|
1646
|
+
}
|
|
1647
|
+
const cachingAge = !_cachingAge || typeof _cachingAge === "number" ? _cachingAge : getTotalSeconds(_cachingAge);
|
|
1648
|
+
if (cachingAge) {
|
|
1649
|
+
res.setHeader("Cache-Control", `public, max-age=${cachingAge}`);
|
|
1650
|
+
}
|
|
1549
1651
|
stream.on("error", (err) => {
|
|
1550
1652
|
var _a3, _b2;
|
|
1551
1653
|
(_a3 = this.logger) == null ? void 0 : _a3.warn(this.reqId, "Stream error", { fileKey: normalizedKey, error: err });
|
|
@@ -1557,7 +1659,12 @@ var S3Stream = class _S3Stream extends S3File {
|
|
|
1557
1659
|
(_a3 = stream == null ? void 0 : stream.destroy) == null ? void 0 : _a3.call(stream);
|
|
1558
1660
|
req.off("close", onClose);
|
|
1559
1661
|
});
|
|
1560
|
-
|
|
1662
|
+
streamMethod || (streamMethod = canDisplayInline ? "pipe" : "pipeline");
|
|
1663
|
+
if (streamMethod === "pipeline") {
|
|
1664
|
+
yield pump(stream, res);
|
|
1665
|
+
} else {
|
|
1666
|
+
stream.pipe(res);
|
|
1667
|
+
}
|
|
1561
1668
|
req.off("close", onClose);
|
|
1562
1669
|
} catch (error) {
|
|
1563
1670
|
abort.abort();
|
|
@@ -1885,6 +1992,14 @@ var S3Stream = class _S3Stream extends S3File {
|
|
|
1885
1992
|
* Middleware for uploading multiple files with different field names
|
|
1886
1993
|
* Adds the uploaded files info to req.s3FilesByField
|
|
1887
1994
|
*/
|
|
1995
|
+
/*
|
|
1996
|
+
example
|
|
1997
|
+
uploadFieldsFiles([
|
|
1998
|
+
{ name: 'cardPosterSrc', maxCount: 1 },
|
|
1999
|
+
{ name: 'sectionPosterSrc', maxCount: 1 },
|
|
2000
|
+
{ name: 'imageSrc', maxCount: 1 },
|
|
2001
|
+
]) as any,
|
|
2002
|
+
*/
|
|
1888
2003
|
// uploadFieldsFiles(
|
|
1889
2004
|
// fields: Array<{ name: string; directory: string; maxCount?: number; options?: S3UploadOptions }>
|
|
1890
2005
|
// ): RequestHandler {
|
|
@@ -2071,5 +2186,6 @@ export {
|
|
|
2071
2186
|
LambdaUtil,
|
|
2072
2187
|
S3LocalstackUtil,
|
|
2073
2188
|
S3Util,
|
|
2074
|
-
SNSUtil
|
|
2189
|
+
SNSUtil,
|
|
2190
|
+
SUPPORTED_IFRAME_EXTENSIONS
|
|
2075
2191
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hdriel/aws-utils",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "Simplified AWS SDK (v3) utilities for S3 (upload, download, streaming) with TypeScript support",
|
|
5
5
|
"author": "Hadriel Benjo (https://github.com/hdriel)",
|
|
6
6
|
"type": "module",
|