frontend-hamroun 1.2.15 → 1.2.17

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 (158) hide show
  1. package/README.md +4 -0
  2. package/bin/cli.js +673 -0
  3. package/dist/component.d.ts +1 -1
  4. package/dist/context.d.ts +4 -3
  5. package/dist/index.client.d.ts +11 -0
  6. package/dist/index.d.ts +9 -89
  7. package/dist/index.js +396 -67
  8. package/dist/index.js.map +1 -0
  9. package/dist/index.mjs +392 -0
  10. package/dist/index.mjs.map +1 -0
  11. package/dist/jsx-runtime/jsx-runtime.d.ts +0 -1
  12. package/dist/jsx-runtime.d.ts +1 -1
  13. package/dist/renderer.d.ts +0 -10
  14. package/dist/server-renderer.d.ts +0 -3
  15. package/dist/server-types.d.ts +42 -0
  16. package/package.json +69 -50
  17. package/templates/basic-app/index.html +6 -6
  18. package/templates/basic-app/package.json +15 -11
  19. package/templates/basic-app/postcss.config.js +0 -1
  20. package/templates/basic-app/src/main.tsx +1 -10
  21. package/templates/basic-app/tailwind.config.js +2 -23
  22. package/templates/basic-app/tsconfig.json +4 -17
  23. package/templates/basic-app/vite.config.ts +3 -54
  24. package/templates/fullstack-app/api/hello.ts +18 -0
  25. package/templates/fullstack-app/api/users/[id].ts +73 -0
  26. package/templates/fullstack-app/api/users/index.ts +32 -0
  27. package/templates/fullstack-app/package.json +31 -0
  28. package/templates/fullstack-app/server.ts +46 -0
  29. package/templates/fullstack-app/src/pages/index.tsx +59 -0
  30. package/templates/ssr-template/vite.config.ts +1 -11
  31. package/bin/cli.cjs +0 -16
  32. package/bin/cli.mjs +0 -237
  33. package/dist/backend/api-utils.d.ts +0 -38
  34. package/dist/backend/api-utils.js +0 -135
  35. package/dist/backend/auth.d.ts +0 -134
  36. package/dist/backend/auth.js +0 -387
  37. package/dist/backend/database.d.ts +0 -27
  38. package/dist/backend/database.js +0 -91
  39. package/dist/backend/model.d.ts +0 -43
  40. package/dist/backend/model.js +0 -178
  41. package/dist/backend/router.d.ts +0 -27
  42. package/dist/backend/router.js +0 -137
  43. package/dist/backend/server.d.ts +0 -19
  44. package/dist/backend/server.js +0 -268
  45. package/dist/backend/types.d.ts +0 -217
  46. package/dist/backend/types.js +0 -1
  47. package/dist/batch.js +0 -22
  48. package/dist/cli/index.d.ts +0 -2
  49. package/dist/cli/index.js +0 -215
  50. package/dist/component.js +0 -84
  51. package/dist/components/Counter.js +0 -2
  52. package/dist/context.js +0 -18
  53. package/dist/frontend-hamroun.es.js +0 -1378
  54. package/dist/frontend-hamroun.umd.js +0 -66
  55. package/dist/hooks.js +0 -164
  56. package/dist/jsx-runtime/index.d.ts +0 -11
  57. package/dist/jsx-runtime/index.js +0 -19
  58. package/dist/jsx-runtime/jsx-dev-runtime.js +0 -1
  59. package/dist/jsx-runtime/jsx-runtime.js +0 -95
  60. package/dist/jsx-runtime.js +0 -192
  61. package/dist/renderer.js +0 -51
  62. package/dist/server-renderer.js +0 -102
  63. package/dist/types.js +0 -1
  64. package/dist/vdom.js +0 -27
  65. package/scripts/build-cli.js +0 -1107
  66. package/scripts/generate.js +0 -134
  67. package/src/backend/api-utils.ts +0 -178
  68. package/src/backend/auth.ts +0 -544
  69. package/src/backend/database.ts +0 -104
  70. package/src/backend/model.ts +0 -198
  71. package/src/backend/router.ts +0 -176
  72. package/src/backend/server.ts +0 -330
  73. package/src/backend/types.ts +0 -257
  74. package/src/batch.ts +0 -24
  75. package/src/cli/index.js +0 -554
  76. package/src/cli/index.ts +0 -257
  77. package/src/component.ts +0 -98
  78. package/src/components/Counter.tsx +0 -4
  79. package/src/context.ts +0 -29
  80. package/src/hooks.ts +0 -211
  81. package/src/index.ts +0 -144
  82. package/src/jsx-runtime/index.ts +0 -27
  83. package/src/jsx-runtime/jsx-dev-runtime.ts +0 -0
  84. package/src/jsx-runtime/jsx-runtime.ts +0 -104
  85. package/src/jsx-runtime.ts +0 -226
  86. package/src/renderer.ts +0 -55
  87. package/src/server-renderer.ts +0 -114
  88. package/src/shims.d.ts +0 -20
  89. package/src/types/bcrypt.d.ts +0 -30
  90. package/src/types/jsonwebtoken.d.ts +0 -55
  91. package/src/types.d.ts +0 -26
  92. package/src/types.ts +0 -21
  93. package/src/vdom.ts +0 -34
  94. package/templates/basic/.eslintignore +0 -5
  95. package/templates/basic/.eslintrc.json +0 -25
  96. package/templates/basic/docs/rapport_pfe.aux +0 -27
  97. package/templates/basic/docs/rapport_pfe.log +0 -399
  98. package/templates/basic/docs/rapport_pfe.out +0 -10
  99. package/templates/basic/docs/rapport_pfe.pdf +0 -0
  100. package/templates/basic/docs/rapport_pfe.tex +0 -68
  101. package/templates/basic/docs/rapport_pfe.toc +0 -14
  102. package/templates/basic/index.html +0 -12
  103. package/templates/basic/jsconfig.json +0 -14
  104. package/templates/basic/package.json +0 -20
  105. package/templates/basic/postcss.config.js +0 -7
  106. package/templates/basic/src/App.js +0 -105
  107. package/templates/basic/src/App.tsx +0 -65
  108. package/templates/basic/src/api.ts +0 -58
  109. package/templates/basic/src/components/Counter.tsx +0 -26
  110. package/templates/basic/src/components/Header.tsx +0 -9
  111. package/templates/basic/src/components/TodoList.tsx +0 -90
  112. package/templates/basic/src/main.css +0 -3
  113. package/templates/basic/src/main.js +0 -11
  114. package/templates/basic/src/main.ts +0 -20
  115. package/templates/basic/src/main.tsx +0 -144
  116. package/templates/basic/src/server.ts +0 -99
  117. package/templates/basic/tailwind.config.js +0 -32
  118. package/templates/basic/tsconfig.json +0 -20
  119. package/templates/basic/tsconfig.node.json +0 -10
  120. package/templates/basic/vite.config.js +0 -18
  121. package/templates/basic/vite.config.ts +0 -86
  122. package/templates/basic-app/src/App.js +0 -105
  123. package/templates/basic-app/src/App.tsx +0 -143
  124. package/templates/basic-app/src/api.ts +0 -58
  125. package/templates/basic-app/src/components/Counter.tsx +0 -26
  126. package/templates/basic-app/src/components/Header.tsx +0 -9
  127. package/templates/basic-app/src/components/TodoList.tsx +0 -90
  128. package/templates/basic-app/src/main.js +0 -10
  129. package/templates/basic-app/src/main.ts +0 -21
  130. package/templates/basic-app/src/react/index.ts +0 -35
  131. package/templates/basic-app/src/react/jsx-dev-runtime.ts +0 -13
  132. package/templates/basic-app/src/react/jsx-runtime.ts +0 -12
  133. package/templates/basic-app/src/server.ts +0 -99
  134. package/templates/basic-app/src/shims.ts +0 -9
  135. package/templates/basic-app/tsconfig.node.json +0 -10
  136. package/templates/basic-app/vite.config.js +0 -22
  137. package/templates/full-stack/.env.example +0 -11
  138. package/templates/full-stack/README.md +0 -51
  139. package/templates/full-stack/index.html +0 -12
  140. package/templates/full-stack/jsconfig.json +0 -14
  141. package/templates/full-stack/package.json +0 -20
  142. package/templates/full-stack/src/App.js +0 -105
  143. package/templates/full-stack/src/client/App.tsx +0 -50
  144. package/templates/full-stack/src/client/components/Header.tsx +0 -42
  145. package/templates/full-stack/src/client/components/UserList.tsx +0 -29
  146. package/templates/full-stack/src/client/main.tsx +0 -5
  147. package/templates/full-stack/src/main.css +0 -3
  148. package/templates/full-stack/src/main.js +0 -11
  149. package/templates/full-stack/src/main.ts +0 -20
  150. package/templates/full-stack/src/server/index.ts +0 -99
  151. package/templates/full-stack/src/server/routes/auth.ts +0 -39
  152. package/templates/full-stack/src/server/routes/users.ts +0 -48
  153. package/templates/full-stack/src/shims.ts +0 -9
  154. package/templates/full-stack/tsconfig.json +0 -20
  155. package/templates/full-stack/tsconfig.node.json +0 -10
  156. package/templates/full-stack/tsconfig.server.json +0 -15
  157. package/templates/full-stack/vite.config.js +0 -18
  158. package/templates/full-stack/vite.config.ts +0 -85
