npm package: @sundogee/codesmith
Description: Micro-generator framework that makes it easy for an entire team to create files with a level of uniformity
Author: Yuyi Liang
Latest version: 0.1.18

codesmith
======

the easy-to-use and developer-friendly Micro-generator framework

# Getting Started


## What is codesmith?
codesmith is a "micro-generator framework." inspired by [plot](https://github.com/amwmedia/plop) and [yeamon](https://github.com/yeoman) but for `extensibility` and `community-friendly`

## Installation
### 1. Install Codesmith globally
```
$ npm install -g @sundogee/codesmith
```

### 2. Get the package from `codestore` or community
```
$ codesmith @codestore/react
```
Have fun!


## Package Config File
Package Config File is a file which determine how the generator run
```Javascript
'use strict';
const path = require('path');
const ts = require('typescript');
const changeCase = require('change-case');

module.exports = function (codesmith) {
    // this generator add a new class component
    codesmith.setGenerator('class-component-ts', {
        description: 'Add a new class component(ts)',
        questions: [
            {
                type: 'directory',
                name: 'basePath',
                message: 'Where you like to put this component?',
                basePath: ".",
            },
            {
                type: 'input',
                name: 'name',
                message: "What's your component class name?"
            },
            {
                type: 'checkbox',
                name: 'decorators',
                message: "What decorator do you want?",
                choices: [
                    {name: 'withRouter', value: 'withRouter'},
                    // {name: 'connect(redux)', value: 'connectRedux'}
                ]
            }
        ],
        actions: [
            {
                type: 'add',
                path: '{{basePath}}/{{dashCase name}}.tsx',
                templateFile: 'generators/class-component-ts/templates/component.tsx',
                abortOnFail: true
            },
            {
                type: 'ts/ast',
                when: (data, config) => {
                    if(data.decorators.indexOf('withRouter') !== -1) {
                        return true
                    }
                    return false
                },
                ast: (tsMorch, data) => {
                    const project = new tsMorch.Project({});
                    project.addExistingSourceFiles(`${process.cwd()}/${data.basePath}/${changeCase.paramCase(data.name)}.tsx`);
                    const testFile = project.getSourceFileOrThrow(`${changeCase.paramCase(data.name)}.tsx`)
                    testFile.transform((traversal) => {
                        const node = traversal.visitChildren(); // return type is `ts.Node`
    
                        if (ts.isExportAssignment(node)) {
                            const callExpression = ts.createCall(
                                ts.createIdentifier('withRouter'),
                                undefined, // type arguments, e.g. Foo<T>()
                                [
                                    node.expression
                                ]
                            )
                            return ts.createExportAssignment(
                                undefined,
                                undefined,
                                false,
                                callExpression
                            );
                        }
    
                        return node;
                    });
                    testFile.addImportDeclaration({
                        namedImports: ['withRouter'],
                        moduleSpecifier: 'react-router'
                    })
                    return project.save();
                }
            }
        ]
    });

    codesmith.setGenerator('functional-component-ts', {
        description: 'Add a new functional component(ts)',
        questions: [
            {
                type: 'directory',
                name: 'basePath',
                message: 'Where you like to put this component?',
                basePath: ".",
            },
            {
                type: 'input',
                name: 'name',
                message: "What's your component class name?"
            }
        ],
        actions: [
            {
                type: 'add',
                path: '{{basePath}}/{{dashCase name}}.tsx',
                templateFile: 'generators/functional-component-ts/templates/component.tsx',
                abortOnFail: true
            }
        ]
    });
};
```

## Corestore list
* [react(@codestore/react)](https://github.com/sundog-codesmith/codesmith-react) quickly add `react` snippet into your project
* [vue(@codestore/vue)](https://github.com/sundog-codesmith/codesmith-vue) quickly add `vue` snippet into your project
* [init(@codestore/init)](https://github.com/sundog-codesmith/codesmith-init) quickly init codesmith package
* [codesmith-init(@codestore/lint)](https://github.com/sundog-codesmith/codesmith-simple-stylelint) quickly add stylelint or commitlint into your project

## Contributors

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore -->
<table>
    <tr>
        <td align="center"><a href="https://asaunders.com"><img
                    src="https://avatars2.githubusercontent.com/u/9214496?v=4" width="100px;"
                    alt="lwyj123" /><br /><sub><b>lwyj123</b></sub></a><br /><a
                href="https://github.com/sundogee/codesmith/commits?author=lwyj123" title="Code">💻</a> <a
                href="#design-lwyj123" title="Design">🎨</a> <a href="#infra-lwyj123"
                title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#ideas-lwyj123"
                title="Ideas, Planning, & Feedback">🤔</a> <a href="#review-lwyj123"
                title="Reviewed Pull Requests">👀</a></td>
    </tr>
</table>

<!-- ALL-CONTRIBUTORS-LIST:END -->