File tree Expand file tree Collapse file tree 5 files changed +219
-0
lines changed
Sources/AWSLambdaEvents/Codable Helpers Expand file tree Collapse file tree 5 files changed +219
-0
lines changed Original file line number Diff line number Diff line change 1+ #if canImport(FoundationEssentials)
2+ import FoundationEssentials
3+ #else
4+ import Foundation
5+ #endif
6+
7+ import HTTPTypes
8+
9+ public extension APIGatewayV2Request {
10+ /// Decodes the body of the request into a `Data` object.
11+ ///
12+ /// - Returns: The decoded body as `Data` or `nil` if the body is empty.
13+ func decodeBody( ) throws -> Data ? {
14+ guard let body else { return nil }
15+
16+ if isBase64Encoded,
17+ let base64Decoded = Data ( base64Encoded: body) {
18+ return base64Decoded
19+ }
20+
21+ return body. data ( using: . utf8)
22+ }
23+
24+ /// Decodes the body of the request into a decodable object. When the
25+ /// body is empty, an error is thrown.
26+ ///
27+ /// - Parameters:
28+ /// - type: The type to decode the body into.
29+ /// - decoder: The decoder to use. Defaults to `JSONDecoder()`.
30+ ///
31+ /// - Returns: The decoded body as `T`.
32+ /// - Throws: An error if the body cannot be decoded.
33+ func decodeBody< T> (
34+ _ type: T . Type ,
35+ using decoder: JSONDecoder = JSONDecoder ( )
36+ ) throws -> T where T: Decodable {
37+ let bodyData = body? . data ( using: . utf8) ?? Data ( )
38+
39+ var requestData = bodyData
40+
41+ if isBase64Encoded,
42+ let base64Decoded = Data ( base64Encoded: requestData) {
43+ requestData = base64Decoded
44+ }
45+
46+ return try decoder. decode ( T . self, from: requestData)
47+ }
48+ }
Original file line number Diff line number Diff line change 1+ #if canImport(FoundationEssentials)
2+ import FoundationEssentials
3+ #else
4+ import Foundation
5+ #endif
6+
7+ import HTTPTypes
8+
9+ public extension APIGatewayV2Response {
10+ /// Encodes a given encodable object into a `APIGatewayV2Response` object.
11+ ///
12+ /// - Parameters:
13+ /// - encodable: The object to encode.
14+ /// - status: The status code to use. Defaults to `ok`.
15+ /// - encoder: The encoder to use. Defaults to a new `JSONEncoder`.
16+ /// - onError: A closure to handle errors, and transform them into a `APIGatewayV2Response`. Defaults
17+ /// to converting the error into a 500 (Internal Server Error) response with the error message as the body.
18+ static func encoding< T> (
19+ _ encodable: T ,
20+ status: HTTPResponse . Status = . ok,
21+ using encoder: JSONEncoder = JSONEncoder ( ) ,
22+ onError: ( ( Error ) -> Self ) ? = nil
23+ ) -> Self where T: Encodable {
24+ do {
25+ let encodedResponse = try encoder. encode ( encodable)
26+ return APIGatewayV2Response (
27+ statusCode: status,
28+ body: String ( data: encodedResponse, encoding: . utf8)
29+ )
30+ } catch {
31+ return ( onError ?? defaultErrorHandler) ( error)
32+ }
33+ }
34+ }
35+
36+ private func defaultErrorHandler( _ error: Error ) -> APIGatewayV2Response {
37+ APIGatewayV2Response (
38+ statusCode: . internalServerError,
39+ body: " Internal Server Error: \( String ( describing: error) ) "
40+ )
41+ }
Original file line number Diff line number Diff line change 1+ #if canImport(FoundationEssentials)
2+ import FoundationEssentials
3+ #else
4+ import Foundation
5+ #endif
6+
7+ import HTTPTypes
8+
9+ public extension FunctionURLRequest {
10+ /// Decodes the body of the request into a `Data` object.
11+ ///
12+ /// - Returns: The decoded body as `Data` or `nil` if the body is empty.
13+ func decodeBody( ) throws -> Data ? {
14+ guard let body else { return nil }
15+
16+ if isBase64Encoded,
17+ let base64Decoded = Data ( base64Encoded: body) {
18+ return base64Decoded
19+ }
20+
21+ return body. data ( using: . utf8)
22+ }
23+
24+ /// Decodes the body of the request into a decodable object. When the
25+ /// body is empty, an error is thrown.
26+ ///
27+ /// - Parameters:
28+ /// - type: The type to decode the body into.
29+ /// - decoder: The decoder to use. Defaults to `JSONDecoder()`.
30+ ///
31+ /// - Returns: The decoded body as `T`.
32+ /// - Throws: An error if the body cannot be decoded.
33+ func decodeBody< T> (
34+ _ type: T . Type ,
35+ using decoder: JSONDecoder = JSONDecoder ( )
36+ ) throws -> T where T: Decodable {
37+ let bodyData = body? . data ( using: . utf8) ?? Data ( )
38+
39+ var requestData = bodyData
40+
41+ if isBase64Encoded,
42+ let base64Decoded = Data ( base64Encoded: requestData) {
43+ requestData = base64Decoded
44+ }
45+
46+ return try decoder. decode ( T . self, from: requestData)
47+ }
48+ }
Original file line number Diff line number Diff line change 1+ #if canImport(FoundationEssentials)
2+ import FoundationEssentials
3+ #else
4+ import Foundation
5+ #endif
6+
7+ import HTTPTypes
8+
9+ public extension FunctionURLResponse {
10+ /// Encodes a given encodable object into a `FunctionURLResponse` object.
11+ ///
12+ /// - Parameters:
13+ /// - encodable: The object to encode.
14+ /// - status: The status code to use. Defaults to `ok`.
15+ /// - encoder: The encoder to use. Defaults to a new `JSONEncoder`.
16+ /// - onError: A closure to handle errors, and transform them into a `FunctionURLResponse`. Defaults
17+ /// to converting the error into a 500 (Internal Server Error) response with the error message as the body.
18+ static func encoding< T> (
19+ _ encodable: T ,
20+ status: HTTPResponse . Status = . ok,
21+ using encoder: JSONEncoder = JSONEncoder ( ) ,
22+ onError: ( ( Error ) -> Self ) ? = nil
23+ ) -> Self where T: Encodable {
24+ do {
25+ let encodedResponse = try encoder. encode ( encodable)
26+ return FunctionURLResponse (
27+ statusCode: status,
28+ body: String ( data: encodedResponse, encoding: . utf8)
29+ )
30+ } catch {
31+ return ( onError ?? defaultErrorHandler) ( error)
32+ }
33+ }
34+ }
35+
36+ private func defaultErrorHandler( _ error: Error ) -> FunctionURLResponse {
37+ FunctionURLResponse (
38+ statusCode: . internalServerError,
39+ body: " Internal Server Error: \( String ( describing: error) ) "
40+ )
41+ }
Original file line number Diff line number Diff line change 1+ #if canImport(FoundationEssentials)
2+ import FoundationEssentials
3+ #else
4+ import Foundation
5+ #endif
6+
7+ public extension SQSEvent {
8+ /// Decodes the records included in the event into an array of decodable objects.
9+ ///
10+ /// - Parameters:
11+ /// - type: The type to decode the body into.
12+ /// - decoder: The decoder to use. Defaults to a new `JSONDecoder`.
13+ ///
14+ /// - Returns: The decoded records as `[T]`.
15+ /// - Throws: An error if any of the records cannot be decoded.
16+ func decodeBody< T> (
17+ _ type: T . Type ,
18+ using decoder: JSONDecoder = JSONDecoder ( )
19+ ) throws -> [ T ] where T: Decodable {
20+ try records. map {
21+ try $0. decodeBody ( type, using: decoder)
22+ }
23+ }
24+ }
25+
26+ public extension SQSEvent . Message {
27+ /// Decodes the body of the message into a decodable object.
28+ ///
29+ /// - Parameters:
30+ /// - type: The type to decode the body into.
31+ /// - decoder: The decoder to use. Defaults to a new `JSONDecoder`.
32+ ///
33+ /// - Returns: The decoded body as `T`.
34+ /// - Throws: An error if the body cannot be decoded.
35+ func decodeBody< T> (
36+ _ type: T . Type ,
37+ using decoder: JSONDecoder = JSONDecoder ( )
38+ ) throws -> T where T: Decodable {
39+ try decoder. decode ( T . self, from: body. data ( using: . utf8) ?? Data ( ) )
40+ }
41+ }
You can’t perform that action at this time.
0 commit comments