import fs = require ( "fs" ) ; import path = require ( "path" ) ; import { Listable , FilterDimensions , ListingMeta } from "../common/Listable" ; const sourceAbbreviations = { "monster-manual" : "mm" , "basic-rules" : "mm" , "players-handbook" : "phb" } ; const formatStringForId = ( str ) => str . toLocaleLowerCase ( ) . replace ( /[\s]/g , "-" ) . replace ( /[^a-z0-9-]/g , "" ) ; const createId = ( name , source ) => { const sourceString = formatStringForId ( source ) ; const sourcePrefix = sourceAbbreviations [ sourceString ] || sourceString ; const lowerCaseName = formatStringForId ( name ) ; return `${ sourcePrefix }.${ lowerCaseName }` ; } ; interface Combatant { Alias : string ; } export interface SavedEncounter extends Listable { Combatants : Combatant [ ] ; } export class Library < TItem extends Listable > { private items : { [ id ] : TItem ; } = { } ; private listings : ListingMeta [ ] = [ ] ; constructor ( private route , private getSearchHint , private getFilterDimensions ) { } public static FromFile < I extends Listable > ( filename , route , getSearchHint , getMetadata ) { const library = new Library < I > ( route , getSearchHint , getMetadata ) ; const filePath = path . join ( __dirname , ".." , filename ) ; fs . readFile ( filePath , ( err , buffer ) => { if ( err ) { throw `Couldn't read ${ filePath } as a library: ${ err }` ; } const newItems = JSON . parse ( buffer . toString ( ) ) ; library . Add ( newItems ) ; } ) ; return library ; } private Add ( items ) { items . forEach ( c => { if ( ! ( c . Name && c . Source ) ) { throw `Missing Name or Source: Couldn't import ${ JSON . stringify ( c ) }` ; } c . Id = createId ( c . Name , c . Source ) ; this . items [ c . Id ] = c ; const listing = { Name : c . Name , Id : c . Id , Path : c . Path || "" , SearchHint : this . getSearchHint ( c ) , FilterDimensions : this . getFilterDimensions ( c ) , Link : this . route + c . Id , LastUpdateMs : 0 } ; this . listings . push ( listing ) ; } ) ; } public GetById ( id ) { return this . items [ id ] ; } public GetListings ( ) { return this . listings ; } public Route = ( ) => this . route ; }