From b520174f4420d4392fd49e06135a7f060c6b55ab Mon Sep 17 00:00:00 2001
From: Kostis Stefanou <kostistefanou@gmail.com>
Date: Thu, 7 Mar 2024 15:20:37 +0200
Subject: [PATCH 1/7] [Generator] Add support of deepObject style in query
 params

https://github.com/apple/swift-openapi-generator/issues/259

~Depends on https://github.com/apple/swift-openapi-runtime/pull/100
landing first and getting released, and the version dependency being
bumped here.~

Added `deepObject` style to serializer & parser in order to support nested keys on query parameters.

Support nested keys on query parameters.

Adapted snippet tests (SnippetBasedReferenceTests)
---
 .../Translator/CommonTypes/Constants.swift    |  3 ++
 .../Parameters/TypedParameter.swift           |  6 ++-
 .../SnippetBasedReferenceTests.swift          | 48 ++++++++++++++++++-
 3 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift b/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift
index d1fbedcf..72eed786 100644
--- a/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift
+++ b/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift
@@ -319,6 +319,9 @@ enum Constants {
 
                 /// The form style.
                 static let form = "form"
+                
+                /// The deepObject style.
+                static let deepObject = "deepObject"
             }
         }
 
diff --git a/Sources/_OpenAPIGeneratorCore/Translator/Parameters/TypedParameter.swift b/Sources/_OpenAPIGeneratorCore/Translator/Parameters/TypedParameter.swift
index d61957ab..bd7db128 100644
--- a/Sources/_OpenAPIGeneratorCore/Translator/Parameters/TypedParameter.swift
+++ b/Sources/_OpenAPIGeneratorCore/Translator/Parameters/TypedParameter.swift
@@ -130,7 +130,10 @@ extension FileTranslator {
             let location = parameter.location
             switch location {
             case .query:
-                guard case .form = style else {
+                switch style {
+                case .form, .deepObject:
+                    break
+                default:
                     try diagnostics.emitUnsupported(
                         "Query params of style \(style.rawValue), explode: \(explode)",
                         foundIn: foundIn
@@ -243,6 +246,7 @@ extension OpenAPI.Parameter.SchemaContext.Style {
     var runtimeName: String {
         switch self {
         case .form: return Constants.Components.Parameters.Style.form
+        case .deepObject: return Constants.Components.Parameters.Style.deepObject
         default: preconditionFailure("Unsupported style")
         }
     }
diff --git a/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift b/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift
index 0ddd7b5e..ada1de32 100644
--- a/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift
+++ b/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift
@@ -2539,6 +2539,18 @@ final class SnippetBasedReferenceTests: XCTestCase {
                       type: array
                       items:
                         type: string
+                  - name: sort
+                    in: query
+                    required: true
+                    style: deepObject
+                    explode: true
+                    schema:
+                      type: object
+                      properties:
+                        option1:
+                          type: string
+                        option2:
+                          type: string
                 responses:
                   default:
                     description: Response
@@ -2549,18 +2561,36 @@ final class SnippetBasedReferenceTests: XCTestCase {
                         public var single: Swift.String?
                         public var manyExploded: [Swift.String]?
                         public var manyUnexploded: [Swift.String]?
+                        public struct sortPayload: Codable, Hashable, Sendable {
+                            public var option1: Swift.String?
+                            public var option2: Swift.String?
+                            public init(
+                                option1: Swift.String? = nil,
+                                option2: Swift.String? = nil
+                            ) {
+                                self.option1 = option1
+                                self.option2 = option2
+                            }
+                            public enum CodingKeys: String, CodingKey {
+                                case option1
+                                case option2
+                            }
+                        }
+                        public var sort: Operations.get_sol_foo.Input.Query.sortPayload
                         public init(
                             single: Swift.String? = nil,
                             manyExploded: [Swift.String]? = nil,
-                            manyUnexploded: [Swift.String]? = nil
+                            manyUnexploded: [Swift.String]? = nil,
+                            sort: Operations.get_sol_foo.Input.Query.sortPayload
                         ) {
                             self.single = single
                             self.manyExploded = manyExploded
                             self.manyUnexploded = manyUnexploded
+                            self.sort = sort
                         }
                     }
                     public var query: Operations.get_sol_foo.Input.Query
-                    public init(query: Operations.get_sol_foo.Input.Query = .init()) {
+                    public init(query: Operations.get_sol_foo.Input.Query) {
                         self.query = query
                     }
                 }
@@ -2597,6 +2627,13 @@ final class SnippetBasedReferenceTests: XCTestCase {
                         name: "manyUnexploded",
                         value: input.query.manyUnexploded
                     )
+                    try converter.setQueryItemAsURI(
+                        in: &request,
+                        style: .deepObject,
+                        explode: true,
+                        name: "sort",
+                        value: input.query.sort
+                    )
                     return (request, nil)
                 }
                 """,
@@ -2623,6 +2660,13 @@ final class SnippetBasedReferenceTests: XCTestCase {
                             explode: false,
                             name: "manyUnexploded",
                             as: [Swift.String].self
+                        ),
+                        sort: try converter.getRequiredQueryItemAsURI(
+                            in: request.soar_query,
+                            style: .deepObject,
+                            explode: true,
+                            name: "sort",
+                            as: Operations.get_sol_foo.Input.Query.sortPayload.self
                         )
                     )
                     return Operations.get_sol_foo.Input(query: query)

From ad9f075227bc196c8e20f4cd453a93789e2102a7 Mon Sep 17 00:00:00 2001
From: Kostis Stefanou <kostistefanou@gmail.com>
Date: Tue, 16 Apr 2024 16:41:07 +0300
Subject: [PATCH 2/7] Update SwiftOpenAPIRuntime library dependency

---
 Package.swift | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Package.swift b/Package.swift
index 44e952d8..13eb1f7c 100644
--- a/Package.swift
+++ b/Package.swift
@@ -54,7 +54,7 @@ let package = Package(
         // Tests-only: Runtime library linked by generated code, and also
         // helps keep the runtime library new enough to work with the generated
         // code.
-        .package(url: "https://github.com/apple/swift-openapi-runtime", from: "1.3.2"),
+        .package(url: "https://github.com/apple/swift-openapi-runtime", from: "1.4.0"),
         .package(url: "https://github.com/apple/swift-http-types", from: "1.0.2"),
     ],
     targets: [

From 28866982e48b4b5fe7117771dbe1b9d4dbab5bdf Mon Sep 17 00:00:00 2001
From: Kostis Stefanou <kostistefanou@gmail.com>
Date: Wed, 17 Apr 2024 18:48:22 +0300
Subject: [PATCH 3/7] Update petstore.yaml with deepObject parameter

---
 .../Resources/Docs/petstore.yaml              | 12 ++++++++
 .../ReferenceSources/Petstore/Client.swift    |  7 +++++
 .../ReferenceSources/Petstore/Server.swift    |  7 +++++
 .../ReferenceSources/Petstore/Types.swift     | 28 +++++++++++++++++++
 4 files changed, 54 insertions(+)

diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/petstore.yaml b/Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/petstore.yaml
index 1d9a5ed5..56a8f46e 100644
--- a/Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/petstore.yaml
+++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/petstore.yaml
@@ -69,6 +69,18 @@ paths:
           schema:
             format: uuid
             type: string
+        - name: sort
+          in: query
+          required: false
+          style: deepObject
+          explode: true
+          schema:
+            type: object
+            properties:
+              id:
+                type: string
+              name:
+                type: string
         - $ref: '#/components/parameters/query.born-since'
       responses:
         '200':
diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift
index 25f1f53d..1bf61f06 100644
--- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift
+++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift
@@ -87,6 +87,13 @@ public struct Client: APIProtocol {
                     name: "My-Request-UUID",
                     value: input.headers.myRequestUUID
                 )
+                try converter.setQueryItemAsURI(
+                    in: &request,
+                    style: .deepObject,
+                    explode: true,
+                    name: "sort",
+                    value: input.query.sort
+                )
                 try converter.setQueryItemAsURI(
                     in: &request,
                     style: .form,
diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift
index c7a02fcf..7f88982f 100644
--- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift
+++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift
@@ -187,6 +187,13 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol {
                         name: "feeds",
                         as: Operations.ListPets.Input.Query.FeedsPayload.self
                     ),
+                    sort: try converter.getOptionalQueryItemAsURI(
+                        in: request.soar_query,
+                        style: .deepObject,
+                        explode: true,
+                        name: "sort",
+                        as: Operations.listPets.Input.Query.sortPayload.self
+                    ),
                     since: try converter.getOptionalQueryItemAsURI(
                         in: request.soar_query,
                         style: .form,
diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift
index cdcb3785..09b836fc 100644
--- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift
+++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift
@@ -1895,6 +1895,31 @@ public enum Operations {
                 public typealias FeedsPayload = [Operations.ListPets.Input.Query.FeedsPayloadPayload]
                 /// - Remark: Generated from `#/paths/pets/GET/query/feeds`.
                 public var feeds: Operations.ListPets.Input.Query.FeedsPayload?
+                /// - Remark: Generated from `#/paths/pets/GET/query/sort`.
+                public struct SortPayload: Codable, Hashable, Sendable {
+                    /// - Remark: Generated from `#/paths/pets/GET/query/sort/id`.
+                    public var id: Swift.String?
+                    /// - Remark: Generated from `#/paths/pets/GET/query/sort/name`.
+                    public var name: Swift.String?
+                    /// Creates a new `sortPayload`.
+                    ///
+                    /// - Parameters:
+                    ///   - id:
+                    ///   - name:
+                    public init(
+                        id: Swift.String? = nil,
+                        name: Swift.String? = nil
+                    ) {
+                        self.id = id
+                        self.name = name
+                    }
+                    public enum CodingKeys: String, CodingKey {
+                        case id
+                        case name
+                    }
+                }
+                /// - Remark: Generated from `#/paths/pets/GET/query/sort`.
+                public var sort: Operations.listPets.Input.Query.SortPayload?
                 /// Supply this parameter to filter pets born since the provided date.
                 ///
                 /// - Remark: Generated from `#/paths/pets/GET/query/since`.
@@ -1905,16 +1930,19 @@ public enum Operations {
                 ///   - limit: How many items to return at one time (max 100)
                 ///   - habitat:
                 ///   - feeds:
+                ///   - sort:
                 ///   - since: Supply this parameter to filter pets born since the provided date.
                 public init(
                     limit: Swift.Int32? = nil,
                     habitat: Operations.ListPets.Input.Query.HabitatPayload? = nil,
                     feeds: Operations.ListPets.Input.Query.FeedsPayload? = nil,
+                    sort: Operations.listPets.Input.Query.SortPayload? = nil,
                     since: Components.Parameters.Query_bornSince? = nil
                 ) {
                     self.limit = limit
                     self.habitat = habitat
                     self.feeds = feeds
+                    self.sort = sort
                     self.since = since
                 }
             }

From 69912909f2a87130f9061aeb807135c8d9f19cd3 Mon Sep 17 00:00:00 2001
From: Kostis Stefanou <kostistefanou@gmail.com>
Date: Sat, 26 Oct 2024 15:53:02 +0300
Subject: [PATCH 4/7] Add Unite tests for DeepObject.

---
 Package.swift                                                 | 2 +-
 .../Translator/Parameters/TypedParameter.swift                | 4 +++-
 Tests/PetstoreConsumerTests/Test_Client.swift                 | 4 ++--
 Tests/PetstoreConsumerTests/Test_Server.swift                 | 3 ++-
 4 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/Package.swift b/Package.swift
index 13eb1f7c..b4087262 100644
--- a/Package.swift
+++ b/Package.swift
@@ -54,7 +54,7 @@ let package = Package(
         // Tests-only: Runtime library linked by generated code, and also
         // helps keep the runtime library new enough to work with the generated
         // code.
-        .package(url: "https://github.com/apple/swift-openapi-runtime", from: "1.4.0"),
+        .package(url: "https://github.com/apple/swift-openapi-runtime", from: "1.5.0"),
         .package(url: "https://github.com/apple/swift-http-types", from: "1.0.2"),
     ],
     targets: [
diff --git a/Sources/_OpenAPIGeneratorCore/Translator/Parameters/TypedParameter.swift b/Sources/_OpenAPIGeneratorCore/Translator/Parameters/TypedParameter.swift
index bd7db128..d005b4ab 100644
--- a/Sources/_OpenAPIGeneratorCore/Translator/Parameters/TypedParameter.swift
+++ b/Sources/_OpenAPIGeneratorCore/Translator/Parameters/TypedParameter.swift
@@ -131,7 +131,9 @@ extension FileTranslator {
             switch location {
             case .query:
                 switch style {
-                case .form, .deepObject:
+                case .form:
+                    break
+                case .deepObject where explode:
                     break
                 default:
                     try diagnostics.emitUnsupported(
diff --git a/Tests/PetstoreConsumerTests/Test_Client.swift b/Tests/PetstoreConsumerTests/Test_Client.swift
index 76cb89f9..1973a773 100644
--- a/Tests/PetstoreConsumerTests/Test_Client.swift
+++ b/Tests/PetstoreConsumerTests/Test_Client.swift
@@ -40,7 +40,7 @@ final class Test_Client: XCTestCase {
             XCTAssertEqual(operationID, "listPets")
             XCTAssertEqual(
                 request.path,
-                "/pets?limit=24&habitat=water&feeds=herbivore&feeds=carnivore&since=2023-01-18T10%3A04%3A11Z"
+                "/pets?limit=24&habitat=water&feeds=herbivore&feeds=carnivore&sort%5Bid%5D=ascending&sort%5Bname%5D=descending&since=2023-01-18T10%3A04%3A11Z"
             )
             XCTAssertEqual(baseURL.absoluteString, "/api")
             XCTAssertEqual(request.method, .get)
@@ -66,7 +66,7 @@ final class Test_Client: XCTestCase {
         }
         let response = try await client.listPets(
             .init(
-                query: .init(limit: 24, habitat: .water, feeds: [.herbivore, .carnivore], since: .test),
+                query: .init(limit: 24, habitat: .water, feeds: [.herbivore, .carnivore], sort: .init(id: "ascending", name: "descending"), since: .test),
                 headers: .init(myRequestUUID: "abcd-1234")
             )
         )
diff --git a/Tests/PetstoreConsumerTests/Test_Server.swift b/Tests/PetstoreConsumerTests/Test_Server.swift
index 9a8fa0f9..222700e9 100644
--- a/Tests/PetstoreConsumerTests/Test_Server.swift
+++ b/Tests/PetstoreConsumerTests/Test_Server.swift
@@ -33,6 +33,7 @@ final class Test_Server: XCTestCase {
             XCTAssertEqual(input.query.habitat, .water)
             XCTAssertEqual(input.query.since, .test)
             XCTAssertEqual(input.query.feeds, [.carnivore, .herbivore])
+            XCTAssertEqual(input.query.sort, .init(id: "ascending", name: "descending"))
             XCTAssertEqual(input.headers.myRequestUUID, "abcd-1234")
             return .ok(
                 .init(
@@ -43,7 +44,7 @@ final class Test_Server: XCTestCase {
         })
         let (response, responseBody) = try await server.listPets(
             .init(
-                soar_path: "/api/pets?limit=24&habitat=water&feeds=carnivore&feeds=herbivore&since=\(Date.testString)",
+                soar_path: "/api/pets?sort%5Bid%5D=ascending&sort%5Bname%5D=descending",
                 method: .get,
                 headerFields: [.init("My-Request-UUID")!: "abcd-1234"]
             ),

From 7e8f9a2ace96c67a66a7fe8c78be5edb34ab1c57 Mon Sep 17 00:00:00 2001
From: kostis stefanou <kostistefanou@gmail.com>
Date: Mon, 28 Oct 2024 21:59:15 +0200
Subject: [PATCH 5/7] Update
 Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift

Co-authored-by: Honza Dvorsky <honza@apple.com>
---
 .../SnippetBasedReferenceTests.swift                            | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift b/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift
index ada1de32..05455feb 100644
--- a/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift
+++ b/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift
@@ -2541,7 +2541,7 @@ final class SnippetBasedReferenceTests: XCTestCase {
                         type: string
                   - name: sort
                     in: query
-                    required: true
+                    required: false
                     style: deepObject
                     explode: true
                     schema:

From 1334311250b199e61e442e3932995f66ae82e006 Mon Sep 17 00:00:00 2001
From: Kostis Stefanou <kostistefanou@gmail.com>
Date: Tue, 11 Feb 2025 10:50:05 +0200
Subject: [PATCH 6/7] Add more Tests for requred & optionals params.

---
 Package.swift                                 |  2 +-
 .../Resources/Docs/petstore.yaml              | 16 ++++++
 .../ReferenceSources/Petstore/Client.swift    |  7 +++
 .../ReferenceSources/Petstore/Server.swift    |  9 +++-
 .../ReferenceSources/Petstore/Types.swift     | 42 ++++++++++++---
 .../SnippetBasedReferenceTests.swift          | 52 +++++++++++++++++--
 Tests/PetstoreConsumerTests/Test_Server.swift |  2 +-
 7 files changed, 117 insertions(+), 13 deletions(-)

diff --git a/Package.swift b/Package.swift
index b4087262..25f45e2c 100644
--- a/Package.swift
+++ b/Package.swift
@@ -54,7 +54,7 @@ let package = Package(
         // Tests-only: Runtime library linked by generated code, and also
         // helps keep the runtime library new enough to work with the generated
         // code.
-        .package(url: "https://github.com/apple/swift-openapi-runtime", from: "1.5.0"),
+        .package(url: "https://github.com/apple/swift-openapi-runtime", from: "1.8.0"),
         .package(url: "https://github.com/apple/swift-http-types", from: "1.0.2"),
     ],
     targets: [
diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/petstore.yaml b/Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/petstore.yaml
index 56a8f46e..052cc8eb 100644
--- a/Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/petstore.yaml
+++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/petstore.yaml
@@ -76,11 +76,27 @@ paths:
           explode: true
           schema:
             type: object
+            required:
+            - id
             properties:
               id:
                 type: string
               name:
                 type: string
+        - name: filter
+          in: query
+          required: true
+          style: deepObject
+          explode: true
+          schema:
+            type: object
+            required:
+            - name
+            properties:
+              name:
+                type: string
+              state:
+                type: string
         - $ref: '#/components/parameters/query.born-since'
       responses:
         '200':
diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift
index 1bf61f06..d9c80e62 100644
--- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift
+++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift
@@ -94,6 +94,13 @@ public struct Client: APIProtocol {
                     name: "sort",
                     value: input.query.sort
                 )
+                try converter.setQueryItemAsURI(
+                    in: &request,
+                    style: .deepObject,
+                    explode: true,
+                    name: "filter",
+                    value: input.query.filter
+                )
                 try converter.setQueryItemAsURI(
                     in: &request,
                     style: .form,
diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift
index 7f88982f..dae16f3f 100644
--- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift
+++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift
@@ -192,7 +192,14 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol {
                         style: .deepObject,
                         explode: true,
                         name: "sort",
-                        as: Operations.listPets.Input.Query.sortPayload.self
+                        as: Operations.ListPets.Input.Query.SortPayload.self
+                    ),
+                    filter: try converter.getRequiredQueryItemAsURI(
+                        in: request.soar_query,
+                        style: .deepObject,
+                        explode: true,
+                        name: "filter",
+                        as: Operations.ListPets.Input.Query.FilterPayload.self
                     ),
                     since: try converter.getOptionalQueryItemAsURI(
                         in: request.soar_query,
diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift
index 09b836fc..43d89225 100644
--- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift
+++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift
@@ -66,7 +66,7 @@ extension APIProtocol {
     /// - Remark: HTTP `GET /pets`.
     /// - Remark: Generated from `#/paths//pets/get(listPets)`.
     public func listPets(
-        query: Operations.ListPets.Input.Query = .init(),
+        query: Operations.ListPets.Input.Query,
         headers: Operations.ListPets.Input.Headers = .init()
     ) async throws -> Operations.ListPets.Output {
         try await listPets(Operations.ListPets.Input(
@@ -1898,16 +1898,16 @@ public enum Operations {
                 /// - Remark: Generated from `#/paths/pets/GET/query/sort`.
                 public struct SortPayload: Codable, Hashable, Sendable {
                     /// - Remark: Generated from `#/paths/pets/GET/query/sort/id`.
-                    public var id: Swift.String?
+                    public var id: Swift.String
                     /// - Remark: Generated from `#/paths/pets/GET/query/sort/name`.
                     public var name: Swift.String?
-                    /// Creates a new `sortPayload`.
+                    /// Creates a new `SortPayload`.
                     ///
                     /// - Parameters:
                     ///   - id:
                     ///   - name:
                     public init(
-                        id: Swift.String? = nil,
+                        id: Swift.String,
                         name: Swift.String? = nil
                     ) {
                         self.id = id
@@ -1919,7 +1919,32 @@ public enum Operations {
                     }
                 }
                 /// - Remark: Generated from `#/paths/pets/GET/query/sort`.
-                public var sort: Operations.listPets.Input.Query.SortPayload?
+                public var sort: Operations.ListPets.Input.Query.SortPayload?
+                /// - Remark: Generated from `#/paths/pets/GET/query/filter`.
+                public struct FilterPayload: Codable, Hashable, Sendable {
+                    /// - Remark: Generated from `#/paths/pets/GET/query/filter/name`.
+                    public var name: Swift.String
+                    /// - Remark: Generated from `#/paths/pets/GET/query/filter/state`.
+                    public var state: Swift.String?
+                    /// Creates a new `FilterPayload`.
+                    ///
+                    /// - Parameters:
+                    ///   - name:
+                    ///   - state:
+                    public init(
+                        name: Swift.String,
+                        state: Swift.String? = nil
+                    ) {
+                        self.name = name
+                        self.state = state
+                    }
+                    public enum CodingKeys: String, CodingKey {
+                        case name
+                        case state
+                    }
+                }
+                /// - Remark: Generated from `#/paths/pets/GET/query/filter`.
+                public var filter: Operations.ListPets.Input.Query.FilterPayload
                 /// Supply this parameter to filter pets born since the provided date.
                 ///
                 /// - Remark: Generated from `#/paths/pets/GET/query/since`.
@@ -1931,18 +1956,21 @@ public enum Operations {
                 ///   - habitat:
                 ///   - feeds:
                 ///   - sort:
+                ///   - filter:
                 ///   - since: Supply this parameter to filter pets born since the provided date.
                 public init(
                     limit: Swift.Int32? = nil,
                     habitat: Operations.ListPets.Input.Query.HabitatPayload? = nil,
                     feeds: Operations.ListPets.Input.Query.FeedsPayload? = nil,
-                    sort: Operations.listPets.Input.Query.SortPayload? = nil,
+                    sort: Operations.ListPets.Input.Query.SortPayload? = nil,
+                    filter: Operations.ListPets.Input.Query.FilterPayload,
                     since: Components.Parameters.Query_bornSince? = nil
                 ) {
                     self.limit = limit
                     self.habitat = habitat
                     self.feeds = feeds
                     self.sort = sort
+                    self.filter = filter
                     self.since = since
                 }
             }
@@ -1974,7 +2002,7 @@ public enum Operations {
             ///   - query:
             ///   - headers:
             public init(
-                query: Operations.ListPets.Input.Query = .init(),
+                query: Operations.ListPets.Input.Query,
                 headers: Operations.ListPets.Input.Headers = .init()
             ) {
                 self.query = query
diff --git a/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift b/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift
index 05455feb..1f6bcf71 100644
--- a/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift
+++ b/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift
@@ -2551,6 +2551,20 @@ final class SnippetBasedReferenceTests: XCTestCase {
                           type: string
                         option2:
                           type: string
+                  - name: filter
+                    in: query
+                    required: true
+                    style: deepObject
+                    explode: true
+                    schema:
+                      type: object
+                      required:
+                        - option3
+                      properties:
+                        option3:
+                          type: string
+                        option4:
+                          type: string
                 responses:
                   default:
                     description: Response
@@ -2576,17 +2590,35 @@ final class SnippetBasedReferenceTests: XCTestCase {
                                 case option2
                             }
                         }
-                        public var sort: Operations.get_sol_foo.Input.Query.sortPayload
+                        public var sort: Operations.get_sol_foo.Input.Query.sortPayload?
+                        public struct filterPayload: Codable, Hashable, Sendable {
+                            public var option3: Swift.String
+                            public var option4: Swift.String?
+                            public init(
+                                option3: Swift.String,
+                                option4: Swift.String? = nil
+                            ) {
+                                self.option3 = option3
+                                self.option4 = option4
+                            }
+                            public enum CodingKeys: String, CodingKey {
+                                case option3
+                                case option4
+                            }
+                        }
+                        public var filter: Operations.get_sol_foo.Input.Query.filterPayload
                         public init(
                             single: Swift.String? = nil,
                             manyExploded: [Swift.String]? = nil,
                             manyUnexploded: [Swift.String]? = nil,
-                            sort: Operations.get_sol_foo.Input.Query.sortPayload
+                            sort: Operations.get_sol_foo.Input.Query.sortPayload? = nil,
+                            filter: Operations.get_sol_foo.Input.Query.filterPayload
                         ) {
                             self.single = single
                             self.manyExploded = manyExploded
                             self.manyUnexploded = manyUnexploded
                             self.sort = sort
+                            self.filter = filter
                         }
                     }
                     public var query: Operations.get_sol_foo.Input.Query
@@ -2634,6 +2666,13 @@ final class SnippetBasedReferenceTests: XCTestCase {
                         name: "sort",
                         value: input.query.sort
                     )
+                    try converter.setQueryItemAsURI(
+                        in: &request,
+                        style: .deepObject,
+                        explode: true,
+                        name: "filter",
+                        value: input.query.filter
+                    )
                     return (request, nil)
                 }
                 """,
@@ -2661,12 +2700,19 @@ final class SnippetBasedReferenceTests: XCTestCase {
                             name: "manyUnexploded",
                             as: [Swift.String].self
                         ),
-                        sort: try converter.getRequiredQueryItemAsURI(
+                        sort: try converter.getOptionalQueryItemAsURI(
                             in: request.soar_query,
                             style: .deepObject,
                             explode: true,
                             name: "sort",
                             as: Operations.get_sol_foo.Input.Query.sortPayload.self
+                        ),
+                        filter: try converter.getRequiredQueryItemAsURI(
+                            in: request.soar_query,
+                            style: .deepObject,
+                            explode: true,
+                            name: "filter",
+                            as: Operations.get_sol_foo.Input.Query.filterPayload.self
                         )
                     )
                     return Operations.get_sol_foo.Input(query: query)
diff --git a/Tests/PetstoreConsumerTests/Test_Server.swift b/Tests/PetstoreConsumerTests/Test_Server.swift
index 222700e9..60f3e9b3 100644
--- a/Tests/PetstoreConsumerTests/Test_Server.swift
+++ b/Tests/PetstoreConsumerTests/Test_Server.swift
@@ -44,7 +44,7 @@ final class Test_Server: XCTestCase {
         })
         let (response, responseBody) = try await server.listPets(
             .init(
-                soar_path: "/api/pets?sort%5Bid%5D=ascending&sort%5Bname%5D=descending",
+                soar_path: "/api/pets?limit=24&habitat=water&feeds=carnivore&feeds=herbivore&sort%5Bid%5D=ascending&sort%5Bname%5D=descending&since=\(Date.testString)",
                 method: .get,
                 headerFields: [.init("My-Request-UUID")!: "abcd-1234"]
             ),

From 3078680d9b9519a9140427ac3da47cd906388165 Mon Sep 17 00:00:00 2001
From: Kostis Stefanou <kostistefanou@gmail.com>
Date: Tue, 11 Feb 2025 15:39:45 +0200
Subject: [PATCH 7/7] Soundness check fixes.

---
 .../Translator/CommonTypes/Constants.swift                | 1 -
 .../Translator/Parameters/TypedParameter.swift            | 6 ++----
 Tests/PetstoreConsumerTests/Test_Client.swift             | 8 +++++++-
 Tests/PetstoreConsumerTests/Test_Server.swift             | 3 ++-
 4 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift b/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift
index 72eed786..34ceca2e 100644
--- a/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift
+++ b/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift
@@ -319,7 +319,6 @@ enum Constants {
 
                 /// The form style.
                 static let form = "form"
-                
                 /// The deepObject style.
                 static let deepObject = "deepObject"
             }
diff --git a/Sources/_OpenAPIGeneratorCore/Translator/Parameters/TypedParameter.swift b/Sources/_OpenAPIGeneratorCore/Translator/Parameters/TypedParameter.swift
index d005b4ab..7ac1f18f 100644
--- a/Sources/_OpenAPIGeneratorCore/Translator/Parameters/TypedParameter.swift
+++ b/Sources/_OpenAPIGeneratorCore/Translator/Parameters/TypedParameter.swift
@@ -131,10 +131,8 @@ extension FileTranslator {
             switch location {
             case .query:
                 switch style {
-                case .form:
-                    break
-                case .deepObject where explode:
-                    break
+                case .form: break
+                case .deepObject where explode: break
                 default:
                     try diagnostics.emitUnsupported(
                         "Query params of style \(style.rawValue), explode: \(explode)",
diff --git a/Tests/PetstoreConsumerTests/Test_Client.swift b/Tests/PetstoreConsumerTests/Test_Client.swift
index 1973a773..3601e3b1 100644
--- a/Tests/PetstoreConsumerTests/Test_Client.swift
+++ b/Tests/PetstoreConsumerTests/Test_Client.swift
@@ -66,7 +66,13 @@ final class Test_Client: XCTestCase {
         }
         let response = try await client.listPets(
             .init(
-                query: .init(limit: 24, habitat: .water, feeds: [.herbivore, .carnivore], sort: .init(id: "ascending", name: "descending"), since: .test),
+                query: .init(
+                    limit: 24,
+                    habitat: .water,
+                    feeds: [.herbivore, .carnivore],
+                    sort: .init(id: "ascending", name: "descending"),
+                    since: .test
+                ),
                 headers: .init(myRequestUUID: "abcd-1234")
             )
         )
diff --git a/Tests/PetstoreConsumerTests/Test_Server.swift b/Tests/PetstoreConsumerTests/Test_Server.swift
index 60f3e9b3..d312bf7b 100644
--- a/Tests/PetstoreConsumerTests/Test_Server.swift
+++ b/Tests/PetstoreConsumerTests/Test_Server.swift
@@ -44,7 +44,8 @@ final class Test_Server: XCTestCase {
         })
         let (response, responseBody) = try await server.listPets(
             .init(
-                soar_path: "/api/pets?limit=24&habitat=water&feeds=carnivore&feeds=herbivore&sort%5Bid%5D=ascending&sort%5Bname%5D=descending&since=\(Date.testString)",
+                soar_path:
+                    "/api/pets?limit=24&habitat=water&feeds=carnivore&feeds=herbivore&sort%5Bid%5D=ascending&sort%5Bname%5D=descending&since=\(Date.testString)",
                 method: .get,
                 headerFields: [.init("My-Request-UUID")!: "abcd-1234"]
             ),