|
|
@ -13,11 +13,11 @@ export interface CompactTransformerContext { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function commentFromAnnotations( |
|
|
|
function commentFromAnnotations( |
|
|
|
annotations?: Annotation[], |
|
|
|
annotations?: Annotation[] |
|
|
|
): string | undefined { |
|
|
|
): string | undefined { |
|
|
|
const commentAnnotationObject = annotations?.find( |
|
|
|
const commentAnnotationObject = annotations?.find( |
|
|
|
(annotation) => |
|
|
|
(annotation) => |
|
|
|
annotation.predicate === "http://www.w3.org/2000/01/rdf-schema#comment", |
|
|
|
annotation.predicate === "http://www.w3.org/2000/01/rdf-schema#comment" |
|
|
|
)?.object; |
|
|
|
)?.object; |
|
|
|
if (typeof commentAnnotationObject === "string") |
|
|
|
if (typeof commentAnnotationObject === "string") |
|
|
|
return commentAnnotationObject; |
|
|
|
return commentAnnotationObject; |
|
|
@ -44,6 +44,18 @@ function isPrimitiveLike(t: dom.Type): boolean { |
|
|
|
return intrinsicKinds.has(kind || ""); |
|
|
|
return intrinsicKinds.has(kind || ""); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function normalizeAnonymousInterface(t: dom.Type): dom.Type { |
|
|
|
|
|
|
|
if ( |
|
|
|
|
|
|
|
(t as dom.InterfaceDeclaration).kind === "interface" && |
|
|
|
|
|
|
|
!(t as dom.InterfaceDeclaration).name |
|
|
|
|
|
|
|
) { |
|
|
|
|
|
|
|
return dom.create.objectType( |
|
|
|
|
|
|
|
(t as dom.InterfaceDeclaration).members as dom.PropertyDeclaration[] |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return t; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Property name collision resolution using predicate IRI mapping
|
|
|
|
// Property name collision resolution using predicate IRI mapping
|
|
|
|
const predicateIriByProp = new WeakMap<dom.PropertyDeclaration, string>(); |
|
|
|
const predicateIriByProp = new WeakMap<dom.PropertyDeclaration, string>(); |
|
|
|
/** |
|
|
|
/** |
|
|
@ -85,7 +97,7 @@ function resolveCollisions(props: dom.PropertyDeclaration[]): void { |
|
|
|
// Detect any remaining duplicates after first pass
|
|
|
|
// Detect any remaining duplicates after first pass
|
|
|
|
const nameCounts = new Map<string, number>(); |
|
|
|
const nameCounts = new Map<string, number>(); |
|
|
|
list.forEach((p) => |
|
|
|
list.forEach((p) => |
|
|
|
nameCounts.set(p.name, (nameCounts.get(p.name) || 0) + 1), |
|
|
|
nameCounts.set(p.name, (nameCounts.get(p.name) || 0) + 1) |
|
|
|
); |
|
|
|
); |
|
|
|
list.forEach((p) => { |
|
|
|
list.forEach((p) => { |
|
|
|
if (nameCounts.get(p.name)! > 1) { |
|
|
|
if (nameCounts.get(p.name)! > 1) { |
|
|
@ -102,7 +114,7 @@ function resolveCollisions(props: dom.PropertyDeclaration[]): void { |
|
|
|
// - if both are Set<A>, Set<B> -> Set<A|B>
|
|
|
|
// - if both are Set<A>, Set<B> -> Set<A|B>
|
|
|
|
// - preserve optional flag if any occurrence optional
|
|
|
|
// - preserve optional flag if any occurrence optional
|
|
|
|
function dedupeCompactProperties( |
|
|
|
function dedupeCompactProperties( |
|
|
|
props: dom.PropertyDeclaration[], |
|
|
|
props: dom.PropertyDeclaration[] |
|
|
|
): dom.PropertyDeclaration[] { |
|
|
|
): dom.PropertyDeclaration[] { |
|
|
|
const byName: Record<string, dom.PropertyDeclaration> = {}; |
|
|
|
const byName: Record<string, dom.PropertyDeclaration> = {}; |
|
|
|
const isSetRef = (t: dom.Type): t is dom.NamedTypeReference => |
|
|
|
const isSetRef = (t: dom.Type): t is dom.NamedTypeReference => |
|
|
@ -161,7 +173,7 @@ function dedupeCompactProperties( |
|
|
|
let mergedType: dom.Type; |
|
|
|
let mergedType: dom.Type; |
|
|
|
if (existingSet && newSet) { |
|
|
|
if (existingSet && newSet) { |
|
|
|
mergedType = toSet( |
|
|
|
mergedType = toSet( |
|
|
|
makeUnion(getSetInner(existing.type), getSetInner(p.type)), |
|
|
|
makeUnion(getSetInner(existing.type), getSetInner(p.type)) |
|
|
|
); |
|
|
|
); |
|
|
|
} else if (existingSet && !newSet) { |
|
|
|
} else if (existingSet && !newSet) { |
|
|
|
mergedType = toSet(makeUnion(getSetInner(existing.type), p.type)); |
|
|
|
mergedType = toSet(makeUnion(getSetInner(existing.type), p.type)); |
|
|
@ -233,21 +245,21 @@ export const ShexJTypingTransformerCompact = ShexJTraverser.createTransformer< |
|
|
|
shapeInterface.shapeId = shapeDecl.id; |
|
|
|
shapeInterface.shapeId = shapeDecl.id; |
|
|
|
if ( |
|
|
|
if ( |
|
|
|
!shapeInterface.members.find( |
|
|
|
!shapeInterface.members.find( |
|
|
|
(m) => m.kind === "property" && m.name === "id", |
|
|
|
(m) => m.kind === "property" && m.name === "id" |
|
|
|
) |
|
|
|
) |
|
|
|
) { |
|
|
|
) { |
|
|
|
shapeInterface.members.unshift( |
|
|
|
shapeInterface.members.unshift( |
|
|
|
dom.create.property( |
|
|
|
dom.create.property( |
|
|
|
"id", |
|
|
|
"id", |
|
|
|
dom.create.namedTypeReference("IRI"), |
|
|
|
dom.create.namedTypeReference("IRI"), |
|
|
|
dom.DeclarationFlags.Optional, |
|
|
|
dom.DeclarationFlags.Optional |
|
|
|
), |
|
|
|
) |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
return shapeInterface; |
|
|
|
return shapeInterface; |
|
|
|
} |
|
|
|
} |
|
|
|
throw new Error( |
|
|
|
throw new Error( |
|
|
|
"Unsupported direct shape expression on ShapeDecl for compact format.", |
|
|
|
"Unsupported direct shape expression on ShapeDecl for compact format." |
|
|
|
); |
|
|
|
); |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
@ -266,14 +278,14 @@ export const ShexJTypingTransformerCompact = ShexJTraverser.createTransformer< |
|
|
|
"interface") |
|
|
|
"interface") |
|
|
|
) { |
|
|
|
) { |
|
|
|
newInterface.members.push( |
|
|
|
newInterface.members.push( |
|
|
|
...(transformedChildren.expression as dom.ObjectType).members, |
|
|
|
...(transformedChildren.expression as dom.ObjectType).members |
|
|
|
); |
|
|
|
); |
|
|
|
} else if ( |
|
|
|
} else if ( |
|
|
|
(transformedChildren.expression as dom.PropertyDeclaration)?.kind === |
|
|
|
(transformedChildren.expression as dom.PropertyDeclaration)?.kind === |
|
|
|
"property" |
|
|
|
"property" |
|
|
|
) { |
|
|
|
) { |
|
|
|
newInterface.members.push( |
|
|
|
newInterface.members.push( |
|
|
|
transformedChildren.expression as dom.PropertyDeclaration, |
|
|
|
transformedChildren.expression as dom.PropertyDeclaration |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
if (transformedChildren.extends) { |
|
|
|
if (transformedChildren.extends) { |
|
|
@ -282,11 +294,11 @@ export const ShexJTypingTransformerCompact = ShexJTraverser.createTransformer< |
|
|
|
if (extInt.kind === "interface") { |
|
|
|
if (extInt.kind === "interface") { |
|
|
|
const merged = [ |
|
|
|
const merged = [ |
|
|
|
...extInt.members.filter( |
|
|
|
...extInt.members.filter( |
|
|
|
(m) => !(m.kind === "property" && m.name === "id"), |
|
|
|
(m) => !(m.kind === "property" && m.name === "id") |
|
|
|
), |
|
|
|
), |
|
|
|
...newInterface.members, |
|
|
|
...newInterface.members, |
|
|
|
].filter( |
|
|
|
].filter( |
|
|
|
(m): m is dom.PropertyDeclaration => m.kind === "property", |
|
|
|
(m): m is dom.PropertyDeclaration => m.kind === "property" |
|
|
|
); |
|
|
|
); |
|
|
|
newInterface.members = dedupeCompactProperties(merged); |
|
|
|
newInterface.members = dedupeCompactProperties(merged); |
|
|
|
} |
|
|
|
} |
|
|
@ -331,7 +343,7 @@ export const ShexJTypingTransformerCompact = ShexJTraverser.createTransformer< |
|
|
|
if ((m as any).kind === "property") { |
|
|
|
if ((m as any).kind === "property") { |
|
|
|
inputProps.push(m as dom.PropertyDeclaration); |
|
|
|
inputProps.push(m as dom.PropertyDeclaration); |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
} |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
@ -349,13 +361,13 @@ export const ShexJTypingTransformerCompact = ShexJTraverser.createTransformer< |
|
|
|
getTransformedChildren, |
|
|
|
getTransformedChildren, |
|
|
|
_setReturnPointer, |
|
|
|
_setReturnPointer, |
|
|
|
node, |
|
|
|
node, |
|
|
|
context, |
|
|
|
context |
|
|
|
) => { |
|
|
|
) => { |
|
|
|
const transformedChildren = await getTransformedChildren(); |
|
|
|
const transformedChildren = await getTransformedChildren(); |
|
|
|
const rdfTypes = getRdfTypesForTripleConstraint(node); |
|
|
|
const rdfTypes = getRdfTypesForTripleConstraint(node); |
|
|
|
const baseName = context.getNameFromIri( |
|
|
|
const baseName = context.getNameFromIri( |
|
|
|
tripleConstraint.predicate, |
|
|
|
tripleConstraint.predicate, |
|
|
|
rdfTypes[0], |
|
|
|
rdfTypes[0] |
|
|
|
); |
|
|
|
); |
|
|
|
const max = tripleConstraint.max; |
|
|
|
const max = tripleConstraint.max; |
|
|
|
const isPlural = max === -1 || (max !== undefined && max !== 1); |
|
|
|
const isPlural = max === -1 || (max !== undefined && max !== 1); |
|
|
@ -365,6 +377,16 @@ export const ShexJTypingTransformerCompact = ShexJTraverser.createTransformer< |
|
|
|
if (transformedChildren.valueExpr) |
|
|
|
if (transformedChildren.valueExpr) |
|
|
|
valueType = transformedChildren.valueExpr as dom.Type; |
|
|
|
valueType = transformedChildren.valueExpr as dom.Type; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( |
|
|
|
|
|
|
|
(valueType as dom.InterfaceDeclaration).kind === "interface" && |
|
|
|
|
|
|
|
!(valueType as dom.InterfaceDeclaration).name |
|
|
|
|
|
|
|
) { |
|
|
|
|
|
|
|
valueType = dom.create.objectType( |
|
|
|
|
|
|
|
(valueType as dom.InterfaceDeclaration) |
|
|
|
|
|
|
|
.members as dom.PropertyDeclaration[] |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Normalize NodeConstraint returned object forms for IRIs into IRI
|
|
|
|
// Normalize NodeConstraint returned object forms for IRIs into IRI
|
|
|
|
// Heuristic: existing transformer (compact) returns string/number/boolean OR object/interface.
|
|
|
|
// Heuristic: existing transformer (compact) returns string/number/boolean OR object/interface.
|
|
|
|
// We treat any simple string/number/boolean/name as primitive.
|
|
|
|
// We treat any simple string/number/boolean/name as primitive.
|
|
|
@ -389,7 +411,7 @@ export const ShexJTypingTransformerCompact = ShexJTraverser.createTransformer< |
|
|
|
const hasPrim = u.members.some(isPrimitiveLike); |
|
|
|
const hasPrim = u.members.some(isPrimitiveLike); |
|
|
|
if (isPlural && hasObj && hasPrim) { |
|
|
|
if (isPlural && hasObj && hasPrim) { |
|
|
|
throw new Error( |
|
|
|
throw new Error( |
|
|
|
`Mixed plural union (object + primitive) not supported for predicate ${tripleConstraint.predicate}`, |
|
|
|
`Mixed plural union (object + primitive) not supported for predicate ${tripleConstraint.predicate}` |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -426,15 +448,15 @@ export const ShexJTypingTransformerCompact = ShexJTraverser.createTransformer< |
|
|
|
m as unknown as { members?: dom.PropertyDeclaration[] } |
|
|
|
m as unknown as { members?: dom.PropertyDeclaration[] } |
|
|
|
).members; |
|
|
|
).members; |
|
|
|
const hasId = (anonMembers || []).some( |
|
|
|
const hasId = (anonMembers || []).some( |
|
|
|
(mm) => mm.name === "id", |
|
|
|
(mm) => mm.name === "id" |
|
|
|
); |
|
|
|
); |
|
|
|
if (!hasId && anonMembers) { |
|
|
|
if (!hasId && anonMembers) { |
|
|
|
anonMembers.unshift( |
|
|
|
anonMembers.unshift( |
|
|
|
dom.create.property( |
|
|
|
dom.create.property( |
|
|
|
"id", |
|
|
|
"id", |
|
|
|
dom.create.namedTypeReference("IRI"), |
|
|
|
dom.create.namedTypeReference("IRI"), |
|
|
|
dom.DeclarationFlags.Optional, |
|
|
|
dom.DeclarationFlags.Optional |
|
|
|
), |
|
|
|
) |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -452,8 +474,8 @@ export const ShexJTypingTransformerCompact = ShexJTraverser.createTransformer< |
|
|
|
dom.create.property( |
|
|
|
dom.create.property( |
|
|
|
"id", |
|
|
|
"id", |
|
|
|
dom.create.namedTypeReference("IRI"), |
|
|
|
dom.create.namedTypeReference("IRI"), |
|
|
|
dom.DeclarationFlags.Optional, |
|
|
|
dom.DeclarationFlags.Optional |
|
|
|
), |
|
|
|
) |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
valueForRecord = anon as dom.Type; |
|
|
|
valueForRecord = anon as dom.Type; |
|
|
@ -481,7 +503,7 @@ export const ShexJTypingTransformerCompact = ShexJTraverser.createTransformer< |
|
|
|
(valueType as dom.InterfaceDeclaration).name |
|
|
|
(valueType as dom.InterfaceDeclaration).name |
|
|
|
) { |
|
|
|
) { |
|
|
|
finalType = dom.create.namedTypeReference( |
|
|
|
finalType = dom.create.namedTypeReference( |
|
|
|
(valueType as dom.InterfaceDeclaration).name, |
|
|
|
(valueType as dom.InterfaceDeclaration).name |
|
|
|
); |
|
|
|
); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
finalType = valueType; |
|
|
|
finalType = valueType; |
|
|
@ -491,7 +513,7 @@ export const ShexJTypingTransformerCompact = ShexJTraverser.createTransformer< |
|
|
|
const prop = dom.create.property( |
|
|
|
const prop = dom.create.property( |
|
|
|
baseName, |
|
|
|
baseName, |
|
|
|
finalType, |
|
|
|
finalType, |
|
|
|
isOptional ? dom.DeclarationFlags.Optional : dom.DeclarationFlags.None, |
|
|
|
isOptional ? dom.DeclarationFlags.Optional : dom.DeclarationFlags.None |
|
|
|
); |
|
|
|
); |
|
|
|
predicateIriByProp.set(prop, tripleConstraint.predicate); |
|
|
|
predicateIriByProp.set(prop, tripleConstraint.predicate); |
|
|
|
prop.jsDocComment = |
|
|
|
prop.jsDocComment = |
|
|
|