@nitronjs/framework 0.2.3 → 0.2.5

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 (68) hide show
  1. package/README.md +3 -1
  2. package/cli/create.js +88 -72
  3. package/cli/njs.js +14 -7
  4. package/lib/Auth/Auth.js +167 -0
  5. package/lib/Build/CssBuilder.js +9 -0
  6. package/lib/Build/FileAnalyzer.js +16 -0
  7. package/lib/Build/HydrationBuilder.js +17 -0
  8. package/lib/Build/Manager.js +15 -0
  9. package/lib/Build/colors.js +4 -0
  10. package/lib/Build/plugins.js +84 -20
  11. package/lib/Console/Commands/DevCommand.js +13 -9
  12. package/lib/Console/Commands/MakeCommand.js +24 -10
  13. package/lib/Console/Commands/MigrateCommand.js +0 -1
  14. package/lib/Console/Commands/MigrateFreshCommand.js +17 -25
  15. package/lib/Console/Commands/MigrateRollbackCommand.js +6 -3
  16. package/lib/Console/Commands/MigrateStatusCommand.js +6 -3
  17. package/lib/Console/Commands/SeedCommand.js +4 -2
  18. package/lib/Console/Commands/StorageLinkCommand.js +20 -5
  19. package/lib/Console/Output.js +142 -0
  20. package/lib/Core/Config.js +2 -1
  21. package/lib/Core/Paths.js +8 -0
  22. package/lib/Database/DB.js +141 -51
  23. package/lib/Database/Drivers/MySQLDriver.js +102 -157
  24. package/lib/Database/Migration/Checksum.js +3 -8
  25. package/lib/Database/Migration/MigrationRepository.js +25 -35
  26. package/lib/Database/Migration/MigrationRunner.js +56 -61
  27. package/lib/Database/Model.js +157 -83
  28. package/lib/Database/QueryBuilder.js +31 -0
  29. package/lib/Database/QueryValidation.js +36 -44
  30. package/lib/Database/Schema/Blueprint.js +25 -36
  31. package/lib/Database/Schema/Manager.js +31 -68
  32. package/lib/Database/Seeder/SeederRunner.js +12 -31
  33. package/lib/Date/DateTime.js +9 -0
  34. package/lib/Encryption/Encryption.js +52 -0
  35. package/lib/Faker/Faker.js +11 -0
  36. package/lib/Filesystem/Storage.js +120 -0
  37. package/lib/HMR/Server.js +81 -10
  38. package/lib/Hashing/Hash.js +41 -0
  39. package/lib/Http/Server.js +177 -152
  40. package/lib/Logging/{Manager.js → Log.js} +68 -80
  41. package/lib/Mail/Mail.js +187 -0
  42. package/lib/Route/Router.js +416 -0
  43. package/lib/Session/File.js +135 -233
  44. package/lib/Session/Manager.js +117 -171
  45. package/lib/Session/Memory.js +28 -38
  46. package/lib/Session/Session.js +71 -107
  47. package/lib/Support/Str.js +103 -0
  48. package/lib/Translation/Lang.js +54 -0
  49. package/lib/View/Client/hmr-client.js +94 -51
  50. package/lib/View/Client/nitronjs-icon.png +0 -0
  51. package/lib/View/{Manager.js → View.js} +44 -29
  52. package/lib/index.d.ts +42 -8
  53. package/lib/index.js +19 -12
  54. package/package.json +1 -1
  55. package/skeleton/app/Controllers/HomeController.js +7 -1
  56. package/skeleton/resources/css/global.css +1 -0
  57. package/skeleton/resources/views/Site/Home.tsx +456 -79
  58. package/skeleton/tsconfig.json +6 -1
  59. package/lib/Auth/Manager.js +0 -111
  60. package/lib/Database/Connection.js +0 -61
  61. package/lib/Database/Manager.js +0 -162
  62. package/lib/Encryption/Manager.js +0 -47
  63. package/lib/Filesystem/Manager.js +0 -74
  64. package/lib/Hashing/Manager.js +0 -25
  65. package/lib/Mail/Manager.js +0 -120
  66. package/lib/Route/Loader.js +0 -80
  67. package/lib/Route/Manager.js +0 -286
  68. package/lib/Translation/Manager.js +0 -49
