@qrvey/object-storage 0.0.10-beta.3 → 0.0.11-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,8 +1,10 @@
1
- import stream from 'stream';
1
+ import stream, { Readable } from 'stream';
2
2
  import { BlobServiceClient, BlobSASPermissions } from '@azure/storage-blob';
3
3
  import { S3Client, S3, ListObjectsV2Command, HeadObjectCommand, GetObjectCommand, PutObjectCommand, DeleteObjectCommand, HeadBucketCommand, UploadPartCommand } from '@aws-sdk/client-s3';
4
4
  import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
5
5
  import { Upload } from '@aws-sdk/lib-storage';
6
+ import { Agent, request as request$1 } from 'http';
7
+ import { Agent as Agent$1, request } from 'https';
6
8
 
7
9
  var __defProp = Object.defineProperty;
8
10
  var __defProps = Object.defineProperties;
@@ -182,16 +184,28 @@ var BlobStorageService = class {
182
184
  * Retrieves an object from the blob storage service.
183
185
  *
184
186
  * @param {string} blobName - The name of the blob to retrieve.
187
+ * @param {Object} [options] - The options that you can pass to the library.
185
188
  * @return {Promise<GetObjectResponse>} A promise that resolves to the object data, including the body, metadata, content type, and content length, or rejects with an error if there was an issue.
186
189
  */
187
- async getObject(blobName) {
190
+ async getObject(blobName, options) {
188
191
  var _a;
189
192
  try {
193
+ let downloadBlockBlobResponse;
190
194
  const containerClient = this.blobServiceClient.getContainerClient(
191
195
  this.containerName
192
196
  );
193
197
  const blockBlobClient = containerClient.getBlockBlobClient(blobName);
194
- const downloadBlockBlobResponse = await blockBlobClient.download(0);
198
+ const expression = (options == null ? void 0 : options.range) || "";
199
+ const matches = expression.match(/\d+/g);
200
+ if (expression && (matches == null ? void 0 : matches.length)) {
201
+ const [start, end] = matches.map(Number);
202
+ downloadBlockBlobResponse = await blockBlobClient.download(
203
+ start,
204
+ end
205
+ );
206
+ } else {
207
+ downloadBlockBlobResponse = await blockBlobClient.download(0);
208
+ }
195
209
  return {
196
210
  body: downloadBlockBlobResponse.readableStreamBody,
197
211
  metadata: downloadBlockBlobResponse.metadata,
@@ -496,7 +510,7 @@ var BlobStorageService = class {
496
510
  );
497
511
  const blobClient = containerClient.getBlockBlobClient(blobName);
498
512
  const listResponse = await blobClient.getBlockList("all");
499
- const parts = ((_a = listResponse == null ? void 0 : listResponse.committedBlocks) == null ? void 0 : _a.map((block, index) => ({
513
+ const parts = ((_a = listResponse == null ? void 0 : listResponse.uncommittedBlocks) == null ? void 0 : _a.map((block, index) => ({
500
514
  PartNumber: index + 1,
501
515
  LastModified: /* @__PURE__ */ new Date(),
502
516
  // Azure Blob Storage doesn't provide the last modified date for individual parts
@@ -613,12 +627,392 @@ function s3ObjectToObjectResponse(s3Object) {
613
627
  lastModified: s3Object.LastModified
614
628
  };
615
629
  }
630
+
631
+ // ../../node_modules/@smithy/types/dist-es/auth/auth.js
632
+ var HttpAuthLocation;
633
+ (function(HttpAuthLocation2) {
634
+ HttpAuthLocation2["HEADER"] = "header";
635
+ HttpAuthLocation2["QUERY"] = "query";
636
+ })(HttpAuthLocation || (HttpAuthLocation = {}));
637
+
638
+ // ../../node_modules/@smithy/types/dist-es/auth/HttpApiKeyAuth.js
639
+ var HttpApiKeyAuthLocation;
640
+ (function(HttpApiKeyAuthLocation2) {
641
+ HttpApiKeyAuthLocation2["HEADER"] = "header";
642
+ HttpApiKeyAuthLocation2["QUERY"] = "query";
643
+ })(HttpApiKeyAuthLocation || (HttpApiKeyAuthLocation = {}));
644
+
645
+ // ../../node_modules/@smithy/types/dist-es/endpoint.js
646
+ var EndpointURLScheme;
647
+ (function(EndpointURLScheme2) {
648
+ EndpointURLScheme2["HTTP"] = "http";
649
+ EndpointURLScheme2["HTTPS"] = "https";
650
+ })(EndpointURLScheme || (EndpointURLScheme = {}));
651
+
652
+ // ../../node_modules/@smithy/types/dist-es/extensions/checksum.js
653
+ var AlgorithmId;
654
+ (function(AlgorithmId2) {
655
+ AlgorithmId2["MD5"] = "md5";
656
+ AlgorithmId2["CRC32"] = "crc32";
657
+ AlgorithmId2["CRC32C"] = "crc32c";
658
+ AlgorithmId2["SHA1"] = "sha1";
659
+ AlgorithmId2["SHA256"] = "sha256";
660
+ })(AlgorithmId || (AlgorithmId = {}));
661
+
662
+ // ../../node_modules/@smithy/types/dist-es/http.js
663
+ var FieldPosition;
664
+ (function(FieldPosition2) {
665
+ FieldPosition2[FieldPosition2["HEADER"] = 0] = "HEADER";
666
+ FieldPosition2[FieldPosition2["TRAILER"] = 1] = "TRAILER";
667
+ })(FieldPosition || (FieldPosition = {}));
668
+
669
+ // ../../node_modules/@smithy/types/dist-es/profile.js
670
+ var IniSectionType;
671
+ (function(IniSectionType2) {
672
+ IniSectionType2["PROFILE"] = "profile";
673
+ IniSectionType2["SSO_SESSION"] = "sso-session";
674
+ IniSectionType2["SERVICES"] = "services";
675
+ })(IniSectionType || (IniSectionType = {}));
676
+
677
+ // ../../node_modules/@smithy/types/dist-es/transfer.js
678
+ var RequestHandlerProtocol;
679
+ (function(RequestHandlerProtocol2) {
680
+ RequestHandlerProtocol2["HTTP_0_9"] = "http/0.9";
681
+ RequestHandlerProtocol2["HTTP_1_0"] = "http/1.0";
682
+ RequestHandlerProtocol2["TDS_8_0"] = "tds/8.0";
683
+ })(RequestHandlerProtocol || (RequestHandlerProtocol = {}));
684
+
685
+ // ../../node_modules/@smithy/protocol-http/dist-es/httpResponse.js
686
+ var HttpResponse = class {
687
+ constructor(options) {
688
+ this.statusCode = options.statusCode;
689
+ this.reason = options.reason;
690
+ this.headers = options.headers || {};
691
+ this.body = options.body;
692
+ }
693
+ static isInstance(response) {
694
+ if (!response)
695
+ return false;
696
+ const resp = response;
697
+ return typeof resp.statusCode === "number" && typeof resp.headers === "object";
698
+ }
699
+ };
700
+
701
+ // ../../node_modules/@smithy/util-uri-escape/dist-es/escape-uri.js
702
+ var escapeUri = (uri) => encodeURIComponent(uri).replace(/[!'()*]/g, hexEncode);
703
+ var hexEncode = (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`;
704
+
705
+ // ../../node_modules/@smithy/querystring-builder/dist-es/index.js
706
+ function buildQueryString(query) {
707
+ const parts = [];
708
+ for (let key of Object.keys(query).sort()) {
709
+ const value = query[key];
710
+ key = escapeUri(key);
711
+ if (Array.isArray(value)) {
712
+ for (let i = 0, iLen = value.length; i < iLen; i++) {
713
+ parts.push(`${key}=${escapeUri(value[i])}`);
714
+ }
715
+ } else {
716
+ let qsEntry = key;
717
+ if (value || typeof value === "string") {
718
+ qsEntry += `=${escapeUri(value)}`;
719
+ }
720
+ parts.push(qsEntry);
721
+ }
722
+ }
723
+ return parts.join("&");
724
+ }
725
+
726
+ // ../../node_modules/@smithy/node-http-handler/dist-es/constants.js
727
+ var NODEJS_TIMEOUT_ERROR_CODES = ["ECONNRESET", "EPIPE", "ETIMEDOUT"];
728
+
729
+ // ../../node_modules/@smithy/node-http-handler/dist-es/get-transformed-headers.js
730
+ var getTransformedHeaders = (headers) => {
731
+ const transformedHeaders = {};
732
+ for (const name of Object.keys(headers)) {
733
+ const headerValues = headers[name];
734
+ transformedHeaders[name] = Array.isArray(headerValues) ? headerValues.join(",") : headerValues;
735
+ }
736
+ return transformedHeaders;
737
+ };
738
+
739
+ // ../../node_modules/@smithy/node-http-handler/dist-es/set-connection-timeout.js
740
+ var setConnectionTimeout = (request, reject, timeoutInMs = 0) => {
741
+ if (!timeoutInMs) {
742
+ return;
743
+ }
744
+ const timeoutId = setTimeout(() => {
745
+ request.destroy();
746
+ reject(Object.assign(new Error(`Socket timed out without establishing a connection within ${timeoutInMs} ms`), {
747
+ name: "TimeoutError"
748
+ }));
749
+ }, timeoutInMs);
750
+ request.on("socket", (socket) => {
751
+ if (socket.connecting) {
752
+ socket.on("connect", () => {
753
+ clearTimeout(timeoutId);
754
+ });
755
+ } else {
756
+ clearTimeout(timeoutId);
757
+ }
758
+ });
759
+ };
760
+
761
+ // ../../node_modules/@smithy/node-http-handler/dist-es/set-socket-keep-alive.js
762
+ var setSocketKeepAlive = (request, { keepAlive, keepAliveMsecs }) => {
763
+ if (keepAlive !== true) {
764
+ return;
765
+ }
766
+ request.on("socket", (socket) => {
767
+ socket.setKeepAlive(keepAlive, keepAliveMsecs || 0);
768
+ });
769
+ };
770
+
771
+ // ../../node_modules/@smithy/node-http-handler/dist-es/set-socket-timeout.js
772
+ var setSocketTimeout = (request, reject, timeoutInMs = 0) => {
773
+ request.setTimeout(timeoutInMs, () => {
774
+ request.destroy();
775
+ reject(Object.assign(new Error(`Connection timed out after ${timeoutInMs} ms`), { name: "TimeoutError" }));
776
+ });
777
+ };
778
+ var MIN_WAIT_TIME = 1e3;
779
+ async function writeRequestBody(httpRequest, request, maxContinueTimeoutMs = MIN_WAIT_TIME) {
780
+ var _a;
781
+ const headers = (_a = request.headers) != null ? _a : {};
782
+ const expect = headers["Expect"] || headers["expect"];
783
+ let timeoutId = -1;
784
+ let hasError = false;
785
+ if (expect === "100-continue") {
786
+ await Promise.race([
787
+ new Promise((resolve) => {
788
+ timeoutId = Number(setTimeout(resolve, Math.max(MIN_WAIT_TIME, maxContinueTimeoutMs)));
789
+ }),
790
+ new Promise((resolve) => {
791
+ httpRequest.on("continue", () => {
792
+ clearTimeout(timeoutId);
793
+ resolve();
794
+ });
795
+ httpRequest.on("error", () => {
796
+ hasError = true;
797
+ clearTimeout(timeoutId);
798
+ resolve();
799
+ });
800
+ })
801
+ ]);
802
+ }
803
+ if (!hasError) {
804
+ writeBody(httpRequest, request.body);
805
+ }
806
+ }
807
+ function writeBody(httpRequest, body) {
808
+ if (body instanceof Readable) {
809
+ body.pipe(httpRequest);
810
+ return;
811
+ }
812
+ if (body) {
813
+ if (Buffer.isBuffer(body) || typeof body === "string") {
814
+ httpRequest.end(body);
815
+ return;
816
+ }
817
+ const uint8 = body;
818
+ if (typeof uint8 === "object" && uint8.buffer && typeof uint8.byteOffset === "number" && typeof uint8.byteLength === "number") {
819
+ httpRequest.end(Buffer.from(uint8.buffer, uint8.byteOffset, uint8.byteLength));
820
+ return;
821
+ }
822
+ httpRequest.end(Buffer.from(body));
823
+ return;
824
+ }
825
+ httpRequest.end();
826
+ }
827
+
828
+ // ../../node_modules/@smithy/node-http-handler/dist-es/node-http-handler.js
829
+ var NodeHttpHandler = class _NodeHttpHandler {
830
+ static create(instanceOrOptions) {
831
+ if (typeof (instanceOrOptions == null ? void 0 : instanceOrOptions.handle) === "function") {
832
+ return instanceOrOptions;
833
+ }
834
+ return new _NodeHttpHandler(instanceOrOptions);
835
+ }
836
+ static checkSocketUsage(agent, socketWarningTimestamp) {
837
+ var _a, _b, _c, _d;
838
+ const { sockets, requests, maxSockets } = agent;
839
+ if (typeof maxSockets !== "number" || maxSockets === Infinity) {
840
+ return socketWarningTimestamp;
841
+ }
842
+ const interval = 15e3;
843
+ if (Date.now() - interval < socketWarningTimestamp) {
844
+ return socketWarningTimestamp;
845
+ }
846
+ if (sockets && requests) {
847
+ for (const origin in sockets) {
848
+ const socketsInUse = (_b = (_a = sockets[origin]) == null ? void 0 : _a.length) != null ? _b : 0;
849
+ const requestsEnqueued = (_d = (_c = requests[origin]) == null ? void 0 : _c.length) != null ? _d : 0;
850
+ if (socketsInUse >= maxSockets && requestsEnqueued >= 2 * maxSockets) {
851
+ console.warn("@smithy/node-http-handler:WARN", `socket usage at capacity=${socketsInUse} and ${requestsEnqueued} additional requests are enqueued.`, "See https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-configuring-maxsockets.html", "or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler config.");
852
+ return Date.now();
853
+ }
854
+ }
855
+ }
856
+ return socketWarningTimestamp;
857
+ }
858
+ constructor(options) {
859
+ this.socketWarningTimestamp = 0;
860
+ this.metadata = { handlerProtocol: "http/1.1" };
861
+ this.configProvider = new Promise((resolve, reject) => {
862
+ if (typeof options === "function") {
863
+ options().then((_options) => {
864
+ resolve(this.resolveDefaultConfig(_options));
865
+ }).catch(reject);
866
+ } else {
867
+ resolve(this.resolveDefaultConfig(options));
868
+ }
869
+ });
870
+ }
871
+ resolveDefaultConfig(options) {
872
+ const { requestTimeout, connectionTimeout, socketTimeout, httpAgent, httpsAgent } = options || {};
873
+ const keepAlive = true;
874
+ const maxSockets = 50;
875
+ return {
876
+ connectionTimeout,
877
+ requestTimeout: requestTimeout != null ? requestTimeout : socketTimeout,
878
+ httpAgent: (() => {
879
+ if (httpAgent instanceof Agent || typeof (httpAgent == null ? void 0 : httpAgent.destroy) === "function") {
880
+ return httpAgent;
881
+ }
882
+ return new Agent(__spreadValues({ keepAlive, maxSockets }, httpAgent));
883
+ })(),
884
+ httpsAgent: (() => {
885
+ if (httpsAgent instanceof Agent$1 || typeof (httpsAgent == null ? void 0 : httpsAgent.destroy) === "function") {
886
+ return httpsAgent;
887
+ }
888
+ return new Agent$1(__spreadValues({ keepAlive, maxSockets }, httpsAgent));
889
+ })()
890
+ };
891
+ }
892
+ destroy() {
893
+ var _a, _b, _c, _d;
894
+ (_b = (_a = this.config) == null ? void 0 : _a.httpAgent) == null ? void 0 : _b.destroy();
895
+ (_d = (_c = this.config) == null ? void 0 : _c.httpsAgent) == null ? void 0 : _d.destroy();
896
+ }
897
+ async handle(request$2, { abortSignal } = {}) {
898
+ if (!this.config) {
899
+ this.config = await this.configProvider;
900
+ }
901
+ let socketCheckTimeoutId;
902
+ return new Promise((_resolve, _reject) => {
903
+ var _a, _b, _c, _d, _e;
904
+ let writeRequestBodyPromise = void 0;
905
+ const resolve = async (arg) => {
906
+ await writeRequestBodyPromise;
907
+ clearTimeout(socketCheckTimeoutId);
908
+ _resolve(arg);
909
+ };
910
+ const reject = async (arg) => {
911
+ await writeRequestBodyPromise;
912
+ _reject(arg);
913
+ };
914
+ if (!this.config) {
915
+ throw new Error("Node HTTP request handler config is not resolved");
916
+ }
917
+ if (abortSignal == null ? void 0 : abortSignal.aborted) {
918
+ const abortError = new Error("Request aborted");
919
+ abortError.name = "AbortError";
920
+ reject(abortError);
921
+ return;
922
+ }
923
+ const isSSL = request$2.protocol === "https:";
924
+ const agent = isSSL ? this.config.httpsAgent : this.config.httpAgent;
925
+ socketCheckTimeoutId = setTimeout(() => {
926
+ this.socketWarningTimestamp = _NodeHttpHandler.checkSocketUsage(agent, this.socketWarningTimestamp);
927
+ }, (_c = this.config.socketAcquisitionWarningTimeout) != null ? _c : ((_a = this.config.requestTimeout) != null ? _a : 2e3) + ((_b = this.config.connectionTimeout) != null ? _b : 1e3));
928
+ const queryString = buildQueryString(request$2.query || {});
929
+ let auth = void 0;
930
+ if (request$2.username != null || request$2.password != null) {
931
+ const username = (_d = request$2.username) != null ? _d : "";
932
+ const password = (_e = request$2.password) != null ? _e : "";
933
+ auth = `${username}:${password}`;
934
+ }
935
+ let path = request$2.path;
936
+ if (queryString) {
937
+ path += `?${queryString}`;
938
+ }
939
+ if (request$2.fragment) {
940
+ path += `#${request$2.fragment}`;
941
+ }
942
+ const nodeHttpsOptions = {
943
+ headers: request$2.headers,
944
+ host: request$2.hostname,
945
+ method: request$2.method,
946
+ path,
947
+ port: request$2.port,
948
+ agent,
949
+ auth
950
+ };
951
+ const requestFunc = isSSL ? request : request$1;
952
+ const req = requestFunc(nodeHttpsOptions, (res) => {
953
+ const httpResponse = new HttpResponse({
954
+ statusCode: res.statusCode || -1,
955
+ reason: res.statusMessage,
956
+ headers: getTransformedHeaders(res.headers),
957
+ body: res
958
+ });
959
+ resolve({ response: httpResponse });
960
+ });
961
+ req.on("error", (err) => {
962
+ if (NODEJS_TIMEOUT_ERROR_CODES.includes(err.code)) {
963
+ reject(Object.assign(err, { name: "TimeoutError" }));
964
+ } else {
965
+ reject(err);
966
+ }
967
+ });
968
+ setConnectionTimeout(req, reject, this.config.connectionTimeout);
969
+ setSocketTimeout(req, reject, this.config.requestTimeout);
970
+ if (abortSignal) {
971
+ abortSignal.onabort = () => {
972
+ req.abort();
973
+ const abortError = new Error("Request aborted");
974
+ abortError.name = "AbortError";
975
+ reject(abortError);
976
+ };
977
+ }
978
+ const httpAgent = nodeHttpsOptions.agent;
979
+ if (typeof httpAgent === "object" && "keepAlive" in httpAgent) {
980
+ setSocketKeepAlive(req, {
981
+ keepAlive: httpAgent.keepAlive,
982
+ keepAliveMsecs: httpAgent.keepAliveMsecs
983
+ });
984
+ }
985
+ writeRequestBodyPromise = writeRequestBody(req, request$2, this.config.requestTimeout).catch(_reject);
986
+ });
987
+ }
988
+ updateHttpClientConfig(key, value) {
989
+ this.config = void 0;
990
+ this.configProvider = this.configProvider.then((config) => {
991
+ return __spreadProps(__spreadValues({}, config), {
992
+ [key]: value
993
+ });
994
+ });
995
+ }
996
+ httpHandlerConfigs() {
997
+ var _a;
998
+ return (_a = this.config) != null ? _a : {};
999
+ }
1000
+ };
1001
+
1002
+ // src/services/storage/s3/s3Storage.service.ts
616
1003
  var S3StorageService = class {
617
1004
  constructor(bucketName, options) {
1005
+ this.httpHandler = new NodeHttpHandler({
1006
+ socketTimeout: 6e4
1007
+ });
618
1008
  this.s3Client = new S3Client({
619
- region: process.env.AWS_DEFAULT_REGION
1009
+ region: process.env.AWS_DEFAULT_REGION,
1010
+ requestHandler: this.httpHandler
1011
+ });
1012
+ this.s3 = new S3({
1013
+ region: process.env.AWS_DEFAULT_REGION,
1014
+ requestHandler: this.httpHandler
620
1015
  });
621
- this.s3 = new S3({ region: process.env.AWS_DEFAULT_REGION });
622
1016
  var _a, _b, _c, _d;
623
1017
  this.bucketName = bucketName;
624
1018
  if (((_a = options == null ? void 0 : options.credentials) == null ? void 0 : _a.accessKeyId) && ((_b = options == null ? void 0 : options.credentials) == null ? void 0 : _b.secretAccessKey)) {
@@ -1029,10 +1423,10 @@ var ObjectStorageService = class _ObjectStorageService {
1029
1423
  * @param {string} [bucketName] - The name of the bucket where the object is stored. If not provided, the default bucket name will be used.
1030
1424
  * @return {Promise<GetObjectResponse>} A promise that resolves to the retrieved object.
1031
1425
  */
1032
- static async getObject(key, bucketName) {
1426
+ static async getObject(key, bucketName, options) {
1033
1427
  return _ObjectStorageService.getObjectStorageServiceInstance(
1034
1428
  bucketName
1035
- ).then((instance) => instance.getObject(key));
1429
+ ).then((instance) => instance.getObject(key, options));
1036
1430
  }
1037
1431
  /**
1038
1432
  * Retrieves an object info (without file content) from the object storage service.