-
Notifications
You must be signed in to change notification settings - Fork 0
/
config.coffee
122 lines (111 loc) · 3.3 KB
/
config.coffee
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
121
122
props = require 'pathval'
fs = require 'fs'
{flatten_object, ends_with} = require './util'
###*
* @class Config
###
class Config
constructor: (@handler, @data) ->
@_value_of_previous_key = ''
@_previous_key = ''
@_value_of_current_key = ''
@_current_key = ''
###*
* gets the value of the key in the previous chain
* @return {(string|number|array|object|null)} - the fetched value
###
val: ->
@_value_of_current_key
###*
* finds a key that ends with given text
* @param {String} partial_key - the key suffix to look for
###
find: (partial_key) ->
flattened_data = flatten_object @data
key = undefined
for own k of flattened_data
if ends_with(k, partial_key)
key = k
break
@get(key)
###*
* sets the value of a key
* @param {string} [key] - the property that is being set
* @param {(string|number|array|object|null)} val - the value to assign
###
set: (args...) ->
if args.length > 1
track.call(@, args[0], props.set(@data, args[0], args[1]))
else if args.length is 1
track.call(@, @_current_key, props.set(@data, @_current_key, args[0]))
else
throw new Error "Figson: .set() expects an argument: [key], value"
return this
###*
* fetches a key
* @param {string} key - the property being fetched
###
get: (key) ->
if key?
track.call(@, key, props.get(@data, key))
else
track.call(@, @_current_key, props.get(@data, @_current_key))
return this
###*
* updates a key - first gets, checks for existence, then either
* sets the key or throws an error if the key does not exist
* @param {string} [key] - the property to update
* @param {(string|number|array|object|null)} val - the value to update with
###
update: (args...) ->
key = undefined
val = undefined
if args.length is 1
val = args[0]
key = @_current_key
else
val = args[1]
key = args[0]
unless @get(key).val()
throw new Error "Figson: cannot update non-existent property '#{key}'"
else
@set(key, val)
return this
###*
* deletes a property
* @param {string} key - the property to delete
###
destroy: (key) ->
if key? then @set(key, undefined)
else @set(@_current_key, undefined)
return this
###*
* saves the current object data to the config file
* @param {Config~saveCallback} [callback] - handles async saving of file
###
save: (callback) ->
if callback?
fs.writeFile(@handler.file, @handler.stringify(@data, null, 2), callback)
###**
* exposes any errors that happened while saving
* @callback Config~saveCallback
* @param {Object} error - an error, if one occured
###
else
try
fs.writeFileSync(@handler.file, @handler.stringifySync(@data, null, 2))
catch error
throw error
return this
###*
* maintains the internal structure, required for chaining to work
* @api private
* @param {String} key - the key being tracked
* @param {[type]} val - the value of the key being tracked
###
track = (key, val) ->
@_value_of_previous_key = @_value_of_current_key
@_previous_key = @_current_key
@_value_of_current_key = val
@_current_key = key
module.exports = Config