lib/util.js
function replaceParams(ast, keys) {
  Object.keys(ast)
    .filter(key => {
      const value = ast[key]
      return Array.isArray(value) || (typeof value === 'object' && value !== null)
    })
    .forEach(key => {
      const expr = ast[key]

      if (!(typeof expr === 'object' && expr.type === 'param')) return replaceParams(expr, keys)

      if (typeof keys[expr.value] === 'undefined') throw new Error(`no value for parameter :${expr.value} found`)
      ast[key] = createValueExpr(keys[expr.value])
      return null
    })

  return ast
}
function replaceParams(ast, keys) {
  Object.keys(ast)
    .filter(key => {
      const value = ast[key]
      return Array.isArray(value) || (typeof value === 'object' && value !== null)
    })
    .forEach(key => {
      const expr = ast[key]

      if (!(typeof expr === 'object' && expr.type === 'param')) return replaceParams(expr, keys)

      if (typeof keys[expr.value] === 'undefined') throw new Error(`no value for parameter :${expr.value} found`)
      ast[key] = createValueExpr(keys[expr.value])
      return null
    })

  return ast
}
function replaceParams ( ast , keys ) { Object . keys ( ast ) . filter ( key => { const value = ast [ key ] return Array . isArray ( value ) || ( typeof value === 'object' && value !== null ) } ) . forEach ( key => { const expr = ast [ key ] if ( ! ( typeof expr === 'object' && expr . type === 'param' ) ) return replaceParams ( expr , keys ) if ( typeof keys [ expr . value ] === 'undefined' ) throw new Error ( ` ${ expr . value } ` ) ast [ key ] = createValueExpr ( keys [ expr . value ] ) return null } ) return ast }
Replace param expressions

@param {Object} ast    - AST object
@param {Object} keys   - Keys = parameter names, values = parameter values
@return {Object}     - Newly created AST object
Replace param expressions