Skip to content

Commit e917e61

Browse files
authored
chore: enforce singular config object for resolver stack (#1552)
* fix: enforce singular object custody in config resolver stack * separate java changes
1 parent 234b491 commit e917e61

25 files changed

+169
-93
lines changed

.changeset/weak-poems-tease.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
"@smithy/eventstream-serde-config-resolver": minor
3+
"@smithy/middleware-apply-body-checksum": minor
4+
"@smithy/middleware-compression": minor
5+
"@smithy/middleware-endpoint": minor
6+
"@smithy/middleware-retry": minor
7+
"@smithy/config-resolver": minor
8+
"@smithy/protocol-http": minor
9+
"@smithy/smithy-client": minor
10+
"@smithy/util-stream": minor
11+
"@smithy/types": minor
12+
---
13+
14+
enforce singular config object during client instantiation

packages/config-resolver/src/endpointsConfig/resolveCustomEndpointsConfig.spec.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,19 @@ describe(resolveCustomEndpointsConfig.name, () => {
2020

2121
beforeEach(() => {
2222
vi.mocked(normalizeProvider).mockImplementation((input) =>
23-
typeof input === "function" ? input : () => Promise.resolve(input)
23+
typeof input === "function" ? (input as any) : () => Promise.resolve(input)
2424
);
2525
});
2626

2727
afterEach(() => {
2828
vi.clearAllMocks();
2929
});
3030

31+
it("maintains object custody", () => {
32+
const input = { ...mockInput };
33+
expect(resolveCustomEndpointsConfig(input)).toBe(input);
34+
});
35+
3136
describe("tls", () => {
3237
afterEach(() => {
3338
expect(normalizeProvider).toHaveBeenCalledTimes(2);
@@ -44,7 +49,7 @@ describe(resolveCustomEndpointsConfig.name, () => {
4449
});
4550

4651
it("returns true for isCustomEndpoint", () => {
47-
expect(resolveCustomEndpointsConfig(mockInput).isCustomEndpoint).toStrictEqual(true);
52+
expect(resolveCustomEndpointsConfig({ ...mockInput }).isCustomEndpoint).toStrictEqual(true);
4853
});
4954

5055
it("returns false when useDualstackEndpoint is not defined", async () => {
@@ -56,23 +61,25 @@ describe(resolveCustomEndpointsConfig.name, () => {
5661
});
5762

5863
describe("returns normalized endpoint", () => {
59-
afterEach(() => {
60-
expect(normalizeProvider).toHaveBeenCalledTimes(2);
61-
expect(normalizeProvider).toHaveBeenNthCalledWith(1, mockInput.endpoint);
62-
expect(normalizeProvider).toHaveBeenNthCalledWith(2, mockInput.useDualstackEndpoint);
63-
});
64-
6564
it("calls urlParser endpoint is of type string", async () => {
6665
const mockEndpointString = "http://localhost/";
6766
const endpoint = await resolveCustomEndpointsConfig({ ...mockInput, endpoint: mockEndpointString }).endpoint();
6867
expect(endpoint).toStrictEqual(mockEndpoint);
6968
expect(mockInput.urlParser).toHaveBeenCalledWith(mockEndpointString);
69+
70+
expect(normalizeProvider).toHaveBeenCalledTimes(2);
71+
expect(normalizeProvider).toHaveBeenNthCalledWith(1, mockInput.endpoint);
72+
expect(normalizeProvider).toHaveBeenNthCalledWith(2, mockInput.useDualstackEndpoint);
7073
});
7174

7275
it("passes endpoint to normalize if not string", async () => {
73-
const endpoint = await resolveCustomEndpointsConfig(mockInput).endpoint();
76+
const endpoint = await resolveCustomEndpointsConfig({ ...mockInput }).endpoint();
7477
expect(endpoint).toStrictEqual(mockEndpoint);
7578
expect(mockInput.urlParser).not.toHaveBeenCalled();
79+
80+
expect(normalizeProvider).toHaveBeenCalledTimes(2);
81+
expect(normalizeProvider).toHaveBeenNthCalledWith(1, mockInput.endpoint);
82+
expect(normalizeProvider).toHaveBeenNthCalledWith(2, mockInput.useDualstackEndpoint);
7683
});
7784
});
7885
});

packages/config-resolver/src/endpointsConfig/resolveCustomEndpointsConfig.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,11 @@ export interface CustomEndpointsResolvedConfig extends EndpointsResolvedConfig {
3737
export const resolveCustomEndpointsConfig = <T>(
3838
input: T & CustomEndpointsInputConfig & PreviouslyResolved
3939
): T & CustomEndpointsResolvedConfig => {
40-
const { endpoint, urlParser } = input;
41-
return {
42-
...input,
43-
tls: input.tls ?? true,
40+
const { tls, endpoint, urlParser, useDualstackEndpoint } = input;
41+
return Object.assign(input, {
42+
tls: tls ?? true,
4443
endpoint: normalizeProvider(typeof endpoint === "string" ? urlParser(endpoint) : endpoint),
4544
isCustomEndpoint: true,
46-
useDualstackEndpoint: normalizeProvider(input.useDualstackEndpoint ?? false),
47-
};
45+
useDualstackEndpoint: normalizeProvider(useDualstackEndpoint ?? false),
46+
} as CustomEndpointsResolvedConfig);
4847
};

packages/config-resolver/src/endpointsConfig/resolveEndpointsConfig.spec.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,19 @@ describe(resolveEndpointsConfig.name, () => {
2525
beforeEach(() => {
2626
vi.mocked(getEndpointFromRegion).mockResolvedValueOnce(mockEndpoint);
2727
vi.mocked(normalizeProvider).mockImplementation((input) =>
28-
typeof input === "function" ? input : () => Promise.resolve(input)
28+
typeof input === "function" ? (input as any) : () => Promise.resolve(input)
2929
);
3030
});
3131

3232
afterEach(() => {
3333
vi.clearAllMocks();
3434
});
3535

36+
it("maintains object custody", () => {
37+
const input = { ...mockInput };
38+
expect(resolveEndpointsConfig(input)).toBe(input);
39+
});
40+
3641
describe("tls", () => {
3742
afterEach(() => {
3843
expect(normalizeProvider).toHaveBeenNthCalledWith(1, mockInput.useDualstackEndpoint);
@@ -53,7 +58,7 @@ describe(resolveEndpointsConfig.name, () => {
5358
});
5459

5560
it("returns true when endpoint is defined", () => {
56-
expect(resolveEndpointsConfig(mockInput).isCustomEndpoint).toStrictEqual(true);
61+
expect(resolveEndpointsConfig({ ...mockInput }).isCustomEndpoint).toStrictEqual(true);
5762
});
5863

5964
it("returns false when endpoint is not defined", () => {
@@ -90,7 +95,7 @@ describe(resolveEndpointsConfig.name, () => {
9095
});
9196

9297
it("passes endpoint to normalize if not string", async () => {
93-
const endpoint = await resolveEndpointsConfig(mockInput).endpoint();
98+
const endpoint = await resolveEndpointsConfig({ ...mockInput }).endpoint();
9499
expect(endpoint).toStrictEqual(mockEndpoint);
95100
expect(mockInput.urlParser).not.toHaveBeenCalled();
96101
});

packages/config-resolver/src/endpointsConfig/resolveEndpointsConfig.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,13 @@ export const resolveEndpointsConfig = <T>(
6565
input: T & EndpointsInputConfig & PreviouslyResolved
6666
): T & EndpointsResolvedConfig => {
6767
const useDualstackEndpoint = normalizeProvider(input.useDualstackEndpoint ?? false);
68-
const { endpoint, useFipsEndpoint, urlParser } = input;
69-
return {
70-
...input,
71-
tls: input.tls ?? true,
68+
const { endpoint, useFipsEndpoint, urlParser, tls } = input;
69+
return Object.assign(input, {
70+
tls: tls ?? true,
7271
endpoint: endpoint
7372
? normalizeProvider(typeof endpoint === "string" ? urlParser(endpoint) : endpoint)
7473
: () => getEndpointFromRegion({ ...input, useDualstackEndpoint, useFipsEndpoint }),
7574
isCustomEndpoint: !!endpoint,
7675
useDualstackEndpoint,
77-
};
76+
});
7877
};

packages/config-resolver/src/regionConfig/resolveRegionConfig.spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ describe("RegionConfig", () => {
2121
vi.clearAllMocks();
2222
});
2323

24+
it("maintains object custody", () => {
25+
const input = {
26+
region: "us-east-1",
27+
};
28+
expect(resolveRegionConfig(input)).toBe(input);
29+
});
30+
2431
describe("region", () => {
2532
it("return normalized value with real region if passed as a string", async () => {
2633
const resolvedRegionConfig = resolveRegionConfig({ region: mockRegion, useFipsEndpoint: mockUseFipsEndpoint });

packages/config-resolver/src/regionConfig/resolveRegionConfig.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ export const resolveRegionConfig = <T>(input: T & RegionInputConfig & Previously
4545
throw new Error("Region is missing");
4646
}
4747

48-
return {
49-
...input,
48+
return Object.assign(input, {
5049
region: async () => {
5150
if (typeof region === "string") {
5251
return getRealRegion(region);
@@ -61,5 +60,5 @@ export const resolveRegionConfig = <T>(input: T & RegionInputConfig & Previously
6160
}
6261
return typeof useFipsEndpoint !== "function" ? Promise.resolve(!!useFipsEndpoint) : useFipsEndpoint();
6362
},
64-
};
63+
});
6564
};

packages/eventstream-serde-config-resolver/src/EventStreamSerdeConfig.spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ describe("resolveEventStreamSerdeConfig", () => {
99
vi.clearAllMocks();
1010
});
1111

12+
it("maintains object custody", () => {
13+
const input = {
14+
eventStreamSerdeProvider: vi.fn(),
15+
};
16+
expect(resolveEventStreamSerdeConfig(input)).toBe(input);
17+
});
18+
1219
it("sets value returned by eventStreamSerdeProvider", () => {
1320
const mockReturn = "mockReturn";
1421
eventStreamSerdeProvider.mockReturnValueOnce(mockReturn);

packages/eventstream-serde-config-resolver/src/EventStreamSerdeConfig.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ interface PreviouslyResolved {
2828
*/
2929
export const resolveEventStreamSerdeConfig = <T>(
3030
input: T & PreviouslyResolved & EventStreamSerdeInputConfig
31-
): T & EventStreamSerdeResolvedConfig => ({
32-
...input,
33-
eventStreamMarshaller: input.eventStreamSerdeProvider(input),
34-
});
31+
): T & EventStreamSerdeResolvedConfig =>
32+
Object.assign(input, {
33+
eventStreamMarshaller: input.eventStreamSerdeProvider(input),
34+
});

packages/middleware-apply-body-checksum/src/index.spec.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
1-
import { describe, expect, test as it } from "vitest";
1+
import { describe, expect, test as it, vi } from "vitest";
22

3-
import { applyMd5BodyChecksumMiddleware } from "./index";
3+
import { applyMd5BodyChecksumMiddleware, resolveMd5BodyChecksumConfig } from "./index";
44

55
describe("middleware-apply-body-checksum package exports", () => {
6+
it("maintains object custody", () => {
7+
const input = {
8+
md5: vi.fn(),
9+
base64Encoder: vi.fn(),
10+
streamHasher: vi.fn(),
11+
};
12+
expect(resolveMd5BodyChecksumConfig(input)).toBe(input);
13+
});
14+
615
it("applyMd5BodyChecksumMiddleware", () => {
716
expect(typeof applyMd5BodyChecksumMiddleware).toBe("function");
817
});

0 commit comments

Comments
 (0)