create-aziz-app 3.1.0 → 3.1.1

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": "3.1.0",
3
+ "version": "3.1.1",
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",
@@ -4,7 +4,7 @@ export default function Page() {
4
4
 
5
5
  return (
6
6
  <div style={{ padding: '40px 32px', maxWidth: '900px', margin: '0 auto' }}>
7
- <h1>Welcome Home 👋</h1>
7
+ <h1>Welcome to Aziz.js</h1>
8
8
 
9
9
  <div class="card">
10
10
  <h2>Counter</h2>
@@ -1,39 +0,0 @@
1
- // API Route: POST /api/contact (classic style — api/contact.js)
2
- //
3
- // Demonstrates validation, cookies, and NextResponse helpers.
4
-
5
- const { NextResponse } = require('../_framework/next-response');
6
-
7
- // In-memory store (replace with a real database in production)
8
- const messages = [];
9
-
10
- async function GET(request) {
11
- return NextResponse.json({ count: messages.length, messages });
12
- }
13
-
14
- async function POST(request) {
15
- let body;
16
- try {
17
- body = await request.json();
18
- } catch (err) {
19
- return NextResponse.json({ error: 'Invalid JSON body' }, { status: err.status || 400 });
20
- }
21
-
22
- const { name, email, message } = body;
23
-
24
- if (!name || !email || !message) {
25
- return NextResponse.json(
26
- { error: 'name, email and message are required' },
27
- { status: 400 }
28
- );
29
- }
30
-
31
- const entry = { name, email, message, at: new Date().toISOString() };
32
- messages.push(entry);
33
-
34
- const res = NextResponse.json({ message: `Thanks, ${name}! We received your message.`, entry }, { status: 201 });
35
- res.cookies.set('last_contact', name, { path: '/', maxAge: 60 * 60 });
36
- return res;
37
- }
38
-
39
- module.exports = { GET, POST };
@@ -1,69 +0,0 @@
1
- // API Route: /api/createUser
2
- // Next.js App Router style
3
-
4
- const { NextResponse } = require('../_framework/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 };
@@ -1,17 +0,0 @@
1
- // API Route: /api/hello
2
- // Next.js App Router style
3
-
4
- const { NextResponse } = require('../_framework/next-response');
5
-
6
- async function GET(request) {
7
- const { searchParams } = new URL(request.url);
8
- const name = searchParams.get('name') || 'World';
9
-
10
- return NextResponse.json({
11
- message: `Hello, ${name}!`,
12
- timestamp: new Date().toISOString(),
13
- method: request.method
14
- });
15
- }
16
-
17
- module.exports = { GET };
@@ -1,61 +0,0 @@
1
- // API Route: /api/loginUser
2
- // Next.js App Router style
3
-
4
- const { NextResponse } = require('../_framework/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 };
@@ -1,59 +0,0 @@
1
- // API Route: /api/users
2
- // Next.js App Router style
3
-
4
- const { NextResponse } = require('../_framework/next-response');
5
-
6
- let users = [
7
- { id: 1, name: 'Aziz Ahmed', email: 'aziz@example.com', createdAt: new Date().toISOString() },
8
- { id: 2, name: 'John Doe', email: 'john@example.com', createdAt: new Date().toISOString() },
9
- { id: 3, name: 'Jane Smith', email: 'jane@example.com', createdAt: new Date().toISOString() }
10
- ];
11
-
12
- async function GET(request) {
13
- const { searchParams } = new URL(request.url);
14
- const id = searchParams.get('id');
15
-
16
- if (id) {
17
- const user = users.find(u => u.id === parseInt(id));
18
- if (!user) return NextResponse.json({ error: 'User not found' }, { status: 404 });
19
- return NextResponse.json(user);
20
- }
21
-
22
- return NextResponse.json({ users, total: users.length });
23
- }
24
-
25
- async function POST(request) {
26
- const { name, email } = await request.json();
27
-
28
- if (!name || !email) {
29
- return NextResponse.json({ error: 'Name and email are required' }, { status: 400 });
30
- }
31
-
32
- if (users.find(u => u.email === email)) {
33
- return NextResponse.json({ error: 'Email already exists' }, { status: 409 });
34
- }
35
-
36
- const newUser = {
37
- id: Math.max(...users.map(u => u.id)) + 1,
38
- name, email,
39
- createdAt: new Date().toISOString()
40
- };
41
- users.push(newUser);
42
-
43
- return NextResponse.json({ message: 'User created', user: newUser }, { status: 201 });
44
- }
45
-
46
- async function DELETE(request) {
47
- const { searchParams } = new URL(request.url);
48
- const id = searchParams.get('id');
49
-
50
- if (!id) return NextResponse.json({ error: 'ID required' }, { status: 400 });
51
-
52
- const idx = users.findIndex(u => u.id === parseInt(id));
53
- if (idx === -1) return NextResponse.json({ error: 'User not found' }, { status: 404 });
54
-
55
- const deleted = users.splice(idx, 1)[0];
56
- return NextResponse.json({ message: 'User deleted', user: deleted });
57
- }
58
-
59
- module.exports = { GET, POST, DELETE };
@@ -1,41 +0,0 @@
1
- // About page — route: /about
2
- export default function Page() {
3
- return (
4
- <div style={{ padding: '40px 32px', maxWidth: '900px', margin: '0 auto' }}>
5
- <h1>About 📖</h1>
6
-
7
- <div class="card">
8
- <h2>What is Aziz.js?</h2>
9
- <p>
10
- A lightweight Next.js clone — file-based routing, React hooks,
11
- server-side API routes, and ES module imports. Zero dependencies.
12
- </p>
13
- </div>
14
-
15
- <div class="card">
16
- <h2>File Structure</h2>
17
- <pre style={{ background: '#282c34', color: '#61dafb', padding: '16px', borderRadius: '8px', fontSize: '13px' }}>
18
- {`app/
19
- layout.js ← root layout
20
- page.js ← /
21
- about/
22
- page.js ← /about
23
- blog/
24
- [slug]/
25
- page.js ← /blog/:slug
26
-
27
- api/
28
- users.js ← /api/users
29
-
30
- components/
31
- Navbar.js
32
- Footer.js`}
33
- </pre>
34
- </div>
35
-
36
- <button class="btn btn-primary" onClick={() => navigate('/')}>
37
- ← Back Home
38
- </button>
39
- </div>
40
- );
41
- }
@@ -1,31 +0,0 @@
1
- // Blog post page — route: /blog/:slug (dynamic segment)
2
- export default function BlogPost() {
3
- const { slug } = useParams();
4
- const search = useSearchParams();
5
- const from = search.get('from');
6
-
7
- return (
8
- <div style={{ padding: '40px 32px', maxWidth: '900px', margin: '0 auto' }}>
9
- <p style={{ color: '#888', marginBottom: '8px' }}>
10
- <a href="/blog/hello-world" onClick={(e) => { e.preventDefault(); navigate('/blog/hello-world'); }}>hello-world</a>
11
- {' · '}
12
- <a href="/blog/aziz-js" onClick={(e) => { e.preventDefault(); navigate('/blog/aziz-js'); }}>aziz-js</a>
13
- </p>
14
-
15
- <h1>Blog: {slug}</h1>
16
-
17
- <div class="card">
18
- <h2>Dynamic routing works!</h2>
19
- <p>
20
- This page is <code>app/blog/[slug]/page.js</code> and it matches any
21
- <code>/blog/&lt;anything&gt;</code> URL. The matched value is available
22
- through the <code>useParams()</code> hook.
23
- </p>
24
- <p><strong>useParams().slug</strong> = <code>{slug}</code></p>
25
- {from && <p><strong>?from=</strong> = <code>{from}</code></p>}
26
- </div>
27
-
28
- <button class="btn btn-primary" onClick={() => navigate('/')}>← Back Home</button>
29
- </div>
30
- );
31
- }
@@ -1,68 +0,0 @@
1
- // Contact page — route: /contact
2
- // Demonstrates the global `api` client calling a server route handler.
3
- export default function ContactPage() {
4
- const [name, setName] = useState('');
5
- const [email, setEmail] = useState('');
6
- const [message, setMessage] = useState('');
7
- const [status, setStatus] = useState(null); // { type, text }
8
- const [sending, setSending] = useState(false);
9
-
10
- const handleSubmit = async (e) => {
11
- e.preventDefault();
12
- setSending(true);
13
- setStatus(null);
14
- try {
15
- const res = await api.post('/api/contact', { name, email, message });
16
- setStatus({ type: 'ok', text: res.message || 'Message sent!' });
17
- setName(''); setEmail(''); setMessage('');
18
- } catch (err) {
19
- setStatus({ type: 'error', text: err.message || 'Something went wrong' });
20
- } finally {
21
- setSending(false);
22
- }
23
- };
24
-
25
- return (
26
- <div style={{ padding: '40px 32px', maxWidth: '640px', margin: '0 auto' }}>
27
- <h1>Contact 📬</h1>
28
-
29
- <div class="card">
30
- <h2>Send us a message</h2>
31
- <p>This form posts to <code>/api/contact</code> using the global <code>api</code> client.</p>
32
-
33
- <form onSubmit={handleSubmit} style={{ display: 'flex', flexDirection: 'column', gap: '12px', marginTop: '16px' }}>
34
- <input
35
- type="text"
36
- placeholder="Your name"
37
- value={name}
38
- onInput={(e) => setName(e.target.value)}
39
- required
40
- />
41
- <input
42
- type="email"
43
- placeholder="Your email"
44
- value={email}
45
- onInput={(e) => setEmail(e.target.value)}
46
- required
47
- />
48
- <textarea
49
- placeholder="Your message"
50
- value={message}
51
- onInput={(e) => setMessage(e.target.value)}
52
- rows={4}
53
- required
54
- />
55
- <button type="submit" class="btn btn-primary" disabled={sending}>
56
- {sending ? 'Sending…' : 'Send message'}
57
- </button>
58
- </form>
59
-
60
- {status && (
61
- <p style={{ marginTop: '12px', color: status.type === 'ok' ? '#1a7f37' : '#c0392b' }}>
62
- {status.text}
63
- </p>
64
- )}
65
- </div>
66
- </div>
67
- );
68
- }
@@ -1,15 +0,0 @@
1
- // Custom 404 page — rendered when no route matches (like Next.js app/not-found.js)
2
- export default function NotFound() {
3
- return (
4
- <div style={{ padding: '80px 24px', textAlign: 'center' }}>
5
- <h1 style={{ fontSize: '96px', margin: '0 0 8px', color: '#61dafb' }}>404</h1>
6
- <h2 style={{ margin: '0 0 16px' }}>Page not found</h2>
7
- <p style={{ color: '#888', marginBottom: '32px' }}>
8
- We couldn't find the page you were looking for.
9
- </p>
10
- <button class="btn btn-primary" onClick={() => navigate('/')}>
11
- ← Back to Home
12
- </button>
13
- </div>
14
- );
15
- }
@@ -1,52 +0,0 @@
1
- // Test page — route: /test
2
- export default function Page() {
3
- const [count, setCount] = useState(0);
4
- const [name, setName] = useState('');
5
- const [email, setEmail] = useState('');
6
-
7
- const handleSubmit = (e) => {
8
- e.preventDefault();
9
- alert(`Name: ${name}\nEmail: ${email}\nCount: ${count}`);
10
- };
11
-
12
- return (
13
- <div style={{ padding: '40px 32px', maxWidth: '900px', margin: '0 auto' }}>
14
- <h1>Test Page 🧪</h1>
15
-
16
- <div class="card">
17
- <h2>useState</h2>
18
- <div class="count-display">{count}</div>
19
- <div class="counter-actions">
20
- <button class="btn btn-primary" onClick={() => setCount(c => c + 1)}>+</button>
21
- <button class="btn btn-danger" onClick={() => setCount(0)}>Reset</button>
22
- </div>
23
- </div>
24
-
25
- <div class="card">
26
- <h2>Form</h2>
27
- <form onSubmit={handleSubmit}>
28
- <input
29
- type="text"
30
- placeholder="Your name"
31
- value={name}
32
- onInput={(e) => setName(e.target.value)}
33
- />
34
- <input
35
- type="email"
36
- placeholder="Your email"
37
- value={email}
38
- onInput={(e) => setEmail(e.target.value)}
39
- />
40
- <button type="submit" class="btn btn-primary">Submit</button>
41
- </form>
42
- </div>
43
-
44
- <div class="card">
45
- <h2>State</h2>
46
- <p>Name: <strong>{name || '—'}</strong></p>
47
- <p>Email: <strong>{email || '—'}</strong></p>
48
- <p>Count: <strong>{count}</strong></p>
49
- </div>
50
- </div>
51
- );
52
- }
@@ -1,7 +0,0 @@
1
- export default function Footer() {
2
- return (
3
- <footer>
4
- <p>Made with ⚡ Aziz.js</p>
5
- </footer>
6
- );
7
- }
@@ -1,28 +0,0 @@
1
- // navigate and useRouter are globals — no imports needed
2
- export default function Navbar() {
3
- const { pathname } = useRouter();
4
-
5
- const links = [
6
- { href: '/', label: 'Home' },
7
- { href: '/about', label: 'About' },
8
- { href: '/blog/hello-world', label: 'Blog' },
9
- { href: '/test', label: 'Test' },
10
- { href: '/contact', label: 'Contact' },
11
- ];
12
-
13
- return (
14
- <nav>
15
- <span class="brand" onClick={() => navigate('/')}>⚡ Aziz.js</span>
16
- {links.map(({ href, label }) =>
17
- <a
18
- key={href}
19
- href={href}
20
- class={pathname === href ? 'active' : ''}
21
- onClick={(e) => { e.preventDefault(); navigate(href); }}
22
- >
23
- {label}
24
- </a>
25
- )}
26
- </nav>
27
- );
28
- }
@@ -1,67 +0,0 @@
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
- */
@@ -1,102 +0,0 @@
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
- */