@shaclmate/compiler 4.0.11 → 4.0.13

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.
@@ -1,10 +1,6 @@
1
1
  import { NodeKind } from "@shaclmate/shacl-ast";
2
2
  import { Either, Left } from "purify-ts";
3
- const defaultNodeShapeNodeKinds = new Set([
4
- "BlankNode",
5
- "IRI",
6
- "Literal",
7
- ]);
3
+ import { defaultNodeShapeNodeKinds } from "./defaultNodeShapeNodeKinds.js";
8
4
  const defaultPropertyShapeNodeKinds = new Set([
9
5
  "BlankNode",
10
6
  "IRI",
@@ -169,7 +165,11 @@ export function shapeNodeKinds(shape, options) {
169
165
  if (shape.kind === "NodeShape") {
170
166
  return Either.of(options?.defaultNodeShapeNodeKinds ?? defaultNodeShapeNodeKinds);
171
167
  }
172
- return Either.of(options?.defaultPropertyShapeNodeKinds ?? defaultPropertyShapeNodeKinds);
168
+ if (shape.path.termType === "InversePath") {
169
+ // Inverse paths can only have blank nodes and IRIs as values, because the value is the subject of a triple.
170
+ return Either.of(new Set(["BlankNode", "IRI"]));
171
+ }
172
+ return Either.of(defaultPropertyShapeNodeKinds);
173
173
  });
174
174
  }
175
175
  //# sourceMappingURL=shapeNodeKinds.js.map
@@ -240,6 +240,10 @@ export function transformPropertyShapeToAstObjectTypeProperty({ objectType, prop
240
240
  invariant(false, `unexpected lazy AST type ${astType.kind}`);
241
241
  }
242
242
  }
243
+ if (propertyShape.path.termType === "InversePath" &&
244
+ astType.nodeKinds.has("Literal")) {
245
+ return Left(new Error(`${propertyShape}: property shapes with inverse paths can only have blank node or IRI node kinds`));
246
+ }
243
247
  return Either.of(new ast.ObjectType.Property({
244
248
  comment: propertyShape.comment,
245
249
  description: propertyShape.description,
@@ -1,3 +1,4 @@
1
+ import type { NodeKind } from "@shaclmate/shacl-ast";
1
2
  import type { TsFeature } from "../enums/TsFeature.js";
2
3
  import { AbstractType } from "./AbstractType.js";
3
4
  import type { BlankNodeType } from "./BlankNodeType.js";
@@ -25,6 +26,7 @@ export declare abstract class AbstractCompoundType<MemberT extends AbstractCompo
25
26
  tsFeatures: ReadonlySet<TsFeature>;
26
27
  } & ConstructorParameters<typeof AbstractType>[0]);
27
28
  get members(): readonly MemberT[];
29
+ get nodeKinds(): ReadonlySet<NodeKind>;
28
30
  get recursive(): boolean;
29
31
  get tsFeatures(): ReadonlySet<TsFeature>;
30
32
  addMember(member: MemberT): void;
@@ -30,6 +30,15 @@ export class AbstractCompoundType extends AbstractType {
30
30
  get members() {
31
31
  return this.#members;
32
32
  }
33
+ get nodeKinds() {
34
+ const nodeKinds = new Set();
35
+ for (const member of this.members) {
36
+ for (const nodeKind of member.type.nodeKinds) {
37
+ nodeKinds.add(nodeKind);
38
+ }
39
+ }
40
+ return nodeKinds;
41
+ }
33
42
  get recursive() {
34
43
  return this.members.some((member) => member.type.recursive);
35
44
  }
@@ -75,6 +84,9 @@ export class AbstractCompoundType extends AbstractType {
75
84
  return `${this.kind}(memberTypes=[${this.members.map((memberType) => memberType.toString()).join(", ")}])`;
76
85
  }
77
86
  }
87
+ __decorate([
88
+ Memoize()
89
+ ], AbstractCompoundType.prototype, "nodeKinds", null);
78
90
  __decorate([
79
91
  Memoize()
80
92
  ], AbstractCompoundType.prototype, "tsFeatures", null);
@@ -1,3 +1,4 @@
1
+ import type { NodeKind } from "@shaclmate/shacl-ast";
1
2
  import { AbstractType } from "./AbstractType.js";
2
3
  import type { BlankNodeType } from "./BlankNodeType.js";
3
4
  import type { IdentifierType } from "./IdentifierType.js";
@@ -23,6 +24,7 @@ export declare abstract class AbstractContainerType<ItemTypeT extends AbstractCo
23
24
  constructor({ itemType, ...superParameters }: {
24
25
  itemType: ItemTypeT;
25
26
  } & ConstructorParameters<typeof AbstractType>[0]);
27
+ get nodeKinds(): ReadonlySet<NodeKind>;
26
28
  get recursive(): boolean;
27
29
  equals(other: AbstractContainerType<ItemTypeT>): boolean;
28
30
  toString(): string;
@@ -14,6 +14,9 @@ export class AbstractContainerType extends AbstractType {
14
14
  super(superParameters);
15
15
  this.itemType = itemType;
16
16
  }
17
+ get nodeKinds() {
18
+ return this.itemType.nodeKinds;
19
+ }
17
20
  get recursive() {
18
21
  return this.itemType.recursive;
19
22
  }
@@ -1,3 +1,4 @@
1
+ import type { NodeKind } from "@shaclmate/shacl-ast";
1
2
  import { AbstractType } from "./AbstractType.js";
2
3
  import type { ObjectType } from "./ObjectType.js";
3
4
  import type { ObjectUnionType } from "./ObjectUnionType.js";
@@ -14,6 +15,7 @@ export declare abstract class AbstractLazyObjectType<PartialTypeT extends Abstra
14
15
  partialType: PartialTypeT;
15
16
  resolveType: ResolveTypeT;
16
17
  } & ConstructorParameters<typeof AbstractType>[0]);
