react-native-mapmagic-gl
Version:
Mapmagic GL is a react-native interactive maps library
197 lines (165 loc) • 5.16 kB
JavaScript
const docgen = require('react-docgen');
const dir = require('node-dir');
const fs = require('fs');
const path = require('path');
const { exec } = require('child_process');
const JSDocNodeTree = require('./JSDocNodeTree');
const COMPONENT_PATH = path.join(
__dirname,
'..',
'..',
'javascript',
'components',
);
const MODULES_PATH = path.join(__dirname, '..', '..', 'javascript', 'modules');
const OUTPUT_PATH = path.join(__dirname, '..', '..', 'docs', 'docs.json');
const IGNORE_FILES = ['AbstractLayer'];
class DocJSONBuilder {
constructor(styledLayers) {
this._styledLayers = {};
for (let styleLayer of styledLayers) {
const ComponentName = pascelCase(styleLayer.name);
this._styledLayers[
ComponentName + (ComponentName === 'Light' ? '' : 'Layer')
] = styleLayer;
}
}
get options() {
return {
match: /.js$/,
shortName: true,
};
}
isPrivateMethod(methodName = '') {
return !methodName || methodName.charAt(0) === '_';
}
postprocess(component, name) {
// Remove all private methods and parse examples from docblock
if (!Array.isArray(component.methods)) {
return;
}
component.name = name;
// styles
if (this._styledLayers[name] && this._styledLayers[name].properties) {
component.styles = [];
for (let prop of this._styledLayers[name].properties) {
let docStyle = {
name: prop.name,
type: prop.type,
values: [],
minimum: prop.doc.minimum,
maximum: prop.doc.maximum,
units: prop.doc.units,
default: prop.doc.default,
description: prop.doc.description,
requires: prop.doc.requires,
disabledBy: prop.doc.disabledBy,
allowedFunctionTypes: prop.allowedFunctionTypes || [],
};
if (prop.type === 'enum') {
docStyle.values = Object.keys(prop.doc.values).map((value) => {
return { value: value, doc: prop.doc.values[value].doc };
});
} else if (prop.type === 'array') {
docStyle.type = `${docStyle.type}<${prop.value}>`;
}
component.styles.push(docStyle);
}
}
// props
component.props = Object.keys(component.props).map((propName) => {
const propMeta = component.props[propName];
return {
name: propName || 'FIX ME NO NAME',
required: propMeta.required || false,
type: propMeta.type.name || 'FIX ME UNKNOWN TYPE',
default: !propMeta.defaultValue
? 'none'
: propMeta.defaultValue.value.replace(/\n/g, ''),
description: propMeta.description || 'FIX ME NO DESCRIPTION',
};
});
// methods
const privateMethods = [];
for (let method of component.methods) {
if (this.isPrivateMethod(method.name)) {
privateMethods.push(method.name);
continue;
}
if (method.docblock) {
const examples = method.docblock
.split('@')
.filter((block) => block.startsWith('example'));
method.examples = examples.map((example) =>
example.substring('example'.length),
);
}
}
component.methods = component.methods.filter(
(method) => !privateMethods.includes(method.name),
);
}
generateReactComponentsTask(results, filePath) {
return new Promise((resolve, reject) => {
dir.readFiles(
filePath,
this.options,
(err, content, fileName, next) => {
if (err) {
return reject(err);
}
fileName = fileName.replace('.js', '');
if (IGNORE_FILES.includes(fileName)) {
next();
return;
}
results[fileName] = docgen.parse(content);
this.postprocess(results[fileName], fileName);
next();
},
() => resolve(),
);
});
}
generateModulesTask(results, filePath) {
return new Promise((resolve, reject) => {
exec(
`documentation build ${MODULES_PATH} -f json`,
(err, stdout, stderr) => {
if (err || stderr) {
reject(err || stderr);
return;
}
const modules = JSON.parse(stdout);
for (let module of modules) {
const node = new JSDocNodeTree(module);
const name = `${module.name
.charAt(0)
.toLowerCase()}${module.name.substring(1)}`;
results[name] = {
name: name,
description: node.getText(),
props: [],
styles: [],
methods: node.getMethods(),
};
}
resolve();
},
);
});
}
generate() {
this.generateModulesTask({}, MODULES_PATH);
let results = {};
const tasks = [
this.generateReactComponentsTask(results, COMPONENT_PATH),
this.generateModulesTask(results, MODULES_PATH),
];
return Promise.all(tasks).then(() => {
fs.writeFileSync(OUTPUT_PATH, JSON.stringify(results, null, 2));
return true;
});
}
}
module.exports = DocJSONBuilder;