Skip to content

Commit

Permalink
resolved 1.2 merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhu2000 committed Mar 5, 2017
2 parents 8713641 + d2a7235 commit ad16f99
Show file tree
Hide file tree
Showing 16 changed files with 231 additions and 89 deletions.
22 changes: 13 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@

This generator helps to create the necessary files for a react-redux application. It follows the file structure below. The `frontend` folder is stored at the root directory of the application.


## New features in version 1.1
- Component generator can accept `-f` and `-nc` flags.
- When generating `root_reducer.js`, all existing reducers will be imported and added to `combineReducers`.
- `root_reducer.js` will update with import statement and key-value pairs whenever a new reducer is created.

## New features in version 1.2
- [Action](docs/action.md) generator detects keyword `receive` in action name and automatically add the argument name and key-value pair to the function.
- [Util](docs/util.md) generator detects keyword `fetch` in util name and automatically add a basic `ajax` request in the body of the function.
- Added command `remove` or `r` to remove generated files.
- [Reducer](docs/reducer.md) now accepts actions and will automatically add the import and case statements.

## Installation
```
Expand Down Expand Up @@ -50,19 +49,20 @@ frontend

| Command | Function |
|---------------------|---------------------------------------|
|`generate` | use the file generator |
|`g` | alias for `generate` |
|`generate`, `g` | use the file generator |
|`remove`, `r` | remove the generated files |
| `-h` `--help` | see available commands |
| `-v` `--version` | see current package version |


## FileTypes

| FileType | Function |
|-----------------------------------------|---------------------------------------------------------------------|
| `base <projectName>` | generate `app.jsx`, `root.jsx`, `<projectName>.jsx`, and `store.js` |
| `action <name> [action1] [action2] ...` | generate `<name>_actions.js` with specified actions |
| `component <name> [options]` | generate `<name>.jsx` and `<name>_container.jsx` |
| `reducer <name>` | generate `<name>_reducer.js` |
| `reducer <name> [action1] [action2] ...`| generate `<name>_reducer.js` |
| `util <name> [util1] [util2] ...` | generate `<name>_util.js` with specified utils |

## Options
Expand All @@ -80,6 +80,10 @@ frontend
- [Store](docs/store.md)
- [Utility](docs/util.md)

## Version notes

To see what features are added during each update, click [here](docs/update_notes.md)

## Contributing

To request a feature or report an issue, click [here](https://github.com/davidhu2000/react_redux_generator/issues).
34 changes: 34 additions & 0 deletions commands/generator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const generateAction = require('../fileTypes/action.js');
const generateBase = require('../fileTypes/base.js');
const generateComponent = require('../fileTypes/component.js');
const generateReducer = require('../fileTypes/reducer.js');
const generateStore = require('../fileTypes/store.js');
const generateUtil = require('../fileTypes/util.js');

const generator = (type, name, actions) => {

switch(type) {
case (type.match(/reducers?/) || {}).input:
generateReducer(name, actions);
break;
case (type.match(/stores?/) || {}).input:
generateStore();
break;
case (type.match(/actions?/) || {}).input:
generateAction(name, actions);
break;
case (type.match(/utils?/) || {}).input:
generateUtil(name, actions);
break;
case (type.match(/components?/) || {}).input:
generateComponent(name, actions);
break;
case (type.match(/bases?/) || {}).input:
generateBase(name);
generateStore();
break;
}

}

module.exports = generator;
47 changes: 47 additions & 0 deletions commands/remover.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const fs = require('fs');

const logFunctions = require('../helpers/logs.js');

// function to delete a single file
const deleteFile = (path) => {
fs.unlink(path, function(err) {
if (err) {
logFunctions.noExistFileErrorLog(path);
} else {
logFunctions.removedFileLog(path);
}
});
}

const removeFile = (type, name) => {
if(type[type.length -1] === 's') {
type = type.slice(0, type.length - 1);
}

if (type === 'component') {
let componentPath = `frontend/components/${name}/${name}.jsx`;
let containerPath = `frontend/components/${name}/${name}_container.jsx`;
deleteFile(containerPath);
deleteFile(componentPath);
} else {
let fileEnding = type;
if (type === 'action') {
fileEnding += 's';
}
let path = `frontend/${type}s/${name}_${fileEnding}.js`;
deleteFile(path);
}
}

const remover = (type, name) => {
if( /bases?/.test(type) ) {
deleteFile(`frontend/${name}.jsx`);
deleteFile(`frontend/components/app.jsx`);
deleteFile(`frontend/components/root.jsx`);
deleteFile(`frontend/store/store.js`);
} else {
path = removeFile(type, name);
}
}

module.exports = remover;
19 changes: 11 additions & 8 deletions docs/action.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,23 @@ _Do not enter `_actions.js` as part of the name_
For example:

```
redux g action session receiveUser receiveError
redux g action song receiveSong playSong
```

The generator will create a file `frontend/actions/session_actions.js` in the actions folder. It will interpret the actions to create constants and action objects. In this example, it will create a `.js` file like below:
The generator will create a file `frontend/actions/song_actions.js` in the actions folder. It will interpret the actions to create constants and action objects. In this example, it will create a `.js` file like below:

```js
export const RECEIVE_USER = 'RECEIVE_USER';
export const RECEIVE_ERROR = 'RECEIVE_ERROR';
export const RECEIVE_SONG = 'RECEIVE_SONG';
export const PLAY_SONG = 'PLAY_SONG';

