1 |
|
2 | module.exports =
|
3 | ###
|
4 | `isPortOpen(port, host, callback)`: Check if a port is already open
|
5 |
|
6 | ###
|
7 | isPortOpen: (port, host, callback) ->
|
8 | if arguments.length is 2
|
9 | callback = host
|
10 | host = '127.0.0.1'
|
11 | exec "nc #{host} #{port} < /dev/null", (err, stdout, stderr) ->
|
12 | return callback null, true unless err
|
13 | return callback null, false if err.code is 1
|
14 | callback err
|
15 | ###
|
16 | `merge([inverse], obj1, obj2, ...]`: Recursively merge objects
|
17 | --------------------------------------------------------------
|
18 | On matching keys, the last object take precedence over previous ones
|
19 | unless the inverse arguments is provided as true. Only objects are
|
20 | merge, arrays are overwritten.
|
21 |
|
22 | Enrich an existing object with a second one:
|
23 | obj1 = { a_key: 'a value', b_key: 'b value'}
|
24 | obj2 = { b_key: 'new b value'}
|
25 | result = misc.merge obj1, obj2
|
26 | assert.eql result, obj1
|
27 | assert.eql obj1.b_key, 'new b value'
|
28 |
|
29 | Create a new object from two objects:
|
30 | obj1 = { a_key: 'a value', b_key: 'b value'}
|
31 | obj2 = { b_key: 'new b value'}
|
32 | result = misc.merge {}, obj1, obj2
|
33 | assert.eql result.b_key, 'new b value'
|
34 |
|
35 | Using inverse:
|
36 | obj1 = { b_key: 'b value'}
|
37 | obj2 = { a_key: 'a value', b_key: 'new b value'}
|
38 | misc.merge true, obj1, obj2
|
39 | assert.eql obj1.a_key, 'a value'
|
40 | assert.eql obj1.b_key, 'b value'
|
41 |
|
42 | ###
|
43 | merge: () ->
|
44 | target = arguments[0]
|
45 | from = 1
|
46 | to = arguments.length
|
47 | if typeof target is 'boolean'
|
48 | inverse = !! target
|
49 | target = arguments[1]
|
50 | from = 2
|
51 | # Handle case when target is a string or something (possible in deep copy)
|
52 | if typeof target isnt "object" and typeof target isnt 'function'
|
53 | target = {}
|
54 | for i in [from ... to]
|
55 | # Only deal with non-null/undefined values
|
56 | if (options = arguments[ i ]) isnt null
|
57 | # Extend the base object
|
58 | for name of options
|
59 | src = target[ name ]
|
60 | copy = options[ name ]
|
61 | # Prevent never-ending loop
|
62 | continue if target is copy
|
63 | # Recurse if we're merging plain objects
|
64 | if copy? and typeof copy is 'object' and not Array.isArray(copy)
|
65 | clone = src and ( if src and typeof src is 'object' then src else {} )
|
66 | # Never move original objects, clone them
|
67 | target[ name ] = @merge false, clone, copy
|
68 | # Don't bring in undefined values
|
69 | else if copy isnt undefined
|
70 | target[ name ] = copy unless inverse and typeof target[ name ] isnt 'undefined'
|
71 | # Return the modified object
|
72 | target
|
73 | ###
|
74 | `options(options)` Normalize options
|
75 | ###
|
76 | options: (options) ->
|
77 | options = [options] unless Array.isArray options
|
78 | for option in options
|
79 | option.if = [option.if] if option.if? and not Array.isArray option.if
|
80 | option.if_exists = [option.if_exists] if option.if_exists? and not Array.isArray option.if_exists
|
81 | option.not_if_exists = [option.not_if_exists] if option.not_if_exists? and not Array.isArray option.not_if_exists
|
82 | options
|
83 |
|
84 |
|
85 |
|
86 |
|
87 |
|