package/package.json CHANGED
@@ -1,84 +1,103 @@
1
1
  {
2
2
  "name": "frontend-hamroun",
3
- "version": "1.2.15",
4
- "description": "A lightweight frontend and backend framework for building modern web applications",
3
+ "version": "1.2.17",
4
+ "description": "A lightweight full-stack JavaScript framework",
5
5
  "type": "module",
6
- "main": "dist/frontend-hamroun.umd.js",
7
- "module": "dist/frontend-hamroun.es.js",
8
- "types": "dist/index.d.ts",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.ts",
9
9
  "files": [
10
10
  "dist",
11
- "src",
12
- "templates",
13
- "scripts",
14
- "bin",
11
+ "README.md",
15
12
  "LICENSE",
16
- "README.md"
13
+ "bin",
14
+ "templates"
17
15
  ],
18
16
  "exports": {
19
17
  ".": {
20
18
  "types": "./dist/index.d.ts",
21
- "import": "./dist/frontend-hamroun.es.js",
22
- "require": "./dist/frontend-hamroun.umd.js"
19
+ "import": "./dist/index.mjs",
20
+ "require": "./dist/index.js",
21
+ "default": "./dist/index.js"
23
22
  }
24
23
  },
25
24
  "bin": {
26
- "hamroun": "./bin/cli.mjs",
27
- "frontend-hamroun": "./bin/cli.mjs"
25
+ "frontend-hamroun": "./bin/cli.js",
26
+ "create-frontend-app": "./bin/cli.js"
28
27
  },
29
28
  "scripts": {
29
+ "build:client": "vite build",
30
+ "build:server": "node build-server.js",
31
+ "build": "npm run build:server && npm run build:client",
32
+ "clean": "node -e \"if(require('fs').existsSync('dist')) require('fs').rmSync('dist',{recursive:true})\"",
33
+ "prepublishOnly": "npm run clean && npm run build",
30
34
  "dev": "vite",
31
- "build": "vite build && tsc && npm run build:cli",
32
- "build:cli": "node scripts/build-cli.js",
33
- "prepublishOnly": "npm run build",
34
- "test": "jest",
35
- "clean": "rimraf dist bin",
36
- "prebuild": "npm run clean",
37
- "generate": "node scripts/generate.js",
38
- "publish:next": "npm publish --tag next"
35
+ "test": "node --loader ts-node/esm tests/run-tests.ts",
36
+ "test:watch": "nodemon --watch src --watch tests --ext ts,tsx --exec 'npm test'",
37
+ "generate-test-report": "node --loader ts-node/esm tests/generate-report.ts"
39
38
  },
40
39
  "keywords": [
41
40
  "frontend",
42
41
  "framework",
43
- "react-like",
44
42
  "jsx",
45
- "ssr",
46
- "server-side-rendering",
47
- "backend",
48
- "api",
49
- "express"
43
+ "hooks",
44
+ "virtual-dom",
45
+ "fullstack",
46
+ "express",
47
+ "api"
50
48
  ],
51
49
  "author": "Hamroun",
52
50
  "license": "MIT",
53
51
  "repository": {
54
52
  "type": "git",
55
- "url": "https://github.com/hamroun/frontend-hamroun.git"
53
+ "url": "your-repo-url"
56
54
  },
57
55
  "devDependencies": {
58
- "@types/bcrypt": "^5.0.2",
59
- "@types/compression": "^1.7.5",
60
- "@types/express": "^4.17.21",
61
- "@types/jest": "^29.5.11",
62
- "@types/jsonwebtoken": "^9.0.5",
63
- "@types/morgan": "^1.9.9",
64
- "@types/node": "^20.10.5",
65
- "jest": "^29.7.0",
66
- "rimraf": "^5.0.5",
67
- "terser": "^5.25.0",
68
- "ts-jest": "^29.1.1",
69
- "typescript": "^5.3.3",
70
- "vite": "^5.0.10",
71
- "vite-plugin-dts": "^3.6.4"
56
+ "@types/bcryptjs": "^2.4.4",
57
+ "@types/cors": "^2.8.14",
58
+ "@types/express": "^4.17.18",
59
+ "@types/jsonwebtoken": "^9.0.3",
60
+ "@types/mongodb": "^4.0.7",
61
+ "@types/node": "^18.16.19",
62
+ "@types/pg": "^8.10.2",
63
+ "@types/react": "^19.0.8",
64
+ "@vitejs/plugin-react": "^4.0.4",
65
+ "nanospinner": "^1.1.0",
66
+ "terser": "^5.38.1",
67
+ "typescript": "^5.0.0",
68
+ "vite": "^4.4.9",
69
+ "vite-plugin-dts": "^4.5.0",
70
+ "vitest": "^0.34.0"
71
+ },
72
+ "publishConfig": {
73
+ "access": "public",
74
+ "registry": "https://registry.npmjs.org/"
72
75
  },
73
76
  "dependencies": {
74
- "bcrypt": "^5.1.1",
75
- "compression": "^1.7.4",
77
+ "bcryptjs": "^2.4.3",
78
+ "chalk": "^5.3.0",
79
+ "commander": "^11.0.0",
80
+ "cors": "^2.8.5",
76
81
  "express": "^4.18.2",
77
- "helmet": "^7.1.0",
82
+ "fs-extra": "^11.1.1",
83
+ "inquirer": "^9.2.10",
78
84
  "jsonwebtoken": "^9.0.2",
79
- "mongoose": "^8.0.3",
80
- "morgan": "^1.10.0",
81
- "ts-node": "^10.9.2",
82
- "vite-plugin-node-polyfills": "^0.23.0"
85
+ "mongodb": "^5.7.0",
86
+ "mysql2": "^3.6.1",
87
+ "nanospinner": "^1.1.0",
88
+ "pg": "^8.11.3",
89
+ "ts-node": "^10.9.2"
90
+ },
91
+ "peerDependencies": {
92
+ "react": ">=16.8.0",
93
+ "react-dom": ">=16.8.0"
94
+ },
95
+ "peerDependenciesMeta": {
96
+ "react": {
97
+ "optional": true
98
+ },
99
+ "react-dom": {
100
+ "optional": true
101
+ }
83
102
  }
84
103
  }
