@jaypie/mcp 0.3.2 โ†’ 0.4.0

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.
Files changed (79) hide show
  1. package/dist/createMcpServer.d.ts +7 -1
  2. package/dist/index.js +26 -3135
  3. package/dist/index.js.map +1 -1
  4. package/dist/suite.d.ts +1 -0
  5. package/dist/suite.js +2442 -0
  6. package/dist/suite.js.map +1 -0
  7. package/package.json +8 -3
  8. package/release-notes/constructs/1.2.17.md +11 -0
  9. package/release-notes/fabric/0.1.2.md +11 -0
  10. package/release-notes/fabric/0.1.3.md +25 -0
  11. package/release-notes/fabric/0.1.4.md +42 -0
  12. package/release-notes/mcp/0.3.3.md +12 -0
  13. package/release-notes/mcp/0.3.4.md +36 -0
  14. package/release-notes/mcp/0.4.0.md +27 -0
  15. package/release-notes/testkit/1.2.15.md +23 -0
  16. package/skills/agents.md +25 -0
  17. package/skills/aws.md +107 -0
  18. package/skills/cdk.md +141 -0
  19. package/skills/cicd.md +152 -0
  20. package/skills/datadog.md +129 -0
  21. package/skills/debugging.md +148 -0
  22. package/skills/dns.md +134 -0
  23. package/skills/dynamodb.md +140 -0
  24. package/skills/errors.md +142 -0
  25. package/skills/fabric.md +191 -0
  26. package/skills/index.md +7 -0
  27. package/skills/jaypie.md +100 -0
  28. package/skills/legacy.md +97 -0
  29. package/skills/logs.md +160 -0
  30. package/skills/mocks.md +174 -0
  31. package/skills/models.md +195 -0
  32. package/skills/releasenotes.md +94 -0
  33. package/skills/secrets.md +155 -0
  34. package/skills/services.md +175 -0
  35. package/skills/style.md +190 -0
  36. package/skills/tests.md +209 -0
  37. package/skills/tools.md +127 -0
  38. package/skills/topics.md +116 -0
  39. package/skills/variables.md +146 -0
  40. package/skills/writing.md +153 -0
  41. package/prompts/Branch_Management.md +0 -34
  42. package/prompts/Development_Process.md +0 -89
  43. package/prompts/Jaypie_Agent_Rules.md +0 -110
  44. package/prompts/Jaypie_Auth0_Express_Mongoose.md +0 -736
  45. package/prompts/Jaypie_Browser_and_Frontend_Web_Packages.md +0 -18
  46. package/prompts/Jaypie_CDK_Constructs_and_Patterns.md +0 -430
  47. package/prompts/Jaypie_CICD_with_GitHub_Actions.md +0 -371
  48. package/prompts/Jaypie_Commander_CLI_Package.md +0 -166
  49. package/prompts/Jaypie_Core_Errors_and_Logging.md +0 -39
  50. package/prompts/Jaypie_DynamoDB_Package.md +0 -774
  51. package/prompts/Jaypie_Eslint_NPM_Package.md +0 -78
  52. package/prompts/Jaypie_Express_Package.md +0 -630
  53. package/prompts/Jaypie_Fabric_Commander.md +0 -411
  54. package/prompts/Jaypie_Fabric_LLM.md +0 -312
  55. package/prompts/Jaypie_Fabric_Lambda.md +0 -308
  56. package/prompts/Jaypie_Fabric_MCP.md +0 -316
  57. package/prompts/Jaypie_Fabric_Package.md +0 -513
  58. package/prompts/Jaypie_Fabricator.md +0 -617
  59. package/prompts/Jaypie_Ideal_Project_Structure.md +0 -78
  60. package/prompts/Jaypie_Init_CICD_with_GitHub_Actions.md +0 -1186
  61. package/prompts/Jaypie_Init_Express_on_Lambda.md +0 -115
  62. package/prompts/Jaypie_Init_Jaypie_CDK_Package.md +0 -35
  63. package/prompts/Jaypie_Init_Lambda_Package.md +0 -505
  64. package/prompts/Jaypie_Init_Monorepo_Project.md +0 -44
  65. package/prompts/Jaypie_Init_Project_Subpackage.md +0 -65
  66. package/prompts/Jaypie_Legacy_Patterns.md +0 -15
  67. package/prompts/Jaypie_Llm_Calls.md +0 -449
  68. package/prompts/Jaypie_Llm_Tools.md +0 -155
  69. package/prompts/Jaypie_MCP_Package.md +0 -281
  70. package/prompts/Jaypie_Mocks_and_Testkit.md +0 -137
  71. package/prompts/Jaypie_Repokit.md +0 -103
  72. package/prompts/Jaypie_Scrub.md +0 -177
  73. package/prompts/Jaypie_Streaming.md +0 -467
  74. package/prompts/Templates_CDK_Subpackage.md +0 -115
  75. package/prompts/Templates_Express_Subpackage.md +0 -187
  76. package/prompts/Templates_Project_Monorepo.md +0 -326
  77. package/prompts/Templates_Project_Subpackage.md +0 -93
  78. package/prompts/Write_Efficient_Prompt_Guides.md +0 -48
  79. package/prompts/Write_and_Maintain_Engaging_Readme.md +0 -67
