woocommerce/plugins/woocommerce-admin/bin/generate-docs/lib/file-system.js

158 lines
4.2 KiB
JavaScript

/**
* External dependencies
*/
const { isArray, uniq } = require( 'lodash' );
const fs = require( 'fs' );
const path = require( 'path' );
const recast = require( 'recast' );
const types = require( 'ast-types' );
const { namedTypes } = types;
/**
* Internal dependencies
*/
const { camelCaseDash } = require( './formatting' );
const ANALYTICS_FOLDER = path.resolve(
__dirname,
'../../../client/analytics/components/'
);
const PACKAGES_FOLDER = path.resolve(
__dirname,
'../../../packages/components/src/'
);
const DOCS_FOLDER = path.resolve( __dirname, '../../../docs/components/' );
/**
* Get an array of files exported from in the given file
*
* @param { string } filePath The file to parse for exports.
* @return { string } Formatted string.
*/
function getExportedFileList( filePath ) {
const content = fs.readFileSync( filePath );
const ast = recast.parse( content );
const files = [];
types.visit( ast, {
// This method will be called for any node with .type "ExportNamedDeclaration":
visitExportNamedDeclaration( nodePath ) {
const { node } = nodePath;
if (
namedTypes.Literal.check( node.source ) &&
isArray( node.specifiers ) &&
namedTypes.ExportSpecifier.check( node.specifiers[ 0 ] )
) {
if ( node.source.value.indexOf( 'use-filters' ) === -1 ) {
files.push( node.source.value );
}
}
// Keep traversing this path…
this.traverse( nodePath );
},
} );
return files;
}
/**
* Return the markdown file name for a given component file.
*
* @param { string } filepath File path for this component.
* @param { string } route Folder where the docs must be stored.
* @param { boolean } absolute Whether to return full path (true) or just filename (false).
* @return { string } Markdown file name.
*/
function getMdFileName( filepath, route, absolute = true ) {
const fileParts = filepath.split( '/components/' );
if ( ! fileParts || ! fileParts[ 1 ] ) {
return;
}
let name = fileParts[ 1 ].replace( 'src/', '' ).split( '/' )[ 0 ];
// Package components have a different structure.
if ( route === 'packages' ) {
name += '/README';
}
if ( ! absolute ) {
return name + '.md';
}
return path.resolve( DOCS_FOLDER + '/' + route + '/', name + '.md' );
}
/**
* Get an array of files exported from in the given file
*
* @param {Array} files A list of files, presumably in the components directory.
* @param { string } basePath The absolute path to the components directory.
* @return {Array} Updated array with absolute paths to all files.
*/
function getRealFilePaths( files, basePath = PACKAGES_FOLDER ) {
files.sort();
return files.map( ( file ) => {
const fullPath = path.resolve( basePath, file );
if ( isFile( fullPath ) ) {
return fullPath;
}
if ( isFile( `${ fullPath }.js` ) ) {
return `${ fullPath }.js`;
}
if ( isFile( `${ fullPath }/index.js` ) ) {
return `${ fullPath }/index.js`;
}
const folderName = path.basename( fullPath );
if ( isFile( `${ fullPath }/${ folderName }.js` ) ) {
return `${ fullPath }/${ folderName }.js`;
}
return fullPath;
} );
}
/**
* Check if a file exists and is not a directory.
*
* @param { string } file A file path to test.
* @return { boolean } True if this path exists and is a file.
*/
function isFile( file ) {
if ( ! fs.existsSync( file ) ) {
return false;
}
const stats = fs.statSync( file );
return stats && stats.isFile();
}
/**
* Create a table of contents given a list of markdown files.
*
* @param {Array} files A list of files, presumably in the components directory.
* @param { string } route Folder where the docs are stored.
* @param { string } title Title of the TOC section
* @return { string } TOC contents.
*/
function getTocSection( files, route, title ) {
const mdFiles = files
.map( ( f ) => getMdFileName( f, route, false ) )
.sort();
const toc = uniq( mdFiles ).map( ( doc ) => {
const name = camelCaseDash(
doc.replace( '.md', '' ).split( '/' )[ 0 ]
);
return ` * [${ name }](components/${ route }/${ doc })`;
} );
return [ ' * [' + title + '](components/' + route + '/)', ...toc ];
}
module.exports = {
DOCS_FOLDER,
ANALYTICS_FOLDER,
PACKAGES_FOLDER,
getExportedFileList,
getMdFileName,
getRealFilePaths,
getTocSection,
};