@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.
Files changed (55) hide show
  1. package/dist/Compiler.d.ts +4 -1
  2. package/dist/Compiler.js +3 -1
  3. package/dist/ShapesGraphToAstTransformer.d.ts +10 -2
  4. package/dist/ShapesGraphToAstTransformer.js +74 -3
  5. package/dist/_ShapesGraphToAstTransformer/ShapeStack.js +6 -5
  6. package/dist/_ShapesGraphToAstTransformer/nodeShapeIdentifierMintingStrategy.d.ts +3 -2
  7. package/dist/_ShapesGraphToAstTransformer/nodeShapeIdentifierMintingStrategy.js +17 -13
  8. package/dist/_ShapesGraphToAstTransformer/nodeShapeTsFeatures.js +2 -1
  9. package/dist/_ShapesGraphToAstTransformer/shapeAstTypeName.js +6 -6
  10. package/dist/_ShapesGraphToAstTransformer/shapeNodeKinds.d.ts +2 -1
  11. package/dist/_ShapesGraphToAstTransformer/shapeNodeKinds.js +37 -30
  12. package/dist/_ShapesGraphToAstTransformer/shapeOntology.d.ts +5 -0
  13. package/dist/_ShapesGraphToAstTransformer/shapeOntology.js +25 -0
  14. package/dist/_ShapesGraphToAstTransformer/transformPropertyShapeToAstObjectTypeProperty.js +23 -16
  15. package/dist/_ShapesGraphToAstTransformer/transformShapeToAstCompoundType.js +10 -6
  16. package/dist/_ShapesGraphToAstTransformer/transformShapeToAstListType.js +22 -22
  17. package/dist/_ShapesGraphToAstTransformer/transformShapeToAstObjectType.js +127 -118
  18. package/dist/_ShapesGraphToAstTransformer/transformShapeToAstTermType.js +10 -8
  19. package/dist/_ShapesGraphToAstTransformer/transformShapeToAstType.js +3 -3
  20. package/dist/ast/ObjectType.d.ts +3 -3
  21. package/dist/enums/IdentifierMintingStrategy.d.ts +4 -0
  22. package/dist/enums/IdentifierMintingStrategy.js +17 -1
  23. package/dist/enums/TsObjectDeclarationType.d.ts +4 -0
  24. package/dist/enums/TsObjectDeclarationType.js +15 -1
  25. package/dist/enums/Visibility.d.ts +6 -0
  26. package/dist/enums/Visibility.js +18 -0
  27. package/dist/generators/ts/AbstractCollectionType.js +1 -7
  28. package/dist/generators/ts/AbstractTermType.d.ts +1 -0
  29. package/dist/generators/ts/AbstractTermType.js +6 -0
  30. package/dist/generators/ts/AbstractUnionType.d.ts +31 -9
  31. package/dist/generators/ts/AbstractUnionType.js +252 -126
  32. package/dist/generators/ts/SetType.d.ts +1 -0
  33. package/dist/generators/ts/SetType.js +12 -0
  34. package/dist/generators/ts/_NamedObjectType/AbstractProperty.d.ts +3 -3
  35. package/dist/input/ShapesGraph.d.ts +39 -22
  36. package/dist/input/ShapesGraph.js +56 -60
  37. package/dist/input/generated.d.ts +389 -191
  38. package/dist/input/generated.js +2501 -829
  39. package/dist/input/index.d.ts +1 -5
  40. package/dist/input/index.js +1 -5
  41. package/package.json +2 -2
  42. package/dist/enums/PropertyVisibility.d.ts +0 -2
  43. package/dist/enums/PropertyVisibility.js +0 -2
  44. package/dist/input/NodeShape.d.ts +0 -49
  45. package/dist/input/NodeShape.js +0 -154
  46. package/dist/input/Ontology.d.ts +0 -13
  47. package/dist/input/Ontology.js +0 -40
  48. package/dist/input/PropertyShape.d.ts +0 -20
  49. package/dist/input/PropertyShape.js +0 -78
  50. package/dist/input/Shape.d.ts +0 -4
  51. package/dist/input/Shape.js +0 -2
  52. package/dist/input/ancestorClassIris.d.ts +0 -4
  53. package/dist/input/ancestorClassIris.js +0 -24
  54. package/dist/input/descendantClassIris.d.ts +0 -4
  55. package/dist/input/descendantClassIris.js +0 -27
@@ -35,6 +35,7 @@ const astListTypePlaceholderItemType = new ast.BlankNodeType({
35
35
  name: Maybe.empty(),
36
36
  shapeIdentifier: dataFactory.blankNode(),
37
37
  });
