Skip to content

Commit

Permalink
feat: Add support for hook triggers on ParseConfig (#179)
Browse files Browse the repository at this point in the history
* feat: Add support for hook triggers on ParseConfig

* fix Swift backwards compatability

* nit

* doc nit

* bump swift requirement

* Update ci.yml
  • Loading branch information
cbaker6 committed Jul 20, 2024
1 parent 1199b57 commit d57b7c9
Show file tree
Hide file tree
Showing 6 changed files with 394 additions and 32 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
branches: [ main ]

env:
CI_XCODE_OLDEST: '/Applications/Xcode_13.3.1.app/Contents/Developer'
CI_XCODE_OLDEST: '/Applications/Xcode_14.2.app/Contents/Developer'
CI_XCODE_14: '/Applications/Xcode_14.3.1.app/Contents/Developer'
CI_XCODE_LATEST: '/Applications/Xcode_15.4.app/Contents/Developer'

Expand Down Expand Up @@ -101,7 +101,7 @@ jobs:
env:
DEVELOPER_DIR: ${{ env.CI_XCODE_LATEST }}

xcode-test-5_5:
xcode-test-5_7:
timeout-minutes: 25
needs: linux
runs-on: macos-12
Expand Down
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
# Parse-Swift Changelog

### main
[Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/5.10.3...main), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/main/documentation/parseswift)
[Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/5.11.0...main), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/main/documentation/parseswift)
* _Contributing to this repo? Add info about your change here to be included in the next release_

### 5.11.0
[Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/5.10.3...5.11.0), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/5.11.0/documentation/parseswift)

