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 v1.2.0
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(`✅ ${name} ${type} created at ${folders[type]}/${name}.mjs`);
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(' Database configured and connected successfully!'))
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mwalajs",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "description": "MwalaJS Framework CLI Tool and Web Framework for Backend and Frontend Development.",
5
5
  "type": "module",
6
6
  "main": "app.mjs",
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
- dotenv.config();
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
- const { DB_TYPE, DB_HOST = 'localhost', DB_USER, DB_PASSWORD, DB_NAME, DB_PORT } = process.env;
38
+ // SQLite and MongoDB don't need user/password
39
+ if (DB_TYPE === 'sqlite' || DB_TYPE === 'mongodb') {
40
+ return true;
41
+ }
19
42
 
20
- // Helper to check if DB is configured
21
- const isDbConfigured = () => {
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=your_pass\n');
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
- connection = new sqlite3.Database(`./${DB_NAME}.sqlite`);
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
- execSync(`mysqldump -h ${DB_HOST} -u ${DB_USER} -p${DB_PASSWORD} ${DB_NAME} > "${file}"`);
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
- fs.copyFileSync(`./${DB_NAME}.sqlite`, file.replace('.sql', '.sqlite'));
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:', err.message);
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
- execSync(`mysql -h ${DB_HOST} -u ${DB_USER} -p${DB_PASSWORD} ${DB_NAME} < "${file}"`);
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
- fs.copyFileSync(file, `./${DB_NAME}.sqlite`);
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(' Database restored from:', file);
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 stats = fs.statSync(`./${DB_NAME}.sqlite`);
337
- console.log(`Database file size: ${(stats.size / 1024 / 1024).toFixed(2)} MB`);
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();