38
+ const empty = Either.of(Maybe.empty());
38
39
  /**
39
40
  * Is an ast.ObjectType actually the shape of an RDF list?
40
41
  * If so, return the type of its rdf:first.
@@ -42,14 +43,13 @@ const astListTypePlaceholderItemType = new ast.BlankNodeType({
42
43
  export function transformShapeToAstListType(shape, shapeStack) {
43
44
  shapeStack.push(shape);
44
45
  try {
45
- if (shape.kind !== "NodeShape") {
46
- return Either.of(Maybe.empty());
46
+ if (shape.$type !== "NodeShape") {
47
+ return empty;
47
48
  }
48
49
  const nodeShape = shape;
49
- if (!nodeShape.isList) {
50
- return Either.of(Maybe.empty());
51
- }
52
- return Eithers.chain3(nodeShapeIdentifierMintingStrategy(nodeShape), shapeNodeKinds(nodeShape, { defaultNodeShapeNodeKinds }), nodeShape.constraints.xone).chain(([identifierMintingStrategy, nodeKinds, xone]) => {
50
+ return Eithers.chain3(nodeShapeIdentifierMintingStrategy.call(this, nodeShape), shapeNodeKinds.call(this, nodeShape, { defaultNodeShapeNodeKinds }), Either.sequence(nodeShape.xone
51
+ .orDefault([])
52
+ .map((shapeIdentifier) => this.shapesGraph.shape(shapeIdentifier)))).chain(([identifierMintingStrategy, nodeKinds, xone]) => {
53
53
  // Put a placeholder in the cache to deal with cyclic references
54
54
  // Remove the placeholder if the transformation fails.
55
55
  const listType = new ast.ListType({
@@ -60,27 +60,27 @@ export function transformShapeToAstListType(shape, shapeStack) {
60
60
  mutable: nodeShape.mutable.orDefault(false),
61
61
  name: shapeAstTypeName(nodeShape),
62
62
  identifierMintingStrategy,
63
- shapeIdentifier: nodeShape.identifier,
63
+ shapeIdentifier: nodeShape.$identifier,
64
64
  toRdfTypes: nodeShape.toRdfTypes,
65
65
  });
66
- this.cachedAstTypesByShapeIdentifier.set(nodeShape.identifier, listType);
66
+ this.cachedAstTypesByShapeIdentifier.set(nodeShape.$identifier, listType);
67
67
  return (() => {
68
68
  let emptyListShape;
69
69
  let nonEmptyListShape;
70
70
  for (const shape of xone) {
71
- if (shape.constraints.hasValues.length === 1 &&
72
- shape.constraints.hasValues[0].equals(rdf.nil)) {
71
+ if (shape.hasValues.length === 1 &&
72
+ shape.hasValues[0].equals(rdf.nil)) {
73
73
  emptyListShape = shape;
74
74
  }
75
- else if (shape.kind === "NodeShape" &&
76
- shape.constraints.properties.orDefault([]).length >= 2) {
75
+ else if (shape.$type === "NodeShape" &&
76
+ shape.properties.length >= 2) {
77
77
  nonEmptyListShape = shape;
78
78
  }
79
79
  }
80
80
  if (!emptyListShape || !nonEmptyListShape) {
81
- return Left(new Error(`${nodeShape} does not have an sh:xone with exactly two shapes, one for the empty list and one for the non-empty list`));
81
+ return empty;
82
82
  }
83
- return nonEmptyListShape.constraints.properties.chain((nonEmptyListShapeProperties) => {
83
+ return Either.sequence(nonEmptyListShape.properties.map((propertyShapeIdentifier) => this.shapesGraph.propertyShape(propertyShapeIdentifier))).chain((nonEmptyListShapeProperties) => {
84
84
  let firstPropertyShape;
85
85
  let restPropertyShape;
86
86
  for (const propertyShape of nonEmptyListShapeProperties) {
@@ -95,17 +95,17 @@ export function transformShapeToAstListType(shape, shapeStack) {
95
95
  }
96
96
  }
97
97
  if (!firstPropertyShape) {
98
- return Left(new Error(`${nodeShape} has a non-empty list shape without an sh:property shape whose sh:path is rdf:first`));
98
+ return empty;
99
99
  }
100
- if (firstPropertyShape.constraints.maxCount.extract() !== 1 ||
101
- firstPropertyShape.constraints.minCount.extract() !== 1) {
100
+ if (firstPropertyShape.maxCount.extract() !== 1 ||
101
+ firstPropertyShape.minCount.extract() !== 1) {
102
102
  return Left(new Error(`${nodeShape} non-empty list shape rdf:first property shape does not have sh:maxCount=1 and/or sh:minCount=1`));
103
103
  }
104
104
  if (!restPropertyShape) {
105
- return Left(new Error(`${nodeShape} has a non-empty list shape without an sh:property shape whose sh:path is rdf:rest`));
105
+ return empty;
106
106
  }
107
- if (restPropertyShape.constraints.maxCount.extract() !== 1 ||
108
- restPropertyShape.constraints.minCount.extract() !== 1) {
107
+ if (restPropertyShape.maxCount.extract() !== 1 ||
108
+ restPropertyShape.minCount.extract() !== 1) {
109
109
  return Left(new Error(`${nodeShape} non-empty list shape rdf:rest property shape does not have sh:maxCount=1 and/or sh:minCount=1`));
110
110
  }
111
111
  return transformPropertyShapeToAstObjectTypeProperty
@@ -127,7 +127,7 @@ export function transformShapeToAstListType(shape, shapeStack) {
127
127
  })
128
128
  .chain((restProperty) => {
129
129
  if (restProperty.type.kind !== "ListType" ||
130
- !restProperty.type.shapeIdentifier.equals(nodeShape.identifier)) {
130
+ !restProperty.type.shapeIdentifier.equals(nodeShape.$identifier)) {
131
131
  return Left(new Error(`${nodeShape} rdf:rest property is not recursive into the node shape`));
132
132
  }
133
133
  return Either.of(Maybe.of(listType));
@@ -135,7 +135,7 @@ export function transformShapeToAstListType(shape, shapeStack) {
135
135
  });
136
136
  });
137
137
  })().ifLeft(() => {
138
- this.cachedAstTypesByShapeIdentifier.delete(nodeShape.identifier);
138
+ this.cachedAstTypesByShapeIdentifier.delete(nodeShape.$identifier);
139
139
  });
140
140
  });
141
141
  }
@@ -1,13 +1,16 @@
1
+ import { owl, rdfs } from "@tpluscode/rdf-ns-builders";
1
2
  import { Either, Left, Maybe } from "purify-ts";
2
3
  import { invariant } from "ts-invariant";
3
4
  import * as ast from "../ast/index.js";
4
5
  import { Eithers } from "../Eithers.js";
6
+ import { TsObjectDeclarationType } from "../enums/TsObjectDeclarationType.js";
5
7
  import { defaultNodeShapeNodeKinds } from "./defaultNodeShapeNodeKinds.js";
6
8
  import { nodeShapeIdentifierMintingStrategy } from "./nodeShapeIdentifierMintingStrategy.js";
7
9
  import { nodeShapeTsFeatures } from "./nodeShapeTsFeatures.js";
8
10
  import { ShapeStack } from "./ShapeStack.js";
9
11
  import { shapeAstTypeName } from "./shapeAstTypeName.js";
10
12
  import { shapeNodeKinds } from "./shapeNodeKinds.js";
13
+ import { shapeOntology } from "./shapeOntology.js";
11
14
  import { transformPropertyShapeToAstObjectTypeProperty } from "./transformPropertyShapeToAstObjectTypeProperty.js";
12
15
  import { transformShapeToAstType } from "./transformShapeToAstType.js";
13
16
  function isObjectTypePropertyRequired(property) {
@@ -43,135 +46,141 @@ function isObjectTypePropertyRequired(property) {
43
46
  export function transformShapeToAstObjectType(shape, shapeStack) {
44
47
  shapeStack.push(shape);
45
48
  try {
46
- if (shape.kind !== "NodeShape") {
49
+ if (shape.$type !== "NodeShape") {
47
50
  return Either.of(Maybe.empty());
48
51
  }
49
52
  const nodeShape = shape;
50
- if (nodeShape.identifier.termType !== "NamedNode") {
53
+ if (nodeShape.and.orDefault([]).length > 0 ||
54
+ nodeShape.xone.orDefault([]).length > 0) {
51
55
  return Either.of(Maybe.empty());
52
56
  }
53
- return Eithers.chain2(nodeShape.constraints.and, nodeShape.constraints.xone).chain(([andShapes, xoneShapes]) => {
54
- if (andShapes.length > 0 || xoneShapes.length > 0) {
55
- return Either.of(Maybe.empty());
56
- }
57
- return Eithers.chain9(nodeShape.ancestorNodeShapes, nodeShape.childNodeShapes, nodeShape.descendantNodeShapes, nodeShape.parentNodeShapes, nodeShapeIdentifierMintingStrategy(nodeShape), shapeNodeKinds(nodeShape, { defaultNodeShapeNodeKinds }), nodeShape.constraints.properties, nodeShapeTsFeatures.call(this, nodeShape), nodeShape.tsObjectDeclarationType.isJust()
58
- ? Either.of(nodeShape.tsObjectDeclarationType)
59
- : nodeShape.isDefinedBy.map((ontology) => ontology.chain((ontology) => ontology.tsObjectDeclarationType))).chain(([ancestorNodeShapes, childNodeShapes, descendantNodeShapes, parentNodeShapes, identifierMintingStrategy, nodeKinds, propertyShapes, tsFeatures, tsObjectDeclarationType,]) => {
60
- const abstract = nodeShape.abstract.orDefault(false);
61
- let fromRdfType;
62
- let toRdfTypes;
63
- if (!abstract) {
64
- fromRdfType = nodeShape.fromRdfType.alt(nodeShape.rdfType);
65
- if (nodeShape.isClass &&
66
- nodeShape.identifier.termType === "NamedNode") {
67
- fromRdfType = fromRdfType.alt(Maybe.of(nodeShape.identifier));
68
- }
69
- toRdfTypes = nodeShape.toRdfTypes.concat();
70
- if (toRdfTypes.length === 0) {
71
- toRdfTypes.push(...nodeShape.rdfType.toList());
72
- }
73
- // Ensure toRdfTypes has fromRdfType
74
- fromRdfType.ifJust((fromRdfType) => {
75
- if (!toRdfTypes.some((toRdfType) => toRdfType.equals(fromRdfType))) {
76
- toRdfTypes.push(fromRdfType);
77
- }
78
- });
79
- }
80
- else {
81
- fromRdfType = Maybe.empty();
82
- toRdfTypes = [];
83
- }
84
- if (nodeKinds.has("Literal")) {
85
- return Left(new Error(`${nodeShape} should not have a nodeKind "Literal"`));
57
+ if (nodeShape.$identifier.termType !== "NamedNode") {
58
+ return Either.of(Maybe.empty());
59
+ }
60
+ return Eithers.chain5(nodeShapeIdentifierMintingStrategy.call(this, nodeShape), shapeNodeKinds.call(this, nodeShape, { defaultNodeShapeNodeKinds }), Either.sequence(nodeShape.properties.map((propertyShapeIdentifier) => this.shapesGraph.propertyShape(propertyShapeIdentifier))), nodeShapeTsFeatures.call(this, nodeShape), nodeShape.tsObjectDeclarationType.isJust()
61
+ ? Either.of(nodeShape.tsObjectDeclarationType.map(TsObjectDeclarationType.fromIri))
62
+ : shapeOntology
63
+ .call(this, nodeShape)
64
+ .map((ontology) => ontology.chain((ontology) => ontology.tsObjectDeclarationType.map(TsObjectDeclarationType.fromIri)))).chain(([identifierMintingStrategy, nodeKinds, propertyShapes, tsFeatures, tsObjectDeclarationType,]) => {
65
+ const abstract = nodeShape.abstract.orDefault(false);
66
+ const { ancestors: ancestorNodeShapes, descendants: descendantNodeShapes, children: childNodeShapes, parents: parentNodeShapes, } = this.relatedNodeShapesByIdentifier.get(nodeShape.$identifier);
67
+ const isClass = nodeShape.subClassOf.length > 0 ||
68
+ descendantNodeShapes.length > 0 || // A node shape that is the object of an rdfs:subClassOf is itself an rdfs:Class
69
+ nodeShape.types.some((type) => type.equals(owl.Class) || type.equals(rdfs.Class));
70
+ let fromRdfType;
71
+ let toRdfTypes;
72
+ if (!abstract) {
73
+ fromRdfType = nodeShape.fromRdfType.alt(nodeShape.rdfType);
74
+ if (isClass && nodeShape.$identifier.termType === "NamedNode") {
75
+ fromRdfType = fromRdfType.alt(Maybe.of(nodeShape.$identifier));
86
76
  }
87
- let identifierType;
88
- const identifierTypeProperties = {
89
- comment: Maybe.empty(),
90
- label: Maybe.empty(),
91
- name: Maybe.empty(),
92
- shapeIdentifier: nodeShape.identifier,
93
- };
94
- if (nodeKinds.size === 2) {
95
- invariant(nodeShape.identifierIn.length === 0);
96
- identifierType = new ast.IdentifierType(identifierTypeProperties);
77
+ toRdfTypes = nodeShape.toRdfTypes.concat();
78
+ if (toRdfTypes.length === 0) {
79
+ toRdfTypes.push(...nodeShape.rdfType.toList());
97
80
  }
98
- else {
99
- switch ([...nodeKinds][0]) {
100
- case "BlankNode":
101
- invariant(nodeShape.identifierIn.length === 0);
102
- identifierType = new ast.BlankNodeType(identifierTypeProperties);
103
- break;
104
- case "IRI":
105
- identifierType = new ast.IriType({
106
- ...identifierTypeProperties,
107
- hasValues: [],
108
- in_: nodeShape.identifierIn,
109
- });
110
- break;
111
- case "Literal":
112
- throw new Error("should never happen");
81
+ // Ensure toRdfTypes has fromRdfType
82
+ fromRdfType.ifJust((fromRdfType) => {
83
+ if (!toRdfTypes.some((toRdfType) => toRdfType.equals(fromRdfType))) {
84
+ toRdfTypes.push(fromRdfType);
113
85
  }
114
- }
115
- invariant(identifierType);
116
- // Put a placeholder in the cache to deal with cyclic references
117
- // Remove the placeholder if the transformation fails.
118
- // If this node shape's properties (directly or indirectly) refer to the node shape itself,
119
- // we'll return this placeholder.
120
- const objectType = new ast.ObjectType({
121
- abstract,
122
- comment: nodeShape.comment,
123
- extern: nodeShape.extern.orDefault(false),
124
- fromRdfType,
125
- label: nodeShape.label,
126
- identifierType,
127
- identifierMintingStrategy,
128
- name: shapeAstTypeName(nodeShape),
129
- shapeIdentifier: nodeShape.identifier,
130
- synthetic: false,
131
- toRdfTypes,
132
- tsFeatures,
133
- tsImports: nodeShape.tsImports,
134
- tsObjectDeclarationType: tsObjectDeclarationType.orDefault("class"),
135
86
  });
136
- this.cachedAstTypesByShapeIdentifier.set(nodeShape.identifier, objectType);
137
- return (() => {
138
- // Populate ancestor and descendant object types
139
- const relatedObjectTypes = (relatedNodeShapes) => {
140
- return relatedNodeShapes
141
- .flatMap((relatedNodeShape) => transformShapeToAstType
142
- .call(this, relatedNodeShape, new ShapeStack())
143
- .toMaybe()
144
- .toList())
145
- .filter((astType) => astType.kind === "ObjectType");
146
- };
147
- objectType.addAncestorObjectTypes(...relatedObjectTypes(ancestorNodeShapes));
148
- objectType.addChildObjectTypes(...relatedObjectTypes(childNodeShapes));
149
- objectType.addDescendantObjectTypes(...relatedObjectTypes(descendantNodeShapes));
150
- objectType.addParentObjectTypes(...relatedObjectTypes(parentNodeShapes));
151
- // Populate properties
152
- for (const propertyShape of propertyShapes) {
153
- const propertyEither = transformPropertyShapeToAstObjectTypeProperty.call(this, {
154
- objectType,
155
- propertyShape,
156
- });
157
- if (propertyEither.isLeft()) {
158
- return propertyEither;
159
- }
160
- propertyEither.ifRight((property) => {
161
- objectType.addProperties(property);
87
+ }
88
+ else {
89
+ fromRdfType = Maybe.empty();
90
+ toRdfTypes = [];
91
+ }
92
+ if (nodeKinds.has("Literal")) {
93
+ return Left(new Error(`${nodeShape} should not have a nodeKind "Literal"`));
94
+ }
95
+ let identifierType;
96
+ const identifierTypeProperties = {
97
+ comment: Maybe.empty(),
98
+ label: Maybe.empty(),
99
+ name: Maybe.empty(),
100
+ shapeIdentifier: nodeShape.$identifier,
101
+ };
102
+ if (nodeKinds.size === 2) {
103
+ invariant(nodeShape.in_.isNothing());
104
+ identifierType = new ast.IdentifierType(identifierTypeProperties);
105
+ }
106
+ else {
107
+ switch ([...nodeKinds][0]) {
108
+ case "BlankNode":
109
+ invariant(nodeShape.in_.isNothing());
110
+ identifierType = new ast.BlankNodeType(identifierTypeProperties);
111
+ break;
112
+ case "IRI":
113
+ identifierType = new ast.IriType({
114
+ ...identifierTypeProperties,
115
+ hasValues: [],
116
+ in_: nodeShape.in_
117
+ .orDefault([])
118
+ .filter((_) => _.termType === "NamedNode"),
162
119
  });
120
+ break;
121
+ default:
122
+ throw new Error("should never happen");
123
+ }
124
+ }
125
+ invariant(identifierType);
126
+ // Put a placeholder in the cache to deal with cyclic references
127
+ // Remove the placeholder if the transformation fails.
128
+ // If this node shape's properties (directly or indirectly) refer to the node shape itself,
129
+ // we'll return this placeholder.
130
+ const objectType = new ast.ObjectType({
131
+ abstract,
132
+ comment: nodeShape.comment,
133
+ extern: nodeShape.extern.orDefault(false),
134
+ fromRdfType,
135
+ label: nodeShape.label,
136
+ identifierType,
137
+ identifierMintingStrategy,
138
+ name: shapeAstTypeName(nodeShape),
139
+ shapeIdentifier: nodeShape.$identifier,
140
+ synthetic: false,
141
+ toRdfTypes,
142
+ tsFeatures,
143
+ tsImports: nodeShape.tsImports,
144
+ tsObjectDeclarationType: tsObjectDeclarationType.orDefault("class"),
145
+ });
146
+ this.cachedAstTypesByShapeIdentifier.set(nodeShape.$identifier, objectType);
147
+ return (() => {
148
+ // Populate ancestor and descendant object types
149
+ const relatedObjectTypes = (relatedNodeShapes) => {
150
+ return relatedNodeShapes
151
+ .flatMap((relatedNodeShape) => transformShapeToAstType
152
+ .call(this, relatedNodeShape, new ShapeStack())
153
+ .toMaybe()
154
+ .toList())
155
+ .filter((astType) => astType.kind === "ObjectType");
156
+ };
157
+ objectType.addAncestorObjectTypes(...relatedObjectTypes(ancestorNodeShapes));
158
+ objectType.addChildObjectTypes(...relatedObjectTypes(childNodeShapes));
159
+ objectType.addDescendantObjectTypes(...relatedObjectTypes(descendantNodeShapes));
160
+ objectType.addParentObjectTypes(...relatedObjectTypes(parentNodeShapes));
161
+ // Populate properties
162
+ for (const propertyShape of propertyShapes) {
163
+ const propertyEither = transformPropertyShapeToAstObjectTypeProperty.call(this, {
164
+ objectType,
165
+ propertyShape,
166
+ });
167
+ if (propertyEither.isLeft()) {
168
+ return propertyEither;
163
169
  }
164
- if (!objectType.abstract &&
165
- !objectType.extern &&
166
- objectType.fromRdfType.isNothing() &&
167
- !objectType.properties.some(isObjectTypePropertyRequired)) {
168
- return Left(new Error(`${nodeShape} has no required properties and no implicitly required rdf:type`));
169
- }
170
- objectType.sortProperties();
171
- return Either.of(Maybe.of(objectType));
172
- })().ifLeft(() => {
173
- this.cachedAstTypesByShapeIdentifier.delete(nodeShape.identifier);
174
- });
170
+ propertyEither.ifRight((property) => {
171
+ objectType.addProperties(property);
172
+ });
173
+ }
174
+ if (!objectType.abstract &&
175
+ !objectType.extern &&
176
+ objectType.fromRdfType.isNothing() &&
177
+ !objectType.properties.some(isObjectTypePropertyRequired)) {
178
+ return Left(new Error(`${nodeShape} has no required properties and no implicitly required rdf:type`));
179
+ }
180
+ objectType.sortProperties();
181
+ return Either.of(Maybe.of(objectType));
182
+ })().ifLeft(() => {
183
+ this.cachedAstTypesByShapeIdentifier.delete(nodeShape.$identifier);
175
184
  });
176
185
  });
177
186
  }
@@ -8,14 +8,14 @@ import { shapeNodeKinds } from "./shapeNodeKinds.js";
8
8
  export function transformShapeToAstTermType(shape, shapeStack) {
9
9
  shapeStack.push(shape);
10
10
  try {
11
- return shapeNodeKinds(shape).chain((nodeKinds) => {
11
+ return shapeNodeKinds.call(this, shape).chain((nodeKinds) => {
12
12
  const hasValues = shapeStack.constraints.hasValues;
13
13
  const in_ = shapeStack.constraints.in_;
14
14
  const astAbstractTypeProperties = {
15
15
  comment: Maybe.empty(),
16
16
  name: Maybe.empty(),
17
17
  label: Maybe.empty(),
18
- shapeIdentifier: shape.identifier,
18
+ shapeIdentifier: shape.$identifier,
19
19
  };
20
20
  let termType;
21
21
  if (nodeKinds.size === 1) {
@@ -35,14 +35,16 @@ export function transformShapeToAstTermType(shape, shapeStack) {
35
35
  case "Literal":
36
36
  termType = new ast.LiteralType({
37
37
  ...astAbstractTypeProperties,
38
- datatype: shape.constraints.datatype,
38
+ datatype: shape.datatype,
39
39
  hasValues: hasValues.filter((_) => _.termType === "Literal"),
40
40
  in_: in_.filter((_) => _.termType === "Literal"),
41
- languageIn: [...new Set(shape.constraints.languageIn)],
42
- maxExclusive: shape.constraints.maxExclusive,
43
- maxInclusive: shape.constraints.maxInclusive,
44
- minExclusive: shape.constraints.minExclusive,
45
- minInclusive: shape.constraints.minInclusive,
41
+ languageIn: shape.languageIn
42
+ .map((languageIn) => [...new Set(languageIn)])
43
+ .orDefault([]),
44
+ maxExclusive: shape.maxExclusive,
45
+ maxInclusive: shape.maxInclusive,
46
+ minExclusive: shape.minExclusive,
47
+ minInclusive: shape.minInclusive,
46
48
  });
47
49
  break;
48
50
  }
@@ -13,7 +13,7 @@ const tryTransformShapeToAstTypeMethods = [
13
13
  * not the other transformShapeToAst*Type functions directly.
14
14
  */
