effortless-aws 0.34.0 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-6HFS224S.js → chunk-Q3ZDMZF3.js} +13 -4
- package/dist/index.d.ts +160 -124
- package/dist/index.js +109 -44
- package/dist/index.js.map +1 -1
- package/dist/runtime/wrap-api.js +19 -3
- package/dist/runtime/wrap-bucket.js +1 -1
- package/dist/runtime/wrap-cron.js +1 -1
- package/dist/runtime/wrap-fifo-queue.js +1 -1
- package/dist/runtime/wrap-mcp.js +76 -19
- package/dist/runtime/wrap-middleware.js +1 -1
- package/dist/runtime/wrap-table-stream.js +1 -1
- package/dist/runtime/wrap-worker.js +1 -1
- package/package.json +2 -1
package/dist/runtime/wrap-api.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AUTH_COOKIE_NAME,
|
|
3
3
|
createHandlerRuntime
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-Q3ZDMZF3.js";
|
|
5
5
|
|
|
6
6
|
// src/runtime/wrap-api.ts
|
|
7
7
|
var CONTENT_TYPE_MAP = {
|
|
@@ -131,7 +131,7 @@ var wrapApi = (handler) => {
|
|
|
131
131
|
}
|
|
132
132
|
const { entry, params: routeParams } = routeMatch;
|
|
133
133
|
const query = event.queryStringParameters ?? {};
|
|
134
|
-
const params = { ...event.pathParameters
|
|
134
|
+
const params = { ...event.pathParameters, ...routeParams };
|
|
135
135
|
const merged = {
|
|
136
136
|
...query,
|
|
137
137
|
...typeof body === "object" && body !== null ? body : {},
|
|
@@ -162,10 +162,26 @@ var wrapApi = (handler) => {
|
|
|
162
162
|
return unauthorized();
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
|
+
let validatedInput = merged;
|
|
166
|
+
if (entry.schema && typeof entry.schema === "object" && "~standard" in entry.schema) {
|
|
167
|
+
const schema = entry.schema;
|
|
168
|
+
if (typeof schema["~standard"].validate === "function") {
|
|
169
|
+
const result = await schema["~standard"].validate(merged);
|
|
170
|
+
if (result.issues) {
|
|
171
|
+
const issues = result.issues.map((i) => {
|
|
172
|
+
const path2 = i.path?.map((p) => typeof p === "object" ? p.key : p).join(".");
|
|
173
|
+
return path2 ? `${path2}: ${i.message}` : i.message;
|
|
174
|
+
});
|
|
175
|
+
rt.logExecution(startTime, logInput, { status: 400 });
|
|
176
|
+
return { statusCode: 400, headers: { "Content-Type": "application/json" }, body: JSON.stringify({ error: "Validation failed", issues }) };
|
|
177
|
+
}
|
|
178
|
+
validatedInput = result.value;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
165
181
|
const { ctx, auth, ...rest } = sharedArgs;
|
|
166
182
|
ctxProps = ctx && typeof ctx === "object" ? { ...ctx } : {};
|
|
167
183
|
delete ctxProps.auth;
|
|
168
|
-
const args = { ...ctxProps, req, input:
|
|
184
|
+
const args = { ...ctxProps, req, input: validatedInput, ok, fail, ...rest };
|
|
169
185
|
if (auth) args.auth = auth;
|
|
170
186
|
if (streamCtx) args.stream = streamCtx.stream;
|
|
171
187
|
try {
|
package/dist/runtime/wrap-mcp.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createHandlerRuntime
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-Q3ZDMZF3.js";
|
|
4
4
|
|
|
5
5
|
// src/runtime/wrap-mcp.ts
|
|
6
6
|
var ErrorCode = {
|
|
@@ -39,6 +39,39 @@ var jsonResponse = (body, status = 200) => ({
|
|
|
39
39
|
body: JSON.stringify(body)
|
|
40
40
|
});
|
|
41
41
|
var RESOURCE_NOT_FOUND = -32002;
|
|
42
|
+
var isStandardSchema = (input) => input != null && typeof input === "object" && "~standard" in input && typeof input["~standard"]?.jsonSchema?.input === "function";
|
|
43
|
+
var validateInput = async (schema, rawArgs, toolName) => {
|
|
44
|
+
const validate = schema["~standard"].validate;
|
|
45
|
+
if (typeof validate !== "function") return rawArgs;
|
|
46
|
+
const result = await validate(rawArgs);
|
|
47
|
+
if (result.issues) {
|
|
48
|
+
const messages = result.issues.map((i) => {
|
|
49
|
+
const path = i.path?.map((p) => typeof p === "object" ? p.key : p).join(".");
|
|
50
|
+
return path ? `${path}: ${i.message}` : i.message;
|
|
51
|
+
});
|
|
52
|
+
throw new Error(`Validation failed for tool "${toolName}": ${messages.join("; ")}`);
|
|
53
|
+
}
|
|
54
|
+
return result.value;
|
|
55
|
+
};
|
|
56
|
+
var wrapResourceResult = (raw, uri) => {
|
|
57
|
+
if (raw == null) return [{ uri, text: "null" }];
|
|
58
|
+
if (Array.isArray(raw)) {
|
|
59
|
+
if (raw.length > 0 && typeof raw[0] === "object" && raw[0] !== null && "uri" in raw[0]) return raw;
|
|
60
|
+
return [{ uri, text: JSON.stringify(raw) }];
|
|
61
|
+
}
|
|
62
|
+
if (typeof raw === "object" && "uri" in raw && ("text" in raw || "blob" in raw)) {
|
|
63
|
+
return [raw];
|
|
64
|
+
}
|
|
65
|
+
const text = typeof raw === "string" ? raw : JSON.stringify(raw);
|
|
66
|
+
return [{ uri, text }];
|
|
67
|
+
};
|
|
68
|
+
var wrapToolResult = (raw) => {
|
|
69
|
+
if (raw != null && typeof raw === "object" && "content" in raw && Array.isArray(raw.content)) {
|
|
70
|
+
return raw;
|
|
71
|
+
}
|
|
72
|
+
const text = typeof raw === "string" ? raw : JSON.stringify(raw ?? null);
|
|
73
|
+
return { content: [{ type: "text", text }] };
|
|
74
|
+
};
|
|
42
75
|
var wrapMcp = (handler) => {
|
|
43
76
|
const rt = createHandlerRuntime(handler, "mcp", handler.__spec.lambda?.logLevel ?? "info");
|
|
44
77
|
const serverName = handler.__spec.name;
|
|
@@ -138,7 +171,7 @@ async function handleMethod(req, ctx, tools, resourceMap, prompts, serverName, s
|
|
|
138
171
|
tools: Object.entries(tools).map(([name, def]) => ({
|
|
139
172
|
name,
|
|
140
173
|
description: def.description,
|
|
141
|
-
inputSchema: def.input
|
|
174
|
+
inputSchema: isStandardSchema(def.input) ? def.input["~standard"].jsonSchema.input({ target: "draft-07" }) : def.input
|
|
142
175
|
}))
|
|
143
176
|
}
|
|
144
177
|
};
|
|
@@ -149,8 +182,10 @@ async function handleMethod(req, ctx, tools, resourceMap, prompts, serverName, s
|
|
|
149
182
|
}
|
|
150
183
|
const tool = tools[toolName];
|
|
151
184
|
try {
|
|
152
|
-
const
|
|
153
|
-
|
|
185
|
+
const rawArgs = req.params?.arguments ?? {};
|
|
186
|
+
const input = isStandardSchema(tool.input) ? await validateInput(tool.input, rawArgs, toolName) : rawArgs;
|
|
187
|
+
const raw = await tool.handler(input, ctx);
|
|
188
|
+
return { jsonrpc: "2.0", id: req.id, result: wrapToolResult(raw) };
|
|
154
189
|
} catch (error) {
|
|
155
190
|
return {
|
|
156
191
|
jsonrpc: "2.0",
|
|
@@ -188,28 +223,47 @@ async function handleMethod(req, ctx, tools, resourceMap, prompts, serverName, s
|
|
|
188
223
|
}
|
|
189
224
|
const staticDef = resourceMap[uri];
|
|
190
225
|
if (staticDef && !isTemplate(uri)) {
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
return { jsonrpc: "2.0", id: req.id, result: { contents } };
|
|
226
|
+
const raw = await staticDef.handler(ctx);
|
|
227
|
+
return { jsonrpc: "2.0", id: req.id, result: { contents: wrapResourceResult(raw, uri) } };
|
|
194
228
|
}
|
|
195
229
|
for (const [template, def] of Object.entries(resourceMap)) {
|
|
196
230
|
if (!isTemplate(template)) continue;
|
|
197
|
-
const
|
|
198
|
-
if (
|
|
199
|
-
const
|
|
200
|
-
const
|
|
201
|
-
|
|
231
|
+
const rawParams = matchTemplate(template, uri);
|
|
232
|
+
if (rawParams) {
|
|
233
|
+
const defAny = def;
|
|
234
|
+
const params = defAny.params && typeof defAny.params === "object" && "~standard" in defAny.params ? await validateInput(defAny.params, rawParams, `resource ${template}`) : rawParams;
|
|
235
|
+
const raw = await def.handler(params, ctx);
|
|
236
|
+
return { jsonrpc: "2.0", id: req.id, result: { contents: wrapResourceResult(raw, uri) } };
|
|
202
237
|
}
|
|
203
238
|
}
|
|
204
239
|
return { jsonrpc: "2.0", id: req.id, error: { code: RESOURCE_NOT_FOUND, message: "Resource not found", data: { uri } } };
|
|
205
240
|
}
|
|
206
241
|
// ── Prompts ──
|
|
207
242
|
case "prompts/list": {
|
|
208
|
-
const promptList = Object.entries(prompts).map(([name, def]) =>
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
243
|
+
const promptList = Object.entries(prompts).map(([name, def]) => {
|
|
244
|
+
const defAny = def;
|
|
245
|
+
let args;
|
|
246
|
+
if (defAny.args && typeof defAny.args === "object" && "~standard" in defAny.args) {
|
|
247
|
+
const jsonSchema = defAny.args["~standard"].jsonSchema?.input?.({ target: "draft-07" });
|
|
248
|
+
if (jsonSchema?.properties) {
|
|
249
|
+
const required = new Set(jsonSchema.required ?? []);
|
|
250
|
+
args = Object.entries(jsonSchema.properties).map(([key, prop]) => ({
|
|
251
|
+
name: key,
|
|
252
|
+
...prop.description ? { description: prop.description } : {},
|
|
253
|
+
...required.has(key) ? { required: true } : {}
|
|
254
|
+
}));
|
|
255
|
+
}
|
|
256
|
+
} else if (Array.isArray(defAny.args)) {
|
|
257
|
+
args = defAny.args;
|
|
258
|
+
} else if (defAny.arguments) {
|
|
259
|
+
args = defAny.arguments;
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
name,
|
|
263
|
+
...def.description ? { description: def.description } : {},
|
|
264
|
+
...args ? { arguments: args } : {}
|
|
265
|
+
};
|
|
266
|
+
});
|
|
213
267
|
return { jsonrpc: "2.0", id: req.id, result: { prompts: promptList } };
|
|
214
268
|
}
|
|
215
269
|
case "prompts/get": {
|
|
@@ -218,9 +272,12 @@ async function handleMethod(req, ctx, tools, resourceMap, prompts, serverName, s
|
|
|
218
272
|
return { jsonrpc: "2.0", id: req.id, error: { code: ErrorCode.InvalidParams, message: `Unknown prompt: ${promptName}` } };
|
|
219
273
|
}
|
|
220
274
|
const prompt = prompts[promptName];
|
|
221
|
-
const
|
|
275
|
+
const rawArgs = req.params?.arguments ?? {};
|
|
222
276
|
try {
|
|
223
|
-
const
|
|
277
|
+
const defAny = prompt;
|
|
278
|
+
const args = defAny.args && typeof defAny.args === "object" && "~standard" in defAny.args ? await validateInput(defAny.args, rawArgs, `prompt ${promptName}`) : rawArgs;
|
|
279
|
+
const raw = await prompt.handler(args, ctx);
|
|
280
|
+
const result = typeof raw === "string" ? { messages: [{ role: "user", content: { type: "text", text: raw } }] } : raw;
|
|
224
281
|
return { jsonrpc: "2.0", id: req.id, result };
|
|
225
282
|
} catch (error) {
|
|
226
283
|
return { jsonrpc: "2.0", id: req.id, error: { code: ErrorCode.InternalError, message: error instanceof Error ? error.message : String(error) } };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "effortless-aws",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.36.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Code-first AWS Lambda framework. Export handlers, deploy with one command.",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"typescript": "^5.9.3",
|
|
50
50
|
"vite-tsconfig-paths": "^6.1.1",
|
|
51
51
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
52
|
+
"@standard-schema/spec": "^1.1.0",
|
|
52
53
|
"vitest": "^4.0.18"
|
|
53
54
|
},
|
|
54
55
|
"scripts": {
|