@@ -1,12 +1,12 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
3
  <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Frontend Hamroun App</title>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>My Frontend App</title>
7
7
  </head>
8
- <body>
9
- <div id="app"></div>
10
- <script type="module" src="/src/main.js"></script>
8
+ <body class="bg-gray-100 min-h-screen">
9
+ <div id="root"></div>
10
+ <script type="module" src="/src/main.tsx"></script>
11
11
  </body>
12
12
  </html>
@@ -1,24 +1,28 @@
1
1
  {
2
- "name": "frontend-hamroun-app",
2
+ "name": "my-app",
3
3
  "private": true,
4
- "version": "0.1.0",
4
+ "version": "0.0.0",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite",
8
8
  "build": "tsc && vite build",
9
- "preview": "vite preview"
9
+ "preview": "vite preview",
10
+ "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
11
+ "lint:fix": "eslint src --ext ts,tsx --fix"
10
12
  },
11
13
  "dependencies": {
12
14
  "frontend-hamroun": "latest"
13
15
  },
14
16
  "devDependencies": {
15
- "@types/node": "^20.10.0",
16
- "typescript": "^5.3.2",
17
- "vite": "^5.0.0",
18
- "vite-plugin-node-polyfills": "^0.21.0"
19
- },
20
- "overrides": {
21
- "react": "npm:@empty-npm-package/react@1.0.0",
22
- "react-dom": "npm:@empty-npm-package/react-dom@1.0.0"
17
+ "typescript": "^5.0.0",
18
+ "vite": "^4.4.9",
19
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
20
+ "@typescript-eslint/parser": "^6.0.0",
21
+ "eslint": "^8.45.0",
22
+ "eslint-plugin-react-hooks": "^4.6.0",
23
+ "eslint-plugin-react-refresh": "^0.4.3",
24
+ "tailwindcss": "^3.3.3",
25
+ "postcss": "^8.4.27",
26
+ "autoprefixer": "^10.4.14"
23
27
  }
