@shaclmate/compiler 4.0.13 → 4.0.15
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/Compiler.d.ts +4 -1
- package/dist/Compiler.js +3 -1
- package/dist/ShapesGraphToAstTransformer.d.ts +10 -2
- package/dist/ShapesGraphToAstTransformer.js +74 -3
- package/dist/_ShapesGraphToAstTransformer/ShapeStack.js +6 -5
- package/dist/_ShapesGraphToAstTransformer/nodeShapeIdentifierMintingStrategy.d.ts +3 -2
- package/dist/_ShapesGraphToAstTransformer/nodeShapeIdentifierMintingStrategy.js +17 -13
- package/dist/_ShapesGraphToAstTransformer/nodeShapeTsFeatures.js +2 -1
- package/dist/_ShapesGraphToAstTransformer/shapeAstTypeName.js +6 -6
- package/dist/_ShapesGraphToAstTransformer/shapeNodeKinds.d.ts +2 -1
- package/dist/_ShapesGraphToAstTransformer/shapeNodeKinds.js +37 -30
- package/dist/_ShapesGraphToAstTransformer/shapeOntology.d.ts +5 -0
- package/dist/_ShapesGraphToAstTransformer/shapeOntology.js +25 -0
- package/dist/_ShapesGraphToAstTransformer/transformPropertyShapeToAstObjectTypeProperty.js +23 -16
- package/dist/_ShapesGraphToAstTransformer/transformShapeToAstCompoundType.js +10 -6
- package/dist/_ShapesGraphToAstTransformer/transformShapeToAstListType.js +22 -22
- package/dist/_ShapesGraphToAstTransformer/transformShapeToAstObjectType.js +127 -118
- package/dist/_ShapesGraphToAstTransformer/transformShapeToAstTermType.js +10 -8
- package/dist/_ShapesGraphToAstTransformer/transformShapeToAstType.js +3 -3
- package/dist/ast/ObjectType.d.ts +3 -3
- package/dist/enums/IdentifierMintingStrategy.d.ts +4 -0
- package/dist/enums/IdentifierMintingStrategy.js +17 -1
- package/dist/enums/TsObjectDeclarationType.d.ts +4 -0
- package/dist/enums/TsObjectDeclarationType.js +15 -1
- package/dist/enums/Visibility.d.ts +6 -0
- package/dist/enums/Visibility.js +18 -0
- package/dist/generators/ts/AbstractCollectionType.js +1 -7
- package/dist/generators/ts/AbstractTermType.d.ts +1 -0
- package/dist/generators/ts/AbstractTermType.js +6 -0
- package/dist/generators/ts/AbstractUnionType.d.ts +31 -9
- package/dist/generators/ts/AbstractUnionType.js +252 -126
- package/dist/generators/ts/SetType.d.ts +1 -0
- package/dist/generators/ts/SetType.js +12 -0
- package/dist/generators/ts/_NamedObjectType/AbstractProperty.d.ts +3 -3
- package/dist/input/ShapesGraph.d.ts +39 -22
- package/dist/input/ShapesGraph.js +56 -60
- package/dist/input/generated.d.ts +389 -191
- package/dist/input/generated.js +2501 -829
- package/dist/input/index.d.ts +1 -5
- package/dist/input/index.js +1 -5
- package/package.json +2 -2
- package/dist/enums/PropertyVisibility.d.ts +0 -2
- package/dist/enums/PropertyVisibility.js +0 -2
- package/dist/input/NodeShape.d.ts +0 -49
- package/dist/input/NodeShape.js +0 -154
- package/dist/input/Ontology.d.ts +0 -13
- package/dist/input/Ontology.js +0 -40
- package/dist/input/PropertyShape.d.ts +0 -20
- package/dist/input/PropertyShape.js +0 -78
- package/dist/input/Shape.d.ts +0 -4
- package/dist/input/Shape.js +0 -2
- package/dist/input/ancestorClassIris.d.ts +0 -4
- package/dist/input/ancestorClassIris.js +0 -24
- package/dist/input/descendantClassIris.d.ts +0 -4
- package/dist/input/descendantClassIris.js +0 -27
package/dist/Compiler.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import type { Either } from "purify-ts";
|
|
2
|
+
import type { TsFeature } from "./enums/TsFeature.js";
|
|
2
3
|
import type { Generator } from "./generators/Generator.js";
|
|
3
4
|
import type { ShapesGraph } from "./input/ShapesGraph.js";
|
|
4
5
|
export declare class Compiler {
|
|
5
6
|
private readonly generator;
|
|
6
|
-
|
|
7
|
+
private readonly tsFeaturesDefault?;
|
|
8
|
+
constructor({ generator, }: {
|
|
7
9
|
generator: Generator;
|
|
10
|
+
tsFeaturesDefault?: ReadonlySet<TsFeature>;
|
|
8
11
|
});
|
|
9
12
|
compile(shapesGraph: ShapesGraph): Either<Error, string>;
|
|
10
13
|
}
|
package/dist/Compiler.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { ShapesGraphToAstTransformer } from "./ShapesGraphToAstTransformer.js";
|
|
2
2
|
export class Compiler {
|
|
3
3
|
generator;
|
|
4
|
-
|
|
4
|
+
tsFeaturesDefault;
|
|
5
|
+
constructor({ generator, }) {
|
|
5
6
|
this.generator = generator;
|
|
6
7
|
}
|
|
7
8
|
compile(shapesGraph) {
|
|
8
9
|
return new ShapesGraphToAstTransformer({
|
|
9
10
|
shapesGraph,
|
|
11
|
+
tsFeaturesDefault: this.tsFeaturesDefault,
|
|
10
12
|
})
|
|
11
13
|
.transform()
|
|
12
14
|
.map((ast) => this.generator.generate(ast));
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import TermMap from "@rdfjs/term-map";
|
|
2
|
-
import type
|
|
2
|
+
import type { BlankNode, NamedNode } from "@rdfjs/types";
|
|
3
3
|
import { Either } from "purify-ts";
|
|
4
4
|
import type * as ast from "./ast/index.js";
|
|
5
5
|
import type { TsFeature } from "./enums/TsFeature.js";
|
|
6
6
|
import type * as input from "./input/index.js";
|
|
7
|
+
interface RelatedNodeShapes {
|
|
8
|
+
readonly ancestors: input.NodeShape[];
|
|
9
|
+
readonly children: input.NodeShape[];
|
|
10
|
+
readonly parents: input.NodeShape[];
|
|
11
|
+
readonly descendants: input.NodeShape[];
|
|
12
|
+
}
|
|
7
13
|
export declare class ShapesGraphToAstTransformer {
|
|
8
|
-
protected readonly cachedAstTypesByShapeIdentifier: TermMap<
|
|
14
|
+
protected readonly cachedAstTypesByShapeIdentifier: TermMap<BlankNode | NamedNode, ast.Type>;
|
|
9
15
|
protected readonly shapesGraph: input.ShapesGraph;
|
|
16
|
+
protected readonly relatedNodeShapesByIdentifier: TermMap<BlankNode | NamedNode, RelatedNodeShapes>;
|
|
10
17
|
protected tsFeaturesDefault: ReadonlySet<TsFeature>;
|
|
11
18
|
constructor({ shapesGraph, tsFeaturesDefault, }: {
|
|
12
19
|
shapesGraph: input.ShapesGraph;
|
|
@@ -14,4 +21,5 @@ export declare class ShapesGraphToAstTransformer {
|
|
|
14
21
|
});
|
|
15
22
|
transform(): Either<Error, ast.Ast>;
|
|
16
23
|
}
|
|
24
|
+
export {};
|
|
17
25
|
//# sourceMappingURL=ShapesGraphToAstTransformer.d.ts.map
|
|
@@ -1,15 +1,86 @@
|
|
|
1
1
|
import TermMap from "@rdfjs/term-map";
|
|
2
2
|
import { dash } from "@tpluscode/rdf-ns-builders";
|
|
3
3
|
import { Either } from "purify-ts";
|
|
4
|
+
import { Resource } from "rdfjs-resource";
|
|
4
5
|
import { invariant } from "ts-invariant";
|
|
5
6
|
import { ShapeStack } from "./_ShapesGraphToAstTransformer/ShapeStack.js";
|
|
6
7
|
import { transformShapeToAstType } from "./_ShapesGraphToAstTransformer/transformShapeToAstType.js";
|
|
8
|
+
import { logger } from "./logger.js";
|
|
9
|
+
function relatedNodeShapes(shapesGraph) {
|
|
10
|
+
const immediateRelatedNodeShapes = new TermMap();
|
|
11
|
+
for (const childNodeShape of shapesGraph.nodeShapes) {
|
|
12
|
+
let childRelatedNodeShapes = immediateRelatedNodeShapes.get(childNodeShape.$identifier);
|
|
13
|
+
if (!childRelatedNodeShapes) {
|
|
14
|
+
childRelatedNodeShapes = {
|
|
15
|
+
children: new TermMap(),
|
|
16
|
+
parents: new TermMap(),
|
|
17
|
+
};
|
|
18
|
+
immediateRelatedNodeShapes.set(childNodeShape.$identifier, childRelatedNodeShapes);
|
|
19
|
+
}
|
|
20
|
+
for (const parentClassIdentifier of childNodeShape.subClassOf) {
|
|
21
|
+
shapesGraph
|
|
22
|
+
.nodeShape(parentClassIdentifier)
|
|
23
|
+
.ifLeft((error) => {
|
|
24
|
+
logger.error("%s is rdfs:subClassOf %s which is either missing or not a node shape: %s", childNodeShape, Resource.Identifier.toString(parentClassIdentifier), error.message);
|
|
25
|
+
})
|
|
26
|
+
.ifRight((parentNodeShape) => {
|
|
27
|
+
childRelatedNodeShapes.parents.set(parentNodeShape.$identifier, parentNodeShape);
|
|
28
|
+
let parentRelatedNodeShapes = immediateRelatedNodeShapes.get(parentNodeShape.$identifier);
|
|
29
|
+
if (!parentRelatedNodeShapes) {
|
|
30
|
+
parentRelatedNodeShapes = {
|
|
31
|
+
children: new TermMap(),
|
|
32
|
+
parents: new TermMap(),
|
|
33
|
+
};
|
|
34
|
+
immediateRelatedNodeShapes.set(parentNodeShape.$identifier, parentRelatedNodeShapes);
|
|
35
|
+
}
|
|
36
|
+
parentRelatedNodeShapes.children.set(childNodeShape.$identifier, childNodeShape);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const result = new TermMap();
|
|
41
|
+
for (const nodeShape of shapesGraph.nodeShapes) {
|
|
42
|
+
const { children: childNodeShapes, parents: parentNodeShapes } = immediateRelatedNodeShapes.get(nodeShape.$identifier);
|
|
43
|
+
const ancestorNodeShapes = new TermMap();
|
|
44
|
+
function recurseAncestorNodeShapes(nodeShape) {
|
|
45
|
+
for (const parentNodeShape of immediateRelatedNodeShapes
|
|
46
|
+
.get(nodeShape.$identifier)
|
|
47
|
+
.parents.values()) {
|
|
48
|
+
if (!ancestorNodeShapes.has(parentNodeShape.$identifier)) {
|
|
49
|
+
ancestorNodeShapes.set(parentNodeShape.$identifier, parentNodeShape);
|
|
50
|
+
recurseAncestorNodeShapes(parentNodeShape);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
recurseAncestorNodeShapes(nodeShape);
|
|
55
|
+
const descendantNodeShapes = new TermMap();
|
|
56
|
+
function recurseDescendantNodeShapes(nodeShape) {
|
|
57
|
+
for (const childNodeShape of immediateRelatedNodeShapes
|
|
58
|
+
.get(nodeShape.$identifier)
|
|
59
|
+
.children.values()) {
|
|
60
|
+
if (!descendantNodeShapes.has(childNodeShape.$identifier)) {
|
|
61
|
+
descendantNodeShapes.set(childNodeShape.$identifier, childNodeShape);
|
|
62
|
+
recurseDescendantNodeShapes(childNodeShape);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
recurseDescendantNodeShapes(nodeShape);
|
|
67
|
+
result.set(nodeShape.$identifier, {
|
|
68
|
+
ancestors: [...ancestorNodeShapes.values()],
|
|
69
|
+
children: [...childNodeShapes.values()],
|
|
70
|
+
descendants: [...descendantNodeShapes.values()],
|
|
71
|
+
parents: [...parentNodeShapes.values()],
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
7
76
|
export class ShapesGraphToAstTransformer {
|
|
8
77
|
// Members are protected so they're accessible to functions in other files
|
|
9
78
|
cachedAstTypesByShapeIdentifier = new TermMap();
|
|
10
79
|
shapesGraph;
|
|
80
|
+
relatedNodeShapesByIdentifier = new TermMap();
|
|
11
81
|
tsFeaturesDefault;
|
|
12
82
|
constructor({ shapesGraph, tsFeaturesDefault, }) {
|
|
83
|
+
this.relatedNodeShapesByIdentifier = relatedNodeShapes(shapesGraph);
|
|
13
84
|
this.shapesGraph = shapesGraph;
|
|
14
85
|
this.tsFeaturesDefault =
|
|
15
86
|
tsFeaturesDefault ??
|
|
@@ -21,10 +92,10 @@ export class ShapesGraphToAstTransformer {
|
|
|
21
92
|
const syntheticAstObjectTypesByName = {};
|
|
22
93
|
const astNamedUnionTypes = [];
|
|
23
94
|
for (const nodeShape of this.shapesGraph.nodeShapes) {
|
|
24
|
-
if (nodeShape
|
|
95
|
+
if (nodeShape.$identifier.termType !== "NamedNode") {
|
|
25
96
|
continue;
|
|
26
97
|
}
|
|
27
|
-
if (nodeShape
|
|
98
|
+
if (nodeShape.$identifier.value.startsWith(dash[""].value)) {
|
|
28
99
|
continue;
|
|
29
100
|
}
|
|
30
101
|
const nodeShapeAstTypeEither = transformShapeToAstType.call(this, nodeShape, new ShapeStack());
|
|
@@ -39,7 +110,7 @@ export class ShapesGraphToAstTransformer {
|
|
|
39
110
|
}
|
|
40
111
|
break;
|
|
41
112
|
case "ObjectType": {
|
|
42
|
-
invariant(nodeShapeAstType.name.isJust());
|
|
113
|
+
invariant(nodeShapeAstType.name.isJust(), `node shape missing name: ${nodeShapeAstType.shapeIdentifier}`);
|
|
43
114
|
astObjectTypes.push(nodeShapeAstType);
|
|
44
115
|
for (const property of nodeShapeAstType.properties) {
|
|
45
116
|
switch (property.type.kind) {
|
|
@@ -7,16 +7,17 @@ export class ShapeStack {
|
|
|
7
7
|
this.constraints = {
|
|
8
8
|
get hasValues() {
|
|
9
9
|
for (const shape of stack.toReversed()) {
|
|
10
|
-
if (shape.
|
|
11
|
-
return shape.
|
|
10
|
+
if (shape.hasValues.length > 0) {
|
|
11
|
+
return shape.hasValues;
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
return [];
|
|
15
15
|
},
|
|
16
16
|
get in_() {
|
|
17
17
|
for (const shape of stack.toReversed()) {
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
const shapeIn = shape.in_.orDefault([]);
|
|
19
|
+
if (shapeIn.length > 0) {
|
|
20
|
+
return shapeIn;
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
23
|
return [];
|
|
@@ -26,7 +27,7 @@ export class ShapeStack {
|
|
|
26
27
|
constraints;
|
|
27
28
|
get defaultValue() {
|
|
28
29
|
for (const shape of this.stack.toReversed()) {
|
|
29
|
-
if (shape
|
|
30
|
+
if (shape.$type !== "PropertyShape") {
|
|
30
31
|
continue;
|
|
31
32
|
}
|
|
32
33
|
if (shape.defaultValue.isJust()) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Either, Maybe } from "purify-ts";
|
|
2
|
-
import
|
|
2
|
+
import { IdentifierMintingStrategy } from "../enums/IdentifierMintingStrategy.js";
|
|
3
3
|
import type * as input from "../input/index.js";
|
|
4
|
-
|
|
4
|
+
import type { ShapesGraphToAstTransformer } from "../ShapesGraphToAstTransformer.js";
|
|
5
|
+
export declare function nodeShapeIdentifierMintingStrategy(this: ShapesGraphToAstTransformer, nodeShape: input.NodeShape): Either<Error, Maybe<IdentifierMintingStrategy>>;
|
|
5
6
|
//# sourceMappingURL=nodeShapeIdentifierMintingStrategy.d.ts.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Either, Left, Maybe } from "purify-ts";
|
|
2
|
+
import { IdentifierMintingStrategy } from "../enums/IdentifierMintingStrategy.js";
|
|
2
3
|
import { shapeNodeKinds } from "./shapeNodeKinds.js";
|
|
3
4
|
const defaultNodeShapeNodeKinds = new Set([
|
|
4
5
|
"BlankNode",
|
|
@@ -6,23 +7,26 @@ const defaultNodeShapeNodeKinds = new Set([
|
|
|
6
7
|
]);
|
|
7
8
|
export function nodeShapeIdentifierMintingStrategy(nodeShape) {
|
|
8
9
|
if (nodeShape.identifierMintingStrategy.isJust()) {
|
|
9
|
-
if (nodeShape.
|
|
10
|
+
if (nodeShape.in_.filter((_) => _.length > 0).isJust()) {
|
|
10
11
|
return Left(new Error(`${nodeShape} cannot have an identifier minting strategy and sh:in`));
|
|
11
12
|
}
|
|
12
|
-
return Either.of(nodeShape.identifierMintingStrategy);
|
|
13
|
+
return Either.of(nodeShape.identifierMintingStrategy.map(IdentifierMintingStrategy.fromIri));
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
// Recurse into parents
|
|
16
|
+
for (const parentNodeShape of this.relatedNodeShapesByIdentifier.get(nodeShape.$identifier).parents) {
|
|
17
|
+
const parentNodeShapeIdentifierMintingStrategy = nodeShapeIdentifierMintingStrategy.call(this, parentNodeShape);
|
|
18
|
+
if (parentNodeShapeIdentifierMintingStrategy.isRight() &&
|
|
19
|
+
parentNodeShapeIdentifierMintingStrategy.extract().isJust()) {
|
|
20
|
+
return parentNodeShapeIdentifierMintingStrategy;
|
|
19
21
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
}
|
|
23
|
+
return shapeNodeKinds
|
|
24
|
+
.call(this, nodeShape, { defaultNodeShapeNodeKinds })
|
|
25
|
+
.map((nodeKinds) => {
|
|
26
|
+
if (nodeKinds.has("BlankNode")) {
|
|
27
|
+
return Maybe.of("blankNode");
|
|
28
|
+
}
|
|
29
|
+
return Maybe.empty();
|
|
26
30
|
});
|
|
27
31
|
}
|
|
28
32
|
//# sourceMappingURL=nodeShapeIdentifierMintingStrategy.js.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Either } from "purify-ts";
|
|
2
2
|
import { TS_FEATURES } from "../enums/TsFeature.js";
|
|
3
|
+
import { shapeOntology } from "./shapeOntology.js";
|
|
3
4
|
export function nodeShapeTsFeatures(nodeShape) {
|
|
4
5
|
const tsFeaturesDefault = this.tsFeaturesDefault;
|
|
5
6
|
function iriToTsFeatures(iri) {
|
|
@@ -26,7 +27,7 @@ export function nodeShapeTsFeatures(nodeShape) {
|
|
|
26
27
|
return ["sparql"];
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
|
-
return nodeShape.
|
|
30
|
+
return shapeOntology.call(this, nodeShape).chain((ontologyMaybe) => {
|
|
30
31
|
let tsFeatureExcludes = nodeShape.tsFeatureExcludes.flatMap(iriToTsFeatures);
|
|
31
32
|
let tsFeatureIncludes = nodeShape.tsFeatureIncludes.flatMap(iriToTsFeatures);
|
|
32
33
|
if (tsFeatureExcludes.length === 0 && tsFeatureIncludes.length === 0) {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Curie } from "@shaclmate/shacl-ast";
|
|
2
2
|
import { Maybe } from "purify-ts";
|
|
3
3
|
export function shapeAstTypeName(shape) {
|
|
4
|
-
if (shape
|
|
4
|
+
if (shape.$type !== "NodeShape") {
|
|
5
5
|
return Maybe.empty();
|
|
6
6
|
}
|
|
7
|
-
if (shape
|
|
7
|
+
if (shape.$identifier.termType !== "NamedNode") {
|
|
8
8
|
return Maybe.empty();
|
|
9
9
|
}
|
|
10
10
|
// Explicit shaclmate:name
|
|
@@ -16,11 +16,11 @@ export function shapeAstTypeName(shape) {
|
|
|
16
16
|
return shape.label;
|
|
17
17
|
}
|
|
18
18
|
// CURIE shape identifier
|
|
19
|
-
if (shape
|
|
20
|
-
if (shape
|
|
21
|
-
return Maybe.of(shape
|
|
19
|
+
if (shape.$identifier instanceof Curie) {
|
|
20
|
+
if (shape.$identifier.hasUniqueReference) {
|
|
21
|
+
return Maybe.of(shape.$identifier.reference);
|
|
22
22
|
}
|
|
23
|
-
return Maybe.of(`${shape
|
|
23
|
+
return Maybe.of(`${shape.$identifier.prefix}_${shape.$identifier.reference}`);
|
|
24
24
|
}
|
|
25
25
|
return Maybe.empty();
|
|
26
26
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { NodeKind } from "@shaclmate/shacl-ast";
|
|
2
2
|
import { Either } from "purify-ts";
|
|
3
3
|
import type * as input from "../input/index.js";
|
|
4
|
-
|
|
4
|
+
import type { ShapesGraphToAstTransformer } from "../ShapesGraphToAstTransformer.js";
|
|
5
|
+
export declare function shapeNodeKinds(this: ShapesGraphToAstTransformer, shape: input.Shape, options?: {
|
|
5
6
|
defaultNodeShapeNodeKinds: ReadonlySet<NodeKind>;
|
|
6
7
|
defaultPropertyShapeNodeKinds?: ReadonlySet<NodeKind>;
|
|
7
8
|
}): Either<Error, ReadonlySet<NodeKind>>;
|
|
@@ -7,34 +7,39 @@ const defaultPropertyShapeNodeKinds = new Set([
|
|
|
7
7
|
"Literal",
|
|
8
8
|
]);
|
|
9
9
|
function nodeShapeNodeKinds(nodeShape) {
|
|
10
|
-
const thisNodeKinds = nodeShape.
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
const thisNodeKinds = nodeShape.nodeKind
|
|
11
|
+
.map(NodeKind.fromIri)
|
|
12
|
+
.orDefault(new Set());
|
|
13
|
+
// Recurse into parents
|
|
14
|
+
const parentNodeKinds = new Set();
|
|
15
|
+
for (const parentNodeShape of this.relatedNodeShapesByIdentifier.get(nodeShape.$identifier).parents) {
|
|
16
|
+
nodeShapeNodeKinds
|
|
17
|
+
.call(this, parentNodeShape)
|
|
18
|
+
.ifRight((parentNodeKinds_) => {
|
|
19
|
+
for (const parentNodeKind of parentNodeKinds_) {
|
|
15
20
|
parentNodeKinds.add(parentNodeKind);
|
|
16
21
|
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
if (parentNodeKinds.size > 0) {
|
|
25
|
+
if (thisNodeKinds.size === 0) {
|
|
26
|
+
return Either.of(parentNodeKinds);
|
|
17
27
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
// Check that thisNodeKinds doesn't conflict with parent node kinds
|
|
23
|
-
for (const thisNodeKind of thisNodeKinds) {
|
|
24
|
-
if (!parentNodeKinds.has(thisNodeKind)) {
|
|
25
|
-
return Left(new Error(`${nodeShape} has a nodeKind ${thisNodeKind} that is not in its parent's node kinds`));
|
|
26
|
-
}
|
|
28
|
+
// Check that thisNodeKinds doesn't conflict with parent node kinds
|
|
29
|
+
for (const thisNodeKind of thisNodeKinds) {
|
|
30
|
+
if (!parentNodeKinds.has(thisNodeKind)) {
|
|
31
|
+
return Left(new Error(`${nodeShape} has a nodeKind ${thisNodeKind} that is not in its parent's node kinds`));
|
|
27
32
|
}
|
|
28
33
|
}
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
}
|
|
35
|
+
return Either.of(thisNodeKinds);
|
|
31
36
|
}
|
|
32
37
|
function propertyShapeNodeKinds(propertyShape) {
|
|
33
|
-
return Either.of(propertyShape.
|
|
38
|
+
return Either.of(propertyShape.nodeKind.map(NodeKind.fromIri).orDefault(new Set()));
|
|
34
39
|
}
|
|
35
40
|
export function shapeNodeKinds(shape, options) {
|
|
36
|
-
return (shape
|
|
37
|
-
? nodeShapeNodeKinds(shape)
|
|
41
|
+
return (shape.$type === "NodeShape"
|
|
42
|
+
? nodeShapeNodeKinds.call(this, shape)
|
|
38
43
|
: propertyShapeNodeKinds(shape)).chain((explicitNodeKinds) => {
|
|
39
44
|
// Consider constraints that dictate certain node kinds, like sh:datatype dictates a Literal nodeKind.
|
|
40
45
|
const constraintExcludeNodeKinds = new Set();
|
|
@@ -42,14 +47,14 @@ export function shapeNodeKinds(shape, options) {
|
|
|
42
47
|
for (const [constraint, { excludeNodeKinds, includeNodeKinds }] of [
|
|
43
48
|
[
|
|
44
49
|
"sh:class",
|
|
45
|
-
shape.
|
|
50
|
+
shape.classes.length > 0
|
|
46
51
|
? { excludeNodeKinds: ["Literal"] }
|
|
47
52
|
: {},
|
|
48
53
|
],
|
|
49
54
|
[
|
|
50
55
|
"sh:datatype",
|
|
51
56
|
{
|
|
52
|
-
includeNodeKinds: shape.
|
|
57
|
+
includeNodeKinds: shape.datatype
|
|
53
58
|
.map(() => ["Literal"])
|
|
54
59
|
.orDefault([]),
|
|
55
60
|
},
|
|
@@ -57,7 +62,7 @@ export function shapeNodeKinds(shape, options) {
|
|
|
57
62
|
[
|
|
58
63
|
"sh:defaultValue",
|
|
59
64
|
{
|
|
60
|
-
includeNodeKinds: shape
|
|
65
|
+
includeNodeKinds: shape.$type === "PropertyShape"
|
|
61
66
|
? shape.defaultValue
|
|
62
67
|
.map((value) => NodeKind.fromTermType(value.termType))
|
|
63
68
|
.toList()
|
|
@@ -67,25 +72,27 @@ export function shapeNodeKinds(shape, options) {
|
|
|
67
72
|
[
|
|
68
73
|
"sh:hasValue",
|
|
69
74
|
{
|
|
70
|
-
includeNodeKinds: shape.
|
|
75
|
+
includeNodeKinds: shape.hasValues.map((value) => NodeKind.fromTermType(value.termType)),
|
|
71
76
|
},
|
|
72
77
|
],
|
|
73
78
|
[
|
|
74
79
|
"sh:in",
|
|
75
80
|
{
|
|
76
|
-
includeNodeKinds: shape.
|
|
81
|
+
includeNodeKinds: shape.in_
|
|
82
|
+
.orDefault([])
|
|
83
|
+
.map((in_) => NodeKind.fromTermType(in_.termType)),
|
|
77
84
|
},
|
|
78
85
|
],
|
|
79
86
|
[
|
|
80
87
|
"sh:languageIn",
|
|
81
|
-
shape.
|
|
88
|
+
shape.languageIn.orDefault([]).length > 0
|
|
82
89
|
? { includeNodeKinds: ["Literal"] }
|
|
83
90
|
: {},
|
|
84
91
|
],
|
|
85
92
|
[
|
|
86
93
|
"sh:maxExclusive",
|
|
87
94
|
{
|
|
88
|
-
includeNodeKinds: shape.
|
|
95
|
+
includeNodeKinds: shape.maxExclusive
|
|
89
96
|
.map(() => ["Literal"])
|
|
90
97
|
.orDefault([]),
|
|
91
98
|
},
|
|
@@ -93,7 +100,7 @@ export function shapeNodeKinds(shape, options) {
|
|
|
93
100
|
[
|
|
94
101
|
"sh:maxInclusive",
|
|
95
102
|
{
|
|
96
|
-
includeNodeKinds: shape.
|
|
103
|
+
includeNodeKinds: shape.maxInclusive
|
|
97
104
|
.map(() => ["Literal"])
|
|
98
105
|
.orDefault([]),
|
|
99
106
|
},
|
|
@@ -101,7 +108,7 @@ export function shapeNodeKinds(shape, options) {
|
|
|
101
108
|
[
|
|
102
109
|
"sh:minExclusive",
|
|
103
110
|
{
|
|
104
|
-
includeNodeKinds: shape.
|
|
111
|
+
includeNodeKinds: shape.minExclusive
|
|
105
112
|
.map(() => ["Literal"])
|
|
106
113
|
.orDefault([]),
|
|
107
114
|
},
|
|
@@ -109,7 +116,7 @@ export function shapeNodeKinds(shape, options) {
|
|
|
109
116
|
[
|
|
110
117
|
"sh:minInclusive",
|
|
111
118
|
{
|
|
112
|
-
includeNodeKinds: shape.
|
|
119
|
+
includeNodeKinds: shape.minInclusive
|
|
113
120
|
.map(() => ["Literal"])
|
|
114
121
|
.orDefault([]),
|
|
115
122
|
},
|
|
@@ -162,7 +169,7 @@ export function shapeNodeKinds(shape, options) {
|
|
|
162
169
|
if (constraintNodeKinds.size > 0) {
|
|
163
170
|
return Either.of(constraintNodeKinds);
|
|
164
171
|
}
|
|
165
|
-
if (shape
|
|
172
|
+
if (shape.$type === "NodeShape") {
|
|
166
173
|
return Either.of(options?.defaultNodeShapeNodeKinds ?? defaultNodeShapeNodeKinds);
|
|
167
174
|
}
|
|
168
175
|
if (shape.path.termType === "InversePath") {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Either, Maybe } from "purify-ts";
|
|
2
|
+
import type * as input from "../input/index.js";
|
|
3
|
+
import type { ShapesGraphToAstTransformer } from "../ShapesGraphToAstTransformer.js";
|
|
4
|
+
export declare function shapeOntology(this: ShapesGraphToAstTransformer, shape: input.Shape): Either<Error, Maybe<input.Ontology>>;
|
|
5
|
+
//# sourceMappingURL=shapeOntology.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Either, Maybe } from "purify-ts";
|
|
2
|
+
export function shapeOntology(shape) {
|
|
3
|
+
if (shape.isDefinedBy.isJust()) {
|
|
4
|
+
// If there's an rdfs:isDefinedBy statement on the shape then don't fall back to anything else
|
|
5
|
+
return this.shapesGraph
|
|
6
|
+
.ontology(shape.isDefinedBy.unsafeCoerce())
|
|
7
|
+
.map(Maybe.of);
|
|
8
|
+
}
|
|
9
|
+
// No rdfs:isDefinedBy statement on the shape
|
|
10
|
+
const ontologies = this.shapesGraph.ontologies;
|
|
11
|
+
if (ontologies.length === 1) {
|
|
12
|
+
// If there's a single ontology in the shapes graph, consider the shape a part of the ontology
|
|
13
|
+
return Either.of(Maybe.of(ontologies[0]));
|
|
14
|
+
}
|
|
15
|
+
if (shape.$identifier.termType === "NamedNode") {
|
|
16
|
+
const prefixOntologies = ontologies.filter((ontology) => ontology.$identifier.termType === "NamedNode" &&
|
|
17
|
+
shape.$identifier.value.startsWith(ontology.$identifier.value));
|
|
18
|
+
if (prefixOntologies.length === 1) {
|
|
19
|
+
// If there's a single ontology whose IRI is a prefix of this shape's IRI, consider the shape a part of the ontology
|
|
20
|
+
return Either.of(Maybe.of(prefixOntologies[0]));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return Either.of(Maybe.empty());
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=shapeOntology.js.map
|
|
@@ -4,6 +4,7 @@ import { Either, Left, Maybe } from "purify-ts";
|
|
|
4
4
|
import { invariant } from "ts-invariant";
|
|
5
5
|
import * as ast from "../ast/index.js";
|
|
6
6
|
import { Eithers } from "../Eithers.js";
|
|
7
|
+
import { Visibility } from "../enums/Visibility.js";
|
|
7
8
|
import { ShapeStack } from "./ShapeStack.js";
|
|
8
9
|
import { transformShapeToAstType } from "./transformShapeToAstType.js";
|
|
9
10
|
function synthesizePartialAstObjectType({ identifierType, tsFeatures, }) {
|
|
@@ -48,13 +49,13 @@ function propertyName(objectType, propertyShape) {
|
|
|
48
49
|
}
|
|
49
50
|
// Pick up the common pattern of a property shape identifier being the node shape's identifier -localName,
|
|
50
51
|
// like ex:NodeShape-property
|
|
51
|
-
if (propertyShape
|
|
52
|
+
if (propertyShape.$identifier.termType === "NamedNode" &&
|
|
52
53
|
objectType.shapeIdentifier.termType === "NamedNode") {
|
|
53
54
|
const propertyShapeIdentifierPrefix = `${objectType.shapeIdentifier.value}-`;
|
|
54
|
-
if (propertyShape
|
|
55
|
-
propertyShape
|
|
55
|
+
if (propertyShape.$identifier.value.startsWith(propertyShapeIdentifierPrefix) &&
|
|
56
|
+
propertyShape.$identifier.value.length >
|
|
56
57
|
propertyShapeIdentifierPrefix.length) {
|
|
57
|
-
return propertyShape
|
|
58
|
+
return propertyShape.$identifier.value.substring(propertyShapeIdentifierPrefix.length);
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
61
|
// sh:path CURIE reference
|
|
@@ -62,12 +63,12 @@ function propertyName(objectType, propertyShape) {
|
|
|
62
63
|
return propertyShape.path.reference;
|
|
63
64
|
}
|
|
64
65
|
// Shape identifier CURIE reference
|
|
65
|
-
if (propertyShape
|
|
66
|
-
return propertyShape
|
|
66
|
+
if (propertyShape.$identifier instanceof Curie) {
|
|
67
|
+
return propertyShape.$identifier.reference;
|
|
67
68
|
}
|
|
68
69
|
// Shape identifier IRI
|
|
69
|
-
if (propertyShape
|
|
70
|
-
return propertyShape
|
|
70
|
+
if (propertyShape.$identifier.termType === "NamedNode") {
|
|
71
|
+
return propertyShape.$identifier.value;
|
|
71
72
|
}
|
|
72
73
|
// sh:path IRI
|
|
73
74
|
if (propertyShape.path.termType === "NamedNode") {
|
|
@@ -84,13 +85,13 @@ function transformPropertyShapeToAstType(propertyShape, shapeStack) {
|
|
|
84
85
|
return transformShapeToAstType
|
|
85
86
|
.call(this, propertyShape, shapeStack)
|
|
86
87
|
.chain((propertyShapeAstType) => {
|
|
87
|
-
let maxCount = propertyShape.
|
|
88
|
-
let minCount = propertyShape.
|
|
88
|
+
let maxCount = propertyShape.maxCount.orDefault(Number.MAX_SAFE_INTEGER);
|
|
89
|
+
let minCount = propertyShape.minCount.orDefault(0);
|
|
89
90
|
if (minCount < 0) {
|
|
90
91
|
minCount = 0;
|
|
91
92
|
}
|
|
92
|
-
if (propertyShape.
|
|
93
|
-
minCount = propertyShape.
|
|
93
|
+
if (propertyShape.hasValues.length > minCount) {
|
|
94
|
+
minCount = propertyShape.hasValues.length;
|
|
94
95
|
}
|
|
95
96
|
if (maxCount < minCount) {
|
|
96
97
|
maxCount = minCount;
|
|
@@ -127,7 +128,11 @@ function transformPropertyShapeToAstType(propertyShape, shapeStack) {
|
|
|
127
128
|
}
|
|
128
129
|
export function transformPropertyShapeToAstObjectTypeProperty({ objectType, propertyShape, }) {
|
|
129
130
|
const shapeStack = new ShapeStack(); // Start a new ShapeStack per property shape
|
|
130
|
-
return Eithers.chain2(propertyShape.resolve
|
|
131
|
+
return Eithers.chain2(propertyShape.resolve.isJust()
|
|
132
|
+
? this.shapesGraph
|
|
133
|
+
.nodeShape(propertyShape.resolve.extract())
|
|
134
|
+
.map(Maybe.of)
|
|
135
|
+
: Either.of(Maybe.empty()), transformPropertyShapeToAstType.call(this, propertyShape, shapeStack)).chain(([propertyShapeResolve, astType]) => {
|
|
131
136
|
let astResolveItemType;
|
|
132
137
|
if (propertyShapeResolve.isJust()) {
|
|
133
138
|
const astResolveTypeEither = transformShapeToAstType
|
|
@@ -196,7 +201,7 @@ export function transformPropertyShapeToAstObjectTypeProperty({ objectType, prop
|
|
|
196
201
|
comment: Maybe.empty(),
|
|
197
202
|
label: Maybe.empty(),
|
|
198
203
|
name: Maybe.empty(),
|
|
199
|
-
shapeIdentifier: propertyShape
|
|
204
|
+
shapeIdentifier: propertyShape.$identifier,
|
|
200
205
|
};
|
|
201
206
|
switch (astType.kind) {
|
|
202
207
|
case "BlankNodeType":
|
|
@@ -253,9 +258,11 @@ export function transformPropertyShapeToAstObjectTypeProperty({ objectType, prop
|
|
|
253
258
|
objectType,
|
|
254
259
|
order: propertyShape.order.orDefault(0),
|
|
255
260
|
path: propertyShape.path,
|
|
256
|
-
shapeIdentifier: propertyShape
|
|
261
|
+
shapeIdentifier: propertyShape.$identifier,
|
|
257
262
|
type: astType,
|
|
258
|
-
visibility: propertyShape.visibility
|
|
263
|
+
visibility: propertyShape.visibility
|
|
264
|
+
.map(Visibility.fromIri)
|
|
265
|
+
.orDefault("public"),
|
|
259
266
|
}));
|
|
260
267
|
});
|
|
261
268
|
}
|
|
@@ -11,9 +11,13 @@ import { transformShapeToAstType } from "./transformShapeToAstType.js";
|
|
|
11
11
|
export function transformShapeToAstCompoundType(shape, shapeStack) {
|
|
12
12
|
shapeStack.push(shape);
|
|
13
13
|
try {
|
|
14
|
-
return Eithers.chain4(shape.
|
|
14
|
+
return Eithers.chain4(Either.sequence(shape.and
|
|
15
|
+
.orDefault([])
|
|
16
|
+
.map((shapeIdentifier) => this.shapesGraph.shape(shapeIdentifier))), Either.sequence(shape.nodes.map((nodeShapeIdentifier) => this.shapesGraph.nodeShape(nodeShapeIdentifier))), shape.$type === "NodeShape"
|
|
15
17
|
? nodeShapeTsFeatures.call(this, shape)
|
|
16
|
-
: Either.of(new Set()), shape.
|
|
18
|
+
: Either.of(new Set()), Either.sequence(shape.xone
|
|
19
|
+
.orDefault([])
|
|
20
|
+
.map((shapeIdentifier) => this.shapesGraph.shape(shapeIdentifier)))).chain(([andConstraintShapes, nodeConstraintShapes, tsFeatures, xoneConstraintShapes,]) => {
|
|
17
21
|
let compoundTypeKind;
|
|
18
22
|
// Distinguish constraints that take arbitrary shapes from those that only take node shapes
|
|
19
23
|
// With the latter we'll do special transformations.
|
|
@@ -41,7 +45,7 @@ export function transformShapeToAstCompoundType(shape, shapeStack) {
|
|
|
41
45
|
comment: shape.comment,
|
|
42
46
|
label: shape.label,
|
|
43
47
|
name: shapeAstTypeName(shape),
|
|
44
|
-
shapeIdentifier: shape
|
|
48
|
+
shapeIdentifier: shape.$identifier,
|
|
45
49
|
tsFeatures,
|
|
46
50
|
});
|
|
47
51
|
if (memberShapes.length === 1) {
|
|
@@ -50,7 +54,7 @@ export function transformShapeToAstCompoundType(shape, shapeStack) {
|
|
|
50
54
|
.map(Maybe.of);
|
|
51
55
|
}
|
|
52
56
|
// Put a placeholder in the cache to deal with cyclic references
|
|
53
|
-
this.cachedAstTypesByShapeIdentifier.set(shape
|
|
57
|
+
this.cachedAstTypesByShapeIdentifier.set(shape.$identifier, compoundType);
|
|
54
58
|
return Either.sequence(memberShapes.map((memberShape) => transformShapeToAstType.call(this, memberShape, shapeStack)))
|
|
55
59
|
.chain((memberShapeTypes) => {
|
|
56
60
|
for (let memberI = 0; memberI < memberShapes.length; memberI++) {
|
|
@@ -65,7 +69,7 @@ export function transformShapeToAstCompoundType(shape, shapeStack) {
|
|
|
65
69
|
}
|
|
66
70
|
let memberDiscriminantValue;
|
|
67
71
|
if (compoundTypeKind === "UnionType") {
|
|
68
|
-
if (memberShape
|
|
72
|
+
if (memberShape.$type === "NodeShape") {
|
|
69
73
|
memberDiscriminantValue =
|
|
70
74
|
memberShape.discriminantValue.extract();
|
|
71
75
|
}
|
|
@@ -84,7 +88,7 @@ export function transformShapeToAstCompoundType(shape, shapeStack) {
|
|
|
84
88
|
return Either.of(Maybe.of(compoundType));
|
|
85
89
|
})
|
|
86
90
|
.ifLeft(() => {
|
|
87
|
-
this.cachedAstTypesByShapeIdentifier.delete(shape
|
|
91
|
+
this.cachedAstTypesByShapeIdentifier.delete(shape.$identifier);
|
|
88
92
|
});
|
|
89
93
|
});
|
|
90
94
|
}
|