From 78283137107494de0305f328bfbd1dd0baa53117 Mon Sep 17 00:00:00 2001 From: Ciaran Schutte Date: Sun, 15 Dec 2024 05:13:24 -0500 Subject: [PATCH] tighten resolver types tighten config resolver --- modules/server/src/gqlServer.ts | 15 +++- modules/server/src/mapping/masking.ts | 4 +- .../server/src/mapping/resolveAggregations.ts | 4 +- modules/server/src/mapping/resolvers.ts | 70 +++++++++++-------- modules/server/src/mapping/types.ts | 18 +---- 5 files changed, 60 insertions(+), 51 deletions(-) diff --git a/modules/server/src/gqlServer.ts b/modules/server/src/gqlServer.ts index 0c372f832..042770aad 100644 --- a/modules/server/src/gqlServer.ts +++ b/modules/server/src/gqlServer.ts @@ -5,9 +5,20 @@ export type Context = { esClient: Client; }; -export type Resolver = ( +export type ResolverOutput = T | Promise; + +/** + * GQL resolver + * + * @param root The parent object of a query. + * @param args The query arguments. + * @param context The context passed to apollo-server for queries. + * @param info The GraphQL info object. + * @return Returns resolved value; + */ +export type Resolver = ( root: Root, args: QueryArgs, context: Context, info: GraphQLResolveInfo, -) => ReturnValue; +) => ResolverOutput | ResolverOutput; diff --git a/modules/server/src/mapping/masking.ts b/modules/server/src/mapping/masking.ts index 7c7f20c7e..0f34fc20b 100644 --- a/modules/server/src/mapping/masking.ts +++ b/modules/server/src/mapping/masking.ts @@ -12,8 +12,8 @@ export type Relation = keyof typeof Relation; * It is calculated by adding +1 for values under threshold or adding bucket.doc_count amount * for values greater than or equal to * - * @param aggregation an aggregation with the most buckets which has data masking applied - * @returns hits total value + * @param aggregation An aggregation with the most buckets which has data masking applied + * @returns Hits total value */ const calculateHitsFromAggregation = ({ aggregation, diff --git a/modules/server/src/mapping/resolveAggregations.ts b/modules/server/src/mapping/resolveAggregations.ts index 616b098f7..838dc829a 100644 --- a/modules/server/src/mapping/resolveAggregations.ts +++ b/modules/server/src/mapping/resolveAggregations.ts @@ -11,7 +11,7 @@ import esSearch from './utils/esSearch'; /* * GQL query types */ -type GQLAggregationQueryFilters = { +export type GQLAggregationQueryFilters = { filters: any; aggregations_filter_themselves: boolean; include_missing: boolean; @@ -31,7 +31,7 @@ export type Aggregation = { buckets: Bucket[]; }; -type Aggregations = Record; +export type Aggregations = Record; const resolveAggregations = ({ type, diff --git a/modules/server/src/mapping/resolvers.ts b/modules/server/src/mapping/resolvers.ts index 52bea2106..4341e1cb9 100644 --- a/modules/server/src/mapping/resolvers.ts +++ b/modules/server/src/mapping/resolvers.ts @@ -1,12 +1,20 @@ -import { ConfigProperties, ExtendedConfigsInterface } from '@/config/types'; -import { Context } from '@/gqlServer'; import { GraphQLResolveInfo } from 'graphql'; import { get } from 'lodash'; + +import { ConfigProperties, ExtendedConfigsInterface } from '@/config/types'; +import { Context, Resolver } from '@/gqlServer'; import { CreateConnectionResolversArgs } from './createConnectionResolvers'; import { applyAggregationMasking } from './masking'; -import resolveAggregations, { Aggregation, aggregationsToGraphql } from './resolveAggregations'; +import resolveAggregations, { + Aggregation, + Aggregations, + aggregationsToGraphql, + GQLAggregationQueryFilters, +} from './resolveAggregations'; import resolveHits from './resolveHits'; -import { Hits, Root } from './types'; +import { HitsQuery } from './types'; + +type Root = Record; /** * Resolve hits from aggregations @@ -15,20 +23,24 @@ import { Hits, Root } from './types'; * @param aggregationsQuery - resolver ES query code for aggregations * @returns Returns a total count that is less than or equal to the actual total hits in the query. */ -const resolveHitsFromAggs = - ( - aggregationsQuery: ( - obj: Root, - args: { - filters?: object; - include_missing?: boolean; - aggregations_filter_themselves?: boolean; - }, - context: Context, - info: GraphQLResolveInfo, - ) => Record, - ) => - async (obj: Root, args: Hits, context: Context, info: GraphQLResolveInfo) => { +const resolveHitsFromAggs = ( + aggregationsQuery: ( + obj: Root, + args: { + filters?: object; + include_missing?: boolean; + aggregations_filter_themselves?: boolean; + }, + context: Context, + info: GraphQLResolveInfo, + ) => Record, +) => { + const resolver: Resolver> = async ( + obj, + args, + context, + info, + ) => { /* * Get "aggregations" field from full query if found * Popular gql parsing libs parse the "info" property which may not include full query based on schema @@ -57,6 +69,8 @@ const resolveHitsFromAggs = return { total: 0 }; } }; + return resolver; +}; export const createResolvers = ({ createStateResolvers, @@ -66,7 +80,11 @@ export const createResolvers = ({ enableDocumentHits, }: Omit) => { // configs - const configs = async (parentObj: Root, { fieldNames }: { fieldNames: string[] }) => { + // TODO: tighten return value type + const configs: Resolver = async ( + parentObj, + { fieldNames }, + ) => { return { downloads: type.config?.[ConfigProperties.DOWNLOADS], extended: fieldNames @@ -86,15 +104,11 @@ export const createResolvers = ({ // @ts-expect-error - tighten types higher up, "type" const aggregationsQuery = resolveAggregations({ type, getServerSideFilter }); - const aggregations = async ( - obj: Root, - args: { - filters: object; - include_missing: boolean; - aggregations_filter_themselves: boolean; - }, - context: Context, - info: GraphQLResolveInfo, + const aggregations: Resolver> = async ( + obj, + args, + context, + info, ) => { const aggregations = await aggregationsQuery(obj, args, context, info); if (enableDocumentHits) { diff --git a/modules/server/src/mapping/types.ts b/modules/server/src/mapping/types.ts index 752d80db9..dcbfb43c0 100644 --- a/modules/server/src/mapping/types.ts +++ b/modules/server/src/mapping/types.ts @@ -1,19 +1,3 @@ -import { Client } from '@elastic/elasticsearch'; -import { Relation } from './masking'; - -export type Bucket = { - doc_count: number; - key: string; - relation: Relation; -}; - -export type Aggregation = { - bucket_count: number; - buckets: Bucket[]; -}; - -export type Root = Record; - enum Missing { first, last, @@ -38,7 +22,7 @@ export type Sort = { missing: Missing; }; -export type Hits = { +export type HitsQuery = { score: string; offset: number; sort: [Sort];