@ulb-darmstadt/shacl-form 1.8.0 → 1.8.1
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.
- package/README.md +7 -4
- package/dist/constants.d.ts +0 -2
- package/dist/form-bootstrap.js +55 -55
- package/dist/form-default.js +52 -52
- package/dist/form-material.js +91 -91
- package/dist/plugins/leaflet.js +8 -8
- package/dist/plugins/mapbox.js +18 -18
- package/dist/theme.d.ts +1 -1
- package/dist/util.d.ts +2 -2
- package/package.json +8 -6
- package/src/constants.ts +0 -2
- package/src/property.ts +2 -2
- package/src/theme.ts +1 -1
- package/src/themes/default.ts +30 -31
- package/src/themes/material.ts +29 -35
- package/src/util.ts +19 -11
- package/dist/node-template.d.ts +0 -17
- package/src/node-template.ts +0 -82
package/dist/theme.d.ts
CHANGED
package/dist/util.d.ts
CHANGED
|
@@ -6,8 +6,8 @@ export declare function findObjectValueByPredicate(quads: Quad[], predicate: str
|
|
|
6
6
|
export declare function findObjectByPredicate(quads: Quad[], predicate: string, prefix?: string, languages?: string[]): Term | undefined;
|
|
7
7
|
export declare function focusFirstInputElement(context: HTMLElement): void;
|
|
8
8
|
export declare function findLabel(quads: Quad[], languages: string[]): string;
|
|
9
|
-
export declare function createInputListEntries(subjects: Term[], shapesGraph: Store, languages: string[]
|
|
9
|
+
export declare function createInputListEntries(subjects: Term[], shapesGraph: Store, languages: string[]): InputListEntry[];
|
|
10
10
|
export declare function removePrefixes(id: string, prefixes: Prefixes): string;
|
|
11
|
-
export declare function findInstancesOf(clazz: NamedNode, template: ShaclPropertyTemplate
|
|
11
|
+
export declare function findInstancesOf(clazz: NamedNode, template: ShaclPropertyTemplate): InputListEntry[];
|
|
12
12
|
export declare function isURL(input: string): boolean;
|
|
13
13
|
export declare function prioritizeByLanguage(languages: string[], text1?: Literal, text2?: Literal): Literal | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ulb-darmstadt/shacl-form",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.1",
|
|
4
4
|
"description": "SHACL form generator",
|
|
5
5
|
"main": "dist/form-default.js",
|
|
6
6
|
"module": "dist/form-default.js",
|
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
".": {
|
|
11
11
|
"import": "./dist/form-default.js",
|
|
12
12
|
"types": "./dist/form-default.d.ts"
|
|
13
|
-
}
|
|
13
|
+
},
|
|
14
|
+
"./*.ts": "./src/*.ts",
|
|
15
|
+
"./plugins/*.ts": "./src/plugins/*.ts"
|
|
14
16
|
},
|
|
15
17
|
"files": [
|
|
16
18
|
"dist",
|
|
@@ -45,7 +47,7 @@
|
|
|
45
47
|
},
|
|
46
48
|
"devDependencies": {
|
|
47
49
|
"@types/jsonld": "^1.5.15",
|
|
48
|
-
"@types/leaflet": "^1.9.
|
|
50
|
+
"@types/leaflet": "^1.9.20",
|
|
49
51
|
"@types/leaflet-editable": "^1.2.6",
|
|
50
52
|
"@types/leaflet.fullscreen": "^3.0.2",
|
|
51
53
|
"@types/mapbox__mapbox-gl-draw": "^1.4.9",
|
|
@@ -53,8 +55,8 @@
|
|
|
53
55
|
"@types/uuid": "^10.0.0",
|
|
54
56
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
55
57
|
"typescript": "^5.8.3",
|
|
56
|
-
"vite": "^
|
|
57
|
-
"vite-plugin-dts": "^4.5.
|
|
58
|
+
"vite": "^7.0.4",
|
|
59
|
+
"vite-plugin-dts": "^4.5.4"
|
|
58
60
|
},
|
|
59
61
|
"dependencies": {
|
|
60
62
|
"@mapbox/mapbox-gl-draw": "^1.5.0",
|
|
@@ -69,7 +71,7 @@
|
|
|
69
71
|
"uuid": "^11.1.0"
|
|
70
72
|
},
|
|
71
73
|
"peerDependencies": {
|
|
72
|
-
"@ro-kit/ui-widgets": "^0.0.
|
|
74
|
+
"@ro-kit/ui-widgets": "^0.0.28",
|
|
73
75
|
"mdui": "^2.1.4"
|
|
74
76
|
}
|
|
75
77
|
}
|
package/src/constants.ts
CHANGED
|
@@ -17,9 +17,7 @@ export const DATA_GRAPH = DataFactory.namedNode('loaded-data')
|
|
|
17
17
|
export const RDF_PREDICATE_TYPE = DataFactory.namedNode(PREFIX_RDF + 'type')
|
|
18
18
|
export const DCTERMS_PREDICATE_CONFORMS_TO = DataFactory.namedNode(PREFIX_DCTERMS + 'conformsTo')
|
|
19
19
|
export const RDFS_PREDICATE_SUBCLASS_OF = DataFactory.namedNode(PREFIX_RDFS + 'subClassOf')
|
|
20
|
-
export const SKOS_PREDICATE_BROADER = DataFactory.namedNode(PREFIX_SKOS + 'broader')
|
|
21
20
|
export const OWL_PREDICATE_IMPORTS = DataFactory.namedNode(PREFIX_OWL + 'imports')
|
|
22
|
-
export const OWL_OBJECT_NAMED_INDIVIDUAL = DataFactory.namedNode(PREFIX_OWL + 'NamedIndividual')
|
|
23
21
|
export const SHACL_OBJECT_NODE_SHAPE = DataFactory.namedNode(PREFIX_SHACL + 'NodeShape')
|
|
24
22
|
export const SHACL_OBJECT_IRI = DataFactory.namedNode(PREFIX_SHACL + 'IRI')
|
|
25
23
|
export const SHACL_PREDICATE_PROPERTY = DataFactory.namedNode(PREFIX_SHACL + 'property')
|
package/src/property.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BlankNode, DataFactory, NamedNode, Quad, Store } from 'n3'
|
|
1
|
+
import { BlankNode, DataFactory, Literal, NamedNode, Quad, Store } from 'n3'
|
|
2
2
|
import { Term } from '@rdfjs/types'
|
|
3
3
|
import { ShaclNode } from './node'
|
|
4
4
|
import { createShaclOrConstraint, resolveShaclOrConstraintOnProperty } from './constraints'
|
|
@@ -103,7 +103,7 @@ export class ShaclProperty extends HTMLElement {
|
|
|
103
103
|
} else {
|
|
104
104
|
// check if value is part of the data graph. if not, create a linked resource
|
|
105
105
|
let linked = false
|
|
106
|
-
if (value) {
|
|
106
|
+
if (value && !(value instanceof Literal)) {
|
|
107
107
|
const clazz = this.getRdfClassToLinkOrCreate()
|
|
108
108
|
if (clazz && this.template.config.store.countQuads(value, RDF_PREDICATE_TYPE, clazz, DATA_GRAPH) === 0) {
|
|
109
109
|
// value is not in data graph, so must be a link in the shapes graph
|
package/src/theme.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { ShaclPropertyTemplate } from './property-template'
|
|
|
6
6
|
import css from './styles.css?raw'
|
|
7
7
|
|
|
8
8
|
export type Editor = HTMLElement & { value: string, type?: string, shaclDatatype?: NamedNode<string>, binaryData?: string, checked?: boolean, disabled?: boolean }
|
|
9
|
-
export type InputListEntry = { value: Term | string, label?: string,
|
|
9
|
+
export type InputListEntry = { value: Term | string, label?: string, children?: InputListEntry[] }
|
|
10
10
|
|
|
11
11
|
export abstract class Theme {
|
|
12
12
|
stylesheet: CSSStyleSheet
|
package/src/themes/default.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Term } from '@rdfjs/types'
|
|
2
2
|
import { ShaclPropertyTemplate } from "../property-template"
|
|
3
3
|
import { Editor, InputListEntry, Theme } from "../theme"
|
|
4
|
-
import { PREFIX_XSD } from '../constants'
|
|
5
|
-
import { Literal } from 'n3'
|
|
4
|
+
import { PREFIX_SHACL, PREFIX_XSD } from '../constants'
|
|
5
|
+
import { Literal, NamedNode } from 'n3'
|
|
6
6
|
import { Term as N3Term } from 'n3'
|
|
7
7
|
import css from './default.css?raw'
|
|
8
|
+
import { RokitSelect } from '@ro-kit/ui-widgets'
|
|
8
9
|
|
|
9
10
|
export class DefaultTheme extends Theme {
|
|
10
11
|
idCtr = 0
|
|
@@ -30,6 +31,8 @@ export class DefaultTheme extends Theme {
|
|
|
30
31
|
}
|
|
31
32
|
if (template?.nodeKind) {
|
|
32
33
|
editor.dataset.nodeKind = template.nodeKind.value
|
|
34
|
+
} else if (value instanceof NamedNode) {
|
|
35
|
+
editor.dataset.nodeKind = PREFIX_SHACL + 'IRI'
|
|
33
36
|
}
|
|
34
37
|
if (template?.hasValue || template?.readonly) {
|
|
35
38
|
editor.disabled = true
|
|
@@ -197,43 +200,39 @@ export class DefaultTheme extends Theme {
|
|
|
197
200
|
}
|
|
198
201
|
|
|
199
202
|
createListEditor(label: string, value: Term | null, required: boolean, listEntries: InputListEntry[], template?: ShaclPropertyTemplate): HTMLElement {
|
|
200
|
-
const editor =
|
|
203
|
+
const editor = new RokitSelect()
|
|
204
|
+
editor.dense = true
|
|
205
|
+
editor.clearable = true
|
|
206
|
+
editor.collapse = true
|
|
201
207
|
const result = this.createDefaultTemplate(label, null, required, editor, template)
|
|
202
|
-
|
|
208
|
+
const ul = document.createElement('ul')
|
|
203
209
|
|
|
204
|
-
|
|
205
|
-
const
|
|
206
|
-
let
|
|
207
|
-
if (typeof
|
|
208
|
-
|
|
210
|
+
const appendListEntry = (entry: InputListEntry, parent: HTMLUListElement) => {
|
|
211
|
+
const li = document.createElement('li')
|
|
212
|
+
let entryValue = ''
|
|
213
|
+
if (typeof entry.value === 'string') {
|
|
214
|
+
entryValue = entry.value
|
|
209
215
|
} else {
|
|
210
216
|
// this is needed for typed rdf literals
|
|
211
|
-
|
|
217
|
+
entryValue = (entry.value as N3Term).id
|
|
212
218
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
219
|
+
li.innerText = entry.label ? entry.label : entryValue
|
|
220
|
+
li.dataset.value = entryValue
|
|
221
|
+
parent.appendChild(li)
|
|
222
|
+
if (entry.children?.length) {
|
|
223
|
+
const ul = document.createElement('ul')
|
|
224
|
+
li.appendChild(ul)
|
|
225
|
+
for (const child of entry.children) {
|
|
226
|
+
appendListEntry(child, ul)
|
|
218
227
|
}
|
|
219
228
|
}
|
|
220
|
-
if (value && value.value === itemValue) {
|
|
221
|
-
option.selected = true
|
|
222
|
-
}
|
|
223
|
-
if (itemValue === '') {
|
|
224
|
-
addEmptyOption = false
|
|
225
|
-
}
|
|
226
|
-
editor.appendChild(option)
|
|
227
|
-
}
|
|
228
|
-
if (addEmptyOption) {
|
|
229
|
-
// add an empty element
|
|
230
|
-
const emptyOption = document.createElement('option')
|
|
231
|
-
emptyOption.value = ''
|
|
232
|
-
if (!value) {
|
|
233
|
-
emptyOption.selected = true
|
|
234
|
-
}
|
|
235
|
-
editor.prepend(emptyOption)
|
|
236
229
|
}
|
|
230
|
+
|
|
231
|
+
for (const item of listEntries) {
|
|
232
|
+
appendListEntry(item, ul)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
editor.appendChild(ul)
|
|
237
236
|
if (value) {
|
|
238
237
|
editor.value = value.value
|
|
239
238
|
}
|
package/src/themes/material.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { ShaclPropertyTemplate } from '../property-template'
|
|
2
2
|
import { Term } from '@rdfjs/types'
|
|
3
|
-
import { Button, TextField,
|
|
3
|
+
import { Button, TextField, Checkbox } from 'mdui'
|
|
4
4
|
import { Theme } from '../theme'
|
|
5
5
|
import { InputListEntry, Editor } from '../theme'
|
|
6
|
-
import { Literal } from 'n3'
|
|
6
|
+
import { Literal, NamedNode } from 'n3'
|
|
7
7
|
import { Term as N3Term } from 'n3'
|
|
8
8
|
import css from './material.css?raw'
|
|
9
|
-
import { PREFIX_XSD } from '../constants'
|
|
9
|
+
import { PREFIX_SHACL, PREFIX_XSD } from '../constants'
|
|
10
|
+
import { RokitSelect } from '@ro-kit/ui-widgets'
|
|
10
11
|
|
|
11
12
|
export class MaterialTheme extends Theme {
|
|
12
13
|
constructor() {
|
|
@@ -29,6 +30,8 @@ export class MaterialTheme extends Theme {
|
|
|
29
30
|
}
|
|
30
31
|
if (template?.nodeKind) {
|
|
31
32
|
editor.dataset.nodeKind = template.nodeKind.value
|
|
33
|
+
} else if (value instanceof NamedNode) {
|
|
34
|
+
editor.dataset.nodeKind = PREFIX_SHACL + 'IRI'
|
|
32
35
|
}
|
|
33
36
|
if (template?.hasValue || template?.readonly) {
|
|
34
37
|
editor.disabled = true
|
|
@@ -92,47 +95,38 @@ export class MaterialTheme extends Theme {
|
|
|
92
95
|
}
|
|
93
96
|
|
|
94
97
|
createListEditor(label: string, value: Term | null, required: boolean, listEntries: InputListEntry[], template?: ShaclPropertyTemplate): HTMLElement {
|
|
95
|
-
const editor = new
|
|
96
|
-
editor.
|
|
97
|
-
editor.label = label
|
|
98
|
-
editor.helper = template?.description?.value
|
|
98
|
+
const editor = new RokitSelect()
|
|
99
|
+
editor.dense = true
|
|
99
100
|
editor.clearable = true
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
let addEmptyOption = true
|
|
101
|
+
const result = this.createDefaultTemplate(label, null, required, editor, template)
|
|
102
|
+
const ul = document.createElement('ul')
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
let
|
|
107
|
-
if (typeof
|
|
108
|
-
|
|
104
|
+
const appendListEntry = (entry: InputListEntry, parent: HTMLUListElement) => {
|
|
105
|
+
const li = document.createElement('li')
|
|
106
|
+
let entryValue = ''
|
|
107
|
+
if (typeof entry.value === 'string') {
|
|
108
|
+
entryValue = entry.value
|
|
109
109
|
} else {
|
|
110
110
|
// this is needed for typed rdf literals
|
|
111
|
-
|
|
111
|
+
entryValue = (entry.value as N3Term).id
|
|
112
112
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
option.innerHTML = '  ' + option.innerHTML
|
|
113
|
+
li.innerText = entry.label ? entry.label : entryValue
|
|
114
|
+
li.dataset.value = entryValue
|
|
115
|
+
parent.appendChild(li)
|
|
116
|
+
if (entry.children?.length) {
|
|
117
|
+
const ul = document.createElement('ul')
|
|
118
|
+
li.appendChild(ul)
|
|
119
|
+
for (const child of entry.children) {
|
|
120
|
+
appendListEntry(child, ul)
|
|
122
121
|
}
|
|
123
122
|
}
|
|
124
|
-
if (itemValue === '') {
|
|
125
|
-
addEmptyOption = false
|
|
126
|
-
option.ariaLabel = 'blank'
|
|
127
|
-
}
|
|
128
|
-
editor.appendChild(option)
|
|
129
123
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
empty.ariaLabel = 'blank'
|
|
134
|
-
editor.prepend(empty)
|
|
124
|
+
|
|
125
|
+
for (const item of listEntries) {
|
|
126
|
+
appendListEntry(item, ul)
|
|
135
127
|
}
|
|
128
|
+
|
|
129
|
+
editor.appendChild(ul)
|
|
136
130
|
if (value) {
|
|
137
131
|
editor.value = value.value
|
|
138
132
|
}
|
package/src/util.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Literal, NamedNode, Prefixes, Quad, Store } from 'n3'
|
|
2
|
-
import { DATA_GRAPH,
|
|
2
|
+
import { DATA_GRAPH, PREFIX_FOAF, PREFIX_RDFS, PREFIX_SHACL, PREFIX_SKOS, RDFS_PREDICATE_SUBCLASS_OF, RDF_PREDICATE_TYPE, SHAPES_GRAPH } from './constants'
|
|
3
3
|
import { Term } from '@rdfjs/types'
|
|
4
4
|
import { InputListEntry } from './theme'
|
|
5
5
|
import { ShaclPropertyTemplate } from './property-template'
|
|
@@ -53,10 +53,10 @@ export function findLabel(quads: Quad[], languages: string[]): string {
|
|
|
53
53
|
findObjectValueByPredicate(quads, 'name', PREFIX_FOAF, languages)
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
export function createInputListEntries(subjects: Term[], shapesGraph: Store, languages: string[]
|
|
56
|
+
export function createInputListEntries(subjects: Term[], shapesGraph: Store, languages: string[]): InputListEntry[] {
|
|
57
57
|
const entries: InputListEntry[] = []
|
|
58
58
|
for (const subject of subjects) {
|
|
59
|
-
entries.push({ value: subject, label: findLabel(shapesGraph.getQuads(subject, null, null, null), languages),
|
|
59
|
+
entries.push({ value: subject, label: findLabel(shapesGraph.getQuads(subject, null, null, null), languages), children: [] })
|
|
60
60
|
}
|
|
61
61
|
return entries
|
|
62
62
|
}
|
|
@@ -82,7 +82,7 @@ function findClassInstancesFromOwlImports(clazz: NamedNode, context: ShaclNode |
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
export function findInstancesOf(clazz: NamedNode, template: ShaclPropertyTemplate
|
|
85
|
+
export function findInstancesOf(clazz: NamedNode, template: ShaclPropertyTemplate): InputListEntry[] {
|
|
86
86
|
let instances: Term[]
|
|
87
87
|
// if template has sh:in, then just use that as class instances
|
|
88
88
|
if (template.shaclIn) {
|
|
@@ -97,16 +97,24 @@ export function findInstancesOf(clazz: NamedNode, template: ShaclPropertyTemplat
|
|
|
97
97
|
findClassInstancesFromOwlImports(clazz, template, template.config.store, instances)
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
const entries = createInputListEntries(instances, template.config.store, template.config.languages
|
|
100
|
+
const entries = createInputListEntries(instances, template.config.store, template.config.languages)
|
|
101
101
|
// build inheritance tree only if sh:in is not defined
|
|
102
102
|
if (template.shaclIn === undefined) {
|
|
103
|
+
// find sub classes via rdfs:subClassOf
|
|
103
104
|
for (const subClass of template.config.store.getSubjects(RDFS_PREDICATE_SUBCLASS_OF, clazz, null)) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
const subClassIntances = findInstancesOf(subClass as NamedNode, template)
|
|
106
|
+
for (const subClassIntance of subClassIntances) {
|
|
107
|
+
let isChild = false
|
|
108
|
+
// check if found sub class also is an instance of its super class. if yes, add it to the children of the InputListEntry.
|
|
109
|
+
for (const entry of entries) {
|
|
110
|
+
if (template.config.store.countQuads(subClassIntance.value, RDF_PREDICATE_TYPE, entry.value, null) > 0) {
|
|
111
|
+
entry.children!.push(subClassIntance)
|
|
112
|
+
isChild = true
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (!isChild) {
|
|
116
|
+
entries.push(subClassIntance)
|
|
117
|
+
}
|
|
110
118
|
}
|
|
111
119
|
}
|
|
112
120
|
}
|
package/dist/node-template.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { BlankNode, NamedNode, Quad } from 'n3';
|
|
2
|
-
import { Config } from './config';
|
|
3
|
-
import { Term } from '@rdfjs/types';
|
|
4
|
-
export declare class ShaclNodeTemplate {
|
|
5
|
-
properties: (NamedNode | BlankNode)[];
|
|
6
|
-
node: NamedNode | undefined;
|
|
7
|
-
shaclAnd: string | undefined;
|
|
8
|
-
shaclOr: Term[] | undefined;
|
|
9
|
-
shaclXone: Term[] | undefined;
|
|
10
|
-
targetClass: NamedNode | undefined;
|
|
11
|
-
owlImports: NamedNode[];
|
|
12
|
-
config: Config;
|
|
13
|
-
extendedShapes: NamedNode[];
|
|
14
|
-
constructor(quads: Quad[], config: Config);
|
|
15
|
-
merge(quads: Quad[]): ShaclNodeTemplate;
|
|
16
|
-
clone(): ShaclNodeTemplate;
|
|
17
|
-
}
|
package/src/node-template.ts
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
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
|
-
}
|