@ulb-darmstadt/shacl-form 1.7.3 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +13 -3
  2. package/dist/config.d.ts +4 -5
  3. package/dist/constants.d.ts +15 -12
  4. package/dist/constraints.d.ts +5 -4
  5. package/dist/exports.d.ts +2 -1
  6. package/dist/form-bootstrap.d.ts +1 -1
  7. package/dist/form-bootstrap.js +361 -2
  8. package/dist/form-default.d.ts +1 -1
  9. package/dist/form-default.js +350 -2
  10. package/dist/form-material.d.ts +1 -1
  11. package/dist/form-material.js +670 -2
  12. package/dist/form.d.ts +3 -2
  13. package/dist/node-template.d.ts +17 -0
  14. package/dist/node.d.ts +5 -1
  15. package/dist/plugins/leaflet.d.ts +2 -4
  16. package/dist/plugins/leaflet.js +720 -2
  17. package/dist/plugins/mapbox.d.ts +2 -2
  18. package/dist/plugins/mapbox.js +2764 -2
  19. package/dist/property-template.d.ts +2 -1
  20. package/dist/property.d.ts +6 -2
  21. package/dist/theme.d.ts +2 -2
  22. package/dist/themes/default.d.ts +3 -3
  23. package/dist/themes/material.d.ts +2 -3
  24. package/package.json +26 -14
  25. package/src/config.ts +11 -10
  26. package/src/constants.ts +4 -1
  27. package/src/constraints.ts +75 -31
  28. package/src/exports.ts +2 -1
  29. package/src/form.ts +32 -17
  30. package/src/group.ts +1 -1
  31. package/src/loader.ts +12 -13
  32. package/src/node-template.ts +82 -0
  33. package/src/node.ts +88 -63
  34. package/src/plugins/leaflet.ts +2 -2
  35. package/src/plugins/mapbox.ts +4 -4
  36. package/src/property-template.ts +19 -8
  37. package/src/property.ts +168 -63
  38. package/src/serialize.ts +14 -1
  39. package/src/styles.css +8 -10
  40. package/src/theme.ts +5 -5
  41. package/src/themes/bootstrap.ts +1 -1
  42. package/src/themes/default.css +2 -2
  43. package/src/themes/default.ts +12 -3
  44. package/src/themes/material.ts +12 -3
  45. package/src/util.ts +12 -14
  46. package/dist/form-bootstrap.js.LICENSE.txt +0 -69
  47. package/dist/form-default.js.LICENSE.txt +0 -69
  48. package/dist/form-material.js.LICENSE.txt +0 -69
  49. package/dist/plugins/file-upload.js +0 -1
  50. package/dist/plugins/fixed-list.js +0 -1
  51. package/dist/plugins/leaflet.js.LICENSE.txt +0 -4
  52. package/dist/plugins/mapbox.js.LICENSE.txt +0 -10