18
+ get nodeKinds(): ReadonlySet<NodeKind>;
17
19
  get recursive(): boolean;
18
20
  equals(other: AbstractLazyObjectType<PartialTypeT, ResolveTypeT>): boolean;
19
21
  toString(): string;
@@ -11,6 +11,9 @@ export class AbstractLazyObjectType extends AbstractType {
11
11
  this.partialType = partialType;
12
12
  this.resolveType = resolveType;
13
13
  }
14
+ get nodeKinds() {
15
+ return this.partialType.nodeKinds;
16
+ }
14
17
  get recursive() {
15
18
  return this.partialType.recursive;
16
19
  }
@@ -1,5 +1,4 @@
1
1
  import type { BlankNode, Literal, NamedNode } from "@rdfjs/types";
2
- import type { NodeKind } from "@shaclmate/shacl-ast";
3
2
  import { AbstractType } from "./AbstractType.js";
4
3
  /**
5
4
  * Abstract base class of term types (BlankNodeType, IdentifierType, LiteralType, IriType, TermType).
@@ -13,7 +12,6 @@ export declare abstract class AbstractTermType<ConstantTermT extends Literal | N
13
12
  readonly hasValues: readonly ConstantTermT[];
14
13
  readonly in_: readonly ConstantTermT[];
15
14
  abstract readonly kind: "BlankNodeType" | "IdentifierType" | "IriType" | "LiteralType" | "TermType";
16
- abstract readonly nodeKinds: ReadonlySet<NodeKind>;
17
15
  readonly recursive = false;
18
16
  constructor({ hasValues, in_, ...superParameters }: {
19
17
  hasValues: readonly ConstantTermT[];
@@ -1,4 +1,5 @@
1
1
  import type { BlankNode, NamedNode } from "@rdfjs/types";
2
+ import type { NodeKind } from "@shaclmate/shacl-ast";
2
3
  import { Maybe } from "purify-ts";
3
4
  /**
4
5
  * Abstract base class for Types.
@@ -16,6 +17,12 @@ export declare abstract class AbstractType {
16
17
  * Name of this type, from shaclmate:name or sh:name.
17
18
  */
18
19
  readonly name: Maybe<string>;
20
+ /**
21
+ * The range of node kinds of this type.
22
+ *
23
+ * For example, an object type has blank and IRI node kinds, while a string type has a Literal node kind.
24
+ */
25
+ abstract readonly nodeKinds: ReadonlySet<NodeKind>;
19
26
  /**
20
27
  * Does this type directly or indirectly reference itself?
21
28
  */
@@ -1,4 +1,5 @@
1
1
  import type { BlankNode, NamedNode } from "@rdfjs/types";
2
+ import type { NodeKind } from "@shaclmate/shacl-ast";
2
3
  import type { Maybe } from "purify-ts";
3
4
  import { PropertyPath } from "rdfjs-resource";
4
5
  import type { IdentifierMintingStrategy } from "../enums/IdentifierMintingStrategy.js";
