@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 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
- cachingAgeSeconds = "1y"
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 = !cachingAgeSeconds || typeof cachingAgeSeconds === "number" ? cachingAgeSeconds : getTotalSeconds(cachingAgeSeconds);
1267
- if (cachingAge) res.setHeader("Cache-Control", `public, max-age=${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, "streamPdfFileCtrl", ({
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
- cachingAgeSeconds = "1y"
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, "pdf fileKey is required");
1289
- next(Error("pdf fileKey is required"));
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 = !cachingAgeSeconds || typeof cachingAgeSeconds === "number" ? cachingAgeSeconds : getTotalSeconds(cachingAgeSeconds);
1311
- res.setHeader("Cache-Control", `public, max-age=${cachingAge}`);
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
- let 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);
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
- res.setHeader("Content-Type", fileInfo.ContentType || "application/octet-stream");
1554
- if (forDownloading) {
1555
- res.setHeader("Content-Disposition", `attachment; filename="${encodeURIComponent(fileName)}"`);
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
- yield pump(stream, res);
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, cachingAgeSeconds, }?: {
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
- cachingAgeSeconds?: null | number | StringValue;
320
+ cachingAge?: null | number | StringValue;
320
321
  }) => (req: Request$1 & any, res: Response & any, next: NextFunction & any) => Promise<void>;
321
- streamPdfFileCtrl: ({ fileKey: _fileKey, queryField, paramsField, headerField, cachingAgeSeconds, }?: {
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
- cachingAgeSeconds?: null | number | StringValue;
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, cachingAgeSeconds, }?: {
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
- cachingAgeSeconds?: null | number | StringValue;
320
+ cachingAge?: null | number | StringValue;
320
321
  }) => (req: Request$1 & any, res: Response & any, next: NextFunction & any) => Promise<void>;
321
- streamPdfFileCtrl: ({ fileKey: _fileKey, queryField, paramsField, headerField, cachingAgeSeconds, }?: {
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
- cachingAgeSeconds?: null | number | StringValue;
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
- cachingAgeSeconds = "1y"
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 = !cachingAgeSeconds || typeof cachingAgeSeconds === "number" ? cachingAgeSeconds : getTotalSeconds(cachingAgeSeconds);
1256
- if (cachingAge) res.setHeader("Cache-Control", `public, max-age=${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, "streamPdfFileCtrl", ({
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
- cachingAgeSeconds = "1y"
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, "pdf fileKey is required");
1278
- next(Error("pdf fileKey is required"));
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 = !cachingAgeSeconds || typeof cachingAgeSeconds === "number" ? cachingAgeSeconds : getTotalSeconds(cachingAgeSeconds);
1300
- res.setHeader("Cache-Control", `public, max-age=${cachingAge}`);
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
- let 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);
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
- res.setHeader("Content-Type", fileInfo.ContentType || "application/octet-stream");
1543
- if (forDownloading) {
1544
- res.setHeader("Content-Disposition", `attachment; filename="${encodeURIComponent(fileName)}"`);
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
- yield pump(stream, res);
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.1",
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",