From af6774fab6502b3f49a71dea955357992e5edc77 Mon Sep 17 00:00:00 2001 From: MohamedBassem Date: Sun, 6 Apr 2025 23:50:39 +0100 Subject: feat: Add a search matcher for rss feed bookmarks --- packages/shared/searchQueryParser.test.ts | 36 +++++++++++++++++++++++++++++++ packages/shared/searchQueryParser.ts | 11 +++++++++- packages/shared/types/search.ts | 8 +++++++ 3 files changed, 54 insertions(+), 1 deletion(-) (limited to 'packages/shared') diff --git a/packages/shared/searchQueryParser.test.ts b/packages/shared/searchQueryParser.test.ts index 17accd1e..ff69756c 100644 --- a/packages/shared/searchQueryParser.test.ts +++ b/packages/shared/searchQueryParser.test.ts @@ -244,6 +244,42 @@ describe("Search Query Parser", () => { inverse: true, }, }); + expect(parseSearchQuery("feed:my-feed")).toEqual({ + result: "full", + text: "", + matcher: { + type: "rssFeedName", + feedName: "my-feed", + inverse: false, + }, + }); + expect(parseSearchQuery("-feed:my-feed")).toEqual({ + result: "full", + text: "", + matcher: { + type: "rssFeedName", + feedName: "my-feed", + inverse: true, + }, + }); + expect(parseSearchQuery('feed:"my feed"')).toEqual({ + result: "full", + text: "", + matcher: { + type: "rssFeedName", + feedName: "my feed", + inverse: false, + }, + }); + expect(parseSearchQuery('-feed:"my feed"')).toEqual({ + result: "full", + text: "", + matcher: { + type: "rssFeedName", + feedName: "my feed", + inverse: true, + }, + }); }); test("date queries", () => { expect(parseSearchQuery("after:2023-10-12")).toEqual({ diff --git a/packages/shared/searchQueryParser.ts b/packages/shared/searchQueryParser.ts index 3d8a1519..d4e2bf2b 100644 --- a/packages/shared/searchQueryParser.ts +++ b/packages/shared/searchQueryParser.ts @@ -40,7 +40,7 @@ const lexerRules: [RegExp, TokenType][] = [ [/^\s+or/i, TokenType.Or], [/^#/, TokenType.Hash], - [/^(is|url|list|after|before):/, TokenType.Qualifier], + [/^(is|url|list|after|before|feed):/, TokenType.Qualifier], [/^"([^"]+)"/, TokenType.StringLiteral], @@ -204,6 +204,15 @@ MATCHER.setPattern( text: "", matcher: { type: "listName", listName: ident, inverse: !!minus }, }; + case "feed:": + return { + text: "", + matcher: { + type: "rssFeedName", + feedName: ident, + inverse: !!minus, + }, + }; case "after:": try { return { diff --git a/packages/shared/types/search.ts b/packages/shared/types/search.ts index 19c5d0e2..533eea25 100644 --- a/packages/shared/types/search.ts +++ b/packages/shared/types/search.ts @@ -14,6 +14,12 @@ const zListNameMatcher = z.object({ inverse: z.boolean(), }); +const zRssFeedNameMatcher = z.object({ + type: z.literal("rssFeedName"), + feedName: z.string(), + inverse: z.boolean(), +}); + const zArchivedMatcher = z.object({ type: z.literal("archived"), archived: z.boolean(), @@ -73,6 +79,7 @@ const zNonRecursiveMatcher = z.union([ zIsTaggedMatcher, zIsInListMatcher, zTypeMatcher, + zRssFeedNameMatcher, ]); type NonRecursiveMatcher = z.infer; @@ -93,6 +100,7 @@ export const zMatcherSchema: z.ZodType = z.lazy(() => { zIsTaggedMatcher, zIsInListMatcher, zTypeMatcher, + zRssFeedNameMatcher, z.object({ type: z.literal("and"), matchers: z.array(zMatcherSchema), -- cgit v1.2.3-70-g09d2