15
15
  export function transformShapeToAstType(shape, shapeStack) {
16
- const astType = this.cachedAstTypesByShapeIdentifier.get(shape.identifier);
16
+ const astType = this.cachedAstTypesByShapeIdentifier.get(shape.$identifier);
17
17
  if (astType) {
18
18
  return Either.of(astType);
19
19
  }
@@ -28,14 +28,14 @@ export function transformShapeToAstType(shape, shapeStack) {
28
28
  }
29
29
  const astType = either.unsafeCoerce().extract();
30
30
  if (astType) {
31
- this.cachedAstTypesByShapeIdentifier.set(shape.identifier, astType);
31
+ this.cachedAstTypesByShapeIdentifier.set(shape.$identifier, astType);
32
32
  return Either.of(astType);
33
33
  }
34
34
  }
35
35
  return transformShapeToAstTermType
36
36
  .call(this, shape, shapeStack)
37
37
  .ifRight((astType) => {
38
- this.cachedAstTypesByShapeIdentifier.set(shape.identifier, astType);
38
+ this.cachedAstTypesByShapeIdentifier.set(shape.$identifier, astType);
39
39
  });
40
40
  }
41
41
  //# sourceMappingURL=transformShapeToAstType.js.map
@@ -3,9 +3,9 @@ import type { NodeKind } from "@shaclmate/shacl-ast";
3
3
  import type { Maybe } from "purify-ts";
