mwalajs 1.1.15 → 1.1.17

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.
@@ -0,0 +1,140 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+ import readline from 'readline';
4
+ import os from 'os';
5
+ import { fileURLToPath } from 'url';
6
+
7
+ /**
8
+ * Get global template path (FIXED)
9
+ */
10
+ function getMwalajsPath() {
11
+ const envPath = process.env.MWALAJSPATH;
12
+
13
+ if (envPath && fs.existsSync(envPath)) {
14
+ return envPath;
15
+ }
16
+
17
+ /**
18
+ * IMPORTANT FIX:
19
+ * Get path of installed npm package, NOT cwd
20
+ */
21
+ try {
22
+ const modulePath = path.dirname(fileURLToPath(import.meta.url));
23
+
24
+ // go up to package root
25
+ const rootPath = path.resolve(modulePath, '..');
26
+
27
+ if (fs.existsSync(path.join(rootPath, 'app.mjs'))) {
28
+ return rootPath;
29
+ }
30
+ } catch (err) {}
31
+
32
+ const fallbackPaths = {
33
+ win32: 'C:\\Program Files\\mwalajs',
34
+ linux: '/usr/local/lib/mwalajs',
35
+ darwin: '/usr/local/lib/mwalajs'
36
+ };
37
+
38
+ const fallback = fallbackPaths[os.platform()];
39
+
40
+ if (fallback && fs.existsSync(fallback)) {
41
+ return fallback;
42
+ }
43
+
44
+ throw new Error("❌ MwalaJS template source not found. Set MWALAJSPATH.");
45
+ }
46
+
47
+ /**
48
+ * Ask helper
49
+ */
50
+ function askQuestion(rl, question) {
51
+ return new Promise(resolve => {
52
+ rl.question(question, ans => resolve(ans.trim()));
53
+ });
54
+ }
55
+
56
+ /**
57
+ * Create project
58
+ */
59
+ export async function createProject(projectArg) {
60
+ const rl = readline.createInterface({
61
+ input: process.stdin,
62
+ output: process.stdout
63
+ });
64
+
65
+ try {
66
+ let projectName = projectArg?.trim();
67
+
68
+ if (!projectName) {
69
+ projectName = await askQuestion(rl, "Enter project name: ");
70
+ }
71
+
72
+ if (!projectName) {
73
+ console.error("❌ Project name required");
74
+ return;
75
+ }
76
+
77
+ const newProjectPath = path.join(process.cwd(), projectName);
78
+
79
+ const templatePath = getMwalajsPath();
80
+
81
+ if (!fs.existsSync(templatePath)) {
82
+ throw new Error("Template path not found: " + templatePath);
83
+ }
84
+
85
+ if (fs.existsSync(newProjectPath)) {
86
+ console.error(`❌ Folder already exists: ${projectName}`);
87
+ return;
88
+ }
89
+
90
+ console.log(`📦 Creating project: ${projectName}`);
91
+ console.log(`📁 From template: ${templatePath}`);
92
+
93
+ fs.mkdirSync(newProjectPath, { recursive: true });
94
+
95
+ const itemsToCopy = [
96
+ "app.mjs",
97
+ "controllers",
98
+ "migrations",
99
+ "routes",
100
+ "views",
101
+ "middlewares",
102
+ "models",
103
+ "public",
104
+ "README.md"
105
+ ];
106
+
107
+ let copied = 0;
108
+
109
+ for (const item of itemsToCopy) {
110
+ const src = path.join(templatePath, item);
111
+ const dest = path.join(newProjectPath, item);
112
+
113
+ if (fs.existsSync(src)) {
114
+ console.log(`✔ Copying ${item}`);
115
+ fs.copySync(src, dest);
116
+ copied++;
117
+ } else {
118
+ console.warn(`⚠ Missing template item: ${item}`);
119
+ }
120
+ }
121
+
122
+ console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━");
123
+ console.log(`✅ Project created: ${projectName}`);
124
+ console.log(`📁 Location: ${newProjectPath}`);
125
+ console.log(`📦 Files copied: ${copied}/${itemsToCopy.length}`);
126
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━");
127
+
128
+ } catch (err) {
129
+ console.error("❌ Create project failed:", err.message);
130
+ } finally {
131
+ rl.close();
132
+ }
133
+ }
134
+
135
+ /**
136
+ * CLI support
137
+ */
138
+ if (import.meta.url === `file://${process.argv[1]}`) {
139
+ createProject(process.argv[2]);
140
+ }
package/createProject.mjs CHANGED
@@ -1,140 +1,364 @@
1
- import fs from 'fs-extra';
2
- import path from 'path';
3
- import readline from 'readline';
4
- import os from 'os';
5
- import { fileURLToPath } from 'url';
1
+ // createProject.mjs (ULTIMATE CROSS-PLATFORM VERSION)
2
+
3
+ import fs from "fs-extra";
4
+ import path from "path";
5
+ import readline from "readline";
6
+ import os from "os";
7
+ import { fileURLToPath } from "url";
8
+
9
+ /* =========================
10
+ SAFE PATH HELPERS
11
+ ========================= */
12
+
13
+ const __filename = fileURLToPath(import.meta.url);
14
+ const __dirname = path.dirname(__filename);
6
15
 
