Migrate APIRequestFactory and RequestParameterFactory to IR types#211
Migrate APIRequestFactory and RequestParameterFactory to IR types#211MadsBogeskov wants to merge 7 commits intomainfrom
Conversation
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>
- Add OpenAPI3Document and supporting model types (schema, parameter, operation, request body, response, components, server, OrRef) - Add OpenAPI3ToIRConverter converting OAS3 → IRDocument - Add SwaggerReader.readSpec() with version detection, returning APISpec (.swagger2 or .openapi3) — both convert to IRDocument via .toIR() - Add 33 tests covering parsing, IR conversion, and version detection - Add BasicOpenAPI3.yaml fixture Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace all SwaggerSwiftML-specific DataFormat/Schema references in the resolver layer with spec-agnostic IRSchema types. Introduces IRStringFormat, IRIntegerFormat, and IRNumberFormat; adds Schema.toIR() / Node<Schema>.toIR() helpers for incremental call-site migration in APIRequestFactory and RequestParameterFactory. All 41 tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Both factories now accept IROperation and [IRParameter] instead of SwaggerSwiftML.Operation, Parameter, Swagger, and SwaggerFile — removing the SwaggerSwiftML dependency from the factory layer entirely. Supporting changes: - Delete SwaggerSwiftCore.HTTPMethod; use SwaggerSwiftIR.HTTPMethod throughout - Delete ParameterType+ToString.swift; factories use modelTypeResolver.resolve() instead - QueryElement.ValueType.array now uses IRParameterStyle? instead of CollectionFormat? - Enumeration drops the dead collectionFormat field - APIFactory converts each ML operation to IR via Operation.toIR(globalConsumes:globalParameters:) before calling the factories - New OperationToIRConverter in SwaggerToIRConverter.swift handles standalone operation conversion - Parameter.toIRParameter() bridge extension for path-level parameter conversion All 41 tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
||
| mutating func run() async throws { | ||
| guard let token = gitHubToken ?? ProcessInfo.processInfo.environment["GITHUB_TOKEN"] else { | ||
| guard let token = githubToken ?? ProcessInfo.processInfo.environment["GITHUB_TOKEN"] else { |
There was a problem hiding this comment.
Error message references old CLI flag name
Medium Severity
Renaming gitHubToken to githubToken changes the auto-generated CLI flag from --git-hub-token to --github-token (Swift ArgumentParser derives kebab-case from camelCase). The error message on line 31 still references --git-hub-token, so users who see this error will try a flag that doesn't exist.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 10a1582. Configure here.
| let queryParameters = parameters.filter { | ||
| if case ParameterLocation.query = $0.location { | ||
| return true | ||
| } else { |
There was a problem hiding this comment.
Non-deterministic dictionary key selection for MIME type
Medium Severity
consumeMimeType selects the MIME type via operation.requestBody?.content.keys.first, but content is a [String: IRMediaType] dictionary whose iteration order is non-deterministic. When a request body defines multiple content types (valid in OpenAPI 3.x), the chosen MIME type varies between runs, producing non-deterministic code generation output.
Reviewed by Cursor Bugbot for commit 10a1582. Configure here.
| requestBody: operation.requestBody, | ||
| typePrefix: typeName, | ||
| swagger: swagger | ||
| serviceName: serviceName |
There was a problem hiding this comment.
Body and form-data parameters both emitted for same request
Medium Severity
resolveBodyParameters and resolveFormDataParameters are both called unconditionally with the same operation.requestBody. When a request body has both an application/json entry and a form-data entry (possible in OpenAPI 3.x), both methods produce parameters, yielding a body parameter alongside form-data parameters for the same request.
Reviewed by Cursor Bugbot for commit 10a1582. Configure here.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
There are 5 total unresolved issues (including 3 from previous reviews).
❌ 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 cc0bc44. Configure here.
| guard let schemaNode = schemaNode, let parameter = parameter else { | ||
| guard let requestBody = requestBody, | ||
| let schema = requestBody.content["application/json"]?.schema | ||
| else { |
There was a problem hiding this comment.
Body parameters silently dropped for non-JSON consumes
Medium Severity
resolveBodyParameters hardcodes requestBody.content["application/json"] to find the body schema, but the IR converter (irRequestBody(fromBodyParam:)) stores the body under consumes.first ?? "application/json". When a Swagger spec declares a non-JSON consume type (e.g. application/xml), the body is keyed by that MIME type in the IR, so the hardcoded "application/json" lookup returns nil and the body parameter is silently dropped. The old code found body parameters by location regardless of MIME type.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit cc0bc44. Configure here.
| let queryParameters = parameters.filter { | ||
| if case ParameterLocation.query = $0.location { | ||
| return true | ||
| } else { |
There was a problem hiding this comment.
Unsupported MIME types silently default to JSON
Medium Severity
consumeMimeType silently returns .json when the request body's MIME type isn't recognized by APIRequestConsumes. The old code threw APIRequestFactoryError.unsupportedMimeType, preventing generation of incorrect code. Now an endpoint with e.g. application/xml body silently gets JSON serialization, producing broken generated code with no warning.
Reviewed by Cursor Bugbot for commit cc0bc44. Configure here.


Summary
IROperationand[IRParameter]instead ofSwaggerSwiftML.Operation,Parameter,Swagger, andSwaggerFile— removingSwaggerSwiftMLdependency from the factory layerSwaggerSwiftCore.HTTPMethod; usesSwaggerSwiftIR.HTTPMethodthroughout (addstrace)ParameterType+ToString.swift; factories usemodelTypeResolver.resolve(forSchema:...)insteadQueryElement.ValueType.arraynow usesIRParameterStyle?instead ofCollectionFormat?Enumerationdrops the deadcollectionFormatfieldAPIFactoryconverts each ML operation to IR viaOperation.toIR(globalConsumes:globalParameters:)before calling the factoriesOperationToIRConverterhandles standalone single-operation conversion without a fullSwaggercontextParameter.toIRParameter()bridge extension for path-level parameter conversionTest plan
swift test --parallel— all 41 tests pass (including golden file snapshot)🤖 Generated with Claude Code
Note
Medium Risk
Moderate risk because it refactors core codegen type resolution and request/response/parameter parsing (including consumes, query array serialization, and form-data handling), which can subtly change generated API signatures and models. Adds new IR/OpenAPI3 conversion paths that may expose edge cases around
$refqualification,allOf, and non-JSON media types.Overview
Migrates SwaggerSwift’s codegen pipeline to a new spec-agnostic intermediate representation (
SwaggerSwiftIR), adding a dedicatedSwaggerSwiftIRtarget and new converters from both Swagger 2.0 and OpenAPI 3.x intoIRDocument/IROperation/IRSchema.APIRequestFactory,RequestParameterFactory,ModelTypeResolver, andObjectModelFactoryare refactored to consume IR types (dropping directSwaggerSwiftML/SwaggerFiledependencies), including updated handling for request bodies, form-data viarequestBodycontent, query array serialization viaIRParameterStyle,allOf/additionalProperties, and service-qualified$reftyping.Cleans up related plumbing: removes
SwaggerSwiftCore.HTTPMethodin favor ofSwaggerSwiftIR.HTTPMethod(addstrace), deletesParameterType+ToString.swift, simplifiesEnumerationby removingcollectionFormat, and updates CLI/CI flag naming from--git-hub-tokento--github-token(note: CLI validation error string still references the old flag).Reviewed by Cursor Bugbot for commit cc0bc44. Bugbot is set up for automated code reviews on this repo. Configure here.