24
28
  }
@@ -2,6 +2,5 @@ export default {
2
2
  plugins: {
3
3
  tailwindcss: {},
4
4
  autoprefixer: {},
5
- cssnano: process.env.NODE_ENV === 'production' ? { preset: 'default' } : false
6
5
  },
7
6
  }
@@ -141,13 +141,4 @@ function ContextConsumer() {
141
141
  );
142
142
  }
143
143
 
144
- import { render } from 'frontend-hamroun';
145
- import { App } from './App';
146
-
147
- document.addEventListener('DOMContentLoaded', () => {
148
- const rootElement = document.getElementById('app');
149
- if (rootElement) {
150
- render(App({}), rootElement);
151
- console.log('App rendered successfully');
152
- }
153
- });
144
+ render(<App />, document.getElementById('root')!);
@@ -5,28 +5,7 @@ export default {
5
5
  "./src/**/*.{js,ts,jsx,tsx}",
6
6
  ],
7
7
  theme: {
8
- extend: {
9
- colors: {
10
- primary: {
11
- 50: '#f0f9ff',
12
- 100: '#e0f2fe',
13
- 200: '#bae6fd',
14
- 300: '#7dd3fc',
15
- 400: '#38bdf8',
16
- 500: '#0ea5e9',
17
- 600: '#0284c7',
18
- 700: '#0369a1',
19
- 800: '#075985',
20
- 900: '#0c4a6e',
21
- },
22
- },
23
- fontFamily: {
24
- sans: ['Inter var', 'sans-serif'],
25
- },
26
- },
8
+ extend: {},
27
9
  },
