@shaclmate/compiler 2.0.20 → 2.0.23

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 (172) hide show
  1. package/dist/ShapesGraphToAstTransformer.d.ts +1 -0
  2. package/dist/ShapesGraphToAstTransformer.js +56 -12
  3. package/dist/_ShapesGraphToAstTransformer/flattenAstObjectCompositeTypeMemberTypes.d.ts +13 -0
  4. package/dist/_ShapesGraphToAstTransformer/flattenAstObjectCompositeTypeMemberTypes.js +51 -0
  5. package/dist/_ShapesGraphToAstTransformer/shapeAstName.js +53 -12
  6. package/dist/_ShapesGraphToAstTransformer/transformNodeShapeToAstType.d.ts +5 -0
  7. package/dist/_ShapesGraphToAstTransformer/transformNodeShapeToAstType.js +130 -54
  8. package/dist/_ShapesGraphToAstTransformer/transformPropertyShapeToAstCompositeType.d.ts +2 -3
  9. package/dist/_ShapesGraphToAstTransformer/transformPropertyShapeToAstCompositeType.js +122 -129
  10. package/dist/_ShapesGraphToAstTransformer/transformPropertyShapeToAstIdentifierType.d.ts +2 -2
  11. package/dist/_ShapesGraphToAstTransformer/transformPropertyShapeToAstLiteralType.d.ts +2 -2
  12. package/dist/_ShapesGraphToAstTransformer/transformPropertyShapeToAstObjectTypeProperty.js +127 -5
  13. package/dist/_ShapesGraphToAstTransformer/transformPropertyShapeToAstTermType.d.ts +3 -3
  14. package/dist/_ShapesGraphToAstTransformer/transformPropertyShapeToAstType.d.ts +2 -3
  15. package/dist/ast/Ast.d.ts +0 -1
  16. package/dist/ast/Curie.d.ts +14 -0
  17. package/dist/ast/Curie.js +21 -0
  18. package/dist/ast/IdentifierType.d.ts +3 -2
  19. package/dist/ast/ListType.d.ts +2 -1
  20. package/dist/ast/LiteralType.d.ts +1 -1
  21. package/dist/ast/Name.d.ts +40 -5
  22. package/dist/ast/ObjectCompositeType.d.ts +11 -0
  23. package/dist/ast/ObjectType.d.ts +18 -13
  24. package/dist/ast/ObjectUnionType.d.ts +0 -11
  25. package/dist/ast/OptionType.d.ts +2 -2
  26. package/dist/ast/SetType.d.ts +2 -2
  27. package/dist/ast/TermType.d.ts +12 -4
  28. package/dist/ast/Type.d.ts +1 -1
  29. package/dist/enums/TsFeature.d.ts +1 -4
  30. package/dist/enums/TsFeature.js +1 -15
  31. package/dist/generators/json/AstJsonGenerator.js +19 -3
  32. package/dist/generators/ts/BooleanType.d.ts +3 -1
  33. package/dist/generators/ts/BooleanType.js +11 -2
  34. package/dist/generators/ts/DateTimeType.d.ts +8 -7
  35. package/dist/generators/ts/DateTimeType.js +31 -7
  36. package/dist/generators/ts/DateType.d.ts +5 -2
  37. package/dist/generators/ts/DateType.js +15 -1
  38. package/dist/generators/ts/DeclaredType.d.ts +2 -2
  39. package/dist/generators/ts/DeclaredType.js +2 -2
  40. package/dist/generators/ts/FloatType.d.ts +6 -0
  41. package/dist/generators/ts/FloatType.js +18 -0
  42. package/dist/generators/ts/IdentifierType.d.ts +12 -7
  43. package/dist/generators/ts/IdentifierType.js +94 -6
  44. package/dist/generators/ts/Import.d.ts +2 -0
  45. package/dist/generators/ts/Import.js +10 -0
  46. package/dist/generators/ts/IntType.d.ts +6 -0
  47. package/dist/generators/ts/IntType.js +18 -0
  48. package/dist/generators/ts/ListType.d.ts +15 -12
  49. package/dist/generators/ts/ListType.js +98 -57
  50. package/dist/generators/ts/LiteralType.d.ts +10 -9
  51. package/dist/generators/ts/LiteralType.js +13 -2
  52. package/dist/generators/ts/NumberType.d.ts +2 -1
  53. package/dist/generators/ts/NumberType.js +7 -2
  54. package/dist/generators/ts/ObjectType.d.ts +66 -43
  55. package/dist/generators/ts/ObjectType.js +144 -123
  56. package/dist/generators/ts/ObjectUnionType.d.ts +49 -8
  57. package/dist/generators/ts/ObjectUnionType.js +290 -97
  58. package/dist/generators/ts/OptionType.d.ts +14 -10
  59. package/dist/generators/ts/OptionType.js +60 -34
  60. package/dist/generators/ts/PrimitiveType.d.ts +4 -4
  61. package/dist/generators/ts/PrimitiveType.js +18 -3
  62. package/dist/generators/ts/SetType.d.ts +16 -12
  63. package/dist/generators/ts/SetType.js +69 -40
  64. package/dist/generators/ts/SnippetDeclarations.d.ts +13 -8
  65. package/dist/generators/ts/SnippetDeclarations.js +215 -101
  66. package/dist/generators/ts/StringType.d.ts +3 -1
  67. package/dist/generators/ts/StringType.js +14 -2
  68. package/dist/generators/ts/TermType.d.ts +22 -14
  69. package/dist/generators/ts/TermType.js +53 -25
  70. package/dist/generators/ts/TsGenerator.d.ts +2 -1
  71. package/dist/generators/ts/TsGenerator.js +23 -12
  72. package/dist/generators/ts/Type.d.ts +89 -31
  73. package/dist/generators/ts/Type.js +57 -54
  74. package/dist/generators/ts/TypeFactory.d.ts +4 -5
  75. package/dist/generators/ts/TypeFactory.js +290 -226
  76. package/dist/generators/ts/UnionType.d.ts +14 -10
  77. package/dist/generators/ts/UnionType.js +319 -142
  78. package/dist/generators/ts/_ObjectType/EagerShaclProperty.d.ts +12 -0
  79. package/dist/generators/ts/_ObjectType/EagerShaclProperty.js +30 -0
  80. package/dist/generators/ts/_ObjectType/IdentifierPrefixProperty.d.ts +13 -12
  81. package/dist/generators/ts/_ObjectType/IdentifierPrefixProperty.js +46 -47
  82. package/dist/generators/ts/_ObjectType/IdentifierProperty.d.ts +20 -13
  83. package/dist/generators/ts/_ObjectType/IdentifierProperty.js +152 -124
  84. package/dist/generators/ts/_ObjectType/LazyShaclProperty.d.ts +87 -0
  85. package/dist/generators/ts/_ObjectType/LazyShaclProperty.js +237 -0
  86. package/dist/generators/ts/_ObjectType/Property.d.ts +39 -44
  87. package/dist/generators/ts/_ObjectType/Property.js +1 -10
  88. package/dist/generators/ts/_ObjectType/ShaclProperty.d.ts +25 -30
  89. package/dist/generators/ts/_ObjectType/ShaclProperty.js +108 -85
  90. package/dist/generators/ts/_ObjectType/TypeDiscriminatorProperty.d.ts +21 -17
  91. package/dist/generators/ts/_ObjectType/TypeDiscriminatorProperty.js +61 -53
  92. package/dist/generators/ts/_ObjectType/classDeclaration.js +6 -5
  93. package/dist/generators/ts/_ObjectType/createFunctionDeclaration.js +5 -4
  94. package/dist/generators/ts/_ObjectType/equalsFunctionOrMethodDeclaration.js +5 -4
  95. package/dist/generators/ts/_ObjectType/fromRdfTypeVariableStatement.d.ts +1 -1
  96. package/dist/generators/ts/_ObjectType/fromRdfTypeVariableStatement.js +8 -5
  97. package/dist/generators/ts/_ObjectType/graphqlTypeVariableStatement.d.ts +5 -0
  98. package/dist/generators/ts/_ObjectType/graphqlTypeVariableStatement.js +37 -0
  99. package/dist/generators/ts/_ObjectType/hashFunctionOrMethodDeclarations.js +7 -8
  100. package/dist/generators/ts/_ObjectType/identifierTypeDeclarations.d.ts +7 -0
  101. package/dist/generators/ts/_ObjectType/identifierTypeDeclarations.js +54 -0
  102. package/dist/generators/ts/_ObjectType/index.d.ts +9 -7
  103. package/dist/generators/ts/_ObjectType/index.js +9 -7
  104. package/dist/generators/ts/_ObjectType/interfaceDeclaration.js +1 -1
  105. package/dist/generators/ts/_ObjectType/jsonFunctionDeclarations.d.ts +4 -0
  106. package/dist/generators/ts/_ObjectType/jsonFunctionDeclarations.js +189 -0
  107. package/dist/generators/ts/_ObjectType/jsonTypeAliasDeclaration.d.ts +5 -0
  108. package/dist/generators/ts/_ObjectType/jsonTypeAliasDeclaration.js +28 -0
  109. package/dist/generators/ts/_ObjectType/objectSetMethodNames.d.ts +9 -0
  110. package/dist/generators/ts/_ObjectType/objectSetMethodNames.js +18 -0
  111. package/dist/generators/ts/_ObjectType/propertiesVariableStatement.d.ts +5 -0
  112. package/dist/generators/ts/_ObjectType/propertiesVariableStatement.js +37 -0
  113. package/dist/generators/ts/_ObjectType/rdfFunctionDeclarations.d.ts +4 -0
  114. package/dist/generators/ts/_ObjectType/rdfFunctionDeclarations.js +152 -0
  115. package/dist/generators/ts/_ObjectType/sparqlConstructQueryFunctionDeclaration.d.ts +1 -1
  116. package/dist/generators/ts/_ObjectType/sparqlConstructQueryFunctionDeclaration.js +4 -3
  117. package/dist/generators/ts/_ObjectType/sparqlConstructQueryStringFunctionDeclaration.d.ts +1 -1
  118. package/dist/generators/ts/_ObjectType/sparqlConstructQueryStringFunctionDeclaration.js +3 -2
  119. package/dist/generators/ts/_ObjectType/sparqlFunctionDeclarations.js +103 -35
  120. package/dist/generators/ts/_ObjectType/toJsonFunctionOrMethodDeclaration.js +6 -6
  121. package/dist/generators/ts/_ObjectType/toRdfFunctionOrMethodDeclaration.js +15 -13
  122. package/dist/generators/ts/graphqlSchemaVariableStatement.d.ts +9 -0
  123. package/dist/generators/ts/graphqlSchemaVariableStatement.js +86 -0
  124. package/dist/generators/ts/objectSetDeclarations.d.ts +8 -0
  125. package/dist/generators/ts/objectSetDeclarations.js +59 -0
  126. package/dist/generators/ts/objectSetInterfaceDeclaration.d.ts +8 -0
  127. package/dist/generators/ts/objectSetInterfaceDeclaration.js +46 -0
  128. package/dist/generators/ts/objectSetMethodSignatures.d.ts +11 -0
  129. package/dist/generators/ts/objectSetMethodSignatures.js +52 -0
  130. package/dist/generators/ts/rdfjsDatasetObjectSetClassDeclaration.d.ts +8 -0
  131. package/dist/generators/ts/rdfjsDatasetObjectSetClassDeclaration.js +393 -0
  132. package/dist/generators/ts/rdfjsTermExpression.d.ts +3 -0
  133. package/dist/generators/ts/rdfjsTermExpression.js +57 -0
  134. package/dist/generators/ts/sparqlObjectSetClassDeclaration.d.ts +8 -0
  135. package/dist/generators/ts/sparqlObjectSetClassDeclaration.js +415 -0
  136. package/dist/generators/ts/syntheticNamePrefix.d.ts +2 -0
  137. package/dist/generators/ts/syntheticNamePrefix.js +2 -0
  138. package/dist/generators/ts/tsName.js +27 -13
  139. package/dist/generators/ts/unsupportedObjectSetMethodDeclarations.d.ts +10 -0
  140. package/dist/generators/ts/unsupportedObjectSetMethodDeclarations.js +19 -0
  141. package/dist/input/NodeShape.d.ts +6 -8
  142. package/dist/input/NodeShape.js +20 -44
  143. package/dist/input/Ontology.d.ts +0 -3
  144. package/dist/input/Ontology.js +0 -9
  145. package/dist/input/PropertyPath.d.ts +6 -5
  146. package/dist/input/PropertyPath.js +14 -22
  147. package/dist/input/PropertyShape.d.ts +3 -1
  148. package/dist/input/PropertyShape.js +8 -2
  149. package/dist/input/ShapesGraph.js +4 -4
  150. package/dist/input/generated.d.ts +923 -105
  151. package/dist/input/generated.js +1865 -969
  152. package/dist/input/tsFeatures.d.ts +3 -2
  153. package/dist/input/tsFeatures.js +44 -27
  154. package/package.json +18 -16
  155. package/dist/generators/ts/_ObjectType/fromJsonFunctionDeclarations.d.ts +0 -4
  156. package/dist/generators/ts/_ObjectType/fromJsonFunctionDeclarations.js +0 -78
  157. package/dist/generators/ts/_ObjectType/fromRdfFunctionDeclarations.d.ts +0 -4
  158. package/dist/generators/ts/_ObjectType/fromRdfFunctionDeclarations.js +0 -91
  159. package/dist/generators/ts/_ObjectType/jsonSchemaFunctionDeclaration.d.ts +0 -5
  160. package/dist/generators/ts/_ObjectType/jsonSchemaFunctionDeclaration.js +0 -19
  161. package/dist/generators/ts/_ObjectType/jsonUiSchemaFunctionDeclaration.d.ts +0 -5
  162. package/dist/generators/ts/_ObjectType/jsonUiSchemaFunctionDeclaration.js +0 -31
  163. package/dist/generators/ts/_ObjectType/jsonZodSchemaFunctionDeclaration.d.ts +0 -5
  164. package/dist/generators/ts/_ObjectType/jsonZodSchemaFunctionDeclaration.js +0 -37
  165. package/dist/generators/ts/_ObjectType/rdfjsTermExpression.d.ts +0 -6
  166. package/dist/generators/ts/_ObjectType/rdfjsTermExpression.js +0 -17
  167. package/dist/generators/ts/_ObjectType/toJsonFunctionDeclaration.d.ts +0 -5
  168. package/dist/generators/ts/_ObjectType/toJsonFunctionDeclaration.js +0 -19
  169. package/dist/generators/ts/_ObjectType/toJsonReturnType.d.ts +0 -3
  170. package/dist/generators/ts/_ObjectType/toJsonReturnType.js +0 -17
  171. package/dist/generators/ts/_ObjectType/toRdfFunctionDeclaration.d.ts +0 -5
  172. package/dist/generators/ts/_ObjectType/toRdfFunctionDeclaration.js +0 -19
