Skip to content

Instantly share code, notes, and snippets.

@brandonmcconnell
Created October 13, 2023 01:54
Show Gist options
  • Save brandonmcconnell/cedaea2bcd16b03c3208305fcfc7d9a7 to your computer and use it in GitHub Desktop.
Save brandonmcconnell/cedaea2bcd16b03c3208305fcfc7d9a7 to your computer and use it in GitHub Desktop.
Simple & elegant JS logging solution (`console.log` decorator)
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);
}
});
type Styles = {
[key: string]: string;
};
type LogMethods = {
spread(obj: Record<string, any>): void;
values(obj: Record<string, any>): void;
keys(obj: Record<string, any>): void;
entries(obj: Record<string, any>): void;
label(obj: Record<string, any>): void;
assert(...args: any[]): void;
[key: string]: any; // index signature
};
type LogMethod = {
(...args: any[]): void;
withStyle(styles: Styles): LogMethod & LogMethods;
if(condition: boolean): ChainableLog;
} & LogMethods;
type ChainableLog = {
then(callback: (logger: LogMethod) => void): ChainableLog;
else(callback: (logger: LogMethod) => void): ChainableLog;
};
function toHyphenated(styleKey: string): string {
return styleKey.replace(/([A-Z])/g, '-$1').toLowerCase();
}
const log: LogMethod = ((...args: any[]) => {
console.log(...args);
}) as LogMethod;
Object.assign(log, {
if(condition: boolean): ChainableLog {
return {
then(callback) {
if (condition)
callback(log);
return this;
},
else(callback) {
if (!condition)
callback(log);
return this;
}
};
},
withStyle(styles: Styles): LogMethod {
const cssString = Object.entries(styles)
.map(([key, value]) => `${toHyphenated(key)}: ${value}`)
.join('; ');
const styledLog = (...args: any[]) => {
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: LogMethod = Object.assign(styledLog, {
...log,
label(obj: Record<string, any>): void {
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: Record<string, any>): void {
console.log(...Object.values(obj));
},
values(obj: Record<string, any>): void {
console.log(...Object.values(obj));
},
keys(obj: Record<string, any>): void {
console.log(...Object.keys(obj));
},
entries(obj: Record<string, any>): void {
console.log(Object.entries(obj));
},
label(obj: Record<string, any>): void {
for (const [k, v] of Object.entries(obj)) {
console.log(`${k}: ${v}`);
}
},
assert(...args: any[]): void {
console.assert(...args);
}
});
log("Simple log message.");
const styled = log.withStyle({
color: "red",
fontSize: "20px",
backgroundColor: "lightgray"
});
styled("Styled message.");
styled.values({ x: 10, y: 20 });
styled.label({ r: "red", s: "blue" });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment