@@ -300,3 +300,60 @@ declare function hent:fix-tde($nodes as node()*, $entity-model-contexts as xs:st
300300 )
301301 default return $n
302302};
303+
304+ declare variable $number-types as xs:string+ := ("byte" ,"decimal" ,"double" ,"float" ,"int" ,"integer" ,"long" ,"negativeInteger" ,"nonNegativeInteger" ,"nonPositiveInteger" ,"positiveInteger" ,"short" ,"unsignedLong" ,"unsignedInt" ,"unsignedShort" ,"unsignedByte" );
305+ declare variable $string-types as xs:string+ := "dateTime" ;
306+
307+ declare function hent:json-schema-generate ($entity-title as xs:string, $uber-model as map:map)
308+ {
309+ let $uber-model := map:new ((
310+ (: Ensure we're not change a map for anyone else :)
311+ map:map (document {$uber-model}/*),
312+ map:entry ("language" , "zxx" ),
313+ map:entry ("$schema" , "http://json-schema.org/draft-07/schema#" )
314+ ))
315+ let $definitions := $uber-model => map:get ("definitions" )
316+ (: JSON Schema needs an extra level of wrapping to account for Entity Model label wrapping it. :)
317+ let $_nest-refs :=
318+ for $definition-type in map:keys ($definitions)
319+ let $definition-properties := $definitions => map:get ($definition-type) => map:get ("properties" )
320+ for $property-name in map:keys ($definition-properties)
321+ let $property := $definition-properties => map:get ($property-name)
322+ let $property-items := $property => map:get ("items" )
323+ let $datatype := $property => map:get ("datatype" )
324+ let $_set-types := (
325+ $property => map:put ("type" , if ($datatype = $number-types) then "number" else if ($datatype = $string-types) then "string" else $datatype),
326+ $property => map:delete ("datatype" ),
327+ if ($property-items instance of map:map) then (
328+ let $items-datatype := $property => map:get ("datatype" )
329+ return (
330+ $property-items => map:put ("type" , if ($items-datatype = $number-types) then "number" else if ($items-datatype = $string-types) then "string" else $datatype),
331+ $property-items => map:delete ("datatype" ))
332+ ) else ()
333+ )
334+ return
335+ (: references can be in the property or in items for arrays :)
336+ if ($property => map:contains ("$ref" )) then
337+ map:put ($definition-properties, $property-name,
338+ map:new ((
339+ map:entry ("type" , "object" ),
340+ map:entry ("properties" ,
341+ map:entry (fn:tokenize (map:get ($property,"$ref" ),"/" )[fn:last ()], $property)
342+ )
343+ ))
344+ )
345+ else if ($property-items instance of map:map and $property-items => map:contains ("$ref" )) then
346+ map:put ($property, "items" ,
347+ map:new ((
348+ map:entry ("type" , "object" ),
349+ map:entry ("properties" ,
350+ map:entry (fn:tokenize (map:get ($property-items,"$ref" ),"/" )[fn:last ()], $property-items)
351+ )
352+ ))
353+ )
354+ else ()
355+ let $_set-info := (
356+ $uber-model => map:put ("properties" , map:entry ($entity-title, map:entry ("$ref" , "#/definitions/" ||$entity-title)))
357+ )
358+ return xdmp:to-json ($uber-model)
359+ };
0 commit comments