Skip to content

Commit 409a66d

Browse files
seefeldbclaude
andcommitted
fix(ts-transformers): Preserve recipe name when transforming recipe("name", (input: T) => ...)
Previously, when transforming recipe calls with both a name string and a typed parameter like `recipe("MyRecipe", (input: Input) => ...)`, the transformer would drop the name argument, resulting in `recipe(toSchema<Input>(), (input) => ...)`. This caused the resulting schema to lose its description. Now the transformer correctly preserves the name argument, producing: `recipe("MyRecipe", toSchema<Input>(), (input) => ...)` Added test fixture to verify the fix. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 5d334bf commit 409a66d

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

packages/ts-transformers/src/transformers/schema-injection.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ export class SchemaInjectionTransformer extends Transformer {
200200
// Only transform if the function parameter has a type annotation
201201
const argsArray = Array.from(node.arguments);
202202
let recipeFunction: ts.Expression | undefined;
203+
let recipeName: ts.StringLiteral | undefined;
203204

204205
if (argsArray.length === 1) {
205206
// Single argument - must be the function
@@ -209,6 +210,7 @@ export class SchemaInjectionTransformer extends Transformer {
209210
ts.isStringLiteral(argsArray[0])
210211
) {
211212
// Two arguments with first being a string - second is the function
213+
recipeName = argsArray[0];
212214
recipeFunction = argsArray[1];
213215
}
214216

@@ -228,10 +230,15 @@ export class SchemaInjectionTransformer extends Transformer {
228230
inputParam.type,
229231
);
230232

233+
// Preserve the name argument if it was provided
234+
const newArgs = recipeName
235+
? [recipeName, toSchemaInput, recipeFn]
236+
: [toSchemaInput, recipeFn];
237+
231238
const updated = factory.createCallExpression(
232239
node.expression,
233240
undefined,
234-
[toSchemaInput, recipeFn],
241+
newArgs,
235242
);
236243

237244
return ts.visitEachChild(updated, visit, transformation);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import * as __ctHelpers from "commontools";
2+
import { recipe } from "commontools";
3+
interface MyInput {
4+
value: number;
5+
}
6+
export default recipe("MyRecipe", {
7+
type: "object",
8+
properties: {
9+
value: {
10+
type: "number"
11+
}
12+
},
13+
required: ["value"]
14+
} as const satisfies __ctHelpers.JSONSchema, (input: MyInput) => {
15+
return {
16+
result: input.value * 2,
17+
};
18+
});
19+
// @ts-ignore: Internals
20+
function h(...args: any[]) { return __ctHelpers.h.apply(null, args); }
21+
// @ts-ignore: Internals
22+
h.fragment = __ctHelpers.h.fragment;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/// <cts-enable />
2+
import { recipe } from "commontools";
3+
4+
interface MyInput {
5+
value: number;
6+
}
7+
8+
export default recipe("MyRecipe", (input: MyInput) => {
9+
return {
10+
result: input.value * 2,
11+
};
12+
});

0 commit comments

Comments
 (0)