112 lines
4.2 KiB
JavaScript
112 lines
4.2 KiB
JavaScript
const fs = require('fs')
|
|
const nodePath = require('path')
|
|
const plugin = require('tailwindcss/plugin')
|
|
const generator = require('./generator')
|
|
const crypto = require('crypto')
|
|
|
|
/**
|
|
* Uretilen renk/olcu listesiyle Custom Component siniflarini ayiran isaret. Bilesen siniflari
|
|
* dosyanin sonunda yasar; kaynak seed dosyasi bulunamadiginda onceki liste oldugu gibi korunur.
|
|
*/
|
|
const COMPONENT_MARKER = '# --- custom component classes ---'
|
|
|
|
/** Seed kokunun `ui/` klasorune gore konumu; calisma dizininden bagimsiz cozulur. */
|
|
const SEEDS_ROOT = nodePath.resolve(__dirname, '../../configs/seeds')
|
|
|
|
const addTokens = (value, classes) =>
|
|
String(value)
|
|
.split(/\s+/)
|
|
.filter(Boolean)
|
|
.forEach((token) => classes.add(token))
|
|
|
|
const collectFromNodes = (nodes, classes) => {
|
|
if (!Array.isArray(nodes)) return
|
|
|
|
for (const node of nodes) {
|
|
for (const [name, value] of Object.entries((node && node.props) || {})) {
|
|
if (typeof value === 'string' && /class(Name)?$/i.test(name)) addTokens(value, classes)
|
|
}
|
|
collectFromNodes(node && node.children, classes)
|
|
}
|
|
}
|
|
|
|
const collectFromRow = (row, classes) => {
|
|
try {
|
|
const props = row && row.Props ? JSON.parse(row.Props) : null
|
|
collectFromNodes(props && props.visualDesigner && props.visualDesigner.nodes, classes)
|
|
} catch {
|
|
// Tasarimci belgesi olmayan (elle yazilmis) bilesen; siniflari asagida kodundan gelir.
|
|
}
|
|
|
|
const code = String((row && row.Code) || '')
|
|
const pattern = /className=\{?["'`]([^"'`]+)["'`]/g
|
|
let match = pattern.exec(code)
|
|
while (match) {
|
|
addTokens(match[1], classes)
|
|
match = pattern.exec(code)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Custom Component'lerin kullandigi siniflar. Bilesen kodu veritabaninda yasar; derlemede
|
|
* taranabilen tek kaynak seed dosyasidir ve o dosya `ui/` disindadir. Derleme baglami depo kokunu
|
|
* gormedigin de (docker, ayri checkout) seed'e ozgu siniflar CSS'e hic girmez ve uygulama sunucuda
|
|
* stilsiz kalir. Siniflar safelist'e yazilir; dosya depoya islendigi icin her ortamda taranir.
|
|
*/
|
|
const collectComponentClasses = () => {
|
|
if (!fs.existsSync(SEEDS_ROOT)) return []
|
|
|
|
const files = fs
|
|
.readdirSync(SEEDS_ROOT, { withFileTypes: true })
|
|
.filter((entry) => entry.isDirectory())
|
|
.map((entry) =>
|
|
nodePath.join(SEEDS_ROOT, entry.name, 'data/App.DeveloperKit.CustomComponents.json'),
|
|
)
|
|
.filter((file) => fs.existsSync(file))
|
|
|
|
const classes = new Set()
|
|
for (const file of files) {
|
|
try {
|
|
const seed = JSON.parse(fs.readFileSync(file, 'utf8'))
|
|
for (const row of seed.Rows || []) collectFromRow(row, classes)
|
|
} catch {
|
|
// Bozuk bir seed dosyasi derlemeyi durdurmaz; diger kapsamlar islenir.
|
|
}
|
|
}
|
|
|
|
return [...classes].sort()
|
|
}
|
|
|
|
module.exports = plugin.withOptions(
|
|
({ path = 'safelist.txt', patterns = [] }) =>
|
|
({ theme }) => {
|
|
// Yol calisma dizinine gore cozulurse depo kokunden calistirilan her arac ikinci bir
|
|
// safelist dosyasi yaratir; eklentinin konumuna sabitlenir, tek dosya kalir.
|
|
const safeListPath = nodePath.isAbsolute(path)
|
|
? path
|
|
: nodePath.resolve(__dirname, '..', path)
|
|
const currentSafeList = fs.existsSync(safeListPath)
|
|
? fs.readFileSync(safeListPath).toString()
|
|
: ''
|
|
const previousComponents = currentSafeList.split(COMPONENT_MARKER)[1] || ''
|
|
|
|
const seedClasses = collectComponentClasses()
|
|
const components = seedClasses.length
|
|
? seedClasses
|
|
: previousComponents.split('\n').filter(Boolean)
|
|
|
|
const safeList = [...generator(theme)(patterns), COMPONENT_MARKER, ...components].join(
|
|
'\n',
|
|
)
|
|
|
|
const hash = crypto.createHash('md5').update(JSON.stringify(safeList)).digest('hex')
|
|
const prevHash = crypto
|
|
.createHash('md5')
|
|
.update(JSON.stringify(currentSafeList))
|
|
.digest('hex')
|
|
|
|
if (hash !== prevHash) {
|
|
return fs.writeFileSync(safeListPath, safeList)
|
|
}
|
|
},
|
|
)
|