4
4
  import { PropertyPath } from "rdfjs-resource";
5
5
  import type { IdentifierMintingStrategy } from "../enums/IdentifierMintingStrategy.js";
6
- import type { PropertyVisibility } from "../enums/PropertyVisibility.js";
7
6
  import type { TsFeature } from "../enums/TsFeature.js";
8
7
  import type { TsObjectDeclarationType } from "../enums/TsObjectDeclarationType.js";
8
+ import type { Visibility } from "../enums/Visibility.js";
9
9
  import { AbstractType } from "./AbstractType.js";
10
10
  import type { BlankNodeType } from "./BlankNodeType.js";
11
11
  import type { IdentifierType } from "./IdentifierType.js";
@@ -146,7 +146,7 @@ export declare namespace ObjectType {
146
146
  /**
147
147
  * Visibility: private, protected, public.
148
148
  */
149
- readonly visibility: PropertyVisibility;
149
+ readonly visibility: Visibility;
150
150
  constructor({ comment, description, label, mutable, name, objectType, order, path, shapeIdentifier, type, visibility, }: {
151
151
  comment: Maybe<string>;
152
152
  description: Maybe<string>;
@@ -158,7 +158,7 @@ export declare namespace ObjectType {
158
158
  path: PropertyPath;
159
159
  shapeIdentifier: BlankNode | NamedNode;
160
160
  type: Type;
161
- visibility: PropertyVisibility;
161
+ visibility: Visibility;
162
162
  });
163
163
  equals(other: Property): boolean;
164
164
  /**
@@ -1,5 +1,9 @@
1
+ import type { NamedNode } from "@rdfjs/types";
1
2
  /**
2
3
  * TypeScript enum corresponding to shaclmate:identifierMintingStrategy, for simpler manipulation.
3
4
  */
4
5
  export type IdentifierMintingStrategy = "blankNode" | "sha256" | "uuidv4";
6
+ export declare namespace IdentifierMintingStrategy {
7
+ function fromIri(iri: NamedNode<"http://purl.org/shaclmate/ontology#_IdentifierMintingStrategy_BlankNode" | "http://purl.org/shaclmate/ontology#_IdentifierMintingStrategy_SHA256" | "http://purl.org/shaclmate/ontology#_IdentifierMintingStrategy_UUIDv4">): IdentifierMintingStrategy;
8
+ }
5
9
  //# sourceMappingURL=IdentifierMintingStrategy.d.ts.map
@@ -1,2 +1,18 @@
1
- export {};
1
+ export var IdentifierMintingStrategy;
2
+ (function (IdentifierMintingStrategy) {
3
+ function fromIri(iri) {
4
+ switch (iri.value) {
5
+ case "http://purl.org/shaclmate/ontology#_IdentifierMintingStrategy_BlankNode":
6
+ return "blankNode";
7
+ case "http://purl.org/shaclmate/ontology#_IdentifierMintingStrategy_SHA256":
8
+ return "sha256";
9
+ case "http://purl.org/shaclmate/ontology#_IdentifierMintingStrategy_UUIDv4":
10
+ return "uuidv4";
11
+ default:
12
+ iri.value;
13
+ throw new RangeError(iri.value);
14
+ }
15
+ }
16
+ IdentifierMintingStrategy.fromIri = fromIri;
17
+ })(IdentifierMintingStrategy || (IdentifierMintingStrategy = {}));
2
18
  //# sourceMappingURL=IdentifierMintingStrategy.js.map
@@ -1,5 +1,9 @@
1
+ import type { NamedNode } from "@rdfjs/types";
1
2
  /**
2
3
  * TypeScript enum corresponding to shaclmate:tsObjectDeclarationType, for simpler manipulation.
3
4
  */
4
5
  export type TsObjectDeclarationType = "class" | "interface";
6
+ export declare namespace TsObjectDeclarationType {
7
+ function fromIri(iri: NamedNode<"http://purl.org/shaclmate/ontology#_TsObjectDeclarationType_Class" | "http://purl.org/shaclmate/ontology#_TsObjectDeclarationType_Interface">): TsObjectDeclarationType;
8
+ }
5
9
  //# sourceMappingURL=TsObjectDeclarationType.d.ts.map
@@ -1,2 +1,16 @@
1
- export {};
1
+ export var TsObjectDeclarationType;
2
+ (function (TsObjectDeclarationType) {
3
+ function fromIri(iri) {
4
+ switch (iri.value) {
5
+ case "http://purl.org/shaclmate/ontology#_TsObjectDeclarationType_Class":
6
+ return "class";
7
+ case "http://purl.org/shaclmate/ontology#_TsObjectDeclarationType_Interface":
8
+ return "interface";
9
+ default:
10
+ iri.value;
11
+ throw new RangeError(iri.value);
12
+ }
13
+ }
14
+ TsObjectDeclarationType.fromIri = fromIri;
15
+ })(TsObjectDeclarationType || (TsObjectDeclarationType = {}));
2
16
  //# sourceMappingURL=TsObjectDeclarationType.js.map
@@ -0,0 +1,6 @@
1
+ import type { NamedNode } from "@rdfjs/types";
2
+ export type Visibility = "private" | "protected" | "public";
3
+ export declare namespace Visibility {
4
+ function fromIri(iri: NamedNode<"http://purl.org/shaclmate/ontology#_Visibility_Private" | "http://purl.org/shaclmate/ontology#_Visibility_Protected" | "http://purl.org/shaclmate/ontology#_Visibility_Public">): Visibility;
5
+ }
6
+ //# sourceMappingURL=Visibility.d.ts.map
@@ -0,0 +1,18 @@
1
+ export var Visibility;
2
+ (function (Visibility) {
3
+ function fromIri(iri) {
4
+ switch (iri.value) {
5
+ case "http://purl.org/shaclmate/ontology#_Visibility_Private":
6
+ return "private";
7
+ case "http://purl.org/shaclmate/ontology#_Visibility_Protected":
8
+ return "protected";
9
+ case "http://purl.org/shaclmate/ontology#_Visibility_Public":
10
+ return "public";
11
+ default:
12
+ iri.value;
13
+ throw new RangeError(iri.value);
14
+ }
15
+ }
16
+ Visibility.fromIri = fromIri;
17
+ })(Visibility || (Visibility = {}));
18
+ //# sourceMappingURL=Visibility.js.map
@@ -55,12 +55,6 @@ export class AbstractCollectionType extends AbstractContainerType {
55
55
  }
56
56
  }
57
57
  if (this.minCount === 0) {
58
- conversions.push({
59
- conversionExpression: () => code `[]`,
60
- sourceTypeCheckExpression: (value) => code `${value} === undefined`,
61
- sourceTypeName: code `undefined`,
62
- sourceTypeof: "undefined",
63
- });
64
58
  if (Object.keys(itemTypeConversionsByTypeof).length <= 1) {
65
59
  // There were no additional conversions with different item typeof's, so we don't need to check .every or do .map
66
60
  // Just check that the original value is an array with typeof "object". Array.isArray() doesn't narrow types for some reason.
@@ -101,7 +95,7 @@ export class AbstractCollectionType extends AbstractContainerType {
101
95
  case "function":
102
96
  case "symbol":
103
97
  case "undefined":
104
- throw new Error("not implemented");
98
+ throw new Error(`source type check on ${itemTypeof} not implemented`);
105
99
  }
106
100
  },
107
101
  sourceTypeName: code `readonly (${itemTypeofConversion.sourceTypeName})[]`,
@@ -31,6 +31,7 @@ export declare abstract class AbstractTermType<ConstantTermT extends Literal | N
31
31
  get conversions(): readonly AbstractType.Conversion[];
32
32
  get discriminantProperty(): Maybe<AbstractType.DiscriminantProperty>;
33
33
  get schema(): Code;
34
+ get termTypes(): ReadonlySet<"BlankNode" | "Literal" | "NamedNode">;
34
35
  get valueSparqlConstructTriplesFunction(): Code;
35
36
  fromRdfResourceValuesExpression(parameters: Parameters<AbstractType["fromRdfResourceValuesExpression"]>[0]): Code;
36
37
  hashStatements({ variables, }: Parameters<AbstractType["hashStatements"]>[0]): readonly Code[];
@@ -90,6 +90,9 @@ export class AbstractTermType extends AbstractType {
90
90
  get schema() {
91
91
  return code `${removeUndefined(this.schemaObject)}`;
92
92
  }
93
+ get termTypes() {
94
+ return new Set([...this.nodeKinds].map(NodeKind.toTermType));
95
+ }
93
96
  get valueSparqlConstructTriplesFunction() {
94
97
  return code `((_: object) => [])`;
95
98
  }
@@ -164,6 +167,9 @@ __decorate([
164
167
  __decorate([
165
168
  Memoize()
166
169
  ], AbstractTermType.prototype, "schema", null);
170
+ __decorate([
171
+ Memoize()
172
+ ], AbstractTermType.prototype, "termTypes", null);
167
173
  __decorate([
168
174
  Memoize()
169
175
  ], AbstractTermType.prototype, "valueSparqlConstructTriplesFunction", null);