Skip to content

Commit

Permalink
feat: 'header-first' api documentation discovery
Browse files Browse the repository at this point in the history
  • Loading branch information
tpluscode committed Sep 22, 2022
1 parent f2a469d commit 7cd5ba8
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/bright-sheep-raise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"alcaeus": patch
---

Option to control where to look for the api documentation link
7 changes: 5 additions & 2 deletions src/Resources/CoreMixins/HydraResource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,11 @@ export function createHydraResourceMixin(alcaeus: () => HydraClient<any>) {

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)
Expand Down
3 changes: 3 additions & 0 deletions src/alcaeus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export interface HydraClient<D extends DatasetCore = DatasetCore> {
resources: ResourceStore<D>
apiDocumentations: ResourceRepresentation<D, ApiDocumentation<D>>[]
cacheStrategy: ResourceCacheStrategy
apiDocumentationDiscovery: 'header-first' | 'representation-first'
}

interface AlcaeusInit<D extends DatasetCore> {
Expand Down Expand Up @@ -78,6 +79,8 @@ export class Alcaeus<D extends DatasetCore> implements HydraClient<D> {

public cacheStrategy: ResourceCacheStrategy = { ...DefaultCacheStrategy }

public apiDocumentationDiscovery = 'representation-first' as const

public readonly resources: ResourceStore<D>

private readonly __apiDocumentations: Map<NamedNode, ResourceRepresentation<D, ApiDocumentation<D>>> = new TermMap()
Expand Down
37 changes: 32 additions & 5 deletions tests/Resources/HydraResource-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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#')
Expand All @@ -23,11 +24,9 @@ const apiDocumentations: ResourceRepresentation<DatasetCore, Hydra.ApiDocumentat
const resources = {
get: jest.fn(),
}
const client = () => ({
apiDocumentations,
resources,
} as any)
const HydraResource: Constructor<Resource> = createHydraResourceMixin(client)(Hydra.ResourceMixin(RdfResourceImpl as any))
let client: HydraClient
const getClient = () => client
const HydraResource: Constructor<Resource> = createHydraResourceMixin(getClient)(Hydra.ResourceMixin(RdfResourceImpl as any))

HydraResource.factory = new ResourceFactory(HydraResource)
HydraResource.factory.addMixin(...Object.values(mixins))
Expand All @@ -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', () => {
Expand Down Expand Up @@ -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`
<http://example.com/> ${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)
})
})
})

0 comments on commit 7cd5ba8

Please sign in to comment.