files.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. const config = require('./figma-import.config')
  2. const path = require('path')
  3. const readline = require('readline')
  4. const fs = require('fs').promises
  5. const { kebabCase } = require('lodash')
  6. const { getImageContent, getNodeChildren, getSvgImageUrl } = require('./utils/api')
  7. const type = process.argv.slice(2)[0] === '--icons' ? 'icons' : 'illustrations'
  8. const filesDir = path.resolve(`src/assets/${type}/svgs`)
  9. let counter = 0
  10. const checkIfFileExists = async (path) => {
  11. try {
  12. await fs.access(path)
  13. return true
  14. } catch {
  15. return false
  16. }
  17. }
  18. const prompt = async (query) => {
  19. const rl = readline.createInterface({
  20. input: process.stdin,
  21. output: process.stdout,
  22. })
  23. const question = (query) =>
  24. new Promise((resolve) =>
  25. rl.question(query, (answer) => {
  26. resolve(answer)
  27. rl.close()
  28. })
  29. )
  30. return question(query)
  31. }
  32. /**
  33. * removes array of files
  34. *
  35. */
  36. const deleteFiles = async (files) => {
  37. for (const file of files) {
  38. try {
  39. const path = `${filesDir}/${file}.svg`
  40. const fileExists = await checkIfFileExists(path)
  41. if (fileExists) {
  42. await fs.unlink(path)
  43. console.log(`${file}.svg successfully deleted!`)
  44. }
  45. } catch (err) {
  46. console.error(`Error while deleting ${file}.svg`)
  47. }
  48. }
  49. }
  50. /**
  51. * clear files dir
  52. *
  53. */
  54. const clearFilesDir = async () => {
  55. try {
  56. await fs.readdir(filesDir).then((files) => Promise.all(files.map((file) => fs.unlink(`${filesDir}/${file}`))))
  57. console.log(`${filesDir} successfully cleared!`)
  58. } catch (err) {
  59. console.error(`Error while clearing ${filesDir}`)
  60. }
  61. }
  62. /**
  63. * generate icon/illustration content
  64. * [fileName].svg files
  65. *
  66. * @param {object} svgNode
  67. * @param {number} total
  68. * @return {Promise<void>}
  69. */
  70. const generateIconOrIllustration = async (svgNode, total) => {
  71. const fileUrl = await getSvgImageUrl(svgNode.id)
  72. const fileName = kebabCase(svgNode.name)
  73. try {
  74. await fs.access(filesDir)
  75. } catch (error) {
  76. await fs.mkdir(filesDir)
  77. }
  78. const { data: fileContent } = await getImageContent(fileUrl)
  79. await Promise.all([await fs.writeFile(path.resolve(filesDir, `${fileName}.svg`), fileContent, 'utf-8')])
  80. counter++
  81. process.stdout.write(` ${counter}/${total} files has been saved\r`)
  82. if (counter === total) {
  83. console.info('All svgs has been saved')
  84. }
  85. }
  86. /**
  87. * generate icons/illustrations components
  88. *
  89. * @param {[Object]} svgNodesArr - array of svgs from frame
  90. * @return {Promise<void>}
  91. */
  92. const generateIconsOrIllustrations = async (svgNodesArr) => {
  93. try {
  94. await Promise.all(
  95. svgNodesArr.map((item, index) => {
  96. setTimeout(() => generateIconOrIllustration(item, svgNodesArr.length), 1000 * index)
  97. })
  98. )
  99. } catch (err) {
  100. console.error('Error while generating icons', err)
  101. }
  102. }
  103. const main = async () => {
  104. try {
  105. const shouldRegenerateAllFiles = await prompt('Do you want to import all files? (y/n) ')
  106. let arrayOfFilesToGenerate = []
  107. if (shouldRegenerateAllFiles === 'n') {
  108. const filesToGenerate =
  109. shouldRegenerateAllFiles &&
  110. (await prompt('Which files do you want to import? (Provide string-separated string with no .svg extension) '))
  111. arrayOfFilesToGenerate = filesToGenerate.split(' ')
  112. await deleteFiles(arrayOfFilesToGenerate)
  113. } else {
  114. await clearFilesDir()
  115. }
  116. const filesNodesArr = await getNodeChildren(
  117. type === 'icons' ? config.FRAME_WITH_ICONS_ID : config.FRAME_WITH_ILLUSTRATIONS_ID
  118. )
  119. const nodesToGenerate = filesNodesArr.filter((node) =>
  120. arrayOfFilesToGenerate.length ? arrayOfFilesToGenerate.includes(node.name) : true
  121. )
  122. if (!nodesToGenerate?.length) {
  123. console.error('No nodes found')
  124. return
  125. }
  126. await generateIconsOrIllustrations(nodesToGenerate)
  127. } catch (e) {
  128. console.error('Unhandled error', e)
  129. }
  130. }
  131. module.exports = main