export const receiveUser = () => ({
type: RECEIVE_USER
export const receiveSong = song => ({
type: RECEIVE_SONG,
song
});

export const receiveError = () => ({
type: RECEIVE_ERROR
export const playSong = () => ({
type: PLAY_SONG
});
```

**Note:** The action generator will look for the word `receive` in the action names, and automatically add the argument name and key-value pair to the function. This is why `receiveSong` has a `song` argument and `song` value in the returned object.
16 changes: 13 additions & 3 deletions docs/reducer.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,39 @@ export default rootReducer;
To generate a reducer, run

```
redux g reducer <name>
redux g reducer <name> [action1] [action2]
```

_Do not enter `_reducer.js` as part of the name_

For example:

```
redux g reducer session
redux g reducer session receiveUser receiveErrors clearErrors
```

This will generate a file `frontend/reducer/session_reducer.js`:

```js
import { merge } from 'lodash';
import {
RECEIVE_USER,
RECEIVE_ERRORS,
CLEAR_ERRORS } from "../actions/session_actions.js"

const sessionReducer = (state, action) => {
Object.freeze(state);
switch(action.type) {
case RECEIVE_USER:
// your code here
case RECEIVE_ERRORS:
// your code here
case CLEAR_ERRORS:
// your code here
default:
return state;
}
}
};

export default sessionReducer;
```
4 changes: 4 additions & 0 deletions docs/update_notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## New features in version 1.1
- [Component](docs/component.md) generator can accept `-f`/`--functional` and `-nc`/`--no-container` flags.
- When generating `root_reducer.js`, all existing [reducers](docs/reducer.md) will be imported and added to `combineReducers`.
- `root_reducer.js` will update with import statement and key-value pairs whenever a new [reducer](docs/reducer.md) is created.
26 changes: 19 additions & 7 deletions redux/action.js → fileTypes/action.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,36 @@ const writeConstant = constName => (
`export const ${constName} = '${constName}';`
);

const writeAction = (actionName, constName) => (
`export const ${actionName} = () => ({
type: ${constName}
const writeAction = (actionName, constName) => {
let arg = '()';
let data = '';

if(/receive/.test(actionName)) {
arg = actionName.replace('receive', '')
arg = caseConverter.convert(arg, caseConverter.toLowerCamelCase)
data = `,\n ${arg}`;
}

return (
`export const ${actionName} = ${arg} => ({
type: ${constName}${data}
});
`
);
);
};

const generateAction = (name, actions) => {
let fullPath = `frontend/actions/${name}_actions.js`
let fileName = `${name}_actions.js`
let fullPath = `frontend/actions/${fileName}`

fs.exists(fullPath, (exists) => {
if(exists) {
logFunctions.fileExistErrorLog(`${name}_actions.js`);
logFunctions.fileExistErrorLog(fileName);
} else {
mkdir('-p', 'frontend/actions/');
cd('frontend/actions');

let writeStream = fs.createWriteStream(`${name}_actions.js`);
let writeStream = fs.createWriteStream(fileName);

let constNames = actions.map( action => (
caseConverter.convert(action, caseConverter.toScreamingSnakeCase)
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion redux/component.js → fileTypes/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const generateComponent = (name, flags) => {
let nameUCC = caseConverter.convert(name, caseConverter.toUpperCamelCase);
flags = flags.join('');

fs.exists(`frontend/components/${nameSC}/${nameSC}.jsx`, (exists) => {
fs.exists(`frontend/components/${nameSC}/${nameSC}.jsx`, exists => {
if(exists) {
logFunctions.fileExistErrorLog(`${nameSC}.jsx`);
} else {
Expand Down
18 changes: 9 additions & 9 deletions redux/reducer.js → fileTypes/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const createRootReducerKeyPairs = reducerNameArray => {

const updateRootReducer = (nameLCC, nameSC) => {

fs.exists(`root_reducer.js`, (exists) => {
fs.exists(`root_reducer.js`, exists => {
if(exists) {
let root = fs.readFileSync('root_reducer.js', 'utf8');
let keyValStr = 'const rootReducer = combineReducers({\n';
Expand All @@ -46,36 +46,36 @@ const updateRootReducer = (nameLCC, nameSC) => {
});
}

const createReducer = (name) => {
const createReducer = (name, actions) => {
let nameLCC = caseConverter.convert(name, caseConverter.toLowerCamelCase);
let nameSC = caseConverter.convert(name, caseConverter.toSnakeCase);
let reducerFiles = [];
let reducerFiles;
let fileName = `${nameSC}_reducer.js`;

if (fs.existsSync('frontend/reducers')) {
reducerFiles = fs.readdirSync('frontend/reducers');
}

fs.exists(`frontend/reducers/${nameSC}_reducer.js`, (exists) => {
fs.exists(`frontend/reducers/${fileName}`, exists => {
if(exists) {
logFunctions.fileExistErrorLog(`${nameSC}_reducer.js`);
logFunctions.fileExistErrorLog(fileName);
} else {
let filename = `${nameSC}_reducer.js`;
mkdir('-p',`frontend/reducers/`);
cd('frontend/reducers');

var writeStream = fs.createWriteStream(filename);
var writeStream = fs.createWriteStream(fileName);
if (name === 'root') {
let importStatements = createRootReducerImports(reducerFiles);
let keyPairStatements = createRootReducerKeyPairs(reducerFiles);
writeStream.write(reducerTemplate.root(importStatements, keyPairStatements));
writeStream.end();
} else {
writeStream.write(reducerTemplate.reducer(nameLCC));
writeStream.write(reducerTemplate.reducer(nameLCC, actions));
writeStream.end();
updateRootReducer(nameLCC, nameSC);
}

logFunctions.createFileLog(`frontend/reducers/${nameSC}_reducer.js`);
logFunctions.createFileLog(`frontend/reducers/${fileName}`);
}
});

Expand Down
2 changes: 1 addition & 1 deletion redux/store.js → fileTypes/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const generateStore = () => {

fs.exists(`frontend/store/store.js`, (exists) => {
if(exists) {
logFunctions.fileExistErrorLog(`store.js`);
logFunctions.fileExistErrorLog('store.js');
} else {
mkdir('-p',`frontend/store/`);
cd('frontend/store');
Expand Down
29 changes: 21 additions & 8 deletions redux/util.js → fileTypes/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,38 @@ const fs = require('fs');
const caseConverter = require('../helpers/case_converter.js');
const logFunctions = require('../helpers/logs.js');

const writeUtil = (utilName) => (
`export const ${utilName} = () => (
// your code here;
);
const writeUtil = (utilName, constName) => {
let arg = '()';
let data = '// your code here';

if(/fetch/.test(utilName)) {
arg = utilName.replace('fetch', '')
arg = caseConverter.convert(arg, caseConverter.toLowerCamelCase)
data = `$.ajax({\n method: '',\n url: '',\n data: ''\n })`;
}

return (
`export const ${utilName} = ${arg} => ({
${data}
});
`
);
);
};

const generateUtil = (name, utils = []) => {
name = caseConverter.convert(name, caseConverter.toSnakeCase);

fs.exists(`frontend/util/${name}_util.js`, (exists) => {
let fileName = `${name}_util.js`;

fs.exists(`frontend/util/${fileName}`, (exists) => {
if(exists) {
logFunctions.fileExistErrorLog(`${name}_util.js`);
} else {

mkdir('-p', 'frontend/util/');
cd('frontend/util');

let writeStream = fs.createWriteStream(`${name}_util.js`);
let writeStream = fs.createWriteStream(fileName);

let data = utils.map( util => {
util = caseConverter.convert(util,caseConverter.toLowerCamelCase);
Expand All @@ -32,7 +45,7 @@ const generateUtil = (name, utils = []) => {
writeStream.write(data);
writeStream.close();
cd('..');
logFunctions.createFileLog(`frontend/util/${name}_util.js`);
logFunctions.createFileLog(`frontend/util/${fileName}`);
}
});
};
Expand Down
Loading

0 comments on commit ad16f99

Please sign in to comment.