-
Notifications
You must be signed in to change notification settings - Fork 0
Migrate ModelTypeResolver and ObjectModelFactory to IR types #210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
c318688
604be66
ee859f0
6b6662e
8ad1c98
80867ee
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| # CLAUDE.md | ||
|
|
||
| This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. | ||
|
|
||
| ## What This Project Does | ||
|
|
||
| SwaggerSwift is a Swift code generator that converts Swagger (OpenAPI 2.0) specifications into a fully-typed, async/await-ready Swift networking layer. It downloads specs from GitHub and generates Swift packages with API clients, data models, and shared utilities. | ||
|
|
||
| ## Commands | ||
|
|
||
| ```bash | ||
| # Build | ||
| swift build -c release | ||
| # Binary: .build/release/swaggerswift | ||
|
|
||
| # Run tests | ||
| swift test --parallel | ||
|
|
||
| # Run a single test | ||
| swift test --filter SwaggerSwiftMLTests.ParserTests/testSomething | ||
|
|
||
| # Run the generator locally | ||
| export GITHUB_TOKEN="ghp_…" | ||
| .build/release/swaggerswift --swagger-file-path ./SwaggerFile.yml --verbose | ||
| ``` | ||
|
|
||
| Code style is enforced by `swift-format` (`.swift-format` config): 120-char line limit, 4-space indentation. | ||
|
|
||
| ## Architecture | ||
|
|
||
| Three targets in `Package.swift`: | ||
|
|
||
| **`SwaggerSwiftML`** — Parsing layer. Defines all Swagger data model types (`Operation`, `Parameter`, `Schema`, `Response`, etc.) and parses JSON/YAML specs via Yams. Produces an in-memory Swagger AST. | ||
|
|
||
| **`SwaggerSwiftCore`** — Code generation engine. Takes the parsed AST and produces Swift source files via Stencil templates. Key components: | ||
| - `Generator` — Main orchestrator; reads `SwaggerFile.yml`, downloads specs from GitHub, and drives the pipeline | ||
| - `ModelTypeResolver` — Maps Swagger types (primitives, enums, arrays, objects, `$ref`) to Swift types | ||
| - `APIRequestFactory` / `APIResponseTypeFactory` — Build async API client methods from `Operation` nodes | ||
| - `TemplateRenderer` — Renders Stencil templates from `Sources/SwaggerSwiftCore/Templates/` | ||
|
|
||
| **`SwaggerSwift`** (executable) — Thin CLI wrapper using swift-argument-parser. Entry point: `MyMain.swift`. | ||
|
|
||
| ### Data Flow | ||
|
|
||
| ``` | ||
| SwaggerFile.yml → Generator → GitHub API (downloads specs) | ||
| → SwaggerParser (SwaggerSwiftML) | ||
| → ModelTypeResolver → ObjectModelFactory | ||
| → APIRequestFactory → TemplateRenderer (Stencil) | ||
| → FileWriter → Generated Swift Package | ||
| ``` | ||
|
|
||
| ### Generated Output Structure | ||
|
|
||
| ``` | ||
| Generated/ | ||
| └── MyAPI/ | ||
| ├── Package.swift | ||
| └── Sources/ | ||
| ├── MyAPIShared/ # Shared networking utilities (templates) | ||
| └── UserService/ # One target per service | ||
| ├── UserServiceClient.swift | ||
| └── Models/ | ||
| ``` | ||
|
|
||
| ### Template System | ||
|
|
||
| Stencil templates live in `Sources/SwaggerSwiftCore/Templates/`. Each template maps to a generated file type (API client, model struct, enum, typealias, shared library files). Templates are loaded from the bundle at runtime — the `Dockerfile` copies them explicitly. | ||
|
|
||
| ### Testing | ||
|
|
||
| - `SwaggerSwiftMLTests` — Unit tests for parsing; uses YAML/JSON fixtures in `Tests/SwaggerSwiftMLTests/TestResources/` | ||
| - `SwaggerSwiftCoreTests` — Unit tests for code generation; includes golden file (snapshot) tests | ||
|
|
||
| CI runs on both macOS (Xcode 26.2) and Linux (Swift 6.0) via `.github/workflows/build_and_test.yml`. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -206,28 +206,23 @@ public struct APIRequestFactory { | |
| } | ||
|
|
||
| if let schemaNode = request.schema { | ||
| switch schemaNode { | ||
| case .node(let schema): | ||
| let resolvedType = try modelTypeResolver.resolve( | ||
| forSchema: schema, | ||
| typeNamePrefix: prefix, | ||
| namespace: swagger.serviceName, | ||
| swagger: swagger | ||
| ) | ||
|
|
||
| return (resolvedType.propertyType, resolvedType.inlineModelDefinitions) | ||
| case .reference(let ref): | ||
| let schema = try swagger.findSchema(reference: ref) | ||
| let modelReference = try ModelReference(rawValue: ref) | ||
|
|
||
| let resolvedType = schema.type(named: modelReference.typeName) | ||
|
|
||
| if case .array = resolvedType { | ||
| return (TypeType.object(typeName: modelReference.typeName), []) | ||
| } else { | ||
| return (resolvedType, []) | ||
| } | ||
| let irSchema = schemaNode.toIR() | ||
| let serviceName = swagger.serviceName | ||
|
|
||
| // A bare $ref in a response schema maps directly to the named type without namespace | ||
| // qualification — matching the historical codegen behaviour where top-level response | ||
| // type references are not prefixed with the service name. | ||
| if case .reference(let name) = irSchema.type { | ||
| return (.object(typeName: name), []) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Response $ref ignores actual type of referenced schemaMedium Severity When a response or body schema contains a bare Additional Locations (1)
Reviewed by Cursor Bugbot for commit 6b6662e. Configure here. |
||
| } | ||
|
|
||
| let resolvedType = try modelTypeResolver.resolve( | ||
| forSchema: irSchema, | ||
| typeNamePrefix: prefix, | ||
| namespace: serviceName, | ||
| serviceName: serviceName | ||
| ) | ||
| return (resolvedType.propertyType, resolvedType.inlineModelDefinitions) | ||
| } else { | ||
| return (.void, []) | ||
| } | ||
|
|
||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error message references old CLI flag name
Medium Severity
The property was renamed from
gitHubTokentogithubToken, which changes the swift-argument-parser derived CLI flag from--git-hub-tokento--github-token. TheValidationErrormessage still references the old--git-hub-tokenflag, so users following the error guidance will use a flag that doesn't exist.Reviewed by Cursor Bugbot for commit 8ad1c98. Configure here.