1 | 'use strict'
|
2 |
|
3 | {createFormatter} = require 'fmt-obj'
|
4 | slice = require 'sliced'
|
5 | chalk = require 'chalk'
|
6 |
|
7 | CONST = require './Constants'
|
8 |
|
9 | ESCAPE_REGEX = /%{2,2}/g
|
10 | TYPE_REGEX = /(%?)(%([Jjds]))/g
|
11 |
|
12 | isEmpty = (arr) -> arr.length is 0
|
13 | isString = (obj) -> typeof obj is 'string'
|
14 | isSymbol = (obj) -> typeof obj is 'symbol'
|
15 | isObject = (obj) -> typeof obj is 'object'
|
16 | isBuffer = (buf) -> buf instanceof Buffer
|
17 | isError = (err) -> err instanceof Error
|
18 | isDate = (date) -> date instanceof Date
|
19 | isFalsy = (value) -> [null, undefined, false].indexOf(value) isnt -1
|
20 | isArray = (arr) -> Array.isArray(arr)
|
21 | hasWhiteSpace = (s) -> s.indexOf(' ') isnt -1
|
22 |
|
23 | colorize = (value, color) -> chalk[color](value)
|
24 |
|
25 | prettyObj = (obj, color, opts) ->
|
26 | lineColor = chalk[CONST.LINE_COLOR]
|
27 | {offset, depth} = opts
|
28 |
|
29 | fmtObj = createFormatter({
|
30 | offset,
|
31 | formatter: {
|
32 | punctuation: lineColor
|
33 | annotation: lineColor
|
34 | property: chalk[color]
|
35 | literal: lineColor
|
36 | number: lineColor
|
37 | string: lineColor
|
38 | }
|
39 | })
|
40 |
|
41 | fmtObj(obj, depth)
|
42 |
|
43 | serialize = (obj, color, key) ->
|
44 |
|
45 | key = key.toString() if isSymbol key
|
46 | obj = obj.toString() if isSymbol obj
|
47 | obj = JSON.stringify obj if isFalsy obj
|
48 |
|
49 | unless isObject obj
|
50 | obj = "'#{obj}'" if key and isString(obj) and hasWhiteSpace(obj)
|
51 | return if key then "#{key}=#{obj}" else obj
|
52 |
|
53 | if isBuffer obj
|
54 | obj = obj.toString 'base64'
|
55 | return if key then "#{key}=#{obj}" else obj
|
56 |
|
57 | return obj.message or obj if isError obj
|
58 |
|
59 | msg = ''
|
60 | keys = Object.keys obj
|
61 | length = keys.length
|
62 | i = 0
|
63 | while i < length
|
64 | key = keys[i]
|
65 | value = obj[key]
|
66 |
|
67 | if isArray value
|
68 | msg += key + '=['
|
69 | j = 0
|
70 | l = value.length
|
71 | while j < l
|
72 | msg += serialize(value[j], color)
|
73 | if j < l - 1
|
74 | msg += ' '
|
75 | j++
|
76 | msg += ']'
|
77 | else if isDate value
|
78 | msg += key + '=' + value
|
79 | else
|
80 | msg += serialize(value, color, colorize(key, color))
|
81 | if i < length - 1
|
82 | msg += ' '
|
83 | i++
|
84 | msg
|
85 |
|
86 | format = (opts) ->
|
87 | (messages) ->
|
88 | args = slice arguments, 1
|
89 | color = args.pop()
|
90 |
|
91 | unless isEmpty args
|
92 | messages = messages.replace(TYPE_REGEX, (match, escaped, ptn, flag) ->
|
93 | arg = args.shift()
|
94 | switch flag
|
95 | when 's'
|
96 | arg = colorize(String(arg), color)
|
97 | when 'd'
|
98 | arg = colorize(Number(arg), color)
|
99 | when 'j'
|
100 | arg = serialize arg, color
|
101 | when 'J'
|
102 | arg = prettyObj arg, color, opts
|
103 | return arg if !escaped
|
104 | args.unshift arg
|
105 | match
|
106 | )
|
107 | messages += ' ' + serialize arg, color for arg in args unless isEmpty args
|
108 |
|
109 | messages = messages.replace(ESCAPE_REGEX, '%') if messages.replace?
|
110 | serialize messages, color
|
111 |
|
112 | module.exports = format
|