create-aziz-app 3.1.1 → 3.1.3

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.
Files changed (33) hide show
  1. package/README.md +658 -207
  2. package/bin/create-aziz-app.js +302 -351
  3. package/package.json +1 -1
  4. package/template/README.md +14 -279
  5. package/template/_framework/api.js +219 -219
  6. package/template/_framework/boot.js +33 -33
  7. package/template/_framework/hooks.js +367 -291
  8. package/template/_framework/next-response.js +128 -128
  9. package/template/_framework/route-match.js +145 -145
  10. package/template/_framework/router.js +465 -259
  11. package/template/_framework/runtime.js +264 -264
  12. package/template/app/layout.js +3 -5
  13. package/template/app/page.js +9 -32
  14. package/template/docs/01-getting-started.md +151 -151
  15. package/template/docs/02-project-structure.md +109 -109
  16. package/template/docs/03-pages-and-layouts.md +140 -140
  17. package/template/docs/04-routing.md +120 -120
  18. package/template/docs/05-hooks.md +169 -169
  19. package/template/docs/06-api-routes.md +210 -210
  20. package/template/docs/07-api-client.md +151 -151
  21. package/template/docs/08-styling.md +94 -94
  22. package/template/docs/09-imports-and-modules.md +97 -97
  23. package/template/docs/10-database-and-models.md +154 -154
  24. package/template/docs/11-authentication.md +171 -171
  25. package/template/docs/12-production-and-deployment.md +121 -121
  26. package/template/docs/13-internals.md +179 -179
  27. package/template/docs/README.md +67 -67
  28. package/template/index.html +20 -20
  29. package/template/package.json +16 -16
  30. package/template/scripts/dev-server.js +493 -381
  31. package/template/scripts/lib/api-router.js +525 -525
  32. package/template/scripts/lib/js-transform.js +213 -141
  33. package/template/scripts/lib/module-resolver.js +132 -132
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-aziz-app",
3
- "version": "3.1.1",
3
+ "version": "3.1.3",
4
4
  "description": "Create Aziz.js apps — lightweight Next.js clone with file-based routing, React hooks, and API routes",
