forked from wiledal/contentful-pull
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
258 lines (223 loc) · 6.98 KB
/
index.js
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
var fs = require("fs"),
contentful = require("contentful"),
helpers = require("./lib/helpers.js");
function throwError(err) {
console.log(err.stack);
}
/*
ContentfulPull
Main constructor
*/
function ContentfulPull(settings) {
this.currentSyncToken = null;
// Holds all the downloaded data in memory
this.data = null;
this.defaultSettings = {
path: null,
space: null,
accessToken: null
}
this.settings = settings;
}
/*
ContentfulSynchronize.sync
syncs the contentful
*/
ContentfulPull.prototype.sync = function(options) {
var _this = this;
console.log("ContentfulPull | Syncing...");
console.log(_this.settings);
return new Promise(function(resolve, reject){
var client = contentful.createClient({
space: _this.settings.space,
accessToken: _this.settings.accessToken
})
var isInitial = _this.currentSyncToken ? false : true;
var spacePromise = client.getSpace();
var contentTypesPromise = client.getContentTypes();
var syncPromise = client.sync({initial: isInitial, resolveLinks: false, nextSyncToken: _this.currentSyncToken});
Promise.all([spacePromise, contentTypesPromise, syncPromise]).then(function(result) {
var handledData = _this.handleSyncResponse({
space: result[0],
contentTypes: result[1],
sync: result[2]
});
resolve(_this.transformData(handledData, options));
});
});
};
/*
ContentfulSynchronize.handleResponse
Handles the response from Contentful
*/
ContentfulPull.prototype.handleSyncResponse = function(resp) {
var _this = this;
this.currentSyncToken = resp.sync.nextSyncToken;
if (!this.data) this.data = resp;
// If there are updates, replace current with new
if (resp.sync.entries) {
var syncIDs = _this.data.sync.entries.map(function(e) { return e.sys.id });
resp.sync.entries.forEach(function(entry) {
var existID = syncIDs.indexOf(entry.sys.id);
if (existID > -1) {
_this.data.sync.entries[existID] = entry;
}else{
_this.data.sync.entries.push(entry);
}
})
}
if (resp.sync.assets) {
var syncIDs = _this.data.sync.assets.map(function(e) { return e.sys.id })
resp.sync.assets.forEach(function(asset) {
var existID = syncIDs.indexOf(asset.sys.id);
if (existID > -1) {
_this.data.sync.assets[existID] = asset;
}else{
_this.data.sync.assets.push(asset);
}
})
}
// remove deleted from entries
if (resp.sync.deletedEntries) {
resp.sync.deletedEntries.forEach(function(deletedEntry) {
_this.data.sync.entries.forEach(function(entry, index) {
if (entry.sys.id == deletedEntry.sys.id) _this.data.sync.entries.splice(index, 1);
})
})
}
// remove deleted from assets
if (resp.sync.deletedAssets) {
resp.sync.deletedAssets.forEach(function(deletedAsset) {
_this.data.sync.assets.forEach(function(asset, index) {
if (asset.sys.id == deletedAsset.sys.id) _this.data.sync.assets.splice(index, 1);
})
})
}
// Save to local file
this.saveLocal(_this.data).catch(throwError);
return this.data;
}
ContentfulPull.prototype.resolveLink = function (field, entries, assets) {
// If field is not an object, return
if (!(field instanceof Object) || !field.type) return field;
var lookArray = entries;
if (field.type == "asset") {
lookArray = assets;
}
var referenced = lookArray.filter(function(e) {
if (e.id === field.id) return true;
return false;
});
return referenced[0];
};
/*
transformData
Transforms the data to preferred format before usage
*/
ContentfulPull.prototype.transformData = function(data, options) {
var self = this;
// If RAW data is requested, return basic object
if (!options) options = {};
if (options.raw) return data;
// Else continue to make workable data
var transformedData = {
assets: [],
entries: []
};
data.sync.entries.forEach(function(entry) {
var formatted = helpers.formatEntry(entry, data.contentTypes, data.space);
transformedData.entries.push(formatted);
});
data.sync.assets.forEach(function(asset) {
var formatted = helpers.formatAsset(asset, data.contentTypes, data.space);
transformedData.assets.push(formatted);
});
// Resolves the links
if (options.resolveLinks) {
for (var i = 0; i < transformedData.entries.length; i++) {
// For each entry
var entry = transformedData.entries[i];
for (var key in entry.fields) {
// Go through each field
var field = entry.fields[key];
for (var lang in field) {
// And go through each language
var fieldContent = field[lang];
if (fieldContent instanceof Object) {
if (fieldContent instanceof Array) {
var links = [];
fieldContent.forEach(function(c) {
var link = self.resolveLink(c, transformedData.entries, transformedData.assets);
if (link) links.push(link);
});
field[lang] = links;
}else{
var link = self.resolveLink(fieldContent, transformedData.entries, transformedData.assets);
field[lang] = link ? link : null;
}
}
}
}
}
}
return transformedData;
}
/*
ContentfulPull.getFromFile
Loads the datafile into memory
*/
ContentfulPull.prototype.getFromFile = function(options) {
var _this = this;
return new Promise(function(resolve, reject){
fs.readFile(_this.settings.path, "utf8", function(err, resp) {
if (err) reject(err);
if (!err) {
_this.data = JSON.parse(resp);
_this.currentSyncToken = _this.data.sync.currentSyncToken;
resolve(_this.transformData(_this.data, options));
}
})
});
}
/*
ContentfulPull.get
Returns a promise with the data in memory, from the web, or from the local store.
*/
ContentfulPull.prototype.get = function(options) {
var _this = this;
return new Promise(function(resolve, reject){
// If no data is in memory, get from file, if that's not existing, sync from contentful
if (!_this.data) {
_this.getFromFile(options).then(resolve).catch(function() {
_this.sync(options).then(resolve);
})
}else{
return new Promise(function(resolve, reject) {
resolve(_this.transformData(_this.data, options));
})
}
});
}
/*
ContentfulSynchronize.saveLocal
Saves the data to a local file
*/
ContentfulPull.prototype.saveLocal = function(data) {
console.log("ContentfulPull | Saving to local file...");
var _this = this;
// Write to local storage
return new Promise(function(resolve, reject){
fs.writeFile(_this.settings.path, JSON.stringify(data), "utf8", function(err) {
if (err) {
console.log("ContentfulPull | An error occurred while saving local file.");
console.log(err.stack);
reject();
}
if (!err) {
console.log("ContentfulPull | File saved successfully.");
resolve();
}
});
});
};
module.exports = ContentfulPull;