├── .npmrc ├── .gitignore ├── src ├── templates │ ├── TypeScript │ │ ├── .gitignore │ │ ├── .env │ │ ├── src │ │ │ ├── modules │ │ │ │ ├── user │ │ │ │ │ ├── services │ │ │ │ │ │ ├── userService.interface.ts │ │ │ │ │ │ └── userService.ts │ │ │ │ │ └── userRouter.ts │ │ │ │ ├── router.interface.ts │ │ │ │ └── baseRouter.ts │ │ │ ├── server │ │ │ │ ├── app.interface.ts │ │ │ │ └── app.ts │ │ │ ├── config │ │ │ │ ├── environment.ts │ │ │ │ └── config.ts │ │ │ ├── helpers │ │ │ │ ├── responseType.ts │ │ │ │ ├── helper.interface.ts │ │ │ │ ├── logger.ts │ │ │ │ └── helper.ts │ │ │ └── index.ts │ │ ├── test │ │ │ └── user.ts │ │ ├── tsconfig.json │ │ ├── .eslintrc.js │ │ └── package.json │ ├── TypeScript-Inversify │ │ ├── .gitignore │ │ ├── .env │ │ ├── src │ │ │ ├── modules │ │ │ │ ├── user │ │ │ │ │ ├── services │ │ │ │ │ │ ├── userService.interface.ts │ │ │ │ │ │ └── userService.ts │ │ │ │ │ └── userRouter.ts │ │ │ │ ├── router.interface.ts │ │ │ │ └── baseRouter.ts │ │ │ ├── server │ │ │ │ ├── app.interface.ts │ │ │ │ └── app.ts │ │ │ ├── config │ │ │ │ ├── environment.ts │ │ │ │ ├── ioc.ts │ │ │ │ └── config.ts │ │ │ ├── const │ │ │ │ └── types.ts │ │ │ ├── helpers │ │ │ │ ├── responseType.ts │ │ │ │ ├── helper.interface.ts │ │ │ │ ├── logger.ts │ │ │ │ └── helper.ts │ │ │ ├── container.ts │ │ │ └── index.ts │ │ ├── tsconfig.json │ │ ├── .eslintrc.js │ │ ├── test │ │ │ └── user.ts │ │ └── package.json │ ├── JavaScript │ │ ├── .gitignore │ │ ├── .env │ │ ├── src │ │ │ ├── config │ │ │ │ └── config.js │ │ │ ├── modules │ │ │ │ ├── route.js │ │ │ │ └── user │ │ │ │ │ ├── userRouter.js │ │ │ │ │ └── userService.js │ │ │ ├── helpers │ │ │ │ └── logger.js │ │ │ └── index.js │ │ ├── test │ │ │ └── user.js │ │ ├── .eslintrc.json │ │ └── package.json │ ├── TypeScript-TypeORM-Inversify │ │ ├── .gitignore │ │ ├── src │ │ │ ├── modules │ │ │ │ ├── user │ │ │ │ │ ├── services │ │ │ │ │ │ ├── userService.interface.ts │ │ │ │ │ │ └── userService.ts │ │ │ │ │ └── userRouter.ts │ │ │ │ ├── router.interface.ts │ │ │ │ └── baseRouter.ts │ │ │ ├── server │ │ │ │ ├── app.interface.ts │ │ │ │ └── app.ts │ │ │ ├── config │ │ │ │ ├── environment.ts │ │ │ │ ├── ioc.ts │ │ │ │ ├── db.ts │ │ │ │ └── config.ts │ │ │ ├── const │ │ │ │ └── types.ts │ │ │ ├── helpers │ │ │ │ ├── responseType.ts │ │ │ │ ├── helper.interface.ts │ │ │ │ ├── logger.ts │ │ │ │ └── helper.ts │ │ │ ├── models │ │ │ │ ├── entities │ │ │ │ │ └── Users.ts │ │ │ │ └── Base.ts │ │ │ ├── container.ts │ │ │ └── index.ts │ │ ├── .env │ │ ├── tsconfig.json │ │ ├── .eslintrc.js │ │ ├── test │ │ │ └── user.ts │ │ └── package.json │ ├── TypeScript-TypeORM │ │ ├── .gitignore │ │ ├── src │ │ │ ├── modules │ │ │ │ ├── user │ │ │ │ │ ├── services │ │ │ │ │ │ ├── userService.interface.ts │ │ │ │ │ │ └── userService.ts │ │ │ │ │ └── userRouter.ts │ │ │ │ ├── router.interface.ts │ │ │ │ └── baseRouter.ts │ │ │ ├── server │ │ │ │ ├── app.interface.ts │ │ │ │ └── app.ts │ │ │ ├── config │ │ │ │ ├── environment.ts │ │ │ │ ├── db.ts │ │ │ │ └── config.ts │ │ │ ├── helpers │ │ │ │ ├── responseType.ts │ │ │ │ ├── helper.interface.ts │ │ │ │ ├── logger.ts │ │ │ │ └── helper.ts │ │ │ ├── models │ │ │ │ ├── entities │ │ │ │ │ └── Users.ts │ │ │ │ └── Base.ts │ │ │ └── index.ts │ │ ├── .env │ │ ├── test │ │ │ └── user.ts │ │ ├── tsconfig.json │ │ ├── .eslintrc.js │ │ └── package.json │ └── JavaScript-Sequelize │ │ ├── .gitignore │ │ ├── test │ │ └── user.js │ │ ├── .env │ │ ├── .eslintrc.json │ │ ├── src │ │ ├── modules │ │ │ ├── route.js │ │ │ └── user │ │ │ │ ├── userRouter.js │ │ │ │ └── userService.js │ │ ├── models │ │ │ ├── user.js │ │ │ └── index.js │ │ ├── config │ │ │ └── config.js │ │ ├── helpers │ │ │ └── logger.js │ │ └── index.js │ │ └── package.json ├── templateMapping.js ├── index.js ├── util.js ├── ui.js ├── create.js └── cli.js ├── working.gif ├── .eslintrc.json ├── .github └── workflows │ └── main.yml ├── test ├── create.js ├── ui.js └── util.js ├── CONTRIBUTING.md ├── LICENSE ├── package.json ├── CODE_OF_CONDUCT.md └── README.md /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /*/*/*/package-lock.json 3 | /*/*/*/yarn.lock 4 | -------------------------------------------------------------------------------- /src/templates/TypeScript/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /dist 3 | /*.log 4 | .vscode -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /dist 3 | /*.log 4 | .vscode -------------------------------------------------------------------------------- /working.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dopecodez/create-express-template/HEAD/working.gif -------------------------------------------------------------------------------- /src/templates/JavaScript/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | .vscode 5 | node_modules 6 | build -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /dist 3 | /*.log 4 | .vscode -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /dist 3 | /*.log 4 | .vscode 5 | yarn.lock -------------------------------------------------------------------------------- /src/templates/TypeScript/.env: -------------------------------------------------------------------------------- 1 | # Environment 2 | NODE_ENV=development 3 | 4 | # Server 5 | PORT=3000 -------------------------------------------------------------------------------- /src/templates/JavaScript-Sequelize/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | .vscode 5 | node_modules 6 | build -------------------------------------------------------------------------------- /src/templates/JavaScript/.env: -------------------------------------------------------------------------------- 1 | # Environment 2 | NODE_ENV=development 3 | 4 | # Server 5 | PORT=3000 6 | HOST=localhost 7 | -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/.env: -------------------------------------------------------------------------------- 1 | # Environment 2 | NODE_ENV=development 3 | 4 | # Server 5 | PORT=3000 6 | HOST=localhost 7 | -------------------------------------------------------------------------------- /src/templates/TypeScript/src/modules/user/services/userService.interface.ts: -------------------------------------------------------------------------------- 1 | export interface IUserService{ 2 | getRandomTest(): Promise; 3 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/src/modules/user/services/userService.interface.ts: -------------------------------------------------------------------------------- 1 | export interface IUserService{ 2 | getRandomTest(): Promise; 3 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/src/modules/user/services/userService.interface.ts: -------------------------------------------------------------------------------- 1 | export interface IUserService{ 2 | getRandomTest(): Promise; 3 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/modules/user/services/userService.interface.ts: -------------------------------------------------------------------------------- 1 | export interface IUserService{ 2 | getRandomTest(): Promise; 3 | } -------------------------------------------------------------------------------- /src/templates/TypeScript/src/modules/router.interface.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | 3 | export interface IRouter { 4 | readonly routes: Router 5 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/src/modules/router.interface.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | 3 | export interface IRouter { 4 | readonly routes: Router 5 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/src/modules/router.interface.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | 3 | export interface IRouter { 4 | readonly routes: Router 5 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/modules/router.interface.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | 3 | export interface IRouter { 4 | readonly routes: Router 5 | } -------------------------------------------------------------------------------- /src/templates/TypeScript/src/server/app.interface.ts: -------------------------------------------------------------------------------- 1 | import { Application } from 'express'; 2 | 3 | export interface ServerInterface { 4 | server(): Promise; 5 | } 6 | -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/src/server/app.interface.ts: -------------------------------------------------------------------------------- 1 | import { Application } from 'express'; 2 | 3 | export interface ServerInterface { 4 | server(): Promise; 5 | } 6 | -------------------------------------------------------------------------------- /src/templates/TypeScript/src/config/environment.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from 'dotenv'; 2 | 3 | export class Environment { 4 | static setup() { 5 | dotenv.config(); 6 | } 7 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/src/server/app.interface.ts: -------------------------------------------------------------------------------- 1 | import { Application } from 'express'; 2 | 3 | export interface ServerInterface { 4 | server(): Promise; 5 | } 6 | -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/src/config/environment.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from 'dotenv'; 2 | 3 | export class Environment { 4 | static setup() { 5 | dotenv.config(); 6 | } 7 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/src/config/environment.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from 'dotenv'; 2 | 3 | export class Environment { 4 | static setup() { 5 | dotenv.config(); 6 | } 7 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/server/app.interface.ts: -------------------------------------------------------------------------------- 1 | import { Application } from 'express'; 2 | 3 | export interface ServerInterface { 4 | server(): Promise; 5 | } 6 | -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/config/environment.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from 'dotenv'; 2 | 3 | export class Environment { 4 | static setup() { 5 | dotenv.config(); 6 | } 7 | } -------------------------------------------------------------------------------- /src/templates/JavaScript/src/config/config.js: -------------------------------------------------------------------------------- 1 | const dotenv = require('dotenv'); 2 | dotenv.config(); 3 | module.exports = { 4 | SERVER_PORT: process.env.PORT || '', 5 | NODE_ENV: process.env.NODE_ENV || '', 6 | }; 7 | -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/src/config/ioc.ts: -------------------------------------------------------------------------------- 1 | import '../server/app'; 2 | import '../modules/baseRouter'; 3 | import '../modules/user/userRouter'; 4 | import '../modules/user/services/userService' 5 | import '../helpers/helper' -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/config/ioc.ts: -------------------------------------------------------------------------------- 1 | import '../server/app'; 2 | import '../modules/baseRouter'; 3 | import '../modules/user/userRouter'; 4 | import '../modules/user/services/userService' 5 | import '../helpers/helper' -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/src/const/types.ts: -------------------------------------------------------------------------------- 1 | export const SERVER = 'server'; 2 | export const USERROUTE = 'userRoute'; 3 | export const BASEROUTE = 'baseRoute'; 4 | export const USERSERVICE = 'userServices'; 5 | export const HELPER = 'helper' -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/const/types.ts: -------------------------------------------------------------------------------- 1 | export const SERVER = 'server'; 2 | export const USERROUTE = 'userRoute'; 3 | export const BASEROUTE = 'baseRoute'; 4 | export const USERSERVICE = 'userServices'; 5 | export const HELPER = 'helper' -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/.env: -------------------------------------------------------------------------------- 1 | # Environment 2 | NODE_ENV=development 3 | 4 | # Server 5 | PORT=3000 6 | HOST=localhost 7 | 8 | #Database 9 | DB_HOST=127.0.0.1 10 | DB_USERNAME=root 11 | DB_PASSWORD=root 12 | DB_NAME=test_db 13 | DB_PORT=5432 14 | -------------------------------------------------------------------------------- /src/templates/TypeScript/src/helpers/responseType.ts: -------------------------------------------------------------------------------- 1 | export interface successResponse { 2 | status: number, 3 | body: any, 4 | message: string 5 | } 6 | 7 | export interface errorResponse { 8 | status: number, 9 | message: string 10 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/src/helpers/responseType.ts: -------------------------------------------------------------------------------- 1 | export interface successResponse { 2 | status: number, 3 | body: any, 4 | message: string 5 | } 6 | 7 | export interface errorResponse { 8 | status: number, 9 | message: string 10 | } -------------------------------------------------------------------------------- /src/templates/TypeScript/src/helpers/helper.interface.ts: -------------------------------------------------------------------------------- 1 | import { successResponse, errorResponse } from "./responseType"; 2 | 3 | export interface IHelper { 4 | createSuccessResponse(body:any): successResponse 5 | createErrorResponse(error:any): errorResponse 6 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/src/helpers/responseType.ts: -------------------------------------------------------------------------------- 1 | export interface successResponse { 2 | status: number, 3 | body: any, 4 | message: string 5 | } 6 | 7 | export interface errorResponse { 8 | status: number, 9 | message: string 10 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/.env: -------------------------------------------------------------------------------- 1 | # Environment 2 | NODE_ENV=development 3 | 4 | # Server 5 | PORT=3000 6 | HOST=localhost 7 | 8 | #Database 9 | DB_HOST=127.0.0.1 10 | DB_USERNAME=root 11 | DB_PASSWORD=root 12 | DB_NAME=test_db 13 | DB_PORT=5432 14 | -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/src/helpers/helper.interface.ts: -------------------------------------------------------------------------------- 1 | import { successResponse, errorResponse } from "./responseType"; 2 | 3 | export interface IHelper { 4 | createSuccessResponse(body:any): successResponse 5 | createErrorResponse(error:any): errorResponse 6 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/helpers/responseType.ts: -------------------------------------------------------------------------------- 1 | export interface successResponse { 2 | status: number, 3 | body: any, 4 | message: string 5 | } 6 | 7 | export interface errorResponse { 8 | status: number, 9 | message: string 10 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/src/helpers/helper.interface.ts: -------------------------------------------------------------------------------- 1 | import { successResponse, errorResponse } from "./responseType"; 2 | 3 | export interface IHelper { 4 | createSuccessResponse(body:any): successResponse 5 | createErrorResponse(error:any): errorResponse 6 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/helpers/helper.interface.ts: -------------------------------------------------------------------------------- 1 | import { successResponse, errorResponse } from "./responseType"; 2 | 3 | export interface IHelper { 4 | createSuccessResponse(body:any): successResponse 5 | createErrorResponse(error:any): errorResponse 6 | } -------------------------------------------------------------------------------- /src/templates/JavaScript/test/user.js: -------------------------------------------------------------------------------- 1 | const userService = require('../src/modules/user/userService') 2 | const { default: test } = require('ava'); 3 | 4 | test('test if user service works', async t => { 5 | let result = await userService.getUsers(); 6 | t.is(result, 'it works'); 7 | }); -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/test/user.ts: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import userService from '../src/modules/user/services/userService' 3 | 4 | test('check if random tests work', async t => { 5 | const result = await userService.getRandomTest(); 6 | t.is(result, 'it works'); 7 | }); -------------------------------------------------------------------------------- /src/templates/TypeScript/test/user.ts: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import userService from '../src/modules/user/services/userService' 3 | 4 | test('check if our random service works', async t => { 5 | const result = await userService.getRandomTest(); 6 | t.is(result, 'it works'); 7 | }); -------------------------------------------------------------------------------- /src/templateMapping.js: -------------------------------------------------------------------------------- 1 | exports.templateMapping = { 2 | js: 'JavaScript', 3 | jss: 'JavaScript-Sequelize', 4 | ts: 'TypeScript', 5 | tst: 'TypeScript-TypeORM', 6 | tsi: 'TypeScript-Inversify', 7 | tsti: 'TypeScript-TypeORM-Inversify', 8 | tsit: 'TypeScript-TypeORM-Inversify' 9 | } -------------------------------------------------------------------------------- /src/templates/JavaScript-Sequelize/test/user.js: -------------------------------------------------------------------------------- 1 | const userService = require('../src/modules/user/userService') 2 | const { default: test } = require('ava'); 3 | 4 | test('test if user service works', async t => { 5 | let result = await userService.getUsers(); 6 | t.is(result, 'it works'); 7 | }); -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint:recommended", 3 | "parserOptions": { 4 | "ecmaVersion": 2018, 5 | "ecmaFeatures": { 6 | "experimentalObjectRestSpread": true 7 | } 8 | }, 9 | "env": { 10 | "es6": true 11 | }, 12 | "rules": { 13 | "no-undef": "off" 14 | } 15 | } -------------------------------------------------------------------------------- /src/templates/JavaScript-Sequelize/.env: -------------------------------------------------------------------------------- 1 | # Environment 2 | NODE_ENV=development 3 | 4 | # Server 5 | PORT=3000 6 | HOST=localhost 7 | 8 | #Database 9 | DATABASE_NAME=test_db 10 | DATABASE_USER=root 11 | DATABASE_PASSWORD=admin 12 | DATABASE_HOST=127.0.0.1 13 | DATABASE_PORT=5432 14 | DATABASE_DIALECT=mysql 15 | LOGGER_PATH=logs -------------------------------------------------------------------------------- /src/templates/JavaScript/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint:recommended", 3 | "parserOptions": { 4 | "ecmaVersion": 2018, 5 | "ecmaFeatures": { 6 | "experimentalObjectRestSpread": true 7 | } 8 | }, 9 | "env": { 10 | "es6": true 11 | }, 12 | "rules": { 13 | "no-undef": "off" 14 | } 15 | } -------------------------------------------------------------------------------- /src/templates/JavaScript-Sequelize/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint:recommended", 3 | "parserOptions": { 4 | "ecmaVersion": 2018, 5 | "ecmaFeatures": { 6 | "experimentalObjectRestSpread": true 7 | } 8 | }, 9 | "env": { 10 | "es6": true 11 | }, 12 | "rules": { 13 | "no-undef": "off" 14 | } 15 | } -------------------------------------------------------------------------------- /src/templates/JavaScript/src/modules/route.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const { Router } = require('express'); 3 | const userRoute = require('./user/userRouter'); 4 | const router = Router(); 5 | 6 | const init = () => { 7 | // *** register routes here *** // 8 | router.use('/users', userRoute); 9 | return router; 10 | }; 11 | 12 | module.exports = {init}; -------------------------------------------------------------------------------- /src/templates/TypeScript/src/config/config.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from 'dotenv'; 2 | 3 | dotenv.config(); 4 | 5 | interface ConfigInterface { 6 | SERVER_PORT: string; 7 | NODE_ENV: string; 8 | } 9 | 10 | export const config: ConfigInterface = { 11 | SERVER_PORT: process.env.PORT || '', 12 | NODE_ENV: process.env.NODE_ENV || '' 13 | }; 14 | 15 | -------------------------------------------------------------------------------- /src/templates/JavaScript-Sequelize/src/modules/route.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const { Router } = require('express'); 3 | const userRoute = require('./user/userRouter'); 4 | const router = Router(); 5 | 6 | const init = () => { 7 | // *** register routes here *** // 8 | router.use('/users', userRoute); 9 | return router; 10 | }; 11 | 12 | module.exports = {init}; -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/src/config/config.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from 'dotenv'; 2 | 3 | dotenv.config(); 4 | 5 | interface ConfigInterface { 6 | SERVER_PORT: string; 7 | NODE_ENV: string; 8 | } 9 | 10 | export const config: ConfigInterface = { 11 | SERVER_PORT: process.env.PORT || '', 12 | NODE_ENV: process.env.NODE_ENV || '' 13 | }; 14 | 15 | -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/src/models/entities/Users.ts: -------------------------------------------------------------------------------- 1 | import { Column, Entity } from 'typeorm'; 2 | import { Base } from '../Base'; 3 | 4 | @Entity() 5 | export class User extends Base { 6 | @Column({ length: 250, name: "first_name", nullable: false }) 7 | firstName!: string; 8 | 9 | @Column({ length: 250, name: "last_name", nullable: true }) 10 | lastName!: string; 11 | } 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/models/entities/Users.ts: -------------------------------------------------------------------------------- 1 | import { Column, Entity } from 'typeorm'; 2 | import { Base } from '../Base'; 3 | 4 | @Entity() 5 | export class User extends Base { 6 | @Column({ length: 250, name: "first_name", nullable: false }) 7 | firstName!: string; 8 | 9 | @Column({ length: 250, name: "last_name", nullable: true }) 10 | lastName!: string; 11 | } 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/templates/TypeScript/src/modules/baseRouter.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { IRouter } from './router.interface'; 3 | import userRouter from './user/userRouter' 4 | 5 | // Init router 6 | const router = Router(); 7 | 8 | class BaseRouter implements IRouter{// eslint-disable-line 9 | get routes(){ 10 | router.use('/users', userRouter.routes); 11 | return router; 12 | } 13 | } 14 | 15 | export default new BaseRouter(); -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/src/models/Base.ts: -------------------------------------------------------------------------------- 1 | import { 2 | CreateDateColumn, 3 | PrimaryGeneratedColumn, 4 | UpdateDateColumn, 5 | } from "typeorm"; 6 | 7 | export abstract class Base { 8 | @PrimaryGeneratedColumn("uuid") 9 | id!: string; 10 | 11 | @CreateDateColumn({ name: "created_at" }) 12 | createdAt!: Date; 13 | 14 | @UpdateDateColumn({ name: "updated_at", select: false }) 15 | updatedAt!: Date; 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/src/modules/baseRouter.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { IRouter } from './router.interface'; 3 | import userRouter from './user/userRouter' 4 | 5 | // Init router 6 | const router = Router(); 7 | 8 | class BaseRouter implements IRouter{// eslint-disable-line 9 | get routes(){ 10 | router.use('/users', userRouter.routes); 11 | return router; 12 | } 13 | } 14 | 15 | export default new BaseRouter(); -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/models/Base.ts: -------------------------------------------------------------------------------- 1 | import { 2 | CreateDateColumn, 3 | PrimaryGeneratedColumn, 4 | UpdateDateColumn, 5 | } from "typeorm"; 6 | 7 | export abstract class Base { 8 | @PrimaryGeneratedColumn("uuid") 9 | id!: string; 10 | 11 | @CreateDateColumn({ name: "created_at" }) 12 | createdAt!: Date; 13 | 14 | @UpdateDateColumn({ name: "updated_at", select: false }) 15 | updatedAt!: Date; 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/templates/JavaScript-Sequelize/src/models/user.js: -------------------------------------------------------------------------------- 1 | 2 | const { DataTypes } = require('sequelize'); 3 | const sequelize = require('./index') 4 | 5 | const User = sequelize.define('User', { 6 | // Model attributes are defined here 7 | firstName: { 8 | type: DataTypes.STRING, 9 | allowNull: false 10 | }, 11 | lastName: { 12 | type: DataTypes.STRING 13 | // allowNull defaults to true 14 | } 15 | }, { 16 | // Other model options go here 17 | }); 18 | 19 | module.exports = User; -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/src/container.ts: -------------------------------------------------------------------------------- 1 | import './config/ioc'; 2 | 3 | import { Container } from 'inversify'; 4 | import { buildProviderModule } from 'inversify-binding-decorators'; 5 | 6 | class ContainerData { 7 | container: Container; 8 | 9 | constructor() { 10 | this.container = new Container(); 11 | this.container.load(buildProviderModule()); 12 | } 13 | 14 | get getContainer() { 15 | return this.container; 16 | } 17 | } 18 | 19 | export const receptacle = new ContainerData(); 20 | -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/container.ts: -------------------------------------------------------------------------------- 1 | import './config/ioc'; 2 | 3 | import { Container } from 'inversify'; 4 | import { buildProviderModule } from 'inversify-binding-decorators'; 5 | 6 | class ContainerData { 7 | container: Container; 8 | 9 | constructor() { 10 | this.container = new Container(); 11 | this.container.load(buildProviderModule()); 12 | } 13 | 14 | get getContainer() { 15 | return this.container; 16 | } 17 | } 18 | 19 | export const receptacle = new ContainerData(); 20 | -------------------------------------------------------------------------------- /src/templates/JavaScript/src/modules/user/userRouter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const router = require('express').Router(); 4 | const userService = require("./userService"); 5 | 6 | /* GET max no: of strings. */ 7 | router.get('/', async function (req, res) { 8 | try { 9 | //refirect to service 10 | const response = await userService.getUsers(); 11 | res.send(response); 12 | } catch (error) { 13 | res.status(error.status || 500).send(error); 14 | } 15 | }); 16 | 17 | module.exports = router; -------------------------------------------------------------------------------- /src/templates/JavaScript-Sequelize/src/config/config.js: -------------------------------------------------------------------------------- 1 | const dotenv = require('dotenv'); 2 | dotenv.config(); 3 | module.exports = { 4 | SERVER_PORT: process.env.PORT || '', 5 | NODE_ENV: process.env.NODE_ENV || '', 6 | DATABASE_NAME: process.env.DATABASE_NAME, 7 | DATABASE_USER: process.env.DATABASE_USER, 8 | DATABASE_PASSWORD: process.env.DATABASE_PASSWORD, 9 | DATABASE_HOST: process.env.DATABASE_HOST, 10 | DATABASE_PORT: process.env.DATABASE_PORT, 11 | DATABASE_DIALECT: process.env.DATABASE_DIALECT || 'mysql' 12 | }; 13 | -------------------------------------------------------------------------------- /src/templates/JavaScript-Sequelize/src/modules/user/userRouter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const router = require('express').Router(), 4 | userService = require("./userService"); 5 | 6 | /* GET max no: of strings. */ 7 | router.get('/', async function (req, res) { 8 | try { 9 | //refirect to service 10 | const response = await userService.getUsers(); 11 | res.send(response); 12 | } catch (error) { 13 | res.status(error.status || 500).send(error); 14 | } 15 | }); 16 | 17 | module.exports = router; -------------------------------------------------------------------------------- /src/templates/TypeScript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "esModuleInterop": true, 5 | "target": "es6", 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "noImplicitAny": true, 9 | "moduleResolution": "node", 10 | "resolveJsonModule": true, 11 | "sourceMap": true, 12 | "outDir": "dist", 13 | "baseUrl": "." 14 | }, 15 | "include": [ 16 | "src", 17 | "test" 18 | ], 19 | "exclude": [ 20 | "node_modules" 21 | ] 22 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "esModuleInterop": true, 5 | "target": "es6", 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "noImplicitAny": true, 9 | "moduleResolution": "node", 10 | "resolveJsonModule": true, 11 | "sourceMap": true, 12 | "outDir": "dist", 13 | "baseUrl": "." 14 | }, 15 | "include": [ 16 | "src", 17 | "test" 18 | ], 19 | "exclude": [ 20 | "node_modules" 21 | ] 22 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "esModuleInterop": true, 5 | "target": "es6", 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "noImplicitAny": true, 9 | "moduleResolution": "node", 10 | "resolveJsonModule": true, 11 | "sourceMap": true, 12 | "outDir": "dist", 13 | "baseUrl": "." 14 | }, 15 | "include": [ 16 | "src", 17 | "test" 18 | ], 19 | "exclude": [ 20 | "node_modules" 21 | ] 22 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "esModuleInterop": true, 5 | "target": "es6", 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "noImplicitAny": true, 9 | "moduleResolution": "node", 10 | "resolveJsonModule": true, 11 | "sourceMap": true, 12 | "outDir": "dist", 13 | "baseUrl": "." 14 | }, 15 | "include": [ 16 | "src", 17 | "test" 18 | ], 19 | "exclude": [ 20 | "node_modules" 21 | ] 22 | } -------------------------------------------------------------------------------- /src/templates/TypeScript/src/modules/user/services/userService.ts: -------------------------------------------------------------------------------- 1 | import { IUserService } from "./userService.interface"; 2 | import { logger } from '../../../helpers/logger' 3 | 4 | class UserService implements IUserService {// eslint-disable-line 5 | 6 | async getRandomTest(): Promise { 7 | try { 8 | logger.info("success") 9 | return "it works"; 10 | } catch (error) { 11 | logger.error(error) 12 | return error; 13 | } 14 | } 15 | } 16 | 17 | export default new UserService(); -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | 2 | name: build 3 | on: 4 | - push 5 | - pull_request 6 | jobs: 7 | test: 8 | name: Node.js ${{ matrix.node-version }} 9 | runs-on: ubuntu-latest 10 | strategy: 11 | fail-fast: false 12 | matrix: 13 | node-version: 14 | - 14 15 | - 16 16 | - 18 17 | steps: 18 | - uses: actions/checkout@v3.2.0 19 | - uses: actions/setup-node@v3.5.1 20 | with: 21 | node-version: ${{ matrix.node-version }} 22 | - run: npm install 23 | - run: npm test -------------------------------------------------------------------------------- /src/templates/JavaScript/src/modules/user/userService.js: -------------------------------------------------------------------------------- 1 | const { logger } = require('../../helpers/logger'); 2 | 3 | class userManager { 4 | async getUsers() { 5 | // eslint-disable-next-line no-useless-catch 6 | try { 7 | //logic here 8 | logger.info("success"); 9 | return "it works"; 10 | // eslint-disable-next-line no-unreachable 11 | } catch (error) { 12 | logger.error(error); 13 | throw error; 14 | } 15 | } 16 | } 17 | 18 | module.exports = new userManager(); 19 | -------------------------------------------------------------------------------- /test/create.js: -------------------------------------------------------------------------------- 1 | const create = require('../src/create'); 2 | const test = require('ava'); 3 | const fs = require('fs'); 4 | 5 | test('Check if folder is created', t => { 6 | create.createProject('testDir1') 7 | t.throws(() => { 8 | create.createProject('testDir1') 9 | }); 10 | }) 11 | 12 | test('Check if copying works', t => { 13 | create.createProject('testDir2'); 14 | t.notThrows(() => { 15 | create.createDirectoryContents('testDir1','testDir2') 16 | }) 17 | }) 18 | 19 | test.after(() => { 20 | fs.rmdirSync('testDir1'); 21 | fs.rmdirSync('testDir2'); 22 | }) 23 | -------------------------------------------------------------------------------- /src/templates/JavaScript-Sequelize/src/models/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const Sequelize = require('sequelize'); 3 | // eslint-disable-next-line no-unused-vars 4 | const env = process.env.NODE_ENV || 'development'; 5 | const config = require('../config/config'); 6 | 7 | const sequelize = new Sequelize(config.DATABASE_NAME, 8 | config.DATABASE_USER, 9 | config.DATABASE_PASSWORD, { 10 | host: config.DATABASE_HOST, 11 | port: config.DATABASE_PORT, 12 | logging: false, 13 | dialect: config.DATABASE_DIALECT, 14 | pool: { 15 | max: 5, 16 | acquire: 30000, 17 | idle: 10000, 18 | }, 19 | }); 20 | 21 | module.exports = sequelize; -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/src/modules/baseRouter.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { inject } from 'inversify'; 3 | import { USERROUTE, BASEROUTE } from '../const/types'; 4 | import { IRouter } from './router.interface'; 5 | import { provide } from 'inversify-binding-decorators'; 6 | 7 | // Init router 8 | const router = Router(); 9 | 10 | //Inject all new routes here and use them 11 | @provide(BASEROUTE) 12 | class BaseRouter implements IRouter{// eslint-disable-line 13 | @inject(USERROUTE) userRouter!: IRouter; 14 | 15 | get routes(){ 16 | router.use('/users', this.userRouter.routes); 17 | return router; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/modules/baseRouter.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { inject } from 'inversify'; 3 | import { USERROUTE, BASEROUTE } from '../const/types'; 4 | import { IRouter } from './router.interface'; 5 | import { provide } from 'inversify-binding-decorators'; 6 | 7 | // Init router 8 | const router = Router(); 9 | 10 | //Inject all new routes here and use them 11 | @provide(BASEROUTE) 12 | class BaseRouter implements IRouter{// eslint-disable-line 13 | @inject(USERROUTE) userRouter!: IRouter; 14 | 15 | get routes(){ 16 | router.use('/users', this.userRouter.routes); 17 | return router; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/templates/TypeScript/src/helpers/logger.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Setup the winston logger. 3 | * 4 | * Documentation: https://github.com/winstonjs/winston 5 | */ 6 | 7 | import { createLogger, format, transports } from 'winston'; 8 | 9 | export const logger = createLogger({ 10 | level: 'info', 11 | format: format.json(), 12 | transports: [ 13 | // 14 | // - Write to all logs with level `info` and below to `combined.log` 15 | // - Write all logs error (and below) to `error.log`. 16 | // 17 | new transports.File({ filename: 'error.log', level: 'error' }), 18 | new transports.File({ filename: 'combined.log' }) 19 | ] 20 | }); -------------------------------------------------------------------------------- /src/templates/JavaScript/src/helpers/logger.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Setup the winston logger. 3 | * 4 | * Documentation: https://github.com/winstonjs/winston 5 | */ 6 | 7 | const { createLogger, format, transports } = require('winston'); 8 | 9 | module.exports.logger = createLogger({ 10 | level: 'info', 11 | format: format.json(), 12 | transports: [ 13 | // 14 | // - Write to all logs with level `info` and below to `combined.log` 15 | // - Write all logs error (and below) to `error.log`. 16 | // 17 | new transports.File({ filename: 'error.log', level: 'error' }), 18 | new transports.File({ filename: 'combined.log' }) 19 | ] 20 | }); -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/src/helpers/logger.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Setup the winston logger. 3 | * 4 | * Documentation: https://github.com/winstonjs/winston 5 | */ 6 | 7 | import { createLogger, format, transports } from 'winston'; 8 | 9 | export const logger = createLogger({ 10 | level: 'info', 11 | format: format.json(), 12 | transports: [ 13 | // 14 | // - Write to all logs with level `info` and below to `combined.log` 15 | // - Write all logs error (and below) to `error.log`. 16 | // 17 | new transports.File({ filename: 'error.log', level: 'error' }), 18 | new transports.File({ filename: 'combined.log' }) 19 | ] 20 | }); -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/src/helpers/logger.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Setup the winston logger. 3 | * 4 | * Documentation: https://github.com/winstonjs/winston 5 | */ 6 | 7 | import { createLogger, format, transports } from 'winston'; 8 | 9 | export const logger = createLogger({ 10 | level: 'info', 11 | format: format.json(), 12 | transports: [ 13 | // 14 | // - Write to all logs with level `info` and below to `combined.log` 15 | // - Write all logs error (and below) to `error.log`. 16 | // 17 | new transports.File({ filename: 'error.log', level: 'error' }), 18 | new transports.File({ filename: 'combined.log' }) 19 | ] 20 | }); -------------------------------------------------------------------------------- /src/templates/JavaScript-Sequelize/src/helpers/logger.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Setup the winston logger. 3 | * 4 | * Documentation: https://github.com/winstonjs/winston 5 | */ 6 | 7 | const { createLogger, format, transports } = require('winston'); 8 | 9 | module.exports.logger = createLogger({ 10 | level: 'info', 11 | format: format.json(), 12 | transports: [ 13 | // 14 | // - Write to all logs with level `info` and below to `combined.log` 15 | // - Write all logs error (and below) to `error.log`. 16 | // 17 | new transports.File({ filename: 'error.log', level: 'error' }), 18 | new transports.File({ filename: 'combined.log' }) 19 | ] 20 | }); -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/src/modules/user/services/userService.ts: -------------------------------------------------------------------------------- 1 | import { USERSERVICE } from '../../../const/types'; 2 | import { provide } from "inversify-binding-decorators"; 3 | import { IUserService } from "./userService.interface"; 4 | import { logger } from '../../../helpers/logger'; 5 | 6 | @provide(USERSERVICE) 7 | class UserService implements IUserService{// eslint-disable-line 8 | 9 | async getRandomTest(): Promise { 10 | try { 11 | //logic here 12 | logger.info("success") 13 | return "it works"; 14 | } catch (error) { 15 | logger.info(error) 16 | return error; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/helpers/logger.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Setup the winston logger. 3 | * 4 | * Documentation: https://github.com/winstonjs/winston 5 | */ 6 | 7 | import { createLogger, format, transports } from 'winston'; 8 | 9 | export const logger = createLogger({ 10 | level: 'info', 11 | format: format.json(), 12 | transports: [ 13 | // 14 | // - Write to all logs with level `info` and below to `combined.log` 15 | // - Write all logs error (and below) to `error.log`. 16 | // 17 | new transports.File({ filename: 'error.log', level: 'error' }), 18 | new transports.File({ filename: 'combined.log' }) 19 | ] 20 | }); -------------------------------------------------------------------------------- /src/templates/JavaScript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "javascript-boilerplate", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "lint": "eslint src/**/*.js", 8 | "start": "npm run lint && node src/index.js", 9 | "test": "ava" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "body-parser": "^1.19.0", 15 | "cors": "^2.8.5", 16 | "dotenv": "^10.0.0", 17 | "express": "^4.17.1", 18 | "winston": "^3.3.3" 19 | }, 20 | "devDependencies": { 21 | "eslint": "^7.32.0", 22 | "ava": "^3.15.0" 23 | }, 24 | "ava": { 25 | "files": [ 26 | "test/*" 27 | ], 28 | "timeout": "1m" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We welcome patches and features. For any new features added, please make sure we add a unit test to it. 4 | 5 | ## How to setup a local copy 6 | 7 | Clone the project, run `npm i` and then `npm link` to setup a local copy which you can change. This is helpful so that you can work on it and test it iteratively without having to continually rebuild. 8 | 9 | ## How to improve available templates 10 | 11 | In case you feel like any of the templates could use any extra features, raise an issue first before you raise a PR. We can discuss any ideas and which would be the right way to implement. 12 | 13 | ## Running test cases 14 | 15 | Make sure your PR passes all the tests by running `npm test` before raising a PR. 16 | -------------------------------------------------------------------------------- /src/templates/TypeScript/src/modules/user/userRouter.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response, Router } from 'express'; 2 | import { IRouter } from '../router.interface'; 3 | import userService from './services/userService' 4 | const router = Router(); 5 | 6 | class UserRouter implements IRouter{// eslint-disable-line 7 | get routes(){ 8 | router.get('/', async (req: Request, res: Response) => { 9 | // eslint-disable-next-line no-useless-catch 10 | try { 11 | const quote = await userService.getRandomTest(); 12 | return res.send(quote); 13 | } catch (err) { 14 | throw err; 15 | } 16 | }); 17 | return router; 18 | } 19 | } 20 | 21 | export default new UserRouter(); -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/src/modules/user/userRouter.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response, Router } from 'express'; 2 | import { IRouter } from '../router.interface'; 3 | import userService from './services/userService' 4 | const router = Router(); 5 | 6 | class UserRouter implements IRouter{// eslint-disable-line 7 | get routes(){ 8 | router.get('/', async (req: Request, res: Response) => { 9 | // eslint-disable-next-line no-useless-catch 10 | try { 11 | const quote = await userService.getRandomTest(); 12 | return res.send(quote); 13 | } catch (err) { 14 | throw err; 15 | } 16 | }); 17 | return router; 18 | } 19 | } 20 | 21 | export default new UserRouter(); -------------------------------------------------------------------------------- /src/templates/JavaScript-Sequelize/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "javascript-sequelize", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "lint": "eslint src/**/*.js", 8 | "start": "npm run lint && node src/index.js", 9 | "test": "ava" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "body-parser": "^1.19.0", 15 | "cors": "^2.8.5", 16 | "dotenv": "^10.0.0", 17 | "express": "^4.17.1", 18 | "mysql2": "^2.3.0", 19 | "sequelize": "^6.6.5", 20 | "winston": "^3.3.3" 21 | }, 22 | "devDependencies": { 23 | "eslint": "^7.32.0", 24 | "ava": "^3.15.0" 25 | }, 26 | "ava": { 27 | "files": [ 28 | "test/*" 29 | ], 30 | "timeout": "1m" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/templates/TypeScript/src/server/app.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import cors from 'cors'; 3 | import { ServerInterface } from './app.interface'; 4 | import baseRouter from '../modules/baseRouter' 5 | 6 | class Server implements ServerInterface {// eslint-disable-line 7 | 8 | async server(): Promise { 9 | const app = express(); 10 | app.use(express.json()); 11 | app.use(express.urlencoded({ extended: true })); 12 | app.use('/api/v1', baseRouter.routes);//setting up base route 13 | // define a route handler for the default home page 14 | app.get("/", (req, res) => { 15 | res.send("Welcome to express-create application! "); 16 | }); 17 | app.use(cors()); 18 | return app; 19 | } 20 | } 21 | 22 | export default new Server(); 23 | -------------------------------------------------------------------------------- /src/templates/JavaScript-Sequelize/src/modules/user/userService.js: -------------------------------------------------------------------------------- 1 | //Uncomment the code in this file to see sequelize at work 2 | // const User = require('../../models/user') 3 | const { logger } = require('../../helpers/logger'); 4 | 5 | class userManager { 6 | async getUsers() { 7 | // eslint-disable-next-line no-useless-catch 8 | try { 9 | //logic here 10 | // const jane = await User.create({ id: 1, firstName: "Jane" }); 11 | // return jane; 12 | logger.info("success"); 13 | return "it works"; 14 | // eslint-disable-next-line no-unreachable 15 | } catch (error) { 16 | logger.error(error); 17 | throw error; 18 | } 19 | } 20 | } 21 | 22 | module.exports = new userManager(); 23 | -------------------------------------------------------------------------------- /src/templates/TypeScript/src/helpers/helper.ts: -------------------------------------------------------------------------------- 1 | import { IHelper } from "./helper.interface"; 2 | import { successResponse, errorResponse } from './responseType' 3 | 4 | class Helper implements IHelper {// eslint-disable-line 5 | createSuccessResponse(body: any): successResponse { 6 | const response: successResponse = { 7 | status: body.status || 200, 8 | body: body.body || {}, 9 | message: body.message || 'Operation Completed Successfully' 10 | } 11 | return response 12 | } 13 | createErrorResponse(error: any): errorResponse { 14 | const response: errorResponse = { 15 | status: error.status || 500, 16 | message: error.message || 'Internal Server Error' 17 | } 18 | return response 19 | } 20 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/src/helpers/helper.ts: -------------------------------------------------------------------------------- 1 | import { IHelper } from "./helper.interface"; 2 | import { successResponse, errorResponse } from './responseType' 3 | 4 | class Helper implements IHelper {// eslint-disable-line 5 | createSuccessResponse(body: any): successResponse { 6 | const response: successResponse = { 7 | status: body.status || 200, 8 | body: body.body || {}, 9 | message: body.message || 'Operation Completed Successfully' 10 | } 11 | return response 12 | } 13 | createErrorResponse(error: any): errorResponse { 14 | const response: errorResponse = { 15 | status: error.status || 500, 16 | message: error.message || 'Internal Server Error' 17 | } 18 | return response 19 | } 20 | } -------------------------------------------------------------------------------- /src/templates/TypeScript/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: "eslint:recommended", 3 | parser: "@typescript-eslint/parser", // Specifies the ESLint parser 4 | parserOptions: { 5 | ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features 6 | sourceType: "module" // Allows for the use of imports 7 | }, 8 | extends: [ 9 | "plugin:@typescript-eslint/recommended" // Uses the recommended rules from the @typescript-eslint/eslint-plugin 10 | ], 11 | rules: { 12 | // Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs 13 | // e.g. "@typescript-eslint/explicit-function-return-type": "off", 14 | "@typescript-eslint/no-explicit-any": "off", 15 | "@typescript-eslint/explicit-module-boundary-types": "off" 16 | } 17 | }; -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: "eslint:recommended", 3 | parser: "@typescript-eslint/parser", // Specifies the ESLint parser 4 | parserOptions: { 5 | ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features 6 | sourceType: "module" // Allows for the use of imports 7 | }, 8 | extends: [ 9 | "plugin:@typescript-eslint/recommended" // Uses the recommended rules from the @typescript-eslint/eslint-plugin 10 | ], 11 | rules: { 12 | // Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs 13 | // e.g. "@typescript-eslint/explicit-function-return-type": "off", 14 | "@typescript-eslint/no-explicit-any": "off", 15 | "@typescript-eslint/explicit-module-boundary-types": "off" 16 | } 17 | }; -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: "eslint:recommended", 3 | parser: "@typescript-eslint/parser", // Specifies the ESLint parser 4 | parserOptions: { 5 | ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features 6 | sourceType: "module" // Allows for the use of imports 7 | }, 8 | extends: [ 9 | "plugin:@typescript-eslint/recommended" // Uses the recommended rules from the @typescript-eslint/eslint-plugin 10 | ], 11 | rules: { 12 | // Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs 13 | // e.g. "@typescript-eslint/explicit-function-return-type": "off", 14 | "@typescript-eslint/no-explicit-any": "off", 15 | "@typescript-eslint/explicit-module-boundary-types": "off" 16 | } 17 | }; -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: "eslint:recommended", 3 | parser: "@typescript-eslint/parser", // Specifies the ESLint parser 4 | parserOptions: { 5 | ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features 6 | sourceType: "module" // Allows for the use of imports 7 | }, 8 | extends: [ 9 | "plugin:@typescript-eslint/recommended" // Uses the recommended rules from the @typescript-eslint/eslint-plugin 10 | ], 11 | rules: { 12 | // Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs 13 | // e.g. "@typescript-eslint/explicit-function-return-type": "off", 14 | "@typescript-eslint/no-explicit-any": "off", 15 | "@typescript-eslint/explicit-module-boundary-types": "off" 16 | } 17 | }; -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const util = require('./util'); 3 | const create = require('./create') 4 | const logSymbols = require('log-symbols') 5 | 6 | module.exports = async (input) => { 7 | const CURR_DIR = process.cwd(); 8 | const templatePath = path.join(__dirname, 'templates', input.template); 9 | const targetPath = path.join(CURR_DIR, input.destinationFolder); 10 | if (create.createProject(targetPath)) { 11 | create.createDirectoryContents(templatePath, input.destinationFolder); 12 | } 13 | console.log(`\n${logSymbols.success} Created template`); 14 | console.log(`Installing dependecies using ${input.pkgManager}...`); 15 | util.editPackageJson(`${targetPath}/package.json`, input.destinationFolder); 16 | await util.installNodeModules(input.pkgManager, targetPath); 17 | return; 18 | } 19 | -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/src/server/app.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import cors from 'cors'; 3 | import { ServerInterface } from './app.interface'; 4 | import { connectToDatabase } from '../config/db'; 5 | import baseRouter from '../modules/baseRouter' 6 | 7 | class Server implements ServerInterface {// eslint-disable-line 8 | constructor(){ 9 | connectToDatabase() 10 | } 11 | 12 | async server(): Promise { 13 | const app = express(); 14 | app.use(express.json()); 15 | app.use(express.urlencoded({ extended: true })); 16 | app.use('/api/v1', baseRouter.routes);//setting up base route 17 | // define a route handler for the default home page 18 | app.get("/", (req, res) => { 19 | res.send("Welcome to express-create application! "); 20 | }); 21 | app.use(cors()); 22 | return app; 23 | } 24 | } 25 | 26 | export default new Server(); 27 | -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/src/config/db.ts: -------------------------------------------------------------------------------- 1 | import { createConnection } from 'typeorm'; 2 | import { config } from './config'; 3 | import { logger } from '../helpers/logger'; 4 | 5 | export async function connectToDatabase() { 6 | try { 7 | const connections = await createConnection({ 8 | type: config.TYPEORM_CONNECTION, 9 | host: config.DB_HOST, 10 | port: config.DB_PORT, 11 | username: config.DB_USERNAME, 12 | password: config.DB_PASSWORD, 13 | database: config.DB_NAME, 14 | entities: [ 15 | __dirname + '/../models/entities/*.*' 16 | ], 17 | synchronize: true, 18 | logging: config.TYPEORM_DEBUG_MODE 19 | }); 20 | return connections; 21 | } catch (err) { 22 | console.log(err); 23 | logger.error(err.message); 24 | throw err; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/templates/TypeScript/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Environment } from './config/environment'; 2 | import server from './server/app'; 3 | import { logger } from './helpers/logger' 4 | /** 5 | * Setuping environment variables 6 | */ 7 | Environment.setup(); 8 | 9 | import { Application } from 'express'; 10 | 11 | import { config } from './config/config'; 12 | 13 | async function startServer() { 14 | const app: Application = await server.server(); 15 | app.listen(config.SERVER_PORT, () => { 16 | console.log(`Listening on port ${config.SERVER_PORT} in ${config.NODE_ENV} mode`); 17 | logger.info(`Listening on port ${config.SERVER_PORT} in ${config.NODE_ENV} mode`); 18 | }); 19 | } 20 | 21 | startServer(); 22 | 23 | process.on("uncaughtException", e => { 24 | console.log(e); 25 | process.exit(1); 26 | }); 27 | 28 | process.on("unhandledRejection", e => { 29 | console.log(e); 30 | process.exit(1); 31 | }); -------------------------------------------------------------------------------- /src/util.js: -------------------------------------------------------------------------------- 1 | const templates = require('./templateMapping').templateMapping; 2 | const editJsonFile = require("edit-json-file"); 3 | const exec = require('execa'); 4 | 5 | exports.isValidTemplate = (template, choices) => { 6 | if (choices.includes(template)) { 7 | return template; 8 | } else { 9 | if (templates[template]) { 10 | return templates[template]; 11 | } else { 12 | throw new Error(`Template ${template} does not exist. Please input a valid template or select from list`) 13 | } 14 | } 15 | } 16 | 17 | exports.editPackageJson = (path, projectName) => { 18 | let file = editJsonFile(path, {autosave:true}); 19 | file.set("name", projectName); 20 | return; 21 | } 22 | 23 | exports.installNodeModules = async (pkgManager, path) => { 24 | const result = await exec(pkgManager, ['install'], 25 | { cwd: path, stdio:"inherit" }); 26 | return result; 27 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/src/helpers/helper.ts: -------------------------------------------------------------------------------- 1 | import { IHelper } from "./helper.interface"; 2 | import { successResponse, errorResponse } from './responseType' 3 | import { provide } from "inversify-binding-decorators"; 4 | import { HELPER } from "../const/types"; 5 | 6 | @provide(HELPER) 7 | class Helper implements IHelper {// eslint-disable-line 8 | createSuccessResponse(body: any): successResponse { 9 | const response: successResponse = { 10 | status: body.status || 200, 11 | body: body.body || {}, 12 | message: body.message || 'Operation Completed Successfully' 13 | } 14 | return response 15 | } 16 | createErrorResponse(error: any): errorResponse { 17 | const response: errorResponse = { 18 | status: error.status || 500, 19 | message: error.message || 'Internal Server Error' 20 | } 21 | return response 22 | } 23 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/config/db.ts: -------------------------------------------------------------------------------- 1 | import { createConnection } from 'typeorm'; 2 | import { config } from './config'; 3 | import { logger } from '../helpers/logger'; 4 | 5 | export async function connectToDatabase() { 6 | try { 7 | const connections = await createConnection({ 8 | type: config.TYPEORM_CONNECTION, 9 | host: config.DB_HOST, 10 | port: config.DB_PORT, 11 | username: config.DB_USERNAME, 12 | password: config.DB_PASSWORD, 13 | database: config.DB_NAME, 14 | entities: [ 15 | __dirname + '/../models/entities/*.*' 16 | ], 17 | synchronize: true, 18 | logging: config.TYPEORM_DEBUG_MODE 19 | }); 20 | return connections; 21 | } catch (err) { 22 | console.log(err); 23 | logger.error(err.message); 24 | throw err; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/helpers/helper.ts: -------------------------------------------------------------------------------- 1 | import { IHelper } from "./helper.interface"; 2 | import { successResponse, errorResponse } from './responseType' 3 | import { provide } from "inversify-binding-decorators"; 4 | import { HELPER } from "../const/types"; 5 | 6 | @provide(HELPER) 7 | class Helper implements IHelper {// eslint-disable-line 8 | createSuccessResponse(body: any): successResponse { 9 | const response: successResponse = { 10 | status: body.status || 200, 11 | body: body.body || {}, 12 | message: body.message || 'Operation Completed Successfully' 13 | } 14 | return response 15 | } 16 | createErrorResponse(error: any): errorResponse { 17 | const response: errorResponse = { 18 | status: error.status || 500, 19 | message: error.message || 'Internal Server Error' 20 | } 21 | return response 22 | } 23 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Environment } from './config/environment'; 2 | import server from './server/app' 3 | import { logger } from './helpers/logger' 4 | /** 5 | * Setuping environment variables 6 | */ 7 | Environment.setup(); 8 | import 'reflect-metadata'; 9 | 10 | import { Application } from 'express'; 11 | 12 | import { config } from './config/config'; 13 | 14 | async function startServer() { 15 | const app: Application = await server.server(); 16 | app.listen(config.SERVER_PORT, () => { 17 | console.log(`Listening on port ${config.SERVER_PORT} in ${config.NODE_ENV} mode`); 18 | logger.info(`Listening on port ${config.SERVER_PORT} in ${config.NODE_ENV} mode`); 19 | }); 20 | } 21 | 22 | startServer(); 23 | 24 | process.on("uncaughtException", e => { 25 | console.log(e); 26 | process.exit(1); 27 | }); 28 | 29 | process.on("unhandledRejection", e => { 30 | console.log(e); 31 | process.exit(1); 32 | }); -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/src/config/config.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from 'dotenv'; 2 | 3 | dotenv.config(); 4 | 5 | interface ConfigInterface { 6 | SERVER_PORT: string; 7 | NODE_ENV: string; 8 | DB_HOST: string; 9 | DB_USERNAME: string; 10 | DB_PASSWORD: string; 11 | DB_NAME: string; 12 | DB_PORT: number; 13 | TYPEORM_CONNECTION: any; 14 | TYPEORM_DEBUG_MODE: any; 15 | } 16 | 17 | export const config: ConfigInterface = { 18 | SERVER_PORT: process.env.PORT || '', 19 | NODE_ENV: process.env.NODE_ENV || '', 20 | DB_HOST: process.env.DB_HOST || '', 21 | DB_USERNAME: process.env.DB_USERNAME || '', 22 | DB_PASSWORD: process.env.DB_PASSWORD || '', 23 | DB_NAME: process.env.DB_NAME || '', 24 | DB_PORT: process.env.DB_PORT 25 | ? Number(process.env.DB_PORT) 26 | : 3306, 27 | TYPEORM_CONNECTION: 'mysql', 28 | TYPEORM_DEBUG_MODE: process.env.TYPEORM_DEBUG_MODE ? JSON.parse(process.env.TYPEORM_DEBUG_MODE) : false 29 | }; 30 | 31 | -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/config/config.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from 'dotenv'; 2 | 3 | dotenv.config(); 4 | 5 | interface ConfigInterface { 6 | SERVER_PORT: string; 7 | NODE_ENV: string; 8 | DB_HOST: string; 9 | DB_USERNAME: string; 10 | DB_PASSWORD: string; 11 | DB_NAME: string; 12 | DB_PORT: number; 13 | TYPEORM_CONNECTION: any; 14 | TYPEORM_DEBUG_MODE: any; 15 | } 16 | 17 | export const config: ConfigInterface = { 18 | SERVER_PORT: process.env.PORT || '', 19 | NODE_ENV: process.env.NODE_ENV || '', 20 | DB_HOST: process.env.DB_HOST || '', 21 | DB_USERNAME: process.env.DB_USERNAME || '', 22 | DB_PASSWORD: process.env.DB_PASSWORD || '', 23 | DB_NAME: process.env.DB_NAME || '', 24 | DB_PORT: process.env.DB_PORT 25 | ? Number(process.env.DB_PORT) 26 | : 3306, 27 | TYPEORM_CONNECTION: 'mysql', 28 | TYPEORM_DEBUG_MODE: process.env.TYPEORM_DEBUG_MODE ? JSON.parse(process.env.TYPEORM_DEBUG_MODE) : false 29 | }; 30 | 31 | -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/src/modules/user/services/userService.ts: -------------------------------------------------------------------------------- 1 | //Uncomment the code in this file to see typeorm in work 2 | 3 | import { IUserService } from "./userService.interface"; 4 | import { logger } from '../../../helpers/logger' 5 | // import { User } from "../../../models/entities/Users"; 6 | // import { EntityManager, getManager } from "typeorm"; 7 | 8 | class UserService implements IUserService {// eslint-disable-line 9 | 10 | // private manager: EntityManager; 11 | // constructor() { 12 | // this.manager = getManager(); 13 | // } 14 | 15 | async getRandomTest(): Promise { 16 | try { 17 | // const user = new User(); 18 | // user.firstName = "Test" 19 | // this.manager.save(user); 20 | logger.info("success") 21 | return "it works"; 22 | } catch (error) { 23 | logger.error(error); 24 | return error; 25 | } 26 | } 27 | } 28 | 29 | export default new UserService(); -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/src/modules/user/userRouter.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response, Router } from 'express'; 2 | import { IRouter } from '../router.interface'; 3 | import { provide } from 'inversify-binding-decorators'; 4 | import { USERROUTE, USERSERVICE } from '../../const/types'; 5 | import { inject } from 'inversify'; 6 | import { IUserService } from './services/userService.interface'; 7 | 8 | const router = Router(); 9 | 10 | @provide(USERROUTE) 11 | class UserRouter implements IRouter{// eslint-disable-line 12 | @inject(USERSERVICE) private userService! : IUserService 13 | 14 | get routes(){ 15 | router.get('/', async (req: Request, res: Response) => { 16 | // eslint-disable-next-line no-useless-catch 17 | try { 18 | const quote = await this.userService.getRandomTest(); 19 | return res.send(quote); 20 | } catch (err) { 21 | throw err; 22 | } 23 | }); 24 | return router; 25 | } 26 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/modules/user/userRouter.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response, Router } from 'express'; 2 | import { IRouter } from '../router.interface'; 3 | import { provide } from 'inversify-binding-decorators'; 4 | import { USERROUTE, USERSERVICE } from '../../const/types'; 5 | import { inject } from 'inversify'; 6 | import { IUserService } from './services/userService.interface'; 7 | 8 | const router = Router(); 9 | 10 | @provide(USERROUTE) 11 | class UserRouter implements IRouter{// eslint-disable-line 12 | @inject(USERSERVICE) private userService! : IUserService 13 | 14 | get routes(){ 15 | router.get('/', async (req: Request, res: Response) => { 16 | // eslint-disable-next-line no-useless-catch 17 | try { 18 | const quote = await this.userService.getRandomTest(); 19 | return res.send(quote); 20 | } catch (err) { 21 | throw err; 22 | } 23 | }); 24 | return router; 25 | } 26 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/src/server/app.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | import express from 'express'; 3 | import { inject } from 'inversify'; 4 | import { provide } from 'inversify-binding-decorators'; 5 | import cors from 'cors'; 6 | import { SERVER, BASEROUTE } from '../const/types'; 7 | import { ServerInterface } from './app.interface'; 8 | import { IRouter } from '../modules/router.interface'; 9 | 10 | @provide(SERVER) 11 | class Server implements ServerInterface {// eslint-disable-line 12 | @inject(BASEROUTE) private baseRouter!: IRouter 13 | 14 | async server(): Promise { 15 | const app = express(); 16 | app.use(express.json()); 17 | app.use(express.urlencoded({ extended: true })); 18 | app.use('/api/v1', this.baseRouter.routes);//setting up base route 19 | // define a route handler for the default home page 20 | app.get("/", (req, res) => { 21 | res.send("Welcome to express-create application! "); 22 | }); 23 | app.use(cors()); 24 | return app; 25 | } 26 | } -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/test/user.ts: -------------------------------------------------------------------------------- 1 | /* 2 | https://github.com/inversify/InversifyJS/issues/532 3 | Check out this issue for more inversify testing tips 4 | */ 5 | import test from 'ava'; 6 | import { receptacle } from "../src/container"; 7 | const container = receptacle.getContainer; 8 | import { USERSERVICE } from "../src/const/types"; 9 | import { IUserService } from '../src/modules/user/services/userService.interface'; 10 | 11 | test.beforeEach(() => { 12 | 13 | // create a snapshot so each unit test can modify 14 | // it without breaking other unit tests 15 | container.snapshot(); 16 | 17 | }); 18 | 19 | test.afterEach(() => { 20 | 21 | // Restore to last snapshot so each unit test 22 | // takes a clean copy of the application container 23 | container.restore(); 24 | 25 | }); 26 | 27 | test('check if our random service works', async t => { 28 | let userService = container.get(USERSERVICE) 29 | const result = await userService.getRandomTest(); 30 | t.is(result, 'it works'); 31 | }); -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/test/user.ts: -------------------------------------------------------------------------------- 1 | /* 2 | https://github.com/inversify/InversifyJS/issues/532 3 | Check out this issue for more inversify testing tips 4 | */ 5 | import test from 'ava'; 6 | import { receptacle } from "../src/container"; 7 | const container = receptacle.getContainer; 8 | import { USERSERVICE } from "../src/const/types"; 9 | import { IUserService } from '../src/modules/user/services/userService.interface'; 10 | 11 | test.beforeEach(() => { 12 | 13 | // create a snapshot so each unit test can modify 14 | // it without breaking other unit tests 15 | container.snapshot(); 16 | 17 | }); 18 | 19 | test.afterEach(() => { 20 | 21 | // Restore to last snapshot so each unit test 22 | // takes a clean copy of the application container 23 | container.restore(); 24 | 25 | }); 26 | 27 | test('check if our random service works', async t => { 28 | let userService = container.get(USERSERVICE) 29 | const result = await userService.getRandomTest(); 30 | t.is(result, 'it works'); 31 | }); -------------------------------------------------------------------------------- /test/ui.js: -------------------------------------------------------------------------------- 1 | const ui = require('../src/ui') 2 | const test = require('ava'); 3 | 4 | test('Check if options are returned correctly', async t => { 5 | const options = { 6 | yarn: false, 7 | default: true 8 | } 9 | const expectedResult = { 10 | yarn: false, 11 | default: true, 12 | destinationFolder: 'Test1', 13 | pkgManager: 'npm', 14 | template: 'TypeScript' 15 | } 16 | let result = await ui(options, 'Test1'); 17 | t.deepEqual(result, expectedResult); 18 | }) 19 | 20 | test('Check if options with template are returned correctly', async t => { 21 | const options = { 22 | yarn: true, 23 | default: false, 24 | template: 'TypeScript-TypeORM-Inversify' 25 | } 26 | const expectedResult = { 27 | yarn: true, 28 | default: false, 29 | destinationFolder: 'Test1', 30 | pkgManager: 'yarn', 31 | template: 'TypeScript-TypeORM-Inversify' 32 | } 33 | let result = await ui(options, 'Test1'); 34 | t.deepEqual(result, expectedResult); 35 | }) -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/modules/user/services/userService.ts: -------------------------------------------------------------------------------- 1 | //Uncomment the code in this file to see typeorm in work 2 | import { USERSERVICE } from '../../../const/types'; 3 | import { provide } from "inversify-binding-decorators"; 4 | import { IUserService } from "./userService.interface"; 5 | import { logger } from '../../../helpers/logger'; 6 | // import { User } from "../../../models/entities/Users"; 7 | // import { EntityManager, getManager } from "typeorm"; 8 | 9 | @provide(USERSERVICE) 10 | class UserService implements IUserService{// eslint-disable-line 11 | 12 | // private manager: EntityManager; 13 | // constructor() { 14 | // this.manager = getManager(); 15 | // } 16 | 17 | async getRandomTest(): Promise { 18 | try { 19 | // const user = new User(); 20 | // user.firstName = "Test" 21 | // this.manager.save(user); 22 | logger.info("success") 23 | return "it works"; 24 | } catch (error) { 25 | logger.error("success") 26 | return error; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Govind S 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 | -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/server/app.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | import express from 'express'; 3 | import { inject } from 'inversify'; 4 | import { provide } from 'inversify-binding-decorators'; 5 | import cors from 'cors'; 6 | import { SERVER, BASEROUTE } from '../const/types'; 7 | import { ServerInterface } from './app.interface'; 8 | import { IRouter } from '../modules/router.interface'; 9 | import { connectToDatabase } from '../config/db'; 10 | 11 | @provide(SERVER) 12 | class Server implements ServerInterface {// eslint-disable-line 13 | @inject(BASEROUTE) private baseRouter!: IRouter 14 | 15 | constructor() { 16 | connectToDatabase() 17 | } 18 | 19 | async server(): Promise { 20 | const app = express(); 21 | app.use(express.json()); 22 | app.use(express.urlencoded({ extended: true })); 23 | app.use('/api/v1', this.baseRouter.routes);//setting up base route 24 | // define a route handler for the default home page 25 | app.get("/", (req, res) => { 26 | res.send("Welcome to express-create application! "); 27 | }); 28 | app.use(cors()); 29 | return app; 30 | } 31 | } -------------------------------------------------------------------------------- /src/templates/TypeScript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-app", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "build": "tsc --build --clean && tsc", 6 | "lint": "eslint src/**/*.ts", 7 | "start": "npm run lint && npm run build && npm run dev", 8 | "test": "npm run build && ava", 9 | "dev": "node ./dist/src/index.js" 10 | }, 11 | "dependencies": { 12 | "cors": "^2.8.5", 13 | "dotenv": "^10.0.0", 14 | "express": "^4.17.1", 15 | "mysql": "^2.18.1", 16 | "typeorm": "^0.2.37", 17 | "winston": "^3.3.3" 18 | }, 19 | "devDependencies": { 20 | "@types/cors": "^2.8.12", 21 | "@types/express": "^4.17.13", 22 | "@types/node": "^16.7.2", 23 | "@typescript-eslint/eslint-plugin": "^4.29.3", 24 | "@typescript-eslint/parser": "^4.29.3", 25 | "eslint": "^7.32.0", 26 | "fs-extra": "^10.0.0", 27 | "typescript": "~4.3", 28 | "ava": "^3.15.0", 29 | "@ava/typescript": "^2.0.0" 30 | }, 31 | "ava": { 32 | "files": [ 33 | "test/*" 34 | ], 35 | "timeout": "1m", 36 | "typescript": { 37 | "rewritePaths": { 38 | "test/": "dist/test/" 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-app", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "build": "tsc --build --clean && tsc", 6 | "lint": "eslint src/**/*.ts", 7 | "start": "npm run lint && npm run build && npm run dev", 8 | "test": "npm run build && ava", 9 | "dev": "node ./dist/src/index.js" 10 | }, 11 | "dependencies": { 12 | "cors": "^2.8.5", 13 | "dotenv": "^10.0.0", 14 | "express": "^4.17.1", 15 | "mysql": "^2.18.1", 16 | "typeorm": "^0.2.37", 17 | "winston": "^3.3.3" 18 | }, 19 | "devDependencies": { 20 | "@types/cors": "^2.8.12", 21 | "@types/express": "^4.17.13", 22 | "@types/node": "^16.7.2", 23 | "@typescript-eslint/eslint-plugin": "^4.29.3", 24 | "@typescript-eslint/parser": "^4.29.3", 25 | "eslint": "^7.32.0", 26 | "fs-extra": "^10.0.0", 27 | "typescript": "~4.3", 28 | "ava": "^3.15.0", 29 | "@ava/typescript": "^2.0.0" 30 | }, 31 | "ava": { 32 | "files": [ 33 | "test/*" 34 | ], 35 | "timeout": "1m", 36 | "typescript": { 37 | "rewritePaths": { 38 | "test/": "dist/test/" 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test/util.js: -------------------------------------------------------------------------------- 1 | const util = require('../src/util') 2 | const test = require('ava'); 3 | 4 | test('Check if valid template is returned if available in choices', t => { 5 | let template = util.isValidTemplate('test1', ['test1', 'test2']); 6 | t.is(template, 'test1'); 7 | }) 8 | 9 | test('Check if error is thrown if not initials and not available in choices', t => { 10 | t.throws(() => { 11 | util.isValidTemplate('test3', ['test1', 'test2']); 12 | }); 13 | }) 14 | 15 | test('Check if valid template is returned if initials given', t => { 16 | let template = util.isValidTemplate('tsti', ['test1', 'test2']); 17 | t.is(template, 'TypeScript-TypeORM-Inversify'); 18 | }) 19 | 20 | test('Check if error is thrown if not valid initials', t => { 21 | t.throws(() => { 22 | util.isValidTemplate('tss', ['test1', 'test2']); 23 | }); 24 | }) 25 | 26 | test('checks if package can be modified', t => { 27 | t.notThrows(() => { 28 | util.editPackageJson('../package.json', 'create-express-app'); 29 | }); 30 | }); 31 | 32 | test('checks if command is executing', t => { 33 | t.notThrows(() => { 34 | util.installNodeModules('npm', '') 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-express-template", 3 | "version": "1.1.0", 4 | "description": "Create an express app template with various options", 5 | "bin": { 6 | "create-express-template": "src/cli.js" 7 | }, 8 | "scripts": { 9 | "test": "ava" 10 | }, 11 | "author": "Govind S", 12 | "license": "MIT", 13 | "homepage": "https://github.com/dopecodez/create-express-template#readme", 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/dopecodez/create-express-template" 17 | }, 18 | "files": [ 19 | "src" 20 | ], 21 | "keywords": [ 22 | "cli-app", 23 | "cli", 24 | "npx", 25 | "express", 26 | "create", 27 | "template", 28 | "generator", 29 | "inversify", 30 | "inversion-of-control", 31 | "typeorm", 32 | "sequelize" 33 | ], 34 | "dependencies": { 35 | "edit-json-file": "^1.4.1", 36 | "execa": "^4.0.3", 37 | "inquirer": "^7.3.3", 38 | "log-symbols": "^3.0.0", 39 | "meow": "^6.0.0" 40 | }, 41 | "devDependencies": { 42 | "eslint": "^7.7.0", 43 | "ava": "^3.8.2" 44 | }, 45 | "ava": { 46 | "files": [ 47 | "test/*" 48 | ], 49 | "timeout": "1m" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Environment } from './config/environment'; 2 | /** 3 | * Setuping environment variables 4 | */ 5 | Environment.setup(); 6 | 7 | import { Application } from 'express'; 8 | import { Container } from 'inversify'; 9 | 10 | import { SERVER } from './const/types'; 11 | import { receptacle } from './container'; 12 | import { ServerInterface } from './server/app.interface'; 13 | import { config } from './config/config'; 14 | import { logger } from './helpers/logger'; 15 | 16 | async function startServer() { 17 | const container: Container = receptacle.getContainer; 18 | const server: ServerInterface = container.get(SERVER); 19 | const app: Application = await server.server(); 20 | app.listen(config.SERVER_PORT, () => { 21 | console.log(`Listening on port ${config.SERVER_PORT} in ${config.NODE_ENV} mode`); 22 | logger.info(`Listening on port ${config.SERVER_PORT} in ${config.NODE_ENV} mode`); 23 | }); 24 | } 25 | 26 | startServer(); 27 | 28 | process.on("uncaughtException", e => { 29 | console.log(e); 30 | process.exit(1); 31 | }); 32 | 33 | process.on("unhandledRejection", e => { 34 | console.log(e); 35 | process.exit(1); 36 | }); -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Environment } from './config/environment'; 2 | /** 3 | * Setuping environment variables 4 | */ 5 | Environment.setup(); 6 | import 'reflect-metadata'; 7 | 8 | import { Application } from 'express'; 9 | import { Container } from 'inversify'; 10 | 11 | import { SERVER } from './const/types'; 12 | import { receptacle } from './container'; 13 | import { ServerInterface } from './server/app.interface'; 14 | import { config } from './config/config'; 15 | import { logger } from './helpers/logger'; 16 | 17 | async function startServer() { 18 | const container: Container = receptacle.getContainer; 19 | const server: ServerInterface = container.get(SERVER); 20 | const app: Application = await server.server(); 21 | app.listen(config.SERVER_PORT, () => { 22 | console.log(`Listening on port ${config.SERVER_PORT} in ${config.NODE_ENV} mode`); 23 | logger.info(`Listening on port ${config.SERVER_PORT} in ${config.NODE_ENV} mode`); 24 | }); 25 | } 26 | 27 | startServer(); 28 | 29 | process.on("uncaughtException", e => { 30 | console.log(e); 31 | process.exit(1); 32 | }); 33 | 34 | process.on("unhandledRejection", e => { 35 | console.log(e); 36 | process.exit(1); 37 | }); -------------------------------------------------------------------------------- /src/templates/TypeScript-Inversify/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-app", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "build": "tsc --build --clean && tsc", 6 | "lint": "eslint src/**/*.ts", 7 | "start": "npm run lint && npm run build && npm run dev", 8 | "test": "npm run build && ava", 9 | "dev": "node ./dist/src/index.js" 10 | }, 11 | "dependencies": { 12 | "cors": "^2.8.5", 13 | "dotenv": "^10.0.0", 14 | "express": "^4.17.1", 15 | "inversify": "^5.1.1", 16 | "inversify-binding-decorators": "^4.0.0", 17 | "reflect-metadata": "^0.1.13", 18 | "mysql": "^2.18.1", 19 | "winston": "^3.3.3" 20 | }, 21 | "devDependencies": { 22 | "@types/cors": "^2.8.12", 23 | "@types/express": "^4.17.13", 24 | "@types/node": "^16.7.2", 25 | "@typescript-eslint/eslint-plugin": "^4.29.3", 26 | "@typescript-eslint/parser": "^4.29.3", 27 | "eslint": "^7.32.0", 28 | "fs-extra": "^10.0.0", 29 | "typescript": "~4.3", 30 | "ava": "^3.15.0", 31 | "@ava/typescript": "^2.0.0" 32 | }, 33 | "ava": { 34 | "files": [ 35 | "test/*" 36 | ], 37 | "timeout": "1m", 38 | "typescript": { 39 | "rewritePaths": { 40 | "test/": "dist/test/" 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/templates/TypeScript-TypeORM-Inversify/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-app", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "build": "tsc --build --clean && tsc", 6 | "lint": "eslint src/**/*.ts", 7 | "start": "npm run lint && npm run build && npm run dev", 8 | "test": "npm run build && ava", 9 | "dev": "node ./dist/src/index.js" 10 | }, 11 | "dependencies": { 12 | "cors": "^2.8.5", 13 | "dotenv": "^10.0.0", 14 | "express": "^4.17.1", 15 | "inversify": "^5.1.1", 16 | "inversify-binding-decorators": "^4.0.0", 17 | "mysql": "^2.18.1", 18 | "reflect-metadata": "^0.1.13", 19 | "typeorm": "^0.2.37", 20 | "winston": "^3.3.3" 21 | }, 22 | "devDependencies": { 23 | "@types/cors": "^2.8.12", 24 | "@types/express": "^4.17.13", 25 | "@types/node": "^16.7.2", 26 | "@typescript-eslint/eslint-plugin": "^4.29.3", 27 | "@typescript-eslint/parser": "^4.29.3", 28 | "eslint": "^7.32.0", 29 | "fs-extra": "^10.0.0", 30 | "typescript": "~4.3", 31 | "ava": "^3.15.0", 32 | "@ava/typescript": "^2.0.0" 33 | }, 34 | "ava": { 35 | "files": [ 36 | "test/*" 37 | ], 38 | "timeout": "1m", 39 | "typescript": { 40 | "rewritePaths": { 41 | "test/": "dist/test/" 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/templates/JavaScript/src/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const express = require('express'); 3 | const bodyParser = require("body-parser"); 4 | const cors = require("cors"); 5 | const routerConfig = require('./modules/route'); 6 | const config = require('./config/config'); 7 | const { logger } = require('./helpers/logger'); 8 | 9 | const init = () => { 10 | // *** express instance *** // 11 | const app = express(); 12 | // Configuraing the standard middlewares. 13 | setupStandardMiddlewares(app); 14 | configureApiEndpoints(app); 15 | app.listen(config.SERVER_PORT); 16 | console.log(`Listening on port ${config.SERVER_PORT} in ${config.NODE_ENV} mode`); 17 | logger.info(`Listening on port ${config.SERVER_PORT} in ${config.NODE_ENV} mode`) 18 | }; 19 | 20 | const setupStandardMiddlewares = (app) => { 21 | // parse requests of content-type - application/json 22 | app.use(bodyParser.json()); 23 | // parse requests of content-type - application/x-www-form-urlencoded 24 | app.use(bodyParser.urlencoded({ extended: true })); 25 | app.use(cors()); 26 | return; 27 | }; 28 | 29 | const configureApiEndpoints = (app) => { 30 | app.use("/api/v1/", routerConfig.init()); 31 | // routerConfig.init(app); 32 | // define a route handler for the default home page 33 | app.get( "/", (req, res) => { 34 | res.send( "Welcome to express-create application! " ); 35 | }); 36 | }; 37 | 38 | init(); 39 | -------------------------------------------------------------------------------- /src/templates/JavaScript-Sequelize/src/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const express = require('express'); 3 | const bodyParser = require("body-parser"); 4 | const cors = require("cors"); 5 | const routerConfig = require('./modules/route'); 6 | const config = require('./config/config'); 7 | const { logger } = require('./helpers/logger'); 8 | const sequelize = require('./models/index') 9 | 10 | const init = () => { 11 | // *** express instance *** // 12 | const app = express(); 13 | // Configuraing the standard middlewares. 14 | setupStandardMiddlewares(app); 15 | configureApiEndpoints(app); 16 | app.listen(config.SERVER_PORT); 17 | console.log(`Listening on port ${config.SERVER_PORT} in ${config.NODE_ENV} mode`); 18 | logger.info(`Listening on port ${config.SERVER_PORT} in ${config.NODE_ENV} mode`); 19 | }; 20 | 21 | const setupStandardMiddlewares = (app) => { 22 | // parse requests of content-type - application/json 23 | app.use(bodyParser.json()); 24 | // parse requests of content-type - application/x-www-form-urlencoded 25 | app.use(bodyParser.urlencoded({ extended: true })); 26 | app.use(cors()); 27 | return; 28 | }; 29 | 30 | const configureApiEndpoints = (app) => { 31 | //creates tables if it does not exist in database 32 | sequelize.sync(); 33 | app.use("/api/v1/", routerConfig.init()); 34 | // define a route handler for the default home page 35 | app.get( "/", (req, res) => { 36 | res.send( "Welcome to express-create application!" ); 37 | }); 38 | }; 39 | 40 | init(); 41 | -------------------------------------------------------------------------------- /src/ui.js: -------------------------------------------------------------------------------- 1 | const fs= require('fs'); 2 | const path = require('path'); 3 | const inquirer = require('inquirer'); 4 | const util = require('./util'); 5 | 6 | module.exports = async (options, destinationFolder) => { 7 | const pkgManager = options.yarn ? 'yarn' : 'npm'; 8 | let template = options.default ? 'TypeScript' : null; 9 | template = options.template ? options.template : template; 10 | const choices = fs.readdirSync(path.join(__dirname, 'templates')); 11 | template = template ? util.isValidTemplate(template, choices) : null; 12 | if (destinationFolder && template) { 13 | return { 14 | ...options, 15 | destinationFolder: destinationFolder, 16 | pkgManager: pkgManager, 17 | template: template 18 | }; 19 | } 20 | 21 | const prompts = []; 22 | if (!destinationFolder) { 23 | prompts.push({ 24 | name: 'name', 25 | type: 'input', 26 | message: 'Project name:' 27 | }); 28 | } 29 | if (template == null) { 30 | prompts.push({ 31 | name: 'template', 32 | type: 'list', 33 | message: 'What project template would you like to generate?', 34 | choices: choices 35 | }); 36 | } 37 | 38 | const answers = await inquirer.prompt(prompts); 39 | 40 | return { 41 | ...options, 42 | pkgManager: pkgManager, 43 | destinationFolder: answers.name || destinationFolder, 44 | template: answers.template || template 45 | }; 46 | }; -------------------------------------------------------------------------------- /src/create.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | 4 | exports.createProject = projectPath => { 5 | if (fs.existsSync(projectPath)) { 6 | throw new Error(`Folder ${projectPath} exists. Delete or use another name`); 7 | } 8 | fs.mkdirSync(projectPath); 9 | return true; 10 | }; 11 | 12 | exports.createDirectoryContents = (templatePath, projectName) => { 13 | // list of file/folder that should not be copied 14 | const SKIP_FILES = ['node_modules', 'dist']; 15 | // read all files/folders (1 level) from template folder 16 | const filesToCreate = fs.readdirSync(templatePath); 17 | // loop each file/folder 18 | filesToCreate.forEach(file => { 19 | const origFilePath = path.join(templatePath, file); 20 | // get stats about the current file 21 | const stats = fs.statSync(origFilePath); 22 | // skip files that should not be copied 23 | if (SKIP_FILES.indexOf(file) > -1) return; 24 | const CURR_DIR = process.cwd(); 25 | if (stats.isFile()) { 26 | // read file content and transform it using template engine 27 | let contents = fs.readFileSync(origFilePath, 'utf8'); 28 | // write file to destination folder 29 | const writePath = path.join(CURR_DIR, projectName, file); 30 | fs.writeFileSync(writePath, contents, 'utf8'); 31 | } else if (stats.isDirectory()) { 32 | // create folder in destination folder 33 | fs.mkdirSync(path.join(CURR_DIR, projectName, file)); 34 | // copy files/folder inside current folder recursively 35 | this.createDirectoryContents(path.join(templatePath, file), path.join(projectName, file)); 36 | } 37 | }); 38 | } -------------------------------------------------------------------------------- /src/cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const meow = require('meow'); 3 | const generate = require('.'); 4 | const ui = require('./ui'); 5 | const logSymbols = require('log-symbols') 6 | 7 | const cli = meow(` 8 | Usage 9 | $ create-express-template 10 | 11 | FolderName can be: 12 | Folder name can be anything without a space 13 | 14 | Options 15 | --template Name of the template(default:TypeScript) 16 | --default Use default template 17 | --yarn Use Yarn 18 | 19 | Examples 20 | $ create-express-template 21 | $ create-express-template my-app 22 | $ create-express-template my-app -d 23 | $ create-express-template my-app --template=TypeScript-Inversify-TypeORM -y 24 | $ create-express-template my-app --template=tsti -y 25 | `, { 26 | flags: { 27 | template: { 28 | type: 'string' 29 | }, 30 | default: { 31 | type: 'boolean', 32 | alias: 'd' 33 | }, 34 | yarn: { 35 | type: 'boolean', 36 | alias: 'y' 37 | } 38 | } 39 | }); 40 | 41 | (async () => { 42 | const defaultFlags = { 43 | default: false, 44 | yarn: false 45 | }; 46 | 47 | const flags = { 48 | ...defaultFlags, 49 | ...cli.flags 50 | }; 51 | 52 | const destFolder = cli.input.length > 0 ? cli.input[0] : false; 53 | 54 | const options = await ui( 55 | {...flags}, 56 | destFolder 57 | ); 58 | 59 | console.log(); // Prints a newline for readability 60 | // eslint-disable-next-line no-unused-vars 61 | const created = await generate(options); 62 | console.log(`\n${logSymbols.success} Template created and dependencies installed`); 63 | })().catch(error => { 64 | console.error(`\n${logSymbols.error} ${error.message}`); 65 | process.exit(1); 66 | }); -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at gvind4@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CREATE-EXPRESS-TEMPLATE [![build](https://github.com/dopecodez/create-express-template/workflows/build/badge.svg)](https://github.com/dopecodez/create-express-template/actions) [![Contributions](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/dopecodez/create-express-template/issues) 2 | 3 | Create a modern express server with a single command. 4 | 5 | 6 | 7 | Scale a development ready server in **one step**. 8 | 9 | Works on macOS, Windows, and Linux. Has both TypeScript and JavaScript templates inbuild. Creates all the boilerplate code along with build process and unit tests configured so that you can focus on the application logic. 10 | 11 | Optionally, add the ORM for database support and also configure dependency injection. 12 | 13 | # USAGE 14 | 15 | ``` 16 | $ npx create-express-template my-app 17 | $ cd my-app 18 | $ npm start 19 | ``` 20 | 21 | We strongly suggest using npx from npm versions 5.2+. You can also install create-express-template globally and use it to create a template anywhere in your system. 22 | 23 | After running `npm start`, go to http://localhost:3000/ to see a simple page(3000 here being the port number, you can change this in the .env file). We also implement a sample route at http://localhost:3000/api/v1/users so you can start building immediately following the pattern. 24 | 25 | ## Highlights 26 | 27 | - [Usage with options](#usage-with-options) 28 | - [Templates](#templates) 29 | - [Under The Hood](#under-the-hood) 30 | - [Contributing](#contributing) 31 | 32 | ## Usage with options 33 | 34 | ``` 35 | $ npx create-express-template --help 36 | 37 | Usage 38 | $ create-express-template 39 | 40 | FolderName can be: 41 | Folder name can be anything without a space 42 | 43 | Options 44 | --template Name of the template(default:TypeScript) 45 | --default(-d) Use default template 46 | --yarn(-y) Use Yarn 47 | 48 | Examples 49 | $ create-express-template 50 | $ create-express-template my-app 51 | $ create-express-template my-app -d 52 | $ create-express-template my-app --template=TypeScript-Inversify-TypeORM -y 53 | $ create-express-template my-app --template=tsti -y 54 | 55 | ``` 56 | 57 | The `folderName` and the `template` will be prompted to the user via the interactive ui in case these are not specified. 58 | 59 | Using the `default` option will use TypeScript as the template. If you aren't already using TypeScript, read about why you should start using it [here](https://serokell.io/blog/why-typescript). 60 | 61 | If you want to use `yarn` as your package manager(by default we use `npm`), specify the `yarn` option. 62 | 63 | The available templates(you can use the full names or the initials) are listed [here](#templates). 64 | 65 | ## Templates 66 | 67 | | Template | Initials | Details 68 | | :--- | :----: | :--- 69 | | JavaScript | js | Plain JavaScript Template 70 | | JavaScript-Sequelize | jss | JS + [Sequelize](https://sequelize.org) 71 | | TypeScript | ts | Plain TypeScript Template 72 | | TypeScript-TypeORM | tst | TS + [TypeORM](https://typeorm.io/#/) 73 | | TypeScript-Inversify | tsi | TS + [Inversify](https://github.com/inversify/InversifyJS) 74 | | TypeScript-TypeORM-Inversify | tsit, tsti | TS + [Inversify](https://github.com/inversify/InversifyJS) + [TypeORM](https://typeorm.io/#/) 75 | 76 | **Note : The `template` option can take any of these template values or their initials.** 77 | 78 | We use [Sequelize](https://sequelize.org) for JavaScript and [TypeORM](https://typeorm.io/#/) for TypeScript and both are excellent ORMs. You can check out their pages for more information on creating models and writing queries. There is a sample model structure created so that you can follow the pattern and start building your models directly. All the values for the database port and name and other settings are stored in the `.env` file which you can change to whatever value which you want to use. 79 | 80 | [Inversify](https://github.com/inversify/InversifyJS) is an excellent and lightweight inversion of control container for JavaScript & Node.js apps powered by TypeScript. For people unfamiliar with why you would want to have [Inversion of control](https://medium.com/@amitkma/understanding-inversion-of-control-ioc-principle-163b1dc97454), this one and many other articles can be found on the topic. Read up more on [Dependency Injection](https://www.freecodecamp.org/news/a-quick-intro-to-dependency-injection-what-it-is-and-when-to-use-it-7578c84fa88f/) and why and when you should use it to understand why `inversify` helps in building modern applications. 81 | 82 | ## Under The Hood 83 | 84 | Internally, there are several things being setup in the templates. We use a module structure to separate our components, but you can change this if you want to. 85 | 86 | The unit tests are configured using [ava](https://github.com/avajs/ava), and all the templates come configured with at least one unit test. You can expand these tests using the sample structure provided or remove them completely if you want to. For logging, we use [Winston](https://github.com/winstonjs/winston) for its ease of use. The logging setup is currently very basic, and will log errors and info in two separate files. 87 | 88 | We use [dotenv](https://www.npmjs.com/package/dotenv) to manage our environment variables. Please note that all the ports and database names can be changed in the `.env` file to the value you want to use. 89 | 90 | We also have `cors` enabled so as not to have errors. We use [eslint](https://eslint.org/) to maintain best coding practices. This can be hugely helpful if you want to maintain certain coding standards within your application. 91 | 92 | ## Contributing 93 | 94 | Before opening a pull request please make sure your changes follow the 95 | [contribution guidelines][1]. 96 | 97 | [1]: https://github.com/dopecodez/create-express-template/blob/master/CONTRIBUTING.md 98 | --------------------------------------------------------------------------------