UNPKG

4.11 kBJavaScriptView Raw
1'use strict';
2
3const _ = require('lodash'),
4 utils = require('clayutils'),
5 refProp = '_ref';
6
7/**
8 * normalize a potential component list
9 * @param {array} arr which may be component list or just data
10 * @return {array}
11 */
12function normalizeComponentList(arr) {
13 if (_.has(_.head(arr), refProp)) {
14 // it's a component list! only return the references
15 return _.map(arr, (item) => _.pick(item, refProp));
16 } else {
17 // just component data, move along
18 return arr;
19 }
20}
21
22/**
23 * normalize a potential component property
24 * @param {object} obj which may be a component prop or just data
25 * @return {object}
26 */
27function normalizeComponentProp(obj) {
28 if (_.has(obj, refProp)) {
29 // it's a component prop! only return the reference
30 return { [refProp]: obj[refProp] };
31 } else {
32 // just component data, move along
33 return obj;
34 }
35}
36
37/**
38 * remove child component data, leaving only their references
39 * note: this removes _ref from the root of component data
40 * @param {object} data for a component
41 * @return {object}
42 */
43function normalize(data) {
44 let cleanData = {};
45
46 _.forOwn(data, (val, key) => {
47 if (_.isArray(val)) {
48 // possibly a component list
49 cleanData[key] = normalizeComponentList(val);
50 } else if (_.isObject(val)) {
51 // possibly a component prop
52 cleanData[key] = normalizeComponentProp(val);
53 } else if (key !== refProp) {
54 // add any other bits of component data
55 cleanData[key] = val;
56 }
57 });
58
59 return cleanData;
60}
61
62function addComponent(item, bootstrap, added) {
63 const uri = item[refProp],
64 name = utils.getComponentName(uri),
65 instance = utils.getComponentInstance(uri),
66 data = instance ? _.get(bootstrap, `_components.${name}.instances.${instance}`) : _.omit(_.get(bootstrap, `_components.${name}`), 'instances');
67
68 if (!data || !_.size(data)) {
69 return item; // just return the _ref, since it doesn't point to any data we currently have
70 // note: there might already be data in the database, or elsewhere
71 } else {
72 // if we've found the component, add its data and mark it as added
73 _.set(added, `asChild['${uri}']`, true);
74 added[uri] = true;
75 return _.assign(item, denormalize(data, bootstrap, added)); // recursion excursion!
76 }
77}
78
79/**
80 * denormalize a potential component list
81 * @param {array} arr which may be component list or just data
82 * @param {object} bootstrap containing all components
83 * @param {object} added
84 * @return {array}
85 */
86function denormalizeComponentList(arr, bootstrap, added) {
87 if (_.has(_.head(arr), refProp)) {
88 // it's a component list! grab the data from the bootstrap
89 return _.map(arr, (item) => addComponent(item, bootstrap, added));
90 } else {
91 // just component data, move along
92 return arr;
93 }
94}
95
96/**
97 * denormalize a potential component prop
98 * @param {object} obj which may be component prop or just data
99 * @param {object} bootstrap containing all components
100 * @param {object} added
101 * @return {array}
102 */
103function denormalizeComponentProp(obj, bootstrap, added) {
104 if (_.has(obj, refProp)) {
105 // it's a component prop! grab the data from the bootstrap
106 return addComponent(obj, bootstrap, added);
107 } else {
108 // just component data, move along
109 return obj;
110 }
111}
112
113/**
114 * add child component data to their references,
115 * and update a list of added components
116 * note: this is similar to how amphora composes json
117 * @param {object} data for a component
118 * @param {object} bootstrap containing all components
119 * @param {object} added
120 * @return {object}
121 */
122function denormalize(data, bootstrap, added) {
123 _.forOwn(data, (val, key) => {
124 if (_.isArray(val)) {
125 // possibly a component list
126 data[key] = denormalizeComponentList(val, bootstrap, added);
127 } else if (_.isObject(val)) {
128 // possibly a component prop
129 data[key] = denormalizeComponentProp(val, bootstrap, added);
130 } else {
131 // add any other bits of component data
132 data[key] = val;
133 }
134 });
135
136 return data;
137}
138
139module.exports.normalize = normalize;
140module.exports.denormalize = denormalize;