Skip to content

Commit 6819180

Browse files
authored
fix: improve anon names (#2449)
1 parent daa2412 commit 6819180

File tree

2 files changed

+157
-6
lines changed

2 files changed

+157
-6
lines changed

src/processors/AsyncAPIInputProcessor.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -445,13 +445,15 @@ export class AsyncAPIInputProcessor extends AbstractInputProcessor {
445445
* Determine the best name for a schema based on available metadata and context.
446446
*
447447
* Priority order:
448+
* 0. User-provided x-modelgen-inferred-name extension (highest priority)
448449
* 1. Component schema key (from components/schemas)
449-
* 2. Schema title field
450-
* 3. Source file name (from custom resolver metadata)
451-
* 4. Message ID (for payloads)
452-
* 5. Context-based inference (property name, array item, enum)
453-
* 6. Inferred name parameter
454-
* 7. Fallback to sanitized anonymous ID
450+
* 2. Schema ID (if looks like component name)
451+
* 3. Schema title field
452+
* 4. Source file name (from custom resolver metadata)
453+
* 5. Message ID (for payloads)
454+
* 6. Context-based inference (property name, array item, enum)
455+
* 7. Inferred name parameter
456+
* 8. Fallback to sanitized anonymous ID
455457
*
456458
* @param schemaId The schema ID from AsyncAPI parser
457459
* @param schemaJson The JSON representation of the schema
@@ -466,6 +468,15 @@ export class AsyncAPIInputProcessor extends AbstractInputProcessor {
466468
context?: SchemaContext,
467469
inferredName?: string
468470
): string {
471+
// Priority 0: User-provided x-modelgen-inferred-name extension (highest priority)
472+
const existingInferredName = schemaJson?.[this.MODELINA_INFERRED_NAME];
473+
if (existingInferredName && typeof existingInferredName === 'string') {
474+
Logger.debug(
475+
`Using user-provided x-modelgen-inferred-name: ${existingInferredName}`
476+
);
477+
return existingInferredName;
478+
}
479+
469480
// Priority 1: Component schema key from context
470481
if (context?.componentKey) {
471482
Logger.debug(`Using component key from context: ${context.componentKey}`);

test/processors/AsyncAPIInputProcessor.spec.ts

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1639,4 +1639,144 @@ describe('AsyncAPIInputProcessor', () => {
16391639
);
16401640
});
16411641
});
1642+
1643+
describe('x-modelgen-inferred-name extension', () => {
1644+
test('should respect user-provided x-modelgen-inferred-name for inline enum', async () => {
1645+
const doc = {
1646+
asyncapi: '2.0.0',
1647+
info: { title: 'Test', version: '1.0.0' },
1648+
channels: {
1649+
test: {
1650+
subscribe: {
1651+
message: {
1652+
payload: {
1653+
$ref: '#/components/schemas/TestPayload'
1654+
}
1655+
}
1656+
}
1657+
}
1658+
},
1659+
components: {
1660+
schemas: {
1661+
TestPayload: {
1662+
type: 'object',
1663+
properties: {
1664+
status: {
1665+
'x-modelgen-inferred-name': 'Status',
1666+
type: 'string',
1667+
enum: ['active', 'inactive']
1668+
}
1669+
}
1670+
}
1671+
}
1672+
}
1673+
};
1674+
const processor = new AsyncAPIInputProcessor();
1675+
const commonInputModel = await processor.process(doc);
1676+
1677+
// The enum should be named "Status", NOT "TestPayloadStatusEnum"
1678+
const schema = AsyncAPIInputProcessor.convertToInternalSchema(
1679+
commonInputModel.originalInput.schemas()[0] as any
1680+
) as any;
1681+
expect(schema.properties.status['x-modelgen-inferred-name']).toEqual(
1682+
'Status'
1683+
);
1684+
});
1685+
1686+
test('should respect user-provided x-modelgen-inferred-name for inline object', async () => {
1687+
const doc = {
1688+
asyncapi: '2.0.0',
1689+
info: { title: 'Test', version: '1.0.0' },
1690+
channels: {
1691+
test: {
1692+
subscribe: {
1693+
message: {
1694+
payload: {
1695+
$ref: '#/components/schemas/TestPayload'
1696+
}
1697+
}
1698+
}
1699+
}
1700+
},
1701+
components: {
1702+
schemas: {
1703+
TestPayload: {
1704+
type: 'object',
1705+
properties: {
1706+
nested: {
1707+
'x-modelgen-inferred-name': 'CustomNestedObject',
1708+
type: 'object',
1709+
properties: {
1710+
value: { type: 'string' }
1711+
}
1712+
}
1713+
}
1714+
}
1715+
}
1716+
}
1717+
};
1718+
const processor = new AsyncAPIInputProcessor();
1719+
const commonInputModel = await processor.process(doc);
1720+
1721+
// The nested object should be named "CustomNestedObject", NOT "TestPayloadNested"
1722+
const schema = AsyncAPIInputProcessor.convertToInternalSchema(
1723+
commonInputModel.originalInput.schemas()[0] as any
1724+
) as any;
1725+
expect(schema.properties.nested['x-modelgen-inferred-name']).toEqual(
1726+
'CustomNestedObject'
1727+
);
1728+
});
1729+
1730+
test('should still use context-based naming for schemas without the extension', async () => {
1731+
const doc = {
1732+
asyncapi: '2.0.0',
1733+
info: { title: 'Test', version: '1.0.0' },
1734+
channels: {
1735+
test: {
1736+
subscribe: {
1737+
message: {
1738+
payload: {
1739+
$ref: '#/components/schemas/TestPayload'
1740+
}
1741+
}
1742+
}
1743+
}
1744+
},
1745+
components: {
1746+
schemas: {
1747+
TestPayload: {
1748+
type: 'object',
1749+
properties: {
1750+
statusWithExtension: {
1751+
'x-modelgen-inferred-name': 'MyCustomStatus',
1752+
type: 'string',
1753+
enum: ['a', 'b']
1754+
},
1755+
statusWithoutExtension: {
1756+
type: 'string',
1757+
enum: ['x', 'y']
1758+
}
1759+
}
1760+
}
1761+
}
1762+
}
1763+
};
1764+
const processor = new AsyncAPIInputProcessor();
1765+
const commonInputModel = await processor.process(doc);
1766+
1767+
const schema = AsyncAPIInputProcessor.convertToInternalSchema(
1768+
commonInputModel.originalInput.schemas()[0] as any
1769+
) as any;
1770+
1771+
// Schema WITH extension should use the provided name
1772+
expect(
1773+
schema.properties.statusWithExtension['x-modelgen-inferred-name']
1774+
).toEqual('MyCustomStatus');
1775+
1776+
// Schema WITHOUT extension should use context-based inferred name
1777+
expect(
1778+
schema.properties.statusWithoutExtension['x-modelgen-inferred-name']
1779+
).toEqual('TestPayloadStatusWithoutExtensionEnum');
1780+
});
1781+
});
16421782
});

0 commit comments

Comments
 (0)