Skip to content

Commit 4ccb8a6

Browse files
authored
feat: add support for ParseFile and beforeConnect triggers (#376)
* 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
1 parent 97885ce commit 4ccb8a6

14 files changed

+188
-45
lines changed

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@
22

33
### main
44

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

8+
### 4.7.0
9+
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/4.6.0...4.7.0)
10+
11+
__New features__
12+
- 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).
13+
814
### 4.6.0
915
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/4.5.0...4.6.0)
1016

ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ var query = GameScore.query("points" > 50,
6767
//: Query asynchronously (preferred way) - Performs work on background
6868
//: queue and returns to specified callbackQueue.
6969
//: If no callbackQueue is specified it returns to main queue.
70-
query.limit(2).find(callbackQueue: .main) { results in
70+
query.limit(2)
71+
.order([.descending("points")])
72+
.find(callbackQueue: .main) { results in
7173
switch results {
7274
case .success(let scores):
7375

Sources/ParseSwift/LiveQuery/LiveQueryConstants.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public enum Event<T: ParseObject>: Equatable {
3939
case .create: self = .created(event.object)
4040
case .update: self = .updated(event.object)
4141
case .delete: self = .deleted(event.object)
42-
default: fatalError()
42+
default: return nil
4343
}
4444
}
4545

Sources/ParseSwift/ParseConstants.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Foundation
1010

1111
enum ParseConstants {
1212
static let sdk = "swift"
13-
static let version = "4.5.0"
13+
static let version = "4.7.0"
1414
static let fileManagementDirectory = "parse/"
1515
static let fileManagementPrivateDocumentsDirectory = "Private Documents/"
1616
static let fileManagementLibraryDirectory = "Library/"

Sources/ParseSwift/Protocols/ParseHookRequestable.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public protocol ParseHookRequestable: ParseTypeable {
2121
Specifies if the **masterKey** was used in the
2222
Parse hook call.
2323
*/
24-
var masterKey: Bool { get }
24+
var masterKey: Bool? { get }
2525
/**
2626
A `ParseUser` that contains additional attributes
2727
needed for Parse hook calls. If **nil** a user with
@@ -35,11 +35,11 @@ public protocol ParseHookRequestable: ParseTypeable {
3535
/**
3636
The IP address of the client making the request.
3737
*/
38-
var ipAddress: String { get }
38+
var ipAddress: String? { get }
3939
/**
4040
The original HTTP headers for the request.
4141
*/
42-
var headers: [String: String] { get }
42+
var headers: [String: String]? { get }
4343
}
4444

4545
extension ParseHookRequestable {
@@ -49,7 +49,8 @@ extension ParseHookRequestable {
4949
*/
5050
public func options() -> API.Options {
5151
var options = API.Options()
52-
if masterKey {
52+
if let masterKey = masterKey,
53+
masterKey == true {
5354
options.insert(.useMasterKey)
5455
} else if let sessionToken = user?.sessionToken {
5556
options.insert(.sessionToken(sessionToken))

Sources/ParseSwift/Protocols/ParseHookTriggerable.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,26 @@ public extension ParseHookTriggerable {
4646
init<T>(object: T, triggerName: ParseHookTriggerType, url: URL) where T: ParseObject {
4747
self.init(className: T.className, triggerName: triggerName, url: url)
4848
}
49+
50+
/**
51+
Creates a new `ParseFile` or `ParseHookTriggerType.beforeConnect` hook trigger.
52+
- parameter triggerName: The `ParseHookTriggerType` type.
53+
- parameter url: The endpoint of the hook.
54+
*/
55+
init(triggerName: ParseHookTriggerType, url: URL) throws {
56+
self.init()
57+
self.triggerName = triggerName
58+
self.url = url
59+
switch triggerName {
60+
case .beforeSave, .afterSave, .beforeDelete, .afterDelete:
61+
self.className = "@File"
62+
case .beforeConnect:
63+
self.className = "@Connect"
64+
default:
65+
throw ParseError(code: .unknownError,
66+
message: "This initializer should only be used for \"ParseFile\" and \"beforeConnect\"")
67+
}
68+
}
4969
}
5070

5171
internal struct TriggerRequest: Encodable {

Sources/ParseSwift/Types/ParseHookFunctionRequest.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,16 @@ import Foundation
1616
*/
1717
public struct ParseHookFunctionRequest<U: ParseCloudUser, P: ParseHookParametable>: ParseHookRequestable {
1818
public typealias UsertType = U
19-
public var masterKey: Bool
19+
public var masterKey: Bool?
2020
public var user: U?
2121
public var installationId: String?
22+
public var ipAddress: String?
23+
public var headers: [String: String]?
2224
/**
2325
The `ParseHookParametable` object containing the parameters passed
2426
to the function.
2527
*/
2628
public var parameters: P
27-
public var ipAddress: String
28-
public var headers: [String: String]
2929
var log: AnyCodable?
3030
var context: AnyCodable?
3131

Sources/ParseSwift/Types/ParseHookTriggerRequest.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ import Foundation
1616
*/
1717
public struct ParseHookTriggerRequest<U: ParseCloudUser, T: ParseObject>: ParseHookRequestable {
1818
public typealias UserType = U
19-
public var masterKey: Bool
19+
public var masterKey: Bool?
2020
public var user: U?
2121
public var installationId: String?
22-
public var ipAddress: String
23-
public var headers: [String: String]
22+
public var ipAddress: String?
23+
public var headers: [String: String]?
2424
/// An object from the hook call.
25-
public var object: T
25+
public var object: T?
2626
/// The results the query yielded..
2727
public var objects: [T]?
2828
/// If set, the object, as currently stored.
@@ -46,6 +46,8 @@ public struct ParseHookTriggerRequest<U: ParseCloudUser, T: ParseObject>: ParseH
4646
LiveQuery from pushing to the client.
4747
*/
4848
public var sendEvent: Bool?
49+
/// The live query event that triggered the request.
50+
public var event: String?
4951
var log: AnyCodable?
5052
var context: AnyCodable?
5153

Sources/ParseSwift/Types/Query.swift

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,72 @@ public struct Query<T>: ParseTypeable where T: ParseObject {
9292
case pipeline
9393
}
9494

95+
public init(from decoder: Decoder) throws {
96+
let values = try decoder.container(keyedBy: CodingKeys.self)
97+
`where` = try values.decode(QueryWhere.self, forKey: .`where`)
98+
if let limit = try values.decodeIfPresent(Int.self, forKey: .limit) {
99+
self.limit = limit
100+
}
101+
if let skip = try values.decodeIfPresent(Int.self, forKey: .skip) {
102+
self.skip = skip
103+
}
104+
do {
105+
keys = try values.decodeIfPresent(Set<String>.self, forKey: .keys)
106+
} catch {
107+
if let commaString = try values.decodeIfPresent(String.self, forKey: .keys) {
108+
let commaArray = commaString
109+
.split(separator: ",")
110+
.compactMap { String($0) }
111+
keys = Set(commaArray)
112+
}
113+
}
114+
do {
115+
include = try values.decodeIfPresent(Set<String>.self, forKey: .include)
116+
} catch {
117+
if let commaString = try values.decodeIfPresent(String.self, forKey: .include) {
118+
let commaArray = commaString
119+
.split(separator: ",")
120+
.compactMap { String($0) }
121+
include = Set(commaArray)
122+
}
123+
}
124+
do {
125+
order = try values.decodeIfPresent([Order].self, forKey: .order)
126+
} catch {
127+
let orderString = try values
128+
.decodeIfPresent(String.self, forKey: .order)?
129+
.split(separator: ",")
130+
.compactMap { String($0) }
131+
order = orderString?.map {
132+
var value = $0
133+
if value.hasPrefix("-") {
134+
value.removeFirst()
135+
return Order.descending(value)
136+
} else {
137+
return Order.ascending(value)
138+
}
139+
}
140+
}
141+
do {
142+
excludeKeys = try values.decodeIfPresent(Set<String>.self, forKey: .excludeKeys)
143+
} catch {
144+
if let commaString = try values.decodeIfPresent(String.self, forKey: .excludeKeys) {
145+
let commaArray = commaString
146+
.split(separator: ",")
147+
.compactMap { String($0) }
148+
excludeKeys = Set(commaArray)
149+
}
150+
}
151+
isCount = try values.decodeIfPresent(Bool.self, forKey: .isCount)
152+
explain = try values.decodeIfPresent(Bool.self, forKey: .explain)
153+
hint = try values.decodeIfPresent(AnyCodable.self, forKey: .hint)
154+
readPreference = try values.decodeIfPresent(String.self, forKey: .readPreference)
155+
includeReadPreference = try values.decodeIfPresent(String.self, forKey: .includeReadPreference)
156+
subqueryReadPreference = try values.decodeIfPresent(String.self, forKey: .subqueryReadPreference)
157+
distinct = try values.decodeIfPresent(String.self, forKey: .distinct)
158+
pipeline = try values.decodeIfPresent([[String: AnyCodable]].self, forKey: .pipeline)
159+
}
160+
95161
/**
96162
An enum that determines the order to sort the results based on a given key.
97163

Tests/ParseSwiftTests/ParseHookFunctionRequestCombineTests.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,15 @@ class ParseHookFunctionRequestCombineTests: XCTestCase {
9393
let functionRequest = ParseHookFunctionRequest<User, Parameters>(masterKey: true,
9494
user: user,
9595
installationId: installationId,
96-
parameters: parameters,
9796
ipAddress: "1.1.1.1",
98-
headers: ["yolo": "me"])
97+
headers: ["yolo": "me"],
98+
parameters: parameters)
9999
let requestHydrated = ParseHookFunctionRequest<User, Parameters>(masterKey: true,
100100
user: server,
101101
installationId: installationId,
102-
parameters: parameters,
103102
ipAddress: "1.1.1.1",
104-
headers: ["yolo": "me"])
103+
headers: ["yolo": "me"],
104+
parameters: parameters)
105105

106106
let publisher = functionRequest.hydrateUserPublisher()
107107
.sink(receiveCompletion: { result in
@@ -135,9 +135,9 @@ class ParseHookFunctionRequestCombineTests: XCTestCase {
135135
let functionRequest = ParseHookFunctionRequest<User, Parameters>(masterKey: true,
136136
user: user,
137137
installationId: installationId,
138-
parameters: parameters,
139138
ipAddress: "1.1.1.1",
140-
headers: ["yolo": "me"])
139+
headers: ["yolo": "me"],
140+
parameters: parameters)
141141
let publisher = functionRequest.hydrateUserPublisher()
142142
.sink(receiveCompletion: { result in
143143

0 commit comments

Comments
 (0)