28
- plugins: [
29
- require('@tailwindcss/forms'),
30
- require('@tailwindcss/typography'),
31
- ],
10
+ plugins: [],
32
11
  }
@@ -1,26 +1,13 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "target": "ES2020",
4
- "useDefineForClassFields": true,
5
4
  "module": "ESNext",
6
5
  "lib": ["ES2020", "DOM", "DOM.Iterable"],
7
- "skipLibCheck": true,
6
+ "jsx": "preserve",
8
7
  "moduleResolution": "bundler",
9
- "allowImportingTsExtensions": true,
10
- "resolveJsonModule": true,
11
- "isolatedModules": true,
12
- "noEmit": true,
8
+ "esModuleInterop": true,
13
9
  "strict": true,
14
- "noUnusedLocals": true,
15
- "noUnusedParameters": true,
16
- "noFallthroughCasesInSwitch": true,
17
- "paths": {
18
- "react": ["./node_modules/frontend-hamroun"],
19
- "react-dom": ["./node_modules/frontend-hamroun"],
20
- "react/jsx-runtime": ["./node_modules/frontend-hamroun"],
21
- "react/jsx-dev-runtime": ["./node_modules/frontend-hamroun"]
22
- }
10
+ "skipLibCheck": true
23
11
  },
24
- "include": ["src"],
25
- "references": [{ "path": "./tsconfig.node.json" }]
12
+ "include": ["src"]
26
13
  }
@@ -1,59 +1,8 @@
1
1
  import { defineConfig } from 'vite';
