From d8f395cbb88cc62581985e8f4810211b81f2c1b7 Mon Sep 17 00:00:00 2001 From: Hui Zhao <10602282+HuiSF@users.noreply.github.com> Date: Mon, 11 Sep 2023 10:40:08 -0700 Subject: [PATCH 01/12] chore(core,aws-amplify): move ssr flag into the libraryOptions param (#11998) - Add unit tests for initSingleton Co-authored-by: Jim Blanchard --- .../createUserPoolsTokenProvider.test.ts | 8 +- .../aws-amplify/__tests__/exports.test.ts | 3 + .../__tests__/initSingleton.test.ts | 169 ++++++++++++++++++ packages/aws-amplify/src/initSingleton.ts | 13 +- packages/core/src/singleton/Amplify.ts | 16 +- packages/core/src/singleton/types.ts | 2 +- 6 files changed, 194 insertions(+), 17 deletions(-) create mode 100644 packages/aws-amplify/__tests__/initSingleton.test.ts diff --git a/packages/aws-amplify/__tests__/adapterCore/authProvidersFactories/cognito/createUserPoolsTokenProvider.test.ts b/packages/aws-amplify/__tests__/adapterCore/authProvidersFactories/cognito/createUserPoolsTokenProvider.test.ts index b08f4900d49..fd47cb59147 100644 --- a/packages/aws-amplify/__tests__/adapterCore/authProvidersFactories/cognito/createUserPoolsTokenProvider.test.ts +++ b/packages/aws-amplify/__tests__/adapterCore/authProvidersFactories/cognito/createUserPoolsTokenProvider.test.ts @@ -19,9 +19,11 @@ const mockKeyValueStorage: KeyValueStorageInterface = { clear: jest.fn(), }; const mockAuthConfig: AuthConfig = { - identityPoolId: '123', - userPoolId: 'abc', - userPoolWebClientId: 'def', + Cognito: { + identityPoolId: '123', + userPoolId: 'abc', + userPoolClientId: 'def', + }, }; const MockDefaultTokenStore = DefaultTokenStore as jest.Mock; const MockTokenOrchestrator = TokenOrchestrator as jest.Mock; diff --git a/packages/aws-amplify/__tests__/exports.test.ts b/packages/aws-amplify/__tests__/exports.test.ts index 7242b35373b..ebf78a76c6d 100644 --- a/packages/aws-amplify/__tests__/exports.test.ts +++ b/packages/aws-amplify/__tests__/exports.test.ts @@ -1,3 +1,6 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + import * as exported from '../src'; describe('aws-amplify', () => { diff --git a/packages/aws-amplify/__tests__/initSingleton.test.ts b/packages/aws-amplify/__tests__/initSingleton.test.ts new file mode 100644 index 00000000000..b2491449780 --- /dev/null +++ b/packages/aws-amplify/__tests__/initSingleton.test.ts @@ -0,0 +1,169 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { + ResourcesConfig, + Amplify as AmplifySingleton, + LocalStorage, + CookieStorage, + TokenProvider, +} from '@aws-amplify/core'; +import { + CognitoUserPoolsTokenProvider, + cognitoCredentialsProvider, +} from '../src/auth/cognito'; + +import { Amplify } from '../src'; + +jest.mock('@aws-amplify/core', () => ({ + ...jest.requireActual('@aws-amplify/core'), + Amplify: { + configure: jest.fn(), + getConfig: jest.fn(), + }, + LocalStorage: jest.fn(), + CookieStorage: jest.fn(), +})); + +jest.mock('../src/auth/cognito', () => ({ + CognitoUserPoolsTokenProvider: { + setAuthConfig: jest.fn(), + setKeyValueStorage: jest.fn(), + }, + cognitoCredentialsProvider: jest.fn(), +})); + +const mockCognitoUserPoolsTokenProviderSetAuthConfig = + CognitoUserPoolsTokenProvider.setAuthConfig as jest.Mock; +const mockCognitoUserPoolsTokenProviderSetKeyValueStorage = + CognitoUserPoolsTokenProvider.setKeyValueStorage as jest.Mock; +const mockAmplifySingletonConfigure = AmplifySingleton.configure as jest.Mock; +const mockAmplifySingletonGetConfig = AmplifySingleton.getConfig as jest.Mock; +const MockCookieStorage = CookieStorage as jest.Mock; + +const mockResourceConfig: ResourcesConfig = { + Auth: { + Cognito: { + userPoolClientId: 'userPoolClientId', + userPoolId: 'userPoolId', + }, + }, + Storage: { + S3: { + bucket: 'bucket', + region: 'us-west-2', + }, + }, +}; + +describe('initSingleton (DefaultAmplify)', () => { + beforeEach(() => { + mockCognitoUserPoolsTokenProviderSetAuthConfig.mockReset(); + mockCognitoUserPoolsTokenProviderSetKeyValueStorage.mockReset(); + mockAmplifySingletonConfigure.mockReset(); + mockAmplifySingletonGetConfig.mockReset(); + }); + + describe('DefaultAmplify.configure()', () => { + describe('when ResourcesConfig.Auth is defined', () => { + describe('when libraryOptions.Auth is undefined', () => { + it('should invoke AmplifySingleton.configure with the default auth providers', () => { + Amplify.configure(mockResourceConfig); + + expect( + mockCognitoUserPoolsTokenProviderSetAuthConfig + ).toHaveBeenCalledWith(mockResourceConfig.Auth); + + expect(mockAmplifySingletonConfigure).toHaveBeenCalledWith( + mockResourceConfig, + { + Auth: { + tokenProvider: CognitoUserPoolsTokenProvider, + credentialsProvider: cognitoCredentialsProvider, + }, + } + ); + }); + + it('should invoke AmplifySingleton.configure with other provided library options', () => { + const libraryOptionsWithStorage = { + Storage: { + S3: { + defaultAccessLevel: 'private', + isObjectLockEnabled: true, + }, + }, + }; + + Amplify.configure(mockResourceConfig, { + Storage: { + S3: { + defaultAccessLevel: 'private', + isObjectLockEnabled: true, + }, + }, + }); + + expect(mockAmplifySingletonConfigure).toHaveBeenCalledWith( + mockResourceConfig, + { + Auth: { + tokenProvider: CognitoUserPoolsTokenProvider, + credentialsProvider: cognitoCredentialsProvider, + }, + ...libraryOptionsWithStorage, + } + ); + }); + + it('should use LocalStorage by default for the default CognitoUserPoolsTokenProvider', () => { + Amplify.configure(mockResourceConfig); + + expect( + mockCognitoUserPoolsTokenProviderSetKeyValueStorage + ).toHaveBeenCalledWith(LocalStorage); + }); + + it('should use cookie storage if LibraryOptions.ssr is set to true for the default CognitoUserPoolsTokenProvider', () => { + Amplify.configure(mockResourceConfig, { ssr: true }); + + expect(MockCookieStorage).toHaveBeenCalledWith({ + sameSite: 'strict', + }); + expect( + mockCognitoUserPoolsTokenProviderSetKeyValueStorage + ).toHaveBeenCalledTimes(1); + }); + }); + + describe('when libraryOptions.Auth is defined', () => { + it('should forward the libraryOptions to AmplifySingleton.configure', () => { + const mockTokenProvider: TokenProvider = { + getTokens: jest.fn(), + }; + const mockLibraryOptions = { + Auth: { + tokenProvider: mockTokenProvider, + }, + }; + Amplify.configure(mockResourceConfig, mockLibraryOptions); + + expect(mockAmplifySingletonConfigure).toHaveBeenCalledWith( + mockResourceConfig, + mockLibraryOptions + ); + }); + }); + }); + }); + + describe('DefaultAmplify.getConfig()', () => { + it('should invoke AmplifySingleton.getConfig and return its result', () => { + mockAmplifySingletonGetConfig.mockReturnValueOnce(mockResourceConfig); + const result = Amplify.getConfig(); + + expect(mockAmplifySingletonGetConfig).toHaveBeenCalledTimes(1); + expect(result).toEqual(mockResourceConfig); + }); + }); +}); diff --git a/packages/aws-amplify/src/initSingleton.ts b/packages/aws-amplify/src/initSingleton.ts index 7be9630df01..7c987777b86 100644 --- a/packages/aws-amplify/src/initSingleton.ts +++ b/packages/aws-amplify/src/initSingleton.ts @@ -14,10 +14,13 @@ import { export const DefaultAmplify = { configure(resourceConfig: ResourcesConfig, libraryOptions?: LibraryOptions) { - if (resourceConfig.Auth && !libraryOptions) { + // When Auth config is provided but no custom Auth provider defined + // use the default Auth Providers + if (resourceConfig.Auth && !libraryOptions?.Auth) { CognitoUserPoolsTokenProvider.setAuthConfig(resourceConfig.Auth); - const defaultLibraryOptions: LibraryOptions = { + const libraryOptionsWithDefaultAuthProviders: LibraryOptions = { + ...libraryOptions, Auth: { tokenProvider: CognitoUserPoolsTokenProvider, credentialsProvider: cognitoCredentialsProvider, @@ -25,14 +28,14 @@ export const DefaultAmplify = { }; CognitoUserPoolsTokenProvider.setKeyValueStorage( - resourceConfig.ssr + libraryOptions?.ssr ? new CookieStorage({ sameSite: 'strict', - }) + }) : LocalStorage ); - Amplify.configure(resourceConfig, defaultLibraryOptions); + Amplify.configure(resourceConfig, libraryOptionsWithDefaultAuthProviders); } else { Amplify.configure(resourceConfig, libraryOptions); } diff --git a/packages/core/src/singleton/Amplify.ts b/packages/core/src/singleton/Amplify.ts index bb3f1f72645..a11a6d46ad1 100644 --- a/packages/core/src/singleton/Amplify.ts +++ b/packages/core/src/singleton/Amplify.ts @@ -88,15 +88,13 @@ function mergeResourceConfig( resultConfig[category] = existingConfig[category as keyof ResourcesConfig]; } - for (const key of Object.keys(newConfig).filter(key => key !== 'ssr')) { + for (const key of Object.keys(newConfig)) { resultConfig[key] = { ...resultConfig[key], - ...newConfig[key as Exclude], + ...newConfig[key as keyof ResourcesConfig], }; } - resultConfig.ssr = newConfig.ssr; - return resultConfig; } @@ -110,12 +108,14 @@ function mergeLibraryOptions( resultConfig[category] = existingConfig[category as keyof LibraryOptions]; } - for (const category of Object.keys(newConfig)) { - resultConfig[category] = { - ...resultConfig[category], - ...newConfig[category as keyof LibraryOptions], + for (const key of Object.keys(newConfig).filter(key => key !== 'ssr')) { + resultConfig[key] = { + ...resultConfig[key], + ...newConfig[key as Exclude], }; } + resultConfig.ssr = newConfig.ssr; + return resultConfig; } diff --git a/packages/core/src/singleton/types.ts b/packages/core/src/singleton/types.ts index 8ad0bddb01a..ce78a4016f9 100644 --- a/packages/core/src/singleton/types.ts +++ b/packages/core/src/singleton/types.ts @@ -28,12 +28,12 @@ export type ResourcesConfig = { // Notifications?: {}; // Predictions?: {}; Storage?: StorageConfig; - ssr?: boolean; }; export type LibraryOptions = { Auth?: LibraryAuthOptions; Storage?: LibraryStorageOptions; + ssr?: boolean; }; export { From cdc25145e49dbc6d414cecf53bae1e3ed50cec9c Mon Sep 17 00:00:00 2001 From: Jim Blanchard Date: Mon, 11 Sep 2023 12:46:39 -0500 Subject: [PATCH 02/12] chore: Remove extra util exports (#12006) --- packages/aws-amplify/src/utils/index.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/aws-amplify/src/utils/index.ts b/packages/aws-amplify/src/utils/index.ts index 08128d33464..a391c235a5e 100644 --- a/packages/aws-amplify/src/utils/index.ts +++ b/packages/aws-amplify/src/utils/index.ts @@ -4,8 +4,4 @@ /* This file maps exports from `aws-amplify/utils`. */ -export { - Cache, - Hub, - I18n -} from '@aws-amplify/core'; +export { Hub } from '@aws-amplify/core'; From 32b81d41eb313365c3209de65c1ebadd1c6ce25d Mon Sep 17 00:00:00 2001 From: Hui Zhao <10602282+HuiSF@users.noreply.github.com> Date: Mon, 11 Sep 2023 11:01:15 -0700 Subject: [PATCH 03/12] chore(auth): fix typo (#12007) --- packages/auth/src/providers/cognito/apis/verifyTOTPSetup.ts | 4 ++-- packages/auth/src/providers/cognito/types/index.ts | 2 +- packages/auth/src/providers/cognito/types/options.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/auth/src/providers/cognito/apis/verifyTOTPSetup.ts b/packages/auth/src/providers/cognito/apis/verifyTOTPSetup.ts index df0477555e4..82414cd49c5 100644 --- a/packages/auth/src/providers/cognito/apis/verifyTOTPSetup.ts +++ b/packages/auth/src/providers/cognito/apis/verifyTOTPSetup.ts @@ -4,7 +4,7 @@ import { AuthValidationErrorCode } from '../../../errors/types/validation'; import { assertValidationError } from '../../../errors/utils/assertValidationError'; import { VerifyTOTPSetupRequest } from '../../../types/requests'; -import { CogntioVerifyTOTPSetupOptions } from '../types/options'; +import { CognitoVerifyTOTPSetupOptions } from '../types/options'; import { verifySoftwareToken } from '../utils/clients/CognitoIdentityProvider'; import { VerifySoftwareTokenException } from '../types/errors'; import { Amplify } from '@aws-amplify/core'; @@ -27,7 +27,7 @@ import { assertAuthTokens } from '../utils/types'; * @throws AuthTokenConfigException - Thrown when the token provider config is invalid. */ export async function verifyTOTPSetup( - verifyTOTPSetupRequest: VerifyTOTPSetupRequest + verifyTOTPSetupRequest: VerifyTOTPSetupRequest ): Promise { const authConfig = Amplify.getConfig().Auth?.Cognito; assertTokenProviderConfig(authConfig); diff --git a/packages/auth/src/providers/cognito/types/index.ts b/packages/auth/src/providers/cognito/types/index.ts index beb3ed906a4..4c193b9f1a0 100644 --- a/packages/auth/src/providers/cognito/types/index.ts +++ b/packages/auth/src/providers/cognito/types/index.ts @@ -18,7 +18,7 @@ export { CognitoConfirmSignUpOptions, CognitoConfirmSignInOptions, CognitoUpdateUserAttributesOptions, - CogntioVerifyTOTPSetupOptions, + CognitoVerifyTOTPSetupOptions, } from './options'; export { UpdateMFAPreferenceRequest } from './requests'; diff --git a/packages/auth/src/providers/cognito/types/options.ts b/packages/auth/src/providers/cognito/types/options.ts index ab10a7f8e02..18592500534 100644 --- a/packages/auth/src/providers/cognito/types/options.ts +++ b/packages/auth/src/providers/cognito/types/options.ts @@ -64,7 +64,7 @@ export type CognitoConfirmSignInOptions< /** * Options specific to a Cognito Verify TOTP Setup request. */ -export type CogntioVerifyTOTPSetupOptions = { +export type CognitoVerifyTOTPSetupOptions = { friendlyDeviceName?: string; }; From 54730e2ad2ec673f5effd2f673424bca8517e1c8 Mon Sep 17 00:00:00 2001 From: ManojNB Date: Mon, 11 Sep 2023 11:41:49 -0700 Subject: [PATCH 04/12] fix(core): parse empty oauth param (#11999) fix: parse empty oauth param Co-authored-by: Jim Blanchard --- packages/core/src/parseAWSExports.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/core/src/parseAWSExports.ts b/packages/core/src/parseAWSExports.ts index 3a8a1156a50..acac048c2c4 100644 --- a/packages/core/src/parseAWSExports.ts +++ b/packages/core/src/parseAWSExports.ts @@ -49,7 +49,10 @@ export const parseAWSExports = ( signUpVerificationMethod: aws_cognito_sign_up_verification_method, userPoolClientId: aws_user_pools_web_client_id, userPoolId: aws_user_pools_id, - ...(oauth && { loginWith: getOAuthConfig(oauth) }), + ...(oauth && + Object.keys(oauth).length > 0 && { + loginWith: getOAuthConfig(oauth), + }), }, }; } From bc302ee4eb9a89253077ce08130f1e09120173c4 Mon Sep 17 00:00:00 2001 From: Ashwin Kumar Date: Mon, 11 Sep 2023 11:51:06 -0700 Subject: [PATCH 05/12] fix(storage): rename list request path to prefix (#11997) fix(storage): list request would expose prefix instead of path Co-authored-by: Sridhar Co-authored-by: Aaron S <94858815+stocaaro@users.noreply.github.com> --- packages/storage/__tests__/providers/s3/apis/list.test.ts | 6 +++--- packages/storage/src/providers/s3/apis/internal/list.ts | 2 +- packages/storage/src/types/requests.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/storage/__tests__/providers/s3/apis/list.test.ts b/packages/storage/__tests__/providers/s3/apis/list.test.ts index 6defa0e89aa..b57d282f096 100644 --- a/packages/storage/__tests__/providers/s3/apis/list.test.ts +++ b/packages/storage/__tests__/providers/s3/apis/list.test.ts @@ -125,7 +125,7 @@ describe('list API', () => { expect.assertions(4); const customPageSize = 5; const response = await list({ - path: 'listWithTokenResultsPath', + prefix: 'listWithTokenResultsPath', options: { accessLevel: 'guest', pageSize: customPageSize, @@ -148,7 +148,7 @@ describe('list API', () => { mockListObjectsV2ApiWithPages(3); const result = await list({ - path: 'listALLResultsPath', + prefix: 'listALLResultsPath', options: { accessLevel: 'guest', listAll: true }, }); @@ -185,7 +185,7 @@ describe('list API', () => { expect.assertions(3); let response = await list({ - path: 'emptyListResultsPath', + prefix: 'emptyListResultsPath', options: { accessLevel: 'guest', }, diff --git a/packages/storage/src/providers/s3/apis/internal/list.ts b/packages/storage/src/providers/s3/apis/internal/list.ts index 3f7fc37776c..fff8647d7ad 100644 --- a/packages/storage/src/providers/s3/apis/internal/list.ts +++ b/packages/storage/src/providers/s3/apis/internal/list.ts @@ -34,7 +34,7 @@ export const list = async ( | StorageListRequest | StorageListRequest ): Promise => { - const { options = {}, path = '' } = listRequest ?? {}; + const { options = {}, prefix: path = '' } = listRequest ?? {}; const { s3Config, bucket, diff --git a/packages/storage/src/types/requests.ts b/packages/storage/src/types/requests.ts index 27eff108b58..2b8f59db3b1 100644 --- a/packages/storage/src/types/requests.ts +++ b/packages/storage/src/types/requests.ts @@ -18,7 +18,7 @@ export type StorageOperationRequest = { export type StorageListRequest< Options extends StorageListAllOptions | StorageListPaginateOptions > = { - path?: string; + prefix?: string; options?: Options; }; From f0dbcf338b0e1584f93245fe0431498f90def7fd Mon Sep 17 00:00:00 2001 From: Jim Blanchard Date: Tue, 12 Sep 2023 10:38:20 -0500 Subject: [PATCH 06/12] chore: Set up missing exports & `typesVersions` specification (#12008) --- packages/auth/cognito/server/package.json | 7 +++++++ packages/auth/package.json | 18 ++++++++++++++++- .../auth/cognito/server/package.json | 7 +++++++ packages/aws-amplify/package.json | 20 +++++++++++++++++++ .../src/auth/cognito/server/index.ts | 7 +++++++ packages/storage/package.json | 9 +++++++++ 6 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 packages/auth/cognito/server/package.json create mode 100644 packages/aws-amplify/auth/cognito/server/package.json create mode 100644 packages/aws-amplify/src/auth/cognito/server/index.ts diff --git a/packages/auth/cognito/server/package.json b/packages/auth/cognito/server/package.json new file mode 100644 index 00000000000..dfc8fc1645f --- /dev/null +++ b/packages/auth/cognito/server/package.json @@ -0,0 +1,7 @@ +{ + "name": "@aws-amplify/auth/cognito/server", + "main": "../../lib/providers/cognito/apis/server/index.js", + "browser": "../../lib-esm/providers/cognito/apis/server/index.js", + "module": "../../lib-esm/providers/cognito/apis/server/index.js", + "typings": "../../lib-esm/providers/cognito/apis/server/index.d.ts" +} diff --git a/packages/auth/package.json b/packages/auth/package.json index d5e70f0e333..212ad073413 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -34,6 +34,15 @@ ], "cognito": [ "./lib-esm/providers/cognito/index.d.ts" + ], + "cognito/server": [ + "./lib-esm/providers/cognito/apis/server/index.d.ts" + ], + "server": [ + "./lib-esm/server.d.ts" + ], + "internals": [ + "./lib-esm/lib-esm/internals/index.d.ts" ] } }, @@ -48,6 +57,11 @@ "import": "./lib-esm/providers/cognito/index.js", "require": "./lib/providers/cognito/index.js" }, + "./cognito/server": { + "types": "./lib-esm/providers/cognito/apis/server/index.d.ts", + "import": "./lib-esm/providers/cognito/apis/server/index.js", + "require": "./lib/providers/cognito/apis/server/index.js" + }, "./server": { "types": "./lib-esm/server.d.ts", "import": "./lib-esm/server.js", @@ -74,7 +88,9 @@ "lib", "lib-esm", "src", - "internals" + "internals", + "cognito", + "server" ], "dependencies": { "@smithy/util-base64": "2.0.0", diff --git a/packages/aws-amplify/auth/cognito/server/package.json b/packages/aws-amplify/auth/cognito/server/package.json new file mode 100644 index 00000000000..bf9f1becd56 --- /dev/null +++ b/packages/aws-amplify/auth/cognito/server/package.json @@ -0,0 +1,7 @@ +{ + "name": "aws-amplify/auth/cognito/server", + "main": "../../../lib/auth/cognito/server/index.js", + "browser": "../../../lib-esm/auth/cognito/server/index.js", + "module": "../../../lib-esm/auth/cognito/server/index.js", + "typings": "../../../lib-esm/auth/cognito/server/index.d.ts" +} diff --git a/packages/aws-amplify/package.json b/packages/aws-amplify/package.json index 7f54446b014..33c8a73aad5 100644 --- a/packages/aws-amplify/package.json +++ b/packages/aws-amplify/package.json @@ -27,6 +27,11 @@ "import": "./lib-esm/auth/cognito/index.js", "require": "./lib/auth/cognito/index.js" }, + "./auth/cognito/server": { + "types": "./lib-esm/auth/cognito/server/index.d.ts", + "import": "./lib-esm/auth/cognito/server/index.js", + "require": "./lib/auth/cognito/server/index.js" + }, "./auth/server": { "types": "./lib-esm/auth/server.d.ts", "import": "./lib-esm/auth/server.js", @@ -83,6 +88,12 @@ "auth/cognito": [ "./lib-esm/auth/cognito/index.d.ts" ], + "auth/cognito/server": [ + "./lib-esm/auth/cognito/server/index.d.ts" + ], + "auth/server": [ + "./lib-esm/auth/server.d.ts" + ], "analytics": [ "./lib-esm/analytics/index.d.ts" ], @@ -94,6 +105,15 @@ ], "storage/s3": [ "./lib-esm/storage/s3/index.d.ts" + ], + "storage/server": [ + "./lib-esm/storage/server.d.ts" + ], + "storage/s3/server": [ + "./lib-esm/storage/s3/server.d.ts" + ], + "internals/adapter-core": [ + "./lib-esm/adapterCore/index.d.ts" ] } }, diff --git a/packages/aws-amplify/src/auth/cognito/server/index.ts b/packages/aws-amplify/src/auth/cognito/server/index.ts new file mode 100644 index 00000000000..991d3b702e4 --- /dev/null +++ b/packages/aws-amplify/src/auth/cognito/server/index.ts @@ -0,0 +1,7 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/* +This file maps exports from `aws-amplify/auth/cognito/server`. It provides access to server-enabled Cognito APIs. +*/ +export * from '@aws-amplify/auth/cognito/server'; diff --git a/packages/storage/package.json b/packages/storage/package.json index 7c19cc94f88..ee062649e50 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -33,6 +33,15 @@ ], "s3": [ "./lib-esm/providers/s3/index.d.ts" + ], + "server": [ + "./lib-esm/server.d.ts" + ], + "internals": [ + "./lib-esm/lib-esm/internals/index.d.ts" + ], + "s3/server": [ + "./lib-esm/providers/s3/server.d.ts" ] } }, From 50b0debc69689135cd8a1f92a548f468f340e5ea Mon Sep 17 00:00:00 2001 From: Hui Zhao <10602282+HuiSF@users.noreply.github.com> Date: Tue, 12 Sep 2023 12:02:50 -0700 Subject: [PATCH 07/12] fix(adapter-nextjs): getAmplifyConfig may not return config in the pages router (#12011) --- .../__tests__/utils/getAmplifyConfig.test.ts | 44 ++++++++++++++----- .../__tests__/withAmplify.test.ts | 10 +++++ .../src/utils/getAmplifyConfig.ts | 12 ++++- packages/adapter-nextjs/src/withAmplify.ts | 8 +++- 4 files changed, 60 insertions(+), 14 deletions(-) diff --git a/packages/adapter-nextjs/__tests__/utils/getAmplifyConfig.test.ts b/packages/adapter-nextjs/__tests__/utils/getAmplifyConfig.test.ts index 7d7f042155b..db38841e89c 100644 --- a/packages/adapter-nextjs/__tests__/utils/getAmplifyConfig.test.ts +++ b/packages/adapter-nextjs/__tests__/utils/getAmplifyConfig.test.ts @@ -1,32 +1,52 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 +import { NextConfig } from 'next'; +import getConfig from 'next/config'; import { getAmplifyConfig } from '../../src/utils/getAmplifyConfig'; +import { AmplifyError } from '@aws-amplify/core/internals/utils'; + +jest.mock('next/config'); + +const mockGetConfig = getConfig as jest.Mock; describe('getAmplifyConfig', () => { + const mockAmplifyConfig = { + Auth: { + identityPoolId: '123', + userPoolId: 'abc', + userPoolWebClientId: 'def', + }, + Storage: { + bucket: 'bucket', + region: 'us-east-1', + }, + }; + beforeEach(() => { + mockGetConfig.mockReturnValue({}); delete process.env.amplifyConfig; }); it('should return amplifyConfig from env vars', () => { - const mockAmplifyConfig = { - Auth: { - identityPoolId: '123', - userPoolId: 'abc', - userPoolWebClientId: 'def', - }, - Storage: { - bucket: 'bucket', - region: 'us-east-1', - }, - }; process.env.amplifyConfig = JSON.stringify(mockAmplifyConfig); const result = getAmplifyConfig(); expect(result).toEqual(mockAmplifyConfig); }); + it('should attempt to get amplifyConfig via getConfig provided by Next.js as a fallback', () => { + mockGetConfig.mockReturnValueOnce({ + serverRuntimeConfig: { + amplifyConfig: JSON.stringify(mockAmplifyConfig), + }, + }); + + const result = getAmplifyConfig(); + expect(result).toEqual(mockAmplifyConfig); + }); + it('should throw error when amplifyConfig is not found from env vars', () => { - expect(() => getAmplifyConfig()).toThrowError(); + expect(() => getAmplifyConfig()).toThrow(AmplifyError); }); }); diff --git a/packages/adapter-nextjs/__tests__/withAmplify.test.ts b/packages/adapter-nextjs/__tests__/withAmplify.test.ts index 4c050fb6d12..f943254b509 100644 --- a/packages/adapter-nextjs/__tests__/withAmplify.test.ts +++ b/packages/adapter-nextjs/__tests__/withAmplify.test.ts @@ -29,6 +29,9 @@ describe('withAmplify', () => { env: { amplifyConfig: JSON.stringify(mockAmplifyConfig), }, + serverRuntimeConfig: { + amplifyConfig: JSON.stringify(mockAmplifyConfig), + }, }); }); @@ -37,6 +40,9 @@ describe('withAmplify', () => { env: { existingKey: '123', }, + serverRuntimeConfig: { + myKey: 'myValue', + }, }; const result = withAmplify(nextConfig, mockAmplifyConfig); @@ -45,6 +51,10 @@ describe('withAmplify', () => { existingKey: '123', amplifyConfig: JSON.stringify(mockAmplifyConfig), }, + serverRuntimeConfig: { + myKey: 'myValue', + amplifyConfig: JSON.stringify(mockAmplifyConfig), + }, }); }); }); diff --git a/packages/adapter-nextjs/src/utils/getAmplifyConfig.ts b/packages/adapter-nextjs/src/utils/getAmplifyConfig.ts index b0697fdbfd0..8b00f207c0e 100644 --- a/packages/adapter-nextjs/src/utils/getAmplifyConfig.ts +++ b/packages/adapter-nextjs/src/utils/getAmplifyConfig.ts @@ -3,9 +3,19 @@ import { ResourcesConfig } from 'aws-amplify'; import { AmplifyServerContextError } from '@aws-amplify/core/internals/adapter-core'; +import getConfig from 'next/config'; export const getAmplifyConfig = (): ResourcesConfig => { - const configStr = process.env.amplifyConfig; + let configStr = process.env.amplifyConfig; + + // With a Next.js app that uses the Pages Router, the key-value pairs + // listed under the `env` field in the `next.config.js` is not accessible + // via process.env. at some occasion. Using the following as a fallback + // See: https://github.com/vercel/next.js/issues/39299 + if (!configStr) { + const { serverRuntimeConfig } = getConfig(); + configStr = serverRuntimeConfig?.amplifyConfig; + } if (!configStr) { throw new AmplifyServerContextError({ diff --git a/packages/adapter-nextjs/src/withAmplify.ts b/packages/adapter-nextjs/src/withAmplify.ts index 745b38f553e..1221196e80a 100644 --- a/packages/adapter-nextjs/src/withAmplify.ts +++ b/packages/adapter-nextjs/src/withAmplify.ts @@ -31,9 +31,15 @@ export const withAmplify = ( nextConfig: NextConfig, amplifyConfig: ResourcesConfig ) => { + const configStr = JSON.stringify(amplifyConfig); nextConfig.env = { ...nextConfig.env, - amplifyConfig: JSON.stringify(amplifyConfig), + amplifyConfig: configStr, + }; + + nextConfig.serverRuntimeConfig = { + ...nextConfig.serverRuntimeConfig, + amplifyConfig: configStr, }; return nextConfig; From 0356b2cf8df23c2c371f4eff182927426124f0dc Mon Sep 17 00:00:00 2001 From: Jim Blanchard Date: Tue, 12 Sep 2023 15:40:52 -0500 Subject: [PATCH 08/12] chore: Sync `next/release` from `next/main` (#12017) fix urlListener when is imported after configure (#12010) Co-authored-by: Ashwin Kumar Co-authored-by: Francisco Rodriguez --- .../cognito/apis/signInWithRedirect.ts | 76 ++++++++++--------- 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/packages/auth/src/providers/cognito/apis/signInWithRedirect.ts b/packages/auth/src/providers/cognito/apis/signInWithRedirect.ts index 1aab14b7ebf..0d4313a5472 100644 --- a/packages/auth/src/providers/cognito/apis/signInWithRedirect.ts +++ b/packages/auth/src/providers/cognito/apis/signInWithRedirect.ts @@ -40,7 +40,7 @@ export function signInWithRedirect( const authConfig = Amplify.getConfig().Auth?.Cognito; assertTokenProviderConfig(authConfig); assertOAuthConfig(authConfig); - + store.setAuthConfig(authConfig); let provider = 'COGNITO'; // Default if (typeof signInWithRedirectRequest?.provider === 'string') { @@ -347,45 +347,49 @@ function validateState(state?: string | null): asserts state { } } +async function parseRedirectURL() { + const authConfig = Amplify.getConfig().Auth?.Cognito; + try { + assertTokenProviderConfig(authConfig); + store.setAuthConfig(authConfig); + } catch (_err) { + // Token provider not configure nothing to do + return; + } + + // No OAuth inflight doesnt need to parse the url + if (!(await store.loadOAuthInFlight())) { + return; + } + try { + assertOAuthConfig(authConfig); + } catch (err) { + // TODO(v6): this should warn you have signInWithRedirect but is not configured + return; + } + + try { + const url = window.location.href; + + handleAuthResponse({ + currentUrl: url, + clientId: authConfig.userPoolClientId, + domain: authConfig.loginWith.oauth.domain, + redirectUri: authConfig.loginWith.oauth.redirectSignIn[0], + responseType: authConfig.loginWith.oauth.responseType, + userAgentValue: getAmplifyUserAgent(), + }); + } catch (err) { + // is ok if there is not OAuthConfig + } +} + function urlListener() { // Listen configure to parse url - // TODO(v6): what happens if configure gets called multiple times during code exchange + parseRedirectURL(); Hub.listen('core', async capsule => { if (capsule.payload.event === 'configure') { - const authConfig = Amplify.getConfig().Auth?.Cognito; - try { - assertTokenProviderConfig(authConfig); - store.setAuthConfig(authConfig); - } catch (_err) { - // Token provider not configure nothing to do - return; - } - - // No OAuth inflight doesnt need to parse the url - if (!(await store.loadOAuthInFlight())) { - return; - } - try { - assertOAuthConfig(authConfig); - } catch (err) { - // TODO(v6): this should warn you have signInWithRedirect but is not configured - return; - } - - try { - const url = window.location.href; - - handleAuthResponse({ - currentUrl: url, - clientId: authConfig.userPoolClientId, - domain: authConfig.loginWith.oauth.domain, - redirectUri: authConfig.loginWith.oauth.redirectSignIn[0], - responseType: authConfig.loginWith.oauth.responseType, - userAgentValue: getAmplifyUserAgent(), - }); - } catch (err) { - // is ok if there is not OAuthConfig - } + parseRedirectURL(); } }); } From 31f1067e4e1c46a2d35a4625e117bb5773dddf59 Mon Sep 17 00:00:00 2001 From: Francisco Rodriguez Date: Tue, 12 Sep 2023 14:26:53 -0700 Subject: [PATCH 09/12] fix(core): allow credentials to be called without token provider and no guest mode (#12012) fix allow guest credentials for custom provider --- .../__tests__/singleton/Singleton.test.ts | 27 +++++++++++++++++++ packages/core/src/singleton/Auth/index.ts | 11 +------- packages/core/src/singleton/Auth/types.ts | 4 +-- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/packages/core/__tests__/singleton/Singleton.test.ts b/packages/core/__tests__/singleton/Singleton.test.ts index 75056a582da..e4eeb991aa2 100644 --- a/packages/core/__tests__/singleton/Singleton.test.ts +++ b/packages/core/__tests__/singleton/Singleton.test.ts @@ -3,6 +3,7 @@ import { AuthClass as Auth } from '../../src/singleton/Auth'; import { decodeJWT } from '../../src/singleton/Auth/utils'; import { AWSCredentialsAndIdentityId } from '../../src/singleton/Auth/types'; import { TextEncoder, TextDecoder } from 'util'; +import { fetchAuthSession } from '../../src'; Object.assign(global, { TextDecoder, TextEncoder }); type ArgumentTypes = F extends (...args: infer A) => any ? A @@ -86,6 +87,32 @@ describe('Session tests', () => { expect(session.credentials).toBe(undefined); }); + test('fetchAuthSession with credentials provider only', async () => { + const mockCredentials = { + accessKeyId: 'accessKeyValue', + secretAccessKey: 'secreatAccessKeyValue', + }; + Amplify.configure( + {}, + { + Auth: { + credentialsProvider: { + getCredentialsAndIdentityId: async () => { + return { + credentials: mockCredentials, + }; + }, + clearCredentialsAndIdentityId: () => {}, + }, + }, + } + ); + + const session = await fetchAuthSession(); + + expect(session.credentials).toBe(mockCredentials); + }); + test('fetch user after no credentials', async () => { expect.assertions(3); const config: ArgumentTypes[0] = { diff --git a/packages/core/src/singleton/Auth/index.ts b/packages/core/src/singleton/Auth/index.ts index 362282963ae..8c84e6b89cb 100644 --- a/packages/core/src/singleton/Auth/index.ts +++ b/packages/core/src/singleton/Auth/index.ts @@ -8,8 +8,6 @@ import { FetchAuthSessionOptions, LibraryAuthOptions, } from './types'; -import { asserts } from '../../Util/errors/AssertError'; -import { AUTH_CONFING_EXCEPTION } from '../../Util/Constants'; export function isTokenExpired({ expiresAt, @@ -53,13 +51,6 @@ export class AuthClass { let credentialsAndIdentityId: AWSCredentialsAndIdentityId | undefined; let userSub: string | undefined; - asserts(!!this.authConfig, { - name: AUTH_CONFING_EXCEPTION, - message: 'AuthConfig is required', - recoverySuggestion: - 'call Amplify.configure in your app with a valid AuthConfig', - }); - // Get tokens will throw if session cannot be refreshed (network or service error) or return null if not available tokens = (await this.authOptions?.tokenProvider?.getTokens(options)) ?? undefined; @@ -77,7 +68,7 @@ export class AuthClass { forceRefresh: options.forceRefresh, } ); - } else if (this.authConfig.Cognito.allowGuestAccess) { + } else { // getCredentialsAndIdentityId will throw if cannot get credentials (network or service error) credentialsAndIdentityId = await this.authOptions?.credentialsProvider?.getCredentialsAndIdentityId( diff --git a/packages/core/src/singleton/Auth/types.ts b/packages/core/src/singleton/Auth/types.ts index 400eb3afdc2..6b3fd2f28ca 100644 --- a/packages/core/src/singleton/Auth/types.ts +++ b/packages/core/src/singleton/Auth/types.ts @@ -152,14 +152,14 @@ export type GetCredentialsOptions = type GetCredentialsAuthenticatedUser = { authenticated: true; forceRefresh?: boolean; - authConfig: AuthConfig; + authConfig: AuthConfig | undefined; tokens: AuthTokens; }; type GetCredentialsUnauthenticatedUser = { authenticated: false; forceRefresh?: boolean; - authConfig: AuthConfig; + authConfig: AuthConfig | undefined; tokens?: never; }; From 1ff5bdf1befaa2a0ae5c8deb2b0aa752a7d10da3 Mon Sep 17 00:00:00 2001 From: Hui Zhao <10602282+HuiSF@users.noreply.github.com> Date: Tue, 12 Sep 2023 17:23:44 -0700 Subject: [PATCH 10/12] chore(core): remove the isomorphic-unfetch dependency (#12023) --- packages/core/__tests__/clients/fetch.test.ts | 20 ++++++------- packages/core/package.json | 2 -- packages/core/src/clients/handlers/fetch.ts | 1 - yarn.lock | 30 ------------------- 4 files changed, 10 insertions(+), 43 deletions(-) diff --git a/packages/core/__tests__/clients/fetch.test.ts b/packages/core/__tests__/clients/fetch.test.ts index ad8cd6fde52..c3aaef011d0 100644 --- a/packages/core/__tests__/clients/fetch.test.ts +++ b/packages/core/__tests__/clients/fetch.test.ts @@ -1,8 +1,3 @@ -const mockUnfetch = jest.fn(); -jest.mock('isomorphic-unfetch', () => { - global['fetch'] = mockUnfetch; -}); - import { fetchTransferHandler } from '../../src/clients/handlers/fetch'; describe(fetchTransferHandler.name, () => { @@ -25,17 +20,22 @@ describe(fetchTransferHandler.name, () => { url: new URL('https://foo.bar'), }; const mockPayloadValue = 'payload value'; + const mockFetch = jest.fn(); + + beforeAll(() => { + global['fetch'] = mockFetch; + }); beforeEach(() => { jest.clearAllMocks(); - mockUnfetch.mockResolvedValue(mockFetchResponse); + mockFetch.mockResolvedValue(mockFetchResponse); }); test('should support abort signal', async () => { const signal = new AbortController().signal; await fetchTransferHandler(mockRequest, { abortSignal: signal }); - expect(mockUnfetch).toBeCalledTimes(1); - expect(mockUnfetch.mock.calls[0][1]).toEqual( + expect(mockFetch).toBeCalledTimes(1); + expect(mockFetch.mock.calls[0][1]).toEqual( expect.objectContaining({ signal }) ); }); @@ -88,8 +88,8 @@ describe(fetchTransferHandler.name, () => { { ...mockRequest, method, body: 'Mock Body' }, {} ); - expect(mockUnfetch).toBeCalledTimes(1); - expect(mockUnfetch.mock.calls[0][0].body).toBeUndefined(); + expect(mockFetch).toBeCalledTimes(1); + expect(mockFetch.mock.calls[0][0].body).toBeUndefined(); } ); }); diff --git a/packages/core/package.json b/packages/core/package.json index 892c31d4c8b..bf1cb7423cf 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -65,8 +65,6 @@ "@aws-crypto/sha256-js": "5.0.0", "@aws-sdk/types": "3.398.0", "@smithy/util-hex-encoding": "2.0.0", - "@types/node-fetch": "2.6.4", - "isomorphic-unfetch": "^3.0.0", "tslib": "^2.5.0", "uuid": "^9.0.0", "zen-observable-ts": "0.8.19", diff --git a/packages/core/src/clients/handlers/fetch.ts b/packages/core/src/clients/handlers/fetch.ts index d26deb20c3c..245d7e2bebf 100644 --- a/packages/core/src/clients/handlers/fetch.ts +++ b/packages/core/src/clients/handlers/fetch.ts @@ -1,7 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -import 'isomorphic-unfetch'; // TODO: remove this dependency in v6 import { HttpRequest, HttpResponse, HttpTransferOptions } from '../types/http'; import { TransferHandler } from '../types/core'; import { withMemoization } from '../utils/memoization'; diff --git a/yarn.lock b/yarn.lock index 93f272b50c3..9258f5ba262 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2761,14 +2761,6 @@ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== -"@types/node-fetch@2.6.4": - version "2.6.4" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.4.tgz#1bc3a26de814f6bf466b25aeb1473fa1afe6a660" - integrity sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg== - dependencies: - "@types/node" "*" - form-data "^3.0.0" - "@types/node@*", "@types/node@^20.3.1": version "20.5.7" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.7.tgz#4b8ecac87fbefbc92f431d09c30e176fc0a7c377" @@ -5684,15 +5676,6 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== -form-data@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - form-data@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -7064,14 +7047,6 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -isomorphic-unfetch@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz#87341d5f4f7b63843d468438128cb087b7c3e98f" - integrity sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q== - dependencies: - node-fetch "^2.6.1" - unfetch "^4.2.0" - isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -12395,11 +12370,6 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" -unfetch@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" - integrity sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA== - unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" From db0527717d3ca97e4a0a5916c9fe18705a6dfc05 Mon Sep 17 00:00:00 2001 From: Ashwin Kumar Date: Wed, 13 Sep 2023 08:57:55 -0700 Subject: [PATCH 11/12] fix(Storage): update storage type names (#12022) * chore(storage): align api types names * fix(Storage): update storage type names * fix: code cleanup --------- Co-authored-by: Sridhar Co-authored-by: AllanZhengYP --- packages/storage/src/index.ts | 23 ++++++++ .../storage/src/providers/s3/apis/copy.ts | 11 ++-- .../src/providers/s3/apis/downloadData.ts | 18 ++---- .../src/providers/s3/apis/getProperties.ts | 13 ++--- .../storage/src/providers/s3/apis/getUrl.ts | 14 ++--- .../src/providers/s3/apis/internal/copy.ts | 13 ++--- .../s3/apis/internal/getProperties.ts | 9 ++- .../src/providers/s3/apis/internal/getUrl.ts | 10 ++-- .../src/providers/s3/apis/internal/list.ts | 29 ++++------ .../src/providers/s3/apis/internal/remove.ts | 13 ++--- .../storage/src/providers/s3/apis/list.ts | 34 ++++++------ .../storage/src/providers/s3/apis/remove.ts | 16 ++---- .../src/providers/s3/apis/server/copy.ts | 12 ++-- .../providers/s3/apis/server/getProperties.ts | 9 ++- .../src/providers/s3/apis/server/getUrl.ts | 9 ++- .../src/providers/s3/apis/server/list.ts | 38 +++++++------ .../src/providers/s3/apis/server/remove.ts | 12 ++-- .../src/providers/s3/apis/uploadData/index.ts | 21 +++---- .../uploadData/multipart/getDataChunker.ts | 4 +- .../uploadData/multipart/initialUpload.ts | 4 +- .../uploadData/multipart/uploadHandlers.ts | 11 +--- .../s3/apis/uploadData/putObjectJob.ts | 11 +--- packages/storage/src/providers/s3/index.ts | 22 ++++++++ .../storage/src/providers/s3/types/index.ts | 42 +++++++++----- .../storage/src/providers/s3/types/inputs.ts | 38 +++++++++++++ .../storage/src/providers/s3/types/options.ts | 55 +++++++++++++++---- .../storage/src/providers/s3/types/outputs.ts | 44 +++++++++++++++ .../storage/src/providers/s3/types/results.ts | 42 -------------- packages/storage/src/types/index.ts | 28 +++++----- packages/storage/src/types/inputs.ts | 49 +++++++++++++++++ packages/storage/src/types/options.ts | 5 -- .../src/types/{results.ts => outputs.ts} | 14 ++--- packages/storage/src/types/requests.ts | 36 ------------ 33 files changed, 396 insertions(+), 313 deletions(-) create mode 100644 packages/storage/src/providers/s3/types/inputs.ts create mode 100644 packages/storage/src/providers/s3/types/outputs.ts delete mode 100644 packages/storage/src/providers/s3/types/results.ts create mode 100644 packages/storage/src/types/inputs.ts rename packages/storage/src/types/{results.ts => outputs.ts} (77%) delete mode 100644 packages/storage/src/types/requests.ts diff --git a/packages/storage/src/index.ts b/packages/storage/src/index.ts index 4a4c9bd45b7..c0923b44efa 100644 --- a/packages/storage/src/index.ts +++ b/packages/storage/src/index.ts @@ -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'; diff --git a/packages/storage/src/providers/s3/apis/copy.ts b/packages/storage/src/providers/s3/apis/copy.ts index 9baee642de8..17c32e557e2 100644 --- a/packages/storage/src/providers/s3/apis/copy.ts +++ b/packages/storage/src/providers/s3/apis/copy.ts @@ -2,8 +2,7 @@ // 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'; /** @@ -11,12 +10,12 @@ import { copy as copyInternal } from './internal/copy'; * different level or identityId (if source object's level is 'protected'). * * @async - * @param {CopyRequest} copyRequest - The request object. - * @return {Promise} Promise resolves upon successful copy of the object. + * @param {CopyInput} input - The request object. + * @return {Promise} 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 => { - return copyInternal(Amplify, copyRequest); +export const copy = async (input: CopyInput): Promise => { + return copyInternal(Amplify, input); }; diff --git a/packages/storage/src/providers/s3/apis/downloadData.ts b/packages/storage/src/providers/s3/apis/downloadData.ts index 2ee1ce265ec..de948b18536 100644 --- a/packages/storage/src/providers/s3/apis/downloadData.ts +++ b/packages/storage/src/providers/s3/apis/downloadData.ts @@ -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} downloadDataRequest The parameters that are passed to the + * @param {DownloadDataRequest} input The parameters that are passed to the * downloadData operation. - * @returns {DownloadTask} 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 -): DownloadTask => { +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, + { options: downloadDataOptions, key }: DownloadDataInput, abortSignal: AbortSignal ) => async () => { diff --git a/packages/storage/src/providers/s3/apis/getProperties.ts b/packages/storage/src/providers/s3/apis/getProperties.ts index 523e6e53364..33034f4132a 100644 --- a/packages/storage/src/providers/s3/apis/getProperties.ts +++ b/packages/storage/src/providers/s3/apis/getProperties.ts @@ -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} A promise that resolves the properties. + * @param {GetPropertiesInput} The input to make an API call. + * @returns {Promise} 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 -): Promise => { - return getPropertiesInternal(Amplify, req); + input: GetPropertiesInput +): Promise => { + return getPropertiesInternal(Amplify, input); }; diff --git a/packages/storage/src/providers/s3/apis/getUrl.ts b/packages/storage/src/providers/s3/apis/getUrl.ts index 9c87b12a467..4fdcafa2a4d 100644 --- a/packages/storage/src/providers/s3/apis/getUrl.ts +++ b/packages/storage/src/providers/s3/apis/getUrl.ts @@ -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} The request object - * @return {Promise} url of the object + * @param {GetUrlInput} The input object + * @return {Promise} 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 -): Promise => { - return getUrlInternal(Amplify, req); +export const getUrl = (input: GetUrlInput): Promise => { + return getUrlInternal(Amplify, input); }; diff --git a/packages/storage/src/providers/s3/apis/internal/copy.ts b/packages/storage/src/providers/s3/apis/internal/copy.ts index 1fe6db384e9..0120a49e97b 100644 --- a/packages/storage/src/providers/s3/apis/internal/copy.ts +++ b/packages/storage/src/providers/s3/apis/internal/copy.ts @@ -2,8 +2,7 @@ // 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'; @@ -11,12 +10,12 @@ import { copyObject } from '../../utils/client'; export const copy = async ( amplify: AmplifyClassV6, - copyRequest: CopyRequest -): Promise => { + input: CopyInput +): Promise => { 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}` diff --git a/packages/storage/src/providers/s3/apis/internal/getProperties.ts b/packages/storage/src/providers/s3/apis/internal/getProperties.ts index 11448142fb4..ce8c4d3168e 100644 --- a/packages/storage/src/providers/s3/apis/internal/getProperties.ts +++ b/packages/storage/src/providers/s3/apis/internal/getProperties.ts @@ -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 -): Promise { - const { key, options } = getPropertiesRequest; + input: GetPropertiesInput +): Promise { + const { key, options } = input; const { s3Config, bucket, keyPrefix } = await resolveS3ConfigAndInput( amplify, options diff --git a/packages/storage/src/providers/s3/apis/internal/getUrl.ts b/packages/storage/src/providers/s3/apis/internal/getUrl.ts index a99ebb26fb1..a0562c7c479 100644 --- a/packages/storage/src/providers/s3/apis/internal/getUrl.ts +++ b/packages/storage/src/providers/s3/apis/internal/getUrl.ts @@ -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 -): Promise { - const { key, options } = getUrlRequest; + input: GetUrlInput +): Promise { + const { key, options } = input; if (options?.validateObjectExistence) { await getProperties(amplify, { key, options }); diff --git a/packages/storage/src/providers/s3/apis/internal/list.ts b/packages/storage/src/providers/s3/apis/internal/list.ts index fff8647d7ad..f5321198262 100644 --- a/packages/storage/src/providers/s3/apis/internal/list.ts +++ b/packages/storage/src/providers/s3/apis/internal/list.ts @@ -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,7 +19,7 @@ import { const MAX_PAGE_SIZE = 1000; -type ListRequestArgs = { +type ListInputArgs = { s3Config: ResolvedS3Config; listParams: ListObjectsV2Input; prefix: string; @@ -30,11 +27,9 @@ type ListRequestArgs = { export const list = async ( amplify: AmplifyClassV6, - listRequest?: - | StorageListRequest - | StorageListRequest -): Promise => { - const { options = {}, prefix: path = '' } = listRequest ?? {}; + input?: ListAllInput | ListPaginateInput +): Promise => { + const { options = {}, prefix: path = '' } = input ?? {}; const { s3Config, bucket, @@ -55,9 +50,9 @@ const _listAll = async ({ s3Config, listParams, prefix, -}: ListRequestArgs): Promise => { +}: ListInputArgs): Promise => { // 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 => { +}: ListInputArgs): Promise => { const listParamsClone = { ...listParams }; if (!listParamsClone.MaxKeys || listParamsClone.MaxKeys > MAX_PAGE_SIZE) { listParamsClone.MaxKeys = MAX_PAGE_SIZE; diff --git a/packages/storage/src/providers/s3/apis/internal/remove.ts b/packages/storage/src/providers/s3/apis/internal/remove.ts index 15e8314c9a9..93fc9a6bead 100644 --- a/packages/storage/src/providers/s3/apis/internal/remove.ts +++ b/packages/storage/src/providers/s3/apis/internal/remove.ts @@ -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 -): Promise => { - const { key, options = {} } = removeRequest; + input: RemoveInput +): Promise => { + const { key, options = {} } = input; const { s3Config, keyPrefix, bucket } = await resolveS3ConfigAndInput( amplify, options diff --git a/packages/storage/src/providers/s3/apis/list.ts b/packages/storage/src/providers/s3/apis/list.ts index f54f78f0678..d7910c43ba3 100644 --- a/packages/storage/src/providers/s3/apis/list.ts +++ b/packages/storage/src/providers/s3/apis/list.ts @@ -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} req - The request object - * @return {Promise} - Promise resolves to list of keys and metadata with + * @param {ListPaginateInput} The input object + * @return {Promise} - 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 - ): Promise; + (input?: ListPaginateInput): Promise; /** * List all files from S3. You can set `listAll` to true in `options` to get all the files from S3. - * @param {StorageListRequest} req - The request object - * @return {Promise} - Promise resolves to list of keys and metadata for all objects in path + * @param {ListAllInput} The input object + * @return {Promise} - 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): Promise; + (input?: ListAllInput): Promise; }; -export const list: S3ListApi = ( - req -): Promise => { - return listInternal(Amplify, req ?? {}); +export const list: ListApi = ( + input?: ListAllInput | ListPaginateInput +): Promise => { + return listInternal(Amplify, input ?? {}); }; diff --git a/packages/storage/src/providers/s3/apis/remove.ts b/packages/storage/src/providers/s3/apis/remove.ts index 76d0a75b3a2..4a4b7428c42 100644 --- a/packages/storage/src/providers/s3/apis/remove.ts +++ b/packages/storage/src/providers/s3/apis/remove.ts @@ -2,22 +2,16 @@ // SPDX-License-Identifier: Apache-2.0 import { Amplify } from '@aws-amplify/core'; -import { - StorageOperationRequest, - StorageRemoveOptions, - StorageRemoveResult, -} from '../../../types'; +import { RemoveInput, RemoveOutput } from '../types'; import { remove as removeInternal } from './internal/remove'; /** * Remove a file from your S3 bucket. - * @param {StorageOperationRequest} req - The request object - * @return {Promise} - Promise resolves upon successful removal of the object + * @param {RemoveInput} The input object + * @return {Promise} - Promise resolves upon successful removal of the object * @throws service: {@link S3Exception} - S3 service errors thrown while getting properties * @throws validation: {@link StorageValidationErrorCode } - Validation errors thrown */ -export const remove = ( - req: StorageOperationRequest -): Promise => { - return removeInternal(Amplify, req); +export const remove = (input: RemoveInput): Promise => { + return removeInternal(Amplify, input); }; diff --git a/packages/storage/src/providers/s3/apis/server/copy.ts b/packages/storage/src/providers/s3/apis/server/copy.ts index 75b039f0aae..ea8e9de90f8 100644 --- a/packages/storage/src/providers/s3/apis/server/copy.ts +++ b/packages/storage/src/providers/s3/apis/server/copy.ts @@ -5,16 +5,12 @@ import { AmplifyServer, getAmplifyServerContext, } from '@aws-amplify/core/internals/adapter-core'; -import { CopyRequest } from '../../../../types'; -import { S3CopyResult } from '../../types'; +import { CopyInput, CopyOutput } from '../../types'; import { copy as copyInternal } from '../internal/copy'; export const copy = async ( contextSpec: AmplifyServer.ContextSpec, - copyRequest: CopyRequest -): Promise => { - return copyInternal( - getAmplifyServerContext(contextSpec).amplify, - copyRequest - ); + input: CopyInput +): Promise => { + return copyInternal(getAmplifyServerContext(contextSpec).amplify, input); }; diff --git a/packages/storage/src/providers/s3/apis/server/getProperties.ts b/packages/storage/src/providers/s3/apis/server/getProperties.ts index d9ec4f490f1..c26bf24f502 100644 --- a/packages/storage/src/providers/s3/apis/server/getProperties.ts +++ b/packages/storage/src/providers/s3/apis/server/getProperties.ts @@ -5,16 +5,15 @@ import { AmplifyServer, getAmplifyServerContext, } from '@aws-amplify/core/internals/adapter-core'; -import { StorageOperationRequest, StorageOptions } from '../../../../types'; -import { S3GetPropertiesResult } from '../../types'; +import { GetPropertiesInput, GetPropertiesOutput } from '../../types'; import { getProperties as getPropertiesInternal } from '../internal/getProperties'; export const getProperties = ( contextSpec: AmplifyServer.ContextSpec, - req: StorageOperationRequest -): Promise => { + input: GetPropertiesInput +): Promise => { return getPropertiesInternal( getAmplifyServerContext(contextSpec).amplify, - req + input ); }; diff --git a/packages/storage/src/providers/s3/apis/server/getUrl.ts b/packages/storage/src/providers/s3/apis/server/getUrl.ts index 44a1ad76740..7b6cc802cbe 100644 --- a/packages/storage/src/providers/s3/apis/server/getUrl.ts +++ b/packages/storage/src/providers/s3/apis/server/getUrl.ts @@ -5,13 +5,12 @@ import { AmplifyServer, getAmplifyServerContext, } from '@aws-amplify/core/internals/adapter-core'; -import { StorageDownloadDataRequest } from '../../../../types'; -import { S3GetUrlOptions, S3GetUrlResult } from '../../types'; +import { GetUrlInput, GetUrlOutput } from '../../types'; import { getUrl as getUrlInternal } from '../internal/getUrl'; export const getUrl = async ( contextSpec: AmplifyServer.ContextSpec, - req: StorageDownloadDataRequest -): Promise => { - return getUrlInternal(getAmplifyServerContext(contextSpec).amplify, req); + input: GetUrlInput +): Promise => { + return getUrlInternal(getAmplifyServerContext(contextSpec).amplify, input); }; diff --git a/packages/storage/src/providers/s3/apis/server/list.ts b/packages/storage/src/providers/s3/apis/server/list.ts index 68b81fdf165..970301c1622 100644 --- a/packages/storage/src/providers/s3/apis/server/list.ts +++ b/packages/storage/src/providers/s3/apis/server/list.ts @@ -6,39 +6,45 @@ import { getAmplifyServerContext, } from '@aws-amplify/core/internals/adapter-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 = { /** * Lists bucket objects with pagination. - * @param {StorageListRequest} req - The request object - * @return {Promise} - Promise resolves to list of keys and metadata with + * @param {ListPaginateInput} The input object + * @return {Promise} - Promise resolves to list of keys and metadata with * pageSize defaulting to 1000. Additionally the result will include a nextToken if there are more items to retrieve * @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 */ ( contextSpec: AmplifyServer.ContextSpec, - req?: StorageListRequest - ): Promise; + input?: ListPaginateInput + ): Promise; /** * Lists all bucket objects. - * @param {StorageListRequest} req - The request object - * @return {Promise} - Promise resolves to list of keys and metadata for all objects in path + * @param {ListAllInput} The input object + * @return {Promise} - 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 */ ( contextSpec: AmplifyServer.ContextSpec, - req?: StorageListRequest - ): Promise; + input?: ListAllInput + ): Promise; }; -export const list: S3ListApi = (contextSpec, req) => { - return listInternal(getAmplifyServerContext(contextSpec).amplify, req ?? {}); +export const list: ListApi = ( + contextSpec: AmplifyServer.ContextSpec, + input?: ListAllInput | ListPaginateInput +): Promise => { + return listInternal( + getAmplifyServerContext(contextSpec).amplify, + input ?? {} + ); }; diff --git a/packages/storage/src/providers/s3/apis/server/remove.ts b/packages/storage/src/providers/s3/apis/server/remove.ts index bfd1a97ef8d..d54d0687333 100644 --- a/packages/storage/src/providers/s3/apis/server/remove.ts +++ b/packages/storage/src/providers/s3/apis/server/remove.ts @@ -5,16 +5,12 @@ import { AmplifyServer, getAmplifyServerContext, } from '@aws-amplify/core/internals/adapter-core'; -import { - StorageOperationRequest, - StorageRemoveOptions, - StorageRemoveResult, -} from '../../../../types'; +import { RemoveInput, RemoveOutput } from '../../types'; import { remove as removeInternal } from '../internal/remove'; export const remove = ( contextSpec: AmplifyServer.ContextSpec, - req: StorageOperationRequest -): Promise => { - return removeInternal(getAmplifyServerContext(contextSpec).amplify, req); + input: RemoveInput +): Promise => { + return removeInternal(getAmplifyServerContext(contextSpec).amplify, input); }; diff --git a/packages/storage/src/providers/s3/apis/uploadData/index.ts b/packages/storage/src/providers/s3/apis/uploadData/index.ts index 3dcf3a783a7..03dbe76f19b 100644 --- a/packages/storage/src/providers/s3/apis/uploadData/index.ts +++ b/packages/storage/src/providers/s3/apis/uploadData/index.ts @@ -1,9 +1,8 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -import { S3UploadDataResult, S3UploadOptions } from '../../types'; +import { UploadDataInput, UploadDataOutput } from '../../types'; import { createUploadTask } from '../../utils'; -import { StorageUploadDataRequest, UploadTask } from '../../../../types'; import { assertValidationError } from '../../../../errors/utils/assertValidationError'; import { StorageValidationErrorCode } from '../../../../errors/types/validation'; import { DEFAULT_PART_SIZE, MAX_OBJECT_SIZE } from '../../utils/constants'; @@ -19,9 +18,9 @@ import { getMultipartUploadHandlers } from './multipart'; * * Maximum object size is 5TB. * * Maximum object size if the size cannot be determined before upload is 50GB. * - * @param {StorageUploadDataRequest} uploadDataRequest The parameters that are passed to the + * @param {UploadDataInput} The input parameters that are passed to the * uploadData operation. - * @returns {UploadTask} Cancelable and Resumable task exposing result promise from `result` + * @returns {UploadDataOutput} Cancelable and Resumable 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. @@ -60,10 +59,8 @@ import { getMultipartUploadHandlers } from './multipart'; * await uploadTask.result; * ``` */ -export const uploadData = ( - uploadDataRequest: StorageUploadDataRequest -): UploadTask => { - const { data } = uploadDataRequest; +export const uploadData = (input: UploadDataInput): UploadDataOutput => { + const { data } = input; const dataByteLength = byteLength(data); assertValidationError( @@ -75,18 +72,14 @@ export const uploadData = ( const abortController = new AbortController(); return createUploadTask({ isMultipartUpload: false, - job: putObjectJob( - uploadDataRequest, - abortController.signal, - dataByteLength - ), + job: putObjectJob(input, abortController.signal, dataByteLength), onCancel: (abortErrorOverwrite?: Error) => { abortController.abort(abortErrorOverwrite); }, }); } else { const { multipartUploadJob, onPause, onResume, onCancel } = - getMultipartUploadHandlers(uploadDataRequest, dataByteLength); + getMultipartUploadHandlers(input, dataByteLength); return createUploadTask({ isMultipartUpload: true, job: multipartUploadJob, diff --git a/packages/storage/src/providers/s3/apis/uploadData/multipart/getDataChunker.ts b/packages/storage/src/providers/s3/apis/uploadData/multipart/getDataChunker.ts index bb91d363010..75e391cc4db 100644 --- a/packages/storage/src/providers/s3/apis/uploadData/multipart/getDataChunker.ts +++ b/packages/storage/src/providers/s3/apis/uploadData/multipart/getDataChunker.ts @@ -1,7 +1,7 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -import { StorageUploadSourceOptions } from '../../../../../types'; +import { StorageUploadDataPayload } from '../../../../../types'; import { StorageValidationErrorCode, validationErrorMap, @@ -16,7 +16,7 @@ export type PartToUpload = { }; export const getDataChunker = ( - data: StorageUploadSourceOptions, + data: StorageUploadDataPayload, totalSize?: number ) => { const partSize = calculatePartSize(totalSize); diff --git a/packages/storage/src/providers/s3/apis/uploadData/multipart/initialUpload.ts b/packages/storage/src/providers/s3/apis/uploadData/multipart/initialUpload.ts index be62c10fcac..1c81e9efa1a 100644 --- a/packages/storage/src/providers/s3/apis/uploadData/multipart/initialUpload.ts +++ b/packages/storage/src/providers/s3/apis/uploadData/multipart/initialUpload.ts @@ -9,12 +9,12 @@ import { getUploadsCacheKey, } from './uploadCache'; import { ResolvedS3Config } from '../../../types/options'; -import { StorageUploadSourceOptions } from '../../../../../types'; +import { StorageUploadDataPayload } from '../../../../../types'; import { Part, createMultipartUpload } from '../../../utils/client'; type LoadOrCreateMultipartUploadOptions = { s3Config: ResolvedS3Config; - data: StorageUploadSourceOptions; + data: StorageUploadDataPayload; bucket: string; accessLevel: StorageAccessLevel; keyPrefix: string; diff --git a/packages/storage/src/providers/s3/apis/uploadData/multipart/uploadHandlers.ts b/packages/storage/src/providers/s3/apis/uploadData/multipart/uploadHandlers.ts index 708bc04b92e..62f01d1de1e 100644 --- a/packages/storage/src/providers/s3/apis/uploadData/multipart/uploadHandlers.ts +++ b/packages/storage/src/providers/s3/apis/uploadData/multipart/uploadHandlers.ts @@ -4,10 +4,9 @@ import { Amplify, StorageAccessLevel } from '@aws-amplify/core'; import { getDataChunker } from './getDataChunker'; -import { S3UploadOptions } from '../../../types'; +import { UploadDataInput } from '../../../types'; import { resolveS3ConfigAndInput } from '../../../utils'; -import { StorageUploadDataRequest } from '../../../../../types'; -import { S3Item } from '../../../types/results'; +import { Item as S3Item } from '../../../types/outputs'; import { DEFAULT_ACCESS_LEVEL, DEFAULT_QUEUE_SIZE, @@ -33,11 +32,7 @@ import { * @internal */ export const getMultipartUploadHandlers = ( - { - options: uploadDataOptions, - key, - data, - }: StorageUploadDataRequest, + { options: uploadDataOptions, key, data }: UploadDataInput, size?: number ) => { let resolveCallback: ((value: S3Item) => void) | undefined; diff --git a/packages/storage/src/providers/s3/apis/uploadData/putObjectJob.ts b/packages/storage/src/providers/s3/apis/uploadData/putObjectJob.ts index 081947e0daf..50922b1334b 100644 --- a/packages/storage/src/providers/s3/apis/uploadData/putObjectJob.ts +++ b/packages/storage/src/providers/s3/apis/uploadData/putObjectJob.ts @@ -3,10 +3,9 @@ import { Amplify } from '@aws-amplify/core'; -import { S3UploadOptions } from '../../types'; +import { UploadDataInput } from '../../types'; import { calculateContentMd5, resolveS3ConfigAndInput } from '../../utils'; -import { StorageUploadDataRequest } from '../../../../types'; -import { S3Item } from '../../types/results'; +import { Item as S3Item } from '../../types/outputs'; import { putObject } from '../../utils/client'; /** @@ -16,11 +15,7 @@ import { putObject } from '../../utils/client'; */ export const putObjectJob = ( - { - options: uploadDataOptions, - key, - data, - }: StorageUploadDataRequest, + { options: uploadDataOptions, key, data }: UploadDataInput, abortSignal: AbortSignal, totalLength?: number ) => diff --git a/packages/storage/src/providers/s3/index.ts b/packages/storage/src/providers/s3/index.ts index d4bf1fb7ae4..dd2f2eb015e 100644 --- a/packages/storage/src/providers/s3/index.ts +++ b/packages/storage/src/providers/s3/index.ts @@ -10,3 +10,25 @@ export { copy, getUrl, } from './apis'; + +export { + UploadDataInput, + DownloadDataInput, + RemoveInput, + ListAllInput, + ListPaginateInput, + GetPropertiesInput, + CopyInput, + GetUrlInput, +} from './types/inputs'; + +export { + UploadDataOutput, + DownloadDataOutput, + RemoveOutput, + ListAllOutput, + ListPaginateOutput, + GetPropertiesOutput, + CopyOutput, + GetUrlOutput, +} from './types/outputs'; diff --git a/packages/storage/src/providers/s3/types/index.ts b/packages/storage/src/providers/s3/types/index.ts index 9e2ecb86f1f..7f8b49c6c15 100644 --- a/packages/storage/src/providers/s3/types/index.ts +++ b/packages/storage/src/providers/s3/types/index.ts @@ -2,20 +2,34 @@ // SPDX-License-Identifier: Apache-2.0 export { - S3Options, - S3TransferOptions, - S3GetUrlOptions, - S3UploadOptions, + GetUrlOptions, + UploadDataOptions, + GetPropertiesOptions, + ListAllOptions, + ListPaginateOptions, + RemoveOptions, + DownloadDataOptions, } from './options'; export { - S3DownloadDataResult, - S3DownloadFileResult, - S3GetUrlResult, - S3UploadDataResult, - S3ListOutputItem, - S3ListAllResult, - S3ListPaginateResult, - S3GetPropertiesResult, - S3CopyResult, -} from './results'; + DownloadDataOutput, + DownloadFileOutput, + GetUrlOutput, + UploadDataOutput, + ListOutputItem, + ListAllOutput, + ListPaginateOutput, + GetPropertiesOutput, + CopyOutput, + RemoveOutput, +} from './outputs'; +export { + CopyInput, + GetPropertiesInput, + GetUrlInput, + ListAllInput, + ListPaginateInput, + RemoveInput, + DownloadDataInput, + UploadDataInput, +} from './inputs'; export { S3Exception } from './errors'; diff --git a/packages/storage/src/providers/s3/types/inputs.ts b/packages/storage/src/providers/s3/types/inputs.ts new file mode 100644 index 00000000000..3640d6cd7ca --- /dev/null +++ b/packages/storage/src/providers/s3/types/inputs.ts @@ -0,0 +1,38 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { + StorageCopyInput, + StorageGetPropertiesInput, + StorageGetUrlInput, + StorageListInput, + StorageRemoveInput, + StorageDownloadDataInput, + StorageUploadDataInput, +} from '../../../types'; +import { + GetPropertiesOptions, + GetUrlOptions, + ListAllOptions, + ListPaginateOptions, + RemoveOptions, + DownloadDataOptions, + UploadDataOptions, +} from '../types'; + +export type CopyInput = StorageCopyInput; + +export type GetPropertiesInput = + StorageGetPropertiesInput; + +export type GetUrlInput = StorageGetUrlInput; + +export type ListAllInput = StorageListInput; + +export type ListPaginateInput = StorageListInput; + +export type RemoveInput = StorageRemoveInput; + +export type DownloadDataInput = StorageDownloadDataInput; + +export type UploadDataInput = StorageUploadDataInput; diff --git a/packages/storage/src/providers/s3/types/options.ts b/packages/storage/src/providers/s3/types/options.ts index 94bd3241fa2..b2bd747e1e9 100644 --- a/packages/storage/src/providers/s3/types/options.ts +++ b/packages/storage/src/providers/s3/types/options.ts @@ -5,12 +5,16 @@ import { Credentials } from '@aws-sdk/types'; import { TransferProgressEvent } from '../../../types'; -import { StorageOptions } from '../../../types/options'; +import { + StorageOptions, + StorageListAllOptions, + StorageListPaginateOptions, +} from '../../../types/options'; /** - * Request options type for S3 Storage operations. + * Input options type for S3 Storage operations. */ -export type S3Options = StorageOptions & { +export type Options = StorageOptions & { /** * Whether to use accelerate endpoint. * @default false @@ -19,16 +23,34 @@ export type S3Options = StorageOptions & { }; /** - * Request options type for S3 downloadData, uploadData APIs. + * Input options type for S3 getProperties API. */ -export type S3TransferOptions = S3Options & { - /** - * Callback function tracking the upload/download progress. - */ - onProgress?: (event: TransferProgressEvent) => void; -}; +export type GetPropertiesOptions = Options; + +/** + * Input options type for S3 getProperties API. + */ +export type RemoveOptions = Options; + +/** + * Input options type for S3 list API. + */ +export type ListAllOptions = StorageListAllOptions; + +/** + * Input options type for S3 list API. + */ +export type ListPaginateOptions = StorageListPaginateOptions; + +/** + * Input options type for S3 downloadData API. + */ +export type DownloadDataOptions = TransferOptions; -export type S3GetUrlOptions = S3Options & { +/** + * Input options type for S3 getUrl API. + */ +export type GetUrlOptions = Options & { /** * Whether to head object to make sure the object existence before downloading. * @default false @@ -41,7 +63,7 @@ export type S3GetUrlOptions = S3Options & { expiresIn?: number; }; -export type S3UploadOptions = Omit & { +export type UploadDataOptions = Omit & { /** * The default content-disposition header value of the file when downloading it. * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition @@ -76,3 +98,12 @@ export type ResolvedS3Config = { forcePathStyle?: boolean; useAccelerateEndpoint?: boolean; }; +/** + * Input options type for S3 downloadData, uploadData APIs. + */ +type TransferOptions = Options & { + /** + * Callback function tracking the upload/download progress. + */ + onProgress?: (event: TransferProgressEvent) => void; +}; diff --git a/packages/storage/src/providers/s3/types/outputs.ts b/packages/storage/src/providers/s3/types/outputs.ts new file mode 100644 index 00000000000..d7c36f66f5c --- /dev/null +++ b/packages/storage/src/providers/s3/types/outputs.ts @@ -0,0 +1,44 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { + StorageDownloadDataOutput, + StorageGetUrlOutput, + StorageItem, + StorageListOutput, + DownloadTask, + UploadTask, +} from '../../../types'; + +export interface Item extends StorageItem { + /** + * VersionId used to reference a specific version of the object. + */ + versionId?: string; + /** + * A standard MIME type describing the format of the object data. + */ + contentType?: string; +} + +export type DownloadDataOutput = DownloadTask>; + +export type DownloadFileOutput = Item; + +export type GetUrlOutput = StorageGetUrlOutput; + +export type UploadDataOutput = UploadTask; + +export type GetPropertiesOutput = Item; + +export type ListOutputItem = Item; + +export type ListAllOutput = StorageListOutput; + +export type ListPaginateOutput = StorageListOutput & { + nextToken?: string; +}; + +// TODO: expose more properties if required +export type CopyOutput = Pick; +export type RemoveOutput = Pick; diff --git a/packages/storage/src/providers/s3/types/results.ts b/packages/storage/src/providers/s3/types/results.ts deleted file mode 100644 index 0e187e733f0..00000000000 --- a/packages/storage/src/providers/s3/types/results.ts +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -import { - StorageDownloadDataResult, - StorageGetUrlResult, - StorageItem, - StorageUploadResult, - StorageListResult, -} from '../../../types'; - -export interface S3Item extends StorageItem { - /** - * VersionId used to reference a specific version of the object. - */ - versionId?: string; - /** - * A standard MIME type describing the format of the object data. - */ - contentType?: string; -} - -export type S3DownloadDataResult = StorageDownloadDataResult; - -export type S3DownloadFileResult = S3Item; - -export type S3GetUrlResult = StorageGetUrlResult; - -export type S3UploadDataResult = S3Item; - -export type S3GetPropertiesResult = S3Item; - -export type S3ListOutputItem = S3Item; - -export type S3ListAllResult = StorageListResult; - -export type S3ListPaginateResult = StorageListResult & { - nextToken?: string; -}; - -// TODO: expose more properties if required -export type S3CopyResult = Required>; diff --git a/packages/storage/src/types/index.ts b/packages/storage/src/types/index.ts index 31e0446d596..4f82a8299b9 100644 --- a/packages/storage/src/types/index.ts +++ b/packages/storage/src/types/index.ts @@ -3,12 +3,16 @@ export { DownloadTask, TransferProgressEvent, UploadTask } from './common'; export { - StorageListRequest, - StorageOperationRequest, - StorageDownloadDataRequest, - StorageUploadDataRequest, - CopyRequest, -} from './requests'; + StorageOperationInput, + StorageListInput, + StorageGetPropertiesInput, + StorageRemoveInput, + StorageDownloadDataInput, + StorageUploadDataInput, + StorageCopyInput, + StorageGetUrlInput, + StorageUploadDataPayload, +} from './inputs'; export { StorageOptions, StorageRemoveOptions, @@ -16,13 +20,11 @@ export { StorageListPaginateOptions, StorageCopySourceOptions, StorageCopyDestinationOptions, - StorageUploadSourceOptions, } from './options'; export { StorageItem, - StorageListResult, - StorageDownloadDataResult, - StorageGetUrlResult, - StorageUploadResult, - StorageRemoveResult, -} from './results'; + StorageListOutput, + StorageDownloadDataOutput, + StorageGetUrlOutput, + StorageUploadOutput, +} from './outputs'; diff --git a/packages/storage/src/types/inputs.ts b/packages/storage/src/types/inputs.ts new file mode 100644 index 00000000000..61ed132335b --- /dev/null +++ b/packages/storage/src/types/inputs.ts @@ -0,0 +1,49 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { + StorageOptions, + StorageListAllOptions, + StorageListPaginateOptions, + StorageCopySourceOptions, + StorageCopyDestinationOptions, +} from './options'; + +export type StorageOperationInput = { + key: string; + options?: Options; +}; + +export type StorageGetPropertiesInput = + StorageOperationInput; + +export type StorageRemoveInput = + StorageOperationInput; + +export type StorageListInput< + Options extends StorageListAllOptions | StorageListPaginateOptions +> = { + prefix?: string; + options?: Options; +}; + +export type StorageGetUrlInput = + StorageOperationInput; + +export type StorageDownloadDataInput = + StorageOperationInput; + +export type StorageUploadDataInput = + StorageOperationInput & { + data: StorageUploadDataPayload; + }; + +export type StorageCopyInput = { + source: StorageCopySourceOptions; + destination: StorageCopyDestinationOptions; +}; + +/** + * The data payload type for upload operation. + */ +export type StorageUploadDataPayload = Blob | BufferSource | string | File; diff --git a/packages/storage/src/types/options.ts b/packages/storage/src/types/options.ts index e0d79933a62..3a95ffa764d 100644 --- a/packages/storage/src/types/options.ts +++ b/packages/storage/src/types/options.ts @@ -10,11 +10,6 @@ export type StorageOptions = targetIdentityId?: string; }; -/** - * The data payload type for upload operation. - */ -export type StorageUploadSourceOptions = Blob | BufferSource | string | File; - export type StorageListAllOptions = StorageOptions & { listAll: true; }; diff --git a/packages/storage/src/types/results.ts b/packages/storage/src/types/outputs.ts similarity index 77% rename from packages/storage/src/types/results.ts rename to packages/storage/src/types/outputs.ts index fb35ccde051..766acf95365 100644 --- a/packages/storage/src/types/results.ts +++ b/packages/storage/src/types/outputs.ts @@ -7,7 +7,7 @@ export type StorageItem = { /** * Key of the object */ - key?: string; + key: string; /** * Creation date of the object. */ @@ -28,11 +28,11 @@ export type StorageItem = { metadata?: Record; }; -export type StorageDownloadDataResult = T & { +export type StorageDownloadDataOutput = T & { body: ResponseBodyMixin; }; -export type StorageGetUrlResult = { +export type StorageGetUrlOutput = { /** * presigned URL of the given object. */ @@ -43,12 +43,8 @@ export type StorageGetUrlResult = { expiresAt: Date; }; -export type StorageUploadResult = Item; - -export type StorageRemoveResult = { - key: string; -}; +export type StorageUploadOutput = Item; -export type StorageListResult = { +export type StorageListOutput = { items: Item[]; }; diff --git a/packages/storage/src/types/requests.ts b/packages/storage/src/types/requests.ts deleted file mode 100644 index 2b8f59db3b1..00000000000 --- a/packages/storage/src/types/requests.ts +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -import { - StorageOptions, - StorageUploadSourceOptions, - StorageListAllOptions, - StorageListPaginateOptions, - StorageCopySourceOptions, - StorageCopyDestinationOptions, -} from './options'; - -export type StorageOperationRequest = { - key: string; - options?: Options; -}; - -export type StorageListRequest< - Options extends StorageListAllOptions | StorageListPaginateOptions -> = { - prefix?: string; - options?: Options; -}; - -export type StorageDownloadDataRequest = - StorageOperationRequest; - -export type StorageUploadDataRequest = - StorageOperationRequest & { - data: StorageUploadSourceOptions; - }; - -export type CopyRequest = { - source: StorageCopySourceOptions; - destination: StorageCopyDestinationOptions; -}; From 7c217083c826d9e842a04fae6bc08f51a7b7e82f Mon Sep 17 00:00:00 2001 From: Ashwin Kumar Date: Wed, 13 Sep 2023 11:44:59 -0700 Subject: [PATCH 12/12] fix(storage): fix listOutput types (#12027) Co-authored-by: Sridhar --- packages/storage/src/providers/s3/types/index.ts | 1 - packages/storage/src/providers/s3/types/outputs.ts | 8 +++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/storage/src/providers/s3/types/index.ts b/packages/storage/src/providers/s3/types/index.ts index 7f8b49c6c15..17c64167090 100644 --- a/packages/storage/src/providers/s3/types/index.ts +++ b/packages/storage/src/providers/s3/types/index.ts @@ -12,7 +12,6 @@ export { } from './options'; export { DownloadDataOutput, - DownloadFileOutput, GetUrlOutput, UploadDataOutput, ListOutputItem, diff --git a/packages/storage/src/providers/s3/types/outputs.ts b/packages/storage/src/providers/s3/types/outputs.ts index d7c36f66f5c..1c149a9213a 100644 --- a/packages/storage/src/providers/s3/types/outputs.ts +++ b/packages/storage/src/providers/s3/types/outputs.ts @@ -23,19 +23,17 @@ export interface Item extends StorageItem { export type DownloadDataOutput = DownloadTask>; -export type DownloadFileOutput = Item; - export type GetUrlOutput = StorageGetUrlOutput; export type UploadDataOutput = UploadTask; export type GetPropertiesOutput = Item; -export type ListOutputItem = Item; +export type ListOutputItem = Omit; -export type ListAllOutput = StorageListOutput; +export type ListAllOutput = StorageListOutput; -export type ListPaginateOutput = StorageListOutput & { +export type ListPaginateOutput = StorageListOutput & { nextToken?: string; };