@@ -1,86 +1,463 @@
1
- type HomeProps = {
2
- version?: string;
3
- };
1
+ "use client";
2
+
3
+ import "@css/global.css";
4
+ import { useEffect, useRef } from "react";
5
+
6
+ export const Meta = {
7
+ title: "Welcome to NitronJS",
8
+ }
9
+
10
+ export default function Home({ version }: { version: string }) {
11
+ const containerRef = useRef<HTMLDivElement>(null);
12
+ const canvasRef = useRef<HTMLCanvasElement>(null);
13
+
14
+ useEffect(() => {
15
+ const container = containerRef.current;
16
+ const canvas = canvasRef.current;
17
+ if (!container || !canvas) return;
18
+
19
+ const ctx = canvas.getContext("2d");
20
+ if (!ctx) return;
21
+
22
+ canvas.width = window.innerWidth;
23
+ canvas.height = window.innerHeight;
24
+
25
+ let mouseX = canvas.width / 2;
26
+ let mouseY = canvas.height / 2;
27
+
28
+ interface Star {
29
+ x: number;
30
+ y: number;
31
+ size: number;
32
+ speed: number;
33
+ opacity: number;
34
+ baseX: number;
35
+ baseY: number;
36
+ twinkleSpeed: number;
37
+ twinkleOffset: number;
38
+ driftX: number;
39
+ driftY: number;
40
+ velocityX: number;
41
+ velocityY: number;
42
+ }
43
+
44
+ interface Particle {
45
+ x: number;
46
+ y: number;
47
+ vx: number;
48
+ vy: number;
49
+ size: number;
50
+ life: number;
51
+ maxLife: number;
52
+ }
53
+
54
+ interface Nebula {
55
+ x: number;
56
+ y: number;
57
+ baseX: number;
58
+ baseY: number;
59
+ size: number;
60
+ speed: number;
61
+ color: { r: number; g: number; b: number };
62
+ opacity: number;
63
+ pulseSpeed: number;
64
+ pulseOffset: number;
65
+ driftX: number;
66
+ driftY: number;
67
+ }
68
+
69
+ const stars: Star[] = [];
70
+ const particles: Particle[] = [];
71
+ const nebulas: Nebula[] = [];
72
+ const starCount = 300;
73
+ const nebulaCount = 5;
74
+
75
+ for (let i = 0; i < starCount; i++) {
76
+ const x = Math.random() * canvas.width;
77
+ const y = Math.random() * canvas.height;
78
+
79
+ stars.push({
80
+ x,
81
+ y,
82
+ baseX: x,
83
+ baseY: y,
84
+ size: Math.random() * 2 + 0.5,
85
+ speed: Math.random() * 0.5 + 0.1,
86
+ opacity: Math.random() * 0.8 + 0.2,
87
+ twinkleSpeed: Math.random() * 0.02 + 0.01,
88
+ twinkleOffset: Math.random() * Math.PI * 2,
89
+ driftX: (Math.random() - 0.5) * 0.2,
90
+ driftY: (Math.random() - 0.5) * 0.2,
91
+ velocityX: 0,
92
+ velocityY: 0
93
+ });
94
+ }
95
+
96
+ // Create nebulas
97
+ const nebulaColors = [
98
+ { r: 147, g: 51, b: 234 }, // Purple
99
+ { r: 59, g: 130, b: 246 }, // Blue
100
+ { r: 236, g: 72, b: 153 }, // Pink
101
+ { r: 79, g: 70, b: 229 }, // Indigo
102
+ ];
103
+
104
+ for (let i = 0; i < nebulaCount; i++) {
105
+ const x = Math.random() * canvas.width;
106
+ const y = Math.random() * canvas.height;
107
+ const colorIndex = Math.floor(Math.random() * nebulaColors.length);
108
+
109
+ nebulas.push({
110
+ x,
111
+ y,
112
+ baseX: x,
113
+ baseY: y,
114
+ size: Math.random() * 250 + 200,
115
+ speed: Math.random() * 0.3 + 0.1,
116
+ color: nebulaColors[colorIndex],
117
+ opacity: Math.random() * 0.25 + 0.15,
118
+ pulseSpeed: Math.random() * 0.01 + 0.005,
119
+ pulseOffset: Math.random() * Math.PI * 2,
120
+ driftX: (Math.random() - 0.5) * 0.3,
121
+ driftY: (Math.random() - 0.5) * 0.3
122
+ });
123
+ }
124
+
125
+ const handleMouseMove = (e: MouseEvent) => {
126
+ const rect = container.getBoundingClientRect();
127
+ mouseX = e.clientX - rect.left;
128
+ mouseY = e.clientY - rect.top;
129
+ };
130
+
131
+ const handleClick = (e: MouseEvent) => {
132
+ const rect = container.getBoundingClientRect();
133
+ const clickX = e.clientX - rect.left;
134
+ const clickY = e.clientY - rect.top;
135
+
136
+ for (let i = 0; i < 30; i++) {
137
+ const angle = (Math.PI * 2 * i) / 30;
138
+ const speed = Math.random() * 3 + 2;
139
+
140
+ particles.push({
141
+ x: clickX,
142
+ y: clickY,
143
+ vx: Math.cos(angle) * speed,
144
+ vy: Math.sin(angle) * speed,
145
+ size: Math.random() * 2 + 1,
146
+ life: 1,
147
+ maxLife: Math.random() * 0.5 + 0.5
148
+ });
149
+ }
150
+
151
+ stars.forEach(star => {
152
+ const dx = star.baseX - clickX;
153
+ const dy = star.baseY - clickY;
154
+ const distance = Math.sqrt(dx * dx + dy * dy);
155
+
156
+ if (distance < 200) {
157
+ const angle = Math.atan2(dy, dx);
158
+ const force = (200 - distance) / 200;
159
+ star.velocityX += Math.cos(angle) * force * 8;
160
+ star.velocityY += Math.sin(angle) * force * 8;
161
+ }
162
+ });
163
+ };
164
+
165
+ const handleResize = () => {
166
+ canvas.width = window.innerWidth;
167
+ canvas.height = window.innerHeight;
168
+
169
+ stars.forEach(star => {
170
+ if (star.baseX > canvas.width) star.baseX = canvas.width - 50;
171
+ if (star.baseY > canvas.height) star.baseY = canvas.height - 50;
172
+ star.x = star.baseX;
173
+ star.y = star.baseY;
174
+ });
175
+
176
+ nebulas.forEach(nebula => {
177
+ if (nebula.baseX > canvas.width) nebula.baseX = canvas.width / 2;
178
+ if (nebula.baseY > canvas.height) nebula.baseY = canvas.height / 2;
179
+ nebula.x = nebula.baseX;
180
+ nebula.y = nebula.baseY;
181
+ });
182
+ };
183
+
184
+ const drawStar = (x: number, y: number, size: number, rotation: number) => {
185
+ const spikes = 5;
186
+ const outerRadius = size;
187
+ const innerRadius = size * 0.4;
188
+
189
+ ctx.save();
190
+ ctx.translate(x, y);
191
+ ctx.rotate(rotation);
192
+ ctx.beginPath();
193
+
194
+ for (let i = 0; i < spikes * 2; i++) {
195
+ const radius = i % 2 === 0 ? outerRadius : innerRadius;
196
+ const angle = (Math.PI * i) / spikes;
197
+ const px = Math.cos(angle) * radius;
198
+ const py = Math.sin(angle) * radius;
199
+
200
+ if (i === 0) {
201
+ ctx.moveTo(px, py);
202
+ }
203
+ else {
204
+ ctx.lineTo(px, py);
205
+ }
206
+ }
207
+
208
+ ctx.closePath();
209
+ ctx.fill();
210
+ ctx.restore();
211
+ };
212
+
213
+ const animate = () => {
214
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
215
+ ctx.fillStyle = "rgb(10, 10, 10)";
216
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
217
+
218
+ const time = Date.now() * 0.001;
219
+
220
+ // Reset all context properties at start of frame
221
+ ctx.shadowBlur = 0;
222
+ ctx.shadowColor = "transparent";
223
+ ctx.filter = "none";
224
+ ctx.globalCompositeOperation = "source-over";
225
+
226
+ // Draw nebulas first (background layer)
227
+ nebulas.forEach(nebula => {
228
+ const pulse = Math.sin(time * nebula.pulseSpeed + nebula.pulseOffset) * 0.3 + 0.7;
229
+ const currentSize = nebula.size * pulse;
230
+ const currentOpacity = nebula.opacity * pulse;
231
+
232
+ // Drift movement with boundary bounce
233
+ nebula.baseX += nebula.driftX;
234
+ nebula.baseY += nebula.driftY;
235
+
236
+ // Bounce off boundaries (with some padding for the nebula size)
237
+ const padding = 50;
238
+ if (nebula.baseX < padding) {
239
+ nebula.baseX = padding;
240
+ nebula.driftX *= -1;
241
+ }
242
+ if (nebula.baseX > canvas.width - padding) {
243
+ nebula.baseX = canvas.width - padding;
244
+ nebula.driftX *= -1;
245
+ }
246
+ if (nebula.baseY < padding) {
247
+ nebula.baseY = padding;
248
+ nebula.driftY *= -1;
249
+ }
250
+ if (nebula.baseY > canvas.height - padding) {
251
+ nebula.baseY = canvas.height - padding;
252
+ nebula.driftY *= -1;
253
+ }
254
+
255
+ nebula.x = nebula.baseX;
256
+ nebula.y = nebula.baseY;
257
+
258
+ const { r, g, b } = nebula.color;
259
+
260
+ ctx.globalCompositeOperation = "screen";
261
+
262
+ // Layer 1: Outer glow (largest, most diffuse)
263
+ const outerGradient = ctx.createRadialGradient(
264
+ nebula.x, nebula.y, 0,
265
+ nebula.x, nebula.y, currentSize * 1.2
266
+ );
267
+ outerGradient.addColorStop(0, `rgba(${r}, ${g}, ${b}, ${currentOpacity * 0.05})`);
268
+ outerGradient.addColorStop(0.4, `rgba(${r}, ${g}, ${b}, ${currentOpacity * 0.03})`);
269
+ outerGradient.addColorStop(1, `rgba(${r}, ${g}, ${b}, 0)`);
270
+
271
+ ctx.fillStyle = outerGradient;
272
+ ctx.filter = `blur(${45 + pulse * 20}px)`;
273
+ ctx.beginPath();
274
+ ctx.arc(nebula.x, nebula.y, currentSize * 1.2, 0, Math.PI * 2);
275
+ ctx.fill();
276
+
277
+ // Layer 2: Middle layer (medium blur)
278
+ const middleGradient = ctx.createRadialGradient(
279
+ nebula.x, nebula.y, 0,
280
+ nebula.x, nebula.y, currentSize * 0.7
281
+ );
282
+ middleGradient.addColorStop(0, `rgba(${r}, ${g}, ${b}, ${currentOpacity * 0.25})`);
283
+ middleGradient.addColorStop(0.5, `rgba(${r}, ${g}, ${b}, ${currentOpacity * 0.15})`);
284
+ middleGradient.addColorStop(1, `rgba(${r}, ${g}, ${b}, 0)`);
285
+
286
+ ctx.fillStyle = middleGradient;
287
+ ctx.filter = `blur(${25 + pulse * 10}px)`;
288
+ ctx.beginPath();
289
+ ctx.arc(nebula.x, nebula.y, currentSize * 0.7, 0, Math.PI * 2);
290
+ ctx.fill();
291
+
292
+ // Layer 3: Inner core (brightest, sharpest)
293
+ const coreGradient = ctx.createRadialGradient(
294
+ nebula.x, nebula.y, 0,
295
+ nebula.x, nebula.y, currentSize * 0.3
296
+ );
297
+ coreGradient.addColorStop(0, `rgba(${r}, ${g}, ${b}, ${currentOpacity * 0.6})`);
298
+ coreGradient.addColorStop(0.5, `rgba(${r}, ${g}, ${b}, ${currentOpacity * 0.3})`);
299
+ coreGradient.addColorStop(1, `rgba(${r}, ${g}, ${b}, 0)`);
300
+
301
+ ctx.fillStyle = coreGradient;
302
+ ctx.filter = `blur(${8 + pulse * 5}px)`;
303
+ ctx.beginPath();
304
+ ctx.arc(nebula.x, nebula.y, currentSize * 0.3, 0, Math.PI * 2);
305
+ ctx.fill();
306
+
307
+ // Layer 4: Bright center point
308
+ const centerGradient = ctx.createRadialGradient(
309
+ nebula.x, nebula.y, 0,
310
+ nebula.x, nebula.y, currentSize * 0.1
311
+ );
312
+ centerGradient.addColorStop(0, `rgba(${Math.min(255, r + 80)}, ${Math.min(255, g + 80)}, ${Math.min(255, b + 80)}, ${currentOpacity * 0.8})`);
313
+ centerGradient.addColorStop(0.7, `rgba(${r}, ${g}, ${b}, ${currentOpacity * 0.4})`);
314
+ centerGradient.addColorStop(1, `rgba(${r}, ${g}, ${b}, 0)`);
315
+
316
+ ctx.fillStyle = centerGradient;
317
+ ctx.filter = `blur(3px)`;
318
+ ctx.beginPath();
319
+ ctx.arc(nebula.x, nebula.y, currentSize * 0.1, 0, Math.PI * 2);
320
+ ctx.fill();
321
+
322
+ // Reset context state after nebula
323
+ ctx.filter = "none";
324
+ ctx.globalCompositeOperation = "source-over";
325
+ });
326
+
327
+ // Draw stars
328
+ stars.forEach((star) => {
329
+ star.baseX += star.driftX + star.velocityX;
330
+ star.baseY += star.driftY + star.velocityY;
331
+
332
+ star.velocityX *= 0.95;
333
+ star.velocityY *= 0.95;
334
+
335
+ if (star.baseX < 20) {
336
+ star.baseX = 20;
337
+ star.driftX *= -1;
338
+ star.velocityX *= -0.5;
339
+ }
340
+ if (star.baseX > canvas.width - 20) {
341
+ star.baseX = canvas.width - 20;
342
+ star.driftX *= -1;
343
+ star.velocityX *= -0.5;
344
+ }
345
+ if (star.baseY < 20) {
346
+ star.baseY = 20;
347
+ star.driftY *= -1;
348
+ star.velocityY *= -0.5;
349
+ }
350
+ if (star.baseY > canvas.height - 20) {
351
+ star.baseY = canvas.height - 20;
352
+ star.driftY *= -1;
353
+ star.velocityY *= -0.5;
354
+ }
355
+
356
+ const dx = mouseX - star.baseX;
357
+ const dy = mouseY - star.baseY;
358
+ const distance = Math.sqrt(dx * dx + dy * dy);
359
+ const maxDistance = 300;
360
+
361
+ const twinkle = Math.sin(time * star.twinkleSpeed + star.twinkleOffset) * 0.3 + 0.7;
362
+
363
+ if (distance < maxDistance) {
364
+ const force = (maxDistance - distance) / maxDistance;
365
+ star.x = star.baseX + dx * force * star.speed * 0.3;
366
+ star.y = star.baseY + dy * force * star.speed * 0.3;
367
+
368
+ const brightness = Math.min(1, star.opacity * twinkle + force * 0.5);
369
+ ctx.fillStyle = `rgba(147, 197, 253, ${brightness})`;
370
+ ctx.shadowBlur = 4 + force * 8;
371
+ ctx.shadowColor = "rgba(147, 197, 253, 0.8)";
372
+ }
373
+ else {
374
+ star.x += (star.baseX - star.x) * 0.1;
375
+ star.y += (star.baseY - star.y) * 0.1;
376
+
377
+ ctx.fillStyle = `rgba(255, 255, 255, ${star.opacity * twinkle})`;
378
+ ctx.shadowBlur = 0;
379
+ }
380
+
381
+ const rotation = time * star.twinkleSpeed * 2;
382
+ drawStar(star.x, star.y, star.size + 1, rotation);
383
+ });
384
+
385
+ // Draw particles
386
+ for (let i = particles.length - 1; i >= 0; i--) {
387
+ const particle = particles[i];
388
+
389
+ particle.x += particle.vx;
390
+ particle.y += particle.vy;
391
+ particle.vx *= 0.98;
392
+ particle.vy *= 0.98;
393
+ particle.life -= 0.02;
394
+
395
+ if (particle.life <= 0) {
396
+ particles.splice(i, 1);
397
+ continue;
398
+ }
399
+
400
+ const alpha = particle.life;
401
+ const gradient = ctx.createRadialGradient(
402
+ particle.x, particle.y, 0,
403
+ particle.x, particle.y, particle.size * 2
404
+ );
405
+ gradient.addColorStop(0, `rgba(147, 197, 253, ${alpha})`);
406
+ gradient.addColorStop(0.5, `rgba(96, 165, 250, ${alpha * 0.5})`);
407
+ gradient.addColorStop(1, `rgba(59, 130, 246, 0)`);
408
+
409
+ ctx.fillStyle = gradient;
410
+ ctx.shadowBlur = 8;
411
+ ctx.shadowColor = `rgba(147, 197, 253, ${alpha})`;
412
+
413
+ ctx.beginPath();
414
+ ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);
415
+ ctx.fill();
416
+
417
+ ctx.shadowBlur = 0;
418
+ }
419
+
420
+ requestAnimationFrame(animate);
421
+ };
422
+
423
+ container.addEventListener("mousemove", handleMouseMove);
424
+ container.addEventListener("click", handleClick);
425
+ window.addEventListener("resize", handleResize);
426
+ const animationId = requestAnimationFrame(animate);
427
+
428
+ return () => {
429
+ container.removeEventListener("mousemove", handleMouseMove);
430
+ container.removeEventListener("click", handleClick);
431
+ window.removeEventListener("resize", handleResize);
432
+ cancelAnimationFrame(animationId);
433
+ };
434
+ }, []);
4
435
 
