function toHyphenated(styleKey) { return styleKey.replace(/([A-Z])/g, "-$1").toLowerCase(); } const log = (...args) => { console.log(...args); }; Object.assign(log, { if(condition) { return { then(callback) { if (condition) callback(log); return this; }, else(callback) { if (!condition) callback(log); return this; } }; }, withStyle(styles) { const cssString = Object.entries(styles) .map(([key, value]) => `${toHyphenated(key)}: ${value}`) .join("; "); const styledLog = (...args) => { const styledArgs = args.reduce((acc, arg) => { if (typeof arg === "string") { acc.push(`%c${arg}`, cssString); } else { acc.push(arg); } return acc; }, []); console.log(...styledArgs); }; const extendedStyledLog = Object.assign( styledLog, Object.assign(Object.assign({}, log), { label(obj) { for (const [key, value] of Object.entries(obj)) { if (typeof value === "string") { console.log( `%c${key}:%c ${value}`, `${cssString}; font-weight: bold;`, cssString ); } else { console.log( `%c${key}:`, `${cssString}; font-weight: bold;`, value ); } } } }) ); return extendedStyledLog; }, spread(obj) { console.log(...Object.values(obj)); }, values(obj) { console.log(...Object.values(obj)); }, keys(obj) { console.log(...Object.keys(obj)); }, entries(obj) { console.log(Object.entries(obj)); }, label(obj) { for (const [k, v] of Object.entries(obj)) { console.log(`${k}: ${v}`); } }, assert(...args) { console.assert(...args); } });