diff --git a/packages/stream_chat/lib/src/models/filter.dart b/packages/stream_chat/lib/src/models/filter.dart index 2356c57b..eb3932ff 100644 --- a/packages/stream_chat/lib/src/models/filter.dart +++ b/packages/stream_chat/lib/src/models/filter.dart @@ -87,8 +87,8 @@ extension FilterOperatorX on FilterOperator { /// See Query Channels Documentation class Filter extends Equatable { const Filter.__({ - required this.operator, required this.value, + this.operator, this.key, }); @@ -159,13 +159,26 @@ class Filter extends Equatable { /// Creates a custom [Filter] if there isn't one already available. const factory Filter.custom({ - required String operator, required Object value, + String? operator, String? key, }) = Filter.__; + /// Creates a custom [Filter] from a raw map value + /// + /// ```dart + /// final filter = Filter.raw( + /// { + /// 'members': [user1.id, user2.id], + /// } + /// ) + /// ``` + const factory Filter.raw({ + required Map value, + }) = Filter.__; + /// An operator used for the filter. The operator string must start with `$` - final String operator; + final String? operator; /// The "left-hand" side of the filter. /// Specifies the name of the field the filter should match. @@ -183,24 +196,22 @@ class Filter extends Equatable { List get props => [operator, key, value]; /// Serializes to json object - Map toJson() { - final json = {}; + Map toJson() { + final json = {}; final groupOperators = _groupOperators.map((it) => it.rawValue); - assert( - groupOperators.contains(operator) || key != null, - 'Filter must contain the `key` when the operator is not a ' - 'group operator.', - ); - if (groupOperators.contains(operator)) { // Filters with group operators are encoded in the following form: // { $: [ , ] } - json[operator] = value; - } else { + json[operator!] = value; + } else if (operator != null) { // Normal filters are encoded in the following form: // { key: { $: } } json[key!] = {operator: value}; + } else if (key != null) { + json[key!] = value; + } else { + return value as Map; } return json; diff --git a/packages/stream_chat/test/src/models/filter_test.dart b/packages/stream_chat/test/src/models/filter_test.dart index c73c0d0b..ac026c6c 100644 --- a/packages/stream_chat/test/src/models/filter_test.dart +++ b/packages/stream_chat/test/src/models/filter_test.dart @@ -130,6 +130,14 @@ void main() { expect(filter.operator, operator); }); + test('raw', () { + const value = { + 'test': ['a', 'b'], + }; + const filter = Filter.raw(value: value); + expect(filter.value, value); + }); + group('groupedOperator', () { final filter1 = Filter.equal('testKey', 'testValue'); final filter2 = Filter.in_('testKey', const ['testValue']); @@ -180,6 +188,30 @@ void main() { '{"$key":{"${FilterOperator.in_.rawValue}":${json.encode(values)}}}', ); }); + + test('custom with no operator', () { + const key = 'testKey'; + const values = ['testValue']; + final filter = Filter.custom(key: key, value: values); + final encoded = json.encode(filter); + expect( + encoded, + '{"$key":${json.encode(values)}}', + ); + }); + + test('raw', () { + const value = { + 'test': ['a', 'b'], + }; + const filter = Filter.raw(value: value); + + final encoded = json.encode(filter); + expect( + encoded, + json.encode(value), + ); + }); }); test('groupedFilter', () {