@@ -3,56 +3,17 @@ import { Either, Left, Maybe } from "purify-ts";
3
3
  import { invariant } from "ts-invariant";
4
4
  import * as input from "../input/index.js";
5
5
  import { logger } from "../logger.js";
6
+ import { flattenAstObjectCompositeTypeMemberTypes } from "./flattenAstObjectCompositeTypeMemberTypes.js";
6
7
  /**
7
8
  * Try to convert a property shape to a composite type (intersection or union) using some heuristics.
8
9
  */
9
10
  export function transformPropertyShapeToAstCompositeType(shape, inherited) {
10
11
  const defaultValue = (shape instanceof input.PropertyShape ? shape.defaultValue : Maybe.empty()).alt(inherited !== null ? inherited.defaultValue : Maybe.empty());
11
- const hasValues = shape.constraints.hasValues;
12
- const extern = shape.extern.alt(inherited !== null ? inherited.extern : Maybe.empty());
13
12
  let memberTypeEithers;
14
13
  let compositeTypeKind;
15
- const transformNodeShapeToAstCompositeMemberType = (nodeShape) => {
16
- const astTypeEither = this.transformNodeShapeToAstType(nodeShape);
17
- if (astTypeEither.isLeft()) {
18
- return astTypeEither;
19
- }
20
- const astType = astTypeEither.unsafeCoerce();
21
- if (extern.orDefault(false)) {
22
- // Use the identifier type instead
23
- let nodeKinds;
24
- switch (astType.kind) {
25
- case "ListType":
26
- nodeKinds = new Set();
27
- nodeKinds.add(astType.identifierNodeKind);
28
- break;
29
- case "ObjectType":
30
- nodeKinds = astType.identifierKinds;
31
- break;
32
- case "ObjectIntersectionType":
33
- case "ObjectUnionType":
34
- nodeKinds = new Set();
35
- for (const memberType of astType.memberTypes) {
36
- for (const nodeKind of memberType.identifierKinds) {
37
- nodeKinds.add(nodeKind);
38
- }
39
- }
40
- }
41
- return Either.of({
42
- defaultValue: defaultValue.filter((term) => term.termType === "NamedNode"),
43
- hasValues: [],
44
- in_: [],
45
- kind: "IdentifierType",
46
- nodeKinds,
47
- });
48
- }
49
- // Not extern, use the type
50
- return Either.of(astType);
51
- };
52
14
  if (shape.constraints.and.length > 0) {
53
15
  memberTypeEithers = shape.constraints.and.map((memberShape) => this.transformPropertyShapeToAstType(memberShape, {
54
16
  defaultValue,
55
- extern: extern,
56
17
  }));
57
18
  compositeTypeKind = "IntersectionType";
58
19
  }
@@ -69,7 +30,7 @@ export function transformPropertyShapeToAstCompositeType(shape, inherited) {
69
30
  if (classNodeShape === null) {
70
31
  return Left(new Error(`class ${classIri.value} did not resolve to a node shape`));
71
32
  }
72
- return transformNodeShapeToAstCompositeMemberType(classNodeShape);
33
+ return this.transformNodeShapeToAstType(classNodeShape);
73
34
  });
