@jaypie/express 1.2.2 → 1.2.3
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/cjs/createServer.d.ts +60 -0
- package/dist/cjs/getCurrentInvokeUuid.adapter.d.ts +10 -1
- package/dist/cjs/getCurrentInvokeUuid.webadapter.d.ts +12 -0
- package/dist/cjs/index.cjs +175 -7
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +3 -0
- package/dist/esm/createServer.d.ts +60 -0
- package/dist/esm/getCurrentInvokeUuid.adapter.d.ts +10 -1
- package/dist/esm/getCurrentInvokeUuid.webadapter.d.ts +12 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +173 -7
- package/dist/esm/index.js.map +1 -1
- package/package.json +4 -1
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { Application, RequestHandler } from "express";
|
|
2
|
+
import type { Server } from "http";
|
|
3
|
+
import type { CorsConfig } from "./cors.helper.js";
|
|
4
|
+
export interface CreateServerOptions {
|
|
5
|
+
/**
|
|
6
|
+
* CORS configuration. Pass false to disable CORS middleware.
|
|
7
|
+
*/
|
|
8
|
+
cors?: CorsConfig | false;
|
|
9
|
+
/**
|
|
10
|
+
* JSON body parser limit. Defaults to "1mb".
|
|
11
|
+
*/
|
|
12
|
+
jsonLimit?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Additional middleware to apply before routes.
|
|
15
|
+
*/
|
|
16
|
+
middleware?: RequestHandler[];
|
|
17
|
+
/**
|
|
18
|
+
* Port to listen on. Defaults to PORT env var or 8080.
|
|
19
|
+
*/
|
|
20
|
+
port?: number | string;
|
|
21
|
+
}
|
|
22
|
+
export interface ServerResult {
|
|
23
|
+
/**
|
|
24
|
+
* The HTTP server instance.
|
|
25
|
+
*/
|
|
26
|
+
server: Server;
|
|
27
|
+
/**
|
|
28
|
+
* The port the server is listening on.
|
|
29
|
+
*/
|
|
30
|
+
port: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Creates and starts an Express server with standard Jaypie middleware.
|
|
34
|
+
*
|
|
35
|
+
* Features:
|
|
36
|
+
* - CORS handling (configurable)
|
|
37
|
+
* - JSON body parsing
|
|
38
|
+
* - Listens on PORT env var (default 8080)
|
|
39
|
+
*
|
|
40
|
+
* Usage:
|
|
41
|
+
* ```ts
|
|
42
|
+
* import express from "express";
|
|
43
|
+
* import { createServer, expressHandler } from "@jaypie/express";
|
|
44
|
+
*
|
|
45
|
+
* const app = express();
|
|
46
|
+
*
|
|
47
|
+
* app.get("/", expressHandler(async (req, res) => {
|
|
48
|
+
* return { message: "Hello World" };
|
|
49
|
+
* }));
|
|
50
|
+
*
|
|
51
|
+
* const { server, port } = await createServer(app);
|
|
52
|
+
* console.log(`Server running on port ${port}`);
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @param app - Express application instance
|
|
56
|
+
* @param options - Server configuration options
|
|
57
|
+
* @returns Promise resolving to server instance and port
|
|
58
|
+
*/
|
|
59
|
+
declare function createServer(app: Application, options?: CreateServerOptions): Promise<ServerResult>;
|
|
60
|
+
export default createServer;
|
|
@@ -1,2 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import type { Request } from "express";
|
|
2
|
+
/**
|
|
3
|
+
* Get the current invoke UUID from Lambda context.
|
|
4
|
+
* Works in both serverless-express mode and Lambda Web Adapter mode.
|
|
5
|
+
*
|
|
6
|
+
* @param req - Optional Express request object. Required for Web Adapter mode
|
|
7
|
+
* to extract the x-amzn-request-id header.
|
|
8
|
+
* @returns The AWS request ID or undefined if not in Lambda context
|
|
9
|
+
*/
|
|
10
|
+
declare function getCurrentInvokeUuid(req?: Request): string | undefined;
|
|
2
11
|
export default getCurrentInvokeUuid;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Request } from "express";
|
|
2
|
+
/**
|
|
3
|
+
* Get the current invoke UUID from Lambda Web Adapter context.
|
|
4
|
+
* This function extracts the request ID from either:
|
|
5
|
+
* 1. The x-amzn-request-id header (set by Lambda Web Adapter)
|
|
6
|
+
* 2. The _X_AMZN_TRACE_ID environment variable (set by Lambda runtime)
|
|
7
|
+
*
|
|
8
|
+
* @param req - Optional Express request object to extract headers from
|
|
9
|
+
* @returns The AWS request ID or undefined if not in Lambda context
|
|
10
|
+
*/
|
|
11
|
+
declare function getWebAdapterUuid(req?: Request): string | undefined;
|
|
12
|
+
export default getWebAdapterUuid;
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
var errors = require('@jaypie/errors');
|
|
4
4
|
var kit = require('@jaypie/kit');
|
|
5
5
|
var expressCors = require('cors');
|
|
6
|
-
var aws = require('@jaypie/aws');
|
|
7
6
|
var logger$2 = require('@jaypie/logger');
|
|
7
|
+
var aws = require('@jaypie/aws');
|
|
8
8
|
var datadog = require('@jaypie/datadog');
|
|
9
9
|
var serverlessExpress = require('@codegenie/serverless-express');
|
|
10
10
|
|
|
@@ -94,7 +94,7 @@ const corsHelper = (config = {}) => {
|
|
|
94
94
|
};
|
|
95
95
|
return expressCors(options);
|
|
96
96
|
};
|
|
97
|
-
var
|
|
97
|
+
var cors = (config) => {
|
|
98
98
|
const cors = corsHelper(config);
|
|
99
99
|
return (req, res, next) => {
|
|
100
100
|
cors(req, res, (error) => {
|
|
@@ -109,11 +109,157 @@ var cors_helper = (config) => {
|
|
|
109
109
|
};
|
|
110
110
|
};
|
|
111
111
|
|
|
112
|
+
//
|
|
113
|
+
//
|
|
114
|
+
// Constants
|
|
115
|
+
//
|
|
116
|
+
const DEFAULT_PORT = 8080;
|
|
117
|
+
//
|
|
118
|
+
//
|
|
119
|
+
// Main
|
|
120
|
+
//
|
|
121
|
+
/**
|
|
122
|
+
* Creates and starts an Express server with standard Jaypie middleware.
|
|
123
|
+
*
|
|
124
|
+
* Features:
|
|
125
|
+
* - CORS handling (configurable)
|
|
126
|
+
* - JSON body parsing
|
|
127
|
+
* - Listens on PORT env var (default 8080)
|
|
128
|
+
*
|
|
129
|
+
* Usage:
|
|
130
|
+
* ```ts
|
|
131
|
+
* import express from "express";
|
|
132
|
+
* import { createServer, expressHandler } from "@jaypie/express";
|
|
133
|
+
*
|
|
134
|
+
* const app = express();
|
|
135
|
+
*
|
|
136
|
+
* app.get("/", expressHandler(async (req, res) => {
|
|
137
|
+
* return { message: "Hello World" };
|
|
138
|
+
* }));
|
|
139
|
+
*
|
|
140
|
+
* const { server, port } = await createServer(app);
|
|
141
|
+
* console.log(`Server running on port ${port}`);
|
|
142
|
+
* ```
|
|
143
|
+
*
|
|
144
|
+
* @param app - Express application instance
|
|
145
|
+
* @param options - Server configuration options
|
|
146
|
+
* @returns Promise resolving to server instance and port
|
|
147
|
+
*/
|
|
148
|
+
async function createServer(app, options = {}) {
|
|
149
|
+
const { cors: corsConfig, jsonLimit = "1mb", middleware = [], port: portOption, } = options;
|
|
150
|
+
// Determine port
|
|
151
|
+
const port = typeof portOption === "string"
|
|
152
|
+
? parseInt(portOption, 10)
|
|
153
|
+
: (portOption ?? parseInt(process.env.PORT || String(DEFAULT_PORT), 10));
|
|
154
|
+
// Apply CORS middleware (unless explicitly disabled)
|
|
155
|
+
if (corsConfig !== false) {
|
|
156
|
+
app.use(cors(corsConfig));
|
|
157
|
+
}
|
|
158
|
+
// Apply JSON body parser
|
|
159
|
+
// Note: We use dynamic import to avoid requiring express as a direct dependency
|
|
160
|
+
const express = await import('express');
|
|
161
|
+
app.use(express.json({ limit: jsonLimit }));
|
|
162
|
+
// Apply additional middleware
|
|
163
|
+
for (const mw of middleware) {
|
|
164
|
+
app.use(mw);
|
|
165
|
+
}
|
|
166
|
+
// Start server
|
|
167
|
+
return new Promise((resolve, reject) => {
|
|
168
|
+
try {
|
|
169
|
+
const server = app.listen(port, () => {
|
|
170
|
+
// Get the actual port (important when port 0 is passed to get an ephemeral port)
|
|
171
|
+
const address = server.address();
|
|
172
|
+
const actualPort = address?.port ?? port;
|
|
173
|
+
logger$2.log.info(`Server listening on port ${actualPort}`);
|
|
174
|
+
resolve({ port: actualPort, server });
|
|
175
|
+
});
|
|
176
|
+
server.on("error", (error) => {
|
|
177
|
+
logger$2.log.error("Server error", { error });
|
|
178
|
+
reject(error);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
reject(error);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
//
|
|
188
|
+
//
|
|
189
|
+
// Constants
|
|
190
|
+
//
|
|
191
|
+
const HEADER_AMZN_REQUEST_ID$1 = "x-amzn-request-id";
|
|
192
|
+
const ENV_AMZN_TRACE_ID = "_X_AMZN_TRACE_ID";
|
|
112
193
|
//
|
|
113
194
|
//
|
|
114
195
|
// Helper Functions
|
|
115
196
|
//
|
|
116
|
-
|
|
197
|
+
/**
|
|
198
|
+
* Extract request ID from X-Ray trace ID environment variable
|
|
199
|
+
* Format: Root=1-5e6b4a90-example;Parent=example;Sampled=1
|
|
200
|
+
* We extract the trace ID from the Root segment
|
|
201
|
+
*/
|
|
202
|
+
function parseTraceId(traceId) {
|
|
203
|
+
if (!traceId)
|
|
204
|
+
return undefined;
|
|
205
|
+
// Extract the Root segment (format: Root=1-{timestamp}-{uuid})
|
|
206
|
+
const rootMatch = traceId.match(/Root=([^;]+)/);
|
|
207
|
+
if (rootMatch && rootMatch[1]) {
|
|
208
|
+
return rootMatch[1];
|
|
209
|
+
}
|
|
210
|
+
return undefined;
|
|
211
|
+
}
|
|
212
|
+
//
|
|
213
|
+
//
|
|
214
|
+
// Main
|
|
215
|
+
//
|
|
216
|
+
/**
|
|
217
|
+
* Get the current invoke UUID from Lambda Web Adapter context.
|
|
218
|
+
* This function extracts the request ID from either:
|
|
219
|
+
* 1. The x-amzn-request-id header (set by Lambda Web Adapter)
|
|
220
|
+
* 2. The _X_AMZN_TRACE_ID environment variable (set by Lambda runtime)
|
|
221
|
+
*
|
|
222
|
+
* @param req - Optional Express request object to extract headers from
|
|
223
|
+
* @returns The AWS request ID or undefined if not in Lambda context
|
|
224
|
+
*/
|
|
225
|
+
function getWebAdapterUuid(req) {
|
|
226
|
+
// First, try to get from request headers
|
|
227
|
+
if (req && req.headers) {
|
|
228
|
+
const headerValue = req.headers[HEADER_AMZN_REQUEST_ID$1];
|
|
229
|
+
if (headerValue) {
|
|
230
|
+
return Array.isArray(headerValue) ? headerValue[0] : headerValue;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// Fall back to environment variable (X-Ray trace ID)
|
|
234
|
+
const traceId = process.env[ENV_AMZN_TRACE_ID];
|
|
235
|
+
if (traceId) {
|
|
236
|
+
return parseTraceId(traceId);
|
|
237
|
+
}
|
|
238
|
+
return undefined;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
//
|
|
242
|
+
//
|
|
243
|
+
// Constants
|
|
244
|
+
//
|
|
245
|
+
const HEADER_AMZN_REQUEST_ID = "x-amzn-request-id";
|
|
246
|
+
//
|
|
247
|
+
//
|
|
248
|
+
// Helper Functions
|
|
249
|
+
//
|
|
250
|
+
/**
|
|
251
|
+
* Detect if we're running in Lambda Web Adapter mode.
|
|
252
|
+
* Web Adapter sets the x-amzn-request-id header on requests.
|
|
253
|
+
*/
|
|
254
|
+
function isWebAdapterMode(req) {
|
|
255
|
+
if (req && req.headers && req.headers[HEADER_AMZN_REQUEST_ID]) {
|
|
256
|
+
return true;
|
|
257
|
+
}
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Adapter for the "@codegenie/serverless-express" uuid
|
|
262
|
+
*/
|
|
117
263
|
function getServerlessExpressUuid() {
|
|
118
264
|
const currentInvoke = serverlessExpress.getCurrentInvoke();
|
|
119
265
|
if (currentInvoke &&
|
|
@@ -127,7 +273,27 @@ function getServerlessExpressUuid() {
|
|
|
127
273
|
//
|
|
128
274
|
// Main
|
|
129
275
|
//
|
|
130
|
-
|
|
276
|
+
/**
|
|
277
|
+
* Get the current invoke UUID from Lambda context.
|
|
278
|
+
* Works in both serverless-express mode and Lambda Web Adapter mode.
|
|
279
|
+
*
|
|
280
|
+
* @param req - Optional Express request object. Required for Web Adapter mode
|
|
281
|
+
* to extract the x-amzn-request-id header.
|
|
282
|
+
* @returns The AWS request ID or undefined if not in Lambda context
|
|
283
|
+
*/
|
|
284
|
+
function getCurrentInvokeUuid(req) {
|
|
285
|
+
// If request is provided and has Web Adapter header, use Web Adapter mode
|
|
286
|
+
if (isWebAdapterMode(req)) {
|
|
287
|
+
return getWebAdapterUuid(req);
|
|
288
|
+
}
|
|
289
|
+
// Try serverless-express mode first
|
|
290
|
+
const serverlessExpressUuid = getServerlessExpressUuid();
|
|
291
|
+
if (serverlessExpressUuid) {
|
|
292
|
+
return serverlessExpressUuid;
|
|
293
|
+
}
|
|
294
|
+
// If no request but we might be in Web Adapter mode, try env var fallback
|
|
295
|
+
return getWebAdapterUuid();
|
|
296
|
+
}
|
|
131
297
|
|
|
132
298
|
//
|
|
133
299
|
//
|
|
@@ -289,7 +455,7 @@ function expressHandler(handlerOrOptions, optionsOrHandler) {
|
|
|
289
455
|
lib: kit.JAYPIE.LIB.EXPRESS,
|
|
290
456
|
});
|
|
291
457
|
// Update the public logger with the request ID
|
|
292
|
-
const invokeUuid = getCurrentInvokeUuid();
|
|
458
|
+
const invokeUuid = getCurrentInvokeUuid(req);
|
|
293
459
|
if (invokeUuid) {
|
|
294
460
|
logger$1.tag({ invoke: invokeUuid });
|
|
295
461
|
logger$1.tag({ shortInvoke: invokeUuid.slice(0, 8) });
|
|
@@ -611,7 +777,7 @@ function expressStreamHandler(handlerOrOptions, optionsOrHandler) {
|
|
|
611
777
|
lib: kit.JAYPIE.LIB.EXPRESS,
|
|
612
778
|
});
|
|
613
779
|
// Update the public logger with the request ID
|
|
614
|
-
const invokeUuid = getCurrentInvokeUuid();
|
|
780
|
+
const invokeUuid = getCurrentInvokeUuid(req);
|
|
615
781
|
if (invokeUuid) {
|
|
616
782
|
logger.tag({ invoke: invokeUuid });
|
|
617
783
|
logger.tag({ shortInvoke: invokeUuid.slice(0, 8) });
|
|
@@ -868,12 +1034,14 @@ const notImplementedRoute = routes.notImplementedRoute;
|
|
|
868
1034
|
|
|
869
1035
|
exports.EXPRESS = EXPRESS;
|
|
870
1036
|
exports.badRequestRoute = badRequestRoute;
|
|
871
|
-
exports.cors =
|
|
1037
|
+
exports.cors = cors;
|
|
1038
|
+
exports.createServer = createServer;
|
|
872
1039
|
exports.echoRoute = echoRoute;
|
|
873
1040
|
exports.expressHandler = expressHandler;
|
|
874
1041
|
exports.expressHttpCodeHandler = httpHandler;
|
|
875
1042
|
exports.expressStreamHandler = expressStreamHandler;
|
|
876
1043
|
exports.forbiddenRoute = forbiddenRoute;
|
|
1044
|
+
exports.getCurrentInvokeUuid = getCurrentInvokeUuid;
|
|
877
1045
|
exports.goneRoute = goneRoute;
|
|
878
1046
|
exports.methodNotAllowedRoute = methodNotAllowedRoute;
|
|
879
1047
|
exports.noContentRoute = noContentRoute;
|