@mastra/hono 0.0.0-trace-timeline-update-20251121114225 → 0.0.0-unified-workspace-snapshot-20260128233410
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/CHANGELOG.md +409 -2637
- package/README.md +37 -433
- package/dist/auth-middleware.d.ts +11 -0
- package/dist/auth-middleware.d.ts.map +1 -0
- package/dist/index.cjs +484 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +36 -34
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +482 -51
- package/dist/index.js.map +1 -1
- package/package.json +16 -15
package/dist/index.js
CHANGED
|
@@ -1,17 +1,29 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { formatZodError } from '@mastra/server/handlers/error';
|
|
2
|
+
import { MastraServer as MastraServer$1, normalizeQueryParams, redactStreamChunk } from '@mastra/server/server-adapter';
|
|
3
|
+
import { toReqRes, toFetchResponse } from 'fetch-to-node';
|
|
4
|
+
import { isDevPlaygroundRequest, isProtectedPath, canAccessPublicly, checkRules, defaultAuthConfig } from '@mastra/server/auth';
|
|
3
5
|
|
|
4
6
|
// src/index.ts
|
|
5
7
|
|
|
6
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
8
|
+
// ../../node_modules/.pnpm/hono@4.11.3/node_modules/hono/dist/http-exception.js
|
|
7
9
|
var HTTPException = class extends Error {
|
|
8
10
|
res;
|
|
9
11
|
status;
|
|
12
|
+
/**
|
|
13
|
+
* Creates an instance of `HTTPException`.
|
|
14
|
+
* @param status - HTTP status code for the exception. Defaults to 500.
|
|
15
|
+
* @param options - Additional options for the exception.
|
|
16
|
+
*/
|
|
10
17
|
constructor(status = 500, options) {
|
|
11
18
|
super(options?.message, { cause: options?.cause });
|
|
12
19
|
this.res = options?.res;
|
|
13
20
|
this.status = status;
|
|
14
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Returns the response object associated with the exception.
|
|
24
|
+
* If a response object is not provided, a new response is created with the error message and status code.
|
|
25
|
+
* @returns The response object.
|
|
26
|
+
*/
|
|
15
27
|
getResponse() {
|
|
16
28
|
if (this.res) {
|
|
17
29
|
const newResponse = new Response(this.res.body, {
|
|
@@ -26,7 +38,7 @@ var HTTPException = class extends Error {
|
|
|
26
38
|
}
|
|
27
39
|
};
|
|
28
40
|
|
|
29
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
41
|
+
// ../../node_modules/.pnpm/hono@4.11.3/node_modules/hono/dist/middleware/body-limit/index.js
|
|
30
42
|
var ERROR_MESSAGE = "Payload Too Large";
|
|
31
43
|
var BodyLimitError = class extends Error {
|
|
32
44
|
constructor(message) {
|
|
@@ -83,14 +95,20 @@ var bodyLimit = (options) => {
|
|
|
83
95
|
};
|
|
84
96
|
};
|
|
85
97
|
|
|
86
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
98
|
+
// ../../node_modules/.pnpm/hono@4.11.3/node_modules/hono/dist/utils/stream.js
|
|
87
99
|
var StreamingApi = class {
|
|
88
100
|
writer;
|
|
89
101
|
encoder;
|
|
90
102
|
writable;
|
|
91
103
|
abortSubscribers = [];
|
|
92
104
|
responseReadable;
|
|
105
|
+
/**
|
|
106
|
+
* Whether the stream has been aborted.
|
|
107
|
+
*/
|
|
93
108
|
aborted = false;
|
|
109
|
+
/**
|
|
110
|
+
* Whether the stream has been closed normally.
|
|
111
|
+
*/
|
|
94
112
|
closed = false;
|
|
95
113
|
constructor(writable, _readable) {
|
|
96
114
|
this.writable = writable;
|
|
@@ -142,6 +160,10 @@ var StreamingApi = class {
|
|
|
142
160
|
onAbort(listener) {
|
|
143
161
|
this.abortSubscribers.push(listener);
|
|
144
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Abort the stream.
|
|
165
|
+
* You can call this method when stream is aborted by external event.
|
|
166
|
+
*/
|
|
145
167
|
abort() {
|
|
146
168
|
if (!this.aborted) {
|
|
147
169
|
this.aborted = true;
|
|
@@ -150,7 +172,7 @@ var StreamingApi = class {
|
|
|
150
172
|
}
|
|
151
173
|
};
|
|
152
174
|
|
|
153
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
175
|
+
// ../../node_modules/.pnpm/hono@4.11.3/node_modules/hono/dist/helper/streaming/utils.js
|
|
154
176
|
var isOldBunVersion = () => {
|
|
155
177
|
const version = typeof Bun !== "undefined" ? Bun.version : void 0;
|
|
156
178
|
if (version === void 0) {
|
|
@@ -161,7 +183,7 @@ var isOldBunVersion = () => {
|
|
|
161
183
|
return result;
|
|
162
184
|
};
|
|
163
185
|
|
|
164
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
186
|
+
// ../../node_modules/.pnpm/hono@4.11.3/node_modules/hono/dist/helper/streaming/stream.js
|
|
165
187
|
var contextStash = /* @__PURE__ */ new WeakMap();
|
|
166
188
|
var stream = (c, cb, onError) => {
|
|
167
189
|
const { readable, writable } = new TransformStream();
|
|
@@ -190,27 +212,318 @@ var stream = (c, cb, onError) => {
|
|
|
190
212
|
return c.newResponse(stream2.responseReadable);
|
|
191
213
|
};
|
|
192
214
|
|
|
193
|
-
//
|
|
194
|
-
var
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
215
|
+
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js
|
|
216
|
+
var util;
|
|
217
|
+
(function(util2) {
|
|
218
|
+
util2.assertEqual = (_) => {
|
|
219
|
+
};
|
|
220
|
+
function assertIs(_arg) {
|
|
221
|
+
}
|
|
222
|
+
util2.assertIs = assertIs;
|
|
223
|
+
function assertNever(_x) {
|
|
224
|
+
throw new Error();
|
|
225
|
+
}
|
|
226
|
+
util2.assertNever = assertNever;
|
|
227
|
+
util2.arrayToEnum = (items) => {
|
|
228
|
+
const obj = {};
|
|
229
|
+
for (const item of items) {
|
|
230
|
+
obj[item] = item;
|
|
231
|
+
}
|
|
232
|
+
return obj;
|
|
233
|
+
};
|
|
234
|
+
util2.getValidEnumValues = (obj) => {
|
|
235
|
+
const validKeys = util2.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== "number");
|
|
236
|
+
const filtered = {};
|
|
237
|
+
for (const k of validKeys) {
|
|
238
|
+
filtered[k] = obj[k];
|
|
239
|
+
}
|
|
240
|
+
return util2.objectValues(filtered);
|
|
241
|
+
};
|
|
242
|
+
util2.objectValues = (obj) => {
|
|
243
|
+
return util2.objectKeys(obj).map(function(e) {
|
|
244
|
+
return obj[e];
|
|
245
|
+
});
|
|
246
|
+
};
|
|
247
|
+
util2.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object) => {
|
|
248
|
+
const keys = [];
|
|
249
|
+
for (const key in object) {
|
|
250
|
+
if (Object.prototype.hasOwnProperty.call(object, key)) {
|
|
251
|
+
keys.push(key);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return keys;
|
|
255
|
+
};
|
|
256
|
+
util2.find = (arr, checker) => {
|
|
257
|
+
for (const item of arr) {
|
|
258
|
+
if (checker(item))
|
|
259
|
+
return item;
|
|
260
|
+
}
|
|
261
|
+
return void 0;
|
|
262
|
+
};
|
|
263
|
+
util2.isInteger = typeof Number.isInteger === "function" ? (val) => Number.isInteger(val) : (val) => typeof val === "number" && Number.isFinite(val) && Math.floor(val) === val;
|
|
264
|
+
function joinValues(array, separator = " | ") {
|
|
265
|
+
return array.map((val) => typeof val === "string" ? `'${val}'` : val).join(separator);
|
|
266
|
+
}
|
|
267
|
+
util2.joinValues = joinValues;
|
|
268
|
+
util2.jsonStringifyReplacer = (_, value) => {
|
|
269
|
+
if (typeof value === "bigint") {
|
|
270
|
+
return value.toString();
|
|
271
|
+
}
|
|
272
|
+
return value;
|
|
273
|
+
};
|
|
274
|
+
})(util || (util = {}));
|
|
275
|
+
var objectUtil;
|
|
276
|
+
(function(objectUtil2) {
|
|
277
|
+
objectUtil2.mergeShapes = (first, second) => {
|
|
278
|
+
return {
|
|
279
|
+
...first,
|
|
280
|
+
...second
|
|
281
|
+
// second overwrites first
|
|
282
|
+
};
|
|
283
|
+
};
|
|
284
|
+
})(objectUtil || (objectUtil = {}));
|
|
285
|
+
util.arrayToEnum([
|
|
286
|
+
"string",
|
|
287
|
+
"nan",
|
|
288
|
+
"number",
|
|
289
|
+
"integer",
|
|
290
|
+
"float",
|
|
291
|
+
"boolean",
|
|
292
|
+
"date",
|
|
293
|
+
"bigint",
|
|
294
|
+
"symbol",
|
|
295
|
+
"function",
|
|
296
|
+
"undefined",
|
|
297
|
+
"null",
|
|
298
|
+
"array",
|
|
299
|
+
"object",
|
|
300
|
+
"unknown",
|
|
301
|
+
"promise",
|
|
302
|
+
"void",
|
|
303
|
+
"never",
|
|
304
|
+
"map",
|
|
305
|
+
"set"
|
|
306
|
+
]);
|
|
307
|
+
|
|
308
|
+
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js
|
|
309
|
+
util.arrayToEnum([
|
|
310
|
+
"invalid_type",
|
|
311
|
+
"invalid_literal",
|
|
312
|
+
"custom",
|
|
313
|
+
"invalid_union",
|
|
314
|
+
"invalid_union_discriminator",
|
|
315
|
+
"invalid_enum_value",
|
|
316
|
+
"unrecognized_keys",
|
|
317
|
+
"invalid_arguments",
|
|
318
|
+
"invalid_return_type",
|
|
319
|
+
"invalid_date",
|
|
320
|
+
"invalid_string",
|
|
321
|
+
"too_small",
|
|
322
|
+
"too_big",
|
|
323
|
+
"invalid_intersection_types",
|
|
324
|
+
"not_multiple_of",
|
|
325
|
+
"not_finite"
|
|
326
|
+
]);
|
|
327
|
+
var ZodError = class _ZodError extends Error {
|
|
328
|
+
get errors() {
|
|
329
|
+
return this.issues;
|
|
330
|
+
}
|
|
331
|
+
constructor(issues) {
|
|
332
|
+
super();
|
|
333
|
+
this.issues = [];
|
|
334
|
+
this.addIssue = (sub) => {
|
|
335
|
+
this.issues = [...this.issues, sub];
|
|
336
|
+
};
|
|
337
|
+
this.addIssues = (subs = []) => {
|
|
338
|
+
this.issues = [...this.issues, ...subs];
|
|
339
|
+
};
|
|
340
|
+
const actualProto = new.target.prototype;
|
|
341
|
+
if (Object.setPrototypeOf) {
|
|
342
|
+
Object.setPrototypeOf(this, actualProto);
|
|
343
|
+
} else {
|
|
344
|
+
this.__proto__ = actualProto;
|
|
345
|
+
}
|
|
346
|
+
this.name = "ZodError";
|
|
347
|
+
this.issues = issues;
|
|
348
|
+
}
|
|
349
|
+
format(_mapper) {
|
|
350
|
+
const mapper = _mapper || function(issue) {
|
|
351
|
+
return issue.message;
|
|
352
|
+
};
|
|
353
|
+
const fieldErrors = { _errors: [] };
|
|
354
|
+
const processError = (error) => {
|
|
355
|
+
for (const issue of error.issues) {
|
|
356
|
+
if (issue.code === "invalid_union") {
|
|
357
|
+
issue.unionErrors.map(processError);
|
|
358
|
+
} else if (issue.code === "invalid_return_type") {
|
|
359
|
+
processError(issue.returnTypeError);
|
|
360
|
+
} else if (issue.code === "invalid_arguments") {
|
|
361
|
+
processError(issue.argumentsError);
|
|
362
|
+
} else if (issue.path.length === 0) {
|
|
363
|
+
fieldErrors._errors.push(mapper(issue));
|
|
364
|
+
} else {
|
|
365
|
+
let curr = fieldErrors;
|
|
366
|
+
let i = 0;
|
|
367
|
+
while (i < issue.path.length) {
|
|
368
|
+
const el = issue.path[i];
|
|
369
|
+
const terminal = i === issue.path.length - 1;
|
|
370
|
+
if (!terminal) {
|
|
371
|
+
curr[el] = curr[el] || { _errors: [] };
|
|
372
|
+
} else {
|
|
373
|
+
curr[el] = curr[el] || { _errors: [] };
|
|
374
|
+
curr[el]._errors.push(mapper(issue));
|
|
375
|
+
}
|
|
376
|
+
curr = curr[el];
|
|
377
|
+
i++;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
processError(this);
|
|
383
|
+
return fieldErrors;
|
|
384
|
+
}
|
|
385
|
+
static assert(value) {
|
|
386
|
+
if (!(value instanceof _ZodError)) {
|
|
387
|
+
throw new Error(`Not a ZodError: ${value}`);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
toString() {
|
|
391
|
+
return this.message;
|
|
392
|
+
}
|
|
393
|
+
get message() {
|
|
394
|
+
return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2);
|
|
395
|
+
}
|
|
396
|
+
get isEmpty() {
|
|
397
|
+
return this.issues.length === 0;
|
|
398
|
+
}
|
|
399
|
+
flatten(mapper = (issue) => issue.message) {
|
|
400
|
+
const fieldErrors = {};
|
|
401
|
+
const formErrors = [];
|
|
402
|
+
for (const sub of this.issues) {
|
|
403
|
+
if (sub.path.length > 0) {
|
|
404
|
+
const firstEl = sub.path[0];
|
|
405
|
+
fieldErrors[firstEl] = fieldErrors[firstEl] || [];
|
|
406
|
+
fieldErrors[firstEl].push(mapper(sub));
|
|
407
|
+
} else {
|
|
408
|
+
formErrors.push(mapper(sub));
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return { formErrors, fieldErrors };
|
|
213
412
|
}
|
|
413
|
+
get formErrors() {
|
|
414
|
+
return this.flatten();
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
ZodError.create = (issues) => {
|
|
418
|
+
const error = new ZodError(issues);
|
|
419
|
+
return error;
|
|
420
|
+
};
|
|
421
|
+
var authenticationMiddleware = async (c, next) => {
|
|
422
|
+
const mastra = c.get("mastra");
|
|
423
|
+
const authConfig = mastra.getServer()?.auth;
|
|
424
|
+
const customRouteAuthConfig = c.get("customRouteAuthConfig");
|
|
425
|
+
if (!authConfig) {
|
|
426
|
+
return next();
|
|
427
|
+
}
|
|
428
|
+
const path = c.req.path;
|
|
429
|
+
const method = c.req.method;
|
|
430
|
+
const getHeader = (name) => c.req.header(name);
|
|
431
|
+
if (isDevPlaygroundRequest(path, method, getHeader, authConfig, customRouteAuthConfig)) {
|
|
432
|
+
return next();
|
|
433
|
+
}
|
|
434
|
+
if (!isProtectedPath(c.req.path, c.req.method, authConfig, customRouteAuthConfig)) {
|
|
435
|
+
return next();
|
|
436
|
+
}
|
|
437
|
+
if (canAccessPublicly(c.req.path, c.req.method, authConfig)) {
|
|
438
|
+
return next();
|
|
439
|
+
}
|
|
440
|
+
const authHeader = c.req.header("Authorization");
|
|
441
|
+
let token = authHeader ? authHeader.replace("Bearer ", "") : null;
|
|
442
|
+
if (!token && c.req.query("apiKey")) {
|
|
443
|
+
token = c.req.query("apiKey") || null;
|
|
444
|
+
}
|
|
445
|
+
if (!token) {
|
|
446
|
+
return c.json({ error: "Authentication required" }, 401);
|
|
447
|
+
}
|
|
448
|
+
try {
|
|
449
|
+
let user;
|
|
450
|
+
if (typeof authConfig.authenticateToken === "function") {
|
|
451
|
+
user = await authConfig.authenticateToken(token, c.req);
|
|
452
|
+
} else {
|
|
453
|
+
throw new Error("No token verification method configured");
|
|
454
|
+
}
|
|
455
|
+
if (!user) {
|
|
456
|
+
return c.json({ error: "Invalid or expired token" }, 401);
|
|
457
|
+
}
|
|
458
|
+
c.get("requestContext").set("user", user);
|
|
459
|
+
return next();
|
|
460
|
+
} catch (err) {
|
|
461
|
+
console.error(err);
|
|
462
|
+
return c.json({ error: "Invalid or expired token" }, 401);
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
var authorizationMiddleware = async (c, next) => {
|
|
466
|
+
const mastra = c.get("mastra");
|
|
467
|
+
const authConfig = mastra.getServer()?.auth;
|
|
468
|
+
const customRouteAuthConfig = c.get("customRouteAuthConfig");
|
|
469
|
+
if (!authConfig) {
|
|
470
|
+
return next();
|
|
471
|
+
}
|
|
472
|
+
const path = c.req.path;
|
|
473
|
+
const method = c.req.method;
|
|
474
|
+
const getHeader = (name) => c.req.header(name);
|
|
475
|
+
if (isDevPlaygroundRequest(path, method, getHeader, authConfig, customRouteAuthConfig)) {
|
|
476
|
+
return next();
|
|
477
|
+
}
|
|
478
|
+
if (!isProtectedPath(c.req.path, c.req.method, authConfig, customRouteAuthConfig)) {
|
|
479
|
+
return next();
|
|
480
|
+
}
|
|
481
|
+
if (canAccessPublicly(path, method, authConfig)) {
|
|
482
|
+
return next();
|
|
483
|
+
}
|
|
484
|
+
const user = c.get("requestContext").get("user");
|
|
485
|
+
if ("authorizeUser" in authConfig && typeof authConfig.authorizeUser === "function") {
|
|
486
|
+
try {
|
|
487
|
+
const isAuthorized = await authConfig.authorizeUser(user, c.req);
|
|
488
|
+
if (isAuthorized) {
|
|
489
|
+
return next();
|
|
490
|
+
}
|
|
491
|
+
return c.json({ error: "Access denied" }, 403);
|
|
492
|
+
} catch (err) {
|
|
493
|
+
console.error(err);
|
|
494
|
+
return c.json({ error: "Authorization error" }, 500);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
if ("authorize" in authConfig && typeof authConfig.authorize === "function") {
|
|
498
|
+
try {
|
|
499
|
+
const isAuthorized = await authConfig.authorize(path, method, user, c);
|
|
500
|
+
if (isAuthorized) {
|
|
501
|
+
return next();
|
|
502
|
+
}
|
|
503
|
+
return c.json({ error: "Access denied" }, 403);
|
|
504
|
+
} catch (err) {
|
|
505
|
+
console.error(err);
|
|
506
|
+
return c.json({ error: "Authorization error" }, 500);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
if ("rules" in authConfig && authConfig.rules && authConfig.rules.length > 0) {
|
|
510
|
+
const isAuthorized = await checkRules(authConfig.rules, path, method, user);
|
|
511
|
+
if (isAuthorized) {
|
|
512
|
+
return next();
|
|
513
|
+
}
|
|
514
|
+
return c.json({ error: "Access denied" }, 403);
|
|
515
|
+
}
|
|
516
|
+
if (defaultAuthConfig.rules && defaultAuthConfig.rules.length > 0) {
|
|
517
|
+
const isAuthorized = await checkRules(defaultAuthConfig.rules, path, method, user);
|
|
518
|
+
if (isAuthorized) {
|
|
519
|
+
return next();
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
return c.json({ error: "Access denied" }, 403);
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
// src/index.ts
|
|
526
|
+
var MastraServer = class extends MastraServer$1 {
|
|
214
527
|
createContextMiddleware() {
|
|
215
528
|
return async (c, next) => {
|
|
216
529
|
let bodyRequestContext;
|
|
@@ -248,12 +561,10 @@ var HonoServerAdapter = class extends MastraServerAdapter {
|
|
|
248
561
|
const requestContext = this.mergeRequestContext({ paramsRequestContext, bodyRequestContext });
|
|
249
562
|
c.set("requestContext", requestContext);
|
|
250
563
|
c.set("mastra", this.mastra);
|
|
251
|
-
c.set("
|
|
564
|
+
c.set("registeredTools", this.tools || {});
|
|
252
565
|
c.set("taskStore", this.taskStore);
|
|
253
|
-
c.set("playground", this.playground === true);
|
|
254
|
-
c.set("isDev", this.isDev === true);
|
|
255
|
-
c.set("customRouteAuthConfig", this.customRouteAuthConfig);
|
|
256
566
|
c.set("abortSignal", c.req.raw.signal);
|
|
567
|
+
c.set("customRouteAuthConfig", this.customRouteAuthConfig);
|
|
257
568
|
return next();
|
|
258
569
|
};
|
|
259
570
|
}
|
|
@@ -274,12 +585,14 @@ var HonoServerAdapter = class extends MastraServerAdapter {
|
|
|
274
585
|
const { done, value } = await reader.read();
|
|
275
586
|
if (done) break;
|
|
276
587
|
if (value) {
|
|
588
|
+
const shouldRedact = this.streamOptions?.redact ?? true;
|
|
589
|
+
const outputValue = shouldRedact ? redactStreamChunk(value) : value;
|
|
277
590
|
if (streamFormat === "sse") {
|
|
278
|
-
await stream2.write(`data: ${JSON.stringify(
|
|
591
|
+
await stream2.write(`data: ${JSON.stringify(outputValue)}
|
|
279
592
|
|
|
280
593
|
`);
|
|
281
594
|
} else {
|
|
282
|
-
await stream2.write(JSON.stringify(
|
|
595
|
+
await stream2.write(JSON.stringify(outputValue) + "");
|
|
283
596
|
}
|
|
284
597
|
}
|
|
285
598
|
}
|
|
@@ -297,17 +610,64 @@ var HonoServerAdapter = class extends MastraServerAdapter {
|
|
|
297
610
|
}
|
|
298
611
|
async getParams(route, request) {
|
|
299
612
|
const urlParams = request.param();
|
|
300
|
-
const queryParams = request.
|
|
613
|
+
const queryParams = normalizeQueryParams(request.queries());
|
|
301
614
|
let body;
|
|
615
|
+
let bodyParseError;
|
|
302
616
|
if (route.method === "POST" || route.method === "PUT" || route.method === "PATCH") {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
617
|
+
const contentType = request.header("content-type") || "";
|
|
618
|
+
if (contentType.includes("multipart/form-data")) {
|
|
619
|
+
try {
|
|
620
|
+
const formData = await request.formData();
|
|
621
|
+
body = await this.parseFormData(formData);
|
|
622
|
+
} catch (error) {
|
|
623
|
+
console.error("Failed to parse multipart form data:", error);
|
|
624
|
+
if (error instanceof Error && error.message.toLowerCase().includes("size")) {
|
|
625
|
+
throw error;
|
|
626
|
+
}
|
|
627
|
+
bodyParseError = {
|
|
628
|
+
message: error instanceof Error ? error.message : "Failed to parse multipart form data"
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
} else if (contentType.includes("application/json")) {
|
|
632
|
+
const clonedReq = request.raw.clone();
|
|
633
|
+
const bodyText = await clonedReq.text();
|
|
634
|
+
if (bodyText && bodyText.trim().length > 0) {
|
|
635
|
+
try {
|
|
636
|
+
body = JSON.parse(bodyText);
|
|
637
|
+
} catch (error) {
|
|
638
|
+
console.error("Failed to parse JSON body:", error);
|
|
639
|
+
bodyParseError = {
|
|
640
|
+
message: error instanceof Error ? error.message : "Invalid JSON in request body"
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
return { urlParams, queryParams, body, bodyParseError };
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* Parse FormData into a plain object, converting File objects to Buffers.
|
|
650
|
+
*/
|
|
651
|
+
async parseFormData(formData) {
|
|
652
|
+
const result = {};
|
|
653
|
+
for (const [key, value] of formData.entries()) {
|
|
654
|
+
if (value instanceof File) {
|
|
655
|
+
const arrayBuffer = await value.arrayBuffer();
|
|
656
|
+
result[key] = Buffer.from(arrayBuffer);
|
|
657
|
+
} else if (typeof value === "string") {
|
|
658
|
+
try {
|
|
659
|
+
result[key] = JSON.parse(value);
|
|
660
|
+
} catch {
|
|
661
|
+
result[key] = value;
|
|
662
|
+
}
|
|
663
|
+
} else {
|
|
664
|
+
result[key] = value;
|
|
306
665
|
}
|
|
307
666
|
}
|
|
308
|
-
return
|
|
667
|
+
return result;
|
|
309
668
|
}
|
|
310
|
-
async sendResponse(route, response, result) {
|
|
669
|
+
async sendResponse(route, response, result, prefix) {
|
|
670
|
+
const resolvedPrefix = prefix ?? this.prefix ?? "";
|
|
311
671
|
if (route.responseType === "json") {
|
|
312
672
|
return response.json(result, 200);
|
|
313
673
|
} else if (route.responseType === "stream") {
|
|
@@ -315,11 +675,51 @@ var HonoServerAdapter = class extends MastraServerAdapter {
|
|
|
315
675
|
} else if (route.responseType === "datastream-response") {
|
|
316
676
|
const fetchResponse = result;
|
|
317
677
|
return fetchResponse;
|
|
678
|
+
} else if (route.responseType === "mcp-http") {
|
|
679
|
+
const { server, httpPath, mcpOptions: routeMcpOptions } = result;
|
|
680
|
+
const { req, res } = toReqRes(response.req.raw);
|
|
681
|
+
try {
|
|
682
|
+
const options = { ...this.mcpOptions, ...routeMcpOptions };
|
|
683
|
+
await server.startHTTP({
|
|
684
|
+
url: new URL(response.req.url),
|
|
685
|
+
httpPath: `${resolvedPrefix}${httpPath}`,
|
|
686
|
+
req,
|
|
687
|
+
res,
|
|
688
|
+
options: Object.keys(options).length > 0 ? options : void 0
|
|
689
|
+
});
|
|
690
|
+
return await toFetchResponse(res);
|
|
691
|
+
} catch {
|
|
692
|
+
if (!res.headersSent) {
|
|
693
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
694
|
+
res.end(
|
|
695
|
+
JSON.stringify({
|
|
696
|
+
jsonrpc: "2.0",
|
|
697
|
+
error: { code: -32603, message: "Internal server error" },
|
|
698
|
+
id: null
|
|
699
|
+
})
|
|
700
|
+
);
|
|
701
|
+
return await toFetchResponse(res);
|
|
702
|
+
}
|
|
703
|
+
return await toFetchResponse(res);
|
|
704
|
+
}
|
|
705
|
+
} else if (route.responseType === "mcp-sse") {
|
|
706
|
+
const { server, ssePath, messagePath } = result;
|
|
707
|
+
try {
|
|
708
|
+
return await server.startHonoSSE({
|
|
709
|
+
url: new URL(response.req.url),
|
|
710
|
+
ssePath: `${resolvedPrefix}${ssePath}`,
|
|
711
|
+
messagePath: `${resolvedPrefix}${messagePath}`,
|
|
712
|
+
context: response
|
|
713
|
+
});
|
|
714
|
+
} catch {
|
|
715
|
+
return response.json({ error: "Error handling MCP SSE request" }, 500);
|
|
716
|
+
}
|
|
318
717
|
} else {
|
|
319
718
|
return response.status(500);
|
|
320
719
|
}
|
|
321
720
|
}
|
|
322
|
-
async registerRoute(app, route, { prefix }) {
|
|
721
|
+
async registerRoute(app, route, { prefix: prefixParam } = {}) {
|
|
722
|
+
const prefix = prefixParam ?? this.prefix ?? "";
|
|
323
723
|
const shouldApplyBodyLimit = this.bodyLimitOptions && ["POST", "PUT", "PATCH"].includes(route.method.toUpperCase());
|
|
324
724
|
const maxSize = route.maxBodySize ?? this.bodyLimitOptions?.maxSize;
|
|
325
725
|
const middlewares = [];
|
|
@@ -335,16 +735,38 @@ var HonoServerAdapter = class extends MastraServerAdapter {
|
|
|
335
735
|
`${prefix}${route.path}`,
|
|
336
736
|
...middlewares,
|
|
337
737
|
async (c) => {
|
|
738
|
+
const authError = await this.checkRouteAuth(route, {
|
|
739
|
+
path: c.req.path,
|
|
740
|
+
method: c.req.method,
|
|
741
|
+
getHeader: (name) => c.req.header(name),
|
|
742
|
+
getQuery: (name) => c.req.query(name),
|
|
743
|
+
requestContext: c.get("requestContext")
|
|
744
|
+
});
|
|
745
|
+
if (authError) {
|
|
746
|
+
return c.json({ error: authError.error }, authError.status);
|
|
747
|
+
}
|
|
338
748
|
const params = await this.getParams(route, c.req);
|
|
749
|
+
if (params.bodyParseError) {
|
|
750
|
+
return c.json(
|
|
751
|
+
{
|
|
752
|
+
error: "Invalid request body",
|
|
753
|
+
issues: [{ field: "body", message: params.bodyParseError.message }]
|
|
754
|
+
},
|
|
755
|
+
400
|
|
756
|
+
);
|
|
757
|
+
}
|
|
339
758
|
if (params.queryParams) {
|
|
340
759
|
try {
|
|
341
760
|
params.queryParams = await this.parseQueryParams(route, params.queryParams);
|
|
342
761
|
} catch (error) {
|
|
343
762
|
console.error("Error parsing query params", error);
|
|
763
|
+
if (error instanceof ZodError) {
|
|
764
|
+
return c.json(formatZodError(error, "query parameters"), 400);
|
|
765
|
+
}
|
|
344
766
|
return c.json(
|
|
345
767
|
{
|
|
346
768
|
error: "Invalid query parameters",
|
|
347
|
-
|
|
769
|
+
issues: [{ field: "unknown", message: error instanceof Error ? error.message : "Unknown error" }]
|
|
348
770
|
},
|
|
349
771
|
400
|
|
350
772
|
);
|
|
@@ -354,11 +776,14 @@ var HonoServerAdapter = class extends MastraServerAdapter {
|
|
|
354
776
|
try {
|
|
355
777
|
params.body = await this.parseBody(route, params.body);
|
|
356
778
|
} catch (error) {
|
|
357
|
-
console.error("Error parsing body", error);
|
|
779
|
+
console.error("Error parsing body:", error instanceof Error ? error.message : String(error));
|
|
780
|
+
if (error instanceof ZodError) {
|
|
781
|
+
return c.json(formatZodError(error, "request body"), 400);
|
|
782
|
+
}
|
|
358
783
|
return c.json(
|
|
359
784
|
{
|
|
360
785
|
error: "Invalid request body",
|
|
361
|
-
|
|
786
|
+
issues: [{ field: "unknown", message: error instanceof Error ? error.message : "Unknown error" }]
|
|
362
787
|
},
|
|
363
788
|
400
|
|
364
789
|
);
|
|
@@ -370,13 +795,14 @@ var HonoServerAdapter = class extends MastraServerAdapter {
|
|
|
370
795
|
...typeof params.body === "object" ? params.body : {},
|
|
371
796
|
requestContext: c.get("requestContext"),
|
|
372
797
|
mastra: this.mastra,
|
|
373
|
-
|
|
798
|
+
registeredTools: c.get("registeredTools"),
|
|
374
799
|
taskStore: c.get("taskStore"),
|
|
375
|
-
abortSignal: c.get("abortSignal")
|
|
800
|
+
abortSignal: c.get("abortSignal"),
|
|
801
|
+
routePrefix: prefix
|
|
376
802
|
};
|
|
377
803
|
try {
|
|
378
804
|
const result = await route.handler(handlerParams);
|
|
379
|
-
return this.sendResponse(route, c, result);
|
|
805
|
+
return this.sendResponse(route, c, result, prefix);
|
|
380
806
|
} catch (error) {
|
|
381
807
|
console.error("Error calling handler", error);
|
|
382
808
|
if (error && typeof error === "object") {
|
|
@@ -394,14 +820,19 @@ var HonoServerAdapter = class extends MastraServerAdapter {
|
|
|
394
820
|
}
|
|
395
821
|
);
|
|
396
822
|
}
|
|
397
|
-
registerContextMiddleware(
|
|
398
|
-
app.use("*", this.createContextMiddleware());
|
|
823
|
+
registerContextMiddleware() {
|
|
824
|
+
this.app.use("*", this.createContextMiddleware());
|
|
399
825
|
}
|
|
400
|
-
|
|
401
|
-
|
|
826
|
+
registerAuthMiddleware() {
|
|
827
|
+
const authConfig = this.mastra.getServer()?.auth;
|
|
828
|
+
if (!authConfig) {
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
this.app.use("*", authenticationMiddleware);
|
|
832
|
+
this.app.use("*", authorizationMiddleware);
|
|
402
833
|
}
|
|
403
834
|
};
|
|
404
835
|
|
|
405
|
-
export {
|
|
836
|
+
export { MastraServer };
|
|
406
837
|
//# sourceMappingURL=index.js.map
|
|
407
838
|
//# sourceMappingURL=index.js.map
|