mwalajs 1.0.7 → 1.0.9
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/.env.backup-2025-12-04T08-55-09-593Z +5 -0
- package/app.mjs +4 -0
- package/bin/mwala copy.mjs +212 -0
- package/bin/mwala.mjs +244 -76
- package/config/createdatabase copy.mjs +362 -0
- package/config/createdatabase.mjs +0 -158
- package/package.json +1 -1
- package/public/images/hekima-mwala.jpg +0 -0
- package/public/images/hekima-mwala2.jpg +0 -0
- package/public/images/mwala3.jpg +0 -0
- package/public/images/mwalajs.jpg +0 -0
- package/public/images/mwalajs1.jpg +0 -0
- package/utils/dbUtils.mjs +150 -0
- package/views/about.ejs +271 -136
- package/views/index.ejs +325 -428
- package/views/mwalajs-framework-documentation.ejs +778 -0
- package/views/partials/footer.ejs +102 -0
- package/views/partials/header.ejs +160 -0
- package/views/steps copy.ejs +243 -0
- package/views/steps.ejs +208 -482
- package/views/welcome.ejs +242 -184
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import readlineSync from 'readline-sync';
|
|
3
|
+
import mysql from 'mysql2/promise';
|
|
4
|
+
import { MongoClient } from 'mongodb';
|
|
5
|
+
import sqlite3 from 'sqlite3';
|
|
6
|
+
import pkg from 'pg';
|
|
7
|
+
import dotenv from 'dotenv';
|
|
8
|
+
|
|
9
|
+
const { Client } = pkg;
|
|
10
|
+
|
|
11
|
+
/* -----------------------------------------------------------
|
|
12
|
+
NEW FUNCTION: CREATE BACKUP OF .ENV BEFORE DELETE
|
|
13
|
+
----------------------------------------------------------- */
|
|
14
|
+
const backupEnvFile = () => {
|
|
15
|
+
try {
|
|
16
|
+
if (!fs.existsSync('.env')) {
|
|
17
|
+
console.log(' ⚠️ No .env file found to backup.');
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const timestamp = new Date()
|
|
22
|
+
.toISOString()
|
|
23
|
+
.replace(/[:.]/g, '-'); // safe filename
|
|
24
|
+
|
|
25
|
+
const backupName = `.env.backup-${timestamp}`;
|
|
26
|
+
|
|
27
|
+
fs.copyFileSync('.env', backupName);
|
|
28
|
+
|
|
29
|
+
console.log(` 📦 Backup created: ${backupName}`);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.error(' ❌ Failed to create .env backup:', error.message);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/* -----------------------------------------------------------
|
|
36
|
+
RESET ENV FILE
|
|
37
|
+
----------------------------------------------------------- */
|
|
38
|
+
const resetEnvFile = () => {
|
|
39
|
+
try {
|
|
40
|
+
fs.writeFileSync('.env', '', 'utf8');
|
|
41
|
+
console.log(' 🧹 Cleared .env file.');
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.error(' ❌ Failed to clear .env file:', error.message);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/* -----------------------------------------------------------
|
|
48
|
+
WRITE DATA TO .ENV
|
|
49
|
+
----------------------------------------------------------- */
|
|
50
|
+
const writeToEnv = (data) => {
|
|
51
|
+
const envContent = Object.keys(data)
|
|
52
|
+
.map(key => `${key}=${data[key]}`)
|
|
53
|
+
.join('\n');
|
|
54
|
+
|
|
55
|
+
fs.writeFileSync('.env', envContent, 'utf8');
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/* -----------------------------------------------------------
|
|
59
|
+
MAIN FUNCTION: CREATE/CONNECT DATABASE
|
|
60
|
+
----------------------------------------------------------- */
|
|
61
|
+
export const getDbConnection = async () => {
|
|
62
|
+
|
|
63
|
+
// 🔥 FIRST CREATE BACKUP
|
|
64
|
+
backupEnvFile();
|
|
65
|
+
|
|
66
|
+
// 🔥 THEN CLEAR OLD ENV
|
|
67
|
+
resetEnvFile();
|
|
68
|
+
|
|
69
|
+
// Reload environment
|
|
70
|
+
dotenv.config();
|
|
71
|
+
|
|
72
|
+
const supportedDbTypes = {
|
|
73
|
+
mysql: 'mysql',
|
|
74
|
+
my: 'mysql',
|
|
75
|
+
postgresql: 'postgresql',
|
|
76
|
+
pg: 'postgresql',
|
|
77
|
+
mongodb: 'mongodb',
|
|
78
|
+
mn: 'mongodb',
|
|
79
|
+
sqlite: 'sqlite',
|
|
80
|
+
sq: 'sqlite'
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
let dbType;
|
|
84
|
+
while (true) {
|
|
85
|
+
dbType = readlineSync.question(
|
|
86
|
+
'Enter DB type (mysql/my, postgresql/pg, mongodb/mn, sqlite/sq): '
|
|
87
|
+
).toLowerCase();
|
|
88
|
+
|
|
89
|
+
if (supportedDbTypes[dbType]) {
|
|
90
|
+
dbType = supportedDbTypes[dbType];
|
|
91
|
+
break;
|
|
92
|
+
} else {
|
|
93
|
+
console.log(' ❌ Invalid database type. Try again.');
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const dbName = readlineSync.question('Enter the database name: ').trim();
|
|
98
|
+
if (!dbName) {
|
|
99
|
+
console.log(' ❌ Database name cannot be empty.');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
let dbHost = 'localhost';
|
|
104
|
+
let dbUser = '';
|
|
105
|
+
let dbPassword = '';
|
|
106
|
+
|
|
107
|
+
if (dbType !== 'sqlite') {
|
|
108
|
+
dbHost = readlineSync.question('Enter DB host (default: localhost): ') || 'localhost';
|
|
109
|
+
dbUser = readlineSync.question('Enter DB user: ').trim();
|
|
110
|
+
dbPassword = readlineSync.question('Enter DB password: ', { hideEchoBack: true }).trim();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const envData = {
|
|
114
|
+
DB_TYPE: dbType,
|
|
115
|
+
DB_NAME: dbName,
|
|
116
|
+
DB_HOST: dbHost,
|
|
117
|
+
DB_USER: dbUser,
|
|
118
|
+
DB_PASSWORD: dbPassword
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
writeToEnv(envData);
|
|
122
|
+
console.log(' Database credentials saved to .env');
|
|
123
|
+
|
|
124
|
+
let connection;
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
/* -------------------- MYSQL -------------------- */
|
|
128
|
+
if (dbType === 'mysql') {
|
|
129
|
+
const tempConnection = await mysql.createConnection({
|
|
130
|
+
host: dbHost,
|
|
131
|
+
user: dbUser,
|
|
132
|
+
password: dbPassword
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const [rows] = await tempConnection.query(`SHOW DATABASES LIKE '${dbName}'`);
|
|
136
|
+
if (rows.length === 0) {
|
|
137
|
+
await tempConnection.query(`CREATE DATABASE \`${dbName}\``);
|
|
138
|
+
console.log(` MySQL database "${dbName}" created.`);
|
|
139
|
+
} else {
|
|
140
|
+
console.log(` MySQL database "${dbName}" already exists.`);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
connection = await mysql.createConnection({
|
|
144
|
+
host: dbHost,
|
|
145
|
+
user: dbUser,
|
|
146
|
+
password: dbPassword,
|
|
147
|
+
database: dbName
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
await tempConnection.end();
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/* -------------------- POSTGRESQL -------------------- */
|
|
154
|
+
else if (dbType === 'postgresql') {
|
|
155
|
+
const tempClient = new Client({
|
|
156
|
+
host: dbHost,
|
|
157
|
+
user: dbUser,
|
|
158
|
+
password: dbPassword
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
await tempClient.connect();
|
|
162
|
+
|
|
163
|
+
const checkDb = await tempClient.query(
|
|
164
|
+
`SELECT datname FROM pg_database WHERE datname = '${dbName}'`
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
if (checkDb.rows.length === 0) {
|
|
168
|
+
await tempClient.query(`CREATE DATABASE ${dbName}`);
|
|
169
|
+
console.log(` PostgreSQL database "${dbName}" created.`);
|
|
170
|
+
} else {
|
|
171
|
+
console.log(` PostgreSQL database "${dbName}" already exists.`);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
await tempClient.end();
|
|
175
|
+
|
|
176
|
+
connection = new Client({
|
|
177
|
+
host: dbHost,
|
|
178
|
+
user: dbUser,
|
|
179
|
+
password: dbPassword,
|
|
180
|
+
database: dbName
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
await connection.connect();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/* -------------------- MONGODB -------------------- */
|
|
187
|
+
else if (dbType === 'mongodb') {
|
|
188
|
+
connection = await MongoClient.connect(`mongodb://${dbHost}:27017`);
|
|
189
|
+
console.log(` MongoDB connected.`);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/* -------------------- SQLITE -------------------- */
|
|
193
|
+
else if (dbType === 'sqlite') {
|
|
194
|
+
connection = new sqlite3.Database(`./${dbName}.sqlite`);
|
|
195
|
+
console.log(` SQLite database "${dbName}.sqlite" ready.`);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
} catch (error) {
|
|
199
|
+
console.error(` ❌ Failed to create database: ${error.message}`);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return connection;
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
// import fs from 'fs';
|
|
207
|
+
// import readlineSync from 'readline-sync';
|
|
208
|
+
// import mysql from 'mysql2/promise';
|
|
209
|
+
// import { MongoClient } from 'mongodb';
|
|
210
|
+
// import sqlite3 from 'sqlite3';
|
|
211
|
+
// import pkg from 'pg';
|
|
212
|
+
// import dotenv from 'dotenv';
|
|
213
|
+
|
|
214
|
+
// const { Client } = pkg;
|
|
215
|
+
|
|
216
|
+
// // Function to reset the .env file before processing
|
|
217
|
+
// const resetEnvFile = () => {
|
|
218
|
+
// try {
|
|
219
|
+
// fs.writeFileSync('.env', '', 'utf8'); // Empty the .env file
|
|
220
|
+
// console.log(' Cleared .env file.');
|
|
221
|
+
// } catch (error) {
|
|
222
|
+
// console.error(' Failed to clear .env file:', error.message);
|
|
223
|
+
// }
|
|
224
|
+
// };
|
|
225
|
+
|
|
226
|
+
// // Function to write data to the .env file
|
|
227
|
+
// const writeToEnv = (data) => {
|
|
228
|
+
// const envContent = Object.keys(data)
|
|
229
|
+
// .map(key => `${key}=${data[key]}`)
|
|
230
|
+
// .join('\n');
|
|
231
|
+
|
|
232
|
+
// fs.writeFileSync('.env', envContent, 'utf8');
|
|
233
|
+
// };
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
// // Function to create the database connection
|
|
237
|
+
// export const getDbConnection = async () => {
|
|
238
|
+
// resetEnvFile(); // Clear .env file before proceeding
|
|
239
|
+
|
|
240
|
+
// dotenv.config(); // Reload the (now empty) .env file
|
|
241
|
+
|
|
242
|
+
// // Supported database types
|
|
243
|
+
// const supportedDbTypes = {
|
|
244
|
+
// mysql: 'mysql',
|
|
245
|
+
// my: 'mysql',
|
|
246
|
+
// postgresql: 'postgresql',
|
|
247
|
+
// pg: 'postgresql',
|
|
248
|
+
// mongodb: 'mongodb',
|
|
249
|
+
// mn: 'mongodb',
|
|
250
|
+
// sqlite: 'sqlite',
|
|
251
|
+
// sq: 'sqlite'
|
|
252
|
+
// };
|
|
253
|
+
|
|
254
|
+
// let dbType;
|
|
255
|
+
// while (true) {
|
|
256
|
+
// dbType = readlineSync.question('Enter the database type (mysql/my, postgresql/pg, mongodb/mn, sqlite/sq): ').toLowerCase();
|
|
257
|
+
// if (supportedDbTypes[dbType]) {
|
|
258
|
+
// dbType = supportedDbTypes[dbType]; // Normalize input
|
|
259
|
+
// break;
|
|
260
|
+
// } else {
|
|
261
|
+
// console.log('❌ Invalid database type. Please enter a valid option.');
|
|
262
|
+
// }
|
|
263
|
+
// }
|
|
264
|
+
|
|
265
|
+
// // Prompt for database details
|
|
266
|
+
// const dbName = readlineSync.question('Enter the database name: ').trim();
|
|
267
|
+
// if (!dbName) {
|
|
268
|
+
// console.log(' Database name cannot be empty.');
|
|
269
|
+
// return;
|
|
270
|
+
// }
|
|
271
|
+
|
|
272
|
+
// let dbHost = 'localhost';
|
|
273
|
+
// let dbUser = '';
|
|
274
|
+
// let dbPassword = '';
|
|
275
|
+
|
|
276
|
+
// if (dbType !== 'sqlite') {
|
|
277
|
+
// dbHost = readlineSync.question('Enter the database host (default: localhost): ') || 'localhost';
|
|
278
|
+
// dbUser = readlineSync.question('Enter the database user: ').trim();
|
|
279
|
+
// dbPassword = readlineSync.question('Enter the database password: ', { hideEchoBack: true }).trim();
|
|
280
|
+
// }
|
|
281
|
+
|
|
282
|
+
// // Save valid details to .env
|
|
283
|
+
// const envData = {
|
|
284
|
+
// DB_TYPE: dbType,
|
|
285
|
+
// DB_NAME: dbName,
|
|
286
|
+
// DB_HOST: dbHost,
|
|
287
|
+
// DB_USER: dbUser,
|
|
288
|
+
// DB_PASSWORD: dbPassword,
|
|
289
|
+
// };
|
|
290
|
+
|
|
291
|
+
// writeToEnv(envData);
|
|
292
|
+
// console.log(' Database credentials saved to .env file.');
|
|
293
|
+
|
|
294
|
+
// let connection;
|
|
295
|
+
|
|
296
|
+
// try {
|
|
297
|
+
// if (dbType === 'mysql') {
|
|
298
|
+
// const tempConnection = await mysql.createConnection({
|
|
299
|
+
// host: dbHost,
|
|
300
|
+
// user: dbUser,
|
|
301
|
+
// password: dbPassword,
|
|
302
|
+
// });
|
|
303
|
+
|
|
304
|
+
// const [rows] = await tempConnection.query(`SHOW DATABASES LIKE '${dbName}'`);
|
|
305
|
+
// if (rows.length === 0) {
|
|
306
|
+
// await tempConnection.query(`CREATE DATABASE \`${dbName}\``);
|
|
307
|
+
// console.log(` MySQL Database "${dbName}" created successfully.`);
|
|
308
|
+
// } else {
|
|
309
|
+
// console.log(` MySQL Database "${dbName}" already exists.`);
|
|
310
|
+
// }
|
|
311
|
+
|
|
312
|
+
// connection = await mysql.createConnection({
|
|
313
|
+
// host: dbHost,
|
|
314
|
+
// user: dbUser,
|
|
315
|
+
// password: dbPassword,
|
|
316
|
+
// database: dbName,
|
|
317
|
+
// });
|
|
318
|
+
|
|
319
|
+
// await tempConnection.end();
|
|
320
|
+
// } else if (dbType === 'postgresql') {
|
|
321
|
+
// const tempClient = new Client({
|
|
322
|
+
// host: dbHost,
|
|
323
|
+
// user: dbUser,
|
|
324
|
+
// password: dbPassword,
|
|
325
|
+
// });
|
|
326
|
+
|
|
327
|
+
// await tempClient.connect();
|
|
328
|
+
|
|
329
|
+
// const checkDb = await tempClient.query(`SELECT datname FROM pg_database WHERE datname = '${dbName}'`);
|
|
330
|
+
// if (checkDb.rows.length === 0) {
|
|
331
|
+
// await tempClient.query(`CREATE DATABASE ${dbName}`);
|
|
332
|
+
// console.log(` PostgreSQL Database "${dbName}" created successfully.`);
|
|
333
|
+
// } else {
|
|
334
|
+
// console.log(` PostgreSQL Database "${dbName}" already exists.`);
|
|
335
|
+
// }
|
|
336
|
+
|
|
337
|
+
// await tempClient.end();
|
|
338
|
+
|
|
339
|
+
// connection = new Client({
|
|
340
|
+
// host: dbHost,
|
|
341
|
+
// user: dbUser,
|
|
342
|
+
// password: dbPassword,
|
|
343
|
+
// database: dbName,
|
|
344
|
+
// });
|
|
345
|
+
|
|
346
|
+
// await connection.connect();
|
|
347
|
+
// } else if (dbType === 'mongodb') {
|
|
348
|
+
// connection = await MongoClient.connect(`mongodb://${dbHost}:27017`);
|
|
349
|
+
// console.log(` MongoDB connection to "${dbName}" established.`);
|
|
350
|
+
// } else if (dbType === 'sqlite') {
|
|
351
|
+
// connection = new sqlite3.Database(`./${dbName}.sqlite`);
|
|
352
|
+
// console.log(` SQLite Database "${dbName}.sqlite" is ready.`);
|
|
353
|
+
// } else {
|
|
354
|
+
// throw new Error(` Unsupported DB type: ${dbType}`);
|
|
355
|
+
// }
|
|
356
|
+
// } catch (error) {
|
|
357
|
+
// console.error(` Failed to create database: ${error.message}`);
|
|
358
|
+
// return;
|
|
359
|
+
// }
|
|
360
|
+
|
|
361
|
+
// return connection;
|
|
362
|
+
// };
|
|
@@ -202,161 +202,3 @@ export const getDbConnection = async () => {
|
|
|
202
202
|
|
|
203
203
|
return connection;
|
|
204
204
|
};
|
|
205
|
-
|
|
206
|
-
// import fs from 'fs';
|
|
207
|
-
// import readlineSync from 'readline-sync';
|
|
208
|
-
// import mysql from 'mysql2/promise';
|
|
209
|
-
// import { MongoClient } from 'mongodb';
|
|
210
|
-
// import sqlite3 from 'sqlite3';
|
|
211
|
-
// import pkg from 'pg';
|
|
212
|
-
// import dotenv from 'dotenv';
|
|
213
|
-
|
|
214
|
-
// const { Client } = pkg;
|
|
215
|
-
|
|
216
|
-
// // Function to reset the .env file before processing
|
|
217
|
-
// const resetEnvFile = () => {
|
|
218
|
-
// try {
|
|
219
|
-
// fs.writeFileSync('.env', '', 'utf8'); // Empty the .env file
|
|
220
|
-
// console.log(' Cleared .env file.');
|
|
221
|
-
// } catch (error) {
|
|
222
|
-
// console.error(' Failed to clear .env file:', error.message);
|
|
223
|
-
// }
|
|
224
|
-
// };
|
|
225
|
-
|
|
226
|
-
// // Function to write data to the .env file
|
|
227
|
-
// const writeToEnv = (data) => {
|
|
228
|
-
// const envContent = Object.keys(data)
|
|
229
|
-
// .map(key => `${key}=${data[key]}`)
|
|
230
|
-
// .join('\n');
|
|
231
|
-
|
|
232
|
-
// fs.writeFileSync('.env', envContent, 'utf8');
|
|
233
|
-
// };
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
// // Function to create the database connection
|
|
237
|
-
// export const getDbConnection = async () => {
|
|
238
|
-
// resetEnvFile(); // Clear .env file before proceeding
|
|
239
|
-
|
|
240
|
-
// dotenv.config(); // Reload the (now empty) .env file
|
|
241
|
-
|
|
242
|
-
// // Supported database types
|
|
243
|
-
// const supportedDbTypes = {
|
|
244
|
-
// mysql: 'mysql',
|
|
245
|
-
// my: 'mysql',
|
|
246
|
-
// postgresql: 'postgresql',
|
|
247
|
-
// pg: 'postgresql',
|
|
248
|
-
// mongodb: 'mongodb',
|
|
249
|
-
// mn: 'mongodb',
|
|
250
|
-
// sqlite: 'sqlite',
|
|
251
|
-
// sq: 'sqlite'
|
|
252
|
-
// };
|
|
253
|
-
|
|
254
|
-
// let dbType;
|
|
255
|
-
// while (true) {
|
|
256
|
-
// dbType = readlineSync.question('Enter the database type (mysql/my, postgresql/pg, mongodb/mn, sqlite/sq): ').toLowerCase();
|
|
257
|
-
// if (supportedDbTypes[dbType]) {
|
|
258
|
-
// dbType = supportedDbTypes[dbType]; // Normalize input
|
|
259
|
-
// break;
|
|
260
|
-
// } else {
|
|
261
|
-
// console.log('❌ Invalid database type. Please enter a valid option.');
|
|
262
|
-
// }
|
|
263
|
-
// }
|
|
264
|
-
|
|
265
|
-
// // Prompt for database details
|
|
266
|
-
// const dbName = readlineSync.question('Enter the database name: ').trim();
|
|
267
|
-
// if (!dbName) {
|
|
268
|
-
// console.log(' Database name cannot be empty.');
|
|
269
|
-
// return;
|
|
270
|
-
// }
|
|
271
|
-
|
|
272
|
-
// let dbHost = 'localhost';
|
|
273
|
-
// let dbUser = '';
|
|
274
|
-
// let dbPassword = '';
|
|
275
|
-
|
|
276
|
-
// if (dbType !== 'sqlite') {
|
|
277
|
-
// dbHost = readlineSync.question('Enter the database host (default: localhost): ') || 'localhost';
|
|
278
|
-
// dbUser = readlineSync.question('Enter the database user: ').trim();
|
|
279
|
-
// dbPassword = readlineSync.question('Enter the database password: ', { hideEchoBack: true }).trim();
|
|
280
|
-
// }
|
|
281
|
-
|
|
282
|
-
// // Save valid details to .env
|
|
283
|
-
// const envData = {
|
|
284
|
-
// DB_TYPE: dbType,
|
|
285
|
-
// DB_NAME: dbName,
|
|
286
|
-
// DB_HOST: dbHost,
|
|
287
|
-
// DB_USER: dbUser,
|
|
288
|
-
// DB_PASSWORD: dbPassword,
|
|
289
|
-
// };
|
|
290
|
-
|
|
291
|
-
// writeToEnv(envData);
|
|
292
|
-
// console.log(' Database credentials saved to .env file.');
|
|
293
|
-
|
|
294
|
-
// let connection;
|
|
295
|
-
|
|
296
|
-
// try {
|
|
297
|
-
// if (dbType === 'mysql') {
|
|
298
|
-
// const tempConnection = await mysql.createConnection({
|
|
299
|
-
// host: dbHost,
|
|
300
|
-
// user: dbUser,
|
|
301
|
-
// password: dbPassword,
|
|
302
|
-
// });
|
|
303
|
-
|
|
304
|
-
// const [rows] = await tempConnection.query(`SHOW DATABASES LIKE '${dbName}'`);
|
|
305
|
-
// if (rows.length === 0) {
|
|
306
|
-
// await tempConnection.query(`CREATE DATABASE \`${dbName}\``);
|
|
307
|
-
// console.log(` MySQL Database "${dbName}" created successfully.`);
|
|
308
|
-
// } else {
|
|
309
|
-
// console.log(` MySQL Database "${dbName}" already exists.`);
|
|
310
|
-
// }
|
|
311
|
-
|
|
312
|
-
// connection = await mysql.createConnection({
|
|
313
|
-
// host: dbHost,
|
|
314
|
-
// user: dbUser,
|
|
315
|
-
// password: dbPassword,
|
|
316
|
-
// database: dbName,
|
|
317
|
-
// });
|
|
318
|
-
|
|
319
|
-
// await tempConnection.end();
|
|
320
|
-
// } else if (dbType === 'postgresql') {
|
|
321
|
-
// const tempClient = new Client({
|
|
322
|
-
// host: dbHost,
|
|
323
|
-
// user: dbUser,
|
|
324
|
-
// password: dbPassword,
|
|
325
|
-
// });
|
|
326
|
-
|
|
327
|
-
// await tempClient.connect();
|
|
328
|
-
|
|
329
|
-
// const checkDb = await tempClient.query(`SELECT datname FROM pg_database WHERE datname = '${dbName}'`);
|
|
330
|
-
// if (checkDb.rows.length === 0) {
|
|
331
|
-
// await tempClient.query(`CREATE DATABASE ${dbName}`);
|
|
332
|
-
// console.log(` PostgreSQL Database "${dbName}" created successfully.`);
|
|
333
|
-
// } else {
|
|
334
|
-
// console.log(` PostgreSQL Database "${dbName}" already exists.`);
|
|
335
|
-
// }
|
|
336
|
-
|
|
337
|
-
// await tempClient.end();
|
|
338
|
-
|
|
339
|
-
// connection = new Client({
|
|
340
|
-
// host: dbHost,
|
|
341
|
-
// user: dbUser,
|
|
342
|
-
// password: dbPassword,
|
|
343
|
-
// database: dbName,
|
|
344
|
-
// });
|
|
345
|
-
|
|
346
|
-
// await connection.connect();
|
|
347
|
-
// } else if (dbType === 'mongodb') {
|
|
348
|
-
// connection = await MongoClient.connect(`mongodb://${dbHost}:27017`);
|
|
349
|
-
// console.log(` MongoDB connection to "${dbName}" established.`);
|
|
350
|
-
// } else if (dbType === 'sqlite') {
|
|
351
|
-
// connection = new sqlite3.Database(`./${dbName}.sqlite`);
|
|
352
|
-
// console.log(` SQLite Database "${dbName}.sqlite" is ready.`);
|
|
353
|
-
// } else {
|
|
354
|
-
// throw new Error(` Unsupported DB type: ${dbType}`);
|
|
355
|
-
// }
|
|
356
|
-
// } catch (error) {
|
|
357
|
-
// console.error(` Failed to create database: ${error.message}`);
|
|
358
|
-
// return;
|
|
359
|
-
// }
|
|
360
|
-
|
|
361
|
-
// return connection;
|
|
362
|
-
// };
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
import dotenv from 'dotenv';
|
|
5
|
+
import mysql from 'mysql2/promise';
|
|
6
|
+
import { Client } from 'pg';
|
|
7
|
+
import { MongoClient } from 'mongodb';
|
|
8
|
+
import sqlite3 from 'sqlite3';
|
|
9
|
+
import readlineSync from 'readline-sync';
|
|
10
|
+
|
|
11
|
+
dotenv.config();
|
|
12
|
+
|
|
13
|
+
const { DB_TYPE, DB_HOST = 'localhost', DB_USER, DB_PASSWORD, DB_NAME } = process.env;
|
|
14
|
+
|
|
15
|
+
let conn = null;
|
|
16
|
+
|
|
17
|
+
const getConn = async () => {
|
|
18
|
+
if (conn) return conn;
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
if (DB_TYPE === 'mysql') {
|
|
22
|
+
conn = await mysql.createConnection({
|
|
23
|
+
host: DB_HOST,
|
|
24
|
+
user: DB_USER,
|
|
25
|
+
password: DB_PASSWORD,
|
|
26
|
+
database: DB_NAME
|
|
27
|
+
});
|
|
28
|
+
} else if (DB_TYPE === 'postgresql') {
|
|
29
|
+
conn = new Client({
|
|
30
|
+
host: DB_HOST,
|
|
31
|
+
user: DB_USER,
|
|
32
|
+
password: DB_PASSWORD,
|
|
33
|
+
database: DB_NAME
|
|
34
|
+
});
|
|
35
|
+
await conn.connect();
|
|
36
|
+
} else if (DB_TYPE === 'sqlite') {
|
|
37
|
+
conn = new sqlite3.Database(`./${DB_NAME}.sqlite`);
|
|
38
|
+
} else if (DB_TYPE === 'mongodb') {
|
|
39
|
+
conn = await MongoClient.connect(`mongodb://${DB_HOST}:27017`);
|
|
40
|
+
conn = conn.db(DB_NAME);
|
|
41
|
+
}
|
|
42
|
+
} catch (err) {
|
|
43
|
+
console.error('Connection failed:', err.message);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return conn;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const listTables = async () => {
|
|
51
|
+
const connection = await getConn();
|
|
52
|
+
if (DB_TYPE === 'mysql') {
|
|
53
|
+
const [rows] = await connection.query('SHOW TABLES');
|
|
54
|
+
console.log('Tables:\n', rows.map(r => Object.values(r)[0]).join('\n'));
|
|
55
|
+
} else if (DB_TYPE === 'postgresql') {
|
|
56
|
+
const res = await connection.query("SELECT tablename FROM pg_tables WHERE schemaname = 'public'");
|
|
57
|
+
console.log('Tables:\n', res.rows.map(r => r.tablename).join('\n'));
|
|
58
|
+
} else if (DB_TYPE === 'sqlite') {
|
|
59
|
+
connection.all("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'", (_, rows) => {
|
|
60
|
+
console.log('Tables:\n', rows.map(r => r.name).join('\n'));
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export const describeTable = async (table) => {
|
|
66
|
+
const connection = await getConn();
|
|
67
|
+
if (DB_TYPE === 'mysql') {
|
|
68
|
+
const [rows] = await connection.query(`DESCRIBE \`${table}\``);
|
|
69
|
+
console.table(rows);
|
|
70
|
+
} else if (DB_TYPE === 'postgresql') {
|
|
71
|
+
const res = await connection.query(`
|
|
72
|
+
SELECT column_name, data_type, is_nullable, column_default
|
|
73
|
+
FROM information_schema.columns WHERE table_name = $1
|
|
74
|
+
`, [table]);
|
|
75
|
+
console.table(res.rows);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export const countRows = async (table) => {
|
|
80
|
+
const connection = await getConn();
|
|
81
|
+
const [res] = await connection.query(`SELECT COUNT(*) AS count FROM \`${table}\``);
|
|
82
|
+
console.log(`Rows in ${table}: ${res[0].count}`);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const truncateTable = async (table) => {
|
|
86
|
+
const connection = await getConn();
|
|
87
|
+
await connection.query(`TRUNCATE TABLE \`${table}\` RESTART IDENTITY CASCADE`);
|
|
88
|
+
console.log(`✅ ${table} truncated`);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export const renameTable = async (oldName, newName) => {
|
|
92
|
+
const connection = await getConn();
|
|
93
|
+
await connection.query(`ALTER TABLE \`${oldName}\` RENAME TO \`${newName}\``);
|
|
94
|
+
console.log(`Renamed ${oldName} → ${newName}`);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export const backupDatabase = () => {
|
|
98
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
99
|
+
const file = `backup-${DB_NAME}-${timestamp}.sql`;
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
if (DB_TYPE === 'mysql') {
|
|
103
|
+
execSync(`mysqldump -h ${DB_HOST} -u ${DB_USER} -p${DB_PASSWORD} ${DB_NAME} > ${file}`);
|
|
104
|
+
} else if (DB_TYPE === 'postgresql') {
|
|
105
|
+
process.env.PGPASSWORD = DB_PASSWORD;
|
|
106
|
+
execSync(`pg_dump -h ${DB_HOST} -U ${DB_USER} ${DB_NAME} > ${file}`);
|
|
107
|
+
}
|
|
108
|
+
console.log(`✅ Backup saved: ${file}`);
|
|
109
|
+
} catch (err) {
|
|
110
|
+
console.error('Backup failed:', err.message);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export const restoreDatabase = (file) => {
|
|
115
|
+
if (!fs.existsSync(file)) {
|
|
116
|
+
console.error('Backup file not found');
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
if (DB_TYPE === 'mysql') {
|
|
121
|
+
execSync(`mysql -h ${DB_HOST} -u ${DB_USER} -p${DB_PASSWORD} ${DB_NAME} < ${file}`);
|
|
122
|
+
} else if (DB_TYPE === 'postgresql') {
|
|
123
|
+
process.env.PGPASSWORD = DB_PASSWORD;
|
|
124
|
+
execSync(`psql -h ${DB_HOST} -U ${DB_USER} -d ${DB_NAME} -f ${file}`);
|
|
125
|
+
}
|
|
126
|
+
console.log('✅ Database restored');
|
|
127
|
+
} catch (err) {
|
|
128
|
+
console.error('Restore failed:', err.message);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export const showDatabaseSize = () => console.log(`Size info not implemented for ${DB_TYPE} yet`);
|
|
133
|
+
export const listIndexes = () => console.log('Indexes list coming soon');
|
|
134
|
+
export const vacuumDatabase = () => console.log('VACUUM/optimize not implemented yet');
|
|
135
|
+
export const showConnections = () => console.log('Connections list not implemented');
|
|
136
|
+
export const killConnections = () => console.log('Kill connections not implemented');
|
|
137
|
+
export const dropAllTables = () => console.log('Drop all tables not implemented (too dangerous without confirmation logic)');
|
|
138
|
+
export const copyTable = () => console.log('Copy table not implemented');
|
|
139
|
+
export const exportTableToCsv = () => console.log('CSV export not implemented');
|
|
140
|
+
export const importCsvToTable = () => console.log('CSV import not implemented');
|
|
141
|
+
export const seedDatabase = (file) => {
|
|
142
|
+
if (fs.existsSync(file)) {
|
|
143
|
+
import(pathToFileURL(path.resolve(file)).href).then(mod => {
|
|
144
|
+
console.log('Seed executed');
|
|
145
|
+
});
|
|
146
|
+
} else {
|
|
147
|
+
console.error('Seed file not found');
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
export const checkTableExists = () => console.log('Check exists not implemented');
|