@jaypie/express 1.2.4 → 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js
CHANGED
|
@@ -32,13 +32,15 @@ class LambdaRequest extends Readable {
|
|
|
32
32
|
this.path = options.url.split("?")[0];
|
|
33
33
|
this.headers = this.normalizeHeaders(options.headers);
|
|
34
34
|
this.bodyBuffer = options.body ?? null;
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
// Use pre-parsed query if provided, otherwise parse from URL
|
|
36
|
+
if (options.query) {
|
|
37
|
+
this.query = options.query;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
const queryIndex = options.url.indexOf("?");
|
|
41
|
+
if (queryIndex !== -1) {
|
|
42
|
+
const queryString = options.url.slice(queryIndex + 1);
|
|
43
|
+
this.query = parseQueryString(queryString);
|
|
42
44
|
}
|
|
43
45
|
}
|
|
44
46
|
// Store Lambda context
|
|
@@ -101,6 +103,66 @@ class LambdaRequest extends Readable {
|
|
|
101
103
|
}
|
|
102
104
|
//
|
|
103
105
|
//
|
|
106
|
+
// Helper Functions
|
|
107
|
+
//
|
|
108
|
+
/**
|
|
109
|
+
* Normalize bracket notation in query parameter key.
|
|
110
|
+
* Removes trailing `[]` from keys (e.g., `filterByStatus[]` → `filterByStatus`).
|
|
111
|
+
*/
|
|
112
|
+
function normalizeQueryKey(key) {
|
|
113
|
+
return key.endsWith("[]") ? key.slice(0, -2) : key;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Parse a query string into a record with proper array handling.
|
|
117
|
+
* Handles bracket notation (e.g., `param[]`) and multi-value parameters.
|
|
118
|
+
*/
|
|
119
|
+
function parseQueryString(queryString) {
|
|
120
|
+
const result = {};
|
|
121
|
+
const params = new URLSearchParams(queryString);
|
|
122
|
+
for (const [rawKey, value] of params) {
|
|
123
|
+
const key = normalizeQueryKey(rawKey);
|
|
124
|
+
const existing = result[key];
|
|
125
|
+
if (existing === undefined) {
|
|
126
|
+
// First occurrence - check if it's bracket notation to determine if it should be an array
|
|
127
|
+
result[key] = rawKey.endsWith("[]") ? [value] : value;
|
|
128
|
+
}
|
|
129
|
+
else if (Array.isArray(existing)) {
|
|
130
|
+
existing.push(value);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
// Convert to array when we encounter a second value
|
|
134
|
+
result[key] = [existing, value];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Build query object from API Gateway v1 multiValueQueryStringParameters.
|
|
141
|
+
* Normalizes bracket notation and preserves array values.
|
|
142
|
+
*/
|
|
143
|
+
function buildQueryFromMultiValue(multiValueParams) {
|
|
144
|
+
const result = {};
|
|
145
|
+
if (!multiValueParams)
|
|
146
|
+
return result;
|
|
147
|
+
for (const [rawKey, values] of Object.entries(multiValueParams)) {
|
|
148
|
+
const key = normalizeQueryKey(rawKey);
|
|
149
|
+
const existingValues = result[key];
|
|
150
|
+
if (existingValues === undefined) {
|
|
151
|
+
// First occurrence - use array if multiple values or bracket notation
|
|
152
|
+
result[key] = values.length === 1 && !rawKey.endsWith("[]") ? values[0] : values;
|
|
153
|
+
}
|
|
154
|
+
else if (Array.isArray(existingValues)) {
|
|
155
|
+
existingValues.push(...values);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
// Convert to array and merge
|
|
159
|
+
result[key] = [existingValues, ...values];
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return result;
|
|
163
|
+
}
|
|
164
|
+
//
|
|
165
|
+
//
|
|
104
166
|
// Type Guards
|
|
105
167
|
//
|
|
106
168
|
/**
|
|
@@ -126,6 +188,7 @@ function createLambdaRequest(event, context) {
|
|
|
126
188
|
let url;
|
|
127
189
|
let method;
|
|
128
190
|
let protocol;
|
|
191
|
+
let query;
|
|
129
192
|
let remoteAddress;
|
|
130
193
|
const headers = { ...event.headers };
|
|
131
194
|
if (isFunctionUrlEvent(event)) {
|
|
@@ -136,6 +199,10 @@ function createLambdaRequest(event, context) {
|
|
|
136
199
|
method = event.requestContext.http.method;
|
|
137
200
|
protocol = event.requestContext.http.protocol.split("/")[0].toLowerCase();
|
|
138
201
|
remoteAddress = event.requestContext.http.sourceIp;
|
|
202
|
+
// Parse query string with proper multi-value and bracket notation support
|
|
203
|
+
if (event.rawQueryString) {
|
|
204
|
+
query = parseQueryString(event.rawQueryString);
|
|
205
|
+
}
|
|
139
206
|
// Normalize cookies into Cookie header if not already present
|
|
140
207
|
if (event.cookies && event.cookies.length > 0 && !headers.cookie) {
|
|
141
208
|
headers.cookie = event.cookies.join("; ");
|
|
@@ -143,7 +210,13 @@ function createLambdaRequest(event, context) {
|
|
|
143
210
|
}
|
|
144
211
|
else if (isApiGatewayV1Event(event)) {
|
|
145
212
|
// API Gateway REST API v1 format
|
|
213
|
+
// Use multiValueQueryStringParameters for proper array support
|
|
214
|
+
const multiValueParams = event.multiValueQueryStringParameters;
|
|
146
215
|
const queryParams = event.queryStringParameters;
|
|
216
|
+
if (multiValueParams && Object.keys(multiValueParams).length > 0) {
|
|
217
|
+
query = buildQueryFromMultiValue(multiValueParams);
|
|
218
|
+
}
|
|
219
|
+
// Build URL with query string
|
|
147
220
|
if (queryParams && Object.keys(queryParams).length > 0) {
|
|
148
221
|
const queryString = new URLSearchParams(queryParams).toString();
|
|
149
222
|
url = `${event.path}?${queryString}`;
|
|
@@ -177,6 +250,7 @@ function createLambdaRequest(event, context) {
|
|
|
177
250
|
lambdaEvent: event,
|
|
178
251
|
method,
|
|
179
252
|
protocol,
|
|
253
|
+
query,
|
|
180
254
|
remoteAddress,
|
|
181
255
|
url,
|
|
182
256
|
});
|