@shaclmate/shacl-ast 4.0.72 → 4.0.73
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/dist/AbstractShapesGraph.d.ts +7 -43
- package/dist/AbstractShapesGraph.js +207 -283
- package/dist/ShapesGraph.d.ts +8 -16
- package/dist/ShapesGraph.js +5 -36
- package/dist/shacl-ast.shaclmate.d.ts +41 -70
- package/dist/shacl-ast.shaclmate.js +180 -742
- package/package.json +1 -2
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type PrefixMap from "@rdfjs/prefix-map/PrefixMap.js";
|
|
2
|
-
import TermMap from "@rdfjs/term-map";
|
|
3
2
|
import type { BlankNode, DatasetCore, NamedNode } from "@rdfjs/types";
|
|
4
|
-
import { type Resource
|
|
3
|
+
import { type Resource } from "@rdfx/resource";
|
|
5
4
|
import { Either } from "purify-ts";
|
|
6
5
|
import type * as generated from "./shacl-ast.shaclmate.js";
|
|
7
6
|
export declare abstract class AbstractShapesGraph<NodeShapeT extends generated.NodeShape, OntologyT extends generated.Ontology, PropertyGroupT extends generated.PropertyGroup, PropertyShapeT extends generated.PropertyShape> {
|
|
@@ -15,12 +14,7 @@ export declare abstract class AbstractShapesGraph<NodeShapeT extends generated.N
|
|
|
15
14
|
PropertyGroup: TypeFunctions<PropertyGroupT>;
|
|
16
15
|
PropertyShape: TypeFunctions<PropertyShapeT>;
|
|
17
16
|
};
|
|
18
|
-
constructor(
|
|
19
|
-
nodeShapesByIdentifier: IdentifierMap<NodeShapeT>;
|
|
20
|
-
ontologiesByIdentifier: IdentifierMap<OntologyT>;
|
|
21
|
-
propertyGroupsByIdentifier: IdentifierMap<PropertyGroupT>;
|
|
22
|
-
propertyShapesByIdentifier: IdentifierMap<PropertyShapeT>;
|
|
23
|
-
});
|
|
17
|
+
protected constructor();
|
|
24
18
|
get nodeShapes(): readonly NodeShapeT[];
|
|
25
19
|
get ontologies(): readonly OntologyT[];
|
|
26
20
|
get propertyGroups(): readonly PropertyGroupT[];
|
|
@@ -30,46 +24,16 @@ export declare abstract class AbstractShapesGraph<NodeShapeT extends generated.N
|
|
|
30
24
|
propertyGroup(identifier: BlankNode | NamedNode): Either<Error, PropertyGroupT>;
|
|
31
25
|
propertyShape(identifier: BlankNode | NamedNode): Either<Error, PropertyShapeT>;
|
|
32
26
|
shape(identifier: BlankNode | NamedNode): Either<Error, NodeShapeT | PropertyShapeT>;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
* Convert the shapes graph to an RDF string.
|
|
39
|
-
*
|
|
40
|
-
* If the format isn't specified, defaults to N-Triples.
|
|
41
|
-
*/
|
|
42
|
-
toString(options?: {
|
|
43
|
-
format?: "application/n-triples" | "application/n-quads";
|
|
44
|
-
}): string;
|
|
27
|
+
protected static _fromDataset<NodeShapeT extends generated.NodeShape, OntologyT extends generated.Ontology, PropertyGroupT extends generated.PropertyGroup, PropertyShapeT extends generated.PropertyShape, ShapesGraphT extends AbstractShapesGraph<NodeShapeT, OntologyT, PropertyGroupT, PropertyShapeT>>(dataset: DatasetCore, options: {
|
|
28
|
+
ignoreUndefinedShapes?: boolean;
|
|
29
|
+
prefixMap?: PrefixMap;
|
|
30
|
+
} | undefined, shapesGraph: ShapesGraphT): Either<Error, ShapesGraphT>;
|
|
31
|
+
protected static _fromShapes<NodeShapeT extends generated.NodeShape, OntologyT extends generated.Ontology, PropertyGroupT extends generated.PropertyGroup, PropertyShapeT extends generated.PropertyShape, ShapesGraphT extends AbstractShapesGraph<NodeShapeT, OntologyT, PropertyGroupT, PropertyShapeT>>(shapesGraph: ShapesGraphT, ...objects: readonly (NodeShapeT | OntologyT | PropertyGroupT | PropertyShapeT)[]): ShapesGraphT;
|
|
45
32
|
}
|
|
46
|
-
type IdentifierMap<T> = TermMap<BlankNode | NamedNode, T>;
|
|
47
33
|
type TypeFunctions<T> = {
|
|
48
34
|
fromRdfResource: (resource: Resource, options?: {
|
|
49
35
|
ignoreRdfType?: boolean;
|
|
50
36
|
}) => Either<Error, T>;
|
|
51
|
-
toRdfResource: (value: T, options?: {
|
|
52
|
-
resourceSet?: ResourceSet;
|
|
53
|
-
}) => Resource;
|
|
54
37
|
};
|
|
55
|
-
export declare namespace AbstractShapesGraph {
|
|
56
|
-
abstract class AbstractBuilder<NodeShapeT extends generated.NodeShape, OntologyT extends generated.Ontology, PropertyGroupT extends generated.PropertyGroup, PropertyShapeT extends generated.PropertyShape> {
|
|
57
|
-
protected readonly nodeShapesByIdentifier: IdentifierMap<NodeShapeT>;
|
|
58
|
-
protected readonly ontologiesByIdentifier: IdentifierMap<OntologyT>;
|
|
59
|
-
protected readonly propertyGroupsByIdentifier: IdentifierMap<PropertyGroupT>;
|
|
60
|
-
protected readonly propertyShapesByIdentifier: IdentifierMap<PropertyShapeT>;
|
|
61
|
-
protected abstract readonly typeFunctions: {
|
|
62
|
-
NodeShape: TypeFunctions<NodeShapeT>;
|
|
63
|
-
Ontology: TypeFunctions<OntologyT>;
|
|
64
|
-
PropertyGroup: TypeFunctions<PropertyGroupT>;
|
|
65
|
-
PropertyShape: TypeFunctions<PropertyShapeT>;
|
|
66
|
-
};
|
|
67
|
-
add(...objects: readonly (NodeShapeT | OntologyT | PropertyGroupT | PropertyShapeT)[]): this;
|
|
68
|
-
parseDataset(dataset: DatasetCore, options?: {
|
|
69
|
-
ignoreUndefinedShapes?: boolean;
|
|
70
|
-
prefixMap?: PrefixMap;
|
|
71
|
-
}): Either<Error, this>;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
38
|
export {};
|
|
75
39
|
//# sourceMappingURL=AbstractShapesGraph.d.ts.map
|
|
@@ -3,30 +3,15 @@ import TermMap from "@rdfjs/term-map";
|
|
|
3
3
|
import TermSet from "@rdfjs/term-set";
|
|
4
4
|
import dataFactory from "@rdfx/data-factory";
|
|
5
5
|
import { ResourceSet } from "@rdfx/resource";
|
|
6
|
-
import { NTriplesTerm } from "@rdfx/string";
|
|
7
6
|
import { owl, sh } from "@tpluscode/rdf-ns-builders";
|
|
8
7
|
import { Either, Left } from "purify-ts";
|
|
9
8
|
import { CurieFactory } from "./CurieFactory.js";
|
|
10
9
|
export class AbstractShapesGraph {
|
|
11
|
-
nodeShapesByIdentifier;
|
|
12
|
-
ontologiesByIdentifier;
|
|
13
|
-
propertyGroupsByIdentifier;
|
|
14
|
-
propertyShapesByIdentifier;
|
|
15
|
-
constructor(
|
|
16
|
-
// Defensive copies
|
|
17
|
-
this.nodeShapesByIdentifier = new TermMap([
|
|
18
|
-
...parameters.nodeShapesByIdentifier.entries(),
|
|
19
|
-
]);
|
|
20
|
-
this.ontologiesByIdentifier = new TermMap([
|
|
21
|
-
...parameters.ontologiesByIdentifier.entries(),
|
|
22
|
-
]);
|
|
23
|
-
this.propertyGroupsByIdentifier = new TermMap([
|
|
24
|
-
...parameters.propertyGroupsByIdentifier.entries(),
|
|
25
|
-
]);
|
|
26
|
-
this.propertyShapesByIdentifier = new TermMap([
|
|
27
|
-
...parameters.propertyShapesByIdentifier.entries(),
|
|
28
|
-
]);
|
|
29
|
-
}
|
|
10
|
+
nodeShapesByIdentifier = new TermMap();
|
|
11
|
+
ontologiesByIdentifier = new TermMap();
|
|
12
|
+
propertyGroupsByIdentifier = new TermMap();
|
|
13
|
+
propertyShapesByIdentifier = new TermMap();
|
|
14
|
+
constructor() { }
|
|
30
15
|
get nodeShapes() {
|
|
31
16
|
return [...this.nodeShapesByIdentifier.values()];
|
|
32
17
|
}
|
|
@@ -68,297 +53,236 @@ export class AbstractShapesGraph {
|
|
|
68
53
|
.alt(this.propertyShape(identifier))
|
|
69
54
|
.mapLeft(() => new Error(`no such shape ${identifier}`));
|
|
70
55
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
for (const nodeShape of this.nodeShapes) {
|
|
78
|
-
this.typeFunctions.NodeShape.toRdfResource(nodeShape, { resourceSet });
|
|
79
|
-
}
|
|
80
|
-
for (const ontology of this.ontologies) {
|
|
81
|
-
this.typeFunctions.Ontology.toRdfResource(ontology, { resourceSet });
|
|
82
|
-
}
|
|
83
|
-
for (const propertyGroup of this.propertyGroups) {
|
|
84
|
-
this.typeFunctions.PropertyGroup.toRdfResource(propertyGroup, {
|
|
85
|
-
resourceSet,
|
|
86
|
-
});
|
|
56
|
+
static _fromDataset(dataset, options, shapesGraph) {
|
|
57
|
+
function datasetHasMatch(subject, predicate, object, graph) {
|
|
58
|
+
for (const _ of dataset.match(subject, predicate, object, graph)) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
87
62
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
63
|
+
let curieDataset;
|
|
64
|
+
if (options?.prefixMap) {
|
|
65
|
+
const curieCache = new Map();
|
|
66
|
+
curieDataset = datasetFactory.dataset();
|
|
67
|
+
const curieFactory = new CurieFactory({
|
|
68
|
+
prefixMap: options.prefixMap,
|
|
91
69
|
});
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Convert the shapes graph to an RDF string.
|
|
97
|
-
*
|
|
98
|
-
* If the format isn't specified, defaults to N-Triples.
|
|
99
|
-
*/
|
|
100
|
-
toString(options) {
|
|
101
|
-
const format = options?.format ?? "application/n-triples";
|
|
102
|
-
const lines = [];
|
|
103
|
-
switch (format) {
|
|
104
|
-
case "application/n-quads": {
|
|
105
|
-
for (const quad of this.toDataset()) {
|
|
106
|
-
const graphString = quad.graph.termType === "DefaultGraph"
|
|
107
|
-
? ""
|
|
108
|
-
: ` ${NTriplesTerm.stringify(quad.graph)}`;
|
|
109
|
-
lines.push(`${NTriplesTerm.stringify(quad.subject)} ${NTriplesTerm.stringify(quad.predicate)} ${NTriplesTerm.stringify(quad.object)}${graphString} .\n`);
|
|
70
|
+
const termToCurie = (term) => {
|
|
71
|
+
if (term.termType !== "NamedNode") {
|
|
72
|
+
return term;
|
|
110
73
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
{
|
|
115
|
-
for (const quad of this.toDataset()) {
|
|
116
|
-
lines.push(`${NTriplesTerm.stringify(quad.subject)} ${NTriplesTerm.stringify(quad.predicate)} ${NTriplesTerm.stringify(quad.object)} .\n`);
|
|
117
|
-
}
|
|
74
|
+
const cachedCurie = curieCache.get(term.value);
|
|
75
|
+
if (cachedCurie) {
|
|
76
|
+
return cachedCurie;
|
|
118
77
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
switch (object.$type) {
|
|
133
|
-
case "NodeShape":
|
|
134
|
-
this.nodeShapesByIdentifier.set(object.$identifier(), object);
|
|
135
|
-
break;
|
|
136
|
-
case "Ontology":
|
|
137
|
-
this.ontologiesByIdentifier.set(object.$identifier(), object);
|
|
138
|
-
break;
|
|
139
|
-
case "PropertyGroup":
|
|
140
|
-
this.propertyGroupsByIdentifier.set(object.$identifier(), object);
|
|
141
|
-
break;
|
|
142
|
-
case "PropertyShape":
|
|
143
|
-
this.propertyShapesByIdentifier.set(object.$identifier(), object);
|
|
144
|
-
break;
|
|
78
|
+
const curie = curieFactory.create(term).extract() ?? term;
|
|
79
|
+
curieCache.set(term.value, curie);
|
|
80
|
+
return curie;
|
|
81
|
+
};
|
|
82
|
+
for (const quad of dataset) {
|
|
83
|
+
const curieObject = termToCurie(quad.object);
|
|
84
|
+
const curieSubject = termToCurie(quad.subject);
|
|
85
|
+
if (!Object.is(curieObject, quad.object) ||
|
|
86
|
+
!Object.is(curieSubject, quad.subject)) {
|
|
87
|
+
curieDataset.add(dataFactory.quad(curieSubject, quad.predicate, curieObject, quad.graph));
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
curieDataset.add(quad);
|
|
145
91
|
}
|
|
146
92
|
}
|
|
147
|
-
return this;
|
|
148
93
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
94
|
+
else {
|
|
95
|
+
curieDataset = dataset;
|
|
96
|
+
}
|
|
97
|
+
const curieResourceSet = new ResourceSet({
|
|
98
|
+
dataFactory,
|
|
99
|
+
dataset: curieDataset,
|
|
100
|
+
});
|
|
101
|
+
return Either.encase(() => {
|
|
102
|
+
function readGraph() {
|
|
103
|
+
const graphs = new TermSet();
|
|
104
|
+
for (const quad of dataset) {
|
|
105
|
+
graphs.add(quad.graph);
|
|
106
|
+
}
|
|
107
|
+
if (graphs.size !== 1) {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
const graph = [...graphs.values()][0];
|
|
111
|
+
switch (graph.termType) {
|
|
112
|
+
case "BlankNode":
|
|
113
|
+
case "DefaultGraph":
|
|
114
|
+
case "NamedNode":
|
|
115
|
+
return graph;
|
|
116
|
+
default:
|
|
117
|
+
throw new RangeError(`expected NamedNode or default graph, actual ${graph.termType}`);
|
|
153
118
|
}
|
|
154
|
-
return false;
|
|
155
119
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
const termToCurie = (term) => {
|
|
164
|
-
if (term.termType !== "NamedNode") {
|
|
165
|
-
return term;
|
|
166
|
-
}
|
|
167
|
-
const cachedCurie = curieCache.get(term.value);
|
|
168
|
-
if (cachedCurie) {
|
|
169
|
-
return cachedCurie;
|
|
170
|
-
}
|
|
171
|
-
const curie = curieFactory.create(term).extract() ?? term;
|
|
172
|
-
curieCache.set(term.value, curie);
|
|
173
|
-
return curie;
|
|
174
|
-
};
|
|
175
|
-
for (const quad of dataset) {
|
|
176
|
-
const curieObject = termToCurie(quad.object);
|
|
177
|
-
const curieSubject = termToCurie(quad.subject);
|
|
178
|
-
if (!Object.is(curieObject, quad.object) ||
|
|
179
|
-
!Object.is(curieSubject, quad.subject)) {
|
|
180
|
-
curieDataset.add(dataFactory.quad(curieSubject, quad.predicate, curieObject, quad.graph));
|
|
181
|
-
}
|
|
182
|
-
else {
|
|
183
|
-
curieDataset.add(quad);
|
|
184
|
-
}
|
|
120
|
+
const graph = readGraph();
|
|
121
|
+
// Read ontologies
|
|
122
|
+
for (const ontologyResource of curieResourceSet.instancesOf(owl.Ontology, {
|
|
123
|
+
graph,
|
|
124
|
+
})) {
|
|
125
|
+
if (shapesGraph.ontologiesByIdentifier.has(ontologyResource.identifier)) {
|
|
126
|
+
continue;
|
|
185
127
|
}
|
|
128
|
+
shapesGraph.typeFunctions.Ontology.fromRdfResource(ontologyResource, {
|
|
129
|
+
ignoreRdfType: true,
|
|
130
|
+
}).ifRight((ontology) => shapesGraph.ontologiesByIdentifier.set(ontology.$identifier(), ontology));
|
|
186
131
|
}
|
|
187
|
-
|
|
188
|
-
|
|
132
|
+
// Read property groups
|
|
133
|
+
for (const propertyGroupResource of curieResourceSet.instancesOf(sh.PropertyGroup, { graph })) {
|
|
134
|
+
if (propertyGroupResource.identifier.termType !== "NamedNode") {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (shapesGraph.propertyGroupsByIdentifier.has(propertyGroupResource.identifier)) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
shapesGraph.typeFunctions.PropertyGroup.fromRdfResource(curieResourceSet.resource(propertyGroupResource.identifier), { ignoreRdfType: true }).ifRight((propertyGroup) => shapesGraph.propertyGroupsByIdentifier.set(propertyGroup.$identifier(), propertyGroup));
|
|
189
141
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
}
|
|
203
|
-
const graph = [...graphs.values()][0];
|
|
204
|
-
switch (graph.termType) {
|
|
205
|
-
case "BlankNode":
|
|
206
|
-
case "DefaultGraph":
|
|
207
|
-
case "NamedNode":
|
|
208
|
-
return graph;
|
|
209
|
-
default:
|
|
210
|
-
throw new RangeError(`expected NamedNode or default graph, actual ${graph.termType}`);
|
|
211
|
-
}
|
|
142
|
+
// Read shapes
|
|
143
|
+
// Collect the shape identifiers in sets
|
|
144
|
+
const shapeNodeSet = new TermSet();
|
|
145
|
+
// Utility function for adding to the shapeNodeSet
|
|
146
|
+
function addShapeNode(shapeNode) {
|
|
147
|
+
switch (shapeNode.termType) {
|
|
148
|
+
case "BlankNode":
|
|
149
|
+
case "NamedNode":
|
|
150
|
+
shapeNodeSet.add(shapeNode);
|
|
151
|
+
return true;
|
|
152
|
+
default:
|
|
153
|
+
throw new RangeError(`unexpected shape node identifier term type: ${shapeNode.termType}`);
|
|
212
154
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
155
|
+
}
|
|
156
|
+
// Test each shape condition
|
|
157
|
+
// https://www.w3.org/TR/shacl/#shapes
|
|
158
|
+
// Subject is a SHACL instance of sh:NodeShape or sh:PropertyShape
|
|
159
|
+
for (const rdfType of [sh.NodeShape, sh.PropertyShape]) {
|
|
160
|
+
for (const resource of curieResourceSet.instancesOf(rdfType, {
|
|
216
161
|
graph,
|
|
217
162
|
})) {
|
|
218
|
-
|
|
219
|
-
continue;
|
|
220
|
-
}
|
|
221
|
-
this.typeFunctions.Ontology.fromRdfResource(ontologyResource, {
|
|
222
|
-
ignoreRdfType: true,
|
|
223
|
-
}).ifRight((ontology) => this.add(ontology));
|
|
163
|
+
addShapeNode(resource.identifier);
|
|
224
164
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
165
|
+
}
|
|
166
|
+
// Subject of a triple with sh:targetClass, sh:targetNode, sh:targetObjectsOf, or sh:targetSubjectsOf predicate
|
|
167
|
+
for (const predicate of [
|
|
168
|
+
sh.targetClass,
|
|
169
|
+
sh.targetNode,
|
|
170
|
+
sh.targetObjectsOf,
|
|
171
|
+
sh.targetSubjectsOf,
|
|
172
|
+
]) {
|
|
173
|
+
for (const quad of dataset.match(null, predicate, null, graph)) {
|
|
174
|
+
addShapeNode(quad.subject);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Subject of a triple that has a parameter as predicate
|
|
178
|
+
// https://www.w3.org/TR/shacl/#constraints
|
|
179
|
+
// https://www.w3.org/TR/shacl/#core-components
|
|
180
|
+
for (const predicate of [
|
|
181
|
+
sh.class,
|
|
182
|
+
sh.datatype,
|
|
183
|
+
sh.nodeKind,
|
|
184
|
+
sh.minCount,
|
|
185
|
+
sh.maxCount,
|
|
186
|
+
sh.minExclusive,
|
|
187
|
+
sh.minInclusive,
|
|
188
|
+
sh.maxExclusive,
|
|
189
|
+
sh.maxInclusive,
|
|
190
|
+
sh.minLength,
|
|
191
|
+
sh.maxLength,
|
|
192
|
+
sh.pattern,
|
|
193
|
+
sh.languageIn,
|
|
194
|
+
sh.uniqueLang,
|
|
195
|
+
sh.equals,
|
|
196
|
+
sh.disjoint,
|
|
197
|
+
sh.lessThan,
|
|
198
|
+
sh.lessThanOrEquals,
|
|
199
|
+
sh.not,
|
|
200
|
+
sh.and,
|
|
201
|
+
sh.or,
|
|
202
|
+
sh.xone,
|
|
203
|
+
sh.node,
|
|
204
|
+
sh.property,
|
|
205
|
+
sh.qualifiedValueShape,
|
|
206
|
+
sh.qualifiedMinCount,
|
|
207
|
+
sh.qualifiedMaxCount,
|
|
208
|
+
sh.closed,
|
|
209
|
+
sh.ignoredProperties,
|
|
210
|
+
sh.hasValue,
|
|
211
|
+
sh.in,
|
|
212
|
+
]) {
|
|
213
|
+
for (const quad of dataset.match(null, predicate, null, graph)) {
|
|
214
|
+
addShapeNode(quad.subject);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// Object of a shape-expecting, non-list-taking parameter such as sh:node
|
|
218
|
+
for (const predicate of [sh.node, sh.not, sh.property]) {
|
|
219
|
+
for (const quad of dataset.match(null, predicate, null, graph)) {
|
|
220
|
+
addShapeNode(quad.object);
|
|
221
|
+
if (!options?.ignoreUndefinedShapes &&
|
|
222
|
+
!datasetHasMatch(quad.object)) {
|
|
223
|
+
throw new Error(`undefined shape: ${quad.object}`);
|
|
232
224
|
}
|
|
233
|
-
this.typeFunctions.PropertyGroup.fromRdfResource(curieResourceSet.resource(propertyGroupResource.identifier), { ignoreRdfType: true }).ifRight((propertyGroup) => this.add(propertyGroup));
|
|
234
225
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
switch (shapeNode.termType) {
|
|
226
|
+
}
|
|
227
|
+
// Member of a SHACL list that is a value of a shape-expecting and list-taking parameter such as sh:or
|
|
228
|
+
for (const predicate of [sh.and, sh.or, sh.xone]) {
|
|
229
|
+
for (const quad of dataset.match(null, predicate, null, graph)) {
|
|
230
|
+
switch (quad.object.termType) {
|
|
241
231
|
case "BlankNode":
|
|
242
232
|
case "NamedNode":
|
|
243
|
-
|
|
244
|
-
return true;
|
|
233
|
+
break;
|
|
245
234
|
default:
|
|
246
|
-
throw new RangeError(`
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
// Test each shape condition
|
|
250
|
-
// https://www.w3.org/TR/shacl/#shapes
|
|
251
|
-
// Subject is a SHACL instance of sh:NodeShape or sh:PropertyShape
|
|
252
|
-
for (const rdfType of [sh.NodeShape, sh.PropertyShape]) {
|
|
253
|
-
for (const resource of curieResourceSet.instancesOf(rdfType, {
|
|
254
|
-
graph,
|
|
255
|
-
})) {
|
|
256
|
-
addShapeNode(resource.identifier);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
// Subject of a triple with sh:targetClass, sh:targetNode, sh:targetObjectsOf, or sh:targetSubjectsOf predicate
|
|
260
|
-
for (const predicate of [
|
|
261
|
-
sh.targetClass,
|
|
262
|
-
sh.targetNode,
|
|
263
|
-
sh.targetObjectsOf,
|
|
264
|
-
sh.targetSubjectsOf,
|
|
265
|
-
]) {
|
|
266
|
-
for (const quad of dataset.match(null, predicate, null, graph)) {
|
|
267
|
-
addShapeNode(quad.subject);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
// Subject of a triple that has a parameter as predicate
|
|
271
|
-
// https://www.w3.org/TR/shacl/#constraints
|
|
272
|
-
// https://www.w3.org/TR/shacl/#core-components
|
|
273
|
-
for (const predicate of [
|
|
274
|
-
sh.class,
|
|
275
|
-
sh.datatype,
|
|
276
|
-
sh.nodeKind,
|
|
277
|
-
sh.minCount,
|
|
278
|
-
sh.maxCount,
|
|
279
|
-
sh.minExclusive,
|
|
280
|
-
sh.minInclusive,
|
|
281
|
-
sh.maxExclusive,
|
|
282
|
-
sh.maxInclusive,
|
|
283
|
-
sh.minLength,
|
|
284
|
-
sh.maxLength,
|
|
285
|
-
sh.pattern,
|
|
286
|
-
sh.languageIn,
|
|
287
|
-
sh.uniqueLang,
|
|
288
|
-
sh.equals,
|
|
289
|
-
sh.disjoint,
|
|
290
|
-
sh.lessThan,
|
|
291
|
-
sh.lessThanOrEquals,
|
|
292
|
-
sh.not,
|
|
293
|
-
sh.and,
|
|
294
|
-
sh.or,
|
|
295
|
-
sh.xone,
|
|
296
|
-
sh.node,
|
|
297
|
-
sh.property,
|
|
298
|
-
sh.qualifiedValueShape,
|
|
299
|
-
sh.qualifiedMinCount,
|
|
300
|
-
sh.qualifiedMaxCount,
|
|
301
|
-
sh.closed,
|
|
302
|
-
sh.ignoredProperties,
|
|
303
|
-
sh.hasValue,
|
|
304
|
-
sh.in,
|
|
305
|
-
]) {
|
|
306
|
-
for (const quad of dataset.match(null, predicate, null, graph)) {
|
|
307
|
-
addShapeNode(quad.subject);
|
|
235
|
+
throw new RangeError(`expected list term to be a blank or named node, not ${quad.object.termType}`);
|
|
308
236
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
237
|
+
for (const value of curieResourceSet
|
|
238
|
+
.resource(quad.object)
|
|
239
|
+
.toList()
|
|
240
|
+
.unsafeCoerce()) {
|
|
241
|
+
const identifier = value.toIdentifier().unsafeCoerce();
|
|
242
|
+
addShapeNode(identifier);
|
|
314
243
|
if (!options?.ignoreUndefinedShapes &&
|
|
315
|
-
!datasetHasMatch(
|
|
316
|
-
throw new Error(`undefined shape: ${
|
|
244
|
+
!datasetHasMatch(identifier)) {
|
|
245
|
+
throw new Error(`undefined shape: ${identifier}`);
|
|
317
246
|
}
|
|
318
247
|
}
|
|
319
248
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
throw new RangeError(`expected list term to be a blank or named node, not ${quad.object.termType}`);
|
|
329
|
-
}
|
|
330
|
-
for (const value of curieResourceSet
|
|
331
|
-
.resource(quad.object)
|
|
332
|
-
.toList()
|
|
333
|
-
.unsafeCoerce()) {
|
|
334
|
-
const identifier = value.toIdentifier().unsafeCoerce();
|
|
335
|
-
addShapeNode(identifier);
|
|
336
|
-
if (!options?.ignoreUndefinedShapes &&
|
|
337
|
-
!datasetHasMatch(identifier)) {
|
|
338
|
-
throw new Error(`undefined shape: ${identifier}`);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
}
|
|
249
|
+
}
|
|
250
|
+
// Separate shapes into node and property shapes.
|
|
251
|
+
for (const shapeNode of shapeNodeSet) {
|
|
252
|
+
if (dataset.match(shapeNode, sh.path, null, graph).size > 0) {
|
|
253
|
+
// A property shape is a shape in the shapes graph that is the subject of a triple that has sh:path as its predicate. A shape has at most one value for sh:path. Each value of sh:path in a shape must be a well-formed SHACL property path. It is recommended, but not required, for a property shape to be declared as a SHACL instance of sh:PropertyShape. SHACL instances of sh:PropertyShape have one value for the property sh:path.
|
|
254
|
+
shapesGraph.propertyShapesByIdentifier.set(shapeNode, shapesGraph.typeFunctions.PropertyShape.fromRdfResource(curieResourceSet.resource(shapeNode), {
|
|
255
|
+
ignoreRdfType: true,
|
|
256
|
+
}).unsafeCoerce());
|
|
342
257
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
ignoreRdfType: true,
|
|
349
|
-
}).unsafeCoerce());
|
|
350
|
-
}
|
|
351
|
-
else {
|
|
352
|
-
// A node shape is a shape in the shapes graph that is not the subject of a triple with sh:path as its predicate. It is recommended, but not required, for a node shape to be declared as a SHACL instance of sh:NodeShape. SHACL instances of sh:NodeShape cannot have a value for the property sh:path.
|
|
353
|
-
this.add(this.typeFunctions.NodeShape.fromRdfResource(curieResourceSet.resource(shapeNode), {
|
|
354
|
-
ignoreRdfType: true,
|
|
355
|
-
}).unsafeCoerce());
|
|
356
|
-
}
|
|
258
|
+
else {
|
|
259
|
+
// A node shape is a shape in the shapes graph that is not the subject of a triple with sh:path as its predicate. It is recommended, but not required, for a node shape to be declared as a SHACL instance of sh:NodeShape. SHACL instances of sh:NodeShape cannot have a value for the property sh:path.
|
|
260
|
+
shapesGraph.nodeShapesByIdentifier.set(shapeNode, shapesGraph.typeFunctions.NodeShape.fromRdfResource(curieResourceSet.resource(shapeNode), {
|
|
261
|
+
ignoreRdfType: true,
|
|
262
|
+
}).unsafeCoerce());
|
|
357
263
|
}
|
|
358
|
-
|
|
359
|
-
|
|
264
|
+
}
|
|
265
|
+
return shapesGraph;
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
static _fromShapes(shapesGraph, ...objects) {
|
|
269
|
+
for (const object of objects) {
|
|
270
|
+
switch (object.$type) {
|
|
271
|
+
case "NodeShape":
|
|
272
|
+
shapesGraph.nodeShapesByIdentifier.set(object.$identifier(), object);
|
|
273
|
+
break;
|
|
274
|
+
case "Ontology":
|
|
275
|
+
shapesGraph.ontologiesByIdentifier.set(object.$identifier(), object);
|
|
276
|
+
break;
|
|
277
|
+
case "PropertyGroup":
|
|
278
|
+
shapesGraph.propertyGroupsByIdentifier.set(object.$identifier(), object);
|
|
279
|
+
break;
|
|
280
|
+
case "PropertyShape":
|
|
281
|
+
shapesGraph.propertyShapesByIdentifier.set(object.$identifier(), object);
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
360
284
|
}
|
|
285
|
+
return shapesGraph;
|
|
361
286
|
}
|
|
362
|
-
|
|
363
|
-
})(AbstractShapesGraph || (AbstractShapesGraph = {}));
|
|
287
|
+
}
|
|
364
288
|
//# sourceMappingURL=AbstractShapesGraph.js.map
|
package/dist/ShapesGraph.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type PrefixMap from "@rdfjs/prefix-map/PrefixMap.js";
|
|
2
|
+
import type { DatasetCore } from "@rdfjs/types";
|
|
3
|
+
import type { Either } from "purify-ts";
|
|
1
4
|
import { AbstractShapesGraph } from "./AbstractShapesGraph.js";
|
|
2
5
|
import * as generated from "./shacl-ast.shaclmate.js";
|
|
3
6
|
export declare class ShapesGraph extends AbstractShapesGraph<generated.NodeShape, generated.Ontology, generated.PropertyGroup, generated.PropertyShape> {
|
|
@@ -7,21 +10,10 @@ export declare class ShapesGraph extends AbstractShapesGraph<generated.NodeShape
|
|
|
7
10
|
readonly PropertyGroup: typeof generated.PropertyGroup;
|
|
8
11
|
readonly PropertyShape: typeof generated.PropertyShape;
|
|
9
12
|
};
|
|
10
|
-
static
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
readonly NodeShape: typeof generated.NodeShape;
|
|
16
|
-
readonly Ontology: typeof generated.Ontology;
|
|
17
|
-
readonly PropertyGroup: typeof generated.PropertyGroup;
|
|
18
|
-
readonly PropertyShape: typeof generated.PropertyShape;
|
|
19
|
-
};
|
|
20
|
-
build(): ShapesGraph;
|
|
21
|
-
nodeShape(parameters?: Parameters<typeof generated.NodeShape.createUnsafe>[0]): generated.NodeShape;
|
|
22
|
-
ontology(parameters?: Parameters<typeof generated.Ontology.createUnsafe>[0]): generated.Ontology;
|
|
23
|
-
propertyGroup(parameters?: Parameters<typeof generated.PropertyGroup.create>[0]): generated.PropertyGroup;
|
|
24
|
-
propertyShape(parameters: Parameters<typeof generated.PropertyShape.createUnsafe>[0]): generated.PropertyShape;
|
|
25
|
-
}
|
|
13
|
+
static fromDataset(dataset: DatasetCore, options?: {
|
|
14
|
+
ignoreUndefinedShapes?: boolean;
|
|
15
|
+
prefixMap?: PrefixMap;
|
|
16
|
+
}): Either<Error, ShapesGraph>;
|
|
17
|
+
static fromShapes(...objects: readonly (generated.NodeShape | generated.Ontology | generated.PropertyGroup | generated.PropertyShape)[]): ShapesGraph;
|
|
26
18
|
}
|
|
27
19
|
//# sourceMappingURL=ShapesGraph.d.ts.map
|