diff --git a/Sources/StreamAttachments/Info.plist b/Sources/StreamAttachments/Info.plist
index 9d6c403..b781e87 100644
--- a/Sources/StreamAttachments/Info.plist
+++ b/Sources/StreamAttachments/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
$(PRODUCT_BUNDLE_PACKAGE_TYPE)
CFBundleShortVersionString
- 0.6.1
+ 0.6.2
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
diff --git a/Sources/StreamCore/Info.plist b/Sources/StreamCore/Info.plist
index 9d6c403..b781e87 100644
--- a/Sources/StreamCore/Info.plist
+++ b/Sources/StreamCore/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
$(PRODUCT_BUNDLE_PACKAGE_TYPE)
CFBundleShortVersionString
- 0.6.1
+ 0.6.2
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
diff --git a/Sources/StreamCore/OpenAPI/Query/Filter+Local.swift b/Sources/StreamCore/OpenAPI/Query/Filter+Local.swift
index c46d37b..be10638 100644
--- a/Sources/StreamCore/OpenAPI/Query/Filter+Local.swift
+++ b/Sources/StreamCore/OpenAPI/Query/Filter+Local.swift
@@ -104,7 +104,14 @@ private struct FilterMatcher: Sendable where Model: Sendable, Valu
case .exists:
return Self.exists(localRawJSONValue, filterRawJSONValue)
case .equal:
- return Self.isEqual(localRawJSONValue, filterRawJSONValue)
+ switch value {
+ case is CircularRegion:
+ return Self.isNear(localRawJSONValue, filterRawJSONValue)
+ case is BoundingBox:
+ return Self.isWithinBounds(localRawJSONValue, filterRawJSONValue)
+ default:
+ return Self.isEqual(localRawJSONValue, filterRawJSONValue)
+ }
case .greater:
return Self.isGreater(localRawJSONValue, filterRawJSONValue)
case .greaterOrEqual:
@@ -123,10 +130,6 @@ private struct FilterMatcher: Sendable where Model: Sendable, Valu
return Self.isIn(localRawJSONValue, filterRawJSONValue)
case .pathExists:
return Self.pathExists(localRawJSONValue, filterRawJSONValue)
- case .near:
- return Self.isNear(localRawJSONValue, filterRawJSONValue)
- case .withinBounds:
- return Self.isWithinBounds(localRawJSONValue, filterRawJSONValue)
case .and, .or:
log.debug("Should never try to match compound operators")
return false
diff --git a/Sources/StreamCore/OpenAPI/Query/Filter.swift b/Sources/StreamCore/OpenAPI/Query/Filter.swift
index 55951f3..f9dcdee 100644
--- a/Sources/StreamCore/OpenAPI/Query/Filter.swift
+++ b/Sources/StreamCore/OpenAPI/Query/Filter.swift
@@ -195,33 +195,6 @@ extension Filter {
Self(filterOperator: .query, field: field, value: value)
}
- /// Creates a filter that uses the Haversine formula to find values
- /// within the specified distance from the given coordinates.
- ///
- /// This filter matches locations that fall within a circular region defined by a center point
- /// and a radius. The distance calculation uses the Haversine formula to account for Earth's curvature.
- ///
- /// - Parameters:
- /// - field: The field containing location coordinates to query.
- /// - value: The circular region defining the center point and radius to match against.
- /// - Returns: A filter that matches when the location field is within the specified circular region.
- public static func near(_ field: FilterField, _ value: CircularRegion) -> Self {
- Self(filterOperator: .near, field: field, value: value)
- }
-
- /// Creates a filter that finds values within the specified rectangular bounding box.
- ///
- /// This filter matches locations that fall within a rectangular geographic region defined by
- /// northeast and southwest corner coordinates.
- ///
- /// - Parameters:
- /// - field: The field containing location coordinates to query.
- /// - value: The bounding box defining the rectangular region to match against.
- /// - Returns: A filter that matches when the location field is within the specified bounding box.
- public static func withinBounds(_ field: FilterField, _ value: BoundingBox) -> Self {
- Self(filterOperator: .withinBounds, field: field, value: value)
- }
-
/// Creates a filter that combines multiple filters with a logical AND operation.
///
/// - Parameter filters: An array of filters to combine.
diff --git a/Sources/StreamCore/OpenAPI/Query/FilterOperator.swift b/Sources/StreamCore/OpenAPI/Query/FilterOperator.swift
index 9ccca5f..0ea21d8 100644
--- a/Sources/StreamCore/OpenAPI/Query/FilterOperator.swift
+++ b/Sources/StreamCore/OpenAPI/Query/FilterOperator.swift
@@ -43,12 +43,6 @@ public enum FilterOperator: String, Sendable {
/// Matches if the value contains JSON with the given path.
case pathExists = "$path_exists"
-
- /// Matches if the location is within the specified circular area.
- case near = "$near"
-
- /// Matches if the location is within the specified rectangular area.
- case withinBounds = "$within_bounds"
}
extension FilterOperator {
diff --git a/Sources/StreamCore/OpenAPI/Query/FilterValue+Location.swift b/Sources/StreamCore/OpenAPI/Query/FilterValue+Location.swift
index c0dfbc7..a1aa599 100644
--- a/Sources/StreamCore/OpenAPI/Query/FilterValue+Location.swift
+++ b/Sources/StreamCore/OpenAPI/Query/FilterValue+Location.swift
@@ -133,7 +133,7 @@ extension BoundingBox: FilterValue {
}
}
-extension CLLocationCoordinate2D: @unchecked Sendable, FilterValue {
+extension CLLocationCoordinate2D: @unchecked @retroactive Sendable, FilterValue {
static let rawJSONLatitudeKey = "lat"
static let rawJSONLongitudeKey = "lng"
diff --git a/Sources/StreamCore/Utils/SystemEnvironment+Version.swift b/Sources/StreamCore/Utils/SystemEnvironment+Version.swift
index 08c4202..3e5113b 100644
--- a/Sources/StreamCore/Utils/SystemEnvironment+Version.swift
+++ b/Sources/StreamCore/Utils/SystemEnvironment+Version.swift
@@ -6,5 +6,5 @@ import Foundation
enum SystemEnvironment {
/// A Stream Core version.
- public static let version: String = "0.6.1"
+ public static let version: String = "0.6.2"
}
diff --git a/Sources/StreamCoreUI/Info.plist b/Sources/StreamCoreUI/Info.plist
index 9d6c403..b781e87 100644
--- a/Sources/StreamCoreUI/Info.plist
+++ b/Sources/StreamCoreUI/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
$(PRODUCT_BUNDLE_PACKAGE_TYPE)
CFBundleShortVersionString
- 0.6.1
+ 0.6.2
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
diff --git a/Tests/StreamCoreTests/OpenAPI/Query/Filter_Tests.swift b/Tests/StreamCoreTests/OpenAPI/Query/Filter_Tests.swift
index 2ee98d0..945ffd8 100644
--- a/Tests/StreamCoreTests/OpenAPI/Query/Filter_Tests.swift
+++ b/Tests/StreamCoreTests/OpenAPI/Query/Filter_Tests.swift
@@ -29,7 +29,8 @@ struct Filter_Tests {
static let createdAt = Self("created_at", localValue: \.createdAt)
static let isActive = Self("is_active", localValue: \.isActive)
static let searchData = Self("search_data", localValue: \.searchData)
- static let location = Self("location", localValue: \.location)
+ static let nearLocation = Self("near", localValue: \.location)
+ static let withinBoundsLocation = Self("within_bounds", localValue: \.location)
}
struct TestFilter: Filter {
@@ -261,12 +262,12 @@ struct Filter_Tests {
@Test func nearFilter() {
let center = CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194)
let region = CircularRegion(center: center, radiusInMeters: 5000)
- let filter = TestFilter.near(.location, region)
+ let filter = TestFilter.equal(.nearLocation, region)
let json = filter.toRawJSONDictionary()
let expected: [String: RawJSON] = [
- "location": .dictionary([
- "$near": .dictionary([
+ "near": .dictionary([
+ "$eq": .dictionary([
"lat": .number(37.7749),
"lng": .number(-122.4194),
"distance": .number(5.0) // 5000 meters = 5 km
@@ -281,12 +282,12 @@ struct Filter_Tests {
let northeast = CLLocationCoordinate2D(latitude: 40.7580, longitude: -73.9855)
let southwest = CLLocationCoordinate2D(latitude: 40.7128, longitude: -74.0060)
let boundingBox = BoundingBox(northeast: northeast, southwest: southwest)
- let filter = TestFilter.withinBounds(.location, boundingBox)
+ let filter = TestFilter.equal(.withinBoundsLocation, boundingBox)
let json = filter.toRawJSONDictionary()
let expected: [String: RawJSON] = [
- "location": .dictionary([
- "$within_bounds": .dictionary([
+ "within_bounds": .dictionary([
+ "$eq": .dictionary([
"ne_lat": .number(40.7580),
"ne_lng": .number(-73.9855),
"sw_lat": .number(40.7128),
@@ -1137,7 +1138,7 @@ struct Filter_Tests {
let center = CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194) // San Francisco
let region = CircularRegion(center: center, radiusInMeters: 5000) // 5 km radius
- let nearFilter = TestFilter.near(.location, region)
+ let nearFilter = TestFilter.equal(.nearLocation, region)
// Location at center should match
#expect(nearFilter.matches(TestUser(location: center)))
@@ -1152,7 +1153,7 @@ struct Filter_Tests {
// Test with smaller radius
let smallRegion = CircularRegion(center: center, radiusInMeters: 100) // 100 meters radius
- let smallNearFilter = TestFilter.near(.location, smallRegion)
+ let smallNearFilter = TestFilter.equal(.nearLocation, smallRegion)
// Location at center should match
#expect(smallNearFilter.matches(TestUser(location: center)))
@@ -1162,7 +1163,7 @@ struct Filter_Tests {
// Test with radius in kilometers
let regionInKM = CircularRegion(center: center, radiusInKM: 10.0) // 10 km radius
- let nearFilterInKM = TestFilter.near(.location, regionInKM)
+ let nearFilterInKM = TestFilter.equal(.nearLocation, regionInKM)
// Location within 10 km should match
#expect(nearFilterInKM.matches(TestUser(location: nearbyLocation)))
@@ -1180,7 +1181,7 @@ struct Filter_Tests {
let southwest = CLLocationCoordinate2D(latitude: 40.7128, longitude: -74.0060) // Lower Manhattan
let boundingBox = BoundingBox(northeast: northeast, southwest: southwest)
- let withinBoundsFilter = TestFilter.withinBounds(.location, boundingBox)
+ let withinBoundsFilter = TestFilter.equal(.withinBoundsLocation, boundingBox)
// Location at northeast corner should match
#expect(withinBoundsFilter.matches(TestUser(location: northeast)))
@@ -1212,7 +1213,7 @@ struct Filter_Tests {
let sfNortheast = CLLocationCoordinate2D(latitude: 37.8044, longitude: -122.4094)
let sfSouthwest = CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194)
let sfBoundingBox = BoundingBox(northeast: sfNortheast, southwest: sfSouthwest)
- let sfWithinBoundsFilter = TestFilter.withinBounds(.location, sfBoundingBox)
+ let sfWithinBoundsFilter = TestFilter.equal(.withinBoundsLocation, sfBoundingBox)
// Location within SF bounding box should match
let sfLocation = CLLocationCoordinate2D(latitude: 37.7897, longitude: -122.4144)
@@ -1225,7 +1226,7 @@ struct Filter_Tests {
let smallNortheast = CLLocationCoordinate2D(latitude: 37.7751, longitude: -122.4192)
let smallSouthwest = CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194)
let smallBoundingBox = BoundingBox(northeast: smallNortheast, southwest: smallSouthwest)
- let smallWithinBoundsFilter = TestFilter.withinBounds(.location, smallBoundingBox)
+ let smallWithinBoundsFilter = TestFilter.equal(.withinBoundsLocation, smallBoundingBox)
// Location at southwest corner should match
#expect(smallWithinBoundsFilter.matches(TestUser(location: smallSouthwest)))