@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/README.md
CHANGED
|
@@ -8,6 +8,7 @@ See [Jaypie](https://github.com/finlaysonstudio/jaypie) for usage.
|
|
|
8
8
|
|
|
9
9
|
| Date | Version | Summary |
|
|
10
10
|
| ---------- | ------- | -------------- |
|
|
11
|
+
| 1/23/2026 | 1.2.5 | Fix array query params with bracket notation in API Gateway v1 |
|
|
11
12
|
| 5/21/2024 | 1.0.0 | Initial release |
|
|
12
13
|
| 5/19/2024 | 0.1.0 | Initial deploy |
|
|
13
14
|
| 5/12/2024 | 0.0.1 | Initial commit |
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -34,13 +34,15 @@ class LambdaRequest extends node_stream.Readable {
|
|
|
34
34
|
this.path = options.url.split("?")[0];
|
|
35
35
|
this.headers = this.normalizeHeaders(options.headers);
|
|
36
36
|
this.bodyBuffer = options.body ?? null;
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
// Use pre-parsed query if provided, otherwise parse from URL
|
|
38
|
+
if (options.query) {
|
|
39
|
+
this.query = options.query;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const queryIndex = options.url.indexOf("?");
|
|
43
|
+
if (queryIndex !== -1) {
|
|
44
|
+
const queryString = options.url.slice(queryIndex + 1);
|
|
45
|
+
this.query = parseQueryString(queryString);
|
|
44
46
|
}
|
|
45
47
|
}
|
|
46
48
|
// Store Lambda context
|
|
@@ -103,6 +105,66 @@ class LambdaRequest extends node_stream.Readable {
|
|
|
103
105
|
}
|
|
104
106
|
//
|
|
105
107
|
//
|
|
108
|
+
// Helper Functions
|
|
109
|
+
//
|
|
110
|
+
/**
|
|
111
|
+
* Normalize bracket notation in query parameter key.
|
|
112
|
+
* Removes trailing `[]` from keys (e.g., `filterByStatus[]` → `filterByStatus`).
|
|
113
|
+
*/
|
|
114
|
+
function normalizeQueryKey(key) {
|
|
115
|
+
return key.endsWith("[]") ? key.slice(0, -2) : key;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Parse a query string into a record with proper array handling.
|
|
119
|
+
* Handles bracket notation (e.g., `param[]`) and multi-value parameters.
|
|
120
|
+
*/
|
|
121
|
+
function parseQueryString(queryString) {
|
|
122
|
+
const result = {};
|
|
123
|
+
const params = new URLSearchParams(queryString);
|
|
124
|
+
for (const [rawKey, value] of params) {
|
|
125
|
+
const key = normalizeQueryKey(rawKey);
|
|
126
|
+
const existing = result[key];
|
|
127
|
+
if (existing === undefined) {
|
|
128
|
+
// First occurrence - check if it's bracket notation to determine if it should be an array
|
|
129
|
+
result[key] = rawKey.endsWith("[]") ? [value] : value;
|
|
130
|
+
}
|
|
131
|
+
else if (Array.isArray(existing)) {
|
|
132
|
+
existing.push(value);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
// Convert to array when we encounter a second value
|
|
136
|
+
result[key] = [existing, value];
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Build query object from API Gateway v1 multiValueQueryStringParameters.
|
|
143
|
+
* Normalizes bracket notation and preserves array values.
|
|
144
|
+
*/
|
|
145
|
+
function buildQueryFromMultiValue(multiValueParams) {
|
|
146
|
+
const result = {};
|
|
147
|
+
if (!multiValueParams)
|
|
148
|
+
return result;
|
|
149
|
+
for (const [rawKey, values] of Object.entries(multiValueParams)) {
|
|
150
|
+
const key = normalizeQueryKey(rawKey);
|
|
151
|
+
const existingValues = result[key];
|
|
152
|
+
if (existingValues === undefined) {
|
|
153
|
+
// First occurrence - use array if multiple values or bracket notation
|
|
154
|
+
result[key] = values.length === 1 && !rawKey.endsWith("[]") ? values[0] : values;
|
|
155
|
+
}
|
|
156
|
+
else if (Array.isArray(existingValues)) {
|
|
157
|
+
existingValues.push(...values);
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
// Convert to array and merge
|
|
161
|
+
result[key] = [existingValues, ...values];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
//
|
|
167
|
+
//
|
|
106
168
|
// Type Guards
|
|
107
169
|
//
|
|
108
170
|
/**
|
|
@@ -128,6 +190,7 @@ function createLambdaRequest(event, context) {
|
|
|
128
190
|
let url;
|
|
129
191
|
let method;
|
|
130
192
|
let protocol;
|
|
193
|
+
let query;
|
|
131
194
|
let remoteAddress;
|
|
132
195
|
const headers = { ...event.headers };
|
|
133
196
|
if (isFunctionUrlEvent(event)) {
|
|
@@ -138,6 +201,10 @@ function createLambdaRequest(event, context) {
|
|
|
138
201
|
method = event.requestContext.http.method;
|
|
139
202
|
protocol = event.requestContext.http.protocol.split("/")[0].toLowerCase();
|
|
140
203
|
remoteAddress = event.requestContext.http.sourceIp;
|
|
204
|
+
// Parse query string with proper multi-value and bracket notation support
|
|
205
|
+
if (event.rawQueryString) {
|
|
206
|
+
query = parseQueryString(event.rawQueryString);
|
|
207
|
+
}
|
|
141
208
|
// Normalize cookies into Cookie header if not already present
|
|
142
209
|
if (event.cookies && event.cookies.length > 0 && !headers.cookie) {
|
|
143
210
|
headers.cookie = event.cookies.join("; ");
|
|
@@ -145,7 +212,13 @@ function createLambdaRequest(event, context) {
|
|
|
145
212
|
}
|
|
146
213
|
else if (isApiGatewayV1Event(event)) {
|
|
147
214
|
// API Gateway REST API v1 format
|
|
215
|
+
// Use multiValueQueryStringParameters for proper array support
|
|
216
|
+
const multiValueParams = event.multiValueQueryStringParameters;
|
|
148
217
|
const queryParams = event.queryStringParameters;
|
|
218
|
+
if (multiValueParams && Object.keys(multiValueParams).length > 0) {
|
|
219
|
+
query = buildQueryFromMultiValue(multiValueParams);
|
|
220
|
+
}
|
|
221
|
+
// Build URL with query string
|
|
149
222
|
if (queryParams && Object.keys(queryParams).length > 0) {
|
|
150
223
|
const queryString = new URLSearchParams(queryParams).toString();
|
|
151
224
|
url = `${event.path}?${queryString}`;
|
|
@@ -179,6 +252,7 @@ function createLambdaRequest(event, context) {
|
|
|
179
252
|
lambdaEvent: event,
|
|
180
253
|
method,
|
|
181
254
|
protocol,
|
|
255
|
+
query,
|
|
182
256
|
remoteAddress,
|
|
183
257
|
url,
|
|
184
258
|
});
|