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