Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
1bbaa5a
feat: Add codegen build plugin to AWS services
jbelkins Nov 9, 2025
6b64c5b
Delete internal clients before codegen
jbelkins Nov 9, 2025
e09a838
Merge branch 'main' into jbe/swift_codegen_schema
jbelkins Nov 11, 2025
13dbbbb
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Nov 19, 2025
eda4169
CI
jbelkins Nov 19, 2025
c3592f7
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Nov 22, 2025
d95a555
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Nov 26, 2025
33c23a0
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Dec 3, 2025
82d5de0
Add codegen plugin to internal AWSSignin client
jbelkins Dec 5, 2025
c845e85
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Dec 5, 2025
6166e97
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Dec 9, 2025
db5195a
Don't apply plugin to internal services
jbelkins Dec 12, 2025
90ec63b
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Dec 12, 2025
7460540
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Dec 15, 2025
4955c12
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Dec 22, 2025
c4168f5
Separate sdkId methods
jbelkins Dec 31, 2025
549b6f1
Protocol tests now run
jbelkins Jan 1, 2026
cf25752
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Jan 1, 2026
589cbf4
Perform mixin transform before protocol tests
jbelkins Jan 5, 2026
30826f8
Configure package for schema-based protocol testing
jbelkins Jan 12, 2026
0a2094b
Implement AWS-specific CBOR extensions
jbelkins Jan 13, 2026
ed08d14
Enable query mode
jbelkins Jan 14, 2026
d1234ca
Enable all protocol tests
jbelkins Jan 14, 2026
6e18e96
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Jan 15, 2026
319bdb7
Fix tests
jbelkins Jan 15, 2026
de522a5
Update internal client models
jbelkins Jan 15, 2026
42b1d35
Fix AWSClientRuntimeTests
jbelkins Jan 15, 2026
d9cfa7c
Remove internal services
jbelkins Jan 15, 2026
5c382f8
Add back internal services
jbelkins Jan 15, 2026
6e736a0
Make configurator Sendable
jbelkins Jan 15, 2026
a64c875
Fix CloudWatch error query compatibility integration test, move query
jbelkins Jan 15, 2026
11b3373
Exclude 6 non-building services
jbelkins Jan 17, 2026
72b9baa
Enable only internal & CBOR svcs
jbelkins Jan 17, 2026
e094bbe
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Jan 19, 2026
98f7b2e
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Jan 30, 2026
efdb46a
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Feb 2, 2026
d182164
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Feb 3, 2026
a9af376
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Feb 4, 2026
1438b50
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Feb 9, 2026
7367958
CBOR uses plugin for path
jbelkins Feb 10, 2026
df83d01
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Feb 12, 2026
1bb65c5
Internal clients generate compiling code
jbelkins Feb 13, 2026
302ed63
Fix lint
jbelkins Feb 13, 2026
f4ca17f
Fix broken tests
jbelkins Feb 13, 2026
0fde46c
AWS JSON services compile
jbelkins Feb 13, 2026
b8d6dad
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Feb 16, 2026
a6bcec6
Fix codegen test
jbelkins Feb 16, 2026
f503b8f
AWSJSON protocol tests now pass
jbelkins Feb 20, 2026
1bf2609
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Feb 20, 2026
bc59b7b
Fix extra return
jbelkins Feb 20, 2026
bc45aa4
Disable initial response test
jbelkins Feb 23, 2026
26e8c17
Fix ktlint
jbelkins Feb 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Resources/Package.Base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@ extension Target.Dependency {
static var AWSSDKIdentityAPI: Self { "AWSSDKIdentityAPI" }
static var AWSSDKChecksums: Self { "AWSSDKChecksums" }
static var AWSSDKDynamic: Self { "AWSSDKDynamic" }
static var AWSSDKRPCv2CBOR: Self { "AWSSDKRPCv2CBOR" }
static var AWSSDKAWSJSON: Self { "AWSSDKAWSJSON" }

// CRT module
static var CRT: Self { .product(name: "AwsCommonRuntimeKit", package: "aws-crt-swift") }

// Smithy modules
static var ClientRuntime: Self { .product(name: "ClientRuntime", package: "smithy-swift") }
static var Smithy: Self { .product(name: "Smithy", package: "smithy-swift") }
static var RPCv2CBOR: Self { .product(name: "RPCv2CBOR", package: "smithy-swift") }
static var SmithySerialization: Self { .product(name: "SmithySerialization", package: "smithy-swift") }
static var SmithyCBOR: Self { .product(name: "SmithyCBOR", package: "smithy-swift") }
static var SmithyChecksumsAPI: Self { .product(name: "SmithyChecksumsAPI", package: "smithy-swift") }
static var SmithyChecksums: Self { .product(name: "SmithyChecksums", package: "smithy-swift") }
Expand Down Expand Up @@ -80,6 +84,8 @@ private var runtimeProducts: [Product] {
"AWSSDKIdentityAPI",
"AWSSDKIdentity",
"AWSSDKChecksums",
"AWSSDKRPCv2CBOR",
"AWSSDKAWSJSON",
].map { .library(name: $0, targets: [$0]) }
}

