From 4d78f1066d510adff37f6c81aacaf85adabe77c4 Mon Sep 17 00:00:00 2001 From: Khan Winter <35942988+thecoolwinter@users.noreply.github.com> Date: Fri, 30 Jul 2021 10:20:21 -0500 Subject: [PATCH 1/5] Fixed RPC builder, removed testing framework Fixed a bug with the RPC builder setting the query builder's method to the RPC's schema. Added a test for RPC functions. Removed unnecessary testing framework. Updated README.md --- Package.resolved | 16 --------- Package.swift | 9 +---- README.md | 29 +++++++++++++++- .../PostgREST/RPC/PostgrestRpcBuilder.swift | 9 +++-- .../PostgRESTTests/BuildURLRequestTests.swift | 33 ------------------ Tests/PostgRESTTests/PostgRESTTests.swift | 34 ++++++++++++++----- ...sers-where-email-ends-with-supabase-co.txt | 3 -- 7 files changed, 61 insertions(+), 72 deletions(-) delete mode 100644 Package.resolved delete mode 100644 Tests/PostgRESTTests/BuildURLRequestTests.swift delete mode 100644 Tests/PostgRESTTests/__Snapshots__/BuildURLRequestTests/testBuildURLRequest.select-all-users-where-email-ends-with-supabase-co.txt diff --git a/Package.resolved b/Package.resolved deleted file mode 100644 index 8b5ef50..0000000 --- a/Package.resolved +++ /dev/null @@ -1,16 +0,0 @@ -{ - "object": { - "pins": [ - { - "package": "SnapshotTesting", - "repositoryURL": "https://github.com/pointfreeco/swift-snapshot-testing.git", - "state": { - "branch": null, - "revision": "f8a9c997c3c1dab4e216a8ec9014e23144cbab37", - "version": "1.9.0" - } - } - ] - }, - "version": 1 -} diff --git a/Package.swift b/Package.swift index 63a5895..584fa82 100644 --- a/Package.swift +++ b/Package.swift @@ -5,9 +5,6 @@ import PackageDescription let package = Package( name: "PostgREST", - platforms: [.iOS(.v11), - .macOS(.v11), - .watchOS(.v2)], products: [ // Products define the executables and libraries a package produces, and make them visible to other packages. .library( @@ -16,10 +13,6 @@ let package = Package( ) ], dependencies: [ - // Dependencies declare other packages that this package depends on. - .package( - name: "SnapshotTesting", - url: "https://github.com/pointfreeco/swift-snapshot-testing.git", from: "1.8.1") ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. @@ -30,7 +23,7 @@ let package = Package( ), .testTarget( name: "PostgRESTTests", - dependencies: ["PostgREST", "SnapshotTesting"] + dependencies: ["PostgREST"] ) ] ) diff --git a/README.md b/README.md index 1c43fb3..c83945c 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ Add `postgrest-swift` as a dependency to your `Package.swift` file. For more inf .package(url: "https://github.com/supabase/postgrest-swift", from: "0.1.0") ``` +### Supabase + +You can also install the [ `supabase-swift`](https://github.com/supabase/supabase-swift) package to use the entire supabase library. + ## Usage Query todo table for all completed todos. @@ -54,12 +58,35 @@ do { // Handle response } } catch { - print("Error querying for todos: \(error)") + print("Error inserting the todo: \(error)") } ``` For more query examples visit [the Javascript docs](https://supabase.io/docs/reference/javascript/select) to learn more. The API design is a near 1:1 match. +Execute an RPC +```swift +let client = PostgrestClient(url: "https://example.supabase.co", schema: nil) + +do { + try client.rpc(fn: "testFunction", parameters: nil).execute { result in + // Handle result + } +} catch { + print("Error executing the RPC: \(error)") +} +``` + +## Auth + +You can add authentication to the databases requests by using the `client.headers` property. For example to add a `Bearer` auth header, simply set the headers dictionary to: +```swift +let client = PostgrestClient(url: "https://example.supabase.co", + headers: ["Bearer": "{ Insert Token Here }"] + schema: nil) +``` +All requests made using this client will be sent with the `Bearer Token` header. + ## Contributing - Fork the repo on GitHub diff --git a/Sources/PostgREST/RPC/PostgrestRpcBuilder.swift b/Sources/PostgREST/RPC/PostgrestRpcBuilder.swift index a7a409e..87d6382 100644 --- a/Sources/PostgREST/RPC/PostgrestRpcBuilder.swift +++ b/Sources/PostgREST/RPC/PostgrestRpcBuilder.swift @@ -2,8 +2,11 @@ public class PostgrestRpcBuilder: PostgrestBuilder { public func rpc(parameters: [String: Any]?) -> PostgrestTransformBuilder { method = "POST" body = parameters - return PostgrestTransformBuilder( - url: url, queryParams: queryParams, headers: headers, schema: schema, method: schema, - body: body) + return PostgrestTransformBuilder(url: url, + queryParams: queryParams, + headers: headers, + schema: schema, + method: method, + body: body) } } diff --git a/Tests/PostgRESTTests/BuildURLRequestTests.swift b/Tests/PostgRESTTests/BuildURLRequestTests.swift deleted file mode 100644 index 0e8bdd5..0000000 --- a/Tests/PostgRESTTests/BuildURLRequestTests.swift +++ /dev/null @@ -1,33 +0,0 @@ -import Foundation -import SnapshotTesting -import XCTest - -@testable import PostgREST - -final class BuildURLRequestTests: XCTestCase { - let url = "https://example.supabase.co" - - struct TestCase { - let name: String - var record = false - let build: (PostgrestClient) throws -> URLRequest - } - - func testBuildURLRequest() throws { - let client = PostgrestClient(url: url, schema: nil) - - let testCases: [TestCase] = [ - TestCase(name: "select all users where email ends with '@supabase.co'") { client in - try client.from("users") - .select() - .like(column: "email", value: "%@supabase.co") - .buildURLRequest(head: false, count: nil) - } - ] - - for testCase in testCases { - let request = try testCase.build(client) - assertSnapshot(matching: request, as: .curl, named: testCase.name, record: testCase.record) - } - } -} diff --git a/Tests/PostgRESTTests/PostgRESTTests.swift b/Tests/PostgRESTTests/PostgRESTTests.swift index 1c6509c..45c2e74 100644 --- a/Tests/PostgRESTTests/PostgRESTTests.swift +++ b/Tests/PostgRESTTests/PostgRESTTests.swift @@ -2,14 +2,32 @@ import XCTest final class PostgRESTTests: XCTestCase { - func testExample() { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct - // results. -// XCTAssertEqual(PostgREST().text, "Hello, World!") + let url: String = "https://example.supabase.co" + + func testBuildURLRequest() throws { + let client = PostgrestClient(url: url, schema: nil) + + let realURL = URL(string: "https://example.supabase.co/users?select=*&email=like.%25@supabase.co")! + + let generatedURLRequest = try client.from("users") + .select() + .like(column: "email", value: "%@supabase.co") + .buildURLRequest(head: false, count: nil) + + XCTAssertTrue(generatedURLRequest.url! == realURL) + XCTAssertTrue(generatedURLRequest.allHTTPHeaderFields == ["Content-Type": "application/json"]) } + + func testBuildRPCRequest() throws { + let client = PostgrestClient(url: url, schema: nil) - static var allTests = [ - ("testExample", testExample) - ] + let realURL = URL(string: "https://example.supabase.co/rpc/testFunction")! + + let generatedURLRequest = try client.rpc(fn: "testFunction", parameters: nil).buildURLRequest(head: false, count: nil) + + XCTAssertTrue(generatedURLRequest.url! == realURL) + XCTAssertTrue(generatedURLRequest.allHTTPHeaderFields == [:]) + XCTAssertTrue(generatedURLRequest.httpMethod == "POST") + } + } diff --git a/Tests/PostgRESTTests/__Snapshots__/BuildURLRequestTests/testBuildURLRequest.select-all-users-where-email-ends-with-supabase-co.txt b/Tests/PostgRESTTests/__Snapshots__/BuildURLRequestTests/testBuildURLRequest.select-all-users-where-email-ends-with-supabase-co.txt deleted file mode 100644 index d62c6b8..0000000 --- a/Tests/PostgRESTTests/__Snapshots__/BuildURLRequestTests/testBuildURLRequest.select-all-users-where-email-ends-with-supabase-co.txt +++ /dev/null @@ -1,3 +0,0 @@ -curl \ - --header "Content-Type: application/json" \ - "https://example.supabase.co/users?select=*&email=like.%25@supabase.co" \ No newline at end of file From e99aa465ff0340a899cd9e24a096c2ef990e7309 Mon Sep 17 00:00:00 2001 From: Khan Winter <35942988+thecoolwinter@users.noreply.github.com> Date: Thu, 12 Aug 2021 12:10:54 -0500 Subject: [PATCH 2/5] Add Test for RPC function call --- .../PostgRESTTests/BuildURLRequestTests.swift | 9 ++++--- Tests/PostgRESTTests/PostgRESTTests.swift | 27 ------------------- .../testBuildURLRequest.call-rpc.txt | 4 +++ 3 files changed, 10 insertions(+), 30 deletions(-) create mode 100644 Tests/PostgRESTTests/__Snapshots__/BuildURLRequestTests/testBuildURLRequest.call-rpc.txt diff --git a/Tests/PostgRESTTests/BuildURLRequestTests.swift b/Tests/PostgRESTTests/BuildURLRequestTests.swift index fae950a..704ded7 100644 --- a/Tests/PostgRESTTests/BuildURLRequestTests.swift +++ b/Tests/PostgRESTTests/BuildURLRequestTests.swift @@ -27,13 +27,16 @@ final class BuildURLRequestTests: XCTestCase { try client.from("users") .insert(values: ["email": "johndoe@supabase.io"]) .buildURLRequest(head: false, count: nil) - } + }, + TestCase(name: "call rpc", build: { client in + try client.rpc(fn: "test_fcn", parameters: ["KEY": "VALUE"]) + .buildURLRequest(head: false, count: nil) + }) ] for testCase in testCases { let request = try testCase.build(client) - assertSnapshot( - matching: request, as: .curl, named: testCase.name, record: testCase.record) + assertSnapshot(matching: request, as: .curl, named: testCase.name, record: testCase.record) } } } diff --git a/Tests/PostgRESTTests/PostgRESTTests.swift b/Tests/PostgRESTTests/PostgRESTTests.swift index cd19f6b..51a26f1 100644 --- a/Tests/PostgRESTTests/PostgRESTTests.swift +++ b/Tests/PostgRESTTests/PostgRESTTests.swift @@ -2,32 +2,5 @@ import XCTest final class PostgRESTTests: XCTestCase { -// let url: String = "https://example.supabase.co" - -// func testBuildURLRequest() throws { -// let client = PostgrestClient(url: url, schema: nil) -// -// let realURL = URL(string: "https://example.supabase.co/users?select=*&email=like.%25@supabase.co")! -// -// let generatedURLRequest = try client.from("users") -// .select() -// .like(column: "email", value: "%@supabase.co") -// .buildURLRequest(head: false, count: nil) -// -// XCTAssertTrue(generatedURLRequest.url! == realURL) -// XCTAssertTrue(generatedURLRequest.allHTTPHeaderFields == ["Content-Type": "application/json"]) -// } -// -// func testBuildRPCRequest() throws { -// let client = PostgrestClient(url: url, schema: nil) -// -// let realURL = URL(string: "https://example.supabase.co/rpc/testFunction")! -// -// let generatedURLRequest = try client.rpc(fn: "testFunction", parameters: nil).buildURLRequest(head: false, count: nil) -// -// XCTAssertTrue(generatedURLRequest.url! == realURL) -// XCTAssertTrue(generatedURLRequest.allHTTPHeaderFields == [:]) -// XCTAssertTrue(generatedURLRequest.httpMethod == "POST") -// } } diff --git a/Tests/PostgRESTTests/__Snapshots__/BuildURLRequestTests/testBuildURLRequest.call-rpc.txt b/Tests/PostgRESTTests/__Snapshots__/BuildURLRequestTests/testBuildURLRequest.call-rpc.txt new file mode 100644 index 0000000..a5168da --- /dev/null +++ b/Tests/PostgRESTTests/__Snapshots__/BuildURLRequestTests/testBuildURLRequest.call-rpc.txt @@ -0,0 +1,4 @@ +curl \ + --request POST \ + --data "{\"KEY\":\"VALUE\"}" \ + "https://example.supabase.co/rpc/test_fcn" \ No newline at end of file From a364567006b07b88da8756a1b615a7a6079f3004 Mon Sep 17 00:00:00 2001 From: Khan Winter <35942988+thecoolwinter@users.noreply.github.com> Date: Thu, 12 Aug 2021 12:26:16 -0500 Subject: [PATCH 3/5] Fix RPC builder bug RPC builder was passing `schema` to the `method` property. --- Sources/PostgREST/PostgrestRpcBuilder.swift | 6 +++++- Tests/PostgRESTTests/BuildURLRequestTests.swift | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Sources/PostgREST/PostgrestRpcBuilder.swift b/Sources/PostgREST/PostgrestRpcBuilder.swift index a7a409e..7e667b8 100644 --- a/Sources/PostgREST/PostgrestRpcBuilder.swift +++ b/Sources/PostgREST/PostgrestRpcBuilder.swift @@ -3,7 +3,11 @@ public class PostgrestRpcBuilder: PostgrestBuilder { method = "POST" body = parameters return PostgrestTransformBuilder( - url: url, queryParams: queryParams, headers: headers, schema: schema, method: schema, + url: url, + queryParams: queryParams, + headers: headers, + schema: schema, + method: method, body: body) } } diff --git a/Tests/PostgRESTTests/BuildURLRequestTests.swift b/Tests/PostgRESTTests/BuildURLRequestTests.swift index 66feda8..d5d09ea 100644 --- a/Tests/PostgRESTTests/BuildURLRequestTests.swift +++ b/Tests/PostgRESTTests/BuildURLRequestTests.swift @@ -24,7 +24,7 @@ final class BuildURLRequestTests: XCTestCase { .buildURLRequest(head: false, count: nil) }, TestCase(name: "insert new user") { client in - try client.from("users") + try client.form("users") .insert(values: ["email": "johndoe@supabase.io"]) .buildURLRequest(head: false, count: nil) }, From fecc91c919c62eeb32101377b35875e314f6745f Mon Sep 17 00:00:00 2001 From: Khan Winter <35942988+thecoolwinter@users.noreply.github.com> Date: Thu, 12 Aug 2021 12:28:28 -0500 Subject: [PATCH 4/5] Rename `form` to `from` --- Sources/PostgREST/PostgrestClient.swift | 2 +- Tests/PostgRESTTests/BuildURLRequestTests.swift | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/PostgREST/PostgrestClient.swift b/Sources/PostgREST/PostgrestClient.swift index 69cecbb..b79668f 100644 --- a/Sources/PostgREST/PostgrestClient.swift +++ b/Sources/PostgREST/PostgrestClient.swift @@ -22,7 +22,7 @@ public class PostgrestClient { /// Select a table to query from /// - Parameter table: The ID of the table to query /// - Returns: `PostgrestQueryBuilder` - public func form(_ table: String) -> PostgrestQueryBuilder { + public func from(_ table: String) -> PostgrestQueryBuilder { return PostgrestQueryBuilder(url: "\(url)/\(table)", queryParams: [], headers: headers, schema: schema, method: nil, body: nil) } diff --git a/Tests/PostgRESTTests/BuildURLRequestTests.swift b/Tests/PostgRESTTests/BuildURLRequestTests.swift index d5d09ea..704ded7 100644 --- a/Tests/PostgRESTTests/BuildURLRequestTests.swift +++ b/Tests/PostgRESTTests/BuildURLRequestTests.swift @@ -18,13 +18,13 @@ final class BuildURLRequestTests: XCTestCase { let testCases: [TestCase] = [ TestCase(name: "select all users where email ends with '@supabase.co'") { client in - try client.form("users") + try client.from("users") .select() .like(column: "email", value: "%@supabase.co") .buildURLRequest(head: false, count: nil) }, TestCase(name: "insert new user") { client in - try client.form("users") + try client.from("users") .insert(values: ["email": "johndoe@supabase.io"]) .buildURLRequest(head: false, count: nil) }, From 4f4f8ef3bed5e3751c295519724985cca990c771 Mon Sep 17 00:00:00 2001 From: Khan Winter <35942988+thecoolwinter@users.noreply.github.com> Date: Wed, 25 Aug 2021 10:20:01 -0500 Subject: [PATCH 5/5] Update PostgrestBuilder.swift --- Sources/PostgREST/PostgrestBuilder.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/PostgREST/PostgrestBuilder.swift b/Sources/PostgREST/PostgrestBuilder.swift index b0a3d57..73e9445 100644 --- a/Sources/PostgREST/PostgrestBuilder.swift +++ b/Sources/PostgREST/PostgrestBuilder.swift @@ -161,6 +161,7 @@ public class PostgrestBuilder { request.httpMethod = method request.allHTTPHeaderFields = headers if let body = body { + headers["Content-Type"] = "application/json" request.httpBody = try JSONSerialization.data(withJSONObject: body, options: []) } return request