__New features__
* Allow hook triggers on ParseConfig and improve SDK ability to throw errors when the developer uses unsupported trigger combinations. Also changes lowest requirements to be Swift 5.7 and Xcode 14.0 which aligns with other Swift Packages ([#179](https://github.com/netreconlab/Parse-Swift/pull/179)), thanks to [Corey Baker](https://github.com/cbaker6).

### 5.10.3
[Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/5.10.2...5.10.3), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/5.10.3/documentation/parseswift)

Expand Down
23 changes: 14 additions & 9 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
// swift-tools-version:5.5.2
// swift-tools-version:5.7

import PackageDescription

let package = Package(
name: "ParseSwift",
platforms: [.iOS(.v13),
.macCatalyst(.v13),
.macOS(.v10_15),
.tvOS(.v13),
.watchOS(.v6)],
platforms: [
.iOS(.v13),
.macCatalyst(.v13),
.macOS(.v10_15),
.tvOS(.v13),
.watchOS(.v6)
],
products: [
.library(
name: "ParseSwift",
targets: ["ParseSwift"])
targets: ["ParseSwift"]
)
],
targets: [
.target(
name: "ParseSwift",
dependencies: []),
dependencies: []
),
.testTarget(
name: "ParseSwiftTests",
dependencies: ["ParseSwift"],
exclude: ["Info.plist"])
exclude: ["Info.plist"]
)
]
)
41 changes: 38 additions & 3 deletions 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 = "5.10.3"
static let version = "5.11.0"
static let fileManagementDirectory = "parse/"
static let fileManagementPrivateDocumentsDirectory = "Private Documents/"
static let fileManagementLibraryDirectory = "Library/"
Expand Down Expand Up @@ -51,9 +51,9 @@ public enum ParseHookTriggerType: String, Codable, Sendable {
case afterLogin
/// Occurs after logout of a `ParseUser`.
case afterLogout
/// Occurs before saving a `ParseObject` or `ParseFile`.
/// Occurs before saving a `ParseObject`, `ParseFile`, or `ParseConfig`.
case beforeSave
/// Occurs after saving a `ParseObject` or `ParseFile`.
/// Occurs after saving a `ParseObject`, `ParseFile`, or `ParseConfig`.
case afterSave
/// Occurs before deleting a `ParseObject` or `ParseFile`.
case beforeDelete
Expand All @@ -70,3 +70,38 @@ public enum ParseHookTriggerType: String, Codable, Sendable {
/// Occurs after a `ParseLiveQuery` event.
case afterEvent
}

/**
The objects that Parse Hooks can be triggered on.
*/
public enum ParseHookTriggerObject: Sendable {
/// The type of `ParseObject` to trigger on.
case objectType(any ParseObject.Type)
/// An instance of a `ParseObject` to trigger on.
case object(any ParseObject)
/// Trigger on `ParseFile`'s.
case file
/// Trigger on `ParseConfig` updates.
/// - warning: Requires Parse Server 7.3.0-alpha.6+.
case config
/// Trigger on `ParseLiveQuery` connections.
case liveQueryConnect

/// The class name of the `ParseObject` to trigger on.
var className: String {
switch self {

case .objectType(let object):
return object.className
case .object(let object):
return object.className
case .file:
return "@File"
case .config:
return "@Config"
case .liveQueryConnect:
return "@Connect"

}
}
}
144 changes: 131 additions & 13 deletions Sources/ParseSwift/Protocols/ParseHookTriggerable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ public extension ParseHookTriggerable {
- parameter trigger: The `ParseHookTriggerType` type.
- parameter url: The endpoint of the hook.
*/
init(className: String, trigger: ParseHookTriggerType, url: URL) {
init(
className: String,
trigger: ParseHookTriggerType,
url: URL
) {
self.init()
self.className = className
self.triggerName = trigger
Expand All @@ -45,7 +49,11 @@ public extension ParseHookTriggerable {
- parameter url: The endpoint of the hook.
*/
@available(*, deprecated, message: "Change \"triggerName\" to \"trigger\"")
init(className: String, triggerName: ParseHookTriggerType, url: URL) {
init(
className: String,
triggerName: ParseHookTriggerType,
url: URL
) {
self.init(className: className, trigger: triggerName, url: url)
}

Expand All @@ -55,7 +63,11 @@ public extension ParseHookTriggerable {
- parameter trigger: The `ParseHookTriggerType` type.
- parameter url: The endpoint of the hook.
*/
init<T>(object: T.Type, trigger: ParseHookTriggerType, url: URL) where T: ParseObject {
init<T>(
object: T.Type,
trigger: ParseHookTriggerType,
url: URL
) where T: ParseObject {
self.init(className: object.className, trigger: trigger, url: url)
}

Expand All @@ -65,7 +77,11 @@ public extension ParseHookTriggerable {
- parameter trigger: The `ParseHookTriggerType` type.
- parameter url: The endpoint of the hook.
*/
init<T>(object: T, trigger: ParseHookTriggerType, url: URL) where T: ParseObject {
init<T>(
object: T,
trigger: ParseHookTriggerType,
url: URL
) where T: ParseObject {
self.init(className: T.className, trigger: trigger, url: url)
}

Expand All @@ -76,27 +92,129 @@ public extension ParseHookTriggerable {
- parameter url: The endpoint of the hook.
*/
@available(*, deprecated, message: "Change \"triggerName\" to \"trigger\"")
init<T>(object: T, triggerName: ParseHookTriggerType, url: URL) where T: ParseObject {
init<T>(
object: T,
triggerName: ParseHookTriggerType,
url: URL
) where T: ParseObject {
self.init(object: object, trigger: triggerName, url: url)
}

/**
Creates a new Parse hook trigger for any supported `ParseHookTriggerObject`.
- parameter object: The `ParseHookTriggerObject` the trigger should act on.
- parameter trigger: The `ParseHookTriggerType` type.
- parameter url: The endpoint of the hook.
*/
init( // swiftlint:disable:this cyclomatic_complexity function_body_length
object: ParseHookTriggerObject,
trigger: ParseHookTriggerType,
url: URL
) throws {

let notSupportedError = ParseError(
code: .otherCause,
message: "This object \"\(object)\" currently does not support the hook trigger \"\(trigger)\""
)

switch object {
case .objectType(let parseObject):
switch trigger {
case .beforeLogin, .afterLogin, .afterLogout:
guard parseObject is (any ParseUser.Type) else {
throw notSupportedError
}
case .beforeSave, .afterSave, .beforeDelete,
.afterDelete, .beforeFind, .afterFind,
.beforeSubscribe, .afterEvent:
break // No op
default:
throw notSupportedError
}
self.init(
className: object.className,
trigger: trigger,
url: url
)
case .object(let parseObject):
switch trigger {
case .beforeLogin, .afterLogin, .afterLogout:
guard parseObject is (any ParseUser) else {
throw notSupportedError
}
case .beforeSave, .afterSave, .beforeDelete,
.afterDelete, .beforeFind, .afterFind,
.beforeSubscribe, .afterEvent:
break // No op
default:
throw notSupportedError
}
self.init(
className: object.className,
trigger: trigger,
url: url
)
case .file:
switch trigger {
case .beforeSave, .afterSave, .beforeDelete, .afterDelete:
break // No op
default:
throw notSupportedError
}
self.init(
className: object.className,
trigger: trigger,
url: url
)
case .config:
switch trigger {
case .beforeSave, .afterSave:
break // No op
default:
throw notSupportedError
}
self.init(
className: object.className,
trigger: trigger,
url: url
)
case .liveQueryConnect:
guard trigger == .beforeConnect else {
throw notSupportedError
}
self.init(
className: object.className,
trigger: trigger,
url: url
)
}
}

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

Expand Down
Loading

0 comments on commit d57b7c9

Please sign in to comment.