import { addressesEqual , ANY_ENTITY } from '../address' ; import { getKernelNamespace } from '../kernel' ; import { DescriptionAnnotation , PostProcessDescription , AragonArtifactRole , } from '../../types' ; import App from '../../entities/App' ; interface CompiledTokens { description : string [ ] ; annotatedDescription : DescriptionAnnotation [ ] ; } type ProcessToken = [ string , string , DescriptionAnnotation ] ; param { string } description return { Promise < Object > } export async function postprocessRadspecDescription ( description , installedApps ) { const addressRegexStr = '0x[a-fA-F0-9]{40}' ; const addressRegex = new RegExp ( `^${ addressRegexStr }$` ) ; const bytes32RegexStr = '0x[a-f0-9]{64}' ; const bytes32Regex = new RegExp ( `^${ bytes32RegexStr }$` ) ; const combinedRegex = new RegExp ( `\\b(${ addressRegexStr }|${ bytes32RegexStr })\\b` ) ; const tokens = description . split ( combinedRegex ) . map ( ( token ) => token . trim ( ) ) . filter ( ( token ) => token ) ; if ( tokens . length < 1 ) { return { description } ; } const roles = installedApps . reduce ( ( roles , app ) => roles . concat ( app . artifact . roles ) , [ ] as AragonArtifactRole [ ] ) ; const annotateAddress = ( input ) : ProcessToken => { if ( addressesEqual ( input , ANY_ENTITY ) ) { return [ input , '"Any account"' , { type : 'any-account' , value : ANY_ENTITY } , ] ; } const app = installedApps . find ( ( { address } ) => addressesEqual ( address , input ) ) ; if ( app ) { const replacement = `${ app . name }${ app . appId ? ` (${ app . appId })` : '' }` ; return [ input , `“${ replacement }”` , { type : 'app' , value : app } ] ; } return [ input , input , { type : 'address' , value : input } ] ; } ; const annotateBytes32 = ( input ) : ProcessToken => { const role = roles . find ( ( { bytes } ) => bytes === input ) ; if ( role && role . name ) { return [ input , `“${ role . name }”` , { type : 'role' , value : role } ] ; } const app = installedApps . find ( ( { appId } ) => appId === input ) ; if ( app ) { return [ input , `“${ app . artifact . appName }”` , { type : 'apmPackage' , value : app } , ] ; } const namespace = getKernelNamespace ( input ) ; if ( namespace ) { return [ input , `“${ namespace . name }”` , { type : 'kernelNamespace' , value : namespace } , ] ; } return [ input , input , { type : 'bytes32' , value : input } ] ; } ; const annotateText = ( input ) : ProcessToken => { return [ input , input , { type : 'text' , value : input } ] ; } ; const annotatedTokens = tokens . map ( ( token ) => { if ( addressRegex . test ( token ) ) { return annotateAddress ( token ) ; } if ( bytes32Regex . test ( token ) ) { return annotateBytes32 ( token ) ; } return annotateText ( token ) ; } ) ; const compiled = annotatedTokens . reduce ( ( acc , [ _ , replacement , annotation ] ) => { acc . description . push ( replacement ) ; acc . annotatedDescription . push ( annotation ) ; return acc ; } , { annotatedDescription : [ ] as DescriptionAnnotation [ ] , description : [ ] as string [ ] , } ) ; return { annotatedDescription : compiled . annotatedDescription , description : compiled . description . join ( ' ' ) , } ; }