import { IICUMessage , IICUMessageCategory , IICUMessageTranslation , INormalizedMessage } from '../api/index' ; import { format , isNullOrUndefined , isString } from 'util' ; import { IMessageParser } from './i-message-parser' ; class MessageCategory implements IICUMessageCategory { constructor ( private _category , private _message ) { } public getCategory ( ) { return this . _category ; } public getMessageNormalized ( ) { return this . _message ; } } /**
 * Implementation of an ICU Message.
 * Created by martin on 05.06.2017.
 */ export class ICUMessage implements IICUMessage { private _isPluralMessage : boolean ; private _categories : IICUMessageCategory [ ] ; constructor ( private _parser , isPluralMessage ) { this . _isPluralMessage = isPluralMessage ; this . _categories = [ ] ; } addCategory ( category , message ) { this . _categories . push ( new MessageCategory ( category , message ) ) ; } return public asNativeString ( ) { const varname = ( this . isPluralMessage ( ) ) ? 'VAR_PLURAL' : 'VAR_SELECT' ; const type = ( this . isPluralMessage ( ) ) ? 'plural' : 'select' ; let choiceString = '' ; this . _categories . forEach ( ( category ) => { choiceString = choiceString + format ( ' %s {%s}' , category . getCategory ( ) , category . getMessageNormalized ( ) . asNativeString ( ) ) ; } ) ; return format ( '{%s, %s,%s}' , varname , type , choiceString ) ; } /**
     * Is it a plural message?
     */ isPluralMessage ( ) { return this . _isPluralMessage ; } /**
     * Is it a select message?
     */ isSelectMessage ( ) { return ! this . _isPluralMessage ; } /**
     * All the parts of the message.
     * E.g. the ICU message {wolves, plural, =0 {no wolves} =1 {one wolf} =2 {two wolves} other {a wolf pack}}
     * has 4 category objects with the categories =0, =1, =2, other.
     */ getCategories ( ) { return this . _categories ; } param translation return throws translate ( translation ) { const message = new ICUMessage ( this . _parser , this . isPluralMessage ( ) ) ; const translatedCategories = new Set < string > ( ) ; this . _categories . forEach ( ( category ) => { let translatedMessage ; const translationForCategory = translation [ category . getCategory ( ) ] ; if ( isNullOrUndefined ( translationForCategory ) ) { translatedMessage = category . getMessageNormalized ( ) ; } else if ( isString ( translationForCategory ) ) { translatedCategories . add ( category . getCategory ( ) ) ; translatedMessage = this . _parser . parseNormalizedString ( < string > translationForCategory , null ) ; } else { translatedMessage = null ; } message . addCategory ( category . getCategory ( ) , translatedMessage ) ; } ) ; Object . keys ( translation ) . forEach ( ( categoryName ) => { if ( ! translatedCategories . has ( categoryName ) ) { if ( this . isSelectMessage ( ) ) { throw new Error ( format ( 'adding a new category not allowed for select messages ("%s" is not part of message)' , categoryName ) ) ; } else { this . checkValidPluralCategory ( categoryName ) ; let translatedMessage = this . _parser . parseNormalizedString ( < string > translation [ categoryName ] , null ) ; message . addCategory ( categoryName , translatedMessage ) ; } } } ) ; return message ; } param categoryName throws private checkValidPluralCategory ( categoryName ) { const allowedKeywords = [ 'zero' , 'one' , 'two' , 'few' , 'many' , 'other' ] ; if ( categoryName . match ( /=\d+/ ) ) { return ; } if ( allowedKeywords . find ( ( key ) => key === categoryName ) ) { return ; } throw new Error ( format ( 'invalid plural category "%s", allowed are =<n> and %s' , categoryName , allowedKeywords ) ) ; } }