function isObject(value) { return Object.prototype.toString.call(value) === '[object Object]'; } function isNumber(value) { return typeof value === 'number' && isFinite(value); } function interpolate(string, object) { var pattern = /(#\{(.*?)\})/g; return string.replace(pattern, function () { var name = arguments[2]; var value = object[name]; if (isNumber(value)) { value = value.toString(); } else if (isObject(value)) { try { value = JSON.stringify(value); } catch (e) { console.error("Stringifying object (likely a circular structure) failed."); } } return typeof value === 'string' ? value : ''; }); } var enumerables = ['valueOf', 'toLocaleString', 'toString', 'constructor']; function apply(object, config, defaults) { if (defaults) { apply(object, defaults); } if (object && config && typeof config === 'object') { var i, j, k; for (i in config) { object[i] = config[i]; } if (enumerables) { for (j = enumerables.length; j--;) { k = enumerables[j]; if (config.hasOwnProperty(k)) { object[k] = config[k]; } } } } return object; } module.exports = { isObject: isObject, isNumber: isNumber, interpolate: interpolate, apply: apply };