Skip to content

Commit

Permalink
Merge pull request #1336 from hey-api/fix/transformers-any-of-null
Browse files Browse the repository at this point in the history
fix: experimental parser transforms anyOf date and null
  • Loading branch information
mrlubos authored Nov 24, 2024
2 parents 1d3ad26 + 6857da8 commit 4d8c6ac
Show file tree
Hide file tree
Showing 15 changed files with 328 additions and 92 deletions.
5 changes: 5 additions & 0 deletions .changeset/new-timers-tie.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@hey-api/openapi-ts': patch
---

fix: experimental parser transforms anyOf date and null
54 changes: 28 additions & 26 deletions packages/openapi-ts/src/openApi/3.0.x/parser/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,26 @@ export const getSchemaType = ({
}
};

const parseSchemaJsDoc = ({
irSchema,
schema,
}: {
irSchema: IRSchemaObject;
schema: SchemaObject;
}) => {
if (schema.deprecated !== undefined) {
irSchema.deprecated = schema.deprecated;
}

if (schema.description) {
irSchema.description = schema.description;
}

if (schema.title) {
irSchema.title = schema.title;
}
};

const parseSchemaMeta = ({
irSchema,
schema,
Expand Down Expand Up @@ -89,10 +109,6 @@ const parseSchemaMeta = ({
} else if (schema.writeOnly) {
irSchema.accessScope = 'write';
}

if (schema.title) {
irSchema.title = schema.title;
}
};

const parseArray = ({
Expand Down Expand Up @@ -238,22 +254,6 @@ const parseString = ({
return irSchema;
};

const parseSchemaJsDoc = ({
irSchema,
schema,
}: {
irSchema: IRSchemaObject;
schema: SchemaObject;
}) => {
if (schema.deprecated !== undefined) {
irSchema.deprecated = schema.deprecated;
}

if (schema.description) {
irSchema.description = schema.description;
}
};

const initIrSchema = ({ schema }: { schema: SchemaObject }): IRSchemaObject => {
const irSchema: IRSchemaObject = {};

Expand Down Expand Up @@ -636,17 +636,19 @@ const parseNullableType = ({
}): IRSchemaObject => {
if (!irSchema) {
irSchema = initIrSchema({ schema });

parseSchemaMeta({
irSchema,
schema,
});
}

const typeIrSchema: IRSchemaObject = {};

parseSchemaMeta({
irSchema: typeIrSchema,
schema,
});

const schemaItems: Array<IRSchemaObject> = [
parseOneType({
context,
irSchema: {},
irSchema: typeIrSchema,
schema,
}),
{
Expand Down
76 changes: 41 additions & 35 deletions packages/openapi-ts/src/openApi/3.1.x/parser/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,26 @@ export const getSchemaTypes = ({
return [];
};

const parseSchemaJsDoc = ({
irSchema,
schema,
}: {
irSchema: IRSchemaObject;
schema: SchemaObject;
}) => {
if (schema.deprecated !== undefined) {
irSchema.deprecated = schema.deprecated;
}

if (schema.description) {
irSchema.description = schema.description;
}

if (schema.title) {
irSchema.title = schema.title;
}
};

const parseSchemaMeta = ({
irSchema,
schema,
Expand Down Expand Up @@ -119,10 +139,6 @@ const parseSchemaMeta = ({
} else if (schema.writeOnly) {
irSchema.accessScope = 'write';
}

if (schema.title) {
irSchema.title = schema.title;
}
};

const parseArray = ({
Expand Down Expand Up @@ -291,22 +307,6 @@ const parseString = ({
return irSchema;
};

const parseSchemaJsDoc = ({
irSchema,
schema,
}: {
irSchema: IRSchemaObject;
schema: SchemaObject;
}) => {
if (schema.deprecated !== undefined) {
irSchema.deprecated = schema.deprecated;
}

if (schema.description) {
irSchema.description = schema.description;
}
};

const initIrSchema = ({ schema }: { schema: SchemaObject }): IRSchemaObject => {
const irSchema: IRSchemaObject = {};

Expand Down Expand Up @@ -742,26 +742,32 @@ const parseManyTypes = ({
}): IRSchemaObject => {
if (!irSchema) {
irSchema = initIrSchema({ schema });

parseSchemaMeta({
irSchema,
schema,
});
}

const typeIrSchema: IRSchemaObject = {};

parseSchemaMeta({
irSchema: typeIrSchema,
schema,
});

const schemaItems: Array<IRSchemaObject> = [];

for (const type of schema.type) {
schemaItems.push(
parseOneType({
context,
irSchema: {},
schema: {
...schema,
type,
},
}),
);
if (type === 'null') {
schemaItems.push({ type: 'null' });
} else {
schemaItems.push(
parseOneType({
context,
irSchema: typeIrSchema,
schema: {
...schema,
type,
},
}),
);
}
}

irSchema = addItemsToSchema({
Expand Down
48 changes: 26 additions & 22 deletions packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ const processSchemaType = ({
});
}

const nodes: Array<ts.Expression | ts.Statement> = [];
let arrayNodes: Array<ts.Expression | ts.Statement> = [];
if (
schema.items.length === 2 &&
schema.items.find((item) => item.type === 'null' || item.type === 'void')
Expand All @@ -323,33 +323,37 @@ const processSchemaType = ({
for (const item of schema.items) {
const nodes = processSchemaType({
context,
dataExpression: 'item',
dataExpression: dataExpression || 'item',
schema: item,
});
if (nodes.length) {
const identifierItem = compiler.identifier({ text: 'item' });
// processed means the item was transformed
nodes.push(
compiler.ifStatement({
expression: identifierItem,
thenStatement: compiler.block({
statements:
nodes.length === 1
? ts.isStatement(nodes[0])
? []
: [
compiler.returnStatement({
expression: nodes[0],
}),
]
: ensureStatements(nodes),
if (dataExpression) {
arrayNodes = arrayNodes.concat(nodes);
} else {
const identifierItem = compiler.identifier({ text: 'item' });
// processed means the item was transformed
arrayNodes.push(
compiler.ifStatement({
expression: identifierItem,
thenStatement: compiler.block({
statements:
nodes.length === 1
? ts.isStatement(nodes[0])
? []
: [
compiler.returnStatement({
expression: nodes[0],
}),
]
: ensureStatements(nodes),
}),
}),
}),
compiler.returnStatement({ expression: identifierItem }),
);
compiler.returnStatement({ expression: identifierItem }),
);
}
}
}
return nodes;
return arrayNodes;
}

console.warn(
Expand Down
10 changes: 9 additions & 1 deletion packages/openapi-ts/test/3.0.x.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,13 +201,21 @@ describe(`OpenAPI ${VERSION}`, () => {
}),
description: 'handles non-exploded array query parameters',
},
{
config: createConfig({
input: 'transformers-any-of-null.json',
output: 'transformers-any-of-null',
plugins: ['@hey-api/transformers'],
}),
description: 'transforms nullable date property',
},
{
config: createConfig({
input: 'transformers-array.json',
output: 'transformers-array',
plugins: ['@hey-api/transformers'],
}),
description: 'correctly transforms an array',
description: 'transforms an array',
},
{
config: createConfig({
Expand Down
10 changes: 9 additions & 1 deletion packages/openapi-ts/test/3.1.x.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,13 +262,21 @@ describe(`OpenAPI ${VERSION}`, () => {
description:
'does not set oneOf composition ref model properties as required',
},
{
config: createConfig({
input: 'transformers-any-of-null.json',
output: 'transformers-any-of-null',
plugins: ['@hey-api/transformers'],
}),
description: 'transforms nullable date property',
},
{
config: createConfig({
input: 'transformers-array.json',
output: 'transformers-array',
plugins: ['@hey-api/transformers'],
}),
description: 'correctly transforms an array',
description: 'transforms an array',
},
{
config: createConfig({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// This file is auto-generated by @hey-api/openapi-ts
export * from './types.gen';
export * from './transformers.gen';
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// This file is auto-generated by @hey-api/openapi-ts

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

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

export const getFooResponseTransformer = async (data: any): Promise<GetFooResponse> => {
data = data.map((item: any) => {
return fooSchemaResponseTransformer(item);
});
return data;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// This file is auto-generated by @hey-api/openapi-ts

export type Foo = {
foo?: string;
bar?: string | null;
};

export type GetFooData = {
body?: never;
url: '/foo';
};

export type GetFooResponses = {
/**
* OK
*/
200: Array<Foo>;
};

export type GetFooResponse = GetFooResponses[keyof GetFooResponses];
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// This file is auto-generated by @hey-api/openapi-ts
export * from './types.gen';
export * from './transformers.gen';
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// This file is auto-generated by @hey-api/openapi-ts

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

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

export const getFooResponseTransformer = async (data: any): Promise<GetFooResponse> => {
data = data.map((item: any) => {
return fooSchemaResponseTransformer(item);
});
return data;
};
Loading

0 comments on commit 4d8c6ac

Please sign in to comment.