verify-medtech-theme.mjs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import { readFileSync, readdirSync, statSync } from 'node:fs'
  2. import { join, relative } from 'node:path'
  3. const root = new URL('..', import.meta.url).pathname
  4. const src = join(root, 'src')
  5. const requiredFiles = [
  6. 'src/styles/theme.css',
  7. 'src/styles/components.css',
  8. 'src/styles/element-plus.css'
  9. ]
  10. const requiredTokens = [
  11. '--color-brand: #2b1f99',
  12. '--color-accent: #3ad4d8',
  13. '--color-bg:',
  14. '--color-surface:',
  15. '--color-border:',
  16. '--color-text:',
  17. '--radius-xs: 4px',
  18. '--radius-sm: 6px',
  19. '--radius-md: 8px'
  20. ]
  21. const bannedEmoji = /[📋📌⚡⏳✅❌🎯🚀💡🔥]/
  22. const bannedDecor = /(radial-gradient|gradient orb|bokeh|blur\(60px\)|border-radius:\s*(1[2-9]|[2-9]\d)px)/
  23. function walk(dir) {
  24. return readdirSync(dir).flatMap((name) => {
  25. const path = join(dir, name)
  26. return statSync(path).isDirectory() ? walk(path) : [path]
  27. })
  28. }
  29. const failures = []
  30. for (const file of requiredFiles) {
  31. try {
  32. readFileSync(join(root, file), 'utf8')
  33. } catch {
  34. failures.push(`missing required style file: ${file}`)
  35. }
  36. }
  37. const themePath = join(root, 'src/styles/theme.css')
  38. let theme = ''
  39. try {
  40. theme = readFileSync(themePath, 'utf8')
  41. } catch {}
  42. for (const token of requiredTokens) {
  43. if (!theme.includes(token)) failures.push(`missing theme token: ${token}`)
  44. }
  45. const main = readFileSync(join(root, 'src/main.js'), 'utf8')
  46. for (const file of requiredFiles) {
  47. const importPath = './' + file.replace('src/', '')
  48. if (!main.includes(importPath)) failures.push(`main.js must import ${importPath}`)
  49. }
  50. const vueAndCssFiles = walk(src).filter((file) => /\.(vue|css)$/.test(file))
  51. for (const file of vueAndCssFiles) {
  52. const text = readFileSync(file, 'utf8')
  53. const rel = relative(root, file)
  54. if (bannedEmoji.test(text)) failures.push(`banned emoji in ${rel}`)
  55. if (bannedDecor.test(text)) failures.push(`banned decorative style in ${rel}`)
  56. }
  57. if (failures.length) {
  58. console.error(failures.join('\n'))
  59. process.exit(1)
  60. }
  61. console.log('medtech theme checks passed')