forked from joelvh/json2json
-
Notifications
You must be signed in to change notification settings - Fork 0
/
TemplateConfig.coffee
98 lines (80 loc) · 3.51 KB
/
TemplateConfig.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
# handle CommonJS/Node.js or browser
sysmo = require?('sysmo') || window?.Sysmo
# class definition
class TemplateConfig
constructor: (config) ->
# if there is no node path, set to current node
config.path or= '.'
# ensure 'as' template exists
config.as or= {}
# convert property name to array
config.choose = [config.choose] if sysmo.isString config.choose
# include multiple templates to apply before this one
config.include = [config.include] if sysmo.isString config.include
# create settings
@arrayToMap = !!config.key
# TODO: Need to implement converting a map to an array...
# This property was created to show how to specify converting maps to arrays
@mapToArray = !@arrayToMap and config.key is false and !config.as
@directMap = !!(@arrayToMap and config.value)
@nestTemplate = !!config.nested
@includeAll = !!config.all
@config = config
getPath: =>
@config.path
# used to get a key when converting an array to a map
getKey: (node) =>
switch sysmo.type @config.key
when 'Function' then name: 'value', value: @config.key node
else name: 'path', value: @config.key
# used to get a single value when converting an array to a map
getValue: (node, context) =>
switch sysmo.type @config.value
when 'Function' then name: 'value', value: @config.value node
when 'String' then name: 'path', value: @config.value
else name: 'template', value: @config.as
# indicates if the key/value pair should be included in transformation
processable: (node, value, key) =>
# no choose() implies all properties go,
# but there are other properties that may cause filtering
return true if [email protected] and @includeAll # and !@nestTemplate
# convert array to chooser function that compares key names
if [email protected] and !@paths
@paths = []
for key, value of @config.as when sysmo.isString(value)
@paths.push value.split('.')[0]
# create callback for arry
if sysmo.isArray @config.choose
paths = @paths or []
paths = paths.concat @config.choose
return true for path in paths when path.split('.')[0] is key
return false
# if not a function yet, treat as boolean value
if !sysmo.isFunction @config.choose
# if config.key and config.value exist, most likely want to map all
!!(@includeAll or @directMap) #boolean
else
[email protected] @, node, value, key
# used to combine or reduce a value if one already exists in the context.
# can be a map that aggregates specific properties
aggregate: (context, key, value, existing) =>
aggregator = @config.aggregate?[key] or @config.aggregate
return false unless sysmo.isFunction(aggregator)
context[key] = aggregator(key, value, existing)
return true
applyFormatting: (node, value, key) =>
# if key is a number, assume this is an array element and skip
if !sysmo.isNumber(key)
formatter = @config.format?[key] or @config.format
pair = if sysmo.isFunction(formatter) then formatter(node, value, key) else {}
else
pair = {}
pair.key = key if 'key' not of pair
pair.value = value if 'value' not of pair
pair
# register module (CommonJS/Node.js) or handle browser
if module?
module.exports = TemplateConfig
else
window.json2json or= {}
window.json2json.TemplateConfig = TemplateConfig