Skip to content

Commit

Permalink
fix: contact point
Browse files Browse the repository at this point in the history
  • Loading branch information
tpluscode committed Feb 1, 2024
1 parent eb1e4a0 commit e96f58b
Show file tree
Hide file tree
Showing 7 changed files with 307 additions and 87 deletions.
5 changes: 5 additions & 0 deletions .changeset/ten-coats-jam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@zazuko/trifid-plugin-ckan": patch
---

Correctly serialize `dcat:contactPoint` which have RDF types in addition to `vcard:Individual` or `vcard:Organization`.
126 changes: 124 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion packages/ckan/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,18 @@
"@zazuko/env": "^1.11.0",
"@zazuko/prefixes": "^2.1.1",
"dotenv": "^16.3.1",
"is-graph-pointer": "^2.1.0",
"sparql-http-client": "^2.4.2",
"xmlbuilder2": "^3.1.1"
},
"devDependencies": {
"c8": "^8.0.1",
"chai": "^5.0.3",
"chai-subset": "^1.6.0",
"mocha": "^10.2.0",
"oxigraph": "^0.3.22",
"trifid-core": "^2.7.1"
"trifid-core": "^2.7.1",
"xml2js": "^0.6.2",
"xml2js-xpath": "^0.13.0"
}
}
4 changes: 2 additions & 2 deletions packages/ckan/src/namespace.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @ts-check
import _rdf from '@zazuko/env'

const { dcat, dcterms, rdf, schema, skos } = _rdf.ns
const { dcat, dcterms, rdf, schema, skos, vcard, xsd } = _rdf.ns

export { dcat, dcterms, rdf, schema, skos }
export { dcat, dcterms, rdf, schema, skos, vcard, xsd }
56 changes: 28 additions & 28 deletions packages/ckan/src/xml.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import rdf from '@zazuko/env'
import prefixes, { shrink } from '@zazuko/prefixes'
import { create as createXml } from 'xmlbuilder2'
import { isBlankNode, isLiteral, isNamedNode } from 'is-graph-pointer'
import * as ns from './namespace.js'

/**
Expand Down Expand Up @@ -109,7 +110,11 @@ const toXML = (dataset) => {
'dcterms:modified': serializeTerm(dataset.out(ns.dcterms.modified)),
'dcterms:publisher': publishers,
'dcterms:creator': serializeTerm(creators),
'dcat:contactPoint': serializeTerm(dataset.out(ns.dcat.contactPoint)),
'dcat:contactPoint': serializeBlankNode(
dataset.out(ns.dcat.contactPoint),
[ns.vcard.Organization, ns.vcard.Individual],
[ns.vcard.fn, ns.vcard.hasEmail],
),
'dcat:theme': serializeTerm(dataset.out(ns.dcat.theme)),
'dcterms:language': serializeTerm(dataset.out(ns.dcterms.language)),
'dcterms:relation': legalBasis,
Expand All @@ -130,38 +135,21 @@ const toXML = (dataset) => {

const serializeTerm = (pointer) => {
return pointer.map((value) => {
if (isLiteral(value)) {
return serializeLiteral(value)
} else if (isNamedNode(value)) {
return serializeNamedNode(value)
} else if (isBlankNode(value)) {
return serializeBlankNode(value)
} else {
return {}
}
return serializeLiteral(value) || serializeNamedNode(value) || serializeBlankNode(value) || {}
})
}

const isLiteral = (pointer) => {
return pointer.term.termType === 'Literal'
}

const isNamedNode = (pointer) => {
return pointer.term.termType === 'NamedNode'
}

const isBlankNode = (pointer) => {
return pointer.term.termType === 'BlankNode'
}
const serializeLiteral = (pointer) => {
if (!isLiteral(pointer)) return null

const serializeLiteral = ({ term }) => {
const { term } = pointer
const attrs = {}

if (term.language) {
attrs['xml:lang'] = term.language
}

if (term.datatype && !term.datatype.equals(ns.rdf.langString)) {
if (term.datatype && !term.datatype.equals(ns.rdf.langString) && !term.datatype.equals(ns.xsd.string)) {
attrs['rdf:datatype'] = term.datatype.value
}

Expand All @@ -171,14 +159,26 @@ const serializeLiteral = ({ term }) => {
}
}

const serializeNamedNode = ({ value }) => {
const serializeNamedNode = (pointer) => {
if (!isNamedNode(pointer)) return null

return {
'@': { 'rdf:resource': value },
'@': { 'rdf:resource': pointer.value },
}
}

const serializeBlankNode = (pointer) => {
const type = pointer.out(ns.rdf.type).value
/**
*
* @param {import('clownface').MultiPointer} pointer
* @param {Array<import('@rdfjs/types').NamedNode>} [allowedTypesArr]
* @return {Record<string, unknown>}
*/
const serializeBlankNode = (pointer, allowedTypesArr = []) => {
if (!isBlankNode(pointer)) return null

const allowedTypes = rdf.termSet(allowedTypesArr)
const types = pointer.out(ns.rdf.type).terms
const type = types.find((term) => !allowedTypes.size || allowedTypes.has(term))

if (!type) return {}

Expand All @@ -190,7 +190,7 @@ const serializeBlankNode = (pointer) => {
({ ...acc, [shrink(property.value)]: serializeTerm(pointer.out(property)) }), {})

return {
[shrink(type)]: resource,
[shrink(type.value)]: resource,
}
}

Expand Down
Loading

0 comments on commit e96f58b

Please sign in to comment.