import Parse from './parse' ; import type { EtaConfig } from './config' ; import type { AstObject } from './parse' ; /**
 * Compiles a template string to a function string. Most often users just use `compile()`, which calls `compileToString` and creates a new function using the result
 *
 * **Example**
 *
 * ```js
 * compileToString("Hi <%= it.user %>", eta.config)
 * // "var tR='',include=E.include.bind(E),includeFile=E.includeFile.bind(E);tR+='Hi ';tR+=E.e(it.user);if(cb){cb(null,tR)} return tR"
 * ```
 */ export default function compileToString ( str , config ) { const buffer = Parse ( str , config ) ; let res = "var tR='',__l,__lP" + ( config . include ? ',include=E.include.bind(E)' : '' ) + ( config . includeFile ? ',includeFile=E.includeFile.bind(E)' : '' ) + '\nfunction layout(p,d){__l=p;__lP=d}\n' + ( config . useWith ? 'with(' + config . varName + '||{}){' : '' ) + compileScope ( buffer , config ) + ( config . includeFile ? 'if(__l)tR=' + ( config . async ? 'await ' : '' ) + `includeFile(__l,Object.assign(${ config . varName },{body:tR},__lP))\n` : config . include ? 'if(__l)tR=' + ( config . async ? 'await ' : '' ) + `include(__l,Object.assign(${ config . varName },{body:tR},__lP))\n` : '' ) + 'if(cb){cb(null,tR)} return tR' + ( config . useWith ? '}' : '' ) ; if ( config . plugins ) { for ( let i = 0 ; i < config . plugins . length ; i ++ ) { const plugin = config . plugins [ i ] ; if ( plugin . processFnString ) { res = plugin . processFnString ( res , config ) ; } } } return res ; } /**
 * Loops through the AST generated by `parse` and transform each item into JS calls
 *
 * **Example**
 *
 * ```js
 * // AST version of 'Hi <%= it.user %>'
 * let templateAST = ['Hi ', { val: 'it.user', t: 'i' }]
 * compileScope(templateAST, eta.config)
 * // "tR+='Hi ';tR+=E.e(it.user);"
 * ```
 */ function compileScope ( buff , config ) { let i = 0 ; const buffLength = buff . length ; let returnStr = '' ; for ( i ; i < buffLength ; i ++ ) { const currentBlock = buff [ i ] ; if ( typeof currentBlock === 'string' ) { const str = currentBlock ; returnStr += "tR+='" + str + "'\n" ; } else { const type = currentBlock . t ; let content = currentBlock . val || '' ; if ( type === 'r' ) { if ( config . filter ) { content = 'E.filter(' + content + ')' ; } returnStr += 'tR+=' + content + '\n' ; } else if ( type === 'i' ) { if ( config . filter ) { content = 'E.filter(' + content + ')' ; } if ( config . autoEscape ) { content = 'E.e(' + content + ')' ; } returnStr += 'tR+=' + content + '\n' ; } else if ( type === 'e' ) { returnStr += content + '\n' ; } } } return returnStr ; }