2019-10-19 02:20:56 +03:00
|
|
|
#!/usr/bin/env node
|
2021-08-12 00:10:47 +03:00
|
|
|
import postcss from 'postcss'
|
|
|
|
import {join} from 'path'
|
|
|
|
import fs from 'fs'
|
|
|
|
import atImport from 'postcss-import'
|
|
|
|
import syntax from 'postcss-scss'
|
|
|
|
import calc from 'postcss-calc'
|
|
|
|
import simpleVars from 'postcss-simple-vars'
|
|
|
|
|
|
|
|
import { dirname } from 'path';
|
|
|
|
import { fileURLToPath } from 'url';
|
|
|
|
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
2019-10-19 02:20:56 +03:00
|
|
|
|
2021-04-09 05:34:17 +03:00
|
|
|
const processor = postcss([
|
|
|
|
atImport({path: ['src']}),
|
|
|
|
collectVariables(),
|
2021-08-12 00:10:47 +03:00
|
|
|
simpleVars({includePaths: [join(__dirname, '../src/support/variables')]})
|
2021-04-09 05:34:17 +03:00
|
|
|
])
|
2019-10-19 02:20:56 +03:00
|
|
|
|
2021-04-09 05:34:17 +03:00
|
|
|
async function analyzeVariables(fileName) {
|
2021-08-12 00:10:47 +03:00
|
|
|
const contents = fs.readFileSync(fileName, 'utf8')
|
2019-10-19 02:20:56 +03:00
|
|
|
|
2021-04-09 05:34:17 +03:00
|
|
|
const result = await processor.process(contents, {from: fileName, map: false, syntax})
|
|
|
|
for (const message of result.messages) {
|
|
|
|
if (message.plugin === 'postcss-simple-vars' && message.type === 'variable') {
|
|
|
|
if (!result.variables[`$${message.name}`].values.includes(message.value)) {
|
|
|
|
result.variables[`$${message.name}`].values.push(message.value)
|
2019-10-19 02:20:56 +03:00
|
|
|
}
|
2021-05-26 00:29:18 +03:00
|
|
|
let computed = message.value
|
|
|
|
try {
|
|
|
|
const c = `--temp-property: calc(${message.value})`.replace('round(', '(')
|
|
|
|
computed = postcss().use(calc()).process(c).css
|
|
|
|
computed = computed.replace('--temp-property: ', '')
|
|
|
|
} catch (e) {
|
|
|
|
// Couldn't calculate because value might not be a number
|
|
|
|
}
|
2021-04-09 05:34:17 +03:00
|
|
|
result.variables[`$${message.name}`].computed = computed
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result.variables
|
2019-10-19 02:20:56 +03:00
|
|
|
}
|
|
|
|
|
2021-04-09 05:34:17 +03:00
|
|
|
function checkNode(node) {
|
|
|
|
const allowedFuncts = ['var', 'round', 'cubic-bezier']
|
2022-04-12 23:57:56 +03:00
|
|
|
const funcMatch = node.value.match(/([^\s]*)\(/)
|
2021-04-09 05:34:17 +03:00
|
|
|
let approvedMatch = true
|
2022-04-12 23:57:56 +03:00
|
|
|
if (funcMatch && !allowedFuncts.includes(funcMatch[1])) {
|
2021-04-09 05:34:17 +03:00
|
|
|
approvedMatch = false
|
|
|
|
}
|
|
|
|
return node.variable && approvedMatch
|
|
|
|
}
|
2019-10-19 02:20:56 +03:00
|
|
|
|
2021-04-09 05:34:17 +03:00
|
|
|
function collectVariables() {
|
|
|
|
return {
|
|
|
|
postcssPlugin: 'prepare-contents',
|
|
|
|
prepare(result) {
|
|
|
|
const variables = {}
|
|
|
|
return {
|
|
|
|
AtRule(atRule) {
|
|
|
|
atRule.remove()
|
|
|
|
},
|
|
|
|
Comment(comment) {
|
|
|
|
comment.remove()
|
|
|
|
},
|
|
|
|
Declaration(node) {
|
|
|
|
if (checkNode(node)) {
|
|
|
|
node.value = node.value.replace(' !default', '')
|
|
|
|
const fileName = node.source.input.file.replace(`${process.cwd()}/`, '')
|
|
|
|
variables[node.prop] = {
|
|
|
|
// computed: value,
|
|
|
|
values: [node.value],
|
|
|
|
source: {
|
|
|
|
path: fileName,
|
|
|
|
line: node.source.start.line
|
2021-04-08 20:27:54 +03:00
|
|
|
}
|
2019-10-19 02:20:56 +03:00
|
|
|
}
|
2021-04-09 05:34:17 +03:00
|
|
|
} else {
|
|
|
|
node.remove()
|
2019-10-19 02:20:56 +03:00
|
|
|
}
|
2021-04-09 05:34:17 +03:00
|
|
|
},
|
|
|
|
OnceExit() {
|
|
|
|
result.variables = variables
|
2019-10-19 02:20:56 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-04-08 20:27:54 +03:00
|
|
|
}
|
2019-10-19 02:20:56 +03:00
|
|
|
}
|
|
|
|
|
2021-08-12 00:10:47 +03:00
|
|
|
export default analyzeVariables
|
|
|
|
|
|
|
|
;(async () => {
|
|
|
|
const args = process.argv.slice(2)
|
|
|
|
const file = args.length ? args.shift() : 'src/support/index.scss'
|
|
|
|
const variables = await analyzeVariables(file)
|
2021-09-10 20:54:26 +03:00
|
|
|
JSON.stringify(variables, null, 2)
|
2021-08-12 00:10:47 +03:00
|
|
|
})()
|