@mastra/koa 1.5.7-alpha.5 → 1.5.7-alpha.9
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 +51 -0
- package/dist/index.cjs +125 -144
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +125 -144
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,56 @@
|
|
|
1
1
|
# @mastra/koa
|
|
2
2
|
|
|
3
|
+
## 1.5.7-alpha.9
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`d72dc4b`](https://github.com/mastra-ai/mastra/commit/d72dc4b12d832546c05c20255fa96fe4eb515900)]:
|
|
8
|
+
- @mastra/core@1.37.0-alpha.9
|
|
9
|
+
- @mastra/server@1.37.0-alpha.9
|
|
10
|
+
|
|
11
|
+
## 1.5.7-alpha.8
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Improved agent thread subscription resilience by keeping server streams active during idle periods and allowing the JavaScript client to reconnect when subscription streams close or resubscribe requests fail. ([#17045](https://github.com/mastra-ai/mastra/pull/17045))
|
|
16
|
+
|
|
17
|
+
Enable automatic reconnection with `subscription.processDataStream({ onChunk: chunk => console.log(chunk), reconnect: true })`.
|
|
18
|
+
|
|
19
|
+
- Updated dependencies [[`c35b962`](https://github.com/mastra-ai/mastra/commit/c35b9625c7e854fcfdeee226a3338a750d0ff211), [`c35b962`](https://github.com/mastra-ai/mastra/commit/c35b9625c7e854fcfdeee226a3338a750d0ff211), [`4084113`](https://github.com/mastra-ai/mastra/commit/408411370fc48a822e8b616b3b63f9409774e0e9), [`bc01b1b`](https://github.com/mastra-ai/mastra/commit/bc01b1bfafe381d90af909f8bce7eeb4eee779f2)]:
|
|
20
|
+
- @mastra/core@1.37.0-alpha.8
|
|
21
|
+
- @mastra/server@1.37.0-alpha.8
|
|
22
|
+
|
|
23
|
+
## 1.5.7-alpha.7
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- Updated dependencies [[`168fa09`](https://github.com/mastra-ai/mastra/commit/168fa09d6b39114cb8c13bd06f1dccb9bc81c6cd)]:
|
|
28
|
+
- @mastra/core@1.37.0-alpha.7
|
|
29
|
+
- @mastra/server@1.37.0-alpha.7
|
|
30
|
+
|
|
31
|
+
## 1.5.7-alpha.6
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- Developers can now cancel long-running custom API route work when clients disconnect. Node-based adapters pass abort signals into custom route handlers, clean up response streams correctly, and still surface upstream response body errors. ([#16335](https://github.com/mastra-ai/mastra/pull/16335))
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
registerApiRoute('/stream', {
|
|
39
|
+
method: 'GET',
|
|
40
|
+
handler: async c => {
|
|
41
|
+
const stream = await agent.stream(prompt, {
|
|
42
|
+
abortSignal: c.req.raw.signal,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
return stream.toTextStreamResponse();
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
- Updated dependencies [[`fafed7a`](https://github.com/mastra-ai/mastra/commit/fafed7a24dc320f7c92ee872c347f4be087fd689), [`0cbece9`](https://github.com/mastra-ai/mastra/commit/0cbece9d832cb134a74cdbf3682d390a058215a4), [`7dfe1bc`](https://github.com/mastra-ai/mastra/commit/7dfe1bcfe71d261a6fd6bbf29b1dec49d78fb98f), [`70cb714`](https://github.com/mastra-ai/mastra/commit/70cb7149c8f16f478e15b58498254a53181750a4), [`7f9da22`](https://github.com/mastra-ai/mastra/commit/7f9da22efd5aa595e138a31de55a5f0f2f28b33d)]:
|
|
51
|
+
- @mastra/server@1.37.0-alpha.6
|
|
52
|
+
- @mastra/core@1.37.0-alpha.6
|
|
53
|
+
|
|
3
54
|
## 1.5.7-alpha.5
|
|
4
55
|
|
|
5
56
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -6,6 +6,9 @@ var serverAdapter = require('@mastra/server/server-adapter');
|
|
|
6
6
|
var requestContext = require('@mastra/core/request-context');
|
|
7
7
|
|
|
8
8
|
// src/index.ts
|
|
9
|
+
|
|
10
|
+
// ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/core.js
|
|
11
|
+
var _a;
|
|
9
12
|
// @__NO_SIDE_EFFECTS__
|
|
10
13
|
function $constructor(name, initializer3, params) {
|
|
11
14
|
function init(inst, def) {
|
|
@@ -58,15 +61,16 @@ function $constructor(name, initializer3, params) {
|
|
|
58
61
|
Object.defineProperty(_, "name", { value: name });
|
|
59
62
|
return _;
|
|
60
63
|
}
|
|
64
|
+
(_a = globalThis).__zod_globalConfig ?? (_a.__zod_globalConfig = {});
|
|
61
65
|
|
|
62
|
-
// ../../node_modules/.pnpm/zod@4.3
|
|
66
|
+
// ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/util.js
|
|
63
67
|
function jsonStringifyReplacer(_, value) {
|
|
64
68
|
if (typeof value === "bigint")
|
|
65
69
|
return value.toString();
|
|
66
70
|
return value;
|
|
67
71
|
}
|
|
68
72
|
|
|
69
|
-
// ../../node_modules/.pnpm/zod@4.3
|
|
73
|
+
// ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/errors.js
|
|
70
74
|
var initializer = (inst, def) => {
|
|
71
75
|
inst.name = "$ZodError";
|
|
72
76
|
Object.defineProperty(inst, "_zod", {
|
|
@@ -84,7 +88,7 @@ var initializer = (inst, def) => {
|
|
|
84
88
|
});
|
|
85
89
|
};
|
|
86
90
|
var $ZodError = $constructor("$ZodError", initializer);
|
|
87
|
-
function flattenError(error, mapper = (
|
|
91
|
+
function flattenError(error, mapper = (issue) => issue.message) {
|
|
88
92
|
const fieldErrors = {};
|
|
89
93
|
const formErrors = [];
|
|
90
94
|
for (const sub of error.issues) {
|
|
@@ -97,32 +101,35 @@ function flattenError(error, mapper = (issue2) => issue2.message) {
|
|
|
97
101
|
}
|
|
98
102
|
return { formErrors, fieldErrors };
|
|
99
103
|
}
|
|
100
|
-
function formatError(error, mapper = (
|
|
104
|
+
function formatError(error, mapper = (issue) => issue.message) {
|
|
101
105
|
const fieldErrors = { _errors: [] };
|
|
102
|
-
const processError = (error2) => {
|
|
103
|
-
for (const
|
|
104
|
-
if (
|
|
105
|
-
|
|
106
|
-
} else if (
|
|
107
|
-
processError({ issues:
|
|
108
|
-
} else if (
|
|
109
|
-
processError({ issues:
|
|
110
|
-
} else if (issue2.path.length === 0) {
|
|
111
|
-
fieldErrors._errors.push(mapper(issue2));
|
|
106
|
+
const processError = (error2, path = []) => {
|
|
107
|
+
for (const issue of error2.issues) {
|
|
108
|
+
if (issue.code === "invalid_union" && issue.errors.length) {
|
|
109
|
+
issue.errors.map((issues) => processError({ issues }, [...path, ...issue.path]));
|
|
110
|
+
} else if (issue.code === "invalid_key") {
|
|
111
|
+
processError({ issues: issue.issues }, [...path, ...issue.path]);
|
|
112
|
+
} else if (issue.code === "invalid_element") {
|
|
113
|
+
processError({ issues: issue.issues }, [...path, ...issue.path]);
|
|
112
114
|
} else {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
115
|
+
const fullpath = [...path, ...issue.path];
|
|
116
|
+
if (fullpath.length === 0) {
|
|
117
|
+
fieldErrors._errors.push(mapper(issue));
|
|
118
|
+
} else {
|
|
119
|
+
let curr = fieldErrors;
|
|
120
|
+
let i = 0;
|
|
121
|
+
while (i < fullpath.length) {
|
|
122
|
+
const el = fullpath[i];
|
|
123
|
+
const terminal = i === fullpath.length - 1;
|
|
124
|
+
if (!terminal) {
|
|
125
|
+
curr[el] = curr[el] || { _errors: [] };
|
|
126
|
+
} else {
|
|
127
|
+
curr[el] = curr[el] || { _errors: [] };
|
|
128
|
+
curr[el]._errors.push(mapper(issue));
|
|
129
|
+
}
|
|
130
|
+
curr = curr[el];
|
|
131
|
+
i++;
|
|
123
132
|
}
|
|
124
|
-
curr = curr[el];
|
|
125
|
-
i++;
|
|
126
133
|
}
|
|
127
134
|
}
|
|
128
135
|
}
|
|
@@ -131,54 +138,7 @@ function formatError(error, mapper = (issue2) => issue2.message) {
|
|
|
131
138
|
return fieldErrors;
|
|
132
139
|
}
|
|
133
140
|
|
|
134
|
-
// ../../node_modules/.pnpm/zod@4.3
|
|
135
|
-
var _a;
|
|
136
|
-
var $ZodRegistry = class {
|
|
137
|
-
constructor() {
|
|
138
|
-
this._map = /* @__PURE__ */ new WeakMap();
|
|
139
|
-
this._idmap = /* @__PURE__ */ new Map();
|
|
140
|
-
}
|
|
141
|
-
add(schema, ..._meta) {
|
|
142
|
-
const meta = _meta[0];
|
|
143
|
-
this._map.set(schema, meta);
|
|
144
|
-
if (meta && typeof meta === "object" && "id" in meta) {
|
|
145
|
-
this._idmap.set(meta.id, schema);
|
|
146
|
-
}
|
|
147
|
-
return this;
|
|
148
|
-
}
|
|
149
|
-
clear() {
|
|
150
|
-
this._map = /* @__PURE__ */ new WeakMap();
|
|
151
|
-
this._idmap = /* @__PURE__ */ new Map();
|
|
152
|
-
return this;
|
|
153
|
-
}
|
|
154
|
-
remove(schema) {
|
|
155
|
-
const meta = this._map.get(schema);
|
|
156
|
-
if (meta && typeof meta === "object" && "id" in meta) {
|
|
157
|
-
this._idmap.delete(meta.id);
|
|
158
|
-
}
|
|
159
|
-
this._map.delete(schema);
|
|
160
|
-
return this;
|
|
161
|
-
}
|
|
162
|
-
get(schema) {
|
|
163
|
-
const p = schema._zod.parent;
|
|
164
|
-
if (p) {
|
|
165
|
-
const pm = { ...this.get(p) ?? {} };
|
|
166
|
-
delete pm.id;
|
|
167
|
-
const f = { ...pm, ...this._map.get(schema) };
|
|
168
|
-
return Object.keys(f).length ? f : void 0;
|
|
169
|
-
}
|
|
170
|
-
return this._map.get(schema);
|
|
171
|
-
}
|
|
172
|
-
has(schema) {
|
|
173
|
-
return this._map.has(schema);
|
|
174
|
-
}
|
|
175
|
-
};
|
|
176
|
-
function registry() {
|
|
177
|
-
return new $ZodRegistry();
|
|
178
|
-
}
|
|
179
|
-
(_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());
|
|
180
|
-
|
|
181
|
-
// ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/errors.js
|
|
141
|
+
// ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/errors.js
|
|
182
142
|
var initializer2 = (inst, issues) => {
|
|
183
143
|
$ZodError.init(inst, issues);
|
|
184
144
|
inst.name = "ZodError";
|
|
@@ -192,8 +152,8 @@ var initializer2 = (inst, issues) => {
|
|
|
192
152
|
// enumerable: false,
|
|
193
153
|
},
|
|
194
154
|
addIssue: {
|
|
195
|
-
value: (
|
|
196
|
-
inst.issues.push(
|
|
155
|
+
value: (issue) => {
|
|
156
|
+
inst.issues.push(issue);
|
|
197
157
|
inst.message = JSON.stringify(inst.issues, jsonStringifyReplacer, 2);
|
|
198
158
|
}
|
|
199
159
|
// enumerable: false,
|
|
@@ -213,7 +173,7 @@ var initializer2 = (inst, issues) => {
|
|
|
213
173
|
}
|
|
214
174
|
});
|
|
215
175
|
};
|
|
216
|
-
var ZodError = $constructor("ZodError", initializer2);
|
|
176
|
+
var ZodError = /* @__PURE__ */ $constructor("ZodError", initializer2);
|
|
217
177
|
function toWebRequest(ctx) {
|
|
218
178
|
const protocol = ctx.protocol || "http";
|
|
219
179
|
const host = ctx.host || "localhost";
|
|
@@ -676,6 +636,10 @@ var MastraServer = class extends serverAdapter.MastraServer {
|
|
|
676
636
|
const { done, value } = await reader.read();
|
|
677
637
|
if (done) break;
|
|
678
638
|
if (value) {
|
|
639
|
+
if (streamFormat === "sse" && typeof value === "string" && value.startsWith(":")) {
|
|
640
|
+
ctx.res.write(value);
|
|
641
|
+
continue;
|
|
642
|
+
}
|
|
679
643
|
const shouldRedact = this.streamOptions?.redact ?? true;
|
|
680
644
|
const outputValue = shouldRedact ? serverAdapter.redactStreamChunk(value) : value;
|
|
681
645
|
if (streamFormat === "sse") {
|
|
@@ -915,77 +879,94 @@ var MastraServer = class extends serverAdapter.MastraServer {
|
|
|
915
879
|
);
|
|
916
880
|
const shouldRunCustomRouteAuth = auth.isProtectedCustomRoute(path, method, server.customRouteAuthConfig);
|
|
917
881
|
const shouldRunCustomRouteFGA = !!matchedRoute?.route.fga;
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
method,
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
882
|
+
const customRouteAbortController = new AbortController();
|
|
883
|
+
const abortCustomRoute = () => {
|
|
884
|
+
customRouteAbortController.abort();
|
|
885
|
+
};
|
|
886
|
+
const abortCustomRouteIfOpen = () => {
|
|
887
|
+
if (!ctx.res.writableEnded) {
|
|
888
|
+
abortCustomRoute();
|
|
889
|
+
}
|
|
890
|
+
};
|
|
891
|
+
ctx.res.once("close", abortCustomRouteIfOpen);
|
|
892
|
+
ctx.res.once("error", abortCustomRouteIfOpen);
|
|
893
|
+
try {
|
|
894
|
+
if (shouldRunCustomRouteAuth || shouldRunCustomRouteFGA) {
|
|
895
|
+
const serverRoute = {
|
|
896
|
+
method: matchedRoute?.route.method ?? method,
|
|
897
|
+
path: matchedRoute?.route.path ?? path,
|
|
898
|
+
responseType: "json",
|
|
899
|
+
handler: async () => {
|
|
900
|
+
},
|
|
901
|
+
requiresAuth: matchedRoute?.route.requiresAuth,
|
|
902
|
+
requiresPermission: matchedRoute?.route.requiresPermission,
|
|
903
|
+
fga: matchedRoute?.route.fga
|
|
904
|
+
};
|
|
905
|
+
if (shouldRunCustomRouteAuth) {
|
|
906
|
+
const authError = await server.checkRouteAuth(serverRoute, {
|
|
907
|
+
path,
|
|
908
|
+
method,
|
|
909
|
+
getHeader: (name) => ctx.headers[name.toLowerCase()],
|
|
910
|
+
getQuery: (name) => ctx.query[name],
|
|
911
|
+
requestContext: ctx.state.requestContext,
|
|
912
|
+
request: toWebRequest2(ctx),
|
|
913
|
+
buildAuthorizeContext: () => toWebRequest2(ctx)
|
|
914
|
+
});
|
|
915
|
+
if (authError) {
|
|
916
|
+
if (authError.headers) {
|
|
917
|
+
for (const [key, value] of Object.entries(authError.headers)) {
|
|
918
|
+
ctx.set(key, value);
|
|
919
|
+
}
|
|
943
920
|
}
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
ctx.body = { error: authError.error };
|
|
948
|
-
return;
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
const authConfig = server.mastra.getServer()?.auth;
|
|
952
|
-
if (authConfig) {
|
|
953
|
-
const hasPermission = await loadHasPermission();
|
|
954
|
-
if (hasPermission) {
|
|
955
|
-
const userPermissions = ctx.state.requestContext.get("mastra__userPermissions");
|
|
956
|
-
const permissionError = server.checkRoutePermission(serverRoute, userPermissions, hasPermission);
|
|
957
|
-
if (permissionError) {
|
|
958
|
-
ctx.status = permissionError.status;
|
|
959
|
-
ctx.body = {
|
|
960
|
-
error: permissionError.error,
|
|
961
|
-
message: permissionError.message
|
|
962
|
-
};
|
|
921
|
+
if (authError.error) {
|
|
922
|
+
ctx.status = authError.status;
|
|
923
|
+
ctx.body = { error: authError.error };
|
|
963
924
|
return;
|
|
964
925
|
}
|
|
965
926
|
}
|
|
927
|
+
const authConfig = server.mastra.getServer()?.auth;
|
|
928
|
+
if (authConfig) {
|
|
929
|
+
const hasPermission = await loadHasPermission();
|
|
930
|
+
if (hasPermission) {
|
|
931
|
+
const userPermissions = ctx.state.requestContext.get("mastra__userPermissions");
|
|
932
|
+
const permissionError = server.checkRoutePermission(serverRoute, userPermissions, hasPermission);
|
|
933
|
+
if (permissionError) {
|
|
934
|
+
ctx.status = permissionError.status;
|
|
935
|
+
ctx.body = {
|
|
936
|
+
error: permissionError.error,
|
|
937
|
+
message: permissionError.message
|
|
938
|
+
};
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
const fgaError = await serverAdapter.checkRouteFGA(server.mastra, serverRoute, ctx.state.requestContext, {
|
|
945
|
+
...matchedRoute?.params ?? {},
|
|
946
|
+
...ctx.query,
|
|
947
|
+
...typeof ctx.request.body === "object" && ctx.request.body !== null ? ctx.request.body : {}
|
|
948
|
+
});
|
|
949
|
+
if (fgaError) {
|
|
950
|
+
ctx.status = fgaError.status;
|
|
951
|
+
ctx.body = { error: fgaError.error, message: fgaError.message };
|
|
952
|
+
return;
|
|
966
953
|
}
|
|
967
954
|
}
|
|
968
|
-
const
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
955
|
+
const response = await server.handleCustomRouteRequest(
|
|
956
|
+
`${ctx.protocol}://${ctx.host}${ctx.originalUrl || ctx.url}`,
|
|
957
|
+
ctx.method,
|
|
958
|
+
ctx.headers,
|
|
959
|
+
ctx.request.body,
|
|
960
|
+
ctx.state.requestContext,
|
|
961
|
+
customRouteAbortController.signal
|
|
962
|
+
);
|
|
963
|
+
if (!response) return next();
|
|
964
|
+
ctx.respond = false;
|
|
965
|
+
await server.writeCustomRouteResponse(response, ctx.res, customRouteAbortController.signal);
|
|
966
|
+
} finally {
|
|
967
|
+
ctx.res.off("close", abortCustomRouteIfOpen);
|
|
968
|
+
ctx.res.off("error", abortCustomRouteIfOpen);
|
|
978
969
|
}
|
|
979
|
-
const response = await server.handleCustomRouteRequest(
|
|
980
|
-
`${ctx.protocol}://${ctx.host}${ctx.originalUrl || ctx.url}`,
|
|
981
|
-
ctx.method,
|
|
982
|
-
ctx.headers,
|
|
983
|
-
ctx.request.body,
|
|
984
|
-
ctx.state.requestContext
|
|
985
|
-
);
|
|
986
|
-
if (!response) return next();
|
|
987
|
-
ctx.respond = false;
|
|
988
|
-
await server.writeCustomRouteResponse(response, ctx.res);
|
|
989
970
|
});
|
|
990
971
|
}
|
|
991
972
|
registerContextMiddleware() {
|
|
@@ -1006,14 +987,14 @@ var MastraServer = class extends serverAdapter.MastraServer {
|
|
|
1006
987
|
const method = ctx.method;
|
|
1007
988
|
const path = ctx.path;
|
|
1008
989
|
await next();
|
|
1009
|
-
const
|
|
990
|
+
const duration = Date.now() - start;
|
|
1010
991
|
const status = ctx.status;
|
|
1011
992
|
const level = server.httpLoggingConfig?.level || "info";
|
|
1012
993
|
const logData = {
|
|
1013
994
|
method,
|
|
1014
995
|
path,
|
|
1015
996
|
status,
|
|
1016
|
-
duration: `${
|
|
997
|
+
duration: `${duration}ms`
|
|
1017
998
|
};
|
|
1018
999
|
if (server.httpLoggingConfig?.includeQueryParams) {
|
|
1019
1000
|
logData.query = ctx.query;
|
|
@@ -1029,7 +1010,7 @@ var MastraServer = class extends serverAdapter.MastraServer {
|
|
|
1029
1010
|
});
|
|
1030
1011
|
logData.headers = headers;
|
|
1031
1012
|
}
|
|
1032
|
-
server.logger[level](`${method} ${path} ${status} ${
|
|
1013
|
+
server.logger[level](`${method} ${path} ${status} ${duration}ms`, logData);
|
|
1033
1014
|
});
|
|
1034
1015
|
}
|
|
1035
1016
|
};
|