From 42749c5a3239b8a5404e3801976ea0f8e8700386 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Fri, 15 Dec 2023 11:47:00 +0800 Subject: [PATCH 1/3] throw error if sort column not exists --- packages/api/src/services/library_item.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/api/src/services/library_item.ts b/packages/api/src/services/library_item.ts index 997870c4e..242365cf4 100644 --- a/packages/api/src/services/library_item.ts +++ b/packages/api/src/services/library_item.ts @@ -148,8 +148,13 @@ const getColumnName = (field: string) => { case 'updated': case 'published': return `${lowerCaseField}_at` - default: + case 'author': + case 'title': + case 'description': + case 'note': return lowerCaseField + default: + throw new Error(`Unexpected field: ${field}`) } } From f915c18dfa4cf22e4478521dc4e00ce897652083 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Fri, 15 Dec 2023 13:18:25 +0800 Subject: [PATCH 2/3] allow plural and singular form for has/no filter --- packages/api/src/services/library_item.ts | 63 ++++++++++------------- 1 file changed, 27 insertions(+), 36 deletions(-) diff --git a/packages/api/src/services/library_item.ts b/packages/api/src/services/library_item.ts index 242365cf4..edcf2c732 100644 --- a/packages/api/src/services/library_item.ts +++ b/packages/api/src/services/library_item.ts @@ -30,12 +30,6 @@ enum InFilter { FOLLOWING = 'following', } -enum HasFilter { - HIGHLIGHTS = 'highlights', - LABELS = 'labels', - SUBSCRIPTIONS = 'subscriptions', -} - export interface SearchArgs { from?: number size?: number @@ -102,6 +96,25 @@ interface Select { alias?: string } +const handleNoCase = (value: string) => { + const keywordRegexMap: Record = { + highlight: /^highlight(s)?$/i, + label: /^label(s)?$/i, + subscription: /^subscription(s)?$/i, + } + + const matchingKeyword = Object.keys(keywordRegexMap).find((keyword) => + value.match(keywordRegexMap[keyword]) + ) + + if (matchingKeyword) { + const column = getColumnName(matchingKeyword) + return `(library_item.${column} IS NULL OR library_item.${column} = '{}')` + } + + throw new Error(`Unexpected keyword: ${value}`) +} + const paramtersToObject = (parameters: ObjectLiteral[]) => { return parameters.reduce((a, b) => ({ ...a, ...b }), {}) } @@ -153,6 +166,10 @@ const getColumnName = (field: string) => { case 'description': case 'note': return lowerCaseField + case 'highlight': + return 'highlight_annotations' + case 'label': + return 'label_names' default: throw new Error(`Unexpected field: ${field}`) } @@ -315,18 +332,8 @@ export const buildQuery = ( orders.push({ by: `library_item.${column}`, order }) return null } - case 'has': { - switch (value.toLowerCase()) { - case HasFilter.HIGHLIGHTS: - return "library_item.highlight_annotations <> '{}'" - case HasFilter.LABELS: - return "library_item.label_names <> '{}'" - case HasFilter.SUBSCRIPTIONS: - return 'library_item.subscription is NOT NULL' - default: - throw new Error(`Unexpected keyword: ${value}`) - } - } + case 'has': + return `NOT (${handleNoCase(value)})` case 'saved': case 'read': case 'updated': @@ -439,24 +446,8 @@ export const buildQuery = ( } ) } - case 'no': { - let column = '' - switch (value.toLowerCase()) { - case 'highlight': - column = 'highlight_annotations' - break - case 'label': - column = 'label_names' - break - case 'subscription': - column = 'subscription' - break - default: - throw new Error(`Unexpected keyword: ${value}`) - } - - return `(library_item.${column} = '{}' OR library_item.${column} IS NULL)` - } + case 'no': + return handleNoCase(value) case 'use': case 'mode': case 'event': From d579a8f90796ef0defda159a0261684f3c9c636f Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Fri, 15 Dec 2023 13:31:22 +0800 Subject: [PATCH 3/3] not throw error if sort keyword not found --- packages/api/src/services/library_item.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/api/src/services/library_item.ts b/packages/api/src/services/library_item.ts index edcf2c732..ecf61067b 100644 --- a/packages/api/src/services/library_item.ts +++ b/packages/api/src/services/library_item.ts @@ -317,18 +317,18 @@ export const buildQuery = ( ) } case 'sort': { - const [sort, sortOrder] = value.split('-') - if (sort.toLowerCase() === 'score') { - // score is not a column and is handled separately + const [sort, sortOrder] = value.toLowerCase().split('-') + const matchingSortBy = Object.values(SortBy).find( + (sortBy) => sortBy === sort + ) + if (!matchingSortBy) { return null } + const column = getColumnName(matchingSortBy) const order = - sortOrder?.toLowerCase() === 'asc' - ? SortOrder.ASCENDING - : SortOrder.DESCENDING + sortOrder === 'asc' ? SortOrder.ASCENDING : SortOrder.DESCENDING - const column = getColumnName(sort) orders.push({ by: `library_item.${column}`, order }) return null }