@@ -1,78 +0,0 @@
1
- ---
2
- description: coding style resource, helpful when stuck on lint errors
3
- ---
4
-
5
- # Jaypie Eslint ๐Ÿฆโ€โฌ›๐Ÿงน
6
-
7
- Linting rules for Jaypie project coding style, Prettier, and bespoke rules.
8
-
9
- ## ๐ŸŽฏ Goals
10
-
11
- * Opinionated "umbrella" config for common projects using Jaypie
12
- * Strengthen rules that prevent mistakes
13
- * Loosen rules that slow down development
14
- * Use warn for things that will not break (console, prettier)
15
-
16
- Tries to "just work" but sometimes conflicts with opinionated project linters like nuxt.
17
-
18
- ## ๐Ÿ”‹ Capabilities
19
-
20
- * `@eslint/js` recommended
21
- * `eslint-plugin-import-x` recommended
22
- * Ignore cdk, dist
23
- * Language options; assume module
24
- * Custom rules
25
- * CommonJS for .cjs
26
- * Ignore Nuxt
27
- * Prettier
28
- * TypeScript for .ts
29
- * Tests
30
- * Prettier-Vue for .vue
31
-
32
- ## ๐Ÿ’ฟ Installation
33
-
34
- ```sh
35
- npm install --save-dev @jaypie/eslint
36
- ```
37
-
38
- ## ๐Ÿ“‹ Usage
39
-
40
- ```javascript
41
- // eslint.config.js
42
- export { default as default } from "@jaypie/eslint";
43
- ```
44
-
45
- ### With Nuxt
46
-
47
- ```javascript
48
- // @ts-check
49
- import jaypie from "@jaypie/eslint/nuxt";
50
- import { withNuxt } from "./.nuxt/eslint.config.mjs";
51
-
52
- export default withNuxt(...jaypie, {
53
- languageOptions: {
54
- globals: {
55
- defineNuxtConfig: "readonly",
56
- },
57
- },
58
- rules: {
59
- "@typescript-eslint/no-explicit-any": "off",
60
- },
61
- });
62
- ```
63
-
64
- ### In CommonJS
65
-
66
- ```javascript
67
- export { default as default } from "@jaypie/commonjs";
68
- ```
69
-
70
- ### Other Configs
71
-
72
- ```javascript
73
- import jaypie from "@jaypie/eslint";
74
- export default [
75
- ...jaypie
76
- // More configuration
77
- ];
78
- ```
@@ -1,630 +0,0 @@
1
- ---
2
- description: Complete guide to using Jaypie Express features including expressHandler, CORS, lifecycle hooks, and pre-built routes
3
- globs: packages/express/**
4
- ---
5
-
6
- # Jaypie Express Package
7
-
8
- Jaypie provides Express utilities through `@jaypie/express` (also available via `jaypie`). The main export is `expressHandler`, a function that wraps Express route handlers to add error handling, logging, lifecycle hooks, and automatic response formatting.
9
-
10
- ## Installation
11
-
12
- ```bash
13
- npm install jaypie
14
- # or
15
- npm install @jaypie/express
16
- ```
17
-
18
- ## expressHandler
19
-
20
- Wraps Express route handlers with error handling, logging, and lifecycle management.
21
-
22
- ### Basic Usage
23
-
24
- ```typescript
25
- import { expressHandler } from "jaypie";
26
- import type { Request, Response } from "express";
27
-
28
- const myRoute = expressHandler(async (req: Request, res: Response) => {
29
- return { message: "Hello, World!" };
30
- });
31
-
32
- // Use in Express
33
- app.get("/hello", myRoute);
34
- ```
35
-
36
- ### Return Value Handling
37
-
38
- expressHandler automatically formats responses based on return values:
39
-
40
- | Return Value | HTTP Status | Response |
41
- |--------------|-------------|----------|
42
- | Object | 200 | JSON body |
43
- | Array | 200 | JSON body |
44
- | String (JSON) | 200 | Parsed JSON |
45
- | String (other) | 200 | Text body |
46
- | Number | 200 | Sent via `res.send()` |
47
- | `true` | 201 Created | Empty |
48
- | `null`, `undefined`, `false` | 204 No Content | Empty |
49
- | Object with `.json()` method | 200 | Result of `.json()` |
50
-
51
- **Note:** If you call `res.json()`, `res.send()`, or `res.end()` directly in your handler, expressHandler will log a warning but respect your call. Prefer using return values instead.
52
-
53
- ### Options
54
-
55
- ```typescript
56
- import { expressHandler } from "jaypie";
57
- import type { ExpressHandlerOptions } from "jaypie";
58
-
59
- const options: ExpressHandlerOptions = {
60
- name: "myHandler", // Handler name for logging
61
- chaos: "low", // Chaos testing level
62
- unavailable: false, // Return 503 if true
63
- setup: [], // Setup function(s)
64
- teardown: [], // Teardown function(s)
65
- validate: [], // Validation function(s)
66
- locals: {}, // Values to set on req.locals
67
- };
68
-
69
- const handler = expressHandler(async (req, res) => {
70
- return { success: true };
71
- }, options);
72
-
73
- // Alternative: options first
74
- const handler2 = expressHandler(options, async (req, res) => {
75
- return { success: true };
76
- });
77
- ```
78
-
79
- ## Lifecycle Hooks
80
-
81
- Lifecycle hooks execute in this order:
82
- 1. Setup functions (in array order)
83
- 2. Locals functions (in object key order, after all setup)
84
- 3. Validate functions (in array order)
85
- 4. Main handler
86
- 5. Teardown functions (always run, even on error)
87
-
88
- ### Setup Functions
89
-
90
- Run before validation and the main handler. Use for initialization, authentication checks, or setting up request context.
91
-
92
- ```typescript
93
- import { expressHandler } from "jaypie";
94
- import type { JaypieHandlerSetup } from "jaypie";
95
-
96
- const authenticateUser: JaypieHandlerSetup = async (req, res) => {
97
- const token = req.headers.authorization;
98
- // Validate token, throw UnauthorizedError if invalid
99
- };
100
-
101
- const loadTenant: JaypieHandlerSetup = async (req, res) => {
102
- req.locals.tenant = await getTenant(req.params.tenantId);
103
- };
104
-
105
- const handler = expressHandler(
106
- async (req, res) => {
107
- // req.locals.tenant is available here
108
- return { tenant: req.locals.tenant };
109
- },
110
- {
111
- setup: [authenticateUser, loadTenant],
112
- }
113
- );
114
- ```
115
-
116
- ### Teardown Functions
117
-
118
- Run after the main handler completes. Teardown functions execute regardless of success or error, making them suitable for cleanup operations.
119
-
120
- ```typescript
121
- import type { JaypieHandlerTeardown } from "jaypie";
122
-
123
- const closeConnection: JaypieHandlerTeardown = async (req, res) => {
124
- await req.locals.dbConnection?.close();
125
- };
126
-
127
- const handler = expressHandler(
128
- async (req, res) => {
129
- req.locals.dbConnection = await openConnection();
130
- return await doWork(req.locals.dbConnection);
131
- },
132
- {
133
- teardown: closeConnection,
134
- }
135
- );
136
- ```
137
-
138
- ### Validation Functions
139
-
140
- Run before the main handler. Return `true` to continue or `false`/throw to reject.
141
-
142
- ```typescript
143
- import { ForbiddenError } from "jaypie";
144
- import type { JaypieHandlerValidate } from "jaypie";
145
-
146
- const requireAdmin: JaypieHandlerValidate = (req, res) => {
147
- if (!req.locals.user?.isAdmin) {
148
- throw new ForbiddenError();
149
- }
150
- return true;
151
- };
152
-
153
- const validateBody: JaypieHandlerValidate = (req, res) => {
154
- return req.body?.email && req.body?.name;
155
- };
156
-
157
- const handler = expressHandler(
158
- async (req, res) => {
159
- // Only runs if user is admin and body is valid
160
- return { success: true };
161
- },
162
- {
163
- validate: [requireAdmin, validateBody],
164
- }
165
- );
166
- ```
167
-
168
- ### Locals
169
-
170
- Set values on `req.locals`. Values can be static or functions that receive `(req, res)`. Locals functions are called AFTER setup functions.
171
-
172
- ```typescript
173
- import type { ExpressHandlerLocals } from "jaypie";
174
-
175
- const getUser: ExpressHandlerLocals = async (req, res) => {
176
- return await User.findById(req.params.userId);
177
- };
178
-
179
- const handler = expressHandler(
180
- async (req, res) => {
181
- // Access via req.locals
182
- console.log(req.locals.apiVersion); // "v1"
183
- console.log(req.locals.user); // User object
184
- return req.locals.user;
185
- },
186
- {
187
- locals: {
188
- apiVersion: "v1", // Static value
189
- user: getUser, // Function called after setup
190
- },
191
- }
192
- );
193
- ```
194
-
195
- ## CORS Helper
196
-
197
- Configures CORS middleware using the `cors` npm package with automatic origin validation.
198
-
199
- ```typescript
200
- import { cors } from "jaypie";
201
- import type { CorsConfig } from "jaypie";
202
-
203
- // Default: uses BASE_URL or PROJECT_BASE_URL env vars
204
- app.use(cors());
205
-
206
- // Wildcard origin
207
- app.use(cors({ origin: "*" }));
208
-
209
- // Specific origin
210
- app.use(cors({ origin: "https://example.com" }));
211
-
212
- // Multiple origins
213
- app.use(cors({ origin: ["https://example.com", "https://app.example.com"] }));
214
-
215
- // Custom configuration
216
- const corsConfig: CorsConfig = {
217
- origin: "https://api.example.com",
218
- overrides: {
219
- // Additional options passed to the cors package
220
- credentials: true,
221
- },
222
- };
223
- app.use(cors(corsConfig));
224
- ```
225
-
226
- Environment variables:
227
- - `BASE_URL` or `PROJECT_BASE_URL`: Default allowed origins
228
- - `PROJECT_ENV=sandbox` or `PROJECT_SANDBOX_MODE=true`: Allows localhost origins (including ports)
229
-
230
- ## Pre-built Routes
231
-
232
- Ready-to-use route handlers for common responses.
233
-
234
- ```typescript
235
- import {
236
- badRequestRoute, // 400 Bad Request
237
- echoRoute, // 200 with request echo
238
- forbiddenRoute, // 403 Forbidden
239
- goneRoute, // 410 Gone
240
- methodNotAllowedRoute, // 405 Method Not Allowed
241
- noContentRoute, // 204 No Content
242
- notFoundRoute, // 404 Not Found
243
- notImplementedRoute, // 501 Not Implemented
244
- } from "jaypie";
245
-
246
- // Use as catch-all or placeholder routes
247
- app.all("/deprecated/*", goneRoute);
248
- app.use("*", notFoundRoute);
249
-
250
- // Echo route for debugging
251
- app.get("/debug/echo", echoRoute);
252
- ```
253
-
254
- ## HTTP Code Handler
255
-
256
- Create custom HTTP status code handlers.
257
-
258
- ```typescript
259
- import { expressHttpCodeHandler, HTTP } from "jaypie";
260
-
261
- // Returns 200 OK with empty body
262
- const okRoute = expressHttpCodeHandler(HTTP.CODE.OK);
263
-
264
- // Returns 202 Accepted
265
- const acceptedRoute = expressHttpCodeHandler(202, { name: "accepted" });
266
-
267
- app.post("/jobs", acceptedRoute);
268
- ```
269
-
270
- ## Error Handling
271
-
272
- Throw Jaypie errors for proper HTTP responses.
273
-
274
- ```typescript
275
- import {
276
- expressHandler,
277
- BadRequestError,
278
- NotFoundError,
279
- UnauthorizedError,
280
- ForbiddenError,
281
- InternalError,
282
- log,
283
- } from "jaypie";
284
-
285
- const handler = expressHandler(async (req, res) => {
286
- const item = await findItem(req.params.id);
287
-
288
- if (!item) {
289
- log.warn("Item not found");
290
- throw new NotFoundError();
291
- }
292
-
293
- if (!canAccess(req.user, item)) {
294
- throw new ForbiddenError();
295
- }
296
-
297
- return item;
298
- });
299
- ```
300
-
301
- Errors return JSON:API compliant error responses:
302
-
303
- ```json
304
- {
305
- "errors": [{
306
- "status": 404,
307
- "title": "Not Found",
308
- "detail": "The requested resource was not found"
309
- }]
310
- }
311
- ```
312
-
313
- ## TypeScript Types
314
-
315
- All lifecycle function types are exported for type safety:
316
-
317
- ```typescript
318
- import type {
319
- ExpressHandlerOptions,
320
- ExpressHandlerLocals,
321
- JaypieHandlerSetup,
322
- JaypieHandlerTeardown,
323
- JaypieHandlerValidate,
324
- CorsConfig,
325
- } from "jaypie";
326
- ```
327
-
328
- ## Complete Example
329
-
330
- ```typescript
331
- import express from "express";
332
- import {
333
- cors,
334
- expressHandler,
335
- notFoundRoute,
336
- NotFoundError,
337
- ForbiddenError,
338
- UnauthorizedError,
339
- log,
340
- } from "jaypie";
341
- import type {
342
- JaypieHandlerSetup,
343
- JaypieHandlerValidate,
344
- ExpressHandlerLocals,
345
- } from "jaypie";
346
-
347
- const app = express();
348
- app.use(express.json());
349
- app.use(cors());
350
-
351
- // Lifecycle functions
352
- const authenticate: JaypieHandlerSetup = async (req, res) => {
353
- const token = req.headers.authorization?.replace("Bearer ", "");
354
- if (!token) throw new UnauthorizedError();
355
- req.locals.user = await verifyToken(token);
356
- };
357
-
358
- const requireOwner: JaypieHandlerValidate = (req, res) => {
359
- return req.locals.resource?.ownerId === req.locals.user?.id;
360
- };
361
-
362
- const loadResource: ExpressHandlerLocals = async (req, res) => {
363
- const resource = await Resource.findById(req.params.id);
364
- if (!resource) throw new NotFoundError();
365
- return resource;
366
- };
367
-
368
- // Route handler
369
- const updateResource = expressHandler(
370
- async (req, res) => {
371
- const { resource, user } = req.locals;
372
-
373
- resource.name = req.body.name;
374
- resource.updatedBy = user.id;
375
- await resource.save();
376
-
377
- log.trace("Resource updated");
378
- return resource;
379
- },
380
- {
381
- name: "updateResource",
382
- setup: authenticate,
383
- validate: requireOwner,
384
- locals: {
385
- resource: loadResource,
386
- },
387
- }
388
- );
389
-
390
- app.put("/resources/:id", updateResource);
391
- app.use("*", notFoundRoute);
392
-
393
- export default app;
394
- ```
395
-
396
- ## Response Headers
397
-
398
- expressHandler automatically sets these headers:
399
- - `X-Powered-By: @jaypie/express` (always set, overrides Express default)
400
- - `X-Project-Handler: {name}` (when name option is provided)
401
- - `X-Project-Invocation: {uuid}` (request tracking ID, always set)
402
- - `X-Project-Environment: {env}` (when PROJECT_ENV is set)
403
- - `X-Project-Key: {key}` (when PROJECT_KEY is set)
404
- - `X-Project-Version: {version}` (when PROJECT_VERSION is set or version option provided)
405
-
406
- ## Datadog Integration
407
-
408
- When Datadog environment variables are configured, expressHandler automatically submits metrics for each request including status code and path.
409
-
410
- ## Streaming Responses
411
-
412
- Use `expressStreamHandler` for Server-Sent Events (SSE) streaming responses. Ideal for real-time updates, LLM streaming, and long-running operations.
413
-
414
- ### Basic Streaming Usage
415
-
416
- ```typescript
417
- import { expressStreamHandler } from "jaypie";
418
- import type { Request, Response } from "express";
419
-
420
- const streamRoute = expressStreamHandler(async (req: Request, res: Response) => {
421
- // Write SSE events directly to response
422
- res.write("event: message\ndata: {\"text\": \"Hello\"}\n\n");
423
- res.write("event: message\ndata: {\"text\": \"World\"}\n\n");
424
- // Handler automatically ends the stream
425
- });
426
-
427
- app.get("/stream", streamRoute);
428
- ```
429
-
430
- ### Streaming with LLM
431
-
432
- ```typescript
433
- import { expressStreamHandler, Llm, createExpressStream } from "jaypie";
434
-
435
- const llmStreamRoute = expressStreamHandler(async (req: Request, res: Response) => {
436
- const llm = new Llm("anthropic");
437
- const stream = llm.stream(req.body.prompt);
438
-
439
- // createExpressStream pipes LLM chunks as SSE events
440
- await createExpressStream(stream, res);
441
- });
442
-
443
- app.post("/chat", llmStreamRoute);
444
- ```
445
-
446
- ### Stream Handler Options
447
-
448
- `expressStreamHandler` supports the same lifecycle options as `expressHandler`:
449
-
450
- ```typescript
451
- import { expressStreamHandler } from "jaypie";
452
- import type { ExpressStreamHandlerOptions } from "jaypie";
453
-
454
- const options: ExpressStreamHandlerOptions = {
455
- name: "myStreamHandler", // Handler name for logging
456
- contentType: "text/event-stream", // Default SSE content type
457
- chaos: "low", // Chaos testing level
458
- secrets: ["API_KEY"], // Secrets to load
459
- setup: [], // Setup function(s)
460
- teardown: [], // Teardown function(s)
461
- validate: [], // Validation function(s)
462
- locals: {}, // Values to set on req.locals
463
- unavailable: false, // Return 503 if true
464
- };
465
-
466
- const handler = expressStreamHandler(async (req, res) => {
467
- // Streaming logic
468
- }, options);
469
- ```
470
-
471
- ### SSE Headers
472
-
473
- `expressStreamHandler` automatically sets SSE headers:
474
- - `Content-Type: text/event-stream`
475
- - `Cache-Control: no-cache`
476
- - `Connection: keep-alive`
477
- - `X-Accel-Buffering: no` (disables nginx buffering)
478
-
479
- ### Error Handling in Streams
480
-
481
- Errors are formatted as SSE error events:
482
-
483
- ```typescript
484
- // Jaypie errors and unhandled errors are written as:
485
- // event: error
486
- // data: {"errors":[{"status":500,"title":"Internal Error"}]}
487
- ```
488
-
489
- ### TypeScript Types
490
-
491
- ```typescript
492
- import type {
493
- ExpressStreamHandlerOptions,
494
- ExpressStreamHandlerLocals,
495
- JaypieStreamHandlerSetup,
496
- JaypieStreamHandlerTeardown,
497
- JaypieStreamHandlerValidate,
498
- } from "jaypie";
499
- ```
500
-
501
- ## Lambda Handlers
502
-
503
- Create Lambda handlers from Express apps using `createLambdaHandler` and `createLambdaStreamHandler`. These functions wrap Express applications to run directly on AWS Lambda Function URLs without requiring a separate Lambda adapter library.
504
-
505
- ### Buffered Handler
506
-
507
- Use `createLambdaHandler` for standard Lambda responses where the entire response is buffered before sending.
508
-
509
- ```typescript
510
- import express from "express";
511
- import { createLambdaHandler, expressHandler } from "jaypie";
512
-
513
- const app = express();
514
-
515
- app.get("/", expressHandler(async (req, res) => {
516
- return { message: "Hello from Lambda!" };
517
- }));
518
-
519
- // Export for Lambda Function URL
520
- export const handler = createLambdaHandler(app);
521
- ```
522
-
523
- ### Streaming Handler
524
-
525
- Use `createLambdaStreamHandler` for Lambda response streaming, ideal for Server-Sent Events (SSE) and real-time updates.
526
-
527
- ```typescript
528
- import express from "express";
529
- import { createLambdaStreamHandler, expressStreamHandler } from "jaypie";
530
-
531
- const app = express();
532
-
533
- app.get("/stream", expressStreamHandler(async (req, res) => {
534
- res.write("event: message\ndata: {\"text\": \"Hello\"}\n\n");
535
- res.write("event: message\ndata: {\"text\": \"World\"}\n\n");
536
- }));
537
-
538
- // Export for Lambda Function URL with streaming
539
- export const handler = createLambdaStreamHandler(app);
540
- ```
541
-
542
- ### Combined Usage
543
-
544
- A typical Lambda Express application with both buffered and streaming endpoints:
545
-
546
- ```typescript
547
- import express from "express";
548
- import {
549
- createLambdaHandler,
550
- createLambdaStreamHandler,
551
- expressHandler,
552
- expressStreamHandler,
553
- cors,
554
- } from "jaypie";
555
-
556
- const app = express();
557
- app.use(express.json());
558
- app.use(cors());
559
-
560
- // Standard buffered route
561
- app.get("/api/data", expressHandler(async (req, res) => {
562
- return { data: "buffered response" };
563
- }));
564
-
565
- // SSE streaming route
566
- app.get("/api/stream", expressStreamHandler(async (req, res) => {
567
- for (let i = 0; i < 5; i++) {
568
- res.write(`event: update\ndata: {"count": ${i}}\n\n`);
569
- }
570
- }));
571
-
572
- // Choose handler based on your needs
573
- // For buffered: export const handler = createLambdaHandler(app);
574
- // For streaming: export const handler = createLambdaStreamHandler(app);
575
- export const handler = createLambdaHandler(app);
576
- ```
577
-
578
- ### Lambda Context Access
579
-
580
- Both handlers expose Lambda context on the request object:
581
-
582
- ```typescript
583
- app.get("/", expressHandler(async (req, res) => {
584
- // Access Lambda context directly on request
585
- const awsRequestId = (req as any)._lambdaContext?.awsRequestId;
586
- return { requestId: awsRequestId };
587
- }));
588
- ```
589
-
590
- ### TypeScript Types
591
-
592
- ```typescript
593
- import type {
594
- LambdaHandler,
595
- LambdaStreamHandler,
596
- LambdaContext,
597
- FunctionUrlEvent,
598
- LambdaResponse,
599
- } from "jaypie";
600
- ```
601
-
602
- ## Invoke UUID Detection
603
-
604
- Use `getCurrentInvokeUuid` to get the current request ID. Automatically detects the environment (Lambda, Lambda Web Adapter, or local development).
605
-
606
- ### Basic Usage
607
-
608
- ```typescript
609
- import { getCurrentInvokeUuid } from "jaypie";
610
-
611
- const handler = expressHandler(async (req, res) => {
612
- const invokeUuid = getCurrentInvokeUuid(req);
613
- // Returns AWS request ID in Lambda, or generates a local UUID
614
- return { requestId: invokeUuid };
615
- });
616
- ```
617
-
618
- ### Environment Detection
619
-
620
- The function adapts to different runtime environments:
621
-
622
- 1. **Lambda (native)**: Uses `awsRequestId` from Lambda context
623
- 2. **Lambda Web Adapter**: Extracts from `x-amzn-request-id` header or `_X_AMZN_TRACE_ID` env var
624
- 3. **Local development**: Generates a UUID for consistent tracing
625
-
626
- ### Lambda Web Adapter Headers
627
-
628
- When running Express behind AWS Lambda Web Adapter, the function extracts the request ID from:
629
- - `x-amzn-request-id` header (set by Lambda Web Adapter)
630
- - `_X_AMZN_TRACE_ID` environment variable (X-Ray trace ID, set by Lambda runtime)