2
- import { nodePolyfills } from 'vite-plugin-node-polyfills';
3
- import path from 'path';
4
2
 
5
3
  export default defineConfig({
6
- build: {
7
- outDir: 'dist',
8
- emptyOutDir: true,
9
- rollupOptions: {
10
- // Mark server-side dependencies as external
11
- external: [
12
- 'react',
13
- 'react-dom',
14
- 'react/jsx-runtime',
15
- 'react/jsx-dev-runtime',
16
- 'express',
17
- 'compression',
18
- 'helmet',
19
- 'morgan',
20
- 'bcrypt',
21
- 'jsonwebtoken',
22
- 'mongoose',
23
- /node:.*/
24
- ]
25
- }
26
- },
27
- server: {
28
- port: 3000,
29
- open: true
30
- },
31
- optimizeDeps: {
32
- // Prevent Vite from optimizing Node.js modules
33
- exclude: ['bcrypt', 'jsonwebtoken', 'mongoose', 'express', 'compression', 'helmet', 'morgan'],
34
- esbuildOptions: {
35
- define: {
36
- global: 'globalThis'
37
- }
38
- },
39
- include: ['frontend-hamroun']
40
- },
41
- plugins: [
42
- nodePolyfills({
43
- protocolImports: true,
44
- }),
45
- ],
46
- resolve: {
47
- alias: {
48
- // Remove any Node.js specific imports that might cause issues
49
- 'bcrypt': 'frontend-hamroun',
50
- 'jsonwebtoken': 'frontend-hamroun',
51
- 'mongoose': 'frontend-hamroun',
52
- // Map React imports to our compatibility layer
53
- 'react': path.resolve(__dirname, 'src/react/index.ts'),
54
- 'react-dom': 'frontend-hamroun',
55
- 'react/jsx-runtime': path.resolve(__dirname, 'src/react/jsx-runtime.ts'),
56
- 'react/jsx-dev-runtime': path.resolve(__dirname, 'src/react/jsx-dev-runtime.ts')
57
- }
4
+ esbuild: {
5
+ jsxFactory: 'jsx',
6
+ jsxFragment: 'Fragment'
58
7
  }
59
8
  });
@@ -0,0 +1,18 @@
1
+ import { Request, Response } from 'express';
2
+
3
+ export const get = (req: Request, res: Response) => {
4
+ res.json({
5
+ message: 'Hello from the API!',
6
+ timestamp: new Date().toISOString()
7
+ });
8
+ };
9
+
10
+ export const post = (req: Request, res: Response) => {
11
+ const { name = 'Guest' } = req.body;
12
+
13
+ res.json({
14
+ message: `Hello, ${name}!`,
15
+ timestamp: new Date().toISOString(),
16
+ receivedData: req.body
17
+ });
18
+ };
@@ -0,0 +1,73 @@
1
+ import { Request, Response } from 'express';
2
+
3
+ // Mock user database - same as in index.ts for simplicity
4
+ const users = [
5
+ { id: 1, name: 'User 1', email: 'user1@example.com' },
6
+ { id: 2, name: 'User 2', email: 'user2@example.com' },
7
+ { id: 3, name: 'User 3', email: 'user3@example.com' }
8
+ ];
9
+
10
+ export const get = (req: Request, res: Response) => {
11
+ const userId = parseInt(req.params.id);
12
+
13
+ if (isNaN(userId)) {
14
+ return res.status(400).json({ error: 'Invalid user ID' });
15
+ }
16
+
17
+ const user = users.find(u => u.id === userId);
18
+
19
+ if (!user) {
20
+ return res.status(404).json({ error: 'User not found' });
21
+ }
22
+
23
+ res.json(user);
24
+ };
25
+
26
+ export const put = (req: Request, res: Response) => {
27
+ const userId = parseInt(req.params.id);
28
+
29
+ if (isNaN(userId)) {
30
+ return res.status(400).json({ error: 'Invalid user ID' });
31
+ }
32
+
33
+ const userIndex = users.findIndex(u => u.id === userId);
34
+
35
+ if (userIndex === -1) {
36
+ return res.status(404).json({ error: 'User not found' });
37
+ }
38
+
39
+ const { name, email } = req.body;
40
+
41
+ if (!name && !email) {
42
+ return res.status(400).json({ error: 'Name or email must be provided' });
43
+ }
44
+
45
+ // Update the user
46
+ users[userIndex] = {
47
+ ...users[userIndex],
48
+ ...(name && { name }),
49
+ ...(email && { email })
50
+ };
51
+
52
+ res.json(users[userIndex]);
53
+ };
54
+
55
+ export const delete_ = (req: Request, res: Response) => {
56
+ const userId = parseInt(req.params.id);
57
+
58
+ if (isNaN(userId)) {
59
+ return res.status(400).json({ error: 'Invalid user ID' });
60
+ }
61
+
62
+ const userIndex = users.findIndex(u => u.id === userId);
63
+
64
+ if (userIndex === -1) {
65
+ return res.status(404).json({ error: 'User not found' });
66
+ }
67
+
68
+ // Remove the user
69
+ const deletedUser = users[userIndex];
70
+ users.splice(userIndex, 1);
71
+
72
+ res.json({ success: true, deletedUser });
73
+ };
@@ -0,0 +1,32 @@
1
+ import { Request, Response } from 'express';
2
+
3
+ // Mock user database
4
+ const users = [
5
+ { id: 1, name: 'User 1', email: 'user1@example.com' },
6
+ { id: 2, name: 'User 2', email: 'user2@example.com' },
7
+ { id: 3, name: 'User 3', email: 'user3@example.com' }
8
+ ];
9
+
10
+ export const get = (req: Request, res: Response) => {
11
+ // Return users without sensitive information
12
+ const safeUsers = users.map(({ id, name, email }) => ({ id, name, email }));
13
+ res.json(safeUsers);
14
+ };
15
+
16
+ export const post = (req: Request, res: Response) => {
17
+ const { name, email } = req.body;
18
+
19
+ if (!name || !email) {
20
+ return res.status(400).json({ error: 'Name and email are required' });
21
+ }
22
+
23
+ // In a real app, validate data and save to database
24
+ const newUser = {
25
+ id: users.length + 1,
26
+ name,
27
+ email
28
+ };
29
+
30
+ users.push(newUser);
31
+ res.status(201).json(newUser);
32
+ };
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "fullstack-app",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "scripts": {
6
+ "dev": "node --loader ts-node/esm server.ts",
7
+ "build": "vite build && tsc --emitDeclarationOnly",
8
+ "start": "node dist/server.js"
9
+ },
10
+ "dependencies": {
11
+ "bcryptjs": "^2.4.3",
12
+ "cors": "^2.8.5",
13
+ "express": "^4.18.2",
14
+ "frontend-hamroun": "latest",
15
+ "jsonwebtoken": "^9.0.2",
16
+ "mongodb": "^5.7.0"
17
+ },
18
+ "devDependencies": {
19
+ "@types/bcryptjs": "^2.4.4",
20
+ "@types/cors": "^2.8.14",
21
+ "@types/express": "^4.17.18",
22
+ "@types/jsonwebtoken": "^9.0.3",
23
+ "@types/node": "^18.16.19",
24
+ "autoprefixer": "^10.4.15",
25
+ "postcss": "^8.4.29",
26
+ "tailwindcss": "^3.3.3",
27
+ "ts-node": "^10.9.1",
28
+ "typescript": "^5.2.2",
29
+ "vite": "^4.4.9"
30
+ }
31
+ }
@@ -0,0 +1,46 @@
1
+ import { Server } from 'frontend-hamroun';
2
+ import path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
+
7
+ const server = new Server({
8
+ port: process.env.PORT ? parseInt(process.env.PORT) : 3000,
9
+ apiDir: './api',
10
+ pagesDir: './src/pages',
11
+ staticDir: './public',
12
+
13
+ // Uncomment to enable database
14
+ /*
15
+ db: {
16
+ url: process.env.DATABASE_URL || 'mongodb://localhost:27017/my_app',
17
+ type: 'mongodb'
18
+ },
19
+ */
20
+
21
+ // Uncomment to enable authentication
22
+ /*
23
+ auth: {
24
+ secret: process.env.JWT_SECRET || 'your-secret-key',
25
+ expiresIn: '7d'
26
+ }
27
+ */
28
+ });
29
+
30
+ // Connect to database if configured
31
+ if (server.getDatabase()) {
32
+ await server.getDatabase()?.connect();
33
+ }
34
+
35
+ // Start the server
36
+ await server.start();
37
+
38
+ // Handle shutdown gracefully
39
+ process.on('SIGINT', async () => {
40
+ console.log('Shutting down server...');
41
+ await server.stop();
42
+ if (server.getDatabase()) {
43
+ await server.getDatabase()?.disconnect();
44
+ }
45
+ process.exit(0);
46
+ });
@@ -0,0 +1,59 @@
1
+ import { useState, useEffect } from 'frontend-hamroun';
2
+
3
+ export default function HomePage() {
4
+ const [apiData, setApiData] = useState(null);
5
+ const [loading, setLoading] = useState(true);
6
+ const [error, setError] = useState(null);
7
+
8
+ useEffect(() => {
9
+ async function fetchData() {
10
+ try {
11
+ const response = await fetch('/api/hello');
12
+ const data = await response.json();
13
+ setApiData(data);
14
+ setLoading(false);
15
+ } catch (err) {
16
+ setError(err.message);
17
+ setLoading(false);
18
+ }
19
+ }
20
+
21
+ fetchData();
22
+ }, []);
23
+
24
+ return (
25
+ <div className="container mx-auto p-4">
26
+ <h1 className="text-3xl font-bold mb-4">Frontend Hamroun Full Stack</h1>
27
+
28
+ <div className="mb-6">
29
+ <h2 className="text-xl font-semibold mb-2">API Response:</h2>
30
+ {loading ? (
31
+ <p>Loading...</p>
32
+ ) : error ? (
33
+ <p className="text-red-500">Error: {error}</p>
34
+ ) : (
35
+ <pre className="bg-gray-100 p-4 rounded">
36
+ {JSON.stringify(apiData, null, 2)}
37
+ </pre>
38
+ )}
39
+ </div>
40
+
41
+ <div className="mb-6">
42
+ <h2 className="text-xl font-semibold mb-2">Features:</h2>
43
+ <ul className="list-disc pl-6">
44
+ <li>Server-side rendering</li>
45
+ <li>API routes with Express</li>
46
+ <li>Database integration</li>
47
+ <li>Authentication and authorization</li>
48
+ <li>File-based routing</li>
49
+ </ul>
50
+ </div>
51
+
52
+ <div>
53
+ <h2 className="text-xl font-semibold mb-2">Get Started:</h2>
54
+ <p>Edit <code className="bg-gray-100 px-2 py-1 rounded">src/pages/index.tsx</code> to customize this page</p>
55
+ <p>API routes are in the <code className="bg-gray-100 px-2 py-1 rounded">api</code> directory</p>
56
+ </div>
57
+ </div>
58
+ );
59
+ }
@@ -19,17 +19,7 @@ export default defineConfig({
19
19
  entryFileNames: '[name].js',
20
20
  chunkFileNames: 'assets/[name]-[hash].js',
21
21
  assetFileNames: 'assets/[name]-[hash].[ext]'
22
- },
23
- // Mark testing dependencies as external so they won't be included in the bundle
24
- external: [
25
- 'mock-aws-s3',
26
- 'aws-sdk',
27
- 'nock',
28
- 'jest',
29
- 'jest-mock',
30
- '@testing-library/react',
31
- '@testing-library/jest-dom'
32
- ]
22
+ }
33
23
  }
34
24
  },
35
25
  esbuild: {
package/bin/cli.cjs DELETED
@@ -1,16 +0,0 @@
1
- #!/usr/bin/env node
2
- // This file is a CommonJS wrapper for the ES module CLI
3
- // It loads the actual CLI implementation using dynamic import()
4
-
5
- async function main() {
6
- try {
7
- // Use dynamic import to load the ES module CLI
8
- const cliPath = new URL('../bin/cli.mjs', import.meta.url).href;
9
- await import(cliPath);
10
- } catch (error) {
11
- console.error('Error loading CLI:', error);
12
- process.exit(1);
13
- }
14
- }
15
-
16
- main();