5
- export default function Home({ version = "0.2.0" }: HomeProps) {
6
436
  return (
7
- <main style={{
8
- minHeight: "100vh",
9
- background: "#0a0a0a",
10
- fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
11
- color: "#e4e4e7",
12
- display: "flex",
13
- flexDirection: "column",
14
- alignItems: "center",
15
- justifyContent: "center",
16
- padding: "2rem",
17
- boxSizing: "border-box"
18
- }}>
19
- <div style={{
20
- width: 64,
21
- height: 64,
22
- background: "#fff",
23
- borderRadius: 14,
24
- display: "flex",
25
- alignItems: "center",
26
- justifyContent: "center",
27
- marginBottom: "2rem"
28
- }}>
29
- <svg width="36" height="36" viewBox="0 0 24 24" fill="none" stroke="#0a0a0a" strokeWidth="2.5">
30
- <path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/>
31
- </svg>
32
- </div>
437
+ <main ref={containerRef} className="relative w-full h-screen overflow-hidden flex flex-col items-center justify-center gap-8">
438
+ <canvas
439
+ ref={canvasRef}
440
+ className="absolute inset-0 bg-neutral-950"
441
+ />
33
442
 
34
- <h1 style={{
35
- fontSize: "2.5rem",
36
- fontWeight: 700,
37
- margin: 0,
38
- color: "#fff",
39
- letterSpacing: "-0.02em"
40
- }}>
41
- Welcome to NitronJS
42
- </h1>
43
-
44
- <p style={{
45
- fontSize: "1.1rem",
46
- color: "#71717a",
47
- maxWidth: 400,
48
- margin: "1.5rem 0 2rem",
49
- lineHeight: 1.6,
50
- textAlign: "center"
51
- }}>
52
- Your application is ready. Start building by editing the files in <code style={{ color: "#a1a1aa", background: "#1a1a1a", padding: "2px 6px", borderRadius: 4 }}>resources/views</code>
53
- </p>
54
-
55
- <a
56
- href="https://nitronjs.dev/docs"
57
- style={{
58
- display: "inline-flex",
59
- alignItems: "center",
60
- gap: "0.5rem",
61
- padding: "0.75rem 1.5rem",
62
- background: "#fff",
63
- color: "#0a0a0a",
64
- textDecoration: "none",
65
- fontWeight: 600,
66
- fontSize: "0.9rem",
67
- borderRadius: 8
68
- }}
69
- >
70
- Documentation
71
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
72
- <path d="M5 12h14M12 5l7 7-7 7"/>
73
- </svg>
74
- </a>
75
-
76
- <div style={{
77
- position: "fixed",
78
- bottom: "1.5rem",
79
- color: "#3f3f46",
80
- fontSize: "0.8rem"
81
- }}>
82
- v{version}
443
+ <div className="z-10 flex flex-col items-center justify-center gap-8 px-4">
444
+ <h1 className="text-center text-white text-6xl font-bold drop-shadow-2xl">
445
+ Welcome to <span className="bg-linear-to-r from-blue-500 to-purple-500 bg-clip-text text-transparent">NitronJS!</span>
446
+ </h1>
447
+ <p className="text-center text-zinc-400 text-xl drop-shadow-lg">
448
+ This is the home page of your NitronJS application.
449
+ </p>
450
+ <a
451
+ className="py-4 px-6 bg-white rounded-lg text-center text-neutral-900 font-semibold hover:scale-105 hover:shadow-2xl hover:shadow-blue-500/20 transition-all duration-300"
452
+ href="https://nitronjs.dev/docs"
453
+ target="_blank"
454
+ >
455
+ Read the Documentation
456
+ </a>
457
+ <p className="absolute bottom-10 left-1/2 -translate-x-1/2 text-center text-zinc-500 text-sm"><b>Version:</b> {version}</p>
83
458
  </div>
459
+
460
+ <div className="absolute bottom-0 left-0 right-0 h-px bg-linear-to-r from-transparent via-blue-500/50 to-transparent" />
84
461
  </main>
85
462
  );
86
463
  }
