Skip to content

Commit 1e15562

Browse files
committed
Fastify Generator initial commit
0 parents  commit 1e15562

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+34755
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019 Sean Maxwell
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.

README.md

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<img alt='overnightjs' src='https://github.com/seanpmaxwell/express-generator-typescript/raw/master/express-typescript.png' border='0'>
2+
3+
[Express](https://www.npmjs.com/package/express) with [TypeScript's](https://www.npmjs.com/package/typescript) application generator.
4+
5+
<a href="https://www.npmjs.com/package/express-generator-typescript" target="_blank"><img src="https://img.shields.io/npm/v/express-generator-typescript.svg" alt="NPM Version" /></a>
6+
<a href="https://www.npmjs.com/package/express-generator-typescript" target="_blank"><img src="https://img.shields.io/npm/l/express-generator-typescript.svg" alt="Package License" /></a>
7+
<a href="https://www.npmjs.com/package/express-generator-typescript" target="_blank"><img src="https://img.shields.io/npm/dm/express-generator-typescript.svg" alt="NPM Downloads" /></a>
8+
9+
10+
## What is it?
11+
12+
Creates a new express application similar to the _express-generator_ module. Except this new
13+
application is configured to use TypeScript instead of plain JavaScript.
14+
15+
16+
17+
## Why express-generator-typescript?
18+
19+
NodeJS is great for the rapid development of web-projects, but is often neglected because of the lack of
20+
type safety. TypeScript solves this issue and (along with its linter file) can even make your code
21+
more robust than some other static languages like Java.
22+
23+
There are some other tools out there to generate express apps with TypeScript such as
24+
_express-generator-ts_, but these either haven't been updated in a while or install a lot of junk
25+
in your project (such as an ORM).
26+
27+
Due to the heavy use of single-page-applications, no view-engine is configured by default. Express is
28+
only setup with the minimal settings for calling APIs and serving an index.html file. All the tools you
29+
need to run for development (while restarting on changes), building, testing, and running for production
30+
are packaged with this library.
31+
32+
In addition, relative paths are also setup, so you don't have to go through the trouble of installing
33+
and configuring _tsconfig-paths_ and _module-alias_. Just make sure to update `paths` in _tsconfig.json_
34+
and `_moduleAliases` in _package.json_ if you want to add/edit the relative paths.
35+
36+
37+
## Sample-project
38+
39+
When you run _express-generator-typescript_, it sets up a very simple application with routes for
40+
adding, updating, deleting, and fetching user objects. This is just to demonstrate how routing is done
41+
with express.
42+
43+
If you want a fully-secure application, you can pass the `--with-auth` option and you will have an
44+
application which requires you to logon before calling APIs on user objects. The app is
45+
configured with production quality client-side security and uses signed-cookies and jsonwebtokens
46+
to store user-session data. If you're new to web-development and still learning about securing websites,
47+
I highly encourage to use this option.
48+
49+
50+
## Installation
51+
52+
```sh
53+
$ Just use 'npx'
54+
Or
55+
$ npm install -g express-generator-typescript
56+
```
57+
58+
59+
## Quick Start
60+
61+
The quickest way to get started is use npx and pass in the name of the project you want to create.
62+
If you don't specify a project name, the default _express-gen-ts_ will be used instead.
63+
64+
Create the app:
65+
66+
```bash
67+
$ npx express-generator-typescript "project name (default is express-gen-ts)"
68+
OR
69+
$ npx express-generator-typescript --with-auth "project name (default is express-gen-ts)"
70+
```
71+
72+
Start your express-generator-typescript app in development mode at `http://localhost:3000/`:
73+
74+
```bash
75+
$ cd "project name" && npm run start:dev
76+
```
77+
78+
79+
## Available commands for the server.
80+
81+
- Run the server in development mode: `npm run start:dev`.
82+
- Run all unit-tests: `npm test`.
83+
- Run a single unit-test: `npm test -- --testFile="name of test file" (i.e. --testFile=Users)`.
84+
- Check for linting errors: `npm run lint`.
85+
- Build the project for production: `npm run build`.
86+
- Run the production build: `npm start`.
87+
- Run production build with a different env file `npm start -- --env="name of env file" (default is production)`.
88+
89+
90+
## Debugging
91+
During development, _express-generator-typescript_ uses `nodemon` to restart the server when changes
92+
are detected. If you want to enable debugging for node, you'll need to modify the nodemon configurations.
93+
This is located under `nodemonConfig:` in `package.json` for the server and `./spec/nodemon.json` for
94+
unit-testing. For the `exec` property, replace `ts-node` with `node --inspect -r ts-node/register`.
95+
96+
97+
## Note for windows users
98+
99+
If you use the `--with-auth` option and are on Windows, the `bcrypt` module tends to be fussy. To
100+
use this module on Windows you need to make sure you have the node Windows build tools installed.
101+
I don't want to post instructions because they might change frequently. I would search the Microsoft
102+
docs on how to setup Node for Windows. To be able to debug in VSCODE on windows I also had to install
103+
the `node-gyp` module globally as well.
104+
105+
Happy web-deving :)
106+
107+
108+
109+
## License
110+
111+
[MIT](LICENSE)