7
16
  /**
8
- * Get global template path (FIXED)
17
+ * Detect best possible MwalaJS template path
18
+ * Works on ALL OS
9
19
  */
10
20
  function getMwalajsPath() {
11
- const envPath = process.env.MWALAJSPATH;
21
+ const envPath = process.env.MWALAJSPATH;
12
22
 
13
- if (envPath && fs.existsSync(envPath)) {
14
- return envPath;
23
+ const possiblePaths = [
24
+ envPath,
25
+ path.join(process.cwd(), "template"),
26
+ path.join(__dirname, "template"),
27
+ path.join(__dirname, "../template"),
28
+ path.join(__dirname, "../../template"),
29
+ "C:\\Program Files\\mwalajs",
30
+ "C:\\mwalajs",
31
+ "/usr/local/lib/mwalajs",
32
+ "/usr/lib/mwalajs",
33
+ "/var/www/mwalajs",
34
+ "/opt/mwalajs"
35
+ ];
36
+
37
+ for (const p of possiblePaths) {
38
+ if (p && fs.existsSync(p)) {
39
+ return fs.realpathSync(p);
15
40
  }
41
+ }
16
42
 
17
- /**
18
- * IMPORTANT FIX:
19
- * Get path of installed npm package, NOT cwd
20
- */
21
- try {
22
- const modulePath = path.dirname(fileURLToPath(import.meta.url));
43
+ return null;
44
+ }
23
45
 
24
- // go up to package root
25
- const rootPath = path.resolve(modulePath, '..');
46
+ /* =========================
47
+ CLI INPUT
48
+ ========================= */
26
49
 
27
- if (fs.existsSync(path.join(rootPath, 'app.mjs'))) {
28
- return rootPath;
29
- }
30
- } catch (err) {}
50
+ function ask(rl, question) {
51
+ return new Promise((resolve) => {
52
+ rl.question(question, (ans) => resolve(ans.trim()));
53
+ });
54
+ }
31
55
 
32
- const fallbackPaths = {
33
- win32: 'C:\\Program Files\\mwalajs',
34
- linux: '/usr/local/lib/mwalajs',
35
- darwin: '/usr/local/lib/mwalajs'
36
- };
56
+ /* =========================
57
+ MANUAL TEMPLATE GENERATOR
58
+ (ALWAYS WORKS - FALLBACK)
59
+ ========================= */
37
60
 
38
- const fallback = fallbackPaths[os.platform()];
61
+ function createManualTemplate(target) {
62
+ console.log("\n⚠ No template found. Generating FULL MwalaJS scaffold...\n");
39
63
 
40
- if (fallback && fs.existsSync(fallback)) {
41
- return fallback;
42
- }
64
+ const dirs = [
65
+ "controllers",
66
+ "routes",
67
+ "models",
68
+ "views",
69
+ "views/layouts",
70
+ "views/pages",
71
+ "middlewares",
72
+ "migrations",
73
+ "config",
74
+ "public",
75
+ "public/css",
76
+ "public/js",
77
+ "public/images",
78
+ "storage",
79
+ "logs"
80
+ ];
43
81
 
44
- throw new Error("❌ MwalaJS template source not found. Set MWALAJSPATH.");
45
- }
82
+ dirs.forEach((dir) => {
83
+ fs.mkdirSync(path.join(target, dir), { recursive: true });
84
+ });
46
85
 
47
- /**
48
- * Ask helper
49
- */
50
- function askQuestion(rl, question) {
51
- return new Promise(resolve => {
52
- rl.question(question, ans => resolve(ans.trim()));
86
+ /* =========================
87
+ APP ENTRY
88
+ ========================= */
89
+
90
+ fs.writeFileSync(
91
+ path.join(target, "app.mjs"),
92
+ `import mwalajs from 'mwalajs';
93
+ import path from 'path';
94
+ import { fileURLToPath } from 'url';
95
+
96
+ const __filename = fileURLToPath(import.meta.url);
97
+ const __dirname = path.dirname(__filename);
98
+
99
+ mwalajs.set('view engine', 'ejs');
100
+ mwalajs.set('views', path.join(__dirname, 'views'));
101
+
102
+ mwalajs.useStatic(path.join(__dirname, 'public'));
103
+
104
+ /* ROUTES */
105
+ mwalajs.get('/', (req, res) => {
106
+ res.render('pages/index', {
107
+ title: '🚀 MwalaJS Application Running'
108
+ });
109
+ });
110
+
111
+ /* SERVER */
112
+ const PORT = process.env.PORT || 3000;
113
+ mwalajs.listen(PORT, () => {
114
+ console.log(\`🚀 Server running on http://localhost:\${PORT}\`);
115
+ });
116
+ `
117
+ );
118
+
119
+ /* =========================
120
+ CONTROLLER
121
+ ========================= */
122
+
123
+ fs.writeFileSync(
124
+ path.join(target, "controllers/homeController.mjs"),
125
+ `export const homeController = {
126
+ index: (req, res) => {
127
+ res.render('pages/index', {
128
+ title: 'Home Page'
53
129
  });
130
+ }
131
+ };`
132
+ );
133
+
134
+ /* =========================
135
+ ROUTES
136
+ ========================= */
137
+
138
+ fs.writeFileSync(
139
+ path.join(target, "routes/homeRoutes.mjs"),
140
+ `import mwalajs from 'mwalajs';
141
+ import { homeController } from '../controllers/homeController.mjs';
142
+
143
+ const router = mwalajs.Router();
144
+
145
+ router.get('/', homeController.index);
146
+
147
+ export { router as homeRoutes };
148
+ `
149
+ );
150
+
151
+ /* =========================
152
+ MODEL EXAMPLE
153
+ ========================= */
154
+
155
+ fs.writeFileSync(
156
+ path.join(target, "models/User.mjs"),
157
+ `export class User {
158
+ constructor() {
159
+ this.table = "users";
160
+ }
161
+
162
+ // Add model logic here
54
163
  }
164
+ `
165
+ );
166
+
167
+ /* =========================
168
+ VIEW
169
+ ========================= */
170
+
171
+ fs.writeFileSync(
172
+ path.join(target, "views/pages/index.ejs"),
173
+ `<!DOCTYPE html>
174
+ <html>
175
+ <head>
176
+ <meta charset="UTF-8" />
177
+ <title><%= title %></title>
178
+ <style>
179
+ body {
180
+ font-family: Arial;
181
+ background: linear-gradient(135deg,#0f172a,#1e293b);
182
+ color: white;
183
+ text-align: center;
184
+ padding: 60px;
185
+ }
186
+
187
+ .box {
188
+ background: rgba(255,255,255,0.05);
189
+ padding: 30px;
190
+ border-radius: 16px;
191
+ display: inline-block;
192
+ box-shadow: 0 10px 30px rgba(0,0,0,0.3);
193
+ }
194
+
195
+ h1 {
196
+ font-size: 40px;
197
+ }
198
+ </style>
199
+ </head>
200
+ <body>
201
+ <div class="box">
202
+ <h1>🚀 MwalaJS Ready</h1>
203
+ <p><%= title %></p>
204
+ </div>
205
+ </body>
206
+ </html>`
207
+ );
208
+
209
+ /* =========================
210
+ PACKAGE JSON
211
+ ========================= */
212
+
213
+ fs.writeFileSync(
214
+ path.join(target, "package.json"),
215
+ `{
216
+ "name": "mwalajs-app",
217
+ "version": "1.0.0",
218
+ "type": "module",
219
+ "scripts": {
220
+ "start": "node app.mjs"
221
+ },
222
+ "dependencies": {
223
+ "mwalajs": "*",
224
+ "ejs": "*"
225
+ }
226
+ }`
227
+ );
228
+
229
+ /* =========================
230
+ README
231
+ ========================= */
232
+
233
+ fs.writeFileSync(
234
+ path.join(target, "README.md"),
235
+ `# 🚀 MwalaJS Project
236
+
237
+ ## Run project
238
+
239
+ npm install
240
+ npm start
241
+
242
+ ## Structure
243
+ - MVC architecture
244
+ - Controllers
245
+ - Routes
246
+ - Models
247
+ - Views
248
+ `
249
+ );
250
+
251
+ console.log("✅ FULL manual scaffold created successfully!");
252
+ }
253
+
254
+ /* =========================
255
+ MAIN PROJECT CREATOR
256
+ ========================= */
55
257
 
56
- /**
57
- * Create project
58
- */
59
258
  export async function createProject(projectArg) {
60
- const rl = readline.createInterface({
61
- input: process.stdin,
62
- output: process.stdout
63
- });
259
+ const rl = readline.createInterface({
260
+ input: process.stdin,
261
+ output: process.stdout
262
+ });
64
263
 
65
- try {
66
- let projectName = projectArg?.trim();
264
+ let createdMode = "unknown";
67
265
 
68
- if (!projectName) {
69
- projectName = await askQuestion(rl, "Enter project name: ");
70
- }
266
+ try {
267
+ let projectName = projectArg?.trim();
71
268
 
72
- if (!projectName) {
73
- console.error(" Project name required");
74
- return;
75
- }
269
+ if (!projectName) {
270
+ projectName = await ask(rl, "Enter project name: ");
271
+ }
76
272
 
77
- const newProjectPath = path.join(process.cwd(), projectName);
273
+ if (!projectName) {
274
+ console.log("❌ Project name is required");
275
+ return;
276
+ }
78
277
 
79
- const templatePath = getMwalajsPath();
278
+ const target = path.join(process.cwd(), projectName);
80
279
 
81
- if (!fs.existsSync(templatePath)) {
82
- throw new Error("Template path not found: " + templatePath);
83
- }
280
+ if (fs.existsSync(target)) {
281
+ console.log(" Folder already exists");
282
+ return;
283
+ }
84
284
 
85
- if (fs.existsSync(newProjectPath)) {
86
- console.error(`❌ Folder already exists: ${projectName}`);
87
- return;
88
- }
285
+ fs.mkdirSync(target, { recursive: true });
286
+
287
+ const templatePath = getMwalajsPath();
288
+
289
+ /* =========================
290
+ TEMPLATE MODE
291
+ ========================= */
292
+
293
+ if (templatePath) {
294
+ console.log("📦 Template found:", templatePath);
295
+
296
+ const items = [
297
+ "controllers",
298
+ "routes",
299
+ "models",
300
+ "views",
301
+ "middlewares",
302
+ "migrations",
303
+ "public",
304
+ "app.mjs",
305
+ "README.md"
306
+ ];
307
+
308
+ let copied = 0;
89
309
 
90
- console.log(`📦 Creating project: ${projectName}`);
91
- console.log(`📁 From template: ${templatePath}`);
92
-
93
- fs.mkdirSync(newProjectPath, { recursive: true });
94
-
95
- const itemsToCopy = [
96
- "app.mjs",
97
- "controllers",
98
- "migrations",
99
- "routes",
100
- "views",
101
- "middlewares",
102
- "models",
103
- "public",
104
- "README.md"
105
- ];
106
-
107
- let copied = 0;
108
-
109
- for (const item of itemsToCopy) {
110
- const src = path.join(templatePath, item);
111
- const dest = path.join(newProjectPath, item);
112
-
113
- if (fs.existsSync(src)) {
114
- console.log(`✔ Copying ${item}`);
115
- fs.copySync(src, dest);
116
- copied++;
117
- } else {
118
- console.warn(`⚠ Missing template item: ${item}`);
119
- }
310
+ for (const item of items) {
311
+ const src = path.join(templatePath, item);
312
+ const dest = path.join(target, item);
313
+
314
+ if (fs.existsSync(src)) {
315
+ fs.copySync(src, dest);
316
+ console.log("✔ copied:", item);
317
+ copied++;
318
+ } else {
319
+ console.log("⚠ missing:", item);
120
320
  }
321
+ }
322
+
323
+ if (copied === 0) {
324
+ console.log("⚠ Template empty → switching to manual mode...");
325
+ createManualTemplate(target);
326
+ createdMode = "manual";
327
+ } else {
328
+ createdMode = "template";
329
+ }
121
330
 
122
- console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━");
123
- console.log(`✅ Project created: ${projectName}`);
124
- console.log(`📁 Location: ${newProjectPath}`);
125
- console.log(`📦 Files copied: ${copied}/${itemsToCopy.length}`);
126
- console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━");
331
+ } else {
332
+ /* =========================
333
+ MANUAL MODE
334
+ ========================= */
127
335
 
128
- } catch (err) {
129
- console.error("❌ Create project failed:", err.message);
130
- } finally {
131
- rl.close();
336
+ createManualTemplate(target);
337
+ createdMode = "manual";
132
338
  }
339
+
340
+ /* =========================
341
+ FINAL OUTPUT (NO FAKE SUCCESS)
342
+ ========================= */
343
+
344
+ console.log("\n============================");
345
+ console.log("🎉 PROJECT CREATED SUCCESSFULLY");
346
+ console.log("============================");
347
+ console.log("📁 Path:", target);
348
+ console.log("⚙ Mode:", createdMode.toUpperCase());
349
+ console.log("============================\n");
350
+
351
+ } catch (err) {
352
+ console.error("❌ Create project failed:", err.message);
353
+ } finally {
354
+ rl.close();
355
+ }
133
356
  }
134
357
 
135
- /**
136
- * CLI support
137
- */
358
+ /* =========================
359
+ CLI EXECUTION
360
+ ========================= */
361
+
138
362
  if (import.meta.url === `file://${process.argv[1]}`) {
139
- createProject(process.argv[2]);
363
+ createProject(process.argv[2]);
140
364
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mwalajs",
3
- "version": "1.1.15",
3
+ "version": "1.1.17",
4
4
  "description": "MwalaJS Framework CLI Tool and Web Framework for Backend and Frontend Development.",
5
5
  "type": "module",
6
6
  "main": "app.mjs",