baraqex 1.0.64 → 1.0.66

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 (97) hide show
  1. package/bin/baraqex.js +1013 -1126
  2. package/dist/api/hello.d.ts +3 -0
  3. package/dist/api/hello.d.ts.map +1 -0
  4. package/dist/api/users/[id].d.ts +5 -0
  5. package/dist/api/users/[id].d.ts.map +1 -0
  6. package/dist/browser.d.ts +40 -0
  7. package/dist/browser.d.ts.map +1 -0
  8. package/dist/browser.js +407 -1
  9. package/dist/browser.js.map +4 -4
  10. package/dist/browser.package.json +4 -0
  11. package/dist/forms/index.d.ts +2 -0
  12. package/dist/forms/index.d.ts.map +1 -0
  13. package/dist/forms/types.d.ts +2 -0
  14. package/dist/forms/types.d.ts.map +1 -0
  15. package/dist/frontend/components/WasmLoader.d.ts +2 -0
  16. package/dist/frontend/components/WasmLoader.d.ts.map +1 -0
  17. package/dist/frontend/hooks/useWasm.d.ts +2 -0
  18. package/dist/frontend/hooks/useWasm.d.ts.map +1 -0
  19. package/dist/frontend/index.d.ts +2 -0
  20. package/dist/frontend/index.d.ts.map +1 -0
  21. package/dist/index.d.ts +38 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +678 -317
  24. package/dist/index.js.map +4 -4
  25. package/dist/renderComponent.d.ts +9 -0
  26. package/dist/renderComponent.d.ts.map +1 -0
  27. package/dist/router/index.d.ts +2 -0
  28. package/dist/router/index.d.ts.map +1 -0
  29. package/dist/router/types.d.ts +2 -0
  30. package/dist/router/types.d.ts.map +1 -0
  31. package/dist/server/api-router.d.ts +16 -0
  32. package/dist/server/api-router.d.ts.map +1 -0
  33. package/dist/server/auth.d.ts +25 -0
  34. package/dist/server/auth.d.ts.map +1 -0
  35. package/dist/server/database.d.ts +22 -0
  36. package/dist/server/database.d.ts.map +1 -0
  37. package/dist/server/index.d.ts +116 -0
  38. package/dist/server/index.d.ts.map +1 -0
  39. package/dist/{server.js → server/index.js} +120 -23
  40. package/dist/server/index.js.map +7 -0
  41. package/dist/server/middleware.d.ts +11 -0
  42. package/dist/server/middleware.d.ts.map +1 -0
  43. package/dist/server/package.json +4 -0
  44. package/dist/server/templates.d.ts +31 -0
  45. package/dist/server/templates.d.ts.map +1 -0
  46. package/dist/server/types.d.ts +69 -0
  47. package/dist/server/types.d.ts.map +1 -0
  48. package/dist/server/utils.d.ts +70 -0
  49. package/dist/server/utils.d.ts.map +1 -0
  50. package/dist/server/wasm.d.ts +29 -0
  51. package/dist/server/wasm.d.ts.map +1 -0
  52. package/dist/server-renderer.d.ts +5 -0
  53. package/dist/server-renderer.d.ts.map +1 -0
  54. package/dist/store/index.d.ts +2 -0
  55. package/dist/store/index.d.ts.map +1 -0
  56. package/dist/store/types.d.ts +2 -0
  57. package/dist/store/types.d.ts.map +1 -0
  58. package/dist/wasm.d.ts +51 -0
  59. package/dist/wasm.d.ts.map +1 -0
  60. package/package.json +65 -56
  61. package/templates/basic-app/src/main.tsx +1 -0
  62. package/templates/fullstack-template/.env.example +42 -0
  63. package/templates/fullstack-template/README.md +38 -42
  64. package/templates/fullstack-template/package-lock.json +7932 -0
  65. package/templates/fullstack-template/package.json +58 -6
  66. package/templates/fullstack-template/server.js +28 -9
  67. package/templates/fullstack-template/src/App.tsx +94 -0
  68. package/templates/fullstack-template/src/api/auth/login.ts +75 -0
  69. package/templates/fullstack-template/src/api/auth/me.ts +66 -0
  70. package/templates/fullstack-template/src/api/auth/register.ts +59 -0
  71. package/templates/fullstack-template/src/api/todos/[id].ts +108 -0
  72. package/templates/fullstack-template/src/api/todos/index.ts +79 -0
  73. package/templates/fullstack-template/src/components/Dashboard.tsx +129 -0
  74. package/templates/fullstack-template/src/components/Header.tsx +76 -0
  75. package/templates/fullstack-template/src/contexts/ApiContext.tsx +69 -0
  76. package/templates/fullstack-template/src/contexts/AuthContext.tsx +155 -0
  77. package/templates/fullstack-template/src/server.ts +167 -0
  78. package/templates/fullstack-template/src/styles/App.css +446 -0
  79. package/templates/ssr-template/package-lock.json +337 -60
  80. package/templates/ssr-template/package.json +1 -1
  81. package/templates/ssr-template/src/App.tsx +2 -2
  82. package/templates/wasm/App.tsx +564 -0
  83. package/templates/wasm/client.tsx +220 -0
  84. package/templates/wasm/index.tsx +21 -0
  85. package/templates/wasm/package-lock.json +5347 -5307
  86. package/templates/wasm/package.json +43 -25
  87. package/templates/wasm/public/example.wasm +0 -0
  88. package/templates/wasm/public/wasm_exec.js +1 -12
  89. package/templates/wasm/server.ts +145 -0
  90. package/templates/wasm/vite.config.ts +42 -24
  91. package/README_WASM.md +0 -472
  92. package/dist/server.js.map +0 -7
  93. package/templates/basic-app/src/App.jsx +0 -0
  94. package/templates/basic-app/src/App.tsx +0 -0
  95. package/templates/fullstack-template/src/api/hello.js +0 -17
  96. package/templates/fullstack-template/src/pages/index.js +0 -206
  97. /package/templates/{basic-app/server.js → wasm/go/wasm_exec.js} +0 -0
