Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 'header-first' api documentation discovery #307

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
})
})
})