Skip to content

Commit

Permalink
Merge branch 'next/release' into auth-bug-bash/enum-to-union-string
Browse files Browse the repository at this point in the history
israx authored Sep 13, 2023
2 parents 35a50b2 + db05277 commit 4d97235
Showing 33 changed files with 396 additions and 313 deletions.
23 changes: 23 additions & 0 deletions packages/storage/src/index.ts
Original file line number Diff line number Diff line change
@@ -10,6 +10,29 @@ export {
copy,
getUrl,
} from './providers/s3';

export {
UploadDataInput,
DownloadDataInput,
RemoveInput,
ListAllInput,
ListPaginateInput,
GetPropertiesInput,
CopyInput,
GetUrlInput,
} from './providers/s3/types/inputs';

export {
UploadDataOutput,
DownloadDataOutput,
RemoveOutput,
ListAllOutput,
ListPaginateOutput,
GetPropertiesOutput,
CopyOutput,
GetUrlOutput,
} from './providers/s3/types/outputs';

// TODO[AllanZhengYP]: support isCancelError in Node.js with node-fetch
export { isCancelError } from './errors/CanceledError';
export { StorageError } from './errors/StorageError';
11 changes: 5 additions & 6 deletions packages/storage/src/providers/s3/apis/copy.ts
Original file line number Diff line number Diff line change
@@ -2,21 +2,20 @@
// SPDX-License-Identifier: Apache-2.0

import { Amplify } from '@aws-amplify/core';
import { CopyRequest } from '../../../types';
import { S3CopyResult } from '../types';
import { CopyInput, CopyOutput } from '../types';
import { copy as copyInternal } from './internal/copy';

