diff --git a/bin/cli.js b/bin/cli.js index 59dd2ca..1085d91 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -1,7 +1,5 @@ #!/usr/bin/env node -var path = require('path'); -var fs = require('fs'); var main = require('../'); // --- @@ -11,7 +9,6 @@ var argv = require('yargs') .alias('p', 'pattern') .alias('d', 'dest') .alias('f', 'outputFormat') - .default('dest', 'illustrator.js') .check(function patternValidator(argv) { if (!argv.pattern.length) { throw new Error('Please define at least one pattern for processing.'); @@ -23,10 +20,8 @@ var argv = require('yargs') // --- -(function genManifest() { - argv.dest = path.resolve(argv.dest); - - main.illustrate(argv.pattern, argv) - .then(fs.writeFileSync.bind(fs, argv.dest)) - ; -})(); +main.illustrate(argv.pattern, argv) + .catch(function (error) { + console.error(error, error.stack); + }) +; diff --git a/src/illustrator.js b/src/illustrator.js index b4656af..052adbc 100644 --- a/src/illustrator.js +++ b/src/illustrator.js @@ -1,55 +1,100 @@ 'use strict'; +import fs from 'fs'; +import path from 'path'; import dox from 'dox'; import {parse as parseRectDoc} from 'react-docgen'; // --- export default class Illustrator { - constructor() { + constructor(options) { + this.options = options; this.store = {}; } // --- record(key) { - return (value) => { - return this.store[key] = value; - }; + return value => this.store[key] = value; + } + + processExample(file) { + return Promise.resolve(file) + .then(this.record('examplePath')) + .then(() => this.relativePath(file)) + .then(this.record('exampleRequirePath')) + .then(() => fs.readFileSync(file, {encoding: 'utf-8'})) + .then(this.record('exampleSource')) + .then(this.parseExampleDoc) + .then(this.record('exampleDoc')) + ; } - parseExampleComments(code) { + processComponent(file) { + return Promise.resolve(file) + .then(this.record('componentPath')) + .then(() => { + let componentPath = path.resolve(this.store.examplePath, file); + if (!/\.js$/.test(componentPath)) { + componentPath += '.js'; + } + return componentPath; + }) + .then(path => fs.readFileSync(path, {encoding: 'utf-8'})) + .then(this.record('componentSource')) + .then(this.parseComponentDoc) + .then(this.record('componentDoc')) + ; + } + + parseExampleDoc(code) { return dox.parseComments(code)[0]; } - parseReactDoc(code) { + parseComponentDoc(code) { return parseRectDoc(code); } + relativePath() { + let paths = Array.from(arguments, p => path.resolve(p)); + paths.unshift(path.dirname(this.options.dest || path.resolve('.'))); + + let relative = path.relative.apply(path, paths); + + if (relative[0] !== '.') { + relative = `.${path.sep}${relative}`; + } + + return relative; + } + run() { return { - comment: this.store.comment, - componentPath: this.componentPath, - documentation: this.store.documentation, - exampleContent: this.store.exampleContent, - examplePath: this.store.examplePath, - sourceContent: this.store.sourceContent + componentDoc: this.store.componentDoc, + componentPath: this.store.componentPath, + componentSource: this.store.componentSource, + exampleDoc: this.store.exampleDoc, + examplePath: this.store.examplePath, + exampleRequirePath: this.store.exampleRequirePath, + exampleSource: this.store.exampleSource }; } get component() { - if (this.componentPath) { - return this.componentPath; + if (this.store.componentPath) { + return this.store.componentPath; } - if (!this.store.comment) { + if (!this.store.exampleDoc) { return null; } - return this.getCommentTag('component').string; + var component = this.getCommentTag('component').string; + return component ? path.resolve(this.store.examplePath, component) : null; } getCommentTag(name) { - return this.store.comment.tags.find(tag => tag.type === name) || {}; + return this.store.exampleDoc.tags.find(tag => tag.type === name) || {}; } } diff --git a/src/index.js b/src/index.js index 4914fa3..cb22347 100644 --- a/src/index.js +++ b/src/index.js @@ -1,8 +1,10 @@ -import fs from 'fs'; import path from 'path'; + import globby from 'globby'; import Illustrator from './illustrator'; -import {generateManifest, relativePath} from './util'; +import {generateManifest} from './util'; + +// --- export function illustrate(patterns, options) { options = parseAndValidateOptions(options); @@ -12,43 +14,36 @@ export function illustrate(patterns, options) { ; if (options.outputFormat === 'manifest') { - components = components.then(generateManifest); + components = components + .then((illustrations) => generateManifest(options, illustrations)) + ; } return components; } export function illustrateOne(file, options) { - let illustrator = new Illustrator(); - - return Promise.resolve(relativePath(options.dest, file)) - .then(illustrator.record('examplePath')) - .then(path => fs.readFileSync(path, {encoding: 'utf-8'})) - .then(illustrator.record('exampleContent')) - .then(illustrator.parseExampleComments) - .then(illustrator.record('comment')) + let illustrator = new Illustrator(options); + + return Promise.resolve(file) + .then(() => illustrator.processExample(file)) .then(() => illustrator.component) - .then(illustrator.record('componentPath')) - .then(file => { - let componentPath = path.resolve(illustrator.store.examplePath, file); - if (!/\.js$/.test(componentPath)) { - componentPath += '.js'; - } - return componentPath; - }) - .then(path => fs.readFileSync(path, {encoding: 'utf-8'})) - .then(illustrator.record('sourceContent')) - .then(illustrator.parseReactDoc) - .then(illustrator.record('documentation')) + .then(componentPath => componentPath ? illustrator.processComponent(componentPath) : null) .then(() => illustrator.run()) - .catch(error => console.log('error', error)) + .catch(error => console.error(error, error.stack)) ; } -function processExample(file) { - return fs.readSync(file); -} +// --- function parseAndValidateOptions(options = {}) { - return Object.assign(options, {}); + options = Object.assign({ + root: path.resolve('.') + }, options); + + if (options.dest) { + options.dest = path.resolve(options.dest); + } + + return options; } diff --git a/src/util.js b/src/util.js index ecaf777..887cae3 100644 --- a/src/util.js +++ b/src/util.js @@ -1,24 +1,25 @@ import path from 'path'; +import fs from 'fs'; -export function generateManifest(items) { - items = items.map(digest); - return `module.exports = [${items}];`; +export function generateManifest(options, items) { + if (options.dest) { + items = items.map(digest); + } + + let contents = `module.exports = [${items}];`; + + if (options.dest) { + fs.writeFileSync(options.dest, contents); + } else { + console.log(contents); + } + + return items; } export function digest(item) { var str = JSON.stringify(item); - str = str.replace(/\}$/, `,renderer: require('${item.examplePath}')}`); + str = str.replace(/\}$/, `,renderer: require('${item.exampleRequirePath}')}`); return str; } - -export function relativePath(from, to) { - var destDir = path.dirname(from); - var relative = path.relative(destDir, to); - - if (relative[0] !== '.') { - relative = `.${path.sep}${relative}`; - } - - return relative; -}