@qrvey/object-storage 0.0.7 → 0.0.9-beta

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.
@@ -1,4 +1,6 @@
1
1
  import stream, { Readable } from 'stream';
2
+ import { ContainerGetPropertiesResponse } from '@azure/storage-blob';
3
+ import { HeadBucketCommandOutput } from '@aws-sdk/client-s3';
2
4
 
3
5
  type UploadResponse = {
4
6
  key: string;
@@ -51,6 +53,8 @@ type CreateUploadWriteStreamResponse = {
51
53
  promise: Promise<unknown>;
52
54
  };
53
55
 
56
+ type HeadBucketResponse = HeadBucketCommandOutput | ContainerGetPropertiesResponse;
57
+
54
58
  interface IObjectStorage {
55
59
  list(options: ListRequestOptions): Promise<ListResponse>;
56
60
  listAll(options: ListRequestOptions): Promise<ListResponse>;
@@ -63,6 +67,10 @@ interface IObjectStorage {
63
67
  }): Promise<UploadResponse>;
64
68
  createUploadWriteStream(key: string): CreateUploadWriteStreamResponse;
65
69
  delete(key: string): Promise<boolean>;
70
+ getHeadBucket(): Promise<HeadBucketResponse>;
71
+ uploadMultipart(key: string, file: FileContent, partNumber: number, uploadId?: string): Promise<string>;
72
+ completeMultipartUpload(key: string, uploadId: string): Promise<void>;
73
+ abortMultipartUpload(key: string, uploadId: string): Promise<void>;
66
74
  }
67
75
 
