Skip to content

Instantly share code, notes, and snippets.

@achhunna
Last active May 27, 2021 15:29
Show Gist options
  • Save achhunna/deaa1565062264eccde5856808d996ba to your computer and use it in GitHub Desktop.
Save achhunna/deaa1565062264eccde5856808d996ba to your computer and use it in GitHub Desktop.
Batch SVG file download from Zeplin's styleguide components
const fs = require('fs');
const mkdirp = require('mkdirp');
const getDirName = require('path').dirname;
const axios = require('axios');
const styleguideId = process.argv.slice(2)[0]; // provide styleguideId ast 1st arg in command line
if (!styleguideId) {
throw Error('Please provide styleguideId as first arg');
}
const token = process.env.ZEPLIN_ACCESS_TOKEN || ''; // add `export ZEPLIN_ACCESS_TOKEN=xxx` in ~/.bash_profile
const baseUrl = 'https://api.zeplin.dev/v1/';
const styleguidesUrl = `styleguides/${styleguideId}/components`;
const limit = 100; // max items per request https://docs.zeplin.dev/reference#pagination
let step = 0;
const maxLimit = 1000; // assuming we won't have > 1000 icons
const offsetList = [];
while (step < maxLimit) {
offsetList.push(step);
step += limit;
}
function writeFile(path, contents, cb) {
mkdirp(getDirName(path), (err) => {
if (err) return cb(err);
fs.writeFile(path, contents, cb);
});
}
function paramsToString(params) {
return Object.keys(params).reduce((acc, p, i) => {
if (i !== 0) {
return `${acc}&${p}=${params[p]}`;
}
return `${acc}${p}=${params[p]}`;
}, '');
}
function getComponentsListUrl(limit, offset) {
return `${baseUrl}${styleguidesUrl}?${paramsToString({ limit, offset })}`;
}
const headers = {
accept: 'application/json',
authorization: `Bearer ${token}`,
};
const getComponentsListPromises = offsetList.map(offset => {
return axios.get(getComponentsListUrl(limit, offset), { headers })
});
Promise.all(getComponentsListPromises)
.then((dataArray) => {
const data = dataArray.reduce((acc, { data, status }) => {
if (status === 200 && data.length > 0) {
return [...acc, ...data];
} else {
return acc;
}
}, []);
return Promise.all(data.filter(c => {
if (c.name.indexOf('/') === -1) { // filter out any non icon components
return true;
} else {
return false;
}
}).map(c => {
const id = c.id;
const getComponentDetailsUrl = `${baseUrl}${styleguidesUrl}/${id}/versions/latest`;
return axios.get(getComponentDetailsUrl, { headers });
}));
})
.then(data => {
data.forEach(({ data, status }) => {
if (status === 200) {
const assets = data.assets;
const lastAsset = assets[assets.length - 1];
if (lastAsset) {
const filename = `${lastAsset.display_name}.svg`;
const svgFiltered = lastAsset.contents.filter(c => c.format === 'svg');
const svgFileUrl = svgFiltered[0].url;
const pathname = '/assets/svg/';
axios.get(svgFileUrl, { headers }).then(({ data, status }) => {
if (status === 200) {
writeFile(`${__dirname}${pathname}${filename}`, data, () => {
console.log(`${filename} saved to ${pathname}`);
});
}
});
}
}
});
})
.catch((error) => {
console.error(error);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment