express-modular-monolith 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/README.md ADDED
@@ -0,0 +1,14 @@
1
+ # Express Modular Monolith
2
+
3
+ Generate an Express modular monolith boilerplate.
4
+
5
+ ## Usage
6
+ ```bash
7
+ npx express-modular-monolith
8
+ ```
9
+ ## Features
10
+
11
+ - JavaScript template
12
+ - TypeScript template
13
+ - Modular monolith structure
14
+ - Express
package/bin/cli.js ADDED
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env node
2
+
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { exec } from "node:child_process";
6
+ import fs from "node:fs/promises";
7
+ import { input, select } from "@inquirer/prompts";
8
+
9
+
10
+ const projectName = await input({
11
+ message: "Project name:"
12
+ });
13
+
14
+ const language = await select({
15
+ message: "Choose a language:",
16
+ choices: [
17
+ {
18
+ name: "JavaScript",
19
+ value: "javascript"
20
+ },
21
+ {
22
+ name: "TypeScript",
23
+ value: "typescript"
24
+ }
25
+ ]
26
+ });
27
+
28
+
29
+ const __filename = fileURLToPath(import.meta.url);
30
+ const __dirname = path.dirname(__filename);
31
+
32
+ const templatePath = path.join(__dirname, "..", "templates", language);
33
+
34
+ const projectPath = projectName === "." ? process.cwd() : path.join(process.cwd(), projectName);
35
+ await fs.cp( templatePath, projectPath, { recursive: true });
36
+
37
+ const packageJsonPath = path.join(projectPath, "package.json");
38
+
39
+ const packageJson = JSON.parse(
40
+ await fs.readFile(packageJsonPath, "utf-8")
41
+ );
42
+
43
+ if (projectName === ".") {
44
+ packageJson.name = path.basename(process.cwd());
45
+ }else{
46
+ packageJson.name = projectName;
47
+ }
48
+
49
+ await fs.writeFile(
50
+ packageJsonPath,
51
+ JSON.stringify(packageJson, null, 2)
52
+ );
53
+
54
+ await exec("npm install", {
55
+ cwd: projectPath
56
+ })
57
+
58
+
package/package.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "express-modular-monolith",
3
+ "version": "1.0.0",
4
+ "description": "This is a modular monolith project generator for Express.js",
5
+ "type": "module",
6
+ "bin": {
7
+ "express-modular-monolith": "./bin/cli.js"
8
+ },
9
+ "keywords": [],
10
+ "license": "MIT",
11
+ "author": "Md Khalid Hossain",
12
+ "dependencies": {
13
+ "@inquirer/prompts": "^8.6.0"
14
+ }
15
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "javascript",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "src/server.js",
6
+ "scripts": {
7
+ "dev": "node src/server.js"
8
+ },
9
+ "dependencies": {
10
+ "cors": "^2.8.6",
11
+ "dotenv": "^17.4.2",
12
+ "express": "^5.2.1"
13
+ },
14
+ "keywords": [],
15
+ "author": "",
16
+ "license": "ISC",
17
+ "type": "module"
18
+ }
@@ -0,0 +1,8 @@
1
+ import express from 'express'
2
+
3
+ const app = express()
4
+
5
+ app.use(express.json())
6
+ app.use(express.urlencoded({ extended: true }))
7
+
8
+ export default app
@@ -0,0 +1 @@
1
+ // write here your database connection code
@@ -0,0 +1,32 @@
1
+ export class ApiError extends Error {
2
+
3
+ constructor(statusCode, message) {
4
+ super(message)
5
+ this.statusCode = statusCode
6
+ Error.captureStackTrace(this, this.constructor)
7
+ }
8
+
9
+ static badRequest(message = "Bad request") {
10
+ return new ApiError(400, message);
11
+ }
12
+
13
+ static unauthorized(message = "Unauthorized") {
14
+ return new ApiError(401, message);
15
+ }
16
+ static conflict(message = "Conflict") {
17
+ return new ApiError(409, message);
18
+ }
19
+ static forbidden(message = "forbidden") {
20
+ return new ApiError(403, message);
21
+ }
22
+ static notfound(message = "notfound") {
23
+ return new ApiError(404, message);
24
+ }
25
+ static unprocessable(message = "unprocessable"){
26
+ return new ApiError(422, message)
27
+ }
28
+
29
+ static internal(message = "Internal Server Error") {
30
+ return new ApiError(500, message);
31
+ }
32
+ }
@@ -0,0 +1,26 @@
1
+ export class ApiResponse {
2
+
3
+ static ok(res, message, data = null)
4
+ {
5
+ return res.status(200).json({
6
+ success: true,
7
+ message,
8
+ data
9
+ })
10
+ }
11
+
12
+ static created(res, message, data = null)
13
+ {
14
+ return res.status(201).json({
15
+ success: true,
16
+ message,
17
+ data
18
+ })
19
+ }
20
+
21
+ static noContent(res)
22
+ {
23
+ return res.status(204).send()
24
+ }
25
+
26
+ }
@@ -0,0 +1,17 @@
1
+ import 'dotenv/config'
2
+ import app from './app.js'
3
+
4
+
5
+ const PORT = process.env.PORT || 8000
6
+
7
+ ;(async function start () {
8
+ try {
9
+ // execute database connection function here
10
+ app.listen(PORT, ()=>{
11
+ console.log(`Server is running at port ${PORT}`)
12
+ })
13
+ } catch (error) {
14
+ console.error('Failed to start server', error)
15
+ process.exit(1)
16
+ }
17
+ })()
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "typescript",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "src/server.js",
6
+ "scripts": {
7
+ "dev": "tsc-watch --onSuccess \"node dist/server.js\""
8
+ },
9
+ "dependencies": {
10
+ "cors": "^2.8.6",
11
+ "dotenv": "^17.4.2",
12
+ "express": "^5.2.1"
13
+ },
14
+ "devDependencies": {
15
+ "@types/cors": "^2.8.19",
16
+ "@types/express": "^5.0.6",
17
+ "@types/node": "^25.6.0",
18
+ "tsc-watch": "^7.2.0",
19
+ "tsx": "^4.21.0"
20
+ },
21
+ "keywords": [],
22
+ "author": "",
23
+ "license": "ISC",
24
+ "type": "module"
25
+ }
@@ -0,0 +1,7 @@
1
+ import express from 'express'
2
+ import type { Express } from 'express'
3
+
4
+
5
+ const app:Express = express()
6
+
7
+ export default app
@@ -0,0 +1 @@
1
+ // write here your database connection code
@@ -0,0 +1,31 @@
1
+ export class ApiError extends Error {
2
+ constructor(public statusCode: number, message: string) {
3
+ super(message)
4
+ this.statusCode = statusCode
5
+ Error.captureStackTrace(this, this.constructor)
6
+ }
7
+
8
+ static badRequest(message = "Bad request") {
9
+ return new ApiError(400, message);
10
+ }
11
+
12
+ static unauthorized(message = "Unauthorized") {
13
+ return new ApiError(401, message);
14
+ }
15
+ static conflict(message = "Conflict") {
16
+ return new ApiError(409, message);
17
+ }
18
+ static forbidden(message = "forbidden") {
19
+ return new ApiError(403, message);
20
+ }
21
+ static notfound(message = "notfound") {
22
+ return new ApiError(404, message);
23
+ }
24
+ static unprocessable(message = "unprocessable"){
25
+ return new ApiError(422, message)
26
+ }
27
+
28
+ static internal(message = "Internal Server Error") {
29
+ return new ApiError(500, message);
30
+ }
31
+ }
@@ -0,0 +1,27 @@
1
+ import type { Response } from "express"
2
+
3
+ export class ApiResponse {
4
+ static ok(res:Response, message:string, data: unknown = null)
5
+ {
6
+ return res.status(200).json({
7
+ success: true,
8
+ message,
9
+ data
10
+ })
11
+ }
12
+
13
+ static created(res:Response, message:string, data: unknown = null)
14
+ {
15
+ return res.status(201).json({
16
+ success: true,
17
+ message,
18
+ data
19
+ })
20
+ }
21
+
22
+ static noContent(res:Response)
23
+ {
24
+ return res.status(204).send()
25
+ }
26
+
27
+ }
@@ -0,0 +1,17 @@
1
+ import 'dotenv/config'
2
+ import app from './app.js'
3
+
4
+
5
+ const PORT = process.env.PORT || 8000
6
+
7
+ ;(async function start () {
8
+ try {
9
+ // execute database connection function here
10
+ app.listen(PORT, ()=>{
11
+ console.log(`Server is running at port ${PORT}`)
12
+ })
13
+ } catch (error) {
14
+ console.error('Failed to start server', error)
15
+ process.exit(1)
16
+ }
17
+ })()
@@ -0,0 +1,44 @@
1
+ {
2
+ // Visit https://aka.ms/tsconfig to read more about this file
3
+ "compilerOptions": {
4
+ // File Layout
5
+ "rootDir": "./src",
6
+ "outDir": "./dist",
7
+
8
+ // Environment Settings
9
+ // See also https://aka.ms/tsconfig/module
10
+ "module": "nodenext",
11
+ "target": "esnext",
12
+ "types": [],
13
+ // For nodejs:
14
+ // "lib": ["esnext"],
15
+ // "types": ["node"],
16
+ // and npm install -D @types/node
17
+
18
+ // Other Outputs
19
+ "sourceMap": true,
20
+ "declaration": true,
21
+ "declarationMap": true,
22
+
23
+ // Stricter Typechecking Options
24
+ "noUncheckedIndexedAccess": true,
25
+ "exactOptionalPropertyTypes": true,
26
+
27
+ // Style Options
28
+ // "noImplicitReturns": true,
29
+ // "noImplicitOverride": true,
30
+ // "noUnusedLocals": true,
31
+ // "noUnusedParameters": true,
32
+ // "noFallthroughCasesInSwitch": true,
33
+ // "noPropertyAccessFromIndexSignature": true,
34
+
35
+ // Recommended Options
36
+ "strict": true,
37
+ "jsx": "react-jsx",
38
+ "verbatimModuleSyntax": true,
39
+ "isolatedModules": true,
40
+ "noUncheckedSideEffectImports": true,
41
+ "moduleDetection": "force",
42
+ "skipLibCheck": true,
43
+ }
44
+ }