UNPKG

@frontify/frontify-api

Version:

Simplifies asset management and UI pattern creation within Frontify.

294 lines (254 loc) 7.83 kB
var path = require('path'); var globby = require('globby'); var rp = require('request-promise'); var extend = require('extend'); var _ = require('lodash'); var fs = require('mz/fs'); var humanize = require('humanize-string'); var auth = require('./auth'); var cache = require('./cache'); /* * Get status of remote assets in Frontify */ function getRemoteStatus(meta) { if (cache.get('patternlibrary')) { return cache.get('patternlibrary'); } var library = Promise.resolve().then(function () { var options = auth(meta); options.uri = '/v1/patterns/list/' + meta.project; options.method = 'GET'; return rp(options).then(function(data) { data.remote = true; return data; }).catch(function (err) { throw new Error('Unable to get pattern library data. ' + err.message); }); }); cache.set('patternlibrary', library); return library; } function getGranularity(value) { value = value.toUpperCase(); var granularities = [ 'ATOM', 'MOLECULE', 'ORGANISM' ]; var granularity = _.find(granularities, function (granularity) { return value.indexOf(granularity) !== -1; }); if (!granularity) { granularity = granularities[0]; } return granularity; } function getStability(value) { // according to https://www.npmjs.com/package/stability-badges value = _.toString(value).toLowerCase(); var stability; switch (value) { case '0': case 'deprecated': stability = 0; break; case '1': case 'experimental': stability = 0; break; case '2': case 'unstable': stability = 0; break; case '3': case 'stable': stability = 0; break; case '4': case 'frozen': stability = 0; break; case '5': case 'locked': stability = 0; break; default: stability = 1; } return stability; } function hasChanged(pattern, existing) { var changed = true; return changed; } function getPattern(meta, pattern) { return Promise.resolve().then(function () { var options = auth(meta); if (!pattern) { throw new Error('Please provide pattern data'); } return getRemoteStatus(meta).then(function (data) { pattern.mode = 'CODE'; var existing = null; if (pattern.id) { // check whether the pattern already exists existing = _.find(data.patterns, function (item) { return item.id == pattern.id; }); if (!existing) { throw new Error('The pattern id ' + pattern.id + ' does not exist in your pattern library'); } } else { // check whether the api id (eg. path) already exists existing = _.find(data.patterns, function (item) { return item.id_api == pattern.id_api; }); if (existing) { // update _.forIn(pattern.snippets, function (snippet, lang) { if (existing.snippets[lang]) { snippet.id = parseInt(existing.snippets[lang].id); } }); } } // skip pattern if it is unchanged if(existing) { pattern.id = parseInt(existing.id); if(!hasChanged(pattern, existing)) { return Promise.resolve(null); } } return Promise.resolve(pattern); }); }); } function getSnippets(opts, assets) { var promises = []; _.forIn(assets, function (values, lang) { promises.push(Promise.resolve().then(function () { return Promise.all(values.map(function (value) { return fs.readFile(path.resolve(opts.cwd, value), 'utf8'); })).then(function (data) { return {lang: lang, code: indent(data.join('\n')), id_api: opts.idApi + '-' + lang}; }); })); }); return Promise.all(promises).then(function (data) { var snippets = {}; data.forEach(function (snippet) { if (snippet.lang) { snippets[snippet.lang] = snippet; } }); return snippets; }); } function indent(value) { return value.replace(/\t/g, ' '); } function syncPatterns(meta, patterns) { var opts = {}; opts.cwd = meta.cwd || ''; // reset library cache cache.reset(); return globby(patterns, opts).then(function (files) { if (files.length === 0) { throw new Error('No files found'); } return Promise.all(files.map(function (file) { var filename = path.resolve(opts.cwd, file); if (path.extname(filename) === '.json') { return fs.readFile(filename, 'utf8').then(function (content) { var localOpts = extend(true, {}, opts, { idApi: _.kebabCase(file.substr(0, file.length - 5)) }); var def = JSON.parse(content); var patternData = { id: def.id || null, id_api: localOpts.idApi, name: def.name || humanize(path.basename(filename, '.json')), description: def.description || '', granularity: getGranularity(def.type), stability: getStability(def.stability) }; return getSnippets(localOpts, def.assets).then(function (snippets) { patternData.snippets = snippets; return getPattern(meta, patternData); }).then(function (parent) { var promises = [ parent ]; if (def.variations) { _.forIn(def.variations, function (variation, key) { var variationData = extend(true, {}, patternData, { id: variation.id || null, id_api: localOpts.idApi + '-' + _.kebabCase(key), pattern: parent.id, description: variation.description || '', name: variation.name || patternData.name + ' ' + humanize(key) }); promises.push(getSnippets(localOpts, variation.assets).then(function (snippets) { variationData.snippets = snippets; return getPattern(meta, variationData); })); }); } return Promise.all(promises); }); }); } else if (path.extname(filename) === '.html') { return fs.readFile(filename, 'utf8').then(function (content) { var idApi = _.kebabCase(file.substr(0, file.length - 5)); var promises = []; promises.push(getPattern(meta, { name: humanize(path.basename(filename, '.html')), id_api: idApi, snippets: { html: { lang: 'html', id_api: idApi + '-html', code: indent(content) } } })); return Promise.all(promises); }).catch(function (err) { throw new Error('An error occured reading ' + filename + ' : ' + err.message); }); } })); }).then(function(patternLists) { var options = auth(meta); options.uri = '/v1/patterns/'; options.method = 'POST'; var patterns = []; patternLists.forEach(function (patternList) { patterns = patterns.concat(patternList); }); options.body = { patterns: patterns, project: meta.project }; if(meta.dryRun) { return Promise.resolve(patterns); } return rp(options) .then(function (data) { if (!data.success) { if (data.errors && data.errors.length > 0) { throw new Error(data.errors.join('\n')); } else { throw new Error(data); } } return data.patterns; }) .catch(function (err) { throw new Error('Could not create/update your patterns. ' + err.message); }); }); } module.exports = { syncPatterns: syncPatterns, getRemoteStatus: getRemoteStatus, getPattern: getPattern };