Skip to content

Commit fcf8dd8

Browse files
committed
feat: variable representation overrides
1 parent 910c7b2 commit fcf8dd8

File tree

3 files changed

+81
-8
lines changed

3 files changed

+81
-8
lines changed

.changeset/long-keys-deny.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@hydrofoil/labyrinth": patch
3+
---
4+
5+
Support for `hydra:variableRepresentation` on template mapping level

packages/labyrinth/lib/template.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import { isUri } from 'valid-url'
1010
const literalValueRegex = /^"(?<value>.+)"(@|\^\^)?((?<=@)(?<language>.*))?((?<=\^\^)(?<datatype>.*))?$/
1111
const TRUE = $rdf.literal('true', xsd.boolean)
1212

13-
function createTermFromVariable({ template, value }: {template: GraphPointer; value: string}) {
14-
if (!hydra.ExplicitRepresentation.equals(template.out(hydra.variableRepresentation).term)) {
13+
function createTermFromVariable({ variableRepresentation, value }: { variableRepresentation: Term | undefined; value: string}) {
14+
if (!hydra.ExplicitRepresentation.equals(variableRepresentation)) {
1515
return value
1616
}
1717

@@ -30,19 +30,21 @@ function createTermFromVariable({ template, value }: {template: GraphPointer; va
3030

3131
export function toPointer(template: GraphPointer, queryParams: ParsedQs): GraphPointer<BlankNode, DatasetExt> {
3232
const templateParams = clownface({ dataset: $rdf.dataset() }).blankNode()
33+
const templateVariableRepresentation = template.out(hydra.variableRepresentation).term
3334

34-
const variablePropertyMap = new Map<string, Term>()
35+
const variablePropertyMap = new Map<string, { property: Term; variableRepresentation: Term | undefined }>()
3536
template.out(hydra.mapping).forEach(mapping => {
3637
const variable = mapping.out(hydra.variable).value
3738
const property = mapping.out(hydra.property).term
3839
const required = mapping.out(hydra.required).term?.equals(TRUE)
40+
const variableRepresentation = mapping.out(hydra.variableRepresentation).term
3941

4042
if (variable && required && !queryParams[variable]) {
4143
throw new httpError.BadRequest(`Missing required template variable ${variable}`)
4244
}
4345

4446
if (variable && property) {
45-
variablePropertyMap.set(variable, property)
47+
variablePropertyMap.set(variable, { property, variableRepresentation })
4648
}
4749
})
4850

@@ -53,14 +55,18 @@ export function toPointer(template: GraphPointer, queryParams: ParsedQs): GraphP
5355
? param.map((item: any) => item.toString())
5456
: []
5557

56-
const property = variablePropertyMap.get(key)
58+
const mapping = variablePropertyMap.get(key)
5759

58-
if (!property) {
60+
if (!mapping) {
5961
return
6062
}
6163

62-
const terms = values.map(value => createTermFromVariable({ template, value }))
63-
templateParams.addOut(property, terms)
64+
const variableRepresentation = mapping.variableRepresentation || templateVariableRepresentation
65+
const terms = values.map(value => createTermFromVariable({
66+
variableRepresentation,
67+
value,
68+
}))
69+
templateParams.addOut(mapping.property, terms)
6470
})
6571

6672
return templateParams

packages/labyrinth/test/lib/template.test.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,5 +76,67 @@ describe('@hydrofoil/labyrinth/lib/template', () => {
7676
expect(graph.out(schema.age).term).to.deep.eq($rdf.literal('20', xsd.unsignedInt))
7777
expect(graph.out(schema.identifier).term).to.deep.eq(schema.Person)
7878
})
79+
80+
it('supports variable representation override by variable', () => {
81+
// given
82+
const template = fromPointer(blankNode(), {
83+
template: '/{name},{age},{type}',
84+
variableRepresentation: hydra.BasicRepresentation,
85+
mapping: [{
86+
variable: 'name',
87+
property: schema.name,
88+
}, {
89+
variable: 'age',
90+
property: schema.age,
91+
}, {
92+
variableRepresentation: hydra.ExplicitRepresentation,
93+
variable: 'type',
94+
property: schema.identifier,
95+
}],
96+
})
97+
98+
// when
99+
const graph = toPointer(template.pointer, {
100+
age: `"20"^^${xsd.unsignedInt.value}`,
101+
name: '"John"@en',
102+
type: schema.Person.value,
103+
})
104+
105+
// then
106+
expect(graph.out(schema.age).term).to.deep.eq($rdf.literal(`"20"^^${xsd.unsignedInt.value}`))
107+
expect(graph.out(schema.name).term).to.deep.eq($rdf.literal('"John"@en'))
108+
expect(graph.out(schema.identifier).term).to.deep.eq(schema.Person)
109+
})
110+
111+
it('supports variable representation override by variable', () => {
112+
// given
113+
const template = fromPointer(blankNode(), {
114+
template: '/{name},{age},{type}',
115+
variableRepresentation: hydra.ExplicitRepresentation,
116+
mapping: [{
117+
variable: 'name',
118+
property: schema.name,
119+
}, {
120+
variable: 'age',
121+
property: schema.age,
122+
}, {
123+
variableRepresentation: hydra.BasicRepresentation,
124+
variable: 'type',
125+
property: schema.identifier,
126+
}],
127+
})
128+
129+
// when
130+
const graph = toPointer(template.pointer, {
131+
age: `"20"^^${xsd.unsignedInt.value}`,
132+
name: '"John"@en',
133+
type: schema.Person.value,
134+
})
135+
136+
// then
137+
expect(graph.out(schema.name).term).to.deep.eq($rdf.literal('John', 'en'))
138+
expect(graph.out(schema.age).term).to.deep.eq($rdf.literal('20', xsd.unsignedInt))
139+
expect(graph.out(schema.identifier).term).to.deep.eq($rdf.literal(schema.Person.value))
140+
})
79141
})
80142
})

0 commit comments

Comments
 (0)