74
35
  compositeTypeKind = "IntersectionType";
75
36
  if (Either.rights(memberTypeEithers).length === 0) {
@@ -79,13 +40,12 @@ export function transformPropertyShapeToAstCompositeType(shape, inherited) {
79
40
  }
80
41
  }
81
42
  else if (shape.constraints.nodes.length > 0) {
82
- memberTypeEithers = shape.constraints.nodes.map((nodeShape) => transformNodeShapeToAstCompositeMemberType(nodeShape));
43
+ memberTypeEithers = shape.constraints.nodes.map((nodeShape) => this.transformNodeShapeToAstType(nodeShape));
83
44
  compositeTypeKind = "IntersectionType";
84
45
  }
85
46
  else if (shape.constraints.xone.length > 0) {
86
47
  memberTypeEithers = shape.constraints.xone.map((memberShape) => this.transformPropertyShapeToAstType(memberShape, {
87
48
  defaultValue,
88
- extern: extern,
89
49
  }));
90
50
  compositeTypeKind = "UnionType";
91
51
  }
@@ -93,108 +53,141 @@ export function transformPropertyShapeToAstCompositeType(shape, inherited) {
93
53
  return Left(new Error(`unable to transform ${shape} into an AST type`));
94
54
  }
95
55
  invariant(memberTypeEithers.length > 0);
