@africode/core 5.0.0
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/AFRICODE_FRAMEWORK_GUIDE.md +707 -0
- package/LICENSE +623 -0
- package/README.md +442 -0
- package/bin/africode.js +73 -0
- package/bin/africode.js.1758507140 +343 -0
- package/bin/cli.ts +83 -0
- package/bin/create-africode.js +158 -0
- package/bin/scaffold.ts +219 -0
- package/components/accordion.js +183 -0
- package/components/alert.js +131 -0
- package/components/auth.js +172 -0
- package/components/avatar.js +117 -0
- package/components/badge.js +104 -0
- package/components/base.d.ts +139 -0
- package/components/base.js +184 -0
- package/components/button.js +164 -0
- package/components/card.js +137 -0
- package/components/cultural-card.js +243 -0
- package/components/divider.js +83 -0
- package/components/dropdown.js +171 -0
- package/components/error-boundary.js +155 -0
- package/components/form.js +131 -0
- package/components/grid.js +273 -0
- package/components/hero.js +138 -0
- package/components/icon.js +36 -0
- package/components/index.js +57 -0
- package/components/input.js +256 -0
- package/components/kanga-card.js +185 -0
- package/components/language-switcher.js +108 -0
- package/components/loader.js +80 -0
- package/components/modal.js +262 -0
- package/components/motion.js +84 -0
- package/components/navbar.js +236 -0
- package/components/pattern-showcase.js +225 -0
- package/components/progress.js +134 -0
- package/components/react.js +111 -0
- package/components/section.js +54 -0
- package/components/select.js +322 -0
- package/components/sidebar.js +180 -0
- package/components/skeleton.js +85 -0
- package/components/table.js +181 -0
- package/components/tabs.js +202 -0
- package/components/theme-toggle.js +82 -0
- package/components/toast.js +139 -0
- package/components/tooltip.js +167 -0
- package/core/a2ui-schema-manager.js +344 -0
- package/core/a2ui.js +431 -0
- package/core/bun-runtime.js +799 -0
- package/core/cli/commands/add.js +23 -0
- package/core/cli/commands/audit.js +58 -0
- package/core/cli/commands/build.js +137 -0
- package/core/cli/commands/create-plugin.js +241 -0
- package/core/cli/commands/dev.js +228 -0
- package/core/cli/commands/lint.js +23 -0
- package/core/cli/commands/test.js +34 -0
- package/core/cli/migrator.js +71 -0
- package/core/cli/ui.js +46 -0
- package/core/compliance.js +628 -0
- package/core/config.js +263 -0
- package/core/db-advanced.js +481 -0
- package/core/db.js +284 -0
- package/core/enhanced-hmr.js +404 -0
- package/core/errors.js +222 -0
- package/core/file-router.js +290 -0
- package/core/heartbeat.js +64 -0
- package/core/hmr-client.js +204 -0
- package/core/hmr.js +196 -0
- package/core/html.d.ts +116 -0
- package/core/html.js +160 -0
- package/core/hydration.js +52 -0
- package/core/lipa-namba-journey.js +572 -0
- package/core/motion.js +106 -0
- package/core/nida-cig-middleware.js +455 -0
- package/core/patterns.d.ts +124 -0
- package/core/patterns.js +833 -0
- package/core/plugins/index.js +312 -0
- package/core/router.js +387 -0
- package/core/sdk-client.js +62 -0
- package/core/sdk.d.ts +133 -0
- package/core/sdk.js +123 -0
- package/core/seo.js +76 -0
- package/core/server/auth-endpoints.js +339 -0
- package/core/server/auth.js +180 -0
- package/core/server/csrf.js +206 -0
- package/core/server/db.js +39 -0
- package/core/server/middleware.js +324 -0
- package/core/server/rate-limit.js +238 -0
- package/core/server/render.js +69 -0
- package/core/server/router.js +120 -0
- package/core/shim.js +28 -0
- package/core/state.d.ts +86 -0
- package/core/state.js +242 -0
- package/core/store.d.ts +122 -0
- package/core/store.js +61 -0
- package/core/validation.d.ts +233 -0
- package/core/validation.js +590 -0
- package/core/websocket.js +639 -0
- package/dist/africode.js +2905 -0
- package/dist/africode.js.map +61 -0
- package/dist/build-info.json +23 -0
- package/dist/components.js +2888 -0
- package/dist/components.js.map +58 -0
- package/dist/styles/africanity.css +322 -0
- package/dist/styles/typography.css +141 -0
- package/docs/IDE-Guide.md +50 -0
- package/package.json +110 -0
- package/src/index.ts +196 -0
- package/styles/africanity.css +322 -0
- package/styles/typography.css +141 -0
- package/templates/starter/.env.example +15 -0
- package/templates/starter/africode.config.js +40 -0
- package/templates/starter/package.json +14 -0
- package/templates/starter/src/pages/index.html +46 -0
- package/templates/starter/src/pages/index.js +32 -0
- package/templates/starter/src/styles/main.css +4 -0
- package/templates/starter-3d/.env.example +7 -0
- package/templates/starter-3d/africode.config.js +29 -0
- package/templates/starter-3d/components/af-model-viewer.js +125 -0
- package/templates/starter-3d/package.json +15 -0
- package/templates/starter-3d/src/pages/index.html +46 -0
- package/templates/starter-3d/src/pages/index.js +50 -0
- package/templates/starter-3d/src/styles/main.css +4 -0
- package/templates/starter-react/.env.example +15 -0
- package/templates/starter-react/africode.config.js +40 -0
- package/templates/starter-react/package.json +16 -0
- package/templates/starter-react/src/pages/index.html +46 -0
- package/templates/starter-react/src/pages/index.js +68 -0
- package/templates/starter-react/src/styles/main.css +4 -0
- package/templates/starter-tailwind/.env.example +15 -0
- package/templates/starter-tailwind/africode.config.js +40 -0
- package/templates/starter-tailwind/package.json +20 -0
- package/templates/starter-tailwind/src/pages/index.html +46 -0
- package/templates/starter-tailwind/src/pages/index.js +37 -0
- package/templates/starter-tailwind/src/styles/main.css +4 -0
- package/templates/starter-tailwind/src/styles/tailwind.css +1 -0
- package/templates/starter-tailwind/src/tailwind-loader.js +30 -0
|
@@ -0,0 +1,707 @@
|
|
|
1
|
+
# AfriCode Framework - Comprehensive Developer Guide
|
|
2
|
+
|
|
3
|
+
**Version:** 4.0.1
|
|
4
|
+
**For IDE Agents:** VS Code Copilot, Anthropic Claude, GitHub Copilot, Antigravity, and similar AI-assisted development environments.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 🌍 Framework Philosophy
|
|
9
|
+
|
|
10
|
+
**AfriCode is not just code—it's a commitment to African digital sovereignty.**
|
|
11
|
+
|
|
12
|
+
AfriCode v4.0.1 is a production-ready, full-stack framework built on Bun that prioritizes:
|
|
13
|
+
|
|
14
|
+
- **Performance**: 10x faster than Node.js with native SQLite, WebAssembly, and zero-config TypeScript
|
|
15
|
+
- **Cultural Authenticity**: Procedurally generated African tribal patterns (Kente, Ndebele, Masai, Zulu, Hadzabe, Kuba, Shuka)
|
|
16
|
+
- **Developer Sovereignty**: Frameworks should celebrate heritage, not erase it
|
|
17
|
+
- **Modern Architecture**: WebSocket real-time, advanced ORM, middleware pipeline, 33 production-ready Web Components
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 📦 Core Stack
|
|
22
|
+
|
|
23
|
+
### Runtime: Bun v1.3.12+
|
|
24
|
+
|
|
25
|
+
- **Why Bun?** Ultra-fast JavaScript runtime with native SQLite support, bundled TypeScript compiler, WebAssembly capabilities
|
|
26
|
+
- **Development:** `bun --serve` for HMR (Hot Module Reloading)
|
|
27
|
+
- **Testing:** `bun test` with 484 passing tests (100% coverage)
|
|
28
|
+
- **Package Management:** Drop-in Node.js compatibility with faster resolution
|
|
29
|
+
|
|
30
|
+
### Database: SQLite (WAL Mode)
|
|
31
|
+
|
|
32
|
+
- **Why SQLite?** Fast, portable, embeddable, perfect for sovereignty
|
|
33
|
+
- **ORM:** Advanced QueryBuilder with relationships, transactions, migrations
|
|
34
|
+
- **Features:** Foreign keys, virtual tables, JSON1 extension, full-text search
|
|
35
|
+
- **Migrations:** Automatic schema versioning with timestamp-based files
|
|
36
|
+
- **Location:** Project root as `afriCode.db` with WAL files for concurrent access
|
|
37
|
+
|
|
38
|
+
### Architecture: Full-Stack Module System
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
core/ → Framework internals (SDK, middleware, ORM)
|
|
42
|
+
components/ → 33 Web Components (no framework dependencies)
|
|
43
|
+
styles/ → African color palette + typography
|
|
44
|
+
pages/ → Server-side rendered pages (SSR with Bun)
|
|
45
|
+
templates/ → HTML templates with data binding
|
|
46
|
+
bin/ → CLI tools for scaffolding
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 🎨 Cultural Integration
|
|
52
|
+
|
|
53
|
+
### Procedural African Pattern System
|
|
54
|
+
|
|
55
|
+
**Core Philosophy:** Patterns are algorithmic, not static images. Generated on-demand.
|
|
56
|
+
|
|
57
|
+
#### 6 Tribal Patterns (Procedurally Generated)
|
|
58
|
+
|
|
59
|
+
1. **Kente** (Ghana/Akan)
|
|
60
|
+
- 8 horizontal bands + geometric dividers
|
|
61
|
+
- Colors: Red, green, gold, white, black
|
|
62
|
+
- Symbolizes: Cloth of kings, wisdom, celebration
|
|
63
|
+
|
|
64
|
+
2. **Ndebele** (South Africa)
|
|
65
|
+
- Nested rectangles with jagged extensions
|
|
66
|
+
- Bold primary colors: Red, white, green, blue
|
|
67
|
+
- Symbolizes: Unity through geometric harmony
|
|
68
|
+
|
|
69
|
+
3. **Masai** (Kenya/Tanzania)
|
|
70
|
+
- Dense beadwork grid with chevron bands
|
|
71
|
+
- Red, white, gold, navy, earth tones
|
|
72
|
+
- Symbolizes: Warrior tradition, pastoral life
|
|
73
|
+
|
|
74
|
+
4. **Zulu** (South Africa)
|
|
75
|
+
- Isivivane triangle panels with love letter geometry
|
|
76
|
+
- White on black with accent colors
|
|
77
|
+
- Symbolizes: Protection, storytelling, heritage
|
|
78
|
+
|
|
79
|
+
5. **Hadzabe** (Tanzania)
|
|
80
|
+
- Cave rock art with constellations, hunters, animals
|
|
81
|
+
- Earth tones, ochre, cream, smoke
|
|
82
|
+
- Symbolizes: Ancient connection to land and cosmos
|
|
83
|
+
|
|
84
|
+
6. **Kuba** (Democratic Republic of Congo)
|
|
85
|
+
- Checkerboard with mandala center
|
|
86
|
+
- Alternating dark/light with radial symmetry
|
|
87
|
+
- Symbolizes: Royal precision, mathematical harmony
|
|
88
|
+
|
|
89
|
+
### Implementation
|
|
90
|
+
|
|
91
|
+
```javascript
|
|
92
|
+
// Patterns are class static methods in PatternRenderer
|
|
93
|
+
PatternRenderer.generateKente((width = 240), (height = 240)); // Returns SVG string
|
|
94
|
+
PatternRenderer.generateNdebele((width = 240), (height = 240)); // Pure SVG (no canvas)
|
|
95
|
+
PatternRenderer.generateMasai((width = 240), (height = 240));
|
|
96
|
+
PatternRenderer.generateZulu((width = 240), (height = 240));
|
|
97
|
+
PatternRenderer.generateHadzabe((width = 240), (height = 240));
|
|
98
|
+
PatternRenderer.generateKuba((width = 240), (height = 240));
|
|
99
|
+
|
|
100
|
+
// Render to DOM
|
|
101
|
+
PatternRenderer.renderToElement('element-id', 'Kente', 300, 300);
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Color Palette (CSS Variables)
|
|
105
|
+
|
|
106
|
+
```css
|
|
107
|
+
--afri-gold: #ffd700 /* Wealth, prestige */ --afri-red: #c55a11 /* Energy, passion */
|
|
108
|
+
--afri-blue: #003d82 /* Stability, trust */ --afri-green: #164b35 /* Growth, life */
|
|
109
|
+
--afri-obsidian: #1a1a1a /* Strength, foundation */;
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 🧩 33 Web Components
|
|
115
|
+
|
|
116
|
+
**Philosophy:** Framework-agnostic, vanilla Web Components. Work with any JavaScript project.
|
|
117
|
+
|
|
118
|
+
### Navigation Components
|
|
119
|
+
|
|
120
|
+
- `<af-navbar>` — Sticky navigation with logo, menu, language switcher
|
|
121
|
+
- `<af-sidebar>` — Collapsible sidebar with icon support
|
|
122
|
+
- `<af-breadcrumb>` — Hierarchical navigation path
|
|
123
|
+
- `<af-pagination>` — Multi-page navigation with prev/next
|
|
124
|
+
|
|
125
|
+
### Form Components
|
|
126
|
+
|
|
127
|
+
- `<af-input>` — Text, email, password, number, date inputs
|
|
128
|
+
- `<af-select>` — Dropdown with search capability
|
|
129
|
+
- `<af-checkbox>` — Single/multi-select checkboxes
|
|
130
|
+
- `<af-radio>` — Radio button groups
|
|
131
|
+
- `<af-textarea>` — Multi-line text with resize
|
|
132
|
+
- `<af-form>` — Form wrapper with validation
|
|
133
|
+
|
|
134
|
+
### Data Display
|
|
135
|
+
|
|
136
|
+
- `<af-table>` — Sortable, paginated data tables
|
|
137
|
+
- `<af-card>` — Content containers with elevation
|
|
138
|
+
- `<af-badge>` — Status labels and tags
|
|
139
|
+
- `<af-progress>` — Progress bars and loaders
|
|
140
|
+
- `<af-skeleton>` — Loading placeholders
|
|
141
|
+
- `<af-grid>` — Responsive grid layout
|
|
142
|
+
|
|
143
|
+
### Feedback Components
|
|
144
|
+
|
|
145
|
+
- `<af-alert>` — Alert boxes (success, error, warning, info)
|
|
146
|
+
- `<af-toast>` — Toast notifications (auto-dismiss)
|
|
147
|
+
- `<af-modal>` — Modal dialogs with actions
|
|
148
|
+
- `<af-tooltip>` — Hover tooltips
|
|
149
|
+
- `<af-dropdown>` — Dropdown menus
|
|
150
|
+
|
|
151
|
+
### Visual Components
|
|
152
|
+
|
|
153
|
+
- `<af-avatar>` — User avatars with fallback
|
|
154
|
+
- `<af-icon>` — Icon system with emoji fallback
|
|
155
|
+
- `<af-button>` — Button variants (primary, secondary, ghost)
|
|
156
|
+
- `<af-hero>` — Hero section with background patterns
|
|
157
|
+
- `<af-section>` — Content sections with padding/background
|
|
158
|
+
- `<af-divider>` — Visual separators
|
|
159
|
+
- `<af-accordion>` — Collapsible content sections
|
|
160
|
+
- `<af-tabs>` — Tabbed content switcher
|
|
161
|
+
- `<af-theme-toggle>` — Dark/light mode toggle
|
|
162
|
+
- `<af-language-switcher>` — Multi-language support (4 languages)
|
|
163
|
+
- `<af-loader>` — Loading spinners
|
|
164
|
+
- `<af-pattern-showcase>` — Pattern display gallery
|
|
165
|
+
|
|
166
|
+
### Usage
|
|
167
|
+
|
|
168
|
+
```html
|
|
169
|
+
<!-- Web Components work in any HTML -->
|
|
170
|
+
<af-button variant="primary" @click="handleClick">Click Me</af-button>
|
|
171
|
+
<af-alert type="success">Operation completed!</af-alert>
|
|
172
|
+
<af-modal id="confirmModal">Confirm action?</af-modal>
|
|
173
|
+
<af-pattern-showcase pattern="Kente" width="300" height="300"></af-pattern-showcase>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## 🔌 Advanced Features
|
|
179
|
+
|
|
180
|
+
### WebSocket Real-Time Communication
|
|
181
|
+
|
|
182
|
+
```javascript
|
|
183
|
+
// Server
|
|
184
|
+
app.ws('/messages', (ws) => {
|
|
185
|
+
ws.subscribe('room:general');
|
|
186
|
+
ws.send({ event: 'user:joined', userId: 123 });
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// Client
|
|
190
|
+
const ws = new WebSocket('ws://localhost:3000/messages');
|
|
191
|
+
ws.addEventListener('message', (event) => {
|
|
192
|
+
console.log('Real-time update:', event.data);
|
|
193
|
+
});
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### ORM & Database
|
|
197
|
+
|
|
198
|
+
```javascript
|
|
199
|
+
// Define models with relationships
|
|
200
|
+
const User = db.model('users', {
|
|
201
|
+
id: 'INTEGER PRIMARY KEY',
|
|
202
|
+
name: 'TEXT NOT NULL',
|
|
203
|
+
email: 'TEXT UNIQUE',
|
|
204
|
+
posts: { relation: 'hasMany', target: 'posts' },
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// Query builder
|
|
208
|
+
const users = await User.where('email', 'like', '%@african-tech.com')
|
|
209
|
+
.with('posts')
|
|
210
|
+
.orderBy('createdAt', 'DESC')
|
|
211
|
+
.paginate(10, 1);
|
|
212
|
+
|
|
213
|
+
// Transactions
|
|
214
|
+
await db.transaction(async () => {
|
|
215
|
+
await User.create({ name: 'Amara' });
|
|
216
|
+
await Activity.create({ type: 'user_signup' });
|
|
217
|
+
});
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Middleware Pipeline
|
|
221
|
+
|
|
222
|
+
```javascript
|
|
223
|
+
app.use(middleware.cors({ origin: 'https://african-tech.com' }));
|
|
224
|
+
app.use(middleware.logging());
|
|
225
|
+
app.use(middleware.rateLimit({ max: 100, window: 60000 }));
|
|
226
|
+
app.use(middleware.auth({ secret: process.env.JWT_SECRET }));
|
|
227
|
+
app.use(middleware.csrf());
|
|
228
|
+
|
|
229
|
+
app.post('/api/users', (req, res) => {
|
|
230
|
+
// All middleware applied automatically
|
|
231
|
+
});
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Security by Default
|
|
235
|
+
|
|
236
|
+
- **Argon2id Hashing**: Password hashing with memory-hard algorithm
|
|
237
|
+
- **CSRF Protection**: Token validation on state-changing requests
|
|
238
|
+
- **Rate Limiting**: Per-IP or per-user request throttling
|
|
239
|
+
- **Secure Headers**: HSTS, X-Frame-Options, X-Content-Type-Options
|
|
240
|
+
- **SQL Injection Prevention**: Parameterized queries with QueryBuilder
|
|
241
|
+
- **Session Management**: Secure, HTTP-only cookies with rotation
|
|
242
|
+
|
|
243
|
+
### Authentication
|
|
244
|
+
|
|
245
|
+
```javascript
|
|
246
|
+
// Simple auth middleware
|
|
247
|
+
const user = await authenticate(req, {
|
|
248
|
+
secret: process.env.AUTH_SECRET,
|
|
249
|
+
algorithm: 'HS256',
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
// Password hashing
|
|
253
|
+
const hash = await hashPassword('user_password');
|
|
254
|
+
const isValid = await verifyPassword('user_password', hash);
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## 📁 Project Structure
|
|
260
|
+
|
|
261
|
+
### Recommended Layout for New Projects
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
my-african-app/
|
|
265
|
+
├── core/ → Business logic, API routes
|
|
266
|
+
│ ├── api/
|
|
267
|
+
│ │ ├── users.js
|
|
268
|
+
│ │ ├── posts.js
|
|
269
|
+
│ │ └── auth.js
|
|
270
|
+
│ └── services/
|
|
271
|
+
│ └── email.js
|
|
272
|
+
├── pages/ → Server-rendered views
|
|
273
|
+
│ ├── home.html
|
|
274
|
+
│ ├── about.html
|
|
275
|
+
│ └── dashboard.html
|
|
276
|
+
├── components/ → Web Components (if custom)
|
|
277
|
+
│ └── custom-widget.js
|
|
278
|
+
├── styles/ → CSS
|
|
279
|
+
│ ├── main.css
|
|
280
|
+
│ └── variables.css
|
|
281
|
+
├── migrations/ → Database schemas
|
|
282
|
+
│ ├── 001_create_users.sql
|
|
283
|
+
│ └── 002_create_posts.sql
|
|
284
|
+
├── public/ → Static assets
|
|
285
|
+
├── server.js → Entry point
|
|
286
|
+
├── package.json
|
|
287
|
+
└── .env.example
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## 🚀 Getting Started
|
|
293
|
+
|
|
294
|
+
### Installation
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
npm install africode
|
|
298
|
+
# or
|
|
299
|
+
bun add africode
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Create New Project
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
npx create-africode my-app
|
|
306
|
+
cd my-app
|
|
307
|
+
bun dev
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Basic Server
|
|
311
|
+
|
|
312
|
+
```javascript
|
|
313
|
+
import { AfriCode } from 'africode/core/sdk.js';
|
|
314
|
+
|
|
315
|
+
const app = new AfriCode({
|
|
316
|
+
port: 3000,
|
|
317
|
+
database: 'afriCode.db',
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
// Define routes
|
|
321
|
+
app.get('/', (req, res) => {
|
|
322
|
+
res.html(`
|
|
323
|
+
<h1>Welcome to AfriCode</h1>
|
|
324
|
+
<af-pattern-showcase pattern="Kente"></af-pattern-showcase>
|
|
325
|
+
`);
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// Start server
|
|
329
|
+
app.listen(() => console.log('🌍 AfriCode running on localhost:3000'));
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## 🧪 Testing
|
|
335
|
+
|
|
336
|
+
**484 Tests Passing** (100% success rate)
|
|
337
|
+
|
|
338
|
+
### Run Tests
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
bun test
|
|
342
|
+
bun test --watch # Watch mode
|
|
343
|
+
bun test --coverage # Coverage report
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### Test Structure
|
|
347
|
+
|
|
348
|
+
```javascript
|
|
349
|
+
import { test, expect } from 'bun:test';
|
|
350
|
+
import { AfriCode } from 'africode/core/sdk.js';
|
|
351
|
+
|
|
352
|
+
test('POST /api/users creates user', async () => {
|
|
353
|
+
const app = new AfriCode();
|
|
354
|
+
const res = await app.request('POST', '/api/users', {
|
|
355
|
+
name: 'Amara',
|
|
356
|
+
email: 'amara@example.com',
|
|
357
|
+
});
|
|
358
|
+
expect(res.status).toBe(201);
|
|
359
|
+
});
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## 📚 Multilingual Support
|
|
365
|
+
|
|
366
|
+
**4 Languages Built-In:**
|
|
367
|
+
|
|
368
|
+
### Implementation
|
|
369
|
+
|
|
370
|
+
```html
|
|
371
|
+
<!-- HTML with multilingual attributes -->
|
|
372
|
+
<h1 data-en="Welcome" data-sw="Karibu" data-yo="Pẹlẹ o" data-am="ደህና መጡ">Welcome</h1>
|
|
373
|
+
|
|
374
|
+
<button class="lang-btn" data-lang="en">EN</button>
|
|
375
|
+
<button class="lang-btn" data-lang="sw">SW</button>
|
|
376
|
+
<button class="lang-btn" data-lang="yo">YO</button>
|
|
377
|
+
<button class="lang-btn" data-lang="am">AM</button>
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### JavaScript
|
|
381
|
+
|
|
382
|
+
```javascript
|
|
383
|
+
function setLanguage(lang) {
|
|
384
|
+
document.querySelectorAll('[data-en]').forEach((el) => {
|
|
385
|
+
const text = el.getAttribute(`data-${lang}`) || el.getAttribute('data-en');
|
|
386
|
+
if (text) el.textContent = text;
|
|
387
|
+
});
|
|
388
|
+
localStorage.setItem('preferredLanguage', lang);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// Auto-load preferred language
|
|
392
|
+
const preferred = localStorage.getItem('preferredLanguage') || 'en';
|
|
393
|
+
setLanguage(preferred);
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### Supported Languages
|
|
397
|
+
|
|
398
|
+
- **EN** (English)
|
|
399
|
+
- **SW** (Kiswahili) - East Africa
|
|
400
|
+
- **YO** (Yoruba) - West Africa
|
|
401
|
+
- **AM** (Amharic) - East Africa
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## 🔧 CLI Tools
|
|
406
|
+
|
|
407
|
+
### AfriCode CLI
|
|
408
|
+
|
|
409
|
+
```bash
|
|
410
|
+
africode dev # Start development server with HMR
|
|
411
|
+
africode build # Build for production
|
|
412
|
+
africode migrate # Run database migrations
|
|
413
|
+
africode generate # Scaffold new components/models
|
|
414
|
+
africode serve # Serve static build
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### Create AfriCode Project
|
|
418
|
+
|
|
419
|
+
```bash
|
|
420
|
+
create-africode my-app # Create new project
|
|
421
|
+
create-africode my-app --template=ecommerce # With templates
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
## 🌟 Best Practices for Developers
|
|
427
|
+
|
|
428
|
+
### 1. Leverage Procedural Patterns
|
|
429
|
+
|
|
430
|
+
Don't hardcode graphics—use `PatternRenderer` for dynamic, responsive designs.
|
|
431
|
+
|
|
432
|
+
### 2. Use Web Components
|
|
433
|
+
|
|
434
|
+
Build with `<af-*>` components. They're framework-agnostic and production-tested.
|
|
435
|
+
|
|
436
|
+
### 3. Think in Sovereignty
|
|
437
|
+
|
|
438
|
+
Your framework should respect where you build it. Use multilingual support, cultural patterns, and local-first design.
|
|
439
|
+
|
|
440
|
+
### 4. Database First
|
|
441
|
+
|
|
442
|
+
Design with SQLite from start. Migrations are cheap, refactoring is expensive.
|
|
443
|
+
|
|
444
|
+
### 5. Real-Time Where It Matters
|
|
445
|
+
|
|
446
|
+
Use WebSocket for chat, notifications, live updates—not for every request.
|
|
447
|
+
|
|
448
|
+
### 6. Security by Default
|
|
449
|
+
|
|
450
|
+
Never skip auth, rate limiting, and CSRF. They're middleware—use them.
|
|
451
|
+
|
|
452
|
+
### 7. Test Everything
|
|
453
|
+
|
|
454
|
+
Write tests for API routes, database queries, and components. Aim for >80% coverage.
|
|
455
|
+
|
|
456
|
+
### 8. Optimize for Performance
|
|
457
|
+
|
|
458
|
+
- Use Bun's native SQLite (faster than driver libraries)
|
|
459
|
+
- Lazy-load Web Components with `<template>` tags
|
|
460
|
+
- Cache pattern renders with memoization
|
|
461
|
+
- Use HTTP/2 server push for critical resources
|
|
462
|
+
|
|
463
|
+
---
|
|
464
|
+
|
|
465
|
+
## 📖 Key Files & Where to Find Them
|
|
466
|
+
|
|
467
|
+
| File | Purpose |
|
|
468
|
+
| ----------------------- | ----------------------------- |
|
|
469
|
+
| `core/sdk.js` | Main framework entry point |
|
|
470
|
+
| `core/db.js` | Database ORM and QueryBuilder |
|
|
471
|
+
| `core/hydration.js` | Server-side rendering |
|
|
472
|
+
| `core/store.js` | Global state management |
|
|
473
|
+
| `components/index.js` | All 33 Web Components |
|
|
474
|
+
| `components/base.js` | Base Web Component class |
|
|
475
|
+
| `styles/africanity.css` | Color variables & typography |
|
|
476
|
+
| `bin/africode.js` | CLI entry point |
|
|
477
|
+
| `migrations/` | Database schema files |
|
|
478
|
+
|
|
479
|
+
---
|
|
480
|
+
|
|
481
|
+
## 🎯 Common Development Patterns
|
|
482
|
+
|
|
483
|
+
### Pattern 1: Fetch User Data with Pattern Display
|
|
484
|
+
|
|
485
|
+
```javascript
|
|
486
|
+
// Fetch user profile
|
|
487
|
+
const user = await User.find(123).with('posts');
|
|
488
|
+
|
|
489
|
+
// Render with pattern
|
|
490
|
+
const html = `
|
|
491
|
+
<div class="profile">
|
|
492
|
+
<h1>${user.name}</h1>
|
|
493
|
+
<af-pattern-showcase pattern="Masai"></af-pattern-showcase>
|
|
494
|
+
<div class="posts">
|
|
495
|
+
${user.posts.map((p) => `<af-card>${p.title}</af-card>`).join('')}
|
|
496
|
+
</div>
|
|
497
|
+
</div>
|
|
498
|
+
`;
|
|
499
|
+
|
|
500
|
+
res.html(html);
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
### Pattern 2: Real-Time Chat with WebSocket
|
|
504
|
+
|
|
505
|
+
```javascript
|
|
506
|
+
app.ws('/chat/:roomId', (ws, req) => {
|
|
507
|
+
const roomId = req.params.roomId;
|
|
508
|
+
ws.subscribe(`chat:${roomId}`);
|
|
509
|
+
|
|
510
|
+
ws.on('message', async (data) => {
|
|
511
|
+
const message = await Message.create({
|
|
512
|
+
roomId,
|
|
513
|
+
userId: req.auth.id,
|
|
514
|
+
text: data.text,
|
|
515
|
+
});
|
|
516
|
+
app.broadcast(`chat:${roomId}`, message);
|
|
517
|
+
});
|
|
518
|
+
});
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
### Pattern 3: Protected API Route
|
|
522
|
+
|
|
523
|
+
```javascript
|
|
524
|
+
app.use(middleware.auth({ secret: process.env.JWT_SECRET }));
|
|
525
|
+
|
|
526
|
+
app.post('/api/posts', async (req, res) => {
|
|
527
|
+
const post = await Post.create({
|
|
528
|
+
title: req.body.title,
|
|
529
|
+
userId: req.auth.id, // Set from middleware
|
|
530
|
+
content: req.body.content,
|
|
531
|
+
});
|
|
532
|
+
res.json({ post }, 201);
|
|
533
|
+
});
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
### Pattern 4: Paginated Data Table
|
|
537
|
+
|
|
538
|
+
```javascript
|
|
539
|
+
app.get('/api/users', async (req, res) => {
|
|
540
|
+
const page = parseInt(req.query.page || 1);
|
|
541
|
+
const limit = parseInt(req.query.limit || 10);
|
|
542
|
+
|
|
543
|
+
const { data, total, pages } = await User
|
|
544
|
+
.where('active', true)
|
|
545
|
+
.paginate(limit, page);
|
|
546
|
+
|
|
547
|
+
res.json({ data, total, pages });
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
// Frontend
|
|
551
|
+
<af-table data-endpoint="/api/users" :columns="['name', 'email', 'role']"></af-table>
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
---
|
|
555
|
+
|
|
556
|
+
## 🔄 Development Workflow
|
|
557
|
+
|
|
558
|
+
### 1. Setup Database
|
|
559
|
+
|
|
560
|
+
```bash
|
|
561
|
+
bun run migrations/001_initial_schema.sql
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
### 2. Start Dev Server
|
|
565
|
+
|
|
566
|
+
```bash
|
|
567
|
+
bun dev # Watches all files, HMR enabled
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
### 3. Build Components
|
|
571
|
+
|
|
572
|
+
```javascript
|
|
573
|
+
// Use Web Components in HTML
|
|
574
|
+
<af-button>Save</af-button>
|
|
575
|
+
<af-modal id="confirm">Confirm?</af-modal>
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
### 4. Handle Events
|
|
579
|
+
|
|
580
|
+
```javascript
|
|
581
|
+
document.getElementById('confirm').addEventListener('confirm', () => {
|
|
582
|
+
console.log('User confirmed');
|
|
583
|
+
});
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
### 5. Test
|
|
587
|
+
|
|
588
|
+
```bash
|
|
589
|
+
bun test --watch
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
### 6. Deploy
|
|
593
|
+
|
|
594
|
+
```bash
|
|
595
|
+
bun build # Build for production
|
|
596
|
+
npm publish # If publishing to npm
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
---
|
|
600
|
+
|
|
601
|
+
## 🌐 Deployment Options
|
|
602
|
+
|
|
603
|
+
### Option 1: Vercel (Recommended)
|
|
604
|
+
|
|
605
|
+
- `vercel deploy` from CLI
|
|
606
|
+
- Auto-detects Bun, builds framework
|
|
607
|
+
- Serverless functions support
|
|
608
|
+
|
|
609
|
+
### Option 2: Railway
|
|
610
|
+
|
|
611
|
+
- Push to GitHub, Railway auto-deploys
|
|
612
|
+
- Supports WebSocket
|
|
613
|
+
- SQLite with persistent volumes
|
|
614
|
+
|
|
615
|
+
### Option 3: Self-Hosted (VPS)
|
|
616
|
+
|
|
617
|
+
```bash
|
|
618
|
+
# On server
|
|
619
|
+
git clone https://github.com/your-repo/my-app.git
|
|
620
|
+
cd my-app
|
|
621
|
+
bun install
|
|
622
|
+
bun run build
|
|
623
|
+
bun start
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
---
|
|
627
|
+
|
|
628
|
+
## 📝 Important Conventions
|
|
629
|
+
|
|
630
|
+
### Naming Conventions
|
|
631
|
+
|
|
632
|
+
- **Files:** `kebab-case` (my-component.js)
|
|
633
|
+
- **Classes:** `PascalCase` (UserModel)
|
|
634
|
+
- **Functions:** `camelCase` (createUser)
|
|
635
|
+
- **Constants:** `UPPER_SNAKE_CASE` (MAX_RETRIES)
|
|
636
|
+
- **Components:** `<af-kebab-case>` (<af-table>, <af-modal>)
|
|
637
|
+
|
|
638
|
+
### Directory Structure
|
|
639
|
+
|
|
640
|
+
- `core/` → Internals (don't modify often)
|
|
641
|
+
- `pages/` → User-facing routes
|
|
642
|
+
- `styles/` → CSS (use CSS variables)
|
|
643
|
+
- `migrations/` → Database schemas
|
|
644
|
+
- `public/` → Static assets
|
|
645
|
+
|
|
646
|
+
### Environment Variables
|
|
647
|
+
|
|
648
|
+
```bash
|
|
649
|
+
# .env
|
|
650
|
+
DATABASE_URL=afriCode.db
|
|
651
|
+
JWT_SECRET=your-secret-here
|
|
652
|
+
API_PORT=3000
|
|
653
|
+
NODE_ENV=production
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
---
|
|
657
|
+
|
|
658
|
+
## 🆘 Debugging Tips
|
|
659
|
+
|
|
660
|
+
### Enable Debug Logs
|
|
661
|
+
|
|
662
|
+
```javascript
|
|
663
|
+
process.env.DEBUG = 'africode:*';
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
### Query Debugging
|
|
667
|
+
|
|
668
|
+
```javascript
|
|
669
|
+
// See generated SQL
|
|
670
|
+
const query = User.where('email', 'like', '%@example.com');
|
|
671
|
+
console.log(query.toSQL()); // Prints: SELECT * FROM users WHERE email LIKE ?
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
### WebSocket Issues
|
|
675
|
+
|
|
676
|
+
```javascript
|
|
677
|
+
// Enable verbose logging
|
|
678
|
+
ws.on('error', (err) => console.error('WS Error:', err));
|
|
679
|
+
ws.on('close', () => console.log('WS Closed'));
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
---
|
|
683
|
+
|
|
684
|
+
## 📞 Support & Community
|
|
685
|
+
|
|
686
|
+
- **GitHub**: https://github.com/tap2payco/AfriCode-js
|
|
687
|
+
- **Documentation**: https://africode.dev/docs
|
|
688
|
+
- **Issues**: https://github.com/tap2payco/AfriCode-js/issues
|
|
689
|
+
- **Discussions**: https://github.com/tap2payco/AfriCode-js/discussions
|
|
690
|
+
|
|
691
|
+
---
|
|
692
|
+
|
|
693
|
+
## ✨ Final Thoughts
|
|
694
|
+
|
|
695
|
+
**AfriCode is built for developers who believe code is cultural.**
|
|
696
|
+
|
|
697
|
+
Use this framework to:
|
|
698
|
+
|
|
699
|
+
- Build fast, sovereignty-respecting web applications
|
|
700
|
+
- Celebrate African heritage in digital spaces
|
|
701
|
+
- Write less boilerplate, more business logic
|
|
702
|
+
- Create real-time, responsive experiences
|
|
703
|
+
- Deploy anywhere with confidence
|
|
704
|
+
|
|
705
|
+
**Remember: Your framework should serve you, not control you.**
|
|
706
|
+
|
|
707
|
+
Happy building! 🌍✨
|