public put()

in packages/storage/src/providers/AWSS3Provider.ts [496:629]


	public put<T extends S3ProviderPutConfig>(
		key: string,
		object: PutObjectCommandInput['Body'],
		config?: T
	): S3ProviderPutOutput<T> {
		const opt = Object.assign({}, this._config, config);
		const { bucket, track, progressCallback, level, resumable } = opt;
		const {
			contentType,
			contentDisposition,
			contentEncoding,
			cacheControl,
			expires,
			metadata,
			tagging,
			acl,
		} = opt;
		const {
			serverSideEncryption,
			SSECustomerAlgorithm,
			SSECustomerKey,
			SSECustomerKeyMD5,
			SSEKMSKeyId,
		} = opt;
		const type = contentType ? contentType : 'binary/octet-stream';

		const params: PutObjectCommandInput = {
			Bucket: bucket,
			Key: key,
			Body: object,
			ContentType: type,
		};
		if (cacheControl) {
			params.CacheControl = cacheControl;
		}
		if (contentDisposition) {
			params.ContentDisposition = contentDisposition;
		}
		if (contentEncoding) {
			params.ContentEncoding = contentEncoding;
		}
		if (expires) {
			params.Expires = expires;
		}
		if (metadata) {
			params.Metadata = metadata;
		}
		if (tagging) {
			params.Tagging = tagging;
		}
		if (serverSideEncryption) {
			params.ServerSideEncryption = serverSideEncryption;
		}
		if (SSECustomerAlgorithm) {
			params.SSECustomerAlgorithm = SSECustomerAlgorithm;
		}
		if (SSECustomerKey) {
			params.SSECustomerKey = SSECustomerKey;
		}
		if (SSECustomerKeyMD5) {
			params.SSECustomerKeyMD5 = SSECustomerKeyMD5;
		}
		if (SSEKMSKeyId) {
			params.SSEKMSKeyId = SSEKMSKeyId;
		}

		const emitter = new events.EventEmitter();
		const uploader = new AWSS3ProviderManagedUpload(params, opt, emitter);

		if (acl) {
			params.ACL = acl;
		}

		if (resumable === true) {
			const s3Client = this._createNewS3Client(opt);
			// we are using aws sdk middleware to inject the prefix to key, this way we don't have to call
			// this._ensureCredentials() which allows us to make this function sync so we can return non-Promise like UploadTask
			s3Client.middlewareStack.add(
				createPrefixMiddleware(opt, key),
				prefixMiddlewareOptions
			);
			const addTaskInput: AddTaskInput = {
				bucket,
				key,
				s3Client,
				file: object as Blob,
				emitter,
				accessLevel: level,
				params,
			};
			// explicitly asserting the type here as Typescript could not infer that resumable is of type true
			return this.startResumableUpload(
				addTaskInput,
				config as typeof config & { resumable: true }
			) as S3ProviderPutOutput<T>;
		}

		try {
			if (progressCallback) {
				if (typeof progressCallback === 'function') {
					emitter.on(SEND_UPLOAD_PROGRESS_EVENT, progress => {
						progressCallback(progress);
					});
				} else {
					logger.warn(
						'progressCallback should be a function, not a ' +
							typeof progressCallback
					);
				}
			}

			return uploader.upload().then(response => {
				logger.debug('upload result', response);
				dispatchStorageEvent(
					track,
					'upload',
					{ method: 'put', result: 'success' },
					null,
					`Upload success for ${key}`
				);
				return { key };
			}) as S3ProviderPutOutput<T>;
		} catch (error) {
			logger.warn('error uploading', error);
			dispatchStorageEvent(
				track,
				'upload',
				{ method: 'put', result: 'failed' },
				null,
				`Error uploading ${key}`
			);
			throw error;
		}
	}