Skip to content
This repository was archived by the owner on May 25, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Solid React Application Generator

## 0.6.1 (August 28, 2019)

#### Generator

##### Added
* New prompt when creating a new application. The new prompt asks if the developer would like to install a full sample application or just a simple one-page application. This provides a way for people familiar with Solid to create new blank applications and get started quicker.

## 0.6.0 (August 14, 2019)

#### Solid React Application Base
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,11 @@ Once the generator is installed, you can create a new application with just a fe

1. In a console window, navigate to the desired parent folder of the new application.
2. Use the command: ``` yo @inrupt/solid-react ```
3. You will be prompted to set:
3. You will be prompted:
1. An application name. This will also be the name of the new folder in which the new application lives.
2. A version number.
3. Whether the application is private or public.
2. Whether or not to install a sample application, or a simple one-page application skeleton
3. A version number.
4. Whether the application is private or public.
4. Navigate into the new folder.
5. If you would like to start the application, simply run ``` npm run start ``` in the new folder, otherwise you can begin editing and writing your application!

Expand Down
16 changes: 8 additions & 8 deletions __tests__/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ const assert = require('yeoman-assert');
const helpers = require('yeoman-test');

describe('generator-solid-react:app', () => {
beforeAll(() => {
return helpers
.run(path.join(__dirname, '../generators/app'))
.withPrompts({ someAnswer: true });
});
beforeAll(() => {
return helpers
.run(path.join(__dirname, '../generators/app'))
.withPrompts({ someAnswer: true });
});

it('creates files', () => {
assert.file(['dummyfile.txt']);
});
it('creates files', () => {
assert.file(['dummyfile.txt']);
});
});
291 changes: 191 additions & 100 deletions generators/app/index.js
Original file line number Diff line number Diff line change
@@ -1,113 +1,204 @@
const Generator = require("yeoman-generator");
const chalk = require("chalk");
const yosay = require("yosay");
const figlet = require("figlet");
const path = require("path");
const mkdirp = require("mkdirp");
const glob = require("glob");
const voca = require("voca");
const Generator = require('yeoman-generator');
const chalk = require('chalk');
const figlet = require('figlet');
const path = require('path');
const mkdirp = require('mkdirp');
const voca = require('voca');

const fileList = [
// ROOT FILES
{ src: 'README.md' },
{ src: 'package.json' },
// SRC ROOT FILES
{ src: 'src/App.js' },
{ src: 'src/App.styled.js' },
{ src: 'src/App.test.js' },
{ src: 'src/i18n.js' },
{ src: 'src/index.css' },
{ src: 'src/index.js' },
{ src: 'src/serviceWorker.js' },
// CONFIG FILES
{ src: 'config/**', dest: 'config' },
{ src: 'scripts/**', dest: 'scripts' },
// PUBLIC FILES
{ src: 'public/**', dest: 'public' },
// TEST FILES
{ src: 'test/**', dest: 'test' },
// COMPONENTS
{ src: 'src/components/**', dest: 'src/components' },
// CONSTANTS
{ src: 'src/constants/**', dest: 'src/constants' },
// CONTEXTS
{ src: 'src/contexts/**', dest: 'src/contexts' },
// HIGHER ORDER COMPONENTS
{ src: 'src/hocs/**', dest: 'src/hocs' },
// HOOKS
{ src: 'src/hooks/**', dest: 'src/hooks' },
// LAYOUTS
{ src: 'src/layouts/**', dest: 'src/layouts' },
// SERVICES
{ src: 'src/services/**', dest: 'src/services' },
// UTILS
{ src: 'src/utils/**', dest: 'src/utils' },
// DEFAULT CONTAINERS
{ src: 'src/containers/Login/**', dest: 'src/containers/Login' },
{
src: 'src/containers/PageNotFound/**',
dest: 'src/containers/PageNotFound',
},
{ src: 'src/containers/Register/**', dest: 'src/containers/Register' },
{ src: 'src/containers/Welcome/**', dest: 'src/containers/Welcome' },
];

