UNPKG

9.05 kBJavaScriptView Raw
1'use strict';
2
3var path = require('path');
4var globby = require('globby');
5var rp = require('request-promise');
6var extend = require('extend');
7var _ = require('lodash');
8var fs = require('mz/fs');
9var humanize = require('humanize-string');
10var cache = {};
11
12var defaults = {
13 baseUrl: 'https://app.frontify.com',
14 qs: {
15 access_token: 'xxxxx xxxxx' // -> uri + '?access_token=xxxxx%20xxxxx'
16 },
17 json: true
18};
19
20function _auth(meta, options) {
21 if (!(meta && meta.access_token)) {
22 throw new Error('Please provide an access_token');
23 }
24 if(meta.baseUrl) {
25 options.baseUrl = meta.baseUrl;
26 }
27 options.qs.access_token = meta.access_token;
28 return options;
29}
30
31function _reset() {
32 cache = {};
33}
34
35function _library(meta) {
36 if (cache['library']) {
37 return cache['library'];
38 }
39
40 return cache['library'] = Promise.resolve().then(function () {
41 var options = extend(true, {}, defaults);
42 options = _auth(meta, options);
43
44 if (!(meta && meta.project)) {
45 throw new Error('Please provide a project id');
46 }
47 options.uri = '/v1/patterns/list/' + meta.project;
48 options.method = 'GET';
49
50 return rp(options).catch(function (err) {
51 throw new Error('Could not get your pattern library data. ' + err.message);
52 });
53 });
54}
55
56function _changed(pattern, existing) {
57 var changed = true;
58 return changed;
59}
60
61function _granularity(value) {
62 value = value.toUpperCase();
63 var granularities = [
64 'ATOM',
65 'MOLECULE',
66 'ORGANISM'
67 ];
68
69 var granularity = _.find(granularities, function (granularity) {
70 return value.indexOf(granularity) !== -1;
71 });
72
73 if (!granularity) {
74 granularity = granularities[0];
75 }
76
77 return granularity;
78}
79
80function _indent(value) {
81 return value.replace(/\t/g, ' ');
82}
83
84function _stability(value) {
85 // according to https://www.npmjs.com/package/stability-badges
86 value = _.toString(value).toLowerCase();
87 var stability;
88
89 switch (value) {
90 case '0':
91 case 'deprecated':
92 stability = 0;
93 break;
94 case '1':
95 case 'experimental':
96 stability = 0;
97 break;
98 case '2':
99 case 'unstable':
100 stability = 0;
101 break;
102 case '3':
103 case 'stable':
104 stability = 0;
105 break;
106 case '4':
107 case 'frozen':
108 stability = 0;
109 break;
110 case '5':
111 case 'locked':
112 stability = 0;
113 break;
114 default:
115 stability = 1;
116 }
117
118 return stability;
119}
120
121function _snippets(opts, assets) {
122 var promises = [];
123
124 _.forIn(assets, function (values, lang) {
125 promises.push(Promise.resolve().then(function () {
126 return Promise.all(values.map(function (value) {
127 return fs.readFile(path.resolve(opts.cwd, value), 'utf8')
128 })).then(function (data) {
129 return {lang: lang, code: _indent(data.join('\n')), id_api: opts.idApi + '-' + lang};
130 });
131 }));
132 });
133
134 return Promise.all(promises).then(function (data) {
135 var snippets = {};
136 data.forEach(function (snippet) {
137 if (snippet.lang) {
138 snippets[snippet.lang] = snippet;
139 }
140 });
141 return snippets;
142 });
143}
144
145function _pattern(meta, pattern) {
146 return Promise.resolve().then(function () {
147 var options = extend(true, {}, defaults);
148 options = _auth(meta, options);
149
150 if (!(meta && meta.project)) {
151 throw new Error('Please provide a project id');
152 }
153
154 if (!pattern) {
155 throw new Error('Please provide pattern data');
156 }
157
158 return _library(meta).then(function (data) {
159 pattern.mode = 'CODE';
160 var existing = null;
161
162 if (pattern.id) {
163 // check whether the pattern already exists
164 existing = _.find(data.patterns, function (item) {
165 return item.id == pattern.id;
166 });
167
168 if (!existing) {
169 throw new Error('The pattern id ' + pattern.id + ' does not exist in your pattern library');
170 }
171 }
172 else {
173 // check whether the api id (eg. path) already exists
174 existing = _.find(data.patterns, function (item) {
175 return item.id_api == pattern.id_api;
176 });
177
178 if (existing) {
179 // update
180 _.forIn(pattern.snippets, function (snippet, lang) {
181 if (existing.snippets[lang]) {
182 snippet['id'] = parseInt(existing.snippets[lang].id);
183 }
184 });
185 }
186 }
187
188 // skip pattern if it is unchanged
189 if(existing) {
190 pattern.id = parseInt(existing.id);
191 if(!_changed(pattern, existing)) {
192 return Promise.resolve(null);
193 }
194 }
195
196 return Promise.resolve(pattern);
197 });
198 });
199}
200
201function syncPatterns(meta, patterns) {
202 var opts = {};
203 opts.cwd = meta.cwd || '';
204
205 // reset library cache
206 _reset();
207
208 return globby(patterns, opts).then(function (files) {
209 if (files.length === 0) {
210 throw new Error('No files found');
211 }
212
213 return Promise.all(files.map(function (file) {
214 var filename = path.resolve(opts.cwd, file);
215
216 if (path.extname(filename) === '.json') {
217 return fs.readFile(filename, 'utf8').then(function (content) {
218 var localOpts = extend(true, {}, opts, {
219 idApi: _.kebabCase(file.substr(0, file.length - 5))
220 });
221 var def = JSON.parse(content);
222 var patternData = {
223 id: def.id || null,
224 id_api: localOpts.idApi,
225 name: def.name || humanize(path.basename(filename, '.json')),
226 description: def.description || '',
227 granularity: _granularity(def.type),
228 stability: _stability(def.stability)
229 };
230
231 return _snippets(localOpts, def.assets).then(function (snippets) {
232 patternData.snippets = snippets;
233 return _pattern(meta, patternData);
234 }).then(function (parent) {
235 var promises = [ parent ];
236 if (def.variations) {
237 _.forIn(def.variations, function (variation, key) {
238 var variationData = extend(true, {}, patternData, {
239 id: variation.id || null,
240 id_api: localOpts.idApi + '-' + _.kebabCase(key),
241 pattern: parent.id,
242 description: variation.description || '',
243 name: variation.name || patternData.name + ' ' + humanize(key)
244 });
245
246 promises.push(_snippets(localOpts, variation.assets).then(function (snippets) {
247 variationData.snippets = snippets;
248 return _pattern(meta, variationData);
249 }));
250 });
251 }
252 return Promise.all(promises);
253 });
254 });
255 }
256 else if (path.extname(filename) === '.html') {
257 return fs.readFile(filename, 'utf8').then(function (content) {
258 var idApi = _.kebabCase(file.substr(0, file.length - 5));
259 var promises = [];
260 promises.push(_pattern(meta, {
261 name: humanize(path.basename(filename, '.html')),
262 id_api: idApi,
263 snippets: {
264 html: {
265 lang: 'html',
266 id_api: idApi + '-html',
267 code: _indent(content)
268 }
269 }
270 }));
271 return Promise.all(promises);
272 }).catch(function (err) {
273 throw new Error('An error occured reading ' + filename + ' : ' + err.message);
274 });
275 }
276 }));
277 }).then(function(patternLists) {
278 var options = extend(true, {}, defaults);
279 options = _auth(meta, options);
280
281 options.uri = '/v1/patterns/';
282 options.method = 'POST';
283
284 var patterns = [];
285 patternLists.forEach(function (patternList) {
286 patterns = patterns.concat(patternList);
287 });
288
289 options.body = { patterns: patterns, project: meta.project };
290
291 if(meta.dryRun) {
292 return Promise.resolve(patterns);
293 }
294
295 return rp(options)
296 .then(function (data) {
297 if (!data.success) {
298 if (data.errors && data.errors.length > 0) {
299 throw new Error(data.errors.join('\n'));
300 }
301 else {
302 throw new Error(data);
303 }
304 }
305
306 return data.patterns;
307 })
308 .catch(function (err) {
309 throw new Error('Could not create/update your patterns. ' + err.message);
310 });
311 });
312}
313
314/* function assets(meta, assets) {
315 var opts = {};
316 opts.cwd = meta.cwd || '';
317
318 return globby(assets, opts).then(function (files) {
319 if (files.length === 0) {
320 throw new Error('No files found');
321 }
322
323 return Promise.all(files.map(function (file) {
324 var filename = path.resolve(opts.cwd, file);
325 var folderName = path.dirname(file);
326 var folders = folderName.split('/');
327
328 return Promise.all(folders.map(function(folder) {
329 return folder(folder);
330 }));
331 }));
332 });
333}
334
335function folder(meta, folder) {
336 if (!(meta && meta.project)) {
337 throw new Error('Please provide a project id');
338 }
339
340 return Promise.resolve();
341} */
342
343module.exports = {
344 syncPatterns: syncPatterns,
345 _pattern: _pattern,
346 _library: _library,
347 _reset: _reset
348};