96
- const memberTypes = Either.rights(memberTypeEithers);
97
- if (memberTypes.length !== memberTypeEithers.length) {
98
- logger.warn("shape %s composition did not map all member types successfully: %s", shape, Either.lefts(memberTypeEithers)
99
- .map((left) => left.message)
100
- .join("; "));
101
- return memberTypeEithers[0];
56
+ let memberObjectTypes = [];
57
+ let memberTypes = [];
58
+ for (const memberTypeEither of memberTypeEithers) {
59
+ if (memberTypeEither.isLeft()) {
60
+ return memberTypeEither;
61
+ }
62
+ const memberType = memberTypeEither.unsafeCoerce();
63
+ memberTypes.push(memberType);
64
+ switch (memberType.kind) {
65
+ case "ObjectType":
66
+ case "ObjectIntersectionType":
67
+ case "ObjectUnionType":
68
+ memberObjectTypes.push(memberType);
69
+ break;
70
+ }
102
71
  }
103
- invariant(memberTypes.length > 0);
104
72
  if (memberTypes.length === 1) {
105
73
  return Either.of(memberTypes[0]);
106
74
  }
75
+ if (memberTypes.length === memberObjectTypes.length) {
76
+ // If all the member types are ast.ObjectType, flatten them.
77
+ const flattenedMemberTypesEither = flattenAstObjectCompositeTypeMemberTypes({
78
+ objectCompositeTypeKind: compositeTypeKind === "IntersectionType"
79
+ ? "ObjectIntersectionType"
80
+ : "ObjectUnionType",
81
+ memberTypes: memberObjectTypes,
82
+ shape,
83
+ });
84
+ if (flattenedMemberTypesEither.isLeft()) {
85
+ return flattenedMemberTypesEither;
86
+ }
87
+ const { memberTypes: flattenedMemberTypes } = flattenedMemberTypesEither.unsafeCoerce();
88
+ memberTypes = memberObjectTypes = flattenedMemberTypes.concat();
89
+ }
90
+ return widenAstCompositeTypeToSingleType({
91
+ defaultValue,
92
+ memberTypes,
93
+ shape,
94
+ }).altLazy(() =>
95
+ // True composite type
96
+ Either.of({
97
+ kind: compositeTypeKind,
98
+ memberTypes,
99
+ }));
100
+ }
101
+ function widenAstCompositeTypeToSingleType({ defaultValue, memberTypes, shape, }) {
102
+ if (shape.constraints.hasValues.length > 0) {
103
+ return Left(new Error(`shape ${shape} hasValues, not attempting to widen composite type into a single type`));
104
+ }
105
+ if (shape instanceof input.PropertyShape && !shape.widen.orDefault(true)) {
106
+ return Left(new Error(`shape ${shape} has widening disabled`));
107
+ }
107
108
  // Get the type underlying a set or option
108
109
  const memberItemTypes = memberTypes.map((memberType) => {
109
110
  switch (memberType.kind) {
110
- case "SetType":
111
- return memberType.itemType;
112
111
  case "OptionType":
113
112
  return memberType.itemType;
113
+ case "SetType":
114
+ return memberType.itemType;
114
115
  default:
115
116
  return memberType;
116
117
  }
117
118
  });
118
- if (hasValues.length === 0) {
119
- // Can't handle hasValues when coalescing types
120
- const canCoalesce = (memberItemType) => {
121
- if (memberItemType.in_.length > 0) {
122
- return false;
123
- }
124
- switch (memberItemType.kind) {
125
- case "LiteralType": {
126
- if (memberItemType.maxExclusive.isJust()) {
127
- return false;
128
- }
129
- if (memberItemType.maxInclusive.isJust()) {
130
- return false;
131
- }
132
- if (memberItemType.minExclusive.isJust()) {
133
- return false;
134
- }
135
- if (memberItemType.minInclusive.isJust()) {
136
- return false;
137
- }
119
+ const canWiden = (memberItemType) => {
120
+ if (memberItemType.in_.length > 0) {
121
+ return false;
122
+ }
123
+ switch (memberItemType.kind) {
124
+ case "LiteralType": {
125
+ if (memberItemType.maxExclusive.isJust()) {
126
+ return false;
127
+ }
128
+ if (memberItemType.maxInclusive.isJust()) {
129
+ return false;
130
+ }
131
+ if (memberItemType.minExclusive.isJust()) {
132
+ return false;
133
+ }
134
+ if (memberItemType.minInclusive.isJust()) {
135
+ return false;
138
136
  }
139
137
  }
140
- return true;
141
- };
142
- if (memberItemTypes.every((memberItemType) => memberItemType.kind === "IdentifierType" &&
143
- canCoalesce(memberItemType))) {
144
- // Special case: all member types are identifiers without further constraints
145
- return Either.of({
146
- defaultValue: defaultValue.filter((term) => term.termType === "NamedNode"),
147
- hasValues: [],
148
- in_: [],
149
- kind: "IdentifierType",
150
- nodeKinds: new Set(memberItemTypes
151
- .filter((memberItemType) => memberItemType.kind === "IdentifierType")
152
- .flatMap((memberItemType) => [
153
- ...memberItemType.nodeKinds,
154
- ])),
155
- });
156
- }
157
- if (memberItemTypes.every((memberItemType) => memberItemType.kind === "LiteralType" && canCoalesce(memberItemType))) {
158
- // Special case: all the member types are Literals without further constraints,
159
- // like dash:StringOrLangString
160
- // Don't try to coalesce range constraints.
161
- return Either.of({
162
- datatype: Maybe.empty(),
163
- defaultValue: defaultValue.filter((term) => term.termType === "Literal"),
164
- hasValues: [],
165
- in_: [],
166
- kind: "LiteralType",
167
- languageIn: [],
168
- maxExclusive: Maybe.empty(),
169
- maxInclusive: Maybe.empty(),
170
- minExclusive: Maybe.empty(),
171
- minInclusive: Maybe.empty(),
172
- nodeKinds: new Set(["Literal"]),
173
- });
174
- }
175
- if (memberItemTypes.every((memberItemType) => (memberItemType.kind === "IdentifierType" ||
176
- memberItemType.kind === "LiteralType" ||
177
- memberItemType.kind === "TermType") &&
178
- canCoalesce(memberItemType))) {
179
- // Special case: all member types are terms without further constraints
180
- const nodeKinds = new Set(memberItemTypes.flatMap((memberItemType) => [
181
- ...memberItemType
182
- .nodeKinds,
183
- ]));
184
- invariant(nodeKinds.has("Literal") &&
185
- (nodeKinds.has("BlankNode") || nodeKinds.has("NamedNode"))); // The identifier-identifier and literal-literal cases should have been caught above
186
- return Either.of({
187
- defaultValue,
188
- hasValues: [],
189
- in_: [],
190
- kind: "TermType",
191
- nodeKinds,
192
- });
193
138
  }
139
+ return true;
140
+ };
141
+ if (memberItemTypes.every((memberItemType) => memberItemType.kind === "IdentifierType" && canWiden(memberItemType))) {
142
+ // Special case: all member types are identifiers without further constraints
143
+ return Either.of({
144
+ defaultValue: defaultValue.filter((term) => term.termType === "NamedNode"),
145
+ hasValues: [],
146
+ in_: [],
147
+ kind: "IdentifierType",
148
+ nodeKinds: new Set(memberItemTypes
149
+ .filter((memberItemType) => memberItemType.kind === "IdentifierType")
150
+ .flatMap((memberItemType) => [
151
+ ...memberItemType.nodeKinds,
152
+ ])),
153
+ });
194
154
  }
195
- return Either.of({
196
- kind: compositeTypeKind,
197
- memberTypes: memberTypes,
198
- });
155
+ if (memberItemTypes.every((memberItemType) => memberItemType.kind === "LiteralType" && canWiden(memberItemType))) {
156
+ // Special case: all the member types are Literals without further constraints,
157
+ // like dash:StringOrLangString
158
+ // Don't try to widen range constraints.
159
+ return Either.of({
160
+ datatype: Maybe.empty(),
161
+ defaultValue: defaultValue.filter((term) => term.termType === "Literal"),
162
+ hasValues: [],
163
+ in_: [],
164
+ kind: "LiteralType",
165
+ languageIn: [],
166
+ maxExclusive: Maybe.empty(),
167
+ maxInclusive: Maybe.empty(),
168
+ minExclusive: Maybe.empty(),
169
+ minInclusive: Maybe.empty(),
170
+ nodeKinds: new Set(["Literal"]),
171
+ });
172
+ }
173
+ if (memberItemTypes.every((memberItemType) => (memberItemType.kind === "IdentifierType" ||
174
+ memberItemType.kind === "LiteralType" ||
175
+ memberItemType.kind === "TermType") &&
176
+ canWiden(memberItemType))) {
177
+ // Special case: all member types are terms without further constraints
178
+ const nodeKinds = new Set(memberItemTypes.flatMap((memberItemType) => [
179
+ ...memberItemType.nodeKinds,
180
+ ]));
181
+ invariant(nodeKinds.has("Literal") &&
182
+ (nodeKinds.has("BlankNode") || nodeKinds.has("NamedNode"))); // The identifier-identifier and literal-literal cases should have been caught above
183
+ return Either.of({
184
+ defaultValue,
185
+ hasValues: [],
186
+ in_: [],
187
+ kind: "TermType",
188
+ nodeKinds,
189
+ });
190
+ }
191
+ return Left(new Error(`shape ${shape} member types could not be widened into a single type`));
199
192
  }
200
193
  //# sourceMappingURL=transformPropertyShapeToAstCompositeType.js.map
@@ -1,4 +1,4 @@
1
- import type { BlankNode, Literal, NamedNode } from "@rdfjs/types";
1
+ import type { Literal, NamedNode } from "@rdfjs/types";
2
2
  import { Either, Maybe } from "purify-ts";
3
3
  import type { ShapesGraphToAstTransformer } from "../ShapesGraphToAstTransformer.js";
4
4
  import type * as ast from "../ast/index.js";
@@ -7,6 +7,6 @@ import * as input from "../input/index.js";
7
7
  * Try to convert a property shape to an AST IdentifierType using some heuristics.
8
8
  */
9
9
  export declare function transformPropertyShapeToAstIdentifierType(this: ShapesGraphToAstTransformer, shape: input.Shape, inherited: {
10
- defaultValue: Maybe<BlankNode | Literal | NamedNode>;
10
+ defaultValue: Maybe<Literal | NamedNode>;
11
11
  } | null): Either<Error, ast.IdentifierType>;
12
12
  //# sourceMappingURL=transformPropertyShapeToAstIdentifierType.d.ts.map
@@ -1,4 +1,4 @@
1
- import type { BlankNode, Literal, NamedNode } from "@rdfjs/types";
1
+ import type { Literal, NamedNode } from "@rdfjs/types";
2
2
  import { Either, Maybe } from "purify-ts";
3
3
  import type { ShapesGraphToAstTransformer } from "../ShapesGraphToAstTransformer.js";
4
4
  import type * as ast from "../ast/index.js";
@@ -7,6 +7,6 @@ import * as input from "../input/index.js";
7
7
  * Try to convert a property shape to an AST LiteralType using some heuristics.
8
8
  */
9
9
  export declare function transformPropertyShapeToAstLiteralType(this: ShapesGraphToAstTransformer, shape: input.Shape, inherited: {
10
- defaultValue: Maybe<BlankNode | Literal | NamedNode>;
10
+ defaultValue: Maybe<Literal | NamedNode>;
11
11
  } | null): Either<Error, ast.LiteralType>;
12
12
  //# sourceMappingURL=transformPropertyShapeToAstLiteralType.d.ts.map
@@ -1,5 +1,61 @@
1
- import { Either, Left } from "purify-ts";
1
+ import N3 from "n3";
2
+ import { Either, Left, Maybe } from "purify-ts";
3
+ import { invariant } from "ts-invariant";
2
4
  import { pickLiteral } from "./pickLiteral.js";
5
+ function identifierNodeKinds(type) {
6
+ switch (type.kind) {
7
+ case "ObjectType":
8
+ return type.identifierNodeKinds;
9
+ case "ObjectUnionType":
10
+ return new Set(type.memberTypes.flatMap((memberType) => [
11
+ ...memberType.identifierNodeKinds,
12
+ ]));
13
+ }
14
+ }
15
+ function synthesizeStubAstObjectType({ identifierNodeKinds, tsFeatures, }) {
16
+ let syntheticName;
17
+ switch (identifierNodeKinds.size) {
18
+ case 1:
19
+ invariant(identifierNodeKinds.has("NamedNode"));
20
+ syntheticName = "NamedDefaultStub";
21
+ break;
22
+ case 2:
23
+ syntheticName = "DefaultStub";
24
+ break;
25
+ default:
26
+ throw new Error("should never happen");
27
+ }
28
+ return {
29
+ abstract: false,
30
+ ancestorObjectTypes: [],
31
+ childObjectTypes: [],
32
+ comment: Maybe.empty(),
33
+ descendantObjectTypes: [],
34
+ export: true,
35
+ extern: false,
36
+ fromRdfType: Maybe.empty(),
37
+ identifierIn: [],
38
+ identifierNodeKinds,
39
+ identifierMintingStrategy: Maybe.empty(),
40
+ kind: "ObjectType",
41
+ label: Maybe.empty(),
42
+ name: {
43
+ identifier: N3.DataFactory.blankNode(),
44
+ label: Maybe.empty(),
45
+ propertyPath: Maybe.empty(),
46
+ shName: Maybe.empty(),
47
+ shaclmateName: Maybe.empty(),
48
+ syntheticName: Maybe.of(syntheticName),
49
+ },
50
+ parentObjectTypes: [],
51
+ properties: [],
52
+ synthetic: true,
53
+ toRdfTypes: [],
54
+ tsFeatures,
55
+ tsImports: [],
56
+ tsObjectDeclarationType: "class",
57
+ };
58
+ }
3
59
  export function transformPropertyShapeToAstObjectTypeProperty(propertyShape) {
4
60
  {
5
61
  const property = this.astObjectTypePropertiesByIdentifier.get(propertyShape.identifier);
@@ -7,9 +63,74 @@ export function transformPropertyShapeToAstObjectTypeProperty(propertyShape) {
7
63
  return Either.of(property);
8
64
  }
9
65
  }
10
- const type = this.transformPropertyShapeToAstType(propertyShape, null);
11
- if (type.isLeft()) {
12
- return type;
66
+ const typeEither = this.transformPropertyShapeToAstType(propertyShape, null);
67
+ if (typeEither.isLeft()) {
68
+ return typeEither;
69
+ }
70
+ const type = typeEither.unsafeCoerce();
71
+ let stubType = Maybe.empty();
72
+ let propertyShapeStubType;
73
+ if (propertyShape.stub.isJust()) {
74
+ const propertyShapeStubTypeEither = this.transformNodeShapeToAstType(propertyShape.stub.unsafeCoerce()).chain((propertyShapeStubType) => {
75
+ switch (propertyShapeStubType.kind) {
76
+ case "ListType":
77
+ case "ObjectIntersectionType":
78
+ return Left(new Error(`${propertyShape} stub cannot refer to a ${propertyShapeStubType.kind}`));
79
+ case "ObjectType":
80
+ case "ObjectUnionType":
81
+ return Either.of(propertyShapeStubType);
82
+ }
83
+ });
84
+ if (propertyShapeStubTypeEither.isLeft()) {
85
+ return propertyShapeStubTypeEither;
86
+ }
87
+ propertyShapeStubType = propertyShapeStubTypeEither.unsafeCoerce();
88
+ }
89
+ if (propertyShapeStubType || propertyShape.lazy.orDefault(false)) {
90
+ switch (type.kind) {
91
+ case "ObjectType":
92
+ case "ObjectUnionType": {
93
+ stubType = Maybe.of(propertyShapeStubType ??
94
+ synthesizeStubAstObjectType({
95
+ identifierNodeKinds: identifierNodeKinds(type),
96
+ tsFeatures: type.tsFeatures,
97
+ }));
98
+ break;
99
+ }
100
+ case "OptionType":
101
+ case "SetType": {
102
+ switch (type.itemType.kind) {
103
+ case "ObjectType":
104
+ case "ObjectUnionType": {
105
+ const stubItemType = propertyShapeStubType ??
106
+ synthesizeStubAstObjectType({
107
+ identifierNodeKinds: identifierNodeKinds(type.itemType),
108
+ tsFeatures: type.itemType.tsFeatures,
109
+ });
110
+ if (type.kind === "OptionType") {
111
+ stubType = Maybe.of({
112
+ kind: "OptionType",
113
+ itemType: stubItemType,
114
+ });
115
+ }
116
+ else {
117
+ stubType = Maybe.of({
118
+ kind: "SetType",
119
+ itemType: stubItemType,
120
+ minCount: 0,
121
+ mutable: Maybe.empty(),
122
+ });
123
+ }
124
+ break;
125
+ }
126
+ default:
127
+ return Left(new Error(`${propertyShape} marked lazy but has ${type.kind} of ${type.itemType.kind}`));
128
+ }
129
+ break;
130
+ }
131
+ default:
132
+ return Left(new Error(`${propertyShape} marked lazy but has ${type.kind}`));
133
+ }
13
134
  }
14
135
  const path = propertyShape.path;
15
136
  if (path.kind !== "PredicatePath") {
@@ -23,7 +144,8 @@ export function transformPropertyShapeToAstObjectTypeProperty(propertyShape) {
23
144
  name: this.shapeAstName(propertyShape),
24
145
  order: propertyShape.order.orDefault(0),
25
146
  path,
26
- type: type.extract(),
147
+ stubType,
148
+ type,
27
149
  visibility: propertyShape.visibility,
28
150
  };
29
151
  this.astObjectTypePropertiesByIdentifier.set(propertyShape.identifier, property);
@@ -1,4 +1,4 @@
1
- import type { BlankNode, Literal, NamedNode } from "@rdfjs/types";
1
+ import type { Literal, NamedNode } from "@rdfjs/types";
2
2
  import { Either, Maybe } from "purify-ts";
3
3
  import type { ShapesGraphToAstTransformer } from "../ShapesGraphToAstTransformer.js";
4
4
  import type * as ast from "../ast/index.js";
@@ -7,8 +7,8 @@ import * as input from "../input/index.js";
7
7
  * Try to convert a property shape to an AST TermType using some heuristics.
8
8
  */
9
9
  export declare function transformPropertyShapeToAstTermType(this: ShapesGraphToAstTransformer, shape: input.Shape, inherited: {
10
- defaultValue: Maybe<BlankNode | Literal | NamedNode>;
11
- } | null): Either<Error, Omit<ast.TermType<BlankNode | Literal | NamedNode>, "kind"> & {
10
+ defaultValue: Maybe<Literal | NamedNode>;
11
+ } | null): Either<Error, Omit<ast.TermType, "kind"> & {
12
12
  readonly kind: "TermType";
13
13
  }>;
14
14
  //# sourceMappingURL=transformPropertyShapeToAstTermType.d.ts.map
@@ -1,4 +1,4 @@
1
- import type { BlankNode, Literal, NamedNode } from "@rdfjs/types";
1
+ import type { Literal, NamedNode } from "@rdfjs/types";
2
2
  import type { Either, Maybe } from "purify-ts";
3
3
  import type { ShapesGraphToAstTransformer } from "../ShapesGraphToAstTransformer.js";
4
4
  import type * as ast from "../ast/index.js";
@@ -10,7 +10,6 @@ import * as input from "../input/index.js";
10
10
  * a shape has one type.
11
11
  */
12
12
  export declare function transformPropertyShapeToAstType(this: ShapesGraphToAstTransformer, shape: input.Shape, inherited: {
13
- defaultValue: Maybe<BlankNode | Literal | NamedNode>;
14
- extern: Maybe<boolean>;
13
+ defaultValue: Maybe<Literal | NamedNode>;
15
14
  } | null): Either<Error, ast.Type>;
16
15
  //# sourceMappingURL=transformPropertyShapeToAstType.d.ts.map
package/dist/ast/Ast.d.ts CHANGED
@@ -5,6 +5,5 @@ export interface Ast {
5
5
  readonly objectIntersectionTypes: readonly ObjectIntersectionType[];
6
6
  readonly objectTypes: readonly ObjectType[];
7
7
  readonly objectUnionTypes: readonly ObjectUnionType[];
8
- readonly tsDataFactoryVariable: string;
9
8
  }
10
9
  //# sourceMappingURL=Ast.d.ts.map
@@ -0,0 +1,14 @@
1
+ /**
2
+ * A Compact URI (https://www.w3.org/TR/curie)
3
+ */
4
+ export declare class Curie {
5
+ readonly prefix: string;
6
+ readonly reference: string;
7
+ constructor({ prefix, reference, }: {
8
+ prefix: string;
9
+ reference: string;
10
+ });
11
+ static parse(curie: string): Curie;
12
+ toString(): string;
13
+ }
14
+ //# sourceMappingURL=Curie.d.ts.map
@@ -0,0 +1,21 @@
1
+ import { invariant } from "ts-invariant";
2
+ /**
3
+ * A Compact URI (https://www.w3.org/TR/curie)
4
+ */
5
+ export class Curie {
6
+ prefix;
7
+ reference;
8
+ constructor({ prefix, reference, }) {
9
+ this.prefix = prefix;
10
+ this.reference = reference;
11
+ }
12
+ static parse(curie) {
13
+ const split = curie.split(":", 2);
14
+ invariant(split.length === 2);
15
+ return new Curie({ prefix: split[0], reference: split[1] });
16
+ }
17
+ toString() {
18
+ return `${this.prefix}:${this.reference}`;
19
+ }
20
+ }
21
+ //# sourceMappingURL=Curie.js.map
@@ -1,10 +1,11 @@
1
1
  import type { BlankNode, NamedNode } from "@rdfjs/types";
2
+ import type { IdentifierNodeKind } from "@shaclmate/shacl-ast";
2
3
  import type { TermType } from "./TermType.js";
3
4
  /**
4
5
  * A type corresponding to sh:nodeKind of a blank node or IRI, and not corresponding to a node shape.
5
6
  */
6
- export interface IdentifierType extends TermType<BlankNode | NamedNode> {
7
+ export interface IdentifierType extends TermType<NamedNode, BlankNode | NamedNode> {
7
8
  readonly kind: "IdentifierType";
8
- readonly nodeKinds: Set<"BlankNode" | "NamedNode">;
9
+ readonly nodeKinds: Set<IdentifierNodeKind>;
9
10
  }
10
11
  //# sourceMappingURL=IdentifierType.d.ts.map
@@ -1,4 +1,5 @@
1
1
  import type { NamedNode } from "@rdfjs/types";
2
+ import type { IdentifierNodeKind } from "@shaclmate/shacl-ast";
2
3
  import type { Maybe } from "purify-ts";
3
4
  import type { IdentifierMintingStrategy } from "../enums/IdentifierMintingStrategy.js";
4
5
  import type { Name } from "./Name.js";
@@ -18,7 +19,7 @@ export interface ListType {
18
19
  /**
19
20
  * Type of identifier (blank or named node) to use for lists and sub-lists.
20
21
  */
21
- readonly identifierNodeKind: "BlankNode" | "NamedNode";
22
+ readonly identifierNodeKind: IdentifierNodeKind;
22
23
  /**
23
24
  * List item type.
24
25
  *
@@ -1,7 +1,7 @@
1
1
  import type { Literal, NamedNode } from "@rdfjs/types";
2
2
  import type { Maybe } from "purify-ts";
3
3
  import type { TermType } from "./TermType.js";
4
- export interface LiteralType extends TermType<Literal> {
4
+ export interface LiteralType extends TermType<Literal, Literal> {
5
5
  readonly datatype: Maybe<NamedNode>;
6
6
  readonly kind: "LiteralType";
7
7
  readonly languageIn: readonly string[];
@@ -1,14 +1,49 @@
1
1
  import type { BlankNode, NamedNode } from "@rdfjs/types";
2
2
  import type { Maybe } from "purify-ts";
3
+ import type { Curie } from "./Curie.js";
3
4
  export interface Name {
4
- readonly curie: Maybe<string>;
5
- readonly identifier: BlankNode | NamedNode;
5
+ readonly identifier: BlankNode | (NamedNode & {
6
+ /**
7
+ * Compact URI (CURIE).
8
+ */
9
+ readonly curie: Maybe<Curie>;
10
+ /**
11
+ * Unique unqualified/local identifier, derived from the CURIE.
12
+ *
13
+ * Returns Just if the local identifier is unique across all CURIEs, otherwise Nothing.
14
+ */
15
+ readonly uniqueLocalPart: () => Maybe<string>;
16
+ });
17
+ /**
18
+ * rdfs:label.
19
+ */
6
20
  readonly label: Maybe<string>;
7
- readonly propertyPath: Maybe<{
8
- curie: Maybe<string>;
9
- identifier: NamedNode;
21
+ /**
22
+ * sh:path for property shapes.
23
+ */
24
+ readonly propertyPath: Maybe<NamedNode & {
25
+ /**
26
+ * Compact URI (CURIE).
27
+ */
28
+ readonly curie: Maybe<Curie>;
29
+ /**
30
+ * Unique unqualified/local identifier, derived from the CURIE.
31
+ *
32
+ * Returns Just if the local identifier is unique across all CURIEs, otherwise Nothing.
33
+ */
34
+ readonly uniqueLocalPart: () => Maybe<string>;
10
35
  }>;
36
+ /**
37
+ * sh:name.
38
+ */
11
39
  readonly shName: Maybe<string>;
40
+ /**
41
+ * shaclmate:name.
42
+ */
12
43
  readonly shaclmateName: Maybe<string>;
44
+ /**
45
+ * Synthesized in code.
46
+ */
47
+ readonly syntheticName: Maybe<string>;
13
48
  }
14
49
  //# sourceMappingURL=Name.d.ts.map