/**
* Copy an object from a source object to a new object within the same bucket. Can optionally copy files across
* different level or identityId (if source object's level is 'protected').
*
* @async
* @param {CopyRequest} copyRequest - The request object.
* @return {Promise<S3CopyResult>} Promise resolves upon successful copy of the object.
* @param {CopyInput} input - The request object.
* @return {Promise<CopyOutput>} Promise resolves upon successful copy of the object.
* @throws service: {@link S3Exception} - Thrown when checking for existence of the object
* @throws validation: {@link StorageValidationErrorCode } - Thrown when
* source or destination key are not defined.
*/
export const copy = async (copyRequest: CopyRequest): Promise<S3CopyResult> => {
return copyInternal(Amplify, copyRequest);
export const copy = async (input: CopyInput): Promise<CopyOutput> => {
return copyInternal(Amplify, input);
};
18 changes: 6 additions & 12 deletions packages/storage/src/providers/s3/apis/downloadData.ts
Original file line number Diff line number Diff line change
@@ -3,19 +3,18 @@

import { Amplify } from '@aws-amplify/core';

import { S3TransferOptions, S3DownloadDataResult } from '../types';
import { DownloadDataInput, DownloadDataOutput } from '../types';
import { resolveS3ConfigAndInput } from '../utils/resolveS3ConfigAndInput';
import { StorageValidationErrorCode } from '../../../errors/types/validation';
import { StorageDownloadDataRequest, DownloadTask } from '../../../types';
import { createDownloadTask } from '../utils';
import { getObject } from '../utils/client';

/**
* Download S3 object data to memory
*
* @param {StorageDownloadDataRequest<S3TransferOptions>} downloadDataRequest The parameters that are passed to the
* @param {DownloadDataRequest<S3DownloadDataOptions>} input The parameters that are passed to the
* downloadData operation.
* @returns {DownloadTask<S3DownloadDataResult>} Cancelable task exposing result promise from `result` property.
* @returns {DownloadDataOutput} Cancelable task exposing result promise from `result` property.
* @throws service: {@link S3Exception} - thrown when checking for existence of the object
* @throws validation: {@link StorageValidationErrorCode } - Validation errors
*
@@ -41,13 +40,11 @@ import { getObject } from '../utils/client';
* }
*```
*/
export const downloadData = (
downloadDataRequest: StorageDownloadDataRequest<S3TransferOptions>
): DownloadTask<S3DownloadDataResult> => {
export const downloadData = (input: DownloadDataInput): DownloadDataOutput => {
const abortController = new AbortController();

const downloadTask = createDownloadTask({
job: downloadDataJob(downloadDataRequest, abortController.signal),
job: downloadDataJob(input, abortController.signal),
onCancel: (abortErrorOverwrite?: Error) => {
abortController.abort(abortErrorOverwrite);
},
@@ -57,10 +54,7 @@ export const downloadData = (

const downloadDataJob =
(
{
options: downloadDataOptions,
key,
}: StorageDownloadDataRequest<S3TransferOptions>,
{ options: downloadDataOptions, key }: DownloadDataInput,
abortSignal: AbortSignal
) =>
async () => {
13 changes: 6 additions & 7 deletions packages/storage/src/providers/s3/apis/getProperties.ts
Original file line number Diff line number Diff line change
@@ -2,21 +2,20 @@
// SPDX-License-Identifier: Apache-2.0

import { Amplify } from '@aws-amplify/core';
import { StorageOperationRequest, StorageOptions } from '../../../types';
import { S3GetPropertiesResult } from '../types';
import { GetPropertiesOutput, GetPropertiesInput } from '../types';
import { getProperties as getPropertiesInternal } from './internal/getProperties';

/**
* Gets the properties of a file. The properties include S3 system metadata and
* the user metadata that was provided when uploading the file.
*
* @param {StorageOperationRequest} req The request to make an API call.
* @returns {Promise<S3GetPropertiesResult>} A promise that resolves the properties.
* @param {GetPropertiesInput} The input to make an API call.
* @returns {Promise<GetPropertiesOutput>} A promise that resolves the properties.
* @throws A {@link S3Exception} when the underlying S3 service returned error.
* @throws A {@link StorageValidationErrorCode} when API call parameters are invalid.
*/
export const getProperties = (
req: StorageOperationRequest<StorageOptions>
): Promise<S3GetPropertiesResult> => {
return getPropertiesInternal(Amplify, req);
input: GetPropertiesInput
): Promise<GetPropertiesOutput> => {
return getPropertiesInternal(Amplify, input);
};
14 changes: 6 additions & 8 deletions packages/storage/src/providers/s3/apis/getUrl.ts
Original file line number Diff line number Diff line change
@@ -2,8 +2,8 @@
// SPDX-License-Identifier: Apache-2.0

import { Amplify } from '@aws-amplify/core';
import { StorageDownloadDataRequest } from '../../../types';
import { S3GetUrlOptions, S3GetUrlResult } from '../types';
import {} from '../../../types';
import { GetUrlInput, GetUrlOutput } from '../types';
import { getUrl as getUrlInternal } from './internal/getUrl';

/**
@@ -14,15 +14,13 @@ import { getUrl as getUrlInternal } from './internal/getUrl';
* to true, this method will verify the given object already exists in S3 before returning a presigned
* URL, and will throw {@link StorageError} if the object does not exist.
*
* @param {StorageDownloadDataRequest<S3GetUrlOptions>} The request object
* @return {Promise<S3GetUrlResult>} url of the object
* @param {GetUrlInput} The input object
* @return {Promise<GetUrlOutput>} url of the object
* @throws service: {@link S3Exception} - thrown when checking for existence of the object
* @throws validation: {@link StorageValidationErrorCode } - Validation errors
* thrown either username or key are not defined.
*
*/
export const getUrl = (
req: StorageDownloadDataRequest<S3GetUrlOptions>
): Promise<S3GetUrlResult> => {
return getUrlInternal(Amplify, req);
export const getUrl = (input: GetUrlInput): Promise<GetUrlOutput> => {
return getUrlInternal(Amplify, input);
};
13 changes: 6 additions & 7 deletions packages/storage/src/providers/s3/apis/internal/copy.ts
Original file line number Diff line number Diff line change
@@ -2,21 +2,20 @@
// SPDX-License-Identifier: Apache-2.0

import { AmplifyClassV6 } from '@aws-amplify/core';
import { S3CopyResult } from '../../types';
import { CopyRequest } from '../../../../types';
import { CopyInput, CopyOutput } from '../../types';
import { resolveS3ConfigAndInput } from '../../utils';
import { StorageValidationErrorCode } from '../../../../errors/types/validation';
import { assertValidationError } from '../../../../errors/utils/assertValidationError';
import { copyObject } from '../../utils/client';

export const copy = async (
amplify: AmplifyClassV6,
copyRequest: CopyRequest
): Promise<S3CopyResult> => {
input: CopyInput
): Promise<CopyOutput> => {
const {
source: { key: sourceKey },
destination: { key: destinationKey },
} = copyRequest;
} = input;

assertValidationError(!!sourceKey, StorageValidationErrorCode.NoSourceKey);
assertValidationError(
@@ -28,10 +27,10 @@ export const copy = async (
s3Config,
bucket,
keyPrefix: sourceKeyPrefix,
} = await resolveS3ConfigAndInput(amplify, copyRequest.source);
} = await resolveS3ConfigAndInput(amplify, input.source);
const { keyPrefix: destinationKeyPrefix } = await resolveS3ConfigAndInput(
amplify,
copyRequest.destination
input.destination
); // resolveS3ConfigAndInput does not make extra API calls or storage access if called repeatedly.

// TODO(ashwinkumar6) V6-logger: warn `You may copy files from another user if the source level is "protected", currently it's ${srcLevel}`
Original file line number Diff line number Diff line change
@@ -2,16 +2,15 @@
// SPDX-License-Identifier: Apache-2.0

import { AmplifyClassV6 } from '@aws-amplify/core';
import { StorageOptions, StorageOperationRequest } from '../../../../types';
import { S3GetPropertiesResult } from '../../types';
import { GetPropertiesInput, GetPropertiesOutput } from '../../types';
import { resolveS3ConfigAndInput } from '../../utils';
import { headObject } from '../../utils/client';

export const getProperties = async function (
amplify: AmplifyClassV6,
getPropertiesRequest: StorageOperationRequest<StorageOptions>
): Promise<S3GetPropertiesResult> {
const { key, options } = getPropertiesRequest;
input: GetPropertiesInput
): Promise<GetPropertiesOutput> {
const { key, options } = input;
const { s3Config, bucket, keyPrefix } = await resolveS3ConfigAndInput(
amplify,
options
10 changes: 4 additions & 6 deletions packages/storage/src/providers/s3/apis/internal/getUrl.ts
Original file line number Diff line number Diff line change
@@ -2,9 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

import { AmplifyClassV6 } from '@aws-amplify/core';

import { StorageDownloadDataRequest } from '../../../../types';
import { S3GetUrlOptions, S3GetUrlResult } from '../../types';
import { GetUrlInput, GetUrlOutput } from '../../types';
import { StorageValidationErrorCode } from '../../../../errors/types/validation';
import { getPresignedGetObjectUrl } from '../../utils/client';
import { getProperties } from './getProperties';
@@ -17,9 +15,9 @@ import {

export const getUrl = async function (
amplify: AmplifyClassV6,
getUrlRequest: StorageDownloadDataRequest<S3GetUrlOptions>
): Promise<S3GetUrlResult> {
const { key, options } = getUrlRequest;
input: GetUrlInput
): Promise<GetUrlOutput> {
const { key, options } = input;

if (options?.validateObjectExistence) {
await getProperties(amplify, { key, options });
29 changes: 12 additions & 17 deletions packages/storage/src/providers/s3/apis/internal/list.ts
Original file line number Diff line number Diff line change
@@ -3,14 +3,11 @@

import { AmplifyClassV6 } from '@aws-amplify/core';
import {
StorageListRequest,
StorageListAllOptions,
StorageListPaginateOptions,
} from '../../../../types';
import {
S3ListOutputItem,
S3ListAllResult,
S3ListPaginateResult,
ListAllInput,
ListPaginateInput,
ListAllOutput,
ListPaginateOutput,
ListOutputItem,
} from '../../types';
import { resolveS3ConfigAndInput } from '../../utils';
import { ResolvedS3Config } from '../../types/options';
@@ -22,19 +19,17 @@ import {

const MAX_PAGE_SIZE = 1000;

type ListRequestArgs = {
type ListInputArgs = {
s3Config: ResolvedS3Config;
listParams: ListObjectsV2Input;
prefix: string;
};

export const list = async (
amplify: AmplifyClassV6,
listRequest?:
| StorageListRequest<StorageListAllOptions>
| StorageListRequest<StorageListPaginateOptions>
): Promise<S3ListAllResult | S3ListPaginateResult> => {
const { options = {}, prefix: path = '' } = listRequest ?? {};
input?: ListAllInput | ListPaginateInput
): Promise<ListAllOutput | ListPaginateOutput> => {
const { options = {}, prefix: path = '' } = input ?? {};
const {
s3Config,
bucket,
@@ -55,9 +50,9 @@ const _listAll = async ({
s3Config,
listParams,
prefix,
}: ListRequestArgs): Promise<S3ListAllResult> => {
}: ListInputArgs): Promise<ListAllOutput> => {
// TODO(ashwinkumar6) V6-logger: pageSize and nextToken aren't required when listing all items
const listResult: S3ListOutputItem[] = [];
const listResult: ListOutputItem[] = [];
let continuationToken = listParams.ContinuationToken;
do {
const { items: pageResults, nextToken: pageNextToken } = await _list({
@@ -82,7 +77,7 @@ const _list = async ({
s3Config,
listParams,
prefix,
}: ListRequestArgs): Promise<S3ListPaginateResult> => {
}: ListInputArgs): Promise<ListPaginateOutput> => {
const listParamsClone = { ...listParams };
if (!listParamsClone.MaxKeys || listParamsClone.MaxKeys > MAX_PAGE_SIZE) {
listParamsClone.MaxKeys = MAX_PAGE_SIZE;
13 changes: 4 additions & 9 deletions packages/storage/src/providers/s3/apis/internal/remove.ts
Original file line number Diff line number Diff line change
@@ -2,20 +2,15 @@
// SPDX-License-Identifier: Apache-2.0

import { AmplifyClassV6 } from '@aws-amplify/core';

import {
StorageOperationRequest,
StorageRemoveOptions,
StorageRemoveResult,
} from '../../../../types';
import { RemoveInput, RemoveOutput } from '../../types';
import { resolveS3ConfigAndInput } from '../../utils';
import { deleteObject } from '../../utils/client';

export const remove = async (
amplify: AmplifyClassV6,
removeRequest: StorageOperationRequest<StorageRemoveOptions>
): Promise<StorageRemoveResult> => {
const { key, options = {} } = removeRequest;
input: RemoveInput
): Promise<RemoveOutput> => {
const { key, options = {} } = input;
const { s3Config, keyPrefix, bucket } = await resolveS3ConfigAndInput(
amplify,
options
34 changes: 16 additions & 18 deletions packages/storage/src/providers/s3/apis/list.ts
Original file line number Diff line number Diff line change
@@ -3,37 +3,35 @@

import { Amplify } from '@aws-amplify/core';
import {
StorageListAllOptions,
StorageListPaginateOptions,
StorageListRequest,
} from '../../../types';
import { S3ListAllResult, S3ListPaginateResult } from '../types';
ListAllInput,
ListPaginateInput,
ListAllOutput,
ListPaginateOutput,
} from '../types';
import { list as listInternal } from './internal/list';

type S3ListApi = {
type ListApi = {
/**
* List files with given prefix in pages
* pageSize defaulted to 1000. Additionally, the result will include a nextToken if there are more items to retrieve.
* @param {StorageListRequest<StorageListPaginateOptions>} req - The request object
* @return {Promise<S3ListPaginateResult>} - Promise resolves to list of keys and metadata with
* @param {ListPaginateInput} The input object
* @return {Promise<ListPaginateOutput>} - Promise resolves to list of keys and metadata with
* @throws service: {@link S3Exception} - S3 service errors thrown when checking for existence of bucket
* @throws validation: {@link StorageValidationErrorCode } - thrown when there are issues with credentials
*/
(
req?: StorageListRequest<StorageListPaginateOptions>
): Promise<S3ListPaginateResult>;
(input?: ListPaginateInput): Promise<ListPaginateOutput>;
/**
* List all files from S3. You can set `listAll` to true in `options` to get all the files from S3.
* @param {StorageListRequest<StorageListAllOptions>} req - The request object
* @return {Promise<S3ListAllResult>} - Promise resolves to list of keys and metadata for all objects in path
* @param {ListAllInput} The input object
* @return {Promise<ListAllOutput>} - Promise resolves to list of keys and metadata for all objects in path
* @throws service: {@link S3Exception} - S3 service errors thrown when checking for existence of bucket
* @throws validation: {@link StorageValidationErrorCode } - thrown when there are issues with credentials
*/
(req?: StorageListRequest<StorageListAllOptions>): Promise<S3ListAllResult>;
(input?: ListAllInput): Promise<ListAllOutput>;
};

export const list: S3ListApi = (
req
): Promise<S3ListAllResult | S3ListPaginateResult> => {
return listInternal(Amplify, req ?? {});
export const list: ListApi = (
input?: ListAllInput | ListPaginateInput
): Promise<ListAllOutput | ListPaginateOutput> => {
return listInternal(Amplify, input ?? {});
};
Loading

0 comments on commit 4d97235

Please sign in to comment.