Created
July 27, 2018 22:17
-
-
Save baransu/ba11c1edbeb3e48894abe109f3029b87 to your computer and use it in GitHub Desktop.
[WIP] Generate ReasonReact bindings
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @noflow | |
const { compile, format } = require("reasonably-typed"); | |
const fs = require("fs"); | |
const COMPONENTS = [ | |
"Button", | |
"Card", | |
"Center", | |
"Checkbox", | |
"CloseIcon", | |
"DatePicker", | |
"DotIcon", | |
"Error", | |
"FormItem", | |
"H2", | |
"Icon", | |
"If", | |
"Input", | |
"KeyValue", | |
"Link", | |
"Notifications", | |
"Pagination", | |
"Popconfirm", | |
"Quote", | |
"RangeDatePicker", | |
"SmallText", | |
"Spinner", | |
"Switch", | |
"Table", | |
"Tabs", | |
"Text", | |
"Textarea", | |
"Tooltip" | |
]; | |
COMPONENTS.forEach(module => { | |
const inputPath = `./src/components/${module}.js`; | |
const source = fs.readFileSync(inputPath).toString(); | |
const CLASS_REGEX = /(class \w+ extends Component<\w+(, \w+)?>)/gm; | |
const TYPE_REGEX = /(type \w+ = (.|\s)+?;)/gm; | |
const FUNCTION_REGEX = /(function|const) [A-Z]\w+ = \(props: Props\)/gm; | |
function getTypes(source) { | |
return (source.match(TYPE_REGEX) || []) | |
.map(type => type.replace(/<\*>/g, "<any>")) | |
.map(type => `declare ${type}`) | |
.join("\n\n"); | |
} | |
function getClasses(source) { | |
return (source.match(CLASS_REGEX) || []) | |
.map(c => c.replace(/Component/, "React$Component")) | |
.map(c => `declare export ${c} { }`) | |
.join("\n\n"); | |
} | |
function getFunctions(source) { | |
return (source.match(FUNCTION_REGEX) || []).join("\n\n"); | |
} | |
const input = ` | |
const React = require('react'); | |
declare module 'components' { | |
${getTypes(source)} | |
${getClasses(source)} | |
${getFunctions(source)} | |
} | |
`; | |
console.log(input); | |
const { bsCode } = compile(input, inputPath, true, true); | |
const clean = bsCode | |
.replace(/elementRef\('any\)/g, "ref(ReasonReact.reactElement)") | |
.replace(/react_Node/g, "ReasonReact.reactElement") | |
.replace(/syntheticEvent\('any\)/g, "ReactEventRe.Synthetic.t") | |
.replace(/unit_or_promise_any/g, "Js.Promise.t(unit)") | |
.replace(/Js\.boolean/g, "bool") | |
.replace(/"style": Js\.Nullable\.t\('any\)/g, `"style": Js.Nullable.t(ReactDOMRe.style)`) | |
.replace(/"type": _type/g, `"_type": _type`) | |
.replace(/Js\.Boolean\.to_js_boolean/g, "") | |
.replace(/Js\.Nullable\.from_opt/g, "Js.Nullable.fromOption"); | |
const reason = format(clean); | |
const output = `./src/${module}.re`; | |
if (fs.existsSync(output)) { | |
console.error(`Output file: ${output} already exists.`); | |
} else { | |
fs.writeFileSync(output, reason, "utf-8"); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment