@mastra/deployer 1.8.0 → 1.9.0

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.
Files changed (72) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/LICENSE.md +15 -0
  3. package/dist/build/analyze/bundleExternals.d.ts +2 -0
  4. package/dist/build/analyze/bundleExternals.d.ts.map +1 -1
  5. package/dist/build/analyze/constants.d.ts.map +1 -1
  6. package/dist/build/analyze.cjs +2 -2
  7. package/dist/build/analyze.d.ts +1 -1
  8. package/dist/build/analyze.d.ts.map +1 -1
  9. package/dist/build/analyze.js +1 -1
  10. package/dist/build/bundler.cjs +3 -3
  11. package/dist/build/bundler.d.ts.map +1 -1
  12. package/dist/build/bundler.js +1 -1
  13. package/dist/build/index.cjs +18 -14
  14. package/dist/build/index.d.ts +2 -2
  15. package/dist/build/index.d.ts.map +1 -1
  16. package/dist/build/index.js +5 -5
  17. package/dist/build/utils.d.ts +43 -0
  18. package/dist/build/utils.d.ts.map +1 -1
  19. package/dist/bundler/index.cjs +3 -3
  20. package/dist/bundler/index.js +1 -1
  21. package/dist/{chunk-SYOOUXQR.cjs → chunk-2U66YH5A.cjs} +16 -16
  22. package/dist/{chunk-SYOOUXQR.cjs.map → chunk-2U66YH5A.cjs.map} +1 -1
  23. package/dist/{chunk-2ADDVHED.js → chunk-56QWTZZP.js} +7 -7
  24. package/dist/{chunk-2ADDVHED.js.map → chunk-56QWTZZP.js.map} +1 -1
  25. package/dist/{chunk-CAHLKF47.js → chunk-6UIXBIO6.js} +43 -22
  26. package/dist/chunk-6UIXBIO6.js.map +1 -0
  27. package/dist/{chunk-SAAWBL2Q.cjs → chunk-73SEUI3W.cjs} +79 -58
  28. package/dist/chunk-73SEUI3W.cjs.map +1 -0
  29. package/dist/{chunk-AMZJCH64.js → chunk-ANF3UFZ3.js} +3 -3
  30. package/dist/{chunk-AMZJCH64.js.map → chunk-ANF3UFZ3.js.map} +1 -1
  31. package/dist/{chunk-TOBYD27M.cjs → chunk-EBHDMP6N.cjs} +16 -16
  32. package/dist/{chunk-TOBYD27M.cjs.map → chunk-EBHDMP6N.cjs.map} +1 -1
  33. package/dist/{chunk-KRRQVSI7.js → chunk-EZBW45SX.js} +7 -13
  34. package/dist/chunk-EZBW45SX.js.map +1 -0
  35. package/dist/{chunk-ITC6JDLC.cjs → chunk-G7R456H2.cjs} +33 -2
  36. package/dist/chunk-G7R456H2.cjs.map +1 -0
  37. package/dist/{chunk-MIZUMHGW.js → chunk-IMLDKOVJ.js} +7 -7
  38. package/dist/{chunk-MIZUMHGW.js.map → chunk-IMLDKOVJ.js.map} +1 -1
  39. package/dist/{chunk-3WL6HPU3.js → chunk-O73YCD6A.js} +3 -3
  40. package/dist/{chunk-3WL6HPU3.js.map → chunk-O73YCD6A.js.map} +1 -1
  41. package/dist/{chunk-R2SIOO54.cjs → chunk-R2SYO6PH.cjs} +20 -26
  42. package/dist/chunk-R2SYO6PH.cjs.map +1 -0
  43. package/dist/{chunk-K7J2W7DJ.cjs → chunk-UPVHAZ5Q.cjs} +7 -7
  44. package/dist/{chunk-K7J2W7DJ.cjs.map → chunk-UPVHAZ5Q.cjs.map} +1 -1
  45. package/dist/{chunk-UKA2IZKF.js → chunk-XN3FKMO6.js} +32 -3
  46. package/dist/chunk-XN3FKMO6.js.map +1 -0
  47. package/dist/{chunk-E4SQOERA.cjs → chunk-YIUDHDPS.cjs} +4 -4
  48. package/dist/{chunk-E4SQOERA.cjs.map → chunk-YIUDHDPS.cjs.map} +1 -1
  49. package/dist/docs/SKILL.md +1 -1
  50. package/dist/docs/assets/SOURCE_MAP.json +1 -1
  51. package/dist/index.cjs +4 -4
  52. package/dist/index.js +2 -2
  53. package/dist/server/index.cjs +151 -155
  54. package/dist/server/index.cjs.map +1 -1
  55. package/dist/server/index.d.ts.map +1 -1
  56. package/dist/server/index.js +149 -153
  57. package/dist/server/index.js.map +1 -1
  58. package/dist/validator/custom-resolver.cjs +28 -2
  59. package/dist/validator/custom-resolver.cjs.map +1 -1
  60. package/dist/validator/custom-resolver.d.ts +15 -1
  61. package/dist/validator/custom-resolver.d.ts.map +1 -1
  62. package/dist/validator/custom-resolver.js +27 -2
  63. package/dist/validator/custom-resolver.js.map +1 -1
  64. package/dist/validator/validate.d.ts +2 -1
  65. package/dist/validator/validate.d.ts.map +1 -1
  66. package/package.json +7 -7
  67. package/dist/chunk-CAHLKF47.js.map +0 -1
  68. package/dist/chunk-ITC6JDLC.cjs.map +0 -1
  69. package/dist/chunk-KRRQVSI7.js.map +0 -1
  70. package/dist/chunk-R2SIOO54.cjs.map +0 -1
  71. package/dist/chunk-SAAWBL2Q.cjs.map +0 -1
  72. package/dist/chunk-UKA2IZKF.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkITC6JDLC_cjs = require('../chunk-ITC6JDLC.cjs');
