Skip to content

Commit

Permalink
Merge pull request #1767 from Schroedi/fix/transformer-returns
Browse files Browse the repository at this point in the history
fix: nested transformers wrong returns
  • Loading branch information
mrlubos authored Mar 4, 2025
2 parents fae5e53 + b5a972b commit 8248f96
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 36 deletions.
5 changes: 5 additions & 0 deletions .changeset/strange-laws-marry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hey-api/openapi-ts": patch
---

fix: handle nested dates in transformers
67 changes: 32 additions & 35 deletions packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,15 @@ const processSchemaType = ({
});

if (dataExpression) {
// In a map callback, the item needs to be returned, not just the transformation result
if (typeof dataExpression === 'string' && dataExpression === 'item') {
return [
compiler.returnStatement({
expression: callExpression,
}),
];
}

return [
typeof dataExpression === 'string'
? callExpression
Expand All @@ -267,17 +276,34 @@ const processSchemaType = ({
? []
: processSchemaType({
context,
dataExpression: 'item',
plugin,
schema: {
...schema,
type: undefined,
},
schema: schema.items?.[0]
? schema.items[0]
: {
...schema,
type: undefined,
},
});

if (!nodes.length) {
return [];
}

// Ensure the map callback has a return statement for the item
const mapCallbackStatements = ensureStatements(nodes);
const hasReturnStatement = mapCallbackStatements.some((stmt) =>
isNodeReturnStatement({ node: stmt }),
);

if (!hasReturnStatement) {
mapCallbackStatements.push(
compiler.returnStatement({
expression: compiler.identifier({ text: 'item' }),
}),
);
}

return [
compiler.assignment({
left: dataExpression,
Expand All @@ -295,16 +321,7 @@ const processSchemaType = ({
type: 'any',
},
],
statements:
nodes.length === 1
? ts.isStatement(nodes[0]!)
? []
: [
compiler.returnStatement({
expression: nodes[0],
}),
]
: ensureStatements(nodes),
statements: mapCallbackStatements,
}),
],
}),
Expand Down Expand Up @@ -344,17 +361,6 @@ const processSchemaType = ({
}
}

if (nodes.length) {
nodes.push(
compiler.returnStatement({
expression:
typeof dataExpression === 'string'
? compiler.identifier({ text: dataExpression })
: dataExpression,
}),
);
}

return nodes;
}

Expand Down Expand Up @@ -406,16 +412,7 @@ const processSchemaType = ({
compiler.ifStatement({
expression: identifierItem,
thenStatement: compiler.block({
statements:
nodes.length === 1
? ts.isStatement(nodes[0]!)
? []
: [
compiler.returnStatement({
expression: nodes[0],
}),
]
: ensureStatements(nodes),
statements: ensureStatements(nodes),
}),
}),
compiler.returnStatement({ expression: identifierItem }),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This file is auto-generated by @hey-api/openapi-ts

import type { GetFooResponse } from './types.gen';
import type { GetFooResponse, NestedDateObjectResponse } from './types.gen';

const fooSchemaResponseTransformer = (data: any) => {
if (data.foo) {
Expand All @@ -20,4 +20,18 @@ export const getFooResponseTransformer = async (data: any): Promise<GetFooRespon
return fooSchemaResponseTransformer(item);
});
return data;
};

const nestedDateObjectSchemaResponseTransformer = (data: any) => {
if (data.foo) {
if (data.foo.bar) {
data.foo.bar = new Date(data.foo.bar);
}
}
return data;
};

export const nestedDateObjectResponseTransformer = async (data: any): Promise<NestedDateObjectResponse> => {
data = nestedDateObjectSchemaResponseTransformer(data);
return data;
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
// This file is auto-generated by @hey-api/openapi-ts

/**
* Object with a nested date structure
*/
export type NestedDateObject = {
foo?: {
bar?: Date;
};
};

export type Foo = {
foo?: Date;
bar?: Date | null;
Expand All @@ -22,6 +31,22 @@ export type GetFooResponses = {

export type GetFooResponse = GetFooResponses[keyof GetFooResponses];

export type NestedDateObjectData = {
body?: never;
path?: never;
query?: never;
url: '/api/nested-date-object';
};

export type NestedDateObjectResponses = {
/**
* Object with nested date
*/
200: NestedDateObject;
};

export type NestedDateObjectResponse = NestedDateObjectResponses[keyof NestedDateObjectResponses];

export type ClientOptions = {
baseUrl: `${string}://${string}` | (string & {});
};
32 changes: 32 additions & 0 deletions packages/openapi-ts/test/spec/3.1.x/transformers-any-of-null.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,42 @@
}
}
}
},
"/api/nested-date-object": {
"get": {
"operationId": "nestedDateObject",
"responses": {
"200": {
"description": "Object with nested date",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NestedDateObject"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"NestedDateObject": {
"description": "Object with a nested date structure",
"type": "object",
"properties": {
"foo": {
"type": "object",
"properties": {
"bar": {
"type": "string",
"format": "date-time"
}
}
}
}
},
"Foo": {
"type": "object",
"properties": {
Expand Down

0 comments on commit 8248f96

Please sign in to comment.