import { IGettextExtractorStats } from './extractor' ; export interface IMessage { text : string | null ; textPlural ? : string | null ; context ? : string | null ; references : string [ ] ; comments : string [ ] ; } export interface IContext { name : string ; messages : IMessage [ ] ; } export type IMessageMap = { [ text ] : IMessage ; } ; export type IContextMap = { [ context ] : IMessageMap ; } ; export class CatalogBuilder { private contexts : IContextMap = { } ; private static compareStrings ( a , b ) { return a . localeCompare ( b ) ; } private static concatUnique ( array ? , items ? ) { array = array || [ ] ; for ( let item of items || [ ] ) { if ( array . indexOf ( item ) === - 1 ) { array . push ( item ) ; } } return array ; } private static extendMessage ( message , data ) { message . text = typeof data . text === 'string' ? data . text : message . text ; message . textPlural = typeof data . textPlural === 'string' ? data . textPlural : message . textPlural ; message . context = typeof data . context === 'string' ? data . context : message . context ; message . references = CatalogBuilder . concatUnique ( message . references , data . references ) ; message . comments = CatalogBuilder . concatUnique ( message . comments , data . comments ) ; return message ; } private static normalizeMessage ( message ) { return CatalogBuilder . extendMessage ( { text : null , textPlural : null , context : null , references : [ ] , comments : [ ] } , message ) ; } constructor ( private stats ? ) { } public addMessage ( message ) { message = CatalogBuilder . normalizeMessage ( message ) ; let context = this . getOrCreateContext ( message . context || '' ) ; if ( context [ message . text ! ] ) { if ( message . textPlural && context [ message . text ! ] . textPlural && context [ message . text ! ] . textPlural !== message . textPlural ) { throw new Error ( `Incompatible plurals found for '${ message . text }' ('${ context [ message . text ! ] . textPlural }' and '${ message . textPlural }')` ) ; } if ( message . textPlural && ! context [ message . text ! ] . textPlural ) { this . stats && this . stats . numberOfPluralMessages ++ ; } CatalogBuilder . extendMessage ( context [ message . text ! ] , message ) ; } else { context [ message . text ! ] = message as IMessage ; this . stats && this . stats . numberOfMessages ++ ; if ( message . textPlural ) { this . stats && this . stats . numberOfPluralMessages ++ ; } } this . stats && this . stats . numberOfMessageUsages ++ ; } public getMessages ( ) { let messages = [ ] ; for ( let context of Object . keys ( this . contexts ) . sort ( CatalogBuilder . compareStrings ) ) { messages = messages . concat ( this . getMessagesByContext ( context ) ) ; } return messages ; } public getContexts ( ) { let contexts = [ ] ; for ( let context of Object . keys ( this . contexts ) . sort ( CatalogBuilder . compareStrings ) ) { contexts . push ( { name : context , messages : this . getMessagesByContext ( context ) } ) ; } return contexts ; } public getMessagesByContext ( context ) { let messages = this . contexts [ context ] ; if ( ! messages ) { return [ ] ; } return Object . keys ( messages ) . sort ( CatalogBuilder . compareStrings ) . map ( text => messages [ text ] ) ; } private getOrCreateContext ( context ) { if ( ! this . contexts [ context ] ) { this . contexts [ context ] = { } ; this . stats && this . stats . numberOfContexts ++ ; } return this . contexts [ context ] ; } }