3
+ var chunkG7R456H2_cjs = require('../chunk-G7R456H2.cjs');
4
4
  var promises = require('fs/promises');
5
5
  var https = require('https');
6
6
  var path = require('path');
@@ -18,7 +18,6 @@ var error = require('@mastra/server/handlers/error');
18
18
  var serverAdapter = require('@mastra/server/server-adapter');
19
19
  var util = require('util');
20
20
  var buffer = require('buffer');
21
- var auth = require('@mastra/server/auth');
22
21
  var store = require('@mastra/server/a2a/store');
23
22
  var hono = require('hono');
24
23
  var cors = require('hono/cors');
@@ -2682,6 +2681,8 @@ function toFetchResponse(res) {
2682
2681
  }
2683
2682
  return res.fetchResponse;
2684
2683
  }
2684
+
2685
+ // ../../server-adapters/hono/dist/index.js
2685
2686
  var HTTPException = class extends Error {
2686
2687
  res;
2687
2688
  status;
@@ -3083,117 +3084,18 @@ ZodError.create = (issues) => {
3083
3084
  const error = new ZodError(issues);
3084
3085
  return error;
3085
3086
  };
3086
- var authenticationMiddleware = async (c, next) => {
3087
- const mastra = c.get("mastra");
3088
- const authConfig = mastra.getServer()?.auth;
3089
- const customRouteAuthConfig = c.get("customRouteAuthConfig");
3090
- if (!authConfig) {
3091
- return next();
3092
- }
3093
- const path = c.req.path;
3094
- const method = c.req.method;
3095
- const getHeader = (name) => c.req.header(name);
3096
- if (auth.isDevPlaygroundRequest(path, method, getHeader, authConfig, customRouteAuthConfig)) {
3097
- return next();
3098
- }
3099
- if (!auth.isProtectedPath(c.req.path, c.req.method, authConfig, customRouteAuthConfig)) {
3100
- return next();
3101
- }
3102
- if (auth.canAccessPublicly(c.req.path, c.req.method, authConfig)) {
3103
- return next();
3104
- }
3105
- const authHeader = c.req.header("Authorization");
3106
- let token = authHeader ? authHeader.replace("Bearer ", "") : null;
3107
- if (!token && c.req.query("apiKey")) {
3108
- token = c.req.query("apiKey") || null;
3109
- }
3110
- if (!token) {
3111
- return c.json({ error: "Authentication required" }, 401);
3112
- }
3113
- try {
3114
- let user;
3115
- if (typeof authConfig.authenticateToken === "function") {
3116
- user = await authConfig.authenticateToken(token, c.req);
3117
- } else {
3118
- throw new Error("No token verification method configured");
3119
- }
3120
- if (!user) {
3121
- return c.json({ error: "Invalid or expired token" }, 401);
3122
- }
3123
- c.get("requestContext").set("user", user);
3124
- return next();
3125
- } catch (err) {
3126
- mastra.getLogger()?.error("Authentication error", {
3127
- error: err instanceof Error ? { message: err.message, stack: err.stack } : err
3087
+ var _hasPermissionPromise;
3088
+ function loadHasPermission() {
3089
+ if (!_hasPermissionPromise) {
3090
+ _hasPermissionPromise = import('@mastra/core/auth/ee').then((m) => m.hasPermission).catch(() => {
3091
+ console.error(
3092
+ "[@mastra/hono] Auth features require @mastra/core >= 1.6.0. Please upgrade: npm install @mastra/core@latest"
3093
+ );
3094
+ return void 0;
3128
3095
  });
3129
- return c.json({ error: "Invalid or expired token" }, 401);
3130
3096
  }
3131
- };
3132
- var authorizationMiddleware = async (c, next) => {
3133
- const mastra = c.get("mastra");
3134
- const authConfig = mastra.getServer()?.auth;
3135
- const customRouteAuthConfig = c.get("customRouteAuthConfig");
3136
- if (!authConfig) {
3137
- return next();
3138
- }
3139
- const path = c.req.path;
3140
- const method = c.req.method;
3141
- const getHeader = (name) => c.req.header(name);
3142
- if (auth.isDevPlaygroundRequest(path, method, getHeader, authConfig, customRouteAuthConfig)) {
3143
- return next();
3144
- }
3145
- if (!auth.isProtectedPath(c.req.path, c.req.method, authConfig, customRouteAuthConfig)) {
3146
- return next();
3147
- }
3148
- if (auth.canAccessPublicly(path, method, authConfig)) {
3149
- return next();
3150
- }
3151
- const user = c.get("requestContext").get("user");
3152
- if ("authorizeUser" in authConfig && typeof authConfig.authorizeUser === "function") {
3153
- try {
3154
- const isAuthorized = await authConfig.authorizeUser(user, c.req);
3155
- if (isAuthorized) {
3156
- return next();
3157
- }
3158
- return c.json({ error: "Access denied" }, 403);
3159
- } catch (err) {
3160
- mastra.getLogger()?.error("Authorization error in authorizeUser", {
3161
- error: err instanceof Error ? { message: err.message, stack: err.stack } : err
3162
- });
3163
- return c.json({ error: "Authorization error" }, 500);
3164
- }
3165
- }
3166
- if ("authorize" in authConfig && typeof authConfig.authorize === "function") {
3167
- try {
3168
- const isAuthorized = await authConfig.authorize(path, method, user, c);
3169
- if (isAuthorized) {
3170
- return next();
3171
- }
3172
- return c.json({ error: "Access denied" }, 403);
3173
- } catch (err) {
3174
- mastra.getLogger()?.error("Authorization error in authorize", {
3175
- error: err instanceof Error ? { message: err.message, stack: err.stack } : err,
3176
- path,
3177
- method
3178
- });
3179
- return c.json({ error: "Authorization error" }, 500);
3180
- }
3181
- }
3182
- if ("rules" in authConfig && authConfig.rules && authConfig.rules.length > 0) {
3183
- const isAuthorized = await auth.checkRules(authConfig.rules, path, method, user);
3184
- if (isAuthorized) {
3185
- return next();
3186
- }
3187
- return c.json({ error: "Access denied" }, 403);
3188
- }
3189
- if (auth.defaultAuthConfig.rules && auth.defaultAuthConfig.rules.length > 0) {
3190
- const isAuthorized = await auth.checkRules(auth.defaultAuthConfig.rules, path, method, user);
3191
- if (isAuthorized) {
3192
- return next();
3193
- }
3194
- }
3195
- return c.json({ error: "Access denied" }, 403);
3196
- };
3097
+ return _hasPermissionPromise;
3098
+ }
3197
3099
  var MastraServer = class extends serverAdapter.MastraServer {
3198
3100
  createContextMiddleware() {
3199
3101
  return async (c, next) => {
@@ -3212,7 +3114,8 @@ var MastraServer = class extends serverAdapter.MastraServer {
3212
3114
  let paramsRequestContext;
3213
3115
  if (c.req.method === "POST" || c.req.method === "PUT") {
3214
3116
  const contentType = c.req.header("content-type");
3215
- if (contentType?.includes("application/json")) {
3117
+ const contentLength = c.req.header("content-length");
3118
+ if (contentType?.includes("application/json") && contentLength !== "0") {
3216
3119
  try {
3217
3120
  const body = await c.req.raw.clone().json();
3218
3121
  if (body.requestContext) {
@@ -3438,7 +3341,9 @@ var MastraServer = class extends serverAdapter.MastraServer {
3438
3341
  method: c.req.method,
3439
3342
  getHeader: (name) => c.req.header(name),
3440
3343
  getQuery: (name) => c.req.query(name),
3441
- requestContext: c.get("requestContext")
3344
+ requestContext: c.get("requestContext"),
3345
+ request: c.req.raw,
3346
+ buildAuthorizeContext: () => c
3442
3347
  });
3443
3348
  if (authError) {
3444
3349
  return c.json({ error: authError.error }, authError.status);
@@ -3519,8 +3424,27 @@ var MastraServer = class extends serverAdapter.MastraServer {
3519
3424
  registeredTools: c.get("registeredTools"),
3520
3425
  taskStore: c.get("taskStore"),
3521
3426
  abortSignal: c.get("abortSignal"),
3522
- routePrefix: prefix
3427
+ routePrefix: prefix,
3428
+ request: c.req.raw
3429
+ // Standard Request object with headers/cookies
3523
3430
  };
3431
+ const authConfig = this.mastra.getServer()?.auth;
3432
+ if (authConfig) {
3433
+ const hasPermission = await loadHasPermission();
3434
+ if (hasPermission) {
3435
+ const userPermissions = c.get("requestContext").get("userPermissions");
3436
+ const permissionError = this.checkRoutePermission(route, userPermissions, hasPermission);
3437
+ if (permissionError) {
3438
+ return c.json(
3439
+ {
3440
+ error: permissionError.error,
3441
+ message: permissionError.message
3442
+ },
3443
+ permissionError.status
3444
+ );
3445
+ }
3446
+ }
3447
+ }
3524
3448
  try {
3525
3449
  const result = await route.handler(handlerParams);
3526
3450
  return this.sendResponse(route, c, result, prefix);
@@ -3566,6 +3490,43 @@ var MastraServer = class extends serverAdapter.MastraServer {
3566
3490
  const handler = "handler" in route && route.handler ? route.handler : "createHandler" in route ? await route.createHandler({ mastra: this.mastra }) : void 0;
3567
3491
  if (!handler) continue;
3568
3492
  const middlewares = [];
3493
+ const serverRoute = {
3494
+ method: route.method,
3495
+ path: route.path,
3496
+ responseType: "json",
3497
+ handler: async () => {
3498
+ },
3499
+ requiresAuth: route.requiresAuth
3500
+ };
3501
+ middlewares.push(async (c, next) => {
3502
+ const authError = await this.checkRouteAuth(serverRoute, {
3503
+ path: c.req.path,
3504
+ method: c.req.method,
3505
+ getHeader: (name) => c.req.header(name),
3506
+ getQuery: (name) => c.req.query(name),
3507
+ requestContext: c.get("requestContext"),
3508
+ request: c.req.raw,
3509
+ buildAuthorizeContext: () => c
3510
+ });
3511
+ if (authError) {
3512
+ return c.json({ error: authError.error }, authError.status);
3513
+ }
3514
+ const authConfig = this.mastra.getServer()?.auth;
3515
+ if (authConfig) {
3516
+ const hasPermission = await loadHasPermission();
3517
+ if (hasPermission) {
3518
+ const userPermissions = c.get("requestContext").get("userPermissions");
3519
+ const permissionError = this.checkRoutePermission(serverRoute, userPermissions, hasPermission);
3520
+ if (permissionError) {
3521
+ return c.json(
3522
+ { error: permissionError.error, message: permissionError.message },
3523
+ permissionError.status
3524
+ );
3525
+ }
3526
+ }
3527
+ }
3528
+ return next();
3529
+ });
3569
3530
  if (route.middleware) {
3570
3531
  middlewares.push(...Array.isArray(route.middleware) ? route.middleware : [route.middleware]);
3571
3532
  }
@@ -3578,12 +3539,44 @@ var MastraServer = class extends serverAdapter.MastraServer {
3578
3539
  this.app.use("*", this.createContextMiddleware());
3579
3540
  }
3580
3541
  registerAuthMiddleware() {
3581
- const authConfig = this.mastra.getServer()?.auth;
3582
- if (!authConfig) {
3542
+ }
3543
+ registerHttpLoggingMiddleware() {
3544
+ if (!this.httpLoggingConfig?.enabled) {
3583
3545
  return;
3584
3546
  }
3585
- this.app.use("*", authenticationMiddleware);
3586
- this.app.use("*", authorizationMiddleware);
3547
+ this.app.use("*", async (c, next) => {
3548
+ if (!this.shouldLogRequest(c.req.path)) {
3549
+ return next();
3550
+ }
3551
+ const start = Date.now();
3552
+ const method = c.req.method;
3553
+ const path = c.req.path;
3554
+ await next();
3555
+ const duration = Date.now() - start;
3556
+ const status = c.res.status;
3557
+ const level = this.httpLoggingConfig?.level || "info";
3558
+ const logData = {
3559
+ method,
3560
+ path,
3561
+ status,
3562
+ duration: `${duration}ms`
3563
+ };
3564
+ if (this.httpLoggingConfig?.includeQueryParams) {
3565
+ logData.query = c.req.query();
3566
+ }
3567
+ if (this.httpLoggingConfig?.includeHeaders) {
3568
+ const headers = Object.fromEntries(c.req.raw.headers.entries());
3569
+ const redactHeaders = this.httpLoggingConfig.redactHeaders || [];
3570
+ redactHeaders.forEach((h) => {
3571
+ const key = h.toLowerCase();
3572
+ if (headers[key] !== void 0) {
3573
+ headers[key] = "[REDACTED]";
3574
+ }
3575
+ });
3576
+ logData.headers = headers;
3577
+ }
3578
+ this.logger[level](`${method} ${path} ${status} ${duration}ms`, logData);
3579
+ });
3587
3580
  }
3588
3581
  };
3589
3582
 
@@ -3944,9 +3937,16 @@ async function createHonoServer(mastra, options = {
3944
3937
  const server = mastra.getServer();
3945
3938
  const a2aTaskStore = new store.InMemoryTaskStore();
3946
3939
  const routes = server?.apiRoutes;
3940
+ const processedRoutes = routes?.map((route) => {
3941
+ if ("openapi" in route && route.openapi) {
3942
+ const existingMiddleware = route.middleware ? Array.isArray(route.middleware) ? route.middleware : [route.middleware] : [];
3943
+ return { ...route, middleware: [describeRoute(route.openapi), ...existingMiddleware] };
3944
+ }
3945
+ return route;
3946
+ });
3947
3947
  const customRouteAuthConfig = /* @__PURE__ */ new Map();
3948
- if (routes) {
3949
- for (const route of routes) {
3948
+ if (processedRoutes) {
3949
+ for (const route of processedRoutes) {
3950
3950
  const requiresAuth = route.requiresAuth !== false;
3951
3951
  const routeKey = `${route.method}:${route.path}`;
3952
3952
  customRouteAuthConfig.set(routeKey, requiresAuth);
@@ -3972,7 +3972,7 @@ async function createHonoServer(mastra, options = {
3972
3972
  bodyLimitOptions,
3973
3973
  openapiPath: options?.isDev || server?.build?.openAPIDocs ? "/openapi.json" : void 0,
3974
3974
  customRouteAuthConfig,
3975
- customApiRoutes: routes
3975
+ customApiRoutes: processedRoutes
3976
3976
  });
3977
3977
  honoServerAdapter.registerContextMiddleware();
3978
3978
  const serverMiddleware = mastra.getServerMiddleware?.();
@@ -3984,10 +3984,20 @@ async function createHonoServer(mastra, options = {
3984
3984
  if (server?.cors === false) {
3985
3985
  app.use("*", timeout.timeout(server?.timeout ?? 3 * 60 * 1e3));
3986
3986
  } else {
3987
+ const hasAuth = !!server?.auth;
3988
+ let corsOrigin;
3989
+ if (server?.cors && typeof server.cors === "object" && "origin" in server.cors && server.cors.origin) {
3990
+ corsOrigin = server.cors.origin;
3991
+ } else if (hasAuth) {
3992
+ corsOrigin = (origin) => origin || void 0;
3993
+ } else {
3994
+ corsOrigin = "*";
3995
+ }
3987
3996
  const corsConfig = {
3988
- origin: "*",
3997
+ origin: corsOrigin,
3989
3998
  allowMethods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
3990
- credentials: false,
3999
+ // Enable credentials for cookie-based auth (e.g., Better Auth sessions)
4000
+ credentials: hasAuth ? true : false,
3991
4001
  maxAge: 3600,
3992
4002
  ...server?.cors,
3993
4003
  allowHeaders: ["Content-Type", "Authorization", "x-mastra-client-type", ...server?.cors?.allowHeaders ?? []],
@@ -4023,6 +4033,7 @@ async function createHonoServer(mastra, options = {
4023
4033
  rootHandler
4024
4034
  );
4025
4035
  }
4036
+ await honoServerAdapter.validateEELicense();
4026
4037
  honoServerAdapter.registerAuthMiddleware();
4027
4038
  if (server?.middleware) {
4028
4039
  const normalizedMiddlewares = Array.isArray(server.middleware) ? server.middleware : [server.middleware];
@@ -4039,24 +4050,7 @@ async function createHonoServer(mastra, options = {
4039
4050
  app.use(middleware2.path, middleware2.handler);
4040
4051
  }
4041
4052
  }
4042
- if (routes) {
4043
- for (const route of routes) {
4044
- const middlewares = [];
4045
- if (route.middleware) {
4046
- middlewares.push(...Array.isArray(route.middleware) ? route.middleware : [route.middleware]);
4047
- }
4048
- if (route.openapi) {
4049
- middlewares.push(describeRoute(route.openapi));
4050
- }
4051
- const handler = "handler" in route ? route.handler : await route.createHandler({ mastra });
4052
- const allHandlers = [...middlewares, handler];
4053
- if (route.method === "ALL") {
4054
- app.all(route.path, allHandlers[0], ...allHandlers.slice(1));
4055
- } else {
4056
- app.on(route.method, route.path, allHandlers[0], ...allHandlers.slice(1));
4057
- }
4058
- }
4059
- }
4053
+ await honoServerAdapter.registerCustomApiRoutes();
4060
4054
  if (server?.build?.apiReqLogs) {
4061
4055
  app.use(logger.logger());
4062
4056
  }
@@ -4086,7 +4080,7 @@ async function createHonoServer(mastra, options = {
4086
4080
  );
4087
4081
  }
4088
4082
  const serverOptions = mastra.getServer();
4089
- const studioBasePath = chunkITC6JDLC_cjs.normalizeStudioBase(serverOptions?.studioBase ?? "/");
4083
+ const studioBasePath = chunkG7R456H2_cjs.normalizeStudioBase(serverOptions?.studioBase ?? "/");
4090
4084
  if (options?.studio) {
4091
4085
  app.get(
4092
4086
  `${studioBasePath}/refresh-events`,
@@ -4156,18 +4150,20 @@ async function createHonoServer(mastra, options = {
4156
4150
  const escapeForHtml = (json) => {
4157
4151
  return json.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
4158
4152
  };
4159
- indexHtml = indexHtml.replace(`'%%MASTRA_SERVER_HOST%%'`, `'${host}'`);
4160
- indexHtml = indexHtml.replace(`'%%MASTRA_SERVER_PORT%%'`, `'${port}'`);
4161
- indexHtml = indexHtml.replace(`'%%MASTRA_API_PREFIX%%'`, `'${serverOptions?.apiPrefix ?? "/api"}'`);
4162
- indexHtml = indexHtml.replace(`'%%MASTRA_HIDE_CLOUD_CTA%%'`, `'${hideCloudCta}'`);
4163
- indexHtml = indexHtml.replace(`'%%MASTRA_SERVER_PROTOCOL%%'`, `'${protocol}'`);
4164
- indexHtml = indexHtml.replace(`'%%MASTRA_CLOUD_API_ENDPOINT%%'`, `'${cloudApiEndpoint}'`);
4165
- indexHtml = indexHtml.replace(`'%%MASTRA_EXPERIMENTAL_FEATURES%%'`, `'${experimentalFeatures}'`);
4166
- indexHtml = indexHtml.replace(
4167
- `'%%MASTRA_REQUEST_CONTEXT_PRESETS%%'`,
4168
- `'${escapeForHtml(requestContextPresets)}'`
4169
- );
4170
- indexHtml = indexHtml.replaceAll("%%MASTRA_STUDIO_BASE_PATH%%", studioBasePath);
4153
+ const autoDetectUrl = process.env.MASTRA_AUTO_DETECT_URL === "true";
4154
+ indexHtml = chunkG7R456H2_cjs.injectStudioHtmlConfig(indexHtml, {
4155
+ host: `'${host}'`,
4156
+ port: `'${port}'`,
4157
+ protocol: `'${protocol}'`,
4158
+ apiPrefix: `'${serverOptions?.apiPrefix ?? "/api"}'`,
4159
+ basePath: studioBasePath,
4160
+ hideCloudCta: `'${hideCloudCta}'`,
4161
+ cloudApiEndpoint: `'${cloudApiEndpoint}'`,
4162
+ experimentalFeatures: `'${experimentalFeatures}'`,
4163
+ telemetryDisabled: `''`,
4164
+ requestContextPresets: `'${escapeForHtml(requestContextPresets)}'`,
4165
+ autoDetectUrl: `'${autoDetectUrl}'`
4166
+ });
4171
4167
  return c.newResponse(indexHtml, 200, { "Content-Type": "text/html" });
4172
4168
  }
4173
4169
  return c.newResponse(html2, 200, { "Content-Type": "text/html" });
@@ -4216,7 +4212,7 @@ async function createNodeServer(mastra, options = { tools: {} }) {
4216
4212
  const logger2 = mastra.getLogger();
4217
4213
  logger2.info(` Mastra API running on ${protocol}://${host}:${port}/api`);
4218
4214
  if (options?.studio) {
4219
- const studioBasePath = chunkITC6JDLC_cjs.normalizeStudioBase(serverOptions?.studioBase ?? "/");
4215
+ const studioBasePath = chunkG7R456H2_cjs.normalizeStudioBase(serverOptions?.studioBase ?? "/");
4220
4216
  const studioUrl = `${protocol}://${host}:${port}${studioBasePath}`;
4221
4217
  logger2.info(`\u{1F468}\u200D\u{1F4BB} Studio available at ${studioUrl}`);
4222
4218
  }