diff --git a/jest.config.js b/jest.config.js index f9e51e2a..4a5b465e 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,4 +1,4 @@ module.exports = { - transform: { "\\.ts$": ['ts-jest'] }, - setupFilesAfterEnv: ['./jest.setup.js', './jest.setup.redis-mock.js'] -}; \ No newline at end of file + preset: 'ts-jest', + testEnvironment: 'node', +}; diff --git a/package.json b/package.json index 8500f999..ec3f7324 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "coveralls": "^3.1.0", "ioredis-mock": "^8.2.2", "jest": "^26.6.3", + "jest-util": "^26.6.2", "prettier": "^2.2.1", "standard-version": "^9.1.1", "ts-jest": "^26.5.4", diff --git a/src/batch_edge_query.ts b/src/batch_edge_query.ts index 0eae0dd3..17c2adfd 100644 --- a/src/batch_edge_query.ts +++ b/src/batch_edge_query.ts @@ -10,7 +10,7 @@ import { StampedLog } from './log_entry'; import { QueryHandlerOptions } from '.'; import QEdge from './query_edge'; import { UnavailableAPITracker } from './types'; -import { Record } from '../../api-response-transform/built'; +import { Record } from '@biothings-explorer/api-response-transform'; export interface BatchEdgeQueryOptions extends QueryHandlerOptions { recordHashEdgeAttributes: string[]; @@ -24,7 +24,7 @@ export default class BatchEdgeQueryHandler { options: QueryHandlerOptions; resolveOutputIDs: boolean; qEdges: QEdge | QEdge[]; - constructor(metaKG: MetaKG, resolveOutputIDs = true, options: BatchEdgeQueryOptions) { + constructor(metaKG: MetaKG, resolveOutputIDs = true, options?: BatchEdgeQueryOptions) { this.metaKG = metaKG; this.subscribers = []; this.logs = []; diff --git a/src/graph/knowledge_graph.ts b/src/graph/knowledge_graph.ts index a6921cc6..7bc8bdad 100644 --- a/src/graph/knowledge_graph.ts +++ b/src/graph/knowledge_graph.ts @@ -26,8 +26,8 @@ export default class KnowledgeGraph { [edgeID: string]: TrapiKGEdge; }; kg: TrapiKnowledgeGraph; - apiList: APIDefinition[]; - constructor(apiList: APIDefinition[]) { + apiList?: APIDefinition[]; + constructor(apiList?: APIDefinition[]) { this.nodes = {}; this.edges = {}; this.kg = { @@ -84,7 +84,7 @@ export default class KnowledgeGraph { for (const key in kgNode.nodeAttributes) { node.attributes.push({ attribute_type_id: key, - value: kgNode.nodeAttributes[key], + value: kgNode.nodeAttributes[key] as string[], //value_type_id: 'bts:' + key, }); } diff --git a/src/index.ts b/src/index.ts index 2b3d3852..0a270559 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,10 +11,8 @@ import EdgeManager from './edge_manager'; import _ from 'lodash'; import QEdge2APIEdgeHandler from './qedge2apiedge'; import LogEntry, { StampedLog } from './log_entry'; -import { redisClient, getNewRedisClient } from './redis-client'; import { promises as fs } from 'fs'; import { getDescendants } from '@biothings-explorer/node-expansion'; -import { getTemplates, supportedLookups } from './inferred_mode/template_lookup'; import { resolveSRI, SRIResolverFailiure } from 'biomedical_id_resolver'; import InferredQueryHandler from './inferred_mode/inferred_mode'; import KGNode from './graph/kg_node'; @@ -32,7 +30,15 @@ import { import BTEGraph from './graph/graph'; import QEdge from './query_edge'; -export { InvalidQueryGraphError, redisClient, getNewRedisClient, LogEntry, getTemplates, supportedLookups }; +// Exports for external availability +export * from './types'; +export { redisClient, getNewRedisClient } from './redis-client'; +export { getTemplates, supportedLookups } from './inferred_mode/template_lookup'; +export { default as QEdge } from './query_edge'; +export { default as QNode } from './query_node'; +export { default as InvalidQueryGraphError } from './exceptions/invalid_query_graph_error'; +export { default as LogEntry } from './log_entry'; +export * from './qedge2apiedge'; export interface QueryHandlerOptions { provenanceUsesServiceProvider?: boolean; @@ -48,7 +54,7 @@ export interface QueryHandlerOptions { caching?: boolean; // from request url query values EDGE_ATTRIBUTES_USED_IN_RECORD_HASH?: string[]; } -export class TRAPIQueryHandler { +export default class TRAPIQueryHandler { logs: StampedLog[]; options: QueryHandlerOptions; includeReasoner: boolean; @@ -62,7 +68,12 @@ export class TRAPIQueryHandler { auxGraphs: TrapiAuxGraphCollection; finalizedResults: TrapiResult[]; queryGraph: TrapiQueryGraph; - constructor(options = {}, smartAPIPath = undefined, predicatesPath = undefined, includeReasoner = true) { + constructor( + options: QueryHandlerOptions = {}, + smartAPIPath: string = undefined, + predicatesPath: string = undefined, + includeReasoner = true, + ) { this.logs = []; this.options = options; this.options.provenanceUsesServiceProvider = this.options.smartAPIID || this.options.teamName ? true : false; @@ -173,8 +184,8 @@ export class TRAPIQueryHandler { subject, object, }); - const source = Object.keys(ontologyKnowledgeSourceMapping).find(([prefix]) => { - if (expanded.includes(prefix)) return true; + const source = Object.entries(ontologyKnowledgeSourceMapping).find(([prefix]) => { + return expanded.includes(prefix); })[1]; subclassEdge.addSource([ { resource_id: source, resource_role: 'primary_knowledge_source' }, @@ -599,9 +610,9 @@ export class TRAPIQueryHandler { new LogEntry( 'INFO', null, - `execution Summary: (${KGNodes}) nodes / (${kgEdges}) edges / (${results}) results; (${resultQueries}/${queries}) queries${ + `Execution Summary: (${KGNodes}) nodes / (${kgEdges}) edges / (${results}) results; (${resultQueries}/${queries}) queries${ cached ? ` (${cached} cached qEdges)` : '' - } returned results from(${sources.length}) unique APIs ${sources.length === 1 ? 's' : ''} `, + } returned results from(${sources.length}) unique API${sources.length === 1 ? 's' : ''}`, ).getLog(), new LogEntry('INFO', null, `APIs: ${sources.join(', ')} `).getLog(), ]; @@ -640,7 +651,7 @@ export class TRAPIQueryHandler { null, `The following APIs were unavailable at the time of execution: ${global.missingAPIs .map((spec) => spec.info.title) - .join(', ')} `, + .join(', ')}`, ).getLog(), ); } diff --git a/src/inferred_mode/inferred_mode.ts b/src/inferred_mode/inferred_mode.ts index a7bfab9b..4734f070 100644 --- a/src/inferred_mode/inferred_mode.ts +++ b/src/inferred_mode/inferred_mode.ts @@ -5,7 +5,7 @@ import async from 'async'; import biolink from '../biolink'; import { getTemplates, MatchedTemplate, TemplateLookup } from './template_lookup'; import { scaled_sigmoid, inverse_scaled_sigmoid } from '../results_assembly/score'; -import { QueryHandlerOptions, TRAPIQueryHandler } from '..'; +import TRAPIQueryHandler, { QueryHandlerOptions } from '../index'; import { CompactQualifiers, TrapiAuxGraphCollection, @@ -20,11 +20,12 @@ import { const debug = Debug('bte:biothings-explorer-trapi:inferred-mode'); export interface CombinedResponse { - workflow: { id: string }[]; + description?: string; + workflow?: { id: string }[]; message: { query_graph: TrapiQueryGraph; knowledge_graph: TrapiKnowledgeGraph; - auxiliary_graphs: TrapiAuxGraphCollection; + auxiliary_graphs?: TrapiAuxGraphCollection; results: { [resultID: string]: TrapiResult; }; @@ -488,6 +489,8 @@ export default class InferredQueryHandler { const { qEdgeID, qEdge, qSubject, qObject } = this.getQueryParts(); const subQueries = await this.createQueries(qEdge, qSubject, qObject); const combinedResponse = { + status: 'Success', + description: '', schema_version: global.SCHEMA_VERSION, biolink_version: global.BIOLINK_VERSION, workflow: [{ id: 'lookup' }], diff --git a/src/qedge2apiedge.ts b/src/qedge2apiedge.ts index 2fc94d94..92b1a2ad 100644 --- a/src/qedge2apiedge.ts +++ b/src/qedge2apiedge.ts @@ -5,8 +5,8 @@ const CURIE_WITH_PREFIXES = ['MONDO', 'DOID', 'UBERON', 'EFO', 'HP', 'CHEBI', 'C import Debug from 'debug'; import QEdge from './query_edge'; import MetaKG from '@biothings-explorer/smartapi-kg'; -import { SmartAPIKGOperationObject } from '../../smartapi-kg/built/parser/types'; -import { SRIBioEntity } from '../../../biomedical_id_resolver/built/common/types'; +import { SmartAPIKGOperationObject } from '@biothings-explorer/smartapi-kg'; +import { SRIBioEntity } from 'biomedical_id_resolver'; const debug = Debug('bte:biothings-explorer-trapi:qedge2btedge'); export interface MetaXEdge extends SmartAPIKGOperationObject { diff --git a/src/query_edge.ts b/src/query_edge.ts index 1b1fb2f9..bd7160c4 100644 --- a/src/query_edge.ts +++ b/src/query_edge.ts @@ -7,7 +7,6 @@ import QNode from './query_node'; import { QNodeInfo } from './query_node'; import { StampedLog } from './log_entry'; import { TrapiAttributeConstraint, TrapiQualifierConstraint } from './types'; -// import { FrozenRecord } from '../../api-response-transform/built/record'; const debug = Debug('bte:biothings-explorer-trapi:QEdge'); diff --git a/src/query_node.ts b/src/query_node.ts index 0d56972a..f430c47a 100644 --- a/src/query_node.ts +++ b/src/query_node.ts @@ -10,7 +10,7 @@ const debug = Debug('bte:biothings-explorer-trapi:QNode'); export interface QNodeInfo { id: string; categories?: string[]; - ids: string[]; + ids?: string[]; is_set?: boolean; expanded_curie?: ExpandedCuries; held_curie?: string[]; diff --git a/src/redis-client.ts b/src/redis-client.ts index c624f46e..f15bce99 100644 --- a/src/redis-client.ts +++ b/src/redis-client.ts @@ -70,7 +70,6 @@ interface RedisClientInterface { usingLock: ( resources: string[], duration: number, - settings: unknown, routine?: (signal: RedlockAbortSignal) => Promise, ) => Promise; incrTimeout: (key: string, callback: Callback) => Promise; @@ -106,8 +105,8 @@ function addClientFuncs(client: Redis | Cluster, redlock: Redlock): RedisClientI ? addPrefixToAll(timeoutFunc((...args: RedisKey[]) => client.del(...args))) : timeoutFunc((...args: RedisKey[]) => client.del(...args)), usingLock: lockPrefix( - (resources: string[], duration: number, settings, routine?: (signal: RedlockAbortSignal) => Promise) => - redlock.using(resources, duration, settings, routine), + (resources: string[], duration: number, routine?: (signal: RedlockAbortSignal) => Promise) => + redlock.using(resources, duration, routine), ), incrTimeout: decorate((key: string) => client.incr(key)), decrTimeout: decorate((key: string) => client.decr(key)), diff --git a/src/types.ts b/src/types.ts index 6ba84552..e3523a6d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -20,19 +20,19 @@ declare global { } export interface TrapiQNode { - ids: string[]; - categories: string[]; - is_set: boolean; - constraints: TrapiAttributeConstraint[]; + ids?: string[]; + categories?: string[]; + is_set?: boolean; + constraints?: TrapiAttributeConstraint[]; } export interface TrapiQEdge { - knowledge_type: string; - predicates: string[]; + knowledge_type?: string; + predicates?: string[]; subject: string; object: string; - attribute_constraints: TrapiAttributeConstraint[]; - qualifier_constraints: TrapiQualifierConstraint[]; + attribute_constraints?: TrapiAttributeConstraint[]; + qualifier_constraints?: TrapiQualifierConstraint[]; } export interface TrapiQueryGraph { @@ -83,9 +83,10 @@ export interface TrapiAttribute { original_attribute_name?: string; value: string | string[] | number | number[]; value_type_id?: string; - attribute_source?: string; - value_url?: string; + attribute_source?: string | null; + value_url?: string | null; attributes?: TrapiAttribute; + [additionalProperties: string]: string | string[] | null | TrapiAttribute | number | number[]; } export interface TrapiQualifier { @@ -117,8 +118,8 @@ export interface TrapiEdgeBinding { } export interface TrapiAnalysis { - resource_id: string; - score: number; + resource_id?: string; + score?: number; edge_bindings: { [qEdgeID: string]: TrapiEdgeBinding[]; }; @@ -152,14 +153,14 @@ export interface TrapiAuxGraphCollection { } export interface TrapiResponse { - description: string; - schema_version: string; - biolink_version: string; - workflow: { id: string }[]; + description?: string; + schema_version?: string; + biolink_version?: string; + workflow?: { id: string }[]; message: { query_graph: TrapiQueryGraph; knowledge_graph: TrapiKnowledgeGraph; - auxiliary_graphs: TrapiAuxGraphCollection; + auxiliary_graphs?: TrapiAuxGraphCollection; results: TrapiResult[]; }; logs: TrapiLog[]; diff --git a/src/update_nodes.ts b/src/update_nodes.ts index f567baef..191dc05e 100644 --- a/src/update_nodes.ts +++ b/src/update_nodes.ts @@ -3,6 +3,7 @@ import Debug from 'debug'; import { ResolverInput, SRIResolverOutput } from '../../../biomedical_id_resolver/built/common/types'; import { Record } from '@biothings-explorer/api-response-transform'; import QEdge from './query_edge'; +import { NodeNormalizerResultObj } from '../../api-response-transform/built'; const debug = Debug('bte:biothings-explorer-trapi:nodeUpdateHandler'); export interface CuriesByCategory { @@ -63,7 +64,7 @@ export default class NodesUpdateHandler { return; } - _createEquivalentIDsObject(record: Record) { + _createEquivalentIDsObject(record: Record): { [curie: string]: NodeNormalizerResultObj } { if (record.object.normalizedInfo !== undefined) { return { [record.object.curie]: record.object.normalizedInfo,