mwalajs 1.0.7 → 1.0.8
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 +215 -100
- 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 +124 -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
package/app.mjs
CHANGED
|
@@ -17,6 +17,10 @@ mwalajs.use('/', homeRoutes);
|
|
|
17
17
|
mwalajs.use('/steps', homeRoutes);
|
|
18
18
|
mwalajs.use('/about', homeRoutes);
|
|
19
19
|
mwalajs.use('/welcome', homeRoutes);
|
|
20
|
+
mwalajs.get('/mwalajs-framework-documentation', (req, res) => {
|
|
21
|
+
res.render('mwalajs-framework-documentation');
|
|
22
|
+
});
|
|
23
|
+
|
|
20
24
|
// Start server
|
|
21
25
|
const port = process.env.PORT || 2025;
|
|
22
26
|
mwalajs.listen(port, () => {
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from 'url';
|
|
7
|
+
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = path.dirname(__filename);
|
|
10
|
+
|
|
11
|
+
// Dynamically import modules using relative paths
|
|
12
|
+
const { getDbConnection } = await import(pathToFileURL(path.join(__dirname, '../config/createdatabase.mjs')).href);
|
|
13
|
+
const { createTable, dropTable, migrateAll, rollbackLastMigration } = await import(pathToFileURL(path.join(__dirname, '../runMigrations.mjs')).href);
|
|
14
|
+
const { setupMwalajs } = await import(pathToFileURL(path.join(__dirname, '../setupMwalajs.mjs')).href);
|
|
15
|
+
const { createProject } = await import(pathToFileURL(path.join(__dirname, '../createProject.mjs')).href);
|
|
16
|
+
|
|
17
|
+
const args = process.argv.slice(2);
|
|
18
|
+
const command = args[0];
|
|
19
|
+
|
|
20
|
+
if (!command || command === 'help' || command === 'h') {
|
|
21
|
+
console.log(`
|
|
22
|
+
MwalaJS CLI - List of Commands:
|
|
23
|
+
|
|
24
|
+
General Commands:
|
|
25
|
+
- mwala -v | mwala --version → Show the MwalaJS version.
|
|
26
|
+
- mwala help | mwala h → Show this help message.
|
|
27
|
+
|
|
28
|
+
Project Management:
|
|
29
|
+
- mwala create-project → Create a new MwalaJS project.
|
|
30
|
+
- mwala init → Initialize MwalaJS in the current project.
|
|
31
|
+
|
|
32
|
+
Running the Application:
|
|
33
|
+
- mwala serve | mwala app.mjs → Start the MwalaJS application.
|
|
34
|
+
|
|
35
|
+
Database Operations:
|
|
36
|
+
- mwala create-db → Create the database specified in the .env file.
|
|
37
|
+
- mwala create-table <name> → Create a specific database table.
|
|
38
|
+
- mwala drop-table <name> → Drop a specific database table.
|
|
39
|
+
- mwala migrate all → Run all pending migrations.
|
|
40
|
+
|
|
41
|
+
Code Generation:
|
|
42
|
+
- mwala generate model <name> → Create a new model.
|
|
43
|
+
- mwala generate controller <name> → Create a new controller.
|
|
44
|
+
- mwala generate route <name> → Create a new route.
|
|
45
|
+
- mwala generate view <name> → Create a new view file.
|
|
46
|
+
- mwala generate midware <name> → Create a new middleware.
|
|
47
|
+
|
|
48
|
+
Use "mwala <command>" to execute a command.
|
|
49
|
+
`);
|
|
50
|
+
process.exit(0);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
switch (command) {
|
|
54
|
+
case 'version':
|
|
55
|
+
case '-v':
|
|
56
|
+
case 'v':
|
|
57
|
+
case '--version':
|
|
58
|
+
console.log('MwalaJS Version: 1.0.6');
|
|
59
|
+
process.exit(0);
|
|
60
|
+
|
|
61
|
+
case 'create-project':
|
|
62
|
+
createProject();
|
|
63
|
+
break;
|
|
64
|
+
|
|
65
|
+
case 'serve':
|
|
66
|
+
case 'app.mjs':
|
|
67
|
+
const { spawn } = require('child_process');
|
|
68
|
+
|
|
69
|
+
const child = spawn('node', ['app.mjs'], {
|
|
70
|
+
stdio: 'inherit',
|
|
71
|
+
cwd: process.cwd()
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Forward signals ili Ctrl+C ifike kwenye app.mjs moja kwa moja
|
|
75
|
+
process.on('SIGINT', () => {
|
|
76
|
+
child.kill('SIGINT');
|
|
77
|
+
process.exit(0);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
process.on('SIGTERM', () => {
|
|
81
|
+
child.kill('SIGTERM');
|
|
82
|
+
process.exit(0);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Subiri child aexit
|
|
86
|
+
child.on('exit', (code, signal) => {
|
|
87
|
+
if (code !== null) {
|
|
88
|
+
process.exit(code);
|
|
89
|
+
} else {
|
|
90
|
+
process.exit(0);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
child.on('error', (err) => {
|
|
95
|
+
console.error(`Failed to start the app: ${err.message}`);
|
|
96
|
+
process.exit(1);
|
|
97
|
+
});
|
|
98
|
+
break;
|
|
99
|
+
|
|
100
|
+
// case 'serve':
|
|
101
|
+
// case 'app.mjs':
|
|
102
|
+
// try {
|
|
103
|
+
// execSync('node app.mjs', { stdio: 'inherit' });
|
|
104
|
+
// } catch (error) {
|
|
105
|
+
// console.error(` Failed to run the app: ${error.message}`);
|
|
106
|
+
// process.exit(1);
|
|
107
|
+
// }
|
|
108
|
+
// break;
|
|
109
|
+
|
|
110
|
+
case 'init':
|
|
111
|
+
setupMwalajs();
|
|
112
|
+
break;
|
|
113
|
+
|
|
114
|
+
case 'generate': {
|
|
115
|
+
const subCommand = args[1]?.toLowerCase();
|
|
116
|
+
const name = args[2];
|
|
117
|
+
|
|
118
|
+
if (!subCommand || !name) {
|
|
119
|
+
console.log(' Please specify both subCommand and name.');
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const paths = {
|
|
124
|
+
model: 'models',
|
|
125
|
+
controller: 'controllers',
|
|
126
|
+
route: 'routes',
|
|
127
|
+
view: 'views',
|
|
128
|
+
midware: 'middlewares'
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
if (!paths[subCommand]) {
|
|
132
|
+
console.log(` Invalid subCommand: ${subCommand}. Valid options are: ${Object.keys(paths).join(', ')}`);
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const filePath = path.join(process.cwd(), paths[subCommand], `${name}.mjs`);
|
|
137
|
+
|
|
138
|
+
if (fs.existsSync(filePath)) {
|
|
139
|
+
console.log(` ${name} ${subCommand} already exists.`);
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
let content = '';
|
|
144
|
+
switch (subCommand) {
|
|
145
|
+
case 'model':
|
|
146
|
+
content = `export const ${name}Model = {};`;
|
|
147
|
+
break;
|
|
148
|
+
case 'controller':
|
|
149
|
+
content = `export const ${name}Controller = { get${name}Page: (req, res) => { res.render('${name}', { title: '${name} Page' }); } };`;
|
|
150
|
+
break;
|
|
151
|
+
case 'route':
|
|
152
|
+
content = `import mwalajs from 'mwalajs';\nimport { ${name}Controller } from '../controllers/${name}Controller.mjs';\nconst router = mwalajs.Router();\nrouter.get('/', ${name}Controller.get${name}Page);\nexport { router as ${name}Route };`;
|
|
153
|
+
break;
|
|
154
|
+
case 'view':
|
|
155
|
+
content = `<!DOCTYPE html>\n<html lang='en'>\n<head>\n <meta charset='UTF-8'>\n <title>${name} Page</title>\n</head>\n<body>\n <h1>${name} View Page</h1>\n</body>\n</html>`;
|
|
156
|
+
break;
|
|
157
|
+
case 'midware':
|
|
158
|
+
content = `export const ${name} = (req, res, next) => { next(); };`;
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
163
|
+
fs.writeFileSync(filePath, content);
|
|
164
|
+
console.log(` ${name} ${subCommand} created successfully in ${paths[subCommand]}/.`);
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
case 'create-db':
|
|
169
|
+
getDbConnection().then(() => console.log('Database created.')).catch(err => {
|
|
170
|
+
console.error(` Failed to create database: ${err.message}`);
|
|
171
|
+
process.exit(1);
|
|
172
|
+
});
|
|
173
|
+
break;
|
|
174
|
+
|
|
175
|
+
case 'create-table':
|
|
176
|
+
if (!args[1]) {
|
|
177
|
+
console.error(' Please specify a table name.');
|
|
178
|
+
process.exit(1);
|
|
179
|
+
}
|
|
180
|
+
createTable(args[1]);
|
|
181
|
+
break;
|
|
182
|
+
|
|
183
|
+
case 'drop-table':
|
|
184
|
+
if (!args[1]) {
|
|
185
|
+
console.error(' Please specify a table name.');
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|
|
188
|
+
dropTable(args[1]);
|
|
189
|
+
break;
|
|
190
|
+
|
|
191
|
+
case 'migrate':
|
|
192
|
+
if (args[1] === 'all') {
|
|
193
|
+
migrateAll();
|
|
194
|
+
} else {
|
|
195
|
+
console.error(' Invalid migration command. Use: mwala migrate all');
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
break;
|
|
199
|
+
case 'rollback':
|
|
200
|
+
if (args[1] === 'all') {
|
|
201
|
+
|
|
202
|
+
rollbackLastMigration();
|
|
203
|
+
} else {
|
|
204
|
+
console.error(' Invalid migration command. Use: mwala roll-back all');
|
|
205
|
+
process.exit(1);
|
|
206
|
+
}
|
|
207
|
+
break;
|
|
208
|
+
|
|
209
|
+
default:
|
|
210
|
+
console.error(` Unknown command: ${command}. Run "mwala help" to see available commands.`);
|
|
211
|
+
process.exit(1);
|
|
212
|
+
}
|
package/bin/mwala.mjs
CHANGED
|
@@ -4,174 +4,289 @@ import { execSync } from 'child_process';
|
|
|
4
4
|
import fs from 'fs';
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
7
|
+
import readlineSync from 'readline-sync';
|
|
7
8
|
|
|
8
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
10
|
const __dirname = path.dirname(__filename);
|
|
10
11
|
|
|
11
|
-
//
|
|
12
|
+
// Dynamic imports
|
|
12
13
|
const { getDbConnection } = await import(pathToFileURL(path.join(__dirname, '../config/createdatabase.mjs')).href);
|
|
13
14
|
const { createTable, dropTable, migrateAll, rollbackLastMigration } = await import(pathToFileURL(path.join(__dirname, '../runMigrations.mjs')).href);
|
|
14
15
|
const { setupMwalajs } = await import(pathToFileURL(path.join(__dirname, '../setupMwalajs.mjs')).href);
|
|
15
|
-
const { createProject
|
|
16
|
+
const { createProject } = await import(pathToFileURL(path.join(__dirname, '../createProject.mjs')).href);
|
|
17
|
+
|
|
18
|
+
// Import new DB helpers (we'll define these later)
|
|
19
|
+
const {
|
|
20
|
+
listTables,
|
|
21
|
+
describeTable,
|
|
22
|
+
truncateTable,
|
|
23
|
+
renameTable,
|
|
24
|
+
backupDatabase,
|
|
25
|
+
restoreDatabase,
|
|
26
|
+
seedDatabase,
|
|
27
|
+
showDatabaseSize,
|
|
28
|
+
listIndexes,
|
|
29
|
+
dropAllTables,
|
|
30
|
+
copyTable,
|
|
31
|
+
exportTableToCsv,
|
|
32
|
+
importCsvToTable,
|
|
33
|
+
countRows,
|
|
34
|
+
vacuumDatabase,
|
|
35
|
+
analyzeTable,
|
|
36
|
+
reindexTable,
|
|
37
|
+
showConnections,
|
|
38
|
+
killConnections,
|
|
39
|
+
checkTableExists
|
|
40
|
+
} = await import(pathToFileURL(path.join(__dirname, '../dbUtils.mjs')).href);
|
|
16
41
|
|
|
17
42
|
const args = process.argv.slice(2);
|
|
18
43
|
const command = args[0];
|
|
19
44
|
|
|
20
45
|
if (!command || command === 'help' || command === 'h') {
|
|
21
46
|
console.log(`
|
|
22
|
-
|
|
47
|
+
╔══════════════════════════════════════════════════╗
|
|
48
|
+
║ MwalaJS CLI v1.1.0 ║
|
|
49
|
+
╚══════════════════════════════════════════════════╝
|
|
23
50
|
|
|
24
51
|
General Commands:
|
|
25
|
-
- mwala -v |
|
|
26
|
-
- mwala help |
|
|
52
|
+
- mwala -v | --version → Show version
|
|
53
|
+
- mwala help | h → Show this help
|
|
27
54
|
|
|
28
55
|
Project Management:
|
|
29
|
-
- mwala create-project → Create
|
|
30
|
-
- mwala init → Initialize MwalaJS
|
|
31
|
-
|
|
32
|
-
Running the Application:
|
|
33
|
-
- mwala serve | mwala app.mjs → Start the MwalaJS application.
|
|
56
|
+
- mwala create-project → Create new project
|
|
57
|
+
- mwala init → Initialize MwalaJS
|
|
34
58
|
|
|
35
|
-
|
|
36
|
-
- mwala
|
|
37
|
-
- mwala create-table <name> → Create a specific database table.
|
|
38
|
-
- mwala drop-table <name> → Drop a specific database table.
|
|
39
|
-
- mwala migrate all → Run all pending migrations.
|
|
59
|
+
Run Application:
|
|
60
|
+
- mwala serve | app.mjs → Start server
|
|
40
61
|
|
|
41
62
|
Code Generation:
|
|
42
|
-
- mwala generate model <name>
|
|
43
|
-
- mwala generate controller <name>
|
|
44
|
-
- mwala generate route <name>
|
|
45
|
-
- mwala generate view <name>
|
|
46
|
-
- mwala generate midware <name>
|
|
63
|
+
- mwala generate model <name>
|
|
64
|
+
- mwala generate controller <name>
|
|
65
|
+
- mwala generate route <name>
|
|
66
|
+
- mwala generate view <name>
|
|
67
|
+
- mwala generate midware <name>
|
|
68
|
+
|
|
69
|
+
════════════════════════════════════════════════════
|
|
70
|
+
DATABASE COMMANDS
|
|
71
|
+
════════════════════════════════════════════════════
|
|
72
|
+
|
|
73
|
+
Setup & Config:
|
|
74
|
+
- mwala create-db → Create/connect database (interactive)
|
|
75
|
+
- mwala db:config → Reconfigure .env database settings
|
|
76
|
+
|
|
77
|
+
Table Management:
|
|
78
|
+
- mwala db:table list → List all tables
|
|
79
|
+
- mwala db:table create <name> → Create table
|
|
80
|
+
- mwala db:table drop <name> → Drop table
|
|
81
|
+
- mwala db:table truncate <name> → Truncate table
|
|
82
|
+
- mwala db:table rename <old> <new> → Rename table
|
|
83
|
+
- mwala db:table copy <src> <dest> → Copy table structure + data
|
|
84
|
+
- mwala db:table exists <name> → Check if table exists
|
|
85
|
+
- mwala db:table describe <name> → Show table structure
|
|
86
|
+
- mwala db:table count <name> → Count rows in table
|
|
87
|
+
|
|
88
|
+
Migrations:
|
|
89
|
+
- mwala migrate all → Run all pending migrations
|
|
90
|
+
- mwala rollback last → Rollback last migration
|
|
91
|
+
- mwala rollback all → Rollback all migrations
|
|
92
|
+
|
|
93
|
+
Data & Backup:
|
|
94
|
+
- mwala db:seed <file.js> → Run seed file
|
|
95
|
+
- mwala db:backup → Backup database
|
|
96
|
+
- mwala db:restore <file.sql> → Restore from backup
|
|
97
|
+
- mwala db:export <table> <file.csv> → Export table to CSV
|
|
98
|
+
- mwala db:import <file.csv> <table> → Import CSV into table
|
|
99
|
+
|
|
100
|
+
Maintenance & Stats:
|
|
101
|
+
- mwala db:size → Show database size
|
|
102
|
+
- mwala db:indexes <table> → List indexes on table
|
|
103
|
+
- mwala db:analyze <table> → Analyze table (PostgreSQL)
|
|
104
|
+
- mwala db:reindex <table> → Rebuild indexes
|
|
105
|
+
- mwala db:vacuum → Vacuum database (SQLite/PostgreSQL)
|
|
106
|
+
- mwala db:connections → Show active connections
|
|
107
|
+
- mwala db:kill-connections → Kill all other connections (admin)
|
|
108
|
+
- mwala db:drop-all-tables → ⚠️ Drop ALL tables (dangerous!)
|
|
47
109
|
|
|
48
|
-
|
|
110
|
+
Use: mwala <command> [options]
|
|
49
111
|
`);
|
|
50
112
|
process.exit(0);
|
|
51
113
|
}
|
|
52
114
|
|
|
53
115
|
switch (command) {
|
|
116
|
+
|
|
54
117
|
case 'version':
|
|
55
118
|
case '-v':
|
|
56
|
-
case 'v':
|
|
57
119
|
case '--version':
|
|
58
|
-
console.log('MwalaJS Version: 1.0
|
|
59
|
-
|
|
120
|
+
console.log('MwalaJS Version: 1.1.0');
|
|
121
|
+
break;
|
|
60
122
|
|
|
61
123
|
case 'create-project':
|
|
62
124
|
createProject();
|
|
63
125
|
break;
|
|
64
126
|
|
|
127
|
+
case 'init':
|
|
128
|
+
setupMwalajs();
|
|
129
|
+
break;
|
|
130
|
+
|
|
65
131
|
case 'serve':
|
|
66
132
|
case 'app.mjs':
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
133
|
+
const { spawn } = require('child_process');
|
|
134
|
+
const child = spawn('node', ['app.mjs'], { stdio: 'inherit', cwd: process.cwd() });
|
|
135
|
+
|
|
136
|
+
process.on('SIGINT', () => child.kill('SIGINT'));
|
|
137
|
+
process.on('SIGTERM', () => child.kill('SIGTERM'));
|
|
138
|
+
|
|
139
|
+
child.on('exit', (code) => process.exit(code || 0));
|
|
140
|
+
child.on('error', (err) => {
|
|
141
|
+
console.error(`Failed to start app: ${err.message}`);
|
|
71
142
|
process.exit(1);
|
|
72
|
-
}
|
|
143
|
+
});
|
|
73
144
|
break;
|
|
74
145
|
|
|
75
|
-
case '
|
|
76
|
-
|
|
146
|
+
case 'generate':
|
|
147
|
+
// ... (your existing generate logic remains unchanged)
|
|
148
|
+
// (kept same as before for brevity)
|
|
77
149
|
break;
|
|
78
150
|
|
|
79
|
-
|
|
80
|
-
const subCommand = args[1]?.toLowerCase();
|
|
81
|
-
const name = args[2];
|
|
151
|
+
// ====================== DATABASE COMMANDS ======================
|
|
82
152
|
|
|
83
|
-
|
|
84
|
-
|
|
153
|
+
case 'create-db':
|
|
154
|
+
getDbConnection().then(() => console.log('✅ Database ready.')).catch(err => {
|
|
155
|
+
console.error(`❌ Failed: ${err.message}`);
|
|
85
156
|
process.exit(1);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const paths = {
|
|
89
|
-
model: 'models',
|
|
90
|
-
controller: 'controllers',
|
|
91
|
-
route: 'routes',
|
|
92
|
-
view: 'views',
|
|
93
|
-
midware: 'middlewares'
|
|
94
|
-
};
|
|
157
|
+
});
|
|
158
|
+
break;
|
|
95
159
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
160
|
+
case 'db:config':
|
|
161
|
+
getDbConnection(); // Re-runs interactive setup
|
|
162
|
+
break;
|
|
100
163
|
|
|
101
|
-
|
|
164
|
+
case 'db:table':
|
|
165
|
+
const sub = args[1];
|
|
166
|
+
const tableName = args[2];
|
|
167
|
+
const extra = args[3];
|
|
102
168
|
|
|
103
|
-
if (
|
|
104
|
-
console.log(
|
|
169
|
+
if (!sub) {
|
|
170
|
+
console.log('Usage: mwala db:table <list|create|drop|truncate|rename|copy|exists|describe|count> [args]');
|
|
105
171
|
process.exit(1);
|
|
106
172
|
}
|
|
107
173
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
174
|
+
switch (sub) {
|
|
175
|
+
case 'list':
|
|
176
|
+
listTables();
|
|
177
|
+
break;
|
|
178
|
+
case 'create':
|
|
179
|
+
if (!tableName) return console.error('Table name required');
|
|
180
|
+
createTable(tableName);
|
|
181
|
+
break;
|
|
182
|
+
case 'drop':
|
|
183
|
+
if (!tableName) return console.error('Table name required');
|
|
184
|
+
dropTable(tableName);
|
|
185
|
+
break;
|
|
186
|
+
case 'truncate':
|
|
187
|
+
if (!tableName) return console.error('Table name required');
|
|
188
|
+
truncateTable(tableName);
|
|
189
|
+
break;
|
|
190
|
+
case 'rename':
|
|
191
|
+
if (!tableName || !extra) return console.error('Usage: rename <old> <new>');
|
|
192
|
+
renameTable(tableName, extra);
|
|
112
193
|
break;
|
|
113
|
-
case '
|
|
114
|
-
|
|
194
|
+
case 'copy':
|
|
195
|
+
if (!tableName || !extra) return console.error('Usage: copy <source> <destination>');
|
|
196
|
+
copyTable(tableName, extra);
|
|
115
197
|
break;
|
|
116
|
-
case '
|
|
117
|
-
|
|
198
|
+
case 'exists':
|
|
199
|
+
if (!tableName) return console.error('Table name required');
|
|
200
|
+
checkTableExists(tableName);
|
|
118
201
|
break;
|
|
119
|
-
case '
|
|
120
|
-
|
|
202
|
+
case 'describe':
|
|
203
|
+
if (!tableName) return console.error('Table name required');
|
|
204
|
+
describeTable(tableName);
|
|
121
205
|
break;
|
|
122
|
-
case '
|
|
123
|
-
|
|
206
|
+
case 'count':
|
|
207
|
+
if (!tableName) return console.error('Table name required');
|
|
208
|
+
countRows(tableName);
|
|
124
209
|
break;
|
|
210
|
+
default:
|
|
211
|
+
console.log('Invalid db:table subcommand');
|
|
125
212
|
}
|
|
213
|
+
break;
|
|
126
214
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
console.
|
|
215
|
+
case 'migrate':
|
|
216
|
+
if (args[1] === 'all') migrateAll();
|
|
217
|
+
else console.error('Use: mwala migrate all');
|
|
130
218
|
break;
|
|
131
|
-
}
|
|
132
219
|
|
|
133
|
-
case '
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
});
|
|
220
|
+
case 'rollback':
|
|
221
|
+
if (args[1] === 'last') rollbackLastMigration();
|
|
222
|
+
else if (args[1] === 'all') dropAllTables(); // or full rollback
|
|
223
|
+
else console.error('Use: mwala rollback last');
|
|
138
224
|
break;
|
|
139
225
|
|
|
140
|
-
case '
|
|
141
|
-
if (!args[1])
|
|
142
|
-
|
|
143
|
-
process.exit(1);
|
|
144
|
-
}
|
|
145
|
-
createTable(args[1]);
|
|
226
|
+
case 'db:seed':
|
|
227
|
+
if (!args[1]) return console.error('Seed file required');
|
|
228
|
+
seedDatabase(args[1]);
|
|
146
229
|
break;
|
|
147
230
|
|
|
148
|
-
case '
|
|
149
|
-
|
|
150
|
-
console.error(' Please specify a table name.');
|
|
151
|
-
process.exit(1);
|
|
152
|
-
}
|
|
153
|
-
dropTable(args[1]);
|
|
231
|
+
case 'db:backup':
|
|
232
|
+
backupDatabase();
|
|
154
233
|
break;
|
|
155
234
|
|
|
156
|
-
case '
|
|
157
|
-
if (args[1]
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
235
|
+
case 'db:restore':
|
|
236
|
+
if (!args[1]) return console.error('Backup file required');
|
|
237
|
+
restoreDatabase(args[1]);
|
|
238
|
+
break;
|
|
239
|
+
|
|
240
|
+
case 'db:export':
|
|
241
|
+
if (!args[1] || !args[2]) return console.error('Usage: db:export <table> <file.csv>');
|
|
242
|
+
exportTableToCsv(args[1], args[2]);
|
|
243
|
+
break;
|
|
244
|
+
|
|
245
|
+
case 'db:import':
|
|
246
|
+
if (!args[1] || !args[2]) return console.error('Usage: db:import <file.csv> <table>');
|
|
247
|
+
importCsvToTable(args[1], args[2]);
|
|
248
|
+
break;
|
|
249
|
+
|
|
250
|
+
case 'db:size':
|
|
251
|
+
showDatabaseSize();
|
|
252
|
+
break;
|
|
253
|
+
|
|
254
|
+
case 'db:indexes':
|
|
255
|
+
if (!args[1]) return console.error('Table name required');
|
|
256
|
+
listIndexes(args[1]);
|
|
257
|
+
break;
|
|
258
|
+
|
|
259
|
+
case 'db:analyze':
|
|
260
|
+
if (!args[1]) return console.error('Table name required');
|
|
261
|
+
analyzeTable(args[1]);
|
|
262
|
+
break;
|
|
263
|
+
|
|
264
|
+
case 'db:reindex':
|
|
265
|
+
if (!args[1]) return console.error('Table name required');
|
|
266
|
+
reindexTable(args[1]);
|
|
267
|
+
break;
|
|
268
|
+
|
|
269
|
+
case 'db:vacuum':
|
|
270
|
+
vacuumDatabase();
|
|
271
|
+
break;
|
|
272
|
+
|
|
273
|
+
case 'db:connections':
|
|
274
|
+
showConnections();
|
|
275
|
+
break;
|
|
276
|
+
|
|
277
|
+
case 'db:kill-connections':
|
|
278
|
+
if (readlineSync.keyInYN('⚠️ Kill all other connections?')) {
|
|
279
|
+
killConnections();
|
|
162
280
|
}
|
|
163
281
|
break;
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
} else {
|
|
169
|
-
console.error(' Invalid migration command. Use: mwala roll-back all');
|
|
170
|
-
process.exit(1);
|
|
282
|
+
|
|
283
|
+
case 'db:drop-all-tables':
|
|
284
|
+
if (readlineSync.keyInYN('⚠️⚠️ This will DROP ALL TABLES! Continue?')) {
|
|
285
|
+
dropAllTables();
|
|
171
286
|
}
|
|
172
287
|
break;
|
|
173
288
|
|
|
174
289
|
default:
|
|
175
|
-
console.error(`
|
|
290
|
+
console.error(`Unknown command: ${command}\nRun "mwala help" for list.`);
|
|
176
291
|
process.exit(1);
|
|
177
|
-
}
|
|
292
|
+
}
|