68
76
  declare class ObjectStorageService {
@@ -138,13 +146,53 @@ declare class ObjectStorageService {
138
146
  */
139
147
  static createUploadWriteStream(key: string, bucketName?: string): Promise<CreateUploadWriteStreamResponse>;
140
148
  /**
141
- * Deletes an object from the object storage service.
149
+ * Deletes an object or multiple objects from the object storage service.
142
150
  *
143
- * @param {string} key - The key of the object to delete.
144
- * @param {string} [bucketName] - The name of the bucket where the object is stored. If not provided, the default bucket name will be used.
145
- * @return {Promise<boolean>} A promise that resolves to true if the object was successfully deleted, or false otherwise.
151
+ * @param {string | string[]} key - The key or array of keys of the objects to delete.
152
+ * @param {string} [bucketName] - The name of the bucket where the objects are stored. If not provided, the default bucket name will be used.
153
+ * @return {Promise<{ key: string; deleted: boolean; error?: string }[] | boolean>} A promise that resolves to an array of objects containing the key, deleted status, and an optional error message for each object deleted, or a boolean value indicating the success of the deletion.
154
+ */
155
+ static delete(key: string | string[], bucketName?: string): Promise<{
156
+ key: string;
157
+ deleted: boolean;
158
+ error?: string;
159
+ }[] | boolean>;
160
+ /**
161
+ * Retrieves the head bucket from the object storage service.
162
+ *
163
+ * @param {string} [bucketName] - The name of the bucket. If not provided, the default bucket name will be used.
164
+ * @return {Promise<HeadBucketResponse>} A promise that resolves to the head bucket response.
165
+ */
166
+ static getHeadBucket(bucketName?: string): Promise<HeadBucketResponse>;
167
+ /**
168
+ * Uploads a multipart file to the specified bucket in the object storage service.
169
+ *
170
+ * @param {string} key - The key of the object to upload the multipart file to.
171
+ * @param {FileContent} file - The content of the file to upload.
172
+ * @param {number} partNumber - The number of the part being uploaded.
173
+ * @param {string} [uploadId] - The ID of the multipart upload.
174
+ * @param {string} [bucketName] - The name of the bucket to upload the file to. If not provided, the default bucket name will be used.
175
+ * @return {Promise<string>} A Promise that resolves to the base64 encoded block ID of the uploaded part.
176
+ */
177
+ static uploadMultipart(key: string, file: FileContent, partNumber: number, uploadId?: string, bucketName?: string): Promise<string>;
178
+ /**
179
+ * Completes a multipart upload for the specified object in the object storage service.
180
+ *
181
+ * @param {string} key - The key of the object to complete the multipart upload for.
182
+ * @param {string} uploadId - The ID of the multipart upload to complete.
183
+ * @param {string} [bucketName] - The name of the bucket to complete the multipart upload in. If not provided, the default bucket name will be used.
184
+ * @return {Promise<void>} A Promise that resolves when the multipart upload is completed.
185
+ */
186
+ static completeMultipartUpload(key: string, uploadId: string, bucketName?: string): Promise<void>;
187
+ /**
188
+ * Aborts a multipart upload for the specified object in the object storage service.
189
+ *
190
+ * @param {string} key - The key of the object to abort the multipart upload for.
191
+ * @param {string} uploadId - The ID of the multipart upload to abort.
192
+ * @param {string} [bucketName] - The name of the bucket to abort the multipart upload in. If not provided, the default bucket name will be used.
193
+ * @return {Promise<void>} A Promise that resolves when the multipart upload is aborted.
146
194
  */
147
- static delete(key: string, bucketName?: string): Promise<boolean>;
195
+ static abortMultipartUpload(key: string, uploadId: string, bucketName?: string): Promise<void>;
148
196
  }
149
197
 
150
198
  export { FileContent, GetObjectResponse, GetUploadUrlResponse, ListRequestOptions, ListResponse, ListResponseItem, ObjectStorageService, UploadResponse };
@@ -1,5 +1,5 @@
1
1
  import { BlobServiceClient, BlobSASPermissions } from '@azure/storage-blob';
2
- import { S3Client, ListObjectsV2Command, HeadObjectCommand, GetObjectCommand, PutObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3';
2
+ import { S3Client, S3, ListObjectsV2Command, HeadObjectCommand, GetObjectCommand, PutObjectCommand, DeleteObjectCommand, HeadBucketCommand } from '@aws-sdk/client-s3';
3
3
  import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
4
4
  import stream from 'stream';
5
5
  import { Upload } from '@aws-sdk/lib-storage';
@@ -23,6 +23,18 @@ var __spreadValues = (a, b) => {
23
23
  return a;
24
24
  };
25
25
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
26
+ var __objRest = (source, exclude) => {
27
+ var target = {};
28
+ for (var prop in source)
29
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
30
+ target[prop] = source[prop];
31
+ if (source != null && __getOwnPropSymbols)
32
+ for (var prop of __getOwnPropSymbols(source)) {
33
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
34
+ target[prop] = source[prop];
35
+ }
36
+ return target;
37
+ };
26
38
 
27
39
  // src/shared/utils/errorHandler.ts
28
40
  var errorMessages = {
@@ -367,6 +379,92 @@ var BlobStorageService = class {
367
379
  });
368
380
  return Promise.all(deleteBlobPromises);
369
381
  }
382
+ async getHeadBucket() {
383
+ try {
384
+ const containerClient = this.blobServiceClient.getContainerClient(
385
+ this.containerName
386
+ );
387
+ const properties = await containerClient.getProperties();
388
+ return properties;
389
+ } catch (error) {
390
+ throw new Error(
391
+ "Error in Azure getHeadContainer. Container: " + this.containerName + " Error: " + error
392
+ );
393
+ }
394
+ }
395
+ /**
396
+ * The `uploadMultipart` function in TypeScript uploads a part of a file as a block to Azure Blob
397
+ * Storage and updates the metadata with the block ID.
398
+ * @param {string} blobName - The `blobName` parameter in the `uploadMultipart` function represents
399
+ * the name of the blob (file) that you want to upload in parts to Azure Blob Storage. It is a
400
+ * string value that identifies the specific blob within the container where it will be stored.
401
+ * @param {FileContent | any} file - The `file` parameter in the `uploadMultipart` function
402
+ * represents the content of the file that you want to upload as a part of a multipart upload. It
403
+ * can be either a `FileContent` object or any other type of data that represents the content of
404
+ * the file.
405
+ * @param {number} partNumber - The `partNumber` parameter in the `uploadMultipart` function
406
+ * represents the number or index of the part being uploaded. It is used to identify and order the
407
+ * different parts of a multipart upload. Each part uploaded to the blob storage service is
408
+ * associated with a unique part number to help in reconstructing
409
+ * @returns The function `uploadMultipart` returns a Promise that resolves to a string representing
410
+ * the base64 encoded block ID of the uploaded part.
411
+ */
412
+ async uploadMultipart(blobName, file, partNumber) {
413
+ var _a;
414
+ const containerClient = this.blobServiceClient.getContainerClient(
415
+ this.containerName
416
+ );
417
+ const blobClient = containerClient.getBlockBlobClient(blobName);
418
+ const partId = partNumber.toString().padStart(6, "0");
419
+ const partIdBase64 = Buffer.from(partId).toString("base64");
420
+ await blobClient.stageBlock(partIdBase64, file, file.length);
421
+ const properties = await blobClient.getProperties();
422
+ const existingBlockIds = ((_a = properties.metadata) == null ? void 0 : _a.blockids) ? JSON.parse(properties.metadata.blockids) : [];
423
+ existingBlockIds.push(partIdBase64);
424
+ await blobClient.setMetadata({
425
+ blockids: JSON.stringify(existingBlockIds)
426
+ });
427
+ return partIdBase64;
428
+ }
429
+ /**
430
+ * The `completeMultipartUpload` function in TypeScript completes a multipart upload by committing
431
+ * the blocks to create the blob.
432
+ * @param {string} blobName - The `blobName` parameter in the `completeMultipartUpload` function is
433
+ * a string that represents the name of the blob for which the multipart upload is being completed.
434
+ */
435
+ async completeMultipartUpload(blobName) {
436
+ var _a;
437
+ const containerClient = this.blobServiceClient.getContainerClient(
438
+ this.containerName
439
+ );
440
+ const blobClient = containerClient.getBlockBlobClient(blobName);
441
+ const properties = await blobClient.getProperties();
442
+ const blockIds = ((_a = properties.metadata) == null ? void 0 : _a.blockids) ? JSON.parse(properties.metadata.blockids) : [];
443
+ if (blockIds.length === 0) {
444
+ throw new Error("No block IDs found in metadata.");
445
+ }
446
+ await blobClient.commitBlockList(blockIds);
447
+ }
448
+ /**
449
+ * This TypeScript function aborts a multipart upload by deleting the specified blob and clearing
450
+ * its block IDs metadata.
451
+ * @param {string} blobName - The `blobName` parameter is a string that represents the name of the
452
+ * blob for which the multipart upload needs to be aborted.
453
+ */
454
+ async abortMultipartUpload(blobName) {
455
+ var _a;
456
+ const containerClient = this.blobServiceClient.getContainerClient(
457
+ this.containerName
458
+ );
459
+ const blobClient = containerClient.getBlockBlobClient(blobName);
460
+ const properties = await blobClient.getProperties();
461
+ const blockIds = ((_a = properties.metadata) == null ? void 0 : _a.blockids) ? JSON.parse(properties.metadata.blockids) : [];
462
+ if (blockIds.length === 0) {
463
+ throw new Error("No block IDs found in metadata.");
464
+ }
465
+ await blobClient.setMetadata({ blockids: "" });
466
+ await blobClient.delete();
467
+ }
370
468
  };
