-
Notifications
You must be signed in to change notification settings - Fork 0
/
mod.ts
86 lines (69 loc) · 2.1 KB
/
mod.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import { groupBy } from "https://deno.land/[email protected]/collections/group_by.ts";
type Term = {
termType: string,
value: string,
language?: string,
datatype?: Term
}
type Quad = {
termType: string,
value: string,
subject: Term,
predicate: Term,
object: Term,
graph: Term,
}
type RdfJsonTerm = {
type: 'bnode' | 'uri' | 'literal' | 'defaultgraph',
value: string,
lang?: string,
datatype?: string
}
const typeMapping = {
'NamedNode': 'uri',
'Literal': 'literal',
'BlankNode': 'bnode',
'DefaultGraph': 'defaultgraph'
} as const
/**
* @See https://rdf.js.org/data-model-spec/
* @See https://www.w3.org/TR/rdf-json/#overview-of-rdf-json
*
* Maps Quads from the RDF data model spec to application/rdf+json
*/
export const convertQuadsToRdfJson = (quads: Array<Quad>) => {
const root: {
[key: string]: {
[key: string]: Array<RdfJsonTerm>
}
} = {}
const groupedSubjectQuads = groupBy(quads, (item: Quad) => item.subject.value)
for (const subjectQuads of Object.values(groupedSubjectQuads)) {
if (!subjectQuads) continue
const subject = subjectQuads[0].subject.value
root[subject] = {}
const groupedPredicatesQuads = groupBy(subjectQuads, (item: Quad) => item.predicate.value)
for (const predicateQuads of Object.values(groupedPredicatesQuads)) {
if (!predicateQuads) continue
const predicate = predicateQuads[0].predicate.value
root[subject][predicate] = []
for (const predicateQuad of predicateQuads) {
if (!(predicateQuad.object.termType in typeMapping))
throw new Error('Unexpected termType')
const type = typeMapping[predicateQuad.object.termType as keyof typeof typeMapping]
const value: RdfJsonTerm = {
type,
value: predicateQuad.object.value,
}
if (predicateQuad.object.language) {
value.lang = predicateQuad.object.language
}
if (predicateQuad.object.datatype) {
value.datatype = predicateQuad.object.datatype.value
}
root[subject][predicate].push(value)
}
}
}
return root
}