Expand Down Expand Up @@ -218,6 +224,28 @@ private var runtimeTargets: [Target] {
name: "AWSSDKDynamic",
path: "Sources/Core/AWSSDKDynamic/Sources/AWSSDKDynamic"
),
.target(
name: "AWSSDKRPCv2CBOR",
dependencies: [
.RPCv2CBOR,
.ClientRuntime,
.AWSClientRuntime,
.Smithy,
.SmithySerialization,
],
path: "Sources/Core/AWSSDKRPCv2CBOR/Sources/AWSSDKRPCv2CBOR"
),
.target(
name: "AWSSDKAWSJSON",
dependencies: [
.ClientRuntime,
.AWSClientRuntime,
.Smithy,
.SmithyJSON,
.SmithySerialization,
],
path: "Sources/Core/AWSSDKAWSJSON/Sources/AWSSDKAWSJSON"
),
] + internalServiceTargets
}

Expand All @@ -226,7 +254,9 @@ private var internalClientDependencies: [Target.Dependency] {
}

private var internalServiceTargets: [Target] {
serviceClientData.filter { $0.serviceType == .internalUse }.map(target(_:))
serviceClientData.filter { $0.serviceType == .internalUse }.map {
.target(name: $0.name, dependencies: $0.dependencies, path: $0.sourcePath, plugins: [.SmithyCodeGeneratorPlugin])
}
}

