@hdriel/aws-utils 1.0.2 → 1.0.4

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
@@ -298,6 +298,7 @@ var parseRangeHeader = (range, contentLength, chunkSize) => {
298
298
  }
299
299
  return [start, Math.min(end, end)];
300
300
  };
301
+ var getNormalizedPath = (directoryPath) => decodeURIComponent((directoryPath == null ? void 0 : directoryPath.replace(/^\/+/, "").replace(/\/+$/, "")) || "");
301
302
  var S3BucketUtil = class _S3BucketUtil {
302
303
  constructor({
303
304
  logger: logger2,
@@ -606,7 +607,7 @@ var S3BucketUtil = class _S3BucketUtil {
606
607
  // ##### DIRECTORY BLOCK ##########################
607
608
  createDirectory(directoryPath) {
608
609
  return __async(this, null, function* () {
609
- let normalizedPath = decodeURIComponent((directoryPath == null ? void 0 : directoryPath.replace(/^\//, "").replace(/\/$/, "")) || "");
610
+ let normalizedPath = getNormalizedPath(directoryPath);
610
611
  if (!normalizedPath) throw new Error("No directory path provided");
611
612
  if (normalizedPath === "/") normalizedPath = "";
612
613
  const command = new import_client_s3.PutObjectCommand({ Bucket: this.bucket, Key: `${normalizedPath}/` });
@@ -617,10 +618,8 @@ var S3BucketUtil = class _S3BucketUtil {
617
618
  deleteDirectory(directoryPath) {
618
619
  return __async(this, null, function* () {
619
620
  var _a2, _b, _c, _d, _e, _f, _g;
620
- let normalizedPath = decodeURIComponent((directoryPath == null ? void 0 : directoryPath.replace(/^\//, "").replace(/\/$/, "")) || "");
621
- if (!normalizedPath) {
622
- throw new Error("No directory path provided");
623
- }
621
+ let normalizedPath = getNormalizedPath(directoryPath);
622
+ if (!normalizedPath) throw new Error("No directory path provided");
624
623
  if (normalizedPath === "/") normalizedPath = "";
625
624
  let totalDeletedCount = 0;
626
625
  let ContinuationToken = void 0;
@@ -687,8 +686,8 @@ var S3BucketUtil = class _S3BucketUtil {
687
686
  }
688
687
  directoryList(directoryPath) {
689
688
  return __async(this, null, function* () {
690
- let normalizedPath = decodeURIComponent((directoryPath == null ? void 0 : directoryPath.replace(/^\//, "").replace(/\/$/, "")) || "");
691
- if (directoryPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
689
+ let normalizedPath = getNormalizedPath(directoryPath);
690
+ if (normalizedPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
692
691
  else normalizedPath = "";
693
692
  const result = yield this.execute(
694
693
  new import_client_s3.ListObjectsV2Command({
@@ -707,19 +706,70 @@ var S3BucketUtil = class _S3BucketUtil {
707
706
  return content.Key !== normalizedPath && !((_a2 = content.Key) == null ? void 0 : _a2.endsWith("/"));
708
707
  }).map((content) => __spreadProps(__spreadValues({}, content), {
709
708
  Name: content.Key.replace(normalizedPath, "") || content.Key,
709
+ Location: `${this.link}${content.Key}`,
710
710
  LastModified: new Date(content.LastModified)
711
711
  }));
712
712
  return { directories, files };
713
713
  });
714
714
  }
715
+ directoryListPaginated(_0) {
716
+ return __async(this, arguments, function* (directoryPath, {
717
+ pageSize = 100,
718
+ pageNumber = 0
719
+ // 0-based: page 0 = items 0-99, page 1 = items 100-199, page 2 = items 200-299
720
+ } = {}) {
721
+ let normalizedPath = getNormalizedPath(directoryPath);
722
+ if (normalizedPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
723
+ else normalizedPath = "";
724
+ let continuationToken = void 0;
725
+ let currentPage = 0;
726
+ let allDirectories = [];
727
+ let allFiles = [];
728
+ while (currentPage <= pageNumber) {
729
+ const result = yield this.execute(
730
+ new import_client_s3.ListObjectsV2Command({
731
+ Bucket: this.bucket,
732
+ Prefix: normalizedPath,
733
+ Delimiter: "/",
734
+ MaxKeys: pageSize,
735
+ ContinuationToken: continuationToken
736
+ })
737
+ );
738
+ if (currentPage === pageNumber) {
739
+ allDirectories = (result.CommonPrefixes || []).map((prefix) => prefix.Prefix).map((prefix) => {
740
+ const relativePath = prefix.replace(normalizedPath, "");
741
+ return relativePath.replace(/\/$/, "");
742
+ }).filter((dir) => dir);
743
+ allFiles = (result.Contents || []).filter((content) => {
744
+ var _a2;
745
+ return content.Key !== normalizedPath && !((_a2 = content.Key) == null ? void 0 : _a2.endsWith("/"));
746
+ }).map((content) => __spreadProps(__spreadValues({}, content), {
747
+ Name: content.Key.replace(normalizedPath, "") || content.Key,
748
+ Location: `${this.link}${content.Key}`,
749
+ LastModified: new Date(content.LastModified)
750
+ }));
751
+ }
752
+ continuationToken = result.NextContinuationToken;
753
+ if (!result.IsTruncated || !continuationToken) {
754
+ break;
755
+ }
756
+ currentPage++;
757
+ }
758
+ return {
759
+ directories: allDirectories,
760
+ files: allFiles,
761
+ totalFetched: allFiles.length + allDirectories.length
762
+ };
763
+ });
764
+ }
715
765
  /**
716
766
  * Get all files recursively (example for search/indexing)
717
767
  * @param directoryPath
718
768
  */
719
769
  directoryListRecursive(directoryPath) {
720
770
  return __async(this, null, function* () {
721
- let normalizedPath = decodeURIComponent((directoryPath == null ? void 0 : directoryPath.replace(/^\//, "").replace(/\/$/, "")) || "");
722
- if (directoryPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
771
+ let normalizedPath = getNormalizedPath(directoryPath);
772
+ if (normalizedPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
723
773
  else normalizedPath = "";
724
774
  const allDirectories = [];
725
775
  const allFiles = [];
@@ -742,6 +792,7 @@ var S3BucketUtil = class _S3BucketUtil {
742
792
  allFiles.push(__spreadProps(__spreadValues({}, content), {
743
793
  Name: filename,
744
794
  Path: fullPath,
795
+ Location: `${this.link}${content.Key}`,
745
796
  LastModified: new Date(content.LastModified)
746
797
  }));
747
798
  }
@@ -783,7 +834,7 @@ var S3BucketUtil = class _S3BucketUtil {
783
834
  */
784
835
  directoryTree(directoryPath) {
785
836
  return __async(this, null, function* () {
786
- let normalizedPath = decodeURIComponent((directoryPath == null ? void 0 : directoryPath.replace(/^\//, "").replace(/\/$/, "")) || "");
837
+ let normalizedPath = getNormalizedPath(directoryPath);
787
838
  const lastDirectory = directoryPath == null ? void 0 : directoryPath.split("/").pop();
788
839
  const { directories, files } = yield this.directoryList(normalizedPath);
789
840
  if (directoryPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
@@ -798,6 +849,7 @@ var S3BucketUtil = class _S3BucketUtil {
798
849
  treeNode.children.push({
799
850
  path: "/" + file.Key,
800
851
  name: file.Name,
852
+ location: `${this.link}${file.Key}`,
801
853
  type: "file",
802
854
  size: file.Size,
803
855
  lastModified: file.LastModified
@@ -814,7 +866,7 @@ var S3BucketUtil = class _S3BucketUtil {
814
866
  // ##### FILES BLOCK ##########################
815
867
  fileInfo(filePath) {
816
868
  return __async(this, null, function* () {
817
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
869
+ const normalizedKey = getNormalizedPath(filePath);
818
870
  if (!normalizedKey || normalizedKey === "/") {
819
871
  throw new Error("No file key provided");
820
872
  }
@@ -825,8 +877,8 @@ var S3BucketUtil = class _S3BucketUtil {
825
877
  fileListInfo(directoryPath, fileNamePrefix) {
826
878
  return __async(this, null, function* () {
827
879
  var _a2, _b;
828
- let normalizedPath = decodeURIComponent((directoryPath == null ? void 0 : directoryPath.replace(/^\//, "").replace(/\/$/, "")) || "");
829
- if (directoryPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
880
+ let normalizedPath = getNormalizedPath(directoryPath);
881
+ if (normalizedPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
830
882
  else normalizedPath = "";
831
883
  const prefix = normalizedPath + (fileNamePrefix || "");
832
884
  const command = new import_client_s3.ListObjectsCommand({
@@ -840,6 +892,7 @@ var S3BucketUtil = class _S3BucketUtil {
840
892
  var _a3, _b2;
841
893
  return __spreadProps(__spreadValues({}, content), {
842
894
  Name: (_b2 = (_a3 = content.Key) == null ? void 0 : _a3.replace(prefix, "")) != null ? _b2 : content.Key,
895
+ Location: `${this.link}${content.Key}`,
843
896
  LastModified: content.LastModified ? new Date(content.LastModified) : null
844
897
  });
845
898
  }
@@ -848,13 +901,66 @@ var S3BucketUtil = class _S3BucketUtil {
848
901
  return files;
849
902
  });
850
903
  }
904
+ fileListInfoPaginated(_0) {
905
+ return __async(this, arguments, function* (directoryPath, {
906
+ fileNamePrefix,
907
+ pageNumber = 0,
908
+ // 0-based: page 0 = items 0-99, page 1 = items 100-199, page 2 = items 200-299
909
+ pageSize = 100
910
+ } = {}) {
911
+ var _a2, _b;
912
+ let normalizedPath = getNormalizedPath(directoryPath);
913
+ if (normalizedPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
914
+ else normalizedPath = "";
915
+ const prefix = normalizedPath + (fileNamePrefix || "");
916
+ let continuationToken;
917
+ let currentPage = 0;
918
+ let resultFiles = [];
919
+ while (currentPage <= pageNumber) {
920
+ const result = yield this.execute(
921
+ new import_client_s3.ListObjectsV2Command({
922
+ Bucket: this.bucket,
923
+ Prefix: prefix,
924
+ Delimiter: "/",
925
+ MaxKeys: pageSize,
926
+ ContinuationToken: continuationToken
927
+ })
928
+ );
929
+ if (currentPage === pageNumber) {
930
+ resultFiles = ((_a2 = result.Contents) != null ? _a2 : []).filter((v) => v).map(
931
+ (content) => {
932
+ var _a3, _b2;
933
+ return __spreadProps(__spreadValues({}, content), {
934
+ Name: (_b2 = (_a3 = content.Key) == null ? void 0 : _a3.replace(prefix, "")) != null ? _b2 : content.Key,
935
+ Location: `${this.link}${content.Key}`,
936
+ LastModified: content.LastModified ? new Date(content.LastModified) : null
937
+ });
938
+ }
939
+ ).filter((content) => content.Name);
940
+ }
941
+ continuationToken = result.NextContinuationToken;
942
+ if (!result.IsTruncated || !continuationToken) {
943
+ break;
944
+ }
945
+ currentPage++;
946
+ }
947
+ (_b = this.logger) == null ? void 0 : _b.debug(null, "file list info paginated", {
948
+ prefix,
949
+ pageNumber,
950
+ pageSize,
951
+ fileCount: resultFiles.length
952
+ });
953
+ return {
954
+ files: resultFiles,
955
+ totalFetched: resultFiles.length
956
+ };
957
+ });
958
+ }
851
959
  taggingFile(filePath, tagVersion = "1.0.0") {
852
960
  return __async(this, null, function* () {
853
961
  try {
854
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
855
- if (!normalizedKey || normalizedKey === "/") {
856
- throw new Error("No file key provided");
857
- }
962
+ const normalizedKey = getNormalizedPath(filePath);
963
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
858
964
  const command = new import_client_s3.PutObjectTaggingCommand({
859
965
  Bucket: this.bucket,
860
966
  Key: normalizedKey,
@@ -870,10 +976,8 @@ var S3BucketUtil = class _S3BucketUtil {
870
976
  fileVersion(filePath) {
871
977
  return __async(this, null, function* () {
872
978
  var _a2, _b;
873
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
874
- if (!normalizedKey || normalizedKey === "/") {
875
- throw new Error("No file key provided");
876
- }
979
+ const normalizedKey = getNormalizedPath(filePath);
980
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
877
981
  const command = new import_client_s3.GetObjectTaggingCommand({ Bucket: this.bucket, Key: normalizedKey });
878
982
  const result = yield this.execute(command);
879
983
  const tag = (_a2 = result.TagSet) == null ? void 0 : _a2.find((tag2) => tag2.Key === "version");
@@ -883,10 +987,8 @@ var S3BucketUtil = class _S3BucketUtil {
883
987
  fileUrl(filePath, expiresIn = "15m") {
884
988
  return __async(this, null, function* () {
885
989
  var _a2;
886
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
887
- if (!normalizedKey || normalizedKey === "/") {
888
- throw new Error("No file key provided");
889
- }
990
+ const normalizedKey = getNormalizedPath(filePath);
991
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
890
992
  const expiresInSeconds = typeof expiresIn === "number" ? expiresIn : (0, import_ms.default)(expiresIn) / 1e3;
891
993
  const command = new import_client_s3.GetObjectCommand({ Bucket: this.bucket, Key: normalizedKey });
892
994
  const url = yield (0, import_s3_request_presigner.getSignedUrl)(this.s3Client, command, {
@@ -900,10 +1002,8 @@ var S3BucketUtil = class _S3BucketUtil {
900
1002
  sizeOf(filePath, unit = "bytes") {
901
1003
  return __async(this, null, function* () {
902
1004
  var _a2, _b, _c;
903
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
904
- if (!normalizedKey || normalizedKey === "/") {
905
- throw new Error("No file key provided");
906
- }
1005
+ const normalizedKey = getNormalizedPath(filePath);
1006
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
907
1007
  try {
908
1008
  const command = new import_client_s3.HeadObjectCommand({ Bucket: this.bucket, Key: normalizedKey });
909
1009
  const headObject = yield this.execute(command);
@@ -931,10 +1031,8 @@ var S3BucketUtil = class _S3BucketUtil {
931
1031
  return __async(this, null, function* () {
932
1032
  var _a2;
933
1033
  try {
934
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
935
- if (!normalizedKey || normalizedKey === "/") {
936
- throw new Error("No file key provided");
937
- }
1034
+ const normalizedKey = getNormalizedPath(filePath);
1035
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
938
1036
  const command = new import_client_s3.HeadObjectCommand({ Bucket: this.bucket, Key: normalizedKey });
939
1037
  yield this.execute(command);
940
1038
  return true;
@@ -948,10 +1046,8 @@ var S3BucketUtil = class _S3BucketUtil {
948
1046
  }
949
1047
  fileContent(filePath, format = "buffer") {
950
1048
  return __async(this, null, function* () {
951
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
952
- if (!normalizedKey || normalizedKey === "/") {
953
- throw new Error("No file key provided");
954
- }
1049
+ const normalizedKey = getNormalizedPath(filePath);
1050
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
955
1051
  const command = new import_client_s3.GetObjectCommand({ Bucket: this.bucket, Key: normalizedKey });
956
1052
  const result = yield this.execute(command);
957
1053
  if (!result.Body) {
@@ -983,10 +1079,8 @@ var S3BucketUtil = class _S3BucketUtil {
983
1079
  }
984
1080
  uploadFile(_0, _1) {
985
1081
  return __async(this, arguments, function* (filePath, fileData, acl = "private" /* private */, version = "1.0.0") {
986
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
987
- if (!normalizedKey || normalizedKey === "/") {
988
- throw new Error("No file key provided");
989
- }
1082
+ const normalizedKey = getNormalizedPath(filePath);
1083
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
990
1084
  const upload = new import_lib_storage.Upload({
991
1085
  client: this.s3Client,
992
1086
  params: {
@@ -1008,10 +1102,8 @@ var S3BucketUtil = class _S3BucketUtil {
1008
1102
  }
1009
1103
  deleteFile(filePath) {
1010
1104
  return __async(this, null, function* () {
1011
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
1012
- if (!normalizedKey || normalizedKey === "/") {
1013
- throw new Error("No file key provided");
1014
- }
1105
+ const normalizedKey = getNormalizedPath(filePath);
1106
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
1015
1107
  const command = new import_client_s3.DeleteObjectCommand({ Bucket: this.bucket, Key: normalizedKey });
1016
1108
  return yield this.execute(command);
1017
1109
  });
@@ -1023,10 +1115,8 @@ var S3BucketUtil = class _S3BucketUtil {
1023
1115
  checkFileExists = true,
1024
1116
  abortSignal
1025
1117
  } = {}) {
1026
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
1027
- if (!normalizedKey || normalizedKey === "/") {
1028
- throw new Error("No file key provided");
1029
- }
1118
+ const normalizedKey = getNormalizedPath(filePath);
1119
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
1030
1120
  if (checkFileExists) {
1031
1121
  const isExists = yield this.fileExists(normalizedKey);
1032
1122
  if (!isExists) return null;
@@ -1049,10 +1139,8 @@ var S3BucketUtil = class _S3BucketUtil {
1049
1139
  abortSignal
1050
1140
  }) {
1051
1141
  var _a2;
1052
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
1053
- if (!normalizedKey || normalizedKey === "/") {
1054
- throw new Error("No file key provided");
1055
- }
1142
+ const normalizedKey = getNormalizedPath(filePath);
1143
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
1056
1144
  try {
1057
1145
  const cmd = new import_client_s3.GetObjectCommand(__spreadValues({
1058
1146
  Bucket: this.bucket,
@@ -1091,9 +1179,7 @@ var S3BucketUtil = class _S3BucketUtil {
1091
1179
  }) {
1092
1180
  return (req, res, next) => __async(this, null, function* () {
1093
1181
  var _a2, _b, _c, _d, _e;
1094
- const filePaths = [].concat(filePath).map((filePath2) => {
1095
- return decodeURIComponent((filePath2 == null ? void 0 : filePath2.replace(/^\//, "").replace(/\/$/, "")) || "");
1096
- }).filter((v) => v && v !== "/");
1182
+ const filePaths = [].concat(filePath).map((filePath2) => getNormalizedPath(filePath2)).filter((v) => v && v !== "/");
1097
1183
  if (!filePaths.length) {
1098
1184
  throw new Error("No file keys provided");
1099
1185
  }
@@ -1234,10 +1320,8 @@ var S3BucketUtil = class _S3BucketUtil {
1234
1320
  (_a3 = stream == null ? void 0 : stream.destroy) == null ? void 0 : _a3.call(stream);
1235
1321
  };
1236
1322
  req.once("close", onClose);
1237
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
1238
- if (!normalizedKey || normalizedKey === "/") {
1239
- throw new Error("No file key provided");
1240
- }
1323
+ const normalizedKey = getNormalizedPath(filePath);
1324
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
1241
1325
  try {
1242
1326
  const isExists = yield this.fileExists(normalizedKey);
1243
1327
  if (!isExists) {
@@ -1308,10 +1392,8 @@ var S3BucketUtil = class _S3BucketUtil {
1308
1392
  }) {
1309
1393
  return (req, res, next) => __async(this, null, function* () {
1310
1394
  var _a2, _b, _c, _d, _e, _f;
1311
- const normalizedKey = decodeURIComponent((fileKey == null ? void 0 : fileKey.replace(/^\//, "").replace(/\/$/, "")) || "");
1312
- if (!normalizedKey || normalizedKey === "/") {
1313
- throw new Error("No file key provided");
1314
- }
1395
+ const normalizedKey = getNormalizedPath(fileKey);
1396
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
1315
1397
  const isExists = yield this.fileExists(normalizedKey);
1316
1398
  const fileSize = yield this.sizeOf(normalizedKey);
1317
1399
  let Range;
@@ -1439,7 +1521,7 @@ var S3BucketUtil = class _S3BucketUtil {
1439
1521
  }
1440
1522
  return fileSize;
1441
1523
  }
1442
- getUploadFileMW(directory, {
1524
+ getUploadFileMW(directoryPath, {
1443
1525
  acl = "private" /* private */,
1444
1526
  maxFileSize,
1445
1527
  filename: _filename,
@@ -1447,8 +1529,8 @@ var S3BucketUtil = class _S3BucketUtil {
1447
1529
  fileExt = [],
1448
1530
  metadata: customMetadata
1449
1531
  } = {}) {
1450
- let normalizedPath = decodeURIComponent((directory == null ? void 0 : directory.replace(/^\//, "").replace(/\/$/, "")) || "");
1451
- if (directory !== "/" && directory !== "" && directory !== void 0) normalizedPath += "/";
1532
+ let normalizedPath = getNormalizedPath(directoryPath);
1533
+ if (normalizedPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
1452
1534
  else normalizedPath = "";
1453
1535
  const fileSize = this.getFileSize(maxFileSize);
1454
1536
  const fileTypes = [].concat(fileType);
package/dist/index.d.cts CHANGED
@@ -179,6 +179,14 @@ declare class S3BucketUtil {
179
179
  directories: string[];
180
180
  files: ContentFile[];
181
181
  }>;
182
+ directoryListPaginated(directoryPath?: string, { pageSize, pageNumber, }?: {
183
+ pageSize?: number;
184
+ pageNumber?: number;
185
+ }): Promise<{
186
+ directories: string[];
187
+ files: ContentFile[];
188
+ totalFetched: number;
189
+ }>;
182
190
  /**
183
191
  * Get all files recursively (example for search/indexing)
184
192
  * @param directoryPath
@@ -220,7 +228,20 @@ declare class S3BucketUtil {
220
228
  */
221
229
  directoryTree(directoryPath?: string): Promise<TreeDirectoryItem>;
222
230
  fileInfo(filePath: string): Promise<HeadObjectCommandOutput>;
223
- fileListInfo(directoryPath?: string, fileNamePrefix?: string): Promise<ContentFile[]>;
231
+ fileListInfo(directoryPath?: string, fileNamePrefix?: string): Promise<(ContentFile & {
232
+ Location: string;
233
+ })[]>;
234
+ fileListInfoPaginated(directoryPath?: string, { fileNamePrefix, pageNumber, // 0-based: page 0 = items 0-99, page 1 = items 100-199, page 2 = items 200-299
235
+ pageSize, }?: {
236
+ fileNamePrefix?: string;
237
+ pageSize?: number;
238
+ pageNumber?: number;
239
+ }): Promise<{
240
+ files: (ContentFile & {
241
+ Location: string;
242
+ })[];
243
+ totalFetched: number;
244
+ }>;
224
245
  taggingFile(filePath: string, tagVersion?: string): Promise<boolean>;
225
246
  fileVersion(filePath: string): Promise<string>;
226
247
  fileUrl(filePath: string, expiresIn?: number | StringValue): Promise<string>;
@@ -249,7 +270,7 @@ declare class S3BucketUtil {
249
270
  }): Promise<(req: Request$1 & any, res: Response & any, next: NextFunction & any) => Promise<any>>;
250
271
  private static fileFilter;
251
272
  private getFileSize;
252
- getUploadFileMW(directory?: string, { acl, maxFileSize, filename: _filename, fileType, fileExt, metadata: customMetadata, }?: S3UploadOptions): Multer;
273
+ getUploadFileMW(directoryPath?: string, { acl, maxFileSize, filename: _filename, fileType, fileExt, metadata: customMetadata, }?: S3UploadOptions): Multer;
253
274
  /**
254
275
  * Middleware for uploading a single file
255
276
  * Adds the uploaded file info to req.s3File
package/dist/index.d.ts CHANGED
@@ -179,6 +179,14 @@ declare class S3BucketUtil {
179
179
  directories: string[];
180
180
  files: ContentFile[];
181
181
  }>;
182
+ directoryListPaginated(directoryPath?: string, { pageSize, pageNumber, }?: {
183
+ pageSize?: number;
184
+ pageNumber?: number;
185
+ }): Promise<{
186
+ directories: string[];
187
+ files: ContentFile[];
188
+ totalFetched: number;
189
+ }>;
182
190
  /**
183
191
  * Get all files recursively (example for search/indexing)
184
192
  * @param directoryPath
@@ -220,7 +228,20 @@ declare class S3BucketUtil {
220
228
  */
221
229
  directoryTree(directoryPath?: string): Promise<TreeDirectoryItem>;
222
230
  fileInfo(filePath: string): Promise<HeadObjectCommandOutput>;
223
- fileListInfo(directoryPath?: string, fileNamePrefix?: string): Promise<ContentFile[]>;
231
+ fileListInfo(directoryPath?: string, fileNamePrefix?: string): Promise<(ContentFile & {
232
+ Location: string;
233
+ })[]>;
234
+ fileListInfoPaginated(directoryPath?: string, { fileNamePrefix, pageNumber, // 0-based: page 0 = items 0-99, page 1 = items 100-199, page 2 = items 200-299
235
+ pageSize, }?: {
236
+ fileNamePrefix?: string;
237
+ pageSize?: number;
238
+ pageNumber?: number;
239
+ }): Promise<{
240
+ files: (ContentFile & {
241
+ Location: string;
242
+ })[];
243
+ totalFetched: number;
244
+ }>;
224
245
  taggingFile(filePath: string, tagVersion?: string): Promise<boolean>;
225
246
  fileVersion(filePath: string): Promise<string>;
226
247
  fileUrl(filePath: string, expiresIn?: number | StringValue): Promise<string>;
@@ -249,7 +270,7 @@ declare class S3BucketUtil {
249
270
  }): Promise<(req: Request$1 & any, res: Response & any, next: NextFunction & any) => Promise<any>>;
250
271
  private static fileFilter;
251
272
  private getFileSize;
252
- getUploadFileMW(directory?: string, { acl, maxFileSize, filename: _filename, fileType, fileExt, metadata: customMetadata, }?: S3UploadOptions): Multer;
273
+ getUploadFileMW(directoryPath?: string, { acl, maxFileSize, filename: _filename, fileType, fileExt, metadata: customMetadata, }?: S3UploadOptions): Multer;
253
274
  /**
254
275
  * Middleware for uploading a single file
255
276
  * Adds the uploaded file info to req.s3File
package/dist/index.js CHANGED
@@ -282,6 +282,7 @@ var parseRangeHeader = (range, contentLength, chunkSize) => {
282
282
  }
283
283
  return [start, Math.min(end, end)];
284
284
  };
285
+ var getNormalizedPath = (directoryPath) => decodeURIComponent((directoryPath == null ? void 0 : directoryPath.replace(/^\/+/, "").replace(/\/+$/, "")) || "");
285
286
  var S3BucketUtil = class _S3BucketUtil {
286
287
  constructor({
287
288
  logger: logger2,
@@ -590,7 +591,7 @@ var S3BucketUtil = class _S3BucketUtil {
590
591
  // ##### DIRECTORY BLOCK ##########################
591
592
  createDirectory(directoryPath) {
592
593
  return __async(this, null, function* () {
593
- let normalizedPath = decodeURIComponent((directoryPath == null ? void 0 : directoryPath.replace(/^\//, "").replace(/\/$/, "")) || "");
594
+ let normalizedPath = getNormalizedPath(directoryPath);
594
595
  if (!normalizedPath) throw new Error("No directory path provided");
595
596
  if (normalizedPath === "/") normalizedPath = "";
596
597
  const command = new PutObjectCommand({ Bucket: this.bucket, Key: `${normalizedPath}/` });
@@ -601,10 +602,8 @@ var S3BucketUtil = class _S3BucketUtil {
601
602
  deleteDirectory(directoryPath) {
602
603
  return __async(this, null, function* () {
603
604
  var _a2, _b, _c, _d, _e, _f, _g;
604
- let normalizedPath = decodeURIComponent((directoryPath == null ? void 0 : directoryPath.replace(/^\//, "").replace(/\/$/, "")) || "");
605
- if (!normalizedPath) {
606
- throw new Error("No directory path provided");
607
- }
605
+ let normalizedPath = getNormalizedPath(directoryPath);
606
+ if (!normalizedPath) throw new Error("No directory path provided");
608
607
  if (normalizedPath === "/") normalizedPath = "";
609
608
  let totalDeletedCount = 0;
610
609
  let ContinuationToken = void 0;
@@ -671,8 +670,8 @@ var S3BucketUtil = class _S3BucketUtil {
671
670
  }
672
671
  directoryList(directoryPath) {
673
672
  return __async(this, null, function* () {
674
- let normalizedPath = decodeURIComponent((directoryPath == null ? void 0 : directoryPath.replace(/^\//, "").replace(/\/$/, "")) || "");
675
- if (directoryPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
673
+ let normalizedPath = getNormalizedPath(directoryPath);
674
+ if (normalizedPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
676
675
  else normalizedPath = "";
677
676
  const result = yield this.execute(
678
677
  new ListObjectsV2Command({
@@ -691,19 +690,70 @@ var S3BucketUtil = class _S3BucketUtil {
691
690
  return content.Key !== normalizedPath && !((_a2 = content.Key) == null ? void 0 : _a2.endsWith("/"));
692
691
  }).map((content) => __spreadProps(__spreadValues({}, content), {
693
692
  Name: content.Key.replace(normalizedPath, "") || content.Key,
693
+ Location: `${this.link}${content.Key}`,
694
694
  LastModified: new Date(content.LastModified)
695
695
  }));
696
696
  return { directories, files };
697
697
  });
698
698
  }
699
+ directoryListPaginated(_0) {
700
+ return __async(this, arguments, function* (directoryPath, {
701
+ pageSize = 100,
702
+ pageNumber = 0
703
+ // 0-based: page 0 = items 0-99, page 1 = items 100-199, page 2 = items 200-299
704
+ } = {}) {
705
+ let normalizedPath = getNormalizedPath(directoryPath);
706
+ if (normalizedPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
707
+ else normalizedPath = "";
708
+ let continuationToken = void 0;
709
+ let currentPage = 0;
710
+ let allDirectories = [];
711
+ let allFiles = [];
712
+ while (currentPage <= pageNumber) {
713
+ const result = yield this.execute(
714
+ new ListObjectsV2Command({
715
+ Bucket: this.bucket,
716
+ Prefix: normalizedPath,
717
+ Delimiter: "/",
718
+ MaxKeys: pageSize,
719
+ ContinuationToken: continuationToken
720
+ })
721
+ );
722
+ if (currentPage === pageNumber) {
723
+ allDirectories = (result.CommonPrefixes || []).map((prefix) => prefix.Prefix).map((prefix) => {
724
+ const relativePath = prefix.replace(normalizedPath, "");
725
+ return relativePath.replace(/\/$/, "");
726
+ }).filter((dir) => dir);
727
+ allFiles = (result.Contents || []).filter((content) => {
728
+ var _a2;
729
+ return content.Key !== normalizedPath && !((_a2 = content.Key) == null ? void 0 : _a2.endsWith("/"));
730
+ }).map((content) => __spreadProps(__spreadValues({}, content), {
731
+ Name: content.Key.replace(normalizedPath, "") || content.Key,
732
+ Location: `${this.link}${content.Key}`,
733
+ LastModified: new Date(content.LastModified)
734
+ }));
735
+ }
736
+ continuationToken = result.NextContinuationToken;
737
+ if (!result.IsTruncated || !continuationToken) {
738
+ break;
739
+ }
740
+ currentPage++;
741
+ }
742
+ return {
743
+ directories: allDirectories,
744
+ files: allFiles,
745
+ totalFetched: allFiles.length + allDirectories.length
746
+ };
747
+ });
748
+ }
699
749
  /**
700
750
  * Get all files recursively (example for search/indexing)
701
751
  * @param directoryPath
702
752
  */
703
753
  directoryListRecursive(directoryPath) {
704
754
  return __async(this, null, function* () {
705
- let normalizedPath = decodeURIComponent((directoryPath == null ? void 0 : directoryPath.replace(/^\//, "").replace(/\/$/, "")) || "");
706
- if (directoryPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
755
+ let normalizedPath = getNormalizedPath(directoryPath);
756
+ if (normalizedPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
707
757
  else normalizedPath = "";
708
758
  const allDirectories = [];
709
759
  const allFiles = [];
@@ -726,6 +776,7 @@ var S3BucketUtil = class _S3BucketUtil {
726
776
  allFiles.push(__spreadProps(__spreadValues({}, content), {
727
777
  Name: filename,
728
778
  Path: fullPath,
779
+ Location: `${this.link}${content.Key}`,
729
780
  LastModified: new Date(content.LastModified)
730
781
  }));
731
782
  }
@@ -767,7 +818,7 @@ var S3BucketUtil = class _S3BucketUtil {
767
818
  */
768
819
  directoryTree(directoryPath) {
769
820
  return __async(this, null, function* () {
770
- let normalizedPath = decodeURIComponent((directoryPath == null ? void 0 : directoryPath.replace(/^\//, "").replace(/\/$/, "")) || "");
821
+ let normalizedPath = getNormalizedPath(directoryPath);
771
822
  const lastDirectory = directoryPath == null ? void 0 : directoryPath.split("/").pop();
772
823
  const { directories, files } = yield this.directoryList(normalizedPath);
773
824
  if (directoryPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
@@ -782,6 +833,7 @@ var S3BucketUtil = class _S3BucketUtil {
782
833
  treeNode.children.push({
783
834
  path: "/" + file.Key,
784
835
  name: file.Name,
836
+ location: `${this.link}${file.Key}`,
785
837
  type: "file",
786
838
  size: file.Size,
787
839
  lastModified: file.LastModified
@@ -798,7 +850,7 @@ var S3BucketUtil = class _S3BucketUtil {
798
850
  // ##### FILES BLOCK ##########################
799
851
  fileInfo(filePath) {
800
852
  return __async(this, null, function* () {
801
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
853
+ const normalizedKey = getNormalizedPath(filePath);
802
854
  if (!normalizedKey || normalizedKey === "/") {
803
855
  throw new Error("No file key provided");
804
856
  }
@@ -809,8 +861,8 @@ var S3BucketUtil = class _S3BucketUtil {
809
861
  fileListInfo(directoryPath, fileNamePrefix) {
810
862
  return __async(this, null, function* () {
811
863
  var _a2, _b;
812
- let normalizedPath = decodeURIComponent((directoryPath == null ? void 0 : directoryPath.replace(/^\//, "").replace(/\/$/, "")) || "");
813
- if (directoryPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
864
+ let normalizedPath = getNormalizedPath(directoryPath);
865
+ if (normalizedPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
814
866
  else normalizedPath = "";
815
867
  const prefix = normalizedPath + (fileNamePrefix || "");
816
868
  const command = new ListObjectsCommand({
@@ -824,6 +876,7 @@ var S3BucketUtil = class _S3BucketUtil {
824
876
  var _a3, _b2;
825
877
  return __spreadProps(__spreadValues({}, content), {
826
878
  Name: (_b2 = (_a3 = content.Key) == null ? void 0 : _a3.replace(prefix, "")) != null ? _b2 : content.Key,
879
+ Location: `${this.link}${content.Key}`,
827
880
  LastModified: content.LastModified ? new Date(content.LastModified) : null
828
881
  });
829
882
  }
@@ -832,13 +885,66 @@ var S3BucketUtil = class _S3BucketUtil {
832
885
  return files;
833
886
  });
834
887
  }
888
+ fileListInfoPaginated(_0) {
889
+ return __async(this, arguments, function* (directoryPath, {
890
+ fileNamePrefix,
891
+ pageNumber = 0,
892
+ // 0-based: page 0 = items 0-99, page 1 = items 100-199, page 2 = items 200-299
893
+ pageSize = 100
894
+ } = {}) {
895
+ var _a2, _b;
896
+ let normalizedPath = getNormalizedPath(directoryPath);
897
+ if (normalizedPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
898
+ else normalizedPath = "";
899
+ const prefix = normalizedPath + (fileNamePrefix || "");
900
+ let continuationToken;
901
+ let currentPage = 0;
902
+ let resultFiles = [];
903
+ while (currentPage <= pageNumber) {
904
+ const result = yield this.execute(
905
+ new ListObjectsV2Command({
906
+ Bucket: this.bucket,
907
+ Prefix: prefix,
908
+ Delimiter: "/",
909
+ MaxKeys: pageSize,
910
+ ContinuationToken: continuationToken
911
+ })
912
+ );
913
+ if (currentPage === pageNumber) {
914
+ resultFiles = ((_a2 = result.Contents) != null ? _a2 : []).filter((v) => v).map(
915
+ (content) => {
916
+ var _a3, _b2;
917
+ return __spreadProps(__spreadValues({}, content), {
918
+ Name: (_b2 = (_a3 = content.Key) == null ? void 0 : _a3.replace(prefix, "")) != null ? _b2 : content.Key,
919
+ Location: `${this.link}${content.Key}`,
920
+ LastModified: content.LastModified ? new Date(content.LastModified) : null
921
+ });
922
+ }
923
+ ).filter((content) => content.Name);
924
+ }
925
+ continuationToken = result.NextContinuationToken;
926
+ if (!result.IsTruncated || !continuationToken) {
927
+ break;
928
+ }
929
+ currentPage++;
930
+ }
931
+ (_b = this.logger) == null ? void 0 : _b.debug(null, "file list info paginated", {
932
+ prefix,
933
+ pageNumber,
934
+ pageSize,
935
+ fileCount: resultFiles.length
936
+ });
937
+ return {
938
+ files: resultFiles,
939
+ totalFetched: resultFiles.length
940
+ };
941
+ });
942
+ }
835
943
  taggingFile(filePath, tagVersion = "1.0.0") {
836
944
  return __async(this, null, function* () {
837
945
  try {
838
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
839
- if (!normalizedKey || normalizedKey === "/") {
840
- throw new Error("No file key provided");
841
- }
946
+ const normalizedKey = getNormalizedPath(filePath);
947
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
842
948
  const command = new PutObjectTaggingCommand({
843
949
  Bucket: this.bucket,
844
950
  Key: normalizedKey,
@@ -854,10 +960,8 @@ var S3BucketUtil = class _S3BucketUtil {
854
960
  fileVersion(filePath) {
855
961
  return __async(this, null, function* () {
856
962
  var _a2, _b;
857
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
858
- if (!normalizedKey || normalizedKey === "/") {
859
- throw new Error("No file key provided");
860
- }
963
+ const normalizedKey = getNormalizedPath(filePath);
964
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
861
965
  const command = new GetObjectTaggingCommand({ Bucket: this.bucket, Key: normalizedKey });
862
966
  const result = yield this.execute(command);
863
967
  const tag = (_a2 = result.TagSet) == null ? void 0 : _a2.find((tag2) => tag2.Key === "version");
@@ -867,10 +971,8 @@ var S3BucketUtil = class _S3BucketUtil {
867
971
  fileUrl(filePath, expiresIn = "15m") {
868
972
  return __async(this, null, function* () {
869
973
  var _a2;
870
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
871
- if (!normalizedKey || normalizedKey === "/") {
872
- throw new Error("No file key provided");
873
- }
974
+ const normalizedKey = getNormalizedPath(filePath);
975
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
874
976
  const expiresInSeconds = typeof expiresIn === "number" ? expiresIn : ms(expiresIn) / 1e3;
875
977
  const command = new GetObjectCommand({ Bucket: this.bucket, Key: normalizedKey });
876
978
  const url = yield getSignedUrl(this.s3Client, command, {
@@ -884,10 +986,8 @@ var S3BucketUtil = class _S3BucketUtil {
884
986
  sizeOf(filePath, unit = "bytes") {
885
987
  return __async(this, null, function* () {
886
988
  var _a2, _b, _c;
887
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
888
- if (!normalizedKey || normalizedKey === "/") {
889
- throw new Error("No file key provided");
890
- }
989
+ const normalizedKey = getNormalizedPath(filePath);
990
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
891
991
  try {
892
992
  const command = new HeadObjectCommand({ Bucket: this.bucket, Key: normalizedKey });
893
993
  const headObject = yield this.execute(command);
@@ -915,10 +1015,8 @@ var S3BucketUtil = class _S3BucketUtil {
915
1015
  return __async(this, null, function* () {
916
1016
  var _a2;
917
1017
  try {
918
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
919
- if (!normalizedKey || normalizedKey === "/") {
920
- throw new Error("No file key provided");
921
- }
1018
+ const normalizedKey = getNormalizedPath(filePath);
1019
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
922
1020
  const command = new HeadObjectCommand({ Bucket: this.bucket, Key: normalizedKey });
923
1021
  yield this.execute(command);
924
1022
  return true;
@@ -932,10 +1030,8 @@ var S3BucketUtil = class _S3BucketUtil {
932
1030
  }
933
1031
  fileContent(filePath, format = "buffer") {
934
1032
  return __async(this, null, function* () {
935
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
936
- if (!normalizedKey || normalizedKey === "/") {
937
- throw new Error("No file key provided");
938
- }
1033
+ const normalizedKey = getNormalizedPath(filePath);
1034
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
939
1035
  const command = new GetObjectCommand({ Bucket: this.bucket, Key: normalizedKey });
940
1036
  const result = yield this.execute(command);
941
1037
  if (!result.Body) {
@@ -967,10 +1063,8 @@ var S3BucketUtil = class _S3BucketUtil {
967
1063
  }
968
1064
  uploadFile(_0, _1) {
969
1065
  return __async(this, arguments, function* (filePath, fileData, acl = "private" /* private */, version = "1.0.0") {
970
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
971
- if (!normalizedKey || normalizedKey === "/") {
972
- throw new Error("No file key provided");
973
- }
1066
+ const normalizedKey = getNormalizedPath(filePath);
1067
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
974
1068
  const upload = new Upload({
975
1069
  client: this.s3Client,
976
1070
  params: {
@@ -992,10 +1086,8 @@ var S3BucketUtil = class _S3BucketUtil {
992
1086
  }
993
1087
  deleteFile(filePath) {
994
1088
  return __async(this, null, function* () {
995
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
996
- if (!normalizedKey || normalizedKey === "/") {
997
- throw new Error("No file key provided");
998
- }
1089
+ const normalizedKey = getNormalizedPath(filePath);
1090
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
999
1091
  const command = new DeleteObjectCommand({ Bucket: this.bucket, Key: normalizedKey });
1000
1092
  return yield this.execute(command);
1001
1093
  });
@@ -1007,10 +1099,8 @@ var S3BucketUtil = class _S3BucketUtil {
1007
1099
  checkFileExists = true,
1008
1100
  abortSignal
1009
1101
  } = {}) {
1010
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
1011
- if (!normalizedKey || normalizedKey === "/") {
1012
- throw new Error("No file key provided");
1013
- }
1102
+ const normalizedKey = getNormalizedPath(filePath);
1103
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
1014
1104
  if (checkFileExists) {
1015
1105
  const isExists = yield this.fileExists(normalizedKey);
1016
1106
  if (!isExists) return null;
@@ -1033,10 +1123,8 @@ var S3BucketUtil = class _S3BucketUtil {
1033
1123
  abortSignal
1034
1124
  }) {
1035
1125
  var _a2;
1036
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
1037
- if (!normalizedKey || normalizedKey === "/") {
1038
- throw new Error("No file key provided");
1039
- }
1126
+ const normalizedKey = getNormalizedPath(filePath);
1127
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
1040
1128
  try {
1041
1129
  const cmd = new GetObjectCommand(__spreadValues({
1042
1130
  Bucket: this.bucket,
@@ -1075,9 +1163,7 @@ var S3BucketUtil = class _S3BucketUtil {
1075
1163
  }) {
1076
1164
  return (req, res, next) => __async(this, null, function* () {
1077
1165
  var _a2, _b, _c, _d, _e;
1078
- const filePaths = [].concat(filePath).map((filePath2) => {
1079
- return decodeURIComponent((filePath2 == null ? void 0 : filePath2.replace(/^\//, "").replace(/\/$/, "")) || "");
1080
- }).filter((v) => v && v !== "/");
1166
+ const filePaths = [].concat(filePath).map((filePath2) => getNormalizedPath(filePath2)).filter((v) => v && v !== "/");
1081
1167
  if (!filePaths.length) {
1082
1168
  throw new Error("No file keys provided");
1083
1169
  }
@@ -1218,10 +1304,8 @@ var S3BucketUtil = class _S3BucketUtil {
1218
1304
  (_a3 = stream == null ? void 0 : stream.destroy) == null ? void 0 : _a3.call(stream);
1219
1305
  };
1220
1306
  req.once("close", onClose);
1221
- const normalizedKey = decodeURIComponent((filePath == null ? void 0 : filePath.replace(/^\//, "").replace(/\/$/, "")) || "");
1222
- if (!normalizedKey || normalizedKey === "/") {
1223
- throw new Error("No file key provided");
1224
- }
1307
+ const normalizedKey = getNormalizedPath(filePath);
1308
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
1225
1309
  try {
1226
1310
  const isExists = yield this.fileExists(normalizedKey);
1227
1311
  if (!isExists) {
@@ -1292,10 +1376,8 @@ var S3BucketUtil = class _S3BucketUtil {
1292
1376
  }) {
1293
1377
  return (req, res, next) => __async(this, null, function* () {
1294
1378
  var _a2, _b, _c, _d, _e, _f;
1295
- const normalizedKey = decodeURIComponent((fileKey == null ? void 0 : fileKey.replace(/^\//, "").replace(/\/$/, "")) || "");
1296
- if (!normalizedKey || normalizedKey === "/") {
1297
- throw new Error("No file key provided");
1298
- }
1379
+ const normalizedKey = getNormalizedPath(fileKey);
1380
+ if (!normalizedKey || normalizedKey === "/") throw new Error("No file key provided");
1299
1381
  const isExists = yield this.fileExists(normalizedKey);
1300
1382
  const fileSize = yield this.sizeOf(normalizedKey);
1301
1383
  let Range;
@@ -1423,7 +1505,7 @@ var S3BucketUtil = class _S3BucketUtil {
1423
1505
  }
1424
1506
  return fileSize;
1425
1507
  }
1426
- getUploadFileMW(directory, {
1508
+ getUploadFileMW(directoryPath, {
1427
1509
  acl = "private" /* private */,
1428
1510
  maxFileSize,
1429
1511
  filename: _filename,
@@ -1431,8 +1513,8 @@ var S3BucketUtil = class _S3BucketUtil {
1431
1513
  fileExt = [],
1432
1514
  metadata: customMetadata
1433
1515
  } = {}) {
1434
- let normalizedPath = decodeURIComponent((directory == null ? void 0 : directory.replace(/^\//, "").replace(/\/$/, "")) || "");
1435
- if (directory !== "/" && directory !== "" && directory !== void 0) normalizedPath += "/";
1516
+ let normalizedPath = getNormalizedPath(directoryPath);
1517
+ if (normalizedPath !== "/" && directoryPath !== "" && directoryPath !== void 0) normalizedPath += "/";
1436
1518
  else normalizedPath = "";
1437
1519
  const fileSize = this.getFileSize(maxFileSize);
1438
1520
  const fileTypes = [].concat(fileType);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hdriel/aws-utils",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
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",
@@ -31,7 +31,7 @@
31
31
  "build:watch": "tsc --watch",
32
32
  "format": "prettier --write .",
33
33
  "clean": "rimraf ./dist",
34
- "yalc:publish": "pnpm run build && yalc publish --private --push && cd demo && npm run yalc:attach",
34
+ "yalc:publish": "pnpm run build && yalc publish --private --push && cd demo && pnpm add @hdriel/aws-utils && cd ../demo && npm run yalc:attach",
35
35
  "docker:localstack:restart": "cross-env NODE_ENV=localhost && docker-compose -f docker-compose.localstack.yml --env-file .env.local up -d --build",
36
36
  "docker:localstack:down": "docker-compose -f docker-compose.localstack.yml down"
37
37
  },