Skip to content

Add SwaggerSwiftIR target with Swagger 2.0 → IR converter#208

Open
MadsBogeskov wants to merge 2 commits intomainfrom
add-swagger-swift-ir
Open

Add SwaggerSwiftIR target with Swagger 2.0 → IR converter#208
MadsBogeskov wants to merge 2 commits intomainfrom
add-swagger-swift-ir

Conversation

@MadsBogeskov
Copy link
Copy Markdown
Contributor

@MadsBogeskov MadsBogeskov commented Apr 7, 2026

Summary

  • Adds a new SwaggerSwiftIR target with spec-agnostic intermediate representation types (IRDocument, IROperation, IRParameter, IRRequestBody, IRResponse, IRSchema, IRServer, etc.)
  • Adds SwaggerToIRConverter in SwaggerSwiftML that converts the existing Swagger 2.0 struct into IRDocument
  • Both Swagger 2.0 and the upcoming OpenAPI 3.x parser will convert into these IR types; SwaggerSwiftCore will eventually consume IR instead of Swagger directly

This is the first step toward OpenAPI 3.x support. No existing code is modified — purely additive.

Key design decisions

  • SwaggerSwiftIR has zero dependencies (pure Swift value types)
  • in: body parameters are converted to IRRequestBody with the correct MIME type from consumes
  • in: formData parameters are aggregated into a single IRRequestBody (auto-detects multipart/form-data vs application/x-www-form-urlencoded based on presence of file params)
  • IRParameterLocation has no body or formData cases — request bodies are first-class via IRRequestBody
  • IRResponseCode supports .status(Int), .range("2XX"), and .default (OAS3-ready)
  • CollectionFormat maps to IRParameterStyle (e.g. .csv.simple, .multi.form)
  • x-nullable custom field maps to nullable: true on IRSchema

Test plan

  • All 98 existing tests pass unchanged
  • Future PR: add unit tests for SwaggerToIRConverter covering body/formData/schema/ref conversion

🤖 Generated with Claude Code


Note

Low Risk
Low risk additive change that introduces a new SwaggerSwiftIR module and wiring in Package.swift; the main risk is limited to build/package integration and correctness of the new Swagger→IR mapping.

Overview
Introduces a new SwaggerSwiftIR target containing spec-agnostic intermediate representation value types (IRDocument, IRSchema, IROperation, request/response/parameter/server models) intended to decouple codegen from Swagger/OpenAPI versions.

Adds SwaggerToIRConverter in SwaggerSwiftML plus a Swagger.toIR() convenience to convert existing Swagger 2.0 parse trees into the IR, including $ref resolution, request-body aggregation for in: body/in: formData, response mapping, and collectionFormat→parameter-style handling.

Updates Package.swift to include the new target and makes SwaggerSwiftML depend on it; also adds CLAUDE.md repository guidance.

Reviewed by Cursor Bugbot for commit 604be66. Bugbot is set up for automated code reviews on this repo. Configure here.

MadsBogeskov and others added 2 commits April 7, 2026 10:39
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces a new `SwaggerSwiftIR` target containing spec-agnostic
intermediate representation types that both Swagger 2.0 and future
OpenAPI 3.x parsers will convert into. Adds `SwaggerToIRConverter`
in `SwaggerSwiftML` to convert the existing `Swagger` struct into
`IRDocument`, including full schema, parameter, request body, and
response mapping.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 7, 2026

Test Results (ubuntu-latest)

98 tests  ±0   98 ✅ ±0   2s ⏱️ ±0s
 1 suites ±0    0 💤 ±0 
 1 files   ±0    0 ❌ ±0 

Results for commit 604be66. ± Comparison against base commit b676a08.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 7, 2026

Test Results (macos-latest)

98 tests  ±0   98 ✅ ±0   7s ⏱️ +3s
 1 suites ±0    0 💤 ±0 
 1 files   ±0    0 ❌ ±0 

Results for commit 604be66. ± Comparison against base commit b676a08.

@MadsBogeskov MadsBogeskov enabled auto-merge April 7, 2026 10:01
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 4 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 604be66. Configure here.

case .pipes: return .pipeDelimited
case .multi: return .form
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CSV maps to simple style, wrong for query parameters

High Severity

irParameterStyle maps .csv to .simple unconditionally, but per the Swagger 2.0 → OpenAPI 3.0 mapping spec, csv for query parameters converts to style: form with explode: false, not simple. The simple style is only valid for path and header parameters. Since .csv is the default collectionFormat in Swagger 2.0, this affects every array-typed query parameter without an explicit collection format — producing semantically invalid IR that will cause incorrect serialization downstream.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 604be66. Configure here.

switch collectionFormat {
case .csv: return .simple
case .ssv: return .spaceDelimited
case .tsv: return .spaceDelimited
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TSV incorrectly mapped to spaceDelimited style

Medium Severity

CollectionFormat.tsv (tab-separated values, delimiter \t) is mapped to IRParameterStyle.spaceDelimited (space-separated values, delimiter ). These use fundamentally different delimiter characters. OpenAPI 3.0 has no direct equivalent for TSV, so this mapping silently changes the serialization behavior from tab-separated to space-separated.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 604be66. Configure here.

case .schema(let s):
additionalProperties = .schema(irSchema(from: s))
}
return .object(IRObjectSchema(additionalProperties: additionalProperties))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dictionary schema drops named property keys during conversion

Medium Severity

The .dictionary(let valueType, _) pattern discards the keys: [KeyType] associated value, which represents named properties defined alongside additionalProperties. The resulting IRObjectSchema is created with empty properties and required, losing all named property information from dictionary-type schemas.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 604be66. Configure here.

content["application/json"] = IRMediaType(schema: irSchema(from: schemaNode))
}
return IRResponse(description: response.description, content: content)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Response MIME type hardcoded, ignores produces field

Medium Severity

irResponse always keys response content under "application/json", completely ignoring the produces field available on both Operation and Swagger. This is inconsistent with how consumes is correctly resolved for request bodies via effectiveConsumes at line 71. APIs producing XML, plain text, binary, or any other non-JSON MIME type will have their responses mislabeled as application/json in the IR.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 604be66. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant