11const errorInstances = require ( '../../../../errors' ) . errorInstances ;
22const constructStringToSignV2 = require ( '../../../../auth/v2/constructStringToSign' ) . default ;
33const crypto = require ( 'crypto' ) ;
4- const getPutTagsMetadata = require ( './GcpUtils' ) . getPutTagsMetadata ;
5- const processTagSet = require ( './GcpUtils' ) . processTagSet ;
64const GcpManagedUpload = require ( '../GCP/GcpManagedUpload' ) ;
7- const async = require ( 'async' ) ;
8- const createMpuKey = require ( './GcpUtils' ) . createMpuKey ;
9- const getPartNumber = require ( './GcpUtils' ) . getPartNumber ;
10- const MpuHelper = require ( './GcpApis/mpuHelper' ) ;
11- const { v4 : uuid } = require ( 'uuid' ) ;
12- const stripTags = require ( './GcpUtils' ) . stripTags ;
13- const retrieveTags = require ( './GcpUtils' ) . retrieveTags ;
145const { S3Client,
156 PutObjectCommand,
167 GetObjectCommand,
@@ -24,6 +15,8 @@ const { S3Client,
2415 GetBucketVersioningCommand,
2516} = require ( '@aws-sdk/client-s3' ) ;
2617const { createNormalizeHeadersMiddleware } = require ( '../../../../utils/normalizeHeaders' ) ;
18+ const { getHeaderCaseInsensitive } = require ( './GcpUtils' ) ;
19+ const gcpApis = require ( './GcpApis' ) ;
2720
2821/**
2922 * GcpClient: S3-compatible client for Google Cloud Storage using AWS SDK v3.
@@ -84,46 +77,6 @@ class GcpClient extends S3Client {
8477 ) ;
8578 }
8679
87- /**
88- * Upload an object to GCP (with optional tagging as metadata).
89- * @param {object } params - S3 putObject params
90- * @param {function } callback
91- */
92- putObject ( params , callback ) {
93- const command = new PutObjectCommand ( params ) ;
94-
95- // Capture GCP-specific headers
96- let objectGeneration ;
97- command . middlewareStack . add (
98- next => async args => {
99- const result = await next ( args ) ;
100- const generationHeader = getHeaderCaseInsensitive (
101- result . response ?. headers ,
102- 'x-goog-generation'
103- ) ;
104- if ( generationHeader !== undefined ) {
105- objectGeneration = generationHeader ;
106- }
107- return result ;
108- } ,
109- {
110- step : 'deserialize' ,
111- name : 'captureGcpHeaders' ,
112- }
113- ) ;
114-
115- return this . send ( command )
116- . then ( data => {
117- // Add GCP-specific fields
118- const result = { ...data } ;
119- if ( objectGeneration ) {
120- result . VersionId = objectGeneration ;
121- }
122- return callback && callback ( null , result ) ;
123- } )
124- . catch ( err => callback ?. ( err ) ) ;
125- }
126-
12780 listBuckets ( params , callback ) {
12881 return callback ( errorInstances . NotImplemented
12982 . customizeDescription ( 'GCP: listBuckets not implemented' ) ) ;
@@ -283,16 +236,6 @@ class GcpClient extends S3Client {
283236 . customizeDescription ( 'GCP: deleteBucketCors not implemented' ) ) ;
284237 }
285238
286- putObjectTagging ( params , callback ) {
287- return callback ( errorInstances . NotImplemented
288- . customizeDescription ( 'GCP: putObjectTagging not implemented' ) ) ;
289- }
290-
291- deleteObjectTagging ( params , callback ) {
292- return callback ( errorInstances . NotImplemented
293- . customizeDescription ( 'GCP: deleteObjectTagging not implemented' ) ) ;
294- }
295-
296239 putObjectAcl ( params , callback ) {
297240 return callback ( errorInstances . NotImplemented
298241 . customizeDescription ( 'GCP: putObjectAcl not implemented' ) ) ;
@@ -318,182 +261,6 @@ class GcpClient extends S3Client {
318261 }
319262 }
320263
321- /**
322- * Initiate a multipart upload (emulated for GCP).
323- * @param {object } params - S3 createMultipartUpload params
324- * @param {function } callback
325- createMultipartUpload(params, callback) {
326- if (!params || !params.Bucket || !params.Key) {
327- const error = errorInstances.InvalidRequest
328- .customizeDescription('Missing required parameter');
329- return callback(error);
330- }
331- const uploadId = uuid().replace(/-/g, '');
332- const mpuParams = {
333- Bucket: params.Bucket,
334- Key: createMpuKey(params.Key, uploadId, 'init'),
335- Metadata: params.Metadata,
336- ContentType: params.ContentType,
337- CacheControl: params.CacheControl,
338- ContentDisposition: params.ContentDisposition,
339- ContentEncoding: params.ContentEncoding,
340- };
341- mpuParams.Metadata = getPutTagsMetadata(mpuParams.Metadata, params.Tagging);
342- return this.putObject(mpuParams, err => {
343- if (err) {
344- return callback(err);
345- }
346- return callback(null, { UploadId: uploadId });
347- });
348- }
349- */
350-
351- /**
352- * Upload a part for MPU (emulated for GCP).
353- * @param {object } params - S3 uploadPart params
354- * @param {function } callback
355- */
356- uploadPart ( params , callback ) {
357- if ( ! params || ! params . UploadId || ! params . Bucket || ! params . Key ) {
358- const error = errorInstances . InvalidRequest
359- . customizeDescription ( 'Missing required parameter' ) ;
360- return callback ( error ) ;
361- }
362- const partNumber = getPartNumber ( params . PartNumber ) ;
363- if ( ! partNumber ) {
364- const error = errorInstances . InvalidArgument
365- . customizeDescription ( 'PartNumber is invalid' ) ;
366- return callback ( error ) ;
367- }
368- const mpuParams = {
369- Bucket : params . Bucket ,
370- Key : createMpuKey ( params . Key , params . UploadId , partNumber ) ,
371- Body : params . Body ,
372- ContentLength : params . ContentLength ,
373- } ;
374- return this . putObject ( mpuParams , callback ) ;
375- }
376-
377- /**
378- * Upload a part by copying from an existing object (emulated for GCP).
379- * @param {object } params - S3 uploadPartCopy params
380- * @param {function } callback
381- */
382- uploadPartCopy ( params , callback ) {
383- if ( ! params || ! params . UploadId || ! params . Bucket || ! params . Key || ! params . CopySource ) {
384- const error = errorInstances . InvalidRequest
385- . customizeDescription ( 'Missing required parameter' ) ;
386- return callback ( error ) ;
387- }
388- const partNumber = getPartNumber ( params . PartNumber ) ;
389- if ( ! partNumber ) {
390- const error = errorInstances . InvalidArgument
391- . customizeDescription ( 'PartNumber is not a number' ) ;
392- return callback ( error ) ;
393- }
394- const mpuParams = {
395- Bucket : params . Bucket ,
396- Key : createMpuKey ( params . Key , params . UploadId , partNumber ) ,
397- CopySource : params . CopySource ,
398- } ;
399- return this . copyObject ( mpuParams , callback ) ;
400- }
401-
402- /**
403- * Complete a multipart upload (emulated for GCP).
404- * @param {object } params - S3 completeMultipartUpload params
405- * @param {function } callback
406- */
407- completeMultipartUpload ( params , callback ) {
408- if ( ! params || ! params . MultipartUpload ||
409- ! params . MultipartUpload . Parts || ! params . UploadId ||
410- ! params . Bucket || ! params . Key ) {
411- const error = errorInstances . InvalidRequest
412- . customizeDescription ( 'Missing required parameter' ) ;
413- return callback ( error ) ;
414- }
415- const partList = params . MultipartUpload . Parts ;
416- if ( partList . length === 0 ) {
417- const error = errorInstances . InvalidRequest
418- . customizeDescription ( 'You must specify at least one part' ) ;
419- return callback ( error ) ;
420- }
421- for ( let ind = 1 ; ind < partList . length ; ++ ind ) {
422- if ( partList [ ind - 1 ] . PartNumber >= partList [ ind ] . PartNumber ) {
423- return callback ( errorInstances . InvalidPartOrder ) ;
424- }
425- }
426- const mpuHelper = new MpuHelper ( this ) ;
427- return async . waterfall ( [
428- next => mpuHelper . splitMerge ( params , partList , 'compose' , next ) ,
429- ( numParts , next ) => {
430- mpuHelper . composeFinal ( numParts , params , next ) ;
431- } ,
432- ( result , next ) => {
433- mpuHelper . generateMpuResult ( result , partList , next ) ;
434- } ,
435- ( result , aggregateETag , next ) => {
436- mpuHelper . copyToMain ( result , aggregateETag , params , next ) ;
437- } ,
438- ( mpuResult , next ) => {
439- const delParams = {
440- Bucket : params . Bucket ,
441- MPU : params . MPU ,
442- Prefix : createMpuKey ( params . Key , params . UploadId ) ,
443- } ;
444- mpuHelper . removeParts ( delParams , err => {
445- next ( err , mpuResult ) ;
446- } ) ;
447- } ,
448- ] , ( err , result ) => {
449- callback ( err , result ) ;
450- } ) ;
451- }
452-
453- /**
454- * Abort a multipart upload (emulated for GCP).
455- * @param {object } params - S3 abortMultipartUpload params
456- * @param {function } callback
457- */
458- abortMultipartUpload ( params , callback ) {
459- if ( ! params || ! params . Key || ! params . UploadId || ! params . Bucket || ! params . MPU ) {
460- const error = errorInstances . InvalidRequest
461- . customizeDescription ( 'Missing required parameter' ) ;
462- return callback ( error ) ;
463- }
464- const mpuHelper = new MpuHelper ( this ) ;
465- const delParams = {
466- Bucket : params . Bucket ,
467- MPU : params . MPU ,
468- Prefix : createMpuKey ( params . Key , params . UploadId ) ,
469- } ;
470- return mpuHelper . removeParts ( delParams , callback ) ;
471- }
472-
473- /**
474- * List parts of a multipart upload (emulated for GCP).
475- * @param {object } params - S3 listParts params
476- * @param {function } callback
477- */
478- listParts ( params , callback ) {
479- if ( ! params || ! params . UploadId || ! params . Bucket || ! params . Key ) {
480- const error = errorInstances . InvalidRequest
481- . customizeDescription ( 'Missing required parameter' ) ;
482- return callback ( error ) ;
483- }
484- if ( params . PartNumberMarker && params . PartNumberMarker < 0 ) {
485- return callback ( errorInstances . InvalidArgument
486- . customizeDescription ( 'The request specified an invalid marker' ) ) ;
487- }
488- const mpuParams = {
489- Bucket : params . Bucket ,
490- Prefix : createMpuKey ( params . Key , params . UploadId , 'parts' ) ,
491- Marker : createMpuKey ( params . Key , params . UploadId , params . PartNumberMarker , 'parts' ) ,
492- MaxKeys : params . MaxParts ,
493- } ;
494- return this . listObjects ( mpuParams , callback ) ;
495- }
496-
497264 /**
498265 * List objects in a bucket.
499266 * @param {object } params - S3 listObjects params
@@ -566,12 +333,7 @@ class GcpClient extends S3Client {
566333 throw err ;
567334 } ) ;
568335 }
569-
570- getObjectTagging ( params , callback ) {
571- return callback ( errorInstances . NotImplemented
572- . customizeDescription ( 'GCP: getObjectTagging not implemented' ) ) ;
573- }
574-
336+
575337 /**
576338 * Get an object (callback style for test compatibility).
577339 */
@@ -862,28 +624,6 @@ function gcpSigningMiddleware(config) {
862624 } ;
863625}
864626
865- function getHeaderCaseInsensitive ( headers , headerName ) {
866- if ( ! headers ) {
867- return undefined ;
868- }
869-
870- const normalized = headerName . toLowerCase ( ) ;
871- if ( headers [ normalized ] !== undefined ) {
872- return headers [ normalized ] ;
873- }
874-
875- const direct = headers [ headerName ] ;
876- if ( direct !== undefined ) {
877- return direct ;
878- }
879-
880- for ( const key of Object . keys ( headers ) ) {
881- if ( key . toLowerCase ( ) === normalized ) {
882- return headers [ key ] ;
883- }
884- }
885-
886- return undefined ;
887- }
627+ Object . assign ( GcpClient . prototype , gcpApis ) ;
888628
889629module . exports = GcpClient ;
0 commit comments