Skip to content

Commit 211379e

Browse files
feat: add support for individual enum variant descriptions
1 parent aef132d commit 211379e

File tree

3 files changed

+192
-7
lines changed

3 files changed

+192
-7
lines changed

packages/openapi-generator/src/knownImports.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,16 @@ export const KNOWN_IMPORTS: KnownImports = {
125125
if (arg.type !== 'object') {
126126
return errorLeft(`Unimplemented keyof type ${arg.type}`);
127127
}
128-
const schemas: Schema[] = Object.keys(arg.properties).map((prop) => ({
129-
type: 'string',
130-
enum: [prop],
131-
}));
128+
const schemas: Schema[] = Object.keys(arg.properties).map((prop) => {
129+
const propertySchema = arg.properties[prop];
130+
return {
131+
type: 'string',
132+
enum: [prop],
133+
// Preserve the comment from the original property
134+
...(propertySchema?.comment ? { comment: propertySchema.comment } : {}),
135+
};
136+
});
137+
132138
return E.right({
133139
type: 'union',
134140
schemas,

packages/openapi-generator/src/optimize.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,14 @@ export function simplifyUnion(schema: Schema, optimize: OptimizeFn): Schema {
160160
const remainder: Schema[] = [];
161161
innerSchemas.forEach((innerSchema) => {
162162
if (isPrimitive(innerSchema) && innerSchema.enum !== undefined) {
163-
innerSchema.enum.forEach((value) => {
164-
literals[innerSchema.type].add(value);
165-
});
163+
// If this enum has a comment, preserve it in the union instead of consolidating
164+
if (innerSchema.comment) {
165+
remainder.push(innerSchema);
166+
} else {
167+
innerSchema.enum.forEach((value) => {
168+
literals[innerSchema.type].add(value);
169+
});
170+
}
166171
} else {
167172
remainder.push(innerSchema);
168173
}

packages/openapi-generator/test/openapi/comments.test.ts

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,6 +1441,180 @@ testCase(
14411441
},
14421442
);
14431443

1444+
const ROUTE_WITH_INDIVIDUAL_ENUM_DESCRIPTIONS = `
1445+
import * as t from 'io-ts';
1446+
import * as h from '@api-ts/io-ts-http';
1447+
1448+
/**
1449+
* Transaction Request State Enum with individual descriptions
1450+
*/
1451+
export const TransactionRequestState = t.keyof(
1452+
{
1453+
/** Transaction is waiting for approval from authorized users */
1454+
pendingApproval: 1,
1455+
/** Transaction was canceled by the user */
1456+
canceled: 1,
1457+
/** Transaction was rejected by approvers */
1458+
rejected: 1,
1459+
/** Transaction has been initialized but not yet processed */
1460+
initialized: 1,
1461+
/** Transaction is ready to be delivered */
1462+
pendingDelivery: 1,
1463+
/** Transaction has been successfully delivered */
1464+
delivered: 1,
1465+
},
1466+
'TransactionRequestState',
1467+
);
1468+
1469+
/**
1470+
* Route to test individual enum variant descriptions
1471+
*
1472+
* @operationId api.v1.enumVariantDescriptions
1473+
* @tag Test Routes
1474+
*/
1475+
export const route = h.httpRoute({
1476+
path: '/transactions',
1477+
method: 'GET',
1478+
request: h.httpRequest({
1479+
query: {
1480+
states: t.array(TransactionRequestState),
1481+
},
1482+
}),
1483+
response: {
1484+
200: {
1485+
result: t.string
1486+
}
1487+
},
1488+
});
1489+
`;
1490+
1491+
testCase(
1492+
'individual enum variant descriptions are preserved in oneOf',
1493+
ROUTE_WITH_INDIVIDUAL_ENUM_DESCRIPTIONS,
1494+
{
1495+
openapi: '3.0.3',
1496+
info: {
1497+
title: 'Test',
1498+
version: '1.0.0',
1499+
},
1500+
paths: {
1501+
'/transactions': {
1502+
get: {
1503+
summary: 'Route to test individual enum variant descriptions',
1504+
operationId: 'api.v1.enumVariantDescriptions',
1505+
tags: ['Test Routes'],
1506+
parameters: [
1507+
{
1508+
name: 'states',
1509+
description:
1510+
'Transaction Request State Enum with individual descriptions',
1511+
in: 'query',
1512+
required: true,
1513+
schema: {
1514+
type: 'array',
1515+
items: {
1516+
oneOf: [
1517+
{
1518+
type: 'string',
1519+
enum: ['pendingApproval'],
1520+
description:
1521+
'Transaction is waiting for approval from authorized users',
1522+
},
1523+
{
1524+
type: 'string',
1525+
enum: ['canceled'],
1526+
description: 'Transaction was canceled by the user',
1527+
},
1528+
{
1529+
type: 'string',
1530+
enum: ['rejected'],
1531+
description: 'Transaction was rejected by approvers',
1532+
},
1533+
{
1534+
type: 'string',
1535+
enum: ['initialized'],
1536+
description:
1537+
'Transaction has been initialized but not yet processed',
1538+
},
1539+
{
1540+
type: 'string',
1541+
enum: ['pendingDelivery'],
1542+
description: 'Transaction is ready to be delivered',
1543+
},
1544+
{
1545+
type: 'string',
1546+
enum: ['delivered'],
1547+
description: 'Transaction has been successfully delivered',
1548+
},
1549+
],
1550+
},
1551+
},
1552+
},
1553+
],
1554+
responses: {
1555+
200: {
1556+
description: 'OK',
1557+
content: {
1558+
'application/json': {
1559+
schema: {
1560+
type: 'object',
1561+
properties: {
1562+
result: {
1563+
type: 'string',
1564+
},
1565+
},
1566+
required: ['result'],
1567+
},
1568+
},
1569+
},
1570+
},
1571+
},
1572+
},
1573+
},
1574+
},
1575+
components: {
1576+
schemas: {
1577+
TransactionRequestState: {
1578+
title: 'TransactionRequestState',
1579+
description: 'Transaction Request State Enum with individual descriptions',
1580+
oneOf: [
1581+
{
1582+
type: 'string',
1583+
enum: ['pendingApproval'],
1584+
description: 'Transaction is waiting for approval from authorized users',
1585+
},
1586+
{
1587+
type: 'string',
1588+
enum: ['canceled'],
1589+
description: 'Transaction was canceled by the user',
1590+
},
1591+
{
1592+
type: 'string',
1593+
enum: ['rejected'],
1594+
description: 'Transaction was rejected by approvers',
1595+
},
1596+
{
1597+
type: 'string',
1598+
enum: ['initialized'],
1599+
description: 'Transaction has been initialized but not yet processed',
1600+
},
1601+
{
1602+
type: 'string',
1603+
enum: ['pendingDelivery'],
1604+
description: 'Transaction is ready to be delivered',
1605+
},
1606+
{
1607+
type: 'string',
1608+
enum: ['delivered'],
1609+
description: 'Transaction has been successfully delivered',
1610+
},
1611+
],
1612+
},
1613+
},
1614+
},
1615+
},
1616+
);
1617+
14441618
const ROUTE_WITH_ENUM_ARRAY_PARAMETER_DESCRIPTIONS = `
14451619
import * as t from 'io-ts';
14461620
import * as h from '@api-ts/io-ts-http';

0 commit comments

Comments
 (0)