vuecssuiant-designantdreactantantd-vueenterprisefrontendui-designvue-antdvue-antd-uivue3vuecomponent
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
165 lines
4.3 KiB
165 lines
4.3 KiB
const program = require('commander'); |
|
const majo = require('majo'); |
|
const fs = require('fs'); |
|
const path = require('path'); |
|
const chalk = require('chalk'); |
|
|
|
const unified = require('unified'); |
|
const parse = require('remark-parse'); |
|
const stringify = require('remark-stringify'); |
|
|
|
const yamlConfig = require('remark-yaml-config'); |
|
const frontmatter = require('remark-frontmatter'); |
|
|
|
let fileAPIs = {}; |
|
const remarkWithYaml = unified() |
|
.use(parse) |
|
.use(stringify, { |
|
paddedTable: false, |
|
listItemIndent: 1, |
|
stringLength: () => 3, |
|
}) |
|
.use(frontmatter) |
|
.use(yamlConfig); |
|
|
|
const stream = majo.majo(); |
|
|
|
function getCellValue(node) { |
|
return node.children[0].children[0].value; |
|
} |
|
|
|
// from small to large |
|
const sizeBreakPoints = ['xs', 'sm', 'md', 'lg', 'xl', 'xxl']; |
|
|
|
const whiteMethodList = ['afterChange', 'beforeChange']; |
|
|
|
const groups = { |
|
isDynamic: val => /^on[A-Z]/.test(val) || whiteMethodList.indexOf(val) > -1, |
|
isSize: val => sizeBreakPoints.indexOf(val) > -1, |
|
}; |
|
|
|
function asciiSort(prev, next) { |
|
if (prev > next) { |
|
return 1; |
|
} |
|
|
|
if (prev < next) { |
|
return -1; |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
// follow the alphabet order |
|
function alphabetSort(nodes) { |
|
// use toLowerCase to keep `case insensitive` |
|
return nodes.sort((...comparison) => |
|
asciiSort(...comparison.map(val => getCellValue(val).toLowerCase())), |
|
); |
|
} |
|
|
|
function sizeSort(nodes) { |
|
return nodes.sort((...comparison) => |
|
asciiSort(...comparison.map(val => sizeBreakPoints.indexOf(getCellValue(val).toLowerCase()))), |
|
); |
|
} |
|
|
|
function sort(ast, filename) { |
|
const nameMatch = filename.match(/^components\/([^/]*)\//); |
|
const componentName = nameMatch[1]; |
|
fileAPIs[componentName] = fileAPIs[componentName] || { |
|
static: new Set(), |
|
size: new Set(), |
|
dynamic: new Set(), |
|
}; |
|
|
|
ast.children.forEach(child => { |
|
const staticProps = []; |
|
// prefix with `on` |
|
const dynamicProps = []; |
|
// one of ['xs', 'sm', 'md', 'lg', 'xl'] |
|
const sizeProps = []; |
|
|
|
// find table markdown type |
|
if (child.type === 'table') { |
|
// slice will create new array, so sort can affect the original array. |
|
// slice(1) cut down the thead |
|
child.children.slice(1).forEach(node => { |
|
const value = getCellValue(node); |
|
if (groups.isDynamic(value)) { |
|
dynamicProps.push(node); |
|
fileAPIs[componentName].dynamic.add(value); |
|
} else if (groups.isSize(value)) { |
|
sizeProps.push(node); |
|
fileAPIs[componentName].size.add(value); |
|
} else { |
|
staticProps.push(node); |
|
fileAPIs[componentName].static.add(value); |
|
} |
|
}); |
|
|
|
// eslint-disable-next-line |
|
child.children = [ |
|
child.children[0], |
|
...alphabetSort(staticProps), |
|
...sizeSort(sizeProps), |
|
...alphabetSort(dynamicProps), |
|
]; |
|
} |
|
}); |
|
|
|
return ast; |
|
} |
|
|
|
function sortAPI(md, filename) { |
|
return remarkWithYaml.stringify(sort(remarkWithYaml.parse(md), filename)); |
|
} |
|
|
|
function sortMiddleware(ctx) { |
|
Object.keys(ctx.files).forEach(filename => { |
|
const content = ctx.fileContents(filename); |
|
ctx.writeContents(filename, sortAPI(content, filename)); |
|
}); |
|
} |
|
|
|
module.exports = () => { |
|
fileAPIs = {}; |
|
|
|
program |
|
.version('0.1.0') |
|
.option( |
|
'-f, --file [file]', |
|
'Specify which file to be transformed', |
|
// default value |
|
'components/**/index.+(zh-CN|en-US).md', |
|
) |
|
.option('-o, --output [output]', 'Specify component api output path', '~component-api.json') |
|
.parse(process.argv); |
|
// Get the markdown file all need to be transformed |
|
|
|
/* eslint-disable no-console */ |
|
stream |
|
.source(program.file) |
|
.use(sortMiddleware) |
|
.dest('.') |
|
.then(() => { |
|
if (program.output) { |
|
const data = {}; |
|
Object.keys(fileAPIs).forEach(componentName => { |
|
data[componentName] = { |
|
static: [...fileAPIs[componentName].static], |
|
size: [...fileAPIs[componentName].size], |
|
dynamic: [...fileAPIs[componentName].dynamic], |
|
}; |
|
}); |
|
|
|
const reportPath = path.resolve(program.output); |
|
fs.writeFileSync(reportPath, JSON.stringify(data, null, 2), 'utf8'); |
|
console.log(chalk.cyan(`API list file: ${reportPath}`)); |
|
} |
|
}) |
|
.then(() => { |
|
console.log(chalk.green(`sort ant-design-vue api successfully!`)); |
|
}); |
|
/* eslint-enable no-console */ |
|
};
|
|
|