File size: 2,818 Bytes
d0aa19c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import * as colors from 'colors';
import * as util from 'util';

type      ConsoleType = "out" | "info" | "error";
interface ConsoleTypeData {
	[text: string]: string | undefined;
}

export default class Log {
	private __name: string | undefined;
	
	private types: ConsoleTypeData = {
		"out":    "white",
		"info":   "cyan",
		"error":  "red",
	}
	
	constructor(name?: string) {
		this.__name = name;
	}
	
	private get date(): string {
		return colors.grey(`[${ new Date().toISOString() }] `);
	}
	
	private get name(): string {
		return this.__name 
			? `{${ this.__name.toUpperCase() }} `
			: '';
	}
	
	private format(...args: any[]) {
		return args.map(o => {
			if (o instanceof Error) {
				return [
					"",
					'-------------------------------------------------------',
					`${o.name}  - ${o.message}`,
					'-------------------------------------------------------',
					`${o.stack || 'NO STACK'}`,
					""
				].map(l => colors.red(l)).join('\n');
			} else if (typeof o === 'string') {
				return o;
			} else {
				return util.inspect(o, { depth: 20 });
			}
		}).join('  ');
	}
	
	print(type: ConsoleType): (...args: any[]) => void {
		return (...args) => {
			const output = this.format(...args);
			const color  = this.types[type];
			
			for (const line of output.split('\n')) {
				process.stdout.write(`${this.date}${this.name}${ color ? colors[color](line) : line }\n`);
			}
		};
	}
	
	static attach(name?: string) {
		const logger = new Log(name);
		
		console.log   = logger.print("out");
		console.info  = logger.print("info");
		console.error = logger.print("error");
	}
}


export const c = {
	__log: (args: any[], opts: {
		color?: colors.Color,
		colors?: boolean,
	} = {}) => {
		const inspectOpts = (opts.colors !== undefined)
			? { depth: 20, compact: false, breakLength: Infinity, colors: opts.colors }
			: { depth: 20, compact: false, breakLength: Infinity, colors: true }
		;
		const s = args.map(o => {
			if (o instanceof Error) {
				// return colors.red(`${o.name}: ${o.message}\n${o.stack}`);
				return (o.stack || `${o.name}: ${o.message}`)
					.split('\n')
					.map(x => colors.red(x))
					.join('\n')
				;
			} else if (typeof o === 'string') {
				return o;
			} else {
				return util.inspect(o, inspectOpts);
			}
		}).join('  ');
		console.log(opts.color ? opts.color(s) : s);
	},
	log: (...args: any[]) => {
		c.__log(args);
	},
	debug: (...args: any[]) => {
		c.__log(args, { color: colors.gray, colors: false });
	},
	success: (...args: any[]) => {
		c.__log(args, { color: colors.green });
	},
	error: (...args: any[]) => {
		c.__log(args, { color: colors.red });
	},
	info: (...args: any[]) => {
		c.__log(args, { color: colors.cyan });
	},
	introspect: (...args: any[]) => {
		c.__log(args.map(a => [
			a,
			typeof a,
			a.constructor.name,
		]));
	},
}