diff --git a/packages/schema-converter-shex/src/typing/ShexJTypingTransformer.ts b/packages/schema-converter-shex/src/typing/ShexJTypingTransformer.ts
index 272aa58..445107c 100644
--- a/packages/schema-converter-shex/src/typing/ShexJTypingTransformer.ts
+++ b/packages/schema-converter-shex/src/typing/ShexJTypingTransformer.ts
@@ -45,6 +45,18 @@ export const ShexJTypingTransformer = ShexJTraverser.createTransformer<
NodeConstraint: {
return: dom.Type;
};
+ ShapeOr: {
+ return: dom.UnionType;
+ };
+ ShapeAnd: {
+ return: dom.IntersectionType;
+ };
+ ShapeNot: {
+ return: never;
+ };
+ ShapeExternal: {
+ return: never;
+ };
},
ShexJTypeTransformerContext
>({
@@ -82,7 +94,7 @@ export const ShexJTypingTransformer = ShexJTraverser.createTransformer<
} else {
// TODO: Handle other items
throw new Error(
- "Cannot handle ShapeOr, ShapeAnd, ShapeNot, ShapeExternal, or NodeConstraint",
+ "Cannot handle ShapeOr, ShapeAnd, ShapeNot, ShapeExternal, or NodeConstraint direcly on ShapeDecl.",
);
}
},
@@ -330,4 +342,34 @@ export const ShexJTypingTransformer = ShexJTraverser.createTransformer<
return dom.type.undefined;
},
},
+ ShapeOr: {
+ transformer: async (shapeOr, getTransformedChildren) => {
+ const transformedChildren = await getTransformedChildren();
+ const validTypes: dom.Type[] = [];
+ transformedChildren.shapeExprs.forEach((type) => {
+ if (typeof type === "object") validTypes.push(type);
+ });
+ return dom.create.union(validTypes);
+ },
+ },
+ ShapeAnd: {
+ transformer: async (shapeAnd, getTransformedChildren) => {
+ const transformedChildren = await getTransformedChildren();
+ const validTypes: dom.Type[] = [];
+ transformedChildren.shapeExprs.forEach((type) => {
+ if (typeof type === "object") validTypes.push(type);
+ });
+ return dom.create.intersection(validTypes);
+ },
+ },
+ ShapeNot: {
+ transformer: async () => {
+ throw new Error("ShapeNot is not supported");
+ },
+ },
+ ShapeExternal: {
+ transformer: async () => {
+ throw new Error("ShapeExternal is not supported");
+ },
+ },
});
diff --git a/packages/schema-converter-shex/test/context.test.ts b/packages/schema-converter-shex/test/context.test.ts
index 0df8e48..152eb4a 100644
--- a/packages/schema-converter-shex/test/context.test.ts
+++ b/packages/schema-converter-shex/test/context.test.ts
@@ -9,7 +9,9 @@ describe("context", () => {
const schema: Schema = parser
.construct("https://ldo.js.org/")
.parse(shexc);
+ // console.log("SCHEMA:", JSON.stringify(schema, null, 2));
const context = await shexjToContext(schema);
+ // console.log("CONTEXT:", JSON.stringify(context, null, 2));
expect(context).toEqual(successfulContext);
});
});
diff --git a/packages/schema-converter-shex/test/testData/andSimple.ts b/packages/schema-converter-shex/test/testData/andSimple.ts
new file mode 100644
index 0000000..54010cf
--- /dev/null
+++ b/packages/schema-converter-shex/test/testData/andSimple.ts
@@ -0,0 +1,47 @@
+import type { TestData } from "./testData";
+
+/**
+ * AND SIMPLE
+ */
+export const andSimple: TestData = {
+ name: "andSimple",
+ shexc: `
+ PREFIX ex:
+
+ ex:MediaContainerShape {
+ a [ ex:MediaContainer ];
+ ex:videoImage (@ex:VideoShape AND @ex:ImageShape) ;
+ }
+
+ ex:VideoShape {
+ a [ ex:Video ];
+ }
+
+ ex:ImageShape {
+ a [ ex:Image ];
+ }
+ `,
+ sampleTurtle: "",
+ baseNode: "",
+ successfulContext: {
+ MediaContainer: {
+ "@id": "https://example.com/MediaContainer",
+ "@context": {
+ type: {
+ "@id": "@type",
+ },
+ videoImage: {
+ "@id": "https://example.com/videoImage",
+ "@type": "@id",
+ },
+ },
+ },
+ type: {
+ "@id": "@type",
+ },
+ Video: "https://example.com/Video",
+ Image: "https://example.com/Image",
+ },
+ successfulTypings:
+ 'import {ContextDefinition} from "jsonld"\n\nexport interface MediaContainerShape {\n "@id"?: string;\n "@context"?: ContextDefinition;\n type: {\n "@id": "MediaContainer";\n };\n videoImage: VideoShape & ImageShape;\n}\n\nexport interface VideoShape {\n "@id"?: string;\n "@context"?: ContextDefinition;\n type: {\n "@id": "Video";\n };\n}\n\nexport interface ImageShape {\n "@id"?: string;\n "@context"?: ContextDefinition;\n type: {\n "@id": "Image";\n };\n}\n\n',
+};
diff --git a/packages/schema-converter-shex/test/testData/orSimple.ts b/packages/schema-converter-shex/test/testData/orSimple.ts
new file mode 100644
index 0000000..b23ac84
--- /dev/null
+++ b/packages/schema-converter-shex/test/testData/orSimple.ts
@@ -0,0 +1,53 @@
+import type { TestData } from "./testData";
+
+/**
+ * OR SIMPLE
+ */
+export const orSimple: TestData = {
+ name: "orSimple",
+ shexc: `
+ PREFIX ex:
+
+ ex:MediaContainerShape {
+ a [ ex:MediaContainer ];
+ ex:primaryMedia (@ex:VideoShape OR @ex:ImageShape) ;
+ ex:media (@ex:VideoShape OR @ex:ImageShape) * ;
+ }
+
+ ex:VideoShape {
+ a [ ex:Video ];
+ }
+
+ ex:ImageShape {
+ a [ ex:Image ];
+ }
+ `,
+ sampleTurtle: "",
+ baseNode: "",
+ successfulContext: {
+ MediaContainer: {
+ "@id": "https://example.com/MediaContainer",
+ "@context": {
+ type: {
+ "@id": "@type",
+ },
+ primaryMedia: {
+ "@id": "https://example.com/primaryMedia",
+ "@type": "@id",
+ },
+ media: {
+ "@id": "https://example.com/media",
+ "@type": "@id",
+ "@isCollection": true,
+ },
+ },
+ },
+ type: {
+ "@id": "@type",
+ },
+ Video: "https://example.com/Video",
+ Image: "https://example.com/Image",
+ },
+ successfulTypings:
+ 'import {ContextDefinition} from "jsonld"\n\nexport interface MediaContainerShape {\n "@id"?: string;\n "@context"?: ContextDefinition;\n type: {\n "@id": "MediaContainer";\n };\n primaryMedia: VideoShape | ImageShape;\n media?: (VideoShape | ImageShape)[];\n}\n\nexport interface VideoShape {\n "@id"?: string;\n "@context"?: ContextDefinition;\n type: {\n "@id": "Video";\n };\n}\n\nexport interface ImageShape {\n "@id"?: string;\n "@context"?: ContextDefinition;\n type: {\n "@id": "Image";\n };\n}\n\n',
+};
diff --git a/packages/schema-converter-shex/test/testData/testData.ts b/packages/schema-converter-shex/test/testData/testData.ts
index bf4d599..04dac04 100644
--- a/packages/schema-converter-shex/test/testData/testData.ts
+++ b/packages/schema-converter-shex/test/testData/testData.ts
@@ -7,6 +7,8 @@ import { simple } from "./simple";
import { extendsSimple } from "./extendsSimple";
import { reusedPredicates } from "./reusedPredicates";
import { oldExtends } from "./oldExtends";
+import { orSimple } from "./orSimple";
+import { andSimple } from "./andSimple";
export interface TestData {
name: string;
@@ -26,4 +28,6 @@ export const testData: TestData[] = [
extendsSimple,
oldExtends,
reusedPredicates,
+ orSimple,
+ andSimple,
];
diff --git a/packages/schema-converter-shex/test/typing.test.ts b/packages/schema-converter-shex/test/typing.test.ts
index 6321e26..f9a828e 100644
--- a/packages/schema-converter-shex/test/typing.test.ts
+++ b/packages/schema-converter-shex/test/typing.test.ts
@@ -9,7 +9,10 @@ describe("typing", () => {
const schema: Schema = parser
.construct("https://ldo.js.org/")
.parse(shexc);
+ // console.log("SCHEMA:", JSON.stringify(schema, null, 2));
const [typings] = await shexjToTyping(schema);
+ // console.log(typings.typingsString);
+ // console.log(JSON.stringify(typings.typingsString));
expect(typings.typingsString).toBe(successfulTypings);
});
});