import { resolve } from 'path' ; import { get , isRegExp , template } from 'lodash' ; import { Engine } from 'random-js' ; import { Arbitrary } from './arbitrary' ; import { elements , regex } from './combinators/index' ; /**
 * Definitions Data
 * *
 * the structure of data looks like
 * {en: {name1: val1}, zh_Hant_TW: {name1: val1}}
 */ export type DefinitionsData = Object ; export type Definition = any [ ] | Function ; export type Formatter = ( result : any , locale : string , engine : Engine ) => string ; function definitionGen ( definitions ) { return ( name ) => ( engine , locale ) => { let pool = definitions . get ( name , locale ) ; if ( Array . isArray ( pool ) ) { pool = pool . map ( ( s ) => { return isRegExp ( s ) ? regex ( s ) . makeGenerator ( ) ( engine ) : s ; } ) ; return elements ( pool ) . makeGenerator ( ) ( engine , locale ) ; } else { return pool ; } } ; } /**
 * Extra definitions manager.
 *
 * A definition is an array of any values/regular expression or a function.
 */ export class Definitions { protected _data : Object ; constructor ( data ) { this . _data = data ; } /**
     * Load a definitions.
     */ static load ( path ) { return new Definitions ( require ( resolve ( path ) ) ) ; } /**
     * Get a definition.
     */ get ( name , locale = 'en' ) { const _locale = locale . replace ( /-/g , '_' ) ; const q = `${ _locale }.${ name }` ; return < Definition > get ( this . _data , q ) ; } /**
     * Create an arbitrary from a definition.
     */ arbitrary ( name ) { return new Arbitrary ( { gen : definitionGen ( this ) , genOpts : name } ) ; } /**
     * Create a special arbitrary transform function for formating
     * the result generated by a arbitrary.
     */ formatter ( name ) { return ( result , engine , locale ) => { let f = this . get ( name , locale ) ; if ( Array . isArray ( f ) ) { f = template ( elements ( f ) . makeGenerator ( ) ( engine ) ) ; } return f ( result ) ; } ; } }