@@ -588,6 +588,37 @@ export function getSortedSchemas(graph: SchemaDirectedGraph): JSONSchema.Interfa
588588 return sortedVertices . map ( ( vertex ) => vertex . data || { } ) . reverse ( ) ;
589589}
590590
591+ export function layerSchemas ( sortedSchemas : JSONSchema . Interface [ ] , layerOrder : string [ ] ) : void {
592+ const schemasByLayer = sortedSchemas . reduce < Record < string , JSONSchema . Interface [ ] > > ( ( acc , jsonSchema ) => {
593+ const layerName = jsonSchema . $id ?. includes ( 'schema.kickstartds.com' )
594+ ? 'kickstartds'
595+ : jsonSchema . $id ?. split ( '//' ) [ 1 ] . split ( '.' ) [ 0 ] ;
596+ if ( ! layerName )
597+ throw new Error ( `Failed to get layer name from schema $id ${ jsonSchema . $id } for layering` ) ;
598+ if ( ! layerOrder . includes ( layerName ) )
599+ throw new Error ( `Layer name ${ layerName } not included in layer order: ${ layerOrder } ` ) ;
600+
601+ if ( ! acc [ layerName ] ) acc [ layerName ] = [ ] ;
602+ acc [ layerName ] . push ( jsonSchema ) ;
603+
604+ return acc ;
605+ } , { } ) ;
606+
607+ for ( const layer of layerOrder ) {
608+ if ( layerOrder . indexOf ( layer ) === layerOrder . length - 1 ) continue ;
609+ if ( ! schemasByLayer [ layer ] || schemasByLayer [ layer ] . length < 1 ) continue ;
610+
611+ for ( const deeperLayer of layerOrder . slice ( layerOrder . indexOf ( layer ) + 1 ) . reverse ( ) ) {
612+ layerRefs (
613+ schemasByLayer [ layer ] ,
614+ schemasByLayer [ deeperLayer ] . filter (
615+ ( schema ) => ! schemasByLayer [ layer ] . some ( ( s ) => s . $id === schema . $id )
616+ )
617+ ) ;
618+ }
619+ }
620+ }
621+
591622export interface IProcessingOptions {
592623 typeResolution : boolean ;
593624 modules : string [ ] ;
@@ -600,6 +631,7 @@ export interface IProcessingOptions {
600631 addExplicitAnyOfs : boolean ;
601632 replaceExamples : boolean ;
602633 hideCmsFields : boolean ;
634+ layerOrder : string [ ] ;
603635}
604636
605637export const defaultProcessingOptions : IProcessingOptions = {
@@ -613,7 +645,8 @@ export const defaultProcessingOptions: IProcessingOptions = {
613645 inlineReferences : true ,
614646 addExplicitAnyOfs : true ,
615647 replaceExamples : true ,
616- hideCmsFields : false
648+ hideCmsFields : false ,
649+ layerOrder : [ 'cms' , 'schema' , 'kickstartds' ]
617650} ;
618651
619652export async function processSchemaGlob (
@@ -655,7 +688,8 @@ export async function processSchemas(
655688 inlineReferences : shouldInlineReferences ,
656689 addExplicitAnyOfs : shouldAddExlicitAnyOfs ,
657690 replaceExamples : shouldReplaceExamples ,
658- hideCmsFields : shouldHideCmsFields
691+ hideCmsFields : shouldHideCmsFields ,
692+ layerOrder
659693 } = { ...defaultProcessingOptions , ...options } ;
660694 // Load all the schema files provided by `@kickstartDS` itself...
661695 const kdsSchemas =
@@ -684,20 +718,11 @@ export async function processSchemas(
684718 ( value : JSONSchema . Interface , index , self ) => self . findIndex ( ( v ) => v . $id === value . $id ) === index
685719 ) ;
686720 const sortedSchemas = getSortedSchemas ( getSchemaGraph ( allSchemas ) ) ;
687- const cmsSchemas = sortedSchemas . filter ( ( sortedSchema ) => sortedSchema . $id ?. startsWith ( 'http://cms.' ) ) ;
688721
689722 // Processing consists of 5 steps currently, that need to be run in this
690723 // exact order, because every step builds on the one before it
691724 // 1. pre-process, before schemas enter `ajv`
692- if ( shouldLayerRefs ) {
693- layerRefs ( cmsSchemas , kdsSchemas ) ;
694- layerRefs (
695- cmsSchemas ,
696- jsonSchemas . filter ( ( schema ) => ! cmsSchemas . some ( ( cmsSchema ) => cmsSchema . $id === schema . $id ) )
697- ) ;
698- layerRefs ( jsonSchemas , kdsSchemas ) ;
699- }
700-
725+ if ( shouldLayerRefs ) layerSchemas ( sortedSchemas , layerOrder ) ;
701726 if ( typeResolution ) addTypeInterfaces ( sortedSchemas ) ;
702727 if ( shouldInlineReferences ) inlineReferences ( sortedSchemas , typeResolution ) ;
703728 if ( additionalProperties && additionalProperties !== 'keep' )
@@ -728,6 +753,7 @@ export async function processSchemas(
728753 reduceSchemaAllOfs ( schemaAnyOf , ajv , shouldReplaceExamples ) ;
729754 } ) ;
730755 if ( shouldHideCmsFields ) hideCmsFields ( sortedSchemas ) ;
756+ if ( shouldHideCmsFields ) hideCmsFields ( schemaAnyOfs ) ;
731757
732758 // 5. return list of processed schema `$id`s.
733759 // Accessing the full schemas works through `ajv`
0 commit comments