lumpiajs 1.0.4 → 1.0.6
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/README.md +114 -48
- package/index.js +1 -1
- package/lib/commands/create.js +68 -67
- package/lib/commands/serve.js +14 -14
- package/lib/core/Controller.js +5 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
# 🥟 LumpiaJS
|
|
2
2
|
|
|
3
|
-
**
|
|
4
|
-
_Framework ini dibuat untuk seru-seruan (have fun)
|
|
3
|
+
**Bahasa Pemrograman Web dengan Kearifan Lokal Semarangan.**
|
|
4
|
+
_Framework ini dibuat untuk seru-seruan (have fun) dan biar bikin web jadi lebih cepat dan menyenangkan!_ (Rencananya sih gitu... wkwkwk)
|
|
5
5
|
|
|
6
|
-
## 🚀 Cara
|
|
6
|
+
## 🚀 Cara Pakai (Quick Start)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Kamu bisa pilih cara yang paling enak buat mulai bikin (masak) web:
|
|
9
9
|
|
|
10
|
-
Langsung
|
|
10
|
+
### 1. Langsung Gas (Tanpa Install)
|
|
11
|
+
|
|
12
|
+
Kalau malas install-install, pastikan komputer kamu sudah ada Node.js, lalu langsung aja pakai `npx`:
|
|
13
|
+
|
|
14
|
+
**Langkah 1: Buat Project**
|
|
11
15
|
|
|
12
16
|
```bash
|
|
13
17
|
npx lumpiajs create-project warung-ku
|
|
@@ -15,116 +19,178 @@ npx lumpiajs create-project warung-ku
|
|
|
15
19
|
|
|
16
20
|
_(Atau pakai istilah lokal: `npx lumpiajs buka-cabang warung-ku`)_
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Masuk ke foldernya dan install dependencies (wajib, biar kodingannya gurih):
|
|
22
|
+
**Langkah 2: Masuk & Install Bumbu (Dependencies)**
|
|
23
|
+
Penting! Kamu harus install dependencies biar `import` framework-nya jalan.
|
|
21
24
|
|
|
22
25
|
```bash
|
|
23
26
|
cd warung-ku
|
|
24
27
|
npm install
|
|
25
28
|
```
|
|
26
29
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
Nyalakan server development:
|
|
30
|
+
**Langkah 3: Nyalakan Kompor (Server)**
|
|
30
31
|
|
|
31
32
|
```bash
|
|
32
33
|
npm start
|
|
33
34
|
```
|
|
34
35
|
|
|
35
|
-
Atau
|
|
36
|
+
_(Atau manual: `npx lumpia dodolan`)_
|
|
36
37
|
Websitemu bakal jalan di `http://localhost:3000`.
|
|
37
38
|
|
|
38
39
|
---
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
### 2. Install Global (Biar Bisa Dipakai Terus)
|
|
42
|
+
|
|
43
|
+
Kalau kamu pengen perintah `lumpia` bisa dipanggil dari mana saja di terminal:
|
|
41
44
|
|
|
42
|
-
|
|
45
|
+
```bash
|
|
46
|
+
# 1. Install dulu secara global
|
|
47
|
+
npm install -g lumpiajs
|
|
48
|
+
|
|
49
|
+
# 2. Bikin project baru
|
|
50
|
+
lumpia create-project toko-lumpia
|
|
51
|
+
|
|
52
|
+
# 3. Masuk folder & install npm
|
|
53
|
+
cd toko-lumpia
|
|
54
|
+
npm install
|
|
55
|
+
|
|
56
|
+
# 4. Jalanin server
|
|
57
|
+
lumpia dodolan
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Cara Update ke Versi Terbaru:**
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npm install -g lumpiajs@latest
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 🏗️ Struktur Project (Standar MVC)
|
|
69
|
+
|
|
70
|
+
LumpiaJS sekarang menggunakan arsitektur **MVC (Model-View-Controller)** yang mengikuti standar internasional, jadi developer Laravel atau Express pasti langsung paham.
|
|
43
71
|
|
|
44
72
|
```
|
|
45
73
|
warung-ku/
|
|
46
74
|
├── app/
|
|
47
|
-
│ ├──
|
|
48
|
-
│ └──
|
|
49
|
-
├──
|
|
50
|
-
│ └── web.js # Rute URL
|
|
51
|
-
├──
|
|
75
|
+
│ ├── controllers/ # Otak Logika (Controller)
|
|
76
|
+
│ └── models/ # Pengolah Data (Model)
|
|
77
|
+
├── routes/
|
|
78
|
+
│ └── web.js # Rute URL
|
|
79
|
+
├── views/ # Tampilan (.lmp)
|
|
52
80
|
├── package.json
|
|
53
81
|
└── ...
|
|
54
82
|
```
|
|
55
83
|
|
|
56
|
-
### 1.
|
|
84
|
+
### 1. Routes (`routes/web.js`)
|
|
57
85
|
|
|
58
|
-
|
|
86
|
+
Tempat mengatur alamat URL web kamu.
|
|
59
87
|
|
|
60
88
|
```javascript
|
|
61
89
|
import { Jalan } from "lumpiajs";
|
|
62
90
|
|
|
63
|
-
//
|
|
64
|
-
Jalan.gawe("/", "
|
|
65
|
-
Jalan.gawe("/api/
|
|
91
|
+
// Jalan.gawe(url, 'NamaController@method')
|
|
92
|
+
Jalan.gawe("/", "HomeController@index");
|
|
93
|
+
Jalan.gawe("/api/products", "ProductController@index");
|
|
66
94
|
```
|
|
67
95
|
|
|
68
|
-
### 2.
|
|
96
|
+
### 2. Controllers (`app/controllers`)
|
|
69
97
|
|
|
70
|
-
|
|
71
|
-
Class harus extend `Logika`.
|
|
98
|
+
Otak dari aplikasimu. Class harus meng-extend `Controller`.
|
|
72
99
|
|
|
73
100
|
```javascript
|
|
74
|
-
import {
|
|
101
|
+
import { Controller } from "lumpiajs";
|
|
75
102
|
|
|
76
|
-
export default class
|
|
103
|
+
export default class HomeController extends Controller {
|
|
77
104
|
index() {
|
|
78
|
-
//
|
|
79
|
-
|
|
80
|
-
|
|
105
|
+
// Tampilkan file di folder views/home.lmp
|
|
106
|
+
// Kirim data 'pesan' ke view
|
|
107
|
+
return this.tampil("home", {
|
|
108
|
+
pesan: "Halo Dunia!",
|
|
81
109
|
tanggal: new Date().toLocaleDateString(),
|
|
82
110
|
});
|
|
83
111
|
}
|
|
84
112
|
}
|
|
85
113
|
```
|
|
86
114
|
|
|
87
|
-
### 3.
|
|
115
|
+
### 3. Views (`views`)
|
|
88
116
|
|
|
89
|
-
|
|
90
|
-
Gunakan `{{
|
|
117
|
+
File `.lmp` adalah tempat kamu menulis HTML, CSS, dan JS Semarangan dalam satu file.
|
|
118
|
+
Gunakan `{{ nama_variabel }}` untuk menampilkan data dari Controller.
|
|
91
119
|
|
|
92
120
|
```html
|
|
93
121
|
<lump>
|
|
94
|
-
<klambi> h1 { color:
|
|
122
|
+
<klambi> /* CSS di sini */ h1 { color: #d35400; } </klambi>
|
|
95
123
|
|
|
96
124
|
<kulit>
|
|
125
|
+
<!-- HTML di sini -->
|
|
97
126
|
<h1>{{ pesan }}</h1>
|
|
98
|
-
<p>
|
|
127
|
+
<p>Tanggal server: {{ tanggal }}</p>
|
|
99
128
|
</kulit>
|
|
129
|
+
|
|
130
|
+
<isi>
|
|
131
|
+
// JavaScript Client-side (Bahasa Semarangan) gawe sapa() { alert("Halo,
|
|
132
|
+
Lur!"); }
|
|
133
|
+
</isi>
|
|
100
134
|
</lump>
|
|
101
135
|
```
|
|
102
136
|
|
|
103
|
-
### 4.
|
|
137
|
+
### 4. Models (`app/models`)
|
|
104
138
|
|
|
105
|
-
|
|
106
|
-
Bisa nggunake `Model` ala Eloquent.
|
|
139
|
+
Tempat mengolah data (Database/API). Mendukung gaya penulisan ala Eloquent.
|
|
107
140
|
|
|
108
141
|
```javascript
|
|
109
142
|
import { Model } from "lumpiajs";
|
|
110
|
-
|
|
143
|
+
|
|
144
|
+
// Contoh penggunaan di Controller:
|
|
145
|
+
// Model.use(dataProduk).dimana('harga', '<', 5000).kabeh();
|
|
111
146
|
```
|
|
112
147
|
|
|
113
148
|
---
|
|
114
149
|
|
|
115
|
-
##
|
|
150
|
+
## 🧐 Kamus Bahasa (Transpiler)
|
|
151
|
+
|
|
152
|
+
Khusus di dalam tag **`<isi>`** (pada file `.lmp`), kamu bisa menggunakan sintaks unik ini:
|
|
153
|
+
|
|
154
|
+
- `ono` ➔ `let`
|
|
155
|
+
- `paten` ➔ `const`
|
|
156
|
+
- `gawe` ➔ `function`
|
|
157
|
+
- `yen` ➔ `if`
|
|
158
|
+
- `liyane` ➔ `else`
|
|
159
|
+
- `mandek` ➔ `return`
|
|
160
|
+
- `ora` ➔ `!`
|
|
161
|
+
- `panjang()` ➔ `.length`
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## 🤝 Cara Lapor Masalah atau Kasih Saran
|
|
166
|
+
|
|
167
|
+
Baru nemu bug? Atau punya ide jenius biar LumpiaJS makin jos? Sampaikan saja!
|
|
116
168
|
|
|
117
|
-
|
|
169
|
+
Caranya gampang:
|
|
118
170
|
|
|
119
171
|
1. Buka link ini: [https://github.com/fastroware/lumpiajs/issues](https://github.com/fastroware/lumpiajs/issues)
|
|
120
|
-
2. Klik **"New Issue"**.
|
|
121
|
-
3.
|
|
172
|
+
2. Klik tombol warna hijau bertuliskan **"New Issue"**.
|
|
173
|
+
3. Isi Judul dengan jelas.
|
|
174
|
+
4. Jelaskan masalah atau saranmu di kolom deskripsi.
|
|
175
|
+
5. Klik **"Submit new issue"**.
|
|
176
|
+
|
|
177
|
+
Selesai! Masukanmu akan saya baca pas lagi senggang.
|
|
122
178
|
|
|
123
179
|
---
|
|
124
180
|
|
|
125
|
-
## ⚠️ DISCLAIMER
|
|
181
|
+
## ⚠️ DISCLAIMER (PENTING BANGET, WAJIB DIBACA!) ⚠️
|
|
182
|
+
|
|
183
|
+
**LumpiaJS ini 100% project _Have Fun_ & Eksperimen.**
|
|
126
184
|
|
|
127
|
-
**
|
|
128
|
-
|
|
185
|
+
Kami **TIDAK BERTANGGUNG JAWAB** atas segala bentuk kerugian yang mungkin terjadi akibat penggunaan software ini, termasuk tapi tidak terbatas pada:
|
|
186
|
+
|
|
187
|
+
- Kebocoran data.
|
|
188
|
+
- Hilangnya file penting.
|
|
189
|
+
- Komputer meledak (lebay, tapi tetap saja hati-hati).
|
|
190
|
+
- Kerugian materiil maupun immateriil lainnya.
|
|
191
|
+
|
|
192
|
+
Gunakan framework ini dengan resiko ditanggung sendiri (_Use at your own risk_). Kalau ada error di production karena nekat pakai ini, jangan nyalahin kami ya! 🙏
|
|
193
|
+
|
|
194
|
+
---
|
|
129
195
|
|
|
130
196
|
_Dibuat dengan ❤️ dan 🥟 dari Semarang._
|
package/index.js
CHANGED
package/lib/commands/create.js
CHANGED
|
@@ -4,101 +4,100 @@ import path from 'path';
|
|
|
4
4
|
// --- TEMPLATES ---
|
|
5
5
|
const routesTemplate = `import { Jalan } from 'lumpiajs';
|
|
6
6
|
|
|
7
|
-
//
|
|
8
|
-
Jalan.gawe('/', '
|
|
9
|
-
Jalan.gawe('/
|
|
10
|
-
Jalan.gawe('/api/
|
|
7
|
+
// Define Routes
|
|
8
|
+
Jalan.gawe('/', 'HomeController@index');
|
|
9
|
+
Jalan.gawe('/profile', 'HomeController@profile');
|
|
10
|
+
Jalan.gawe('/api/products', 'ProductController@index');
|
|
11
11
|
`;
|
|
12
12
|
|
|
13
|
-
const controllerTemplate = `import {
|
|
13
|
+
const controllerTemplate = `import { Controller } from 'lumpiajs';
|
|
14
14
|
|
|
15
|
-
export default class
|
|
15
|
+
export default class HomeController extends Controller {
|
|
16
16
|
index() {
|
|
17
|
-
//
|
|
18
|
-
return this.tampil('
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
// Render view in 'views' folder
|
|
18
|
+
return this.tampil('home', {
|
|
19
|
+
message: 'Welcome to LumpiaJS MVC!',
|
|
20
|
+
author: 'Pakdhe Koding'
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
return this.tampil('
|
|
24
|
+
profile() {
|
|
25
|
+
return this.tampil('profile', { name: 'Loyal User' });
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
`;
|
|
29
29
|
|
|
30
|
-
const modelTemplate = `//
|
|
31
|
-
const
|
|
32
|
-
{ id: 1,
|
|
33
|
-
{ id: 2,
|
|
34
|
-
{ id: 3,
|
|
30
|
+
const modelTemplate = `// Example dummy data
|
|
31
|
+
const productData = [
|
|
32
|
+
{ id: 1, name: 'Lumpia Basah', price: 5000 },
|
|
33
|
+
{ id: 2, name: 'Lumpia Goreng', price: 6000 },
|
|
34
|
+
{ id: 3, name: 'Tahu Gimbal', price: 12000 }
|
|
35
35
|
];
|
|
36
36
|
|
|
37
|
-
export default
|
|
37
|
+
export default productData;
|
|
38
38
|
`;
|
|
39
39
|
|
|
40
|
-
const
|
|
41
|
-
import
|
|
40
|
+
const productControllerTemplate = `import { Controller, Model } from 'lumpiajs';
|
|
41
|
+
import ProductData from '../../app/models/Product.js';
|
|
42
42
|
|
|
43
|
-
export default class
|
|
43
|
+
export default class ProductController extends Controller {
|
|
44
44
|
index() {
|
|
45
45
|
// Eloquent-style: Model.use(data).dimana(...).jupuk()
|
|
46
|
-
const
|
|
47
|
-
.dimana('
|
|
46
|
+
const result = Model.use(ProductData)
|
|
47
|
+
.dimana('price', '>', 5500)
|
|
48
48
|
.jupuk();
|
|
49
49
|
|
|
50
50
|
return this.json({
|
|
51
|
-
status: '
|
|
52
|
-
data:
|
|
51
|
+
status: 'success',
|
|
52
|
+
data: result
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
`;
|
|
57
57
|
|
|
58
|
-
const
|
|
58
|
+
const viewHomeTemplate = `<lump>
|
|
59
59
|
<klambi>
|
|
60
60
|
h1 { color: #d35400; text-align: center; }
|
|
61
61
|
.box { border: 1px solid #ddd; padding: 20px; text-align: center; margin-top: 20px; }
|
|
62
62
|
</klambi>
|
|
63
63
|
|
|
64
64
|
<kulit>
|
|
65
|
-
<h1>{{
|
|
65
|
+
<h1>{{ message }}</h1>
|
|
66
66
|
<div class="box">
|
|
67
|
-
<p>
|
|
68
|
-
<button onclick="
|
|
67
|
+
<p>Created with love by: <strong>{{ author }}</strong></p>
|
|
68
|
+
<button onclick="checkPrice()">Check Price API</button>
|
|
69
69
|
<br><br>
|
|
70
|
-
<a href="/
|
|
70
|
+
<a href="/profile">Go to Profile</a>
|
|
71
71
|
</div>
|
|
72
72
|
</kulit>
|
|
73
73
|
|
|
74
74
|
<isi>
|
|
75
|
-
gawe
|
|
76
|
-
fetch('/api/
|
|
75
|
+
gawe checkPrice() {
|
|
76
|
+
fetch('/api/products')
|
|
77
77
|
.then(res => res.json())
|
|
78
78
|
.then(data => {
|
|
79
|
-
alert('Data
|
|
79
|
+
alert('Data from API: ' + JSON.stringify(data));
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
</isi>
|
|
83
83
|
</lump>`;
|
|
84
84
|
|
|
85
|
-
const
|
|
85
|
+
const viewProfileTemplate = `<lump>
|
|
86
86
|
<kulit>
|
|
87
|
-
<h1>
|
|
88
|
-
<p>
|
|
89
|
-
<a href="/">
|
|
87
|
+
<h1>User Profile</h1>
|
|
88
|
+
<p>Hello, <strong>{{ name }}</strong>!</p>
|
|
89
|
+
<a href="/">Back Home</a>
|
|
90
90
|
</kulit>
|
|
91
91
|
</lump>`;
|
|
92
92
|
|
|
93
93
|
const packageJsonTemplate = (name) => `{
|
|
94
94
|
"name": "${name}",
|
|
95
95
|
"version": "1.0.0",
|
|
96
|
-
"main": "
|
|
96
|
+
"main": "routes/web.js",
|
|
97
97
|
"type": "module",
|
|
98
98
|
"scripts": {
|
|
99
99
|
"start": "lumpia dodolan",
|
|
100
|
-
"serve": "lumpia dodolan"
|
|
101
|
-
"goreng": "lumpia goreng"
|
|
100
|
+
"serve": "lumpia dodolan"
|
|
102
101
|
},
|
|
103
102
|
"dependencies": {
|
|
104
103
|
"lumpiajs": "latest"
|
|
@@ -107,42 +106,44 @@ const packageJsonTemplate = (name) => `{
|
|
|
107
106
|
`;
|
|
108
107
|
|
|
109
108
|
export function createProject(parameter) {
|
|
110
|
-
const
|
|
111
|
-
if (!
|
|
112
|
-
console.log('❌
|
|
113
|
-
console.log('
|
|
109
|
+
const projectName = parameter;
|
|
110
|
+
if (!projectName) {
|
|
111
|
+
console.log('❌ Please specify project name.');
|
|
112
|
+
console.log('Example: lumpia create-project my-app');
|
|
114
113
|
return;
|
|
115
114
|
}
|
|
116
115
|
|
|
117
|
-
const root = path.join(process.cwd(),
|
|
118
|
-
if (fs.existsSync(root)) return console.log(`❌ Folder ${
|
|
116
|
+
const root = path.join(process.cwd(), projectName);
|
|
117
|
+
if (fs.existsSync(root)) return console.log(`❌ Folder ${projectName} already exists.`);
|
|
119
118
|
|
|
120
|
-
console.log(`🔨
|
|
119
|
+
console.log(`🔨 Building MVC foundation in ${projectName}...`);
|
|
121
120
|
|
|
122
121
|
fs.mkdirSync(root);
|
|
123
|
-
// STRUCTURE UPDATE:
|
|
124
|
-
// app/logika (Controller)
|
|
125
|
-
// app/belakang (Model)
|
|
126
|
-
// depan (View)
|
|
127
122
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
123
|
+
// STANDARD MVC STRUCTURE:
|
|
124
|
+
// app/controllers
|
|
125
|
+
// app/models
|
|
126
|
+
// views
|
|
127
|
+
// routes
|
|
128
|
+
|
|
129
|
+
fs.mkdirSync(path.join(root, 'app', 'controllers'), { recursive: true });
|
|
130
|
+
fs.mkdirSync(path.join(root, 'app', 'models'), { recursive: true });
|
|
131
|
+
fs.mkdirSync(path.join(root, 'routes'));
|
|
132
|
+
fs.mkdirSync(path.join(root, 'views'));
|
|
132
133
|
|
|
133
134
|
// Write files
|
|
134
|
-
fs.writeFileSync(path.join(root, 'package.json'), packageJsonTemplate(
|
|
135
|
-
fs.writeFileSync(path.join(root, '
|
|
136
|
-
fs.writeFileSync(path.join(root, 'app', '
|
|
137
|
-
fs.writeFileSync(path.join(root, 'app', '
|
|
138
|
-
fs.writeFileSync(path.join(root, 'app', '
|
|
139
|
-
fs.writeFileSync(path.join(root, '
|
|
140
|
-
fs.writeFileSync(path.join(root, '
|
|
141
|
-
|
|
142
|
-
console.log('✅
|
|
135
|
+
fs.writeFileSync(path.join(root, 'package.json'), packageJsonTemplate(projectName));
|
|
136
|
+
fs.writeFileSync(path.join(root, 'routes', 'web.js'), routesTemplate);
|
|
137
|
+
fs.writeFileSync(path.join(root, 'app', 'controllers', 'HomeController.js'), controllerTemplate);
|
|
138
|
+
fs.writeFileSync(path.join(root, 'app', 'controllers', 'ProductController.js'), productControllerTemplate);
|
|
139
|
+
fs.writeFileSync(path.join(root, 'app', 'models', 'Product.js'), modelTemplate);
|
|
140
|
+
fs.writeFileSync(path.join(root, 'views', 'home.lmp'), viewHomeTemplate);
|
|
141
|
+
fs.writeFileSync(path.join(root, 'views', 'profile.lmp'), viewProfileTemplate);
|
|
142
|
+
|
|
143
|
+
console.log('✅ Project ready! Standard MVC Structure.');
|
|
143
144
|
console.log('----------------------------------------------------');
|
|
144
|
-
console.log(`cd ${
|
|
145
|
-
console.log('npm install
|
|
146
|
-
console.log('npm
|
|
145
|
+
console.log(`cd ${projectName}`);
|
|
146
|
+
console.log('npm install');
|
|
147
|
+
console.log('npm start');
|
|
147
148
|
console.log('----------------------------------------------------');
|
|
148
149
|
}
|
package/lib/commands/serve.js
CHANGED
|
@@ -6,18 +6,18 @@ import { renderLumpia } from '../core/View.js';
|
|
|
6
6
|
|
|
7
7
|
export async function serveProject() {
|
|
8
8
|
const root = process.cwd();
|
|
9
|
-
const routesFile = path.join(root, '
|
|
9
|
+
const routesFile = path.join(root, 'routes', 'web.js');
|
|
10
10
|
|
|
11
|
-
if (!fs.existsSync(routesFile)) return console.log("❌
|
|
11
|
+
if (!fs.existsSync(routesFile)) return console.log("❌ This is not a LumpiaJS MVC project! (Cannot find routes/web.js)");
|
|
12
12
|
|
|
13
13
|
console.log('🔄 Loading core framework...');
|
|
14
14
|
|
|
15
15
|
try {
|
|
16
16
|
// Load User Routes
|
|
17
|
-
const userRouteUrl = path.join(root, '
|
|
17
|
+
const userRouteUrl = path.join(root, 'routes', 'web.js');
|
|
18
18
|
await import('file://' + userRouteUrl);
|
|
19
19
|
|
|
20
|
-
console.log(`🛣️
|
|
20
|
+
console.log(`🛣️ Routes found: ${routes.length}`);
|
|
21
21
|
|
|
22
22
|
// Start Server
|
|
23
23
|
const server = http.createServer(async (req, res) => {
|
|
@@ -31,20 +31,20 @@ export async function serveProject() {
|
|
|
31
31
|
|
|
32
32
|
if (match) {
|
|
33
33
|
try {
|
|
34
|
-
// Action format: '
|
|
34
|
+
// Action format: 'ControllerName@method'
|
|
35
35
|
const [controllerName, methodName] = match.action.split('@');
|
|
36
36
|
|
|
37
|
-
// Path
|
|
38
|
-
const controllerPath = path.join(root, 'app', '
|
|
37
|
+
// Path to 'app/controllers'
|
|
38
|
+
const controllerPath = path.join(root, 'app', 'controllers', controllerName + '.js');
|
|
39
39
|
|
|
40
|
-
if (!fs.existsSync(controllerPath)) throw new Error(`
|
|
40
|
+
if (!fs.existsSync(controllerPath)) throw new Error(`Controller ${controllerName} not found in app/controllers!`);
|
|
41
41
|
|
|
42
42
|
const module = await import('file://' + controllerPath + '?update=' + Date.now());
|
|
43
43
|
const ControllerClass = module.default;
|
|
44
44
|
const instance = new ControllerClass();
|
|
45
45
|
|
|
46
46
|
if (typeof instance[methodName] !== 'function') {
|
|
47
|
-
throw new Error(`Method ${methodName}
|
|
47
|
+
throw new Error(`Method ${methodName} does not exist in ${controllerName}`);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
const result = await instance[methodName]();
|
|
@@ -62,21 +62,21 @@ export async function serveProject() {
|
|
|
62
62
|
} catch (e) {
|
|
63
63
|
console.error(e);
|
|
64
64
|
res.writeHead(500, {'Content-Type': 'text/html'});
|
|
65
|
-
res.end(`<h1>500:
|
|
65
|
+
res.end(`<h1>500: Server Error</h1><pre>${e.message}\n${e.stack}</pre>`);
|
|
66
66
|
}
|
|
67
67
|
} else {
|
|
68
68
|
res.writeHead(404, {'Content-Type': 'text/html'});
|
|
69
|
-
res.end('<h1>404:
|
|
69
|
+
res.end('<h1>404: Not Found</h1>');
|
|
70
70
|
}
|
|
71
71
|
});
|
|
72
72
|
|
|
73
73
|
const port = 3000;
|
|
74
74
|
server.listen(port, () => {
|
|
75
|
-
console.log(`🚀
|
|
76
|
-
console.log(`(
|
|
75
|
+
console.log(`🚀 Server running at http://localhost:${port}`);
|
|
76
|
+
console.log(`(Press Ctrl+C to stop)`);
|
|
77
77
|
});
|
|
78
78
|
|
|
79
79
|
} catch (err) {
|
|
80
|
-
console.error('Fatal Error
|
|
80
|
+
console.error('Fatal Error loading routes:', err);
|
|
81
81
|
}
|
|
82
82
|
}
|
package/lib/core/Controller.js
CHANGED
|
@@ -2,15 +2,15 @@ import fs from 'fs';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { renderLumpia } from './View.js';
|
|
4
4
|
|
|
5
|
-
// 3. BASE
|
|
6
|
-
export class
|
|
5
|
+
// 3. CONTROLLER BASE
|
|
6
|
+
export class Controller {
|
|
7
7
|
tampil(viewName, data = {}) {
|
|
8
|
-
// Cek lokasi view relative dari CWD user (folder '
|
|
9
|
-
const viewPath = path.join(process.cwd(), '
|
|
8
|
+
// Cek lokasi view relative dari CWD user (folder 'views')
|
|
9
|
+
const viewPath = path.join(process.cwd(), 'views', `${viewName}.lmp`);
|
|
10
10
|
if (fs.existsSync(viewPath)) {
|
|
11
11
|
return { type: 'html', content: renderLumpia(viewPath, data) };
|
|
12
12
|
} else {
|
|
13
|
-
return { type: 'html', content: `<h1>404:
|
|
13
|
+
return { type: 'html', content: `<h1>404: View '${viewName}' not found in 'views' folder.</h1>` };
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|