@@ -4,8 +4,9 @@ import { JsonPath, Optional } from '@stoplight/types';
44import { JSONSchema4 } from 'json-schema' ;
55import { get as _get , isEqual as _isEqual , isObject as _isObject } from 'lodash' ;
66import { ResolvingError } from '../errors' ;
7- import { ViewMode } from '../types' ;
8- import { hasRefItems , isRefNode } from '../utils/guards' ;
7+ import { IArrayNode , IObjectNode , SchemaKind , SchemaNode , ViewMode } from '../types' ;
8+ import { hasRefItems , isArrayNodeWithItems , isCombinerNode , isRefNode } from '../utils/guards' ;
9+ import { inferType } from '../utils/inferType' ;
910import { getSchemaNodeMetadata } from './metadata' ;
1011import { canStepIn } from './utils/canStepIn' ;
1112import { createErrorTreeNode } from './utils/createErrorTreeNode' ;
@@ -50,16 +51,45 @@ export class SchemaTree extends Tree {
5051
5152 protected readonly visited = new WeakSet ( ) ;
5253
54+ protected isViewModeRespected = ( fragment : JSONSchema4 ) => {
55+ return ! (
56+ ! ! fragment . writeOnly !== ! ! fragment . readOnly &&
57+ ( ( this . treeOptions . viewMode === 'read' && fragment . writeOnly ) ||
58+ ( this . treeOptions . viewMode === 'write' && fragment . readOnly ) )
59+ ) ;
60+ } ;
61+
62+ public getChildrenCount ( node : SchemaNode ) {
63+ const type = isRefNode ( node ) ? '$ref' : isCombinerNode ( node ) ? node . combiner : node . type ;
64+ const subtype = isArrayNodeWithItems ( node ) ? ( hasRefItems ( node ) ? '$ref' : inferType ( node . items ) ) : void 0 ;
65+
66+ let children ;
67+
68+ if ( type === SchemaKind . Object || ( Array . isArray ( type ) && type . includes ( SchemaKind . Object ) ) ) {
69+ children = ( node as IObjectNode ) . properties ;
70+ }
71+
72+ if ( subtype === SchemaKind . Object ) {
73+ children = ( ( node as IArrayNode ) . items as IObjectNode ) . properties ;
74+ }
75+
76+ if ( subtype === SchemaKind . Array ) {
77+ children = ( node as IArrayNode ) . items as IArrayNode ;
78+ }
79+
80+ if ( typeof children === 'object' && children !== null ) {
81+ return Object . values ( children ) . filter ( this . isViewModeRespected ) . length ;
82+ }
83+
84+ return null ;
85+ }
86+
5387 public populate ( ) {
5488 const expanded = { } ;
5589 populateTree ( this . schema , this . root , 0 , [ ] , {
5690 mergeAllOf : this . treeOptions . mergeAllOf ,
5791 onNode : ( fragment , node , parentTreeNode , level ) : boolean => {
58- if (
59- ! ! fragment . writeOnly !== ! ! fragment . readOnly &&
60- ( ( this . treeOptions . viewMode === 'read' && fragment . writeOnly ) ||
61- ( this . treeOptions . viewMode === 'write' && fragment . readOnly ) )
62- ) {
92+ if ( ! this . isViewModeRespected ( fragment ) ) {
6393 return false ;
6494 }
6595 if (
@@ -88,6 +118,9 @@ export class SchemaTree extends Tree {
88118 populateTree ( schema , artificialRoot , initialLevel , path , {
89119 mergeAllOf : this . treeOptions . mergeAllOf ,
90120 onNode : ( fragment , node , parentTreeNode , level ) => {
121+ if ( ! this . isViewModeRespected ( fragment ) ) {
122+ return false ;
123+ }
91124 if ( level <= this . treeOptions . expandedDepth || level <= initialLevel ) return true ;
92125 return stepIn && level <= initialLevel + 1 && canStepIn ( getSchemaNodeMetadata ( parentTreeNode ) . schema ) ;
93126 } ,
0 commit comments