ms-systems 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/Dockerfile ADDED
@@ -0,0 +1,15 @@
1
+ FROM node:22-alpine
2
+
3
+ WORKDIR /app
4
+
5
+ COPY package*.json ./
6
+
7
+ RUN npm install
8
+
9
+ COPY . .
10
+
11
+ RUN npm run build
12
+
13
+ EXPOSE 4000
14
+
15
+ CMD ["node", "dist/app.js"]
package/dist/app.js ADDED
@@ -0,0 +1,217 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ const dotenv_1 = __importDefault(require("dotenv"));
41
+ dotenv_1.default.config();
42
+ const chalk_1 = __importDefault(require("chalk"));
43
+ const inquirer_1 = __importDefault(require("inquirer"));
44
+ const fs_1 = __importDefault(require("fs"));
45
+ const path_1 = __importDefault(require("path"));
46
+ const child_process_1 = require("child_process");
47
+ const biolerplate_1 = require("./util/biolerplate");
48
+ const util_1 = require("util");
49
+ const log = console.log;
50
+ const Exec = (0, util_1.promisify)(child_process_1.exec);
51
+ const validateService = (service) => {
52
+ if (!service || service.length === 0)
53
+ throw new Error("Service name is requird");
54
+ const regex = /^[a-zA-Z0-9-]+$/;
55
+ const isValid = regex.test(service);
56
+ if (!isValid)
57
+ throw new Error("Space or any symbol not allowed in service name you can use -");
58
+ return service.toLowerCase();
59
+ };
60
+ const exitApp = (msg = null) => {
61
+ const message = chalk_1.default.bgGreenBright.black.bold(msg || "👋 Good Bye !");
62
+ log(message);
63
+ process.exit(0);
64
+ };
65
+ const makeFolder = (path) => {
66
+ const isExist = fs_1.default.existsSync(path);
67
+ if (isExist)
68
+ throw new Error(`${path.split("\\").pop()} service already exists !`);
69
+ fs_1.default.mkdirSync(path);
70
+ };
71
+ const copyFiles = (files, inputPath, outputPath) => {
72
+ files.forEach((file) => {
73
+ fs_1.default.copyFileSync(path_1.default.join(`${inputPath}`, file), path_1.default.join(`${outputPath}`, file));
74
+ });
75
+ };
76
+ const getBiolerplate = (file, service) => {
77
+ if (file === ".router.ts")
78
+ return (0, biolerplate_1.routerBoilerplate)(service);
79
+ if (file === ".interface.ts")
80
+ return (0, biolerplate_1.interfaceBoilerplate)(service);
81
+ if (file === ".model.ts")
82
+ return (0, biolerplate_1.modelBoilerplate)(service);
83
+ return "";
84
+ };
85
+ const createFiles = (files, service, srcPath) => {
86
+ files.forEach((file) => {
87
+ const filename = `${service}${file}`;
88
+ const filepath = path_1.default.join(srcPath, filename);
89
+ fs_1.default.writeFileSync(filepath, getBiolerplate(file, service));
90
+ });
91
+ };
92
+ const updateLastPort = (pipelinePath, newPort) => {
93
+ const envFilePath = path_1.default.join(pipelinePath, ".env");
94
+ const envData = fs_1.default.readFileSync(envFilePath, "utf-8");
95
+ const updatedPortString = envData.replace(/LAST_PORT\s*=\s*\d+/, `LAST_PORT = ${newPort}`);
96
+ fs_1.default.writeFileSync(envFilePath, updatedPortString);
97
+ };
98
+ const createEnvForNewService = (pipelinePath, servicePath, newPort) => {
99
+ const pipelineEnvPath = path_1.default.join(pipelinePath, ".env");
100
+ const newEnvPath = path_1.default.join(servicePath, ".env");
101
+ const envData = fs_1.default.readFileSync(pipelineEnvPath, "utf-8");
102
+ const stringChangedAfterPort = envData.replace(/PORT\s*=\s*\d+/, `PORT = ${newPort}`);
103
+ const arr = stringChangedAfterPort.split("\n");
104
+ const modifiedData = arr.map((item) => {
105
+ if (item.startsWith("LAST_PORT"))
106
+ return null;
107
+ if (item.startsWith("SERVER"))
108
+ return `SERVER = http://localhost:${newPort}\r`;
109
+ return item;
110
+ }).filter(Boolean);
111
+ const finalData = modifiedData.join("\n");
112
+ fs_1.default.writeFileSync(newEnvPath, finalData);
113
+ };
114
+ const createPackageForNewService = (service, servicePath) => {
115
+ const data = (0, biolerplate_1.packageBoilerplate)(service);
116
+ const newPackagePath = path_1.default.join(servicePath, "package.json");
117
+ fs_1.default.writeFileSync(newPackagePath, data);
118
+ };
119
+ const createDockerFileForNewService = (pipelinePath, servicePath, newPort) => {
120
+ const pipelineDockerFilePath = path_1.default.join(pipelinePath, "Dockerfile");
121
+ const newDockerFilePath = path_1.default.join(servicePath, "Dockerfile");
122
+ const dockerFileData = fs_1.default.readFileSync(pipelineDockerFilePath, "utf-8");
123
+ const replacedWithDocker = dockerFileData.replace(/EXPOSE\s*\d+/, `EXPOSE ${newPort}`);
124
+ fs_1.default.writeFileSync(newDockerFilePath, replacedWithDocker);
125
+ };
126
+ const getNewPort = (pipelinePath) => {
127
+ const envPath = path_1.default.join(pipelinePath, ".env");
128
+ const envData = fs_1.default.readFileSync(envPath, "utf-8");
129
+ const arr = envData.split("\n");
130
+ const lastPortLine = arr.find((line) => {
131
+ return line.trimStart().startsWith("LAST_PORT");
132
+ });
133
+ const regExpForPortValue = /LAST_PORT\s*=\s*(\d+)/;
134
+ const lastPort = parseInt(lastPortLine?.match(regExpForPortValue)?.[1]);
135
+ return lastPort + 1;
136
+ };
137
+ const addGateway = (gatewayPath, serviceName, newPort) => {
138
+ const data = (0, biolerplate_1.gatewayBoilerplate)(serviceName, newPort);
139
+ const input = path_1.default.join(gatewayPath, "src", "app.ts");
140
+ fs_1.default.appendFileSync(input, data);
141
+ };
142
+ const addServer = async (gatewayPath, serviceName) => {
143
+ const main = path_1.default.resolve(gatewayPath, "../../");
144
+ const inputPath = path_1.default.join(main, "src", "servers.json");
145
+ const { default: servers } = await Promise.resolve(`${inputPath}`).then(s => __importStar(require(s)));
146
+ servers.push(serviceName);
147
+ fs_1.default.writeFileSync(inputPath, JSON.stringify(servers, null, 2));
148
+ };
149
+ const app = async () => {
150
+ try {
151
+ const welcomeMessage = chalk_1.default.bgMagenta.white.bold("---💥 Welcome team ! 💥---\n");
152
+ log(welcomeMessage);
153
+ const { service } = await inquirer_1.default.prompt({
154
+ type: 'input',
155
+ name: 'service',
156
+ message: chalk_1.default.yellow('Enter service name || To exit app write :q\n')
157
+ });
158
+ if (service === ":q")
159
+ exitApp();
160
+ if (service === "pipeline")
161
+ exitApp("Pipeline name not allowed");
162
+ const serviceName = validateService(service);
163
+ const currentDir = path_1.default.join(process.cwd(), 'services');
164
+ const appPath = __dirname;
165
+ const rootPath = currentDir;
166
+ const pipelinePath = path_1.default.resolve(appPath, "../");
167
+ const gatewayPath = path_1.default.join(currentDir, "gateway");
168
+ const servicePath = path_1.default.join(rootPath, serviceName);
169
+ const srcPath = path_1.default.join(servicePath, "src");
170
+ const appFilePath = path_1.default.join(srcPath, "app.ts");
171
+ const filesListForCopy = [
172
+ "tsconfig.json"
173
+ ];
174
+ const filesListForCreate = [
175
+ ".controller.ts",
176
+ ".service.ts",
177
+ ".model.ts",
178
+ ".interface.ts",
179
+ ".enum.ts",
180
+ ".middleware.ts",
181
+ ".dto.ts",
182
+ ".router.ts"
183
+ ];
184
+ // Service folder
185
+ makeFolder(servicePath);
186
+ // Src folder inside service
187
+ makeFolder(srcPath);
188
+ // Creating app.ts
189
+ const newPort = getNewPort(pipelinePath);
190
+ fs_1.default.writeFileSync(appFilePath, (0, biolerplate_1.appBoilerplate)(serviceName, newPort), "utf-8");
191
+ // Change last port in pipeline
192
+ updateLastPort(pipelinePath, newPort);
193
+ createEnvForNewService(pipelinePath, servicePath, newPort);
194
+ createDockerFileForNewService(pipelinePath, servicePath, newPort);
195
+ createPackageForNewService(serviceName, servicePath);
196
+ // Copieng all required files for typescript
197
+ copyFiles(filesListForCopy, pipelinePath, servicePath);
198
+ // Creating required files for start coding
199
+ createFiles(filesListForCreate, serviceName, srcPath);
200
+ // Adding gateway
201
+ addGateway(gatewayPath, serviceName, newPort);
202
+ // Adding server
203
+ await addServer(gatewayPath, serviceName);
204
+ log(chalk_1.default.bgGreen.black.bold(" 🚀 Installing dependencies... Please wait ⏳ "));
205
+ await Exec("npm install", { cwd: servicePath });
206
+ log(chalk_1.default.bgYellow.black.bold(`Success - ${serviceName} created successfully !`));
207
+ log(chalk_1.default.green.bold(`🚀Browse service folder and write npm run dev`));
208
+ exitApp();
209
+ }
210
+ catch (err) {
211
+ if (err instanceof Error) {
212
+ log(chalk_1.default.bgRed.white.bold(` 🛑 Error - ${err.message} \n`));
213
+ app();
214
+ }
215
+ }
216
+ };
217
+ app();
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.gatewayBoilerplate = exports.packageBoilerplate = exports.modelBoilerplate = exports.interfaceBoilerplate = exports.routerBoilerplate = exports.appBoilerplate = void 0;
4
+ const getServiceInPascalCase = (service) => {
5
+ const arr = service.split("-");
6
+ const tmp = arr.map((item) => {
7
+ const firstLetter = item[0].toUpperCase();
8
+ const restLetter = item.slice(1);
9
+ return firstLetter + restLetter;
10
+ });
11
+ return tmp.join("");
12
+ };
13
+ const appBoilerplate = (service, port) => {
14
+ return [
15
+ `import dotenv from "dotenv"`,
16
+ `dotenv.config()\n`,
17
+ `import mongoose from "mongoose"`,
18
+ `mongoose.connect(process.env.DB!)`,
19
+ `.then(()=>console.log("${service} - Database is running"))`,
20
+ `.catch(()=>console.log("${service} - Failed to connect with database"))\n`,
21
+ `import express, { Request, Response } from "express"`,
22
+ `import ${getServiceInPascalCase(service)}Router from "./${service}.router"`,
23
+ `import morgan from "morgan"`,
24
+ `import cors from "cors"`,
25
+ `const app = express()`,
26
+ `app.listen(process.env.PORT, ()=>console.log("${service} service is running on - http://localhost:${port}/${service}"))\n`,
27
+ `app.use(cors({`,
28
+ `\torigin: process.env.CLIENT,`,
29
+ `\tcredentials: true`,
30
+ `}))`,
31
+ `app.use(express.json())`,
32
+ `app.use(express.urlencoded({extended: false}))\n`,
33
+ `app.use("/${service}", ${getServiceInPascalCase(service)}Router)`
34
+ ].join("\n");
35
+ };
36
+ exports.appBoilerplate = appBoilerplate;
37
+ const routerBoilerplate = (service) => {
38
+ return [
39
+ `import {Router, Request, Response} from "express"`,
40
+ `const ${getServiceInPascalCase(service)}Router = Router()\n`,
41
+ `${getServiceInPascalCase(service)}Router.get("/", (req: Request, res: Response)=>{`,
42
+ `\tres.json({message: "Hello from ${service} service"})`,
43
+ `})\n`,
44
+ `export default ${getServiceInPascalCase(service)}Router`
45
+ ].join("\n");
46
+ };
47
+ exports.routerBoilerplate = routerBoilerplate;
48
+ const interfaceBoilerplate = (service) => {
49
+ const Provider = getServiceInPascalCase(service);
50
+ return [
51
+ `import { Document } from "mongoose"\n`,
52
+ `export interface ${Provider}ModelInterface extends Document {\n`,
53
+ `\t`,
54
+ `}`
55
+ ].join("\n");
56
+ };
57
+ exports.interfaceBoilerplate = interfaceBoilerplate;
58
+ const modelBoilerplate = (service) => {
59
+ const Provider = getServiceInPascalCase(service);
60
+ return [
61
+ `import { Schema, model } from "mongoose"`,
62
+ `import { ${Provider}ModelInterface } from "./${service}.interface"\n`,
63
+ `const schema = new Schema<${Provider}ModelInterface>({\n`,
64
+ `\t`,
65
+ `}, {timestamps: true})\n`,
66
+ `const ${Provider}Model = model<${Provider}ModelInterface>("${Provider}", schema)`,
67
+ `export default ${Provider}Model`
68
+ ].join("\n");
69
+ };
70
+ exports.modelBoilerplate = modelBoilerplate;
71
+ const packageBoilerplate = (service) => {
72
+ const data = {
73
+ "name": service,
74
+ "version": "1.0.0",
75
+ "main": "index.js",
76
+ "scripts": {
77
+ "dev": "ts-node-dev --respawn --transpile-only src/app.ts",
78
+ "build": "tsc",
79
+ "start": "node dist/app.js"
80
+ },
81
+ "keywords": [],
82
+ "author": "",
83
+ "license": "ISC",
84
+ "description": "",
85
+ "dependencies": {
86
+ "cors": "^2.8.5",
87
+ "dotenv": "^17.0.0",
88
+ "express": "^5.1.0",
89
+ "mongoose": "^8.16.1",
90
+ "morgan": "^1.10.0"
91
+ },
92
+ "devDependencies": {
93
+ "@types/cors": "^2.8.19",
94
+ "@types/express": "^5.0.3",
95
+ "@types/morgan": "^1.9.10",
96
+ "@types/node": "^24.0.7",
97
+ "ts-node-dev": "^2.0.0",
98
+ "typescript": "^5.8.3"
99
+ }
100
+ };
101
+ return JSON.stringify(data, null, 2);
102
+ };
103
+ exports.packageBoilerplate = packageBoilerplate;
104
+ const gatewayBoilerplate = (service, port) => {
105
+ return [
106
+ `\n\napp.use("/${service}", createProxyMiddleware({`,
107
+ `\ttarget: 'http://localhost:${port}/${service}',`,
108
+ `\tchangeOrigin: true`,
109
+ `}))`
110
+ ].join("\n");
111
+ };
112
+ exports.gatewayBoilerplate = gatewayBoilerplate;
Binary file
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "ms-systems",
3
+ "version": "1.0.0",
4
+ "main": "dist/app.js",
5
+ "types": "dist/app.d.ts",
6
+ "bin": {
7
+ "ms-systems": "dist/app.js"
8
+ },
9
+ "scripts": {
10
+ "dev": "ts-node-dev --transpile-only src/app.ts",
11
+ "build": "tsc",
12
+ "start": "node dist/app.js"
13
+ },
14
+ "keywords": [],
15
+ "author": "",
16
+ "license": "ISC",
17
+ "description": "",
18
+ "dependencies": {
19
+ "chalk": "^5.4.1",
20
+ "cors": "^2.8.5",
21
+ "dotenv": "^17.0.0",
22
+ "express": "^5.1.0",
23
+ "gateway": "file:../..",
24
+ "inquirer": "^12.6.3",
25
+ "mongoose": "^8.16.1",
26
+ "morgan": "^1.10.0"
27
+ },
28
+ "devDependencies": {
29
+ "@types/cors": "^2.8.19",
30
+ "@types/express": "^5.0.3",
31
+ "@types/morgan": "^1.9.10",
32
+ "@types/node": "^24.0.7",
33
+ "ts-node-dev": "^2.0.0",
34
+ "typescript": "^5.8.3"
35
+ }
36
+ }