create-aziz-app 2.0.13 → 2.0.14

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-aziz-app",
3
- "version": "2.0.13",
3
+ "version": "2.0.14",
4
4
  "description": "A React-like framework with state management, routing, and API routes - Create apps with auto-import, live reload, and Next.js-like features",
5
5
  "keywords": [
6
6
  "react",
@@ -0,0 +1,69 @@
1
+ // API Route: /api/createUser
2
+ // Next.js App Router style
3
+
4
+ const { NextResponse } = require('../modules/next-response');
5
+
6
+ // Mock database
7
+ let users = [
8
+ { _id: '1', name: 'Aziz Ahmed', email: 'aziz@example.com', role: 'admin', phone: '123-456-7890' }
9
+ ];
10
+
11
+ // POST handler
12
+ async function POST(request) {
13
+ try {
14
+ // Parse request body
15
+ const body = await request.json();
16
+ const { name, email, password, role, phone } = body;
17
+
18
+ // Validation
19
+ if (!name || !email || !password) {
20
+ return NextResponse.json(
21
+ {
22
+ error: 'Validation failed',
23
+ message: 'Name, email, and password are required'
24
+ },
25
+ { status: 400 }
26
+ );
27
+ }
28
+
29
+ // Check if email already exists
30
+ if (users.find(u => u.email === email)) {
31
+ return NextResponse.json(
32
+ { error: 'User with this email already exists' },
33
+ { status: 409 }
34
+ );
35
+ }
36
+
37
+ // Create new user
38
+ const newUser = {
39
+ _id: String(users.length + 1),
40
+ name,
41
+ email,
42
+ password, // In production, hash this with bcrypt!
43
+ role: role || 'user',
44
+ phone: phone || '',
45
+ createdAt: new Date().toISOString()
46
+ };
47
+
48
+ users.push(newUser);
49
+
50
+ // Return user data (without password)
51
+ const { password: _, ...userData } = newUser;
52
+
53
+ return NextResponse.json(
54
+ {
55
+ message: 'User created successfully',
56
+ user: userData
57
+ },
58
+ { status: 201 }
59
+ );
60
+ } catch (error) {
61
+ console.error('Create user error:', error);
62
+ return NextResponse.json(
63
+ { error: 'Failed to create user' },
64
+ { status: 500 }
65
+ );
66
+ }
67
+ }
68
+
69
+ module.exports = { POST };
@@ -0,0 +1,60 @@
1
+ // API Route: /api/getUser
2
+ // Next.js App Router style with NextResponse
3
+
4
+ const { NextResponse } = require('../modules/next-response');
5
+
6
+ // Mock database
7
+ const users = [
8
+ { _id: '1', name: 'Aziz Ahmed', email: 'aziz@example.com', role: 'admin', phone: '123-456-7890' },
9
+ { _id: '2', name: 'John Doe', email: 'john@example.com', role: 'user', phone: '098-765-4321' },
10
+ { _id: '3', name: 'Jane Smith', email: 'jane@example.com', role: 'user', phone: '555-123-4567' }
11
+ ];
12
+
13
+ // GET handler - Next.js App Router style
14
+ async function GET(request) {
15
+ try {
16
+ // Parse URL and get search params
17
+ const { searchParams } = new URL(request.url);
18
+ const email = searchParams.get('email');
19
+ const id = searchParams.get('id');
20
+
21
+ // Find by email
22
+ if (email) {
23
+ const user = users.find(u => u.email === email);
24
+ if (!user) {
25
+ return NextResponse.json(
26
+ { error: 'User not found' },
27
+ { status: 404 }
28
+ );
29
+ }
30
+ return NextResponse.json(user);
31
+ }
32
+
33
+ // Find by ID
34
+ if (id) {
35
+ const user = users.find(u => u._id === id);
36
+ if (!user) {
37
+ return NextResponse.json(
38
+ { error: 'User not found' },
39
+ { status: 404 }
40
+ );
41
+ }
42
+ return NextResponse.json(user);
43
+ }
44
+
45
+ // No params provided
46
+ return NextResponse.json(
47
+ { error: 'Email or ID required' },
48
+ { status: 400 }
49
+ );
50
+ } catch (error) {
51
+ console.error('Error fetching user:', error);
52
+ return NextResponse.json(
53
+ { error: 'Failed to fetch user' },
54
+ { status: 500 }
55
+ );
56
+ }
57
+ }
58
+
59
+ // Export the handler
60
+ module.exports = { GET };
@@ -0,0 +1,65 @@
1
+ // API Route: /api/getUserWithDB
2
+ // Complete Next.js App Router style with DB and Model
3
+
4
+ const { NextResponse } = require('../modules/next-response');
5
+ const connectDB = require('../lib/db');
6
+ const User = require('../models/User');
7
+
8
+ // GET handler - Exactly like Next.js!
9
+ async function GET(request) {
10
+ try {
11
+ // Connect to database
12
+ await connectDB();
13
+
14
+ // Parse URL and get search params
15
+ const { searchParams } = new URL(request.url);
16
+ const email = searchParams.get('email');
17
+ const id = searchParams.get('id');
18
+
19
+ // Find by email
20
+ if (email) {
21
+ const user = await User.findOne({ email });
22
+
23
+ if (!user) {
24
+ return NextResponse.json(
25
+ { error: 'User not found' },
26
+ { status: 404 }
27
+ );
28
+ }
29
+
30
+ // Return user without sensitive fields
31
+ const { password, ...userData } = user;
32
+ return NextResponse.json(userData);
33
+ }
34
+
35
+ // Find by ID
36
+ if (id) {
37
+ const user = await User.findById(id);
38
+
39
+ if (!user) {
40
+ return NextResponse.json(
41
+ { error: 'User not found' },
42
+ { status: 404 }
43
+ );
44
+ }
45
+
46
+ // Return user without sensitive fields
47
+ const { password, ...userData } = user;
48
+ return NextResponse.json(userData);
49
+ }
50
+
51
+ // No params - return error
52
+ return NextResponse.json(
53
+ { error: 'Email or ID required' },
54
+ { status: 400 }
55
+ );
56
+ } catch (error) {
57
+ console.error('Error fetching user:', error);
58
+ return NextResponse.json(
59
+ { error: 'Failed to fetch user' },
60
+ { status: 500 }
61
+ );
62
+ }
63
+ }
64
+
65
+ module.exports = { GET };
@@ -0,0 +1,61 @@
1
+ // API Route: /api/loginUser
2
+ // Next.js App Router style
3
+
4
+ const { NextResponse } = require('../modules/next-response');
5
+
6
+ // Mock database
7
+ const users = [
8
+ { _id: '1', name: 'Aziz Ahmed', email: 'aziz@example.com', password: 'admin123', role: 'admin' },
9
+ { _id: '2', name: 'John Doe', email: 'john@example.com', password: 'user123', role: 'user' }
10
+ ];
11
+
12
+ // POST handler
13
+ async function POST(request) {
14
+ try {
15
+ // Parse request body
16
+ const body = await request.json();
17
+ const { email, password } = body;
18
+
19
+ // Validation
20
+ if (!email || !password) {
21
+ return NextResponse.json(
22
+ { error: 'Email and password are required' },
23
+ { status: 400 }
24
+ );
25
+ }
26
+
27
+ // Find user
28
+ const user = users.find(u => u.email === email);
29
+
30
+ if (!user) {
31
+ return NextResponse.json(
32
+ { error: 'Invalid credentials' },
33
+ { status: 401 }
34
+ );
35
+ }
36
+
37
+ // Check password (in production, use bcrypt!)
38
+ if (user.password !== password) {
39
+ return NextResponse.json(
40
+ { error: 'Invalid credentials' },
41
+ { status: 401 }
42
+ );
43
+ }
44
+
45
+ // Return user data (without password)
46
+ const { password: _, ...userData } = user;
47
+
48
+ return NextResponse.json({
49
+ ...userData,
50
+ message: 'Login successful'
51
+ });
52
+ } catch (error) {
53
+ console.error('Login error:', error);
54
+ return NextResponse.json(
55
+ { error: 'Failed to login' },
56
+ { status: 500 }
57
+ );
58
+ }
59
+ }
60
+
61
+ module.exports = { POST };
@@ -0,0 +1,536 @@
1
+ # Next.js App Router Style API Routes
2
+
3
+ ## Overview
4
+
5
+ Write API routes **exactly like Next.js App Router** with `NextResponse` and named HTTP method exports!
6
+
7
+ ## Quick Example
8
+
9
+ ```javascript
10
+ // api/getUser.js
11
+ const { NextResponse } = require('../modules/next-response');
12
+
13
+ export async function GET(request) {
14
+ const { searchParams } = new URL(request.url);
15
+ const email = searchParams.get('email');
16
+
17
+ if (!email) {
18
+ return NextResponse.json(
19
+ { error: 'Email required' },
20
+ { status: 400 }
21
+ );
22
+ }
23
+
24
+ const user = await findUser(email);
25
+ return NextResponse.json(user);
26
+ }
27
+
28
+ module.exports = { GET };
29
+ ```
30
+
31
+ ## NextResponse API
32
+
33
+ ### NextResponse.json()
34
+
35
+ ```javascript
36
+ // Success response
37
+ return NextResponse.json({ message: 'Success' });
38
+
39
+ // With status code
40
+ return NextResponse.json(
41
+ { error: 'Not found' },
42
+ { status: 404 }
43
+ );
44
+
45
+ // With custom headers
46
+ return NextResponse.json(
47
+ { data: 'value' },
48
+ {
49
+ status: 200,
50
+ headers: {
51
+ 'X-Custom-Header': 'value'
52
+ }
53
+ }
54
+ );
55
+ ```
56
+
57
+ ### NextResponse.text()
58
+
59
+ ```javascript
60
+ return NextResponse.text('Hello World');
61
+
62
+ return NextResponse.text(
63
+ 'Error message',
64
+ { status: 500 }
65
+ );
66
+ ```
67
+
68
+ ### NextResponse.redirect()
69
+
70
+ ```javascript
71
+ return NextResponse.redirect('/login');
72
+
73
+ return NextResponse.redirect(
74
+ '/dashboard',
75
+ { status: 307 }
76
+ );
77
+ ```
78
+
79
+ ### NextResponse.error()
80
+
81
+ ```javascript
82
+ return NextResponse.error();
83
+ // Returns 500 with generic error message
84
+ ```
85
+
86
+ ## HTTP Method Exports
87
+
88
+ ### Single Method
89
+
90
+ ```javascript
91
+ // api/getUser.js
92
+ const { NextResponse } = require('../modules/next-response');
93
+
94
+ async function GET(request) {
95
+ return NextResponse.json({ message: 'GET request' });
96
+ }
97
+
98
+ module.exports = { GET };
99
+ ```
100
+
101
+ ### Multiple Methods
102
+
103
+ ```javascript
104
+ // api/users.js
105
+ const { NextResponse } = require('../modules/next-response');
106
+
107
+ async function GET(request) {
108
+ const users = await getAllUsers();
109
+ return NextResponse.json(users);
110
+ }
111
+
112
+ async function POST(request) {
113
+ const body = await request.json();
114
+ const user = await createUser(body);
115
+ return NextResponse.json(user, { status: 201 });
116
+ }
117
+
118
+ async function PUT(request) {
119
+ const body = await request.json();
120
+ const user = await updateUser(body);
121
+ return NextResponse.json(user);
122
+ }
123
+
124
+ async function DELETE(request) {
125
+ const { searchParams } = new URL(request.url);
126
+ const id = searchParams.get('id');
127
+ await deleteUser(id);
128
+ return NextResponse.json({ message: 'Deleted' });
129
+ }
130
+
131
+ module.exports = { GET, POST, PUT, DELETE };
132
+ ```
133
+
134
+ ## Request Object
135
+
136
+ ### URL and Search Params
137
+
138
+ ```javascript
139
+ async function GET(request) {
140
+ // Parse URL
141
+ const { searchParams } = new URL(request.url);
142
+
143
+ // Get query parameters
144
+ const email = searchParams.get('email');
145
+ const id = searchParams.get('id');
146
+ const page = searchParams.get('page') || '1';
147
+
148
+ return NextResponse.json({ email, id, page });
149
+ }
150
+ ```
151
+
152
+ ### Request Body
153
+
154
+ ```javascript
155
+ async function POST(request) {
156
+ // Parse JSON body
157
+ const body = await request.json();
158
+ const { name, email, password } = body;
159
+
160
+ return NextResponse.json({ name, email });
161
+ }
162
+ ```
163
+
164
+ ### Headers
165
+
166
+ ```javascript
167
+ async function GET(request) {
168
+ // Access headers
169
+ const auth = request.headers.authorization;
170
+ const contentType = request.headers['content-type'];
171
+
172
+ return NextResponse.json({ auth, contentType });
173
+ }
174
+ ```
175
+
176
+ ### Method
177
+
178
+ ```javascript
179
+ async function GET(request) {
180
+ console.log(request.method); // 'GET'
181
+ return NextResponse.json({ method: request.method });
182
+ }
183
+ ```
184
+
185
+ ## Complete Examples
186
+
187
+ ### Example 1: User Login
188
+
189
+ ```javascript
190
+ // api/loginUser.js
191
+ const { NextResponse } = require('../modules/next-response');
192
+ const connectDB = require('../lib/db');
193
+ const User = require('../models/User');
194
+
195
+ async function POST(request) {
196
+ try {
197
+ await connectDB();
198
+
199
+ const { email, password } = await request.json();
200
+
201
+ // Validation
202
+ if (!email || !password) {
203
+ return NextResponse.json(
204
+ { error: 'Email and password required' },
205
+ { status: 400 }
206
+ );
207
+ }
208
+
209
+ // Find user
210
+ const user = await User.findOne({ email });
211
+ if (!user) {
212
+ return NextResponse.json(
213
+ { error: 'Invalid credentials' },
214
+ { status: 401 }
215
+ );
216
+ }
217
+
218
+ // Check password (use bcrypt in production!)
219
+ if (user.password !== password) {
220
+ return NextResponse.json(
221
+ { error: 'Invalid credentials' },
222
+ { status: 401 }
223
+ );
224
+ }
225
+
226
+ // Return user data
227
+ const { password: _, ...userData } = user;
228
+ return NextResponse.json(userData);
229
+
230
+ } catch (error) {
231
+ console.error('Login error:', error);
232
+ return NextResponse.json(
233
+ { error: 'Failed to login' },
234
+ { status: 500 }
235
+ );
236
+ }
237
+ }
238
+
239
+ module.exports = { POST };
240
+ ```
241
+
242
+ ### Example 2: Create User
243
+
244
+ ```javascript
245
+ // api/createUser.js
246
+ const { NextResponse } = require('../modules/next-response');
247
+ const connectDB = require('../lib/db');
248
+ const User = require('../models/User');
249
+
250
+ async function POST(request) {
251
+ try {
252
+ await connectDB();
253
+
254
+ const body = await request.json();
255
+ const { name, email, password, role, phone } = body;
256
+
257
+ // Validation
258
+ if (!name || !email || !password) {
259
+ return NextResponse.json(
260
+ { error: 'Name, email, and password required' },
261
+ { status: 400 }
262
+ );
263
+ }
264
+
265
+ // Check if exists
266
+ const existing = await User.findOne({ email });
267
+ if (existing) {
268
+ return NextResponse.json(
269
+ { error: 'User already exists' },
270
+ { status: 409 }
271
+ );
272
+ }
273
+
274
+ // Create user
275
+ const user = await User.create({
276
+ name,
277
+ email,
278
+ password, // Hash with bcrypt in production!
279
+ role: role || 'user',
280
+ phone
281
+ });
282
+
283
+ // Return without password
284
+ const { password: _, ...userData } = user;
285
+ return NextResponse.json(
286
+ { message: 'User created', user: userData },
287
+ { status: 201 }
288
+ );
289
+
290
+ } catch (error) {
291
+ console.error('Create user error:', error);
292
+ return NextResponse.json(
293
+ { error: 'Failed to create user' },
294
+ { status: 500 }
295
+ );
296
+ }
297
+ }
298
+
299
+ module.exports = { POST };
300
+ ```
301
+
302
+ ### Example 3: Get User
303
+
304
+ ```javascript
305
+ // api/getUser.js
306
+ const { NextResponse } = require('../modules/next-response');
307
+ const connectDB = require('../lib/db');
308
+ const User = require('../models/User');
309
+
310
+ async function GET(request) {
311
+ try {
312
+ await connectDB();
313
+
314
+ const { searchParams } = new URL(request.url);
315
+ const email = searchParams.get('email');
316
+ const id = searchParams.get('id');
317
+
318
+ if (email) {
319
+ const user = await User.findOne({ email });
320
+ if (!user) {
321
+ return NextResponse.json(
322
+ { error: 'User not found' },
323
+ { status: 404 }
324
+ );
325
+ }
326
+ return NextResponse.json(user);
327
+ }
328
+
329
+ if (id) {
330
+ const user = await User.findById(id);
331
+ if (!user) {
332
+ return NextResponse.json(
333
+ { error: 'User not found' },
334
+ { status: 404 }
335
+ );
336
+ }
337
+ return NextResponse.json(user);
338
+ }
339
+
340
+ return NextResponse.json(
341
+ { error: 'Email or ID required' },
342
+ { status: 400 }
343
+ );
344
+
345
+ } catch (error) {
346
+ console.error('Error:', error);
347
+ return NextResponse.json(
348
+ { error: 'Failed to fetch user' },
349
+ { status: 500 }
350
+ );
351
+ }
352
+ }
353
+
354
+ module.exports = { GET };
355
+ ```
356
+
357
+ ## Client-Side Usage
358
+
359
+ ### Basic Fetch
360
+
361
+ ```javascript
362
+ async function LoginUser(email, password) {
363
+ try {
364
+ const response = await fetch('/api/loginUser', {
365
+ method: 'POST',
366
+ headers: { 'Content-Type': 'application/json' },
367
+ body: JSON.stringify({ email, password })
368
+ });
369
+
370
+ const result = await response.json();
371
+
372
+ if (!response.ok) {
373
+ throw new Error(result.error);
374
+ }
375
+
376
+ return result;
377
+ } catch (error) {
378
+ console.error('Login failed:', error);
379
+ throw error;
380
+ }
381
+ }
382
+ ```
383
+
384
+ ### With React Hooks
385
+
386
+ ```javascript
387
+ function LoginForm() {
388
+ const [email, setEmail] = useState('');
389
+ const [password, setPassword] = useState('');
390
+ const [error, setError] = useState('');
391
+ const [loading, setLoading] = useState(false);
392
+
393
+ const handleLogin = async (e) => {
394
+ e.preventDefault();
395
+ setLoading(true);
396
+ setError('');
397
+
398
+ try {
399
+ const response = await fetch('/api/loginUser', {
400
+ method: 'POST',
401
+ headers: { 'Content-Type': 'application/json' },
402
+ body: JSON.stringify({ email, password })
403
+ });
404
+
405
+ const result = await response.json();
406
+
407
+ if (!response.ok) {
408
+ setError(result.error);
409
+ return;
410
+ }
411
+
412
+ // Success!
413
+ localStorage.setItem('user', JSON.stringify(result));
414
+ window.location.href = '/dashboard';
415
+
416
+ } catch (err) {
417
+ setError('Failed to login');
418
+ } finally {
419
+ setLoading(false);
420
+ }
421
+ };
422
+
423
+ return (
424
+ <form onSubmit={handleLogin}>
425
+ <input
426
+ type="email"
427
+ value={email}
428
+ onChange={(e) => setEmail(e.target.value)}
429
+ placeholder="Email"
430
+ />
431
+ <input
432
+ type="password"
433
+ value={password}
434
+ onChange={(e) => setPassword(e.target.value)}
435
+ placeholder="Password"
436
+ />
437
+ {error && <p style={{ color: 'red' }}>{error}</p>}
438
+ <button type="submit" disabled={loading}>
439
+ {loading ? 'Loading...' : 'Login'}
440
+ </button>
441
+ </form>
442
+ );
443
+ }
444
+ ```
445
+
446
+ ## Database Integration
447
+
448
+ ### Setup (MongoDB Example)
449
+
450
+ ```bash
451
+ npm install mongoose
452
+ ```
453
+
454
+ ```javascript
455
+ // lib/db.js
456
+ const mongoose = require('mongoose');
457
+
458
+ async function connectDB() {
459
+ if (mongoose.connections[0].readyState) {
460
+ return;
461
+ }
462
+
463
+ await mongoose.connect(process.env.MONGODB_URI);
464
+ console.log('✅ MongoDB connected');
465
+ }
466
+
467
+ module.exports = connectDB;
468
+ ```
469
+
470
+ ### Model (Mongoose Example)
471
+
472
+ ```javascript
473
+ // models/User.js
474
+ const mongoose = require('mongoose');
475
+
476
+ const userSchema = new mongoose.Schema({
477
+ name: { type: String, required: true },
478
+ email: { type: String, required: true, unique: true },
479
+ password: { type: String, required: true },
480
+ role: { type: String, enum: ['user', 'admin'], default: 'user' },
481
+ phone: String
482
+ }, { timestamps: true });
483
+
484
+ module.exports = mongoose.models.User || mongoose.model('User', userSchema);
485
+ ```
486
+
487
+ ## Environment Variables
488
+
489
+ ```bash
490
+ # .env.local
491
+ MONGODB_URI=mongodb://localhost:27017/myapp
492
+ DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
493
+ API_KEY=your_secret_key
494
+ ```
495
+
496
+ ```javascript
497
+ // Access in API routes
498
+ const dbUrl = process.env.MONGODB_URI;
499
+ const apiKey = process.env.API_KEY;
500
+ ```
501
+
502
+ ## Migration from Old Style
503
+
504
+ ### Old Style
505
+
506
+ ```javascript
507
+ export default async function handler(req, res) {
508
+ if (req.method === 'GET') {
509
+ return res.status(200).json({ data: 'value' });
510
+ }
511
+ }
512
+ ```
513
+
514
+ ### New Style
515
+
516
+ ```javascript
517
+ const { NextResponse } = require('../modules/next-response');
518
+
519
+ async function GET(request) {
520
+ return NextResponse.json({ data: 'value' });
521
+ }
522
+
523
+ module.exports = { GET };
524
+ ```
525
+
526
+ ## Summary
527
+
528
+ ✅ **Identical to Next.js App Router**
529
+ ✅ **NextResponse API**
530
+ ✅ **Named HTTP method exports**
531
+ ✅ **URL and search params**
532
+ ✅ **Request body parsing**
533
+ ✅ **Database integration ready**
534
+ ✅ **Easy migration path**
535
+
536
+ Write your APIs exactly like Next.js! 🎉
@@ -0,0 +1,67 @@
1
+ // Database connection helper
2
+ // This is a mock - replace with real database connection
3
+
4
+ let isConnected = false;
5
+
6
+ async function connectDB() {
7
+ if (isConnected) {
8
+ console.log('✅ Using existing database connection');
9
+ return;
10
+ }
11
+
12
+ try {
13
+ // In production, connect to real database here:
14
+ // await mongoose.connect(process.env.MONGODB_URI);
15
+ // or
16
+ // db = await new Database(process.env.DATABASE_URL);
17
+
18
+ console.log('✅ Database connected (mock)');
19
+ isConnected = true;
20
+ } catch (error) {
21
+ console.error('❌ Database connection failed:', error);
22
+ throw error;
23
+ }
24
+ }
25
+
26
+ module.exports = connectDB;
27
+
28
+ // Example usage with MongoDB:
29
+ /*
30
+ const mongoose = require('mongoose');
31
+
32
+ async function connectDB() {
33
+ if (mongoose.connections[0].readyState) {
34
+ return;
35
+ }
36
+
37
+ await mongoose.connect(process.env.MONGODB_URI, {
38
+ useNewUrlParser: true,
39
+ useUnifiedTopology: true,
40
+ });
41
+
42
+ console.log('✅ MongoDB connected');
43
+ }
44
+
45
+ module.exports = connectDB;
46
+ */
47
+
48
+ // Example usage with PostgreSQL:
49
+ /*
50
+ const { Pool } = require('pg');
51
+
52
+ const pool = new Pool({
53
+ connectionString: process.env.DATABASE_URL,
54
+ });
55
+
56
+ async function connectDB() {
57
+ try {
58
+ await pool.query('SELECT NOW()');
59
+ console.log('✅ PostgreSQL connected');
60
+ } catch (error) {
61
+ console.error('❌ PostgreSQL connection failed:', error);
62
+ throw error;
63
+ }
64
+ }
65
+
66
+ module.exports = connectDB;
67
+ */
@@ -0,0 +1,102 @@
1
+ // User Model
2
+ // This is a mock - replace with real database model
3
+
4
+ // Mock in-memory database
5
+ let users = [
6
+ { _id: '1', name: 'Aziz Ahmed', email: 'aziz@example.com', role: 'admin', phone: '123-456-7890' },
7
+ { _id: '2', name: 'John Doe', email: 'john@example.com', role: 'user', phone: '098-765-4321' }
8
+ ];
9
+
10
+ class User {
11
+ // Find one user
12
+ static async findOne(query) {
13
+ const user = users.find(u => {
14
+ return Object.keys(query).every(key => u[key] === query[key]);
15
+ });
16
+ return user || null;
17
+ }
18
+
19
+ // Find by ID
20
+ static async findById(id) {
21
+ return users.find(u => u._id === id) || null;
22
+ }
23
+
24
+ // Find all users
25
+ static async find(query = {}) {
26
+ if (Object.keys(query).length === 0) {
27
+ return users;
28
+ }
29
+ return users.filter(u => {
30
+ return Object.keys(query).every(key => u[key] === query[key]);
31
+ });
32
+ }
33
+
34
+ // Create new user
35
+ static async create(userData) {
36
+ const newUser = {
37
+ _id: String(users.length + 1),
38
+ ...userData,
39
+ createdAt: new Date().toISOString()
40
+ };
41
+ users.push(newUser);
42
+ return newUser;
43
+ }
44
+
45
+ // Update user
46
+ static async findByIdAndUpdate(id, updates) {
47
+ const index = users.findIndex(u => u._id === id);
48
+ if (index === -1) return null;
49
+
50
+ users[index] = { ...users[index], ...updates, updatedAt: new Date().toISOString() };
51
+ return users[index];
52
+ }
53
+
54
+ // Delete user
55
+ static async findByIdAndDelete(id) {
56
+ const index = users.findIndex(u => u._id === id);
57
+ if (index === -1) return null;
58
+
59
+ const deleted = users.splice(index, 1)[0];
60
+ return deleted;
61
+ }
62
+
63
+ // Select specific fields
64
+ select(fields) {
65
+ // This is a chainable method for field selection
66
+ // In real Mongoose, this would be: User.findOne().select('name email')
67
+ return this;
68
+ }
69
+ }
70
+
71
+ module.exports = User;
72
+
73
+ // Example usage with Mongoose:
74
+ /*
75
+ const mongoose = require('mongoose');
76
+
77
+ const userSchema = new mongoose.Schema({
78
+ name: {
79
+ type: String,
80
+ required: true
81
+ },
82
+ email: {
83
+ type: String,
84
+ required: true,
85
+ unique: true
86
+ },
87
+ password: {
88
+ type: String,
89
+ required: true
90
+ },
91
+ role: {
92
+ type: String,
93
+ enum: ['user', 'admin'],
94
+ default: 'user'
95
+ },
96
+ phone: String
97
+ }, {
98
+ timestamps: true
99
+ });
100
+
101
+ module.exports = mongoose.models.User || mongoose.model('User', userSchema);
102
+ */
@@ -0,0 +1,58 @@
1
+ // NextResponse - Next.js-compatible response helper
2
+ class NextResponse {
3
+ constructor(body, init = {}) {
4
+ this.body = body;
5
+ this.status = init.status || 200;
6
+ this.headers = new Map(Object.entries(init.headers || {}));
7
+ }
8
+
9
+ static json(data, init = {}) {
10
+ return new NextResponse(JSON.stringify(data), {
11
+ ...init,
12
+ headers: {
13
+ 'Content-Type': 'application/json',
14
+ ...(init.headers || {})
15
+ }
16
+ });
17
+ }
18
+
19
+ static text(text, init = {}) {
20
+ return new NextResponse(text, {
21
+ ...init,
22
+ headers: {
23
+ 'Content-Type': 'text/plain',
24
+ ...(init.headers || {})
25
+ }
26
+ });
27
+ }
28
+
29
+ static redirect(url, init = {}) {
30
+ return new NextResponse(null, {
31
+ ...init,
32
+ status: init.status || 307,
33
+ headers: {
34
+ 'Location': url,
35
+ ...(init.headers || {})
36
+ }
37
+ });
38
+ }
39
+
40
+ static error() {
41
+ return new NextResponse(JSON.stringify({ error: 'Internal Server Error' }), {
42
+ status: 500,
43
+ headers: {
44
+ 'Content-Type': 'application/json'
45
+ }
46
+ });
47
+ }
48
+ }
49
+
50
+ // Export for Node.js (server-side)
51
+ if (typeof module !== 'undefined' && module.exports) {
52
+ module.exports = { NextResponse };
53
+ }
54
+
55
+ // Export for browser (if needed)
56
+ if (typeof window !== 'undefined') {
57
+ window.NextResponse = NextResponse;
58
+ }
@@ -30,17 +30,34 @@ function loadApiRoutes() {
30
30
  // Clear require cache to allow hot reload
31
31
  delete require.cache[require.resolve(filePath)];
32
32
 
33
- // Load the API handler
33
+ // Load the API module
34
34
  const module = require(filePath);
35
35
 
36
- // Support both default export and module.exports
37
- const handler = module.default || module;
36
+ // Support both styles:
37
+ // 1. Default export function (old style)
38
+ // 2. Named exports: GET, POST, PUT, DELETE (new Next.js App Router style)
38
39
 
39
- if (typeof handler === 'function') {
40
- apiHandlers[routeName] = handler;
41
- console.log(` ✅ /api/${routeName}`);
40
+ if (module.GET || module.POST || module.PUT || module.DELETE || module.PATCH) {
41
+ // New style: Named exports
42
+ const methods = {};
43
+ if (module.GET) methods.GET = module.GET;
44
+ if (module.POST) methods.POST = module.POST;
45
+ if (module.PUT) methods.PUT = module.PUT;
46
+ if (module.DELETE) methods.DELETE = module.DELETE;
47
+ if (module.PATCH) methods.PATCH = module.PATCH;
48
+
49
+ apiHandlers[routeName] = methods;
50
+ console.log(` ✅ /api/${routeName} [${Object.keys(methods).join(', ')}]`);
42
51
  } else {
43
- console.log(` ⚠️ /api/${routeName} - No handler function exported`);
52
+ // Old style: Default export
53
+ const handler = module.default || module;
54
+
55
+ if (typeof handler === 'function') {
56
+ apiHandlers[routeName] = handler;
57
+ console.log(` ✅ /api/${routeName}`);
58
+ } else {
59
+ console.log(` ⚠️ /api/${routeName} - No handler function exported`);
60
+ }
44
61
  }
45
62
  } catch (error) {
46
63
  console.error(` ❌ /api/${routeName} - ${error.message}`);
@@ -49,6 +66,7 @@ function loadApiRoutes() {
49
66
 
50
67
  console.log('');
51
68
  }
69
+ }
52
70
 
53
71
  // Parse request body
54
72
  function parseBody(req) {
@@ -103,48 +121,91 @@ async function handleApiRequest(req, res) {
103
121
  const body = await parseBody(req);
104
122
  const query = parseQuery(req.url);
105
123
 
106
- // Create Next.js-like req/res objects
107
- const apiReq = {
108
- method: req.method,
109
- body: body,
110
- query: query,
111
- headers: req.headers,
112
- url: req.url
113
- };
114
-
115
- const apiRes = {
116
- statusCode: 200,
117
- headers: {},
118
- status(code) {
119
- this.statusCode = code;
120
- return this;
121
- },
122
- json(data) {
123
- res.writeHead(this.statusCode, {
124
+ // Check if handler is a function (old style) or object with HTTP methods (new style)
125
+ let result;
126
+
127
+ if (typeof handler === 'function') {
128
+ // Old style: default export function
129
+ const apiReq = {
130
+ method: req.method,
131
+ body: body,
132
+ query: query,
133
+ headers: req.headers,
134
+ url: req.url
135
+ };
136
+
137
+ const apiRes = {
138
+ statusCode: 200,
139
+ headers: {},
140
+ status(code) {
141
+ this.statusCode = code;
142
+ return this;
143
+ },
144
+ json(data) {
145
+ res.writeHead(this.statusCode, {
146
+ 'Content-Type': 'application/json',
147
+ 'Access-Control-Allow-Origin': '*',
148
+ ...this.headers
149
+ });
150
+ res.end(JSON.stringify(data));
151
+ return this;
152
+ },
153
+ send(data) {
154
+ res.writeHead(this.statusCode, {
155
+ 'Content-Type': 'text/plain',
156
+ 'Access-Control-Allow-Origin': '*',
157
+ ...this.headers
158
+ });
159
+ res.end(data);
160
+ return this;
161
+ },
162
+ setHeader(key, value) {
163
+ this.headers[key] = value;
164
+ return this;
165
+ }
166
+ };
167
+
168
+ await handler(apiReq, apiRes);
169
+ } else if (typeof handler === 'object') {
170
+ // New style: Named exports (GET, POST, PUT, DELETE)
171
+ const methodHandler = handler[req.method];
172
+
173
+ if (!methodHandler) {
174
+ res.writeHead(405, {
124
175
  'Content-Type': 'application/json',
125
- 'Access-Control-Allow-Origin': '*',
126
- ...this.headers
127
- });
128
- res.end(JSON.stringify(data));
129
- return this;
130
- },
131
- send(data) {
132
- res.writeHead(this.statusCode, {
133
- 'Content-Type': 'text/plain',
134
- 'Access-Control-Allow-Origin': '*',
135
- ...this.headers
176
+ 'Allow': Object.keys(handler).join(', ')
136
177
  });
137
- res.end(data);
138
- return this;
139
- },
140
- setHeader(key, value) {
141
- this.headers[key] = value;
142
- return this;
178
+ res.end(JSON.stringify({
179
+ error: 'Method not allowed',
180
+ allowedMethods: Object.keys(handler)
181
+ }));
182
+ return;
143
183
  }
144
- };
145
184
 
146
- // Call the handler
147
- await handler(apiReq, apiRes);
185
+ // Create Next.js-style request object
186
+ const request = {
187
+ method: req.method,
188
+ headers: req.headers,
189
+ url: `http://localhost:${PORT}${req.url}`,
190
+ json: async () => body,
191
+ text: async () => typeof body === 'string' ? body : JSON.stringify(body)
192
+ };
193
+
194
+ // Call the handler
195
+ result = await methodHandler(request);
196
+
197
+ // Handle NextResponse
198
+ if (result && result.body !== undefined) {
199
+ const statusCode = result.status || 200;
200
+ const headers = {
201
+ 'Access-Control-Allow-Origin': '*',
202
+ ...Object.fromEntries(result.headers || [])
203
+ };
204
+
205
+ res.writeHead(statusCode, headers);
206
+ res.end(result.body);
207
+ }
208
+ }
148
209
 
149
210
  } catch (error) {
150
211
  console.error(`❌ API Error on /api/${routeName}:`, error);