diff --git a/src/shacl.ts b/src/shacl.ts index 9e8d7b4..47c90f3 100644 --- a/src/shacl.ts +++ b/src/shacl.ts @@ -11,7 +11,7 @@ import { unique, } from "./lens"; -import { DataFactory } from "rdf-data-factory"; +import { DataFactory, NamedNode } from "rdf-data-factory"; import { RDFL, RDFS, SHACL } from "./ontology"; const { literal } = new DataFactory(); @@ -156,9 +156,7 @@ export const ShaclAlternativepath: BasicLens< export const ShaclPredicatePath: BasicLens< Cont, BasicLensM -> = new BasicLens((c) => { - return pred(c.id); -}); +> = extractLeaf(XSD.terms.custom("iri")).map(pred); export const ShaclInversePath: BasicLens> = pred( SHACL.inversePath, @@ -289,6 +287,9 @@ function dataTypeToExtract(dataType: Term, t: Term): unknown { if (dataType.equals(XSD.terms.string)) return t.value; if (dataType.equals(XSD.terms.dateTime)) return new Date(t.value); if (dataType.equals(XSD.terms.custom("boolean"))) return t.value === "true"; + if (dataType.equals(XSD.terms.custom("iri"))) return new NamedNode(t.value); + if (dataType.equals(XSD.terms.custom("anyURI"))) + return new NamedNode(t.value); return t; } @@ -341,6 +342,12 @@ function envLens(dataType: Term): BasicLens { }); } +function extractLeaf(datatype: Term): BasicLens { + return envLens(datatype).or( + empty().map((item) => dataTypeToExtract(datatype, item.id)), + ); +} + function extractProperty( cache: Cache, _subClasses: SubClasses, @@ -360,9 +367,7 @@ function extractProperty( pred(SHACL.datatype) .one() .map(({ id }) => ({ - extract: envLens(id).or( - empty().map((item) => dataTypeToExtract(id, item.id)), - ), + extract: extractLeaf(id), })); const clazzLens: BasicLens = diff --git a/test/shacl2.test.ts b/test/shacl2.test.ts index ee890e0..9bac7c9 100644 --- a/test/shacl2.test.ts +++ b/test/shacl2.test.ts @@ -4,6 +4,7 @@ import { RDF } from "@treecg/types"; import { Parser } from "n3"; import { extractShapes } from "../src/shacl"; import { RDFL } from "../src/ontology"; +import { BasicLensM, Cont } from "../src"; const prefixes = ` @prefix js: . @@ -457,4 +458,110 @@ ${prefixes} expect(obj.custom.value).toBe("VALUE"); }); }); + + describe("Extract path from env variable", () => { + const shape = ` +${prefixes} + +[] a sh:NodeShape; + sh:targetClass js:Point; + sh:property [ + sh:datatype xsd:string; + sh:path ; + sh:name "str"; + sh:maxCount 1; + ], [ + sh:class rdfl:PathLens; + sh:path ; + sh:name "path"; + sh:maxCount 1; + ], [ + sh:class rdfl:PathLens; + sh:path ; + sh:name "path2"; + sh:maxCount 1; + ], [ + sh:class rdfl:PathLens; + sh:path ; + sh:name "complex"; + sh:maxCount 1; + ]. +`; + const data = ` +${prefixes} + a js:Point; + js:generatedAtTime 42; + 43; + [ + js:generatedAtTime 45; + ]; + [ + a rdfl:EnvVariable; + rdfl:envDefault js:generatedAtTime; + rdfl:envKey "envworks" + ]; + [ + a rdfl:EnvVariable; + rdfl:envDefault js:generatedAtTime; + rdfl:envKey "test" + ]; + [ + a rdfl:EnvVariable; + rdfl:envDefault js:generatedAtTime; + rdfl:envKey "notset" + ]; + ([ + a rdfl:EnvVariable; + rdfl:envDefault js:generatedAtTime; + rdfl:envKey "test2" + ] + [ + a rdfl:EnvVariable; + rdfl:envDefault js:generatedAtTime; + rdfl:envKey "notset" + ] +). +`; + + const output = extractShapes(parseQuads(shape)); + const quads = parseQuads(data); + + process.env["envworks"] = "true"; + process.env["test"] = "testpred"; + process.env["test2"] = "entry"; + + const quad = quads.find((x) => x.predicate.equals(RDF.terms.type))!; + const start = { + id: quad.subject, + quads, + }; + + const obj = < + { + str: string; + path: BasicLensM; + path2: BasicLensM; + complex: BasicLensM; + } + >output.lenses[quad.object.value].execute(start, []); + + test("From env variable that is set", () => { + const path1 = obj.path.execute(start).map((x) => x.id.value); + expect(path1).toEqual(["43"]); + }); + + test("From env variable that is not set", () => { + const path2 = obj.path2.execute(start).map((x) => x.id.value); + expect(path2).toEqual(["42"]); + }); + + test("Works in complex paths", () => { + const path2 = obj.complex.execute(start).map((x) => x.id.value); + expect(path2).toEqual(["45"]); + }); + + test("Check if process.env.VAR is the way", () => { + expect(obj.str).toBe("true"); + }); + }); });