baraqex 1.0.70 → 1.0.72
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/dist/index.js +5 -1
- package/dist/index.js.map +3 -3
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +5 -1
- package/dist/server/index.js.map +3 -3
- package/package.json +1 -1
- package/templates/fullstack-template/package-lock.json +338 -5
- package/templates/fullstack-template/package.json +3 -2
- package/templates/fullstack-template/server.js +15 -1
- package/templates/fullstack-template/src/server.ts +5 -5
- package/templates/fullstack-template/vite.config.ts +56 -0
- package/templates/ssr-template/src/App.tsx +29 -20
- package/templates/fullstack-template/src/App.tsx +0 -271
- package/templates/fullstack-template/src/api/auth/login.ts +0 -75
- package/templates/fullstack-template/src/api/auth/me.ts +0 -66
- package/templates/fullstack-template/src/api/auth/register.ts +0 -59
- package/templates/fullstack-template/src/api/hello.js +0 -19
- package/templates/fullstack-template/src/api/todos/[id].ts +0 -108
- package/templates/fullstack-template/src/api/todos/index.ts +0 -79
- package/templates/fullstack-template/src/api/users.js +0 -39
- package/templates/fullstack-template/src/components/Dashboard.tsx +0 -129
- package/templates/fullstack-template/src/components/Header.tsx +0 -76
- package/templates/fullstack-template/src/contexts/ApiContext.tsx +0 -69
- package/templates/fullstack-template/src/contexts/AuthContext.tsx +0 -155
- package/templates/fullstack-template/src/pages/index.tsx +0 -200
- package/templates/fullstack-template/src/styles/App.css +0 -446
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { useState, useEffect, useRef, useMemo } from 'baraqex';
|
|
2
2
|
|
|
3
|
+
// JSX type declarations for TypeScript
|
|
4
|
+
declare global {
|
|
5
|
+
namespace JSX {
|
|
6
|
+
interface IntrinsicElements {
|
|
7
|
+
[elemName: string]: any;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
3
12
|
// Custom hooks for better code organization
|
|
4
13
|
function useTimer(initialTime = 0) {
|
|
5
14
|
const [time, setTime] = useState(initialTime);
|
|
@@ -10,7 +19,7 @@ function useTimer(initialTime = 0) {
|
|
|
10
19
|
if (!isRunning) {
|
|
11
20
|
setIsRunning(true);
|
|
12
21
|
intervalRef.current = setInterval(() => {
|
|
13
|
-
setTime((prev) => prev + 1);
|
|
22
|
+
setTime((prev: number) => prev + 1);
|
|
14
23
|
}, 1000);
|
|
15
24
|
}
|
|
16
25
|
};
|
|
@@ -50,10 +59,10 @@ function useTimer(initialTime = 0) {
|
|
|
50
59
|
function useCounter(initialValue = 0, step = 1) {
|
|
51
60
|
const [count, setCount] = useState(initialValue);
|
|
52
61
|
|
|
53
|
-
const increment = () => setCount((prev) => prev + step);
|
|
54
|
-
const decrement = () => setCount((prev) => prev - step);
|
|
62
|
+
const increment = () => setCount((prev: number) => prev + step);
|
|
63
|
+
const decrement = () => setCount((prev: number) => prev - step);
|
|
55
64
|
const reset = () => setCount(initialValue);
|
|
56
|
-
const setValue = (value) => setCount(typeof value === 'function' ? value : value);
|
|
65
|
+
const setValue = (value: any) => setCount(typeof value === 'function' ? value : value);
|
|
57
66
|
|
|
58
67
|
return { count, increment, decrement, reset, setValue };
|
|
59
68
|
}
|
|
@@ -67,10 +76,10 @@ function useTodos() {
|
|
|
67
76
|
]);
|
|
68
77
|
const [filter, setFilter] = useState('all');
|
|
69
78
|
|
|
70
|
-
const addTodo = (text) => {
|
|
79
|
+
const addTodo = (text: any) => {
|
|
71
80
|
const textString = String(text || '').trim();
|
|
72
81
|
if (textString) {
|
|
73
|
-
setTodos((prev) => [...prev, {
|
|
82
|
+
setTodos((prev: any) => [...prev, {
|
|
74
83
|
id: Date.now(),
|
|
75
84
|
text: textString,
|
|
76
85
|
completed: false
|
|
@@ -78,14 +87,14 @@ function useTodos() {
|
|
|
78
87
|
}
|
|
79
88
|
};
|
|
80
89
|
|
|
81
|
-
const toggleTodo = (id) => {
|
|
82
|
-
setTodos((prev) => prev.map((todo) =>
|
|
90
|
+
const toggleTodo = (id: any) => {
|
|
91
|
+
setTodos((prev: any[]) => prev.map((todo: { id: any; completed: any; }) =>
|
|
83
92
|
todo.id === id ? { ...todo, completed: !todo.completed } : todo
|
|
84
93
|
));
|
|
85
94
|
};
|
|
86
95
|
|
|
87
|
-
const deleteTodo = (id) => {
|
|
88
|
-
setTodos((prev) => prev.filter((todo) => todo.id !== id));
|
|
96
|
+
const deleteTodo = (id: any) => {
|
|
97
|
+
setTodos((prev: any[]) => prev.filter((todo: { id: any; }) => todo.id !== id));
|
|
89
98
|
};
|
|
90
99
|
|
|
91
100
|
const filteredTodos = useMemo(() => {
|
|
@@ -124,7 +133,7 @@ function useTheme() {
|
|
|
124
133
|
const [theme, setTheme] = useState('light');
|
|
125
134
|
|
|
126
135
|
const toggleTheme = () => {
|
|
127
|
-
setTheme((prev) => prev === 'light' ? 'dark' : 'light');
|
|
136
|
+
setTheme((prev: string) => prev === 'light' ? 'dark' : 'light');
|
|
128
137
|
};
|
|
129
138
|
|
|
130
139
|
const themeColors = useMemo(() => {
|
|
@@ -149,13 +158,13 @@ function useTheme() {
|
|
|
149
158
|
}
|
|
150
159
|
|
|
151
160
|
// Todo Item Component
|
|
152
|
-
function TodoItem({ todo, onToggle, onDelete }) {
|
|
153
|
-
const handleToggle = (e) => {
|
|
161
|
+
function TodoItem({ todo, onToggle, onDelete }: { todo: { id: number; text: string; completed: boolean; }; onToggle: (id: number) => void; onDelete: (id: number) => void; }) {
|
|
162
|
+
const handleToggle = (e: { preventDefault: () => void; }) => {
|
|
154
163
|
e.preventDefault();
|
|
155
164
|
onToggle(todo.id);
|
|
156
165
|
};
|
|
157
166
|
|
|
158
|
-
const handleDelete = (e) => {
|
|
167
|
+
const handleDelete = (e: { preventDefault: () => void; }) => {
|
|
159
168
|
e.preventDefault();
|
|
160
169
|
onDelete(todo.id);
|
|
161
170
|
};
|
|
@@ -199,7 +208,7 @@ function TodoItem({ todo, onToggle, onDelete }) {
|
|
|
199
208
|
}
|
|
200
209
|
|
|
201
210
|
// Stats Component
|
|
202
|
-
function StatsCard({ title, value, color = '#3498db' }) {
|
|
211
|
+
function StatsCard({ title, value, color = '#3498db' }: { title: string; value: string | number; color?: string }) {
|
|
203
212
|
return (
|
|
204
213
|
<div style={{
|
|
205
214
|
background: 'white',
|
|
@@ -244,7 +253,7 @@ export function App() {
|
|
|
244
253
|
const inputRef = useRef(null);
|
|
245
254
|
|
|
246
255
|
// Handle todo form submission
|
|
247
|
-
const handleTodoSubmit = (e) => {
|
|
256
|
+
const handleTodoSubmit = (e: { preventDefault: () => void; stopPropagation: () => void; }) => {
|
|
248
257
|
e.preventDefault();
|
|
249
258
|
e.stopPropagation();
|
|
250
259
|
|
|
@@ -262,15 +271,15 @@ export function App() {
|
|
|
262
271
|
}
|
|
263
272
|
};
|
|
264
273
|
|
|
265
|
-
const handleNewTodoChange = (e) => {
|
|
274
|
+
const handleNewTodoChange = (e: { target: { value: any; }; }) => {
|
|
266
275
|
setNewTodo(e.target.value);
|
|
267
276
|
};
|
|
268
277
|
|
|
269
|
-
const handleStepChange = (e) => {
|
|
278
|
+
const handleStepChange = (e: { target: { value: string; }; }) => {
|
|
270
279
|
setStep(parseInt(e.target.value) || 1);
|
|
271
280
|
};
|
|
272
281
|
|
|
273
|
-
const handleSetValue = (e) => {
|
|
282
|
+
const handleSetValue = (e: { key: string; target: { value: string; }; }) => {
|
|
274
283
|
if (e.key === 'Enter') {
|
|
275
284
|
const value = parseInt(e.target.value) || 0;
|
|
276
285
|
setValue(value);
|
|
@@ -738,7 +747,7 @@ export function App() {
|
|
|
738
747
|
'🎉 No completed todos yet!'}
|
|
739
748
|
</div>
|
|
740
749
|
) : (
|
|
741
|
-
todos.map((todo) => (
|
|
750
|
+
todos.map((todo: { id: any; }) => (
|
|
742
751
|
<TodoItem
|
|
743
752
|
key={todo.id}
|
|
744
753
|
todo={todo}
|
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
import { AuthProvider, useAuth } from './contexts/AuthContext';
|
|
2
|
-
import { ApiProvider } from './contexts/ApiContext';
|
|
3
|
-
import { Header } from './components/Header';
|
|
4
|
-
import { Dashboard } from './components/Dashboard';
|
|
5
|
-
import { LoginForm } from './components/LoginForm';
|
|
6
|
-
import { TodoList } from './components/TodoList';
|
|
7
|
-
import { UserProfile } from './components/UserProfile';
|
|
8
|
-
import { LoadingSpinner } from './components/LoadingSpinner';
|
|
9
|
-
import './styles/App.css';
|
|
10
|
-
import { useState, useEffect } from 'baraqex';
|
|
11
|
-
|
|
12
|
-
interface User {
|
|
13
|
-
id: number;
|
|
14
|
-
name: string;
|
|
15
|
-
email: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
type View = 'dashboard' | 'todos' | 'profile' | 'login';
|
|
19
|
-
|
|
20
|
-
function AppContent() {
|
|
21
|
-
const { user, loading: authLoading } = useAuth();
|
|
22
|
-
const [currentView, setCurrentView] = useState<View>('dashboard');
|
|
23
|
-
const [loading, setLoading] = useState(true);
|
|
24
|
-
const [users, setUsers] = useState<User[]>([]);
|
|
25
|
-
const [newUser, setNewUser] = useState({ name: '', email: '' });
|
|
26
|
-
const [userLoading, setUserLoading] = useState(false);
|
|
27
|
-
|
|
28
|
-
useEffect(() => {
|
|
29
|
-
// Simulate app initialization
|
|
30
|
-
const timer = setTimeout(() => {
|
|
31
|
-
setLoading(false);
|
|
32
|
-
}, 1000);
|
|
33
|
-
|
|
34
|
-
return () => clearTimeout(timer);
|
|
35
|
-
}, []);
|
|
36
|
-
|
|
37
|
-
useEffect(() => {
|
|
38
|
-
fetchUsers();
|
|
39
|
-
}, []);
|
|
40
|
-
|
|
41
|
-
const fetchUsers = async () => {
|
|
42
|
-
try {
|
|
43
|
-
const response = await fetch('/api/users');
|
|
44
|
-
const data = await response.json();
|
|
45
|
-
if (data.success) {
|
|
46
|
-
setUsers(data.users);
|
|
47
|
-
}
|
|
48
|
-
} catch (error) {
|
|
49
|
-
console.error('Error fetching users:', error);
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const handleSubmit = async (e: React.FormEvent) => {
|
|
54
|
-
e.preventDefault();
|
|
55
|
-
setUserLoading(true);
|
|
56
|
-
|
|
57
|
-
try {
|
|
58
|
-
const response = await fetch('/api/users', {
|
|
59
|
-
method: 'POST',
|
|
60
|
-
headers: {
|
|
61
|
-
'Content-Type': 'application/json',
|
|
62
|
-
},
|
|
63
|
-
body: JSON.stringify(newUser),
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
const data = await response.json();
|
|
67
|
-
|
|
68
|
-
if (data.success) {
|
|
69
|
-
setUsers([...users, data.user]);
|
|
70
|
-
setNewUser({ name: '', email: '' });
|
|
71
|
-
} else {
|
|
72
|
-
alert('Error: ' + data.error);
|
|
73
|
-
}
|
|
74
|
-
} catch (error) {
|
|
75
|
-
console.error('Error creating user:', error);
|
|
76
|
-
alert('Error creating user');
|
|
77
|
-
} finally {
|
|
78
|
-
setUserLoading(false);
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
if (loading || authLoading) {
|
|
83
|
-
return <LoadingSpinner message="Loading application..." />;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (!user) {
|
|
87
|
-
return (
|
|
88
|
-
<div className="app">
|
|
89
|
-
<Header
|
|
90
|
-
user={null}
|
|
91
|
-
onNavigate={setCurrentView}
|
|
92
|
-
currentView={currentView}
|
|
93
|
-
/>
|
|
94
|
-
<main className="main-content">
|
|
95
|
-
<LoginForm />
|
|
96
|
-
</main>
|
|
97
|
-
</div>
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const renderView = () => {
|
|
102
|
-
switch (currentView) {
|
|
103
|
-
case 'dashboard':
|
|
104
|
-
return <Dashboard />;
|
|
105
|
-
case 'todos':
|
|
106
|
-
return <TodoList />;
|
|
107
|
-
case 'profile':
|
|
108
|
-
return <UserProfile />;
|
|
109
|
-
default:
|
|
110
|
-
return <Dashboard />;
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
return (
|
|
115
|
-
<div className="app">
|
|
116
|
-
<Header
|
|
117
|
-
user={user}
|
|
118
|
-
onNavigate={setCurrentView}
|
|
119
|
-
currentView={currentView}
|
|
120
|
-
/>
|
|
121
|
-
<main className="main-content">
|
|
122
|
-
{renderView()}
|
|
123
|
-
</main>
|
|
124
|
-
<footer className="app-footer">
|
|
125
|
-
<p>© 2024 Fullstack Baraqex App. Built with ❤️ using Baraqex Framework.</p>
|
|
126
|
-
</footer>
|
|
127
|
-
|
|
128
|
-
{/* Add User Form */}
|
|
129
|
-
<div style={{
|
|
130
|
-
background: '#f5f5f5',
|
|
131
|
-
padding: '20px',
|
|
132
|
-
borderRadius: '8px',
|
|
133
|
-
marginBottom: '30px'
|
|
134
|
-
}}>
|
|
135
|
-
<h2 style={{ marginTop: '0', color: '#333' }}>Add New User</h2>
|
|
136
|
-
<form onSubmit={handleSubmit}>
|
|
137
|
-
<div style={{ marginBottom: '15px' }}>
|
|
138
|
-
<input
|
|
139
|
-
type="text"
|
|
140
|
-
placeholder="Name"
|
|
141
|
-
value={newUser.name}
|
|
142
|
-
onChange={(e) => setNewUser({ ...newUser, name: e.target.value })}
|
|
143
|
-
style={{
|
|
144
|
-
width: '100%',
|
|
145
|
-
padding: '10px',
|
|
146
|
-
border: '1px solid #ddd',
|
|
147
|
-
borderRadius: '4px',
|
|
148
|
-
fontSize: '14px'
|
|
149
|
-
}}
|
|
150
|
-
required
|
|
151
|
-
/>
|
|
152
|
-
</div>
|
|
153
|
-
<div style={{ marginBottom: '15px' }}>
|
|
154
|
-
<input
|
|
155
|
-
type="email"
|
|
156
|
-
placeholder="Email"
|
|
157
|
-
value={newUser.email}
|
|
158
|
-
onChange={(e) => setNewUser({ ...newUser, email: e.target.value })}
|
|
159
|
-
style={{
|
|
160
|
-
width: '100%',
|
|
161
|
-
padding: '10px',
|
|
162
|
-
border: '1px solid #ddd',
|
|
163
|
-
borderRadius: '4px',
|
|
164
|
-
fontSize: '14px'
|
|
165
|
-
}}
|
|
166
|
-
required
|
|
167
|
-
/>
|
|
168
|
-
</div>
|
|
169
|
-
<button
|
|
170
|
-
type="submit"
|
|
171
|
-
disabled={userLoading}
|
|
172
|
-
style={{
|
|
173
|
-
background: userLoading ? '#ccc' : '#007bff',
|
|
174
|
-
color: 'white',
|
|
175
|
-
border: 'none',
|
|
176
|
-
padding: '10px 20px',
|
|
177
|
-
borderRadius: '4px',
|
|
178
|
-
cursor: userLoading ? 'not-allowed' : 'pointer',
|
|
179
|
-
fontSize: '14px'
|
|
180
|
-
}}
|
|
181
|
-
>
|
|
182
|
-
{userLoading ? 'Adding...' : 'Add User'}
|
|
183
|
-
</button>
|
|
184
|
-
</form>
|
|
185
|
-
</div>
|
|
186
|
-
|
|
187
|
-
{/* Users List */}
|
|
188
|
-
<div>
|
|
189
|
-
<h2 style={{ color: '#333' }}>Users ({users.length})</h2>
|
|
190
|
-
{users.length === 0 ? (
|
|
191
|
-
<p style={{ color: '#666', fontStyle: 'italic' }}>
|
|
192
|
-
No users found. Add some users using the form above!
|
|
193
|
-
</p>
|
|
194
|
-
) : (
|
|
195
|
-
<div style={{ display: 'grid', gap: '10px' }}>
|
|
196
|
-
{users.map((user) => (
|
|
197
|
-
<div
|
|
198
|
-
key={user.id}
|
|
199
|
-
style={{
|
|
200
|
-
background: 'white',
|
|
201
|
-
border: '1px solid #ddd',
|
|
202
|
-
borderRadius: '6px',
|
|
203
|
-
padding: '15px',
|
|
204
|
-
display: 'flex',
|
|
205
|
-
justifyContent: 'space-between',
|
|
206
|
-
alignItems: 'center'
|
|
207
|
-
}}
|
|
208
|
-
>
|
|
209
|
-
<div>
|
|
210
|
-
<strong style={{ color: '#333' }}>{user.name}</strong>
|
|
211
|
-
<br />
|
|
212
|
-
<span style={{ color: '#666', fontSize: '14px' }}>{user.email}</span>
|
|
213
|
-
</div>
|
|
214
|
-
<div style={{
|
|
215
|
-
background: '#28a745',
|
|
216
|
-
color: 'white',
|
|
217
|
-
padding: '4px 8px',
|
|
218
|
-
borderRadius: '4px',
|
|
219
|
-
fontSize: '12px'
|
|
220
|
-
}}>
|
|
221
|
-
ID: {user.id}
|
|
222
|
-
</div>
|
|
223
|
-
</div>
|
|
224
|
-
))}
|
|
225
|
-
</div>
|
|
226
|
-
)}
|
|
227
|
-
</div>
|
|
228
|
-
|
|
229
|
-
{/* API Info */}
|
|
230
|
-
<div style={{
|
|
231
|
-
marginTop: '40px',
|
|
232
|
-
padding: '20px',
|
|
233
|
-
background: '#e7f3ff',
|
|
234
|
-
borderRadius: '8px'
|
|
235
|
-
}}>
|
|
236
|
-
<h3 style={{ marginTop: '0', color: '#0066cc' }}>🔗 API Endpoints</h3>
|
|
237
|
-
<ul style={{ color: '#333' }}>
|
|
238
|
-
<li><code>GET /api/users</code> - Fetch all users</li>
|
|
239
|
-
<li><code>POST /api/users</code> - Create a new user</li>
|
|
240
|
-
<li><code>GET /api/hello</code> - Simple hello endpoint</li>
|
|
241
|
-
</ul>
|
|
242
|
-
<p style={{ color: '#666', fontSize: '14px', marginBottom: '0' }}>
|
|
243
|
-
Try visiting <a href="/api/users" target="_blank">/api/users</a> or <a href="/api/hello" target="_blank">/api/hello</a> to see the API responses.
|
|
244
|
-
</p>
|
|
245
|
-
</div>
|
|
246
|
-
</div>
|
|
247
|
-
);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
export default function App() {
|
|
251
|
-
return (
|
|
252
|
-
<AuthProvider>
|
|
253
|
-
<ApiProvider>
|
|
254
|
-
<AppContent />
|
|
255
|
-
</ApiProvider>
|
|
256
|
-
</AuthProvider>
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
// SSR support
|
|
261
|
-
App.getTitle = () => "Fullstack Baraqex App";
|
|
262
|
-
App.getDescription = () => "A complete fullstack application with authentication, API integration, and modern UI";
|
|
263
|
-
App.getMeta = () => ({
|
|
264
|
-
'og:title': 'Fullstack Baraqex App',
|
|
265
|
-
'og:description': 'Complete fullstack solution with Baraqex',
|
|
266
|
-
'og:type': 'website'
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
// Page metadata for SEO
|
|
270
|
-
App.title = 'Baraqex Fullstack Demo';
|
|
271
|
-
App.description = 'A demonstration of Baraqex fullstack capabilities with SSR and API integration';
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { AuthService, sendSuccess, sendError, validateFields } from 'baraqex';
|
|
2
|
-
|
|
3
|
-
// Login endpoint
|
|
4
|
-
export async function post(req: any, res: any) {
|
|
5
|
-
try {
|
|
6
|
-
// Validate required fields
|
|
7
|
-
const validation = validateFields(req, ['username', 'password']);
|
|
8
|
-
if (!validation.valid) {
|
|
9
|
-
return sendError(res, 'Missing required fields', 400, { missing: validation.missing });
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const { username, password } = req.body;
|
|
13
|
-
|
|
14
|
-
// Get auth service from server
|
|
15
|
-
const authService = req.app.locals.authService as AuthService;
|
|
16
|
-
if (!authService) {
|
|
17
|
-
return sendError(res, 'Authentication service not available', 500);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// In a real app, you'd fetch user from database
|
|
21
|
-
// This is a demo implementation
|
|
22
|
-
const demoUsers = [
|
|
23
|
-
{
|
|
24
|
-
id: 1,
|
|
25
|
-
username: 'admin',
|
|
26
|
-
password: '$2a$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
|
|
27
|
-
email: 'admin@example.com',
|
|
28
|
-
roles: ['admin', 'user'],
|
|
29
|
-
name: 'Administrator'
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
id: 2,
|
|
33
|
-
username: 'user',
|
|
34
|
-
password: '$2a$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
|
|
35
|
-
email: 'user@example.com',
|
|
36
|
-
roles: ['user'],
|
|
37
|
-
name: 'Regular User'
|
|
38
|
-
}
|
|
39
|
-
];
|
|
40
|
-
|
|
41
|
-
// Find user
|
|
42
|
-
const user = demoUsers.find(u => u.username === username);
|
|
43
|
-
if (!user) {
|
|
44
|
-
return sendError(res, 'Invalid credentials', 401);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Verify password
|
|
48
|
-
const isValid = await authService.comparePasswords(password, user.password);
|
|
49
|
-
if (!isValid) {
|
|
50
|
-
return sendError(res, 'Invalid credentials', 401);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Generate token
|
|
54
|
-
const userForToken = {
|
|
55
|
-
id: user.id,
|
|
56
|
-
username: user.username,
|
|
57
|
-
email: user.email,
|
|
58
|
-
roles: user.roles,
|
|
59
|
-
name: user.name
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
const token = authService.generateToken(userForToken);
|
|
63
|
-
|
|
64
|
-
// Send response
|
|
65
|
-
return sendSuccess(res, {
|
|
66
|
-
token,
|
|
67
|
-
user: userForToken,
|
|
68
|
-
expiresIn: '7d'
|
|
69
|
-
}, 'Login successful');
|
|
70
|
-
|
|
71
|
-
} catch (error: any) {
|
|
72
|
-
console.error('Login error:', error);
|
|
73
|
-
return sendError(res, 'Login failed', 500);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { sendSuccess, sendError } from 'baraqex';
|
|
2
|
-
|
|
3
|
-
// Middleware to require authentication
|
|
4
|
-
export const middleware = [
|
|
5
|
-
(req: any, res: any, next: any) => {
|
|
6
|
-
if (!req.user) {
|
|
7
|
-
return sendError(res, 'Authentication required', 401);
|
|
8
|
-
}
|
|
9
|
-
next();
|
|
10
|
-
}
|
|
11
|
-
];
|
|
12
|
-
|
|
13
|
-
// Get current user endpoint
|
|
14
|
-
export async function get(req: any, res: any) {
|
|
15
|
-
try {
|
|
16
|
-
const user = req.user;
|
|
17
|
-
|
|
18
|
-
// In a real app, you might fetch fresh user data from database
|
|
19
|
-
// For demo, we'll just return the user from token
|
|
20
|
-
|
|
21
|
-
return sendSuccess(res, {
|
|
22
|
-
user: {
|
|
23
|
-
id: user.id,
|
|
24
|
-
username: user.username,
|
|
25
|
-
email: user.email || `${user.username}@example.com`,
|
|
26
|
-
name: user.name || user.username,
|
|
27
|
-
roles: user.roles || ['user'],
|
|
28
|
-
lastLogin: new Date().toISOString()
|
|
29
|
-
}
|
|
30
|
-
}, 'User profile retrieved');
|
|
31
|
-
|
|
32
|
-
} catch (error: any) {
|
|
33
|
-
console.error('Get user error:', error);
|
|
34
|
-
return sendError(res, 'Failed to get user profile', 500);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Update user profile
|
|
39
|
-
export async function put(req: any, res: any) {
|
|
40
|
-
try {
|
|
41
|
-
const user = req.user;
|
|
42
|
-
const { name, email } = req.body;
|
|
43
|
-
|
|
44
|
-
// Basic validation
|
|
45
|
-
if (email && !email.includes('@')) {
|
|
46
|
-
return sendError(res, 'Invalid email format', 400);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// In a real app, you'd update the database
|
|
50
|
-
// For demo, we'll just return updated user data
|
|
51
|
-
const updatedUser = {
|
|
52
|
-
...user,
|
|
53
|
-
name: name || user.name,
|
|
54
|
-
email: email || user.email,
|
|
55
|
-
updatedAt: new Date().toISOString()
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
return sendSuccess(res, {
|
|
59
|
-
user: updatedUser
|
|
60
|
-
}, 'Profile updated successfully');
|
|
61
|
-
|
|
62
|
-
} catch (error: any) {
|
|
63
|
-
console.error('Update user error:', error);
|
|
64
|
-
return sendError(res, 'Failed to update profile', 500);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { AuthService, sendSuccess, sendError, validateFields } from 'baraqex';
|
|
2
|
-
|
|
3
|
-
// Registration endpoint
|
|
4
|
-
export async function post(req: any, res: any) {
|
|
5
|
-
try {
|
|
6
|
-
// Validate required fields
|
|
7
|
-
const validation = validateFields(req, ['username', 'password', 'email', 'name']);
|
|
8
|
-
if (!validation.valid) {
|
|
9
|
-
return sendError(res, 'Missing required fields', 400, { missing: validation.missing });
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const { username, password, email, name } = req.body;
|
|
13
|
-
|
|
14
|
-
// Basic validation
|
|
15
|
-
if (password.length < 6) {
|
|
16
|
-
return sendError(res, 'Password must be at least 6 characters long', 400);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
if (!email.includes('@')) {
|
|
20
|
-
return sendError(res, 'Invalid email format', 400);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Get auth service
|
|
24
|
-
const authService = req.app.locals.authService as AuthService;
|
|
25
|
-
if (!authService) {
|
|
26
|
-
return sendError(res, 'Authentication service not available', 500);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// In a real app, you'd check if user exists in database
|
|
30
|
-
// For demo purposes, we'll just simulate registration
|
|
31
|
-
|
|
32
|
-
// Hash password
|
|
33
|
-
const hashedPassword = await authService.hashPassword(password);
|
|
34
|
-
|
|
35
|
-
// Create user object (in real app, save to database)
|
|
36
|
-
const newUser = {
|
|
37
|
-
id: Date.now(), // In real app, this would be from database
|
|
38
|
-
username,
|
|
39
|
-
email,
|
|
40
|
-
name,
|
|
41
|
-
roles: ['user'],
|
|
42
|
-
createdAt: new Date().toISOString()
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
// Generate token
|
|
46
|
-
const token = authService.generateToken(newUser);
|
|
47
|
-
|
|
48
|
-
// Send response
|
|
49
|
-
return sendSuccess(res, {
|
|
50
|
-
token,
|
|
51
|
-
user: newUser,
|
|
52
|
-
expiresIn: '7d'
|
|
53
|
-
}, 'Registration successful');
|
|
54
|
-
|
|
55
|
-
} catch (error: any) {
|
|
56
|
-
console.error('Registration error:', error);
|
|
57
|
-
return sendError(res, 'Registration failed', 500);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
// Example API route: GET /api/hello
|
|
2
|
-
export async function get(req, res) {
|
|
3
|
-
res.json({
|
|
4
|
-
message: 'Hello from Baraqex API!',
|
|
5
|
-
timestamp: new Date().toISOString(),
|
|
6
|
-
method: 'GET'
|
|
7
|
-
});
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
// POST /api/hello
|
|
11
|
-
export async function post(req, res) {
|
|
12
|
-
const { name } = req.body;
|
|
13
|
-
res.json({
|
|
14
|
-
message: `Hello ${name || 'World'}!`,
|
|
15
|
-
timestamp: new Date().toISOString(),
|
|
16
|
-
method: 'POST',
|
|
17
|
-
body: req.body
|
|
18
|
-
});
|
|
19
|
-
}
|