diff --git a/packages/api/src/resolvers/article/index.ts b/packages/api/src/resolvers/article/index.ts index 808cb367a..037f3958e 100644 --- a/packages/api/src/resolvers/article/index.ts +++ b/packages/api/src/resolvers/article/index.ts @@ -99,7 +99,7 @@ import { Merge } from '../../util' import { analytics } from '../../utils/analytics' import { isSiteBlockedForParse } from '../../utils/blocked' import { enqueueBulkAction } from '../../utils/createTask' -import { authorized } from '../../utils/gql-utils' +import { authorized, isFieldInSelectionSet } from '../../utils/gql-utils' import { cleanUrl, errorHandler, @@ -596,7 +596,7 @@ export const searchResolver = authorized< >, SearchError, QuerySearchArgs ->(async (_obj, params, { uid }) => { +>(async (_obj, params, { uid }, info) => { const startCursor = params.after || '' const first = Math.min(params.first || 10, 100) // limit to 100 items @@ -605,9 +605,14 @@ export const searchResolver = authorized< return { errorCodes: [SearchErrorCode.QueryTooLong] } } + const selectionSet = info.fieldNodes[0].selectionSet + const isContentRequested = selectionSet + ? isFieldInSelectionSet(selectionSet, 'content') + : false + const searchLibraryItemArgs = { includePending: true, - includeContent: params.includeContent ?? true, // by default include content for offline use for now + includeContent: params.includeContent || isContentRequested, includeDeleted: params.query?.includes('in:trash'), query: params.query, useFolders: params.query?.includes('use:folders'), diff --git a/packages/api/src/resolvers/function_resolvers.ts b/packages/api/src/resolvers/function_resolvers.ts index d3cd06b1a..d042b7811 100644 --- a/packages/api/src/resolvers/function_resolvers.ts +++ b/packages/api/src/resolvers/function_resolvers.ts @@ -577,6 +577,7 @@ export const functionResolvers = { pageType: (item: LibraryItem) => item.itemType, highlightsCount: (item: LibraryItem) => item.highlightAnnotations?.length, ...readingProgressHandlers, + content: (item: LibraryItem) => item.readableContent, }, PageInfo: { async totalCount( diff --git a/packages/api/src/utils/gql-utils.ts b/packages/api/src/utils/gql-utils.ts index 62bbf2d09..3efed41d5 100644 --- a/packages/api/src/utils/gql-utils.ts +++ b/packages/api/src/utils/gql-utils.ts @@ -1,3 +1,4 @@ +import { SelectionSetNode } from 'graphql' import { ResolverFn } from '../generated/graphql' import { Claims, ResolverContext } from '../resolvers/types' @@ -24,3 +25,26 @@ export function authorized< return { errorCodes: ['UNAUTHORIZED'] } as TError } } + +export const isFieldInSelectionSet = ( + selectionSet: SelectionSetNode, + fieldName: string +) => { + // recursively check if the field is in the selection set + for (const selection of selectionSet.selections) { + if (selection.kind === 'Field' && selection.name.value === fieldName) { + return true + } + + if ( + (selection.kind === 'InlineFragment' || selection.kind === 'Field') && + selection.selectionSet + ) { + if (isFieldInSelectionSet(selection.selectionSet, fieldName)) { + return true + } + } + } + + return false +}