Skip to content

Commit 85128a5

Browse files
authored
fix: AWS ApiGW v1 (REST) converter incorrectly parses all query parameters as arrays (#1055)
* Fix AWS ApiGW v1 (REST) incoming query parameters handling * Changeset * Fix linter errors
1 parent 47a84a7 commit 85128a5

File tree

3 files changed

+67
-3
lines changed

3 files changed

+67
-3
lines changed

.changeset/vast-paws-attack.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@opennextjs/aws": patch
3+
---
4+
5+
fix: AWS ApiGW v1 (REST) converter incorrectly parses all query parameters as arrays

packages/open-next/src/overrides/converters/aws-apigw-v1.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,24 @@ function normalizeAPIGatewayProxyEventQueryParams(
5353
return value ? `?${value}` : "";
5454
}
5555

56+
function normalizeAPIGatewayProxyEventMultiValueQueryStringParameters(
57+
event: APIGatewayProxyEvent,
58+
): Record<string, string[] | string> {
59+
const params: Record<string, string | string[]> = {};
60+
for (const [key, value] of Object.entries(
61+
event.multiValueQueryStringParameters || {},
62+
)) {
63+
if (value !== undefined && Array.isArray(value)) {
64+
if (value.length === 1) {
65+
params[key] = value[0];
66+
} else {
67+
params[key] = value;
68+
}
69+
}
70+
}
71+
return params;
72+
}
73+
5674
async function convertFromAPIGatewayProxyEvent(
5775
event: APIGatewayProxyEvent,
5876
): Promise<InternalEvent> {
@@ -67,7 +85,7 @@ async function convertFromAPIGatewayProxyEvent(
6785
headers,
6886
remoteAddress: requestContext.identity.sourceIp,
6987
query: removeUndefinedFromQuery(
70-
event.multiValueQueryStringParameters ?? {},
88+
normalizeAPIGatewayProxyEventMultiValueQueryStringParameters(event),
7189
),
7290
cookies:
7391
event.multiValueHeaders?.cookie?.reduce(

packages/tests-unit/tests/converters/aws-apigw-v1.test.ts

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ describe("convertFrom", () => {
137137
});
138138
});
139139

140-
it("Should handle queryStringParameters and multiValueQueryStringParameters", async () => {
140+
it("Should handle queryStringParameters and multiValueQueryStringParameters for single value parameters", async () => {
141141
const event: APIGatewayProxyEvent = {
142142
body: JSON.stringify({ message: "Hello, world!" }),
143143
headers: {},
@@ -172,7 +172,48 @@ describe("convertFrom", () => {
172172
headers: {},
173173
remoteAddress: "::1",
174174
query: {
175-
test: ["test"],
175+
test: "test",
176+
},
177+
cookies: {},
178+
});
179+
});
180+
181+
it("Should handle queryStringParameters and multiValueQueryStringParameters for multi value parameters", async () => {
182+
const event: APIGatewayProxyEvent = {
183+
body: JSON.stringify({ message: "Hello, world!" }),
184+
headers: {},
185+
multiValueHeaders: {},
186+
httpMethod: "POST",
187+
isBase64Encoded: false,
188+
path: "/",
189+
pathParameters: null,
190+
queryStringParameters: {
191+
test: "testB",
192+
},
193+
multiValueQueryStringParameters: {
194+
test: ["testA", "testB"],
195+
},
196+
stageVariables: null,
197+
requestContext: {
198+
identity: {
199+
sourceIp: "::1",
200+
},
201+
} as any,
202+
resource: "",
203+
};
204+
205+
const response = await converter.convertFrom(event);
206+
207+
expect(response).toEqual({
208+
type: "core",
209+
method: "POST",
210+
rawPath: "/",
211+
url: "https://on/?test=testA&test=testB",
212+
body: Buffer.from('{"message":"Hello, world!"}'),
213+
headers: {},
214+
remoteAddress: "::1",
215+
query: {
216+
test: ["testA", "testB"],
176217
},
177218
cookies: {},
178219
});

0 commit comments

Comments
 (0)