main
Laurin Weger 2 weeks ago
parent 3188733329
commit 3f73d6267a
No known key found for this signature in database
GPG Key ID: 9B372BB0B792770F
  1. 76
      packages/schema-converter-shex/src/schema/ShexJSchemaTransformerCompact.ts
  2. 6
      packages/schema-converter-shex/src/typing/shexjToTypingCompact.ts

@ -2,23 +2,34 @@ import type { ObjectLiteral } from "@ldo/traverser-shexj";
import ShexJTraverser from "@ldo/traverser-shexj";
export interface CompactShape {
schemaUri: string;
iri: string;
predicates: CompactSchemaProperty[];
}
type NodeConstraintRet = {
type CompactSchemaValue = {
literals?: number[] | string[] | boolean;
type: "number" | "string" | "boolean" | "literal";
};
interface CompactSchemaProperty {
type: "number" | "string" | "boolean" | "nested" | "literal";
/** Type of property. */
type: "number" | "string" | "boolean" | "literal" | "nested" | "eitherOf";
/** The RDF predicate URI. */
predicateUri: string;
/** The alias of the `predicateUri` when serialized to a JSON object. */
readablePredicate: string;
/** The required literal value(s), if type is `literal`. Others are allowed, if `extra` is true. */
literalValue?: number | string | boolean | number[] | string[];
/** If type is `nested`, the shape or its IRI. */
nestedSchema?: string | CompactShape;
/** Maximum allowed number of values. `-1` means infinite. */
maxCardinality: number;
/** Minimum required number of values */
minCardinality: number;
/** If type is `eitherOf`, specifies multiple allowed types (CompactSchemaValue, shapes, or shape IRI). */
eitherOf?: (CompactSchemaValue | CompactShape | string)[];
/** If other (additional) values are permitted. Useful for literals. */
extra?: boolean;
}
export const ShexJSchemaTransformerCompact = ShexJTraverser.createTransformer<
@ -28,15 +39,14 @@ export const ShexJSchemaTransformerCompact = ShexJTraverser.createTransformer<
Shape: { return: CompactShape };
EachOf: { return: CompactShape };
TripleConstraint: { return: CompactSchemaProperty };
NodeConstraint: { return: NodeConstraintRet };
ShapeOr: { return: never };
NodeConstraint: { return: CompactSchemaValue };
ShapeOr: { return: (CompactSchemaValue | CompactShape | string)[] };
ShapeAnd: { return: never };
ShapeNot: { return: never };
ShapeExternal: { return: never };
},
null
>({
// Transformer from Schema to interfaces
Schema: {
transformer: async (_schema, getTransformedChildren) => {
const transformedChildren = await getTransformedChildren();
@ -45,35 +55,41 @@ export const ShexJSchemaTransformerCompact = ShexJTraverser.createTransformer<
},
},
// Transformer from ShapeDecl to interface
ShapeDecl: {
transformer: async (shapeDecl, getTransformedChildren) => {
const schema = await getTransformedChildren();
const shape = schema.shapeExpr as CompactShape;
return { ...schema.shapeExpr, schemaUri: shapeDecl.id } as CompactShape;
return { ...shape, iri: shapeDecl.id } as CompactShape;
},
},
// Transformer from Shape to interface
Shape: {
transformer: async (_shape, getTransformedChildren, setReturnPointer) => {
transformer: async (_shape, getTransformedChildren) => {
// TODO: We don't handles those
_shape.closed;
_shape.extra;
const transformedChildren = await getTransformedChildren();
// Return prelim or expression or assign things?
return transformedChildren.expression as CompactShape;
const compactShape = transformedChildren.expression as CompactShape;
for (const extra of _shape.extra || []) {
const extraPredicate = compactShape.predicates.find(
(p) => p.predicateUri === extra,
);
if (extraPredicate) extraPredicate.extra = true;
}
return compactShape;
},
},
// Transformer from EachOf to object type. EachOf contains the `expressions` array of properties (TripleConstraint)
// EachOf contains the `expressions` array of properties (TripleConstraint)
EachOf: {
transformer: async (eachOf, getTransformedChildren, setReturnPointer) => {
transformer: async (eachOf, getTransformedChildren) => {
const transformedChildren = await getTransformedChildren();
return {
schemaUri: "",
iri: "",
predicates: transformedChildren.expressions.map(
// We disregard cases where properties are referenced (strings)
// or where they consist of Unions or Intersections (not supported).
@ -83,7 +99,6 @@ export const ShexJSchemaTransformerCompact = ShexJTraverser.createTransformer<
},
},
// Transformer from triple constraints to type properties.
TripleConstraint: {
transformer: async (
tripleConstraint,
@ -116,10 +131,16 @@ export const ShexJSchemaTransformerCompact = ShexJTraverser.createTransformer<
nestedSchema: transformedChildren.valueExpr as CompactShape,
...commonProperties,
} satisfies CompactSchemaProperty;
} else if (Array.isArray(transformedChildren.valueExpr)) {
return {
type: "eitherOf",
eitherOf: transformedChildren.valueExpr,
...commonProperties,
};
} else {
// type or literal
const nodeConstraint =
transformedChildren.valueExpr as NodeConstraintRet;
transformedChildren.valueExpr as CompactSchemaValue;
return {
type: nodeConstraint.type,
literalValue: nodeConstraint.literals,
@ -129,7 +150,6 @@ export const ShexJSchemaTransformerCompact = ShexJTraverser.createTransformer<
},
},
// Transformer from node constraint to type
NodeConstraint: {
transformer: async (nodeConstraint) => {
if (nodeConstraint.datatype) {
@ -179,28 +199,34 @@ export const ShexJSchemaTransformerCompact = ShexJTraverser.createTransformer<
},
},
// Transformer from ShapeOr to union type
// Transformer from ShapeOr
ShapeOr: {
transformer: async () => {
throw new Error("ShapeOr not supported (compact)");
transformer: async (shapeOr, getTransformedChildren) => {
const tc = await getTransformedChildren();
// Either a shape IRI, a nested shape or a node CompactSchemaValue (node constraint).
return (Array.isArray(tc) ? tc : [tc]) as (
| string
| CompactShape
| CompactSchemaValue
)[];
},
},
// Transformer from ShapeAnd to intersection type
// Transformer from ShapeAnd
ShapeAnd: {
transformer: async () => {
throw new Error("ShapeAnd not supported (compact)");
},
},
// Transformer from ShapeNot to type - not supported.
// Transformer from ShapeNot - not supported.
ShapeNot: {
transformer: async () => {
throw new Error("ShapeNot not supported (compact)");
},
},
// Transformer from ShapeExternal to type - not supported.
// Transformer from ShapeExternal - not supported.
ShapeExternal: {
transformer: async () => {
throw new Error("ShapeExternal not supported (compact)");

@ -69,7 +69,7 @@ function flattenSchema(shapes: CompactShape[]): CompactSchema {
let schema: CompactSchema = {};
for (const shape of shapes) {
schema[shape.schemaUri] = shape;
schema[shape.iri] = shape;
// Find nested, unflattened (i.e. anonymous) schemas in properties.
const nestedSchemaPredicates = shape.predicates.filter(
@ -77,13 +77,13 @@ function flattenSchema(shapes: CompactShape[]): CompactSchema {
);
for (const pred of nestedSchemaPredicates) {
const newId = shape.schemaUri + "::" + pred.predicateUri;
const newId = shape.iri + "||" + pred.predicateUri;
// Recurse
const flattened = flattenSchema([
{
...(pred.nestedSchema as CompactShape),
schemaUri: newId,
iri: newId,
},
]);
// Replace the nested schema with its new id.

Loading…
Cancel
Save