Merge pull request #22 from harsha-iiiv/fix/schema-cycle-detection
feat: Enhance schema mapping with cycle protection
This commit is contained in:
commit
78c3d91ec2
32
CHANGELOG.md
32
CHANGELOG.md
@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [3.1.2] - 2025-06-08
|
||||
|
||||
### Fixed
|
||||
- Prevent stack overflow (RangeError: Maximum call stack size exceeded) when processing recursive or cyclic OpenAPI schemas (e.g., self-referencing objects).
|
||||
- Added cycle detection to schema mapping, ensuring robust handling of recursive structures.
|
||||
|
||||
## [3.1.1] - 2025-05-26
|
||||
|
||||
### Added
|
||||
- Introduced a new executable command-line script for easier usage in Unix-like environments.
|
||||
|
||||
### Changed
|
||||
- Use new CLI entry point to use the new `bin/openapi-mcp-generator.js` file.
|
||||
- Updated build script to ensure the new CLI file has the correct permissions.
|
||||
- Refactored `index.ts` to streamline argument parsing and error handling.
|
||||
|
||||
|
||||
## [3.1.0] - 2025-05-18
|
||||
|
||||
### Added
|
||||
@ -18,6 +35,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Improved module structure with better exports
|
||||
- Enhanced detection of module execution context
|
||||
|
||||
## [3.0.0] - 2025-04-26
|
||||
|
||||
### Added
|
||||
- Streamable HTTP support for OpenAPI MCP generator, enabling efficient handling of large payloads and real-time data transfer.
|
||||
- Major architectural refactor to support streaming responses and requests.
|
||||
|
||||
### Fixed
|
||||
- Multiple bugs related to HTTP/HTTPS connection handling, stream closure, and error propagation in streaming scenarios.
|
||||
- Fixed resource leak issues on server aborts and client disconnects during streaming.
|
||||
|
||||
### Changed
|
||||
- Major version bump due to breaking changes in API and internal structures to support streaming.
|
||||
- Updated documentation to reflect new streaming capabilities and usage instructions.
|
||||
- Enhanced performance and robustness of HTTP/HTTPS transport layers.
|
||||
|
||||
## [2.0.0] - 2025-04-12
|
||||
|
||||
### Added
|
||||
|
||||
6
package-lock.json
generated
6
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "openapi-mcp-generator",
|
||||
"version": "3.1.0",
|
||||
"version": "3.1.2",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "openapi-mcp-generator",
|
||||
"version": "3.1.0",
|
||||
"version": "3.1.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@apidevtools/swagger-parser": "^10.1.1",
|
||||
@ -14,7 +14,7 @@
|
||||
"openapi-types": "^12.1.3"
|
||||
},
|
||||
"bin": {
|
||||
"openapi-mcp-generator": "dist/index.js"
|
||||
"openapi-mcp-generator": "bin/openapi-mcp-generator.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.15.2",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "openapi-mcp-generator",
|
||||
"version": "3.1.1",
|
||||
"version": "3.1.2",
|
||||
"description": "Generates MCP server code from OpenAPI specifications",
|
||||
"license": "MIT",
|
||||
"author": "Harsha",
|
||||
|
||||
@ -72,7 +72,7 @@ program
|
||||
(val) => parseInt(val, 10)
|
||||
)
|
||||
.option('--force', 'Overwrite existing files without prompting')
|
||||
.version('3.1.1') // Match package.json version
|
||||
.version('3.1.2') // Match package.json version
|
||||
.action(options => {
|
||||
runGenerator(options)
|
||||
.catch((error) => {
|
||||
|
||||
@ -153,13 +153,15 @@ export function generateInputSchemaAndDetails(operation: OpenAPIV3.OperationObje
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps an OpenAPI schema to a JSON Schema
|
||||
* Maps an OpenAPI schema to a JSON Schema with cycle protection.
|
||||
*
|
||||
* @param schema OpenAPI schema object or reference
|
||||
* @param seen WeakSet tracking already visited schema objects
|
||||
* @returns JSON Schema representation
|
||||
*/
|
||||
export function mapOpenApiSchemaToJsonSchema(
|
||||
schema: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject
|
||||
schema: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject,
|
||||
seen: WeakSet<object> = new WeakSet()
|
||||
): JSONSchema7 | boolean {
|
||||
// Handle reference objects
|
||||
if ('$ref' in schema) {
|
||||
@ -170,6 +172,14 @@ export function mapOpenApiSchemaToJsonSchema(
|
||||
// Handle boolean schemas
|
||||
if (typeof schema === 'boolean') return schema;
|
||||
|
||||
// Detect cycles
|
||||
if (seen.has(schema)) {
|
||||
console.warn(`Cycle detected in schema${schema.title ? ` "${schema.title}"` : ''}, returning generic object to break recursion.`);
|
||||
return { type: 'object' };
|
||||
}
|
||||
seen.add(schema);
|
||||
|
||||
try {
|
||||
// Create a copy of the schema to modify
|
||||
const jsonSchema: JSONSchema7 = { ...schema } as any;
|
||||
|
||||
@ -202,7 +212,7 @@ export function mapOpenApiSchemaToJsonSchema(
|
||||
|
||||
for (const [key, propSchema] of Object.entries(jsonSchema.properties)) {
|
||||
if (typeof propSchema === 'object' && propSchema !== null) {
|
||||
mappedProps[key] = mapOpenApiSchemaToJsonSchema(propSchema as OpenAPIV3.SchemaObject);
|
||||
mappedProps[key] = mapOpenApiSchemaToJsonSchema(propSchema as OpenAPIV3.SchemaObject, seen);
|
||||
} else if (typeof propSchema === 'boolean') {
|
||||
mappedProps[key] = propSchema;
|
||||
}
|
||||
@ -218,9 +228,12 @@ export function mapOpenApiSchemaToJsonSchema(
|
||||
jsonSchema.items !== null
|
||||
) {
|
||||
jsonSchema.items = mapOpenApiSchemaToJsonSchema(
|
||||
jsonSchema.items as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject
|
||||
jsonSchema.items as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject,
|
||||
seen
|
||||
);
|
||||
}
|
||||
|
||||
return jsonSchema;
|
||||
} finally {
|
||||
seen.delete(schema);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user