mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-07 01:09:54 +08:00
init: the first public commit for AFFiNE
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
const path = require('path');
|
||||
const fs = require('fs-extra');
|
||||
const { pascalCase, paramCase } = require('change-case');
|
||||
const initializeApi = require('./api');
|
||||
const svgo = require('./svgo');
|
||||
const util = require('./util');
|
||||
const generateReactIcon = require('./generateReactIcon');
|
||||
|
||||
function getRemoveAttrs(name) {
|
||||
if (util.isBrands(name)) {
|
||||
return {
|
||||
name: 'removeAttrs',
|
||||
params: {
|
||||
attrs: '',
|
||||
},
|
||||
};
|
||||
}
|
||||
return {
|
||||
name: 'removeAttrs',
|
||||
params: {
|
||||
attrs: util.isDuotone(name) ? 'stroke' : '(stroke|fill)',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async function generateImportEntry(iconNodes, folder) {
|
||||
const fileWithImportsPath = path.resolve(folder, 'index.ts');
|
||||
|
||||
const importsContent = iconNodes
|
||||
.map(iconNode => {
|
||||
const iconName = paramCase(iconNode.name);
|
||||
if (!iconName) {
|
||||
return `// Error: ${iconNode.name}`;
|
||||
}
|
||||
|
||||
return `export * from './${iconName}/${iconName}';`;
|
||||
})
|
||||
.join('\n');
|
||||
|
||||
await fs.writeFile(
|
||||
fileWithImportsPath,
|
||||
`export const timestamp = ${Date.now()};\n${importsContent}`,
|
||||
{ encoding: 'utf8' }
|
||||
);
|
||||
}
|
||||
|
||||
function filterIcons(icons, iconsUrl) {
|
||||
const icon_name_set = new Set();
|
||||
const icons_filtered = icons.filter(i => {
|
||||
if (icon_name_set.has(paramCase(i.name))) {
|
||||
console.warn(
|
||||
`\nWarn: There is an icon with the same name: ${i.name}`
|
||||
);
|
||||
return false;
|
||||
}
|
||||
icon_name_set.add(paramCase(i.name));
|
||||
return iconsUrl[i.id];
|
||||
});
|
||||
return icons_filtered;
|
||||
}
|
||||
|
||||
async function downloadFigmaIcons(props) {
|
||||
const { token, fileId, nodeId, folder, patchStyles } = props;
|
||||
await fs.ensureDir(folder);
|
||||
await fs.emptyDir(folder);
|
||||
const api = await initializeApi(token);
|
||||
let icons = await api.getChildren(fileId, nodeId);
|
||||
const iconsUrl = await api.getIconsUrl(
|
||||
fileId,
|
||||
icons.map(i => i.id).join(',')
|
||||
);
|
||||
icons = filterIcons(icons, iconsUrl);
|
||||
const generateIcons = icons.map(async icon => {
|
||||
const iconUrl = iconsUrl[icon.id];
|
||||
const iconName = paramCase(icon.name);
|
||||
let originSvg;
|
||||
try {
|
||||
originSvg = await api.downloadIcon(iconUrl);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
let optimizedSvg;
|
||||
try {
|
||||
const data = await svgo.optimize(
|
||||
originSvg,
|
||||
getRemoveAttrs(iconName)
|
||||
);
|
||||
optimizedSvg = data.data;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
console.log(iconName);
|
||||
}
|
||||
|
||||
const iconFolder = path.resolve(folder, iconName);
|
||||
const JSXContent = await generateReactIcon(
|
||||
pascalCase(icon.name),
|
||||
optimizedSvg,
|
||||
patchStyles?.[iconName]
|
||||
);
|
||||
await Promise.all([
|
||||
fs.outputFile(
|
||||
path.resolve(iconFolder, `${iconName || icon.name}.svg`),
|
||||
optimizedSvg,
|
||||
{ encoding: 'utf8' }
|
||||
),
|
||||
fs.outputFile(
|
||||
path.resolve(iconFolder, `${iconName || icon.name}.tsx`),
|
||||
JSXContent,
|
||||
{ encoding: 'utf8', flag: '' }
|
||||
),
|
||||
]);
|
||||
});
|
||||
await Promise.allSettled([
|
||||
...generateIcons,
|
||||
generateImportEntry(icons, folder),
|
||||
]);
|
||||
}
|
||||
|
||||
module.exports = downloadFigmaIcons;
|
||||
Reference in New Issue
Block a user