Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: swift-server/swift-aws-lambda-events
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0.5.0
Choose a base ref
...
head repository: swift-server/swift-aws-lambda-events
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
  • 10 commits
  • 23 files changed
  • 4 contributors

Commits on Nov 7, 2024

  1. Fix CI (#72)

    * fix ci, use swiftlang workflows
    
    * typo
    
    * typo
    
    * fix format
    
    * use 6.0-noble for format check
    
    * fix format
    sebsto authored Nov 7, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    bbd2810 View commit details

Commits on Nov 12, 2024

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    7bb1b04 View commit details

Commits on Nov 26, 2024

  1. fix CI (#77)

    * add semantic version check
    
    * disable yaml linter
    
    * Disable Swift 5.8 unit test
    
    * re-enable additional soundness checks
    
    * fix shell scripts
    
    * fix yaml lint
    sebsto authored Nov 26, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    ee11dac View commit details

Commits on Dec 2, 2024

  1. Make S3 eTag optional (#78)

    Make S3 Object eTag optional, because it's not always there.
    
    ### Motivation:
    
    I'm seeing real events without an eTag, which naturally is causing
    decoding failures.
    
    ### Modifications:
    
    Made S3 Object eTag optional.
    
    ### Result:
    
    S3 Object eTag is now optional...
    jsonfry authored Dec 2, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    3c1161a View commit details

Commits on Dec 3, 2024

  1. Add custom Decodable conformance (#80)

    Add custom Decodable conformance.
    Closes #73
    Duplicate of
    #76 created
    by @twistinside
    
    **Motivation:**
    Absent collections would fail to decode, when in reality it is possible
    to have empty headers, for example. This allows processing to continue
    in the context of the Lambda runtime where users can handle the
    collections as dictated by their code.
    
    **Modifications:**
    Custom Decodable conformance has been added to both API Gateway request
    objects to optionally decode absent collections to empty collections.
    
    Unit testa have been added for the same.
    
    **Result:**
    This will make the swift lambda runtime more accepting of input,
    allowing processing to proceed in the rare cases where collection fields
    would be absent in the JSON received by the runtime. This will unlock
    certain functionality in edge cases such as testing lambda code from API
    Gateway console with empty headers (the use case that prompted this
    change).
    
    This change will require users to update their code to remove optional
    handling for the collections involved, potentially also requiring extra
    logic to validate that the collections they've received aren't empty.
    
    ---------
    
    Authored-by: twistinside <twistinside@users.noreply.github.com>
    sebsto authored Dec 3, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    334d865 View commit details

Commits on Dec 18, 2024

  1. Update release.yml (#83)

    Update the release.yml file with the latest label changes
    FranzBusch authored Dec 18, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    18c4c26 View commit details

Commits on Dec 19, 2024

  1. Adds devcontainer config (#82)

    Adds default devcontainer configuration from SSWG:
    https://github.com/swift-server/swift-devcontainer-template
    
    ### Motivation:
    
    Developing for linux can be challenging on macOS because some APIs are
    not available on Linux. By using VSCode and devcontainer you can
    essentially develop "on linux".
    
    ### Modifications:
    
    Adds devcontainer config.
    
    ### Result:
    
    When working in VSCode, you can now easily open the project inside a
    devcontainer.
    
    Co-authored-by: Sébastien Stormacq <sebastien.stormacq@gmail.com>
    t089 and sebsto authored Dec 19, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    d2761dc View commit details
  2. Use only FoundationEssentials when possible (#81)

    Linking against `Foundation` on linux adds a hefty binary size penalty.
    Mostly due to the ICU data from `FoundationInternationalization`. To
    address this we conditionally import `FoundationEssentials` instead of
    `Foundation` if possible and replace `Foundation`-only API with a
    different implementation.
    
    ### Motivation:
    
    Smaller binary sizes are better.
    
    ### Modifications:
    
    - Replace `import Foundation` with `import FoundationEssentials`.
    - Update date parsing logic to use newer API if available.
    - Implement a custom parser for RFC5322 dates
    
    ### Result:
    
    Ability to build the package without linking `Foundation`.
    
    ---------
    
    Co-authored-by: Sébastien Stormacq <sebastien.stormacq@gmail.com>
    t089 and sebsto authored Dec 19, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    7bcecc5 View commit details
  3. Update .gitignore to ignore .devcontainer (#84)

    `.devcontainer` should not be versioned to allow developers to customize
    it without git to interfere
    sebsto authored Dec 19, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    20fa5fe View commit details

Commits on Dec 21, 2024

  1. Add an encodable version of the APIGatewayResponse (#86)

    Add a convenience initializer to the APIGatewayResponse v2 that accepts
    an Encodable object
    
    ### Motivation:
    
    Most Lambda developers will return a JSON object when exposing their
    function through the API Gateway. The current initializer only accepts a
    `String` body as per the AWS message definition.
    
    This obliges all developers to write two lines of code + error handling
    to encode their object and transform the `Data` to a string.
    
    ### Modifications:
    
    Add a new initializer that accepts a `body` as `Encodable`
    
    ```swift
    public init<Input: Encodable> (
            statusCode: HTTPResponse.Status,
            headers: HTTPHeaders? = nil,
            body: Input,
            isBase64Encoded: Bool? = nil,
            cookies: [String]? = nil
    ) throws { ... }
    ```
    
    ### Result:
    
    Developers can now pass a Swift struct to the APIGatewayResponse.
    
    ```swift
    let businessResponse = BusinessResponse(message: "Hello World", code: 200)
    return APIGatewayV2Response(statusCode: .ok, body: businessResponse)
    ```
    sebsto authored Dec 21, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    0025b1a View commit details
39 changes: 39 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "Swift",
"image": "swift:6.0",
"features": {
"ghcr.io/devcontainers/features/common-utils:2": {
"installZsh": "false",
"username": "vscode",
"upgradePackages": "false"
},
"ghcr.io/devcontainers/features/git:1": {
"version": "os-provided",
"ppa": "false"
}
},
"runArgs": [
"--cap-add=SYS_PTRACE",
"--security-opt",
"seccomp=unconfined"
],
// Configure tool-specific properties.
"customizations": {
// Configure properties specific to VS Code.
"vscode": {
// Set *default* container specific settings.json values on container create.
"settings": {
"lldb.library": "/usr/lib/liblldb.so"
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"sswg.swift-lang"
]
}
},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

// Set `remoteUser` to `root` to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode"
}
14 changes: 14 additions & 0 deletions .github/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
changelog:
categories:
- title: SemVer Major
labels:
- ⚠️ semver/major
- title: SemVer Minor
labels:
- 🆕 semver/minor
- title: SemVer Patch
labels:
- 🔨 semver/patch
- title: Other Changes
labels:
- semver/none
58 changes: 36 additions & 22 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
name: PR

on:
pull_request:
types: [opened, reopened, synchronize]
pull_request:
types: [opened, reopened, synchronize]

jobs:
soundness:
name: Soundness
uses: apple/swift-nio/.github/workflows/soundness.yml@main
with:
license_header_check_project_name: "SwiftAWSLambdaRuntime"
shell_check_enabled: false
api_breakage_check_container_image: "swift:6.0-noble"
docs_check_container_image: "swift:6.0-noble"
soundness:
name: Soundness
uses: swiftlang/github-workflows/.github/workflows/soundness.yml@main
with:
license_header_check_project_name: "SwiftAWSLambdaRuntime"
shell_check_enabled: true
python_lint_check_enabled: true
api_breakage_check_container_image: "swift:6.0-noble"
docs_check_container_image: "swift:6.0-noble"
format_check_container_image: "swift:6.0-noble"
yamllint_check_enabled: true

unit-tests:
name: Unit tests
uses: apple/swift-nio/.github/workflows/unit_tests.yml@main
with:
linux_5_8_enabled: true
linux_5_9_enabled: true
linux_5_10_enabled: true
linux_nightly_6_0_arguments_override: "--explicit-target-dependency-import-check error"
linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error"
unit-tests:
name: Unit tests
uses: apple/swift-nio/.github/workflows/unit_tests.yml@main
with:
linux_5_9_enabled: false
linux_5_10_enabled: false
linux_nightly_6_0_arguments_override: "--explicit-target-dependency-import-check error"
linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error"

swift-6-language-mode:
name: Swift 6 Language Mode
uses: apple/swift-nio/.github/workflows/swift_6_language_mode.yml@main
swift-6-language-mode:
name: Swift 6 Language Mode
uses: apple/swift-nio/.github/workflows/swift_6_language_mode.yml@main

semver-label-check:
name: Semantic Version label check
runs-on: ubuntu-latest
timeout-minutes: 1
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Check for Semantic Version label
uses: apple/swift-nio/.github/actions/pull_request_semver_label_checker@main
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.DS_Store
*.build
*.index-build
/.xcodeproj
*.pem
.podspecs
@@ -8,3 +9,4 @@
xcuserdata
Package.resolved
.serverless
.devcontainer
66 changes: 66 additions & 0 deletions Sources/AWSLambdaEvents/APIGateway+Encodable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftAWSLambdaRuntime open source project
//
// Copyright (c) 2017-2022 Apple Inc. and the SwiftAWSLambdaRuntime project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import HTTPTypes

#if canImport(FoundationEssentials)
import class FoundationEssentials.JSONEncoder
import struct FoundationEssentials.Data
#else
import class Foundation.JSONEncoder
import struct Foundation.Data
#endif

extension Encodable {
fileprivate func string() throws -> String {
let encoded = try JSONEncoder().encode(self)
return String(decoding: encoded, as: UTF8.self)
}
}

extension APIGatewayResponse {

public init<Input: Encodable>(
statusCode: HTTPResponse.Status,
headers: HTTPHeaders? = nil,
multiValueHeaders: HTTPMultiValueHeaders? = nil,
encodableBody: Input
) throws {
self.init(
statusCode: statusCode,
headers: headers,
multiValueHeaders: multiValueHeaders,
body: try encodableBody.string(),
isBase64Encoded: nil
)
}
}

extension APIGatewayV2Response {

public init<Input: Encodable>(
statusCode: HTTPResponse.Status,
headers: HTTPHeaders? = nil,
encodableBody: Input,
cookies: [String]? = nil
) throws {
self.init(
statusCode: statusCode,
headers: headers,
body: try encodableBody.string(),
isBase64Encoded: nil,
cookies: cookies
)
}
}
33 changes: 28 additions & 5 deletions Sources/AWSLambdaEvents/APIGateway+V2.swift
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@
import HTTPTypes

/// `APIGatewayV2Request` contains data coming from the new HTTP API Gateway.
public struct APIGatewayV2Request: Codable, Sendable {
public struct APIGatewayV2Request: Encodable, Sendable {
/// `Context` contains information to identify the AWS account and resources invoking the Lambda function.
public struct Context: Codable, Sendable {
public struct HTTP: Codable, Sendable {
@@ -96,13 +96,13 @@ public struct APIGatewayV2Request: Codable, Sendable {
public let rawPath: String
public let rawQueryString: String

public let cookies: [String]?
public let cookies: [String]
public let headers: HTTPHeaders
public let queryStringParameters: [String: String]?
public let pathParameters: [String: String]?
public let queryStringParameters: [String: String]
public let pathParameters: [String: String]

public let context: Context
public let stageVariables: [String: String]?
public let stageVariables: [String: String]

public let body: String?
public let isBase64Encoded: Bool
@@ -147,3 +147,26 @@ public struct APIGatewayV2Response: Codable, Sendable {
self.cookies = cookies
}
}

extension APIGatewayV2Request: Decodable {
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)

self.version = try container.decode(String.self, forKey: .version)
self.routeKey = try container.decode(String.self, forKey: .routeKey)
self.rawPath = try container.decode(String.self, forKey: .rawPath)
self.rawQueryString = try container.decode(String.self, forKey: .rawQueryString)

self.cookies = try container.decodeIfPresent([String].self, forKey: .cookies) ?? []
self.headers = try container.decodeIfPresent(HTTPHeaders.self, forKey: .headers) ?? HTTPHeaders()
self.queryStringParameters =
try container.decodeIfPresent([String: String].self, forKey: .queryStringParameters) ?? [:]
self.pathParameters = try container.decodeIfPresent([String: String].self, forKey: .pathParameters) ?? [:]

self.context = try container.decode(Context.self, forKey: .context)
self.stageVariables = try container.decodeIfPresent([String: String].self, forKey: .stageVariables) ?? [:]

self.body = try container.decodeIfPresent(String.self, forKey: .body)
self.isBase64Encoded = try container.decode(Bool.self, forKey: .isBase64Encoded)
}
}
35 changes: 30 additions & 5 deletions Sources/AWSLambdaEvents/APIGateway.swift
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ import Foundation
// https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html

/// `APIGatewayRequest` contains data coming from the API Gateway.
public struct APIGatewayRequest: Codable, Sendable {
public struct APIGatewayRequest: Encodable, Sendable {
public struct Context: Codable, Sendable {
public struct Identity: Codable, Sendable {
public let cognitoIdentityPoolId: String?
@@ -64,12 +64,12 @@ public struct APIGatewayRequest: Codable, Sendable {
public let path: String
public let httpMethod: HTTPRequest.Method

public let queryStringParameters: [String: String]?
public let multiValueQueryStringParameters: [String: [String]]?
public let queryStringParameters: [String: String]
public let multiValueQueryStringParameters: [String: [String]]
public let headers: HTTPHeaders
public let multiValueHeaders: HTTPMultiValueHeaders
public let pathParameters: [String: String]?
public let stageVariables: [String: String]?
public let pathParameters: [String: String]
public let stageVariables: [String: String]

public let requestContext: Context
public let body: String?
@@ -99,3 +99,28 @@ public struct APIGatewayResponse: Codable, Sendable {
self.isBase64Encoded = isBase64Encoded
}
}

extension APIGatewayRequest: Decodable {
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)

self.resource = try container.decode(String.self, forKey: .resource)
self.path = try container.decode(String.self, forKey: .path)
self.httpMethod = try container.decode(HTTPRequest.Method.self, forKey: .httpMethod)

self.queryStringParameters =
try container.decodeIfPresent([String: String].self, forKey: .queryStringParameters) ?? [:]
self.multiValueQueryStringParameters =
try container.decodeIfPresent([String: [String]].self, forKey: .multiValueQueryStringParameters) ?? [:]
self.headers = try container.decodeIfPresent(HTTPHeaders.self, forKey: .headers) ?? HTTPHeaders()
self.multiValueHeaders =
try container.decodeIfPresent(HTTPMultiValueHeaders.self, forKey: .multiValueHeaders)
?? HTTPMultiValueHeaders()
self.pathParameters = try container.decodeIfPresent([String: String].self, forKey: .pathParameters) ?? [:]
self.stageVariables = try container.decodeIfPresent([String: String].self, forKey: .stageVariables) ?? [:]

self.requestContext = try container.decode(Context.self, forKey: .requestContext)
self.body = try container.decodeIfPresent(String.self, forKey: .body)
self.isBase64Encoded = try container.decode(Bool.self, forKey: .isBase64Encoded)
}
}
2 changes: 1 addition & 1 deletion Sources/AWSLambdaEvents/AWSRegion.swift
Original file line number Diff line number Diff line change
@@ -58,7 +58,7 @@ public struct AWSRegion: RawRepresentable, Equatable, Sendable {
Self.sa_east_1,
Self.me_central_1,
Self.me_south_1,
Self.il_central_1
Self.il_central_1,
]

public static var af_south_1: Self { AWSRegion(rawValue: "af-south-1")! }
Loading