private var runtimeTestTargets: [Target] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,18 @@ class CloudWatchErrorTests: XCTestCase {
private let region = "us-west-2"

override func setUp() async throws {
self.client = try CloudWatchClient(region: "us-west-2")
self.client = try CloudWatchClient(region: region)
}

// this test can be removed when smoke tests are run during all builds
// Per discussion with Smithy, this test should resolve to `ResourceNotFound` instead of
// `DashboardNotFound` as this test did previously, because the query-compatible
// code should be checked against shape names for a match before attempting to match it
// against an awsQueryError value.
func test_AmbiguousError() async throws {
do {
let response = try await client.getDashboard(input: .init(dashboardName: "foo"))
XCTFail("Expected ResourceNotFound error but got successful response: \(response)")
} catch let error as DashboardNotFoundError {
} catch let error as ResourceNotFound {
// Test passed - we expected this error
XCTAssertEqual(error.errorCode, "ResourceNotFound")
} catch {
Expand Down
338 changes: 184 additions & 154 deletions Package.swift

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public extension HTTPResponse {

/// The value of the x-amz-request-id header.
var requestID: String? {
return headers.value(for: "x-amz-request-id")
return headers.value(for: "x-amz-request-id") ?? headers.value(for: "x-amzn-RequestId")
}

/// The value of the x-amz-id-2 header.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,12 @@
// SPDX-License-Identifier: Apache-2.0
//

@_spi(SmithyReadWrite) import struct ClientRuntime.RpcV2CborError
@_spi(SmithyReadWrite) import class SmithyCBOR.Reader
import class SmithyHTTPAPI.HTTPResponse
@_spi(SmithyReadWrite) import class SmithyJSON.Reader

@_spi(SmithyReadWrite)
public enum AWSQueryCompatibleUtils {

// CBOR
public static func makeQueryCompatibleError(
httpResponse: HTTPResponse,
responseReader: SmithyCBOR.Reader,
noErrorWrapping: Bool,
errorDetails: String?
) throws -> RpcV2CborError {
let errorCode = try AwsQueryCompatibleErrorDetails.parse(errorDetails)?.code
return try RpcV2CborError(
httpResponse: httpResponse,
responseReader: responseReader,
noErrorWrapping: noErrorWrapping,
code: errorCode
)
}

// awsJson1_0
public static func makeQueryCompatibleError(
httpResponse: HTTPResponse,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,5 +167,5 @@ private struct ClockSkewTestError: Error, ServiceError {
static var notDueToClockSkew: Self { .init(typeName: "NotAClockSkewError") }

var typeName: String?
var message: String? { "" }
var message: String? = ""
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import ClientRuntime
import Smithy
import class SmithyHTTPAPI.HTTPRequest
import class SmithyHTTPAPI.HTTPResponse
import protocol SmithySerialization.DeserializableStruct
import protocol SmithySerialization.SerializableStruct

public struct Plugin: ClientRuntime.Plugin {

public init() {}

public func configureClient<Config: ClientConfiguration>(clientConfiguration: inout Config) async throws {
guard var defaultConfig = clientConfiguration as? DefaultHttpClientConfiguration else { return }
defaultConfig.addInterceptorProvider(URLPathInterceptorProvider())
guard let modifiedConfig = defaultConfig as? Config else { return }
clientConfiguration = modifiedConfig
}
}

struct URLPathInterceptorProvider: HttpInterceptorProvider {

func create<InputType, OutputType>() -> any Interceptor<InputType, OutputType, HTTPRequest, HTTPResponse> {
ClientRuntime.URLPathMiddleware<InputType, OutputType>() { _ in "/" }
}
}
69 changes: 69 additions & 0 deletions Sources/Core/AWSSDKAWSJSON/Sources/AWSSDKAWSJSON/BaseError.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import enum Smithy.Prelude
import struct Smithy.Schema
import protocol SmithySerialization.DeserializableStruct
import typealias SmithySerialization.ReadStructConsumer
import protocol SmithySerialization.ShapeDeserializer

struct BaseError {
var __type: String?
var code: String?
var message: String?
}

extension BaseError: DeserializableStruct {

private static var schema: Schema {
.init(
id: .init("swift.synthetic", "BaseError"),
type: .structure,
members: [
.init(
id: .init("swift.synthetic", "BaseError", "__type"),
type: .member,
target: Prelude.stringSchema,
index: 0
),
.init(
id: .init("swift.synthetic", "BaseError", "code"),
type: .member,
target: Prelude.stringSchema,
index: 1
),
.init(
id: .init("swift.synthetic", "BaseError", "message"),
type: .member,
target: Prelude.stringSchema,
index: 2
),
]
)
}

public static var readConsumer: SmithySerialization.ReadStructConsumer<Self> {
{ memberSchema, value, deserializer in
switch memberSchema.index {
case 0:
value.__type = try deserializer.readString(memberSchema)
case 1:
value.code = try deserializer.readString(memberSchema)
case 2:
value.message = try deserializer.readString(memberSchema)
default:
break
}
}
}

public static func deserialize(_ deserializer: any ShapeDeserializer) throws -> Self {
var value = Self()
try deserializer.readStruct(Self.schema, &value)
return value
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import protocol ClientRuntime.ServiceError
import protocol ClientRuntime.HTTPError
import struct ClientRuntime.UnknownHTTPServiceError
import struct Foundation.Data
import enum Smithy.ClientError
import class Smithy.Context
import struct Smithy.ShapeID
import class SmithyHTTPAPI.HTTPRequest
import class SmithyHTTPAPI.HTTPRequestBuilder
import class SmithyHTTPAPI.HTTPResponse
import protocol SmithySerialization.ClientProtocol
import protocol SmithySerialization.Codec
import protocol SmithySerialization.DeserializableStruct
import struct SmithySerialization.Operation
import protocol SmithySerialization.SerializableStruct

public struct ClientProtocol: SmithySerialization.ClientProtocol {
public typealias RequestType = HTTPRequest
public typealias ResponseType = HTTPResponse

public var id: ShapeID { try! .init("aws.protocols#awsJson1_0") }

public var codec: any SmithySerialization.Codec = Codec()

public init() {}

public func serializeRequest<Input, Output>(
operation: Operation<Input, Output>,
input: Input,
requestBuilder: HTTPRequestBuilder,
context: Context
) throws where Input: SerializableStruct, Output: DeserializableStruct {
let serializer = try codec.makeSerializer()
try input.serialize(serializer)
let data = try serializer.data
requestBuilder.withBody(.data(data))
}

public func deserializeResponse<Input, Output>(
operation: Operation<Input, Output>,
context: Context,
response: HTTPResponse
) async throws -> Output where Input: SerializableStruct, Output: DeserializableStruct {
let data = try await response.body.readData() ?? Data()
let deserializer = try codec.makeDeserializer(data: data)
if (200..<300).contains(response.statusCode.rawValue) {
return try Output.deserialize(deserializer)
} else {
let baseError = try BaseError.deserialize(deserializer)
let code = baseError.__type ?? baseError.code ?? response.headers.value(for: "X-Amzn-Errortype") ?? "<NoCodeFound>"
let strippedCode = String(code.split(separator: ":").first!.split(separator: "#").last!)
if let entry = operation.errorTypeRegistry.codeLookup(code: strippedCode, matcher: { code, entry in
entry.schema.id.name == code
}) {
let deserializer = try codec.makeDeserializer(data: data)
let error = try entry.swiftType.deserialize(deserializer)

// Cast the error so that we can fill its fields
guard var modeledError = error as? ServiceError & HTTPError & Error else {
throw ClientError.invalidValue(
"Modeled error does not conform to ServiceError & HTTPError & Error. " +
"This should never happen, please file a bug on aws-sdk-swift."
)
}
modeledError.message = baseError.message
modeledError.httpResponse = response

// Throw the error to the caller
throw modeledError
} else {
throw UnknownHTTPServiceError(httpResponse: response, message: baseError.message, typeName: code)
}
}
}
}
26 changes: 26 additions & 0 deletions Sources/Core/AWSSDKAWSJSON/Sources/AWSSDKAWSJSON/Codec.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import struct Foundation.Data
import class SmithyJSON.Deserializer
import class SmithyJSON.Serializer
import protocol SmithySerialization.Codec
import protocol SmithySerialization.ShapeDeserializer
import protocol SmithySerialization.ShapeSerializer

struct Codec: SmithySerialization.Codec {

func makeSerializer() throws -> any ShapeSerializer {
SmithyJSON.Serializer()
}

func makeDeserializer(data: Data) throws -> any ShapeDeserializer {
try SmithyJSON.Deserializer(data: data)
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ This SDK is open-source. Code is available on Github [here](https://github.com/

[ClientRuntime](../../../../../swift/api/clientruntime/latest)

[RPCv2CBOR](../../../../../swift/api/rpcv2cbor/latest)

[Smithy](../../../../../swift/api/smithy/latest)

[SmithyCBOR](../../../../../swift/api/smithycbor/latest)
Expand Down Expand Up @@ -74,6 +76,8 @@ This SDK is open-source. Code is available on Github [here](https://github.com/

[AWSClientRuntime](../../../../../swift/api/awsclientruntime/latest)

[AWSSDKAWSJSON](../../../../../swift/api/awssdkawsjson/latest)

[AWSSDKChecksums](../../../../../swift/api/awssdkchecksums/latest)

[AWSSDKCommon](../../../../../swift/api/awssdkcommon/latest)
Expand All @@ -86,6 +90,8 @@ This SDK is open-source. Code is available on Github [here](https://github.com/

[AWSSDKIdentityAPI](../../../../../swift/api/awssdkidentityapi/latest)

[AWSSDKRPCv2CBOR](../../../../../swift/api/awssdkrpcv2cbor/latest)


## Service Documentation

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@
"modelPath": "codegen/sdk-codegen/aws-models/cognito-identity.json",
"dependencies": [
"AWSClientRuntime",
"AWSSDKAWSJSON",
"AWSSDKChecksums",
"AWSSDKHTTPAuth",
"ClientRuntime",
"Smithy",
"SmithyHTTPAPI",
"SmithyHTTPAuthAPI",
"SmithyIdentity",
"SmithyJSON",
"SmithyReadWrite",
"SmithyRetries",
"SmithyRetriesAPI",
"SmithyTimestamps"
"SmithyRetriesAPI"
]
}
Loading
Loading