@@ -0,0 +1,82 @@
1
+ import { BlankNode, NamedNode, Quad } from "n3"
2
+ import { Config } from "./config"
3
+ import { OWL_PREDICATE_IMPORTS, PREFIX_SHACL } from "./constants";
4
+ import { Term } from "@rdfjs/types";
5
+
6
+ const mappers: Record<string, (template: ShaclNodeTemplate, term: Term) => void> = {
7
+ [`${PREFIX_SHACL}property`]: (template, term) => { template.properties.push(term as (BlankNode | NamedNode)) },
8
+ [`${PREFIX_SHACL}and`]: (template, term) => { template.shaclAnd = term.value },
9
+ [`${PREFIX_SHACL}node`]: (template, term) => { template.node = term as NamedNode },
10
+ [`${PREFIX_SHACL}targetClass`]: (template, term) => { template.targetClass = term as NamedNode },
11
+ [`${PREFIX_SHACL}or`]: (template, term) => {
12
+ const list = template.config.lists[term.value]
13
+ if (list?.length) {
14
+ template.shaclOr = list
15
+ } else {
16
+ console.error('list for sh:or not found:', term.value, 'existing lists:', template.config.lists)
17
+ }
18
+ },
19
+ [`${PREFIX_SHACL}xone`]: (template, term) => {
20
+ const list = template.config.lists[term.value]
21
+ if (list?.length) {
22
+ template.shaclXone = list
23
+ } else {
24
+ console.error('list for sh:xone not found:', term.value, 'existing lists:', template.config.lists)
25
+ }
26
+ },
27
+ [OWL_PREDICATE_IMPORTS.id]: (template, term) => { template.owlImports.push(term as NamedNode) }
28
+ }
29
+
30
+ export class ShaclNodeTemplate {
31
+ properties: (NamedNode | BlankNode)[] = []
32
+ node: NamedNode | undefined
33
+ shaclAnd: string | undefined
34
+ shaclOr: Term[] | undefined
35
+ shaclXone: Term[] | undefined
36
+ targetClass: NamedNode | undefined
37
+
38
+ owlImports: NamedNode[] = []
39
+ config: Config
40
+ extendedShapes: NamedNode[] = []
41
+
42
+ constructor(quads: Quad[], config: Config) {
43
+ this.config = config
44
+ this.merge(quads)
45
+ }
46
+
47
+ merge(quads: Quad[]): ShaclNodeTemplate {
48
+ for (const quad of quads) {
49
+ mappers[quad.predicate.id]?.call(this, this, quad.object)
50
+ }
51
+ // resolve extended shapes
52
+ if (this.node || this.shaclAnd) {
53
+ if (this.node) {
54
+ this.extendedShapes.push(this.node)
55
+ }
56
+ if (this.shaclAnd) {
57
+ const list = this.config.lists[this.shaclAnd]
58
+ if (list?.length) {
59
+ for (const node of list) {
60
+ this.extendedShapes.push(node as NamedNode)
61
+ }
62
+ }
63
+ }
64
+ }
65
+ return this
66
+ }
67
+
68
+ clone(): ShaclNodeTemplate {
69
+ const copy = Object.assign({}, this)
70
+ // arrays are not cloned but referenced, so create them manually
71
+ copy.owlImports = [ ...this.owlImports ]
72
+ if (this.shaclOr) {
73
+ copy.shaclOr = [ ...this.shaclOr ]
74
+ }
75
+ if (this.shaclXone) {
76
+ copy.shaclXone = [ ...this.shaclXone ]
77
+ }
78
+ copy.merge = this.merge.bind(copy)
79
+ copy.clone = this.clone.bind(copy)
80
+ return copy
81
+ }
82
+ }
package/src/node.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { BlankNode, DataFactory, NamedNode, Store } from 'n3'
2
2
  import { Term } from '@rdfjs/types'
3
- import { PREFIX_SHACL, RDF_PREDICATE_TYPE, OWL_PREDICATE_IMPORTS } from './constants'
3
+ import { PREFIX_SHACL, RDF_PREDICATE_TYPE, OWL_PREDICATE_IMPORTS, SHACL_PREDICATE_PROPERTY } from './constants'
4
4
  import { ShaclProperty } from './property'
5
5
  import { createShaclGroup } from './group'
6
6
  import { v4 as uuidv4 } from 'uuid'
7
- import { createShaclOrConstraint } from './constraints'
7
+ import { createShaclOrConstraint, resolveShaclOrConstraintOnNode } from './constraints'
8
8
  import { Config } from './config'
9
9
 