371
469
 
372
470
  // src/services/storage/s3/s3Helpers.ts
@@ -397,8 +495,9 @@ function s3ObjectToObjectResponse(s3Object) {
397
495
  var S3StorageService = class {
398
496
  constructor(bucketName) {
399
497
  this.s3Client = new S3Client({
400
- region: process.env.AWS_REGION
498
+ region: process.env.AWS_DEFAULT_REGION
401
499
  });
500
+ this.s3 = new S3({ region: process.env.AWS_DEFAULT_REGION });
402
501
  this.bucketName = bucketName;
403
502
  }
404
503
  /**
@@ -599,6 +698,69 @@ var S3StorageService = class {
599
698
  await this.s3Client.send(command);
600
699
  return true;
601
700
  }
701
+ async getHeadBucket() {
702
+ try {
703
+ const command = new HeadBucketCommand({
704
+ Bucket: this.bucketName
705
+ });
706
+ return this.s3Client.send(command);
707
+ } catch (error) {
708
+ throw new Error(
709
+ "Error in S3 getHeadContainer. bucketName: " + this.bucketName + " Error: " + error
710
+ );
711
+ }
712
+ }
713
+ async uploadMultipart(key, file, partNumber, uploadId) {
714
+ let upId = uploadId;
715
+ if (!upId) {
716
+ const params2 = {
717
+ Bucket: this.bucketName,
718
+ Key: key
719
+ };
720
+ const response = await this.s3.createMultipartUpload(params2);
721
+ if (!(response == null ? void 0 : response.UploadId))
722
+ throw new Error("No upload ID was generated");
723
+ upId = response.UploadId;
724
+ }
725
+ const params = {
726
+ Bucket: this.bucketName,
727
+ Key: key,
728
+ Body: file,
729
+ PartNumber: partNumber,
730
+ UploadId: upId
731
+ };
732
+ await this.s3.uploadPart(params);
733
+ return upId;
734
+ }
735
+ async completeMultipartUpload(key, uploadId) {
736
+ const listPartsParams = {
737
+ Bucket: this.bucketName,
738
+ Key: key,
739
+ UploadId: uploadId
740
+ };
741
+ const partsResponse = await this.s3.listParts(listPartsParams);
742
+ const partsList = (partsResponse == null ? void 0 : partsResponse.Parts) && partsResponse.Parts.map(
743
+ // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
744
+ (_a) => {
745
+ var _b = _a, partList = __objRest(_b, ["Size", "LastModified"]);
746
+ return partList;
747
+ }
748
+ );
749
+ const completeMultipartParams = __spreadProps(__spreadValues({}, listPartsParams), {
750
+ MultipartUpload: {
751
+ Parts: partsList
752
+ }
753
+ });
754
+ await this.s3.completeMultipartUpload(completeMultipartParams);
755
+ }
756
+ async abortMultipartUpload(key, uploadId) {
757
+ const params = {
758
+ Bucket: this.bucketName,
759
+ Key: key,
760
+ UploadId: uploadId
761
+ };
762
+ await this.s3.abortMultipartUpload(params);
763
+ }
602
764
  };
603
765
 
604
766
  // src/services/objectStorageFactory.service.ts
@@ -723,16 +885,89 @@ var ObjectStorageService = class _ObjectStorageService {
723
885
  ).then((instance) => instance.createUploadWriteStream(key));
724
886
  }
725
887
  /**
726
- * Deletes an object from the object storage service.
888
+ * Deletes an object or multiple objects from the object storage service.
727
889
  *
728
- * @param {string} key - The key of the object to delete.
729
- * @param {string} [bucketName] - The name of the bucket where the object is stored. If not provided, the default bucket name will be used.
730
- * @return {Promise<boolean>} A promise that resolves to true if the object was successfully deleted, or false otherwise.
890
+ * @param {string | string[]} key - The key or array of keys of the objects to delete.
891
+ * @param {string} [bucketName] - The name of the bucket where the objects are stored. If not provided, the default bucket name will be used.
892
+ * @return {Promise<{ key: string; deleted: boolean; error?: string }[] | boolean>} A promise that resolves to an array of objects containing the key, deleted status, and an optional error message for each object deleted, or a boolean value indicating the success of the deletion.
731
893
  */
732
894
  static async delete(key, bucketName) {
733
895
  return _ObjectStorageService.getObjectStorageServiceInstance(
734
896
  bucketName
735
- ).then((instance) => instance.delete(key));
897
+ ).then(async (instance) => {
898
+ if (Array.isArray(key)) {
899
+ const deleteBlobPromises = key.map(async (blobName) => {
900
+ var _a;
901
+ try {
902
+ await instance.delete(blobName);
903
+ return { key: blobName, deleted: true };
904
+ } catch (error) {
905
+ return {
906
+ key: blobName,
907
+ deleted: false,
908
+ error: (_a = error == null ? void 0 : error.message) != null ? _a : ""
909
+ };
910
+ }
911
+ });
912
+ return Promise.all(deleteBlobPromises);
913
+ } else {
914
+ return instance.delete(key);
915
+ }
916
+ });
917
+ }
918
+ /**
919
+ * Retrieves the head bucket from the object storage service.
920
+ *
921
+ * @param {string} [bucketName] - The name of the bucket. If not provided, the default bucket name will be used.
922
+ * @return {Promise<HeadBucketResponse>} A promise that resolves to the head bucket response.
923
+ */
924
+ static async getHeadBucket(bucketName) {
925
+ return _ObjectStorageService.getObjectStorageServiceInstance(
926
+ bucketName
927
+ ).then((instance) => instance.getHeadBucket());
928
+ }
929
+ /**
930
+ * Uploads a multipart file to the specified bucket in the object storage service.
931
+ *
932
+ * @param {string} key - The key of the object to upload the multipart file to.
933
+ * @param {FileContent} file - The content of the file to upload.
934
+ * @param {number} partNumber - The number of the part being uploaded.
935
+ * @param {string} [uploadId] - The ID of the multipart upload.
936
+ * @param {string} [bucketName] - The name of the bucket to upload the file to. If not provided, the default bucket name will be used.
937
+ * @return {Promise<string>} A Promise that resolves to the base64 encoded block ID of the uploaded part.
938
+ */
939
+ static async uploadMultipart(key, file, partNumber, uploadId, bucketName) {
940
+ return _ObjectStorageService.getObjectStorageServiceInstance(
941
+ bucketName
942
+ ).then(
943
+ (instance) => instance.uploadMultipart(key, file, partNumber, uploadId)
944
+ );
945
+ }
946
+ /**
947
+ * Completes a multipart upload for the specified object in the object storage service.
948
+ *
949
+ * @param {string} key - The key of the object to complete the multipart upload for.
950
+ * @param {string} uploadId - The ID of the multipart upload to complete.
951
+ * @param {string} [bucketName] - The name of the bucket to complete the multipart upload in. If not provided, the default bucket name will be used.
952
+ * @return {Promise<void>} A Promise that resolves when the multipart upload is completed.
953
+ */
954
+ static async completeMultipartUpload(key, uploadId, bucketName) {
955
+ return _ObjectStorageService.getObjectStorageServiceInstance(
956
+ bucketName
957
+ ).then((instance) => instance.completeMultipartUpload(key, uploadId));
958
+ }
959
+ /**
960
+ * Aborts a multipart upload for the specified object in the object storage service.
961
+ *
962
+ * @param {string} key - The key of the object to abort the multipart upload for.
963
+ * @param {string} uploadId - The ID of the multipart upload to abort.
964
+ * @param {string} [bucketName] - The name of the bucket to abort the multipart upload in. If not provided, the default bucket name will be used.
965
+ * @return {Promise<void>} A Promise that resolves when the multipart upload is aborted.
966
+ */
967
+ static async abortMultipartUpload(key, uploadId, bucketName) {
968
+ return _ObjectStorageService.getObjectStorageServiceInstance(
969
+ bucketName
970
+ ).then((instance) => instance.abortMultipartUpload(key, uploadId));
736
971
  }
737
972
  };
738
973