aboutsummaryrefslogtreecommitdiffstats
path: root/packages/shared
diff options
context:
space:
mode:
authorMohamed Bassem <me@mbassem.com>2025-01-12 20:03:47 +0000
committerMohamed Bassem <me@mbassem.com>2025-01-12 20:03:47 +0000
commit9fd26b472b18924ab11afcebace90329b0fe3abf (patch)
tree04d2a8f8603978c27611574d663dfc58b3f285b0 /packages/shared
parentc5298cf4b43795c0c261922ef0ad0f20245be4d5 (diff)
downloadkarakeep-9fd26b472b18924ab11afcebace90329b0fe3abf.tar.zst
feat: Add ability to filter by bookmark type
Diffstat (limited to 'packages/shared')
-rw-r--r--packages/shared/searchQueryParser.test.ts55
-rw-r--r--packages/shared/searchQueryParser.ts28
-rw-r--r--packages/shared/types/search.ts14
3 files changed, 97 insertions, 0 deletions
diff --git a/packages/shared/searchQueryParser.test.ts b/packages/shared/searchQueryParser.test.ts
index 5af7ca2f..7430d58f 100644
--- a/packages/shared/searchQueryParser.test.ts
+++ b/packages/shared/searchQueryParser.test.ts
@@ -1,6 +1,7 @@
import { describe, expect, test } from "vitest";
import { parseSearchQuery } from "./searchQueryParser";
+import { BookmarkTypes } from "./types/bookmarks";
describe("Search Query Parser", () => {
test("simple is queries", () => {
@@ -68,6 +69,60 @@ describe("Search Query Parser", () => {
inList: false,
},
});
+ expect(parseSearchQuery("is:link")).toEqual({
+ result: "full",
+ text: "",
+ matcher: {
+ type: "type",
+ typeName: BookmarkTypes.LINK,
+ inverse: false,
+ },
+ });
+ expect(parseSearchQuery("-is:link")).toEqual({
+ result: "full",
+ text: "",
+ matcher: {
+ type: "type",
+ typeName: BookmarkTypes.LINK,
+ inverse: true,
+ },
+ });
+ expect(parseSearchQuery("is:text")).toEqual({
+ result: "full",
+ text: "",
+ matcher: {
+ type: "type",
+ typeName: BookmarkTypes.TEXT,
+ inverse: false,
+ },
+ });
+ expect(parseSearchQuery("-is:text")).toEqual({
+ result: "full",
+ text: "",
+ matcher: {
+ type: "type",
+ typeName: BookmarkTypes.TEXT,
+ inverse: true,
+ },
+ });
+ expect(parseSearchQuery("is:media")).toEqual({
+ result: "full",
+ text: "",
+ matcher: {
+ type: "type",
+ typeName: BookmarkTypes.ASSET,
+ inverse: false,
+ },
+ });
+ expect(parseSearchQuery("-is:media")).toEqual({
+ result: "full",
+ text: "",
+ matcher: {
+ type: "type",
+ typeName: BookmarkTypes.ASSET,
+ inverse: true,
+ },
+ });
});
test("simple string queries", () => {
diff --git a/packages/shared/searchQueryParser.ts b/packages/shared/searchQueryParser.ts
index e52af274..4f68523b 100644
--- a/packages/shared/searchQueryParser.ts
+++ b/packages/shared/searchQueryParser.ts
@@ -15,6 +15,7 @@ import {
} from "typescript-parsec";
import { z } from "zod";
+import { BookmarkTypes } from "./types/bookmarks";
import { Matcher } from "./types/search";
enum TokenType {
@@ -136,6 +137,33 @@ MATCHER.setPattern(
text: "",
matcher: { type: "inlist", inList: !minus },
};
+ case "link":
+ return {
+ text: "",
+ matcher: {
+ type: "type",
+ typeName: BookmarkTypes.LINK,
+ inverse: !!minus,
+ },
+ };
+ case "text":
+ return {
+ text: "",
+ matcher: {
+ type: "type",
+ typeName: BookmarkTypes.TEXT,
+ inverse: !!minus,
+ },
+ };
+ case "media":
+ return {
+ text: "",
+ matcher: {
+ type: "type",
+ typeName: BookmarkTypes.ASSET,
+ inverse: !!minus,
+ },
+ };
default:
// If the token is not known, emit it as pure text
return {
diff --git a/packages/shared/types/search.ts b/packages/shared/types/search.ts
index 9d97fdd8..19c5d0e2 100644
--- a/packages/shared/types/search.ts
+++ b/packages/shared/types/search.ts
@@ -1,5 +1,7 @@
import { z } from "zod";
+import { BookmarkTypes } from "./bookmarks";
+
const zTagNameMatcher = z.object({
type: z.literal("tagName"),
tagName: z.string(),
@@ -50,6 +52,16 @@ const zIsInListMatcher = z.object({
inList: z.boolean(),
});
+const zTypeMatcher = z.object({
+ type: z.literal("type"),
+ typeName: z.enum([
+ BookmarkTypes.LINK,
+ BookmarkTypes.TEXT,
+ BookmarkTypes.ASSET,
+ ]),
+ inverse: z.boolean(),
+});
+
const zNonRecursiveMatcher = z.union([
zTagNameMatcher,
zListNameMatcher,
@@ -60,6 +72,7 @@ const zNonRecursiveMatcher = z.union([
zDateBeforeMatcher,
zIsTaggedMatcher,
zIsInListMatcher,
+ zTypeMatcher,
]);
type NonRecursiveMatcher = z.infer<typeof zNonRecursiveMatcher>;
@@ -79,6 +92,7 @@ export const zMatcherSchema: z.ZodType<Matcher> = z.lazy(() => {
zDateBeforeMatcher,
zIsTaggedMatcher,
zIsInListMatcher,
+ zTypeMatcher,
z.object({
type: z.literal("and"),
matchers: z.array(zMatcherSchema),