@mastra/deployer-vercel 1.2.12 → 1.2.13-alpha.1
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 +35 -0
- package/dist/index.cjs +36 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +36 -20
- package/dist/index.js.map +1 -1
- package/dist/routes.d.ts +3 -8
- package/dist/routes.d.ts.map +1 -1
- package/dist/studio/assets/{core--7ykYG3U.js → core-BTgqVtGn.js} +1 -1
- package/dist/studio/assets/{index-C5anT3qx.js → index-BmTyd9Wa.js} +2 -2
- package/dist/studio/assets/{main-DomdLuyE.js → main-97-NJ4f3.js} +234 -234
- package/dist/studio/assets/style-CAUk37Fq.css +1 -0
- package/dist/studio/index.html +2 -2
- package/package.json +4 -4
- package/dist/studio/assets/style-BP65E3ZK.css +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# @mastra/deployer-vercel
|
|
2
2
|
|
|
3
|
+
## 1.2.13-alpha.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Fixed custom API routes being unreachable when deploying to Vercel with `studio: true`. ([#20517](https://github.com/mastra-ai/mastra/pull/20517))
|
|
8
|
+
|
|
9
|
+
Routes registered with `registerApiRoute()` are mounted at the root of the server, but the generated Vercel route table only forwarded `/api/*` and `/health` to your app. Every other path fell through to Studio's `index.html`, so a request to a custom route returned the Studio HTML page and the handler never ran. Moving the route under `/api` was not an option either, since that prefix is reserved for built-in routes.
|
|
10
|
+
|
|
11
|
+
The route table now serves the paths Studio owns from the CDN and sends everything else to your server, so custom routes behave the same as they do with `mastra dev` and `studio: false`. Studio and its assets are still served as static files with no function invocations.
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
export const mastra = new Mastra({
|
|
15
|
+
deployer: new VercelDeployer({ studio: true }),
|
|
16
|
+
server: {
|
|
17
|
+
apiRoutes: [registerApiRoute('/my/webhook', { method: 'POST', handler: c => c.json({ ok: true }) })],
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`POST /my/webhook` now returns `{"ok":true}` instead of Studio's `index.html`.
|
|
23
|
+
|
|
24
|
+
Requests to a custom `server.apiPrefix` now reach your server too, instead of being answered with the Studio page. Studio's own UI still calls `/api`, so pointing Studio at a custom prefix is not supported yet.
|
|
25
|
+
|
|
26
|
+
- Updated dependencies [[`4844167`](https://github.com/mastra-ai/mastra/commit/4844167cff2d5ec5004e94edd34970833040fa3f), [`5faf93f`](https://github.com/mastra-ai/mastra/commit/5faf93f03e19daea394b9e2a923f2e4f833407f2), [`80ad891`](https://github.com/mastra-ai/mastra/commit/80ad891f8cd10379aa5b5af7510c763783b2ab56), [`b1abe41`](https://github.com/mastra-ai/mastra/commit/b1abe41fbb5060b864aaa79e0ac3b5afcd414513), [`a1cb98d`](https://github.com/mastra-ai/mastra/commit/a1cb98d11990b560b98482292a1f34aa1a2d9092), [`598ad82`](https://github.com/mastra-ai/mastra/commit/598ad82d41c41389a686338a1d0e50b7400e1938), [`1fd6aad`](https://github.com/mastra-ai/mastra/commit/1fd6aad1ea4a9d32f65efa832307c35e981a4c0a)]:
|
|
27
|
+
- @mastra/core@1.56.0-alpha.4
|
|
28
|
+
- @mastra/deployer@1.56.0-alpha.4
|
|
29
|
+
|
|
30
|
+
## 1.2.13-alpha.0
|
|
31
|
+
|
|
32
|
+
### Patch Changes
|
|
33
|
+
|
|
34
|
+
- Updated dependencies [[`7f4e26d`](https://github.com/mastra-ai/mastra/commit/7f4e26dd57bd9b23c278ea21235ab823a3810a6c), [`b582f7f`](https://github.com/mastra-ai/mastra/commit/b582f7fa2f9c1f87d19efc63d344fbe5dda2608c), [`6306f2c`](https://github.com/mastra-ai/mastra/commit/6306f2cac6fbe9a89d881044a609cc1d4aace797), [`b582f7f`](https://github.com/mastra-ai/mastra/commit/b582f7fa2f9c1f87d19efc63d344fbe5dda2608c)]:
|
|
35
|
+
- @mastra/core@1.56.0-alpha.0
|
|
36
|
+
- @mastra/deployer@1.56.0-alpha.0
|
|
37
|
+
|
|
3
38
|
## 1.2.12
|
|
4
39
|
|
|
5
40
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -30,30 +30,28 @@ let _mastra_deployer = require("@mastra/deployer");
|
|
|
30
30
|
let _mastra_deployer_build = require("@mastra/deployer/build");
|
|
31
31
|
let fs_extra_esm = require("fs-extra/esm");
|
|
32
32
|
//#region src/routes.ts
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
34
|
+
function getVercelRoutes({ studio, studioRouteRoots = [] }) {
|
|
35
|
+
if (!studio) return [{
|
|
36
|
+
src: "/(.*)",
|
|
37
|
+
dest: "/"
|
|
38
|
+
}];
|
|
39
|
+
const spaRoots = studioRouteRoots.map(escapeRegExp).join("|");
|
|
40
|
+
return [
|
|
35
41
|
{
|
|
36
42
|
src: "^/$",
|
|
37
43
|
dest: "/index.html"
|
|
38
44
|
},
|
|
39
|
-
{
|
|
40
|
-
src:
|
|
41
|
-
dest: "/"
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
src: "/health",
|
|
45
|
-
dest: "/"
|
|
46
|
-
},
|
|
45
|
+
...spaRoots ? [{
|
|
46
|
+
src: `^/(?:${spaRoots})(?:/.*)?$`,
|
|
47
|
+
dest: "/index.html"
|
|
48
|
+
}] : [],
|
|
47
49
|
{ handle: "filesystem" },
|
|
48
50
|
{
|
|
49
51
|
src: "/(.*)",
|
|
50
|
-
dest: "/
|
|
51
|
-
check: true
|
|
52
|
+
dest: "/"
|
|
52
53
|
}
|
|
53
|
-
]
|
|
54
|
-
src: "/(.*)",
|
|
55
|
-
dest: "/"
|
|
56
|
-
}];
|
|
54
|
+
];
|
|
57
55
|
}
|
|
58
56
|
//#endregion
|
|
59
57
|
//#region src/index.ts
|
|
@@ -75,9 +73,9 @@ var VercelDeployer = class extends _mastra_deployer.Deployer {
|
|
|
75
73
|
}
|
|
76
74
|
async prepare(outputDirectory) {
|
|
77
75
|
await super.prepare(outputDirectory);
|
|
78
|
-
|
|
76
|
+
const studioSource = (0, path.join)((0, path.dirname)((0, path.dirname)((0, url.fileURLToPath)(require("url").pathToFileURL(__filename).href))), "dist", "studio");
|
|
77
|
+
this.writeVercelJSON((0, path.join)(outputDirectory, this.outputDir, "..", ".."), this.studio ? this.readStudioRouteRoots(studioSource) : []);
|
|
79
78
|
if (this.studio) {
|
|
80
|
-
const studioSource = (0, path.join)((0, path.dirname)((0, path.dirname)((0, url.fileURLToPath)(require("url").pathToFileURL(__filename).href))), "dist", "studio");
|
|
81
79
|
const staticDir = (0, path.join)(outputDirectory, ".vercel", "output", "static");
|
|
82
80
|
try {
|
|
83
81
|
await (0, fs_extra_esm.copy)(studioSource, staticDir, { overwrite: true });
|
|
@@ -87,6 +85,21 @@ var VercelDeployer = class extends _mastra_deployer.Deployer {
|
|
|
87
85
|
this.injectStudioConfig(staticDir);
|
|
88
86
|
}
|
|
89
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Studio's top-level route segments, emitted by the Studio build alongside index.html.
|
|
90
|
+
* The Vercel route table needs them explicitly: custom `registerApiRoute()` paths are mounted
|
|
91
|
+
* at the root of the server, so the function has to own every path Studio doesn't claim.
|
|
92
|
+
*/
|
|
93
|
+
readStudioRouteRoots(studioSource) {
|
|
94
|
+
const manifestPath = (0, path.join)(studioSource, "routes-manifest.json");
|
|
95
|
+
try {
|
|
96
|
+
const roots = JSON.parse((0, fs.readFileSync)(manifestPath, "utf-8"));
|
|
97
|
+
if (!Array.isArray(roots) || roots.some((root) => typeof root !== "string")) throw new Error("expected an array of route segments");
|
|
98
|
+
return roots;
|
|
99
|
+
} catch (err) {
|
|
100
|
+
throw new Error(`Failed to read studio routes manifest at "${manifestPath}": ${err instanceof Error ? err.message : err}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
90
103
|
getEntry() {
|
|
91
104
|
return `
|
|
92
105
|
import { handle } from 'hono/vercel'
|
|
@@ -138,10 +151,13 @@ export const HEAD = handle(app);
|
|
|
138
151
|
});
|
|
139
152
|
(0, fs.writeFileSync)(indexPath, html);
|
|
140
153
|
}
|
|
141
|
-
writeVercelJSON(outputDirectory) {
|
|
154
|
+
writeVercelJSON(outputDirectory, studioRouteRoots) {
|
|
142
155
|
(0, fs.writeFileSync)((0, path.join)(outputDirectory, "config.json"), JSON.stringify({
|
|
143
156
|
version: 3,
|
|
144
|
-
routes: getVercelRoutes({
|
|
157
|
+
routes: getVercelRoutes({
|
|
158
|
+
studio: this.studio,
|
|
159
|
+
studioRouteRoots
|
|
160
|
+
})
|
|
145
161
|
}));
|
|
146
162
|
}
|
|
147
163
|
async bundle(entryFile, outputDirectory, { toolsPaths, projectRoot }) {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["Deployer"],"sources":["../src/routes.ts","../src/index.ts"],"sourcesContent":["type VercelRoutesOptions = {\n studio: boolean;\n};\n\nexport function getVercelRoutes({ studio }: VercelRoutesOptions) {\n return studio\n ? [\n { src: '^/$', dest: '/index.html' },\n { src: '/api/(.*)', dest: '/' },\n { src: '/health', dest: '/' },\n { handle: 'filesystem' as const },\n { src: '/(.*)', dest: '/index.html', check: true },\n ]\n : [{ src: '/(.*)', dest: '/' }];\n}\n","import { readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport process from 'node:process';\nimport { fileURLToPath } from 'node:url';\nimport type { Config } from '@mastra/core/mastra';\nimport { Deployer } from '@mastra/deployer';\nimport { escapeStudioHtmlValue, injectStudioHtmlConfig } from '@mastra/deployer/build';\nimport { copy, move } from 'fs-extra/esm';\nimport { getVercelRoutes } from './routes';\nimport type { VcConfig, VcConfigOverrides, VercelDeployerOptions } from './types';\n\nexport class VercelDeployer extends Deployer {\n private vcConfigOverrides: VcConfigOverrides = {};\n private studio: boolean;\n\n constructor(options: VercelDeployerOptions = {}) {\n super({ name: 'VERCEL' });\n this.outputDir = join('.vercel', 'output', 'functions', 'index.func');\n this.studio = options.studio ?? false;\n\n const { studio, ...overrides } = options;\n this.vcConfigOverrides = { ...overrides };\n }\n\n protected async getUserBundlerOptions(\n mastraEntryFile: string,\n outputDirectory: string,\n ): Promise<NonNullable<Config['bundler']>> {\n const bundlerOptions = await super.getUserBundlerOptions(mastraEntryFile, outputDirectory);\n\n // Always force externals: true for Vercel deployments.\n // Vercel serverless functions resolve dependencies from node_modules,\n // so bundling them inline serves no purpose. Bundling inline can also cause\n // circular module evaluation deadlocks when dynamic imports produce chunks\n // that depend back on the entry module via static imports, resulting in\n // \"Detected unsettled top-level await\" errors (Node.js exit code 13).\n // See: https://github.com/mastra-ai/mastra/issues/14860\n return {\n ...bundlerOptions,\n externals: true,\n };\n }\n\n async prepare(outputDirectory: string): Promise<void> {\n await super.prepare(outputDirectory);\n\n this.writeVercelJSON(join(outputDirectory, this.outputDir, '..', '..'));\n\n if (this.studio) {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n\n const studioSource = join(dirname(__dirname), 'dist', 'studio');\n const staticDir = join(outputDirectory, '.vercel', 'output', 'static');\n\n try {\n await copy(studioSource, staticDir, { overwrite: true });\n } catch (err) {\n throw new Error(\n `Failed to copy studio assets from \"${studioSource}\" to \"${staticDir}\": ${err instanceof Error ? err.message : err}`,\n );\n }\n\n this.injectStudioConfig(staticDir);\n }\n }\n\n private getEntry(): string {\n return `\nimport { handle } from 'hono/vercel'\nimport { mastra } from '#mastra';\nimport { createHonoServer, getToolExports } from '#server';\nimport { tools } from '#tools';\nimport { scoreTracesWorkflow } from '@mastra/core/evals/scoreTraces';\n\nif (mastra.getStorage()) {\n mastra.__registerInternalWorkflow(scoreTracesWorkflow);\n}\n\nconst app = await createHonoServer(mastra, { tools: getToolExports(tools) });\n\nexport const GET = handle(app);\nexport const POST = handle(app);\nexport const PUT = handle(app);\nexport const DELETE = handle(app);\nexport const PATCH = handle(app);\nexport const OPTIONS = handle(app);\nexport const HEAD = handle(app);\n`;\n }\n\n private injectStudioConfig(staticDir: string) {\n const indexPath = join(staticDir, 'index.html');\n let html = readFileSync(indexPath, 'utf-8');\n\n /**\n * Use window.location expressions so the SPA constructs the correct same-origin endpoint.\n * Port uses a ternary: window.location.port is '' for default ports (80/443), and the SPA falls back to 4111 for empty strings, so we return the default port explicitly instead.\n */\n html = injectStudioHtmlConfig(html, {\n host: `window.location.hostname`,\n port: `(window.location.port || (window.location.protocol === 'https:' ? '443' : '80'))`,\n protocol: `window.location.protocol.replace(':', '')`,\n apiPrefix: `'/api'`,\n basePath: '',\n hideCloudCta: `'true'`,\n templates: `'false'`,\n cloudApiEndpoint: `''`,\n experimentalFeatures: `'false'`,\n telemetryDisabled: `''`,\n requestContextPresets: `''`,\n experimentalUI: `'false'`,\n agentSignals: process.env.MASTRA_AGENT_SIGNALS === 'false' ? `'false'` : `'true'`,\n signalsUI: process.env.MASTRA_SIGNALS_UI === 'true' ? `'true'` : `'false'`,\n organizationId: `'${escapeStudioHtmlValue(process.env.MASTRA_ORGANIZATION_ID || '')}'`,\n platformProjectId: `'${escapeStudioHtmlValue(process.env.MASTRA_PLATFORM_PROJECT_ID || '')}'`,\n platformObservabilityEndpoint: `'${escapeStudioHtmlValue(process.env.MASTRA_PLATFORM_OBSERVABILITY_ENDPOINT || '')}'`,\n });\n\n writeFileSync(indexPath, html);\n }\n\n private writeVercelJSON(outputDirectory: string) {\n writeFileSync(\n join(outputDirectory, 'config.json'),\n JSON.stringify({ version: 3, routes: getVercelRoutes({ studio: this.studio }) }),\n );\n }\n\n async bundle(\n entryFile: string,\n outputDirectory: string,\n { toolsPaths, projectRoot }: { toolsPaths: (string | string[])[]; projectRoot: string },\n ): Promise<void> {\n const result = await this._bundle(\n this.getEntry(),\n entryFile,\n { outputDirectory, projectRoot },\n toolsPaths,\n join(outputDirectory, this.outputDir),\n );\n\n const nodeVersion = process.version?.split('.')?.[0]?.replace('v', '') ?? '22';\n\n const vcConfig: VcConfig = {\n handler: 'index.mjs',\n launcherType: 'Nodejs',\n runtime: `nodejs${nodeVersion}.x`,\n shouldAddHelpers: true,\n };\n\n // Merge supported overrides\n const { maxDuration, memory, regions } = this.vcConfigOverrides;\n if (typeof maxDuration === 'number') vcConfig.maxDuration = maxDuration;\n if (typeof memory === 'number') vcConfig.memory = memory;\n if (Array.isArray(regions) && regions.length > 0) vcConfig.regions = regions;\n\n writeFileSync(join(outputDirectory, this.outputDir, '.vc-config.json'), JSON.stringify(vcConfig, null, 2));\n\n await move(join(outputDirectory, '.vercel', 'output'), join(process.cwd(), '.vercel', 'output'), {\n overwrite: true,\n });\n\n return result;\n }\n\n async deploy(): Promise<void> {\n this.logger?.info('Deploying to Vercel is deprecated. Please use the Vercel dashboard to deploy.');\n }\n\n async lint(entryFile: string, outputDirectory: string, toolsPaths: (string | string[])[]): Promise<void> {\n await super.lint(entryFile, outputDirectory, toolsPaths);\n\n const hasLibsql = (await this.deps.checkDependencies(['@mastra/libsql'])) === `ok`;\n\n if (hasLibsql) {\n this.logger.error(\n `Vercel Deployer does not support @libsql/client(which may have been installed by @mastra/libsql) as a dependency. \n\t\t\t\tUse other Mastra Storage options instead e.g @mastra/pg`,\n );\n process.exit(1);\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["Deployer"],"sources":["../src/routes.ts","../src/index.ts"],"sourcesContent":["type VercelRoutesOptions = {\n studio: boolean;\n /** Studio's top-level route segments, read from the Studio build's routes-manifest.json. */\n studioRouteRoots?: string[];\n};\n\nconst escapeRegExp = (value: string) => value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\nexport function getVercelRoutes({ studio, studioRouteRoots = [] }: VercelRoutesOptions) {\n if (!studio) {\n return [{ src: '/(.*)', dest: '/' }];\n }\n\n // Studio owns a known set of SPA paths; everything else belongs to the server function.\n // The function has to be the catch-all because custom `registerApiRoute()` paths are mounted\n // at the root of the server (never under `apiPrefix`), so the CDN cannot tell them apart from\n // an unknown path — an SPA catch-all would swallow every one of them.\n const spaRoots = studioRouteRoots.map(escapeRegExp).join('|');\n\n return [\n { src: '^/$', dest: '/index.html' },\n ...(spaRoots ? [{ src: `^/(?:${spaRoots})(?:/.*)?$`, dest: '/index.html' }] : []),\n { handle: 'filesystem' as const },\n { src: '/(.*)', dest: '/' },\n ];\n}\n","import { readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport process from 'node:process';\nimport { fileURLToPath } from 'node:url';\nimport type { Config } from '@mastra/core/mastra';\nimport { Deployer } from '@mastra/deployer';\nimport { escapeStudioHtmlValue, injectStudioHtmlConfig } from '@mastra/deployer/build';\nimport { copy, move } from 'fs-extra/esm';\nimport { getVercelRoutes } from './routes';\nimport type { VcConfig, VcConfigOverrides, VercelDeployerOptions } from './types';\n\nexport class VercelDeployer extends Deployer {\n private vcConfigOverrides: VcConfigOverrides = {};\n private studio: boolean;\n\n constructor(options: VercelDeployerOptions = {}) {\n super({ name: 'VERCEL' });\n this.outputDir = join('.vercel', 'output', 'functions', 'index.func');\n this.studio = options.studio ?? false;\n\n const { studio, ...overrides } = options;\n this.vcConfigOverrides = { ...overrides };\n }\n\n protected async getUserBundlerOptions(\n mastraEntryFile: string,\n outputDirectory: string,\n ): Promise<NonNullable<Config['bundler']>> {\n const bundlerOptions = await super.getUserBundlerOptions(mastraEntryFile, outputDirectory);\n\n // Always force externals: true for Vercel deployments.\n // Vercel serverless functions resolve dependencies from node_modules,\n // so bundling them inline serves no purpose. Bundling inline can also cause\n // circular module evaluation deadlocks when dynamic imports produce chunks\n // that depend back on the entry module via static imports, resulting in\n // \"Detected unsettled top-level await\" errors (Node.js exit code 13).\n // See: https://github.com/mastra-ai/mastra/issues/14860\n return {\n ...bundlerOptions,\n externals: true,\n };\n }\n\n async prepare(outputDirectory: string): Promise<void> {\n await super.prepare(outputDirectory);\n\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n\n const studioSource = join(dirname(__dirname), 'dist', 'studio');\n\n this.writeVercelJSON(\n join(outputDirectory, this.outputDir, '..', '..'),\n this.studio ? this.readStudioRouteRoots(studioSource) : [],\n );\n\n if (this.studio) {\n const staticDir = join(outputDirectory, '.vercel', 'output', 'static');\n\n try {\n await copy(studioSource, staticDir, { overwrite: true });\n } catch (err) {\n throw new Error(\n `Failed to copy studio assets from \"${studioSource}\" to \"${staticDir}\": ${err instanceof Error ? err.message : err}`,\n );\n }\n\n this.injectStudioConfig(staticDir);\n }\n }\n\n /**\n * Studio's top-level route segments, emitted by the Studio build alongside index.html.\n * The Vercel route table needs them explicitly: custom `registerApiRoute()` paths are mounted\n * at the root of the server, so the function has to own every path Studio doesn't claim.\n */\n private readStudioRouteRoots(studioSource: string): string[] {\n const manifestPath = join(studioSource, 'routes-manifest.json');\n\n try {\n const roots = JSON.parse(readFileSync(manifestPath, 'utf-8'));\n if (!Array.isArray(roots) || roots.some(root => typeof root !== 'string')) {\n throw new Error('expected an array of route segments');\n }\n return roots;\n } catch (err) {\n throw new Error(\n `Failed to read studio routes manifest at \"${manifestPath}\": ${err instanceof Error ? err.message : err}`,\n );\n }\n }\n\n private getEntry(): string {\n return `\nimport { handle } from 'hono/vercel'\nimport { mastra } from '#mastra';\nimport { createHonoServer, getToolExports } from '#server';\nimport { tools } from '#tools';\nimport { scoreTracesWorkflow } from '@mastra/core/evals/scoreTraces';\n\nif (mastra.getStorage()) {\n mastra.__registerInternalWorkflow(scoreTracesWorkflow);\n}\n\nconst app = await createHonoServer(mastra, { tools: getToolExports(tools) });\n\nexport const GET = handle(app);\nexport const POST = handle(app);\nexport const PUT = handle(app);\nexport const DELETE = handle(app);\nexport const PATCH = handle(app);\nexport const OPTIONS = handle(app);\nexport const HEAD = handle(app);\n`;\n }\n\n private injectStudioConfig(staticDir: string) {\n const indexPath = join(staticDir, 'index.html');\n let html = readFileSync(indexPath, 'utf-8');\n\n /**\n * Use window.location expressions so the SPA constructs the correct same-origin endpoint.\n * Port uses a ternary: window.location.port is '' for default ports (80/443), and the SPA falls back to 4111 for empty strings, so we return the default port explicitly instead.\n */\n html = injectStudioHtmlConfig(html, {\n host: `window.location.hostname`,\n port: `(window.location.port || (window.location.protocol === 'https:' ? '443' : '80'))`,\n protocol: `window.location.protocol.replace(':', '')`,\n apiPrefix: `'/api'`,\n basePath: '',\n hideCloudCta: `'true'`,\n templates: `'false'`,\n cloudApiEndpoint: `''`,\n experimentalFeatures: `'false'`,\n telemetryDisabled: `''`,\n requestContextPresets: `''`,\n experimentalUI: `'false'`,\n agentSignals: process.env.MASTRA_AGENT_SIGNALS === 'false' ? `'false'` : `'true'`,\n signalsUI: process.env.MASTRA_SIGNALS_UI === 'true' ? `'true'` : `'false'`,\n organizationId: `'${escapeStudioHtmlValue(process.env.MASTRA_ORGANIZATION_ID || '')}'`,\n platformProjectId: `'${escapeStudioHtmlValue(process.env.MASTRA_PLATFORM_PROJECT_ID || '')}'`,\n platformObservabilityEndpoint: `'${escapeStudioHtmlValue(process.env.MASTRA_PLATFORM_OBSERVABILITY_ENDPOINT || '')}'`,\n });\n\n writeFileSync(indexPath, html);\n }\n\n private writeVercelJSON(outputDirectory: string, studioRouteRoots: string[]) {\n writeFileSync(\n join(outputDirectory, 'config.json'),\n JSON.stringify({ version: 3, routes: getVercelRoutes({ studio: this.studio, studioRouteRoots }) }),\n );\n }\n\n async bundle(\n entryFile: string,\n outputDirectory: string,\n { toolsPaths, projectRoot }: { toolsPaths: (string | string[])[]; projectRoot: string },\n ): Promise<void> {\n const result = await this._bundle(\n this.getEntry(),\n entryFile,\n { outputDirectory, projectRoot },\n toolsPaths,\n join(outputDirectory, this.outputDir),\n );\n\n const nodeVersion = process.version?.split('.')?.[0]?.replace('v', '') ?? '22';\n\n const vcConfig: VcConfig = {\n handler: 'index.mjs',\n launcherType: 'Nodejs',\n runtime: `nodejs${nodeVersion}.x`,\n shouldAddHelpers: true,\n };\n\n // Merge supported overrides\n const { maxDuration, memory, regions } = this.vcConfigOverrides;\n if (typeof maxDuration === 'number') vcConfig.maxDuration = maxDuration;\n if (typeof memory === 'number') vcConfig.memory = memory;\n if (Array.isArray(regions) && regions.length > 0) vcConfig.regions = regions;\n\n writeFileSync(join(outputDirectory, this.outputDir, '.vc-config.json'), JSON.stringify(vcConfig, null, 2));\n\n await move(join(outputDirectory, '.vercel', 'output'), join(process.cwd(), '.vercel', 'output'), {\n overwrite: true,\n });\n\n return result;\n }\n\n async deploy(): Promise<void> {\n this.logger?.info('Deploying to Vercel is deprecated. Please use the Vercel dashboard to deploy.');\n }\n\n async lint(entryFile: string, outputDirectory: string, toolsPaths: (string | string[])[]): Promise<void> {\n await super.lint(entryFile, outputDirectory, toolsPaths);\n\n const hasLibsql = (await this.deps.checkDependencies(['@mastra/libsql'])) === `ok`;\n\n if (hasLibsql) {\n this.logger.error(\n `Vercel Deployer does not support @libsql/client(which may have been installed by @mastra/libsql) as a dependency. \n\t\t\t\tUse other Mastra Storage options instead e.g @mastra/pg`,\n );\n process.exit(1);\n }\n }\n}\n"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,12 @@ export declare class VercelDeployer extends Deployer {
|
|
|
7
7
|
constructor(options?: VercelDeployerOptions);
|
|
8
8
|
protected getUserBundlerOptions(mastraEntryFile: string, outputDirectory: string): Promise<NonNullable<Config['bundler']>>;
|
|
9
9
|
prepare(outputDirectory: string): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Studio's top-level route segments, emitted by the Studio build alongside index.html.
|
|
12
|
+
* The Vercel route table needs them explicitly: custom `registerApiRoute()` paths are mounted
|
|
13
|
+
* at the root of the server, so the function has to own every path Studio doesn't claim.
|
|
14
|
+
*/
|
|
15
|
+
private readStudioRouteRoots;
|
|
10
16
|
private getEntry;
|
|
11
17
|
private injectStudioConfig;
|
|
12
18
|
private writeVercelJSON;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAI5C,OAAO,KAAK,EAA+B,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAElF,qBAAa,cAAe,SAAQ,QAAQ;IAC1C,OAAO,CAAC,iBAAiB,CAAyB;IAClD,OAAO,CAAC,MAAM,CAAU;gBAEZ,OAAO,GAAE,qBAA0B;cAS/B,qBAAqB,CACnC,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;IAgBpC,OAAO,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAI5C,OAAO,KAAK,EAA+B,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAElF,qBAAa,cAAe,SAAQ,QAAQ;IAC1C,OAAO,CAAC,iBAAiB,CAAyB;IAClD,OAAO,CAAC,MAAM,CAAU;gBAEZ,OAAO,GAAE,qBAA0B;cAS/B,qBAAqB,CACnC,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;IAgBpC,OAAO,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BrD;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAgB5B,OAAO,CAAC,QAAQ;IAwBhB,OAAO,CAAC,kBAAkB;IA+B1B,OAAO,CAAC,eAAe;IAOjB,MAAM,CACV,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE;QAAE,UAAU,EAAE,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GACtF,OAAO,CAAC,IAAI,CAAC;IAiCV,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAIvB,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAazG"}
|
package/dist/index.js
CHANGED
|
@@ -6,30 +6,28 @@ import { Deployer } from "@mastra/deployer";
|
|
|
6
6
|
import { escapeStudioHtmlValue, injectStudioHtmlConfig } from "@mastra/deployer/build";
|
|
7
7
|
import { copy, move } from "fs-extra/esm";
|
|
8
8
|
//#region src/routes.ts
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
10
|
+
function getVercelRoutes({ studio, studioRouteRoots = [] }) {
|
|
11
|
+
if (!studio) return [{
|
|
12
|
+
src: "/(.*)",
|
|
13
|
+
dest: "/"
|
|
14
|
+
}];
|
|
15
|
+
const spaRoots = studioRouteRoots.map(escapeRegExp).join("|");
|
|
16
|
+
return [
|
|
11
17
|
{
|
|
12
18
|
src: "^/$",
|
|
13
19
|
dest: "/index.html"
|
|
14
20
|
},
|
|
15
|
-
{
|
|
16
|
-
src:
|
|
17
|
-
dest: "/"
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
src: "/health",
|
|
21
|
-
dest: "/"
|
|
22
|
-
},
|
|
21
|
+
...spaRoots ? [{
|
|
22
|
+
src: `^/(?:${spaRoots})(?:/.*)?$`,
|
|
23
|
+
dest: "/index.html"
|
|
24
|
+
}] : [],
|
|
23
25
|
{ handle: "filesystem" },
|
|
24
26
|
{
|
|
25
27
|
src: "/(.*)",
|
|
26
|
-
dest: "/
|
|
27
|
-
check: true
|
|
28
|
+
dest: "/"
|
|
28
29
|
}
|
|
29
|
-
]
|
|
30
|
-
src: "/(.*)",
|
|
31
|
-
dest: "/"
|
|
32
|
-
}];
|
|
30
|
+
];
|
|
33
31
|
}
|
|
34
32
|
//#endregion
|
|
35
33
|
//#region src/index.ts
|
|
@@ -51,9 +49,9 @@ var VercelDeployer = class extends Deployer {
|
|
|
51
49
|
}
|
|
52
50
|
async prepare(outputDirectory) {
|
|
53
51
|
await super.prepare(outputDirectory);
|
|
54
|
-
|
|
52
|
+
const studioSource = join(dirname(dirname(fileURLToPath(import.meta.url))), "dist", "studio");
|
|
53
|
+
this.writeVercelJSON(join(outputDirectory, this.outputDir, "..", ".."), this.studio ? this.readStudioRouteRoots(studioSource) : []);
|
|
55
54
|
if (this.studio) {
|
|
56
|
-
const studioSource = join(dirname(dirname(fileURLToPath(import.meta.url))), "dist", "studio");
|
|
57
55
|
const staticDir = join(outputDirectory, ".vercel", "output", "static");
|
|
58
56
|
try {
|
|
59
57
|
await copy(studioSource, staticDir, { overwrite: true });
|
|
@@ -63,6 +61,21 @@ var VercelDeployer = class extends Deployer {
|
|
|
63
61
|
this.injectStudioConfig(staticDir);
|
|
64
62
|
}
|
|
65
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Studio's top-level route segments, emitted by the Studio build alongside index.html.
|
|
66
|
+
* The Vercel route table needs them explicitly: custom `registerApiRoute()` paths are mounted
|
|
67
|
+
* at the root of the server, so the function has to own every path Studio doesn't claim.
|
|
68
|
+
*/
|
|
69
|
+
readStudioRouteRoots(studioSource) {
|
|
70
|
+
const manifestPath = join(studioSource, "routes-manifest.json");
|
|
71
|
+
try {
|
|
72
|
+
const roots = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
73
|
+
if (!Array.isArray(roots) || roots.some((root) => typeof root !== "string")) throw new Error("expected an array of route segments");
|
|
74
|
+
return roots;
|
|
75
|
+
} catch (err) {
|
|
76
|
+
throw new Error(`Failed to read studio routes manifest at "${manifestPath}": ${err instanceof Error ? err.message : err}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
66
79
|
getEntry() {
|
|
67
80
|
return `
|
|
68
81
|
import { handle } from 'hono/vercel'
|
|
@@ -114,10 +127,13 @@ export const HEAD = handle(app);
|
|
|
114
127
|
});
|
|
115
128
|
writeFileSync(indexPath, html);
|
|
116
129
|
}
|
|
117
|
-
writeVercelJSON(outputDirectory) {
|
|
130
|
+
writeVercelJSON(outputDirectory, studioRouteRoots) {
|
|
118
131
|
writeFileSync(join(outputDirectory, "config.json"), JSON.stringify({
|
|
119
132
|
version: 3,
|
|
120
|
-
routes: getVercelRoutes({
|
|
133
|
+
routes: getVercelRoutes({
|
|
134
|
+
studio: this.studio,
|
|
135
|
+
studioRouteRoots
|
|
136
|
+
})
|
|
121
137
|
}));
|
|
122
138
|
}
|
|
123
139
|
async bundle(entryFile, outputDirectory, { toolsPaths, projectRoot }) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/routes.ts","../src/index.ts"],"sourcesContent":["type VercelRoutesOptions = {\n studio: boolean;\n};\n\nexport function getVercelRoutes({ studio }: VercelRoutesOptions) {\n return studio\n ? [\n { src: '^/$', dest: '/index.html' },\n { src: '/api/(.*)', dest: '/' },\n { src: '/health', dest: '/' },\n { handle: 'filesystem' as const },\n { src: '/(.*)', dest: '/index.html', check: true },\n ]\n : [{ src: '/(.*)', dest: '/' }];\n}\n","import { readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport process from 'node:process';\nimport { fileURLToPath } from 'node:url';\nimport type { Config } from '@mastra/core/mastra';\nimport { Deployer } from '@mastra/deployer';\nimport { escapeStudioHtmlValue, injectStudioHtmlConfig } from '@mastra/deployer/build';\nimport { copy, move } from 'fs-extra/esm';\nimport { getVercelRoutes } from './routes';\nimport type { VcConfig, VcConfigOverrides, VercelDeployerOptions } from './types';\n\nexport class VercelDeployer extends Deployer {\n private vcConfigOverrides: VcConfigOverrides = {};\n private studio: boolean;\n\n constructor(options: VercelDeployerOptions = {}) {\n super({ name: 'VERCEL' });\n this.outputDir = join('.vercel', 'output', 'functions', 'index.func');\n this.studio = options.studio ?? false;\n\n const { studio, ...overrides } = options;\n this.vcConfigOverrides = { ...overrides };\n }\n\n protected async getUserBundlerOptions(\n mastraEntryFile: string,\n outputDirectory: string,\n ): Promise<NonNullable<Config['bundler']>> {\n const bundlerOptions = await super.getUserBundlerOptions(mastraEntryFile, outputDirectory);\n\n // Always force externals: true for Vercel deployments.\n // Vercel serverless functions resolve dependencies from node_modules,\n // so bundling them inline serves no purpose. Bundling inline can also cause\n // circular module evaluation deadlocks when dynamic imports produce chunks\n // that depend back on the entry module via static imports, resulting in\n // \"Detected unsettled top-level await\" errors (Node.js exit code 13).\n // See: https://github.com/mastra-ai/mastra/issues/14860\n return {\n ...bundlerOptions,\n externals: true,\n };\n }\n\n async prepare(outputDirectory: string): Promise<void> {\n await super.prepare(outputDirectory);\n\n this.writeVercelJSON(join(outputDirectory, this.outputDir, '..', '..'));\n\n if (this.studio) {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n\n const studioSource = join(dirname(__dirname), 'dist', 'studio');\n const staticDir = join(outputDirectory, '.vercel', 'output', 'static');\n\n try {\n await copy(studioSource, staticDir, { overwrite: true });\n } catch (err) {\n throw new Error(\n `Failed to copy studio assets from \"${studioSource}\" to \"${staticDir}\": ${err instanceof Error ? err.message : err}`,\n );\n }\n\n this.injectStudioConfig(staticDir);\n }\n }\n\n private getEntry(): string {\n return `\nimport { handle } from 'hono/vercel'\nimport { mastra } from '#mastra';\nimport { createHonoServer, getToolExports } from '#server';\nimport { tools } from '#tools';\nimport { scoreTracesWorkflow } from '@mastra/core/evals/scoreTraces';\n\nif (mastra.getStorage()) {\n mastra.__registerInternalWorkflow(scoreTracesWorkflow);\n}\n\nconst app = await createHonoServer(mastra, { tools: getToolExports(tools) });\n\nexport const GET = handle(app);\nexport const POST = handle(app);\nexport const PUT = handle(app);\nexport const DELETE = handle(app);\nexport const PATCH = handle(app);\nexport const OPTIONS = handle(app);\nexport const HEAD = handle(app);\n`;\n }\n\n private injectStudioConfig(staticDir: string) {\n const indexPath = join(staticDir, 'index.html');\n let html = readFileSync(indexPath, 'utf-8');\n\n /**\n * Use window.location expressions so the SPA constructs the correct same-origin endpoint.\n * Port uses a ternary: window.location.port is '' for default ports (80/443), and the SPA falls back to 4111 for empty strings, so we return the default port explicitly instead.\n */\n html = injectStudioHtmlConfig(html, {\n host: `window.location.hostname`,\n port: `(window.location.port || (window.location.protocol === 'https:' ? '443' : '80'))`,\n protocol: `window.location.protocol.replace(':', '')`,\n apiPrefix: `'/api'`,\n basePath: '',\n hideCloudCta: `'true'`,\n templates: `'false'`,\n cloudApiEndpoint: `''`,\n experimentalFeatures: `'false'`,\n telemetryDisabled: `''`,\n requestContextPresets: `''`,\n experimentalUI: `'false'`,\n agentSignals: process.env.MASTRA_AGENT_SIGNALS === 'false' ? `'false'` : `'true'`,\n signalsUI: process.env.MASTRA_SIGNALS_UI === 'true' ? `'true'` : `'false'`,\n organizationId: `'${escapeStudioHtmlValue(process.env.MASTRA_ORGANIZATION_ID || '')}'`,\n platformProjectId: `'${escapeStudioHtmlValue(process.env.MASTRA_PLATFORM_PROJECT_ID || '')}'`,\n platformObservabilityEndpoint: `'${escapeStudioHtmlValue(process.env.MASTRA_PLATFORM_OBSERVABILITY_ENDPOINT || '')}'`,\n });\n\n writeFileSync(indexPath, html);\n }\n\n private writeVercelJSON(outputDirectory: string) {\n writeFileSync(\n join(outputDirectory, 'config.json'),\n JSON.stringify({ version: 3, routes: getVercelRoutes({ studio: this.studio }) }),\n );\n }\n\n async bundle(\n entryFile: string,\n outputDirectory: string,\n { toolsPaths, projectRoot }: { toolsPaths: (string | string[])[]; projectRoot: string },\n ): Promise<void> {\n const result = await this._bundle(\n this.getEntry(),\n entryFile,\n { outputDirectory, projectRoot },\n toolsPaths,\n join(outputDirectory, this.outputDir),\n );\n\n const nodeVersion = process.version?.split('.')?.[0]?.replace('v', '') ?? '22';\n\n const vcConfig: VcConfig = {\n handler: 'index.mjs',\n launcherType: 'Nodejs',\n runtime: `nodejs${nodeVersion}.x`,\n shouldAddHelpers: true,\n };\n\n // Merge supported overrides\n const { maxDuration, memory, regions } = this.vcConfigOverrides;\n if (typeof maxDuration === 'number') vcConfig.maxDuration = maxDuration;\n if (typeof memory === 'number') vcConfig.memory = memory;\n if (Array.isArray(regions) && regions.length > 0) vcConfig.regions = regions;\n\n writeFileSync(join(outputDirectory, this.outputDir, '.vc-config.json'), JSON.stringify(vcConfig, null, 2));\n\n await move(join(outputDirectory, '.vercel', 'output'), join(process.cwd(), '.vercel', 'output'), {\n overwrite: true,\n });\n\n return result;\n }\n\n async deploy(): Promise<void> {\n this.logger?.info('Deploying to Vercel is deprecated. Please use the Vercel dashboard to deploy.');\n }\n\n async lint(entryFile: string, outputDirectory: string, toolsPaths: (string | string[])[]): Promise<void> {\n await super.lint(entryFile, outputDirectory, toolsPaths);\n\n const hasLibsql = (await this.deps.checkDependencies(['@mastra/libsql'])) === `ok`;\n\n if (hasLibsql) {\n this.logger.error(\n `Vercel Deployer does not support @libsql/client(which may have been installed by @mastra/libsql) as a dependency. \n\t\t\t\tUse other Mastra Storage options instead e.g @mastra/pg`,\n );\n process.exit(1);\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/routes.ts","../src/index.ts"],"sourcesContent":["type VercelRoutesOptions = {\n studio: boolean;\n /** Studio's top-level route segments, read from the Studio build's routes-manifest.json. */\n studioRouteRoots?: string[];\n};\n\nconst escapeRegExp = (value: string) => value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\nexport function getVercelRoutes({ studio, studioRouteRoots = [] }: VercelRoutesOptions) {\n if (!studio) {\n return [{ src: '/(.*)', dest: '/' }];\n }\n\n // Studio owns a known set of SPA paths; everything else belongs to the server function.\n // The function has to be the catch-all because custom `registerApiRoute()` paths are mounted\n // at the root of the server (never under `apiPrefix`), so the CDN cannot tell them apart from\n // an unknown path — an SPA catch-all would swallow every one of them.\n const spaRoots = studioRouteRoots.map(escapeRegExp).join('|');\n\n return [\n { src: '^/$', dest: '/index.html' },\n ...(spaRoots ? [{ src: `^/(?:${spaRoots})(?:/.*)?$`, dest: '/index.html' }] : []),\n { handle: 'filesystem' as const },\n { src: '/(.*)', dest: '/' },\n ];\n}\n","import { readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport process from 'node:process';\nimport { fileURLToPath } from 'node:url';\nimport type { Config } from '@mastra/core/mastra';\nimport { Deployer } from '@mastra/deployer';\nimport { escapeStudioHtmlValue, injectStudioHtmlConfig } from '@mastra/deployer/build';\nimport { copy, move } from 'fs-extra/esm';\nimport { getVercelRoutes } from './routes';\nimport type { VcConfig, VcConfigOverrides, VercelDeployerOptions } from './types';\n\nexport class VercelDeployer extends Deployer {\n private vcConfigOverrides: VcConfigOverrides = {};\n private studio: boolean;\n\n constructor(options: VercelDeployerOptions = {}) {\n super({ name: 'VERCEL' });\n this.outputDir = join('.vercel', 'output', 'functions', 'index.func');\n this.studio = options.studio ?? false;\n\n const { studio, ...overrides } = options;\n this.vcConfigOverrides = { ...overrides };\n }\n\n protected async getUserBundlerOptions(\n mastraEntryFile: string,\n outputDirectory: string,\n ): Promise<NonNullable<Config['bundler']>> {\n const bundlerOptions = await super.getUserBundlerOptions(mastraEntryFile, outputDirectory);\n\n // Always force externals: true for Vercel deployments.\n // Vercel serverless functions resolve dependencies from node_modules,\n // so bundling them inline serves no purpose. Bundling inline can also cause\n // circular module evaluation deadlocks when dynamic imports produce chunks\n // that depend back on the entry module via static imports, resulting in\n // \"Detected unsettled top-level await\" errors (Node.js exit code 13).\n // See: https://github.com/mastra-ai/mastra/issues/14860\n return {\n ...bundlerOptions,\n externals: true,\n };\n }\n\n async prepare(outputDirectory: string): Promise<void> {\n await super.prepare(outputDirectory);\n\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n\n const studioSource = join(dirname(__dirname), 'dist', 'studio');\n\n this.writeVercelJSON(\n join(outputDirectory, this.outputDir, '..', '..'),\n this.studio ? this.readStudioRouteRoots(studioSource) : [],\n );\n\n if (this.studio) {\n const staticDir = join(outputDirectory, '.vercel', 'output', 'static');\n\n try {\n await copy(studioSource, staticDir, { overwrite: true });\n } catch (err) {\n throw new Error(\n `Failed to copy studio assets from \"${studioSource}\" to \"${staticDir}\": ${err instanceof Error ? err.message : err}`,\n );\n }\n\n this.injectStudioConfig(staticDir);\n }\n }\n\n /**\n * Studio's top-level route segments, emitted by the Studio build alongside index.html.\n * The Vercel route table needs them explicitly: custom `registerApiRoute()` paths are mounted\n * at the root of the server, so the function has to own every path Studio doesn't claim.\n */\n private readStudioRouteRoots(studioSource: string): string[] {\n const manifestPath = join(studioSource, 'routes-manifest.json');\n\n try {\n const roots = JSON.parse(readFileSync(manifestPath, 'utf-8'));\n if (!Array.isArray(roots) || roots.some(root => typeof root !== 'string')) {\n throw new Error('expected an array of route segments');\n }\n return roots;\n } catch (err) {\n throw new Error(\n `Failed to read studio routes manifest at \"${manifestPath}\": ${err instanceof Error ? err.message : err}`,\n );\n }\n }\n\n private getEntry(): string {\n return `\nimport { handle } from 'hono/vercel'\nimport { mastra } from '#mastra';\nimport { createHonoServer, getToolExports } from '#server';\nimport { tools } from '#tools';\nimport { scoreTracesWorkflow } from '@mastra/core/evals/scoreTraces';\n\nif (mastra.getStorage()) {\n mastra.__registerInternalWorkflow(scoreTracesWorkflow);\n}\n\nconst app = await createHonoServer(mastra, { tools: getToolExports(tools) });\n\nexport const GET = handle(app);\nexport const POST = handle(app);\nexport const PUT = handle(app);\nexport const DELETE = handle(app);\nexport const PATCH = handle(app);\nexport const OPTIONS = handle(app);\nexport const HEAD = handle(app);\n`;\n }\n\n private injectStudioConfig(staticDir: string) {\n const indexPath = join(staticDir, 'index.html');\n let html = readFileSync(indexPath, 'utf-8');\n\n /**\n * Use window.location expressions so the SPA constructs the correct same-origin endpoint.\n * Port uses a ternary: window.location.port is '' for default ports (80/443), and the SPA falls back to 4111 for empty strings, so we return the default port explicitly instead.\n */\n html = injectStudioHtmlConfig(html, {\n host: `window.location.hostname`,\n port: `(window.location.port || (window.location.protocol === 'https:' ? '443' : '80'))`,\n protocol: `window.location.protocol.replace(':', '')`,\n apiPrefix: `'/api'`,\n basePath: '',\n hideCloudCta: `'true'`,\n templates: `'false'`,\n cloudApiEndpoint: `''`,\n experimentalFeatures: `'false'`,\n telemetryDisabled: `''`,\n requestContextPresets: `''`,\n experimentalUI: `'false'`,\n agentSignals: process.env.MASTRA_AGENT_SIGNALS === 'false' ? `'false'` : `'true'`,\n signalsUI: process.env.MASTRA_SIGNALS_UI === 'true' ? `'true'` : `'false'`,\n organizationId: `'${escapeStudioHtmlValue(process.env.MASTRA_ORGANIZATION_ID || '')}'`,\n platformProjectId: `'${escapeStudioHtmlValue(process.env.MASTRA_PLATFORM_PROJECT_ID || '')}'`,\n platformObservabilityEndpoint: `'${escapeStudioHtmlValue(process.env.MASTRA_PLATFORM_OBSERVABILITY_ENDPOINT || '')}'`,\n });\n\n writeFileSync(indexPath, html);\n }\n\n private writeVercelJSON(outputDirectory: string, studioRouteRoots: string[]) {\n writeFileSync(\n join(outputDirectory, 'config.json'),\n JSON.stringify({ version: 3, routes: getVercelRoutes({ studio: this.studio, studioRouteRoots }) }),\n );\n }\n\n async bundle(\n entryFile: string,\n outputDirectory: string,\n { toolsPaths, projectRoot }: { toolsPaths: (string | string[])[]; projectRoot: string },\n ): Promise<void> {\n const result = await this._bundle(\n this.getEntry(),\n entryFile,\n { outputDirectory, projectRoot },\n toolsPaths,\n join(outputDirectory, this.outputDir),\n );\n\n const nodeVersion = process.version?.split('.')?.[0]?.replace('v', '') ?? '22';\n\n const vcConfig: VcConfig = {\n handler: 'index.mjs',\n launcherType: 'Nodejs',\n runtime: `nodejs${nodeVersion}.x`,\n shouldAddHelpers: true,\n };\n\n // Merge supported overrides\n const { maxDuration, memory, regions } = this.vcConfigOverrides;\n if (typeof maxDuration === 'number') vcConfig.maxDuration = maxDuration;\n if (typeof memory === 'number') vcConfig.memory = memory;\n if (Array.isArray(regions) && regions.length > 0) vcConfig.regions = regions;\n\n writeFileSync(join(outputDirectory, this.outputDir, '.vc-config.json'), JSON.stringify(vcConfig, null, 2));\n\n await move(join(outputDirectory, '.vercel', 'output'), join(process.cwd(), '.vercel', 'output'), {\n overwrite: true,\n });\n\n return result;\n }\n\n async deploy(): Promise<void> {\n this.logger?.info('Deploying to Vercel is deprecated. Please use the Vercel dashboard to deploy.');\n }\n\n async lint(entryFile: string, outputDirectory: string, toolsPaths: (string | string[])[]): Promise<void> {\n await super.lint(entryFile, outputDirectory, toolsPaths);\n\n const hasLibsql = (await this.deps.checkDependencies(['@mastra/libsql'])) === `ok`;\n\n if (hasLibsql) {\n this.logger.error(\n `Vercel Deployer does not support @libsql/client(which may have been installed by @mastra/libsql) as a dependency. \n\t\t\t\tUse other Mastra Storage options instead e.g @mastra/pg`,\n );\n process.exit(1);\n }\n }\n}\n"],"mappings":"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"}
|
package/dist/routes.d.ts
CHANGED
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
type VercelRoutesOptions = {
|
|
2
2
|
studio: boolean;
|
|
3
|
+
/** Studio's top-level route segments, read from the Studio build's routes-manifest.json. */
|
|
4
|
+
studioRouteRoots?: string[];
|
|
3
5
|
};
|
|
4
|
-
export declare function getVercelRoutes({ studio }: VercelRoutesOptions): ({
|
|
6
|
+
export declare function getVercelRoutes({ studio, studioRouteRoots }: VercelRoutesOptions): ({
|
|
5
7
|
src: string;
|
|
6
8
|
dest: string;
|
|
7
9
|
handle?: undefined;
|
|
8
|
-
check?: undefined;
|
|
9
10
|
} | {
|
|
10
11
|
handle: "filesystem";
|
|
11
12
|
src?: undefined;
|
|
12
13
|
dest?: undefined;
|
|
13
|
-
check?: undefined;
|
|
14
|
-
} | {
|
|
15
|
-
src: string;
|
|
16
|
-
dest: string;
|
|
17
|
-
check: boolean;
|
|
18
|
-
handle?: undefined;
|
|
19
14
|
})[];
|
|
20
15
|
export {};
|
|
21
16
|
//# sourceMappingURL=routes.d.ts.map
|
package/dist/routes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAAA,KAAK,mBAAmB,GAAG;IACzB,MAAM,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAAA,KAAK,mBAAmB,GAAG;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,4FAA4F;IAC5F,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B,CAAC;AAIF,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,gBAAqB,EAAE,EAAE,mBAAmB;;;;;;;;KAiBrF"}
|