mwalajs 1.1.1 → 1.1.3
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.
|
File without changes
|
|
File without changes
|
package/bin/mwala.mjs
CHANGED
|
@@ -43,7 +43,7 @@ const {
|
|
|
43
43
|
if (!command || command === 'help' || command === 'h') {
|
|
44
44
|
console.log(`
|
|
45
45
|
╔══════════════════════════════════════════════════════════╗
|
|
46
|
-
║ MwalaJS CLI
|
|
46
|
+
║ MwalaJS CLI ║
|
|
47
47
|
╚══════════════════════════════════════════════════════════╝
|
|
48
48
|
|
|
49
49
|
General:
|
|
@@ -181,7 +181,7 @@ switch (command) {
|
|
|
181
181
|
|
|
182
182
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
183
183
|
fs.writeFileSync(filePath, content);
|
|
184
|
-
console.log(
|
|
184
|
+
console.log(` ${name} ${type} created at ${folders[type]}/${name}.mjs`);
|
|
185
185
|
break;
|
|
186
186
|
}
|
|
187
187
|
|
|
@@ -189,7 +189,7 @@ switch (command) {
|
|
|
189
189
|
|
|
190
190
|
case 'create-db':
|
|
191
191
|
getDbConnection()
|
|
192
|
-
.then(() => console.log('
|
|
192
|
+
.then(() => console.log(' Database configured and connected successfully!'))
|
|
193
193
|
.catch(err => {
|
|
194
194
|
console.error('❌ Database setup failed:', err.message);
|
|
195
195
|
process.exit(1);
|
package/package.json
CHANGED
package/utils/dbUtils.mjs
CHANGED
|
@@ -12,27 +12,74 @@ import sqlite3 from 'sqlite3';
|
|
|
12
12
|
import readlineSync from 'readline-sync';
|
|
13
13
|
import { fileURLToPath } from 'url';
|
|
14
14
|
|
|
15
|
-
// Load .env
|
|
16
|
-
|
|
15
|
+
// Load .env from current project directory (important!)
|
|
16
|
+
const envPath = path.join(process.cwd(), '.env');
|
|
17
|
+
if (fs.existsSync(envPath)) {
|
|
18
|
+
dotenv.config({ path: envPath });
|
|
19
|
+
} else {
|
|
20
|
+
dotenv.config(); // fallback to default behavior
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const {
|
|
24
|
+
DB_TYPE,
|
|
25
|
+
DB_HOST = 'localhost',
|
|
26
|
+
DB_USER,
|
|
27
|
+
DB_PASSWORD = '', // Allow empty or missing password
|
|
28
|
+
DB_NAME,
|
|
29
|
+
DB_PORT
|
|
30
|
+
} = process.env;
|
|
31
|
+
|
|
32
|
+
// FIXED: Smart config check - allows empty password for MySQL/PostgreSQL
|
|
33
|
+
const isDbConfigured = () => {
|
|
34
|
+
if (!DB_TYPE || !DB_NAME) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
17
37
|
|
|
18
|
-
|
|
38
|
+
// SQLite and MongoDB don't need user/password
|
|
39
|
+
if (DB_TYPE === 'sqlite' || DB_TYPE === 'mongodb') {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
19
42
|
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
return DB_TYPE && DB_NAME && (DB_TYPE === 'sqlite' || (DB_USER && DB_PASSWORD));
|
|
43
|
+
// MySQL/PostgreSQL: need user, but password can be empty
|
|
44
|
+
return !!DB_USER; // Only require DB_USER, not DB_PASSWORD
|
|
23
45
|
};
|
|
24
46
|
|
|
25
47
|
const suggestDbSetup = () => {
|
|
26
48
|
console.log('\n⚠️ Database not configured or connection failed.');
|
|
27
49
|
console.log(' Run: mwala create-db → to set up your database interactively');
|
|
28
|
-
console.log(' Or manually create a .env file with:');
|
|
50
|
+
console.log(' Or manually create a .env file in your project folder with:');
|
|
29
51
|
console.log(' DB_TYPE=mysql|postgresql|sqlite|mongodb');
|
|
30
52
|
console.log(' DB_NAME=your_db_name');
|
|
31
53
|
console.log(' DB_HOST=localhost');
|
|
32
54
|
console.log(' DB_USER=your_user');
|
|
33
|
-
console.log(' DB_PASSWORD=
|
|
55
|
+
console.log(' DB_PASSWORD= ← can be empty (just leave blank)\n');
|
|
34
56
|
};
|
|
35
57
|
|
|
58
|
+
// === WINDOWS MYSQL TOOLS AUTO-DETECTION ===
|
|
59
|
+
let mysqlTools = null;
|
|
60
|
+
if (process.platform === 'win32') {
|
|
61
|
+
const commonPaths = [
|
|
62
|
+
'C:\\Program Files\\MySQL\\MySQL Server 8.0\\bin',
|
|
63
|
+
'C:\\Program Files\\MySQL\\MySQL Server 8.4\\bin',
|
|
64
|
+
'C:\\Program Files (x86)\\MySQL\\MySQL Server 8.0\\bin',
|
|
65
|
+
'C:\\xampp\\mysql\\bin',
|
|
66
|
+
'C:\\wamp64\\bin\\mysql\\mysql8.0.31\\bin',
|
|
67
|
+
'C:\\laragon\\bin\\mysql\\mysql-8.0.30-winx64\\bin',
|
|
68
|
+
'C:\\Program Files\\MariaDB 10.6\\bin',
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
for (const basePath of commonPaths) {
|
|
72
|
+
if (fs.existsSync(basePath)) {
|
|
73
|
+
const mysqldump = path.join(basePath, 'mysqldump.exe');
|
|
74
|
+
const mysqlCmd = path.join(basePath, 'mysql.exe');
|
|
75
|
+
if (fs.existsSync(mysqldump) && fs.existsSync(mysqlCmd)) {
|
|
76
|
+
mysqlTools = { mysqldump, mysql: mysqlCmd };
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
36
83
|
// Global connection cache
|
|
37
84
|
let connection = null;
|
|
38
85
|
|
|
@@ -63,7 +110,8 @@ const getConnection = async () => {
|
|
|
63
110
|
});
|
|
64
111
|
await connection.connect();
|
|
65
112
|
} else if (DB_TYPE === 'sqlite') {
|
|
66
|
-
|
|
113
|
+
const dbPath = path.join(process.cwd(), `${DB_NAME}.sqlite`);
|
|
114
|
+
connection = new sqlite3.Database(dbPath);
|
|
67
115
|
connection.serialize();
|
|
68
116
|
} else if (DB_TYPE === 'mongodb') {
|
|
69
117
|
const client = await MongoClient.connect(`mongodb://${DB_HOST}:${DB_PORT || 27017}`);
|
|
@@ -275,19 +323,43 @@ export const backupDatabase = () => {
|
|
|
275
323
|
|
|
276
324
|
try {
|
|
277
325
|
if (DB_TYPE === 'mysql') {
|
|
278
|
-
|
|
326
|
+
let cmd;
|
|
327
|
+
if (process.platform === 'win32' && mysqlTools) {
|
|
328
|
+
// Use full path on Windows
|
|
329
|
+
cmd = `"${mysqlTools.mysqldump}" -h ${DB_HOST} -u ${DB_USER} ${DB_PASSWORD ? '-p' + DB_PASSWORD : ''} ${DB_NAME} > "${file}"`;
|
|
330
|
+
} else {
|
|
331
|
+
// Linux/macOS or if in PATH
|
|
332
|
+
cmd = `mysqldump -h ${DB_HOST} -u ${DB_USER} ${DB_PASSWORD ? '-p' + DB_PASSWORD : ''} ${DB_NAME} > "${file}"`;
|
|
333
|
+
}
|
|
334
|
+
execSync(cmd, { stdio: 'inherit' });
|
|
279
335
|
}
|
|
280
336
|
else if (DB_TYPE === 'postgresql') {
|
|
281
337
|
process.env.PGPASSWORD = DB_PASSWORD;
|
|
282
|
-
execSync(`pg_dump -h ${DB_HOST} -U ${DB_USER} ${DB_NAME} > "${file}"
|
|
338
|
+
execSync(`pg_dump -h ${DB_HOST} -U ${DB_USER} ${DB_NAME} > "${file}"`, { stdio: 'inherit' });
|
|
283
339
|
}
|
|
284
340
|
else if (DB_TYPE === 'sqlite') {
|
|
285
|
-
|
|
341
|
+
const source = path.join(process.cwd(), `${DB_NAME}.sqlite`);
|
|
342
|
+
const backupFile = file.replace('.sql', '.sqlite');
|
|
343
|
+
if (fs.existsSync(source)) {
|
|
344
|
+
fs.copyFileSync(source, backupFile);
|
|
345
|
+
console.log(` Backup saved: ${backupFile}`);
|
|
346
|
+
return;
|
|
347
|
+
} else {
|
|
348
|
+
console.log(' No SQLite database file found to backup.');
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
286
351
|
}
|
|
287
352
|
|
|
288
353
|
console.log(` Backup saved: ${file}`);
|
|
289
354
|
} catch (err) {
|
|
290
|
-
console.error(' Backup failed
|
|
355
|
+
console.error(' Backup failed.');
|
|
356
|
+
if (process.platform === 'win32' && !mysqlTools) {
|
|
357
|
+
console.log('\n❌ mysqldump.exe not found.');
|
|
358
|
+
console.log(' Install MySQL or use XAMPP/WAMP/Laragon.');
|
|
359
|
+
console.log(' Or add MySQL bin folder to your system PATH.');
|
|
360
|
+
} else {
|
|
361
|
+
console.error(' Error:', err.message);
|
|
362
|
+
}
|
|
291
363
|
}
|
|
292
364
|
};
|
|
293
365
|
|
|
@@ -299,17 +371,26 @@ export const restoreDatabase = (file) => {
|
|
|
299
371
|
|
|
300
372
|
try {
|
|
301
373
|
if (DB_TYPE === 'mysql') {
|
|
302
|
-
|
|
374
|
+
let cmd;
|
|
375
|
+
if (process.platform === 'win32' && mysqlTools) {
|
|
376
|
+
cmd = `"${mysqlTools.mysql}" -h ${DB_HOST} -u ${DB_USER} ${DB_PASSWORD ? '-p' + DB_PASSWORD : ''} ${DB_NAME} < "${file}"`;
|
|
377
|
+
} else {
|
|
378
|
+
cmd = `mysql -h ${DB_HOST} -u ${DB_USER} ${DB_PASSWORD ? '-p' + DB_PASSWORD : ''} ${DB_NAME} < "${file}"`;
|
|
379
|
+
}
|
|
380
|
+
execSync(cmd, { stdio: 'inherit' });
|
|
303
381
|
}
|
|
304
382
|
else if (DB_TYPE === 'postgresql') {
|
|
305
383
|
process.env.PGPASSWORD = DB_PASSWORD;
|
|
306
|
-
execSync(`psql -h ${DB_HOST} -U ${DB_USER} -d ${DB_NAME} -f "${file}"
|
|
384
|
+
execSync(`psql -h ${DB_HOST} -U ${DB_USER} -d ${DB_NAME} -f "${file}"`, { stdio: 'inherit' });
|
|
307
385
|
}
|
|
308
386
|
else if (DB_TYPE === 'sqlite') {
|
|
309
|
-
|
|
387
|
+
const target = path.join(process.cwd(), `${DB_NAME}.sqlite`);
|
|
388
|
+
fs.copyFileSync(file, target);
|
|
389
|
+
console.log(` Restored SQLite database to: ${target}`);
|
|
390
|
+
return;
|
|
310
391
|
}
|
|
311
392
|
|
|
312
|
-
console.log(
|
|
393
|
+
console.log(` Database restored from: ${file}`);
|
|
313
394
|
} catch (err) {
|
|
314
395
|
console.error(' Restore failed:', err.message);
|
|
315
396
|
}
|
|
@@ -333,8 +414,13 @@ export const showDatabaseSize = async () => {
|
|
|
333
414
|
console.log(`Database size: ${res.rows[0].size}`);
|
|
334
415
|
}
|
|
335
416
|
else if (DB_TYPE === 'sqlite') {
|
|
336
|
-
const
|
|
337
|
-
|
|
417
|
+
const dbFile = path.join(process.cwd(), `${DB_NAME}.sqlite`);
|
|
418
|
+
if (fs.existsSync(dbFile)) {
|
|
419
|
+
const stats = fs.statSync(dbFile);
|
|
420
|
+
console.log(`Database file size: ${(stats.size / 1024 / 1024).toFixed(2)} MB`);
|
|
421
|
+
} else {
|
|
422
|
+
console.log('Database file not created yet (0 MB)');
|
|
423
|
+
}
|
|
338
424
|
}
|
|
339
425
|
else if (DB_TYPE === 'mongodb') {
|
|
340
426
|
const stats = await conn.stats();
|