ngapakin 1.0.0__tar.gz
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.
- ngapakin-1.0.0/LICENSE +21 -0
- ngapakin-1.0.0/PKG-INFO +230 -0
- ngapakin-1.0.0/README.md +207 -0
- ngapakin-1.0.0/framework/__init__.py +5 -0
- ngapakin-1.0.0/framework/auth.py +75 -0
- ngapakin-1.0.0/framework/cache.py +72 -0
- ngapakin-1.0.0/framework/container.py +42 -0
- ngapakin-1.0.0/framework/controller.py +51 -0
- ngapakin-1.0.0/framework/database.py +58 -0
- ngapakin-1.0.0/framework/env.py +44 -0
- ngapakin-1.0.0/framework/event.py +30 -0
- ngapakin-1.0.0/framework/middleware.py +62 -0
- ngapakin-1.0.0/framework/model.py +232 -0
- ngapakin-1.0.0/framework/package_manager.py +127 -0
- ngapakin-1.0.0/framework/query_builder.py +105 -0
- ngapakin-1.0.0/framework/queue.py +145 -0
- ngapakin-1.0.0/framework/request.py +47 -0
- ngapakin-1.0.0/framework/response.py +60 -0
- ngapakin-1.0.0/framework/router.py +74 -0
- ngapakin-1.0.0/framework/schema.py +52 -0
- ngapakin-1.0.0/framework/session.py +85 -0
- ngapakin-1.0.0/framework/template_engine.py +283 -0
- ngapakin-1.0.0/framework/validation.py +100 -0
- ngapakin-1.0.0/framework/view.py +8 -0
- ngapakin-1.0.0/ngapak/__init__.py +9 -0
- ngapakin-1.0.0/ngapak/ast.py +186 -0
- ngapakin-1.0.0/ngapak/builtins.py +76 -0
- ngapakin-1.0.0/ngapak/bytecode.py +34 -0
- ngapakin-1.0.0/ngapak/compiler.py +580 -0
- ngapakin-1.0.0/ngapak/debugger.py +138 -0
- ngapakin-1.0.0/ngapak/environment.py +63 -0
- ngapakin-1.0.0/ngapak/errors.py +28 -0
- ngapakin-1.0.0/ngapak/frame.py +10 -0
- ngapakin-1.0.0/ngapak/interpreter.py +236 -0
- ngapakin-1.0.0/ngapak/lexer.py +193 -0
- ngapakin-1.0.0/ngapak/opcode.py +41 -0
- ngapakin-1.0.0/ngapak/parser.py +417 -0
- ngapakin-1.0.0/ngapak/token.py +90 -0
- ngapakin-1.0.0/ngapak/vm.py +579 -0
- ngapakin-1.0.0/ngapakin.egg-info/PKG-INFO +230 -0
- ngapakin-1.0.0/ngapakin.egg-info/SOURCES.txt +55 -0
- ngapakin-1.0.0/ngapakin.egg-info/dependency_links.txt +1 -0
- ngapakin-1.0.0/ngapakin.egg-info/entry_points.txt +2 -0
- ngapakin-1.0.0/ngapakin.egg-info/top_level.txt +3 -0
- ngapakin-1.0.0/ngapakin.py +905 -0
- ngapakin-1.0.0/setup.cfg +4 -0
- ngapakin-1.0.0/setup.py +25 -0
- ngapakin-1.0.0/tests/test_compiler.py +69 -0
- ngapakin-1.0.0/tests/test_ecosystem.py +196 -0
- ngapakin-1.0.0/tests/test_interpreter.py +93 -0
- ngapakin-1.0.0/tests/test_lexer.py +76 -0
- ngapakin-1.0.0/tests/test_orm.py +144 -0
- ngapakin-1.0.0/tests/test_parser.py +96 -0
- ngapakin-1.0.0/tests/test_router.py +49 -0
- ngapakin-1.0.0/tests/test_template.py +132 -0
- ngapakin-1.0.0/tests/test_vm.py +108 -0
- ngapakin-1.0.0/tests/test_vm_features.py +175 -0
ngapakin-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ilham Hatta Manggala
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
ngapakin-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ngapakin
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Bahasa pemrograman berekstensi .ngpk dengan dialek Ngapak/Banyumasan & Larapak MVC Web Framework.
|
|
5
|
+
Home-page: https://github.com/IlhamHattaManggala/ngapakin
|
|
6
|
+
Author: Ilham Hatta Manggala
|
|
7
|
+
Author-email: ilham.hatta@example.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Dynamic: author
|
|
15
|
+
Dynamic: author-email
|
|
16
|
+
Dynamic: classifier
|
|
17
|
+
Dynamic: description
|
|
18
|
+
Dynamic: description-content-type
|
|
19
|
+
Dynamic: home-page
|
|
20
|
+
Dynamic: license-file
|
|
21
|
+
Dynamic: requires-python
|
|
22
|
+
Dynamic: summary
|
|
23
|
+
|
|
24
|
+
# NgapakIn & Larapak MVC 🚀
|
|
25
|
+
|
|
26
|
+
[](https://github.com/IlhamHattaManggala/ngapakin/actions/workflows/python.yml)
|
|
27
|
+
[](https://opensource.org/licenses/MIT)
|
|
28
|
+
[](https://www.python.org/)
|
|
29
|
+
|
|
30
|
+
NgapakIn adalah bahasa pemrograman open-source dengan ekstensi `.ngpk`, dirancang dengan sintaksis berbasis bahasa Ngapak / Banyumasan / Indonesia.
|
|
31
|
+
Larapak adalah MVC Web Framework lengkap yang berjalan di atas VM NgapakIn, dirancang meniru arsitektur elegan Laravel dengan fungsionalitas modern seperti ORM, Migrasi, Job Queues, Session/Cookies, Validasi, Caching, Event Dispatcher, Package Manager, hingga Language Server Protocol (LSP).
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 🌟 Fitur Utama Ekosistem (Phase 1 - Phase 5)
|
|
36
|
+
|
|
37
|
+
1. **Inti Bahasa NgapakIn (Phase 1 & 2)**:
|
|
38
|
+
- Sintaksis berbasis dialek Banyumasan (`gawe`, `rampung`, `nek - ya - liyane`, `balekna`).
|
|
39
|
+
- Tipe data lengkap: Angka, Teks, Boolean (`bener`/`salah`), dan Null (`kosong`).
|
|
40
|
+
- Stack-based Virtual Machine (VM) yang efisien dengan eksekusi bytecode cepat.
|
|
41
|
+
2. **Larapak MVC Framework (Phase 3)**:
|
|
42
|
+
- Web Server berbasis standard library HTTP.
|
|
43
|
+
- Routing dinamis (`routes/web.ngpk`, `routes/api.ngpk`).
|
|
44
|
+
- Blade-like Template Engine dengan layouting (`@layout`, `@sekat`, `@mlebui`).
|
|
45
|
+
3. **Database & ORM System (Phase 4)**:
|
|
46
|
+
- Kelas berorientasi objek (`kelas ... extends Model`).
|
|
47
|
+
- Fluent SQL Query Builder berbasis SQLite.
|
|
48
|
+
- Skema Migrasi (`schema.gawe`, `schema.buang`) dan CLI migration engine.
|
|
49
|
+
4. **Ecosystem & Advanced Features (Phase 5)**:
|
|
50
|
+
- **Autentikasi**: Fitur `auth` bawaan (`mlebu`, `metu`, `user`, `cek`).
|
|
51
|
+
- **Sesi & Cookies**: Penyimpanan sesi berbasis database SQLite, helper cookies.
|
|
52
|
+
- **Validasi**: Validator input dengan aturan `required`, `email`, `numeric`, `min`, `max`.
|
|
53
|
+
- **Cache**: Penyimpanan data sementara berbasis SQLite dengan waktu kedaluwarsa (TTL).
|
|
54
|
+
- **Event/Listener**: Dispatcher event bawaan untuk pemrograman reaktif.
|
|
55
|
+
- **Job Queues**: Pemrosesan latar belakang (background queue workers) dengan `queue:work`.
|
|
56
|
+
- **Package Manager**: Pemasangan paket otomatis beserta auto-discovery Service Provider.
|
|
57
|
+
- **REPL Terminal**: Interactive terminal interaktif via `repl`.
|
|
58
|
+
- **Step Debugger**: Breakpoint debugger interaktif (`s` step, `c` continue, `l` locals, `g` globals).
|
|
59
|
+
- **VSCode Support & LSP**: Syntax highlighting TextMate & diagnostik LSP syntax errors.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 📁 Struktur Folder Proyek
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
ngapakin/
|
|
67
|
+
├── .github/workflows/ # CI/CD Pipeline
|
|
68
|
+
├── app/
|
|
69
|
+
│ ├── Controllers/ # Controller Kelas Larapak
|
|
70
|
+
│ ├── Jobs/ # Background Jobs
|
|
71
|
+
│ ├── Middleware/ # Request Middlewares
|
|
72
|
+
│ └── Models/ # Model Database (Autoloaded)
|
|
73
|
+
├── database/
|
|
74
|
+
│ ├── migrations/ # Berkas Migrasi Database
|
|
75
|
+
│ └── seeders/ # Berkas Database Seeder
|
|
76
|
+
├── editors/vscode/ # Ekstensi VSCode & LSP Server
|
|
77
|
+
├── framework/ # Modul Internal Larapak Core
|
|
78
|
+
├── ngapak/ # Compiler, Lexer, Parser & VM NgapakLang
|
|
79
|
+
├── packages/ # Lokasi Paket yang Diinstal
|
|
80
|
+
├── routes/ # Rute web & API (.ngpk)
|
|
81
|
+
├── tests/ # Berkas Unit Testing
|
|
82
|
+
├── ngapakin.py # Entrypoint CLI
|
|
83
|
+
└── README.md
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## 🛠️ Instalasi & Penggunaan
|
|
89
|
+
|
|
90
|
+
### Prasyarat
|
|
91
|
+
- Python 3.8 ke atas (tanpa ketergantungan pustaka pihak ketiga).
|
|
92
|
+
|
|
93
|
+
### Cara Kloning & Memulai Proyek
|
|
94
|
+
```bash
|
|
95
|
+
git clone https://github.com/IlhamHattaManggala/ngapakin.git
|
|
96
|
+
cd ngapakin
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 💻 Panduan CLI Command
|
|
102
|
+
|
|
103
|
+
Larapak menyediakan CLI helper komprehensif melalui `ngapakin.py`:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# Menjalankan berkas kode biasa
|
|
107
|
+
python ngapakin.py run berkas.ngpk
|
|
108
|
+
|
|
109
|
+
# Menjalankan server web Larapak (port default: 8000)
|
|
110
|
+
python ngapakin.py serve 8000
|
|
111
|
+
|
|
112
|
+
# Melihat daftar rute terdaftar
|
|
113
|
+
python ngapakin.py route:list
|
|
114
|
+
|
|
115
|
+
# Membuat komponen baru (Scaffolding)
|
|
116
|
+
python ngapakin.py make:controller UserController
|
|
117
|
+
python ngapakin.py make:model Member
|
|
118
|
+
python ngapakin.py make:middleware AuthMiddleware
|
|
119
|
+
python ngapakin.py make:migration create_users_table
|
|
120
|
+
python ngapakin.py make:job SendEmailJob
|
|
121
|
+
|
|
122
|
+
# Migrasi Database
|
|
123
|
+
python ngapakin.py migrate # Jalankan migrasi
|
|
124
|
+
python ngapakin.py rollback # Kembalikan migrasi terakhir
|
|
125
|
+
python ngapakin.py db:seed # Jalankan seeder database
|
|
126
|
+
|
|
127
|
+
# Layanan Ekosistem
|
|
128
|
+
python ngapakin.py cache:clear # Hapus data cache
|
|
129
|
+
python ngapakin.py queue:work # Jalankan pemroses job queue
|
|
130
|
+
python ngapakin.py package:install auth-helper # Pasang paket baru
|
|
131
|
+
python ngapakin.py repl # Masuk ke REPL interaktif
|
|
132
|
+
python ngapakin.py debug berkas.ngpk # Debug bytecode berkas
|
|
133
|
+
python ngapakin.py test # Jalankan seluruh unit test suite
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 📖 Cara Menggunakan Fitur Ekosistem
|
|
139
|
+
|
|
140
|
+
### 1. Validasi & Autentikasi
|
|
141
|
+
```ngapak
|
|
142
|
+
# Validasi data request
|
|
143
|
+
data = ["email": "ilham@example.com", "umur": 20]
|
|
144
|
+
aturan = ["email": "required|email", "umur": "required|numeric|min:18"]
|
|
145
|
+
|
|
146
|
+
val = validator.gawe(data, aturan)
|
|
147
|
+
nek val.gagal() ya
|
|
148
|
+
tulis "Validasi Gagal!"
|
|
149
|
+
tulis val.errors()
|
|
150
|
+
liyane
|
|
151
|
+
tulis "Validasi Sukses!"
|
|
152
|
+
rampung
|
|
153
|
+
|
|
154
|
+
# Login user
|
|
155
|
+
nek auth.mlebu("ilham@example.com", "password123") ya
|
|
156
|
+
tulis "Berhasil Login!"
|
|
157
|
+
tulis auth.user().name
|
|
158
|
+
liyane
|
|
159
|
+
tulis "Login Gagal!"
|
|
160
|
+
rampung
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### 2. Caching & Sesi
|
|
164
|
+
```ngapak
|
|
165
|
+
# Sesi
|
|
166
|
+
sesi.pasang("cart_total", 150000)
|
|
167
|
+
total = sesi.entuk("cart_total")
|
|
168
|
+
|
|
169
|
+
# Cache (Simpan data 60 detik)
|
|
170
|
+
cache.pasang("weather_jakarta", "Hujan", 60)
|
|
171
|
+
cuaca = cache.entuk("weather_jakarta")
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### 3. Event & Queue
|
|
175
|
+
```ngapak
|
|
176
|
+
# Event
|
|
177
|
+
gawe kirimNotif(data)
|
|
178
|
+
tulis "Mengirim notifikasi ke user ID: " + data
|
|
179
|
+
rampung
|
|
180
|
+
event.listen("user.registered", kirimNotif)
|
|
181
|
+
event.dispatch("user.registered", 99)
|
|
182
|
+
|
|
183
|
+
# Queue Job
|
|
184
|
+
queue.push("SendEmailJob", ["pesan": "Halo Selamat Datang!"])
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## 🔍 Interactive Breakpoint Debugger
|
|
190
|
+
|
|
191
|
+
Jalankan debug program menggunakan perintah `python ngapakin.py debug <file.ngpk>`. Ketika VM menyala di mode tracing debugger, Anda dapat memasukkan perintah berikut di shell `dbg>`:
|
|
192
|
+
- `s` atau [Enter]: Melangkah 1 instruksi bytecode (Step Over/Into).
|
|
193
|
+
- `c`: Lanjutkan eksekusi normal tanpa jeda (Continue).
|
|
194
|
+
- `l` atau `locals`: Cetak semua variabel lokal di call frame aktif.
|
|
195
|
+
- `g` atau `globals`: Cetak semua variabel global yang terdaftar.
|
|
196
|
+
- `st` or `stack`: Cetak kondisi VM stack saat ini.
|
|
197
|
+
- `q` atau `quit`: Hentikan program seketika.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## 🎨 VSCode Extension & LSP Setup
|
|
202
|
+
|
|
203
|
+
1. Salin seluruh isi direktori `editors/vscode` ke dalam folder ekstensi VSCode lokal Anda:
|
|
204
|
+
- Windows: `%USERPROFILE%\.vscode\extensions\ngapaklang-vscode`
|
|
205
|
+
- Linux/macOS: `~/.vscode/extensions/ngapaklang-vscode`
|
|
206
|
+
2. Jalankan ulang VSCode. Berkas berekstensi `.ngpk` kini mendapatkan pewarnaan sintaksis.
|
|
207
|
+
3. Language Server otomatis memindai sintaksis dan menampilkan tanda garis bawah merah jika terjadi error penulisan (LSP Diagnostics).
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## 🧪 Pengujian Pipeline
|
|
212
|
+
|
|
213
|
+
Kami menjaga kualitas ekosistem dengan unit testing komprehensif. Jalankan perintah berikut untuk memvalidasi:
|
|
214
|
+
```bash
|
|
215
|
+
$env:PYTHONPATH="."; pytest
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## 🗺️ Roadmap Masa Depan
|
|
221
|
+
|
|
222
|
+
- **v1.1.0**: Dukungan HTTP Client terintegrasi untuk komunikasi API eksternal.
|
|
223
|
+
- **v1.2.0**: Relasi ORM Polimorfik (Many-to-Many dinamis).
|
|
224
|
+
- **v1.3.0**: Enkripsi berkas bytecode `.ngpkc` terkompresi tingkat lanjut.
|
|
225
|
+
- **v2.0.0**: Compiler NgapakIn JIT (Just-In-Time) untuk kecepatan setara kode mesin.
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## 📄 Lisensi
|
|
230
|
+
Dilindungi oleh Lisensi **MIT** - Lihat berkas [LICENSE](file:///d:/Ilham%20Hatta%20Manggala/Joki%20Project/NgapakLang/LICENSE) untuk detail.
|
ngapakin-1.0.0/README.md
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# NgapakIn & Larapak MVC 🚀
|
|
2
|
+
|
|
3
|
+
[](https://github.com/IlhamHattaManggala/ngapakin/actions/workflows/python.yml)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://www.python.org/)
|
|
6
|
+
|
|
7
|
+
NgapakIn adalah bahasa pemrograman open-source dengan ekstensi `.ngpk`, dirancang dengan sintaksis berbasis bahasa Ngapak / Banyumasan / Indonesia.
|
|
8
|
+
Larapak adalah MVC Web Framework lengkap yang berjalan di atas VM NgapakIn, dirancang meniru arsitektur elegan Laravel dengan fungsionalitas modern seperti ORM, Migrasi, Job Queues, Session/Cookies, Validasi, Caching, Event Dispatcher, Package Manager, hingga Language Server Protocol (LSP).
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 🌟 Fitur Utama Ekosistem (Phase 1 - Phase 5)
|
|
13
|
+
|
|
14
|
+
1. **Inti Bahasa NgapakIn (Phase 1 & 2)**:
|
|
15
|
+
- Sintaksis berbasis dialek Banyumasan (`gawe`, `rampung`, `nek - ya - liyane`, `balekna`).
|
|
16
|
+
- Tipe data lengkap: Angka, Teks, Boolean (`bener`/`salah`), dan Null (`kosong`).
|
|
17
|
+
- Stack-based Virtual Machine (VM) yang efisien dengan eksekusi bytecode cepat.
|
|
18
|
+
2. **Larapak MVC Framework (Phase 3)**:
|
|
19
|
+
- Web Server berbasis standard library HTTP.
|
|
20
|
+
- Routing dinamis (`routes/web.ngpk`, `routes/api.ngpk`).
|
|
21
|
+
- Blade-like Template Engine dengan layouting (`@layout`, `@sekat`, `@mlebui`).
|
|
22
|
+
3. **Database & ORM System (Phase 4)**:
|
|
23
|
+
- Kelas berorientasi objek (`kelas ... extends Model`).
|
|
24
|
+
- Fluent SQL Query Builder berbasis SQLite.
|
|
25
|
+
- Skema Migrasi (`schema.gawe`, `schema.buang`) dan CLI migration engine.
|
|
26
|
+
4. **Ecosystem & Advanced Features (Phase 5)**:
|
|
27
|
+
- **Autentikasi**: Fitur `auth` bawaan (`mlebu`, `metu`, `user`, `cek`).
|
|
28
|
+
- **Sesi & Cookies**: Penyimpanan sesi berbasis database SQLite, helper cookies.
|
|
29
|
+
- **Validasi**: Validator input dengan aturan `required`, `email`, `numeric`, `min`, `max`.
|
|
30
|
+
- **Cache**: Penyimpanan data sementara berbasis SQLite dengan waktu kedaluwarsa (TTL).
|
|
31
|
+
- **Event/Listener**: Dispatcher event bawaan untuk pemrograman reaktif.
|
|
32
|
+
- **Job Queues**: Pemrosesan latar belakang (background queue workers) dengan `queue:work`.
|
|
33
|
+
- **Package Manager**: Pemasangan paket otomatis beserta auto-discovery Service Provider.
|
|
34
|
+
- **REPL Terminal**: Interactive terminal interaktif via `repl`.
|
|
35
|
+
- **Step Debugger**: Breakpoint debugger interaktif (`s` step, `c` continue, `l` locals, `g` globals).
|
|
36
|
+
- **VSCode Support & LSP**: Syntax highlighting TextMate & diagnostik LSP syntax errors.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 📁 Struktur Folder Proyek
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
ngapakin/
|
|
44
|
+
├── .github/workflows/ # CI/CD Pipeline
|
|
45
|
+
├── app/
|
|
46
|
+
│ ├── Controllers/ # Controller Kelas Larapak
|
|
47
|
+
│ ├── Jobs/ # Background Jobs
|
|
48
|
+
│ ├── Middleware/ # Request Middlewares
|
|
49
|
+
│ └── Models/ # Model Database (Autoloaded)
|
|
50
|
+
├── database/
|
|
51
|
+
│ ├── migrations/ # Berkas Migrasi Database
|
|
52
|
+
│ └── seeders/ # Berkas Database Seeder
|
|
53
|
+
├── editors/vscode/ # Ekstensi VSCode & LSP Server
|
|
54
|
+
├── framework/ # Modul Internal Larapak Core
|
|
55
|
+
├── ngapak/ # Compiler, Lexer, Parser & VM NgapakLang
|
|
56
|
+
├── packages/ # Lokasi Paket yang Diinstal
|
|
57
|
+
├── routes/ # Rute web & API (.ngpk)
|
|
58
|
+
├── tests/ # Berkas Unit Testing
|
|
59
|
+
├── ngapakin.py # Entrypoint CLI
|
|
60
|
+
└── README.md
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 🛠️ Instalasi & Penggunaan
|
|
66
|
+
|
|
67
|
+
### Prasyarat
|
|
68
|
+
- Python 3.8 ke atas (tanpa ketergantungan pustaka pihak ketiga).
|
|
69
|
+
|
|
70
|
+
### Cara Kloning & Memulai Proyek
|
|
71
|
+
```bash
|
|
72
|
+
git clone https://github.com/IlhamHattaManggala/ngapakin.git
|
|
73
|
+
cd ngapakin
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 💻 Panduan CLI Command
|
|
79
|
+
|
|
80
|
+
Larapak menyediakan CLI helper komprehensif melalui `ngapakin.py`:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Menjalankan berkas kode biasa
|
|
84
|
+
python ngapakin.py run berkas.ngpk
|
|
85
|
+
|
|
86
|
+
# Menjalankan server web Larapak (port default: 8000)
|
|
87
|
+
python ngapakin.py serve 8000
|
|
88
|
+
|
|
89
|
+
# Melihat daftar rute terdaftar
|
|
90
|
+
python ngapakin.py route:list
|
|
91
|
+
|
|
92
|
+
# Membuat komponen baru (Scaffolding)
|
|
93
|
+
python ngapakin.py make:controller UserController
|
|
94
|
+
python ngapakin.py make:model Member
|
|
95
|
+
python ngapakin.py make:middleware AuthMiddleware
|
|
96
|
+
python ngapakin.py make:migration create_users_table
|
|
97
|
+
python ngapakin.py make:job SendEmailJob
|
|
98
|
+
|
|
99
|
+
# Migrasi Database
|
|
100
|
+
python ngapakin.py migrate # Jalankan migrasi
|
|
101
|
+
python ngapakin.py rollback # Kembalikan migrasi terakhir
|
|
102
|
+
python ngapakin.py db:seed # Jalankan seeder database
|
|
103
|
+
|
|
104
|
+
# Layanan Ekosistem
|
|
105
|
+
python ngapakin.py cache:clear # Hapus data cache
|
|
106
|
+
python ngapakin.py queue:work # Jalankan pemroses job queue
|
|
107
|
+
python ngapakin.py package:install auth-helper # Pasang paket baru
|
|
108
|
+
python ngapakin.py repl # Masuk ke REPL interaktif
|
|
109
|
+
python ngapakin.py debug berkas.ngpk # Debug bytecode berkas
|
|
110
|
+
python ngapakin.py test # Jalankan seluruh unit test suite
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## 📖 Cara Menggunakan Fitur Ekosistem
|
|
116
|
+
|
|
117
|
+
### 1. Validasi & Autentikasi
|
|
118
|
+
```ngapak
|
|
119
|
+
# Validasi data request
|
|
120
|
+
data = ["email": "ilham@example.com", "umur": 20]
|
|
121
|
+
aturan = ["email": "required|email", "umur": "required|numeric|min:18"]
|
|
122
|
+
|
|
123
|
+
val = validator.gawe(data, aturan)
|
|
124
|
+
nek val.gagal() ya
|
|
125
|
+
tulis "Validasi Gagal!"
|
|
126
|
+
tulis val.errors()
|
|
127
|
+
liyane
|
|
128
|
+
tulis "Validasi Sukses!"
|
|
129
|
+
rampung
|
|
130
|
+
|
|
131
|
+
# Login user
|
|
132
|
+
nek auth.mlebu("ilham@example.com", "password123") ya
|
|
133
|
+
tulis "Berhasil Login!"
|
|
134
|
+
tulis auth.user().name
|
|
135
|
+
liyane
|
|
136
|
+
tulis "Login Gagal!"
|
|
137
|
+
rampung
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 2. Caching & Sesi
|
|
141
|
+
```ngapak
|
|
142
|
+
# Sesi
|
|
143
|
+
sesi.pasang("cart_total", 150000)
|
|
144
|
+
total = sesi.entuk("cart_total")
|
|
145
|
+
|
|
146
|
+
# Cache (Simpan data 60 detik)
|
|
147
|
+
cache.pasang("weather_jakarta", "Hujan", 60)
|
|
148
|
+
cuaca = cache.entuk("weather_jakarta")
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### 3. Event & Queue
|
|
152
|
+
```ngapak
|
|
153
|
+
# Event
|
|
154
|
+
gawe kirimNotif(data)
|
|
155
|
+
tulis "Mengirim notifikasi ke user ID: " + data
|
|
156
|
+
rampung
|
|
157
|
+
event.listen("user.registered", kirimNotif)
|
|
158
|
+
event.dispatch("user.registered", 99)
|
|
159
|
+
|
|
160
|
+
# Queue Job
|
|
161
|
+
queue.push("SendEmailJob", ["pesan": "Halo Selamat Datang!"])
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## 🔍 Interactive Breakpoint Debugger
|
|
167
|
+
|
|
168
|
+
Jalankan debug program menggunakan perintah `python ngapakin.py debug <file.ngpk>`. Ketika VM menyala di mode tracing debugger, Anda dapat memasukkan perintah berikut di shell `dbg>`:
|
|
169
|
+
- `s` atau [Enter]: Melangkah 1 instruksi bytecode (Step Over/Into).
|
|
170
|
+
- `c`: Lanjutkan eksekusi normal tanpa jeda (Continue).
|
|
171
|
+
- `l` atau `locals`: Cetak semua variabel lokal di call frame aktif.
|
|
172
|
+
- `g` atau `globals`: Cetak semua variabel global yang terdaftar.
|
|
173
|
+
- `st` or `stack`: Cetak kondisi VM stack saat ini.
|
|
174
|
+
- `q` atau `quit`: Hentikan program seketika.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## 🎨 VSCode Extension & LSP Setup
|
|
179
|
+
|
|
180
|
+
1. Salin seluruh isi direktori `editors/vscode` ke dalam folder ekstensi VSCode lokal Anda:
|
|
181
|
+
- Windows: `%USERPROFILE%\.vscode\extensions\ngapaklang-vscode`
|
|
182
|
+
- Linux/macOS: `~/.vscode/extensions/ngapaklang-vscode`
|
|
183
|
+
2. Jalankan ulang VSCode. Berkas berekstensi `.ngpk` kini mendapatkan pewarnaan sintaksis.
|
|
184
|
+
3. Language Server otomatis memindai sintaksis dan menampilkan tanda garis bawah merah jika terjadi error penulisan (LSP Diagnostics).
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## 🧪 Pengujian Pipeline
|
|
189
|
+
|
|
190
|
+
Kami menjaga kualitas ekosistem dengan unit testing komprehensif. Jalankan perintah berikut untuk memvalidasi:
|
|
191
|
+
```bash
|
|
192
|
+
$env:PYTHONPATH="."; pytest
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## 🗺️ Roadmap Masa Depan
|
|
198
|
+
|
|
199
|
+
- **v1.1.0**: Dukungan HTTP Client terintegrasi untuk komunikasi API eksternal.
|
|
200
|
+
- **v1.2.0**: Relasi ORM Polimorfik (Many-to-Many dinamis).
|
|
201
|
+
- **v1.3.0**: Enkripsi berkas bytecode `.ngpkc` terkompresi tingkat lanjut.
|
|
202
|
+
- **v2.0.0**: Compiler NgapakIn JIT (Just-In-Time) untuk kecepatan setara kode mesin.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## 📄 Lisensi
|
|
207
|
+
Dilindungi oleh Lisensi **MIT** - Lihat berkas [LICENSE](file:///d:/Ilham%20Hatta%20Manggala/Joki%20Project/NgapakLang/LICENSE) untuk detail.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Authentication System for Larapak
|
|
2
|
+
|
|
3
|
+
from framework.database import db_manager
|
|
4
|
+
|
|
5
|
+
class Auth:
|
|
6
|
+
def __init__(self, vm=None):
|
|
7
|
+
self.vm = vm
|
|
8
|
+
|
|
9
|
+
@property
|
|
10
|
+
def sesi(self):
|
|
11
|
+
if self.vm and "sesi" in self.vm.globals:
|
|
12
|
+
return self.vm.globals["sesi"]
|
|
13
|
+
return None
|
|
14
|
+
|
|
15
|
+
def user(self):
|
|
16
|
+
ses = self.sesi
|
|
17
|
+
if not ses:
|
|
18
|
+
return None
|
|
19
|
+
user_id = ses.get("auth_user_id")
|
|
20
|
+
if not user_id:
|
|
21
|
+
return None
|
|
22
|
+
|
|
23
|
+
if self.vm and "User" in self.vm.globals:
|
|
24
|
+
User = self.vm.globals["User"]
|
|
25
|
+
# Call User.golek(user_id)
|
|
26
|
+
# golek is a classmethod on Model, which wraps it.
|
|
27
|
+
# In Python, we can call it using __func__ since Model.golek is a classmethod
|
|
28
|
+
from framework.model import Model
|
|
29
|
+
return Model.golek.__func__(User, user_id)
|
|
30
|
+
return None
|
|
31
|
+
|
|
32
|
+
def cek(self):
|
|
33
|
+
return self.user() is not None
|
|
34
|
+
|
|
35
|
+
def check(self):
|
|
36
|
+
return self.cek()
|
|
37
|
+
|
|
38
|
+
def mlebu(self, email, password):
|
|
39
|
+
"""Login user with email and password."""
|
|
40
|
+
if self.vm and "User" in self.vm.globals:
|
|
41
|
+
User = self.vm.globals["User"]
|
|
42
|
+
from framework.model import Model
|
|
43
|
+
# Query user using ModelQueryBuilder
|
|
44
|
+
# We will make sure Model.nek works and returns a user.
|
|
45
|
+
# Or we can query directly via SQL for safety inside auth:
|
|
46
|
+
table = Model.get_table_name(User)
|
|
47
|
+
row = db_manager.execute(f"SELECT * FROM {table} WHERE email = ?", [email]).fetchone()
|
|
48
|
+
if row:
|
|
49
|
+
user_dict = dict(row)
|
|
50
|
+
if user_dict.get("password") == password:
|
|
51
|
+
ses = self.sesi
|
|
52
|
+
if ses:
|
|
53
|
+
ses.set("auth_user_id", user_dict.get("id"))
|
|
54
|
+
|
|
55
|
+
# Instantiate user object
|
|
56
|
+
from ngapak.vm import NgapakInstance
|
|
57
|
+
instance = User() if hasattr(User, 'attributes') else User.__new__(User)
|
|
58
|
+
if isinstance(instance, NgapakInstance):
|
|
59
|
+
instance.fields.update(user_dict)
|
|
60
|
+
else:
|
|
61
|
+
instance.__dict__.update(user_dict)
|
|
62
|
+
return True
|
|
63
|
+
return False
|
|
64
|
+
|
|
65
|
+
def login(self, email, password):
|
|
66
|
+
return self.mlebu(email, password)
|
|
67
|
+
|
|
68
|
+
def metu(self):
|
|
69
|
+
"""Logout current user."""
|
|
70
|
+
ses = self.sesi
|
|
71
|
+
if ses:
|
|
72
|
+
ses.forget("auth_user_id")
|
|
73
|
+
|
|
74
|
+
def logout(self):
|
|
75
|
+
self.metu()
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Cache Manager for Larapak
|
|
2
|
+
|
|
3
|
+
import time
|
|
4
|
+
import json
|
|
5
|
+
from framework.database import db_manager
|
|
6
|
+
|
|
7
|
+
class Cache:
|
|
8
|
+
def __init__(self):
|
|
9
|
+
self._ensure_table()
|
|
10
|
+
|
|
11
|
+
def _ensure_table(self):
|
|
12
|
+
db_manager.execute_write(
|
|
13
|
+
"CREATE TABLE IF NOT EXISTS cache (key VARCHAR(255) PRIMARY KEY, value TEXT, expiration INTEGER)"
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
def pasang(self, key, value, seconds=None):
|
|
17
|
+
expiration = None
|
|
18
|
+
if seconds is not None:
|
|
19
|
+
expiration = int(time.time() + seconds)
|
|
20
|
+
|
|
21
|
+
serialized = json.dumps(value)
|
|
22
|
+
db_manager.execute_write(
|
|
23
|
+
"INSERT OR REPLACE INTO cache (key, value, expiration) VALUES (?, ?, ?)",
|
|
24
|
+
[key, serialized, expiration]
|
|
25
|
+
)
|
|
26
|
+
return True
|
|
27
|
+
|
|
28
|
+
def set(self, key, value, seconds=None):
|
|
29
|
+
return self.pasang(key, value, seconds)
|
|
30
|
+
|
|
31
|
+
def entuk(self, key, default=None):
|
|
32
|
+
row = db_manager.execute("SELECT value, expiration FROM cache WHERE key = ?", [key]).fetchone()
|
|
33
|
+
if not row:
|
|
34
|
+
return default
|
|
35
|
+
|
|
36
|
+
expiration = row["expiration"]
|
|
37
|
+
if expiration is not None and expiration <= time.time():
|
|
38
|
+
# Expired, remove it
|
|
39
|
+
self.lalekna(key)
|
|
40
|
+
return default
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
return json.loads(row["value"])
|
|
44
|
+
except Exception:
|
|
45
|
+
return default
|
|
46
|
+
|
|
47
|
+
def get(self, key, default=None):
|
|
48
|
+
return self.entuk(key, default)
|
|
49
|
+
|
|
50
|
+
def lalekna(self, key):
|
|
51
|
+
db_manager.execute_write("DELETE FROM cache WHERE key = ?", [key])
|
|
52
|
+
return True
|
|
53
|
+
|
|
54
|
+
def forget(self, key):
|
|
55
|
+
return self.lalekna(key)
|
|
56
|
+
|
|
57
|
+
def remove(self, key):
|
|
58
|
+
return self.lalekna(key)
|
|
59
|
+
|
|
60
|
+
def resiki(self):
|
|
61
|
+
db_manager.execute_write("DELETE FROM cache")
|
|
62
|
+
return True
|
|
63
|
+
|
|
64
|
+
def clear(self):
|
|
65
|
+
return self.resiki()
|
|
66
|
+
|
|
67
|
+
def nduwe(self, key):
|
|
68
|
+
val = self.entuk(key, None)
|
|
69
|
+
return val is not None
|
|
70
|
+
|
|
71
|
+
def has(self, key):
|
|
72
|
+
return self.nduwe(key)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Service Container for Larapak Web Framework
|
|
2
|
+
|
|
3
|
+
class Container:
|
|
4
|
+
def __init__(self):
|
|
5
|
+
self.bindings = {}
|
|
6
|
+
self.instances = {}
|
|
7
|
+
self.vm = None # Injected by VM
|
|
8
|
+
|
|
9
|
+
def bind(self, name, factory):
|
|
10
|
+
"""Bind a dependency resolver function to a name."""
|
|
11
|
+
self.bindings[name] = factory
|
|
12
|
+
|
|
13
|
+
def singleton(self, name, factory):
|
|
14
|
+
"""Bind a singleton dependency resolver."""
|
|
15
|
+
def singleton_factory():
|
|
16
|
+
if name not in self.instances:
|
|
17
|
+
if self.vm and callable(factory):
|
|
18
|
+
# If it's a VM function, invoke it
|
|
19
|
+
self.instances[name] = self.vm.execute_callable(factory, [])
|
|
20
|
+
else:
|
|
21
|
+
self.instances[name] = factory()
|
|
22
|
+
return self.instances[name]
|
|
23
|
+
self.bindings[name] = singleton_factory
|
|
24
|
+
|
|
25
|
+
def make(self, name):
|
|
26
|
+
"""Resolve dependency by name."""
|
|
27
|
+
if name in self.instances:
|
|
28
|
+
return self.instances[name]
|
|
29
|
+
|
|
30
|
+
if name in self.bindings:
|
|
31
|
+
factory = self.bindings[name]
|
|
32
|
+
# Check if it is a VM function
|
|
33
|
+
if self.vm and hasattr(factory, 'chunk'):
|
|
34
|
+
res = self.vm.execute_callable(factory, [])
|
|
35
|
+
return res
|
|
36
|
+
elif callable(factory):
|
|
37
|
+
res = factory()
|
|
38
|
+
return res
|
|
39
|
+
else:
|
|
40
|
+
return factory
|
|
41
|
+
|
|
42
|
+
raise KeyError(f"Dependency '{name}' tidak ditemukan di Service Container.")
|