module.exports = class extends Generator {
constructor(args, opts) {
super(args, opts);
}
prompting() {
const done = this.async();
this.log(chalk.cyan.bold('Welcome to the \n Solid React Generator'));

return this.prompt([
{
type: 'input',
name: 'appName',
message: 'Please enter your application name :',
store: true,
validate: appName => {
const pass = appName.match(/^[^\d\s!@£$%^&*()+=]+$/);
if (pass) {
return true;
}
return `${chalk.red(
'Provide a valid "App name", digits and whitespaces not allowed'
)}`;
},
default: voca.kebabCase(this.appname), // Default to current folder name
},
{
type: 'confirm',
name: 'appInstalled',
message:
'Solid React Generator can install an example application illustrating how to interact with Solid, or a basic application framework. Do you want to install the example application?',
},
{
type: 'input',
name: 'appVersion',
message: 'Initial version:',
store: true,
validate: appVersion => {
const pass = appVersion.match(
/^\d{1,2}\.\d{1,2}\.\d{1,2}$/
);
if (pass) {
return true;
}
return `${chalk.red(
'Provide a valid version (ex: 0.1.0)'
)}`;
},
default: '0.1.0',
},
{
type: 'list',
name: 'isPrivate',
message: 'Is this application private?',
choices: ['false', 'true'],
default: 'false',
},
]).then(answers => {
this.props = answers;
done();
});
}

prompting() {
const done = this.async();
this.log(chalk.cyan.bold("Welcome to the \n Solid React Generator"));
writing() {
const { appName, appVersion, isPrivate, appInstalled } = this.props;
const pkgJson = {
name: appName,
version: appVersion,
private: isPrivate === 'true',
};

return this.prompt([
{
type: "input",
name: "appName",
message: "Please enter your application name :",
store: true,
validate: appName => {
const pass = appName.match(/^[^\d\s!@£$%^&*()+=]+$/);
if (pass) {
return true;
}
return `${chalk.red(
'Provide a valid "App name", digits and whitespaces not allowed'
)}`;
},
default: voca.kebabCase(this.appname) // Default to current folder name
},
{
type: "input",
name: "appVersion",
message: "version:",
store: true,
validate: appVersion => {
const pass = appVersion.match(/^\d{1,2}\.\d{1,2}\.\d{1,2}$/);
if (pass) {
return true;
}
return `${chalk.red("Provide a valid version (ex: 0.1.0)")}`;
},
default: "0.1.0"
},
{
type: "list",
name: "isPrivate",
message: "Is it private?",
choices: ["false", "true"],
default: "false"
}
]).then(answers => {
this.props = answers;
done();
});
}
// FINALIZE FILES TO INSTALL
this.log('Processing Configuration...');
if (appInstalled) {
fileList.push(
{ src: 'src/containers/index.js' },
{ src: 'src/routes.js' },
{
src: 'src/constants/navigation.js',
dest: 'src/constants/navigation.js',
},
{
src: 'src/containers/Profile/**',
dest: 'src/containers/Profile',
},
{
src: 'src/containers/TicTacToe/**',
dest: 'src/containers/TicTacToe',
},
{ src: '.env' }
);
} else {
fileList.push(
{ src: 'src/_routes.lite.js', dest: 'src/routes.js' },
{
src: 'src/containers/_index.lite.js',
dest: 'src/containers/index.js',
},
{
src: 'src/constants/_navigation.lite.js',
dest: 'src/constants/navigation.js',
},
{ src: '.env.lite', dest: '.env' },
{
src: 'src/components/AuthNavBar/_auth-nav-bar.lite.js',
dest: 'src/components/AuthNavBar/auth-nav-bar.component.js',
}
);
}

writing() {
const { appName, appVersion, isPrivate } = this.props;
const pkgJson = {
name: appName,
version: appVersion,
private: isPrivate === "true"
};
this.log(chalk.blue(this.templatePath('package.json')));

this.log(chalk.blue(this.templatePath("package.json")));
const fromTemplateFiles = glob.sync(this.templatePath("./*"), {
ignore: ["**/node_modules", "**/dist"],
dot: true
});

if (path.basename(this.destinationPath()) !== appName) {
this.log("Creating folder...");
mkdirp(appName);
this.destinationRoot(this.destinationPath(appName));
}
if (path.basename(this.destinationPath()) !== appName) {
this.log('Creating folder...');
mkdirp(appName);
this.destinationRoot(this.destinationPath(appName));
}

this.log("Copying app directory...");
this.log('Copying app directory...');

this.fs.copyTpl(fromTemplateFiles, this.destinationRoot(), {
title: voca.titleCase(appName)
});
this.fs.extendJSON(this.destinationPath("package.json"), pkgJson);
// EXTEND PACKAGE.JSON WITH USER PROMPTS
this.fs.extendJSON(this.destinationPath('package.json'), pkgJson);

}
this.log(this.templatePath());

install() {
this.log("Installing dependencies...");
this.npmInstall();
this.completed = true;
}
// WRITE NEW FILES BASED ON USER PROMPTS
fileList.forEach(newFile => {
return this.fs.copyTpl(
this.templatePath(newFile.src),
this.destinationPath(newFile.dest || newFile.src),
{ title: voca.titleCase(appName) }
);
});
}

install() {
this.log('Installing dependencies...');
this.npmInstall();
this.completed = true;
}

end() {
if (this.completed) {
this.log("Installation complete. Welcome to Solid");
this.log(
chalk.bold.blue(
figlet.textSync("SOLID", {
font: "3D-ASCII",
horizontalLayout: "full",
verticalLayout: "full"
})
)
);
return;
end() {
if (this.completed) {
this.log('Installation complete. Welcome to Solid');
this.log(
chalk.bold.blue(
figlet.textSync('SOLID', {
font: '3D-ASCII',
horizontalLayout: 'full',
verticalLayout: 'full',
})
)
);
}
}
}
};
3 changes: 3 additions & 0 deletions generators/app/templates/.env.lite
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
REACT_APP_VERSION=$npm_package_version
REACT_APP_NAME=$npm_package_name
REACT_APP_COMPANY_NAME=inrupt Inc.
31 changes: 31 additions & 0 deletions generators/app/templates/src/_routes.lite.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React, { Fragment } from 'react';
import { PrivateLayout, PublicLayout, NotLoggedInLayout } from '@layouts';
import { BrowserRouter as Router, Switch, Redirect } from 'react-router-dom';

import { Login, Register, PageNotFound, Welcome, RegistrationSuccess } from './containers';

const privateRoutes = [
{
id: 'welcome',
path: '/welcome',
component: Welcome
}
];

const Routes = () => (
<Router>
<Fragment>
<Switch>
<NotLoggedInLayout component={Login} path="/login" exact />
<NotLoggedInLayout component={Register} path="/register" exact />
<NotLoggedInLayout path="/register/success" component={RegistrationSuccess} exact />
<PublicLayout path="/404" component={PageNotFound} exact />
<Redirect from="/" to="/welcome" exact />
<PrivateLayout path="/" routes={privateRoutes} />
<Redirect to="/404" />
</Switch>
</Fragment>
</Router>
);

export default Routes;
Loading