@jaypie/mcp 0.2.10 → 0.2.12
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/index.js +1 -1
- package/package.json +1 -1
- package/prompts/Jaypie_CDK_Constructs_and_Patterns.md +23 -28
- package/prompts/Jaypie_DynamoDB_Package.md +55 -55
- package/prompts/Jaypie_Express_Package.md +0 -44
- package/prompts/{Jaypie_Vocabulary_Commander.md → Jaypie_Fabric_Commander.md} +38 -38
- package/prompts/{Jaypie_Vocabulary_LLM.md → Jaypie_Fabric_LLM.md} +45 -45
- package/prompts/{Jaypie_Vocabulary_Lambda.md → Jaypie_Fabric_Lambda.md} +40 -42
- package/prompts/{Jaypie_Vocabulary_MCP.md → Jaypie_Fabric_MCP.md} +39 -39
- package/prompts/{Jaypie_Vocabulary_Package.md → Jaypie_Fabric_Package.md} +151 -142
- package/prompts/Jaypie_Init_CICD_with_GitHub_Actions.md +12 -12
- package/prompts/Jaypie_Streaming.md +408 -0
package/dist/index.js
CHANGED
|
@@ -885,7 +885,7 @@ function listLlmProviders() {
|
|
|
885
885
|
};
|
|
886
886
|
}
|
|
887
887
|
|
|
888
|
-
const BUILD_VERSION_STRING = "@jaypie/mcp@0.2.
|
|
888
|
+
const BUILD_VERSION_STRING = "@jaypie/mcp@0.2.12#512ddebf"
|
|
889
889
|
;
|
|
890
890
|
const __filename$1 = fileURLToPath(import.meta.url);
|
|
891
891
|
const __dirname$1 = path.dirname(__filename$1);
|
package/package.json
CHANGED
|
@@ -102,33 +102,27 @@ Preconfigured with API-optimized timeouts and role tags.
|
|
|
102
102
|
|
|
103
103
|
### Streaming Lambda Functions
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
For streaming responses (SSE, real-time updates), use `createLambdaStreamHandler` from `@jaypie/express` with `JaypieDistribution`:
|
|
106
106
|
|
|
107
107
|
```typescript
|
|
108
|
-
import {
|
|
108
|
+
import { JaypieExpressLambda, JaypieDistribution } from "@jaypie/constructs";
|
|
109
|
+
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
109
110
|
|
|
110
|
-
// Create
|
|
111
|
-
const
|
|
111
|
+
// Create Lambda (handler uses createLambdaStreamHandler internally)
|
|
112
|
+
const streamingApi = new JaypieExpressLambda(this, "StreamingApi", {
|
|
112
113
|
code: "dist/api",
|
|
113
|
-
handler: "
|
|
114
|
-
streaming: true, // Enables RESPONSE_STREAM invoke mode
|
|
115
|
-
port: 8000, // Port your app listens on (default: 8000)
|
|
114
|
+
handler: "index.handler",
|
|
116
115
|
});
|
|
117
116
|
|
|
118
|
-
// CloudFront
|
|
117
|
+
// Use with CloudFront and RESPONSE_STREAM invoke mode
|
|
119
118
|
new JaypieDistribution(this, "Distribution", {
|
|
120
|
-
handler:
|
|
119
|
+
handler: streamingApi,
|
|
120
|
+
invokeMode: lambda.InvokeMode.RESPONSE_STREAM,
|
|
121
121
|
host: "api.example.com",
|
|
122
122
|
zone: "example.com",
|
|
123
123
|
});
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
-
Features:
|
|
127
|
-
- Automatically adds AWS Lambda Web Adapter layer (supports ARM64 and x86_64)
|
|
128
|
-
- Sets `AWS_LAMBDA_EXEC_WRAPPER` and `AWS_LWA_INVOKE_MODE` environment variables
|
|
129
|
-
- Exposes `invokeMode` property for auto-detection by `JaypieDistribution`
|
|
130
|
-
- Use `streaming: false` for buffered mode (traditional Lambda behavior)
|
|
131
|
-
|
|
132
126
|
For direct Function URL access (bypass CloudFront):
|
|
133
127
|
```typescript
|
|
134
128
|
import { FunctionUrlAuthType, InvokeMode } from "aws-cdk-lib/aws-lambda";
|
|
@@ -147,7 +141,7 @@ const functionUrl = streamingLambda.addFunctionUrl({
|
|
|
147
141
|
new cdk.CfnOutput(this, "StreamingUrl", { value: functionUrl.url });
|
|
148
142
|
```
|
|
149
143
|
|
|
150
|
-
Note:
|
|
144
|
+
Note: Streaming requires Lambda Function URLs (not API Gateway). `JaypieDistribution` uses Function URLs by default.
|
|
151
145
|
|
|
152
146
|
### Stack Types
|
|
153
147
|
|
|
@@ -323,21 +317,22 @@ Common usage:
|
|
|
323
317
|
|
|
324
318
|
### DynamoDB Tables
|
|
325
319
|
|
|
326
|
-
Use `JaypieDynamoDb` for single-table design with Jaypie
|
|
320
|
+
Use `JaypieDynamoDb` for single-table design with Jaypie patterns:
|
|
327
321
|
```typescript
|
|
328
322
|
// Shorthand: tableName becomes "myApp", construct id is "JaypieDynamoDb-myApp"
|
|
329
323
|
const table = new JaypieDynamoDb(this, "myApp");
|
|
330
324
|
|
|
331
|
-
//
|
|
332
|
-
const
|
|
333
|
-
|
|
325
|
+
// With standard Jaypie GSIs (indexScope, indexAlias, indexClass, indexType, indexXid)
|
|
326
|
+
const tableWithIndexes = new JaypieDynamoDb(this, "myApp", {
|
|
327
|
+
indexes: JaypieDynamoDb.DEFAULT_INDEXES,
|
|
334
328
|
});
|
|
335
329
|
|
|
336
|
-
//
|
|
337
|
-
const
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
330
|
+
// With custom indexes using IndexDefinition from @jaypie/fabric
|
|
331
|
+
const customTable = new JaypieDynamoDb(this, "myApp", {
|
|
332
|
+
indexes: [
|
|
333
|
+
{ pk: ["scope", "model"], sk: ["sequence"] }, // indexScopeModel
|
|
334
|
+
{ pk: ["scope", "model", "type"], sparse: true }, // indexScopeModelType
|
|
335
|
+
{ name: "byAlias", pk: ["alias"], sk: ["createdAt"] }, // custom name
|
|
341
336
|
],
|
|
342
337
|
});
|
|
343
338
|
|
|
@@ -352,9 +347,9 @@ Features:
|
|
|
352
347
|
- Default partition key: `model` (string), sort key: `id` (string)
|
|
353
348
|
- PAY_PER_REQUEST billing mode by default
|
|
354
349
|
- RETAIN removal policy in production, DESTROY otherwise
|
|
355
|
-
-
|
|
356
|
-
-
|
|
357
|
-
-
|
|
350
|
+
- No GSIs by default - use `indexes` prop to add them
|
|
351
|
+
- `JaypieDynamoDb.DEFAULT_INDEXES` provides standard Jaypie GSIs from `@jaypie/fabric`
|
|
352
|
+
- Uses `IndexDefinition` from `@jaypie/fabric` for GSI configuration
|
|
358
353
|
- Implements `ITableV2` interface
|
|
359
354
|
|
|
360
355
|
For single-table design patterns, key builders, and query utilities, see `Jaypie_DynamoDB_Package.md`.
|
|
@@ -21,21 +21,21 @@ All entities share a single DynamoDB table with:
|
|
|
21
21
|
- **Primary Key**: `model` (partition) + `id` (sort)
|
|
22
22
|
- **Five GSIs**: All use `sequence` as sort key for chronological ordering
|
|
23
23
|
|
|
24
|
-
###
|
|
24
|
+
### Scope
|
|
25
25
|
|
|
26
|
-
The `
|
|
27
|
-
- Root entities: `
|
|
28
|
-
- Child entities: `
|
|
26
|
+
The `scope` field creates hierarchical relationships:
|
|
27
|
+
- Root entities: `scope = "@"` (APEX constant)
|
|
28
|
+
- Child entities: `scope = "{parent.model}#{parent.id}"`
|
|
29
29
|
|
|
30
30
|
### GSI Pattern
|
|
31
31
|
|
|
32
32
|
| GSI Name | Partition Key | Use Case |
|
|
33
33
|
|----------|---------------|----------|
|
|
34
|
-
| `
|
|
35
|
-
| `indexAlias` | `{
|
|
36
|
-
| `indexClass` | `{
|
|
37
|
-
| `indexType` | `{
|
|
38
|
-
| `indexXid` | `{
|
|
34
|
+
| `indexScope` | `{scope}#{model}` | List all entities under a parent |
|
|
35
|
+
| `indexAlias` | `{scope}#{model}#{alias}` | Human-friendly slug lookup |
|
|
36
|
+
| `indexClass` | `{scope}#{model}#{class}` | Category filtering |
|
|
37
|
+
| `indexType` | `{scope}#{model}#{type}` | Type filtering |
|
|
38
|
+
| `indexXid` | `{scope}#{model}#{xid}` | External system ID lookup |
|
|
39
39
|
|
|
40
40
|
## Client Initialization
|
|
41
41
|
|
|
@@ -75,7 +75,7 @@ interface MyRecord extends StorableEntity {
|
|
|
75
75
|
|
|
76
76
|
// Required fields
|
|
77
77
|
name: string;
|
|
78
|
-
|
|
78
|
+
scope: string; // APEX or hierarchical
|
|
79
79
|
sequence: number; // Date.now()
|
|
80
80
|
|
|
81
81
|
// Timestamps (ISO 8601)
|
|
@@ -108,7 +108,7 @@ const record = await putEntity({
|
|
|
108
108
|
model: "record",
|
|
109
109
|
id: crypto.randomUUID(),
|
|
110
110
|
name: "Daily Log",
|
|
111
|
-
|
|
111
|
+
scope: APEX,
|
|
112
112
|
sequence: Date.now(),
|
|
113
113
|
alias: "2026-01-07", // Optional
|
|
114
114
|
class: "memory", // Optional
|
|
@@ -118,7 +118,7 @@ const record = await putEntity({
|
|
|
118
118
|
});
|
|
119
119
|
|
|
120
120
|
// Result includes auto-populated indexes:
|
|
121
|
-
//
|
|
121
|
+
// indexScope: "@#record"
|
|
122
122
|
// indexAlias: "@#record#2026-01-07"
|
|
123
123
|
// indexClass: "@#record#memory"
|
|
124
124
|
```
|
|
@@ -187,16 +187,16 @@ await destroyEntity({ id: "123", model: "record" });
|
|
|
187
187
|
|
|
188
188
|
### Hierarchical Entities
|
|
189
189
|
|
|
190
|
-
Use `
|
|
190
|
+
Use `calculateScope` to derive scope from parent:
|
|
191
191
|
|
|
192
192
|
```typescript
|
|
193
|
-
import {
|
|
193
|
+
import { calculateScope, putEntity, queryByScope } from "@jaypie/dynamodb";
|
|
194
194
|
|
|
195
195
|
// Parent reference
|
|
196
196
|
const chat = { model: "chat", id: "abc-123" };
|
|
197
197
|
|
|
198
|
-
// Calculate child
|
|
199
|
-
const
|
|
198
|
+
// Calculate child scope
|
|
199
|
+
const messageScope = calculateScope(chat); // "chat#abc-123"
|
|
200
200
|
|
|
201
201
|
// Create child entity
|
|
202
202
|
const message = await putEntity({
|
|
@@ -204,39 +204,39 @@ const message = await putEntity({
|
|
|
204
204
|
model: "message",
|
|
205
205
|
id: crypto.randomUUID(),
|
|
206
206
|
name: "First message",
|
|
207
|
-
|
|
207
|
+
scope: messageScope,
|
|
208
208
|
sequence: Date.now(),
|
|
209
209
|
createdAt: now,
|
|
210
210
|
updatedAt: now,
|
|
211
211
|
},
|
|
212
212
|
});
|
|
213
|
-
//
|
|
213
|
+
// indexScope: "chat#abc-123#message"
|
|
214
214
|
|
|
215
215
|
// Query all messages in chat
|
|
216
|
-
const { items } = await
|
|
216
|
+
const { items } = await queryByScope({ model: "message", scope: messageScope });
|
|
217
217
|
```
|
|
218
218
|
|
|
219
219
|
## Query Functions
|
|
220
220
|
|
|
221
221
|
All queries use object parameters and filter soft-deleted and archived records by default.
|
|
222
222
|
|
|
223
|
-
###
|
|
223
|
+
### queryByScope - List by Parent
|
|
224
224
|
|
|
225
225
|
List all entities of a model under a parent:
|
|
226
226
|
|
|
227
227
|
```typescript
|
|
228
|
-
import { APEX,
|
|
228
|
+
import { APEX, queryByScope } from "@jaypie/dynamodb";
|
|
229
229
|
|
|
230
230
|
// Root-level records
|
|
231
|
-
const { items, lastEvaluatedKey } = await
|
|
231
|
+
const { items, lastEvaluatedKey } = await queryByScope({
|
|
232
232
|
model: "record",
|
|
233
|
-
|
|
233
|
+
scope: APEX,
|
|
234
234
|
});
|
|
235
235
|
|
|
236
236
|
// Messages under a chat
|
|
237
|
-
const { items: messages } = await
|
|
237
|
+
const { items: messages } = await queryByScope({
|
|
238
238
|
model: "message",
|
|
239
|
-
|
|
239
|
+
scope: "chat#abc-123",
|
|
240
240
|
});
|
|
241
241
|
```
|
|
242
242
|
|
|
@@ -250,7 +250,7 @@ import { APEX, queryByAlias } from "@jaypie/dynamodb";
|
|
|
250
250
|
const record = await queryByAlias({
|
|
251
251
|
alias: "2026-01-07",
|
|
252
252
|
model: "record",
|
|
253
|
-
|
|
253
|
+
scope: APEX,
|
|
254
254
|
});
|
|
255
255
|
// Returns entity or null
|
|
256
256
|
```
|
|
@@ -263,14 +263,14 @@ import { APEX, queryByClass, queryByType } from "@jaypie/dynamodb";
|
|
|
263
263
|
// All memory records
|
|
264
264
|
const { items } = await queryByClass({
|
|
265
265
|
model: "record",
|
|
266
|
-
|
|
266
|
+
scope: APEX,
|
|
267
267
|
recordClass: "memory",
|
|
268
268
|
});
|
|
269
269
|
|
|
270
270
|
// All note-type records
|
|
271
271
|
const { items: notes } = await queryByType({
|
|
272
272
|
model: "record",
|
|
273
|
-
|
|
273
|
+
scope: APEX,
|
|
274
274
|
type: "note",
|
|
275
275
|
});
|
|
276
276
|
```
|
|
@@ -284,7 +284,7 @@ import { APEX, queryByXid } from "@jaypie/dynamodb";
|
|
|
284
284
|
|
|
285
285
|
const record = await queryByXid({
|
|
286
286
|
model: "record",
|
|
287
|
-
|
|
287
|
+
scope: APEX,
|
|
288
288
|
xid: "ext-12345",
|
|
289
289
|
});
|
|
290
290
|
// Returns entity or null
|
|
@@ -295,9 +295,9 @@ const record = await queryByXid({
|
|
|
295
295
|
```typescript
|
|
296
296
|
import type { BaseQueryOptions } from "@jaypie/dynamodb";
|
|
297
297
|
|
|
298
|
-
const result = await
|
|
298
|
+
const result = await queryByScope({
|
|
299
299
|
model: "record",
|
|
300
|
-
|
|
300
|
+
scope: APEX,
|
|
301
301
|
// BaseQueryOptions:
|
|
302
302
|
limit: 25, // Max items to return
|
|
303
303
|
ascending: true, // Oldest first (default: false = newest first)
|
|
@@ -310,15 +310,15 @@ const result = await queryByOu({
|
|
|
310
310
|
### Pagination
|
|
311
311
|
|
|
312
312
|
```typescript
|
|
313
|
-
import { APEX,
|
|
313
|
+
import { APEX, queryByScope } from "@jaypie/dynamodb";
|
|
314
314
|
|
|
315
315
|
let startKey: Record<string, unknown> | undefined;
|
|
316
316
|
const allItems: StorableEntity[] = [];
|
|
317
317
|
|
|
318
318
|
do {
|
|
319
|
-
const { items, lastEvaluatedKey } = await
|
|
319
|
+
const { items, lastEvaluatedKey } = await queryByScope({
|
|
320
320
|
model: "record",
|
|
321
|
-
|
|
321
|
+
scope: APEX,
|
|
322
322
|
limit: 100,
|
|
323
323
|
startKey,
|
|
324
324
|
});
|
|
@@ -337,11 +337,11 @@ import { indexEntity } from "@jaypie/dynamodb";
|
|
|
337
337
|
const indexed = indexEntity({
|
|
338
338
|
model: "record",
|
|
339
339
|
id: "123",
|
|
340
|
-
|
|
340
|
+
scope: "@",
|
|
341
341
|
alias: "my-alias",
|
|
342
342
|
// ...
|
|
343
343
|
});
|
|
344
|
-
//
|
|
344
|
+
// indexScope: "@#record"
|
|
345
345
|
// indexAlias: "@#record#my-alias"
|
|
346
346
|
```
|
|
347
347
|
|
|
@@ -349,14 +349,14 @@ Use individual key builders for manual key construction:
|
|
|
349
349
|
|
|
350
350
|
```typescript
|
|
351
351
|
import {
|
|
352
|
-
|
|
352
|
+
buildIndexScope,
|
|
353
353
|
buildIndexAlias,
|
|
354
354
|
buildIndexClass,
|
|
355
355
|
buildIndexType,
|
|
356
356
|
buildIndexXid,
|
|
357
357
|
} from "@jaypie/dynamodb";
|
|
358
358
|
|
|
359
|
-
|
|
359
|
+
buildIndexScope("@", "record"); // "@#record"
|
|
360
360
|
buildIndexAlias("@", "record", "my-alias"); // "@#record#my-alias"
|
|
361
361
|
buildIndexClass("@", "record", "memory"); // "@#record#memory"
|
|
362
362
|
buildIndexType("@", "record", "note"); // "@#record#note"
|
|
@@ -369,7 +369,7 @@ buildIndexXid("@", "record", "ext-123"); // "@#record#ext-123"
|
|
|
369
369
|
import {
|
|
370
370
|
APEX, // "@" - Root-level marker
|
|
371
371
|
SEPARATOR, // "#" - Composite key separator
|
|
372
|
-
|
|
372
|
+
INDEX_SCOPE, // "indexScope"
|
|
373
373
|
INDEX_ALIAS, // "indexAlias"
|
|
374
374
|
INDEX_CLASS, // "indexClass"
|
|
375
375
|
INDEX_TYPE, // "indexType"
|
|
@@ -385,7 +385,7 @@ AttributeDefinitions:
|
|
|
385
385
|
AttributeType: S
|
|
386
386
|
- AttributeName: id
|
|
387
387
|
AttributeType: S
|
|
388
|
-
- AttributeName:
|
|
388
|
+
- AttributeName: indexScope
|
|
389
389
|
AttributeType: S
|
|
390
390
|
- AttributeName: indexAlias
|
|
391
391
|
AttributeType: S
|
|
@@ -405,9 +405,9 @@ KeySchema:
|
|
|
405
405
|
KeyType: RANGE
|
|
406
406
|
|
|
407
407
|
GlobalSecondaryIndexes:
|
|
408
|
-
- IndexName:
|
|
408
|
+
- IndexName: indexScope
|
|
409
409
|
KeySchema:
|
|
410
|
-
- AttributeName:
|
|
410
|
+
- AttributeName: indexScope
|
|
411
411
|
KeyType: HASH
|
|
412
412
|
- AttributeName: sequence
|
|
413
413
|
KeyType: RANGE
|
|
@@ -445,7 +445,7 @@ const created = await seedEntityIfNotExists({
|
|
|
445
445
|
alias: "config-main",
|
|
446
446
|
model: "config",
|
|
447
447
|
name: "Main Configuration",
|
|
448
|
-
|
|
448
|
+
scope: APEX,
|
|
449
449
|
});
|
|
450
450
|
// Returns true if created, false if already exists
|
|
451
451
|
```
|
|
@@ -458,8 +458,8 @@ Seed multiple entities with idempotency:
|
|
|
458
458
|
import { APEX, seedEntities } from "@jaypie/dynamodb";
|
|
459
459
|
|
|
460
460
|
const result = await seedEntities([
|
|
461
|
-
{ alias: "vocab-en", model: "vocabulary", name: "English",
|
|
462
|
-
{ alias: "vocab-es", model: "vocabulary", name: "Spanish",
|
|
461
|
+
{ alias: "vocab-en", model: "vocabulary", name: "English", scope: APEX },
|
|
462
|
+
{ alias: "vocab-es", model: "vocabulary", name: "Spanish", scope: APEX },
|
|
463
463
|
]);
|
|
464
464
|
// result.created: aliases of created entities
|
|
465
465
|
// result.skipped: aliases of entities that already existed
|
|
@@ -476,7 +476,7 @@ Auto-generates `id` (UUID), `createdAt`, `updatedAt`, and `sequence` if missing.
|
|
|
476
476
|
|
|
477
477
|
### exportEntities
|
|
478
478
|
|
|
479
|
-
Export entities by model and
|
|
479
|
+
Export entities by model and scope:
|
|
480
480
|
|
|
481
481
|
```typescript
|
|
482
482
|
import { APEX, exportEntities } from "@jaypie/dynamodb";
|
|
@@ -546,11 +546,11 @@ import {
|
|
|
546
546
|
exportEntities,
|
|
547
547
|
getEntity,
|
|
548
548
|
putEntity,
|
|
549
|
-
|
|
549
|
+
queryByScope,
|
|
550
550
|
seedEntities,
|
|
551
551
|
} from "@jaypie/testkit/mock";
|
|
552
552
|
|
|
553
|
-
|
|
553
|
+
queryByScope.mockResolvedValue({
|
|
554
554
|
items: [{ id: "123", name: "Test" }],
|
|
555
555
|
lastEvaluatedKey: undefined,
|
|
556
556
|
});
|
|
@@ -644,12 +644,12 @@ await deleteEntity({ id: "123", model: "record" });
|
|
|
644
644
|
await archiveEntity({ id: "123", model: "record" });
|
|
645
645
|
|
|
646
646
|
// Queries exclude both by default
|
|
647
|
-
const { items } = await
|
|
647
|
+
const { items } = await queryByScope({ model: "record", scope: APEX });
|
|
648
648
|
|
|
649
649
|
// Include if needed
|
|
650
|
-
const { items: all } = await
|
|
650
|
+
const { items: all } = await queryByScope({
|
|
651
651
|
model: "record",
|
|
652
|
-
|
|
652
|
+
scope: APEX,
|
|
653
653
|
includeDeleted: true,
|
|
654
654
|
includeArchived: true,
|
|
655
655
|
});
|
|
@@ -704,7 +704,7 @@ const { tools } = registerDynamoDbTools({ server });
|
|
|
704
704
|
#### Query Operations
|
|
705
705
|
| Tool | Description |
|
|
706
706
|
|------|-------------|
|
|
707
|
-
| `
|
|
707
|
+
| `dynamodb_query_scope` | Query by scope |
|
|
708
708
|
| `dynamodb_query_alias` | Query by human-friendly alias |
|
|
709
709
|
| `dynamodb_query_class` | Query by category classification |
|
|
710
710
|
| `dynamodb_query_type` | Query by type classification |
|
|
@@ -753,15 +753,15 @@ Generate docker-compose and create table:
|
|
|
753
753
|
"id": "abc-123",
|
|
754
754
|
"model": "record",
|
|
755
755
|
"name": "My Record",
|
|
756
|
-
"
|
|
756
|
+
"scope": "@",
|
|
757
757
|
"alias": "my-record",
|
|
758
758
|
"class": "memory"
|
|
759
759
|
}
|
|
760
760
|
|
|
761
|
-
//
|
|
761
|
+
// dynamodb_query_scope
|
|
762
762
|
{
|
|
763
763
|
"model": "record",
|
|
764
|
-
"
|
|
764
|
+
"scope": "@",
|
|
765
765
|
"limit": 10
|
|
766
766
|
}
|
|
767
767
|
|
|
@@ -407,50 +407,6 @@ expressHandler automatically sets these headers:
|
|
|
407
407
|
|
|
408
408
|
When Datadog environment variables are configured, expressHandler automatically submits metrics for each request including status code and path.
|
|
409
409
|
|
|
410
|
-
## Server Creation
|
|
411
|
-
|
|
412
|
-
Use `createServer` to quickly set up an Express server with standard Jaypie middleware.
|
|
413
|
-
|
|
414
|
-
### Basic Server Usage
|
|
415
|
-
|
|
416
|
-
```typescript
|
|
417
|
-
import express from "express";
|
|
418
|
-
import { createServer, expressHandler } from "jaypie";
|
|
419
|
-
|
|
420
|
-
const app = express();
|
|
421
|
-
|
|
422
|
-
app.get("/", expressHandler(async (req, res) => {
|
|
423
|
-
return { message: "Hello World" };
|
|
424
|
-
}));
|
|
425
|
-
|
|
426
|
-
const { server, port } = await createServer(app);
|
|
427
|
-
console.log(`Server running on port ${port}`);
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
### Server Options
|
|
431
|
-
|
|
432
|
-
```typescript
|
|
433
|
-
import { createServer } from "jaypie";
|
|
434
|
-
import type { CreateServerOptions } from "jaypie";
|
|
435
|
-
|
|
436
|
-
const options: CreateServerOptions = {
|
|
437
|
-
port: 3000, // Port to listen on (default: PORT env var or 8080)
|
|
438
|
-
cors: { origin: "*" }, // CORS config (false to disable)
|
|
439
|
-
jsonLimit: "10mb", // JSON body parser limit (default: "1mb")
|
|
440
|
-
middleware: [myMiddleware], // Additional middleware to apply
|
|
441
|
-
};
|
|
442
|
-
|
|
443
|
-
const { server, port } = await createServer(app, options);
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
### Server Result
|
|
447
|
-
|
|
448
|
-
```typescript
|
|
449
|
-
import type { ServerResult } from "jaypie";
|
|
450
|
-
|
|
451
|
-
// { server: Server, port: number }
|
|
452
|
-
```
|
|
453
|
-
|
|
454
410
|
## Streaming Responses
|
|
455
411
|
|
|
456
412
|
Use `expressStreamHandler` for Server-Sent Events (SSE) streaming responses. Ideal for real-time updates, LLM streaming, and long-running operations.
|