@mastra/express 0.0.0-trace-timeline-update-20251121092347

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":["MastraServerAdapter","InMemoryTaskStore"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Mastra } from '@mastra/core/mastra';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport type { Tool } from '@mastra/core/tools';\nimport { InMemoryTaskStore } from '@mastra/server/a2a/store';\nimport type { ServerRoute, BodyLimitOptions } from '@mastra/server/server-adapter';\nimport { MastraServerAdapter } from '@mastra/server/server-adapter';\nimport type { Application, NextFunction, Request, Response } from 'express';\n\n// Extend Express types to include Mastra context\ndeclare global {\n namespace Express {\n interface Locals {\n mastra: Mastra;\n requestContext: RequestContext;\n abortSignal: AbortSignal;\n tools: Record<string, Tool>;\n taskStore: InMemoryTaskStore;\n customRouteAuthConfig?: Map<string, boolean>;\n playground?: boolean;\n isDev?: boolean;\n }\n }\n}\n\nexport class ExpressServerAdapter extends MastraServerAdapter<Application, Request, Response> {\n private taskStore: InMemoryTaskStore;\n private customRouteAuthConfig?: Map<string, boolean>;\n private playground?: boolean;\n private isDev?: boolean;\n\n constructor({\n mastra,\n tools,\n taskStore,\n customRouteAuthConfig,\n playground,\n isDev,\n bodyLimitOptions,\n }: {\n mastra: Mastra;\n tools?: Record<string, Tool>;\n taskStore?: InMemoryTaskStore;\n customRouteAuthConfig?: Map<string, boolean>;\n playground?: boolean;\n isDev?: boolean;\n bodyLimitOptions?: BodyLimitOptions;\n }) {\n super({ mastra, bodyLimitOptions, tools });\n this.taskStore = taskStore || new InMemoryTaskStore();\n this.customRouteAuthConfig = customRouteAuthConfig;\n this.playground = playground;\n this.isDev = isDev;\n }\n\n createContextMiddleware(): (req: Request, res: Response, next: NextFunction) => Promise<void> {\n return async (req: Request, res: Response, next: NextFunction) => {\n // Parse request context from request body and add to context\n let bodyRequestContext: Record<string, any> | undefined;\n let paramsRequestContext: Record<string, any> | undefined;\n\n // Parse request context from request body (POST/PUT)\n if (req.method === 'POST' || req.method === 'PUT') {\n const contentType = req.headers['content-type'];\n if (contentType?.includes('application/json') && req.body) {\n if (req.body.requestContext) {\n bodyRequestContext = req.body.requestContext;\n }\n }\n }\n\n // Parse request context from query params (GET)\n if (req.method === 'GET') {\n try {\n const encodedRequestContext = req.query.requestContext;\n if (typeof encodedRequestContext === 'string') {\n // Try JSON first\n try {\n paramsRequestContext = JSON.parse(encodedRequestContext);\n } catch {\n // Fallback to base64(JSON)\n try {\n const json = Buffer.from(encodedRequestContext, 'base64').toString('utf-8');\n paramsRequestContext = JSON.parse(json);\n } catch {\n // ignore if still invalid\n }\n }\n }\n } catch {\n // ignore query parsing errors\n }\n }\n\n const requestContext = this.mergeRequestContext({ paramsRequestContext, bodyRequestContext });\n\n // Set context in res.locals\n res.locals.requestContext = requestContext;\n res.locals.mastra = this.mastra;\n res.locals.tools = this.tools || {};\n res.locals.taskStore = this.taskStore;\n res.locals.playground = this.playground === true;\n res.locals.isDev = this.isDev === true;\n res.locals.customRouteAuthConfig = this.customRouteAuthConfig;\n const controller = new AbortController();\n req.on('close', () => {\n controller.abort();\n });\n res.locals.abortSignal = controller.signal;\n next();\n };\n }\n async stream(route: ServerRoute, res: Response, result: { fullStream: ReadableStream }): Promise<void> {\n res.setHeader('Content-Type', 'text/plain');\n res.setHeader('Transfer-Encoding', 'chunked');\n\n const streamFormat = route.streamFormat || 'stream';\n\n const readableStream = result instanceof ReadableStream ? result : result.fullStream;\n const reader = readableStream.getReader();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n if (value) {\n if (streamFormat === 'sse') {\n res.write(`data: ${JSON.stringify(value)}\\n\\n`);\n } else {\n res.write(JSON.stringify(value) + '\\x1E');\n }\n }\n }\n } catch (error) {\n console.error(error);\n } finally {\n res.end();\n }\n }\n\n async getParams(\n route: ServerRoute,\n request: Request,\n ): Promise<{ urlParams: Record<string, string>; queryParams: Record<string, string>; body: unknown }> {\n const urlParams = request.params;\n const queryParams = request.query;\n const body = await request.body;\n return { urlParams, queryParams: queryParams as Record<string, string>, body };\n }\n\n async sendResponse(route: ServerRoute, response: Response, result: unknown): Promise<void> {\n if (route.responseType === 'json') {\n response.json(result);\n } else if (route.responseType === 'stream') {\n await this.stream(route, response, result as { fullStream: ReadableStream });\n } else if (route.responseType === 'datastream-response') {\n // Handle AI SDK Response objects - pipe Response.body to Express response\n const fetchResponse = result as globalThis.Response;\n fetchResponse.headers.forEach((value, key) => response.setHeader(key, value));\n response.status(fetchResponse.status);\n if (fetchResponse.body) {\n const reader = fetchResponse.body.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n response.write(value);\n }\n } finally {\n response.end();\n }\n } else {\n response.end();\n }\n } else {\n response.sendStatus(500);\n }\n }\n\n async registerRoute(app: Application, route: ServerRoute, { prefix }: { prefix?: string }): Promise<void> {\n // Determine if body limits should be applied\n const shouldApplyBodyLimit = this.bodyLimitOptions && ['POST', 'PUT', 'PATCH'].includes(route.method.toUpperCase());\n\n // Get the body size limit for this route (route-specific or default)\n const maxSize = route.maxBodySize ?? this.bodyLimitOptions?.maxSize;\n\n // Create middleware array\n const middlewares: Array<(req: Request, res: Response, next: NextFunction) => void> = [];\n\n // Add body limit middleware if needed\n if (shouldApplyBodyLimit && maxSize && this.bodyLimitOptions) {\n const bodyLimitMiddleware = (req: Request, res: Response, next: NextFunction) => {\n const contentLength = req.headers['content-length'];\n if (contentLength && parseInt(contentLength, 10) > maxSize) {\n try {\n const errorResponse = this.bodyLimitOptions!.onError({ error: 'Request body too large' });\n return res.status(413).json(errorResponse);\n } catch {\n return res.status(413).json({ error: 'Request body too large' });\n }\n }\n next();\n };\n middlewares.push(bodyLimitMiddleware);\n }\n\n app[route.method.toLowerCase() as keyof Application](\n `${prefix}${route.path}`,\n ...middlewares,\n async (req: Request, res: Response) => {\n const params = await this.getParams(route, req);\n\n if (params.queryParams) {\n try {\n params.queryParams = await this.parseQueryParams(route, params.queryParams as Record<string, string>);\n } catch (error) {\n console.error('Error parsing query params', error);\n // Zod validation errors should return 400 Bad Request, not 500\n return res.status(400).json({\n error: 'Invalid query parameters',\n details: error instanceof Error ? error.message : 'Unknown error',\n });\n }\n }\n\n if (params.body) {\n try {\n params.body = await this.parseBody(route, params.body);\n } catch (error) {\n console.error('Error parsing body', error);\n // Zod validation errors should return 400 Bad Request, not 500\n return res.status(400).json({\n error: 'Invalid request body',\n details: error instanceof Error ? error.message : 'Unknown error',\n });\n }\n }\n\n const handlerParams = {\n ...params.urlParams,\n ...params.queryParams,\n ...(typeof params.body === 'object' ? params.body : {}),\n requestContext: res.locals.requestContext,\n mastra: this.mastra,\n tools: res.locals.tools,\n taskStore: res.locals.taskStore,\n abortSignal: res.locals.abortSignal,\n };\n\n try {\n const result = await route.handler(handlerParams);\n await this.sendResponse(route, res, result);\n } catch (error) {\n console.error('Error calling handler', error);\n // Check if it's an HTTPException or MastraError with a status code\n let status = 500;\n if (error && typeof error === 'object') {\n // Check for direct status property (HTTPException)\n if ('status' in error) {\n status = (error as any).status;\n }\n // Check for MastraError with status in details\n else if (\n 'details' in error &&\n error.details &&\n typeof error.details === 'object' &&\n 'status' in error.details\n ) {\n status = (error.details as any).status;\n }\n }\n res.status(status).json({ error: error instanceof Error ? error.message : 'Unknown error' });\n }\n },\n );\n }\n\n registerContextMiddleware(app: Application): void {\n app.use(this.createContextMiddleware());\n }\n\n async registerRoutes(\n app: Application,\n { prefix, openapiPath }: { prefix?: string; openapiPath?: string },\n ): Promise<void> {\n await super.registerRoutes(app, { prefix, openapiPath });\n }\n}\n"]}
@@ -0,0 +1,55 @@
1
+ import type { Mastra } from '@mastra/core/mastra';
2
+ import type { RequestContext } from '@mastra/core/request-context';
3
+ import type { Tool } from '@mastra/core/tools';
4
+ import { InMemoryTaskStore } from '@mastra/server/a2a/store';
5
+ import type { ServerRoute, BodyLimitOptions } from '@mastra/server/server-adapter';
6
+ import { MastraServerAdapter } from '@mastra/server/server-adapter';
7
+ import type { Application, NextFunction, Request, Response } from 'express';
8
+ declare global {
9
+ namespace Express {
10
+ interface Locals {
11
+ mastra: Mastra;
12
+ requestContext: RequestContext;
13
+ abortSignal: AbortSignal;
14
+ tools: Record<string, Tool>;
15
+ taskStore: InMemoryTaskStore;
16
+ customRouteAuthConfig?: Map<string, boolean>;
17
+ playground?: boolean;
18
+ isDev?: boolean;
19
+ }
20
+ }
21
+ }
22
+ export declare class ExpressServerAdapter extends MastraServerAdapter<Application, Request, Response> {
23
+ private taskStore;
24
+ private customRouteAuthConfig?;
25
+ private playground?;
26
+ private isDev?;
27
+ constructor({ mastra, tools, taskStore, customRouteAuthConfig, playground, isDev, bodyLimitOptions, }: {
28
+ mastra: Mastra;
29
+ tools?: Record<string, Tool>;
30
+ taskStore?: InMemoryTaskStore;
31
+ customRouteAuthConfig?: Map<string, boolean>;
32
+ playground?: boolean;
33
+ isDev?: boolean;
34
+ bodyLimitOptions?: BodyLimitOptions;
35
+ });
36
+ createContextMiddleware(): (req: Request, res: Response, next: NextFunction) => Promise<void>;
37
+ stream(route: ServerRoute, res: Response, result: {
38
+ fullStream: ReadableStream;
39
+ }): Promise<void>;
40
+ getParams(route: ServerRoute, request: Request): Promise<{
41
+ urlParams: Record<string, string>;
42
+ queryParams: Record<string, string>;
43
+ body: unknown;
44
+ }>;
45
+ sendResponse(route: ServerRoute, response: Response, result: unknown): Promise<void>;
46
+ registerRoute(app: Application, route: ServerRoute, { prefix }: {
47
+ prefix?: string;
48
+ }): Promise<void>;
49
+ registerContextMiddleware(app: Application): void;
50
+ registerRoutes(app: Application, { prefix, openapiPath }: {
51
+ prefix?: string;
52
+ openapiPath?: string;
53
+ }): Promise<void>;
54
+ }
55
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,213 @@
1
+ import { InMemoryTaskStore } from '@mastra/server/a2a/store';
2
+ import { MastraServerAdapter } from '@mastra/server/server-adapter';
3
+
4
+ // src/index.ts
5
+ var ExpressServerAdapter = class extends MastraServerAdapter {
6
+ taskStore;
7
+ customRouteAuthConfig;
8
+ playground;
9
+ isDev;
10
+ constructor({
11
+ mastra,
12
+ tools,
13
+ taskStore,
14
+ customRouteAuthConfig,
15
+ playground,
16
+ isDev,
17
+ bodyLimitOptions
18
+ }) {
19
+ super({ mastra, bodyLimitOptions, tools });
20
+ this.taskStore = taskStore || new InMemoryTaskStore();
21
+ this.customRouteAuthConfig = customRouteAuthConfig;
22
+ this.playground = playground;
23
+ this.isDev = isDev;
24
+ }
25
+ createContextMiddleware() {
26
+ return async (req, res, next) => {
27
+ let bodyRequestContext;
28
+ let paramsRequestContext;
29
+ if (req.method === "POST" || req.method === "PUT") {
30
+ const contentType = req.headers["content-type"];
31
+ if (contentType?.includes("application/json") && req.body) {
32
+ if (req.body.requestContext) {
33
+ bodyRequestContext = req.body.requestContext;
34
+ }
35
+ }
36
+ }
37
+ if (req.method === "GET") {
38
+ try {
39
+ const encodedRequestContext = req.query.requestContext;
40
+ if (typeof encodedRequestContext === "string") {
41
+ try {
42
+ paramsRequestContext = JSON.parse(encodedRequestContext);
43
+ } catch {
44
+ try {
45
+ const json = Buffer.from(encodedRequestContext, "base64").toString("utf-8");
46
+ paramsRequestContext = JSON.parse(json);
47
+ } catch {
48
+ }
49
+ }
50
+ }
51
+ } catch {
52
+ }
53
+ }
54
+ const requestContext = this.mergeRequestContext({ paramsRequestContext, bodyRequestContext });
55
+ res.locals.requestContext = requestContext;
56
+ res.locals.mastra = this.mastra;
57
+ res.locals.tools = this.tools || {};
58
+ res.locals.taskStore = this.taskStore;
59
+ res.locals.playground = this.playground === true;
60
+ res.locals.isDev = this.isDev === true;
61
+ res.locals.customRouteAuthConfig = this.customRouteAuthConfig;
62
+ const controller = new AbortController();
63
+ req.on("close", () => {
64
+ controller.abort();
65
+ });
66
+ res.locals.abortSignal = controller.signal;
67
+ next();
68
+ };
69
+ }
70
+ async stream(route, res, result) {
71
+ res.setHeader("Content-Type", "text/plain");
72
+ res.setHeader("Transfer-Encoding", "chunked");
73
+ const streamFormat = route.streamFormat || "stream";
74
+ const readableStream = result instanceof ReadableStream ? result : result.fullStream;
75
+ const reader = readableStream.getReader();
76
+ try {
77
+ while (true) {
78
+ const { done, value } = await reader.read();
79
+ if (done) break;
80
+ if (value) {
81
+ if (streamFormat === "sse") {
82
+ res.write(`data: ${JSON.stringify(value)}
83
+
84
+ `);
85
+ } else {
86
+ res.write(JSON.stringify(value) + "");
87
+ }
88
+ }
89
+ }
90
+ } catch (error) {
91
+ console.error(error);
92
+ } finally {
93
+ res.end();
94
+ }
95
+ }
96
+ async getParams(route, request) {
97
+ const urlParams = request.params;
98
+ const queryParams = request.query;
99
+ const body = await request.body;
100
+ return { urlParams, queryParams, body };
101
+ }
102
+ async sendResponse(route, response, result) {
103
+ if (route.responseType === "json") {
104
+ response.json(result);
105
+ } else if (route.responseType === "stream") {
106
+ await this.stream(route, response, result);
107
+ } else if (route.responseType === "datastream-response") {
108
+ const fetchResponse = result;
109
+ fetchResponse.headers.forEach((value, key) => response.setHeader(key, value));
110
+ response.status(fetchResponse.status);
111
+ if (fetchResponse.body) {
112
+ const reader = fetchResponse.body.getReader();
113
+ try {
114
+ while (true) {
115
+ const { done, value } = await reader.read();
116
+ if (done) break;
117
+ response.write(value);
118
+ }
119
+ } finally {
120
+ response.end();
121
+ }
122
+ } else {
123
+ response.end();
124
+ }
125
+ } else {
126
+ response.sendStatus(500);
127
+ }
128
+ }
129
+ async registerRoute(app, route, { prefix }) {
130
+ const shouldApplyBodyLimit = this.bodyLimitOptions && ["POST", "PUT", "PATCH"].includes(route.method.toUpperCase());
131
+ const maxSize = route.maxBodySize ?? this.bodyLimitOptions?.maxSize;
132
+ const middlewares = [];
133
+ if (shouldApplyBodyLimit && maxSize && this.bodyLimitOptions) {
134
+ const bodyLimitMiddleware = (req, res, next) => {
135
+ const contentLength = req.headers["content-length"];
136
+ if (contentLength && parseInt(contentLength, 10) > maxSize) {
137
+ try {
138
+ const errorResponse = this.bodyLimitOptions.onError({ error: "Request body too large" });
139
+ return res.status(413).json(errorResponse);
140
+ } catch {
141
+ return res.status(413).json({ error: "Request body too large" });
142
+ }
143
+ }
144
+ next();
145
+ };
146
+ middlewares.push(bodyLimitMiddleware);
147
+ }
148
+ app[route.method.toLowerCase()](
149
+ `${prefix}${route.path}`,
150
+ ...middlewares,
151
+ async (req, res) => {
152
+ const params = await this.getParams(route, req);
153
+ if (params.queryParams) {
154
+ try {
155
+ params.queryParams = await this.parseQueryParams(route, params.queryParams);
156
+ } catch (error) {
157
+ console.error("Error parsing query params", error);
158
+ return res.status(400).json({
159
+ error: "Invalid query parameters",
160
+ details: error instanceof Error ? error.message : "Unknown error"
161
+ });
162
+ }
163
+ }
164
+ if (params.body) {
165
+ try {
166
+ params.body = await this.parseBody(route, params.body);
167
+ } catch (error) {
168
+ console.error("Error parsing body", error);
169
+ return res.status(400).json({
170
+ error: "Invalid request body",
171
+ details: error instanceof Error ? error.message : "Unknown error"
172
+ });
173
+ }
174
+ }
175
+ const handlerParams = {
176
+ ...params.urlParams,
177
+ ...params.queryParams,
178
+ ...typeof params.body === "object" ? params.body : {},
179
+ requestContext: res.locals.requestContext,
180
+ mastra: this.mastra,
181
+ tools: res.locals.tools,
182
+ taskStore: res.locals.taskStore,
183
+ abortSignal: res.locals.abortSignal
184
+ };
185
+ try {
186
+ const result = await route.handler(handlerParams);
187
+ await this.sendResponse(route, res, result);
188
+ } catch (error) {
189
+ console.error("Error calling handler", error);
190
+ let status = 500;
191
+ if (error && typeof error === "object") {
192
+ if ("status" in error) {
193
+ status = error.status;
194
+ } else if ("details" in error && error.details && typeof error.details === "object" && "status" in error.details) {
195
+ status = error.details.status;
196
+ }
197
+ }
198
+ res.status(status).json({ error: error instanceof Error ? error.message : "Unknown error" });
199
+ }
200
+ }
201
+ );
202
+ }
203
+ registerContextMiddleware(app) {
204
+ app.use(this.createContextMiddleware());
205
+ }
206
+ async registerRoutes(app, { prefix, openapiPath }) {
207
+ await super.registerRoutes(app, { prefix, openapiPath });
208
+ }
209
+ };
210
+
211
+ export { ExpressServerAdapter };
212
+ //# sourceMappingURL=index.js.map
213
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { Mastra } from '@mastra/core/mastra';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport type { Tool } from '@mastra/core/tools';\nimport { InMemoryTaskStore } from '@mastra/server/a2a/store';\nimport type { ServerRoute, BodyLimitOptions } from '@mastra/server/server-adapter';\nimport { MastraServerAdapter } from '@mastra/server/server-adapter';\nimport type { Application, NextFunction, Request, Response } from 'express';\n\n// Extend Express types to include Mastra context\ndeclare global {\n namespace Express {\n interface Locals {\n mastra: Mastra;\n requestContext: RequestContext;\n abortSignal: AbortSignal;\n tools: Record<string, Tool>;\n taskStore: InMemoryTaskStore;\n customRouteAuthConfig?: Map<string, boolean>;\n playground?: boolean;\n isDev?: boolean;\n }\n }\n}\n\nexport class ExpressServerAdapter extends MastraServerAdapter<Application, Request, Response> {\n private taskStore: InMemoryTaskStore;\n private customRouteAuthConfig?: Map<string, boolean>;\n private playground?: boolean;\n private isDev?: boolean;\n\n constructor({\n mastra,\n tools,\n taskStore,\n customRouteAuthConfig,\n playground,\n isDev,\n bodyLimitOptions,\n }: {\n mastra: Mastra;\n tools?: Record<string, Tool>;\n taskStore?: InMemoryTaskStore;\n customRouteAuthConfig?: Map<string, boolean>;\n playground?: boolean;\n isDev?: boolean;\n bodyLimitOptions?: BodyLimitOptions;\n }) {\n super({ mastra, bodyLimitOptions, tools });\n this.taskStore = taskStore || new InMemoryTaskStore();\n this.customRouteAuthConfig = customRouteAuthConfig;\n this.playground = playground;\n this.isDev = isDev;\n }\n\n createContextMiddleware(): (req: Request, res: Response, next: NextFunction) => Promise<void> {\n return async (req: Request, res: Response, next: NextFunction) => {\n // Parse request context from request body and add to context\n let bodyRequestContext: Record<string, any> | undefined;\n let paramsRequestContext: Record<string, any> | undefined;\n\n // Parse request context from request body (POST/PUT)\n if (req.method === 'POST' || req.method === 'PUT') {\n const contentType = req.headers['content-type'];\n if (contentType?.includes('application/json') && req.body) {\n if (req.body.requestContext) {\n bodyRequestContext = req.body.requestContext;\n }\n }\n }\n\n // Parse request context from query params (GET)\n if (req.method === 'GET') {\n try {\n const encodedRequestContext = req.query.requestContext;\n if (typeof encodedRequestContext === 'string') {\n // Try JSON first\n try {\n paramsRequestContext = JSON.parse(encodedRequestContext);\n } catch {\n // Fallback to base64(JSON)\n try {\n const json = Buffer.from(encodedRequestContext, 'base64').toString('utf-8');\n paramsRequestContext = JSON.parse(json);\n } catch {\n // ignore if still invalid\n }\n }\n }\n } catch {\n // ignore query parsing errors\n }\n }\n\n const requestContext = this.mergeRequestContext({ paramsRequestContext, bodyRequestContext });\n\n // Set context in res.locals\n res.locals.requestContext = requestContext;\n res.locals.mastra = this.mastra;\n res.locals.tools = this.tools || {};\n res.locals.taskStore = this.taskStore;\n res.locals.playground = this.playground === true;\n res.locals.isDev = this.isDev === true;\n res.locals.customRouteAuthConfig = this.customRouteAuthConfig;\n const controller = new AbortController();\n req.on('close', () => {\n controller.abort();\n });\n res.locals.abortSignal = controller.signal;\n next();\n };\n }\n async stream(route: ServerRoute, res: Response, result: { fullStream: ReadableStream }): Promise<void> {\n res.setHeader('Content-Type', 'text/plain');\n res.setHeader('Transfer-Encoding', 'chunked');\n\n const streamFormat = route.streamFormat || 'stream';\n\n const readableStream = result instanceof ReadableStream ? result : result.fullStream;\n const reader = readableStream.getReader();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n if (value) {\n if (streamFormat === 'sse') {\n res.write(`data: ${JSON.stringify(value)}\\n\\n`);\n } else {\n res.write(JSON.stringify(value) + '\\x1E');\n }\n }\n }\n } catch (error) {\n console.error(error);\n } finally {\n res.end();\n }\n }\n\n async getParams(\n route: ServerRoute,\n request: Request,\n ): Promise<{ urlParams: Record<string, string>; queryParams: Record<string, string>; body: unknown }> {\n const urlParams = request.params;\n const queryParams = request.query;\n const body = await request.body;\n return { urlParams, queryParams: queryParams as Record<string, string>, body };\n }\n\n async sendResponse(route: ServerRoute, response: Response, result: unknown): Promise<void> {\n if (route.responseType === 'json') {\n response.json(result);\n } else if (route.responseType === 'stream') {\n await this.stream(route, response, result as { fullStream: ReadableStream });\n } else if (route.responseType === 'datastream-response') {\n // Handle AI SDK Response objects - pipe Response.body to Express response\n const fetchResponse = result as globalThis.Response;\n fetchResponse.headers.forEach((value, key) => response.setHeader(key, value));\n response.status(fetchResponse.status);\n if (fetchResponse.body) {\n const reader = fetchResponse.body.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n response.write(value);\n }\n } finally {\n response.end();\n }\n } else {\n response.end();\n }\n } else {\n response.sendStatus(500);\n }\n }\n\n async registerRoute(app: Application, route: ServerRoute, { prefix }: { prefix?: string }): Promise<void> {\n // Determine if body limits should be applied\n const shouldApplyBodyLimit = this.bodyLimitOptions && ['POST', 'PUT', 'PATCH'].includes(route.method.toUpperCase());\n\n // Get the body size limit for this route (route-specific or default)\n const maxSize = route.maxBodySize ?? this.bodyLimitOptions?.maxSize;\n\n // Create middleware array\n const middlewares: Array<(req: Request, res: Response, next: NextFunction) => void> = [];\n\n // Add body limit middleware if needed\n if (shouldApplyBodyLimit && maxSize && this.bodyLimitOptions) {\n const bodyLimitMiddleware = (req: Request, res: Response, next: NextFunction) => {\n const contentLength = req.headers['content-length'];\n if (contentLength && parseInt(contentLength, 10) > maxSize) {\n try {\n const errorResponse = this.bodyLimitOptions!.onError({ error: 'Request body too large' });\n return res.status(413).json(errorResponse);\n } catch {\n return res.status(413).json({ error: 'Request body too large' });\n }\n }\n next();\n };\n middlewares.push(bodyLimitMiddleware);\n }\n\n app[route.method.toLowerCase() as keyof Application](\n `${prefix}${route.path}`,\n ...middlewares,\n async (req: Request, res: Response) => {\n const params = await this.getParams(route, req);\n\n if (params.queryParams) {\n try {\n params.queryParams = await this.parseQueryParams(route, params.queryParams as Record<string, string>);\n } catch (error) {\n console.error('Error parsing query params', error);\n // Zod validation errors should return 400 Bad Request, not 500\n return res.status(400).json({\n error: 'Invalid query parameters',\n details: error instanceof Error ? error.message : 'Unknown error',\n });\n }\n }\n\n if (params.body) {\n try {\n params.body = await this.parseBody(route, params.body);\n } catch (error) {\n console.error('Error parsing body', error);\n // Zod validation errors should return 400 Bad Request, not 500\n return res.status(400).json({\n error: 'Invalid request body',\n details: error instanceof Error ? error.message : 'Unknown error',\n });\n }\n }\n\n const handlerParams = {\n ...params.urlParams,\n ...params.queryParams,\n ...(typeof params.body === 'object' ? params.body : {}),\n requestContext: res.locals.requestContext,\n mastra: this.mastra,\n tools: res.locals.tools,\n taskStore: res.locals.taskStore,\n abortSignal: res.locals.abortSignal,\n };\n\n try {\n const result = await route.handler(handlerParams);\n await this.sendResponse(route, res, result);\n } catch (error) {\n console.error('Error calling handler', error);\n // Check if it's an HTTPException or MastraError with a status code\n let status = 500;\n if (error && typeof error === 'object') {\n // Check for direct status property (HTTPException)\n if ('status' in error) {\n status = (error as any).status;\n }\n // Check for MastraError with status in details\n else if (\n 'details' in error &&\n error.details &&\n typeof error.details === 'object' &&\n 'status' in error.details\n ) {\n status = (error.details as any).status;\n }\n }\n res.status(status).json({ error: error instanceof Error ? error.message : 'Unknown error' });\n }\n },\n );\n }\n\n registerContextMiddleware(app: Application): void {\n app.use(this.createContextMiddleware());\n }\n\n async registerRoutes(\n app: Application,\n { prefix, openapiPath }: { prefix?: string; openapiPath?: string },\n ): Promise<void> {\n await super.registerRoutes(app, { prefix, openapiPath });\n }\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "@mastra/express",
3
+ "version": "0.0.0-trace-timeline-update-20251121092347",
4
+ "description": "Mastra Express adapter for the server",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ },
14
+ "require": {
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/index.cjs"
17
+ }
18
+ },
19
+ "./package.json": "./package.json"
20
+ },
21
+ "license": "Apache-2.0",
22
+ "dependencies": {
23
+ "@mastra/server": "0.0.0-trace-timeline-update-20251121092347"
24
+ },
25
+ "devDependencies": {
26
+ "@types/node": "^20.19.0",
27
+ "eslint": "^9.37.0",
28
+ "tsup": "^8.5.0",
29
+ "typescript": "^5.8.3",
30
+ "vitest": "^3.2.4",
31
+ "express": "^5.1.0",
32
+ "@types/express": "^5.0.5",
33
+ "@types/cors": "^2.8.19",
34
+ "cors": "^2.8.5",
35
+ "@ai-sdk/openai": "^2.0.62",
36
+ "zod": "^3.25.0",
37
+ "swagger-ui-express": "^5.0.1",
38
+ "@types/swagger-ui-express": "^4.1.6",
39
+ "@internal/server-adapter-test-utils": "0.0.1",
40
+ "@internal/lint": "0.0.0-trace-timeline-update-20251121092347",
41
+ "@internal/storage-test-utils": "0.0.49",
42
+ "@mastra/evals": "0.0.0-trace-timeline-update-20251121092347",
43
+ "@mastra/core": "0.0.0-trace-timeline-update-20251121092347",
44
+ "@mastra/libsql": "0.0.0-trace-timeline-update-20251121092347",
45
+ "@mastra/observability": "0.0.0-trace-timeline-update-20251121092347",
46
+ "@internal/types-builder": "0.0.0-trace-timeline-update-20251121092347",
47
+ "@mastra/memory": "0.0.0-trace-timeline-update-20251121092347"
48
+ },
49
+ "peerDependencies": {
50
+ "express": "^5.1.0",
51
+ "@types/express": "^5.0.5",
52
+ "@mastra/core": "0.0.0-trace-timeline-update-20251121092347"
53
+ },
54
+ "engines": {
55
+ "node": ">=22.13.0"
56
+ },
57
+ "files": [
58
+ "dist",
59
+ "CHANGELOG.md"
60
+ ],
61
+ "homepage": "https://mastra.ai",
62
+ "repository": {
63
+ "type": "git",
64
+ "url": "git+https://github.com/mastra-ai/mastra.git",
65
+ "directory": "server-adapters/express"
66
+ },
67
+ "bugs": {
68
+ "url": "https://github.com/mastra-ai/mastra/issues"
69
+ },
70
+ "scripts": {
71
+ "build": "tsup --silent --config tsup.config.ts",
72
+ "build:watch": "pnpm build --watch",
73
+ "test": "vitest run",
74
+ "lint": "eslint ."
75
+ }
76
+ }