import { forEachProperty } from '@fluid-experimental/property-binder' ; import { BaseProxifiedProperty , PropertyProxy } from '@fluid-experimental/property-proxy' ; import { Workspace } from '@fluid-experimental/property-properties' ; import { TypeIdHelper } from '@fluid-experimental/property-changeset' ; import { BaseProperty , PropertyFactory , ReferenceArrayProperty , ReferenceProperty , ContainerProperty , MapProperty } from '@fluid-experimental/property-properties' ; import memoize from 'memoize-one' ; import { HashCalculator } from './HashCalculator' ; import { IColumns , IExpandedMap , IInspectorRow , IInspectorSearchAbortHandler , IInspectorSearchCallback , IInspectorSearchMatch , IInspectorSearchMatchMap , IInspectorTableProps } from './InspectorTableTypes' ; import { Utils } from './typeUtils' ; const { isEnumProperty , isEnumArrayProperty , isInt64Property , isReferenceProperty , isUint64Property , isCollectionProperty , isReferenceArrayProperty , isReferenceCollectionTypeid , isReferenceMapProperty } = Utils ; const idSeparator = '/' ; interface IShowNextResultResult { /**
     * New rows needed to expand to show next results
     */ expandedRows : IExpandedMap ; /**
     * row index of the next result. This value is used to automatically scroll in the table
     */ rowIdx : number ; /**
     * Next result column index
     */ columnIdx : number ; } type { IShowNextResultResult } data type { IInspectorRow } param currentlyExpanded param filteredExpanded param allMatches type { IInspectorSearchMatch } param resultIndex export const showNextResult = ( data , currentlyExpanded , allMatches , resultIndex , childToParentMap ) : IShowNextResultResult => { const desiredDataItem = allMatches [ resultIndex ] ; if ( ! desiredDataItem ) { return { expandedRows : currentlyExpanded , rowIdx : - 1 , columnIdx : - 1 } ; } let toBeExpandedNode = childToParentMap [ desiredDataItem . rowId ] ; while ( toBeExpandedNode ) { if ( ! ( toBeExpandedNode in currentlyExpanded ) ) { currentlyExpanded [ toBeExpandedNode ] = true ; } toBeExpandedNode = childToParentMap [ toBeExpandedNode ] ; } const rowInfo = findMatchingElementIndexInDataSet ( data , currentlyExpanded , desiredDataItem ) ; return { expandedRows : currentlyExpanded , rowIdx : rowInfo . idx , columnIdx : desiredDataItem . indexOfColumn } ; } ; param data type { IInspectorRow } param currentlyExpanded param matchingElement type { IInspectorSearchMatch } param rowCounter function findMatchingElementIndexInDataSet ( data , currentlyExpanded , matchingElement , rowCounter = 0 ) { for ( const row of data ) { if ( row . id === matchingElement . rowId ) { return { idx : rowCounter , found : true } ; } rowCounter ++ ; if ( row . id in currentlyExpanded ) { const res = findMatchingElementIndexInDataSet ( row . children ! , currentlyExpanded , matchingElement , rowCounter ) ; if ( res . found ) { return res ; } else { rowCounter = res . idx ; } } } return { idx : rowCounter , found : false } ; } interface ISearchLevelState { data ? : IInspectorRow [ ] ; index : number ; } export interface IInspectorSearchState { abort ? : boolean ; newMatchFound ? : boolean ; updateScheduled ? : number ; chunkSize ? : number ; expression ? : string ; foundMatches : IInspectorSearchMatch [ ] ; levels ? : ISearchLevelState [ ] ; matchesMap : IInspectorSearchMatchMap ; scheduled ? : number ; childToParentMap : { [ key ] : string ; } ; } export interface IInspectorSearchControls { abortHandler : IInspectorSearchAbortHandler ; state : IInspectorSearchState ; } const abortSearch = ( searchState ) => { if ( searchState . scheduled !== undefined || searchState . updateScheduled !== undefined ) { clearTimeout ( searchState . scheduled ) ; clearTimeout ( searchState . updateScheduled ) ; } searchState . abort = true ; } ; const updateHandler = ( callback , searchState , done ) => { searchState . newMatchFound = false ; searchState . updateScheduled = window . setTimeout ( ( ) => { callback ( searchState . foundMatches , searchState . matchesMap , done , searchState . childToParentMap ) ; } , 0 ) ; } ; param searchExpression param data param dataGetter param columns param handleUpdate param toTableRowsProps param toTableRowsOptions param searchState param chunkSize param recursive param entryPoint return export const search = ( searchExpression , data , dataGetter , columns , handleUpdate , toTableRowsProps , toTableRowsOptions , searchState = { foundMatches : [ ] , matchesMap : { } , childToParentMap : { } } , chunkSize = 1000 , recursive = false , entryPoint = true ) : IInspectorSearchControls => { if ( searchState . abort ) { return { abortHandler : ( ) => { } , state : searchState } ; } let searchControls ; if ( searchState . expression === undefined ) { searchState . expression = searchExpression . toLowerCase ( ) ; } if ( searchState . scheduled !== undefined ) { searchState . scheduled = undefined ; } if ( ! searchState . levels ) { searchState . levels = [ { data , index : 0 } ] ; } if ( searchState . chunkSize === undefined ) { searchState . chunkSize = chunkSize ; } const levelState = searchState . levels [ searchState . levels . length - 1 ] ; const rows = levelState . data || data ; let item ; for ( ; levelState . index < rows . length ; ++ levelState . index ) { if ( searchState . chunkSize === 0 || searchState . newMatchFound ) { if ( searchState . chunkSize === 0 && ! searchState . newMatchFound ) { if ( searchState . scheduled === undefined ) { searchState . scheduled = window . setTimeout ( ( ) => { searchState . chunkSize = chunkSize ; search ( searchExpression , rows , dataGetter , columns , handleUpdate , toTableRowsProps , toTableRowsOptions , searchState , chunkSize , false , true ) ; } , 10 ) ; } } if ( entryPoint && searchState . newMatchFound ) { updateHandler ( handleUpdate , searchState , false ) ; } return { abortHandler : abortSearch . bind ( null , searchState ) , state : searchState } ; } item = rows [ levelState . index ] ; searchState . childToParentMap [ item . id ] = item . parentId ; if ( item . context === undefined ) { continue ; } for ( let columnIndex = 0 ; columnIndex < columns . length ; columnIndex ++ ) { const column = columns [ columnIndex ] ; const validGetter = dataGetter && dataGetter ( { column , columnIndex , columns , rowData : item , rowIndex : levelState . index } ) ; const cell = validGetter || item [ column . dataKey ] ; if ( ( cell !== undefined ? String ( cell ) . toLowerCase ( ) : '' ) . includes ( searchState . expression ! ) ) { if ( ! searchState . matchesMap [ item . id ] ) { searchState . matchesMap [ item . id ] = [ ] ; } if ( ! searchState . matchesMap [ item . id ] [ columnIndex ] ) { searchState . foundMatches . push ( { rowId : item . id , indexOfColumn : columnIndex } ) ; searchState . matchesMap [ item . id ] [ columnIndex ] = true ; searchState . newMatchFound = true ; break ; } } } if ( searchState . newMatchFound ) { if ( entryPoint ) { updateHandler ( handleUpdate , searchState , false ) ; } return { abortHandler : abortSearch . bind ( null , searchState ) , state : searchState } ; } -- searchState . chunkSize ; if ( item . children && ! item . isReference ) { if ( item . children [ 0 ] . context === 'd' ) { fillExpanded ( { [ item . id ] : true } , [ item ] , toTableRowsProps , toTableRowsOptions ) ; } if ( item . children . length > 0 ) { searchState . levels . push ( { data : item . children , index : 0 } ) ; searchControls = search ( searchExpression , item . children , dataGetter , columns , handleUpdate , toTableRowsProps , toTableRowsOptions , searchState , chunkSize , true , false ) ; if ( searchState . newMatchFound || ( searchState . chunkSize === 0 && searchState . scheduled !== undefined ) ) { if ( entryPoint && searchState . newMatchFound ) { updateHandler ( handleUpdate , searchState , false ) ; } return searchControls ; } } } } searchState . levels . pop ( ) ; if ( ! recursive && searchState . levels . length > 0 ) { const parent = searchState . levels [ searchState . levels . length - 1 ] ; ++ parent . index ; searchControls = search ( searchExpression , parent . data ! , dataGetter , columns , handleUpdate , toTableRowsProps , toTableRowsOptions , searchState , chunkSize , false , false ) ; } if ( entryPoint && ( searchState . newMatchFound || searchState . levels . length === 0 ) ) { updateHandler ( handleUpdate , searchState , searchState . levels . length === 0 ) ; } return searchControls ? searchControls : { abortHandler : abortSearch . bind ( null , searchState ) , state : searchState } ; } ; export const isPrimitive = memoize ( ( typeid ) : boolean => { return TypeIdHelper . isPrimitiveType ( typeid ) ; } ) ; const getTypeid = memoize ( ( property ) : string => { return isEnumProperty ( property ) || property . getContext ( ) !== 'single' ? property . getFullTypeid ( ) : property . getTypeid ( ) ; } ) ; export const getCollectionTypeid = memoize ( ( property ) : string => { return isEnumArrayProperty ( property ) ? ( property as any ) . getFullTypeid ( true ) : property . getTypeid ( ) ; } ) ; export const getReferenceValue = ( rowData ) => { const parentProp = ( rowData . parent ! as ContainerProperty ) ; let path = '' ; if ( Utils . isReferenceCollectionTypeid ( getCollectionTypeid ( parentProp ) ) ) { path = parentProp . getValue ( rowData . propertyId ) as string ; } else { const unresolvedProperty = parentProp . get ( [ rowData . propertyId , BaseProperty . PATH_TOKENS . REF ] ) as unknown as ReferenceProperty ; path = unresolvedProperty . getValue ( ) as string ; } return path ; } ; const getShortId = ( parentPath , childId = undefined ) : string => { const sanitizer = [ { searchFor : /[.]|[\[]/g , replaceWith : idSeparator } , { searchFor : /[\]]/g , replaceWith : '' } , { searchFor : /\/[\/]+/g , replaceWith : idSeparator } , ] ; const absolutePath = childId !== undefined ? parentPath + idSeparator + childId : parentPath ; const hash = new HashCalculator ( ) ; hash . pushString ( sanitizePath ( absolutePath , sanitizer ) ) ; return hash . getHash ( ) ; } ; param data param context param typeid param dataCreation const isExpandable = ( data , context , typeid , dataCreation ) : boolean => { context = ( data && data . getProperty ) ? data . getProperty ( ) . getContext ( ) : context ; return dataCreation ? data && ( context !== 'single' || ! isPrimitive ( typeid ) ) : data && ( ( context !== 'single' && ( data . size > 0 || data . length > 0 ) ) || ( ! isPrimitive ( typeid ) && Object . keys ( data ) . length > 0 ) ) ; } ; const addAdditionalRow = ( subRows , id , parentProperty ) => { const undefinedRowData = { context : undefined , data : undefined , id : id + '/Add' , name : '' , parent : parentProperty , typeid : undefined , value : undefined } ; const isDefinedParent = parentProperty . getParent ( ) !== undefined ; const isNotUint64Property = ! isUint64Property ( parentProperty ) ; const isNotInt64Property = ! isInt64Property ( parentProperty ) ; const isNotEnumProperty = ! isEnumProperty ( parentProperty ) ; const canAddData = ( isDefinedParent || parentProperty . isRoot ( ) ) && ( parentProperty . isDynamic ( ) || isCollectionProperty ( parentProperty ) ) && ( isNotUint64Property || isNotInt64Property || isNotEnumProperty ) ; if ( canAddData ) { subRows . push ( undefinedRowData ) ; } } ; const compareName = ( a , b ) => { const nameA = a . toUpperCase ( ) ; const nameB = b . toUpperCase ( ) ; if ( nameA < nameB ) { return - 1 ; } if ( nameA > nameB ) { return 1 ; } return 0 ; } ; const compareNameDesc = ( a , b ) => { return compareName ( a , b ) * - 1 ; } ; interface IToTableRowsOptions { depth : number ; addDummy : boolean ; followReferences : boolean ; ascending : boolean ; parentIsConstant ? : boolean ; } interface IPropertyToTableRowOptions extends Partial < IToTableRowsOptions > { depth : number ; dataCreation : boolean ; } export const dummyChild = { children : undefined , context : 'd' , data : 'd' , id : 'd' , isConstant : false , isReference : false , name : 'd' , parentId : 'd' , parentIsConstant : false , propertyId : 'd' , typeid : 'd' , value : 'd' } ; const OPTION_DEFAULTS = { depth : 0 , addDummy : true , followReferences : true , ascending : true , parentIsConstant : false } ; type IToTableRowsProps = Pick < IInspectorTableProps , 'dataCreationHandler' | 'dataCreationOptionGenerationHandler' | 'childGetter' | 'nameGetter' | 'readOnly' > ; export const toTableRows = ( { data , id = '' , } , props , options = { } , pathPrefix = '' ) : IInspectorRow [ ] => { const { ascending , parentIsConstant } = { ... OPTION_DEFAULTS , ... options } ; const dataCreation = ( props . readOnly !== true ) && ! parentIsConstant && ! ! props . dataCreationHandler && ! ! props . dataCreationOptionGenerationHandler ; const subRows = [ ] ; const parentProperty = data . getProperty ( ) ; const dataContext = parentProperty . getContext ( ) ; const keys = Object . keys ( parentProperty . getEntriesReadOnly ( ) ) ; let sortedKeys = keys ; if ( dataContext === 'map' || dataContext === 'single' ) { if ( ascending ) { sortedKeys = keys . sort ( compareName ) ; } else { sortedKeys = keys . sort ( compareNameDesc ) ; } } switch ( dataContext ) { case 'single' : { sortedKeys . forEach ( ( key ) => { const newRow = singlePropertyTableRow ( data , key , id , props , { ... OPTION_DEFAULTS , ... options , dataCreation } , pathPrefix ) ; subRows . push ( newRow ) ; } ) ; break ; } default : { sortedKeys . forEach ( ( key ) => { const newRow = collectionChildTableRow ( data , key , id , props , { ... OPTION_DEFAULTS , ... options , dataCreation } , pathPrefix ) ; subRows . push ( newRow ) ; } ) ; break ; } } if ( dataCreation ) { addAdditionalRow ( subRows , id , parentProperty ) ; } return subRows ; } ; const createInvalidReference = ( parentData , propertyId , parentRowId , props , options , pathPrefix ) => { const parentProperty = parentData . getProperty ( ) ; const newId = getShortId ( pathPrefix + parentProperty . getAbsolutePath ( ) , propertyId ) ; const parentIsConstant = ! ! options . parentIsConstant ; const newRow = { children : undefined , context : 'single' , data : undefined , id : newId , isConstant : false , isReference : true , name : String ( propertyId ) , parent : parentProperty , parentId : parentRowId , parentIsConstant , propertyId : String ( propertyId ) , typeid : 'Reference' , value : '' } ; return newRow ; } ; /**
 * Construct a table row for an entry in a property that is not a collection.
 */ export const singlePropertyTableRow = ( parentData , propertyId , parentRowId , props , options , pathPrefix ) : IInspectorRow => { const { depth , addDummy , dataCreation , followReferences , ascending } = options ; const parentIsConstant = ! ! options . parentIsConstant ; const parentProperty = parentData . getProperty ( ) ; let property ; try { property = ( parentProperty as ContainerProperty ) . get ( propertyId ) ; } catch { return createInvalidReference ( parentData , propertyId , parentRowId , props , options , pathPrefix ) ; } const unresolvedProperty = parentData . getProperty ( [ propertyId , BaseProperty . PATH_TOKENS . REF ] ) ; if ( property === undefined || ! followReferences || ! property . getContext ) { property = unresolvedProperty ; } const currentContext = property . getContext ( ) ; const currentTypeid = getTypeid ( property ) ; let determinedData = parentData [ propertyId ] ; const determinedValue = getPropertyValue ( parentData , propertyId , currentContext , currentTypeid , followReferences ) ; if ( isReferenceProperty ( property ) && ! followReferences ) { determinedData = undefined ; } determinedData = props . childGetter ! ( determinedData , propertyId , parentProperty , currentTypeid , currentContext ) ; const name = props . nameGetter ! ( propertyId , parentProperty , currentTypeid , currentContext ) ; const isPropExpandable = isExpandable ( determinedData , currentContext , currentTypeid , dataCreation ) ; const newId = getShortId ( pathPrefix + parentProperty . getAbsolutePath ( ) , propertyId ) ; const propertyIdString = String ( propertyId ) ; const newRow = { children : undefined , context : currentContext , data : determinedData , id : newId , isConstant : property && ( property as any ) . _isConstant , isReference : isReferenceProperty ( unresolvedProperty ) , name : name === propertyId ? propertyIdString : name , parent : parentProperty , parentId : parentRowId , parentIsConstant , propertyId : propertyIdString , typeid : currentTypeid , value : determinedValue } ; if ( isPropExpandable ) { if ( depth !== 0 ) { newRow . children = toTableRows ( { ... newRow } , props , { addDummy , ascending , depth : depth - 1 , followReferences , parentIsConstant : newRow . isConstant || newRow . parentIsConstant } , pathPrefix ) ; } else if ( addDummy ) { newRow . children = [ dummyChild ] ; } } return newRow ; } ; /**
 * Construct a table row for an entry in a collection property.
 */ export const collectionChildTableRow = ( collectionPropertyProxy , propertyId , parentRowId , props , options , pathPrefix ) : IInspectorRow => { const collectionProperty = collectionPropertyProxy . getProperty ( ) as ContainerProperty ; let propertyProxy ; let prop ; try { prop = ( collectionProperty as ContainerProperty ) . get ( propertyId ) ; } catch { return createInvalidReference ( collectionPropertyProxy , propertyId , parentRowId , props , options , pathPrefix ) ; } propertyProxy = ( prop && PropertyFactory . instanceOf ( prop , 'BaseProperty' ) ? PropertyProxy . proxify ( prop ) : prop ) as BaseProxifiedProperty ; const { depth , addDummy , dataCreation , followReferences , ascending } = options ; const parentIsConstant = ! ! options . parentIsConstant ; const collectionTypeid = getCollectionTypeid ( collectionProperty ) ; const isReferenceCollection = isReferenceCollectionTypeid ( collectionTypeid ) ; let determinedData ; let determinedValue ; let currentTypeid = collectionTypeid ; let currentContext = 'single' ; let property = propertyProxy ; if ( ! isReferenceCollection || ( isReferenceCollection && followReferences ) ) { if ( propertyProxy !== undefined && propertyProxy . getProperty && PropertyFactory . instanceOf ( propertyProxy . getProperty ( ) , 'BaseProperty' ) ) { property = propertyProxy . getProperty ( ) ; currentTypeid = getTypeid ( property ) ; currentContext = property . getContext ( ) ; } else if ( isReferenceCollection ) { const { referencedPropertyParent , relativePathFromParent } = PropertyProxy . getParentOfReferencedProperty ( collectionProperty as ReferenceArrayProperty , propertyId ) ; if ( referencedPropertyParent && relativePathFromParent ) { property = ( referencedPropertyParent as ContainerProperty ) . get ( relativePathFromParent ) ! ; if ( property ) { if ( PropertyFactory . instanceOf ( property as BaseProperty , 'BaseProperty' ) ) { currentTypeid = getTypeid ( property ) ; currentContext = property . getContext ( ) ; } else { currentTypeid = getCollectionTypeid ( referencedPropertyParent ) ; } } } } else if ( isEnumProperty ( collectionProperty . get ( propertyId ) ! ) && collectionProperty . getContext ( ) === 'map' ) { property = ( collectionProperty as MapProperty ) . get ( propertyId ) ! ; currentTypeid = property . getFullTypeid ( ) ; currentContext = property . getContext ( ) ; } } propertyId = collectionProperty . getContext ( ) === 'set' ? ( propertyProxy as any ) . guid : propertyId ; determinedValue = getPropertyValue ( collectionPropertyProxy , propertyId , currentContext , currentTypeid , followReferences ) ; if ( propertyProxy && ( followReferences || ! TypeIdHelper . isReferenceTypeId ( currentTypeid ) ) ) { determinedData = propertyProxy ; } determinedData = props . childGetter ! ( determinedData , propertyId , collectionProperty , currentTypeid , currentContext ) ; const name = props . nameGetter ! ( propertyId , collectionProperty , currentTypeid , currentContext ) ; const isPropExpandable = isExpandable ( determinedData , currentContext , currentTypeid , dataCreation ) ; const children = undefined ; const newId = getShortId ( pathPrefix + collectionProperty . getAbsolutePath ( ) , propertyId ) ; const propertyIdString = String ( propertyId ) ; const newRow = { children , context : currentContext , data : determinedData , id : newId , isConstant : property && ( property as any ) . _isConstant , isReference : isReferenceCollection , name : name === propertyId ? propertyIdString : name , parent : collectionProperty , parentId : parentRowId , parentIsConstant , propertyId : propertyIdString , typeid : currentTypeid , value : determinedValue } ; if ( isPropExpandable ) { if ( addDummy ) { newRow . children = [ dummyChild ] ; } else if ( depth !== 0 ) { newRow . children = toTableRows ( { ... newRow } , props , { addDummy , ascending , depth : depth - 1 , followReferences } , pathPrefix ) ; } } return newRow ; } ; export interface ISanitizer { searchFor : RegExp ; replaceWith : string ; } export const sanitizePath = ( inPath , sanitizer ) => { let outPath = inPath ; sanitizer . forEach ( ( replaceCase ) => { outPath = outPath . replace ( replaceCase . searchFor , replaceCase . replaceWith ) ; } ) ; return outPath ; } ; export const expandAll = ( workspace ) => { const expanded = { } ; const root = ( workspace as any ) . root ; forEachProperty ( root , ( property ) => { if ( ! isPrimitive ( property . getFullTypeid ( ) ) ) { const newId = getShortId ( property . getAbsolutePath ( ) ) ; expanded [ newId ] = true ; } return true ; } ) ; return expanded ; } ; export const fillExpanded = ( expanded , innerRows , props , toTableRowsOptions ? , pathPrefix = '' ) => { for ( const row of innerRows ) { if ( row . id in expanded ) { const newPathPrefix = row . parent && row . isReference ? pathPrefix + row . parent . getAbsolutePath ( ) + idSeparator + row . name : pathPrefix ; if ( row . children && row . children [ 0 ] . context === 'd' ) { row . children = toTableRows ( { ... row } , props , { ... toTableRowsOptions , parentIsConstant : row . isConstant || row . parentIsConstant } , newPathPrefix ) ; } fillExpanded ( expanded , row . children ! , props , toTableRowsOptions , newPathPrefix ) ; } } } ; const isPropertyProxy = ( p ) : p is BaseProxifiedProperty => { return p . getProperty && PropertyFactory . instanceOf ( p . getProperty ( ) , 'BaseProperty' ) ; } ; const invalidReference = ( parentProxy , id ) => { return 'Invalid Reference: ' + ( isReferenceMapProperty ( parentProxy . getProperty ( ) ) ? ( parentProxy as any ) . get ( id + '*' ) : parentProxy [ id + '*' ] ) ; } ; param parent param id return export const getPropertyValue = ( parent , id , context , typeid , followReferences = true ) : string | number | boolean => { let parentProperty ; let parentProxy ; if ( isPropertyProxy ( parent ) ) { parentProxy = parent ; parentProperty = parentProxy . getProperty ( ) ; } else { parentProperty = parent ; parentProxy = PropertyProxy . proxify ( parent ) ; } let property ; try { property = ( parentProperty as ContainerProperty ) . get ( id ) ; } catch ( e ) { if ( Utils . isReferenceCollectionTypeid ( parentProperty . getTypeid ( ) ) || Utils . isReferenceProperty ( parentProxy . getProperty ( [ id , BaseProperty . PATH_TOKENS . REF ] ) ) ) { return invalidReference ( parentProxy , id ) ; } else { throw ( e ) ; } } if ( property === undefined || ! followReferences ) { property = parentProxy . getProperty ( [ id , BaseProperty . PATH_TOKENS . REF ] ) as BaseProperty ; } let propertyProxy = ( parentProperty . getContext ( ) === 'map' ? ( parentProxy as any ) . get ( id ) : parentProxy [ id ] ) ; if ( parentProperty . getContext ( ) === 'set' ) { propertyProxy = PropertyProxy . proxify ( property ) ; } const contextIsSingle = context === 'single' ; const parentContextIsSingle = parentProperty . getContext ( ) === 'single' ; id = parentProperty . getContext ( ) === 'set' ? ( propertyProxy as any ) . guid : id ; let determinedValue ; if ( ! followReferences && TypeIdHelper . isReferenceTypeId ( typeid ) ) { if ( parentContextIsSingle || isReferenceArrayProperty ( parentProperty ) ) { determinedValue = parentProxy [ id + '*' ] ; } else { determinedValue = ( parentProxy as any ) . get ( id + '*' ) ; } } else if ( contextIsSingle && propertyProxy !== undefined && isPrimitive ( typeid ) ) { try { if ( parentProxy [ id + '^' ] !== undefined ) { determinedValue = parentProxy [ id + '^' ] ; } else if ( ( parentProxy as any ) . get ( id + '^' ) !== undefined ) { determinedValue = ( parentProxy as any ) . get ( id + '^' ) ; } else { determinedValue = parentProxy ; } } catch ( error ) { console . error ( error ) ; } } else if ( ( propertyProxy === undefined && ( isReferenceArrayProperty ( parentProperty ) || isReferenceMapProperty ( parentProperty ) ) && ! parentProperty . isReferenceValid ( id as never ) ) || ( contextIsSingle && PropertyFactory . instanceOf ( property , 'Reference' ) && ! ( property as ReferenceProperty ) . isReferenceValid ( ) ) ) { determinedValue = invalidReference ( parentProxy , id ) ; } return determinedValue ; } ;