create-express-modular 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +88 -0
- package/bin/cli.js +158 -0
- package/package.json +38 -0
- package/template/.eslintignore +3 -0
- package/template/.eslintrc.json +27 -0
- package/template/.prettierrc.json +12 -0
- package/template/gitignore +5 -0
- package/template/package.json +31 -0
- package/template/src/app/errors/AppError.ts +12 -0
- package/template/src/app/middlewares/globalErrorhandler.ts +26 -0
- package/template/src/app/middlewares/notFound.ts +15 -0
- package/template/src/app/routes/index.ts +5 -0
- package/template/src/app.ts +23 -0
- package/template/src/server.ts +15 -0
- package/template/tsconfig.json +19 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 levi9111
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
```markdown
|
|
2
|
+
# π Create Express Modular
|
|
3
|
+
|
|
4
|
+
> A powerful interactive CLI to scaffold a scalable, databaseβagnostic Express + TypeScript server β inspired by NestJS structure, but lightweight and flexible.
|
|
5
|
+
|
|
6
|
+
[](https://www.npmjs.com/package/create-express-modular)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
|
|
9
|
+
Stop copying boilerplate manually. Define your modules once, and let `create-express-modular` generate a productionβready, strictly typed Express application in seconds.
|
|
10
|
+
|
|
11
|
+
## β¨ Why use this?
|
|
12
|
+
|
|
13
|
+
- **Interactive Scaffolding** β The CLI asks for your module names (e.g. `User, Product, Order`) and builds the entire folder structure and initial files automatically.
|
|
14
|
+
- **Database Agnostic** β No ORM is forced. Works equally well with MongoDB (Mongoose), PostgreSQL (Prisma/TypeORM), MySQL, or plain SQL.
|
|
15
|
+
- **NestJSβinspired Modular Design** β Each module contains its own controller, service, routes, model, interface, and validation β separation of concerns out of the box.
|
|
16
|
+
- **Autoβwired Routing** β Your custom modules are automatically imported and registered in `src/app/routes/index.ts`. No manual wiring required.
|
|
17
|
+
- **Productionβready DX** β TypeScript strict mode, ESLint (v8), Prettier, and `ts-node-dev` for instant hotβreload during development.
|
|
18
|
+
|
|
19
|
+
## π¦ Quick Start
|
|
20
|
+
|
|
21
|
+
You don't need to install anything globally. Use `npx` to run the latest version:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx create-express-modular
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The CLI will guide you through two simple steps:
|
|
28
|
+
1. **Project name** β Choose a name for your new backend.
|
|
29
|
+
2. **Module names** β List the feature modules you need (e.g. `Auth, Receipt, Property`).
|
|
30
|
+
|
|
31
|
+
Once finished, your project is ready with all dependencies installed and Git initialised.
|
|
32
|
+
|
|
33
|
+
## π Generated Project Structure
|
|
34
|
+
|
|
35
|
+
After generating a project with a `User` module, your `src` directory will look like this:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
src/
|
|
39
|
+
βββ app/
|
|
40
|
+
β βββ builder/
|
|
41
|
+
β βββ config/
|
|
42
|
+
β βββ constants/
|
|
43
|
+
β βββ errors/
|
|
44
|
+
β βββ interface/
|
|
45
|
+
β βββ middlewares/
|
|
46
|
+
β βββ modules/
|
|
47
|
+
β β βββ User/ # β¨ Generated module
|
|
48
|
+
β β βββ user.controller.ts
|
|
49
|
+
β β βββ user.interface.ts
|
|
50
|
+
β β βββ user.model.ts
|
|
51
|
+
β β βββ user.route.ts
|
|
52
|
+
β β βββ user.service.ts
|
|
53
|
+
β β βββ user.utils.ts
|
|
54
|
+
β β βββ user.validation.ts
|
|
55
|
+
β βββ routes/
|
|
56
|
+
β β βββ index.ts # β¨ Autoβwired with your modules
|
|
57
|
+
β βββ utils/
|
|
58
|
+
βββ app.ts
|
|
59
|
+
βββ server.ts
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
> **Tip:** The architecture is domainβdriven and easily extensible β perfect for growing APIs.
|
|
63
|
+
|
|
64
|
+
## π Builtβin Scripts
|
|
65
|
+
|
|
66
|
+
Inside your generated project, you can run:
|
|
67
|
+
|
|
68
|
+
| Command | Description |
|
|
69
|
+
|-----------------------|-----------------------------------------------------------|
|
|
70
|
+
| `npm run start:dev` | Starts the dev server with hotβreload (`ts-node-dev`) |
|
|
71
|
+
| `npm run build` | Compiles TypeScript to JavaScript (`dist/`) |
|
|
72
|
+
| `npm start` | Runs the compiled app in production |
|
|
73
|
+
| `npm run lint` | Lints the codebase with ESLint |
|
|
74
|
+
| `npm run lint:fix` | Automatically fixes linting issues |
|
|
75
|
+
| `npm run prettier` | Formats all files using Prettier |
|
|
76
|
+
|
|
77
|
+
## π§© Customisation & Extensibility
|
|
78
|
+
|
|
79
|
+
Because the tool generates standard Express + TypeScript code, you can easily add any middleware, ORM, or utility library. The structure is designed to stay out of your way while keeping everything organised.
|
|
80
|
+
|
|
81
|
+
## π€ Contributing
|
|
82
|
+
|
|
83
|
+
We welcome contributions! Feel free to open an issue or submit a pull request on [GitHub](https://github.com/Levi9111/npm-create-express-modular).
|
|
84
|
+
|
|
85
|
+
## π License
|
|
86
|
+
|
|
87
|
+
This project is licensed under the [MIT License](https://opensource.org/licenses/MIT).
|
|
88
|
+
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const {
|
|
6
|
+
execSync
|
|
7
|
+
} = require('child_process');
|
|
8
|
+
const readline = require('readline');
|
|
9
|
+
|
|
10
|
+
const rl = readline.createInterface({
|
|
11
|
+
input: process.stdin,
|
|
12
|
+
output: process.stdout,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const askQuestion = (query) => new Promise((resolve) => rl.question(query, resolve));
|
|
16
|
+
|
|
17
|
+
async function runCLI() {
|
|
18
|
+
console.log('\nπ Welcome to Create Express Modular!\n');
|
|
19
|
+
|
|
20
|
+
// 1. Get Project Name
|
|
21
|
+
let projectName = process.argv[2];
|
|
22
|
+
if (!projectName) {
|
|
23
|
+
projectName = await askQuestion('π¦ What is your project named? (e.g., my-api): ');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (!projectName) {
|
|
27
|
+
console.error('β Project name is required.');
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// 2. Ask for Modules
|
|
32
|
+
const modulesInput = await askQuestion(
|
|
33
|
+
'π οΈ Which modules should we generate? (comma-separated, e.g., User,Product,Order): '
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
rl.close();
|
|
37
|
+
|
|
38
|
+
const currentPath = process.cwd();
|
|
39
|
+
const projectPath = path.join(currentPath, projectName);
|
|
40
|
+
const templatePath = path.join(__dirname, '../template');
|
|
41
|
+
|
|
42
|
+
// 3. Create Project Directory
|
|
43
|
+
try {
|
|
44
|
+
fs.mkdirSync(projectPath);
|
|
45
|
+
} catch (err) {
|
|
46
|
+
if (err.code === 'EEXIST') {
|
|
47
|
+
console.error(`β Directory '${projectName}' already exists.`);
|
|
48
|
+
} else {
|
|
49
|
+
console.error(err);
|
|
50
|
+
}
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Helper to copy the base template
|
|
55
|
+
function copyFolderSync(from, to) {
|
|
56
|
+
fs.mkdirSync(to, {
|
|
57
|
+
recursive: true
|
|
58
|
+
});
|
|
59
|
+
fs.readdirSync(from).forEach((element) => {
|
|
60
|
+
const fromPath = path.join(from, element);
|
|
61
|
+
const toPath = path.join(to, element);
|
|
62
|
+
if (fs.lstatSync(fromPath).isFile()) {
|
|
63
|
+
fs.copyFileSync(fromPath, toPath);
|
|
64
|
+
} else {
|
|
65
|
+
copyFolderSync(fromPath, toPath);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
console.log(`\nπ Scaffolding base architecture...`);
|
|
71
|
+
copyFolderSync(templatePath, projectPath);
|
|
72
|
+
|
|
73
|
+
// 4. Rename gitignore to .gitignore
|
|
74
|
+
const gitignorePath = path.join(projectPath, 'gitignore');
|
|
75
|
+
if (fs.existsSync(gitignorePath)) {
|
|
76
|
+
fs.renameSync(gitignorePath, path.join(projectPath, '.gitignore'));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// 5. Update the new package.json with the user's project name
|
|
80
|
+
const packageJsonPath = path.join(projectPath, 'package.json');
|
|
81
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
82
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
83
|
+
packageJson.name = projectName.toLowerCase().replace(/\s+/g, '-');
|
|
84
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 6. Dynamically Generate the Modules based on user input
|
|
88
|
+
const modulesToCreate = modulesInput
|
|
89
|
+
.split(',')
|
|
90
|
+
.map((m) => m.trim())
|
|
91
|
+
.filter((m) => m.length > 0);
|
|
92
|
+
|
|
93
|
+
if (modulesToCreate.length > 0) {
|
|
94
|
+
console.log(`\nπ§© Generating custom modules...`);
|
|
95
|
+
|
|
96
|
+
const modulesBaseDir = path.join(projectPath, 'src/app/modules');
|
|
97
|
+
if (!fs.existsSync(modulesBaseDir)) fs.mkdirSync(modulesBaseDir, {
|
|
98
|
+
recursive: true
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
let routeImports = '';
|
|
102
|
+
let routeArray = 'const moduleRoutes = [\n';
|
|
103
|
+
|
|
104
|
+
modulesToCreate.forEach((mod) => {
|
|
105
|
+
const moduleName = mod.charAt(0).toUpperCase() + mod.slice(1);
|
|
106
|
+
const fileName = mod.toLowerCase();
|
|
107
|
+
const modulePath = path.join(modulesBaseDir, moduleName);
|
|
108
|
+
|
|
109
|
+
fs.mkdirSync(modulePath, {
|
|
110
|
+
recursive: true
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Create the 7 standard files for each module
|
|
114
|
+
const fileTypes = ['controller', 'interface', 'model', 'route', 'service', 'utils', 'validation'];
|
|
115
|
+
fileTypes.forEach((type) => {
|
|
116
|
+
fs.writeFileSync(
|
|
117
|
+
path.join(modulePath, `${fileName}.${type}.ts`),
|
|
118
|
+
`// TODO: Implement ${moduleName} ${type}\n`
|
|
119
|
+
);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
console.log(` - Created ${moduleName} module`);
|
|
123
|
+
|
|
124
|
+
// Prepare data for the routes/index.ts file
|
|
125
|
+
routeImports += `import { ${moduleName}Routes } from '../modules/${moduleName}/${fileName}.route';\n`;
|
|
126
|
+
routeArray += ` { path: '/${fileName}s', route: ${moduleName}Routes },\n`;
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
routeArray += '];\n';
|
|
130
|
+
|
|
131
|
+
// 7. Generate src/app/routes/index.ts to wire up the router automatically
|
|
132
|
+
const routesDir = path.join(projectPath, 'src/app/routes');
|
|
133
|
+
if (!fs.existsSync(routesDir)) fs.mkdirSync(routesDir, {
|
|
134
|
+
recursive: true
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const routeFileContent = `import { Router } from 'express';\n\n${routeImports}\nconst router = Router();\n\n${routeArray}\nmoduleRoutes.forEach((route) => router.use(route.path, route.route));\n\nexport default router;\n`;
|
|
138
|
+
fs.writeFileSync(path.join(routesDir, 'index.ts'), routeFileContent);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// 8. Install Dependencies
|
|
142
|
+
console.log('\nπ¦ Installing dependencies (this takes a minute)...');
|
|
143
|
+
try {
|
|
144
|
+
execSync('npm install', {
|
|
145
|
+
cwd: projectPath,
|
|
146
|
+
stdio: 'inherit'
|
|
147
|
+
});
|
|
148
|
+
} catch (error) {
|
|
149
|
+
console.error('\nβ Failed to install dependencies.');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
console.log(`\nβ
Success! Your Express architecture is ready.`);
|
|
153
|
+
console.log(`\nNext steps:`);
|
|
154
|
+
console.log(` cd ${projectName}`);
|
|
155
|
+
console.log(` npm run start:dev\n`);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
runCLI();
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-express-modular",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Scaffold a modular Express TS server",
|
|
5
|
+
"bin": {
|
|
6
|
+
"create-express-modular": "./bin/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"bin",
|
|
10
|
+
"template",
|
|
11
|
+
"README.md",
|
|
12
|
+
"package.json",
|
|
13
|
+
"LICENSE"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"express",
|
|
20
|
+
"typescript",
|
|
21
|
+
"modular",
|
|
22
|
+
"scaffold",
|
|
23
|
+
"cli"
|
|
24
|
+
],
|
|
25
|
+
"author": "levi9111",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/Levi9111/npm-create-express-modular.git"
|
|
30
|
+
},
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/Levi9111/npm-create-express-modular/issues"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/Levi9111/npm-create-express-modular#readme",
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"http-status-codes": "^2.3.0"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"env": {
|
|
3
|
+
"browser": true,
|
|
4
|
+
"es2021": true
|
|
5
|
+
},
|
|
6
|
+
"extends": [
|
|
7
|
+
"eslint:recommended",
|
|
8
|
+
"plugin:@typescript-eslint/recommended",
|
|
9
|
+
"prettier"
|
|
10
|
+
],
|
|
11
|
+
"parser": "@typescript-eslint/parser",
|
|
12
|
+
"parserOptions": {
|
|
13
|
+
"ecmaVersion": "latest",
|
|
14
|
+
"sourceType": "module"
|
|
15
|
+
},
|
|
16
|
+
"plugins": ["@typescript-eslint"],
|
|
17
|
+
"rules": {
|
|
18
|
+
"no-unused-vars": "error",
|
|
19
|
+
"no-unused-expressions": "error",
|
|
20
|
+
"prefer-const": "error",
|
|
21
|
+
"no-console": "warn",
|
|
22
|
+
"no-undef": "error"
|
|
23
|
+
},
|
|
24
|
+
"globals": {
|
|
25
|
+
"process": "readonly"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "template",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "src/server.ts",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "npm install && tsc",
|
|
7
|
+
"start": "node dist/server.js",
|
|
8
|
+
"start:dev": "ts-node-dev --respawn --transpile-only src/server.ts",
|
|
9
|
+
"lint": "eslint src --ignore-path .eslintignore --ext .ts",
|
|
10
|
+
"lint:fix": "eslint src --fix --ignore-path .eslintignore --ext .ts",
|
|
11
|
+
"prettier": "prettier --ignore-path .gitignore --write \"./src/**/*.{js,ts,json}\"",
|
|
12
|
+
"prettier:fix": "prettier --write src"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"cors": "^2.8.5",
|
|
16
|
+
"dotenv": "^16.3.1",
|
|
17
|
+
"express": "^4.18.2"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@types/cors": "^2.8.13",
|
|
21
|
+
"@types/express": "^4.17.17",
|
|
22
|
+
"@types/node": "^20.4.5",
|
|
23
|
+
"@typescript-eslint/eslint-plugin": "^6.2.0",
|
|
24
|
+
"@typescript-eslint/parser": "^6.2.0",
|
|
25
|
+
"eslint": "^8.45.0",
|
|
26
|
+
"eslint-config-prettier": "^8.8.0",
|
|
27
|
+
"prettier": "^3.0.0",
|
|
28
|
+
"ts-node-dev": "^2.0.0",
|
|
29
|
+
"typescript": "^5.1.6"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
class AppError extends Error {
|
|
2
|
+
public statusCode: number;
|
|
3
|
+
|
|
4
|
+
constructor(statusCode: number, message: string, stack: string = '') {
|
|
5
|
+
super(message);
|
|
6
|
+
this.statusCode = statusCode;
|
|
7
|
+
if (stack) this.stack = stack;
|
|
8
|
+
else Error.captureStackTrace(this, this.constructor);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default AppError;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ErrorRequestHandler } from 'express';
|
|
2
|
+
import AppError from '../errors/AppError';
|
|
3
|
+
|
|
4
|
+
const globalErrorHandler: ErrorRequestHandler = (err, req, res, next) => {
|
|
5
|
+
let statusCode = 500;
|
|
6
|
+
let message = 'Something went wrong!';
|
|
7
|
+
let errorMessages: { path: string | number; message: string }[] = [];
|
|
8
|
+
|
|
9
|
+
if (err instanceof AppError) {
|
|
10
|
+
statusCode = err.statusCode;
|
|
11
|
+
message = err.message;
|
|
12
|
+
errorMessages = err.message ? [{ path: '', message: err.message }] : [];
|
|
13
|
+
} else if (err instanceof Error) {
|
|
14
|
+
message = err.message;
|
|
15
|
+
errorMessages = err.message ? [{ path: '', message: err.message }] : [];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
res.status(statusCode).json({
|
|
19
|
+
success: false,
|
|
20
|
+
message,
|
|
21
|
+
errorMessages,
|
|
22
|
+
stack: process.env.NODE_ENV !== 'production' ? err.stack : undefined,
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default globalErrorHandler;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/* eslint-disable no-unused-vars */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
3
|
+
|
|
4
|
+
import { NextFunction, Request, Response } from 'express';
|
|
5
|
+
import httpStatus from 'http-status-codes';
|
|
6
|
+
|
|
7
|
+
const notFound = (req: Request, res: Response, next: NextFunction) => {
|
|
8
|
+
return res.status(httpStatus.NOT_FOUND).json({
|
|
9
|
+
success: false,
|
|
10
|
+
message: 'API Not Found !!',
|
|
11
|
+
error: '',
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default notFound;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import cors from 'cors';
|
|
2
|
+
import express, { Application, Request, Response } from 'express';
|
|
3
|
+
import router from './app/routes/index';
|
|
4
|
+
import notFound from './app/middlewares/notFound';
|
|
5
|
+
import globalErrorHandler from './app/middlewares/globalErrorhandler';
|
|
6
|
+
|
|
7
|
+
const app: Application = express();
|
|
8
|
+
|
|
9
|
+
//parsers
|
|
10
|
+
app.use(express.json());
|
|
11
|
+
app.use(cors());
|
|
12
|
+
|
|
13
|
+
// application routes
|
|
14
|
+
app.use('/api/v1', router);
|
|
15
|
+
|
|
16
|
+
app.get('/', (_req: Request, res: Response) => {
|
|
17
|
+
res.send('Welcome to Express Modular Server!');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
app.use(globalErrorHandler);
|
|
21
|
+
app.use(notFound);
|
|
22
|
+
|
|
23
|
+
export default app;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"rootDir": "./src",
|
|
7
|
+
"outDir": "./dist",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"baseUrl": ".",
|
|
13
|
+
"paths": {
|
|
14
|
+
"@/*": ["src/*"]
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"include": ["src/**/*.ts"],
|
|
18
|
+
"exclude": ["node_modules"]
|
|
19
|
+
}
|