Files
react/scripts/collect-meta.js
2020-04-06 08:56:06 +08:00

139 lines
3.9 KiB
JavaScript

const fs = require('fs-extra')
const path = require('path')
const extractMetadata = require('extract-mdx-metadata')
const metaLocales = require('./locales')
const pagePrefix = path.join(__dirname, '../pages')
const targetPath = path.join(__dirname, '../lib/data/metadata.json')
const weights = {
'guide': 1,
'docs': 2,
'getting-started': 3,
'customization': 4,
'components': 5,
}
const groupWeights = {
'快速上手': 1,
'起步': 2,
'定制化': 5,
'general': 1,
'通用': 1,
'layout': 2,
'布局': 2,
'surfaces': 3,
'表面': 3,
'data entry': 4,
'数据录入': 4,
'data display': 5,
'数据展示': 5,
'feedback': 6,
'反馈': 6,
'navigation': 7,
'导航': 7,
'others': 8,
'其他': 8,
}
const getMetadata = async (files, parentPath) => {
return Promise.all(
files
.filter(name => name.endsWith('.mdx') || !name.includes('.'))
.map(async file => {
const filePath = path.join(parentPath, file)
const isDirectory = fs.statSync(filePath).isDirectory()
if (isDirectory) {
const children = await fs.readdir(filePath)
const childrenMetadata = await getMetadata(children, filePath)
const sorted = childrenMetadata.sort((a, b) => a.index - b.index)
// grouping
const childrenHasGroup = sorted.find(item => item.group)
if (childrenHasGroup) {
const groups = [...new Set(sorted.map(item => item.group || 'others'))]
const groupChildren = groups
.map(groupName => ({
name: groupName,
children: sorted.filter(item => (item.group || 'others') === groupName)
}))
.sort((a, b) => {
const pre = a.name.toLowerCase()
const current = b.name.toLowerCase()
return groupWeights[pre] - groupWeights[current]
})
return {
name: file,
children: groupChildren,
}
}
return { name: file, children: sorted }
}
const content = await fs.readFile(filePath, 'utf-8')
const meta = await extractMetadata(content)
const url = filePath
.replace(pagePrefix, '')
.replace('.mdx', '')
return {
name: meta.title || file,
url,
index: meta.index || 100,
group: meta.group || null,
}
})
)
}
const deepTranslate = (metadata, locales) => {
if (!metadata || !Array.isArray(metadata)) return metadata
return metadata.map(data => {
if (typeof data !== 'object') return data
if (data.children) {
data.children = deepTranslate(data.children, locales)
}
const localeName = locales[data.name]
if (!localeName) return data
return {
...data,
localeName,
}
})
}
;(async () => {
try {
const locales = (await fs.readdir(pagePrefix))
.filter(name => {
const fullPath = path.join(pagePrefix, name)
if (name === 'docs') return false
return fs.statSync(fullPath).isDirectory()
})
const sortdMetaData = await Promise.all(locales.map(async name => {
const currentLocale = metaLocales[name] || {}
const dir = path.join(pagePrefix, name)
const childDirs = await fs.readdir(dir)
const data = await getMetadata(childDirs, dir)
const sorted = data
.sort((a, b) => weights[a.name] - weights[b.name])
const translatedData = deepTranslate(sorted, currentLocale)
return {
name,
content: translatedData
}
}))
const jsonData = sortdMetaData.reduce((pre, current) => {
return {
...pre,
[current.name]: current.content,
}
}, [])
await fs.ensureFile(targetPath)
await fs.writeJson(targetPath, jsonData)
} catch (e) {
console.log(e)
process.exit(1)
}
})()