import fs from 'fs' ; import path from 'path' ; import { Globals } from './globals' ; import eol from 'eol' ; /**
 * Holds all templates, and know how to apply them
 */ export class Templates { private templates : { [ key ] : HandlebarsTemplateDelegate ; } = { } ; private globals : { [ key ] : any ; } = { } ; constructor ( builtInDir , customDir , handlebars ) { const builtInTemplates = fs . readdirSync ( builtInDir ) ; const customTemplates = customDir === '' ? [ ] : fs . readdirSync ( customDir ) ; for ( const file of builtInTemplates ) { const dir = customTemplates . includes ( file ) ? customDir : builtInDir ; this . parseTemplate ( dir , file , handlebars ) ; } for ( const file of customTemplates ) { this . parseTemplate ( customDir , file , handlebars ) ; } } private parseTemplate ( dir , file , handlebars ) { const baseName = this . baseName ( file ) ; if ( baseName ) { const text = eol . auto ( fs . readFileSync ( path . join ( dir , file ) , 'utf-8' ) ) ; const compiled = handlebars . compile ( text ) ; this . templates [ baseName ] = compiled ; handlebars . registerPartial ( baseName , compiled ) ; } } /**
     * Sets a global variable, that is, added to the model of all templates
     */ setGlobals ( globals ) { for ( const name of Object . keys ( globals ) ) { const value = ( globals as { [ key ] : any ; } ) [ name ] ; this . globals [ name ] = value ; } } private baseName ( file ) { if ( ! file . endsWith ( '.handlebars' ) ) { return null ; } return file . substring ( 0 , file . length - '.handlebars' . length ) ; } param templateName param model apply ( templateName , model ? ) { const template = this . templates [ templateName ] ; if ( ! template ) { throw new Error ( `Template not found: ${ templateName }` ) ; } const actualModel = { ... this . globals , ... ( model || { } ) } ; return template ( actualModel ) ; } }