@@ -43,6 +44,7 @@ export declare class ObjectType extends AbstractType {
43
44
  * Type discriminant.
44
45
  */
45
46
  readonly kind = "ObjectType";
47
+ readonly nodeKinds: ReadonlySet<NodeKind>;
46
48
  /**
47
49
  * Was this type synthesized or did it come from SHACL?
48
50
  */
@@ -73,6 +73,7 @@ export class ObjectType extends AbstractType {
73
73
  * Type discriminant.
74
74
  */
75
75
  kind = "ObjectType";
76
+ nodeKinds = nodeKinds;
76
77
  /**
77
78
  * Was this type synthesized or did it come from SHACL?
78
79
  */
@@ -169,6 +170,7 @@ export class ObjectType extends AbstractType {
169
170
  return `${this.kind}(shapeIdentifier=${Resource.Identifier.toString(this.shapeIdentifier)})`;
170
171
  }
171
172
  }
173
+ const nodeKinds = new Set(["BlankNode", "IRI"]);
172
174
  (function (ObjectType) {
173
175
  class Property {
174
176
  /**
@@ -196,7 +196,10 @@ export class AbstractCollectionType extends AbstractContainerType {
196
196
  schema = code `${schema}.nonempty().min(${this.minCount})`;
197
197
  }
198
198
  else {
199
- schema = code `${schema}.default(() => [])`;
199
+ schema = code `${schema}.optional()`;
200
+ }
201
+ if (!this._mutable) {
202
+ schema = code `${schema}.readonly()`;
200
203
  }
201
204
  return schema;
202
205
  }
@@ -296,9 +296,9 @@ ${joinCode(this.concreteMembers.map(({ jsonTypeCheck, type, unwrap, wrap }) => c
296
296
  return code `${imports.z}.discriminatedUnion("${this.discriminant.name}", [${joinCode(this.concreteMembers.map(({ type }) => type.jsonSchema({
297
297
  includeDiscriminantProperty: true,
298
298
  context: "type",
299
- })), { on: "," })}])`;
299
+ })), { on: "," })}]).readonly()`;
300
300
  case "typeof":
301
- return code `${imports.z}.union([${joinCode(this.concreteMembers.map(({ type }) => type.jsonSchema({ context: "type" })), { on: "," })}])`;
301
+ return code `${imports.z}.union([${joinCode(this.concreteMembers.map(({ type }) => type.jsonSchema({ context: "type" })), { on: "," })}]).readonly()`;
302
302
  default:
303
303
  throw this.discriminant;
304
304
  }
@@ -6,25 +6,19 @@ export function NamedObjectType_jsonSchemaFunctionDeclaration() {
6
6
  if (!this.features.has("json")) {
7
7
  return Maybe.empty();
8
8
  }
9
- const mergeZodObjectSchemas = [];
9
+ let properties = [];
10
10
  for (const parentObjectType of this.parentObjectTypes) {
11
- mergeZodObjectSchemas.push(parentObjectType.jsonSchema({ context: "type" }));
11
+ properties.push(code `...${parentObjectType.jsonSchema({ context: "type" })}.shape`);
12
12
  }
13
13
  if (this.properties.length > 0) {
14
- mergeZodObjectSchemas.push(code `${imports.z}.object({ ${joinCode(this.properties
14
+ properties = properties.concat(this.properties
15
15
  .flatMap((property) => property.jsonZchema.toList())
16
- .map(({ key, schema }) => code `"${key}": ${schema}`), { on: "," })} })`);
16
+ .map(({ key, schema }) => code `"${key}": ${schema}`));
17
17
  }
18
+ // ${this.properties.every((property) => !property.mutable) ? `.readonly()` : ""}
18
19
  return Maybe.of(code `\
19
20
  export function schema() {
20
- return ${mergeZodObjectSchemas.length > 0
21
- ? mergeZodObjectSchemas.reduce((merged, zodObjectSchema) => {
22
- if (merged === null) {
23
- return zodObjectSchema;
24
- }
25
- return code `${merged}.merge(${zodObjectSchema})`;
26
- }, null)
27
- : `${imports.z}.object()`} satisfies ${imports.z}.ZodType<${syntheticNamePrefix}Json>;
21
+ return ${imports.z}.object({${joinCode(properties, { on: "," })}}) satisfies ${imports.z}.ZodType<${syntheticNamePrefix}Json>;
28
22
  }`);
29
23
  }
30
24
  //# sourceMappingURL=NamedObjectType_jsonSchemaFunctionDeclaration.js.map
@@ -101,7 +101,7 @@ export class ShaclProperty extends AbstractProperty {
101
101
  }
102
102
  get jsonSignature() {
103
103
  const typeJsonType = this.type.jsonType();
104
- return Maybe.of(code `readonly ${this.name}${typeJsonType.optional ? "?" : ""}: ${typeJsonType.requiredName}`);
104
+ return Maybe.of(code `${!this.mutable ? "readonly " : ""}${this.name}${typeJsonType.optional ? "?" : ""}: ${typeJsonType.requiredName}`);
105
105
  }
106
106
  get jsonZchema() {
107
107
  let schema = this.type.jsonSchema({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "dependencies": {
3
- "@shaclmate/shacl-ast": "4.0.11",
3
+ "@shaclmate/shacl-ast": "4.0.13",
4
4
  "@rdfjs/data-model": "~2.1.1",
5
5
  "@rdfjs/dataset": "~2.0.2",
6
6
  "@rdfjs/prefix-map": "~0.1.2",
@@ -78,5 +78,5 @@
78
78
  },
79
79
  "type": "module",
80
80
  "types": "./dist/index.d.ts",
81
- "version": "4.0.11"
81
+ "version": "4.0.13"
82
82
  }