Skip to content

Commit

Permalink
feat: add support for ParseFile and beforeConnect triggers (#376)
Browse files Browse the repository at this point in the history
* feat: add support for ParseFile and beforeConnect triggers

* fix test

* make masterKey optional on hook requests

* make other hook properties optional

* add decoder to Query

* decode query comma strings

* Fix codecov

* remove test from linux and windows

* remove extra test

* codecov

* nits

* add Event to trigger request
  • Loading branch information
cbaker6 authored Jun 26, 2022
1 parent 97885ce commit 4ccb8a6
Show file tree
Hide file tree
Showing 14 changed files with 188 additions and 45 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@

### main

[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/4.6.0...main)
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/4.7.0...main)
* _Contributing to this repo? Add info about your change here to be included in the next release_

### 4.7.0
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/4.6.0...4.7.0)

__New features__
- Add support for ParseFile and beforeConnect triggers ([#376](https://github.com/parse-community/Parse-Swift/pull/376)), thanks to [Corey Baker](https://github.com/cbaker6).

### 4.6.0
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/4.5.0...4.6.0)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ var query = GameScore.query("points" > 50,
//: Query asynchronously (preferred way) - Performs work on background
//: queue and returns to specified callbackQueue.
//: If no callbackQueue is specified it returns to main queue.
query.limit(2).find(callbackQueue: .main) { results in
query.limit(2)
.order([.descending("points")])
.find(callbackQueue: .main) { results in
switch results {
case .success(let scores):

Expand Down
2 changes: 1 addition & 1 deletion Sources/ParseSwift/LiveQuery/LiveQueryConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public enum Event<T: ParseObject>: Equatable {
case .create: self = .created(event.object)
case .update: self = .updated(event.object)
case .delete: self = .deleted(event.object)
default: fatalError()
default: return nil
}
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/ParseSwift/ParseConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation

enum ParseConstants {
static let sdk = "swift"
static let version = "4.5.0"
static let version = "4.7.0"
static let fileManagementDirectory = "parse/"
static let fileManagementPrivateDocumentsDirectory = "Private Documents/"
static let fileManagementLibraryDirectory = "Library/"
Expand Down
9 changes: 5 additions & 4 deletions Sources/ParseSwift/Protocols/ParseHookRequestable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public protocol ParseHookRequestable: ParseTypeable {
Specifies if the **masterKey** was used in the
Parse hook call.
*/
var masterKey: Bool { get }
var masterKey: Bool? { get }
/**
A `ParseUser` that contains additional attributes
needed for Parse hook calls. If **nil** a user with
Expand All @@ -35,11 +35,11 @@ public protocol ParseHookRequestable: ParseTypeable {
/**
The IP address of the client making the request.
*/
var ipAddress: String { get }
var ipAddress: String? { get }
/**
The original HTTP headers for the request.
*/
var headers: [String: String] { get }
var headers: [String: String]? { get }
}

extension ParseHookRequestable {
Expand All @@ -49,7 +49,8 @@ extension ParseHookRequestable {
*/
public func options() -> API.Options {
var options = API.Options()
if masterKey {
if let masterKey = masterKey,
masterKey == true {
options.insert(.useMasterKey)
} else if let sessionToken = user?.sessionToken {
options.insert(.sessionToken(sessionToken))
Expand Down
20 changes: 20 additions & 0 deletions Sources/ParseSwift/Protocols/ParseHookTriggerable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,26 @@ public extension ParseHookTriggerable {
init<T>(object: T, triggerName: ParseHookTriggerType, url: URL) where T: ParseObject {
self.init(className: T.className, triggerName: triggerName, url: url)
}

/**
Creates a new `ParseFile` or `ParseHookTriggerType.beforeConnect` hook trigger.
- parameter triggerName: The `ParseHookTriggerType` type.
- parameter url: The endpoint of the hook.
*/
init(triggerName: ParseHookTriggerType, url: URL) throws {
self.init()
self.triggerName = triggerName
self.url = url
switch triggerName {
case .beforeSave, .afterSave, .beforeDelete, .afterDelete:
self.className = "@File"
case .beforeConnect:
self.className = "@Connect"
default:
throw ParseError(code: .unknownError,
message: "This initializer should only be used for \"ParseFile\" and \"beforeConnect\"")
}
}
}

internal struct TriggerRequest: Encodable {
Expand Down
6 changes: 3 additions & 3 deletions Sources/ParseSwift/Types/ParseHookFunctionRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ import Foundation
*/
public struct ParseHookFunctionRequest<U: ParseCloudUser, P: ParseHookParametable>: ParseHookRequestable {
public typealias UsertType = U
public var masterKey: Bool
public var masterKey: Bool?
public var user: U?
public var installationId: String?
public var ipAddress: String?
public var headers: [String: String]?
/**
The `ParseHookParametable` object containing the parameters passed
to the function.
*/
public var parameters: P
public var ipAddress: String
public var headers: [String: String]
var log: AnyCodable?
var context: AnyCodable?

Expand Down
10 changes: 6 additions & 4 deletions Sources/ParseSwift/Types/ParseHookTriggerRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ import Foundation
*/
public struct ParseHookTriggerRequest<U: ParseCloudUser, T: ParseObject>: ParseHookRequestable {
public typealias UserType = U
public var masterKey: Bool
public var masterKey: Bool?
public var user: U?
public var installationId: String?
public var ipAddress: String
public var headers: [String: String]
public var ipAddress: String?
public var headers: [String: String]?
/// An object from the hook call.
public var object: T
public var object: T?
/// The results the query yielded..
public var objects: [T]?
/// If set, the object, as currently stored.
Expand All @@ -46,6 +46,8 @@ public struct ParseHookTriggerRequest<U: ParseCloudUser, T: ParseObject>: ParseH
LiveQuery from pushing to the client.
*/
public var sendEvent: Bool?
/// The live query event that triggered the request.
public var event: String?
var log: AnyCodable?
var context: AnyCodable?

Expand Down
66 changes: 66 additions & 0 deletions Sources/ParseSwift/Types/Query.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,72 @@ public struct Query<T>: ParseTypeable where T: ParseObject {
case pipeline
}

public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
`where` = try values.decode(QueryWhere.self, forKey: .`where`)
if let limit = try values.decodeIfPresent(Int.self, forKey: .limit) {
self.limit = limit
}
if let skip = try values.decodeIfPresent(Int.self, forKey: .skip) {
self.skip = skip
}
do {
keys = try values.decodeIfPresent(Set<String>.self, forKey: .keys)
} catch {
if let commaString = try values.decodeIfPresent(String.self, forKey: .keys) {
let commaArray = commaString
.split(separator: ",")
.compactMap { String($0) }
keys = Set(commaArray)
}
}
do {
include = try values.decodeIfPresent(Set<String>.self, forKey: .include)
} catch {
if let commaString = try values.decodeIfPresent(String.self, forKey: .include) {
let commaArray = commaString
.split(separator: ",")
.compactMap { String($0) }
include = Set(commaArray)
}
}
do {
order = try values.decodeIfPresent([Order].self, forKey: .order)
} catch {
let orderString = try values
.decodeIfPresent(String.self, forKey: .order)?
.split(separator: ",")
.compactMap { String($0) }
order = orderString?.map {
var value = $0
if value.hasPrefix("-") {
value.removeFirst()
return Order.descending(value)
} else {
return Order.ascending(value)
}
}
}
do {
excludeKeys = try values.decodeIfPresent(Set<String>.self, forKey: .excludeKeys)
} catch {
if let commaString = try values.decodeIfPresent(String.self, forKey: .excludeKeys) {
let commaArray = commaString
.split(separator: ",")
.compactMap { String($0) }
excludeKeys = Set(commaArray)
}
}
isCount = try values.decodeIfPresent(Bool.self, forKey: .isCount)
explain = try values.decodeIfPresent(Bool.self, forKey: .explain)
hint = try values.decodeIfPresent(AnyCodable.self, forKey: .hint)
readPreference = try values.decodeIfPresent(String.self, forKey: .readPreference)
includeReadPreference = try values.decodeIfPresent(String.self, forKey: .includeReadPreference)
subqueryReadPreference = try values.decodeIfPresent(String.self, forKey: .subqueryReadPreference)
distinct = try values.decodeIfPresent(String.self, forKey: .distinct)
pipeline = try values.decodeIfPresent([[String: AnyCodable]].self, forKey: .pipeline)
}

/**
An enum that determines the order to sort the results based on a given key.
Expand Down
12 changes: 6 additions & 6 deletions Tests/ParseSwiftTests/ParseHookFunctionRequestCombineTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,15 @@ class ParseHookFunctionRequestCombineTests: XCTestCase {
let functionRequest = ParseHookFunctionRequest<User, Parameters>(masterKey: true,
user: user,
installationId: installationId,
parameters: parameters,
ipAddress: "1.1.1.1",
headers: ["yolo": "me"])
headers: ["yolo": "me"],
parameters: parameters)
let requestHydrated = ParseHookFunctionRequest<User, Parameters>(masterKey: true,
user: server,
installationId: installationId,
parameters: parameters,
ipAddress: "1.1.1.1",
headers: ["yolo": "me"])
headers: ["yolo": "me"],
parameters: parameters)

let publisher = functionRequest.hydrateUserPublisher()
.sink(receiveCompletion: { result in
Expand Down Expand Up @@ -135,9 +135,9 @@ class ParseHookFunctionRequestCombineTests: XCTestCase {
let functionRequest = ParseHookFunctionRequest<User, Parameters>(masterKey: true,
user: user,
installationId: installationId,
parameters: parameters,
ipAddress: "1.1.1.1",
headers: ["yolo": "me"])
headers: ["yolo": "me"],
parameters: parameters)
let publisher = functionRequest.hydrateUserPublisher()
.sink(receiveCompletion: { result in

Expand Down
Loading

0 comments on commit 4ccb8a6

Please sign in to comment.