@mastra/fastify 1.3.26-alpha.5 → 1.3.26-alpha.6
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 +10 -0
- package/dist/index.cjs +15 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @mastra/fastify
|
|
2
2
|
|
|
3
|
+
## 1.3.26-alpha.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Fixed custom API route responses dropping headers set by Fastify plugins. Headers applied via Fastify hooks (e.g. `Access-Control-Allow-Origin` from `@fastify/cors`) were overwritten when the adapter hijacked the reply to stream the custom route response. The adapter now merges hook-set headers into the response before hijack — matching the behavior already implemented for streaming routes. ([#15719](https://github.com/mastra-ai/mastra/pull/15719))
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`bb3fce8`](https://github.com/mastra-ai/mastra/commit/bb3fce8f8d80079170c0f98cb2efbb29ae34375d), [`19a8658`](https://github.com/mastra-ai/mastra/commit/19a86589c788ef48bb6c1b0612cc82a201857379), [`1a97509`](https://github.com/mastra-ai/mastra/commit/1a975099596faf8c3d7e19f6235d5b2969cc39a9), [`1fad344`](https://github.com/mastra-ai/mastra/commit/1fad344c6554142b2061f480ae0b336164ab5efb), [`a659a77`](https://github.com/mastra-ai/mastra/commit/a659a779bdebe3a52a518c56d2260592d0240fe0), [`3332be9`](https://github.com/mastra-ai/mastra/commit/3332be9701ecd77aba840959d9a1d1ce7aef02d3)]:
|
|
10
|
+
- @mastra/server@1.38.0-alpha.6
|
|
11
|
+
- @mastra/core@1.38.0-alpha.6
|
|
12
|
+
|
|
3
13
|
## 1.3.26-alpha.5
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -678,6 +678,21 @@ var MastraServer = class extends serverAdapter.MastraServer {
|
|
|
678
678
|
reply.status(404).send({ error: "Not Found" });
|
|
679
679
|
return;
|
|
680
680
|
}
|
|
681
|
+
const existingHeaders = reply.getHeaders();
|
|
682
|
+
for (const [key, value] of Object.entries(existingHeaders)) {
|
|
683
|
+
if (value === void 0) continue;
|
|
684
|
+
const lowerKey = key.toLowerCase();
|
|
685
|
+
if (lowerKey === "content-length" || lowerKey === "transfer-encoding") continue;
|
|
686
|
+
const isSetCookie = lowerKey === "set-cookie";
|
|
687
|
+
if (!isSetCookie && response.headers.has(key)) continue;
|
|
688
|
+
if (Array.isArray(value)) {
|
|
689
|
+
for (const item of value) response.headers.append(key, String(item));
|
|
690
|
+
} else if (isSetCookie) {
|
|
691
|
+
response.headers.append(key, String(value));
|
|
692
|
+
} else {
|
|
693
|
+
response.headers.set(key, String(value));
|
|
694
|
+
}
|
|
695
|
+
}
|
|
681
696
|
reply.hijack();
|
|
682
697
|
await this.writeCustomRouteResponse(response, reply.raw, request.abortSignal);
|
|
683
698
|
};
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/auth-middleware.ts","../src/index.ts"],"names":["RequestContext","coreAuthMiddleware","toWebRequest","MastraServerBase","redactStreamChunk","normalizeQueryParams","busboy","Busboy","isZodError","checkRouteFGA"],"mappings":";;;;;;;;AAUA,SAAS,aAAa,OAAA,EAA6C;AACjE,EAAA,MAAM,QAAA,GAAW,QAAQ,QAAA,IAAY,MAAA;AACrC,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,OAAA,CAAQ,IAAA,IAAQ,WAAA;AACrC,EAAA,MAAM,MAAM,CAAA,EAAG,QAAQ,MAAM,IAAI,CAAA,EAAG,QAAQ,GAAG,CAAA,CAAA;AAE/C,EAAA,MAAM,OAAA,GAAU,IAAI,OAAA,EAAQ;AAC5B,EAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,OAAA,CAAQ,OAAO,CAAA,EAAG;AAC1D,IAAA,IAAI,CAAC,KAAA,EAAO;AACZ,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,MAAA,KAAA,CAAM,QAAQ,CAAA,CAAA,KAAK,OAAA,CAAQ,MAAA,CAAO,GAAA,EAAK,CAAC,CAAC,CAAA;AAAA,IAC3C,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,GAAA,CAAI,KAAK,KAAK,CAAA;AAAA,IACxB;AAAA,EACF;AAEA,EAAA,OAAO,IAAI,UAAA,CAAW,OAAA,CAAQ,GAAA,EAAK;AAAA,IACjC,QAAQ,OAAA,CAAQ,MAAA;AAAA,IAChB;AAAA,GACD,CAAA;AACH;AAEO,SAAS,oBAAA,CAAqB;AAAA,EACnC,MAAA;AAAA,EACA,YAAA,GAAe;AACjB,CAAA,EAAwD;AACtD,EAAA,OAAO,OAAO,SAAyB,KAAA,KAAwB;AAC7D,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,UAAA,GAAa,MAAA,CAAO,SAAA,EAAU,EAAG,IAAA;AACvC,IAAA,IAAI,CAAC,UAAA,EAAY;AACf,MAAA;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,cAAA,KAAmB,IAAIA,6BAAA,EAAe;AAC9C,IAAA,OAAA,CAAQ,MAAA,KAAW,MAAA;AAEnB,IAAA,MAAM,IAAA,GAAO,OAAO,OAAA,CAAQ,GAAA,CAAI,MAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,GAAG,CAAA;AACpD,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,OAAA,CAAQ,MAAA,IAAU,KAAK,CAAA;AAC7C,IAAA,MAAM,wBAAwB,IAAI,GAAA,CAAqB,OAAA,CAAQ,qBAAA,IAAyB,EAAE,CAAA;AAC1F,IAAA,qBAAA,CAAsB,IAAI,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,IAAI,IAAI,IAAI,CAAA;AAEnD,IAAA,MAAM,UAAA,GAAa,QAAQ,OAAA,CAAQ,aAAA;AACnC,IAAA,IAAI,QAAuB,UAAA,GAAa,UAAA,CAAW,OAAA,CAAQ,SAAA,EAAW,EAAE,CAAA,GAAI,IAAA;AAC5E,IAAA,MAAM,QAAQ,OAAA,CAAQ,KAAA;AACtB,IAAA,IAAI,CAAC,KAAA,IAAS,KAAA,CAAM,MAAA,EAAQ;AAC1B,MAAA,KAAA,GAAQ,MAAM,MAAA,IAAU,IAAA;AAAA,IAC1B;AAEA,IAAA,MAAM,MAAA,GAAS,MAAMC,uBAAA,CAAmB;AAAA,MACtC,IAAA;AAAA,MACA,MAAA;AAAA,MACA,WAAW,CAAA,IAAA,KAAQ,OAAA,CAAQ,OAAA,CAAQ,IAAA,CAAK,aAAa,CAAA;AAAA,MACrD,MAAA;AAAA,MACA,UAAA;AAAA,MACA,qBAAA;AAAA,MACA,gBAAgB,OAAA,CAAQ,cAAA;AAAA,MACxB,UAAA,EAAY,aAAa,OAAO,CAAA;AAAA,MAChC,KAAA;AAAA,MACA,qBAAA,EAAuB,MAAM,YAAA,CAAa,OAAO;AAAA,KAClD,CAAA;AAED,IAAA,IAAI,MAAA,CAAO,WAAW,OAAA,EAAS;AAC7B,MAAA,OAAO,MAAM,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA,CAAE,IAAA,CAAK,OAAO,IAAI,CAAA;AAAA,IACrD;AAAA,EACF,CAAA;AACF;;;AC1DA,IAAI,qBAAA;AACJ,SAAS,iBAAA,GAA0D;AACjE,EAAA,IAAI,CAAC,qBAAA,EAAuB;AAC1B,IAAA,qBAAA,GAAwB,OAAO,sBAAsB,CAAA,CAClD,IAAA,CAAK,OAAK,CAAA,CAAE,aAAa,CAAA,CACzB,KAAA,CAAM,MAAM;AACX,MAAA,OAAA,CAAQ,KAAA;AAAA,QACN;AAAA,OACF;AACA,MAAA,OAAO,MAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACL;AACA,EAAA,OAAO,qBAAA;AACT;AAKA,SAASC,cAAa,OAAA,EAA6C;AACjE,EAAA,MAAM,QAAA,GAAW,QAAQ,QAAA,IAAY,MAAA;AACrC,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,OAAA,CAAQ,IAAA,IAAQ,WAAA;AACrC,EAAA,MAAM,MAAM,CAAA,EAAG,QAAQ,MAAM,IAAI,CAAA,EAAG,QAAQ,GAAG,CAAA,CAAA;AAE/C,EAAA,MAAM,OAAA,GAAU,IAAI,OAAA,EAAQ;AAC5B,EAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,OAAA,CAAQ,OAAO,CAAA,EAAG;AAC1D,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,QAAA,KAAA,CAAM,QAAQ,CAAA,CAAA,KAAK,OAAA,CAAQ,MAAA,CAAO,GAAA,EAAK,CAAC,CAAC,CAAA;AAAA,MAC3C,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,GAAA,CAAI,KAAK,KAAK,CAAA;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,IAAI,UAAA,CAAW,OAAA,CAAQ,GAAA,EAAK;AAAA,IACjC,QAAQ,OAAA,CAAQ,MAAA;AAAA,IAChB;AAAA,GACD,CAAA;AACH;AAEA,SAAS,iBAAiB,UAAA,EAA4C;AAIpE,EAAA,OAAO,UAAA,CAAW,OAAA,IAAW,UAAA,CAAW,eAAA,IAAmB,CAAC,UAAA,CAAW,QAAA;AACzE;AAcO,IAAM,YAAA,GAAN,cAA2BC,0BAAA,CAAgE;AAAA,EAChG,uBAAA,GAAiD;AAC/C,IAAA,OAAO,OAAO,SAAyB,KAAA,KAAwB;AAE7D,MAAA,IAAI,kBAAA;AACJ,MAAA,IAAI,oBAAA;AAGJ,MAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,MAAA,IAAU,OAAA,CAAQ,WAAW,KAAA,EAAO;AACzD,QAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,OAAA,CAAQ,cAAc,CAAA;AAClD,QAAA,IAAI,WAAA,EAAa,QAAA,CAAS,kBAAkB,CAAA,IAAK,QAAQ,IAAA,EAAM;AAC7D,UAAA,MAAM,OAAO,OAAA,CAAQ,IAAA;AACrB,UAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,YAAA,kBAAA,GAAqB,IAAA,CAAK,cAAA;AAAA,UAC5B;AAAA,QACF;AAAA,MACF;AAGA,MAAA,IAAI,OAAA,CAAQ,WAAW,KAAA,EAAO;AAC5B,QAAA,IAAI;AACF,UAAA,MAAM,QAAQ,OAAA,CAAQ,KAAA;AACtB,UAAA,MAAM,wBAAwB,KAAA,CAAM,cAAA;AACpC,UAAA,IAAI,OAAO,0BAA0B,QAAA,EAAU;AAE7C,YAAA,IAAI;AACF,cAAA,oBAAA,GAAuB,IAAA,CAAK,MAAM,qBAAqB,CAAA;AAAA,YACzD,CAAA,CAAA,MAAQ;AAEN,cAAA,IAAI;AACF,gBAAA,MAAM,OAAO,MAAA,CAAO,IAAA,CAAK,uBAAuB,QAAQ,CAAA,CAAE,SAAS,OAAO,CAAA;AAC1E,gBAAA,oBAAA,GAAuB,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,cACxC,CAAA,CAAA,MAAQ;AAAA,cAER;AAAA,YACF;AAAA,UACF;AAAA,QACF,CAAA,CAAA,MAAQ;AAAA,QAER;AAAA,MACF;AAEA,MAAA,MAAM,iBAAiB,IAAA,CAAK,mBAAA,CAAoB,EAAE,oBAAA,EAAsB,oBAAoB,CAAA;AAC5F,MAAA,IAAA,CAAK,6BAAA,CAA8B;AAAA,QACjC,cAAA;AAAA,QACA,WAAW,CAAA,IAAA,KAAQ;AACjB,UAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,OAAA,CAAQ,IAAA,CAAK,aAAa,CAAA;AAChD,UAAA,OAAO,MAAM,OAAA,CAAQ,KAAK,CAAA,GAAI,KAAA,CAAM,CAAC,CAAA,GAAI,KAAA;AAAA,QAC3C;AAAA,OACD,CAAA;AAGD,MAAA,OAAA,CAAQ,cAAA,GAAiB,cAAA;AACzB,MAAA,OAAA,CAAQ,SAAS,IAAA,CAAK,MAAA;AACtB,MAAA,OAAA,CAAQ,eAAA,GAAkB,IAAA,CAAK,KAAA,IAAS,EAAC;AACzC,MAAA,IAAI,KAAK,SAAA,EAAW;AAClB,QAAA,OAAA,CAAQ,YAAY,IAAA,CAAK,SAAA;AAAA,MAC3B;AACA,MAAA,OAAA,CAAQ,wBAAwB,IAAA,CAAK,qBAAA;AAGrC,MAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,MAAA,OAAA,CAAQ,GAAA,CAAI,EAAA,CAAG,OAAA,EAAS,MAAM;AAC5B,QAAA,IAAI,gBAAA,CAAiB,OAAA,CAAQ,GAAG,CAAA,EAAG;AACjC,UAAA,UAAA,CAAW,KAAA,EAAM;AAAA,QACnB;AAAA,MACF,CAAC,CAAA;AACD,MAAA,KAAA,CAAM,GAAA,CAAI,EAAA,CAAG,OAAA,EAAS,MAAM;AAG1B,QAAA,IAAI,CAAC,KAAA,CAAM,GAAA,CAAI,aAAA,EAAe;AAC5B,UAAA,UAAA,CAAW,KAAA,EAAM;AAAA,QACnB;AAAA,MACF,CAAC,CAAA;AACD,MAAA,OAAA,CAAQ,cAAc,UAAA,CAAW,MAAA;AAAA,IACnC,CAAA;AAAA,EACF;AAAA,EAEA,MAAM,MAAA,CACJ,KAAA,EACA,KAAA,EACA,QACA,OAAA,EACe;AAIf,IAAA,MAAM,UAAA,GAAa,MAAM,UAAA,EAAW;AAGpC,IAAA,MAAM,kBAA8D,EAAC;AACrE,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA,EAAG;AACrD,MAAA,IAAI,UAAU,MAAA,EAAW;AACzB,MAAA,MAAM,QAAA,GAAW,IAAI,WAAA,EAAY;AACjC,MAAA,IAAI,QAAA,KAAa,gBAAA,IAAoB,QAAA,KAAa,mBAAA,EAAqB;AACvE,MAAA,eAAA,CAAgB,GAAG,CAAA,GAAI,KAAA;AAAA,IACzB;AAIA,IAAA,KAAA,CAAM,MAAA,EAAO;AAEb,IAAA,MAAM,YAAA,GAAe,MAAM,YAAA,IAAgB,QAAA;AAI3C,IAAA,MAAM,UAAA,GACJ,iBAAiB,KAAA,GACb;AAAA,MACE,cAAA,EAAgB,mBAAA;AAAA,MAChB,eAAA,EAAiB,UAAA;AAAA,MACjB,UAAA,EAAY,YAAA;AAAA,MACZ,mBAAA,EAAqB;AAAA,KACvB,GACA;AAAA,MACE,cAAA,EAAgB;AAAA,KAClB;AAEN,IAAA,KAAA,CAAM,GAAA,CAAI,UAAU,GAAA,EAAK;AAAA,MACvB,GAAG,eAAA;AAAA,MACH,GAAG,UAAA;AAAA,MACH,mBAAA,EAAqB;AAAA,KACtB,CAAA;AAED,IAAA,IAAI,YAAA,KAAiB,KAAA,IAAS,KAAA,CAAM,iBAAA,EAAmB;AACrD,MAAA,KAAA,CAAM,GAAA,CAAI,MAAM,iBAAiB,CAAA;AAAA,IACnC;AAEA,IAAA,MAAM,cAAA,GAAiB,MAAA,YAAkB,cAAA,GAAiB,MAAA,GAAS,MAAA,CAAO,UAAA;AAC1E,IAAA,MAAM,MAAA,GAAS,eAAe,SAAA,EAAU;AAExC,IAAA,IAAI,cAAA,GAAiB,KAAA;AACrB,IAAA,MAAM,YAAA,GAAe,CAAC,MAAA,KAAmB;AACvC,MAAA,IAAI,cAAA,EAAgB;AACpB,MAAA,cAAA,GAAiB,IAAA;AACjB,MAAA,KAAK,MAAA,CAAO,OAAO,MAAM,CAAA;AAAA,IAC3B,CAAA;AACA,IAAA,MAAM,2BAAA,GAA8B,MAAM,YAAA,CAAa,iBAAiB,CAAA;AACxE,IAAA,MAAM,6BAA6B,MAAM;AACvC,MAAA,IAAI,OAAA,IAAW,gBAAA,CAAiB,OAAA,CAAQ,GAAG,CAAA,EAAG;AAC5C,QAAA,YAAA,CAAa,iBAAiB,CAAA;AAAA,MAChC;AAAA,IACF,CAAA;AACA,IAAA,KAAA,CAAM,GAAA,CAAI,EAAA,CAAG,OAAA,EAAS,2BAA2B,CAAA;AACjD,IAAA,OAAA,EAAS,GAAA,CAAI,EAAA,CAAG,OAAA,EAAS,0BAA0B,CAAA;AAEnD,IAAA,IAAI;AACF,MAAA,OAAO,IAAA,EAAM;AACX,QAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAM,GAAI,MAAM,OAAO,IAAA,EAAK;AAC1C,QAAA,IAAI,IAAA,EAAM;AAEV,QAAA,IAAI,KAAA,EAAO;AACT,UAAA,IAAI,YAAA,KAAiB,SAAS,OAAO,KAAA,KAAU,YAAY,KAAA,CAAM,UAAA,CAAW,GAAG,CAAA,EAAG;AAChF,YAAA,KAAA,CAAM,GAAA,CAAI,MAAM,KAAK,CAAA;AACrB,YAAA;AAAA,UACF;AAGA,UAAA,MAAM,YAAA,GAAe,IAAA,CAAK,aAAA,EAAe,MAAA,IAAU,IAAA;AACnD,UAAA,MAAM,WAAA,GAAc,YAAA,GAAeC,+BAAA,CAAkB,KAAK,CAAA,GAAI,KAAA;AAC9D,UAAA,IAAI,iBAAiB,KAAA,EAAO;AAC1B,YAAA,KAAA,CAAM,IAAI,KAAA,CAAM,CAAA,MAAA,EAAS,IAAA,CAAK,SAAA,CAAU,WAAW,CAAC;;AAAA,CAAM,CAAA;AAAA,UAC5D,CAAA,MAAO;AACL,YAAA,KAAA,CAAM,IAAI,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU,WAAW,IAAI,GAAM,CAAA;AAAA,UACtD;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAA,CAAO,SAAA,EAAU,EAAG,KAAA,CAAM,4BAAA,EAA8B;AAAA,QAC3D,KAAA,EAAO,KAAA,YAAiB,KAAA,GAAQ,EAAE,OAAA,EAAS,MAAM,OAAA,EAAS,KAAA,EAAO,KAAA,CAAM,KAAA,EAAM,GAAI;AAAA,OAClF,CAAA;AAAA,IACH,CAAA,SAAE;AACA,MAAA,KAAA,CAAM,GAAA,CAAI,GAAA,CAAI,OAAA,EAAS,2BAA2B,CAAA;AAClD,MAAA,OAAA,EAAS,GAAA,CAAI,GAAA,CAAI,OAAA,EAAS,0BAA0B,CAAA;AACpD,MAAA,IAAI,CAAC,KAAA,CAAM,GAAA,CAAI,iBAAiB,CAAC,KAAA,CAAM,IAAI,SAAA,EAAW;AACpD,QAAA,KAAA,CAAM,IAAI,GAAA,EAAI;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,SAAA,CAAU,KAAA,EAAoB,OAAA,EAAuD;AACzF,IAAA,MAAM,SAAA,GAAa,OAAA,CAAQ,MAAA,IAAU,EAAC;AAEtC,IAAA,MAAM,WAAA,GAAcC,kCAAA,CAAsB,OAAA,CAAQ,KAAA,IAAS,EAA8B,CAAA;AACzF,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI,cAAA;AAEJ,IAAA,IAAI,KAAA,CAAM,MAAA,KAAW,MAAA,IAAU,KAAA,CAAM,MAAA,KAAW,KAAA,IAAS,KAAA,CAAM,MAAA,KAAW,OAAA,IAAW,KAAA,CAAM,MAAA,KAAW,QAAA,EAAU;AAC9G,MAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,OAAA,CAAQ,cAAc,CAAA,IAAK,EAAA;AAEvD,MAAA,IAAI,WAAA,CAAY,QAAA,CAAS,qBAAqB,CAAA,EAAG;AAC/C,QAAA,IAAI;AACF,UAAA,MAAM,WAAA,GAAc,KAAA,CAAM,WAAA,IAAe,IAAA,CAAK,gBAAA,EAAkB,OAAA;AAChE,UAAA,IAAA,GAAO,MAAM,IAAA,CAAK,sBAAA,CAAuB,OAAA,EAAS,WAAW,CAAA;AAAA,QAC/D,SAAS,KAAA,EAAO;AACd,UAAA,IAAA,CAAK,MAAA,CAAO,SAAA,EAAU,EAAG,KAAA,CAAM,qCAAA,EAAuC;AAAA,YACpE,KAAA,EAAO,KAAA,YAAiB,KAAA,GAAQ,EAAE,OAAA,EAAS,MAAM,OAAA,EAAS,KAAA,EAAO,KAAA,CAAM,KAAA,EAAM,GAAI;AAAA,WAClF,CAAA;AAED,UAAA,IAAI,KAAA,YAAiB,SAAS,KAAA,CAAM,OAAA,CAAQ,aAAY,CAAE,QAAA,CAAS,MAAM,CAAA,EAAG;AAC1E,YAAA,MAAM,KAAA;AAAA,UACR;AACA,UAAA,cAAA,GAAiB;AAAA,YACf,OAAA,EAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU;AAAA,WACpD;AAAA,QACF;AAAA,MACF,CAAA,MAAO;AACL,QAAA,IAAA,GAAO,OAAA,CAAQ,IAAA;AAAA,MACjB;AAAA,IACF;AAEA,IAAA,OAAO,EAAE,SAAA,EAAW,WAAA,EAAa,IAAA,EAAM,cAAA,EAAe;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,sBAAA,CAAuB,SAAyB,WAAA,EAAwD;AAC9G,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,MAAM,SAAkC,EAAC;AAEzC,MAAA,MAAMC,QAAA,GAAS,IAAIC,aAAA,CAAO;AAAA,QACxB,OAAA,EAAS;AAAA,UACP,cAAA,EAAgB,OAAA,CAAQ,OAAA,CAAQ,cAAc;AAAA,SAChD;AAAA,QACA,MAAA,EAAQ,WAAA,GAAc,EAAE,QAAA,EAAU,aAAY,GAAI;AAAA,OACnD,CAAA;AAED,MAAAD,QAAA,CAAO,EAAA;AAAA,QACL,MAAA;AAAA,QACA,CAAC,SAAA,EAAmB,IAAA,EAA6B,SAAA,EAAmB,WAAmB,SAAA,KAAsB;AAC3G,UAAA,MAAM,SAAmB,EAAC;AAC1B,UAAA,IAAI,aAAA,GAAgB,KAAA;AAEpB,UAAA,IAAA,CAAK,EAAA,CAAG,MAAA,EAAQ,CAAC,KAAA,KAAkB;AACjC,YAAA,MAAA,CAAO,KAAK,KAAK,CAAA;AAAA,UACnB,CAAC,CAAA;AAED,UAAA,IAAA,CAAK,EAAA,CAAG,SAAS,MAAM;AACrB,YAAA,aAAA,GAAgB,IAAA;AAChB,YAAA,IAAA,CAAK,MAAA,EAAO;AACZ,YAAA,MAAA,CAAO,IAAI,MAAM,CAAA,wBAAA,EAA2B,WAAA,GAAc,UAAU,WAAW,CAAA,OAAA,CAAA,GAAY,EAAE,CAAA,CAAE,CAAC,CAAA;AAAA,UAClG,CAAC,CAAA;AAED,UAAA,IAAA,CAAK,EAAA,CAAG,OAAO,MAAM;AACnB,YAAA,IAAI,CAAC,aAAA,EAAe;AAClB,cAAA,MAAA,CAAO,SAAS,CAAA,GAAI,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA;AAAA,YAC1C;AAAA,UACF,CAAC,CAAA;AAAA,QACH;AAAA,OACF;AAEA,MAAAA,QAAA,CAAO,EAAA,CAAG,OAAA,EAAS,CAAC,SAAA,EAAmB,KAAA,KAAkB;AAEvD,QAAA,IAAI;AACF,UAAA,MAAA,CAAO,SAAS,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AAAA,QACtC,CAAA,CAAA,MAAQ;AACN,UAAA,MAAA,CAAO,SAAS,CAAA,GAAI,KAAA;AAAA,QACtB;AAAA,MACF,CAAC,CAAA;AAED,MAAAA,QAAA,CAAO,EAAA,CAAG,UAAU,MAAM;AACxB,QAAA,OAAA,CAAQ,MAAM,CAAA;AAAA,MAChB,CAAC,CAAA;AAED,MAAAA,QAAA,CAAO,EAAA,CAAG,OAAA,EAAS,CAAC,KAAA,KAAiB;AACnC,QAAA,MAAA,CAAO,KAAK,CAAA;AAAA,MACd,CAAC,CAAA;AAGD,MAAA,OAAA,CAAQ,GAAA,CAAI,KAAKA,QAAM,CAAA;AAAA,IACzB,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,YAAA,CACJ,KAAA,EACA,KAAA,EACA,MAAA,EACA,SACA,MAAA,EACe;AACf,IAAA,MAAM,cAAA,GAAiB,MAAA,IAAU,IAAA,CAAK,MAAA,IAAU,EAAA;AAGhD,IAAA,IAAI,MAAA,IAAU,OAAO,MAAA,KAAW,QAAA,IAAY,sBAAsB,MAAA,EAAQ;AACxE,MAAA,MAAM,iBAAkB,MAAA,CAAe,gBAAA;AACvC,MAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,cAAc,CAAA,EAAG;AACzD,QAAA,KAAA,CAAM,MAAA,CAAO,KAAK,KAAK,CAAA;AAAA,MACzB;AACA,MAAA,OAAQ,MAAA,CAAe,gBAAA;AAAA,IACzB;AAEA,IAAA,IAAI,KAAA,CAAM,iBAAiB,MAAA,EAAQ;AACjC,MAAA,MAAM,KAAA,CAAM,KAAK,MAAM,CAAA;AAAA,IACzB,CAAA,MAAA,IAAW,KAAA,CAAM,YAAA,KAAiB,QAAA,EAAU;AAC1C,MAAA,MAAM,IAAA,CAAK,MAAA,CAAO,KAAA,EAAO,KAAA,EAAO,QAA0C,OAAO,CAAA;AAAA,IACnF,CAAA,MAAA,IAAW,KAAA,CAAM,YAAA,KAAiB,qBAAA,EAAuB;AAEvD,MAAA,MAAM,aAAA,GAAgB,MAAA;AACtB,MAAA,aAAA,CAAc,OAAA,CAAQ,QAAQ,CAAC,KAAA,EAAO,QAAQ,KAAA,CAAM,MAAA,CAAO,GAAA,EAAK,KAAK,CAAC,CAAA;AACtE,MAAA,KAAA,CAAM,MAAA,CAAO,cAAc,MAAM,CAAA;AACjC,MAAA,IAAI,cAAc,IAAA,EAAM;AACtB,QAAA,MAAM,MAAA,GAAS,aAAA,CAAc,IAAA,CAAK,SAAA,EAAU;AAC5C,QAAA,IAAI,cAAA,GAAiB,KAAA;AAErB,QAAA,MAAM,YAAA,GAAe,CAAC,MAAA,KAAmB;AACvC,UAAA,IAAI,cAAA,EAAgB;AACpB,UAAA,cAAA,GAAiB,IAAA;AACjB,UAAA,KAAK,MAAA,CAAO,OAAO,MAAM,CAAA;AAAA,QAC3B,CAAA;AAEA,QAAA,MAAM,2BAAA,GAA8B,MAAM,YAAA,CAAa,iBAAiB,CAAA;AACxE,QAAA,MAAM,6BAA6B,MAAM;AACvC,UAAA,IAAI,OAAA,IAAW,gBAAA,CAAiB,OAAA,CAAQ,GAAG,CAAA,EAAG;AAC5C,YAAA,YAAA,CAAa,iBAAiB,CAAA;AAAA,UAChC;AAAA,QACF,CAAA;AAEA,QAAA,MAAM,UAAA,GAAa,CAAC,GAAA,KAAiB;AACnC,UAAA,IAAA,CAAK,MAAA,CAAO,SAAA,EAAU,EAAG,KAAA,CAAM,mCAAA,EAAqC;AAAA,YAClE,KAAA,EAAO,GAAA,YAAe,KAAA,GAAQ,EAAE,OAAA,EAAS,IAAI,OAAA,EAAS,KAAA,EAAO,GAAA,CAAI,KAAA,EAAM,GAAI;AAAA,WAC5E,CAAA;AACD,UAAA,YAAA,CAAa,sBAAsB,CAAA;AAAA,QACrC,CAAA;AACA,QAAA,KAAA,CAAM,GAAA,CAAI,IAAA,CAAK,OAAA,EAAS,UAAU,CAAA;AAClC,QAAA,KAAA,CAAM,GAAA,CAAI,EAAA,CAAG,OAAA,EAAS,2BAA2B,CAAA;AACjD,QAAA,OAAA,EAAS,GAAA,CAAI,EAAA,CAAG,OAAA,EAAS,0BAA0B,CAAA;AAEnD,QAAA,IAAI;AACF,UAAA,OAAO,IAAA,EAAM;AACX,YAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAM,GAAI,MAAM,OAAO,IAAA,EAAK;AAC1C,YAAA,IAAI,IAAA,EAAM;AACV,YAAA,KAAA,CAAM,GAAA,CAAI,MAAM,KAAK,CAAA;AAAA,UACvB;AAAA,QACF,SAAS,KAAA,EAAO;AACd,UAAA,IAAA,CAAK,MAAA,CAAO,SAAA,EAAU,EAAG,KAAA,CAAM,gCAAA,EAAkC;AAAA,YAC/D,KAAA,EAAO,KAAA,YAAiB,KAAA,GAAQ,EAAE,OAAA,EAAS,MAAM,OAAA,EAAS,KAAA,EAAO,KAAA,CAAM,KAAA,EAAM,GAAI;AAAA,WAClF,CAAA;AAAA,QACH,CAAA,SAAE;AACA,UAAA,KAAA,CAAM,GAAA,CAAI,GAAA,CAAI,OAAA,EAAS,UAAU,CAAA;AACjC,UAAA,KAAA,CAAM,GAAA,CAAI,GAAA,CAAI,OAAA,EAAS,2BAA2B,CAAA;AAClD,UAAA,OAAA,EAAS,GAAA,CAAI,GAAA,CAAI,OAAA,EAAS,0BAA0B,CAAA;AACpD,UAAA,IAAI,CAAC,KAAA,CAAM,GAAA,CAAI,iBAAiB,CAAC,KAAA,CAAM,IAAI,SAAA,EAAW;AACpD,YAAA,KAAA,CAAM,IAAI,GAAA,EAAI;AAAA,UAChB;AAAA,QACF;AAAA,MACF,CAAA,MAAO;AACL,QAAA,KAAA,CAAM,IAAI,GAAA,EAAI;AAAA,MAChB;AAAA,IACF,CAAA,MAAA,IAAW,KAAA,CAAM,YAAA,KAAiB,UAAA,EAAY;AAE5C,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,MAAM,KAAA,CAAM,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,KAAA,EAAO,6CAA6C,CAAA;AACnF,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,EAAE,MAAA,EAAQ,QAAA,EAAU,UAAA,EAAY,iBAAgB,GAAI,MAAA;AAE1D,MAAA,IAAI;AAGF,QAAA,KAAA,CAAM,MAAA,EAAO;AAIb,QAAA,MAAM,SAAS,OAAA,CAAQ,GAAA;AACvB,QAAA,IAAI,OAAA,CAAQ,SAAS,MAAA,EAAW;AAC9B,UAAA,MAAA,CAAO,OAAO,OAAA,CAAQ,IAAA;AAAA,QACxB;AAGA,QAAA,MAAM,UAAU,EAAE,GAAG,IAAA,CAAK,UAAA,EAAY,GAAG,eAAA,EAAgB;AAEzD,QAAA,MAAM,OAAO,SAAA,CAAU;AAAA,UACrB,GAAA,EAAK,IAAI,GAAA,CAAI,OAAA,CAAQ,KAAK,CAAA,OAAA,EAAU,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA,CAAE,CAAA;AAAA,UAC1D,QAAA,EAAU,CAAA,EAAG,cAAc,CAAA,EAAG,QAAQ,CAAA,CAAA;AAAA,UACtC,GAAA,EAAK,MAAA;AAAA,UACL,KAAK,KAAA,CAAM,GAAA;AAAA,UACX,SAAS,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA,CAAE,MAAA,GAAS,IAAI,OAAA,GAAU;AAAA,SACtD,CAAA;AAAA,MAEH,CAAA,CAAA,MAAQ;AACN,QAAA,IAAI,CAAC,KAAA,CAAM,GAAA,CAAI,WAAA,EAAa;AAC1B,UAAA,KAAA,CAAM,IAAI,SAAA,CAAU,GAAA,EAAK,EAAE,cAAA,EAAgB,oBAAoB,CAAA;AAC/D,UAAA,KAAA,CAAM,GAAA,CAAI,GAAA;AAAA,YACR,KAAK,SAAA,CAAU;AAAA,cACb,OAAA,EAAS,KAAA;AAAA,cACT,KAAA,EAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAS,uBAAA,EAAwB;AAAA,cACxD,EAAA,EAAI;AAAA,aACL;AAAA,WACH;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAA,MAAA,IAAW,KAAA,CAAM,YAAA,KAAiB,SAAA,EAAW;AAE3C,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,MAAM,KAAA,CAAM,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,KAAA,EAAO,6CAA6C,CAAA;AACnF,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,EAAE,MAAA,EAAQ,OAAA,EAAS,WAAA,EAAY,GAAI,MAAA;AAEzC,MAAA,IAAI;AAGF,QAAA,KAAA,CAAM,MAAA,EAAO;AAIb,QAAA,MAAM,SAAS,OAAA,CAAQ,GAAA;AACvB,QAAA,IAAI,OAAA,CAAQ,SAAS,MAAA,EAAW;AAC9B,UAAA,MAAA,CAAO,OAAO,OAAA,CAAQ,IAAA;AAAA,QACxB;AAEA,QAAA,MAAM,OAAO,QAAA,CAAS;AAAA,UACpB,GAAA,EAAK,IAAI,GAAA,CAAI,OAAA,CAAQ,KAAK,CAAA,OAAA,EAAU,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA,CAAE,CAAA;AAAA,UAC1D,OAAA,EAAS,CAAA,EAAG,cAAc,CAAA,EAAG,OAAO,CAAA,CAAA;AAAA,UACpC,WAAA,EAAa,CAAA,EAAG,cAAc,CAAA,EAAG,WAAW,CAAA,CAAA;AAAA,UAC5C,GAAA,EAAK,MAAA;AAAA,UACL,KAAK,KAAA,CAAM;AAAA,SACZ,CAAA;AAAA,MAEH,CAAA,CAAA,MAAQ;AACN,QAAA,IAAI,CAAC,KAAA,CAAM,GAAA,CAAI,WAAA,EAAa;AAC1B,UAAA,KAAA,CAAM,IAAI,SAAA,CAAU,GAAA,EAAK,EAAE,cAAA,EAAgB,oBAAoB,CAAA;AAC/D,UAAA,KAAA,CAAM,GAAA,CAAI,IAAI,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,gCAAA,EAAkC,CAAC,CAAA;AAAA,QAC3E;AAAA,MACF;AAAA,IACF,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,OAAO,GAAG,CAAA;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,MAAM,cACJ,GAAA,EACA,KAAA,EACA,EAAE,MAAA,EAAQ,WAAA,EAAY,GAAyB,EAAC,EACjC;AAEf,IAAA,MAAM,MAAA,GAAS,WAAA,IAAe,IAAA,CAAK,MAAA,IAAU,EAAA;AAE7C,IAAA,MAAM,QAAA,GAAW,CAAA,EAAG,MAAM,CAAA,EAAG,MAAM,IAAI,CAAA,CAAA;AAGvC,IAAA,MAAM,WAAA,GAAc,QAAA;AAGpB,IAAA,MAAM,OAAA,GAA8B,OAAO,OAAA,EAAyB,KAAA,KAAwB;AAE1F,MAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,cAAA,CAAe,KAAA,EAAO;AAAA,QACjD,IAAA,EAAM,OAAO,OAAA,CAAQ,GAAA,CAAI,MAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,GAAG,CAAA;AAAA,QAC7C,MAAA,EAAQ,MAAA,CAAO,OAAA,CAAQ,MAAA,IAAU,KAAK,CAAA;AAAA,QACtC,WAAW,CAAA,IAAA,KAAQ,OAAA,CAAQ,OAAA,CAAQ,IAAA,CAAK,aAAa,CAAA;AAAA,QACrD,QAAA,EAAU,CAAA,IAAA,KAAS,OAAA,CAAQ,KAAA,CAAiC,IAAI,CAAA;AAAA,QAChE,gBAAgB,OAAA,CAAQ,cAAA;AAAA,QACxB,OAAA,EAASJ,cAAa,OAAO,CAAA;AAAA,QAC7B,qBAAA,EAAuB,MAAMA,aAAAA,CAAa,OAAO;AAAA,OAClD,CAAA;AAED,MAAA,IAAI,SAAA,EAAW;AAEb,QAAA,IAAI,UAAU,OAAA,EAAS;AACrB,UAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,SAAA,CAAU,OAAO,CAAA,EAAG;AAC5D,YAAA,KAAK,KAAA,CAAM,MAAA,CAAO,GAAA,EAAK,KAAK,CAAA;AAAA,UAC9B;AAAA,QACF;AAGA,QAAA,IAAI,UAAU,KAAA,EAAO;AACnB,UAAA,OAAO,KAAA,CAAM,MAAA,CAAO,SAAA,CAAU,MAAM,CAAA,CAAE,KAAK,EAAE,KAAA,EAAO,SAAA,CAAU,KAAA,EAAO,CAAA;AAAA,QACvE;AAAA,MACF;AAEA,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,SAAA,CAAU,OAAO,OAAO,CAAA;AAGlD,MAAA,IAAI,OAAO,cAAA,EAAgB;AACzB,QAAA,OAAO,KAAA,CAAM,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,UAC5B,KAAA,EAAO,sBAAA;AAAA,UACP,MAAA,EAAQ,CAAC,EAAE,KAAA,EAAO,QAAQ,OAAA,EAAS,MAAA,CAAO,cAAA,CAAe,OAAA,EAAS;AAAA,SACnE,CAAA;AAAA,MACH;AAEA,MAAA,IAAI,OAAO,WAAA,EAAa;AACtB,QAAA,IAAI;AACF,UAAA,MAAA,CAAO,cAAc,MAAM,IAAA,CAAK,gBAAA,CAAiB,KAAA,EAAO,OAAO,WAAW,CAAA;AAAA,QAC5E,SAAS,KAAA,EAAO;AACd,UAAA,IAAA,CAAK,MAAA,CAAO,SAAA,EAAU,EAAG,KAAA,CAAM,4BAAA,EAA8B;AAAA,YAC3D,KAAA,EAAO,KAAA,YAAiB,KAAA,GAAQ,EAAE,OAAA,EAAS,MAAM,OAAA,EAAS,KAAA,EAAO,KAAA,CAAM,KAAA,EAAM,GAAI;AAAA,WAClF,CAAA;AACD,UAAA,IAAIM,wBAAA,CAAW,KAAK,CAAA,EAAG;AACrB,YAAA,MAAM,EAAE,QAAQ,IAAA,EAAK,GAAI,KAAK,sBAAA,CAAuB,KAAA,EAAO,OAAO,OAAO,CAAA;AAC1E,YAAA,OAAO,KAAA,CAAM,MAAA,CAAO,MAAM,CAAA,CAAE,KAAK,IAAI,CAAA;AAAA,UACvC;AACA,UAAA,OAAO,KAAA,CAAM,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,YAC5B,KAAA,EAAO,0BAAA;AAAA,YACP,MAAA,EAAQ,CAAC,EAAE,KAAA,EAAO,SAAA,EAAW,OAAA,EAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA,EAAiB;AAAA,WACjG,CAAA;AAAA,QACH;AAAA,MACF;AAEA,MAAA,IAAI,OAAO,IAAA,EAAM;AACf,QAAA,IAAI;AACF,UAAA,MAAA,CAAO,OAAO,MAAM,IAAA,CAAK,SAAA,CAAU,KAAA,EAAO,OAAO,IAAI,CAAA;AAAA,QACvD,SAAS,KAAA,EAAO;AACd,UAAA,IAAA,CAAK,MAAA,CAAO,SAAA,EAAU,EAAG,KAAA,CAAM,oBAAA,EAAsB;AAAA,YACnD,KAAA,EAAO,KAAA,YAAiB,KAAA,GAAQ,EAAE,OAAA,EAAS,MAAM,OAAA,EAAS,KAAA,EAAO,KAAA,CAAM,KAAA,EAAM,GAAI;AAAA,WAClF,CAAA;AACD,UAAA,IAAIA,wBAAA,CAAW,KAAK,CAAA,EAAG;AACrB,YAAA,MAAM,EAAE,QAAQ,IAAA,EAAK,GAAI,KAAK,sBAAA,CAAuB,KAAA,EAAO,OAAO,MAAM,CAAA;AACzE,YAAA,OAAO,KAAA,CAAM,MAAA,CAAO,MAAM,CAAA,CAAE,KAAK,IAAI,CAAA;AAAA,UACvC;AACA,UAAA,OAAO,KAAA,CAAM,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,YAC5B,KAAA,EAAO,sBAAA;AAAA,YACP,MAAA,EAAQ,CAAC,EAAE,KAAA,EAAO,SAAA,EAAW,OAAA,EAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA,EAAiB;AAAA,WACjG,CAAA;AAAA,QACH;AAAA,MACF;AAGA,MAAA,IAAI,OAAO,SAAA,EAAW;AACpB,QAAA,IAAI;AACF,UAAA,MAAA,CAAO,YAAY,MAAM,IAAA,CAAK,eAAA,CAAgB,KAAA,EAAO,OAAO,SAAS,CAAA;AAAA,QACvE,SAAS,KAAA,EAAO;AACd,UAAA,IAAA,CAAK,MAAA,CAAO,SAAA,EAAU,EAAG,KAAA,CAAM,2BAAA,EAA6B;AAAA,YAC1D,KAAA,EAAO,KAAA,YAAiB,KAAA,GAAQ,EAAE,OAAA,EAAS,MAAM,OAAA,EAAS,KAAA,EAAO,KAAA,CAAM,KAAA,EAAM,GAAI;AAAA,WAClF,CAAA;AACD,UAAA,IAAIA,wBAAA,CAAW,KAAK,CAAA,EAAG;AACrB,YAAA,MAAM,EAAE,QAAQ,IAAA,EAAK,GAAI,KAAK,sBAAA,CAAuB,KAAA,EAAO,OAAO,MAAM,CAAA;AACzE,YAAA,OAAO,KAAA,CAAM,MAAA,CAAO,MAAM,CAAA,CAAE,KAAK,IAAI,CAAA;AAAA,UACvC;AACA,UAAA,OAAO,KAAA,CAAM,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,YAC5B,KAAA,EAAO,yBAAA;AAAA,YACP,MAAA,EAAQ,CAAC,EAAE,KAAA,EAAO,SAAA,EAAW,OAAA,EAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA,EAAiB;AAAA,WACjG,CAAA;AAAA,QACH;AAAA,MACF;AAEA,MAAA,MAAM,aAAA,GAAgB;AAAA,QACpB,GAAG,MAAA,CAAO,SAAA;AAAA,QACV,GAAG,MAAA,CAAO,WAAA;AAAA,QACV,GAAI,OAAO,MAAA,CAAO,SAAS,QAAA,GAAW,MAAA,CAAO,OAAO,EAAC;AAAA,QACrD,gBAAgB,OAAA,CAAQ,cAAA;AAAA,QACxB,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,iBAAiB,OAAA,CAAQ,eAAA;AAAA,QACzB,WAAW,OAAA,CAAQ,SAAA;AAAA,QACnB,aAAa,OAAA,CAAQ,WAAA;AAAA,QACrB,WAAA,EAAa;AAAA,OACf;AAKA,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,MAAA,CAAO,SAAA,EAAU,EAAG,IAAA;AAC5C,MAAA,IAAI,UAAA,EAAY;AACd,QAAA,MAAM,aAAA,GAAgB,MAAM,iBAAA,EAAkB;AAC9C,QAAA,IAAI,aAAA,EAAe;AACjB,UAAA,MAAM,eAAA,GAAkB,OAAA,CAAQ,cAAA,CAAe,GAAA,CAAI,yBAAyB,CAAA;AAC5E,UAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,oBAAA,CAAqB,KAAA,EAAO,iBAAiB,aAAa,CAAA;AAEvF,UAAA,IAAI,eAAA,EAAiB;AACnB,YAAA,OAAO,KAAA,CAAM,MAAA,CAAO,eAAA,CAAgB,MAAM,EAAE,IAAA,CAAK;AAAA,cAC/C,OAAO,eAAA,CAAgB,KAAA;AAAA,cACvB,SAAS,eAAA,CAAgB;AAAA,aAC1B,CAAA;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAGA,MAAA,MAAM,WAAW,MAAMC,2BAAA,CAAc,KAAK,MAAA,EAAQ,KAAA,EAAO,QAAQ,cAAA,EAAgB;AAAA,QAC/E,GAAG,MAAA,CAAO,SAAA;AAAA,QACV,GAAG,MAAA,CAAO,WAAA;AAAA,QACV,GAAI,OAAO,MAAA,CAAO,SAAS,QAAA,GAAW,MAAA,CAAO,OAAO;AAAC,OACtD,CAAA;AACD,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,OAAO,KAAA,CAAM,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,CAAE,IAAA,CAAK,EAAE,KAAA,EAAO,QAAA,CAAS,KAAA,EAAO,OAAA,EAAS,QAAA,CAAS,SAAS,CAAA;AAAA,MAChG;AAEA,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,GAAS,MAAM,KAAA,CAAM,OAAA,CAAQ,aAAa,CAAA;AAChD,QAAA,MAAM,KAAK,YAAA,CAAa,KAAA,EAAO,KAAA,EAAO,MAAA,EAAQ,SAAS,MAAM,CAAA;AAAA,MAC/D,SAAS,KAAA,EAAO;AACd,QAAA,IAAA,CAAK,MAAA,CAAO,SAAA,EAAU,EAAG,KAAA,CAAM,uBAAA,EAAyB;AAAA,UACtD,KAAA,EAAO,KAAA,YAAiB,KAAA,GAAQ,EAAE,OAAA,EAAS,MAAM,OAAA,EAAS,KAAA,EAAO,KAAA,CAAM,KAAA,EAAM,GAAI,KAAA;AAAA,UACjF,MAAM,KAAA,CAAM,IAAA;AAAA,UACZ,QAAQ,KAAA,CAAM;AAAA,SACf,CAAA;AAED,QAAA,IAAI,MAAA,GAAS,GAAA;AACb,QAAA,IAAI,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,EAAU;AAEtC,UAAA,IAAI,YAAY,KAAA,EAAO;AACrB,YAAA,MAAA,GAAU,KAAA,CAAc,MAAA;AAAA,UAC1B,CAAA,MAAA,IAGE,SAAA,IAAa,KAAA,IACb,KAAA,CAAM,OAAA,IACN,OAAO,KAAA,CAAM,OAAA,KAAY,QAAA,IACzB,QAAA,IAAY,KAAA,CAAM,OAAA,EAClB;AACA,YAAA,MAAA,GAAU,MAAM,OAAA,CAAgB,MAAA;AAAA,UAClC;AAAA,QACF;AACA,QAAA,MAAM,KAAA,CAAM,MAAA,CAAO,MAAM,CAAA,CAAE,IAAA,CAAK,EAAE,KAAA,EAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA,EAAiB,CAAA;AAAA,MACrG;AAAA,IACF,CAAA;AAGA,IAAA,MAAM,oBAAA,GAAuB,IAAA,CAAK,gBAAA,IAAoB,CAAC,MAAA,EAAQ,KAAA,EAAO,OAAO,CAAA,CAAE,QAAA,CAAS,KAAA,CAAM,MAAA,CAAO,WAAA,EAAa,CAAA;AAClH,IAAA,MAAM,OAAA,GAAU,KAAA,CAAM,WAAA,IAAe,IAAA,CAAK,gBAAA,EAAkB,OAAA;AAE5D,IAAA,MAAM,SAAS,oBAAA,IAAwB,OAAA,GAAU,EAAE,SAAA,EAAW,SAAQ,GAAI,MAAA;AAI1E,IAAA,IAAI,KAAA,CAAM,MAAA,CAAO,WAAA,EAAY,KAAM,KAAA,EAAO;AAGxC,MAAA,MAAM,UAAU,CAAC,KAAA,EAAO,MAAA,EAAQ,KAAA,EAAO,UAAU,OAAO,CAAA;AACxD,MAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,QAAA,IAAI;AACF,UAAA,GAAA,CAAI,KAAA,CAAM;AAAA,YACR,MAAA;AAAA,YACA,GAAA,EAAK,WAAA;AAAA,YACL,OAAA;AAAA,YACA;AAAA,WACD,CAAA;AAAA,QACH,SAAS,GAAA,EAAK;AAEZ,UAAA,IAAI,eAAe,KAAA,IAAS,GAAA,CAAI,OAAA,CAAQ,QAAA,CAAS,kBAAkB,CAAA,EAAG;AACpE,YAAA;AAAA,UACF;AACA,UAAA,MAAM,GAAA;AAAA,QACR;AAAA,MACF;AAAA,IACF,CAAA,MAAO;AACL,MAAA,GAAA,CAAI,KAAA,CAAM;AAAA,QACR,QAAQ,KAAA,CAAM,MAAA;AAAA,QACd,GAAA,EAAK,WAAA;AAAA,QACL,OAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,uBAAA,GAAyC;AAC7C,IAAA,IAAI,CAAE,MAAM,IAAA,CAAK,uBAAA,EAAwB,EAAI;AAE7C,IAAA,MAAM,MAAA,GAAS,KAAK,eAAA,IAAmB,IAAA,CAAK,OAAO,SAAA,EAAU,EAAG,aAAa,EAAC;AAE9E,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAE1B,MAAA,MAAM,WAAA,GAA2B;AAAA,QAC/B,QAAQ,KAAA,CAAM,MAAA;AAAA,QACd,MAAM,KAAA,CAAM,IAAA;AAAA,QACZ,YAAA,EAAc,MAAA;AAAA,QACd,SAAS,YAAY;AAAA,QAAC,CAAA;AAAA,QACtB,cAAc,KAAA,CAAM,YAAA;AAAA,QACpB,oBAAoB,KAAA,CAAM,kBAAA;AAAA,QAC1B,KAAK,KAAA,CAAM;AAAA,OACb;AAEA,MAAA,MAAM,cAAA,GAAqC,OAAO,OAAA,EAAyB,KAAA,KAAwB;AAEjG,QAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,cAAA,CAAe,WAAA,EAAa;AAAA,UACvD,IAAA,EAAM,OAAO,OAAA,CAAQ,GAAA,CAAI,MAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,GAAG,CAAA;AAAA,UAC7C,MAAA,EAAQ,MAAA,CAAO,OAAA,CAAQ,MAAA,IAAU,KAAK,CAAA;AAAA,UACtC,WAAW,CAAA,IAAA,KAAQ,OAAA,CAAQ,OAAA,CAAQ,IAAA,CAAK,aAAa,CAAA;AAAA,UACrD,QAAA,EAAU,CAAA,IAAA,KAAS,OAAA,CAAQ,KAAA,CAAiC,IAAI,CAAA;AAAA,UAChE,gBAAgB,OAAA,CAAQ,cAAA;AAAA,UACxB,OAAA,EAASP,cAAa,OAAO,CAAA;AAAA,UAC7B,qBAAA,EAAuB,MAAMA,aAAAA,CAAa,OAAO;AAAA,SAClD,CAAA;AAED,QAAA,IAAI,SAAA,EAAW;AACb,UAAA,IAAI,UAAU,OAAA,EAAS;AACrB,YAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,SAAA,CAAU,OAAO,CAAA,EAAG;AAC5D,cAAA,KAAK,KAAA,CAAM,MAAA,CAAO,GAAA,EAAK,KAAK,CAAA;AAAA,YAC9B;AAAA,UACF;AACA,UAAA,IAAI,UAAU,KAAA,EAAO;AACnB,YAAA,OAAO,KAAA,CAAM,MAAA,CAAO,SAAA,CAAU,MAAM,CAAA,CAAE,KAAK,EAAE,KAAA,EAAO,SAAA,CAAU,KAAA,EAAO,CAAA;AAAA,UACvE;AAAA,QACF;AAEA,QAAA,MAAM,UAAA,GAAa,IAAA,CAAK,MAAA,CAAO,SAAA,EAAU,EAAG,IAAA;AAC5C,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,IAAI,aAAA;AACJ,UAAA,IAAI;AACF,YAAA,CAAC,EAAE,aAAA,EAAc,GAAI,MAAM,OAAO,sBAAsB,CAAA;AAAA,UAC1D,CAAA,CAAA,MAAQ;AACN,YAAA,OAAA,CAAQ,KAAA;AAAA,cACN;AAAA,aACF;AAAA,UACF;AAEA,UAAA,IAAI,aAAA,EAAe;AACjB,YAAA,MAAM,eAAA,GAAkB,OAAA,CAAQ,cAAA,CAAe,GAAA,CAAI,yBAAyB,CAAA;AAC5E,YAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,oBAAA,CAAqB,WAAA,EAAa,iBAAiB,aAAa,CAAA;AAC7F,YAAA,IAAI,eAAA,EAAiB;AACnB,cAAA,OAAO,KAAA,CAAM,MAAA,CAAO,eAAA,CAAgB,MAAM,EAAE,IAAA,CAAK;AAAA,gBAC/C,OAAO,eAAA,CAAgB,KAAA;AAAA,gBACvB,SAAS,eAAA,CAAgB;AAAA,eAC1B,CAAA;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAGA,QAAA,MAAM,WAAW,MAAMO,2BAAA,CAAc,KAAK,MAAA,EAAQ,WAAA,EAAa,QAAQ,cAAA,EAAgB;AAAA,UACrF,GAAI,OAAA,CAAQ,MAAA;AAAA,UACZ,GAAI,OAAA,CAAQ,KAAA;AAAA,UACZ,GAAI,OAAO,OAAA,CAAQ,IAAA,KAAS,QAAA,IAAY,QAAQ,IAAA,KAAS,IAAA,GACpD,OAAA,CAAQ,IAAA,GACT;AAAC,SACN,CAAA;AACD,QAAA,IAAI,QAAA,EAAU;AACZ,UAAA,OAAO,KAAA,CAAM,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,CAAE,IAAA,CAAK,EAAE,KAAA,EAAO,QAAA,CAAS,KAAA,EAAO,OAAA,EAAS,QAAA,CAAS,SAAS,CAAA;AAAA,QAChG;AAEA,QAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,wBAAA;AAAA,UAC1B,UAAU,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA,EAAG,QAAQ,GAAG,CAAA,CAAA;AAAA,UAC5C,OAAA,CAAQ,MAAA;AAAA,UACR,OAAA,CAAQ,OAAA;AAAA,UACR,OAAA,CAAQ,IAAA;AAAA,UACR,OAAA,CAAQ,cAAA;AAAA,UACR,OAAA,CAAQ;AAAA,SACV;AACA,QAAA,IAAI,CAAC,QAAA,EAAU;AACb,UAAA,KAAA,CAAM,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,KAAA,EAAO,aAAa,CAAA;AAC7C,UAAA;AAAA,QACF;AACA,QAAA,KAAA,CAAM,MAAA,EAAO;AACb,QAAA,MAAM,KAAK,wBAAA,CAAyB,QAAA,EAAU,KAAA,CAAM,GAAA,EAAK,QAAQ,WAAW,CAAA;AAAA,MAC9E,CAAA;AAEA,MAAA,IAAI,KAAA,CAAM,WAAW,KAAA,EAAO;AAC1B,QAAA,MAAM,UAAU,CAAC,KAAA,EAAO,MAAA,EAAQ,KAAA,EAAO,UAAU,OAAO,CAAA;AACxD,QAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,UAAA,IAAA,CAAK,GAAA,CAAI,MAAM,EAAE,MAAA,EAAQ,KAAK,KAAA,CAAM,IAAA,EAAM,OAAA,EAAS,cAAA,EAAgB,CAAA;AAAA,QACrE;AAAA,MACF,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,IAAI,KAAA,CAAM;AAAA,UACb,QAAQ,KAAA,CAAM,MAAA;AAAA,UACd,KAAK,KAAA,CAAM,IAAA;AAAA,UACX,OAAA,EAAS;AAAA,SACV,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEA,yBAAA,GAAkC;AAGhC,IAAA,IAAA,CAAK,GAAA,CAAI,wBAAwB,kBAAkB,CAAA;AACnD,IAAA,IAAA,CAAK,GAAA,CAAI,oBAAA,CAAqB,kBAAA,EAAoB,EAAE,OAAA,EAAS,UAAS,EAAG,CAAC,QAAA,EAAU,IAAA,EAAM,IAAA,KAAS;AACjG,MAAA,IAAI;AAEF,QAAA,IAAI,CAAC,QAAS,OAAO,IAAA,KAAS,YAAY,IAAA,CAAK,IAAA,OAAW,EAAA,EAAK;AAC7D,UAAA,IAAA,CAAK,MAAM,MAAS,CAAA;AACpB,UAAA;AAAA,QACF;AACA,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,IAAc,CAAA;AACxC,QAAA,IAAA,CAAK,MAAM,MAAM,CAAA;AAAA,MACnB,SAAS,GAAA,EAAK;AACZ,QAAA,IAAA,CAAK,KAAc,MAAS,CAAA;AAAA,MAC9B;AAAA,IACF,CAAC,CAAA;AAKD,IAAA,IAAA,CAAK,IAAI,oBAAA,CAAqB,qBAAA,EAAuB,CAAC,QAAA,EAAU,UAAU,IAAA,KAAS;AAEjF,MAAA,IAAA,CAAK,MAAM,MAAS,CAAA;AAAA,IACtB,CAAC,CAAA;AAED,IAAA,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,YAAA,EAAc,IAAA,CAAK,yBAAyB,CAAA;AAAA,EAC/D;AAAA,EAEA,sBAAA,GAA+B;AAAA,EAG/B;AAAA,EAEA,6BAAA,GAAsC;AACpC,IAAA,IAAI,CAAC,IAAA,CAAK,iBAAA,EAAmB,OAAA,EAAS;AACpC,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,WAAA,EAAa,OAAO,SAAyB,KAAA,KAAwB;AACpF,MAAA,MAAM,UAAU,OAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA;AACxC,MAAA,IAAI,CAAC,IAAA,CAAK,gBAAA,CAAiB,OAAO,CAAA,EAAG;AACnC,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,EAAI;AACvB,MAAA,MAAM,SAAS,OAAA,CAAQ,MAAA;AACvB,MAAA,MAAM,IAAA,GAAO,OAAA;AAEb,MAAA,KAAA,CAAM,GAAA,CAAI,IAAA,CAAK,QAAA,EAAU,MAAM;AAC7B,QAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,GAAI,KAAA;AAC9B,QAAA,MAAM,SAAS,KAAA,CAAM,UAAA;AACrB,QAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,iBAAA,EAAmB,KAAA,IAAS,MAAA;AAE/C,QAAA,MAAM,OAAA,GAA+B;AAAA,UACnC,MAAA;AAAA,UACA,IAAA;AAAA,UACA,MAAA;AAAA,UACA,QAAA,EAAU,GAAG,QAAQ,CAAA,EAAA;AAAA,SACvB;AAEA,QAAA,IAAI,IAAA,CAAK,mBAAmB,kBAAA,EAAoB;AAC9C,UAAA,OAAA,CAAQ,QAAQ,OAAA,CAAQ,KAAA;AAAA,QAC1B;AAEA,QAAA,IAAI,IAAA,CAAK,mBAAmB,cAAA,EAAgB;AAC1C,UAAA,MAAM,OAAA,GAAU,EAAE,GAAG,OAAA,CAAQ,OAAA,EAAQ;AACrC,UAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,iBAAA,CAAkB,aAAA,IAAiB,EAAC;AAC/D,UAAA,aAAA,CAAc,OAAA,CAAQ,CAAC,CAAA,KAAc;AACnC,YAAA,MAAM,GAAA,GAAM,EAAE,WAAA,EAAY;AAC1B,YAAA,IAAI,OAAA,CAAQ,GAAG,CAAA,KAAM,MAAA,EAAW;AAC9B,cAAA,OAAA,CAAQ,GAAG,CAAA,GAAI,YAAA;AAAA,YACjB;AAAA,UACF,CAAC,CAAA;AACD,UAAA,OAAA,CAAQ,OAAA,GAAU,OAAA;AAAA,QACpB;AAEA,QAAA,IAAA,CAAK,MAAA,CAAO,KAAK,CAAA,CAAE,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA,EAAI,QAAQ,CAAA,EAAA,CAAA,EAAM,OAAO,CAAA;AAAA,MACzE,CAAC,CAAA;AAAA,IACH,CAAC,CAAA;AAAA,EACH;AACF","file":"index.cjs","sourcesContent":["import type { Mastra } from '@mastra/core/mastra';\nimport { RequestContext } from '@mastra/core/request-context';\nimport { coreAuthMiddleware } from '@mastra/server/auth';\nimport type { FastifyReply, FastifyRequest, preHandlerHookHandler } from 'fastify';\n\nexport interface FastifyAuthMiddlewareOptions {\n mastra: Mastra;\n requiresAuth?: boolean;\n}\n\nfunction toWebRequest(request: FastifyRequest): globalThis.Request {\n const protocol = request.protocol || 'http';\n const host = request.headers.host || 'localhost';\n const url = `${protocol}://${host}${request.url}`;\n\n const headers = new Headers();\n for (const [key, value] of Object.entries(request.headers)) {\n if (!value) continue;\n if (Array.isArray(value)) {\n value.forEach(v => headers.append(key, v));\n } else {\n headers.set(key, value);\n }\n }\n\n return new globalThis.Request(url, {\n method: request.method,\n headers,\n });\n}\n\nexport function createAuthMiddleware({\n mastra,\n requiresAuth = true,\n}: FastifyAuthMiddlewareOptions): preHandlerHookHandler {\n return async (request: FastifyRequest, reply: FastifyReply) => {\n if (!requiresAuth) {\n return;\n }\n\n const authConfig = mastra.getServer()?.auth;\n if (!authConfig) {\n return;\n }\n\n request.requestContext ??= new RequestContext();\n request.mastra ??= mastra;\n\n const path = String(request.url.split('?')[0] || '/');\n const method = String(request.method || 'GET');\n const customRouteAuthConfig = new Map<string, boolean>(request.customRouteAuthConfig ?? []);\n customRouteAuthConfig.set(`${method}:${path}`, true);\n\n const authHeader = request.headers.authorization;\n let token: string | null = authHeader ? authHeader.replace('Bearer ', '') : null;\n const query = request.query as Record<string, string>;\n if (!token && query.apiKey) {\n token = query.apiKey || null;\n }\n\n const result = await coreAuthMiddleware({\n path,\n method,\n getHeader: name => request.headers[name.toLowerCase()] as string | undefined,\n mastra,\n authConfig,\n customRouteAuthConfig,\n requestContext: request.requestContext,\n rawRequest: toWebRequest(request),\n token,\n buildAuthorizeContext: () => toWebRequest(request),\n });\n\n if (result.action === 'error') {\n return reply.status(result.status).send(result.body);\n }\n };\n}\n","import { Busboy } from '@fastify/busboy';\nimport type { ToolsInput } from '@mastra/core/agent';\nimport type { Mastra } from '@mastra/core/mastra';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport type { InMemoryTaskStore } from '@mastra/server/a2a/store';\nimport type { MCPHttpTransportResult, MCPSseTransportResult } from '@mastra/server/handlers/mcp';\nimport type { ParsedRequestParams, ServerRoute } from '@mastra/server/server-adapter';\nimport {\n MastraServer as MastraServerBase,\n checkRouteFGA,\n isZodError,\n normalizeQueryParams,\n redactStreamChunk,\n} from '@mastra/server/server-adapter';\nimport type { FastifyInstance, FastifyReply, FastifyRequest, preHandlerHookHandler, RouteHandlerMethod } from 'fastify';\nexport { createAuthMiddleware } from './auth-middleware';\nexport type { FastifyAuthMiddlewareOptions } from './auth-middleware';\n\ntype HasPermissionFn = (userPerms: string[], required: string) => boolean;\nlet _hasPermissionPromise: Promise<HasPermissionFn | undefined> | undefined;\nfunction loadHasPermission(): Promise<HasPermissionFn | undefined> {\n if (!_hasPermissionPromise) {\n _hasPermissionPromise = import('@mastra/core/auth/ee')\n .then(m => m.hasPermission)\n .catch(() => {\n console.error(\n '[@mastra/fastify] Auth features require @mastra/core >= 1.6.0. Please upgrade: npm install @mastra/core@latest',\n );\n return undefined;\n });\n }\n return _hasPermissionPromise;\n}\n\n/**\n * Convert Fastify request to Web API Request for cookie-based auth providers.\n */\nfunction toWebRequest(request: FastifyRequest): globalThis.Request {\n const protocol = request.protocol || 'http';\n const host = request.headers.host || 'localhost';\n const url = `${protocol}://${host}${request.url}`;\n\n const headers = new Headers();\n for (const [key, value] of Object.entries(request.headers)) {\n if (value) {\n if (Array.isArray(value)) {\n value.forEach(v => headers.append(key, v));\n } else {\n headers.set(key, value);\n }\n }\n }\n\n return new globalThis.Request(url, {\n method: request.method,\n headers,\n });\n}\n\nfunction isRequestAborted(rawRequest: FastifyRequest['raw']): boolean {\n // Fastify can emit request close after a POST body is fully consumed while\n // the response stream is still active, so only treat it as disconnect when\n // the request itself reports an abort or never completed.\n return rawRequest.aborted || rawRequest.readableAborted || !rawRequest.complete;\n}\n\n// Extend Fastify types to include Mastra context\ndeclare module 'fastify' {\n interface FastifyRequest {\n mastra: Mastra;\n requestContext: RequestContext;\n registeredTools: ToolsInput;\n abortSignal: AbortSignal;\n taskStore: InMemoryTaskStore;\n customRouteAuthConfig?: Map<string, boolean>;\n }\n}\n\nexport class MastraServer extends MastraServerBase<FastifyInstance, FastifyRequest, FastifyReply> {\n createContextMiddleware(): preHandlerHookHandler {\n return async (request: FastifyRequest, reply: FastifyReply) => {\n // Parse request context from request body and add to context\n let bodyRequestContext: Record<string, any> | undefined;\n let paramsRequestContext: Record<string, any> | undefined;\n\n // Parse request context from request body (POST/PUT)\n if (request.method === 'POST' || request.method === 'PUT') {\n const contentType = request.headers['content-type'];\n if (contentType?.includes('application/json') && request.body) {\n const body = request.body as { requestContext?: Record<string, any> };\n if (body.requestContext) {\n bodyRequestContext = body.requestContext;\n }\n }\n }\n\n // Parse request context from query params (GET)\n if (request.method === 'GET') {\n try {\n const query = request.query as Record<string, string>;\n const encodedRequestContext = query.requestContext;\n if (typeof encodedRequestContext === 'string') {\n // Try JSON first\n try {\n paramsRequestContext = JSON.parse(encodedRequestContext);\n } catch {\n // Fallback to base64(JSON)\n try {\n const json = Buffer.from(encodedRequestContext, 'base64').toString('utf-8');\n paramsRequestContext = JSON.parse(json);\n } catch {\n // ignore if still invalid\n }\n }\n }\n } catch {\n // ignore query parsing errors\n }\n }\n\n const requestContext = this.mergeRequestContext({ paramsRequestContext, bodyRequestContext });\n this.applyRequestMetadataToContext({\n requestContext,\n getHeader: name => {\n const value = request.headers[name.toLowerCase()];\n return Array.isArray(value) ? value[0] : value;\n },\n });\n\n // Set context in request object\n request.requestContext = requestContext;\n request.mastra = this.mastra;\n request.registeredTools = this.tools || {};\n if (this.taskStore) {\n request.taskStore = this.taskStore;\n }\n request.customRouteAuthConfig = this.customRouteAuthConfig;\n\n // Create abort controller for request cancellation\n const controller = new AbortController();\n request.raw.on('close', () => {\n if (isRequestAborted(request.raw)) {\n controller.abort();\n }\n });\n reply.raw.on('close', () => {\n // Response close fires for normal completion too; only abort if the\n // response did not finish successfully.\n if (!reply.raw.writableEnded) {\n controller.abort();\n }\n });\n request.abortSignal = controller.signal;\n };\n }\n\n async stream(\n route: ServerRoute,\n reply: FastifyReply,\n result: { fullStream: ReadableStream },\n request?: FastifyRequest,\n ): Promise<void> {\n // Capture headers set by plugins (e.g., @fastify/cors) BEFORE hijacking\n // reply.hijack() bypasses Fastify's response handling, so we need to preserve\n // any headers that were set by hooks/plugins and manually include them\n const rawHeaders = reply.getHeaders();\n // Filter out undefined values and conflicting headers (content-length, transfer-encoding)\n // Having both Content-Length and Transfer-Encoding: chunked violates RFC 7230\n const existingHeaders: Record<string, string | number | string[]> = {};\n for (const [key, value] of Object.entries(rawHeaders)) {\n if (value === undefined) continue;\n const lowerKey = key.toLowerCase();\n if (lowerKey === 'content-length' || lowerKey === 'transfer-encoding') continue;\n existingHeaders[key] = value;\n }\n\n // Hijack the reply to take control of the response\n // This is required when writing directly to reply.raw\n reply.hijack();\n\n const streamFormat = route.streamFormat || 'stream';\n\n // Write headers directly to the raw response, merging existing headers (like CORS)\n // with our stream-specific headers\n const sseHeaders =\n streamFormat === 'sse'\n ? {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n 'X-Accel-Buffering': 'no',\n }\n : {\n 'Content-Type': 'text/plain',\n };\n\n reply.raw.writeHead(200, {\n ...existingHeaders,\n ...sseHeaders,\n 'Transfer-Encoding': 'chunked',\n });\n\n if (streamFormat === 'sse' && route.sseFlushOnConnect) {\n reply.raw.write(': connected\\n\\n');\n }\n\n const readableStream = result instanceof ReadableStream ? result : result.fullStream;\n const reader = readableStream.getReader();\n\n let readerCanceled = false;\n const cancelReader = (reason: string) => {\n if (readerCanceled) return;\n readerCanceled = true;\n void reader.cancel(reason);\n };\n const cancelReaderOnResponseClose = () => cancelReader('request aborted');\n const cancelReaderOnRequestClose = () => {\n if (request && isRequestAborted(request.raw)) {\n cancelReader('request aborted');\n }\n };\n reply.raw.on('close', cancelReaderOnResponseClose);\n request?.raw.on('close', cancelReaderOnRequestClose);\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n if (value) {\n if (streamFormat === 'sse' && typeof value === 'string' && value.startsWith(':')) {\n reply.raw.write(value);\n continue;\n }\n\n // Optionally redact sensitive data (system prompts, tool definitions, API keys) before sending to the client\n const shouldRedact = this.streamOptions?.redact ?? true;\n const outputValue = shouldRedact ? redactStreamChunk(value) : value;\n if (streamFormat === 'sse') {\n reply.raw.write(`data: ${JSON.stringify(outputValue)}\\n\\n`);\n } else {\n reply.raw.write(JSON.stringify(outputValue) + '\\x1E');\n }\n }\n }\n } catch (error) {\n this.mastra.getLogger()?.error('Error in stream processing', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n } finally {\n reply.raw.off('close', cancelReaderOnResponseClose);\n request?.raw.off('close', cancelReaderOnRequestClose);\n if (!reply.raw.writableEnded && !reply.raw.destroyed) {\n reply.raw.end();\n }\n }\n }\n\n async getParams(route: ServerRoute, request: FastifyRequest): Promise<ParsedRequestParams> {\n const urlParams = (request.params || {}) as Record<string, string>;\n // Fastify's request.query can contain string | string[] for repeated params\n const queryParams = normalizeQueryParams((request.query || {}) as Record<string, unknown>);\n let body: unknown;\n let bodyParseError: { message: string } | undefined;\n\n if (route.method === 'POST' || route.method === 'PUT' || route.method === 'PATCH' || route.method === 'DELETE') {\n const contentType = request.headers['content-type'] || '';\n\n if (contentType.includes('multipart/form-data')) {\n try {\n const maxFileSize = route.maxBodySize ?? this.bodyLimitOptions?.maxSize;\n body = await this.parseMultipartFormData(request, maxFileSize);\n } catch (error) {\n this.mastra.getLogger()?.error('Failed to parse multipart form data', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n // Re-throw size limit errors, let others fall through to validation\n if (error instanceof Error && error.message.toLowerCase().includes('size')) {\n throw error;\n }\n bodyParseError = {\n message: error instanceof Error ? error.message : 'Failed to parse multipart form data',\n };\n }\n } else {\n body = request.body;\n }\n }\n\n return { urlParams, queryParams, body, bodyParseError };\n }\n\n /**\n * Parse multipart/form-data using @fastify/busboy.\n * Converts file uploads to Buffers and parses JSON field values.\n *\n * @param request - The Fastify request object\n * @param maxFileSize - Optional maximum file size in bytes\n */\n private parseMultipartFormData(request: FastifyRequest, maxFileSize?: number): Promise<Record<string, unknown>> {\n return new Promise((resolve, reject) => {\n const result: Record<string, unknown> = {};\n\n const busboy = new Busboy({\n headers: {\n 'content-type': request.headers['content-type'] as string,\n },\n limits: maxFileSize ? { fileSize: maxFileSize } : undefined,\n });\n\n busboy.on(\n 'file',\n (fieldname: string, file: NodeJS.ReadableStream, _filename: string, _encoding: string, _mimetype: string) => {\n const chunks: Buffer[] = [];\n let limitExceeded = false;\n\n file.on('data', (chunk: Buffer) => {\n chunks.push(chunk);\n });\n\n file.on('limit', () => {\n limitExceeded = true;\n file.resume();\n reject(new Error(`File size limit exceeded${maxFileSize ? ` (max: ${maxFileSize} bytes)` : ''}`));\n });\n\n file.on('end', () => {\n if (!limitExceeded) {\n result[fieldname] = Buffer.concat(chunks);\n }\n });\n },\n );\n\n busboy.on('field', (fieldname: string, value: string) => {\n // Try to parse JSON strings (like 'options')\n try {\n result[fieldname] = JSON.parse(value);\n } catch {\n result[fieldname] = value;\n }\n });\n\n busboy.on('finish', () => {\n resolve(result);\n });\n\n busboy.on('error', (error: Error) => {\n reject(error);\n });\n\n // Pipe the raw request to busboy\n request.raw.pipe(busboy);\n });\n }\n\n async sendResponse(\n route: ServerRoute,\n reply: FastifyReply,\n result: unknown,\n request?: FastifyRequest,\n prefix?: string,\n ): Promise<void> {\n const resolvedPrefix = prefix ?? this.prefix ?? '';\n\n // Apply refresh headers from transparent session refresh (e.g. Set-Cookie after token refresh)\n if (result && typeof result === 'object' && '__refreshHeaders' in result) {\n const refreshHeaders = (result as any).__refreshHeaders as Record<string, string>;\n for (const [key, value] of Object.entries(refreshHeaders)) {\n reply.header(key, value);\n }\n delete (result as any).__refreshHeaders;\n }\n\n if (route.responseType === 'json') {\n await reply.send(result);\n } else if (route.responseType === 'stream') {\n await this.stream(route, reply, result as { fullStream: ReadableStream }, request);\n } else if (route.responseType === 'datastream-response') {\n // Handle AI SDK Response objects - pipe Response.body to Fastify response\n const fetchResponse = result as globalThis.Response;\n fetchResponse.headers.forEach((value, key) => reply.header(key, value));\n reply.status(fetchResponse.status);\n if (fetchResponse.body) {\n const reader = fetchResponse.body.getReader();\n let readerCanceled = false;\n\n const cancelReader = (reason: string) => {\n if (readerCanceled) return;\n readerCanceled = true;\n void reader.cancel(reason);\n };\n\n const cancelReaderOnResponseClose = () => cancelReader('request aborted');\n const cancelReaderOnRequestClose = () => {\n if (request && isRequestAborted(request.raw)) {\n cancelReader('request aborted');\n }\n };\n\n const onResError = (err: unknown) => {\n this.mastra.getLogger()?.error('Error writing datastream response', {\n error: err instanceof Error ? { message: err.message, stack: err.stack } : err,\n });\n cancelReader('response write error');\n };\n reply.raw.once('error', onResError);\n reply.raw.on('close', cancelReaderOnResponseClose);\n request?.raw.on('close', cancelReaderOnRequestClose);\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n reply.raw.write(value);\n }\n } catch (error) {\n this.mastra.getLogger()?.error('Error in datastream processing', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n } finally {\n reply.raw.off('error', onResError);\n reply.raw.off('close', cancelReaderOnResponseClose);\n request?.raw.off('close', cancelReaderOnRequestClose);\n if (!reply.raw.writableEnded && !reply.raw.destroyed) {\n reply.raw.end();\n }\n }\n } else {\n reply.raw.end();\n }\n } else if (route.responseType === 'mcp-http') {\n // MCP Streamable HTTP transport - request is required\n if (!request) {\n await reply.status(500).send({ error: 'Request object required for MCP transport' });\n return;\n }\n\n const { server, httpPath, mcpOptions: routeMcpOptions } = result as MCPHttpTransportResult;\n\n try {\n // Hijack the response to bypass Fastify's response handling\n // This is required when we write directly to reply.raw\n reply.hijack();\n\n // Attach parsed body to raw request so MCP server's readJsonBody can use it\n // Fastify consumes the body stream, so we need to provide the pre-parsed body\n const rawReq = request.raw as typeof request.raw & { body?: unknown };\n if (request.body !== undefined) {\n rawReq.body = request.body;\n }\n\n // Merge class-level mcpOptions with route-specific options (route takes precedence)\n const options = { ...this.mcpOptions, ...routeMcpOptions };\n\n await server.startHTTP({\n url: new URL(request.url, `http://${request.headers.host}`),\n httpPath: `${resolvedPrefix}${httpPath}`,\n req: rawReq,\n res: reply.raw,\n options: Object.keys(options).length > 0 ? options : undefined,\n });\n // Response handled by startHTTP\n } catch {\n if (!reply.raw.headersSent) {\n reply.raw.writeHead(500, { 'Content-Type': 'application/json' });\n reply.raw.end(\n JSON.stringify({\n jsonrpc: '2.0',\n error: { code: -32603, message: 'Internal server error' },\n id: null,\n }),\n );\n }\n }\n } else if (route.responseType === 'mcp-sse') {\n // MCP SSE transport - request is required\n if (!request) {\n await reply.status(500).send({ error: 'Request object required for MCP transport' });\n return;\n }\n\n const { server, ssePath, messagePath } = result as MCPSseTransportResult;\n\n try {\n // Hijack the response to bypass Fastify's response handling\n // This is required when we write directly to reply.raw for SSE\n reply.hijack();\n\n // Attach parsed body to raw request so MCP server's readJsonBody can use it\n // Fastify consumes the body stream, so we need to provide the pre-parsed body\n const rawReq = request.raw as typeof request.raw & { body?: unknown };\n if (request.body !== undefined) {\n rawReq.body = request.body;\n }\n\n await server.startSSE({\n url: new URL(request.url, `http://${request.headers.host}`),\n ssePath: `${resolvedPrefix}${ssePath}`,\n messagePath: `${resolvedPrefix}${messagePath}`,\n req: rawReq,\n res: reply.raw,\n });\n // Response handled by startSSE\n } catch {\n if (!reply.raw.headersSent) {\n reply.raw.writeHead(500, { 'Content-Type': 'application/json' });\n reply.raw.end(JSON.stringify({ error: 'Error handling MCP SSE request' }));\n }\n }\n } else {\n reply.status(500);\n }\n }\n\n async registerRoute(\n app: FastifyInstance,\n route: ServerRoute,\n { prefix: prefixParam }: { prefix?: string } = {},\n ): Promise<void> {\n // Default prefix to this.prefix if not provided, or empty string\n const prefix = prefixParam ?? this.prefix ?? '';\n\n const fullPath = `${prefix}${route.path}`;\n\n // Convert Express-style :param to Fastify-style :param (they're the same, but ensure consistency)\n const fastifyPath = fullPath;\n\n // Define the route handler\n const handler: RouteHandlerMethod = async (request: FastifyRequest, reply: FastifyReply) => {\n // Check route-level authentication/authorization\n const authError = await this.checkRouteAuth(route, {\n path: String(request.url.split('?')[0] || '/'),\n method: String(request.method || 'GET'),\n getHeader: name => request.headers[name.toLowerCase()] as string | undefined,\n getQuery: name => (request.query as Record<string, string>)[name],\n requestContext: request.requestContext,\n request: toWebRequest(request),\n buildAuthorizeContext: () => toWebRequest(request),\n });\n\n if (authError) {\n // Apply any refresh headers (e.g. Set-Cookie from transparent session refresh)\n if (authError.headers) {\n for (const [key, value] of Object.entries(authError.headers)) {\n void reply.header(key, value);\n }\n }\n\n // If this is an auth error (not just a success-with-headers), return error response\n if (authError.error) {\n return reply.status(authError.status).send({ error: authError.error });\n }\n }\n\n const params = await this.getParams(route, request);\n\n // Return 400 Bad Request if body parsing failed (e.g., malformed multipart data)\n if (params.bodyParseError) {\n return reply.status(400).send({\n error: 'Invalid request body',\n issues: [{ field: 'body', message: params.bodyParseError.message }],\n });\n }\n\n if (params.queryParams) {\n try {\n params.queryParams = await this.parseQueryParams(route, params.queryParams);\n } catch (error) {\n this.mastra.getLogger()?.error('Error parsing query params', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n if (isZodError(error)) {\n const { status, body } = this.resolveValidationError(route, error, 'query');\n return reply.status(status).send(body);\n }\n return reply.status(400).send({\n error: 'Invalid query parameters',\n issues: [{ field: 'unknown', message: error instanceof Error ? error.message : 'Unknown error' }],\n });\n }\n }\n\n if (params.body) {\n try {\n params.body = await this.parseBody(route, params.body);\n } catch (error) {\n this.mastra.getLogger()?.error('Error parsing body', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n if (isZodError(error)) {\n const { status, body } = this.resolveValidationError(route, error, 'body');\n return reply.status(status).send(body);\n }\n return reply.status(400).send({\n error: 'Invalid request body',\n issues: [{ field: 'unknown', message: error instanceof Error ? error.message : 'Unknown error' }],\n });\n }\n }\n\n // Parse path params through pathParamSchema for type coercion (e.g., z.coerce.number())\n if (params.urlParams) {\n try {\n params.urlParams = await this.parsePathParams(route, params.urlParams);\n } catch (error) {\n this.mastra.getLogger()?.error('Error parsing path params', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n if (isZodError(error)) {\n const { status, body } = this.resolveValidationError(route, error, 'path');\n return reply.status(status).send(body);\n }\n return reply.status(400).send({\n error: 'Invalid path parameters',\n issues: [{ field: 'unknown', message: error instanceof Error ? error.message : 'Unknown error' }],\n });\n }\n }\n\n const handlerParams = {\n ...params.urlParams,\n ...params.queryParams,\n ...(typeof params.body === 'object' ? params.body : {}),\n requestContext: request.requestContext,\n mastra: this.mastra,\n registeredTools: request.registeredTools,\n taskStore: request.taskStore,\n abortSignal: request.abortSignal,\n routePrefix: prefix,\n };\n\n // Check route permission requirement (EE feature)\n // Uses convention-based permission derivation: permissions are auto-derived\n // from route path/method unless explicitly set or route is public\n const authConfig = this.mastra.getServer()?.auth;\n if (authConfig) {\n const hasPermission = await loadHasPermission();\n if (hasPermission) {\n const userPermissions = request.requestContext.get('mastra__userPermissions') as string[] | undefined;\n const permissionError = this.checkRoutePermission(route, userPermissions, hasPermission);\n\n if (permissionError) {\n return reply.status(permissionError.status).send({\n error: permissionError.error,\n message: permissionError.message,\n });\n }\n }\n }\n\n // Check FGA authorization (EE feature)\n const fgaError = await checkRouteFGA(this.mastra, route, request.requestContext, {\n ...params.urlParams,\n ...params.queryParams,\n ...(typeof params.body === 'object' ? params.body : {}),\n });\n if (fgaError) {\n return reply.status(fgaError.status).send({ error: fgaError.error, message: fgaError.message });\n }\n\n try {\n const result = await route.handler(handlerParams);\n await this.sendResponse(route, reply, result, request, prefix);\n } catch (error) {\n this.mastra.getLogger()?.error('Error calling handler', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n path: route.path,\n method: route.method,\n });\n // Check if it's an HTTPException or MastraError with a status code\n let status = 500;\n if (error && typeof error === 'object') {\n // Check for direct status property (HTTPException)\n if ('status' in error) {\n status = (error as any).status;\n }\n // Check for MastraError with status in details\n else if (\n 'details' in error &&\n error.details &&\n typeof error.details === 'object' &&\n 'status' in error.details\n ) {\n status = (error.details as any).status;\n }\n }\n await reply.status(status).send({ error: error instanceof Error ? error.message : 'Unknown error' });\n }\n };\n\n // Add body limit if configured\n const shouldApplyBodyLimit = this.bodyLimitOptions && ['POST', 'PUT', 'PATCH'].includes(route.method.toUpperCase());\n const maxSize = route.maxBodySize ?? this.bodyLimitOptions?.maxSize;\n\n const config = shouldApplyBodyLimit && maxSize ? { bodyLimit: maxSize } : undefined;\n\n // Handle ALL method by registering for each HTTP method\n // Fastify doesn't support 'ALL' method natively like Express\n if (route.method.toUpperCase() === 'ALL') {\n // Only register the main HTTP methods that MCP actually uses\n // Skip HEAD/OPTIONS to avoid potential conflicts with Fastify's auto-generated routes\n const methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'] as const;\n for (const method of methods) {\n try {\n app.route({\n method,\n url: fastifyPath,\n handler,\n config,\n });\n } catch (err) {\n // Skip duplicate route errors - can happen if route is registered multiple times\n if (err instanceof Error && err.message.includes('already declared')) {\n continue;\n }\n throw err;\n }\n }\n } else {\n app.route({\n method: route.method as 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',\n url: fastifyPath,\n handler,\n config,\n });\n }\n }\n\n async registerCustomApiRoutes(): Promise<void> {\n if (!(await this.buildCustomRouteHandler())) return;\n\n const routes = this.customApiRoutes ?? this.mastra.getServer()?.apiRoutes ?? [];\n\n for (const route of routes) {\n // Create pseudo ServerRoute for auth checking\n const serverRoute: ServerRoute = {\n method: route.method as any,\n path: route.path,\n responseType: 'json',\n handler: async () => {},\n requiresAuth: route.requiresAuth,\n requiresPermission: route.requiresPermission,\n fga: route.fga,\n };\n\n const fastifyHandler: RouteHandlerMethod = async (request: FastifyRequest, reply: FastifyReply) => {\n // Per-route auth check (same pattern as registerRoute)\n const authError = await this.checkRouteAuth(serverRoute, {\n path: String(request.url.split('?')[0] || '/'),\n method: String(request.method || 'GET'),\n getHeader: name => request.headers[name.toLowerCase()] as string | undefined,\n getQuery: name => (request.query as Record<string, string>)[name],\n requestContext: request.requestContext,\n request: toWebRequest(request),\n buildAuthorizeContext: () => toWebRequest(request),\n });\n\n if (authError) {\n if (authError.headers) {\n for (const [key, value] of Object.entries(authError.headers)) {\n void reply.header(key, value);\n }\n }\n if (authError.error) {\n return reply.status(authError.status).send({ error: authError.error });\n }\n }\n\n const authConfig = this.mastra.getServer()?.auth;\n if (authConfig) {\n let hasPermission: ((userPerms: string[], required: string) => boolean) | undefined;\n try {\n ({ hasPermission } = await import('@mastra/core/auth/ee'));\n } catch {\n console.error(\n '[@mastra/fastify] Auth features require @mastra/core >= 1.6.0. Please upgrade: npm install @mastra/core@latest',\n );\n }\n\n if (hasPermission) {\n const userPermissions = request.requestContext.get('mastra__userPermissions') as string[] | undefined;\n const permissionError = this.checkRoutePermission(serverRoute, userPermissions, hasPermission);\n if (permissionError) {\n return reply.status(permissionError.status).send({\n error: permissionError.error,\n message: permissionError.message,\n });\n }\n }\n }\n\n // Check FGA authorization (EE feature)\n const fgaError = await checkRouteFGA(this.mastra, serverRoute, request.requestContext, {\n ...(request.params as Record<string, string>),\n ...(request.query as Record<string, string>),\n ...(typeof request.body === 'object' && request.body !== null\n ? (request.body as Record<string, unknown>)\n : {}),\n });\n if (fgaError) {\n return reply.status(fgaError.status).send({ error: fgaError.error, message: fgaError.message });\n }\n\n const response = await this.handleCustomRouteRequest(\n `http://${request.headers.host}${request.url}`,\n request.method,\n request.headers as Record<string, string | string[] | undefined>,\n request.body,\n request.requestContext,\n request.abortSignal,\n );\n if (!response) {\n reply.status(404).send({ error: 'Not Found' });\n return;\n }\n reply.hijack();\n await this.writeCustomRouteResponse(response, reply.raw, request.abortSignal);\n };\n\n if (route.method === 'ALL') {\n const methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'] as const;\n for (const method of methods) {\n this.app.route({ method, url: route.path, handler: fastifyHandler });\n }\n } else {\n this.app.route({\n method: route.method as 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',\n url: route.path,\n handler: fastifyHandler,\n });\n }\n }\n }\n\n registerContextMiddleware(): void {\n // Override the default JSON parser to allow empty bodies\n // This matches Express behavior where empty POST requests with Content-Type: application/json are allowed\n this.app.removeContentTypeParser('application/json');\n this.app.addContentTypeParser('application/json', { parseAs: 'string' }, (_request, body, done) => {\n try {\n // Allow empty body\n if (!body || (typeof body === 'string' && body.trim() === '')) {\n done(null, undefined);\n return;\n }\n const parsed = JSON.parse(body as string);\n done(null, parsed);\n } catch (err) {\n done(err as Error, undefined);\n }\n });\n\n // Register content type parser for multipart/form-data\n // This allows Fastify to accept multipart requests without parsing them\n // We'll parse them manually in getParams using busboy\n this.app.addContentTypeParser('multipart/form-data', (_request, _payload, done) => {\n // Don't parse the body, we'll handle it manually with busboy\n done(null, undefined);\n });\n\n this.app.addHook('preHandler', this.createContextMiddleware());\n }\n\n registerAuthMiddleware(): void {\n // Auth is handled per-route in registerRoute() and registerCustomApiRoutes()\n // No global middleware needed\n }\n\n registerHttpLoggingMiddleware(): void {\n if (!this.httpLoggingConfig?.enabled) {\n return;\n }\n\n this.app.addHook('onRequest', async (request: FastifyRequest, reply: FastifyReply) => {\n const urlPath = request.url.split('?')[0]!;\n if (!this.shouldLogRequest(urlPath)) {\n return;\n }\n\n const start = Date.now();\n const method = request.method;\n const path = urlPath;\n\n reply.raw.once('finish', () => {\n const duration = Date.now() - start;\n const status = reply.statusCode;\n const level = this.httpLoggingConfig?.level || 'info';\n\n const logData: Record<string, any> = {\n method,\n path,\n status,\n duration: `${duration}ms`,\n };\n\n if (this.httpLoggingConfig?.includeQueryParams) {\n logData.query = request.query;\n }\n\n if (this.httpLoggingConfig?.includeHeaders) {\n const headers = { ...request.headers };\n const redactHeaders = this.httpLoggingConfig.redactHeaders || [];\n redactHeaders.forEach((h: string) => {\n const key = h.toLowerCase();\n if (headers[key] !== undefined) {\n headers[key] = '[REDACTED]';\n }\n });\n logData.headers = headers;\n }\n\n this.logger[level](`${method} ${path} ${status} ${duration}ms`, logData);\n });\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/auth-middleware.ts","../src/index.ts"],"names":["RequestContext","coreAuthMiddleware","toWebRequest","MastraServerBase","redactStreamChunk","normalizeQueryParams","busboy","Busboy","isZodError","checkRouteFGA"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Mastra } from '@mastra/core/mastra';\nimport { RequestContext } from '@mastra/core/request-context';\nimport { coreAuthMiddleware } from '@mastra/server/auth';\nimport type { FastifyReply, FastifyRequest, preHandlerHookHandler } from 'fastify';\n\nexport interface FastifyAuthMiddlewareOptions {\n mastra: Mastra;\n requiresAuth?: boolean;\n}\n\nfunction toWebRequest(request: FastifyRequest): globalThis.Request {\n const protocol = request.protocol || 'http';\n const host = request.headers.host || 'localhost';\n const url = `${protocol}://${host}${request.url}`;\n\n const headers = new Headers();\n for (const [key, value] of Object.entries(request.headers)) {\n if (!value) continue;\n if (Array.isArray(value)) {\n value.forEach(v => headers.append(key, v));\n } else {\n headers.set(key, value);\n }\n }\n\n return new globalThis.Request(url, {\n method: request.method,\n headers,\n });\n}\n\nexport function createAuthMiddleware({\n mastra,\n requiresAuth = true,\n}: FastifyAuthMiddlewareOptions): preHandlerHookHandler {\n return async (request: FastifyRequest, reply: FastifyReply) => {\n if (!requiresAuth) {\n return;\n }\n\n const authConfig = mastra.getServer()?.auth;\n if (!authConfig) {\n return;\n }\n\n request.requestContext ??= new RequestContext();\n request.mastra ??= mastra;\n\n const path = String(request.url.split('?')[0] || '/');\n const method = String(request.method || 'GET');\n const customRouteAuthConfig = new Map<string, boolean>(request.customRouteAuthConfig ?? []);\n customRouteAuthConfig.set(`${method}:${path}`, true);\n\n const authHeader = request.headers.authorization;\n let token: string | null = authHeader ? authHeader.replace('Bearer ', '') : null;\n const query = request.query as Record<string, string>;\n if (!token && query.apiKey) {\n token = query.apiKey || null;\n }\n\n const result = await coreAuthMiddleware({\n path,\n method,\n getHeader: name => request.headers[name.toLowerCase()] as string | undefined,\n mastra,\n authConfig,\n customRouteAuthConfig,\n requestContext: request.requestContext,\n rawRequest: toWebRequest(request),\n token,\n buildAuthorizeContext: () => toWebRequest(request),\n });\n\n if (result.action === 'error') {\n return reply.status(result.status).send(result.body);\n }\n };\n}\n","import { Busboy } from '@fastify/busboy';\nimport type { ToolsInput } from '@mastra/core/agent';\nimport type { Mastra } from '@mastra/core/mastra';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport type { InMemoryTaskStore } from '@mastra/server/a2a/store';\nimport type { MCPHttpTransportResult, MCPSseTransportResult } from '@mastra/server/handlers/mcp';\nimport type { ParsedRequestParams, ServerRoute } from '@mastra/server/server-adapter';\nimport {\n MastraServer as MastraServerBase,\n checkRouteFGA,\n isZodError,\n normalizeQueryParams,\n redactStreamChunk,\n} from '@mastra/server/server-adapter';\nimport type { FastifyInstance, FastifyReply, FastifyRequest, preHandlerHookHandler, RouteHandlerMethod } from 'fastify';\nexport { createAuthMiddleware } from './auth-middleware';\nexport type { FastifyAuthMiddlewareOptions } from './auth-middleware';\n\ntype HasPermissionFn = (userPerms: string[], required: string) => boolean;\nlet _hasPermissionPromise: Promise<HasPermissionFn | undefined> | undefined;\nfunction loadHasPermission(): Promise<HasPermissionFn | undefined> {\n if (!_hasPermissionPromise) {\n _hasPermissionPromise = import('@mastra/core/auth/ee')\n .then(m => m.hasPermission)\n .catch(() => {\n console.error(\n '[@mastra/fastify] Auth features require @mastra/core >= 1.6.0. Please upgrade: npm install @mastra/core@latest',\n );\n return undefined;\n });\n }\n return _hasPermissionPromise;\n}\n\n/**\n * Convert Fastify request to Web API Request for cookie-based auth providers.\n */\nfunction toWebRequest(request: FastifyRequest): globalThis.Request {\n const protocol = request.protocol || 'http';\n const host = request.headers.host || 'localhost';\n const url = `${protocol}://${host}${request.url}`;\n\n const headers = new Headers();\n for (const [key, value] of Object.entries(request.headers)) {\n if (value) {\n if (Array.isArray(value)) {\n value.forEach(v => headers.append(key, v));\n } else {\n headers.set(key, value);\n }\n }\n }\n\n return new globalThis.Request(url, {\n method: request.method,\n headers,\n });\n}\n\nfunction isRequestAborted(rawRequest: FastifyRequest['raw']): boolean {\n // Fastify can emit request close after a POST body is fully consumed while\n // the response stream is still active, so only treat it as disconnect when\n // the request itself reports an abort or never completed.\n return rawRequest.aborted || rawRequest.readableAborted || !rawRequest.complete;\n}\n\n// Extend Fastify types to include Mastra context\ndeclare module 'fastify' {\n interface FastifyRequest {\n mastra: Mastra;\n requestContext: RequestContext;\n registeredTools: ToolsInput;\n abortSignal: AbortSignal;\n taskStore: InMemoryTaskStore;\n customRouteAuthConfig?: Map<string, boolean>;\n }\n}\n\nexport class MastraServer extends MastraServerBase<FastifyInstance, FastifyRequest, FastifyReply> {\n createContextMiddleware(): preHandlerHookHandler {\n return async (request: FastifyRequest, reply: FastifyReply) => {\n // Parse request context from request body and add to context\n let bodyRequestContext: Record<string, any> | undefined;\n let paramsRequestContext: Record<string, any> | undefined;\n\n // Parse request context from request body (POST/PUT)\n if (request.method === 'POST' || request.method === 'PUT') {\n const contentType = request.headers['content-type'];\n if (contentType?.includes('application/json') && request.body) {\n const body = request.body as { requestContext?: Record<string, any> };\n if (body.requestContext) {\n bodyRequestContext = body.requestContext;\n }\n }\n }\n\n // Parse request context from query params (GET)\n if (request.method === 'GET') {\n try {\n const query = request.query as Record<string, string>;\n const encodedRequestContext = query.requestContext;\n if (typeof encodedRequestContext === 'string') {\n // Try JSON first\n try {\n paramsRequestContext = JSON.parse(encodedRequestContext);\n } catch {\n // Fallback to base64(JSON)\n try {\n const json = Buffer.from(encodedRequestContext, 'base64').toString('utf-8');\n paramsRequestContext = JSON.parse(json);\n } catch {\n // ignore if still invalid\n }\n }\n }\n } catch {\n // ignore query parsing errors\n }\n }\n\n const requestContext = this.mergeRequestContext({ paramsRequestContext, bodyRequestContext });\n this.applyRequestMetadataToContext({\n requestContext,\n getHeader: name => {\n const value = request.headers[name.toLowerCase()];\n return Array.isArray(value) ? value[0] : value;\n },\n });\n\n // Set context in request object\n request.requestContext = requestContext;\n request.mastra = this.mastra;\n request.registeredTools = this.tools || {};\n if (this.taskStore) {\n request.taskStore = this.taskStore;\n }\n request.customRouteAuthConfig = this.customRouteAuthConfig;\n\n // Create abort controller for request cancellation\n const controller = new AbortController();\n request.raw.on('close', () => {\n if (isRequestAborted(request.raw)) {\n controller.abort();\n }\n });\n reply.raw.on('close', () => {\n // Response close fires for normal completion too; only abort if the\n // response did not finish successfully.\n if (!reply.raw.writableEnded) {\n controller.abort();\n }\n });\n request.abortSignal = controller.signal;\n };\n }\n\n async stream(\n route: ServerRoute,\n reply: FastifyReply,\n result: { fullStream: ReadableStream },\n request?: FastifyRequest,\n ): Promise<void> {\n // Capture headers set by plugins (e.g., @fastify/cors) BEFORE hijacking\n // reply.hijack() bypasses Fastify's response handling, so we need to preserve\n // any headers that were set by hooks/plugins and manually include them\n const rawHeaders = reply.getHeaders();\n // Filter out undefined values and conflicting headers (content-length, transfer-encoding)\n // Having both Content-Length and Transfer-Encoding: chunked violates RFC 7230\n const existingHeaders: Record<string, string | number | string[]> = {};\n for (const [key, value] of Object.entries(rawHeaders)) {\n if (value === undefined) continue;\n const lowerKey = key.toLowerCase();\n if (lowerKey === 'content-length' || lowerKey === 'transfer-encoding') continue;\n existingHeaders[key] = value;\n }\n\n // Hijack the reply to take control of the response\n // This is required when writing directly to reply.raw\n reply.hijack();\n\n const streamFormat = route.streamFormat || 'stream';\n\n // Write headers directly to the raw response, merging existing headers (like CORS)\n // with our stream-specific headers\n const sseHeaders =\n streamFormat === 'sse'\n ? {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n 'X-Accel-Buffering': 'no',\n }\n : {\n 'Content-Type': 'text/plain',\n };\n\n reply.raw.writeHead(200, {\n ...existingHeaders,\n ...sseHeaders,\n 'Transfer-Encoding': 'chunked',\n });\n\n if (streamFormat === 'sse' && route.sseFlushOnConnect) {\n reply.raw.write(': connected\\n\\n');\n }\n\n const readableStream = result instanceof ReadableStream ? result : result.fullStream;\n const reader = readableStream.getReader();\n\n let readerCanceled = false;\n const cancelReader = (reason: string) => {\n if (readerCanceled) return;\n readerCanceled = true;\n void reader.cancel(reason);\n };\n const cancelReaderOnResponseClose = () => cancelReader('request aborted');\n const cancelReaderOnRequestClose = () => {\n if (request && isRequestAborted(request.raw)) {\n cancelReader('request aborted');\n }\n };\n reply.raw.on('close', cancelReaderOnResponseClose);\n request?.raw.on('close', cancelReaderOnRequestClose);\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n if (value) {\n if (streamFormat === 'sse' && typeof value === 'string' && value.startsWith(':')) {\n reply.raw.write(value);\n continue;\n }\n\n // Optionally redact sensitive data (system prompts, tool definitions, API keys) before sending to the client\n const shouldRedact = this.streamOptions?.redact ?? true;\n const outputValue = shouldRedact ? redactStreamChunk(value) : value;\n if (streamFormat === 'sse') {\n reply.raw.write(`data: ${JSON.stringify(outputValue)}\\n\\n`);\n } else {\n reply.raw.write(JSON.stringify(outputValue) + '\\x1E');\n }\n }\n }\n } catch (error) {\n this.mastra.getLogger()?.error('Error in stream processing', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n } finally {\n reply.raw.off('close', cancelReaderOnResponseClose);\n request?.raw.off('close', cancelReaderOnRequestClose);\n if (!reply.raw.writableEnded && !reply.raw.destroyed) {\n reply.raw.end();\n }\n }\n }\n\n async getParams(route: ServerRoute, request: FastifyRequest): Promise<ParsedRequestParams> {\n const urlParams = (request.params || {}) as Record<string, string>;\n // Fastify's request.query can contain string | string[] for repeated params\n const queryParams = normalizeQueryParams((request.query || {}) as Record<string, unknown>);\n let body: unknown;\n let bodyParseError: { message: string } | undefined;\n\n if (route.method === 'POST' || route.method === 'PUT' || route.method === 'PATCH' || route.method === 'DELETE') {\n const contentType = request.headers['content-type'] || '';\n\n if (contentType.includes('multipart/form-data')) {\n try {\n const maxFileSize = route.maxBodySize ?? this.bodyLimitOptions?.maxSize;\n body = await this.parseMultipartFormData(request, maxFileSize);\n } catch (error) {\n this.mastra.getLogger()?.error('Failed to parse multipart form data', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n // Re-throw size limit errors, let others fall through to validation\n if (error instanceof Error && error.message.toLowerCase().includes('size')) {\n throw error;\n }\n bodyParseError = {\n message: error instanceof Error ? error.message : 'Failed to parse multipart form data',\n };\n }\n } else {\n body = request.body;\n }\n }\n\n return { urlParams, queryParams, body, bodyParseError };\n }\n\n /**\n * Parse multipart/form-data using @fastify/busboy.\n * Converts file uploads to Buffers and parses JSON field values.\n *\n * @param request - The Fastify request object\n * @param maxFileSize - Optional maximum file size in bytes\n */\n private parseMultipartFormData(request: FastifyRequest, maxFileSize?: number): Promise<Record<string, unknown>> {\n return new Promise((resolve, reject) => {\n const result: Record<string, unknown> = {};\n\n const busboy = new Busboy({\n headers: {\n 'content-type': request.headers['content-type'] as string,\n },\n limits: maxFileSize ? { fileSize: maxFileSize } : undefined,\n });\n\n busboy.on(\n 'file',\n (fieldname: string, file: NodeJS.ReadableStream, _filename: string, _encoding: string, _mimetype: string) => {\n const chunks: Buffer[] = [];\n let limitExceeded = false;\n\n file.on('data', (chunk: Buffer) => {\n chunks.push(chunk);\n });\n\n file.on('limit', () => {\n limitExceeded = true;\n file.resume();\n reject(new Error(`File size limit exceeded${maxFileSize ? ` (max: ${maxFileSize} bytes)` : ''}`));\n });\n\n file.on('end', () => {\n if (!limitExceeded) {\n result[fieldname] = Buffer.concat(chunks);\n }\n });\n },\n );\n\n busboy.on('field', (fieldname: string, value: string) => {\n // Try to parse JSON strings (like 'options')\n try {\n result[fieldname] = JSON.parse(value);\n } catch {\n result[fieldname] = value;\n }\n });\n\n busboy.on('finish', () => {\n resolve(result);\n });\n\n busboy.on('error', (error: Error) => {\n reject(error);\n });\n\n // Pipe the raw request to busboy\n request.raw.pipe(busboy);\n });\n }\n\n async sendResponse(\n route: ServerRoute,\n reply: FastifyReply,\n result: unknown,\n request?: FastifyRequest,\n prefix?: string,\n ): Promise<void> {\n const resolvedPrefix = prefix ?? this.prefix ?? '';\n\n // Apply refresh headers from transparent session refresh (e.g. Set-Cookie after token refresh)\n if (result && typeof result === 'object' && '__refreshHeaders' in result) {\n const refreshHeaders = (result as any).__refreshHeaders as Record<string, string>;\n for (const [key, value] of Object.entries(refreshHeaders)) {\n reply.header(key, value);\n }\n delete (result as any).__refreshHeaders;\n }\n\n if (route.responseType === 'json') {\n await reply.send(result);\n } else if (route.responseType === 'stream') {\n await this.stream(route, reply, result as { fullStream: ReadableStream }, request);\n } else if (route.responseType === 'datastream-response') {\n // Handle AI SDK Response objects - pipe Response.body to Fastify response\n const fetchResponse = result as globalThis.Response;\n fetchResponse.headers.forEach((value, key) => reply.header(key, value));\n reply.status(fetchResponse.status);\n if (fetchResponse.body) {\n const reader = fetchResponse.body.getReader();\n let readerCanceled = false;\n\n const cancelReader = (reason: string) => {\n if (readerCanceled) return;\n readerCanceled = true;\n void reader.cancel(reason);\n };\n\n const cancelReaderOnResponseClose = () => cancelReader('request aborted');\n const cancelReaderOnRequestClose = () => {\n if (request && isRequestAborted(request.raw)) {\n cancelReader('request aborted');\n }\n };\n\n const onResError = (err: unknown) => {\n this.mastra.getLogger()?.error('Error writing datastream response', {\n error: err instanceof Error ? { message: err.message, stack: err.stack } : err,\n });\n cancelReader('response write error');\n };\n reply.raw.once('error', onResError);\n reply.raw.on('close', cancelReaderOnResponseClose);\n request?.raw.on('close', cancelReaderOnRequestClose);\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n reply.raw.write(value);\n }\n } catch (error) {\n this.mastra.getLogger()?.error('Error in datastream processing', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n } finally {\n reply.raw.off('error', onResError);\n reply.raw.off('close', cancelReaderOnResponseClose);\n request?.raw.off('close', cancelReaderOnRequestClose);\n if (!reply.raw.writableEnded && !reply.raw.destroyed) {\n reply.raw.end();\n }\n }\n } else {\n reply.raw.end();\n }\n } else if (route.responseType === 'mcp-http') {\n // MCP Streamable HTTP transport - request is required\n if (!request) {\n await reply.status(500).send({ error: 'Request object required for MCP transport' });\n return;\n }\n\n const { server, httpPath, mcpOptions: routeMcpOptions } = result as MCPHttpTransportResult;\n\n try {\n // Hijack the response to bypass Fastify's response handling\n // This is required when we write directly to reply.raw\n reply.hijack();\n\n // Attach parsed body to raw request so MCP server's readJsonBody can use it\n // Fastify consumes the body stream, so we need to provide the pre-parsed body\n const rawReq = request.raw as typeof request.raw & { body?: unknown };\n if (request.body !== undefined) {\n rawReq.body = request.body;\n }\n\n // Merge class-level mcpOptions with route-specific options (route takes precedence)\n const options = { ...this.mcpOptions, ...routeMcpOptions };\n\n await server.startHTTP({\n url: new URL(request.url, `http://${request.headers.host}`),\n httpPath: `${resolvedPrefix}${httpPath}`,\n req: rawReq,\n res: reply.raw,\n options: Object.keys(options).length > 0 ? options : undefined,\n });\n // Response handled by startHTTP\n } catch {\n if (!reply.raw.headersSent) {\n reply.raw.writeHead(500, { 'Content-Type': 'application/json' });\n reply.raw.end(\n JSON.stringify({\n jsonrpc: '2.0',\n error: { code: -32603, message: 'Internal server error' },\n id: null,\n }),\n );\n }\n }\n } else if (route.responseType === 'mcp-sse') {\n // MCP SSE transport - request is required\n if (!request) {\n await reply.status(500).send({ error: 'Request object required for MCP transport' });\n return;\n }\n\n const { server, ssePath, messagePath } = result as MCPSseTransportResult;\n\n try {\n // Hijack the response to bypass Fastify's response handling\n // This is required when we write directly to reply.raw for SSE\n reply.hijack();\n\n // Attach parsed body to raw request so MCP server's readJsonBody can use it\n // Fastify consumes the body stream, so we need to provide the pre-parsed body\n const rawReq = request.raw as typeof request.raw & { body?: unknown };\n if (request.body !== undefined) {\n rawReq.body = request.body;\n }\n\n await server.startSSE({\n url: new URL(request.url, `http://${request.headers.host}`),\n ssePath: `${resolvedPrefix}${ssePath}`,\n messagePath: `${resolvedPrefix}${messagePath}`,\n req: rawReq,\n res: reply.raw,\n });\n // Response handled by startSSE\n } catch {\n if (!reply.raw.headersSent) {\n reply.raw.writeHead(500, { 'Content-Type': 'application/json' });\n reply.raw.end(JSON.stringify({ error: 'Error handling MCP SSE request' }));\n }\n }\n } else {\n reply.status(500);\n }\n }\n\n async registerRoute(\n app: FastifyInstance,\n route: ServerRoute,\n { prefix: prefixParam }: { prefix?: string } = {},\n ): Promise<void> {\n // Default prefix to this.prefix if not provided, or empty string\n const prefix = prefixParam ?? this.prefix ?? '';\n\n const fullPath = `${prefix}${route.path}`;\n\n // Convert Express-style :param to Fastify-style :param (they're the same, but ensure consistency)\n const fastifyPath = fullPath;\n\n // Define the route handler\n const handler: RouteHandlerMethod = async (request: FastifyRequest, reply: FastifyReply) => {\n // Check route-level authentication/authorization\n const authError = await this.checkRouteAuth(route, {\n path: String(request.url.split('?')[0] || '/'),\n method: String(request.method || 'GET'),\n getHeader: name => request.headers[name.toLowerCase()] as string | undefined,\n getQuery: name => (request.query as Record<string, string>)[name],\n requestContext: request.requestContext,\n request: toWebRequest(request),\n buildAuthorizeContext: () => toWebRequest(request),\n });\n\n if (authError) {\n // Apply any refresh headers (e.g. Set-Cookie from transparent session refresh)\n if (authError.headers) {\n for (const [key, value] of Object.entries(authError.headers)) {\n void reply.header(key, value);\n }\n }\n\n // If this is an auth error (not just a success-with-headers), return error response\n if (authError.error) {\n return reply.status(authError.status).send({ error: authError.error });\n }\n }\n\n const params = await this.getParams(route, request);\n\n // Return 400 Bad Request if body parsing failed (e.g., malformed multipart data)\n if (params.bodyParseError) {\n return reply.status(400).send({\n error: 'Invalid request body',\n issues: [{ field: 'body', message: params.bodyParseError.message }],\n });\n }\n\n if (params.queryParams) {\n try {\n params.queryParams = await this.parseQueryParams(route, params.queryParams);\n } catch (error) {\n this.mastra.getLogger()?.error('Error parsing query params', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n if (isZodError(error)) {\n const { status, body } = this.resolveValidationError(route, error, 'query');\n return reply.status(status).send(body);\n }\n return reply.status(400).send({\n error: 'Invalid query parameters',\n issues: [{ field: 'unknown', message: error instanceof Error ? error.message : 'Unknown error' }],\n });\n }\n }\n\n if (params.body) {\n try {\n params.body = await this.parseBody(route, params.body);\n } catch (error) {\n this.mastra.getLogger()?.error('Error parsing body', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n if (isZodError(error)) {\n const { status, body } = this.resolveValidationError(route, error, 'body');\n return reply.status(status).send(body);\n }\n return reply.status(400).send({\n error: 'Invalid request body',\n issues: [{ field: 'unknown', message: error instanceof Error ? error.message : 'Unknown error' }],\n });\n }\n }\n\n // Parse path params through pathParamSchema for type coercion (e.g., z.coerce.number())\n if (params.urlParams) {\n try {\n params.urlParams = await this.parsePathParams(route, params.urlParams);\n } catch (error) {\n this.mastra.getLogger()?.error('Error parsing path params', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n if (isZodError(error)) {\n const { status, body } = this.resolveValidationError(route, error, 'path');\n return reply.status(status).send(body);\n }\n return reply.status(400).send({\n error: 'Invalid path parameters',\n issues: [{ field: 'unknown', message: error instanceof Error ? error.message : 'Unknown error' }],\n });\n }\n }\n\n const handlerParams = {\n ...params.urlParams,\n ...params.queryParams,\n ...(typeof params.body === 'object' ? params.body : {}),\n requestContext: request.requestContext,\n mastra: this.mastra,\n registeredTools: request.registeredTools,\n taskStore: request.taskStore,\n abortSignal: request.abortSignal,\n routePrefix: prefix,\n };\n\n // Check route permission requirement (EE feature)\n // Uses convention-based permission derivation: permissions are auto-derived\n // from route path/method unless explicitly set or route is public\n const authConfig = this.mastra.getServer()?.auth;\n if (authConfig) {\n const hasPermission = await loadHasPermission();\n if (hasPermission) {\n const userPermissions = request.requestContext.get('mastra__userPermissions') as string[] | undefined;\n const permissionError = this.checkRoutePermission(route, userPermissions, hasPermission);\n\n if (permissionError) {\n return reply.status(permissionError.status).send({\n error: permissionError.error,\n message: permissionError.message,\n });\n }\n }\n }\n\n // Check FGA authorization (EE feature)\n const fgaError = await checkRouteFGA(this.mastra, route, request.requestContext, {\n ...params.urlParams,\n ...params.queryParams,\n ...(typeof params.body === 'object' ? params.body : {}),\n });\n if (fgaError) {\n return reply.status(fgaError.status).send({ error: fgaError.error, message: fgaError.message });\n }\n\n try {\n const result = await route.handler(handlerParams);\n await this.sendResponse(route, reply, result, request, prefix);\n } catch (error) {\n this.mastra.getLogger()?.error('Error calling handler', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n path: route.path,\n method: route.method,\n });\n // Check if it's an HTTPException or MastraError with a status code\n let status = 500;\n if (error && typeof error === 'object') {\n // Check for direct status property (HTTPException)\n if ('status' in error) {\n status = (error as any).status;\n }\n // Check for MastraError with status in details\n else if (\n 'details' in error &&\n error.details &&\n typeof error.details === 'object' &&\n 'status' in error.details\n ) {\n status = (error.details as any).status;\n }\n }\n await reply.status(status).send({ error: error instanceof Error ? error.message : 'Unknown error' });\n }\n };\n\n // Add body limit if configured\n const shouldApplyBodyLimit = this.bodyLimitOptions && ['POST', 'PUT', 'PATCH'].includes(route.method.toUpperCase());\n const maxSize = route.maxBodySize ?? this.bodyLimitOptions?.maxSize;\n\n const config = shouldApplyBodyLimit && maxSize ? { bodyLimit: maxSize } : undefined;\n\n // Handle ALL method by registering for each HTTP method\n // Fastify doesn't support 'ALL' method natively like Express\n if (route.method.toUpperCase() === 'ALL') {\n // Only register the main HTTP methods that MCP actually uses\n // Skip HEAD/OPTIONS to avoid potential conflicts with Fastify's auto-generated routes\n const methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'] as const;\n for (const method of methods) {\n try {\n app.route({\n method,\n url: fastifyPath,\n handler,\n config,\n });\n } catch (err) {\n // Skip duplicate route errors - can happen if route is registered multiple times\n if (err instanceof Error && err.message.includes('already declared')) {\n continue;\n }\n throw err;\n }\n }\n } else {\n app.route({\n method: route.method as 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',\n url: fastifyPath,\n handler,\n config,\n });\n }\n }\n\n async registerCustomApiRoutes(): Promise<void> {\n if (!(await this.buildCustomRouteHandler())) return;\n\n const routes = this.customApiRoutes ?? this.mastra.getServer()?.apiRoutes ?? [];\n\n for (const route of routes) {\n // Create pseudo ServerRoute for auth checking\n const serverRoute: ServerRoute = {\n method: route.method as any,\n path: route.path,\n responseType: 'json',\n handler: async () => {},\n requiresAuth: route.requiresAuth,\n requiresPermission: route.requiresPermission,\n fga: route.fga,\n };\n\n const fastifyHandler: RouteHandlerMethod = async (request: FastifyRequest, reply: FastifyReply) => {\n // Per-route auth check (same pattern as registerRoute)\n const authError = await this.checkRouteAuth(serverRoute, {\n path: String(request.url.split('?')[0] || '/'),\n method: String(request.method || 'GET'),\n getHeader: name => request.headers[name.toLowerCase()] as string | undefined,\n getQuery: name => (request.query as Record<string, string>)[name],\n requestContext: request.requestContext,\n request: toWebRequest(request),\n buildAuthorizeContext: () => toWebRequest(request),\n });\n\n if (authError) {\n if (authError.headers) {\n for (const [key, value] of Object.entries(authError.headers)) {\n void reply.header(key, value);\n }\n }\n if (authError.error) {\n return reply.status(authError.status).send({ error: authError.error });\n }\n }\n\n const authConfig = this.mastra.getServer()?.auth;\n if (authConfig) {\n let hasPermission: ((userPerms: string[], required: string) => boolean) | undefined;\n try {\n ({ hasPermission } = await import('@mastra/core/auth/ee'));\n } catch {\n console.error(\n '[@mastra/fastify] Auth features require @mastra/core >= 1.6.0. Please upgrade: npm install @mastra/core@latest',\n );\n }\n\n if (hasPermission) {\n const userPermissions = request.requestContext.get('mastra__userPermissions') as string[] | undefined;\n const permissionError = this.checkRoutePermission(serverRoute, userPermissions, hasPermission);\n if (permissionError) {\n return reply.status(permissionError.status).send({\n error: permissionError.error,\n message: permissionError.message,\n });\n }\n }\n }\n\n // Check FGA authorization (EE feature)\n const fgaError = await checkRouteFGA(this.mastra, serverRoute, request.requestContext, {\n ...(request.params as Record<string, string>),\n ...(request.query as Record<string, string>),\n ...(typeof request.body === 'object' && request.body !== null\n ? (request.body as Record<string, unknown>)\n : {}),\n });\n if (fgaError) {\n return reply.status(fgaError.status).send({ error: fgaError.error, message: fgaError.message });\n }\n\n const response = await this.handleCustomRouteRequest(\n `http://${request.headers.host}${request.url}`,\n request.method,\n request.headers as Record<string, string | string[] | undefined>,\n request.body,\n request.requestContext,\n request.abortSignal,\n );\n if (!response) {\n reply.status(404).send({ error: 'Not Found' });\n return;\n }\n // Merge headers set by Fastify hooks/plugins (e.g. @fastify/cors) into\n // the Fetch Response before hijacking. Otherwise writeCustomRouteResponse's\n // nodeRes.writeHead() overwrites them with only the response.headers set\n // by the custom route handler. Route-set headers win on conflict, except\n // for set-cookie which is always appended so plugin cookies survive\n // alongside handler cookies (distinct cookies, not a collision).\n // Skip framing headers (RFC 7230) — writeCustomRouteResponse /\n // Node's writeHead owns content-length and transfer-encoding.\n const existingHeaders = reply.getHeaders();\n for (const [key, value] of Object.entries(existingHeaders)) {\n if (value === undefined) continue;\n const lowerKey = key.toLowerCase();\n if (lowerKey === 'content-length' || lowerKey === 'transfer-encoding') continue;\n const isSetCookie = lowerKey === 'set-cookie';\n if (!isSetCookie && response.headers.has(key)) continue;\n if (Array.isArray(value)) {\n for (const item of value) response.headers.append(key, String(item));\n } else if (isSetCookie) {\n // set-cookie must always append so plugin cookies coexist with handler cookies.\n response.headers.append(key, String(value));\n } else {\n response.headers.set(key, String(value));\n }\n }\n reply.hijack();\n await this.writeCustomRouteResponse(response, reply.raw, request.abortSignal);\n };\n\n if (route.method === 'ALL') {\n const methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'] as const;\n for (const method of methods) {\n this.app.route({ method, url: route.path, handler: fastifyHandler });\n }\n } else {\n this.app.route({\n method: route.method as 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',\n url: route.path,\n handler: fastifyHandler,\n });\n }\n }\n }\n\n registerContextMiddleware(): void {\n // Override the default JSON parser to allow empty bodies\n // This matches Express behavior where empty POST requests with Content-Type: application/json are allowed\n this.app.removeContentTypeParser('application/json');\n this.app.addContentTypeParser('application/json', { parseAs: 'string' }, (_request, body, done) => {\n try {\n // Allow empty body\n if (!body || (typeof body === 'string' && body.trim() === '')) {\n done(null, undefined);\n return;\n }\n const parsed = JSON.parse(body as string);\n done(null, parsed);\n } catch (err) {\n done(err as Error, undefined);\n }\n });\n\n // Register content type parser for multipart/form-data\n // This allows Fastify to accept multipart requests without parsing them\n // We'll parse them manually in getParams using busboy\n this.app.addContentTypeParser('multipart/form-data', (_request, _payload, done) => {\n // Don't parse the body, we'll handle it manually with busboy\n done(null, undefined);\n });\n\n this.app.addHook('preHandler', this.createContextMiddleware());\n }\n\n registerAuthMiddleware(): void {\n // Auth is handled per-route in registerRoute() and registerCustomApiRoutes()\n // No global middleware needed\n }\n\n registerHttpLoggingMiddleware(): void {\n if (!this.httpLoggingConfig?.enabled) {\n return;\n }\n\n this.app.addHook('onRequest', async (request: FastifyRequest, reply: FastifyReply) => {\n const urlPath = request.url.split('?')[0]!;\n if (!this.shouldLogRequest(urlPath)) {\n return;\n }\n\n const start = Date.now();\n const method = request.method;\n const path = urlPath;\n\n reply.raw.once('finish', () => {\n const duration = Date.now() - start;\n const status = reply.statusCode;\n const level = this.httpLoggingConfig?.level || 'info';\n\n const logData: Record<string, any> = {\n method,\n path,\n status,\n duration: `${duration}ms`,\n };\n\n if (this.httpLoggingConfig?.includeQueryParams) {\n logData.query = request.query;\n }\n\n if (this.httpLoggingConfig?.includeHeaders) {\n const headers = { ...request.headers };\n const redactHeaders = this.httpLoggingConfig.redactHeaders || [];\n redactHeaders.forEach((h: string) => {\n const key = h.toLowerCase();\n if (headers[key] !== undefined) {\n headers[key] = '[REDACTED]';\n }\n });\n logData.headers = headers;\n }\n\n this.logger[level](`${method} ${path} ${status} ${duration}ms`, logData);\n });\n });\n }\n}\n"]}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACtF,OAAO,EACL,YAAY,IAAI,gBAAgB,EAKjC,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAsB,MAAM,SAAS,CAAC;AACxH,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,YAAY,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAmDtE,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,cAAc;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,cAAc,EAAE,cAAc,CAAC;QAC/B,eAAe,EAAE,UAAU,CAAC;QAC5B,WAAW,EAAE,WAAW,CAAC;QACzB,SAAS,EAAE,iBAAiB,CAAC;QAC7B,qBAAqB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC9C;CACF;AAED,qBAAa,YAAa,SAAQ,gBAAgB,CAAC,eAAe,EAAE,cAAc,EAAE,YAAY,CAAC;IAC/F,uBAAuB,IAAI,qBAAqB;IA6E1C,MAAM,CACV,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE;QAAE,UAAU,EAAE,cAAc,CAAA;KAAE,EACtC,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC;IAiGV,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAkC1F;;;;;;OAMG;IACH,OAAO,CAAC,sBAAsB;IAyDxB,YAAY,CAChB,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,OAAO,EACf,OAAO,CAAC,EAAE,cAAc,EACxB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC;IAyJV,aAAa,CACjB,GAAG,EAAE,eAAe,EACpB,KAAK,EAAE,WAAW,EAClB,EAAE,MAAM,EAAE,WAAW,EAAE,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAChD,OAAO,CAAC,IAAI,CAAC;IAkNV,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACtF,OAAO,EACL,YAAY,IAAI,gBAAgB,EAKjC,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAsB,MAAM,SAAS,CAAC;AACxH,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,YAAY,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAmDtE,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,cAAc;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,cAAc,EAAE,cAAc,CAAC;QAC/B,eAAe,EAAE,UAAU,CAAC;QAC5B,WAAW,EAAE,WAAW,CAAC;QACzB,SAAS,EAAE,iBAAiB,CAAC;QAC7B,qBAAqB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC9C;CACF;AAED,qBAAa,YAAa,SAAQ,gBAAgB,CAAC,eAAe,EAAE,cAAc,EAAE,YAAY,CAAC;IAC/F,uBAAuB,IAAI,qBAAqB;IA6E1C,MAAM,CACV,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE;QAAE,UAAU,EAAE,cAAc,CAAA;KAAE,EACtC,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC;IAiGV,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAkC1F;;;;;;OAMG;IACH,OAAO,CAAC,sBAAsB;IAyDxB,YAAY,CAChB,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,OAAO,EACf,OAAO,CAAC,EAAE,cAAc,EACxB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC;IAyJV,aAAa,CACjB,GAAG,EAAE,eAAe,EACpB,KAAK,EAAE,WAAW,EAClB,EAAE,MAAM,EAAE,WAAW,EAAE,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAChD,OAAO,CAAC,IAAI,CAAC;IAkNV,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC;IAkI9C,yBAAyB,IAAI,IAAI;IA6BjC,sBAAsB,IAAI,IAAI;IAK9B,6BAA6B,IAAI,IAAI;CA+CtC"}
|
package/dist/index.js
CHANGED
|
@@ -676,6 +676,21 @@ var MastraServer = class extends MastraServer$1 {
|
|
|
676
676
|
reply.status(404).send({ error: "Not Found" });
|
|
677
677
|
return;
|
|
678
678
|
}
|
|
679
|
+
const existingHeaders = reply.getHeaders();
|
|
680
|
+
for (const [key, value] of Object.entries(existingHeaders)) {
|
|
681
|
+
if (value === void 0) continue;
|
|
682
|
+
const lowerKey = key.toLowerCase();
|
|
683
|
+
if (lowerKey === "content-length" || lowerKey === "transfer-encoding") continue;
|
|
684
|
+
const isSetCookie = lowerKey === "set-cookie";
|
|
685
|
+
if (!isSetCookie && response.headers.has(key)) continue;
|
|
686
|
+
if (Array.isArray(value)) {
|
|
687
|
+
for (const item of value) response.headers.append(key, String(item));
|
|
688
|
+
} else if (isSetCookie) {
|
|
689
|
+
response.headers.append(key, String(value));
|
|
690
|
+
} else {
|
|
691
|
+
response.headers.set(key, String(value));
|
|
692
|
+
}
|
|
693
|
+
}
|
|
679
694
|
reply.hijack();
|
|
680
695
|
await this.writeCustomRouteResponse(response, reply.raw, request.abortSignal);
|
|
681
696
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/auth-middleware.ts","../src/index.ts"],"names":["toWebRequest","MastraServerBase"],"mappings":"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","file":"index.js","sourcesContent":["import type { Mastra } from '@mastra/core/mastra';\nimport { RequestContext } from '@mastra/core/request-context';\nimport { coreAuthMiddleware } from '@mastra/server/auth';\nimport type { FastifyReply, FastifyRequest, preHandlerHookHandler } from 'fastify';\n\nexport interface FastifyAuthMiddlewareOptions {\n mastra: Mastra;\n requiresAuth?: boolean;\n}\n\nfunction toWebRequest(request: FastifyRequest): globalThis.Request {\n const protocol = request.protocol || 'http';\n const host = request.headers.host || 'localhost';\n const url = `${protocol}://${host}${request.url}`;\n\n const headers = new Headers();\n for (const [key, value] of Object.entries(request.headers)) {\n if (!value) continue;\n if (Array.isArray(value)) {\n value.forEach(v => headers.append(key, v));\n } else {\n headers.set(key, value);\n }\n }\n\n return new globalThis.Request(url, {\n method: request.method,\n headers,\n });\n}\n\nexport function createAuthMiddleware({\n mastra,\n requiresAuth = true,\n}: FastifyAuthMiddlewareOptions): preHandlerHookHandler {\n return async (request: FastifyRequest, reply: FastifyReply) => {\n if (!requiresAuth) {\n return;\n }\n\n const authConfig = mastra.getServer()?.auth;\n if (!authConfig) {\n return;\n }\n\n request.requestContext ??= new RequestContext();\n request.mastra ??= mastra;\n\n const path = String(request.url.split('?')[0] || '/');\n const method = String(request.method || 'GET');\n const customRouteAuthConfig = new Map<string, boolean>(request.customRouteAuthConfig ?? []);\n customRouteAuthConfig.set(`${method}:${path}`, true);\n\n const authHeader = request.headers.authorization;\n let token: string | null = authHeader ? authHeader.replace('Bearer ', '') : null;\n const query = request.query as Record<string, string>;\n if (!token && query.apiKey) {\n token = query.apiKey || null;\n }\n\n const result = await coreAuthMiddleware({\n path,\n method,\n getHeader: name => request.headers[name.toLowerCase()] as string | undefined,\n mastra,\n authConfig,\n customRouteAuthConfig,\n requestContext: request.requestContext,\n rawRequest: toWebRequest(request),\n token,\n buildAuthorizeContext: () => toWebRequest(request),\n });\n\n if (result.action === 'error') {\n return reply.status(result.status).send(result.body);\n }\n };\n}\n","import { Busboy } from '@fastify/busboy';\nimport type { ToolsInput } from '@mastra/core/agent';\nimport type { Mastra } from '@mastra/core/mastra';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport type { InMemoryTaskStore } from '@mastra/server/a2a/store';\nimport type { MCPHttpTransportResult, MCPSseTransportResult } from '@mastra/server/handlers/mcp';\nimport type { ParsedRequestParams, ServerRoute } from '@mastra/server/server-adapter';\nimport {\n MastraServer as MastraServerBase,\n checkRouteFGA,\n isZodError,\n normalizeQueryParams,\n redactStreamChunk,\n} from '@mastra/server/server-adapter';\nimport type { FastifyInstance, FastifyReply, FastifyRequest, preHandlerHookHandler, RouteHandlerMethod } from 'fastify';\nexport { createAuthMiddleware } from './auth-middleware';\nexport type { FastifyAuthMiddlewareOptions } from './auth-middleware';\n\ntype HasPermissionFn = (userPerms: string[], required: string) => boolean;\nlet _hasPermissionPromise: Promise<HasPermissionFn | undefined> | undefined;\nfunction loadHasPermission(): Promise<HasPermissionFn | undefined> {\n if (!_hasPermissionPromise) {\n _hasPermissionPromise = import('@mastra/core/auth/ee')\n .then(m => m.hasPermission)\n .catch(() => {\n console.error(\n '[@mastra/fastify] Auth features require @mastra/core >= 1.6.0. Please upgrade: npm install @mastra/core@latest',\n );\n return undefined;\n });\n }\n return _hasPermissionPromise;\n}\n\n/**\n * Convert Fastify request to Web API Request for cookie-based auth providers.\n */\nfunction toWebRequest(request: FastifyRequest): globalThis.Request {\n const protocol = request.protocol || 'http';\n const host = request.headers.host || 'localhost';\n const url = `${protocol}://${host}${request.url}`;\n\n const headers = new Headers();\n for (const [key, value] of Object.entries(request.headers)) {\n if (value) {\n if (Array.isArray(value)) {\n value.forEach(v => headers.append(key, v));\n } else {\n headers.set(key, value);\n }\n }\n }\n\n return new globalThis.Request(url, {\n method: request.method,\n headers,\n });\n}\n\nfunction isRequestAborted(rawRequest: FastifyRequest['raw']): boolean {\n // Fastify can emit request close after a POST body is fully consumed while\n // the response stream is still active, so only treat it as disconnect when\n // the request itself reports an abort or never completed.\n return rawRequest.aborted || rawRequest.readableAborted || !rawRequest.complete;\n}\n\n// Extend Fastify types to include Mastra context\ndeclare module 'fastify' {\n interface FastifyRequest {\n mastra: Mastra;\n requestContext: RequestContext;\n registeredTools: ToolsInput;\n abortSignal: AbortSignal;\n taskStore: InMemoryTaskStore;\n customRouteAuthConfig?: Map<string, boolean>;\n }\n}\n\nexport class MastraServer extends MastraServerBase<FastifyInstance, FastifyRequest, FastifyReply> {\n createContextMiddleware(): preHandlerHookHandler {\n return async (request: FastifyRequest, reply: FastifyReply) => {\n // Parse request context from request body and add to context\n let bodyRequestContext: Record<string, any> | undefined;\n let paramsRequestContext: Record<string, any> | undefined;\n\n // Parse request context from request body (POST/PUT)\n if (request.method === 'POST' || request.method === 'PUT') {\n const contentType = request.headers['content-type'];\n if (contentType?.includes('application/json') && request.body) {\n const body = request.body as { requestContext?: Record<string, any> };\n if (body.requestContext) {\n bodyRequestContext = body.requestContext;\n }\n }\n }\n\n // Parse request context from query params (GET)\n if (request.method === 'GET') {\n try {\n const query = request.query as Record<string, string>;\n const encodedRequestContext = query.requestContext;\n if (typeof encodedRequestContext === 'string') {\n // Try JSON first\n try {\n paramsRequestContext = JSON.parse(encodedRequestContext);\n } catch {\n // Fallback to base64(JSON)\n try {\n const json = Buffer.from(encodedRequestContext, 'base64').toString('utf-8');\n paramsRequestContext = JSON.parse(json);\n } catch {\n // ignore if still invalid\n }\n }\n }\n } catch {\n // ignore query parsing errors\n }\n }\n\n const requestContext = this.mergeRequestContext({ paramsRequestContext, bodyRequestContext });\n this.applyRequestMetadataToContext({\n requestContext,\n getHeader: name => {\n const value = request.headers[name.toLowerCase()];\n return Array.isArray(value) ? value[0] : value;\n },\n });\n\n // Set context in request object\n request.requestContext = requestContext;\n request.mastra = this.mastra;\n request.registeredTools = this.tools || {};\n if (this.taskStore) {\n request.taskStore = this.taskStore;\n }\n request.customRouteAuthConfig = this.customRouteAuthConfig;\n\n // Create abort controller for request cancellation\n const controller = new AbortController();\n request.raw.on('close', () => {\n if (isRequestAborted(request.raw)) {\n controller.abort();\n }\n });\n reply.raw.on('close', () => {\n // Response close fires for normal completion too; only abort if the\n // response did not finish successfully.\n if (!reply.raw.writableEnded) {\n controller.abort();\n }\n });\n request.abortSignal = controller.signal;\n };\n }\n\n async stream(\n route: ServerRoute,\n reply: FastifyReply,\n result: { fullStream: ReadableStream },\n request?: FastifyRequest,\n ): Promise<void> {\n // Capture headers set by plugins (e.g., @fastify/cors) BEFORE hijacking\n // reply.hijack() bypasses Fastify's response handling, so we need to preserve\n // any headers that were set by hooks/plugins and manually include them\n const rawHeaders = reply.getHeaders();\n // Filter out undefined values and conflicting headers (content-length, transfer-encoding)\n // Having both Content-Length and Transfer-Encoding: chunked violates RFC 7230\n const existingHeaders: Record<string, string | number | string[]> = {};\n for (const [key, value] of Object.entries(rawHeaders)) {\n if (value === undefined) continue;\n const lowerKey = key.toLowerCase();\n if (lowerKey === 'content-length' || lowerKey === 'transfer-encoding') continue;\n existingHeaders[key] = value;\n }\n\n // Hijack the reply to take control of the response\n // This is required when writing directly to reply.raw\n reply.hijack();\n\n const streamFormat = route.streamFormat || 'stream';\n\n // Write headers directly to the raw response, merging existing headers (like CORS)\n // with our stream-specific headers\n const sseHeaders =\n streamFormat === 'sse'\n ? {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n 'X-Accel-Buffering': 'no',\n }\n : {\n 'Content-Type': 'text/plain',\n };\n\n reply.raw.writeHead(200, {\n ...existingHeaders,\n ...sseHeaders,\n 'Transfer-Encoding': 'chunked',\n });\n\n if (streamFormat === 'sse' && route.sseFlushOnConnect) {\n reply.raw.write(': connected\\n\\n');\n }\n\n const readableStream = result instanceof ReadableStream ? result : result.fullStream;\n const reader = readableStream.getReader();\n\n let readerCanceled = false;\n const cancelReader = (reason: string) => {\n if (readerCanceled) return;\n readerCanceled = true;\n void reader.cancel(reason);\n };\n const cancelReaderOnResponseClose = () => cancelReader('request aborted');\n const cancelReaderOnRequestClose = () => {\n if (request && isRequestAborted(request.raw)) {\n cancelReader('request aborted');\n }\n };\n reply.raw.on('close', cancelReaderOnResponseClose);\n request?.raw.on('close', cancelReaderOnRequestClose);\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n if (value) {\n if (streamFormat === 'sse' && typeof value === 'string' && value.startsWith(':')) {\n reply.raw.write(value);\n continue;\n }\n\n // Optionally redact sensitive data (system prompts, tool definitions, API keys) before sending to the client\n const shouldRedact = this.streamOptions?.redact ?? true;\n const outputValue = shouldRedact ? redactStreamChunk(value) : value;\n if (streamFormat === 'sse') {\n reply.raw.write(`data: ${JSON.stringify(outputValue)}\\n\\n`);\n } else {\n reply.raw.write(JSON.stringify(outputValue) + '\\x1E');\n }\n }\n }\n } catch (error) {\n this.mastra.getLogger()?.error('Error in stream processing', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n } finally {\n reply.raw.off('close', cancelReaderOnResponseClose);\n request?.raw.off('close', cancelReaderOnRequestClose);\n if (!reply.raw.writableEnded && !reply.raw.destroyed) {\n reply.raw.end();\n }\n }\n }\n\n async getParams(route: ServerRoute, request: FastifyRequest): Promise<ParsedRequestParams> {\n const urlParams = (request.params || {}) as Record<string, string>;\n // Fastify's request.query can contain string | string[] for repeated params\n const queryParams = normalizeQueryParams((request.query || {}) as Record<string, unknown>);\n let body: unknown;\n let bodyParseError: { message: string } | undefined;\n\n if (route.method === 'POST' || route.method === 'PUT' || route.method === 'PATCH' || route.method === 'DELETE') {\n const contentType = request.headers['content-type'] || '';\n\n if (contentType.includes('multipart/form-data')) {\n try {\n const maxFileSize = route.maxBodySize ?? this.bodyLimitOptions?.maxSize;\n body = await this.parseMultipartFormData(request, maxFileSize);\n } catch (error) {\n this.mastra.getLogger()?.error('Failed to parse multipart form data', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n // Re-throw size limit errors, let others fall through to validation\n if (error instanceof Error && error.message.toLowerCase().includes('size')) {\n throw error;\n }\n bodyParseError = {\n message: error instanceof Error ? error.message : 'Failed to parse multipart form data',\n };\n }\n } else {\n body = request.body;\n }\n }\n\n return { urlParams, queryParams, body, bodyParseError };\n }\n\n /**\n * Parse multipart/form-data using @fastify/busboy.\n * Converts file uploads to Buffers and parses JSON field values.\n *\n * @param request - The Fastify request object\n * @param maxFileSize - Optional maximum file size in bytes\n */\n private parseMultipartFormData(request: FastifyRequest, maxFileSize?: number): Promise<Record<string, unknown>> {\n return new Promise((resolve, reject) => {\n const result: Record<string, unknown> = {};\n\n const busboy = new Busboy({\n headers: {\n 'content-type': request.headers['content-type'] as string,\n },\n limits: maxFileSize ? { fileSize: maxFileSize } : undefined,\n });\n\n busboy.on(\n 'file',\n (fieldname: string, file: NodeJS.ReadableStream, _filename: string, _encoding: string, _mimetype: string) => {\n const chunks: Buffer[] = [];\n let limitExceeded = false;\n\n file.on('data', (chunk: Buffer) => {\n chunks.push(chunk);\n });\n\n file.on('limit', () => {\n limitExceeded = true;\n file.resume();\n reject(new Error(`File size limit exceeded${maxFileSize ? ` (max: ${maxFileSize} bytes)` : ''}`));\n });\n\n file.on('end', () => {\n if (!limitExceeded) {\n result[fieldname] = Buffer.concat(chunks);\n }\n });\n },\n );\n\n busboy.on('field', (fieldname: string, value: string) => {\n // Try to parse JSON strings (like 'options')\n try {\n result[fieldname] = JSON.parse(value);\n } catch {\n result[fieldname] = value;\n }\n });\n\n busboy.on('finish', () => {\n resolve(result);\n });\n\n busboy.on('error', (error: Error) => {\n reject(error);\n });\n\n // Pipe the raw request to busboy\n request.raw.pipe(busboy);\n });\n }\n\n async sendResponse(\n route: ServerRoute,\n reply: FastifyReply,\n result: unknown,\n request?: FastifyRequest,\n prefix?: string,\n ): Promise<void> {\n const resolvedPrefix = prefix ?? this.prefix ?? '';\n\n // Apply refresh headers from transparent session refresh (e.g. Set-Cookie after token refresh)\n if (result && typeof result === 'object' && '__refreshHeaders' in result) {\n const refreshHeaders = (result as any).__refreshHeaders as Record<string, string>;\n for (const [key, value] of Object.entries(refreshHeaders)) {\n reply.header(key, value);\n }\n delete (result as any).__refreshHeaders;\n }\n\n if (route.responseType === 'json') {\n await reply.send(result);\n } else if (route.responseType === 'stream') {\n await this.stream(route, reply, result as { fullStream: ReadableStream }, request);\n } else if (route.responseType === 'datastream-response') {\n // Handle AI SDK Response objects - pipe Response.body to Fastify response\n const fetchResponse = result as globalThis.Response;\n fetchResponse.headers.forEach((value, key) => reply.header(key, value));\n reply.status(fetchResponse.status);\n if (fetchResponse.body) {\n const reader = fetchResponse.body.getReader();\n let readerCanceled = false;\n\n const cancelReader = (reason: string) => {\n if (readerCanceled) return;\n readerCanceled = true;\n void reader.cancel(reason);\n };\n\n const cancelReaderOnResponseClose = () => cancelReader('request aborted');\n const cancelReaderOnRequestClose = () => {\n if (request && isRequestAborted(request.raw)) {\n cancelReader('request aborted');\n }\n };\n\n const onResError = (err: unknown) => {\n this.mastra.getLogger()?.error('Error writing datastream response', {\n error: err instanceof Error ? { message: err.message, stack: err.stack } : err,\n });\n cancelReader('response write error');\n };\n reply.raw.once('error', onResError);\n reply.raw.on('close', cancelReaderOnResponseClose);\n request?.raw.on('close', cancelReaderOnRequestClose);\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n reply.raw.write(value);\n }\n } catch (error) {\n this.mastra.getLogger()?.error('Error in datastream processing', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n } finally {\n reply.raw.off('error', onResError);\n reply.raw.off('close', cancelReaderOnResponseClose);\n request?.raw.off('close', cancelReaderOnRequestClose);\n if (!reply.raw.writableEnded && !reply.raw.destroyed) {\n reply.raw.end();\n }\n }\n } else {\n reply.raw.end();\n }\n } else if (route.responseType === 'mcp-http') {\n // MCP Streamable HTTP transport - request is required\n if (!request) {\n await reply.status(500).send({ error: 'Request object required for MCP transport' });\n return;\n }\n\n const { server, httpPath, mcpOptions: routeMcpOptions } = result as MCPHttpTransportResult;\n\n try {\n // Hijack the response to bypass Fastify's response handling\n // This is required when we write directly to reply.raw\n reply.hijack();\n\n // Attach parsed body to raw request so MCP server's readJsonBody can use it\n // Fastify consumes the body stream, so we need to provide the pre-parsed body\n const rawReq = request.raw as typeof request.raw & { body?: unknown };\n if (request.body !== undefined) {\n rawReq.body = request.body;\n }\n\n // Merge class-level mcpOptions with route-specific options (route takes precedence)\n const options = { ...this.mcpOptions, ...routeMcpOptions };\n\n await server.startHTTP({\n url: new URL(request.url, `http://${request.headers.host}`),\n httpPath: `${resolvedPrefix}${httpPath}`,\n req: rawReq,\n res: reply.raw,\n options: Object.keys(options).length > 0 ? options : undefined,\n });\n // Response handled by startHTTP\n } catch {\n if (!reply.raw.headersSent) {\n reply.raw.writeHead(500, { 'Content-Type': 'application/json' });\n reply.raw.end(\n JSON.stringify({\n jsonrpc: '2.0',\n error: { code: -32603, message: 'Internal server error' },\n id: null,\n }),\n );\n }\n }\n } else if (route.responseType === 'mcp-sse') {\n // MCP SSE transport - request is required\n if (!request) {\n await reply.status(500).send({ error: 'Request object required for MCP transport' });\n return;\n }\n\n const { server, ssePath, messagePath } = result as MCPSseTransportResult;\n\n try {\n // Hijack the response to bypass Fastify's response handling\n // This is required when we write directly to reply.raw for SSE\n reply.hijack();\n\n // Attach parsed body to raw request so MCP server's readJsonBody can use it\n // Fastify consumes the body stream, so we need to provide the pre-parsed body\n const rawReq = request.raw as typeof request.raw & { body?: unknown };\n if (request.body !== undefined) {\n rawReq.body = request.body;\n }\n\n await server.startSSE({\n url: new URL(request.url, `http://${request.headers.host}`),\n ssePath: `${resolvedPrefix}${ssePath}`,\n messagePath: `${resolvedPrefix}${messagePath}`,\n req: rawReq,\n res: reply.raw,\n });\n // Response handled by startSSE\n } catch {\n if (!reply.raw.headersSent) {\n reply.raw.writeHead(500, { 'Content-Type': 'application/json' });\n reply.raw.end(JSON.stringify({ error: 'Error handling MCP SSE request' }));\n }\n }\n } else {\n reply.status(500);\n }\n }\n\n async registerRoute(\n app: FastifyInstance,\n route: ServerRoute,\n { prefix: prefixParam }: { prefix?: string } = {},\n ): Promise<void> {\n // Default prefix to this.prefix if not provided, or empty string\n const prefix = prefixParam ?? this.prefix ?? '';\n\n const fullPath = `${prefix}${route.path}`;\n\n // Convert Express-style :param to Fastify-style :param (they're the same, but ensure consistency)\n const fastifyPath = fullPath;\n\n // Define the route handler\n const handler: RouteHandlerMethod = async (request: FastifyRequest, reply: FastifyReply) => {\n // Check route-level authentication/authorization\n const authError = await this.checkRouteAuth(route, {\n path: String(request.url.split('?')[0] || '/'),\n method: String(request.method || 'GET'),\n getHeader: name => request.headers[name.toLowerCase()] as string | undefined,\n getQuery: name => (request.query as Record<string, string>)[name],\n requestContext: request.requestContext,\n request: toWebRequest(request),\n buildAuthorizeContext: () => toWebRequest(request),\n });\n\n if (authError) {\n // Apply any refresh headers (e.g. Set-Cookie from transparent session refresh)\n if (authError.headers) {\n for (const [key, value] of Object.entries(authError.headers)) {\n void reply.header(key, value);\n }\n }\n\n // If this is an auth error (not just a success-with-headers), return error response\n if (authError.error) {\n return reply.status(authError.status).send({ error: authError.error });\n }\n }\n\n const params = await this.getParams(route, request);\n\n // Return 400 Bad Request if body parsing failed (e.g., malformed multipart data)\n if (params.bodyParseError) {\n return reply.status(400).send({\n error: 'Invalid request body',\n issues: [{ field: 'body', message: params.bodyParseError.message }],\n });\n }\n\n if (params.queryParams) {\n try {\n params.queryParams = await this.parseQueryParams(route, params.queryParams);\n } catch (error) {\n this.mastra.getLogger()?.error('Error parsing query params', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n if (isZodError(error)) {\n const { status, body } = this.resolveValidationError(route, error, 'query');\n return reply.status(status).send(body);\n }\n return reply.status(400).send({\n error: 'Invalid query parameters',\n issues: [{ field: 'unknown', message: error instanceof Error ? error.message : 'Unknown error' }],\n });\n }\n }\n\n if (params.body) {\n try {\n params.body = await this.parseBody(route, params.body);\n } catch (error) {\n this.mastra.getLogger()?.error('Error parsing body', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n if (isZodError(error)) {\n const { status, body } = this.resolveValidationError(route, error, 'body');\n return reply.status(status).send(body);\n }\n return reply.status(400).send({\n error: 'Invalid request body',\n issues: [{ field: 'unknown', message: error instanceof Error ? error.message : 'Unknown error' }],\n });\n }\n }\n\n // Parse path params through pathParamSchema for type coercion (e.g., z.coerce.number())\n if (params.urlParams) {\n try {\n params.urlParams = await this.parsePathParams(route, params.urlParams);\n } catch (error) {\n this.mastra.getLogger()?.error('Error parsing path params', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n if (isZodError(error)) {\n const { status, body } = this.resolveValidationError(route, error, 'path');\n return reply.status(status).send(body);\n }\n return reply.status(400).send({\n error: 'Invalid path parameters',\n issues: [{ field: 'unknown', message: error instanceof Error ? error.message : 'Unknown error' }],\n });\n }\n }\n\n const handlerParams = {\n ...params.urlParams,\n ...params.queryParams,\n ...(typeof params.body === 'object' ? params.body : {}),\n requestContext: request.requestContext,\n mastra: this.mastra,\n registeredTools: request.registeredTools,\n taskStore: request.taskStore,\n abortSignal: request.abortSignal,\n routePrefix: prefix,\n };\n\n // Check route permission requirement (EE feature)\n // Uses convention-based permission derivation: permissions are auto-derived\n // from route path/method unless explicitly set or route is public\n const authConfig = this.mastra.getServer()?.auth;\n if (authConfig) {\n const hasPermission = await loadHasPermission();\n if (hasPermission) {\n const userPermissions = request.requestContext.get('mastra__userPermissions') as string[] | undefined;\n const permissionError = this.checkRoutePermission(route, userPermissions, hasPermission);\n\n if (permissionError) {\n return reply.status(permissionError.status).send({\n error: permissionError.error,\n message: permissionError.message,\n });\n }\n }\n }\n\n // Check FGA authorization (EE feature)\n const fgaError = await checkRouteFGA(this.mastra, route, request.requestContext, {\n ...params.urlParams,\n ...params.queryParams,\n ...(typeof params.body === 'object' ? params.body : {}),\n });\n if (fgaError) {\n return reply.status(fgaError.status).send({ error: fgaError.error, message: fgaError.message });\n }\n\n try {\n const result = await route.handler(handlerParams);\n await this.sendResponse(route, reply, result, request, prefix);\n } catch (error) {\n this.mastra.getLogger()?.error('Error calling handler', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n path: route.path,\n method: route.method,\n });\n // Check if it's an HTTPException or MastraError with a status code\n let status = 500;\n if (error && typeof error === 'object') {\n // Check for direct status property (HTTPException)\n if ('status' in error) {\n status = (error as any).status;\n }\n // Check for MastraError with status in details\n else if (\n 'details' in error &&\n error.details &&\n typeof error.details === 'object' &&\n 'status' in error.details\n ) {\n status = (error.details as any).status;\n }\n }\n await reply.status(status).send({ error: error instanceof Error ? error.message : 'Unknown error' });\n }\n };\n\n // Add body limit if configured\n const shouldApplyBodyLimit = this.bodyLimitOptions && ['POST', 'PUT', 'PATCH'].includes(route.method.toUpperCase());\n const maxSize = route.maxBodySize ?? this.bodyLimitOptions?.maxSize;\n\n const config = shouldApplyBodyLimit && maxSize ? { bodyLimit: maxSize } : undefined;\n\n // Handle ALL method by registering for each HTTP method\n // Fastify doesn't support 'ALL' method natively like Express\n if (route.method.toUpperCase() === 'ALL') {\n // Only register the main HTTP methods that MCP actually uses\n // Skip HEAD/OPTIONS to avoid potential conflicts with Fastify's auto-generated routes\n const methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'] as const;\n for (const method of methods) {\n try {\n app.route({\n method,\n url: fastifyPath,\n handler,\n config,\n });\n } catch (err) {\n // Skip duplicate route errors - can happen if route is registered multiple times\n if (err instanceof Error && err.message.includes('already declared')) {\n continue;\n }\n throw err;\n }\n }\n } else {\n app.route({\n method: route.method as 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',\n url: fastifyPath,\n handler,\n config,\n });\n }\n }\n\n async registerCustomApiRoutes(): Promise<void> {\n if (!(await this.buildCustomRouteHandler())) return;\n\n const routes = this.customApiRoutes ?? this.mastra.getServer()?.apiRoutes ?? [];\n\n for (const route of routes) {\n // Create pseudo ServerRoute for auth checking\n const serverRoute: ServerRoute = {\n method: route.method as any,\n path: route.path,\n responseType: 'json',\n handler: async () => {},\n requiresAuth: route.requiresAuth,\n requiresPermission: route.requiresPermission,\n fga: route.fga,\n };\n\n const fastifyHandler: RouteHandlerMethod = async (request: FastifyRequest, reply: FastifyReply) => {\n // Per-route auth check (same pattern as registerRoute)\n const authError = await this.checkRouteAuth(serverRoute, {\n path: String(request.url.split('?')[0] || '/'),\n method: String(request.method || 'GET'),\n getHeader: name => request.headers[name.toLowerCase()] as string | undefined,\n getQuery: name => (request.query as Record<string, string>)[name],\n requestContext: request.requestContext,\n request: toWebRequest(request),\n buildAuthorizeContext: () => toWebRequest(request),\n });\n\n if (authError) {\n if (authError.headers) {\n for (const [key, value] of Object.entries(authError.headers)) {\n void reply.header(key, value);\n }\n }\n if (authError.error) {\n return reply.status(authError.status).send({ error: authError.error });\n }\n }\n\n const authConfig = this.mastra.getServer()?.auth;\n if (authConfig) {\n let hasPermission: ((userPerms: string[], required: string) => boolean) | undefined;\n try {\n ({ hasPermission } = await import('@mastra/core/auth/ee'));\n } catch {\n console.error(\n '[@mastra/fastify] Auth features require @mastra/core >= 1.6.0. Please upgrade: npm install @mastra/core@latest',\n );\n }\n\n if (hasPermission) {\n const userPermissions = request.requestContext.get('mastra__userPermissions') as string[] | undefined;\n const permissionError = this.checkRoutePermission(serverRoute, userPermissions, hasPermission);\n if (permissionError) {\n return reply.status(permissionError.status).send({\n error: permissionError.error,\n message: permissionError.message,\n });\n }\n }\n }\n\n // Check FGA authorization (EE feature)\n const fgaError = await checkRouteFGA(this.mastra, serverRoute, request.requestContext, {\n ...(request.params as Record<string, string>),\n ...(request.query as Record<string, string>),\n ...(typeof request.body === 'object' && request.body !== null\n ? (request.body as Record<string, unknown>)\n : {}),\n });\n if (fgaError) {\n return reply.status(fgaError.status).send({ error: fgaError.error, message: fgaError.message });\n }\n\n const response = await this.handleCustomRouteRequest(\n `http://${request.headers.host}${request.url}`,\n request.method,\n request.headers as Record<string, string | string[] | undefined>,\n request.body,\n request.requestContext,\n request.abortSignal,\n );\n if (!response) {\n reply.status(404).send({ error: 'Not Found' });\n return;\n }\n reply.hijack();\n await this.writeCustomRouteResponse(response, reply.raw, request.abortSignal);\n };\n\n if (route.method === 'ALL') {\n const methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'] as const;\n for (const method of methods) {\n this.app.route({ method, url: route.path, handler: fastifyHandler });\n }\n } else {\n this.app.route({\n method: route.method as 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',\n url: route.path,\n handler: fastifyHandler,\n });\n }\n }\n }\n\n registerContextMiddleware(): void {\n // Override the default JSON parser to allow empty bodies\n // This matches Express behavior where empty POST requests with Content-Type: application/json are allowed\n this.app.removeContentTypeParser('application/json');\n this.app.addContentTypeParser('application/json', { parseAs: 'string' }, (_request, body, done) => {\n try {\n // Allow empty body\n if (!body || (typeof body === 'string' && body.trim() === '')) {\n done(null, undefined);\n return;\n }\n const parsed = JSON.parse(body as string);\n done(null, parsed);\n } catch (err) {\n done(err as Error, undefined);\n }\n });\n\n // Register content type parser for multipart/form-data\n // This allows Fastify to accept multipart requests without parsing them\n // We'll parse them manually in getParams using busboy\n this.app.addContentTypeParser('multipart/form-data', (_request, _payload, done) => {\n // Don't parse the body, we'll handle it manually with busboy\n done(null, undefined);\n });\n\n this.app.addHook('preHandler', this.createContextMiddleware());\n }\n\n registerAuthMiddleware(): void {\n // Auth is handled per-route in registerRoute() and registerCustomApiRoutes()\n // No global middleware needed\n }\n\n registerHttpLoggingMiddleware(): void {\n if (!this.httpLoggingConfig?.enabled) {\n return;\n }\n\n this.app.addHook('onRequest', async (request: FastifyRequest, reply: FastifyReply) => {\n const urlPath = request.url.split('?')[0]!;\n if (!this.shouldLogRequest(urlPath)) {\n return;\n }\n\n const start = Date.now();\n const method = request.method;\n const path = urlPath;\n\n reply.raw.once('finish', () => {\n const duration = Date.now() - start;\n const status = reply.statusCode;\n const level = this.httpLoggingConfig?.level || 'info';\n\n const logData: Record<string, any> = {\n method,\n path,\n status,\n duration: `${duration}ms`,\n };\n\n if (this.httpLoggingConfig?.includeQueryParams) {\n logData.query = request.query;\n }\n\n if (this.httpLoggingConfig?.includeHeaders) {\n const headers = { ...request.headers };\n const redactHeaders = this.httpLoggingConfig.redactHeaders || [];\n redactHeaders.forEach((h: string) => {\n const key = h.toLowerCase();\n if (headers[key] !== undefined) {\n headers[key] = '[REDACTED]';\n }\n });\n logData.headers = headers;\n }\n\n this.logger[level](`${method} ${path} ${status} ${duration}ms`, logData);\n });\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/auth-middleware.ts","../src/index.ts"],"names":["toWebRequest","MastraServerBase"],"mappings":"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","file":"index.js","sourcesContent":["import type { Mastra } from '@mastra/core/mastra';\nimport { RequestContext } from '@mastra/core/request-context';\nimport { coreAuthMiddleware } from '@mastra/server/auth';\nimport type { FastifyReply, FastifyRequest, preHandlerHookHandler } from 'fastify';\n\nexport interface FastifyAuthMiddlewareOptions {\n mastra: Mastra;\n requiresAuth?: boolean;\n}\n\nfunction toWebRequest(request: FastifyRequest): globalThis.Request {\n const protocol = request.protocol || 'http';\n const host = request.headers.host || 'localhost';\n const url = `${protocol}://${host}${request.url}`;\n\n const headers = new Headers();\n for (const [key, value] of Object.entries(request.headers)) {\n if (!value) continue;\n if (Array.isArray(value)) {\n value.forEach(v => headers.append(key, v));\n } else {\n headers.set(key, value);\n }\n }\n\n return new globalThis.Request(url, {\n method: request.method,\n headers,\n });\n}\n\nexport function createAuthMiddleware({\n mastra,\n requiresAuth = true,\n}: FastifyAuthMiddlewareOptions): preHandlerHookHandler {\n return async (request: FastifyRequest, reply: FastifyReply) => {\n if (!requiresAuth) {\n return;\n }\n\n const authConfig = mastra.getServer()?.auth;\n if (!authConfig) {\n return;\n }\n\n request.requestContext ??= new RequestContext();\n request.mastra ??= mastra;\n\n const path = String(request.url.split('?')[0] || '/');\n const method = String(request.method || 'GET');\n const customRouteAuthConfig = new Map<string, boolean>(request.customRouteAuthConfig ?? []);\n customRouteAuthConfig.set(`${method}:${path}`, true);\n\n const authHeader = request.headers.authorization;\n let token: string | null = authHeader ? authHeader.replace('Bearer ', '') : null;\n const query = request.query as Record<string, string>;\n if (!token && query.apiKey) {\n token = query.apiKey || null;\n }\n\n const result = await coreAuthMiddleware({\n path,\n method,\n getHeader: name => request.headers[name.toLowerCase()] as string | undefined,\n mastra,\n authConfig,\n customRouteAuthConfig,\n requestContext: request.requestContext,\n rawRequest: toWebRequest(request),\n token,\n buildAuthorizeContext: () => toWebRequest(request),\n });\n\n if (result.action === 'error') {\n return reply.status(result.status).send(result.body);\n }\n };\n}\n","import { Busboy } from '@fastify/busboy';\nimport type { ToolsInput } from '@mastra/core/agent';\nimport type { Mastra } from '@mastra/core/mastra';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport type { InMemoryTaskStore } from '@mastra/server/a2a/store';\nimport type { MCPHttpTransportResult, MCPSseTransportResult } from '@mastra/server/handlers/mcp';\nimport type { ParsedRequestParams, ServerRoute } from '@mastra/server/server-adapter';\nimport {\n MastraServer as MastraServerBase,\n checkRouteFGA,\n isZodError,\n normalizeQueryParams,\n redactStreamChunk,\n} from '@mastra/server/server-adapter';\nimport type { FastifyInstance, FastifyReply, FastifyRequest, preHandlerHookHandler, RouteHandlerMethod } from 'fastify';\nexport { createAuthMiddleware } from './auth-middleware';\nexport type { FastifyAuthMiddlewareOptions } from './auth-middleware';\n\ntype HasPermissionFn = (userPerms: string[], required: string) => boolean;\nlet _hasPermissionPromise: Promise<HasPermissionFn | undefined> | undefined;\nfunction loadHasPermission(): Promise<HasPermissionFn | undefined> {\n if (!_hasPermissionPromise) {\n _hasPermissionPromise = import('@mastra/core/auth/ee')\n .then(m => m.hasPermission)\n .catch(() => {\n console.error(\n '[@mastra/fastify] Auth features require @mastra/core >= 1.6.0. Please upgrade: npm install @mastra/core@latest',\n );\n return undefined;\n });\n }\n return _hasPermissionPromise;\n}\n\n/**\n * Convert Fastify request to Web API Request for cookie-based auth providers.\n */\nfunction toWebRequest(request: FastifyRequest): globalThis.Request {\n const protocol = request.protocol || 'http';\n const host = request.headers.host || 'localhost';\n const url = `${protocol}://${host}${request.url}`;\n\n const headers = new Headers();\n for (const [key, value] of Object.entries(request.headers)) {\n if (value) {\n if (Array.isArray(value)) {\n value.forEach(v => headers.append(key, v));\n } else {\n headers.set(key, value);\n }\n }\n }\n\n return new globalThis.Request(url, {\n method: request.method,\n headers,\n });\n}\n\nfunction isRequestAborted(rawRequest: FastifyRequest['raw']): boolean {\n // Fastify can emit request close after a POST body is fully consumed while\n // the response stream is still active, so only treat it as disconnect when\n // the request itself reports an abort or never completed.\n return rawRequest.aborted || rawRequest.readableAborted || !rawRequest.complete;\n}\n\n// Extend Fastify types to include Mastra context\ndeclare module 'fastify' {\n interface FastifyRequest {\n mastra: Mastra;\n requestContext: RequestContext;\n registeredTools: ToolsInput;\n abortSignal: AbortSignal;\n taskStore: InMemoryTaskStore;\n customRouteAuthConfig?: Map<string, boolean>;\n }\n}\n\nexport class MastraServer extends MastraServerBase<FastifyInstance, FastifyRequest, FastifyReply> {\n createContextMiddleware(): preHandlerHookHandler {\n return async (request: FastifyRequest, reply: FastifyReply) => {\n // Parse request context from request body and add to context\n let bodyRequestContext: Record<string, any> | undefined;\n let paramsRequestContext: Record<string, any> | undefined;\n\n // Parse request context from request body (POST/PUT)\n if (request.method === 'POST' || request.method === 'PUT') {\n const contentType = request.headers['content-type'];\n if (contentType?.includes('application/json') && request.body) {\n const body = request.body as { requestContext?: Record<string, any> };\n if (body.requestContext) {\n bodyRequestContext = body.requestContext;\n }\n }\n }\n\n // Parse request context from query params (GET)\n if (request.method === 'GET') {\n try {\n const query = request.query as Record<string, string>;\n const encodedRequestContext = query.requestContext;\n if (typeof encodedRequestContext === 'string') {\n // Try JSON first\n try {\n paramsRequestContext = JSON.parse(encodedRequestContext);\n } catch {\n // Fallback to base64(JSON)\n try {\n const json = Buffer.from(encodedRequestContext, 'base64').toString('utf-8');\n paramsRequestContext = JSON.parse(json);\n } catch {\n // ignore if still invalid\n }\n }\n }\n } catch {\n // ignore query parsing errors\n }\n }\n\n const requestContext = this.mergeRequestContext({ paramsRequestContext, bodyRequestContext });\n this.applyRequestMetadataToContext({\n requestContext,\n getHeader: name => {\n const value = request.headers[name.toLowerCase()];\n return Array.isArray(value) ? value[0] : value;\n },\n });\n\n // Set context in request object\n request.requestContext = requestContext;\n request.mastra = this.mastra;\n request.registeredTools = this.tools || {};\n if (this.taskStore) {\n request.taskStore = this.taskStore;\n }\n request.customRouteAuthConfig = this.customRouteAuthConfig;\n\n // Create abort controller for request cancellation\n const controller = new AbortController();\n request.raw.on('close', () => {\n if (isRequestAborted(request.raw)) {\n controller.abort();\n }\n });\n reply.raw.on('close', () => {\n // Response close fires for normal completion too; only abort if the\n // response did not finish successfully.\n if (!reply.raw.writableEnded) {\n controller.abort();\n }\n });\n request.abortSignal = controller.signal;\n };\n }\n\n async stream(\n route: ServerRoute,\n reply: FastifyReply,\n result: { fullStream: ReadableStream },\n request?: FastifyRequest,\n ): Promise<void> {\n // Capture headers set by plugins (e.g., @fastify/cors) BEFORE hijacking\n // reply.hijack() bypasses Fastify's response handling, so we need to preserve\n // any headers that were set by hooks/plugins and manually include them\n const rawHeaders = reply.getHeaders();\n // Filter out undefined values and conflicting headers (content-length, transfer-encoding)\n // Having both Content-Length and Transfer-Encoding: chunked violates RFC 7230\n const existingHeaders: Record<string, string | number | string[]> = {};\n for (const [key, value] of Object.entries(rawHeaders)) {\n if (value === undefined) continue;\n const lowerKey = key.toLowerCase();\n if (lowerKey === 'content-length' || lowerKey === 'transfer-encoding') continue;\n existingHeaders[key] = value;\n }\n\n // Hijack the reply to take control of the response\n // This is required when writing directly to reply.raw\n reply.hijack();\n\n const streamFormat = route.streamFormat || 'stream';\n\n // Write headers directly to the raw response, merging existing headers (like CORS)\n // with our stream-specific headers\n const sseHeaders =\n streamFormat === 'sse'\n ? {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n 'X-Accel-Buffering': 'no',\n }\n : {\n 'Content-Type': 'text/plain',\n };\n\n reply.raw.writeHead(200, {\n ...existingHeaders,\n ...sseHeaders,\n 'Transfer-Encoding': 'chunked',\n });\n\n if (streamFormat === 'sse' && route.sseFlushOnConnect) {\n reply.raw.write(': connected\\n\\n');\n }\n\n const readableStream = result instanceof ReadableStream ? result : result.fullStream;\n const reader = readableStream.getReader();\n\n let readerCanceled = false;\n const cancelReader = (reason: string) => {\n if (readerCanceled) return;\n readerCanceled = true;\n void reader.cancel(reason);\n };\n const cancelReaderOnResponseClose = () => cancelReader('request aborted');\n const cancelReaderOnRequestClose = () => {\n if (request && isRequestAborted(request.raw)) {\n cancelReader('request aborted');\n }\n };\n reply.raw.on('close', cancelReaderOnResponseClose);\n request?.raw.on('close', cancelReaderOnRequestClose);\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n if (value) {\n if (streamFormat === 'sse' && typeof value === 'string' && value.startsWith(':')) {\n reply.raw.write(value);\n continue;\n }\n\n // Optionally redact sensitive data (system prompts, tool definitions, API keys) before sending to the client\n const shouldRedact = this.streamOptions?.redact ?? true;\n const outputValue = shouldRedact ? redactStreamChunk(value) : value;\n if (streamFormat === 'sse') {\n reply.raw.write(`data: ${JSON.stringify(outputValue)}\\n\\n`);\n } else {\n reply.raw.write(JSON.stringify(outputValue) + '\\x1E');\n }\n }\n }\n } catch (error) {\n this.mastra.getLogger()?.error('Error in stream processing', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n } finally {\n reply.raw.off('close', cancelReaderOnResponseClose);\n request?.raw.off('close', cancelReaderOnRequestClose);\n if (!reply.raw.writableEnded && !reply.raw.destroyed) {\n reply.raw.end();\n }\n }\n }\n\n async getParams(route: ServerRoute, request: FastifyRequest): Promise<ParsedRequestParams> {\n const urlParams = (request.params || {}) as Record<string, string>;\n // Fastify's request.query can contain string | string[] for repeated params\n const queryParams = normalizeQueryParams((request.query || {}) as Record<string, unknown>);\n let body: unknown;\n let bodyParseError: { message: string } | undefined;\n\n if (route.method === 'POST' || route.method === 'PUT' || route.method === 'PATCH' || route.method === 'DELETE') {\n const contentType = request.headers['content-type'] || '';\n\n if (contentType.includes('multipart/form-data')) {\n try {\n const maxFileSize = route.maxBodySize ?? this.bodyLimitOptions?.maxSize;\n body = await this.parseMultipartFormData(request, maxFileSize);\n } catch (error) {\n this.mastra.getLogger()?.error('Failed to parse multipart form data', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n // Re-throw size limit errors, let others fall through to validation\n if (error instanceof Error && error.message.toLowerCase().includes('size')) {\n throw error;\n }\n bodyParseError = {\n message: error instanceof Error ? error.message : 'Failed to parse multipart form data',\n };\n }\n } else {\n body = request.body;\n }\n }\n\n return { urlParams, queryParams, body, bodyParseError };\n }\n\n /**\n * Parse multipart/form-data using @fastify/busboy.\n * Converts file uploads to Buffers and parses JSON field values.\n *\n * @param request - The Fastify request object\n * @param maxFileSize - Optional maximum file size in bytes\n */\n private parseMultipartFormData(request: FastifyRequest, maxFileSize?: number): Promise<Record<string, unknown>> {\n return new Promise((resolve, reject) => {\n const result: Record<string, unknown> = {};\n\n const busboy = new Busboy({\n headers: {\n 'content-type': request.headers['content-type'] as string,\n },\n limits: maxFileSize ? { fileSize: maxFileSize } : undefined,\n });\n\n busboy.on(\n 'file',\n (fieldname: string, file: NodeJS.ReadableStream, _filename: string, _encoding: string, _mimetype: string) => {\n const chunks: Buffer[] = [];\n let limitExceeded = false;\n\n file.on('data', (chunk: Buffer) => {\n chunks.push(chunk);\n });\n\n file.on('limit', () => {\n limitExceeded = true;\n file.resume();\n reject(new Error(`File size limit exceeded${maxFileSize ? ` (max: ${maxFileSize} bytes)` : ''}`));\n });\n\n file.on('end', () => {\n if (!limitExceeded) {\n result[fieldname] = Buffer.concat(chunks);\n }\n });\n },\n );\n\n busboy.on('field', (fieldname: string, value: string) => {\n // Try to parse JSON strings (like 'options')\n try {\n result[fieldname] = JSON.parse(value);\n } catch {\n result[fieldname] = value;\n }\n });\n\n busboy.on('finish', () => {\n resolve(result);\n });\n\n busboy.on('error', (error: Error) => {\n reject(error);\n });\n\n // Pipe the raw request to busboy\n request.raw.pipe(busboy);\n });\n }\n\n async sendResponse(\n route: ServerRoute,\n reply: FastifyReply,\n result: unknown,\n request?: FastifyRequest,\n prefix?: string,\n ): Promise<void> {\n const resolvedPrefix = prefix ?? this.prefix ?? '';\n\n // Apply refresh headers from transparent session refresh (e.g. Set-Cookie after token refresh)\n if (result && typeof result === 'object' && '__refreshHeaders' in result) {\n const refreshHeaders = (result as any).__refreshHeaders as Record<string, string>;\n for (const [key, value] of Object.entries(refreshHeaders)) {\n reply.header(key, value);\n }\n delete (result as any).__refreshHeaders;\n }\n\n if (route.responseType === 'json') {\n await reply.send(result);\n } else if (route.responseType === 'stream') {\n await this.stream(route, reply, result as { fullStream: ReadableStream }, request);\n } else if (route.responseType === 'datastream-response') {\n // Handle AI SDK Response objects - pipe Response.body to Fastify response\n const fetchResponse = result as globalThis.Response;\n fetchResponse.headers.forEach((value, key) => reply.header(key, value));\n reply.status(fetchResponse.status);\n if (fetchResponse.body) {\n const reader = fetchResponse.body.getReader();\n let readerCanceled = false;\n\n const cancelReader = (reason: string) => {\n if (readerCanceled) return;\n readerCanceled = true;\n void reader.cancel(reason);\n };\n\n const cancelReaderOnResponseClose = () => cancelReader('request aborted');\n const cancelReaderOnRequestClose = () => {\n if (request && isRequestAborted(request.raw)) {\n cancelReader('request aborted');\n }\n };\n\n const onResError = (err: unknown) => {\n this.mastra.getLogger()?.error('Error writing datastream response', {\n error: err instanceof Error ? { message: err.message, stack: err.stack } : err,\n });\n cancelReader('response write error');\n };\n reply.raw.once('error', onResError);\n reply.raw.on('close', cancelReaderOnResponseClose);\n request?.raw.on('close', cancelReaderOnRequestClose);\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n reply.raw.write(value);\n }\n } catch (error) {\n this.mastra.getLogger()?.error('Error in datastream processing', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n } finally {\n reply.raw.off('error', onResError);\n reply.raw.off('close', cancelReaderOnResponseClose);\n request?.raw.off('close', cancelReaderOnRequestClose);\n if (!reply.raw.writableEnded && !reply.raw.destroyed) {\n reply.raw.end();\n }\n }\n } else {\n reply.raw.end();\n }\n } else if (route.responseType === 'mcp-http') {\n // MCP Streamable HTTP transport - request is required\n if (!request) {\n await reply.status(500).send({ error: 'Request object required for MCP transport' });\n return;\n }\n\n const { server, httpPath, mcpOptions: routeMcpOptions } = result as MCPHttpTransportResult;\n\n try {\n // Hijack the response to bypass Fastify's response handling\n // This is required when we write directly to reply.raw\n reply.hijack();\n\n // Attach parsed body to raw request so MCP server's readJsonBody can use it\n // Fastify consumes the body stream, so we need to provide the pre-parsed body\n const rawReq = request.raw as typeof request.raw & { body?: unknown };\n if (request.body !== undefined) {\n rawReq.body = request.body;\n }\n\n // Merge class-level mcpOptions with route-specific options (route takes precedence)\n const options = { ...this.mcpOptions, ...routeMcpOptions };\n\n await server.startHTTP({\n url: new URL(request.url, `http://${request.headers.host}`),\n httpPath: `${resolvedPrefix}${httpPath}`,\n req: rawReq,\n res: reply.raw,\n options: Object.keys(options).length > 0 ? options : undefined,\n });\n // Response handled by startHTTP\n } catch {\n if (!reply.raw.headersSent) {\n reply.raw.writeHead(500, { 'Content-Type': 'application/json' });\n reply.raw.end(\n JSON.stringify({\n jsonrpc: '2.0',\n error: { code: -32603, message: 'Internal server error' },\n id: null,\n }),\n );\n }\n }\n } else if (route.responseType === 'mcp-sse') {\n // MCP SSE transport - request is required\n if (!request) {\n await reply.status(500).send({ error: 'Request object required for MCP transport' });\n return;\n }\n\n const { server, ssePath, messagePath } = result as MCPSseTransportResult;\n\n try {\n // Hijack the response to bypass Fastify's response handling\n // This is required when we write directly to reply.raw for SSE\n reply.hijack();\n\n // Attach parsed body to raw request so MCP server's readJsonBody can use it\n // Fastify consumes the body stream, so we need to provide the pre-parsed body\n const rawReq = request.raw as typeof request.raw & { body?: unknown };\n if (request.body !== undefined) {\n rawReq.body = request.body;\n }\n\n await server.startSSE({\n url: new URL(request.url, `http://${request.headers.host}`),\n ssePath: `${resolvedPrefix}${ssePath}`,\n messagePath: `${resolvedPrefix}${messagePath}`,\n req: rawReq,\n res: reply.raw,\n });\n // Response handled by startSSE\n } catch {\n if (!reply.raw.headersSent) {\n reply.raw.writeHead(500, { 'Content-Type': 'application/json' });\n reply.raw.end(JSON.stringify({ error: 'Error handling MCP SSE request' }));\n }\n }\n } else {\n reply.status(500);\n }\n }\n\n async registerRoute(\n app: FastifyInstance,\n route: ServerRoute,\n { prefix: prefixParam }: { prefix?: string } = {},\n ): Promise<void> {\n // Default prefix to this.prefix if not provided, or empty string\n const prefix = prefixParam ?? this.prefix ?? '';\n\n const fullPath = `${prefix}${route.path}`;\n\n // Convert Express-style :param to Fastify-style :param (they're the same, but ensure consistency)\n const fastifyPath = fullPath;\n\n // Define the route handler\n const handler: RouteHandlerMethod = async (request: FastifyRequest, reply: FastifyReply) => {\n // Check route-level authentication/authorization\n const authError = await this.checkRouteAuth(route, {\n path: String(request.url.split('?')[0] || '/'),\n method: String(request.method || 'GET'),\n getHeader: name => request.headers[name.toLowerCase()] as string | undefined,\n getQuery: name => (request.query as Record<string, string>)[name],\n requestContext: request.requestContext,\n request: toWebRequest(request),\n buildAuthorizeContext: () => toWebRequest(request),\n });\n\n if (authError) {\n // Apply any refresh headers (e.g. Set-Cookie from transparent session refresh)\n if (authError.headers) {\n for (const [key, value] of Object.entries(authError.headers)) {\n void reply.header(key, value);\n }\n }\n\n // If this is an auth error (not just a success-with-headers), return error response\n if (authError.error) {\n return reply.status(authError.status).send({ error: authError.error });\n }\n }\n\n const params = await this.getParams(route, request);\n\n // Return 400 Bad Request if body parsing failed (e.g., malformed multipart data)\n if (params.bodyParseError) {\n return reply.status(400).send({\n error: 'Invalid request body',\n issues: [{ field: 'body', message: params.bodyParseError.message }],\n });\n }\n\n if (params.queryParams) {\n try {\n params.queryParams = await this.parseQueryParams(route, params.queryParams);\n } catch (error) {\n this.mastra.getLogger()?.error('Error parsing query params', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n if (isZodError(error)) {\n const { status, body } = this.resolveValidationError(route, error, 'query');\n return reply.status(status).send(body);\n }\n return reply.status(400).send({\n error: 'Invalid query parameters',\n issues: [{ field: 'unknown', message: error instanceof Error ? error.message : 'Unknown error' }],\n });\n }\n }\n\n if (params.body) {\n try {\n params.body = await this.parseBody(route, params.body);\n } catch (error) {\n this.mastra.getLogger()?.error('Error parsing body', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n if (isZodError(error)) {\n const { status, body } = this.resolveValidationError(route, error, 'body');\n return reply.status(status).send(body);\n }\n return reply.status(400).send({\n error: 'Invalid request body',\n issues: [{ field: 'unknown', message: error instanceof Error ? error.message : 'Unknown error' }],\n });\n }\n }\n\n // Parse path params through pathParamSchema for type coercion (e.g., z.coerce.number())\n if (params.urlParams) {\n try {\n params.urlParams = await this.parsePathParams(route, params.urlParams);\n } catch (error) {\n this.mastra.getLogger()?.error('Error parsing path params', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n });\n if (isZodError(error)) {\n const { status, body } = this.resolveValidationError(route, error, 'path');\n return reply.status(status).send(body);\n }\n return reply.status(400).send({\n error: 'Invalid path parameters',\n issues: [{ field: 'unknown', message: error instanceof Error ? error.message : 'Unknown error' }],\n });\n }\n }\n\n const handlerParams = {\n ...params.urlParams,\n ...params.queryParams,\n ...(typeof params.body === 'object' ? params.body : {}),\n requestContext: request.requestContext,\n mastra: this.mastra,\n registeredTools: request.registeredTools,\n taskStore: request.taskStore,\n abortSignal: request.abortSignal,\n routePrefix: prefix,\n };\n\n // Check route permission requirement (EE feature)\n // Uses convention-based permission derivation: permissions are auto-derived\n // from route path/method unless explicitly set or route is public\n const authConfig = this.mastra.getServer()?.auth;\n if (authConfig) {\n const hasPermission = await loadHasPermission();\n if (hasPermission) {\n const userPermissions = request.requestContext.get('mastra__userPermissions') as string[] | undefined;\n const permissionError = this.checkRoutePermission(route, userPermissions, hasPermission);\n\n if (permissionError) {\n return reply.status(permissionError.status).send({\n error: permissionError.error,\n message: permissionError.message,\n });\n }\n }\n }\n\n // Check FGA authorization (EE feature)\n const fgaError = await checkRouteFGA(this.mastra, route, request.requestContext, {\n ...params.urlParams,\n ...params.queryParams,\n ...(typeof params.body === 'object' ? params.body : {}),\n });\n if (fgaError) {\n return reply.status(fgaError.status).send({ error: fgaError.error, message: fgaError.message });\n }\n\n try {\n const result = await route.handler(handlerParams);\n await this.sendResponse(route, reply, result, request, prefix);\n } catch (error) {\n this.mastra.getLogger()?.error('Error calling handler', {\n error: error instanceof Error ? { message: error.message, stack: error.stack } : error,\n path: route.path,\n method: route.method,\n });\n // Check if it's an HTTPException or MastraError with a status code\n let status = 500;\n if (error && typeof error === 'object') {\n // Check for direct status property (HTTPException)\n if ('status' in error) {\n status = (error as any).status;\n }\n // Check for MastraError with status in details\n else if (\n 'details' in error &&\n error.details &&\n typeof error.details === 'object' &&\n 'status' in error.details\n ) {\n status = (error.details as any).status;\n }\n }\n await reply.status(status).send({ error: error instanceof Error ? error.message : 'Unknown error' });\n }\n };\n\n // Add body limit if configured\n const shouldApplyBodyLimit = this.bodyLimitOptions && ['POST', 'PUT', 'PATCH'].includes(route.method.toUpperCase());\n const maxSize = route.maxBodySize ?? this.bodyLimitOptions?.maxSize;\n\n const config = shouldApplyBodyLimit && maxSize ? { bodyLimit: maxSize } : undefined;\n\n // Handle ALL method by registering for each HTTP method\n // Fastify doesn't support 'ALL' method natively like Express\n if (route.method.toUpperCase() === 'ALL') {\n // Only register the main HTTP methods that MCP actually uses\n // Skip HEAD/OPTIONS to avoid potential conflicts with Fastify's auto-generated routes\n const methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'] as const;\n for (const method of methods) {\n try {\n app.route({\n method,\n url: fastifyPath,\n handler,\n config,\n });\n } catch (err) {\n // Skip duplicate route errors - can happen if route is registered multiple times\n if (err instanceof Error && err.message.includes('already declared')) {\n continue;\n }\n throw err;\n }\n }\n } else {\n app.route({\n method: route.method as 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',\n url: fastifyPath,\n handler,\n config,\n });\n }\n }\n\n async registerCustomApiRoutes(): Promise<void> {\n if (!(await this.buildCustomRouteHandler())) return;\n\n const routes = this.customApiRoutes ?? this.mastra.getServer()?.apiRoutes ?? [];\n\n for (const route of routes) {\n // Create pseudo ServerRoute for auth checking\n const serverRoute: ServerRoute = {\n method: route.method as any,\n path: route.path,\n responseType: 'json',\n handler: async () => {},\n requiresAuth: route.requiresAuth,\n requiresPermission: route.requiresPermission,\n fga: route.fga,\n };\n\n const fastifyHandler: RouteHandlerMethod = async (request: FastifyRequest, reply: FastifyReply) => {\n // Per-route auth check (same pattern as registerRoute)\n const authError = await this.checkRouteAuth(serverRoute, {\n path: String(request.url.split('?')[0] || '/'),\n method: String(request.method || 'GET'),\n getHeader: name => request.headers[name.toLowerCase()] as string | undefined,\n getQuery: name => (request.query as Record<string, string>)[name],\n requestContext: request.requestContext,\n request: toWebRequest(request),\n buildAuthorizeContext: () => toWebRequest(request),\n });\n\n if (authError) {\n if (authError.headers) {\n for (const [key, value] of Object.entries(authError.headers)) {\n void reply.header(key, value);\n }\n }\n if (authError.error) {\n return reply.status(authError.status).send({ error: authError.error });\n }\n }\n\n const authConfig = this.mastra.getServer()?.auth;\n if (authConfig) {\n let hasPermission: ((userPerms: string[], required: string) => boolean) | undefined;\n try {\n ({ hasPermission } = await import('@mastra/core/auth/ee'));\n } catch {\n console.error(\n '[@mastra/fastify] Auth features require @mastra/core >= 1.6.0. Please upgrade: npm install @mastra/core@latest',\n );\n }\n\n if (hasPermission) {\n const userPermissions = request.requestContext.get('mastra__userPermissions') as string[] | undefined;\n const permissionError = this.checkRoutePermission(serverRoute, userPermissions, hasPermission);\n if (permissionError) {\n return reply.status(permissionError.status).send({\n error: permissionError.error,\n message: permissionError.message,\n });\n }\n }\n }\n\n // Check FGA authorization (EE feature)\n const fgaError = await checkRouteFGA(this.mastra, serverRoute, request.requestContext, {\n ...(request.params as Record<string, string>),\n ...(request.query as Record<string, string>),\n ...(typeof request.body === 'object' && request.body !== null\n ? (request.body as Record<string, unknown>)\n : {}),\n });\n if (fgaError) {\n return reply.status(fgaError.status).send({ error: fgaError.error, message: fgaError.message });\n }\n\n const response = await this.handleCustomRouteRequest(\n `http://${request.headers.host}${request.url}`,\n request.method,\n request.headers as Record<string, string | string[] | undefined>,\n request.body,\n request.requestContext,\n request.abortSignal,\n );\n if (!response) {\n reply.status(404).send({ error: 'Not Found' });\n return;\n }\n // Merge headers set by Fastify hooks/plugins (e.g. @fastify/cors) into\n // the Fetch Response before hijacking. Otherwise writeCustomRouteResponse's\n // nodeRes.writeHead() overwrites them with only the response.headers set\n // by the custom route handler. Route-set headers win on conflict, except\n // for set-cookie which is always appended so plugin cookies survive\n // alongside handler cookies (distinct cookies, not a collision).\n // Skip framing headers (RFC 7230) — writeCustomRouteResponse /\n // Node's writeHead owns content-length and transfer-encoding.\n const existingHeaders = reply.getHeaders();\n for (const [key, value] of Object.entries(existingHeaders)) {\n if (value === undefined) continue;\n const lowerKey = key.toLowerCase();\n if (lowerKey === 'content-length' || lowerKey === 'transfer-encoding') continue;\n const isSetCookie = lowerKey === 'set-cookie';\n if (!isSetCookie && response.headers.has(key)) continue;\n if (Array.isArray(value)) {\n for (const item of value) response.headers.append(key, String(item));\n } else if (isSetCookie) {\n // set-cookie must always append so plugin cookies coexist with handler cookies.\n response.headers.append(key, String(value));\n } else {\n response.headers.set(key, String(value));\n }\n }\n reply.hijack();\n await this.writeCustomRouteResponse(response, reply.raw, request.abortSignal);\n };\n\n if (route.method === 'ALL') {\n const methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'] as const;\n for (const method of methods) {\n this.app.route({ method, url: route.path, handler: fastifyHandler });\n }\n } else {\n this.app.route({\n method: route.method as 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',\n url: route.path,\n handler: fastifyHandler,\n });\n }\n }\n }\n\n registerContextMiddleware(): void {\n // Override the default JSON parser to allow empty bodies\n // This matches Express behavior where empty POST requests with Content-Type: application/json are allowed\n this.app.removeContentTypeParser('application/json');\n this.app.addContentTypeParser('application/json', { parseAs: 'string' }, (_request, body, done) => {\n try {\n // Allow empty body\n if (!body || (typeof body === 'string' && body.trim() === '')) {\n done(null, undefined);\n return;\n }\n const parsed = JSON.parse(body as string);\n done(null, parsed);\n } catch (err) {\n done(err as Error, undefined);\n }\n });\n\n // Register content type parser for multipart/form-data\n // This allows Fastify to accept multipart requests without parsing them\n // We'll parse them manually in getParams using busboy\n this.app.addContentTypeParser('multipart/form-data', (_request, _payload, done) => {\n // Don't parse the body, we'll handle it manually with busboy\n done(null, undefined);\n });\n\n this.app.addHook('preHandler', this.createContextMiddleware());\n }\n\n registerAuthMiddleware(): void {\n // Auth is handled per-route in registerRoute() and registerCustomApiRoutes()\n // No global middleware needed\n }\n\n registerHttpLoggingMiddleware(): void {\n if (!this.httpLoggingConfig?.enabled) {\n return;\n }\n\n this.app.addHook('onRequest', async (request: FastifyRequest, reply: FastifyReply) => {\n const urlPath = request.url.split('?')[0]!;\n if (!this.shouldLogRequest(urlPath)) {\n return;\n }\n\n const start = Date.now();\n const method = request.method;\n const path = urlPath;\n\n reply.raw.once('finish', () => {\n const duration = Date.now() - start;\n const status = reply.statusCode;\n const level = this.httpLoggingConfig?.level || 'info';\n\n const logData: Record<string, any> = {\n method,\n path,\n status,\n duration: `${duration}ms`,\n };\n\n if (this.httpLoggingConfig?.includeQueryParams) {\n logData.query = request.query;\n }\n\n if (this.httpLoggingConfig?.includeHeaders) {\n const headers = { ...request.headers };\n const redactHeaders = this.httpLoggingConfig.redactHeaders || [];\n redactHeaders.forEach((h: string) => {\n const key = h.toLowerCase();\n if (headers[key] !== undefined) {\n headers[key] = '[REDACTED]';\n }\n });\n logData.headers = headers;\n }\n\n this.logger[level](`${method} ${path} ${status} ${duration}ms`, logData);\n });\n });\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/fastify",
|
|
3
|
-
"version": "1.3.26-alpha.
|
|
3
|
+
"version": "1.3.26-alpha.6",
|
|
4
4
|
"description": "Mastra Fastify adapter for the server",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"license": "Apache-2.0",
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@fastify/busboy": "^3.2.0",
|
|
24
|
-
"@mastra/server": "1.38.0-alpha.
|
|
24
|
+
"@mastra/server": "1.38.0-alpha.6"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@ai-sdk/openai": "^2.0.106",
|
|
@@ -34,13 +34,13 @@
|
|
|
34
34
|
"typescript": "^6.0.3",
|
|
35
35
|
"vitest": "4.1.5",
|
|
36
36
|
"zod": "^4.4.3",
|
|
37
|
-
"@internal/lint": "0.0.99",
|
|
38
37
|
"@internal/server-adapter-test-utils": "0.0.22",
|
|
39
|
-
"@internal/
|
|
38
|
+
"@internal/lint": "0.0.99",
|
|
40
39
|
"@internal/types-builder": "0.0.74",
|
|
41
|
-
"@
|
|
40
|
+
"@internal/storage-test-utils": "0.0.95",
|
|
42
41
|
"@mastra/evals": "1.2.4-alpha.0",
|
|
43
42
|
"@mastra/memory": "1.20.1-alpha.1",
|
|
43
|
+
"@mastra/core": "1.38.0-alpha.6",
|
|
44
44
|
"@mastra/observability": "1.14.1-alpha.0",
|
|
45
45
|
"@mastra/libsql": "1.12.0-alpha.0"
|
|
46
46
|
},
|