@@ -1,14 +1,66 @@
1
1
  {
2
- "name": "fullstack-app",
3
- "version": "1.0.0",
2
+ "name": "fullstack-baraqex-app",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "description": "A fullstack application built with Baraqex",
4
6
  "type": "module",
5
7
  "scripts": {
6
8
  "dev": "node server.js",
7
- "start": "node server.js",
8
- "build": "echo \"No build step required\""
9
+ "build": "npm run build:client && npm run build:server",
10
+ "build:client": "esbuild src/client.tsx --bundle --outfile=dist/client.js --format=esm --target=es2020 --platform=browser --external:express --external:path --external:fs --external:http",
11
+ "build:server": "esbuild src/server.ts --bundle --outfile=dist/server.js --platform=node --target=node16 --format=esm --external:express --external:cors --external:jsonwebtoken --external:bcryptjs --external:mongodb --external:mysql2 --external:pg --sourcemap",
12
+ "start": "NODE_ENV=production node dist/server.js",
13
+ "test": "jest",
14
+ "lint": "eslint src --ext .ts,.tsx,.js,.jsx",
15
+ "format": "prettier --write src/**/*.{ts,tsx,js,jsx,json,css,md}",
16
+ "db:migrate": "node scripts/migrate.js",
17
+ "db:seed": "node scripts/seed.js"
9
18
  },
10
19
  "dependencies": {
20
+ "baraqex": "^1.0.60",
21
+ "bcryptjs": "^2.4.3",
22
+ "compression": "^1.7.4",
23
+ "cors": "^2.8.5",
24
+ "dotenv": "^16.3.1",
25
+ "express": "^4.18.2",
26
+ "express-rate-limit": "^6.10.0",
11
27
  "frontend-hamroun": "latest",
12
- "baraqex": "latest"
13
- }
28
+ "helmet": "^7.0.0",
29
+ "jsonwebtoken": "^9.0.2",
30
+ "morgan": "^1.10.0",
31
+ "multer": "latest"
32
+ },
33
+ "devDependencies": {
34
+ "@types/bcryptjs": "^2.4.2",
35
+ "@types/compression": "^1.7.2",
36
+ "@types/cors": "^2.8.13",
37
+ "@types/express": "^4.17.17",
38
+ "@types/jest": "^29.5.4",
39
+ "@types/jsonwebtoken": "^9.0.2",
40
+ "@types/morgan": "^1.9.4",
41
+ "@types/multer": "^1.4.7",
42
+ "@types/node": "^20.5.0",
43
+ "esbuild": "^0.19.0",
44
+ "eslint": "^8.47.0",
45
+ "jest": "^29.6.0",
46
+ "nodemon": "^3.0.1",
47
+ "prettier": "^3.0.0",
48
+ "typescript": "^5.0.0"
49
+ },
50
+ "optionalDependencies": {
51
+ "mongodb": "^5.7.0",
52
+ "mysql2": "^3.6.0",
53
+ "pg": "^8.11.3"
54
+ },
55
+ "keywords": [
56
+ "baraqex",
57
+ "fullstack",
58
+ "react",
59
+ "typescript",
60
+ "express",
61
+ "api",
62
+ "authentication"
63
+ ],
64
+ "author": "",
65
+ "license": "MIT"
14
66
  }
