validate-icons.mjs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import { globSync } from 'glob'
  2. import fs from 'fs'
  3. import { basename } from 'path'
  4. import { HOME_DIR, ICONS_SRC_DIR, iconTemplate, parseMatter, types, getArgvs } from './helpers.mjs'
  5. import { join } from 'path'
  6. let error = false
  7. const outlineIconsNames = globSync(join(ICONS_SRC_DIR, 'outline/*.svg')).map(i => basename(i, '.svg')).sort(),
  8. filledIconsNames = globSync(join(ICONS_SRC_DIR, 'filled/*.svg')).map(i => basename(i, '.svg')).sort(),
  9. argvs = getArgvs(),
  10. aliases = JSON.parse(fs.readFileSync(join(HOME_DIR, 'aliases.json'), 'utf-8'));
  11. let unicodes = []
  12. const duplicateExists = (arr) => {
  13. return new Set(arr).size !== arr.length
  14. }
  15. const getIconName = (icon) => {
  16. //return last two parts of the path
  17. return icon.split('/').slice(-2).join('/')
  18. }
  19. types.forEach(type => {
  20. const icons = globSync(join(ICONS_SRC_DIR, type, '*.svg')).sort()
  21. icons.forEach((icon) => {
  22. const iconContent = fs.readFileSync(icon, 'utf-8'),
  23. iconName = getIconName(icon)
  24. if (!iconContent.includes(iconTemplate(type))) {
  25. console.log(`⛔️ Icon \`${iconName}\` is not properly formatted`)
  26. error = true
  27. }
  28. if (!iconContent.includes('<!--') || !iconContent.includes('-->')) {
  29. console.log(`⛔️ Icon \`${iconName}\` has no metadata`)
  30. error = true
  31. }
  32. try {
  33. const { data } = parseMatter(icon)
  34. if (data.unicode) {
  35. if (unicodes.indexOf(data.unicode) !== -1) {
  36. console.log(`⛔️ Icon \`${iconName}\` has duplicate unicode \`${data.unicode}\``)
  37. error = true
  38. }
  39. if (data.unicode.length !== 4 && data.unicode.length !== 5) {
  40. console.log(`⛔️ Icon \`${iconName}\` has invalid unicode \`${data.unicode}\``)
  41. error = true
  42. }
  43. unicodes.push(data.unicode)
  44. } else if (argvs.hard) {
  45. console.log(`⛔️ Icon \`${iconName}\` has no unicode`)
  46. error = true
  47. }
  48. // check duplicates in tags
  49. if (duplicateExists(data.tags || [])) {
  50. console.log(`⛔️ Icon \`${iconName}\` has duplicate tags`)
  51. error = true
  52. }
  53. if (argvs.hard && !data.version) {
  54. console.log(`⛔️ Icon \`${iconName}\` has no version`)
  55. error = true
  56. }
  57. if (type === 'filled' && data.category) {
  58. console.log(`⛔️ Icon \`${iconName}\` has category in filled version`)
  59. error = true
  60. }
  61. if (type === 'filled' && data.tags) {
  62. console.log(`⛔️ Icon \`${iconName}\` has tags in filled version`)
  63. error = true
  64. }
  65. } catch (e) {
  66. console.log(`⛔️ Icon \`${iconName}\` has invalid metadata`)
  67. error = true
  68. }
  69. })
  70. filledIconsNames.forEach((icon) => {
  71. const iconName = getIconName(icon)
  72. if (outlineIconsNames.indexOf(icon) === -1) {
  73. console.log(`⛔️ Icon \`${iconName}\` exists in filled version but doesn't exists in outline`)
  74. error = true
  75. }
  76. })
  77. })
  78. // check aliases
  79. Object.entries(aliases).forEach(([type, replacers]) => {
  80. Object.entries(replacers).forEach(([from, to]) => {
  81. if (!fs.existsSync(join(ICONS_SRC_DIR, type, `${to}.svg`))) {
  82. console.log(`⛔️ Alias \`${type}/${from}\` for \`${type}/${to}\` doesn't exists`)
  83. error = true
  84. }
  85. })
  86. })
  87. if (error) {
  88. process.exit(1)
  89. } else {
  90. console.log('✅ All icons are valid!')
  91. process.exit(0)
  92. }