10
10
  export class ShaclNode extends HTMLElement {
@@ -14,24 +14,26 @@ export class ShaclNode extends HTMLElement {
14
14
  targetClass: NamedNode | undefined
15
15
  owlImports: NamedNode[] = []
16
16
  config: Config
17
+ linked: boolean
17
18
 
18
- constructor(shaclSubject: NamedNode, config: Config, valueSubject: NamedNode | BlankNode | undefined, parent?: ShaclNode, nodeKind?: NamedNode, label?: string) {
19
+ constructor(shaclSubject: NamedNode, config: Config, valueSubject: NamedNode | BlankNode | undefined, parent?: ShaclNode, nodeKind?: NamedNode, label?: string, linked?: boolean) {
19
20
  super()
20
21
 
21
22
  this.parent = parent
22
23
  this.config = config
23
24
  this.shaclSubject = shaclSubject
25
+ this.linked = linked || false
24
26
  let nodeId: NamedNode | BlankNode | undefined = valueSubject
25
27
  if (!nodeId) {
26
28
  // if no value subject given, create new node id with a type depending on own nodeKind or given parent property nodeKind
27
29
  if (!nodeKind) {
28
- const spec = config.shapesGraph.getObjects(shaclSubject, `${PREFIX_SHACL}nodeKind`, null)
30
+ const spec = config.store.getObjects(shaclSubject, `${PREFIX_SHACL}nodeKind`, null)
29
31
  if (spec.length) {
30
32
  nodeKind = spec[0] as NamedNode
31
33
  }
32
34
  }
33
35
  // if nodeKind is not set, but a value namespace is configured or if nodeKind is sh:IRI, then create a NamedNode
34
- if ((nodeKind === undefined && config.attributes.valuesNamespace) || nodeKind?.id === `${PREFIX_SHACL}IRI`) {
36
+ if ((nodeKind === undefined && config.attributes.valuesNamespace) || nodeKind?.value === `${PREFIX_SHACL}IRI`) {
35
37
  // no requirements on node type, so create a NamedNode and use configured value namespace
36
38
  nodeId = DataFactory.namedNode(config.attributes.valuesNamespace + uuidv4())
37
39
  } else {
@@ -45,17 +47,19 @@ export class ShaclNode extends HTMLElement {
45
47
  const id = JSON.stringify([shaclSubject, valueSubject])
46
48
  if (valueSubject && config.renderedNodes.has(id)) {
47
49
  // node/value pair is already rendered in the form, so just display a reference
48
- if (label && config.attributes.collapse === null) {
49
- const labelElem = document.createElement('label')
50
- labelElem.innerText = label
51
- this.appendChild(labelElem)
52
- }
50
+ label = label || "Link"
51
+ const labelElem = document.createElement('label')
52
+ labelElem.innerText = label
53
+ labelElem.classList.add('linked')
54
+ this.appendChild(labelElem)
55
+
53
56
  const anchor = document.createElement('a')
54
- anchor.innerText = valueSubject.id
57
+ let refId = (valueSubject.termType === 'BlankNode') ? '_:' + valueSubject.value : valueSubject.value
58
+ anchor.innerText = refId
55
59
  anchor.classList.add('ref-link')
56
60
  anchor.onclick = () => {
57
61
  // if anchor is clicked, scroll referenced shacl node into view
58
- this.config.form.querySelector(`shacl-node[data-node-id='${this.nodeId.id}']`)?.scrollIntoView()
62
+ this.config.form.querySelector(`shacl-node[data-node-id='${refId}']`)?.scrollIntoView()
59
63
  }
60
64
  this.appendChild(anchor)
61
65
  this.style.flexDirection = 'row'
@@ -64,9 +68,6 @@ export class ShaclNode extends HTMLElement {
64
68
  config.renderedNodes.add(id)
65
69
  }
66
70
  this.dataset.nodeId = this.nodeId.id
67
- const quads = config.shapesGraph.getQuads(shaclSubject, null, null, null)
68
- let list: Term[] | undefined
69
-
70
71
  if (this.config.attributes.showNodeIds !== null) {
71
72
  const div = document.createElement('div')
72
73
  div.innerText = `id: ${this.nodeId.id}`
@@ -74,39 +75,19 @@ export class ShaclNode extends HTMLElement {
74
75
  this.appendChild(div)
75
76
  }
76
77
 
77
- for (const quad of quads) {
78
+ // first initialize owl:imports, this is needed before adding properties to properly resolve class instances etc.
79
+ for (const owlImport of config.store.getQuads(shaclSubject, OWL_PREDICATE_IMPORTS, null, null)) {
80
+ this.owlImports.push(owlImport.object as NamedNode)
81
+ }
82
+ // now parse other node quads
83
+ for (const quad of config.store.getQuads(shaclSubject, null, null, null)) {
78
84
  switch (quad.predicate.id) {
79
- case `${PREFIX_SHACL}property`:
80
- let parentElement: HTMLElement = this
81
- // check if property belongs to a group
82
- const groupRef = config.shapesGraph.getQuads(quad.object as Term, `${PREFIX_SHACL}group`, null, null)
83
- if (groupRef.length > 0) {
84
- const groupSubject = groupRef[0].object.value
85
- if (config.groups.indexOf(groupSubject) > -1) {
86
- // check if group element already exists, otherwise create it
87
- let group = this.querySelector(`:scope > .shacl-group[data-subject='${groupSubject}']`) as HTMLElement
88
- if (!group) {
89
- group = createShaclGroup(groupSubject, config)
90
- this.appendChild(group)
91
- }
92
- parentElement = group
93
- } else {
94
- console.warn('ignoring unknown group reference', groupRef[0], 'existing groups:', config.groups)
95
- }
96
- }
97
- // delay creating/appending the property until we finished parsing the node.
98
- // This is needed to have possible owlImports parsed before creating the property.
99
- setTimeout(() => {
100
- const property = new ShaclProperty(quad.object as NamedNode | BlankNode, this, config, valueSubject)
101
- // do not add empty properties (i.e. properties with no instances). This can be the case e.g. in viewer mode when there is no data for the respective property.
102
- if (property.childElementCount > 0) {
103
- parentElement.appendChild(property)
104
- }
105
- })
85
+ case SHACL_PREDICATE_PROPERTY.id:
86
+ this.addPropertyInstance(quad.object, config, valueSubject)
106
87
  break;
107
88
  case `${PREFIX_SHACL}and`:
108
89
  // inheritance via sh:and
109
- list = config.lists[quad.object.value]
90
+ const list = config.lists[quad.object.value]
110
91
  if (list?.length) {
111
92
  for (const shape of list) {
112
93
  this.prepend(new ShaclNode(shape as NamedNode, config, valueSubject, this))
@@ -123,17 +104,11 @@ export class ShaclNode extends HTMLElement {
123
104
  case `${PREFIX_SHACL}targetClass`:
124
105
  this.targetClass = quad.object as NamedNode
125
106
  break;
126
- case OWL_PREDICATE_IMPORTS.id:
127
- this.owlImports.push(quad.object as NamedNode)
128
- break;
129
107
  case `${PREFIX_SHACL}or`:
130
- list = config.lists[quad.object.value]
131
- if (list?.length) {
132
- this.appendChild(createShaclOrConstraint(list, this, config))
133
- }
134
- else {
135
- console.error('list not found:', quad.object.value, 'existing lists:', config.lists)
136
- }
108
+ this.tryResolve(quad.object, valueSubject, config)
109
+ break;
110
+ case `${PREFIX_SHACL}xone`:
111
+ this.tryResolve(quad.object, valueSubject, config)
137
112
  break;
138
113
  }
139
114
  }
@@ -150,18 +125,68 @@ export class ShaclNode extends HTMLElement {
150
125
  if (!subject) {
151
126
  subject = this.nodeId
152
127
  }
153
- for (const shape of this.querySelectorAll(':scope > shacl-node, :scope > .shacl-group > shacl-node, :scope > shacl-property, :scope > .shacl-group > shacl-property')) {
154
- (shape as ShaclNode | ShaclProperty).toRDF(graph, subject)
128
+ // output triples only if node is not a link
129
+ if (!this.linked) {
130
+ for (const shape of this.querySelectorAll(':scope > shacl-node, :scope > .shacl-group > shacl-node, :scope > shacl-property, :scope > .shacl-group > shacl-property')) {
131
+ (shape as ShaclNode | ShaclProperty).toRDF(graph, subject)
132
+ }
133
+ if (this.targetClass) {
134
+ graph.addQuad(subject, RDF_PREDICATE_TYPE, this.targetClass, this.config.valuesGraphId)
135
+ }
136
+ // if this is the root shacl node, check if we should add one of the rdf:type or dcterms:conformsTo predicates
137
+ if (this.config.attributes.generateNodeShapeReference && !this.parent) {
138
+ graph.addQuad(subject, DataFactory.namedNode(this.config.attributes.generateNodeShapeReference), this.shaclSubject, this.config.valuesGraphId)
139
+ }
140
+ }
141
+ return subject
142
+ }
143
+
144
+ addPropertyInstance(shaclSubject: Term, config: Config, valueSubject: NamedNode | BlankNode | undefined) {
145
+ let parentElement: HTMLElement = this
146
+ // check if property belongs to a group
147
+ const groupRef = config.store.getQuads(shaclSubject as Term, `${PREFIX_SHACL}group`, null, null)
148
+ if (groupRef.length > 0) {
149
+ const groupSubject = groupRef[0].object.value
150
+ if (config.groups.indexOf(groupSubject) > -1) {
151
+ // check if group element already exists, otherwise create it
152
+ let group = this.querySelector(`:scope > .shacl-group[data-subject='${groupSubject}']`) as HTMLElement
153
+ if (!group) {
154
+ group = createShaclGroup(groupSubject, config)
155
+ this.appendChild(group)
156
+ }
157
+ parentElement = group
158
+ } else {
159
+ console.warn('ignoring unknown group reference', groupRef[0], 'existing groups:', config.groups)
160
+ }
161
+ }
162
+ const property = new ShaclProperty(shaclSubject as NamedNode | BlankNode, this, config, valueSubject)
163
+ // do not add empty properties (i.e. properties with no instances). This can be the case e.g. in viewer mode when there is no data for the respective property.
164
+ if (property.childElementCount > 0) {
165
+ parentElement.appendChild(property)
155
166
  }
156
- if (this.targetClass) {
157
- graph.addQuad(subject, RDF_PREDICATE_TYPE, this.targetClass, this.config.valuesGraph)
167
+ }
168
+
169
+ tryResolve(subject: Term, valueSubject: NamedNode | BlankNode | undefined, config: Config) {
170
+ const list = config.lists[subject.value]
171
+ if (list?.length) {
172
+ let resolved = false
173
+ if (valueSubject) {
174
+ const resolvedPropertySubjects = resolveShaclOrConstraintOnNode(list, valueSubject, config)
175
+ if (resolvedPropertySubjects.length) {
176
+ for (const propertySubject of resolvedPropertySubjects) {
177
+ this.addPropertyInstance(propertySubject, config, valueSubject)
178
+ }
179
+ resolved = true
180
+ }
181
+ }
182
+ if (!resolved) {
183
+ this.appendChild(createShaclOrConstraint(list, this, config))
184
+ }
158
185
  }
159
- // if this is the root shacl node, check if we should add one of the rdf:type or dcterms:conformsTo predicates
160
- if (this.config.attributes.generateNodeShapeReference && !this.parent) {
161
- graph.addQuad(subject, DataFactory.namedNode(this.config.attributes.generateNodeShapeReference), this.shaclSubject, this.config.valuesGraph)
186
+ else {
187
+ console.error('list for sh:or/sh:xone not found:', subject, 'existing lists:', config.lists)
162
188
  }
163
- return subject
164
189
  }
165
190
  }
166
191
 
167
- window.customElements.define('shacl-node', ShaclNode)
192
+ window.customElements.define('shacl-node', ShaclNode)
@@ -136,12 +136,12 @@ export class LeafletPlugin extends Plugin {
136
136
  document.body.style.position = 'fixed'
137
137
  dialog.showModal()
138
138
  }
139
- const instance = fieldFactory(template, value || null)
139
+ const instance = fieldFactory(template, value || null, true)
140
140
  instance.appendChild(button)
141
141
  return instance
142
142
  }
143
143
 
144
- createViewer(template: ShaclPropertyTemplate, value: Term): HTMLElement {
144
+ createViewer(_: ShaclPropertyTemplate, value: Term): HTMLElement {
145
145
  const container = document.createElement('div')
146
146
  const geometry = wktToGeometry(value.value)
147
147
  if (geometry?.coordinates?.length) {
@@ -4,8 +4,8 @@ import { ShaclPropertyTemplate } from '../property-template'
4
4
  import { Editor, fieldFactory } from '../theme'
5
5
  import { Map, NavigationControl, FullscreenControl, LngLatBounds, LngLatLike } from 'mapbox-gl'
6
6
  import MapboxDraw from '@mapbox/mapbox-gl-draw'
7
- import mapboxGlCss from 'mapbox-gl/dist/mapbox-gl.css'
8
- import mapboxGlDrawCss from '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css'
7
+ import mapboxGlCss from 'mapbox-gl/dist/mapbox-gl.css?raw'
8
+ import mapboxGlDrawCss from '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css?raw'
9
9
  import { Geometry, geometryToWkt, wktToGeometry } from './map-util'
10
10
 
11
11
  const css = `
@@ -106,12 +106,12 @@ export class MapboxPlugin extends Plugin {
106
106
  document.body.style.position = 'fixed'
107
107
  dialog.showModal()
108
108
  }
109
- const instance = fieldFactory(template, value || null)
109
+ const instance = fieldFactory(template, value || null, true)
110
110
  instance.appendChild(button)
111
111
  return instance
112
112
  }
113
113
 
114
- createViewer(template: ShaclPropertyTemplate, value: Term): HTMLElement {
114
+ createViewer(_: ShaclPropertyTemplate, value: Term): HTMLElement {
115
115
  const container = document.createElement('div')
116
116
  const geometry = wktToGeometry(value.value)
117
117
  if (geometry?.coordinates?.length) {
@@ -34,11 +34,11 @@ const mappers: Record<string, (template: ShaclPropertyTemplate, term: Term) => v
34
34
  [`${PREFIX_SHACL}qualifiedValueShape`]: (template, term) => { template.qualifiedValueShape = term },
35
35
  [`${PREFIX_SHACL}qualifiedMinCount`]: (template, term) => { template.minCount = parseInt(term.value) },
36
36
  [`${PREFIX_SHACL}qualifiedMaxCount`]: (template, term) => { template.maxCount = parseInt(term.value) },
37
- [OWL_PREDICATE_IMPORTS.id]: (template, term) => { template.owlImports.push(term as NamedNode) },
38
- [SHACL_PREDICATE_CLASS.id]: (template, term) => {
37
+ [OWL_PREDICATE_IMPORTS.id]: (template, term) => { template.owlImports.push(term as NamedNode) },
38
+ [SHACL_PREDICATE_CLASS.id]: (template, term) => {
39
39
  template.class = term as NamedNode
40
40
  // try to find node shape that has requested target class
41
- const nodeShapes = template.config.shapesGraph.getSubjects(SHACL_PREDICATE_TARGET_CLASS, term, null)
41
+ const nodeShapes = template.config.store.getSubjects(SHACL_PREDICATE_TARGET_CLASS, term, null)
42
42
  if (nodeShapes.length > 0) {
43
43
  template.node = nodeShapes[0] as NamedNode
44
44
  }
@@ -48,12 +48,20 @@ const mappers: Record<string, (template: ShaclPropertyTemplate, term: Term) => v
48
48
  if (list?.length) {
49
49
  template.shaclOr = list
50
50
  } else {
51
- console.error('list not found:', term.value, 'existing lists:', template.config.lists)
51
+ console.error('list for sh:or not found:', term.value, 'existing lists:', template.config.lists)
52
+ }
53
+ },
54
+ [`${PREFIX_SHACL}xone`]: (template, term) => {
55
+ const list = template.config.lists[term.value]
56
+ if (list?.length) {
57
+ template.shaclXone = list
58
+ } else {
59
+ console.error('list for sh:xone not found:', term.value, 'existing lists:', template.config.lists)
52
60
  }
53
61
  }
54
62
  }
55
63
 
56
- export class ShaclPropertyTemplate {
64
+ export class ShaclPropertyTemplate {
57
65
  parent: ShaclNode
58
66
  label = ''
59
67
  name: Literal | undefined
@@ -79,6 +87,7 @@ export class ShaclPropertyTemplate {
79
87
  shaclAnd: string | undefined
80
88
  shaclIn: string | undefined
81
89
  shaclOr: Term[] | undefined
90
+ shaclXone: Term[] | undefined
82
91
  languageIn: Term[] | undefined
83
92
  datatype: NamedNode | undefined
84
93
  hasValue: Term | undefined
@@ -86,14 +95,14 @@ export class ShaclPropertyTemplate {
86
95
  owlImports: NamedNode[] = []
87
96
 
88
97
  config: Config
89
- extendedShapes: NamedNode[] | undefined
98
+ extendedShapes: NamedNode[] = []
90
99
 
91
100
  constructor(quads: Quad[], parent: ShaclNode, config: Config) {
92
101
  this.parent = parent
93
102
  this.config = config
94
103
  this.merge(quads)
95
104
  if (this.qualifiedValueShape) {
96
- this.merge(config.shapesGraph.getQuads(this.qualifiedValueShape, null, null, null))
105
+ this.merge(config.store.getQuads(this.qualifiedValueShape, null, null, null))
97
106
  }
98
107
  }
99
108
 
@@ -108,7 +117,6 @@ export class ShaclPropertyTemplate {
108
117
  }
109
118
  // resolve extended shapes
110
119
  if (this.node || this.shaclAnd) {
111
- this.extendedShapes = []
112
120
  if (this.node) {
113
121
  this.extendedShapes.push(this.node)
114
122
  }
@@ -134,6 +142,9 @@ export class ShaclPropertyTemplate {
134
142
  if (this.shaclOr) {
135
143
  copy.shaclOr = [ ...this.shaclOr ]
136
144
  }
145
+ if (this.shaclXone) {
146
+ copy.shaclXone = [ ...this.shaclXone ]
147
+ }
137
148
  copy.merge = this.merge.bind(copy)
138
149
  copy.clone = this.clone.bind(copy)
139
150
  return copy