From db84498b11a004707658619b3ca8938014fb1041 Mon Sep 17 00:00:00 2001 From: Allan Zheng <zheallan@amazon.com> Date: Tue, 12 Sep 2023 15:07:52 -0700 Subject: [PATCH 1/4] feat: disable caching for cognito APIs --- .../utils/clients/CognitoIdentityProvider/base.ts | 1 + .../__tests__/clients/composeApiHandler.test.ts | 2 +- packages/core/__tests__/clients/fetch.test.ts | 9 +++++++++ .../core/src/AwsClients/CognitoIdentity/base.ts | 4 ++-- packages/core/src/AwsClients/Pinpoint/base.ts | 8 ++------ packages/core/src/clients/handlers/authenticated.ts | 3 ++- packages/core/src/clients/handlers/fetch.ts | 3 ++- .../core/src/clients/handlers/unauthenticated.ts | 3 ++- .../core/src/clients/internal/composeServiceApi.ts | 13 ++++++++++--- packages/core/src/clients/types/aws.ts | 10 ---------- packages/core/src/clients/types/http.ts | 8 ++++++++ packages/core/src/clients/types/index.ts | 1 - .../core/src/providers/pinpoint/types/buffer.ts | 2 +- .../core/src/providers/pinpoint/types/pinpoint.ts | 13 +++++++------ 14 files changed, 47 insertions(+), 33 deletions(-) diff --git a/packages/auth/src/providers/cognito/utils/clients/CognitoIdentityProvider/base.ts b/packages/auth/src/providers/cognito/utils/clients/CognitoIdentityProvider/base.ts index 75a8650779b..436e7402dd5 100644 --- a/packages/auth/src/providers/cognito/utils/clients/CognitoIdentityProvider/base.ts +++ b/packages/auth/src/providers/cognito/utils/clients/CognitoIdentityProvider/base.ts @@ -61,6 +61,7 @@ export const defaultConfig = { retryDecider: getRetryDecider(parseJsonError), computeDelay: jitteredBackoff, userAgentValue: getAmplifyUserAgent(), + cache: 'no-store', }; /** diff --git a/packages/core/__tests__/clients/composeApiHandler.test.ts b/packages/core/__tests__/clients/composeApiHandler.test.ts index 8b056a823e6..e89311e9a4d 100644 --- a/packages/core/__tests__/clients/composeApiHandler.test.ts +++ b/packages/core/__tests__/clients/composeApiHandler.test.ts @@ -18,7 +18,7 @@ describe(composeServiceApi.name, () => { jest.clearAllMocks(); }); - test('should call transfer handler with resolved config', async () => { + test('should call transfer handler with resolved config including default config values', async () => { const mockTransferHandler = jest.fn().mockResolvedValue(defaultResponse); const config = { ...defaultConfig, diff --git a/packages/core/__tests__/clients/fetch.test.ts b/packages/core/__tests__/clients/fetch.test.ts index ad8cd6fde52..855248e6a61 100644 --- a/packages/core/__tests__/clients/fetch.test.ts +++ b/packages/core/__tests__/clients/fetch.test.ts @@ -40,6 +40,15 @@ describe(fetchTransferHandler.name, () => { ); }); + test('should cache configure', async () => { + const cacheMode = 'no-store'; + await fetchTransferHandler(mockRequest, { cache: cacheMode }); + expect(mockUnfetch).toBeCalledTimes(1); + expect(mockUnfetch.mock.calls[0][1]).toEqual( + expect.objectContaining({ cache: cacheMode }) + ); + }); + test('should support headers', async () => { mockFetchResponse.headers.forEach.mockImplementation((cb: any) => { cb('foo', 'bar'); diff --git a/packages/core/src/AwsClients/CognitoIdentity/base.ts b/packages/core/src/AwsClients/CognitoIdentity/base.ts index 4ae0e912058..20a1a876c70 100644 --- a/packages/core/src/AwsClients/CognitoIdentity/base.ts +++ b/packages/core/src/AwsClients/CognitoIdentity/base.ts @@ -19,7 +19,6 @@ import { } from '../../clients/middleware/retry'; import { getAmplifyUserAgent } from '../../Platform'; import { observeFrameworkChanges } from '../../Platform/detectFramework'; -import { DefaultConfigOptions } from '../../clients/types'; /** * The service name used to sign requests if the API requires authentication. @@ -59,12 +58,13 @@ export const cognitoIdentityTransferHandler = composeTransferHandler< /** * @internal */ -export const defaultConfig: DefaultConfigOptions = { +export const defaultConfig = { service: SERVICE_NAME, endpointResolver, retryDecider: getRetryDecider(parseJsonError), computeDelay: jitteredBackoff, userAgentValue: getAmplifyUserAgent(), + cache: 'no-store', }; observeFrameworkChanges(() => { diff --git a/packages/core/src/AwsClients/Pinpoint/base.ts b/packages/core/src/AwsClients/Pinpoint/base.ts index a74c9a268e1..2c6030d0463 100644 --- a/packages/core/src/AwsClients/Pinpoint/base.ts +++ b/packages/core/src/AwsClients/Pinpoint/base.ts @@ -7,11 +7,7 @@ import { getRetryDecider, } from '../../clients/middleware/retry'; import { parseJsonError } from '../../clients/serde/json'; -import type { - DefaultConfigOptions, - EndpointResolverOptions, - Headers, -} from '../../clients/types'; +import type { EndpointResolverOptions, Headers } from '../../clients/types'; import { getAmplifyUserAgent } from '../../Platform'; /** @@ -29,7 +25,7 @@ const endpointResolver = ({ region }: EndpointResolverOptions) => ({ /** * @internal */ -export const defaultConfig: DefaultConfigOptions = { +export const defaultConfig = { service: SERVICE_NAME, endpointResolver, retryDecider: getRetryDecider(parseJsonError), diff --git a/packages/core/src/clients/handlers/authenticated.ts b/packages/core/src/clients/handlers/authenticated.ts index 09bb90c494b..0260c20ebd9 100644 --- a/packages/core/src/clients/handlers/authenticated.ts +++ b/packages/core/src/clients/handlers/authenticated.ts @@ -11,7 +11,8 @@ import { HttpRequest, HttpResponse } from '../types'; export const authenticatedHandler = composeTransferHandler< [UserAgentOptions, RetryOptions<HttpResponse>, SigningOptions], HttpRequest, - HttpResponse + HttpResponse, + typeof fetchTransferHandler >(fetchTransferHandler, [ userAgentMiddleware, retryMiddleware, diff --git a/packages/core/src/clients/handlers/fetch.ts b/packages/core/src/clients/handlers/fetch.ts index d26deb20c3c..b03f8bd662d 100644 --- a/packages/core/src/clients/handlers/fetch.ts +++ b/packages/core/src/clients/handlers/fetch.ts @@ -14,7 +14,7 @@ export const fetchTransferHandler: TransferHandler< HttpRequest, HttpResponse, HttpTransferOptions -> = async ({ url, method, headers, body }, { abortSignal }) => { +> = async ({ url, method, headers, body }, { abortSignal, cache }) => { let resp: Response; try { resp = await fetch(url, { @@ -22,6 +22,7 @@ export const fetchTransferHandler: TransferHandler< headers, body: shouldSendBody(method) ? body : undefined, signal: abortSignal, + cache, }); } catch (e) { // TODO: needs to revise error handling in v6 diff --git a/packages/core/src/clients/handlers/unauthenticated.ts b/packages/core/src/clients/handlers/unauthenticated.ts index 4f19a2a894b..047d7afcb01 100644 --- a/packages/core/src/clients/handlers/unauthenticated.ts +++ b/packages/core/src/clients/handlers/unauthenticated.ts @@ -10,5 +10,6 @@ import { HttpRequest, HttpResponse } from '../types'; export const unauthenticatedHandler = composeTransferHandler< [UserAgentOptions, RetryOptions<HttpResponse>], HttpRequest, - HttpResponse + HttpResponse, + typeof fetchTransferHandler >(fetchTransferHandler, [userAgentMiddleware, retryMiddleware]); diff --git a/packages/core/src/clients/internal/composeServiceApi.ts b/packages/core/src/clients/internal/composeServiceApi.ts index 98d9959ac56..b7f861a5bc3 100644 --- a/packages/core/src/clients/internal/composeServiceApi.ts +++ b/packages/core/src/clients/internal/composeServiceApi.ts @@ -29,7 +29,7 @@ export const composeServiceApi = < ServiceClientOptions & Partial<DefaultConfig> & InferEndpointResolverOptionType<DefaultConfig>, - keyof DefaultConfig + DefaultConfig >, input: Input ) => { @@ -54,8 +54,15 @@ export const composeServiceApi = < }; }; -type OptionalizeKey<T, K extends keyof T> = Omit<T, K> & { - [P in K & keyof T]?: T[P]; +type OptionalizeKey<InputType, InputDefaultsType> = { + [KeyWithDefaultValue in keyof InputDefaultsType]?: KeyWithDefaultValue extends keyof InputType + ? InputType[KeyWithDefaultValue] + : never; +} & { + [KeyWithoutDefaultValue in keyof Omit< + InputType, + keyof InputDefaultsType + >]: InputType[KeyWithoutDefaultValue]; }; type InferEndpointResolverOptionType<T> = T extends { diff --git a/packages/core/src/clients/types/aws.ts b/packages/core/src/clients/types/aws.ts index 84e145688fb..5c6aa3baa40 100644 --- a/packages/core/src/clients/types/aws.ts +++ b/packages/core/src/clients/types/aws.ts @@ -26,13 +26,3 @@ export interface ServiceClientOptions { export type ErrorParser = ( response?: HttpResponse ) => Promise<(Error & MetadataBearer) | undefined>; - -/** - * Default config options for the `composeServiceApi`. - */ -export type DefaultConfigOptions< - TransferHandlerOptions extends Record<string, unknown> = Record< - string, - unknown - > -> = Partial<TransferHandlerOptions & ServiceClientOptions>; diff --git a/packages/core/src/clients/types/http.ts b/packages/core/src/clients/types/http.ts index f8c3aa34cb9..ae3cc9b908a 100644 --- a/packages/core/src/clients/types/http.ts +++ b/packages/core/src/clients/types/http.ts @@ -34,6 +34,14 @@ export interface HttpResponse extends Response { export interface HttpTransferOptions { abortSignal?: AbortSignal; + /** + * Cache mode for the request. Note that this is only effective when the underlying HTTP handler is fetch. + * For XHR handler, or Node.js `"http(s)"` module or running on React Native, this option is ignored. + * Instead, you can configure the `Cache-Control` headers to achieve similar effects. + * @default 'default' + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/cache} + */ + cache?: RequestCache; } export type HttpTransferHandler = TransferHandler< diff --git a/packages/core/src/clients/types/index.ts b/packages/core/src/clients/types/index.ts index 8e7b5a81aa9..e2b8953a4d2 100644 --- a/packages/core/src/clients/types/index.ts +++ b/packages/core/src/clients/types/index.ts @@ -22,5 +22,4 @@ export { EndpointResolverOptions, ErrorParser, ServiceClientOptions, - DefaultConfigOptions, } from './aws'; diff --git a/packages/core/src/providers/pinpoint/types/buffer.ts b/packages/core/src/providers/pinpoint/types/buffer.ts index 5ba2c3df27a..6652d4db3bb 100644 --- a/packages/core/src/providers/pinpoint/types/buffer.ts +++ b/packages/core/src/providers/pinpoint/types/buffer.ts @@ -7,7 +7,7 @@ import { PinpointAnalyticsEvent, PinpointSession } from './pinpoint'; export type EventBufferConfig = { appId: string; bufferSize: number; - credentials: AuthSession['credentials']; + credentials: Required<AuthSession>['credentials']; identityId: AuthSession['identityId']; flushInterval: number; flushSize: number; diff --git a/packages/core/src/providers/pinpoint/types/pinpoint.ts b/packages/core/src/providers/pinpoint/types/pinpoint.ts index 297cdc5b11b..545e75d6cbb 100644 --- a/packages/core/src/providers/pinpoint/types/pinpoint.ts +++ b/packages/core/src/providers/pinpoint/types/pinpoint.ts @@ -38,17 +38,18 @@ export type PinpointAnalyticsEvent = { type PinpointCommonParameters = { appId: string; category: SupportedCategory; - credentials: AuthSession['credentials']; + credentials: Required<AuthSession>['credentials']; identityId?: AuthSession['identityId']; region: string; userAgentValue?: string; }; -export type PinpointUpdateEndpointParameters = PinpointCommonParameters & PinpointServiceOptions & { - channelType?: SupportedChannelType; - userId?: string; - userProfile?: UserProfile; -}; +export type PinpointUpdateEndpointParameters = PinpointCommonParameters & + PinpointServiceOptions & { + channelType?: SupportedChannelType; + userId?: string; + userProfile?: UserProfile; + }; export type PinpointRecordParameters = PinpointCommonParameters & { event: PinpointAnalyticsEvent; From 4d4173712724aed45d7788923e94c76028402f2d Mon Sep 17 00:00:00 2001 From: AllanZhengYP <zheallan@amazon.com> Date: Wed, 13 Sep 2023 09:44:56 -0700 Subject: [PATCH 2/4] fix: address feedbacks Co-authored-by: Jim Blanchard <jim.l.blanchard@gmail.com> --- packages/core/__tests__/clients/fetch.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/__tests__/clients/fetch.test.ts b/packages/core/__tests__/clients/fetch.test.ts index 7ad7cbcf6d0..bb1deab4b33 100644 --- a/packages/core/__tests__/clients/fetch.test.ts +++ b/packages/core/__tests__/clients/fetch.test.ts @@ -40,7 +40,7 @@ describe(fetchTransferHandler.name, () => { ); }); - test('should cache configure', async () => { + test('should configure cache', async () => { const cacheMode = 'no-store'; await fetchTransferHandler(mockRequest, { cache: cacheMode }); expect(mockUnfetch).toBeCalledTimes(1); From c75fa5bd88661ca62ce3b2f6ae5f199e058a5695 Mon Sep 17 00:00:00 2001 From: Allan Zheng <zheallan@amazon.com> Date: Wed, 13 Sep 2023 15:44:01 -0700 Subject: [PATCH 3/4] fix: broken test from merge --- packages/core/__tests__/clients/fetch.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/__tests__/clients/fetch.test.ts b/packages/core/__tests__/clients/fetch.test.ts index bb1deab4b33..70321d26d4d 100644 --- a/packages/core/__tests__/clients/fetch.test.ts +++ b/packages/core/__tests__/clients/fetch.test.ts @@ -43,8 +43,8 @@ describe(fetchTransferHandler.name, () => { test('should configure cache', async () => { const cacheMode = 'no-store'; await fetchTransferHandler(mockRequest, { cache: cacheMode }); - expect(mockUnfetch).toBeCalledTimes(1); - expect(mockUnfetch.mock.calls[0][1]).toEqual( + expect(mockFetch).toBeCalledTimes(1); + expect(mockFetch.mock.calls[0][1]).toEqual( expect.objectContaining({ cache: cacheMode }) ); }); From 388894fb87c4352df8459e067d4faa44c085a17b Mon Sep 17 00:00:00 2001 From: Allan Zheng <zheallan@amazon.com> Date: Wed, 13 Sep 2023 16:42:45 -0700 Subject: [PATCH 4/4] chore: fix diffs --- .../analytics/src/providers/pinpoint/apis/identifyUser.ts | 8 ++++---- packages/analytics/src/providers/pinpoint/apis/record.ts | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/analytics/src/providers/pinpoint/apis/identifyUser.ts b/packages/analytics/src/providers/pinpoint/apis/identifyUser.ts index b86f24a465d..219f93adaca 100644 --- a/packages/analytics/src/providers/pinpoint/apis/identifyUser.ts +++ b/packages/analytics/src/providers/pinpoint/apis/identifyUser.ts @@ -17,11 +17,11 @@ import { resolveConfig, resolveCredentials } from '../utils'; * API. * * @throws service: {@link UpdateEndpointException} - Thrown when the underlying Pinpoint service returns an error. - * @throws validation: {@link AnalyticsValidationErrorCode} - Thrown when the provided parameters or library + * @throws validation: {@link AnalyticsValidationErrorCode} - Thrown when the provided parameters or library * configuration is incorrect. - * + * * @returns A promise that will resolve when the operation is complete. - * + * * @example * ```ts * // Identify a user with Pinpoint @@ -34,7 +34,7 @@ import { resolveConfig, resolveCredentials } from '../utils'; * } * }); * ``` - * + * * @example * ```ts * // Identify a user with Pinpoint with some additional demographics diff --git a/packages/analytics/src/providers/pinpoint/apis/record.ts b/packages/analytics/src/providers/pinpoint/apis/record.ts index 1df99786efb..5d33e5503a8 100644 --- a/packages/analytics/src/providers/pinpoint/apis/record.ts +++ b/packages/analytics/src/providers/pinpoint/apis/record.ts @@ -21,9 +21,9 @@ const logger = new Logger('Analytics'); * * @param {RecordInput} params The input object used to construct the request. * - * @throws validation: {@link AnalyticsValidationErrorCode} - Thrown when the provided parameters or library + * @throws validation: {@link AnalyticsValidationErrorCode} - Thrown when the provided parameters or library * configuration is incorrect. - * + * * @example * ```ts * // Send an event to Pinpoint @@ -33,7 +33,7 @@ const logger = new Logger('Analytics'); * } * }) * ``` - * + * * @example * ```ts * // Send an event to Pinpoint with metrics & custom attributes