cli.js

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#!/usr/bin/env node
2+
3+
const path = require('path');
4+
const fastifyGenTs = require('./fastify-generator');
5+
const { start, get } = require('prompt');
6+
7+
const options = [
8+
{
9+
description: "Fastify Plugin Structure with Mongoose and Swagger",
10+
defaultName: "fastify-plugin-mongoose-swagger",
11+
templateName: "plugin-structure-mongoose",
12+
dependencies: "dotenv fastify fastify-cors fastify-oas mongoose",
13+
devDependencies: "@types/cors @types/jest @types/node jest nodemon ts-jest ts-node typescript @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint"
14+
}, {
15+
description: "Fastify Plugin Structure with TypeORM and Swagger",
16+
defaultName: "fastify-plugin-typeorm-swagger",
17+
templateName: "plugin-structure-typeorm",
18+
dependencies: "dotenv fastify fastify-cors fastify-oas fastify-plugin mongodb reflect-metadata typeorm",
19+
devDependencies: "@types/cors @types/jest @types/node jest nodemon ts-jest ts-node typescript @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint"
20+
}, {
21+
description: "Fastify with Mongoose and Express Directory Structure",
22+
defaultName: "fastify-express-mongoose",
23+
templateName: "express-structure-mongoose",
24+
dependencies: "dotenv fastify fastify-cors mongoose",
25+
devDependencies: "@types/cors @types/jest @types/node jest nodemon ts-jest ts-node typescript @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint"
26+
}, {
27+
description: "Fastify with TypeORM and Express Directory Structure",
28+
defaultName: "fastify-express-typeorm",
29+
templateName: "express-structure-typeorm",
30+
dependencies: "dotenv fastify fastify-cors fastify-plugin mongodb reflect-metadata typeorm",
31+
devDependencies: "@types/cors @types/jest @types/node jest nodemon ts-jest ts-node typescript @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint"
32+
},
33+
];
34+
const schema = {
35+
properties: {
36+
option: {
37+
description: 'Select a options for the type of project',
38+
pattern: /^[1-4]{0,1}$/,
39+
message: 'Specify a number in range of 4 corresponding options',
40+
required: true
41+
},
42+
path: {
43+
description: '[OPTIONAL] Specify directory where create the files, if no path is provided, current directory will be used',
44+
message: '[OPTIONAL] Specify directory where create the files, if no path is provided, current directory will be used',
45+
default: './',
46+
required: false
47+
},
48+
projectName: {
49+
description: '[OPTIONAL] Specify project name',
50+
pattern: /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/,
51+
message: '[OPTIONAL] Specify project name',
52+
required: false
53+
}
54+
}
55+
};
56+
57+
58+
const getDest = (option, destFolder, projectName) => {
59+
return `${path.join(process.cwd(), destFolder)}/${projectName || option.defaultName}`;
60+
}
61+
62+
63+
const initiate = async (option, path, projectName) => {
64+
try {
65+
const destination = getDest(option, path, projectName);
66+
console.log(`Choose the number for corresponding option.\n${destination}`);
67+
await fastifyGenTs(option, destination);
68+
console.log('Project setup complete!');
69+
} catch (error) {
70+
console.error(error);
71+
}
72+
};
73+
74+
75+
console.log('\x1b[33m\x1b[40m%s\x1b[0m', 'Setting up new Fastify TypeScript project...\n');
76+
console.log('\x1b[33m\x1b[40m%s\x1b[0m', `Available options:\n`);
77+
options.map((el, index) => console.log(`${index + 1}. ${el.description} -> ${el.templateName}\n`));
78+
79+
80+
start();
81+
82+
83+
get(schema, (error, argv) => {
84+
if (error) {
85+
console.error(`Prompt error: ${error}`);
86+
throw error;
87+
} else {
88+
console.log(`Option Chosen:\n${options[argv.option].templateName}\nDirectory Chosen/Default:\n${argv.path}\nProject Name:\n${argv.projectName || options[argv.option].defaultName}`);
89+
console.log(`Starting Project creation...`);
90+
initiate(options[argv.option], argv.path, argv.projectName);
91+
}
92+
});

fastify-generator.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
const path = require('path');
2+
const { execSync } = require('child_process');
3+
const ncp = require('ncp').ncp;
4+
const { writeFile, mkdir } = require('fs/promises');
5+
const { existsSync } = require('fs');
6+
7+
8+
const copyProjectFiles = (config, destination) => {
9+
const prjFolder = `./templates/${config.templateName}`;
10+
const source = path.join(__dirname, prjFolder);
11+
return new Promise((resolve, reject) => {
12+
ncp.limit = 16;
13+
ncp(source, destination, { filter: /^((?!node_modules|coverage|package-lock.json).)*$/ }, (err) => {
14+
if (err) {
15+
reject(err);
16+
}
17+
resolve();
18+
});
19+
})
20+
}
21+
22+
23+
const updatePackageJson = async (destination) => {
24+
try {
25+
const pathName = `${destination}/package.json`
26+
let data = require(pathName);
27+
data.name = path.basename(destination);
28+
data = JSON.stringify(data, null, 2);
29+
await writeFile(pathName, data);
30+
} catch (err) {
31+
throw err;
32+
}
33+
}
34+
35+
36+
const downloadNodeModules = (config, destination) => {
37+
const options = {cwd: destination};
38+
console.log('\x1b[31m\x1b[40m%s\x1b[0m', 'Installing dependencies...\n');
39+
execSync('npm i -s ' + config.dependencies, options);
40+
execSync('npm i -D ' + config.devDependencies, options);
41+
console.log('\x1b[32m\x1b[40m%s\x1b[0m', 'Dependencies installation done...\n');
42+
}
43+
44+
45+
const fastifyGenTs = async (config, destination) => {
46+
try {
47+
if (!existsSync(destination)) {
48+
await mkdir(destination, { recursive: true });
49+
}
50+
await copyProjectFiles(config, destination);
51+
await updatePackageJson(destination);
52+
downloadNodeModules(config, destination);
53+
} catch (err) {
54+
console.error(err);
55+
}
56+
}
57+
58+
59+
module.exports = fastifyGenTs;

0 commit comments

Comments
 (0)