Skip to content

Commit cb6d2d1

Browse files
feat: [CHA-1584] - Predefined filters support (#1675)
Signed-off-by: Lennart Kuijs <mail@lennartkuijs.nl> Co-authored-by: MartinCupela <32706194+MartinCupela@users.noreply.github.com> Co-authored-by: martincupela <martin.cupela@gmail.com>
1 parent 32705e1 commit cb6d2d1

3 files changed

Lines changed: 588 additions & 10 deletions

File tree

src/client.ts

Lines changed: 103 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ import type {
7676
CreatePollAPIResponse,
7777
CreatePollData,
7878
CreatePollOptionAPIResponse,
79+
CreatePredefinedFilterOptions,
7980
CreateReminderOptions,
8081
CustomPermissionOptions,
8182
DeactivateUsersOptions,
@@ -124,6 +125,8 @@ import type {
124125
ListCommandsResponse,
125126
ListImportsPaginationOptions,
126127
ListImportsResponse,
128+
ListPredefinedFiltersOptions,
129+
ListPredefinedFiltersResponse,
127130
LocalMessage,
128131
Logger,
129132
MarkChannelsReadOptions,
@@ -153,6 +156,7 @@ import type {
153156
PollVote,
154157
PollVoteData,
155158
PollVotesAPIResponse,
159+
PredefinedFilterResponse,
156160
Product,
157161
PushPreference,
158162
PushProvider,
@@ -221,6 +225,7 @@ import type {
221225
UpdateMessageOptions,
222226
UpdatePollAPIResponse,
223227
UpdatePollOptionAPIResponse,
228+
UpdatePredefinedFilterOptions,
224229
UpdateReminderOptions,
225230
UpdateSegmentData,
226231
UpdateUsersAPIResponse,
@@ -1841,10 +1846,10 @@ export class StreamChat {
18411846
/**
18421847
* queryChannelsRequest - Queries channels and returns the raw response
18431848
*
1844-
* @param {ChannelFilters} filterConditions object MongoDB style filters
1849+
* @param {ChannelFilters} filterConditions object MongoDB style filters. Can be empty object when using predefined_filter in options.
18451850
* @param {ChannelSort} [sort] Sort options, for instance {created_at: -1}.
18461851
* When using multiple fields, make sure you use array of objects to guarantee field order, for instance [{last_updated: -1}, {created_at: 1}]
1847-
* @param {ChannelOptions} [options] Options object
1852+
* @param {ChannelOptions} [options] Options object. Can include predefined_filter, filter_values, and sort_values for using predefined filters.
18481853
*
18491854
* @return {Promise<Array<ChannelAPIResponse>>} search channels response
18501855
*/
@@ -1865,13 +1870,23 @@ export class StreamChat {
18651870
defaultOptions.watch = false;
18661871
}
18671872

1868-
// Return a list of channels
1869-
const payload = {
1870-
filter_conditions: filterConditions,
1871-
sort: normalizeQuerySort(sort),
1872-
...defaultOptions,
1873-
...options,
1874-
};
1873+
const { predefined_filter, filter_values, sort_values, ...restOptions } = options;
1874+
1875+
// Build payload based on whether we're using a predefined filter or traditional filters
1876+
const payload = predefined_filter
1877+
? {
1878+
predefined_filter,
1879+
filter_values,
1880+
sort_values,
1881+
...defaultOptions,
1882+
...restOptions,
1883+
}
1884+
: {
1885+
filter_conditions: filterConditions,
1886+
sort: normalizeQuerySort(sort),
1887+
...defaultOptions,
1888+
...restOptions,
1889+
};
18751890

18761891
const data = await this.post<QueryChannelsAPIResponse>(
18771892
this.baseURL + '/channels',
@@ -3769,7 +3784,7 @@ export class StreamChat {
37693784
validateServerSideAuth() {
37703785
if (!this.secret) {
37713786
throw new Error(
3772-
'Campaigns is a server-side only feature. Please initialize the client with a secret to use this feature.',
3787+
'This feature can be used server-side only. Please initialize the client with a secret to use this feature.',
37733788
);
37743789
}
37753790
}
@@ -4817,4 +4832,82 @@ export class StreamChat {
48174832
payload,
48184833
);
48194834
}
4835+
4836+
/**
4837+
* createPredefinedFilter - Creates a new predefined filter (server-side only)
4838+
*
4839+
* @param {CreatePredefinedFilterOptions} options Predefined filter options
4840+
*
4841+
* @return {Promise<PredefinedFilterResponse>} The created predefined filter
4842+
*/
4843+
async createPredefinedFilter(options: CreatePredefinedFilterOptions) {
4844+
this.validateServerSideAuth();
4845+
return await this.post<PredefinedFilterResponse>(
4846+
`${this.baseURL}/predefined_filters`,
4847+
options,
4848+
);
4849+
}
4850+
4851+
/**
4852+
* getPredefinedFilter - Gets a predefined filter by name (server-side only)
4853+
*
4854+
* @param {string} name Predefined filter name
4855+
*
4856+
* @return {Promise<PredefinedFilterResponse>} The predefined filter
4857+
*/
4858+
async getPredefinedFilter(name: string) {
4859+
this.validateServerSideAuth();
4860+
return await this.get<PredefinedFilterResponse>(
4861+
`${this.baseURL}/predefined_filters/${encodeURIComponent(name)}`,
4862+
);
4863+
}
4864+
4865+
/**
4866+
* updatePredefinedFilter - Updates a predefined filter (server-side only)
4867+
*
4868+
* @param {string} name Predefined filter name
4869+
* @param {UpdatePredefinedFilterOptions} options Predefined filter options
4870+
*
4871+
* @return {Promise<PredefinedFilterResponse>} The updated predefined filter
4872+
*/
4873+
async updatePredefinedFilter(name: string, options: UpdatePredefinedFilterOptions) {
4874+
this.validateServerSideAuth();
4875+
return await this.put<PredefinedFilterResponse>(
4876+
`${this.baseURL}/predefined_filters/${encodeURIComponent(name)}`,
4877+
options,
4878+
);
4879+
}
4880+
4881+
/**
4882+
* deletePredefinedFilter - Deletes a predefined filter (server-side only)
4883+
*
4884+
* @param {string} name Predefined filter name
4885+
*
4886+
* @return {Promise<APIResponse>} The server response
4887+
*/
4888+
async deletePredefinedFilter(name: string) {
4889+
this.validateServerSideAuth();
4890+
return await this.delete<APIResponse>(
4891+
`${this.baseURL}/predefined_filters/${encodeURIComponent(name)}`,
4892+
);
4893+
}
4894+
4895+
/**
4896+
* listPredefinedFilters - Lists all predefined filters (server-side only)
4897+
*
4898+
* @param {ListPredefinedFiltersOptions} options Query options
4899+
*
4900+
* @return {Promise<ListPredefinedFiltersResponse>} The list of predefined filters
4901+
*/
4902+
async listPredefinedFilters(options: ListPredefinedFiltersOptions = {}) {
4903+
this.validateServerSideAuth();
4904+
const { sort, ...paginationOptions } = options;
4905+
return await this.get<ListPredefinedFiltersResponse>(
4906+
`${this.baseURL}/predefined_filters`,
4907+
{
4908+
...paginationOptions,
4909+
...(sort ? { sort: JSON.stringify(sort) } : {}),
4910+
},
4911+
);
4912+
}
48204913
}

src/types.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,21 @@ export type ChannelOptions = {
10111011
state?: boolean;
10121012
user_id?: string;
10131013
watch?: boolean;
1014+
/**
1015+
* Name of a predefined filter to use instead of filter_conditions.
1016+
* When provided, filter_conditions and sort parameters are ignored.
1017+
*/
1018+
predefined_filter?: string;
1019+
/**
1020+
* Values to interpolate into the predefined filter template placeholders.
1021+
* Only used when predefined_filter is provided.
1022+
*/
1023+
filter_values?: Record<string, unknown>;
1024+
/**
1025+
* Values to interpolate into the predefined filter sort template placeholders.
1026+
* Only used when predefined_filter is provided.
1027+
*/
1028+
sort_values?: Record<string, unknown>;
10141029
};
10151030

10161031
export type ChannelQueryOptions = {
@@ -4544,3 +4559,52 @@ export type UpdateChannelsBatchFilters = QueryFilters<{
45444559
export type UpdateChannelsBatchResponse = {
45454560
result: Record<string, string>;
45464561
} & Partial<TaskResponse>;
4562+
4563+
/**
4564+
* Predefined Filter Types
4565+
*/
4566+
4567+
export type PredefinedFilterOperation = 'QueryChannels';
4568+
4569+
export type PredefinedFilterSortParam = {
4570+
field: string;
4571+
direction?: AscDesc;
4572+
type?: string;
4573+
};
4574+
4575+
export type PredefinedFilter = {
4576+
name: string;
4577+
operation: PredefinedFilterOperation;
4578+
filter: Record<string, unknown>;
4579+
created_at: string;
4580+
updated_at: string;
4581+
description?: string;
4582+
sort?: PredefinedFilterSortParam[];
4583+
query_id?: number;
4584+
};
4585+
4586+
export type CreatePredefinedFilterOptions = {
4587+
name: string;
4588+
operation: PredefinedFilterOperation;
4589+
filter: Record<string, unknown>;
4590+
description?: string;
4591+
sort?: PredefinedFilterSortParam[];
4592+
};
4593+
4594+
export type UpdatePredefinedFilterOptions = Omit<CreatePredefinedFilterOptions, 'name'>;
4595+
4596+
export type PredefinedFilterResponse = APIResponse & {
4597+
predefined_filter: PredefinedFilter;
4598+
};
4599+
4600+
export type ListPredefinedFiltersResponse = APIResponse & {
4601+
predefined_filters: PredefinedFilter[];
4602+
next?: string;
4603+
prev?: string;
4604+
};
4605+
4606+
export type PredefinedFilterSort = SortParam[];
4607+
4608+
export type ListPredefinedFiltersOptions = Pager & {
4609+
sort?: PredefinedFilterSort;
4610+
};

0 commit comments

Comments
 (0)