db-model-router 1.0.2 → 1.0.4

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.
@@ -1,359 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const path = require("path");
4
- const fs = require("fs");
5
- const { execFileSync } = require("child_process");
6
-
7
- const DB_TYPE_MAP = {
8
- mysql: "mysql",
9
- postgres: "postgres",
10
- postgresql: "postgres",
11
- sqlite3: "sqlite3",
12
- mssql: "mssql",
13
- oracle: "oracle",
14
- cockroachdb: "cockroachdb",
15
- };
16
-
17
- const SUPPORTED_TYPES = Object.keys(DB_TYPE_MAP);
18
-
19
- function ensureDir(dir) {
20
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
21
- }
22
-
23
- function generateAppJs(dbType) {
24
- return `let express;
25
- try { express = require("ultimate-express"); } catch (_) { express = require("express"); }
26
- const { init, db } = require("db-model-router");
27
- const logger = require("./middleware/logger");
28
- const routes = require("./routes");
29
-
30
- // Load environment variables
31
- require("dotenv").config();
32
-
33
- // Initialize database adapter
34
- init("${dbType}");
35
- db.connect({
36
- host: process.env.DB_HOST || "localhost",
37
- port: process.env.DB_PORT,
38
- database: process.env.DB_NAME,
39
- user: process.env.DB_USER,
40
- password: process.env.DB_PASS,
41
- });
42
-
43
- const app = express();
44
- const PORT = process.env.PORT || 3000;
45
-
46
- // Middleware
47
- app.use(express.json());
48
- app.use(express.urlencoded({ extended: true }));
49
- app.use(logger);
50
-
51
- // Routes
52
- app.use("/api", routes);
53
-
54
- // Health check
55
- app.get("/health", (req, res) => {
56
- res.json({ status: "ok", timestamp: new Date().toISOString() });
57
- });
58
-
59
- // Error handler
60
- app.use((err, req, res, next) => {
61
- console.error(err.stack);
62
- res.status(500).json({ type: "danger", message: "Internal Server Error" });
63
- });
64
-
65
- app.listen(PORT, () => {
66
- console.log(\`Server running on port \${PORT}\`);
67
- });
68
-
69
- module.exports = app;
70
- `;
71
- }
72
-
73
- function generateLoggerMiddleware() {
74
- return `/**
75
- * Simple request logger middleware.
76
- * Logs method, URL, status code, and response time.
77
- */
78
- module.exports = function logger(req, res, next) {
79
- const start = Date.now();
80
- const { method, originalUrl } = req;
81
-
82
- res.on("finish", () => {
83
- const duration = Date.now() - start;
84
- const status = res.statusCode;
85
- const level = status >= 400 ? "WARN" : "INFO";
86
- console.log(
87
- \`[\${new Date().toISOString()}] [\${level}] \${method} \${originalUrl} \${status} \${duration}ms\`,
88
- );
89
- });
90
-
91
- next();
92
- };
93
- `;
94
- }
95
-
96
- function generateEnvExample(dbType) {
97
- const lines = [
98
- "# Server",
99
- "PORT=3000",
100
- "",
101
- "# Database",
102
- `DB_TYPE=${dbType}`,
103
- ];
104
- switch (dbType) {
105
- case "mysql":
106
- lines.push(
107
- "DB_HOST=localhost",
108
- "DB_PORT=3306",
109
- "DB_NAME=my_app",
110
- "DB_USER=root",
111
- "DB_PASS=password",
112
- );
113
- break;
114
- case "postgres":
115
- case "cockroachdb":
116
- lines.push(
117
- "DB_HOST=localhost",
118
- `DB_PORT=${dbType === "cockroachdb" ? 26257 : 5432}`,
119
- "DB_NAME=my_app",
120
- "DB_USER=postgres",
121
- "DB_PASS=password",
122
- );
123
- break;
124
- case "sqlite3":
125
- lines.push("DB_NAME=./data.db");
126
- break;
127
- case "mssql":
128
- lines.push(
129
- "DB_HOST=localhost",
130
- "DB_PORT=1433",
131
- "DB_NAME=my_app",
132
- "DB_USER=sa",
133
- "DB_PASS=password",
134
- );
135
- break;
136
- case "oracle":
137
- lines.push(
138
- "DB_HOST=localhost",
139
- "DB_PORT=1521",
140
- "DB_NAME=my_app",
141
- "DB_USER=system",
142
- "DB_PASS=password",
143
- );
144
- break;
145
- case "mongodb":
146
- lines.push(
147
- "DB_HOST=localhost",
148
- "DB_PORT=27017",
149
- "DB_NAME=my_app",
150
- "DB_USER=",
151
- "DB_PASS=",
152
- );
153
- break;
154
- case "redis":
155
- lines.push("DB_HOST=localhost", "DB_PORT=6379", "DB_PASS=");
156
- break;
157
- case "dynamodb":
158
- lines.push(
159
- "AWS_REGION=us-east-1",
160
- "AWS_ENDPOINT=http://localhost:8000",
161
- "AWS_ACCESS_KEY_ID=local",
162
- "AWS_SECRET_ACCESS_KEY=local",
163
- );
164
- break;
165
- default:
166
- lines.push(
167
- "DB_HOST=localhost",
168
- "DB_PORT=3306",
169
- "DB_NAME=my_app",
170
- "DB_USER=root",
171
- "DB_PASS=password",
172
- );
173
- }
174
- return lines.join("\n") + "\n";
175
- }
176
-
177
- function generateGitignore() {
178
- return `node_modules/
179
- .env
180
- *.db
181
- `;
182
- }
183
-
184
- async function main() {
185
- const args = parseArgs(process.argv.slice(2));
186
-
187
- if (args.help) {
188
- printUsage();
189
- process.exit(0);
190
- }
191
-
192
- const dbType = DB_TYPE_MAP[(args.type || "").toLowerCase()];
193
- if (!dbType) {
194
- console.error(
195
- `Error: --type is required. Supported: ${SUPPORTED_TYPES.join(", ")}`,
196
- );
197
- process.exit(1);
198
- }
199
-
200
- const outputDir = path.resolve(args.output || ".");
201
- const modelsDir = path.join(outputDir, "models");
202
- const routesDir = path.join(outputDir, "routes");
203
- const middlewareDir = path.join(outputDir, "middleware");
204
- const migrationsDir = path.join(outputDir, "migrations");
205
- const sessionsDir = path.join(outputDir, "sessions");
206
-
207
- console.log(`Scaffolding app in ${outputDir}...\n`);
208
-
209
- // Create directories
210
- for (const dir of [outputDir, middlewareDir, migrationsDir, sessionsDir]) {
211
- ensureDir(dir);
212
- }
213
-
214
- // Generate models via generate-model CLI
215
- const generateModelArgs = ["--type", dbType, "--output", modelsDir];
216
- if (args.host) generateModelArgs.push("--host", args.host);
217
- if (args.port) generateModelArgs.push("--port", args.port);
218
- if (args.database) generateModelArgs.push("--database", args.database);
219
- if (args.user) generateModelArgs.push("--user", args.user);
220
- if (args.password) generateModelArgs.push("--password", args.password);
221
- if (args.schema) generateModelArgs.push("--schema", args.schema);
222
- if (args.env) generateModelArgs.push("--env", args.env);
223
- if (args.tables) generateModelArgs.push("--tables", args.tables);
224
-
225
- try {
226
- execFileSync(
227
- process.execPath,
228
- [path.join(__dirname, "generate-model.js"), ...generateModelArgs],
229
- { stdio: "inherit" },
230
- );
231
- } catch (err) {
232
- console.error("Model generation failed.");
233
- process.exit(1);
234
- }
235
-
236
- // Generate routes via generate-route CLI
237
- const generateRouteArgs = ["--models", modelsDir, "--output", routesDir];
238
- if (args.tables) generateRouteArgs.push("--tables", args.tables);
239
-
240
- try {
241
- execFileSync(
242
- process.execPath,
243
- [path.join(__dirname, "generate-route.js"), ...generateRouteArgs],
244
- { stdio: "inherit" },
245
- );
246
- } catch (err) {
247
- console.error("Route generation failed.");
248
- process.exit(1);
249
- }
250
-
251
- // Write app.js
252
- const appPath = path.join(outputDir, "app.js");
253
- if (!fs.existsSync(appPath)) {
254
- fs.writeFileSync(appPath, generateAppJs(dbType));
255
- console.log(` Created ${appPath}`);
256
- } else {
257
- console.log(` Skipped ${appPath} (already exists)`);
258
- }
259
-
260
- // Write middleware/logger.js
261
- const loggerPath = path.join(middlewareDir, "logger.js");
262
- if (!fs.existsSync(loggerPath)) {
263
- fs.writeFileSync(loggerPath, generateLoggerMiddleware());
264
- console.log(` Created ${loggerPath}`);
265
- }
266
-
267
- // Write .env.example
268
- const envPath = path.join(outputDir, ".env.example");
269
- if (!fs.existsSync(envPath)) {
270
- fs.writeFileSync(envPath, generateEnvExample(dbType));
271
- console.log(` Created ${envPath}`);
272
- }
273
-
274
- // Write .gitignore
275
- const gitignorePath = path.join(outputDir, ".gitignore");
276
- if (!fs.existsSync(gitignorePath)) {
277
- fs.writeFileSync(gitignorePath, generateGitignore());
278
- console.log(` Created ${gitignorePath}`);
279
- }
280
-
281
- // Write placeholder files
282
- const migrationReadme = path.join(migrationsDir, "README.md");
283
- if (!fs.existsSync(migrationReadme)) {
284
- fs.writeFileSync(
285
- migrationReadme,
286
- "# Migrations\n\nPlace your database migration scripts here.\n",
287
- );
288
- }
289
- const sessionReadme = path.join(sessionsDir, "README.md");
290
- if (!fs.existsSync(sessionReadme)) {
291
- fs.writeFileSync(
292
- sessionReadme,
293
- "# Sessions\n\nSession configuration and store setup.\n",
294
- );
295
- }
296
-
297
- console.log("\nApp scaffolded. To start:");
298
- console.log(` cp .env.example .env`);
299
- console.log(` npm install`);
300
- console.log(` node app.js`);
301
- }
302
-
303
- function parseArgs(argv) {
304
- const args = {};
305
- for (let i = 0; i < argv.length; i++) {
306
- const arg = argv[i];
307
- if (arg.startsWith("--")) {
308
- const key = arg.slice(2);
309
- const next = argv[i + 1];
310
- if (next && !next.startsWith("--")) {
311
- args[key] = next;
312
- i++;
313
- } else {
314
- args[key] = true;
315
- }
316
- }
317
- }
318
- return args;
319
- }
320
-
321
- function printUsage() {
322
- console.log(`
323
- Usage: db-model-router-generate-app --type <db_type> [options]
324
-
325
- Scaffolds a complete Express REST API app from an existing database.
326
- Creates: app.js, models/, routes/, middleware/logger.js, migrations/, sessions/, .env.example
327
-
328
- Options:
329
- --type Database type (${SUPPORTED_TYPES.join(", ")}) [required]
330
- --output Output directory (default: current directory)
331
- --host Database host
332
- --port Database port
333
- --database Database name or file path
334
- --user Database user
335
- --password Database password
336
- --schema Schema name (postgres only)
337
- --tables Comma-separated tables (supports parent.child notation)
338
- --env Path to .env file for DB connection
339
- --help Show this help message
340
-
341
- Examples:
342
- db-model-router-generate-app --type mysql --env .env
343
- db-model-router-generate-app --type sqlite3 --database ./myapp.db --output ./my-api
344
- db-model-router-generate-app --type postgres --env .env --tables users,posts,posts.comments
345
- `);
346
- }
347
-
348
- if (require.main === module) {
349
- main().catch((err) => {
350
- console.error("Error:", err.message);
351
- process.exit(1);
352
- });
353
- }
354
-
355
- module.exports = {
356
- generateAppJs,
357
- generateLoggerMiddleware,
358
- generateEnvExample,
359
- };