@mastra/express 0.0.0-main-test-2-20251127211532 → 0.0.0-mastra-auto-detect-server-20260108233416

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.cjs CHANGED
@@ -1,29 +1,335 @@
1
1
  'use strict';
2
2
 
3
- var store = require('@mastra/server/a2a/store');
3
+ var busboy = require('@fastify/busboy');
4
+ var error = require('@mastra/server/handlers/error');
4
5
  var serverAdapter = require('@mastra/server/server-adapter');
6
+ var auth = require('@mastra/server/auth');
5
7
 
6
8
  // src/index.ts
7
- var ExpressServerAdapter = class extends serverAdapter.MastraServerAdapter {
8
- taskStore;
9
- customRouteAuthConfig;
10
- playground;
11
- isDev;
12
- constructor({
13
- mastra,
14
- tools,
15
- taskStore,
16
- customRouteAuthConfig,
17
- playground,
18
- isDev,
19
- bodyLimitOptions
20
- }) {
21
- super({ mastra, bodyLimitOptions, tools });
22
- this.taskStore = taskStore || new store.InMemoryTaskStore();
23
- this.customRouteAuthConfig = customRouteAuthConfig;
24
- this.playground = playground;
25
- this.isDev = isDev;
9
+
10
+ // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js
11
+ var util;
12
+ (function(util2) {
13
+ util2.assertEqual = (_) => {
14
+ };
15
+ function assertIs(_arg) {
16
+ }
17
+ util2.assertIs = assertIs;
18
+ function assertNever(_x) {
19
+ throw new Error();
20
+ }
21
+ util2.assertNever = assertNever;
22
+ util2.arrayToEnum = (items) => {
23
+ const obj = {};
24
+ for (const item of items) {
25
+ obj[item] = item;
26
+ }
27
+ return obj;
28
+ };
29
+ util2.getValidEnumValues = (obj) => {
30
+ const validKeys = util2.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== "number");
31
+ const filtered = {};
32
+ for (const k of validKeys) {
33
+ filtered[k] = obj[k];
34
+ }
35
+ return util2.objectValues(filtered);
36
+ };
37
+ util2.objectValues = (obj) => {
38
+ return util2.objectKeys(obj).map(function(e) {
39
+ return obj[e];
40
+ });
41
+ };
42
+ util2.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object) => {
43
+ const keys = [];
44
+ for (const key in object) {
45
+ if (Object.prototype.hasOwnProperty.call(object, key)) {
46
+ keys.push(key);
47
+ }
48
+ }
49
+ return keys;
50
+ };
51
+ util2.find = (arr, checker) => {
52
+ for (const item of arr) {
53
+ if (checker(item))
54
+ return item;
55
+ }
56
+ return void 0;
57
+ };
58
+ util2.isInteger = typeof Number.isInteger === "function" ? (val) => Number.isInteger(val) : (val) => typeof val === "number" && Number.isFinite(val) && Math.floor(val) === val;
59
+ function joinValues(array, separator = " | ") {
60
+ return array.map((val) => typeof val === "string" ? `'${val}'` : val).join(separator);
61
+ }
62
+ util2.joinValues = joinValues;
63
+ util2.jsonStringifyReplacer = (_, value) => {
64
+ if (typeof value === "bigint") {
65
+ return value.toString();
66
+ }
67
+ return value;
68
+ };
69
+ })(util || (util = {}));
70
+ var objectUtil;
71
+ (function(objectUtil2) {
72
+ objectUtil2.mergeShapes = (first, second) => {
73
+ return {
74
+ ...first,
75
+ ...second
76
+ // second overwrites first
77
+ };
78
+ };
79
+ })(objectUtil || (objectUtil = {}));
80
+ util.arrayToEnum([
81
+ "string",
82
+ "nan",
83
+ "number",
84
+ "integer",
85
+ "float",
86
+ "boolean",
87
+ "date",
88
+ "bigint",
89
+ "symbol",
90
+ "function",
91
+ "undefined",
92
+ "null",
93
+ "array",
94
+ "object",
95
+ "unknown",
96
+ "promise",
97
+ "void",
98
+ "never",
99
+ "map",
100
+ "set"
101
+ ]);
102
+
103
+ // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js
104
+ util.arrayToEnum([
105
+ "invalid_type",
106
+ "invalid_literal",
107
+ "custom",
108
+ "invalid_union",
109
+ "invalid_union_discriminator",
110
+ "invalid_enum_value",
111
+ "unrecognized_keys",
112
+ "invalid_arguments",
113
+ "invalid_return_type",
114
+ "invalid_date",
115
+ "invalid_string",
116
+ "too_small",
117
+ "too_big",
118
+ "invalid_intersection_types",
119
+ "not_multiple_of",
120
+ "not_finite"
121
+ ]);
122
+ var ZodError = class _ZodError extends Error {
123
+ get errors() {
124
+ return this.issues;
125
+ }
126
+ constructor(issues) {
127
+ super();
128
+ this.issues = [];
129
+ this.addIssue = (sub) => {
130
+ this.issues = [...this.issues, sub];
131
+ };
132
+ this.addIssues = (subs = []) => {
133
+ this.issues = [...this.issues, ...subs];
134
+ };
135
+ const actualProto = new.target.prototype;
136
+ if (Object.setPrototypeOf) {
137
+ Object.setPrototypeOf(this, actualProto);
138
+ } else {
139
+ this.__proto__ = actualProto;
140
+ }
141
+ this.name = "ZodError";
142
+ this.issues = issues;
143
+ }
144
+ format(_mapper) {
145
+ const mapper = _mapper || function(issue) {
146
+ return issue.message;
147
+ };
148
+ const fieldErrors = { _errors: [] };
149
+ const processError = (error) => {
150
+ for (const issue of error.issues) {
151
+ if (issue.code === "invalid_union") {
152
+ issue.unionErrors.map(processError);
153
+ } else if (issue.code === "invalid_return_type") {
154
+ processError(issue.returnTypeError);
155
+ } else if (issue.code === "invalid_arguments") {
156
+ processError(issue.argumentsError);
157
+ } else if (issue.path.length === 0) {
158
+ fieldErrors._errors.push(mapper(issue));
159
+ } else {
160
+ let curr = fieldErrors;
161
+ let i = 0;
162
+ while (i < issue.path.length) {
163
+ const el = issue.path[i];
164
+ const terminal = i === issue.path.length - 1;
165
+ if (!terminal) {
166
+ curr[el] = curr[el] || { _errors: [] };
167
+ } else {
168
+ curr[el] = curr[el] || { _errors: [] };
169
+ curr[el]._errors.push(mapper(issue));
170
+ }
171
+ curr = curr[el];
172
+ i++;
173
+ }
174
+ }
175
+ }
176
+ };
177
+ processError(this);
178
+ return fieldErrors;
179
+ }
180
+ static assert(value) {
181
+ if (!(value instanceof _ZodError)) {
182
+ throw new Error(`Not a ZodError: ${value}`);
183
+ }
184
+ }
185
+ toString() {
186
+ return this.message;
187
+ }
188
+ get message() {
189
+ return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2);
190
+ }
191
+ get isEmpty() {
192
+ return this.issues.length === 0;
193
+ }
194
+ flatten(mapper = (issue) => issue.message) {
195
+ const fieldErrors = {};
196
+ const formErrors = [];
197
+ for (const sub of this.issues) {
198
+ if (sub.path.length > 0) {
199
+ const firstEl = sub.path[0];
200
+ fieldErrors[firstEl] = fieldErrors[firstEl] || [];
201
+ fieldErrors[firstEl].push(mapper(sub));
202
+ } else {
203
+ formErrors.push(mapper(sub));
204
+ }
205
+ }
206
+ return { formErrors, fieldErrors };
207
+ }
208
+ get formErrors() {
209
+ return this.flatten();
210
+ }
211
+ };
212
+ ZodError.create = (issues) => {
213
+ const error = new ZodError(issues);
214
+ return error;
215
+ };
216
+ var authenticationMiddleware = async (req, res, next) => {
217
+ const mastra = res.locals.mastra;
218
+ const authConfig = mastra.getServer()?.auth;
219
+ const customRouteAuthConfig = res.locals.customRouteAuthConfig;
220
+ if (!authConfig) {
221
+ return next();
222
+ }
223
+ const path = req.path;
224
+ const method = req.method;
225
+ const getHeader = (name) => req.headers[name.toLowerCase()];
226
+ if (auth.isDevPlaygroundRequest(path, method, getHeader, authConfig)) {
227
+ return next();
228
+ }
229
+ if (!auth.isProtectedPath(req.path, req.method, authConfig, customRouteAuthConfig)) {
230
+ return next();
231
+ }
232
+ if (auth.canAccessPublicly(req.path, req.method, authConfig)) {
233
+ return next();
234
+ }
235
+ const authHeader = req.headers.authorization;
236
+ let token = authHeader ? authHeader.replace("Bearer ", "") : null;
237
+ if (!token && req.query.apiKey) {
238
+ token = req.query.apiKey || null;
239
+ }
240
+ if (!token) {
241
+ return res.status(401).json({ error: "Authentication required" });
242
+ }
243
+ try {
244
+ let user;
245
+ if (typeof authConfig.authenticateToken === "function") {
246
+ user = await authConfig.authenticateToken(token, req);
247
+ } else {
248
+ throw new Error("No token verification method configured");
249
+ }
250
+ if (!user) {
251
+ return res.status(401).json({ error: "Invalid or expired token" });
252
+ }
253
+ res.locals.requestContext.set("user", user);
254
+ return next();
255
+ } catch (err) {
256
+ console.error(err);
257
+ return res.status(401).json({ error: "Invalid or expired token" });
258
+ }
259
+ };
260
+ var authorizationMiddleware = async (req, res, next) => {
261
+ const mastra = res.locals.mastra;
262
+ const authConfig = mastra.getServer()?.auth;
263
+ const customRouteAuthConfig = res.locals.customRouteAuthConfig;
264
+ if (!authConfig) {
265
+ return next();
26
266
  }
267
+ const path = req.path;
268
+ const method = req.method;
269
+ const getHeader = (name) => req.headers[name.toLowerCase()];
270
+ if (auth.isDevPlaygroundRequest(path, method, getHeader, authConfig)) {
271
+ return next();
272
+ }
273
+ if (!auth.isProtectedPath(req.path, req.method, authConfig, customRouteAuthConfig)) {
274
+ return next();
275
+ }
276
+ if (auth.canAccessPublicly(path, method, authConfig)) {
277
+ return next();
278
+ }
279
+ const user = res.locals.requestContext.get("user");
280
+ if ("authorizeUser" in authConfig && typeof authConfig.authorizeUser === "function") {
281
+ try {
282
+ const isAuthorized = await authConfig.authorizeUser(user, req);
283
+ if (isAuthorized) {
284
+ return next();
285
+ }
286
+ return res.status(403).json({ error: "Access denied" });
287
+ } catch (err) {
288
+ console.error(err);
289
+ return res.status(500).json({ error: "Authorization error" });
290
+ }
291
+ }
292
+ if ("authorize" in authConfig && typeof authConfig.authorize === "function") {
293
+ try {
294
+ const context = {
295
+ get: (key) => {
296
+ if (key === "mastra") return res.locals.mastra;
297
+ if (key === "requestContext") return res.locals.requestContext;
298
+ if (key === "tools") return res.locals.tools;
299
+ if (key === "taskStore") return res.locals.taskStore;
300
+ if (key === "customRouteAuthConfig") return res.locals.customRouteAuthConfig;
301
+ return void 0;
302
+ },
303
+ req
304
+ };
305
+ const isAuthorized = await authConfig.authorize(path, method, user, context);
306
+ if (isAuthorized) {
307
+ return next();
308
+ }
309
+ return res.status(403).json({ error: "Access denied" });
310
+ } catch (err) {
311
+ console.error(err);
312
+ return res.status(500).json({ error: "Authorization error" });
313
+ }
314
+ }
315
+ if ("rules" in authConfig && authConfig.rules && authConfig.rules.length > 0) {
316
+ const isAuthorized = await auth.checkRules(authConfig.rules, path, method, user);
317
+ if (isAuthorized) {
318
+ return next();
319
+ }
320
+ return res.status(403).json({ error: "Access denied" });
321
+ }
322
+ if (auth.defaultAuthConfig.rules && auth.defaultAuthConfig.rules.length > 0) {
323
+ const isAuthorized = await auth.checkRules(auth.defaultAuthConfig.rules, path, method, user);
324
+ if (isAuthorized) {
325
+ return next();
326
+ }
327
+ }
328
+ return res.status(403).json({ error: "Access denied" });
329
+ };
330
+
331
+ // src/index.ts
332
+ var MastraServer = class extends serverAdapter.MastraServer {
27
333
  createContextMiddleware() {
28
334
  return async (req, res, next) => {
29
335
  let bodyRequestContext;
@@ -57,13 +363,15 @@ var ExpressServerAdapter = class extends serverAdapter.MastraServerAdapter {
57
363
  res.locals.requestContext = requestContext;
58
364
  res.locals.mastra = this.mastra;
59
365
  res.locals.tools = this.tools || {};
60
- res.locals.taskStore = this.taskStore;
61
- res.locals.playground = this.playground === true;
62
- res.locals.isDev = this.isDev === true;
366
+ if (this.taskStore) {
367
+ res.locals.taskStore = this.taskStore;
368
+ }
63
369
  res.locals.customRouteAuthConfig = this.customRouteAuthConfig;
64
370
  const controller = new AbortController();
65
- req.on("close", () => {
66
- controller.abort();
371
+ res.on("close", () => {
372
+ if (!res.writableFinished) {
373
+ controller.abort();
374
+ }
67
375
  });
68
376
  res.locals.abortSignal = controller.signal;
69
377
  next();
@@ -80,12 +388,14 @@ var ExpressServerAdapter = class extends serverAdapter.MastraServerAdapter {
80
388
  const { done, value } = await reader.read();
81
389
  if (done) break;
82
390
  if (value) {
391
+ const shouldRedact = this.streamOptions?.redact ?? true;
392
+ const outputValue = shouldRedact ? serverAdapter.redactStreamChunk(value) : value;
83
393
  if (streamFormat === "sse") {
84
- res.write(`data: ${JSON.stringify(value)}
394
+ res.write(`data: ${JSON.stringify(outputValue)}
85
395
 
86
396
  `);
87
397
  } else {
88
- res.write(JSON.stringify(value) + "");
398
+ res.write(JSON.stringify(outputValue) + "");
89
399
  }
90
400
  }
91
401
  }
@@ -97,11 +407,75 @@ var ExpressServerAdapter = class extends serverAdapter.MastraServerAdapter {
97
407
  }
98
408
  async getParams(route, request) {
99
409
  const urlParams = request.params;
100
- const queryParams = request.query;
101
- const body = await request.body;
410
+ const queryParams = serverAdapter.normalizeQueryParams(request.query);
411
+ let body;
412
+ if (route.method === "POST" || route.method === "PUT" || route.method === "PATCH") {
413
+ const contentType = request.headers["content-type"] || "";
414
+ if (contentType.includes("multipart/form-data")) {
415
+ try {
416
+ const maxFileSize = route.maxBodySize ?? this.bodyLimitOptions?.maxSize;
417
+ body = await this.parseMultipartFormData(request, maxFileSize);
418
+ } catch (error) {
419
+ console.error("Failed to parse multipart form data:", error);
420
+ if (error instanceof Error && error.message.toLowerCase().includes("size")) {
421
+ throw error;
422
+ }
423
+ }
424
+ } else {
425
+ body = request.body;
426
+ }
427
+ }
102
428
  return { urlParams, queryParams, body };
103
429
  }
104
- async sendResponse(route, response, result) {
430
+ /**
431
+ * Parse multipart/form-data using @fastify/busboy.
432
+ * Converts file uploads to Buffers and parses JSON field values.
433
+ *
434
+ * @param request - The Express request object
435
+ * @param maxFileSize - Optional maximum file size in bytes
436
+ */
437
+ parseMultipartFormData(request, maxFileSize) {
438
+ return new Promise((resolve, reject) => {
439
+ const result = {};
440
+ const busboy$1 = new busboy.Busboy({
441
+ headers: {
442
+ "content-type": request.headers["content-type"]
443
+ },
444
+ limits: maxFileSize ? { fileSize: maxFileSize } : void 0
445
+ });
446
+ busboy$1.on("file", (fieldname, file) => {
447
+ const chunks = [];
448
+ let limitExceeded = false;
449
+ file.on("data", (chunk) => {
450
+ chunks.push(chunk);
451
+ });
452
+ file.on("limit", () => {
453
+ limitExceeded = true;
454
+ reject(new Error(`File size limit exceeded${maxFileSize ? ` (max: ${maxFileSize} bytes)` : ""}`));
455
+ });
456
+ file.on("end", () => {
457
+ if (!limitExceeded) {
458
+ result[fieldname] = Buffer.concat(chunks);
459
+ }
460
+ });
461
+ });
462
+ busboy$1.on("field", (fieldname, value) => {
463
+ try {
464
+ result[fieldname] = JSON.parse(value);
465
+ } catch {
466
+ result[fieldname] = value;
467
+ }
468
+ });
469
+ busboy$1.on("finish", () => {
470
+ resolve(result);
471
+ });
472
+ busboy$1.on("error", (error) => {
473
+ reject(error);
474
+ });
475
+ request.pipe(busboy$1);
476
+ });
477
+ }
478
+ async sendResponse(route, response, result, request) {
105
479
  if (route.responseType === "json") {
106
480
  response.json(result);
107
481
  } else if (route.responseType === "stream") {
@@ -124,6 +498,47 @@ var ExpressServerAdapter = class extends serverAdapter.MastraServerAdapter {
124
498
  } else {
125
499
  response.end();
126
500
  }
501
+ } else if (route.responseType === "mcp-http") {
502
+ if (!request) {
503
+ response.status(500).json({ error: "Request object required for MCP transport" });
504
+ return;
505
+ }
506
+ const { server, httpPath } = result;
507
+ try {
508
+ await server.startHTTP({
509
+ url: new URL(request.url, `http://${request.headers.host}`),
510
+ httpPath,
511
+ req: request,
512
+ res: response
513
+ });
514
+ } catch {
515
+ if (!response.headersSent) {
516
+ response.status(500).json({
517
+ jsonrpc: "2.0",
518
+ error: { code: -32603, message: "Internal server error" },
519
+ id: null
520
+ });
521
+ }
522
+ }
523
+ } else if (route.responseType === "mcp-sse") {
524
+ if (!request) {
525
+ response.status(500).json({ error: "Request object required for MCP transport" });
526
+ return;
527
+ }
528
+ const { server, ssePath, messagePath } = result;
529
+ try {
530
+ await server.startSSE({
531
+ url: new URL(request.url, `http://${request.headers.host}`),
532
+ ssePath,
533
+ messagePath,
534
+ req: request,
535
+ res: response
536
+ });
537
+ } catch {
538
+ if (!response.headersSent) {
539
+ response.status(500).json({ error: "Error handling MCP SSE request" });
540
+ }
541
+ }
127
542
  } else {
128
543
  response.sendStatus(500);
129
544
  }
@@ -155,22 +570,28 @@ var ExpressServerAdapter = class extends serverAdapter.MastraServerAdapter {
155
570
  if (params.queryParams) {
156
571
  try {
157
572
  params.queryParams = await this.parseQueryParams(route, params.queryParams);
158
- } catch (error) {
159
- console.error("Error parsing query params", error);
573
+ } catch (error$1) {
574
+ console.error("Error parsing query params", error$1);
575
+ if (error$1 instanceof ZodError) {
576
+ return res.status(400).json(error.formatZodError(error$1, "query parameters"));
577
+ }
160
578
  return res.status(400).json({
161
579
  error: "Invalid query parameters",
162
- details: error instanceof Error ? error.message : "Unknown error"
580
+ issues: [{ field: "unknown", message: error$1 instanceof Error ? error$1.message : "Unknown error" }]
163
581
  });
164
582
  }
165
583
  }
166
584
  if (params.body) {
167
585
  try {
168
586
  params.body = await this.parseBody(route, params.body);
169
- } catch (error) {
170
- console.error("Error parsing body", error);
587
+ } catch (error$1) {
588
+ console.error("Error parsing body:", error$1 instanceof Error ? error$1.message : String(error$1));
589
+ if (error$1 instanceof ZodError) {
590
+ return res.status(400).json(error.formatZodError(error$1, "request body"));
591
+ }
171
592
  return res.status(400).json({
172
593
  error: "Invalid request body",
173
- details: error instanceof Error ? error.message : "Unknown error"
594
+ issues: [{ field: "unknown", message: error$1 instanceof Error ? error$1.message : "Unknown error" }]
174
595
  });
175
596
  }
176
597
  }
@@ -186,7 +607,7 @@ var ExpressServerAdapter = class extends serverAdapter.MastraServerAdapter {
186
607
  };
187
608
  try {
188
609
  const result = await route.handler(handlerParams);
189
- await this.sendResponse(route, res, result);
610
+ await this.sendResponse(route, res, result, req);
190
611
  } catch (error) {
191
612
  console.error("Error calling handler", error);
192
613
  let status = 500;
@@ -202,14 +623,19 @@ var ExpressServerAdapter = class extends serverAdapter.MastraServerAdapter {
202
623
  }
203
624
  );
204
625
  }
205
- registerContextMiddleware(app) {
206
- app.use(this.createContextMiddleware());
626
+ registerContextMiddleware() {
627
+ this.app.use(this.createContextMiddleware());
207
628
  }
208
- async registerRoutes(app, { prefix, openapiPath }) {
209
- await super.registerRoutes(app, { prefix, openapiPath });
629
+ registerAuthMiddleware() {
630
+ const authConfig = this.mastra.getServer()?.auth;
631
+ if (!authConfig) {
632
+ return;
633
+ }
634
+ this.app.use(authenticationMiddleware);
635
+ this.app.use(authorizationMiddleware);
210
636
  }
211
637
  };
212
638
 
213
- exports.ExpressServerAdapter = ExpressServerAdapter;
639
+ exports.MastraServer = MastraServer;
214
640
  //# sourceMappingURL=index.cjs.map
215
641
  //# sourceMappingURL=index.cjs.map