import prop from 'property-expr' ; const IS_ARRAY = /^\d+$/ ; function isQuoted ( str ) { return ! ! ( typeof str === 'string' && str && ( str [ 0 ] === '"' || str [ 0 ] === "'" ) ) ; } function copy < T > ( value ) { return Array . isArray ( value ) ? value . concat ( ) : value !== null && typeof value === 'object' ? Object . assign ( new value . constructor ( ) , value ) : value ; } function clean ( part ) { return isQuoted ( part ) ? part . substr ( 1 , part . length - 2 ) : part ; } export default function update < T > ( model , path , value ) { let parts = prop . split ( path ) ; let newModel = copy ( model ) ; let part ; let islast ; if ( newModel == null ) newModel = IS_ARRAY . test ( parts [ 0 ] ) ? [ ] : { } ; let current = newModel ; for ( let idx = 0 ; idx < parts . length ; idx ++ ) { islast = idx === parts . length - 1 ; part = clean ( parts [ idx ] ) ; if ( islast ) current [ part ] = value ; else { current = current [ part ] = current [ part ] == null ? IS_ARRAY . test ( parts [ idx + 1 ] ) ? [ ] : { } : copy ( current [ part ] ) ; } } return newModel as T ; }