@mastra/express 0.0.2-beta.0 → 0.0.2-beta.2

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 CHANGED
@@ -1,27 +1,126 @@
1
- import { InMemoryTaskStore } from '@mastra/server/a2a/store';
2
- import { MastraServerAdapter } from '@mastra/server/server-adapter';
1
+ import { MastraServer as MastraServer$1, redactStreamChunk } from '@mastra/server/server-adapter';
2
+ import { isDevPlaygroundRequest, isProtectedPath, canAccessPublicly, checkRules, defaultAuthConfig } from '@mastra/server/auth';
3
3
 
4
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;
5
+ var authenticationMiddleware = async (req, res, next) => {
6
+ const mastra = res.locals.mastra;
7
+ const authConfig = mastra.getServer()?.auth;
8
+ const customRouteAuthConfig = res.locals.customRouteAuthConfig;
9
+ if (!authConfig) {
10
+ return next();
24
11
  }
12
+ const path = req.path;
13
+ const method = req.method;
14
+ const getHeader = (name) => req.headers[name.toLowerCase()];
15
+ if (isDevPlaygroundRequest(path, method, getHeader, authConfig)) {
16
+ return next();
17
+ }
18
+ if (!isProtectedPath(req.path, req.method, authConfig, customRouteAuthConfig)) {
19
+ return next();
20
+ }
21
+ if (canAccessPublicly(req.path, req.method, authConfig)) {
22
+ return next();
23
+ }
24
+ const authHeader = req.headers.authorization;
25
+ let token = authHeader ? authHeader.replace("Bearer ", "") : null;
26
+ if (!token && req.query.apiKey) {
27
+ token = req.query.apiKey || null;
28
+ }
29
+ if (!token) {
30
+ return res.status(401).json({ error: "Authentication required" });
31
+ }
32
+ try {
33
+ let user;
34
+ if (typeof authConfig.authenticateToken === "function") {
35
+ user = await authConfig.authenticateToken(token, req);
36
+ } else {
37
+ throw new Error("No token verification method configured");
38
+ }
39
+ if (!user) {
40
+ return res.status(401).json({ error: "Invalid or expired token" });
41
+ }
42
+ res.locals.requestContext.set("user", user);
43
+ return next();
44
+ } catch (err) {
45
+ console.error(err);
46
+ return res.status(401).json({ error: "Invalid or expired token" });
47
+ }
48
+ };
49
+ var authorizationMiddleware = async (req, res, next) => {
50
+ const mastra = res.locals.mastra;
51
+ const authConfig = mastra.getServer()?.auth;
52
+ const customRouteAuthConfig = res.locals.customRouteAuthConfig;
53
+ if (!authConfig) {
54
+ return next();
55
+ }
56
+ const path = req.path;
57
+ const method = req.method;
58
+ const getHeader = (name) => req.headers[name.toLowerCase()];
59
+ if (isDevPlaygroundRequest(path, method, getHeader, authConfig)) {
60
+ return next();
61
+ }
62
+ if (!isProtectedPath(req.path, req.method, authConfig, customRouteAuthConfig)) {
63
+ return next();
64
+ }
65
+ if (canAccessPublicly(path, method, authConfig)) {
66
+ return next();
67
+ }
68
+ const user = res.locals.requestContext.get("user");
69
+ if ("authorizeUser" in authConfig && typeof authConfig.authorizeUser === "function") {
70
+ try {
71
+ const isAuthorized = await authConfig.authorizeUser(user, req);
72
+ if (isAuthorized) {
73
+ return next();
74
+ }
75
+ return res.status(403).json({ error: "Access denied" });
76
+ } catch (err) {
77
+ console.error(err);
78
+ return res.status(500).json({ error: "Authorization error" });
79
+ }
80
+ }
81
+ if ("authorize" in authConfig && typeof authConfig.authorize === "function") {
82
+ try {
83
+ const context = {
84
+ get: (key) => {
85
+ if (key === "mastra") return res.locals.mastra;
86
+ if (key === "requestContext") return res.locals.requestContext;
87
+ if (key === "tools") return res.locals.tools;
88
+ if (key === "taskStore") return res.locals.taskStore;
89
+ if (key === "customRouteAuthConfig") return res.locals.customRouteAuthConfig;
90
+ if (key === "playground") return res.locals.playground;
91
+ if (key === "isDev") return res.locals.isDev;
92
+ return void 0;
93
+ },
94
+ req
95
+ };
96
+ const isAuthorized = await authConfig.authorize(path, method, user, context);
97
+ if (isAuthorized) {
98
+ return next();
99
+ }
100
+ return res.status(403).json({ error: "Access denied" });
101
+ } catch (err) {
102
+ console.error(err);
103
+ return res.status(500).json({ error: "Authorization error" });
104
+ }
105
+ }
106
+ if ("rules" in authConfig && authConfig.rules && authConfig.rules.length > 0) {
107
+ const isAuthorized = await checkRules(authConfig.rules, path, method, user);
108
+ if (isAuthorized) {
109
+ return next();
110
+ }
111
+ return res.status(403).json({ error: "Access denied" });
112
+ }
113
+ if (defaultAuthConfig.rules && defaultAuthConfig.rules.length > 0) {
114
+ const isAuthorized = await checkRules(defaultAuthConfig.rules, path, method, user);
115
+ if (isAuthorized) {
116
+ return next();
117
+ }
118
+ }
119
+ return res.status(403).json({ error: "Access denied" });
120
+ };
121
+
122
+ // src/index.ts
123
+ var MastraServer = class extends MastraServer$1 {
25
124
  createContextMiddleware() {
26
125
  return async (req, res, next) => {
27
126
  let bodyRequestContext;
@@ -55,13 +154,17 @@ var ExpressServerAdapter = class extends MastraServerAdapter {
55
154
  res.locals.requestContext = requestContext;
56
155
  res.locals.mastra = this.mastra;
57
156
  res.locals.tools = this.tools || {};
58
- res.locals.taskStore = this.taskStore;
157
+ if (this.taskStore) {
158
+ res.locals.taskStore = this.taskStore;
159
+ }
59
160
  res.locals.playground = this.playground === true;
60
161
  res.locals.isDev = this.isDev === true;
61
162
  res.locals.customRouteAuthConfig = this.customRouteAuthConfig;
62
163
  const controller = new AbortController();
63
- req.on("close", () => {
64
- controller.abort();
164
+ res.on("close", () => {
165
+ if (!res.writableFinished) {
166
+ controller.abort();
167
+ }
65
168
  });
66
169
  res.locals.abortSignal = controller.signal;
67
170
  next();
@@ -78,12 +181,14 @@ var ExpressServerAdapter = class extends MastraServerAdapter {
78
181
  const { done, value } = await reader.read();
79
182
  if (done) break;
80
183
  if (value) {
184
+ const shouldRedact = this.streamOptions?.redact ?? true;
185
+ const outputValue = shouldRedact ? redactStreamChunk(value) : value;
81
186
  if (streamFormat === "sse") {
82
- res.write(`data: ${JSON.stringify(value)}
187
+ res.write(`data: ${JSON.stringify(outputValue)}
83
188
 
84
189
  `);
85
190
  } else {
86
- res.write(JSON.stringify(value) + "");
191
+ res.write(JSON.stringify(outputValue) + "");
87
192
  }
88
193
  }
89
194
  }
@@ -99,7 +204,7 @@ var ExpressServerAdapter = class extends MastraServerAdapter {
99
204
  const body = await request.body;
100
205
  return { urlParams, queryParams, body };
101
206
  }
102
- async sendResponse(route, response, result) {
207
+ async sendResponse(route, response, result, request) {
103
208
  if (route.responseType === "json") {
104
209
  response.json(result);
105
210
  } else if (route.responseType === "stream") {
@@ -122,6 +227,47 @@ var ExpressServerAdapter = class extends MastraServerAdapter {
122
227
  } else {
123
228
  response.end();
124
229
  }
230
+ } else if (route.responseType === "mcp-http") {
231
+ if (!request) {
232
+ response.status(500).json({ error: "Request object required for MCP transport" });
233
+ return;
234
+ }
235
+ const { server, httpPath } = result;
236
+ try {
237
+ await server.startHTTP({
238
+ url: new URL(request.url, `http://${request.headers.host}`),
239
+ httpPath,
240
+ req: request,
241
+ res: response
242
+ });
243
+ } catch {
244
+ if (!response.headersSent) {
245
+ response.status(500).json({
246
+ jsonrpc: "2.0",
247
+ error: { code: -32603, message: "Internal server error" },
248
+ id: null
249
+ });
250
+ }
251
+ }
252
+ } else if (route.responseType === "mcp-sse") {
253
+ if (!request) {
254
+ response.status(500).json({ error: "Request object required for MCP transport" });
255
+ return;
256
+ }
257
+ const { server, ssePath, messagePath } = result;
258
+ try {
259
+ await server.startSSE({
260
+ url: new URL(request.url, `http://${request.headers.host}`),
261
+ ssePath,
262
+ messagePath,
263
+ req: request,
264
+ res: response
265
+ });
266
+ } catch {
267
+ if (!response.headersSent) {
268
+ response.status(500).json({ error: "Error handling MCP SSE request" });
269
+ }
270
+ }
125
271
  } else {
126
272
  response.sendStatus(500);
127
273
  }
@@ -165,7 +311,7 @@ var ExpressServerAdapter = class extends MastraServerAdapter {
165
311
  try {
166
312
  params.body = await this.parseBody(route, params.body);
167
313
  } catch (error) {
168
- console.error("Error parsing body", error);
314
+ console.error("Error parsing body:", error instanceof Error ? error.message : String(error));
169
315
  return res.status(400).json({
170
316
  error: "Invalid request body",
171
317
  details: error instanceof Error ? error.message : "Unknown error"
@@ -184,7 +330,7 @@ var ExpressServerAdapter = class extends MastraServerAdapter {
184
330
  };
185
331
  try {
186
332
  const result = await route.handler(handlerParams);
187
- await this.sendResponse(route, res, result);
333
+ await this.sendResponse(route, res, result, req);
188
334
  } catch (error) {
189
335
  console.error("Error calling handler", error);
190
336
  let status = 500;
@@ -200,14 +346,19 @@ var ExpressServerAdapter = class extends MastraServerAdapter {
200
346
  }
201
347
  );
202
348
  }
203
- registerContextMiddleware(app) {
204
- app.use(this.createContextMiddleware());
349
+ registerContextMiddleware() {
350
+ this.app.use(this.createContextMiddleware());
205
351
  }
206
- async registerRoutes(app, { prefix, openapiPath }) {
207
- await super.registerRoutes(app, { prefix, openapiPath });
352
+ registerAuthMiddleware() {
353
+ const authConfig = this.mastra.getServer()?.auth;
354
+ if (!authConfig) {
355
+ return;
356
+ }
357
+ this.app.use(authenticationMiddleware);
358
+ this.app.use(authorizationMiddleware);
208
359
  }
209
360
  };
210
361
 
211
- export { ExpressServerAdapter };
362
+ export { MastraServer };
212
363
  //# sourceMappingURL=index.js.map
213
364
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +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"]}
1
+ {"version":3,"sources":["../src/auth-middleware.ts","../src/index.ts"],"names":["MastraServerBase"],"mappings":"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","file":"index.js","sourcesContent":["import {\n canAccessPublicly,\n checkRules,\n defaultAuthConfig,\n isDevPlaygroundRequest,\n isProtectedPath,\n} from '@mastra/server/auth';\nimport type { NextFunction, Request, Response } from 'express';\n\nexport const authenticationMiddleware = async (req: Request, res: Response, next: NextFunction) => {\n const mastra = res.locals.mastra;\n const authConfig = mastra.getServer()?.auth;\n const customRouteAuthConfig = res.locals.customRouteAuthConfig;\n\n if (!authConfig) {\n // No auth config, skip authentication\n return next();\n }\n\n const path = req.path;\n const method = req.method;\n const getHeader = (name: string) => req.headers[name.toLowerCase()] as string | undefined;\n\n if (isDevPlaygroundRequest(path, method, getHeader, authConfig)) {\n // Skip authentication for dev playground requests\n return next();\n }\n\n if (!isProtectedPath(req.path, req.method, authConfig, customRouteAuthConfig)) {\n return next();\n }\n\n // Skip authentication for public routes\n if (canAccessPublicly(req.path, req.method, authConfig)) {\n return next();\n }\n\n // Get token from header or query\n const authHeader = req.headers.authorization;\n let token: string | null = authHeader ? authHeader.replace('Bearer ', '') : null;\n\n if (!token && req.query.apiKey) {\n token = (req.query.apiKey as string) || null;\n }\n\n // Handle missing token\n if (!token) {\n return res.status(401).json({ error: 'Authentication required' });\n }\n\n try {\n // Verify token and get user data\n let user: unknown;\n\n // Client provided verify function\n if (typeof authConfig.authenticateToken === 'function') {\n // Note: Express doesn't have HonoRequest, so we pass the Express Request\n // The auth config function signature accepts HonoRequest, but in practice\n // it should work with any request object that has the necessary properties\n user = await authConfig.authenticateToken(token, req as any);\n } else {\n throw new Error('No token verification method configured');\n }\n\n if (!user) {\n return res.status(401).json({ error: 'Invalid or expired token' });\n }\n\n // Store user in context\n res.locals.requestContext.set('user', user);\n\n return next();\n } catch (err) {\n console.error(err);\n return res.status(401).json({ error: 'Invalid or expired token' });\n }\n};\n\nexport const authorizationMiddleware = async (req: Request, res: Response, next: NextFunction) => {\n const mastra = res.locals.mastra;\n const authConfig = mastra.getServer()?.auth;\n const customRouteAuthConfig = res.locals.customRouteAuthConfig;\n\n if (!authConfig) {\n // No auth config, skip authorization\n return next();\n }\n\n const path = req.path;\n const method = req.method;\n const getHeader = (name: string) => req.headers[name.toLowerCase()] as string | undefined;\n\n if (isDevPlaygroundRequest(path, method, getHeader, authConfig)) {\n // Skip authorization for dev playground requests\n return next();\n }\n\n if (!isProtectedPath(req.path, req.method, authConfig, customRouteAuthConfig)) {\n return next();\n }\n\n // Skip for public routes\n if (canAccessPublicly(path, method, authConfig)) {\n return next();\n }\n\n const user = res.locals.requestContext.get('user');\n\n if ('authorizeUser' in authConfig && typeof authConfig.authorizeUser === 'function') {\n try {\n const isAuthorized = await authConfig.authorizeUser(user, req as any);\n\n if (isAuthorized) {\n return next();\n }\n\n return res.status(403).json({ error: 'Access denied' });\n } catch (err) {\n console.error(err);\n return res.status(500).json({ error: 'Authorization error' });\n }\n }\n\n // Client-provided authorization function\n if ('authorize' in authConfig && typeof authConfig.authorize === 'function') {\n try {\n // Note: The authorize function signature expects ContextWithMastra as 4th param\n // For Express, we pass a compatible object with similar structure\n const context = {\n get: (key: string) => {\n if (key === 'mastra') return res.locals.mastra;\n if (key === 'requestContext') return res.locals.requestContext;\n if (key === 'tools') return res.locals.tools;\n if (key === 'taskStore') return res.locals.taskStore;\n if (key === 'customRouteAuthConfig') return res.locals.customRouteAuthConfig;\n if (key === 'playground') return res.locals.playground;\n if (key === 'isDev') return res.locals.isDev;\n return undefined;\n },\n req: req as any,\n } as any;\n\n const isAuthorized = await authConfig.authorize(path, method, user, context);\n\n if (isAuthorized) {\n return next();\n }\n\n return res.status(403).json({ error: 'Access denied' });\n } catch (err) {\n console.error(err);\n return res.status(500).json({ error: 'Authorization error' });\n }\n }\n\n // Custom rule-based authorization\n if ('rules' in authConfig && authConfig.rules && authConfig.rules.length > 0) {\n const isAuthorized = await checkRules(authConfig.rules, path, method, user);\n\n if (isAuthorized) {\n return next();\n }\n\n return res.status(403).json({ error: 'Access denied' });\n }\n\n // Default rule-based authorization\n if (defaultAuthConfig.rules && defaultAuthConfig.rules.length > 0) {\n const isAuthorized = await checkRules(defaultAuthConfig.rules, path, method, user);\n\n if (isAuthorized) {\n return next();\n }\n }\n\n return res.status(403).json({ error: 'Access denied' });\n};\n","import type { Mastra } from '@mastra/core/mastra';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport type { Tool } from '@mastra/core/tools';\nimport type { InMemoryTaskStore } from '@mastra/server/a2a/store';\nimport type { MCPHttpTransportResult, MCPSseTransportResult } from '@mastra/server/handlers/mcp';\nimport type { ServerRoute } from '@mastra/server/server-adapter';\nimport { MastraServer as MastraServerBase, redactStreamChunk } from '@mastra/server/server-adapter';\nimport type { Application, NextFunction, Request, Response } from 'express';\n\nimport { authenticationMiddleware, authorizationMiddleware } from './auth-middleware';\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 MastraServer extends MastraServerBase<Application, Request, Response> {\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 if (this.taskStore) {\n res.locals.taskStore = this.taskStore;\n }\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 // Use res.on('close') instead of req.on('close') because the request's 'close' event\n // fires when the request body is fully consumed (e.g., after express.json() parses it),\n // NOT when the client disconnects. The response's 'close' event fires when the underlying\n // connection is actually closed, which is the correct signal for client disconnection.\n res.on('close', () => {\n // Only abort if the response wasn't successfully completed\n if (!res.writableFinished) {\n controller.abort();\n }\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 // Optionally redact sensitive data (system prompts, tool definitions, API keys) before sending to the client\n const shouldRedact = this.streamOptions?.redact ?? true;\n const outputValue = shouldRedact ? redactStreamChunk(value) : value;\n if (streamFormat === 'sse') {\n res.write(`data: ${JSON.stringify(outputValue)}\\n\\n`);\n } else {\n res.write(JSON.stringify(outputValue) + '\\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, request?: Request): 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 if (route.responseType === 'mcp-http') {\n // MCP Streamable HTTP transport - request is required\n if (!request) {\n response.status(500).json({ error: 'Request object required for MCP transport' });\n return;\n }\n\n const { server, httpPath } = result as MCPHttpTransportResult;\n\n try {\n await server.startHTTP({\n url: new URL(request.url, `http://${request.headers.host}`),\n httpPath,\n req: request,\n res: response,\n });\n // Response handled by startHTTP\n } catch {\n if (!response.headersSent) {\n response.status(500).json({\n jsonrpc: '2.0',\n error: { code: -32603, message: 'Internal server error' },\n id: null,\n });\n }\n }\n } else if (route.responseType === 'mcp-sse') {\n // MCP SSE transport - request is required\n if (!request) {\n response.status(500).json({ error: 'Request object required for MCP transport' });\n return;\n }\n\n const { server, ssePath, messagePath } = result as MCPSseTransportResult;\n\n try {\n await server.startSSE({\n url: new URL(request.url, `http://${request.headers.host}`),\n ssePath,\n messagePath,\n req: request,\n res: response,\n });\n // Response handled by startSSE\n } catch {\n if (!response.headersSent) {\n response.status(500).json({ error: 'Error handling MCP SSE request' });\n }\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 instanceof Error ? error.message : String(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, req);\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(): void {\n this.app.use(this.createContextMiddleware());\n }\n\n registerAuthMiddleware(): void {\n const authConfig = this.mastra.getServer()?.auth;\n if (!authConfig) {\n // No auth config, skip registration\n return;\n }\n\n this.app.use(authenticationMiddleware);\n this.app.use(authorizationMiddleware);\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/express",
3
- "version": "0.0.2-beta.0",
3
+ "version": "0.0.2-beta.2",
4
4
  "description": "Mastra Express adapter for the server",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "license": "Apache-2.0",
22
22
  "dependencies": {
23
- "@mastra/server": "1.0.0-beta.5"
23
+ "@mastra/server": "1.0.0-beta.7"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@types/node": "^20.19.0",
@@ -36,14 +36,14 @@
36
36
  "zod": "^3.25.0",
37
37
  "swagger-ui-express": "^5.0.1",
38
38
  "@types/swagger-ui-express": "^4.1.6",
39
- "@internal/lint": "0.0.53",
40
39
  "@internal/server-adapter-test-utils": "0.0.1",
40
+ "@internal/lint": "0.0.53",
41
41
  "@internal/storage-test-utils": "0.0.49",
42
- "@mastra/core": "1.0.0-beta.5",
43
- "@mastra/evals": "1.0.0-beta.1",
44
- "@mastra/observability": "1.0.0-beta.1",
45
- "@mastra/libsql": "1.0.0-beta.2",
46
- "@mastra/memory": "1.0.0-beta.2",
42
+ "@mastra/core": "1.0.0-beta.7",
43
+ "@mastra/evals": "1.0.0-beta.2",
44
+ "@mastra/libsql": "1.0.0-beta.4",
45
+ "@mastra/observability": "1.0.0-beta.3",
46
+ "@mastra/memory": "1.0.0-beta.3",
47
47
  "@internal/types-builder": "0.0.28"
48
48
  },
49
49
  "peerDependencies": {