From ffd7259523c67911b884029bdc1dae9b09530e29 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Wed, 23 Nov 2022 16:28:38 +0800 Subject: [PATCH 1/6] Add read filter --- packages/rule-handler/src/index.ts | 1 + packages/rule-handler/src/rule.ts | 6 +++++- .../src/search_filter/content_filter.ts | 4 +--- packages/rule-handler/src/search_filter/index.ts | 4 ++-- .../src/search_filter/read_filter.ts | 16 ++++++++++++++++ .../src/search_filter/subscription_filter.ts | 6 ++---- 6 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 packages/rule-handler/src/search_filter/read_filter.ts diff --git a/packages/rule-handler/src/index.ts b/packages/rule-handler/src/index.ts index f2274cccf..316861c24 100644 --- a/packages/rule-handler/src/index.ts +++ b/packages/rule-handler/src/index.ts @@ -25,6 +25,7 @@ export interface PubSubData { subscription: string image: string content: string + readingProgressPercent: number } enum EntityType { diff --git a/packages/rule-handler/src/rule.ts b/packages/rule-handler/src/rule.ts index df89c9039..f38e99a5c 100644 --- a/packages/rule-handler/src/rule.ts +++ b/packages/rule-handler/src/rule.ts @@ -7,6 +7,7 @@ import { archivePage, markPageAsRead } from './page' import { SearchFilter } from './search_filter' import { SubscriptionFilter } from './search_filter/subscription_filter' import { ContentFilter } from './search_filter/content_filter' +import { ReadFilter } from './search_filter/read_filter' export enum RuleActionType { AddLabel = 'ADD_LABEL', @@ -41,7 +42,7 @@ const parseSearchFilter = (filter: string): SearchFilter[] => { } const parsed = parse(searchFilter, { - keywords: ['subscription', 'content'], + keywords: ['subscription', 'content', 'is'], tokenize: true, }) if (parsed.offsets) { @@ -57,6 +58,9 @@ const parseSearchFilter = (filter: string): SearchFilter[] => { case 'content': keyword.value && result.push(new ContentFilter(keyword.value)) break + case 'is': + keyword.value && result.push(new ReadFilter(keyword.value)) + break } } } diff --git a/packages/rule-handler/src/search_filter/content_filter.ts b/packages/rule-handler/src/search_filter/content_filter.ts index 822c27b0d..0207c79a2 100644 --- a/packages/rule-handler/src/search_filter/content_filter.ts +++ b/packages/rule-handler/src/search_filter/content_filter.ts @@ -3,13 +3,11 @@ import { PubSubData } from '../index' export class ContentFilter extends SearchFilter { public isValid(data: PubSubData): boolean { - console.debug('ContentFilter.isValid', this.filter, data.content) - if (!data.content) { return false } // TODO: implement content filter with semantic search - return this.filter === '*' || data.content.includes(this.filter) + return this.query === '*' || data.content.includes(this.query) } } diff --git a/packages/rule-handler/src/search_filter/index.ts b/packages/rule-handler/src/search_filter/index.ts index 37461efbc..adb2230c9 100644 --- a/packages/rule-handler/src/search_filter/index.ts +++ b/packages/rule-handler/src/search_filter/index.ts @@ -1,8 +1,8 @@ import { PubSubData } from '../index' export abstract class SearchFilter { - constructor(protected filter: string) { - this.filter = filter + constructor(protected query: string) { + this.query = query } public abstract isValid(data: PubSubData): boolean diff --git a/packages/rule-handler/src/search_filter/read_filter.ts b/packages/rule-handler/src/search_filter/read_filter.ts new file mode 100644 index 000000000..7d4904b2a --- /dev/null +++ b/packages/rule-handler/src/search_filter/read_filter.ts @@ -0,0 +1,16 @@ +import { PubSubData } from '../index' +import { SearchFilter } from './index' + +export class ReadFilter extends SearchFilter { + public isValid(data: PubSubData): boolean { + if (!data.readingProgressPercent) { + return false + } + + if (this.query === 'read') { + return data.readingProgressPercent >= 98 + } + + return data.readingProgressPercent < 98 + } +} diff --git a/packages/rule-handler/src/search_filter/subscription_filter.ts b/packages/rule-handler/src/search_filter/subscription_filter.ts index 43893c318..ac2f4ee73 100644 --- a/packages/rule-handler/src/search_filter/subscription_filter.ts +++ b/packages/rule-handler/src/search_filter/subscription_filter.ts @@ -3,16 +3,14 @@ import { PubSubData } from '../index' export class SubscriptionFilter extends SearchFilter { public isValid(data: PubSubData): boolean { - console.debug('SubscriptionFilter.isValid', this.filter, data.subscription) - if (!data.subscription) { return false } // compare subscription name case insensitive return ( - this.filter === '*' || - data.subscription.toLowerCase() === this.filter.toLowerCase() + this.query === '*' || + data.subscription.toLowerCase() === this.query.toLowerCase() ) } } From 52b1cb8cfac8afc8cc7dd886f14a4949e3a0efa8 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Wed, 23 Nov 2022 17:41:09 +0800 Subject: [PATCH 2/6] Add type filter --- packages/rule-handler/src/index.ts | 1 + packages/rule-handler/src/rule.ts | 14 ++++++++++---- .../rule-handler/src/search_filter/type_filter.ts | 12 ++++++++++++ 3 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 packages/rule-handler/src/search_filter/type_filter.ts diff --git a/packages/rule-handler/src/index.ts b/packages/rule-handler/src/index.ts index 316861c24..506b5c63e 100644 --- a/packages/rule-handler/src/index.ts +++ b/packages/rule-handler/src/index.ts @@ -26,6 +26,7 @@ export interface PubSubData { image: string content: string readingProgressPercent: number + pageType: string } enum EntityType { diff --git a/packages/rule-handler/src/rule.ts b/packages/rule-handler/src/rule.ts index f38e99a5c..26fa90e4a 100644 --- a/packages/rule-handler/src/rule.ts +++ b/packages/rule-handler/src/rule.ts @@ -42,7 +42,7 @@ const parseSearchFilter = (filter: string): SearchFilter[] => { } const parsed = parse(searchFilter, { - keywords: ['subscription', 'content', 'is'], + keywords: ['subscription', 'content', 'is', 'type'], tokenize: true, }) if (parsed.offsets) { @@ -51,15 +51,21 @@ const parseSearchFilter = (filter: string): SearchFilter[] => { .map((offset) => offset as SearchParserKeyWordOffset) for (const keyword of keywords) { + if (!keyword.value) { + continue + } switch (keyword.keyword) { case 'subscription': - keyword.value && result.push(new SubscriptionFilter(keyword.value)) + result.push(new SubscriptionFilter(keyword.value)) break case 'content': - keyword.value && result.push(new ContentFilter(keyword.value)) + result.push(new ContentFilter(keyword.value)) break case 'is': - keyword.value && result.push(new ReadFilter(keyword.value)) + result.push(new ReadFilter(keyword.value)) + break + case 'type': + result.push(new ReadFilter(keyword.value)) break } } diff --git a/packages/rule-handler/src/search_filter/type_filter.ts b/packages/rule-handler/src/search_filter/type_filter.ts new file mode 100644 index 000000000..5fac9b48d --- /dev/null +++ b/packages/rule-handler/src/search_filter/type_filter.ts @@ -0,0 +1,12 @@ +import { SearchFilter } from './index' +import { PubSubData } from '../index' + +export class TypeFilter extends SearchFilter { + public isValid(data: PubSubData): boolean { + if (!data.pageType) { + return false + } + + return this.query === '*' || data.pageType === this.query + } +} From 83a619f826a93c31c5b6b1180211289731174a57 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Wed, 23 Nov 2022 18:22:04 +0800 Subject: [PATCH 3/6] Use promise.all to trigger all actions --- packages/rule-handler/src/index.ts | 1 + packages/rule-handler/src/label.ts | 2 +- packages/rule-handler/src/notification.ts | 16 ++++---- packages/rule-handler/src/page.ts | 4 +- packages/rule-handler/src/rule.ts | 48 +++++++++++------------ 5 files changed, 35 insertions(+), 36 deletions(-) diff --git a/packages/rule-handler/src/index.ts b/packages/rule-handler/src/index.ts index 506b5c63e..029efcd26 100644 --- a/packages/rule-handler/src/index.ts +++ b/packages/rule-handler/src/index.ts @@ -125,6 +125,7 @@ export const ruleHandler = Sentry.GCPFunction.wrapHttpFunction( jwtSecret ) if (triggeredActions.length === 0) { + console.log('No actions triggered') res.status(200).send('No Actions') return } diff --git a/packages/rule-handler/src/label.ts b/packages/rule-handler/src/label.ts index 18f1549ec..47c562282 100644 --- a/packages/rule-handler/src/label.ts +++ b/packages/rule-handler/src/label.ts @@ -28,7 +28,7 @@ export const addLabels = async ( }) try { - await axios.post(`${apiEndpoint}/graphql`, data, { + return axios.post(`${apiEndpoint}/graphql`, data, { headers: { Cookie: `auth=${auth};`, 'Content-Type': 'application/json', diff --git a/packages/rule-handler/src/notification.ts b/packages/rule-handler/src/notification.ts index ed715209d..a03ddc323 100644 --- a/packages/rule-handler/src/notification.ts +++ b/packages/rule-handler/src/notification.ts @@ -1,6 +1,6 @@ import axios from 'axios' -interface NotificationData { +interface RequestData { body: string title?: string data?: Record @@ -11,19 +11,21 @@ interface NotificationData { export const sendNotification = async ( apiEndpoint: string, auth: string, - message: string, + body: string, title?: string, - image?: string + image?: string, + data?: Record ) => { - const data: NotificationData = { - body: message, - title: title || message, + const requestData: RequestData = { + body, + title, image, notificationType: 'rule', + data, } try { - await axios.post(`${apiEndpoint}/notification/send`, data, { + return axios.post(`${apiEndpoint}/notification/send`, requestData, { headers: { Cookie: `auth=${auth};`, 'Content-Type': 'application/json', diff --git a/packages/rule-handler/src/page.ts b/packages/rule-handler/src/page.ts index 27b99b230..9070f7192 100644 --- a/packages/rule-handler/src/page.ts +++ b/packages/rule-handler/src/page.ts @@ -27,7 +27,7 @@ export const archivePage = async ( }) try { - await axios.post(`${apiEndpoint}/graphql`, data, { + return axios.post(`${apiEndpoint}/graphql`, data, { headers: { Cookie: `auth=${auth};`, 'Content-Type': 'application/json', @@ -66,7 +66,7 @@ export const markPageAsRead = async ( }) try { - await axios.post(`${apiEndpoint}/graphql`, data, { + return axios.post(`${apiEndpoint}/graphql`, data, { headers: { Cookie: `auth=${auth};`, 'Content-Type': 'application/json', diff --git a/packages/rule-handler/src/rule.ts b/packages/rule-handler/src/rule.ts index 26fa90e4a..0d4d9ee2f 100644 --- a/packages/rule-handler/src/rule.ts +++ b/packages/rule-handler/src/rule.ts @@ -131,49 +131,45 @@ export const triggerActions = async ( apiEndpoint: string, jwtSecret: string ) => { - const triggeredActions: RuleAction[] = [] const authToken = await getAuthToken(userId, jwtSecret) - for (const rule of rules) { + const actionPromises = rules.map((rule) => { if (!isValidData(rule.filter, data)) { - continue + return } - for (const action of rule.actions) { + return rule.actions.map((action) => { switch (action.type) { case RuleActionType.AddLabel: if (!data.id || action.params.length === 0) { console.log('invalid data for add label action') - continue + return } - await addLabels(apiEndpoint, authToken, data.id, action.params) - triggeredActions.push(action) - break + + return addLabels(apiEndpoint, authToken, data.id, action.params) case RuleActionType.Archive: if (!data.id) { console.log('invalid data for archive action') - continue + return } - await archivePage(apiEndpoint, authToken, data.id) - triggeredActions.push(action) - break + + return archivePage(apiEndpoint, authToken, data.id) case RuleActionType.MarkAsRead: if (!data.id) { console.log('invalid data for mark as read action') - continue + return } - await markPageAsRead(apiEndpoint, authToken, data.id) - triggeredActions.push(action) - break - case RuleActionType.SendNotification: - for (const message of action.params) { - await sendNotification(apiEndpoint, authToken, message) - } - triggeredActions.push(action) - break - } - } - } - return triggeredActions + return markPageAsRead(apiEndpoint, authToken, data.id) + case RuleActionType.SendNotification: + return sendNotification( + apiEndpoint, + authToken, + 'New page added to your feed' + ) + } + }) + }) + + return Promise.all(actionPromises.flat().filter((p) => p !== undefined)) } From b77d718754a3450f1006d5032558d84ee560a85b Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Wed, 23 Nov 2022 18:25:12 +0800 Subject: [PATCH 4/6] Fix a bug --- packages/rule-handler/src/rule.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/rule-handler/src/rule.ts b/packages/rule-handler/src/rule.ts index 0d4d9ee2f..027f2b198 100644 --- a/packages/rule-handler/src/rule.ts +++ b/packages/rule-handler/src/rule.ts @@ -8,6 +8,7 @@ import { SearchFilter } from './search_filter' import { SubscriptionFilter } from './search_filter/subscription_filter' import { ContentFilter } from './search_filter/content_filter' import { ReadFilter } from './search_filter/read_filter' +import { TypeFilter } from './search_filter/type_filter' export enum RuleActionType { AddLabel = 'ADD_LABEL', @@ -65,7 +66,7 @@ const parseSearchFilter = (filter: string): SearchFilter[] => { result.push(new ReadFilter(keyword.value)) break case 'type': - result.push(new ReadFilter(keyword.value)) + result.push(new TypeFilter(keyword.value)) break } } From 3f24d9a99e3bad53e308be181f623fc0edd96341 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Thu, 24 Nov 2022 14:10:13 +0800 Subject: [PATCH 5/6] Add includes filter to search by ids in search api --- packages/api/src/elastic/pages.ts | 12 ++++++++++++ packages/api/src/elastic/types.ts | 6 ++++++ packages/api/src/utils/search.ts | 17 +++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/packages/api/src/elastic/pages.ts b/packages/api/src/elastic/pages.ts index b65af5c41..1c4a9d482 100644 --- a/packages/api/src/elastic/pages.ts +++ b/packages/api/src/elastic/pages.ts @@ -179,6 +179,14 @@ const appendMatchFilters = (body: SearchBody, filters: FieldFilter[]): void => { }) } +const appendIdsFilter = (body: SearchBody, ids: string[]): void => { + body.query.bool.must.push({ + terms: { + _id: ids, + }, + }) +} + export const createPage = async ( page: Page, ctx: PageContext @@ -359,6 +367,7 @@ export const searchPages = async ( dateFilters, termFilters, matchFilters, + ids, } = args // default order is descending const sortOrder = sort?.order || SortOrder.DESCENDING @@ -430,6 +439,9 @@ export const searchPages = async ( if (matchFilters) { appendMatchFilters(body, matchFilters) } + if (ids && ids.length > 0) { + appendIdsFilter(body, ids) + } if (!args.includePending) { body.query.bool.must_not.push({ diff --git a/packages/api/src/elastic/types.ts b/packages/api/src/elastic/types.ts index 2cc85d417..46b9722f7 100644 --- a/packages/api/src/elastic/types.ts +++ b/packages/api/src/elastic/types.ts @@ -56,6 +56,11 @@ export interface SearchBody { [K: string]: string } } + | { + terms: { + [K: string]: string[] + } + } )[] should: { multi_match: { @@ -278,4 +283,5 @@ export interface PageSearchArgs { matchFilters?: FieldFilter[] includePending?: boolean | null includeDeleted?: boolean + ids?: string[] } diff --git a/packages/api/src/utils/search.ts b/packages/api/src/utils/search.ts index c0244926d..da9a157a6 100644 --- a/packages/api/src/utils/search.ts +++ b/packages/api/src/utils/search.ts @@ -34,6 +34,7 @@ export interface SearchFilter { dateFilters: DateFilter[] termFilters: FieldFilter[] matchFilters: FieldFilter[] + ids: string[] } export enum LabelFilterType { @@ -245,6 +246,14 @@ const parseFieldFilter = ( } } +const parseIds = (field: string, str?: string): string[] | undefined => { + if (str === undefined) { + return undefined + } + + return str.split(',') +} + export const parseSearchQuery = (query: string | undefined): SearchFilter => { const searchQuery = query ? query.replace(/\W\s":/g, '') : undefined const result: SearchFilter = { @@ -256,6 +265,7 @@ export const parseSearchQuery = (query: string | undefined): SearchFilter => { dateFilters: [], termFilters: [], matchFilters: [], + ids: [], } if (!searchQuery) { @@ -268,6 +278,7 @@ export const parseSearchQuery = (query: string | undefined): SearchFilter => { dateFilters: [], termFilters: [], matchFilters: [], + ids: [], } } @@ -288,6 +299,7 @@ export const parseSearchQuery = (query: string | undefined): SearchFilter => { 'description', 'content', 'updated', + 'includes', ], tokenize: true, }) @@ -364,6 +376,11 @@ export const parseSearchQuery = (query: string | undefined): SearchFilter => { fieldFilter && result.matchFilters.push(fieldFilter) break } + case 'includes': { + const ids = parseIds(keyword.keyword, keyword.value) + ids && result.ids.push(...ids) + break + } } } } From 1e6e2b82ee2a7c1d671709d5cccae22893415068 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Thu, 24 Nov 2022 15:04:59 +0800 Subject: [PATCH 6/6] Run search API to filter rules --- packages/rule-handler/src/filter.ts | 81 ++++++++++++ packages/rule-handler/src/rule.ts | 116 +++++------------- .../src/search_filter/content_filter.ts | 13 -- .../rule-handler/src/search_filter/index.ts | 9 -- .../src/search_filter/read_filter.ts | 16 --- .../src/search_filter/subscription_filter.ts | 16 --- .../src/search_filter/type_filter.ts | 12 -- 7 files changed, 110 insertions(+), 153 deletions(-) create mode 100644 packages/rule-handler/src/filter.ts delete mode 100644 packages/rule-handler/src/search_filter/content_filter.ts delete mode 100644 packages/rule-handler/src/search_filter/index.ts delete mode 100644 packages/rule-handler/src/search_filter/read_filter.ts delete mode 100644 packages/rule-handler/src/search_filter/subscription_filter.ts delete mode 100644 packages/rule-handler/src/search_filter/type_filter.ts diff --git a/packages/rule-handler/src/filter.ts b/packages/rule-handler/src/filter.ts new file mode 100644 index 000000000..6f361db51 --- /dev/null +++ b/packages/rule-handler/src/filter.ts @@ -0,0 +1,81 @@ +import axios from 'axios' + +interface SearchResponse { + data: { + search: { + edges: Edge[] + } + } +} + +interface Edge { + node: Node +} + +interface Node { + id: string +} + +export const search = async ( + userId: string, + apiEndpoint: string, + auth: string, + query: string +): Promise => { + const requestData = JSON.stringify({ + query: `query Search($query: String) { + search(query: $query) { + ... on SearchSuccess { + edges { + node { + id + } + } + } + ... on SearchError { + errorCodes + } + } + }`, + variables: { + query, + }, + }) + + try { + const response = await axios.post( + `${apiEndpoint}/graphql`, + requestData, + { + headers: { + Cookie: `auth=${auth};`, + 'Content-Type': 'application/json', + }, + } + ) + + const edges = response.data.data.search.edges + if (edges.length == 0) { + return [] + } + + return edges.map((edge: Edge) => edge.node) + } catch (e) { + console.error(e) + + return [] + } +} + +export const isMatched = async ( + userId: string, + apiEndpoint: string, + auth: string, + filter: string, + pageId: string +): Promise => { + filter += ` includes:${pageId}` + const nodes = await search(userId, apiEndpoint, auth, filter) + + return nodes.length > 0 +} diff --git a/packages/rule-handler/src/rule.ts b/packages/rule-handler/src/rule.ts index 027f2b198..d8dd35f48 100644 --- a/packages/rule-handler/src/rule.ts +++ b/packages/rule-handler/src/rule.ts @@ -1,14 +1,9 @@ import { sendNotification } from './notification' import { getAuthToken, PubSubData } from './index' -import axios from 'axios' -import { parse, SearchParserKeyWordOffset } from 'search-query-parser' +import axios, { AxiosResponse } from 'axios' import { addLabels } from './label' import { archivePage, markPageAsRead } from './page' -import { SearchFilter } from './search_filter' -import { SubscriptionFilter } from './search_filter/subscription_filter' -import { ContentFilter } from './search_filter/content_filter' -import { ReadFilter } from './search_filter/read_filter' -import { TypeFilter } from './search_filter/type_filter' +import { isMatched } from './filter' export enum RuleActionType { AddLabel = 'ADD_LABEL', @@ -34,58 +29,6 @@ export interface Rule { updatedAt: Date } -const parseSearchFilter = (filter: string): SearchFilter[] => { - const searchFilter = filter ? filter.replace(/\W\s":/g, '') : undefined - const result: SearchFilter[] = [] - - if (!searchFilter || searchFilter === '*') { - return result - } - - const parsed = parse(searchFilter, { - keywords: ['subscription', 'content', 'is', 'type'], - tokenize: true, - }) - if (parsed.offsets) { - const keywords = parsed.offsets - .filter((offset) => 'keyword' in offset) - .map((offset) => offset as SearchParserKeyWordOffset) - - for (const keyword of keywords) { - if (!keyword.value) { - continue - } - switch (keyword.keyword) { - case 'subscription': - result.push(new SubscriptionFilter(keyword.value)) - break - case 'content': - result.push(new ContentFilter(keyword.value)) - break - case 'is': - result.push(new ReadFilter(keyword.value)) - break - case 'type': - result.push(new TypeFilter(keyword.value)) - break - } - } - } - - return result -} - -const isValidData = (filter: string, data: PubSubData): boolean => { - const searchFilters = parseSearchFilter(filter) - - if (searchFilters.length === 0) { - console.debug('no search filters found') - return true - } - - return searchFilters.every((searchFilter) => searchFilter.isValid(data)) -} - export const getEnabledRules = async ( userId: string, apiEndpoint: string, @@ -133,44 +76,43 @@ export const triggerActions = async ( jwtSecret: string ) => { const authToken = await getAuthToken(userId, jwtSecret) + const actionPromises: Promise | undefined>[] = [] - const actionPromises = rules.map((rule) => { - if (!isValidData(rule.filter, data)) { - return + for (const rule of rules) { + if ( + !(await isMatched(userId, apiEndpoint, authToken, rule.filter, data.id)) + ) { + continue } - return rule.actions.map((action) => { + rule.actions.forEach((action) => { switch (action.type) { case RuleActionType.AddLabel: - if (!data.id || action.params.length === 0) { - console.log('invalid data for add label action') - return - } - - return addLabels(apiEndpoint, authToken, data.id, action.params) + data.id && + actionPromises.push( + addLabels(apiEndpoint, authToken, data.id, action.params) + ) + break case RuleActionType.Archive: - if (!data.id) { - console.log('invalid data for archive action') - return - } - - return archivePage(apiEndpoint, authToken, data.id) + data.id && + actionPromises.push(archivePage(apiEndpoint, authToken, data.id)) + break case RuleActionType.MarkAsRead: - if (!data.id) { - console.log('invalid data for mark as read action') - return - } - - return markPageAsRead(apiEndpoint, authToken, data.id) + data.id && + actionPromises.push(markPageAsRead(apiEndpoint, authToken, data.id)) + break case RuleActionType.SendNotification: - return sendNotification( - apiEndpoint, - authToken, - 'New page added to your feed' + actionPromises.push( + sendNotification( + apiEndpoint, + authToken, + 'New page added to your feed' + ) ) + break } }) - }) + } - return Promise.all(actionPromises.flat().filter((p) => p !== undefined)) + return Promise.all(actionPromises) } diff --git a/packages/rule-handler/src/search_filter/content_filter.ts b/packages/rule-handler/src/search_filter/content_filter.ts deleted file mode 100644 index 0207c79a2..000000000 --- a/packages/rule-handler/src/search_filter/content_filter.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { SearchFilter } from './index' -import { PubSubData } from '../index' - -export class ContentFilter extends SearchFilter { - public isValid(data: PubSubData): boolean { - if (!data.content) { - return false - } - - // TODO: implement content filter with semantic search - return this.query === '*' || data.content.includes(this.query) - } -} diff --git a/packages/rule-handler/src/search_filter/index.ts b/packages/rule-handler/src/search_filter/index.ts deleted file mode 100644 index adb2230c9..000000000 --- a/packages/rule-handler/src/search_filter/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { PubSubData } from '../index' - -export abstract class SearchFilter { - constructor(protected query: string) { - this.query = query - } - - public abstract isValid(data: PubSubData): boolean -} diff --git a/packages/rule-handler/src/search_filter/read_filter.ts b/packages/rule-handler/src/search_filter/read_filter.ts deleted file mode 100644 index 7d4904b2a..000000000 --- a/packages/rule-handler/src/search_filter/read_filter.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { PubSubData } from '../index' -import { SearchFilter } from './index' - -export class ReadFilter extends SearchFilter { - public isValid(data: PubSubData): boolean { - if (!data.readingProgressPercent) { - return false - } - - if (this.query === 'read') { - return data.readingProgressPercent >= 98 - } - - return data.readingProgressPercent < 98 - } -} diff --git a/packages/rule-handler/src/search_filter/subscription_filter.ts b/packages/rule-handler/src/search_filter/subscription_filter.ts deleted file mode 100644 index ac2f4ee73..000000000 --- a/packages/rule-handler/src/search_filter/subscription_filter.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { SearchFilter } from './index' -import { PubSubData } from '../index' - -export class SubscriptionFilter extends SearchFilter { - public isValid(data: PubSubData): boolean { - if (!data.subscription) { - return false - } - - // compare subscription name case insensitive - return ( - this.query === '*' || - data.subscription.toLowerCase() === this.query.toLowerCase() - ) - } -} diff --git a/packages/rule-handler/src/search_filter/type_filter.ts b/packages/rule-handler/src/search_filter/type_filter.ts deleted file mode 100644 index 5fac9b48d..000000000 --- a/packages/rule-handler/src/search_filter/type_filter.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { SearchFilter } from './index' -import { PubSubData } from '../index' - -export class TypeFilter extends SearchFilter { - public isValid(data: PubSubData): boolean { - if (!data.pageType) { - return false - } - - return this.query === '*' || data.pageType === this.query - } -}