DefinitelyTyped/scripts/material-ui/generate.js
Daisuke Mino 193d9dc3bf [material-ui] Update svg-icons (#18931)
* [material-ui] Update svg-icons

* Update mark for code generation

* Add a code generation script for material-ui

* Remove .js in ./scripts
2017-08-17 07:58:09 -07:00

148 lines
4.3 KiB
JavaScript

const {get} = require('https')
const {readdir, readFile, writeFile} = require('fs')
const {join, extname, basename, dirname, relative} = require('path')
const token = process.env.GITHUB_ACCESS_TOKEN || ''
const toMixedCase = (name) => {
let dist = name[0].toUpperCase()
for (let i = 1; i < name.length; i++) {
const c = name[i]
if (c !== '-') {
dist += c
continue
}
i++
dist += name[i].toUpperCase()
}
return dist
}
const github = (path) => new Promise((resolve, reject) => {
get({
headers: {'user-agent': 'DefinitelyTyped/material-ui/generate'},
host: 'api.github.com',
path,
}, (res) => {
if ((res.statusCode / 100 >> 0) != 2) {
reject(`GitHub response: ${res.statusCode} ${res.statusMessage}`)
return
}
let data = '';
res
.on('data', (chunk) => data += chunk)
.on('end', () => resolve(JSON.parse(data)))
}).on('error', reject)
})
const categories = () => github(`/repos/callemall/material-ui/contents/src/svg-icons?ref=master&access_token=${token}`)
const contents = (path) => github(`/repos/callemall/material-ui/contents/${path}?ref=master&access_token=${token}`)
const collator = new Intl.Collator()
const resolvePath = (filename) => join(__dirname, '../../types/material-ui', filename)
const readText = (filename) => new Promise((resolve, reject) => {
readFile(resolvePath(filename), 'utf8', (err, data) => {
if (err != null) {
reject(err)
return
}
resolve(data)
})
})
const writeText = (filename, text) => new Promise((resolve, reject) => {
writeFile(resolvePath(filename), text, 'utf8', (err) => {
if (err != null) {
reject(err)
return
}
resolve()
})
})
const inject = (content) => {
content.category = this.name
return content
}
const rMark = /(\/{2} \{{3})[\s\S]*?(\/{2} \}{3})/g
categories()
.then((cats) => Promise.all(Array.prototype.map.call(cats, (cat) => contents(cat.path)
.then((cons) => Array.prototype.map.call(cons, (con) => {
con.category = cat.name
return con
}))
)))
.then((contentsList) => Array.prototype.concat.apply([], contentsList)
.map((content) => {
const {path} = content
const name = basename(path, extname(path))
content.id = join(relative('src', dirname(path)), name)
content.className = toMixedCase(content.category) + toMixedCase(name)
return content
})
.sort((a, b) => collator.compare(a.id, b.id))
.reduce((prev, content) => {
const {dts, test} = prev
dts.individuals.push(`declare module 'material-ui/${content.id}' {
export import ${content.className} = __MaterialUI.SvgIcon;
export default ${content.className};
}`)
dts.summarizeds.push(` export import ${content.className} = __MaterialUI.SvgIcon; // require('material-ui/${content.id}');`)
test.individuals.push(`import _${content.className} from 'material-ui/${content.id}';`)
test.summarizeds.push(` ${content.className},`)
return prev
}, {
dts: {individuals: [], summarizeds: []},
test: {individuals: [], summarizeds: []},
})
)
.then(({dts, test}) => {
return Promise.all([
(() => {
const {individuals, summarizeds} = dts
const file = 'index.d.ts'
let index = 0
return readText(file)
.then((script) => writeText(file, script.replace(rMark, (_, p1, p2) => {
let text = ''
switch (index) {
case 0:
text = individuals.join('\n\n')
break
case 1:
text = summarizeds.join('\n')
break
}
index++
return p1 + '\n' + text + '\n' + p2
})))
})(),
(() => {
const {individuals, summarizeds} = test
const file = join('material-ui-tests.tsx')
let index = 0
return readText(file)
.then((script) => writeText(file, script.replace(rMark, (_, p1, p2) => {
let text = ''
switch (index) {
case 0:
text = individuals.join('\n')
break
case 1:
text = summarizeds.join('\n')
break
}
index++
return p1 + '\n' + text + '\n' + p2
})))
})(),
])
})
.catch((err) => console.error(err))