From 7cd5ba82029aea5acfd39d6aa47518fc96852d62 Mon Sep 17 00:00:00 2001 From: tpluscode Date: Thu, 22 Sep 2022 20:13:47 +0200 Subject: [PATCH] feat: 'header-first' api documentation discovery --- .changeset/bright-sheep-raise.md | 5 +++ src/Resources/CoreMixins/HydraResource.ts | 7 +++-- src/alcaeus.ts | 3 ++ tests/Resources/HydraResource-spec.ts | 37 ++++++++++++++++++++--- 4 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 .changeset/bright-sheep-raise.md diff --git a/.changeset/bright-sheep-raise.md b/.changeset/bright-sheep-raise.md new file mode 100644 index 00000000..d30e0904 --- /dev/null +++ b/.changeset/bright-sheep-raise.md @@ -0,0 +1,5 @@ +--- +"alcaeus": patch +--- + +Option to control where to look for the api documentation link diff --git a/src/Resources/CoreMixins/HydraResource.ts b/src/Resources/CoreMixins/HydraResource.ts index 357e792e..056237a0 100644 --- a/src/Resources/CoreMixins/HydraResource.ts +++ b/src/Resources/CoreMixins/HydraResource.ts @@ -110,8 +110,11 @@ export function createHydraResourceMixin(alcaeus: () => HydraClient) { public get apiDocumentation(): ApiDocumentation | undefined { const client = alcaeus() - const id = this.pointer.out(hydra.apiDocumentation).value || - client.resources.get(this.pointer)?.response.apiDocumentationLink + const representationLink = this.pointer.out(hydra.apiDocumentation).value + const headerLink = client.resources.get(this.pointer)?.response.apiDocumentationLink + const id = client.apiDocumentationDiscovery === 'header-first' + ? headerLink || representationLink + : representationLink || headerLink if (id) { const idNode = namedNode(id) diff --git a/src/alcaeus.ts b/src/alcaeus.ts index 655eb249..ff6b8edb 100644 --- a/src/alcaeus.ts +++ b/src/alcaeus.ts @@ -51,6 +51,7 @@ export interface HydraClient { resources: ResourceStore apiDocumentations: ResourceRepresentation>[] cacheStrategy: ResourceCacheStrategy + apiDocumentationDiscovery: 'header-first' | 'representation-first' } interface AlcaeusInit { @@ -78,6 +79,8 @@ export class Alcaeus implements HydraClient { public cacheStrategy: ResourceCacheStrategy = { ...DefaultCacheStrategy } + public apiDocumentationDiscovery = 'representation-first' as const + public readonly resources: ResourceStore private readonly __apiDocumentations: Map>> = new TermMap() diff --git a/tests/Resources/HydraResource-spec.ts b/tests/Resources/HydraResource-spec.ts index 0f0dd03d..a65d8af2 100644 --- a/tests/Resources/HydraResource-spec.ts +++ b/tests/Resources/HydraResource-spec.ts @@ -15,6 +15,7 @@ import { hydra, rdf, schema } from '@tpluscode/rdf-ns-builders' import * as mixins from '../../src/Resources/Mixins' import { ResourceRepresentation } from '../../src/ResourceRepresentation' import { createHydraResourceMixin } from '../../src/Resources/CoreMixins' +import { HydraClient } from '../../src/alcaeus' const parser = new Parser() const ex = namespace('http://example.com/vocab#') @@ -23,11 +24,9 @@ const apiDocumentations: ResourceRepresentation ({ - apiDocumentations, - resources, -} as any) -const HydraResource: Constructor = createHydraResourceMixin(client)(Hydra.ResourceMixin(RdfResourceImpl as any)) +let client: HydraClient +const getClient = () => client +const HydraResource: Constructor = createHydraResourceMixin(getClient)(Hydra.ResourceMixin(RdfResourceImpl as any)) HydraResource.factory = new ResourceFactory(HydraResource) HydraResource.factory.addMixin(...Object.values(mixins)) @@ -50,6 +49,10 @@ async function pushApiDocumentation(apiGraph: Stream, term = ex.api) { describe('HydraResource', () => { beforeEach(() => { apiDocumentations.splice(0, apiDocumentations.length) + client = { + apiDocumentations, + resources, + } as any }) describe('get operations', () => { @@ -550,5 +553,29 @@ describe('HydraResource', () => { // then expect(apiDocumentation?.id).toEqual(ex.api1) }) + + it('ignores link within representation when set to "header-first"', async () => { + // given + client.apiDocumentationDiscovery = 'header-first' + resources.get.mockReturnValue({ + response: { + apiDocumentationLink: ex.api1.value, + }, + }) + const resourceGraph = parse( + turtle` + ${hydra.apiDocumentation} ${ex.api2} . + `) + const resource = new HydraResource(cf({ + dataset: await $rdf.dataset().import(resourceGraph), + term: namedNode('http://example.com/'), + })) + + // when + const { apiDocumentation } = resource + + // then + expect(apiDocumentation?.id).toEqual(ex.api1) + }) }) })