@@ -13,7 +13,12 @@
13
13
  "noEmit": true,
14
14
  "baseUrl": ".",
15
15
  "paths": {
16
- "@/*": ["./*"]
16
+ "@/*": ["./*"],
17
+ "@css/*": ["./resources/css/*"],
18
+ "@views/*": ["./resources/views/*"],
19
+ "@models/*": ["./app/Models/*"],
20
+ "@controllers/*": ["./app/Controllers/*"],
21
+ "@middlewares/*": ["./app/Middlewares/*"],
17
22
  }
18
23
  },
19
24
  "include": [
@@ -1,111 +0,0 @@
1
- import Hash from "../Hashing/Manager.js";
2
- import Config from "../Core/Config.js";
3
-
4
- class Auth {
5
- static setup(server) {
6
- server.decorateRequest('auth', null);
7
-
8
- server.addHook('onRequest', async (req, res) => {
9
- req.auth = {
10
- guard: (guardName = null) => ({
11
- attempt: (credentials) => Auth.attempt(req, credentials, guardName),
12
- logout: () => Auth.logout(req, guardName),
13
- user: () => Auth.user(req, guardName),
14
- check: () => Auth.check(req, guardName),
15
- home: () => Auth.home(res, guardName),
16
- redirect: () => Auth.redirect(res, guardName)
17
- }),
18
- attempt: (credentials) => Auth.attempt(req, credentials, null),
19
- logout: () => Auth.logout(req, null),
20
- user: () => Auth.user(req, null),
21
- check: () => Auth.check(req, null),
22
- home: () => Auth.home(res, null),
23
- redirect: () => Auth.redirect(res, null)
24
- };
25
- });
26
- }
27
-
28
- static #getAuthConfig() {
29
- return Config.all("auth");
30
- }
31
-
32
- static async attempt(req, credentials, guardName = null) {
33
- const authConfig = this.#getAuthConfig();
34
- const guard = guardName || authConfig.defaults.guard;
35
- const config = authConfig.guards[guard];
36
-
37
- if (!config) throw new Error(`Guard '${guard}' not configured`);
38
-
39
- const { provider, identifier } = config;
40
-
41
- const user = await provider
42
- .where(identifier, '=', credentials[identifier])
43
- .first();
44
-
45
- if (!user) return false;
46
-
47
- const isValid = await Hash.check(credentials.password, user.password);
48
- if (!isValid) return false;
49
-
50
- req.session.regenerate();
51
- req.session.set(`auth_${guard}`, user.id);
52
-
53
- return true;
54
- }
55
-
56
- static logout(req, guardName = null) {
57
- const authConfig = this.#getAuthConfig();
58
- const guard = guardName || authConfig.defaults.guard;
59
-
60
- req.session.set(`auth_${guard}`, null);
61
- }
62
-
63
- static async user(req, guardName = null) {
64
- const authConfig = this.#getAuthConfig();
65
- const guard = guardName || authConfig.defaults.guard;
66
- const userId = req.session.get(`auth_${guard}`) || null;
67
-
68
- if (!userId) return null;
69
-
70
- const config = authConfig.guards[guard];
71
-
72
- if (!config) return null;
73
-
74
- return await config.provider.find(userId);
75
- }
76
-
77
- static check(req, guardName = null) {
78
- const authConfig = this.#getAuthConfig();
79
- const guard = guardName || authConfig.defaults.guard;
80
-
81
- return req.session.get(`auth_${guard}`) !== null && req.session.get(`auth_${guard}`) !== undefined;
82
- }
83
-
84
- static home(res, guardName = null) {
85
- const authConfig = this.#getAuthConfig();
86
- const guard = guardName || authConfig.defaults.guard;
87
- const config = authConfig.guards[guard];
88
-
89
- return res.redirect(this.#resolveUrl(config?.home));
90
- }
91
-
92
- static redirect(res, guardName = null) {
93
- const authConfig = this.#getAuthConfig();
94
- const guard = guardName || authConfig.defaults.guard;
95
- const config = authConfig.guards[guard];
96
-
97
- return res.redirect(this.#resolveUrl(config?.redirect));
98
- }
99
-
100
- static #resolveUrl(path) {
101
- if (!path) return '/';
102
-
103
- if (path.startsWith('/') || path.startsWith('http://') || path.startsWith('https://')) {
104
- return path;
105
- }
106
-
107
- return route(path);
108
- }
109
- }
110
-
111
- export default Auth;