5
5
  "keywords": [
6
6
  "aziz.js",
@@ -1,6 +1,6 @@
1
1
  # ⚡ Aziz.js
2
2
 
3
- A lightweight Next.js clone with file-based routing, React hooks, server-side API routes, and ES module imports — **zero dependencies, instant startup**.
3
+ A lightweight Next.js clone with file-based routing, React hooks, and ES module imports — **zero dependencies, instant startup**.
4
4
 
5
5
  ```
6
6
  Next.js: ~400KB + 20 dependencies + 10s startup
@@ -12,8 +12,7 @@ Aziz.js: ~50KB + 0 dependencies + <1s startup
12
12
  ## Quick Start
13
13
 
14
14
  ```bash
15
- npx create-aziz-app my-app
16
- cd my-app
15
+ npm install
17
16
  npm run dev
18
17
  ```
19
18
 
@@ -28,30 +27,15 @@ my-app/
28
27
  ├── index.html ← entry point (don't touch)
29
28
  │
30
29
  ├── app/ ← your pages and layouts
31
- │ ├── layout.js ← root layout (navbar, footer, etc.)
32
- │ ├── page.js ← route: /
33
- │ ├── about/
34
- │ │ └── page.js ← route: /about
35
- │ └── blog/
36
- │ └── [slug]/
37
- │ └── page.js ← route: /blog/:slug (dynamic)
30
+ │ ├── layout.js ← root layout (wraps every page)
31
+ │ └── page.js ← route: /
38
32
  │
39
- ├── api/ ← server-side API routes (Node.js)
40
- │ ├── users.js ← route: /api/users
41
- │ └── hello.js ← route: /api/hello
33
+ ├── styles/
34
+ │ └── globals.css ← global styles
42
35
  │
43
- ├── components/ ← shared UI components
44
- │ ├── Navbar.js
45
- │ └── Footer.js
46
- │
47
- ├── lib/ ← utilities, database connections
48
- │ └── db.js
49
- │
50
- ├── models/ ← data models
51
- │ └── User.js
52
- │
53
- └── styles/
54
- └── globals.css
36
+ ├── _framework/ ← runtime, hooks, router (don't touch)
37
+ ├── scripts/ ← dev server + live reload (don't touch)
38
+ └── docs/ ← full documentation
55
39
  ```
56
40
 
57
41
  ---
@@ -88,7 +72,6 @@ Just create the file — no registration needed:
88
72
 
89
73
  ```bash
90
74
  mkdir app/dashboard
91
- touch app/dashboard/page.js
92
75
  ```
93
76
 
94
77
  ```js
@@ -106,15 +89,10 @@ export default function Page() {
106
89
 
107
90
  ```js
108
91
  // app/layout.js
109
- import Navbar from '/components/Navbar.js';
110
- import Footer from '/components/Footer.js';
111
-
112
92
  export default function Layout({ children }) {
113
93
  return (
114
94
  <div>
115
- <Navbar />
116
95
  <main>{children}</main>
117
- <Footer />
118
96
  </div>
119
97
  );
120
98
  }
@@ -124,12 +102,9 @@ export default function Layout({ children }) {
124
102
 
125
103
  ```js
126
104
  // app/dashboard/layout.js — wraps all /dashboard/* pages
127
- import Sidebar from '/components/Sidebar.js';
128
-
129
105
  export default function Layout({ children }) {
130
106
  return (
131
107
  <div style={{ display: 'flex' }}>
132
- <Sidebar />
133
108
  <div style={{ flex: 1 }}>{children}</div>
134
109
  </div>
135
110
  );
@@ -204,8 +179,6 @@ All hooks work exactly like React — **no imports needed**.
204
179
 
205
180
  ```js
206
181
  const [count, setCount] = useState(0);
207
- const [user, setUser] = useState(null);
208
- const [items, setItems] = useState([]);
209
182
 
210
183
  setCount(prev => prev + 1);
211
184
  ```
@@ -213,10 +186,6 @@ setCount(prev => prev + 1);
213
186
  ### useEffect
214
187
 
215
188
  ```js
216
- useEffect(() => {
217
- console.log('mounted');
218
- }, []);
219
-
220
189
  useEffect(() => {
221
190
  document.title = `Count: ${count}`;
222
191
  }, [count]);
@@ -260,14 +229,11 @@ const reducer = (state, action) => {
260
229
  switch (action.type) {
261
230
  case 'increment': return { count: state.count + 1 };
262
231
  case 'decrement': return { count: state.count - 1 };
263
- case 'reset': return { count: 0 };
264
232
  default: return state;
265
233
  }
266
234
  };
267
235
 
268
236
  const [state, dispatch] = useReducer(reducer, { count: 0 });
269
-
270
- dispatch({ type: 'increment' });
271
237
  ```
272
238
 
273
239
  ### useContext
@@ -275,12 +241,10 @@ dispatch({ type: 'increment' });
275
241
  ```js
276
242
  const ThemeContext = createContext('light');
277
243
 
278
- // Provide value (in layout or parent)
279
244
  <ThemeContext.Provider value="dark">
280
245
  {children}
281
246
  </ThemeContext.Provider>
282
247
 
283
- // Consume anywhere
284
248
  const theme = useContext(ThemeContext);
285
249
  ```
286
250
 
@@ -290,106 +254,21 @@ const theme = useContext(ThemeContext);
290
254
  const [name, setName] = useLocalStorage('userName', '');
291
255
  ```
292
256
 
293
- ### useFetch
294
-
295
- ```js
296
- const { data, loading, error } = useFetch('/api/users');
297
-
298
- if (loading) return <p>Loading...</p>;
299
- if (error) return <p>Error: {error}</p>;
300
-
301
- return <pre>{JSON.stringify(data, null, 2)}</pre>;
302
- ```
303
-
304
- ---
305
-
306
- ## API Routes
307
-
308
- API routes run on the **server** (Node.js). Every `.js` file in `api/` becomes an endpoint.
309
-
310
- ### Basic example
311
-
312
- ```js
313
- // api/hello.js → GET /api/hello
314
- const { NextResponse } = require('../_framework/next-response');
315
-
316
- async function GET(request) {
317
- const { searchParams } = new URL(request.url);
318
- const name = searchParams.get('name') || 'World';
319
- return NextResponse.json({ message: `Hello, ${name}!` });
320
- }
321
-
322
- module.exports = { GET };
323
- ```
324
-
325
- ### CRUD example
326
-
327
- ```js
328
- // api/users.js → /api/users
329
- const { NextResponse } = require('../_framework/next-response');
330
-
331
- async function GET(request) {
332
- const users = await User.find();
333
- return NextResponse.json(users);
334
- }
335
-
336
- async function POST(request) {
337
- const { name, email } = await request.json();
338
- if (!name || !email) {
339
- return NextResponse.json({ error: 'Name and email required' }, { status: 400 });
340
- }
341
- const user = await User.create({ name, email });
342
- return NextResponse.json(user, { status: 201 });
343
- }
344
-
345
- async function DELETE(request) {
346
- const { searchParams } = new URL(request.url);
347
- await User.findByIdAndDelete(searchParams.get('id'));
348
- return NextResponse.json({ message: 'Deleted' });
349
- }
350
-
351
- module.exports = { GET, POST, DELETE };
352
- ```
353
-
354
- ### NextResponse
355
-
356
- ```js
357
- return NextResponse.json({ data: 'value' });
358
- return NextResponse.json({ error: 'Not found' }, { status: 404 });
359
- return NextResponse.redirect('/login');
360
- return NextResponse.text('Hello');
361
- ```
362
-
363
257
  ---
364
258
 
365
259
  ## Imports
366
260
 
367
- ### Components and pages — no imports needed for JSX or hooks
368
-
369
- ```js
370
- // app/dashboard/page.js
371
- export default function Page() {
372
- const [count, setCount] = useState(0); // hooks are global
373
- return <h1>Count: {count}</h1>; // JSX works automatically
374
- }
375
- ```
376
-
377
261
  ### Importing other files
378
262
 
379
263
  ```js
380
264
  // Absolute path
381
- import Navbar from '/components/Navbar.js';
382
- import connectDB from '/lib/db.js';
383
- import User from '/models/User.js';
265
+ import Button from '/components/Button.js';
384
266
 
385
267
  // @/ alias (same as absolute)
386
- import connectDB from '@/lib/db';
387
- import User from '@/models/User';
268
+ import Button from '@/components/Button';
388
269
 
389
- // npm packages (install first: npm install mongoose)
390
- import mongoose from 'mongoose';
391
- import bcrypt from 'bcryptjs';
392
- import jwt from 'jsonwebtoken';
270
+ // npm packages (install first: npm install lodash)
271
+ import _ from 'lodash';
393
272
  ```
394
273
 
395
274
  The dev server resolves bare imports from `node_modules` automatically — no bundler config needed.
@@ -442,137 +321,6 @@ import Button from '/components/Button.js';
442
321
 
443
322
  ---
444
323
 
445
- ## Database
446
-
447
- ### MongoDB with Mongoose
448
-
449
- ```bash
450
- npm install mongoose
451
- ```
452
-
453
- ```js
454
- // lib/db.js
455
- import mongoose from 'mongoose';
456
-
457
- let isConnected = false;
458
-
459
- export default async function connectDB() {
460
- if (isConnected) return;
461
- await mongoose.connect(process.env.MONGODB_URI);
462
- isConnected = true;
463
- }
464
- ```
465
-
466
- ```js
467
- // models/User.js
468
- import mongoose from 'mongoose';
469
-
470
- const userSchema = new mongoose.Schema({
471
- name: { type: String, required: true },
472
- email: { type: String, required: true, unique: true },
473
- password: { type: String, required: true },
474
- }, { timestamps: true });
475
-
476
- export default mongoose.models.User || mongoose.model('User', userSchema);
477
- ```
478
-
479
- ### Environment variables
480
-
481
- Create `.env` in your project root:
482
-
483
- ```bash
484
- MONGODB_URI=mongodb://localhost:27017/myapp
485
- JWT_SECRET=your_secret_key
486
- ```
487
-
488
- > Install `dotenv` and add `require('dotenv').config()` at the top of `scripts/dev-server.js` to load `.env` automatically.
489
-
490
- ---
491
-
492
- ## Calling APIs from Pages
493
-
494
- ```js
495
- // GET
496
- const res = await fetch('/api/users');
497
- const users = await res.json();
498
-
499
- // POST
500
- const res = await fetch('/api/users', {
501
- method: 'POST',
502
- headers: { 'Content-Type': 'application/json' },
503
- body: JSON.stringify({ name: 'Aziz', email: 'aziz@example.com' })
504
- });
505
- const result = await res.json();
506
- ```
507
-
508
- ### Full login example
509
-
510
- ```js
511
- export default function Page() {
512
- const [email, setEmail] = useState('');
513
- const [password, setPassword] = useState('');
514
- const [error, setError] = useState('');
515
- const [loading, setLoading] = useState(false);
516
-
517
- const handleLogin = async (e) => {
518
- e.preventDefault();
519
- setLoading(true);
520
- setError('');
521
-
522
- try {
523
- const res = await fetch('/api/loginUser', {
524
- method: 'POST',
525
- headers: { 'Content-Type': 'application/json' },
526
- body: JSON.stringify({ email, password })
527
- });
528
-
529
- const result = await res.json();
530
-
531
- if (!res.ok) {
532
- setError(result.error);
533
- return;
534
- }
535
-
536
- localStorage.setItem('user', JSON.stringify(result));
537
- navigate(result.role === 'admin' ? '/admin' : '/dashboard');
538
-
539
- } catch (err) {
540
- setError('Something went wrong. Try again.');
541
- } finally {
542
- setLoading(false);
543
- }
544
- };
545
-
546
- return (
547
- <div style={{ maxWidth: '400px', margin: '80px auto', padding: '0 16px' }}>
548
- <h1>Login</h1>
549
- <form onSubmit={handleLogin}>
550
- <input
551
- type="email"
552
- placeholder="Email"
553
- value={email}
554
- onInput={(e) => setEmail(e.target.value)}
555
- required
556
- />
557
- <input
558
- type="password"
559
- placeholder="Password"
560
- value={password}
561
- onInput={(e) => setPassword(e.target.value)}
562
- required
563
- />
564
- {error && <p style={{ color: 'red' }}>{error}</p>}
565
- <button type="submit" class="btn btn-primary" disabled={loading}>
566
- {loading ? 'Logging in...' : 'Login'}
567
- </button>
568
- </form>
569
- </div>
570
- );
571
- }
572
- ```
573
-
574
- ---
575
-
576
324
  ## Styling
577
325
 
578
326
  ### globals.css
@@ -597,25 +345,15 @@ Edit `styles/globals.css` for global styles. Built-in utility classes:
597
345
 
598
346
  ### Tailwind CSS
599
347
 
600
- Tailwind CSS is included by default via CDN with `primary` and `dark` colors pre-configured:
348
+ If you scaffolded with Tailwind, it is loaded via CDN with `primary` and `dark` colors pre-configured:
601
349
 
602
350
  ```js
603
351
  // Use Tailwind classes directly in any file
604
352
  <div class="flex items-center gap-4 p-6 bg-white rounded-lg shadow">
605
353
  <h1 class="text-2xl font-bold text-dark">Hello</h1>
606
- <button class="bg-primary text-dark font-bold px-4 py-2 rounded-lg">
607
- Click me
608
- </button>
609
354
  </div>
610
355
  ```
611
356
 
612
- Custom colors available out of the box:
613
-
614
- | Class | Value |
615
- |-------|-------|
616
- | `bg-primary` / `text-primary` | `#61dafb` (cyan) |
617
- | `bg-dark` / `text-dark` | `#282c34` (dark) |
618
-
619
357
  To extend the config, edit the `tailwind.config` block in `index.html`.
620
358
 
621
359
  ---
@@ -629,7 +367,6 @@ npm run dev
629
367
  - Serves your app at `http://localhost:3000`
630
368
  - Watches all source folders and live-reloads on save
631
369
  - Resolves bare imports from `node_modules`
632
- - Hot-reloads API routes when changed
633
370
 
634
371
  ```bash
635
372
  # Custom port
@@ -647,8 +384,6 @@ PORT=4000 npm run dev
647
384
  | `layout.js` convention | ✅ | ✅ |
648
385
  | Dynamic routes `[slug]` | ✅ | ✅ |
649
386
  | Catch-all `[...slug]` | ✅ | ✅ |
650
- | API routes | ✅ | ✅ |
651
- | `NextResponse` | ✅ | ✅ |
652
387
  | React hooks | ✅ | ✅ |
653
388
  | No imports needed in pages | ✅ | ❌ |
654
389
  | ES module imports | ✅ | ✅ |