MCPcopy Index your code
hub / github.com/cloudflare/agents / normalizeCode

Function normalizeCode

packages/codemode/src/normalize.ts:14–81  ·  view source on GitHub ↗
(code: string)

Source from the content-addressed store, hash-verified

12}
13
14export function normalizeCode(code: string): string {
15 const trimmed = stripCodeFences(code.trim());
16 if (!trimmed.trim()) return "async () => {}";
17
18 const source = trimmed.trim();
19
20 try {
21 const ast = acorn.parse(source, {
22 ecmaVersion: "latest",
23 sourceType: "module"
24 });
25
26 // Already an arrow function — pass through
27 if (ast.body.length === 1 && ast.body[0].type === "ExpressionStatement") {
28 const expr = (ast.body[0] as acorn.ExpressionStatement).expression;
29 if (expr.type === "ArrowFunctionExpression") return source;
30 }
31
32 // export default <expression> → unwrap to just the expression
33 if (
34 ast.body.length === 1 &&
35 ast.body[0].type === "ExportDefaultDeclaration"
36 ) {
37 const decl = (ast.body[0] as acorn.ExportDefaultDeclaration).declaration;
38 const inner = source.slice(decl.start, decl.end);
39
40 // Anonymous function/class declarations aren't valid as standalone
41 // statements — wrap them as expressions directly.
42 if (
43 decl.type === "FunctionDeclaration" &&
44 !(decl as acorn.FunctionDeclaration).id
45 ) {
46 return `async () => {\nreturn (${inner})();\n}`;
47 }
48 if (
49 decl.type === "ClassDeclaration" &&
50 !(decl as acorn.ClassDeclaration).id
51 ) {
52 return `async () => {\nreturn (${inner});\n}`;
53 }
54
55 return normalizeCode(inner);
56 }
57
58 // Single named function declaration → wrap and call it
59 if (ast.body.length === 1 && ast.body[0].type === "FunctionDeclaration") {
60 const fn = ast.body[0] as acorn.FunctionDeclaration;
61 const name = fn.id?.name ?? "fn";
62 return `async () => {\n${source}\nreturn ${name}();\n}`;
63 }
64
65 // Last statement is expression → splice in return
66 const last = ast.body[ast.body.length - 1];
67 if (last?.type === "ExpressionStatement") {
68 const exprStmt = last as acorn.ExpressionStatement;
69 const before = source.slice(0, last.start);
70 const exprText = source.slice(
71 exprStmt.expression.start,

Callers 4

createCodeToolFunction · 0.90
executeMethod · 0.90
createCodeToolFunction · 0.90
normalize.test.tsFile · 0.90

Calls 2

stripCodeFencesFunction · 0.85
parseMethod · 0.80

Tested by

no test coverage detected