├── .babelrc
├── .codeclimate.yml
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── bin
└── wooo.js
├── lib
├── argv.js
├── dependencies.js
├── files.js
├── fn.js
├── index.js
└── options.js
├── package.json
├── src
├── argv.js
├── dependencies.js
├── files.js
├── fn.js
├── index.js
└── options.js
├── templates
├── default
│ ├── components
│ │ └── Header
│ │ │ ├── index.css
│ │ │ └── index.js
│ ├── containers
│ │ ├── App.js
│ │ └── Home.js
│ ├── index.js
│ ├── modules
│ │ ├── index.js
│ │ └── user.js
│ ├── static
│ │ ├── index.css
│ │ └── normalize.css
│ └── store
│ │ ├── configureStore.dev.js
│ │ ├── configureStore.prod.js
│ │ └── index.js
└── react-router-4
│ ├── components
│ └── Button.js
│ ├── containers
│ ├── App.js
│ └── Home.js
│ ├── index.js
│ ├── modules
│ ├── index.js
│ └── user.js
│ ├── static
│ └── css
│ │ └── reboot.css
│ └── store
│ └── index.js
└── test
├── pretest.js
└── test.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "env",
5 | {
6 | "targets": {
7 | "node": "current"
8 | }
9 | }
10 | ],
11 | "stage-0"
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/.codeclimate.yml:
--------------------------------------------------------------------------------
1 | engines:
2 | duplication:
3 | enabled: true
4 | config:
5 | languages:
6 | - javascript
7 | ratings:
8 | paths:
9 | - src/**/*
10 | exclude_paths:
11 | - lib/**/*
12 | - node_modules/**/*
13 | - _test_/**/*
14 | - test/**/*
15 | - templates/**/*
16 | - src/options.js
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # nyc test coverage
18 | .nyc_output
19 |
20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21 | .grunt
22 |
23 | # node-waf configuration
24 | .lock-wscript
25 |
26 | # Compiled binary addons (http://nodejs.org/api/addons.html)
27 | build/Release
28 |
29 | # Dependency directories
30 | node_modules
31 | jspm_packages
32 |
33 | # Optional npm cache directory
34 | .npm
35 |
36 | # Optional REPL history
37 | .node_repl_history
38 |
39 | .test
40 | tst
41 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "node"
4 | - "6"
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Ondřej Kocián
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | # Wooo [](https://travis-ci.org/Kocisov/wooo) [](http://npmjs.com/redux-wooo) [](https://david-dm.org/kocisov/wooo) [](https://codeclimate.com/github/Kocisov/wooo)
6 | > Tool that helps you add Redux to your React project without pain
7 |
8 | ## Main goal of wooo
9 | Let users write one command instead of creating 5 folders, 10+ files and installing 4 dependencies for Redux to get going.
10 |
11 | ## So, what does wooo do?
12 | **Wooo** does install required dependencies and create [template files](https://github.com/Kocisov/wooo/tree/master/templates) in specified path with:
13 | 1. One [duck](https://github.com/erikras/ducks-modular-redux) module for user login/logout
14 | 2. One stateless Component with CSS
15 | 3. React-router and react-router-redux reducer (You can choose v4 or v3 (default) template)
16 | 4. Redux store configuration for production and development by process.env.NODE_ENV check
17 | 5. One Container with connected props by connect() function
18 |
19 | **This is pretty much just fast scaffolding, not actual code! But it can be edited to be production-ready with few more lines.**
20 |
21 | ## Installation
22 | **Node version 6 or higher is required!**
23 | ```bash
24 | # with yarn
25 | $ yarn global add redux-wooo
26 |
27 | # with npm
28 | $ npm install -g redux-wooo
29 | ```
30 |
31 | ## Usage
32 | ```
33 | wooo [options]
34 | --help, -h Show Wooo's usage.
35 | --version, -v Show Wooo's version.
36 | --template, -t [name] Specify which template should Wooo create (templates directory)
37 | --npm, -n Use npm for installing dependencies. (Wooo uses Yarn by default)
38 | --dir, -d [path] Directory, where do you want to create files by Wooo. (Dependencies are written into package.json (yarn creates new package.json if it is not present) in current directory)
39 | ```
40 |
41 | **Default path for files is src folder in your current location in command line!**
42 |
43 | ## Contribution
44 | If you want to add template, just fork the repo and add your template files in folder into [/template](https://github.com/Kocisov/wooo/tree/master/templates).
45 |
46 | This is not ideal and in the future Wooo will have better system for this.
47 |
--------------------------------------------------------------------------------
/bin/wooo.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | const wooo = require('../lib/index').default()
3 |
--------------------------------------------------------------------------------
/lib/argv.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.default = argv;
7 |
8 | var _yargs = require('yargs');
9 |
10 | var _yargs2 = _interopRequireDefault(_yargs);
11 |
12 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13 |
14 | function argv() {
15 | return _yargs2.default.usage('Usage: wooo [Options]').example('wooo -d ./src/ -t react-router-4', 'Create react-router-4 template files and install its needed dependencies').alias('v', 'version').alias('d', 'dir').alias('n', 'npm').alias('t', 'template').alias('h', 'help').boolean('v').boolean('n').string('d').string('t').describe('v', 'Show version of Wooo').describe('d', 'Specify directory where Wooo should create files').describe('t', 'Specify template that Wooo should create').describe('n', 'Specify if Wooo should install dependencies with npm instead of yarn').help('h').argv;
16 | }
--------------------------------------------------------------------------------
/lib/dependencies.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.install = exports.prepare = undefined;
7 |
8 | let prepare = exports.prepare = (() => {
9 | var _ref = _asyncToGenerator(function* ({ manager, template }) {
10 | const _manager = manager;
11 |
12 | const command = manager && manager === 'yarn' ? 'yarn add' : 'npm install --save';
13 |
14 | const dependencies = ['react-redux', 'redux', 'redux-thunk'];
15 |
16 | if (template === 'react-router-4') {
17 | dependencies.push('react-router-dom', 'react-router-redux@next', 'styled-components');
18 | } else {
19 | dependencies.push('react-router-redux', 'react-router@3.0.2');
20 | }
21 |
22 | return {
23 | manager: _manager,
24 | command,
25 | dependencies
26 | };
27 | });
28 |
29 | return function prepare(_x) {
30 | return _ref.apply(this, arguments);
31 | };
32 | })();
33 |
34 | let install = exports.install = (() => {
35 | var _ref2 = _asyncToGenerator(function* ({ command, manager, dependencies }) {
36 | console.log((0, _fn.yellow)(`Installing dependencies with ${manager}`));
37 | const e = yield (0, _fn.exec)(`${command} ${dependencies.join(' ')}`);
38 | return e;
39 | });
40 |
41 | return function install(_x2) {
42 | return _ref2.apply(this, arguments);
43 | };
44 | })();
45 |
46 | var _fn = require('./fn');
47 |
48 | function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
--------------------------------------------------------------------------------
/lib/files.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.default = createFiles;
7 |
8 | var _fsExtra = require('fs-extra');
9 |
10 | var _path = require('path');
11 |
12 | var _fn = require('./fn');
13 |
14 | function createFiles({ dir, template }) {
15 | let tmplt;
16 |
17 | const ad = (0, _fsExtra.realpathSync)(process.cwd());
18 | const p = (0, _path.resolve)(__dirname, `../templates/${template}`);
19 |
20 | const resolvedDir = (0, _path.resolve)(ad, dir);
21 |
22 | console.log((0, _fn.white)(`Wooo will create files in ${resolvedDir} directory.`));
23 |
24 | if ((0, _fsExtra.existsSync)(p)) {
25 | tmplt = p;
26 | } else {
27 | tmplt = (0, _path.resolve)(__dirname, `../templates/default`);
28 |
29 | console.log((0, _fn.red)(`Template ${template} was not found!`));
30 |
31 | console.log((0, _fn.yellow)(`Installing default template instead...`));
32 | }
33 |
34 | (0, _fsExtra.copySync)(tmplt, resolvedDir);
35 |
36 | return (0, _fn.green)(`Wooo!!! Everything is done.
37 | Let's build something cool.`);
38 | }
--------------------------------------------------------------------------------
/lib/fn.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.green = exports.red = exports.white = exports.yellow = exports.exec = undefined;
7 |
8 | var _child_process = require('child_process');
9 |
10 | var _chalk = require('chalk');
11 |
12 | var _chalk2 = _interopRequireDefault(_chalk);
13 |
14 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15 |
16 | const exec = exports.exec = cmd => (0, _child_process.execSync)(cmd, {
17 | stdio: 'inherit'
18 | });
19 |
20 | const yellow = exports.yellow = n => _chalk2.default.yellow(n);
21 |
22 | const white = exports.white = n => _chalk2.default.white(n);
23 |
24 | const red = exports.red = n => _chalk2.default.red(n);
25 |
26 | const green = exports.green = n => _chalk2.default.green(n);
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | require('babel-polyfill');
8 |
9 | var _argv = require('./argv');
10 |
11 | var _argv2 = _interopRequireDefault(_argv);
12 |
13 | var _options = require('./options');
14 |
15 | var _options2 = _interopRequireDefault(_options);
16 |
17 | var _dependencies = require('./dependencies');
18 |
19 | var _files = require('./files');
20 |
21 | var _files2 = _interopRequireDefault(_files);
22 |
23 | var _clear = require('clear');
24 |
25 | var _clear2 = _interopRequireDefault(_clear);
26 |
27 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
28 |
29 | function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
30 |
31 | exports.default = (() => {
32 | var _ref = _asyncToGenerator(function* () {
33 | const args = yield (0, _argv2.default)();
34 | const options = yield (0, _options2.default)(args);
35 | const prepared = yield (0, _dependencies.prepare)(options);
36 | const installed = yield (0, _dependencies.install)(prepared);
37 | const created = yield (0, _files2.default)(options);
38 |
39 | (0, _clear2.default)();
40 |
41 | console.log(created);
42 | });
43 |
44 | function wooo() {
45 | return _ref.apply(this, arguments);
46 | }
47 |
48 | return wooo;
49 | })();
--------------------------------------------------------------------------------
/lib/options.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _clear = require('clear');
8 |
9 | var _clear2 = _interopRequireDefault(_clear);
10 |
11 | var _package = require('../package.json');
12 |
13 | var _fn = require('./fn');
14 |
15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16 |
17 | function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
18 |
19 | exports.default = (() => {
20 | var _ref = _asyncToGenerator(function* (args) {
21 | let opts = {
22 | template: 'default',
23 | manager: 'yarn',
24 | dir: './src'
25 | };
26 |
27 | if (args.version) {
28 | (0, _clear2.default)();
29 | console.log((0, _fn.white)(`Wooo's current version is ${_package.version}.`));
30 | process.exit();
31 | }
32 |
33 | if (args.template && args.template.length > 0) {
34 | opts.template = args.template;
35 | }
36 |
37 | if (args.npm) {
38 | opts.manager = 'npm';
39 | }
40 |
41 | if (args.dir && args.dir.length > 0) {
42 | opts.dir = args.dir;
43 | }
44 |
45 | return opts;
46 | });
47 |
48 | function checkOptions(_x) {
49 | return _ref.apply(this, arguments);
50 | }
51 |
52 | return checkOptions;
53 | })();
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "redux-wooo",
3 | "version": "1.0.9",
4 | "description": "Add redux scaffolding into your folder without pain.",
5 | "main": "lib/index.js",
6 | "repository": {
7 | "url": "kocisov/wooo",
8 | "type": "git"
9 | },
10 | "author": "kocisov ",
11 | "scripts": {
12 | "compile": "babel src -d lib",
13 | "compile:with-minify": "babel src -d lib --minified",
14 | "pretest": "node test/pretest.js -d ./_test_ -t react-router-4",
15 | "test": "mocha test/test.js"
16 | },
17 | "bin": {
18 | "wooo": "bin/wooo.js"
19 | },
20 | "license": "MIT",
21 | "devDependencies": {
22 | "babel-cli": "^6.24.1",
23 | "babel-core": "^6.24.1",
24 | "babel-plugin-transform-async-to-generator": "^6.24.1",
25 | "babel-preset-env": "^1.4.0",
26 | "babel-preset-stage-0": "^6.24.1",
27 | "mocha": "^4.0.1",
28 | "prettier": "^1.2.2"
29 | },
30 | "dependencies": {
31 | "babel-polyfill": "^6.23.0",
32 | "chalk": "^2.1.0",
33 | "clear": "^0.0.1",
34 | "fs-extra": "^4.0.2",
35 | "yargs": "^9.0.1"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/argv.js:
--------------------------------------------------------------------------------
1 | import yargs from 'yargs'
2 |
3 | export default function argv() {
4 | return yargs
5 | .usage('Usage: wooo [Options]')
6 | .example(
7 | 'wooo -d ./src/ -t react-router-4',
8 | 'Create react-router-4 template files and install its needed dependencies'
9 | )
10 | .alias('v', 'version')
11 | .alias('d', 'dir')
12 | .alias('n', 'npm')
13 | .alias('t', 'template')
14 | .alias('h', 'help')
15 | .boolean('v')
16 | .boolean('n')
17 | .string('d')
18 | .string('t')
19 | .describe('v', 'Show version of Wooo')
20 | .describe('d', 'Specify directory where Wooo should create files')
21 | .describe('t', 'Specify template that Wooo should create')
22 | .describe(
23 | 'n',
24 | 'Specify if Wooo should install dependencies with npm instead of yarn'
25 | )
26 | .help('h').argv
27 | }
28 |
--------------------------------------------------------------------------------
/src/dependencies.js:
--------------------------------------------------------------------------------
1 | import { exec, yellow } from './fn'
2 |
3 | export async function prepare({ manager, template }) {
4 | const _manager = manager
5 |
6 | const command =
7 | manager && manager === 'yarn' ? 'yarn add' : 'npm install --save'
8 |
9 | const dependencies = ['react-redux', 'redux', 'redux-thunk']
10 |
11 | if (template === 'react-router-4') {
12 | dependencies.push(
13 | 'react-router-dom',
14 | 'react-router-redux@next',
15 | 'styled-components'
16 | )
17 | } else {
18 | dependencies.push('react-router-redux', 'react-router@3.0.2')
19 | }
20 |
21 | return {
22 | manager: _manager,
23 | command,
24 | dependencies,
25 | }
26 | }
27 |
28 | export async function install({ command, manager, dependencies }) {
29 | console.log(yellow(`Installing dependencies with ${manager}`))
30 | const e = await exec(`${command} ${dependencies.join(' ')}`)
31 | return e
32 | }
33 |
--------------------------------------------------------------------------------
/src/files.js:
--------------------------------------------------------------------------------
1 | import { existsSync, realpathSync, copySync } from 'fs-extra'
2 | import { resolve } from 'path'
3 | import { red, green, yellow, white } from './fn'
4 |
5 | export default function createFiles({ dir, template }) {
6 | let tmplt
7 |
8 | const ad = realpathSync(process.cwd())
9 | const p = resolve(__dirname, `../templates/${template}`)
10 |
11 | const resolvedDir = resolve(ad, dir)
12 |
13 | console.log(white(`Wooo will create files in ${resolvedDir} directory.`))
14 |
15 | if (existsSync(p)) {
16 | tmplt = p
17 | } else {
18 | tmplt = resolve(__dirname, `../templates/default`)
19 |
20 | console.log(red(`Template ${template} was not found!`))
21 |
22 | console.log(yellow(`Installing default template instead...`))
23 | }
24 |
25 | copySync(tmplt, resolvedDir)
26 |
27 | return green(
28 | `Wooo!!! Everything is done.
29 | Let's build something cool.`
30 | )
31 | }
32 |
--------------------------------------------------------------------------------
/src/fn.js:
--------------------------------------------------------------------------------
1 | import { execSync } from 'child_process'
2 | import chalk from 'chalk'
3 |
4 | export const exec = (cmd) =>
5 | execSync(cmd, {
6 | stdio: 'inherit',
7 | })
8 |
9 | export const yellow = (n) => chalk.yellow(n)
10 | export const white = (n) => chalk.white(n)
11 | export const red = (n) => chalk.red(n)
12 | export const green = (n) => chalk.green(n)
13 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import 'babel-polyfill'
2 | import argv from './argv'
3 | import checkOptions from './options'
4 | import { install, prepare } from './dependencies'
5 | import createFiles from './files'
6 | import clear from 'clear'
7 |
8 | export default async function wooo() {
9 | const args = await argv()
10 | const options = await checkOptions(args)
11 | const prepared = await prepare(options)
12 | const installed = await install(prepared)
13 | const created = await createFiles(options)
14 |
15 | clear()
16 |
17 | console.log(created)
18 | }
19 |
--------------------------------------------------------------------------------
/src/options.js:
--------------------------------------------------------------------------------
1 | import clear from 'clear'
2 | import { version } from '../package.json'
3 | import { white } from './fn'
4 |
5 | export default async function checkOptions(args) {
6 | let opts = {
7 | template: 'default',
8 | manager: 'yarn',
9 | dir: './src',
10 | }
11 |
12 | if (args.version) {
13 | clear()
14 | console.log(white(`Wooo's current version is ${version}.`))
15 | process.exit()
16 | }
17 |
18 | if (args.template && args.template.length > 0) {
19 | opts.template = args.template
20 | }
21 |
22 | if (args.npm) {
23 | opts.manager = 'npm'
24 | }
25 |
26 | if (args.dir && args.dir.length > 0) {
27 | opts.dir = args.dir
28 | }
29 |
30 | return opts
31 | }
32 |
--------------------------------------------------------------------------------
/templates/default/components/Header/index.css:
--------------------------------------------------------------------------------
1 | .header {
2 | align-items: center;
3 | background: #fff;
4 | display: flex;
5 | }
6 |
--------------------------------------------------------------------------------
/templates/default/components/Header/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import './index.css';
3 |
4 | export default ({ children }) => (
5 |
8 | );
9 |
--------------------------------------------------------------------------------
/templates/default/containers/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import Header from '../components/Header';
3 |
4 | export default class App extends Component {
5 | render() {
6 | return (
7 |
8 |
9 |
10 | {this.props.children}
11 |
12 |
13 | );
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/templates/default/containers/Home.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from 'react';
2 | import { connect } from 'react-redux';
3 | import { fakeLogin, logout } from '../modules/user';
4 |
5 | class Home extends PureComponent {
6 | render() {
7 | const { name, isAuthenticated } = this.props.user;
8 | const { fakeLogin, logout } = this.props;
9 |
10 | return (
11 |
12 | {isAuthenticated
13 | ?
14 |
Hello, {name}
15 |
16 |
17 | :
18 |
Hello
19 |
20 | }
21 |
22 | );
23 | }
24 | }
25 |
26 | export default connect(({ user }) => ({ user }), {
27 | fakeLogin,
28 | logout
29 | })(Home);
30 |
--------------------------------------------------------------------------------
/templates/default/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from 'react-dom';
3 | import { Provider } from 'react-redux';
4 | import { syncHistoryWithStore } from 'react-router-redux';
5 | import store from './store';
6 |
7 | import { Router, Route, IndexRoute, browserHistory } from 'react-router';
8 |
9 | import App from './containers/App';
10 | import Home from './containers/Home';
11 |
12 | import './static/normalize.css';
13 | import './static/index.css';
14 |
15 | const history = syncHistoryWithStore(browserHistory, store);
16 |
17 | render(
18 |
19 |
20 |
21 |
22 | {/* Your routes here */}
23 |
24 |
25 | ,
26 | document.getElementById('root')
27 | );
28 |
--------------------------------------------------------------------------------
/templates/default/modules/index.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from 'redux';
2 | import { routerReducer } from 'react-router-redux';
3 | import user from './user';
4 |
5 | export default combineReducers({
6 | user,
7 | routing: routerReducer
8 | });
9 |
--------------------------------------------------------------------------------
/templates/default/modules/user.js:
--------------------------------------------------------------------------------
1 | const USER_LOGGED_IN = 'app/user/USER_LOGGED_IN';
2 | const USER_LOGGED_OUT = 'app/user/USER_LOGGED_OUT';
3 |
4 | const initialState = {
5 | avatar: null,
6 | isAuthenticated: false,
7 | name: null,
8 | points: null,
9 | rank_group: null
10 | };
11 |
12 | export default function user(state = initialState, action) {
13 | switch (action.type) {
14 | case USER_LOGGED_IN:
15 | return {
16 | ...state,
17 | isAuthenticated: true,
18 |
19 | // spread over payload, instead of manually adding each key
20 | ...action.payload
21 | };
22 |
23 | case USER_LOGGED_OUT:
24 | return initialState;
25 |
26 | default:
27 | return state;
28 | }
29 | }
30 |
31 | export function fakeLogin() {
32 | return dispatch => {
33 | setTimeout(
34 | () => {
35 | dispatch({
36 | type: USER_LOGGED_IN,
37 | payload: {
38 | avatar: '//placecage.com/200/200',
39 | name: 'UserName',
40 | points: 1337,
41 | rank_group: 5
42 | }
43 | });
44 | },
45 | 2000
46 | ); // fake db delay
47 | };
48 | }
49 |
50 | export function logout() {
51 | return {
52 | type: USER_LOGGED_OUT
53 | };
54 | }
55 |
--------------------------------------------------------------------------------
/templates/default/static/index.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 |
5 | ::selection {
6 | background: #3a3e3e;
7 | color: #fff;
8 | text-shadow: none;
9 | }
10 |
11 | body {
12 | -webkit-font-smoothing: antialiased;
13 | font-family: sans-serif;
14 | font-size: 14px;
15 | font-weight: 300;
16 | line-height: 1.5;
17 | margin: 0;
18 | }
19 |
20 | h1,
21 | h2,
22 | h3,
23 | h4,
24 | h5,
25 | h6,
26 | ul,
27 | li,
28 | ol,
29 | p,
30 | a {
31 | margin: 0;
32 | }
33 |
--------------------------------------------------------------------------------
/templates/default/static/normalize.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v6.0.0 | MIT License | github.com/necolas/normalize.css */
2 |
3 | /* Document
4 | ========================================================================== */
5 |
6 | /**
7 | * 1. Correct the line height in all browsers.
8 | * 2. Prevent adjustments of font size after orientation changes in
9 | * IE on Windows Phone and in iOS.
10 | */
11 |
12 | html {
13 | line-height: 1.15; /* 1 */
14 | -ms-text-size-adjust: 100%; /* 2 */
15 | -webkit-text-size-adjust: 100%; /* 2 */
16 | }
17 |
18 | /* Sections
19 | ========================================================================== */
20 |
21 | /**
22 | * Add the correct display in IE 9-.
23 | */
24 |
25 | article,
26 | aside,
27 | footer,
28 | header,
29 | nav,
30 | section {
31 | display: block;
32 | }
33 |
34 | /**
35 | * Correct the font size and margin on `h1` elements within `section` and
36 | * `article` contexts in Chrome, Firefox, and Safari.
37 | */
38 |
39 | h1 {
40 | font-size: 2em;
41 | margin: 0.67em 0;
42 | }
43 |
44 | /* Grouping content
45 | ========================================================================== */
46 |
47 | /**
48 | * Add the correct display in IE 9-.
49 | * 1. Add the correct display in IE.
50 | */
51 |
52 | figcaption,
53 | figure,
54 | main { /* 1 */
55 | display: block;
56 | }
57 |
58 | /**
59 | * Add the correct margin in IE 8.
60 | */
61 |
62 | figure {
63 | margin: 1em 40px;
64 | }
65 |
66 | /**
67 | * 1. Add the correct box sizing in Firefox.
68 | * 2. Show the overflow in Edge and IE.
69 | */
70 |
71 | hr {
72 | box-sizing: content-box; /* 1 */
73 | height: 0; /* 1 */
74 | overflow: visible; /* 2 */
75 | }
76 |
77 | /**
78 | * 1. Correct the inheritance and scaling of font size in all browsers.
79 | * 2. Correct the odd `em` font sizing in all browsers.
80 | */
81 |
82 | pre {
83 | font-family: monospace, monospace; /* 1 */
84 | font-size: 1em; /* 2 */
85 | }
86 |
87 | /* Text-level semantics
88 | ========================================================================== */
89 |
90 | /**
91 | * 1. Remove the gray background on active links in IE 10.
92 | * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
93 | */
94 |
95 | a {
96 | background-color: transparent; /* 1 */
97 | -webkit-text-decoration-skip: objects; /* 2 */
98 | }
99 |
100 | /**
101 | * 1. Remove the bottom border in Chrome 57- and Firefox 39-.
102 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
103 | */
104 |
105 | abbr[title] {
106 | border-bottom: none; /* 1 */
107 | text-decoration: underline; /* 2 */
108 | text-decoration: underline dotted; /* 2 */
109 | }
110 |
111 | /**
112 | * Prevent the duplicate application of `bolder` by the next rule in Safari 6.
113 | */
114 |
115 | b,
116 | strong {
117 | font-weight: inherit;
118 | }
119 |
120 | /**
121 | * Add the correct font weight in Chrome, Edge, and Safari.
122 | */
123 |
124 | b,
125 | strong {
126 | font-weight: bolder;
127 | }
128 |
129 | /**
130 | * 1. Correct the inheritance and scaling of font size in all browsers.
131 | * 2. Correct the odd `em` font sizing in all browsers.
132 | */
133 |
134 | code,
135 | kbd,
136 | samp {
137 | font-family: monospace, monospace; /* 1 */
138 | font-size: 1em; /* 2 */
139 | }
140 |
141 | /**
142 | * Add the correct font style in Android 4.3-.
143 | */
144 |
145 | dfn {
146 | font-style: italic;
147 | }
148 |
149 | /**
150 | * Add the correct background and color in IE 9-.
151 | */
152 |
153 | mark {
154 | background-color: #ff0;
155 | color: #000;
156 | }
157 |
158 | /**
159 | * Add the correct font size in all browsers.
160 | */
161 |
162 | small {
163 | font-size: 80%;
164 | }
165 |
166 | /**
167 | * Prevent `sub` and `sup` elements from affecting the line height in
168 | * all browsers.
169 | */
170 |
171 | sub,
172 | sup {
173 | font-size: 75%;
174 | line-height: 0;
175 | position: relative;
176 | vertical-align: baseline;
177 | }
178 |
179 | sub {
180 | bottom: -0.25em;
181 | }
182 |
183 | sup {
184 | top: -0.5em;
185 | }
186 |
187 | /* Embedded content
188 | ========================================================================== */
189 |
190 | /**
191 | * Add the correct display in IE 9-.
192 | */
193 |
194 | audio,
195 | video {
196 | display: inline-block;
197 | }
198 |
199 | /**
200 | * Add the correct display in iOS 4-7.
201 | */
202 |
203 | audio:not([controls]) {
204 | display: none;
205 | height: 0;
206 | }
207 |
208 | /**
209 | * Remove the border on images inside links in IE 10-.
210 | */
211 |
212 | img {
213 | border-style: none;
214 | }
215 |
216 | /**
217 | * Hide the overflow in IE.
218 | */
219 |
220 | svg:not(:root) {
221 | overflow: hidden;
222 | }
223 |
224 | /* Forms
225 | ========================================================================== */
226 |
227 | /**
228 | * Remove the margin in Firefox and Safari.
229 | */
230 |
231 | button,
232 | input,
233 | optgroup,
234 | select,
235 | textarea {
236 | margin: 0;
237 | }
238 |
239 | /**
240 | * Show the overflow in IE.
241 | * 1. Show the overflow in Edge.
242 | */
243 |
244 | button,
245 | input { /* 1 */
246 | overflow: visible;
247 | }
248 |
249 | /**
250 | * Remove the inheritance of text transform in Edge, Firefox, and IE.
251 | * 1. Remove the inheritance of text transform in Firefox.
252 | */
253 |
254 | button,
255 | select { /* 1 */
256 | text-transform: none;
257 | }
258 |
259 | /**
260 | * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
261 | * controls in Android 4.
262 | * 2. Correct the inability to style clickable types in iOS and Safari.
263 | */
264 |
265 | button,
266 | html [type="button"], /* 1 */
267 | [type="reset"],
268 | [type="submit"] {
269 | -webkit-appearance: button; /* 2 */
270 | }
271 |
272 | /**
273 | * Remove the inner border and padding in Firefox.
274 | */
275 |
276 | button::-moz-focus-inner,
277 | [type="button"]::-moz-focus-inner,
278 | [type="reset"]::-moz-focus-inner,
279 | [type="submit"]::-moz-focus-inner {
280 | border-style: none;
281 | padding: 0;
282 | }
283 |
284 | /**
285 | * Restore the focus styles unset by the previous rule.
286 | */
287 |
288 | button:-moz-focusring,
289 | [type="button"]:-moz-focusring,
290 | [type="reset"]:-moz-focusring,
291 | [type="submit"]:-moz-focusring {
292 | outline: 1px dotted ButtonText;
293 | }
294 |
295 | /**
296 | * 1. Correct the text wrapping in Edge and IE.
297 | * 2. Correct the color inheritance from `fieldset` elements in IE.
298 | * 3. Remove the padding so developers are not caught out when they zero out
299 | * `fieldset` elements in all browsers.
300 | */
301 |
302 | legend {
303 | box-sizing: border-box; /* 1 */
304 | color: inherit; /* 2 */
305 | display: table; /* 1 */
306 | max-width: 100%; /* 1 */
307 | padding: 0; /* 3 */
308 | white-space: normal; /* 1 */
309 | }
310 |
311 | /**
312 | * 1. Add the correct display in IE 9-.
313 | * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.
314 | */
315 |
316 | progress {
317 | display: inline-block; /* 1 */
318 | vertical-align: baseline; /* 2 */
319 | }
320 |
321 | /**
322 | * Remove the default vertical scrollbar in IE.
323 | */
324 |
325 | textarea {
326 | overflow: auto;
327 | }
328 |
329 | /**
330 | * 1. Add the correct box sizing in IE 10-.
331 | * 2. Remove the padding in IE 10-.
332 | */
333 |
334 | [type="checkbox"],
335 | [type="radio"] {
336 | box-sizing: border-box; /* 1 */
337 | padding: 0; /* 2 */
338 | }
339 |
340 | /**
341 | * Correct the cursor style of increment and decrement buttons in Chrome.
342 | */
343 |
344 | [type="number"]::-webkit-inner-spin-button,
345 | [type="number"]::-webkit-outer-spin-button {
346 | height: auto;
347 | }
348 |
349 | /**
350 | * 1. Correct the odd appearance in Chrome and Safari.
351 | * 2. Correct the outline style in Safari.
352 | */
353 |
354 | [type="search"] {
355 | -webkit-appearance: textfield; /* 1 */
356 | outline-offset: -2px; /* 2 */
357 | }
358 |
359 | /**
360 | * Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
361 | */
362 |
363 | [type="search"]::-webkit-search-cancel-button,
364 | [type="search"]::-webkit-search-decoration {
365 | -webkit-appearance: none;
366 | }
367 |
368 | /**
369 | * 1. Correct the inability to style clickable types in iOS and Safari.
370 | * 2. Change font properties to `inherit` in Safari.
371 | */
372 |
373 | ::-webkit-file-upload-button {
374 | -webkit-appearance: button; /* 1 */
375 | font: inherit; /* 2 */
376 | }
377 |
378 | /* Interactive
379 | ========================================================================== */
380 |
381 | /*
382 | * Add the correct display in IE 9-.
383 | * 1. Add the correct display in Edge, IE, and Firefox.
384 | */
385 |
386 | details, /* 1 */
387 | menu {
388 | display: block;
389 | }
390 |
391 | /*
392 | * Add the correct display in all browsers.
393 | */
394 |
395 | summary {
396 | display: list-item;
397 | }
398 |
399 | /* Scripting
400 | ========================================================================== */
401 |
402 | /**
403 | * Add the correct display in IE 9-.
404 | */
405 |
406 | canvas {
407 | display: inline-block;
408 | }
409 |
410 | /**
411 | * Add the correct display in IE.
412 | */
413 |
414 | template {
415 | display: none;
416 | }
417 |
418 | /* Hidden
419 | ========================================================================== */
420 |
421 | /**
422 | * Add the correct display in IE 10-.
423 | */
424 |
425 | [hidden] {
426 | display: none;
427 | }
428 |
--------------------------------------------------------------------------------
/templates/default/store/configureStore.dev.js:
--------------------------------------------------------------------------------
1 | import { createStore, applyMiddleware, compose } from 'redux';
2 | import rootReducer from '../modules';
3 | import thunk from 'redux-thunk';
4 |
5 | const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
6 |
7 | export default createStore(
8 | rootReducer,
9 | composeEnhancers(applyMiddleware(thunk))
10 | );
11 |
--------------------------------------------------------------------------------
/templates/default/store/configureStore.prod.js:
--------------------------------------------------------------------------------
1 | import { createStore, applyMiddleware } from 'redux';
2 | import rootReducer from '../modules';
3 | import thunk from 'redux-thunk';
4 |
5 | export default createStore(rootReducer, applyMiddleware(thunk));
6 |
--------------------------------------------------------------------------------
/templates/default/store/index.js:
--------------------------------------------------------------------------------
1 | if (process.env.NODE_ENV === 'production') {
2 | module.exports = require('./configureStore.prod');
3 | } else {
4 | module.exports = require('./configureStore.dev');
5 | }
6 |
--------------------------------------------------------------------------------
/templates/react-router-4/components/Button.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components'
2 |
3 | export default styled.header`
4 | align-items: center;
5 | background: #333;
6 | color: #fff;
7 | display: flex;
8 | min-height: 40px;
9 | `
10 |
--------------------------------------------------------------------------------
/templates/react-router-4/containers/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Route } from 'react-router-dom'
3 | import Home from './Home'
4 |
5 | export default class App extends Component {
6 | render() {
7 | return (
8 |
9 |
10 |
11 | )
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/templates/react-router-4/containers/Home.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from 'react'
2 | import { connect } from 'react-redux'
3 | import { fakeLogin, logout } from '../modules/user'
4 |
5 | class Home extends PureComponent {
6 | render() {
7 | const { name, isAuthenticated } = this.props.user
8 | const { fakeLogin, logout } = this.props
9 |
10 | return (
11 |
12 | {isAuthenticated ? (
13 |
14 |
Hello, {name}
15 |
16 |
17 | ) : (
18 |
19 |
Hello
20 |
21 |
22 | )}
23 |
24 | )
25 | }
26 | }
27 |
28 | export default connect(({ user }) => ({ user }), {
29 | fakeLogin,
30 | logout,
31 | })(Home)
32 |
--------------------------------------------------------------------------------
/templates/react-router-4/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { render } from 'react-dom'
3 | import { Provider } from 'react-redux'
4 | import { ConnectedRouter as Router } from 'react-router-redux'
5 | import createHistory from 'history/createBrowserHistory'
6 | import createStore from './store'
7 | import App from './containers/App'
8 | import './static/css/reboot.css'
9 |
10 | const history = createHistory()
11 | const el = document.getElementById('root')
12 |
13 | const store = createStore(history)
14 |
15 | function r(Component) {
16 | render(
17 |
18 |
19 |
20 |
21 | ,
22 | el
23 | )
24 | }
25 |
26 | r(App)
27 |
28 | if (module.hot) {
29 | module.hot.accept('./containers/App', () => {
30 | const NextApp = require('./containers/App').default
31 | r(NextApp)
32 | })
33 | }
34 |
--------------------------------------------------------------------------------
/templates/react-router-4/modules/index.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from 'redux'
2 | import { routerReducer } from 'react-router-redux'
3 | import user from './user'
4 |
5 | export default combineReducers({
6 | user,
7 | router: routerReducer,
8 | })
9 |
--------------------------------------------------------------------------------
/templates/react-router-4/modules/user.js:
--------------------------------------------------------------------------------
1 | const USER_LOGGED_IN = 'app/user/USER_LOGGED_IN'
2 | const USER_LOGGED_OUT = 'app/user/USER_LOGGED_OUT'
3 |
4 | const initialState = {
5 | avatar: null,
6 | isAuthenticated: false,
7 | name: null,
8 | points: null,
9 | rank_group: null,
10 | }
11 |
12 | export default function user(state = initialState, action) {
13 | switch (action.type) {
14 | case USER_LOGGED_IN:
15 | return {
16 | ...state,
17 | isAuthenticated: true,
18 |
19 | // spread over payload, instead of manually adding each key
20 | ...action.payload,
21 | }
22 |
23 | case USER_LOGGED_OUT:
24 | return initialState
25 |
26 | default:
27 | return state
28 | }
29 | }
30 |
31 | export function fakeLogin() {
32 | return dispatch => {
33 | setTimeout(() => {
34 | dispatch({
35 | type: USER_LOGGED_IN,
36 | payload: {
37 | avatar: '//placecage.com/200/200',
38 | name: 'UserName',
39 | points: 1337,
40 | rank_group: 5,
41 | },
42 | })
43 | }, 2000) // fake db delay
44 | }
45 | }
46 |
47 | export function logout() {
48 | return {
49 | type: USER_LOGGED_OUT,
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/templates/react-router-4/static/css/reboot.css:
--------------------------------------------------------------------------------
1 | *,
2 | *::before,
3 | *::after {
4 | box-sizing: border-box;
5 | }
6 |
7 | html {
8 | font-family: sans-serif;
9 | line-height: 1.15;
10 | -webkit-text-size-adjust: 100%;
11 | -ms-text-size-adjust: 100%;
12 | -ms-overflow-style: scrollbar;
13 | -webkit-tap-highlight-color: transparent;
14 | }
15 |
16 | @-ms-viewport {
17 | width: device-width;
18 | }
19 |
20 | article,
21 | aside,
22 | dialog,
23 | figcaption,
24 | figure,
25 | footer,
26 | header,
27 | hgroup,
28 | main,
29 | nav,
30 | section {
31 | display: block;
32 | }
33 |
34 | body {
35 | margin: 0;
36 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
37 | 'Helvetica Neue', Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
38 | 'Segoe UI Symbol';
39 | font-size: 1rem;
40 | font-weight: normal;
41 | line-height: 1.5;
42 | color: #212529;
43 | text-align: left;
44 | background-color: #fff;
45 | }
46 |
47 | [tabindex='-1']:focus {
48 | outline: none !important;
49 | }
50 |
51 | hr {
52 | box-sizing: content-box;
53 | height: 0;
54 | overflow: visible;
55 | }
56 |
57 | h1,
58 | h2,
59 | h3,
60 | h4,
61 | h5,
62 | h6 {
63 | margin-top: 0;
64 | margin-bottom: 0.5rem;
65 | }
66 |
67 | p {
68 | margin-top: 0;
69 | margin-bottom: 1rem;
70 | }
71 |
72 | abbr[title],
73 | abbr[data-original-title] {
74 | text-decoration: underline;
75 | -webkit-text-decoration: underline dotted;
76 | text-decoration: underline dotted;
77 | cursor: help;
78 | border-bottom: 0;
79 | }
80 |
81 | address {
82 | margin-bottom: 1rem;
83 | font-style: normal;
84 | line-height: inherit;
85 | }
86 |
87 | ol,
88 | ul,
89 | dl {
90 | margin-top: 0;
91 | margin-bottom: 1rem;
92 | }
93 |
94 | ol ol,
95 | ul ul,
96 | ol ul,
97 | ul ol {
98 | margin-bottom: 0;
99 | }
100 |
101 | dt {
102 | font-weight: bold;
103 | }
104 |
105 | dd {
106 | margin-bottom: 0.5rem;
107 | margin-left: 0;
108 | }
109 |
110 | blockquote {
111 | margin: 0 0 1rem;
112 | }
113 |
114 | dfn {
115 | font-style: italic;
116 | }
117 |
118 | b,
119 | strong {
120 | font-weight: bolder;
121 | }
122 |
123 | small {
124 | font-size: 80%;
125 | }
126 |
127 | sub,
128 | sup {
129 | position: relative;
130 | font-size: 75%;
131 | line-height: 0;
132 | vertical-align: baseline;
133 | }
134 |
135 | sub {
136 | bottom: -0.25em;
137 | }
138 |
139 | sup {
140 | top: -0.5em;
141 | }
142 |
143 | a {
144 | color: #007bff;
145 | text-decoration: none;
146 | background-color: transparent;
147 | -webkit-text-decoration-skip: objects;
148 | }
149 |
150 | a:hover {
151 | color: #0056b3;
152 | text-decoration: underline;
153 | }
154 |
155 | a:not([href]):not([tabindex]) {
156 | color: inherit;
157 | text-decoration: none;
158 | }
159 |
160 | a:not([href]):not([tabindex]):focus,
161 | a:not([href]):not([tabindex]):hover {
162 | color: inherit;
163 | text-decoration: none;
164 | }
165 |
166 | a:not([href]):not([tabindex]):focus {
167 | outline: 0;
168 | }
169 |
170 | pre,
171 | code,
172 | kbd,
173 | samp {
174 | font-family: monospace, monospace;
175 | font-size: 1em;
176 | }
177 |
178 | pre {
179 | margin-top: 0;
180 | margin-bottom: 1rem;
181 | overflow: auto;
182 | -ms-overflow-style: scrollbar;
183 | }
184 |
185 | figure {
186 | margin: 0 0 1rem;
187 | }
188 |
189 | img {
190 | vertical-align: middle;
191 | border-style: none;
192 | }
193 |
194 | svg:not(:root) {
195 | overflow: hidden;
196 | }
197 |
198 | a,
199 | area,
200 | button,
201 | [role='button'],
202 | input:not([type='range']),
203 | label,
204 | select,
205 | summary,
206 | textarea {
207 | -ms-touch-action: manipulation;
208 | touch-action: manipulation;
209 | }
210 |
211 | table {
212 | border-collapse: collapse;
213 | }
214 |
215 | caption {
216 | padding-top: 0.75rem;
217 | padding-bottom: 0.75rem;
218 | color: #868e96;
219 | text-align: left;
220 | caption-side: bottom;
221 | }
222 |
223 | th {
224 | text-align: inherit;
225 | }
226 |
227 | label {
228 | display: inline-block;
229 | margin-bottom: 0.5rem;
230 | }
231 |
232 | button {
233 | border-radius: 0;
234 | }
235 |
236 | button:focus {
237 | outline: 1px dotted;
238 | outline: 5px auto -webkit-focus-ring-color;
239 | }
240 |
241 | input,
242 | button,
243 | select,
244 | optgroup,
245 | textarea {
246 | margin: 0;
247 | font-family: inherit;
248 | font-size: inherit;
249 | line-height: inherit;
250 | }
251 |
252 | button,
253 | input {
254 | overflow: visible;
255 | }
256 |
257 | button,
258 | select {
259 | text-transform: none;
260 | }
261 |
262 | button,
263 | html [type='button'],
264 | [type='reset'],
265 | [type='submit'] {
266 | -webkit-appearance: button;
267 | }
268 |
269 | button::-moz-focus-inner,
270 | [type='button']::-moz-focus-inner,
271 | [type='reset']::-moz-focus-inner,
272 | [type='submit']::-moz-focus-inner {
273 | padding: 0;
274 | border-style: none;
275 | }
276 |
277 | input[type='radio'],
278 | input[type='checkbox'] {
279 | box-sizing: border-box;
280 | padding: 0;
281 | }
282 |
283 | input[type='date'],
284 | input[type='time'],
285 | input[type='datetime-local'],
286 | input[type='month'] {
287 | -webkit-appearance: listbox;
288 | }
289 |
290 | textarea {
291 | overflow: auto;
292 | resize: vertical;
293 | }
294 |
295 | fieldset {
296 | min-width: 0;
297 | padding: 0;
298 | margin: 0;
299 | border: 0;
300 | }
301 |
302 | legend {
303 | display: block;
304 | width: 100%;
305 | max-width: 100%;
306 | padding: 0;
307 | margin-bottom: 0.5rem;
308 | font-size: 1.5rem;
309 | line-height: inherit;
310 | color: inherit;
311 | white-space: normal;
312 | }
313 |
314 | progress {
315 | vertical-align: baseline;
316 | }
317 |
318 | [type='number']::-webkit-inner-spin-button,
319 | [type='number']::-webkit-outer-spin-button {
320 | height: auto;
321 | }
322 |
323 | [type='search'] {
324 | outline-offset: -2px;
325 | -webkit-appearance: none;
326 | }
327 |
328 | [type='search']::-webkit-search-cancel-button,
329 | [type='search']::-webkit-search-decoration {
330 | -webkit-appearance: none;
331 | }
332 |
333 | ::-webkit-file-upload-button {
334 | font: inherit;
335 | -webkit-appearance: button;
336 | }
337 |
338 | output {
339 | display: inline-block;
340 | }
341 |
342 | summary {
343 | display: list-item;
344 | }
345 |
346 | template {
347 | display: none;
348 | }
349 |
350 | [hidden] {
351 | display: none !important;
352 | }
353 |
--------------------------------------------------------------------------------
/templates/react-router-4/store/index.js:
--------------------------------------------------------------------------------
1 | import { createStore, applyMiddleware, compose } from 'redux'
2 | import { routerMiddleware } from 'react-router-redux'
3 | import thunk from 'redux-thunk'
4 | import reducers from '../modules'
5 |
6 | export default history => {
7 | const composeEnhancers =
8 | window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
9 |
10 | const middleware = [routerMiddleware(history), thunk]
11 |
12 | // add redux-devtools for development
13 | const middlewares =
14 | process.env.NODE_ENV === 'production'
15 | ? applyMiddleware(...middleware)
16 | : composeEnhancers(applyMiddleware(...middleware))
17 |
18 | const store = createStore(reducers, middlewares)
19 |
20 | // hot module replacement for reducers
21 | if (module.hot) {
22 | module.hot.accept('../modules', () => {
23 | const nextRootReducer = require('../modules').default
24 | store.replaceReducer(nextRootReducer)
25 | })
26 | }
27 |
28 | return store
29 | }
30 |
--------------------------------------------------------------------------------
/test/pretest.js:
--------------------------------------------------------------------------------
1 | const wooo = require('../lib').default()
2 |
--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const { resolve } = require('path')
3 |
4 | function dp(pth, done) {
5 | fs.open(pth, 'r', (err, fd) => {
6 | if (err) {
7 | return done(err)
8 | }
9 |
10 | done()
11 | })
12 | }
13 |
14 | function resolveDir(dir) {
15 | return resolve(__dirname, dir)
16 | }
17 |
18 | describe('after running wooo', () => {
19 | describe('containers', () => {
20 | it('should created containers folder', done => {
21 | dp(resolveDir('../_test_/containers'), done)
22 | })
23 |
24 | describe('App', () => {
25 | it('should created containers/App.js', done => {
26 | dp(resolveDir('../_test_/containers/App.js'), done)
27 | })
28 | })
29 |
30 | describe('Home', () => {
31 | it('should created containers/Home.js', done => {
32 | dp(resolveDir('../_test_/containers/Home.js'), done)
33 | })
34 | })
35 | })
36 |
37 | describe('modules', () => {
38 | it('should created modules folder', done => {
39 | dp(resolveDir('../_test_/modules'), done)
40 | })
41 |
42 | it('should created modules/index file', done => {
43 | dp(resolveDir('../_test_/modules/index.js'), done)
44 | })
45 |
46 | it('should created modules/user file', done => {
47 | dp(resolveDir('../_test_/modules/user.js'), done)
48 | })
49 | })
50 |
51 | describe('static', () => {
52 | it('should created static folder', done => {
53 | dp(resolveDir('../_test_/static'), done)
54 | })
55 |
56 | it('should created static/css/reboot.css file', done => {
57 | dp(resolveDir('../_test_/static/css/reboot.css'), done)
58 | })
59 | })
60 |
61 | describe('store', () => {
62 | it('should created store folder', done => {
63 | dp(resolveDir('../_test_/store'), done)
64 | })
65 |
66 | it('should created store/index file', done => {
67 | dp(resolveDir('../_test_/store/index.js'), done)
68 | })
69 | })
70 | })
71 |
--------------------------------------------------------------------------------