@@ -1,16 +1,35 @@
1
- import { createDevServer } from 'baraqex/server';
1
+ import { createServer } from 'baraqex';
2
+ import dotenv from 'dotenv';
2
3
 
3
- const server = createDevServer({
4
- port: 3000,
5
- enableCors: true
4
+ // Load environment variables
5
+ dotenv.config();
6
+
7
+ // Create development server
8
+ const server = createServer({
9
+ port: parseInt(process.env.PORT || '3000'),
10
+ apiDir: './src/api',
11
+ pagesDir: './src/pages',
12
+ staticDir: './public',
13
+ enableCors: true,
14
+ auth: {
15
+ secret: process.env.JWT_SECRET || 'dev-secret-key',
16
+ expiresIn: '7d'
17
+ }
6
18
  });
7
19
 
8
- // Enable SSR with hydration
20
+ // Enable SSR
9
21
  server.enableSSR({ hydratable: true });
10
22
 
11
- // Start the server
23
+ // Start server
24
+ console.log('🚀 Starting Fullstack Baraqex Development Server...');
25
+
12
26
  server.start().then(() => {
13
- console.log('Full-stack server started!');
14
- console.log('Visit http://localhost:3000');
15
- console.log('API available at http://localhost:3000/api');
27
+ console.log('✅ Server running successfully!');
28
+ console.log('🌐 Frontend: http://localhost:3000');
29
+ console.log('🔗 API: http://localhost:3000/api');
30
+ console.log('📋 API Docs: http://localhost:3000/api-docs');
31
+ console.log('💚 Health: http://localhost:3000/health');
32
+ }).catch(error => {
33
+ console.error('❌ Failed to start server:', error);
34
+ process.exit(1);
16
35
  });
@@ -0,0 +1,94 @@
1
+ import { jsx, useState, useEffect } from 'frontend-hamroun';
2
+ import { AuthProvider, useAuth } from './contexts/AuthContext';
3
+ import { ApiProvider } from './contexts/ApiContext';
4
+ import { Header } from './components/Header';
5
+ import { Dashboard } from './components/Dashboard';
6
+ import { LoginForm } from './components/LoginForm';
7
+ import { TodoList } from './components/TodoList';
8
+ import { UserProfile } from './components/UserProfile';
9
+ import { LoadingSpinner } from './components/LoadingSpinner';
10
+ import './styles/App.css';
11
+
12
+ type View = 'dashboard' | 'todos' | 'profile' | 'login';
13
+
14
+ function AppContent() {
15
+ const { user, loading: authLoading } = useAuth();
16
+ const [currentView, setCurrentView] = useState<View>('dashboard');
17
+ const [loading, setLoading] = useState(true);
18
+
19
+ useEffect(() => {
20
+ // Simulate app initialization
21
+ const timer = setTimeout(() => {
22
+ setLoading(false);
23
+ }, 1000);
24
+
25
+ return () => clearTimeout(timer);
26
+ }, []);
27
+
28
+ if (loading || authLoading) {
29
+ return <LoadingSpinner message="Loading application..." />;
30
+ }
31
+
32
+ if (!user) {
33
+ return (
34
+ <div className="app">
35
+ <Header
36
+ user={null}
37
+ onNavigate={setCurrentView}
38
+ currentView={currentView}
39
+ />
40
+ <main className="main-content">
41
+ <LoginForm />
42
+ </main>
43
+ </div>
44
+ );
45
+ }
46
+
47
+ const renderView = () => {
48
+ switch (currentView) {
49
+ case 'dashboard':
50
+ return <Dashboard />;
51
+ case 'todos':
52
+ return <TodoList />;
53
+ case 'profile':
54
+ return <UserProfile />;
55
+ default:
56
+ return <Dashboard />;
57
+ }
58
+ };
59
+
60
+ return (
61
+ <div className="app">
62
+ <Header
63
+ user={user}
64
+ onNavigate={setCurrentView}
65
+ currentView={currentView}
66
+ />
67
+ <main className="main-content">
68
+ {renderView()}
69
+ </main>
70
+ <footer className="app-footer">
71
+ <p>&copy; 2024 Fullstack Baraqex App. Built with ❤️ using Baraqex Framework.</p>
72
+ </footer>
73
+ </div>
74
+ );
75
+ }
76
+
77
+ export default function App() {
78
+ return (
79
+ <AuthProvider>
80
+ <ApiProvider>
81
+ <AppContent />
82
+ </ApiProvider>
83
+ </AuthProvider>
84
+ );
85
+ }
86
+
87
+ // SSR support
88
+ App.getTitle = () => "Fullstack Baraqex App";
89
+ App.getDescription = () => "A complete fullstack application with authentication, API integration, and modern UI";
90
+ App.getMeta = () => ({
91
+ 'og:title': 'Fullstack Baraqex App',
92
+ 'og:description': 'Complete fullstack solution with Baraqex',
93
+ 'og:type': 'website'
94
+ });
@@ -0,0 +1,75 @@
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
+ }
@@ -0,0 +1,66 @@
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
+ }
@@ -0,0 +1,59 @@
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
+ }
@@ -0,0 +1,108 @@
1
+ import { sendSuccess, sendError } from 'baraqex';
2
+
3
+ // Import the todos array from the index file
4
+ // In a real app, this would be in a database
5
+ let todos = [
6
+ { id: 1, text: 'Learn Baraqex Framework', completed: false, userId: 1, createdAt: new Date().toISOString() },
7
+ { id: 2, text: 'Build awesome fullstack app', completed: false, userId: 1, createdAt: new Date().toISOString() },
8
+ { id: 3, text: 'Deploy to production', completed: false, userId: 1, createdAt: new Date().toISOString() }
9
+ ];
10
+
11
+ // Require authentication
12
+ export const middleware = [
13
+ (req: any, res: any, next: any) => {
14
+ if (!req.user) {
15
+ return sendError(res, 'Authentication required', 401);
16
+ }
17
+ next();
18
+ }
19
+ ];
20
+
21
+ // Get specific todo
22
+ export async function get(req: any, res: any) {
23
+ try {
24
+ const todoId = parseInt(req.params.id);
25
+ const userId = req.user.id;
26
+
27
+ if (isNaN(todoId)) {
28
+ return sendError(res, 'Invalid todo ID', 400);
29
+ }
30
+
31
+ const todo = todos.find(t => t.id === todoId && t.userId === userId);
32
+ if (!todo) {
33
+ return sendError(res, 'Todo not found', 404);
34
+ }
35
+
36
+ return sendSuccess(res, { todo }, 'Todo retrieved successfully');
37
+
38
+ } catch (error: any) {
39
+ console.error('Get todo error:', error);
40
+ return sendError(res, 'Failed to get todo', 500);
41
+ }
42
+ }
43
+
44
+ // Update todo
45
+ export async function put(req: any, res: any) {
46
+ try {
47
+ const todoId = parseInt(req.params.id);
48
+ const userId = req.user.id;
49
+ const { text, completed } = req.body;
50
+
51
+ if (isNaN(todoId)) {
52
+ return sendError(res, 'Invalid todo ID', 400);
53
+ }
54
+
55
+ const todoIndex = todos.findIndex(t => t.id === todoId && t.userId === userId);
56
+ if (todoIndex === -1) {
57
+ return sendError(res, 'Todo not found', 404);
58
+ }
59
+
60
+ // Update todo
61
+ if (text !== undefined) {
62
+ if (text.trim().length === 0) {
63
+ return sendError(res, 'Todo text cannot be empty', 400);
64
+ }
65
+ todos[todoIndex].text = text.trim();
66
+ }
67
+
68
+ if (completed !== undefined) {
69
+ todos[todoIndex].completed = Boolean(completed);
70
+ }
71
+
72
+ todos[todoIndex].updatedAt = new Date().toISOString();
73
+
74
+ return sendSuccess(res, { todo: todos[todoIndex] }, 'Todo updated successfully');
75
+
76
+ } catch (error: any) {
77
+ console.error('Update todo error:', error);
78
+ return sendError(res, 'Failed to update todo', 500);
79
+ }
80
+ }
81
+
82
+ // Delete todo
83
+ export async function del(req: any, res: any) {
84
+ try {
85
+ const todoId = parseInt(req.params.id);
86
+ const userId = req.user.id;
87
+
88
+ if (isNaN(todoId)) {
89
+ return sendError(res, 'Invalid todo ID', 400);
90
+ }
91
+
92
+ const todoIndex = todos.findIndex(t => t.id === todoId && t.userId === userId);
93
+ if (todoIndex === -1) {
94
+ return sendError(res, 'Todo not found', 404);
95
+ }
96
+
97
+ const deletedTodo = todos.splice(todoIndex, 1)[0];
98
+
99
+ return sendSuccess(res, { todo: deletedTodo }, 'Todo deleted successfully');
100
+
101
+ } catch (error: any) {
102
+ console.error('Delete todo error:', error);
103
+ return sendError(res, 'Failed to delete todo', 500);
104
+ }
105
+ }
106
+
107
+ // Export delete function with correct name
108
+ export { del as delete };
@@ -0,0 +1,79 @@
1
+ import { sendSuccess, sendError, validateFields, getPagination } from 'baraqex';
2
+
3
+ // In-memory storage for demo (use database in real app)
4
+ let todos = [
5
+ { id: 1, text: 'Learn Baraqex Framework', completed: false, userId: 1, createdAt: new Date().toISOString() },
6
+ { id: 2, text: 'Build awesome fullstack app', completed: false, userId: 1, createdAt: new Date().toISOString() },
7
+ { id: 3, text: 'Deploy to production', completed: false, userId: 1, createdAt: new Date().toISOString() }
8
+ ];
9
+
10
+ // Require authentication for all todo endpoints
11
+ export const middleware = [
12
+ (req: any, res: any, next: any) => {
13
+ if (!req.user) {
14
+ return sendError(res, 'Authentication required', 401);
15
+ }
16
+ next();
17
+ }
18
+ ];
19
+
20
+ // Get todos for current user
21
+ export async function get(req: any, res: any) {
22
+ try {
23
+ const userId = req.user.id;
24
+ const { page, limit, skip } = getPagination(req);
25
+
26
+ // Filter todos for current user
27
+ const userTodos = todos.filter(todo => todo.userId === userId);
28
+
29
+ // Apply pagination
30
+ const paginatedTodos = userTodos.slice(skip, skip + limit);
31
+
32
+ return sendSuccess(res, {
33
+ todos: paginatedTodos,
34
+ pagination: {
35
+ page,
36
+ limit,
37
+ total: userTodos.length,
38
+ pages: Math.ceil(userTodos.length / limit)
39
+ }
40
+ }, 'Todos retrieved successfully');
41
+
42
+ } catch (error: any) {
43
+ console.error('Get todos error:', error);
44
+ return sendError(res, 'Failed to get todos', 500);
45
+ }
46
+ }
47
+
48
+ // Create new todo
49
+ export async function post(req: any, res: any) {
50
+ try {
51
+ const validation = validateFields(req, ['text']);
52
+ if (!validation.valid) {
53
+ return sendError(res, 'Missing required fields', 400, { missing: validation.missing });
54
+ }
55
+
56
+ const { text } = req.body;
57
+ const userId = req.user.id;
58
+
59
+ if (text.trim().length === 0) {
60
+ return sendError(res, 'Todo text cannot be empty', 400);
61
+ }
62
+
63
+ const newTodo = {
64
+ id: Date.now(),
65
+ text: text.trim(),
66
+ completed: false,
67
+ userId,
68
+ createdAt: new Date().toISOString()
69
+ };
70
+
71
+ todos.push(newTodo);
72
+
73
+ return sendSuccess(res, { todo: newTodo }, 'Todo created successfully');
74
+
75
+ } catch (error: any) {
76
+ console.error('Create todo error:', error);
77
+ return sendError(res, 'Failed to create todo', 500);
78
+ }
79
+ }