arikajs 0.0.3 → 0.0.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 (111) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +55 -1
  3. package/dist/Application.d.ts +17 -0
  4. package/dist/Application.d.ts.map +1 -1
  5. package/dist/Application.js +132 -22
  6. package/dist/Application.js.bak +301 -0
  7. package/dist/Application.js.map +1 -1
  8. package/dist/Contracts/Application.d.ts +6 -0
  9. package/dist/Contracts/Application.d.ts.map +1 -1
  10. package/dist/helpers.d.ts +47 -0
  11. package/dist/helpers.d.ts.map +1 -0
  12. package/dist/helpers.js +104 -0
  13. package/dist/helpers.js.map +1 -0
  14. package/dist/http/Handler.d.ts +18 -1
  15. package/dist/http/Handler.d.ts.map +1 -1
  16. package/dist/http/Handler.js +113 -4
  17. package/dist/http/Handler.js.map +1 -1
  18. package/dist/http/Kernel.d.ts.map +1 -1
  19. package/dist/http/Kernel.js +24 -11
  20. package/dist/http/Kernel.js.map +1 -1
  21. package/dist/http/Middleware/ServeStaticMiddleware.d.ts +7 -0
  22. package/dist/http/Middleware/ServeStaticMiddleware.d.ts.map +1 -0
  23. package/dist/http/Middleware/ServeStaticMiddleware.js +36 -0
  24. package/dist/http/Middleware/ServeStaticMiddleware.js.map +1 -0
  25. package/dist/http/Middleware/VerifyCsrfToken.d.ts +36 -0
  26. package/dist/http/Middleware/VerifyCsrfToken.d.ts.map +1 -0
  27. package/dist/http/Middleware/VerifyCsrfToken.js +96 -0
  28. package/dist/http/Middleware/VerifyCsrfToken.js.map +1 -0
  29. package/dist/http/Middleware/ViewMiddleware.d.ts.map +1 -1
  30. package/dist/http/Middleware/ViewMiddleware.js +13 -0
  31. package/dist/http/Middleware/ViewMiddleware.js.map +1 -1
  32. package/dist/http/views/errors/401.ark.html +57 -0
  33. package/dist/http/views/errors/403.ark.html +54 -0
  34. package/dist/http/views/errors/404.ark.html +179 -0
  35. package/dist/http/views/errors/419.ark.html +54 -0
  36. package/dist/http/views/errors/429.ark.html +54 -0
  37. package/dist/http/views/errors/500.ark.html +54 -0
  38. package/dist/http/views/errors/503.ark.html +49 -0
  39. package/dist/index.d.ts +20 -4
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +76 -2
  42. package/dist/index.js.map +1 -1
  43. package/dist/providers/CacheServiceProvider.d.ts +12 -0
  44. package/dist/providers/CacheServiceProvider.d.ts.map +1 -0
  45. package/dist/providers/CacheServiceProvider.js +29 -0
  46. package/dist/providers/CacheServiceProvider.js.map +1 -0
  47. package/dist/providers/DatabaseServiceProvider.d.ts.map +1 -1
  48. package/dist/providers/DatabaseServiceProvider.js +6 -1
  49. package/dist/providers/DatabaseServiceProvider.js.map +1 -1
  50. package/dist/providers/EventsServiceProvider.d.ts +6 -0
  51. package/dist/providers/EventsServiceProvider.d.ts.map +1 -0
  52. package/dist/providers/EventsServiceProvider.js +20 -0
  53. package/dist/providers/EventsServiceProvider.js.map +1 -0
  54. package/dist/providers/FrameworkServiceProvider.d.ts.map +1 -1
  55. package/dist/providers/FrameworkServiceProvider.js +16 -0
  56. package/dist/providers/FrameworkServiceProvider.js.map +1 -1
  57. package/dist/providers/HttpServiceProvider.d.ts.map +1 -1
  58. package/dist/providers/HttpServiceProvider.js +6 -4
  59. package/dist/providers/HttpServiceProvider.js.map +1 -1
  60. package/dist/providers/MailServiceProvider.d.ts +12 -0
  61. package/dist/providers/MailServiceProvider.d.ts.map +1 -0
  62. package/dist/providers/MailServiceProvider.js +32 -0
  63. package/dist/providers/MailServiceProvider.js.map +1 -0
  64. package/dist/providers/QueueServiceProvider.d.ts +12 -0
  65. package/dist/providers/QueueServiceProvider.d.ts.map +1 -0
  66. package/dist/providers/QueueServiceProvider.js +37 -0
  67. package/dist/providers/QueueServiceProvider.js.map +1 -0
  68. package/dist/providers/SchedulerServiceProvider.d.ts +6 -0
  69. package/dist/providers/SchedulerServiceProvider.d.ts.map +1 -0
  70. package/dist/providers/SchedulerServiceProvider.js +19 -0
  71. package/dist/providers/SchedulerServiceProvider.js.map +1 -0
  72. package/dist/providers/SessionServiceProvider.d.ts +12 -0
  73. package/dist/providers/SessionServiceProvider.d.ts.map +1 -0
  74. package/dist/providers/SessionServiceProvider.js +98 -0
  75. package/dist/providers/SessionServiceProvider.js.map +1 -0
  76. package/dist/providers/TranslationServiceProvider.d.ts +12 -0
  77. package/dist/providers/TranslationServiceProvider.d.ts.map +1 -0
  78. package/dist/providers/TranslationServiceProvider.js +51 -0
  79. package/dist/providers/TranslationServiceProvider.js.map +1 -0
  80. package/dist/providers/ViewServiceProvider.d.ts.map +1 -1
  81. package/dist/providers/ViewServiceProvider.js +3 -1
  82. package/dist/providers/ViewServiceProvider.js.map +1 -1
  83. package/package.json +41 -24
  84. package/src/Application.ts +156 -21
  85. package/src/Contracts/Application.ts +6 -0
  86. package/src/helpers.ts +106 -0
  87. package/src/http/Handler.ts +87 -4
  88. package/src/http/Kernel.ts +26 -13
  89. package/src/http/Middleware/ServeStaticMiddleware.ts +34 -0
  90. package/src/http/Middleware/VerifyCsrfToken.ts +101 -0
  91. package/src/http/Middleware/ViewMiddleware.ts +11 -0
  92. package/src/http/views/errors/401.ark.html +57 -0
  93. package/src/http/views/errors/403.ark.html +54 -0
  94. package/src/http/views/errors/404.ark.html +179 -0
  95. package/src/http/views/errors/419.ark.html +54 -0
  96. package/src/http/views/errors/429.ark.html +54 -0
  97. package/src/http/views/errors/500.ark.html +54 -0
  98. package/src/http/views/errors/503.ark.html +49 -0
  99. package/src/index.ts +44 -5
  100. package/src/providers/CacheServiceProvider.ts +29 -0
  101. package/src/providers/DatabaseServiceProvider.ts +7 -1
  102. package/src/providers/EventsServiceProvider.ts +19 -0
  103. package/src/providers/FrameworkServiceProvider.ts +16 -0
  104. package/src/providers/HttpServiceProvider.ts +6 -4
  105. package/src/providers/MailServiceProvider.ts +33 -0
  106. package/src/providers/QueueServiceProvider.ts +36 -0
  107. package/src/providers/SchedulerServiceProvider.ts +18 -0
  108. package/src/providers/SessionServiceProvider.ts +68 -0
  109. package/src/providers/TranslationServiceProvider.ts +51 -0
  110. package/src/providers/ViewServiceProvider.ts +5 -1
  111. package/tests/Framework.test.ts +20 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,37 @@
1
+ # arikajs
2
+
3
+ ## 0.0.5
4
+
5
+ ### Patch Changes
6
+
7
+ - feat: implement CSRF protection and standardized middleware architecture
8
+
9
+ - Added session-based CSRF protection middleware.
10
+ - Refactored middleware into project-level stubs for better customization.
11
+ - Standardized auth controller stubs.
12
+ - Enhanced CLI project scaffolding.
13
+ - Added session and localization packages.
14
+
15
+ - Updated dependencies
16
+ - @arikajs/auth@0.0.5
17
+ - @arikajs/authorization@0.0.5
18
+ - @arikajs/cache@0.0.5
19
+ - @arikajs/cli@0.0.5
20
+ - @arikajs/console@0.0.5
21
+ - @arikajs/database@0.0.5
22
+ - @arikajs/dispatcher@0.0.5
23
+ - @arikajs/encryption@0.0.5
24
+ - @arikajs/events@0.0.5
25
+ - @arikajs/foundation@0.0.5
26
+ - @arikajs/http@0.0.5
27
+ - @arikajs/localization@0.0.5
28
+ - @arikajs/logging@0.0.5
29
+ - @arikajs/mail@0.0.5
30
+ - @arikajs/middleware@0.0.5
31
+ - @arikajs/queue@0.0.5
32
+ - @arikajs/router@0.0.5
33
+ - @arikajs/scheduler@0.0.5
34
+ - @arikajs/session@0.0.5
35
+ - @arikajs/storage@0.0.5
36
+ - @arikajs/validation@0.0.5
37
+ - @arikajs/view@0.0.5
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  <div align="center">
4
4
 
5
- ![ArikaJS Logo](https://via.placeholder.com/200x200?text=ArikaJS)
5
+ <img src="../cli/templates/app/public/assets/img/logo.png" alt="ArikaJS Logo" width="400">
6
6
 
7
7
  **A Modern, Elegant Web Framework for Node.js**
8
8
 
@@ -38,7 +38,9 @@ ArikaJS is a **modern, elegant, and powerful** Node.js framework that brings ent
38
38
  - 🔄 **Queue System** - Background job processing
39
39
  - 📦 **Service Providers** - Modular application architecture
40
40
  - 🎨 **Template Engine** - Flexible view rendering
41
+ - ⚡ **Event System** - Decouple your application with powerful events and listeners
41
42
  - 🧪 **Testing Ready** - Built with testing in mind
43
+ - 🛠️ **Global Helpers** - Intuitive functions like `app()`, `config()`, and `route()`
42
44
 
43
45
  ---
44
46
 
@@ -267,6 +269,23 @@ export class PaymentServiceProvider extends ServiceProvider {
267
269
  }
268
270
  ```
269
271
 
272
+ ### 🛠️ Global Helpers
273
+
274
+ ArikaJS provides several global helper functions to make your code more concise:
275
+
276
+ ```typescript
277
+ import { app, config, route } from 'arikajs';
278
+
279
+ // Access the application container
280
+ const userService = app().make(UserService);
281
+
282
+ // Get configuration values with defaults
283
+ const debug = config('app.debug', false);
284
+
285
+ // Generate URLs for named routes
286
+ const profileUrl = route('users.show', { id: 1 });
287
+ ```
288
+
270
289
  ### Database Migrations
271
290
 
272
291
  Manage your database schema with migrations:
@@ -382,6 +401,40 @@ For guides and examples, check out:
382
401
 
383
402
  ---
384
403
 
404
+ ## 🏗 Architecture
405
+
406
+ ```text
407
+ arikajs/
408
+ ├── src/
409
+ │ ├── Contracts
410
+ │ │ └── Application.ts
411
+ │ ├── http
412
+ │ │ ├── Middleware
413
+ │ │ │ ├── RequestLoggingMiddleware.ts
414
+ │ │ │ ├── ValidateRequestMiddleware.ts
415
+ │ │ │ └── ViewMiddleware.ts
416
+ │ │ ├── Handler.ts
417
+ │ │ └── Kernel.ts
418
+ │ ├── providers
419
+ │ │ ├── AuthServiceProvider.ts
420
+ │ │ ├── DatabaseServiceProvider.ts
421
+ │ │ ├── EventsServiceProvider.ts
422
+ │ │ ├── FrameworkServiceProvider.ts
423
+ │ │ ├── HttpServiceProvider.ts
424
+ │ │ ├── LoggingServiceProvider.ts
425
+ │ │ ├── SchedulerServiceProvider.ts
426
+ │ │ ├── ValidationServiceProvider.ts
427
+ │ │ └── ViewServiceProvider.ts
428
+ │ ├── Application.ts
429
+ │ ├── createApp.ts
430
+ │ ├── helpers.ts
431
+ │ └── index.ts
432
+ ├── tests/
433
+ ├── package.json
434
+ ├── tsconfig.json
435
+ └── README.md
436
+ ```
437
+
385
438
  ## 🤝 Contributing
386
439
 
387
440
  We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
@@ -430,3 +483,4 @@ ArikaJS draws inspiration from the best practices and patterns of modern web fra
430
483
  [GitHub](https://github.com/arikajs) • [npm](https://www.npmjs.com/package/arikajs)
431
484
 
432
485
  </div>
486
+
@@ -2,8 +2,13 @@ import { Application as FoundationApplication } from '@arikajs/foundation';
2
2
  import { Router } from '@arikajs/router';
3
3
  import { Application as ApplicationContract } from './Contracts/Application';
4
4
  export declare class Application extends FoundationApplication implements ApplicationContract {
5
+ static readonly VERSION = "0.0.4";
5
6
  protected router: Router;
7
+ protected server?: any;
8
+ protected isTerminating: boolean;
6
9
  constructor(basePath?: string);
10
+ boot(): Promise<void>;
11
+ version(): string;
7
12
  /**
8
13
  * Map a GET route.
9
14
  */
@@ -16,14 +21,26 @@ export declare class Application extends FoundationApplication implements Applic
16
21
  * Map a PUT route.
17
22
  */
18
23
  put(path: string, handler: any): import("@arikajs/router").RouteEntry;
24
+ patch(path: string, handler: any): import("@arikajs/router").RouteEntry;
19
25
  /**
20
26
  * Map a DELETE route.
21
27
  */
22
28
  delete(path: string, handler: any): import("@arikajs/router").RouteEntry;
29
+ options(path: string, handler: any): import("@arikajs/router").RouteEntry;
30
+ match(methods: string[], path: string, handler: any): import("@arikajs/router").RouteEntry[];
23
31
  /**
24
32
  * Start the HTTP server.
25
33
  */
26
34
  listen(port?: number): Promise<void>;
35
+ protected displayBanner(port: number): void;
36
+ /**
37
+ * Get the HTTP server callback for raw http.createServer() usage.
38
+ */
39
+ getCallback(): (req: any, res: any) => void;
40
+ /**
41
+ * Gracefully terminate the application.
42
+ */
43
+ terminate(): Promise<void>;
27
44
  /**
28
45
  * Get the router instance.
29
46
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Application.d.ts","sourceRoot":"","sources":["../src/Application.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,IAAI,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAS,MAAM,iBAAiB,CAAC;AAGhD,OAAO,EAAE,WAAW,IAAI,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE7E,qBAAa,WAAY,SAAQ,qBAAsB,YAAW,mBAAmB;IACjF,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEb,QAAQ,GAAE,MAAsB;IAa5C;;OAEG;IACI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG;IAIrC;;OAEG;IACI,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG;IAItC;;OAEG;IACI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG;IAIrC;;OAEG;IACI,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG;IAIxC;;OAEG;IACU,MAAM,CAAC,IAAI,GAAE,MAAa;IAyCvC;;OAEG;IACI,SAAS,IAAI,MAAM;CAG7B"}
1
+ {"version":3,"file":"Application.d.ts","sourceRoot":"","sources":["../src/Application.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,IAAI,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAS,MAAM,iBAAiB,CAAC;AAGhD,OAAO,EAAE,WAAW,IAAI,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAG7E,qBAAa,WAAY,SAAQ,qBAAsB,YAAW,mBAAmB;IACjF,gBAAuB,OAAO,WAAW;IAEzC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC;IACvB,SAAS,CAAC,aAAa,EAAE,OAAO,CAAS;gBAE7B,QAAQ,GAAE,MAAsB;IAc/B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B,OAAO,IAAI,MAAM;IAIxB;;OAEG;IACI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG;IAIrC;;OAEG;IACI,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG;IAItC;;OAEG;IACI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG;IAI9B,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG;IAIvC;;OAEG;IACI,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG;IAIjC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG;IAIlC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG;IAI1D;;OAEG;IACU,MAAM,CAAC,IAAI,GAAE,MAAa;IA4BvC,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM;IAgBpC;;OAEG;IACI,WAAW,KAmBN,KAAK,GAAG,EAAE,KAAK,GAAG;IAwB9B;;OAEG;IACU,SAAS;IAuDtB;;OAEG;IACI,SAAS,IAAI,MAAM;CAG7B"}
@@ -38,9 +38,12 @@ const foundation_1 = require("@arikajs/foundation");
38
38
  const router_1 = require("@arikajs/router");
39
39
  const FrameworkServiceProvider_1 = require("./providers/FrameworkServiceProvider");
40
40
  const logging_1 = require("@arikajs/logging");
41
+ const helpers_1 = require("./helpers");
41
42
  class Application extends foundation_1.Application {
42
43
  constructor(basePath = process.cwd()) {
43
44
  super(basePath);
45
+ this.isTerminating = false;
46
+ (0, helpers_1.setApp)(this);
44
47
  // Initialize Core Components
45
48
  this.router = new router_1.Router(this.getContainer());
46
49
  // Register within container
@@ -48,6 +51,15 @@ class Application extends foundation_1.Application {
48
51
  // Register Core Framework Provider
49
52
  this.register(FrameworkServiceProvider_1.FrameworkServiceProvider);
50
53
  }
54
+ async boot() {
55
+ if (this.isBooted())
56
+ return;
57
+ await super.boot();
58
+ this.router.sync();
59
+ }
60
+ version() {
61
+ return Application.VERSION;
62
+ }
51
63
  /**
52
64
  * Map a GET route.
53
65
  */
@@ -66,12 +78,21 @@ class Application extends foundation_1.Application {
66
78
  put(path, handler) {
67
79
  return router_1.Route.put(path, handler);
68
80
  }
81
+ patch(path, handler) {
82
+ return router_1.Route.patch(path, handler);
83
+ }
69
84
  /**
70
85
  * Map a DELETE route.
71
86
  */
72
87
  delete(path, handler) {
73
88
  return router_1.Route.delete(path, handler);
74
89
  }
90
+ options(path, handler) {
91
+ return router_1.Route.options(path, handler);
92
+ }
93
+ match(methods, path, handler) {
94
+ return router_1.Route.match(methods, path, handler);
95
+ }
75
96
  /**
76
97
  * Start the HTTP server.
77
98
  */
@@ -84,33 +105,121 @@ class Application extends foundation_1.Application {
84
105
  const { Kernel } = await Promise.resolve().then(() => __importStar(require('./http/Kernel')));
85
106
  // Resolve Kernel from the container
86
107
  const kernel = this.make(Kernel);
87
- const server = http.createServer(async (req, res) => {
88
- // Instantiate Request and Response
89
- // In a future refactor, these could also be resolved from factories
90
- const request = new Request(this, req);
91
- const response = new Response(res);
92
- try {
93
- const finalResponse = await kernel.handle(request, response);
94
- kernel.terminate(request, finalResponse);
95
- }
96
- catch (error) {
97
- if (!res.headersSent) {
98
- res.writeHead(500, { 'Content-Type': 'application/json' });
99
- res.end(JSON.stringify({
100
- error: 'Internal Server Error',
101
- message: error.message,
102
- stack: process.env.NODE_ENV === 'development' ? error.stack : undefined
103
- }));
104
- }
105
- }
106
- });
108
+ const callback = this.getCallback();
109
+ this.server = http.createServer(callback);
110
+ // Graceful shutdown
111
+ const shutdown = () => this.terminate();
112
+ process.on('SIGINT', shutdown);
113
+ process.on('SIGTERM', shutdown);
107
114
  return new Promise((resolve) => {
108
- server.listen(port, () => {
109
- logging_1.Log.info(`ArikaJS application listening on http://localhost:${port}`);
115
+ this.server.listen(port, () => {
116
+ this.displayBanner(port);
110
117
  resolve();
111
118
  });
112
119
  });
113
120
  }
121
+ displayBanner(port) {
122
+ const env = this.config().get('app.env', 'development');
123
+ console.log(`\x1b[38;5;99m
124
+ _ _ _ _ ____
125
+ / \\ _ __(_) | ____ _ | / ___|
126
+ / _ \\ | '__| | |/ / _\` | | \\___ \\
127
+ / ___ \\| | | | < (_| | __| |___) |
128
+ /_/ \\_\\_| |_|_|\\_\\__,_| |____|____/
129
+ \x1b[0m`);
130
+ console.log(` \x1b[1mArikaJS Framework\x1b[0m \x1b[38;5;99mv${this.version()}\x1b[0m`);
131
+ console.log(` \x1b[90mEnvironment:\x1b[0m \x1b[33m${env}\x1b[0m`);
132
+ console.log(` \x1b[90mLocal URL:\x1b[0m \x1b[36mhttp://localhost:${port}\x1b[0m`);
133
+ console.log('');
134
+ }
135
+ /**
136
+ * Get the HTTP server callback for raw http.createServer() usage.
137
+ */
138
+ getCallback() {
139
+ if (!this.isBooted()) {
140
+ throw new Error('Application must be booted before calling getCallback()');
141
+ }
142
+ const { Kernel } = require('./http/Kernel');
143
+ const kernel = this.make(Kernel);
144
+ const { ObjectPool } = require('@arikajs/foundation');
145
+ const { Request: ArikaRequest, Response: ArikaResponse, RawResponse } = require('@arikajs/http');
146
+ const requestPool = new ObjectPool(() => new ArikaRequest(this, null), (obj) => obj.reset(null));
147
+ const responsePool = new ObjectPool(() => new ArikaResponse(null), (obj) => obj.reset(null));
148
+ return (req, res) => {
149
+ const request = requestPool.acquire();
150
+ const response = responsePool.acquire();
151
+ request.reset(req);
152
+ response.reset(res);
153
+ const handleRequest = async () => {
154
+ try {
155
+ const finalResponse = await kernel.handle(request, response);
156
+ kernel.terminate(request, finalResponse);
157
+ }
158
+ catch (error) {
159
+ if (!res.headersSent) {
160
+ res.writeHead(500, { 'Content-Type': 'application/json' });
161
+ res.end(JSON.stringify({ error: 'Internal Server Error', message: error.message }));
162
+ }
163
+ }
164
+ finally {
165
+ requestPool.release(request);
166
+ responsePool.release(response);
167
+ }
168
+ };
169
+ handleRequest();
170
+ };
171
+ }
172
+ /**
173
+ * Gracefully terminate the application.
174
+ */
175
+ async terminate() {
176
+ if (this.isTerminating)
177
+ return;
178
+ this.isTerminating = true;
179
+ if (this.server) {
180
+ // Close all active connections to speed up shutdown (Node 18.2+)
181
+ if (typeof this.server.closeAllConnections === 'function') {
182
+ this.server.closeAllConnections();
183
+ }
184
+ // Force close idle connections
185
+ if (typeof this.server.closeIdleConnections === 'function') {
186
+ this.server.closeIdleConnections();
187
+ }
188
+ await new Promise((resolve) => {
189
+ // Set a timeout to force resolve if server doesn't close in time
190
+ const timeout = setTimeout(() => {
191
+ logging_1.Log.warning('HTTP server forced to close due to timeout.');
192
+ resolve();
193
+ }, 1000);
194
+ this.server.close(() => {
195
+ clearTimeout(timeout);
196
+ logging_1.Log.info('HTTP server closed.');
197
+ resolve();
198
+ });
199
+ });
200
+ }
201
+ // Close database connections
202
+ if (this.has('db')) {
203
+ try {
204
+ const db = this.make('db');
205
+ if (typeof db.closeAll === 'function') {
206
+ await db.closeAll();
207
+ }
208
+ }
209
+ catch (e) { }
210
+ }
211
+ // Potential for other service termination (Queues, etc.)
212
+ // Remove signal listeners to prevent double triggers during exit
213
+ process.removeAllListeners('SIGINT');
214
+ process.removeAllListeners('SIGTERM');
215
+ // If we are in a testing or specific environment, we might not want to exit
216
+ if (process.env.NODE_ENV !== 'test') {
217
+ // Give a short delay for logs to flush before exiting
218
+ setTimeout(() => {
219
+ process.exit(0);
220
+ }, 50);
221
+ }
222
+ }
114
223
  /**
115
224
  * Get the router instance.
116
225
  */
@@ -119,4 +228,5 @@ class Application extends foundation_1.Application {
119
228
  }
120
229
  }
121
230
  exports.Application = Application;
231
+ Application.VERSION = '0.0.4';
122
232
  //# sourceMappingURL=Application.js.map
@@ -0,0 +1,301 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.Application = void 0;
37
+ const foundation_1 = require("@arikajs/foundation");
38
+ const router_1 = require("@arikajs/router");
39
+ const FrameworkServiceProvider_1 = require("./providers/FrameworkServiceProvider");
40
+ const logging_1 = require("@arikajs/logging");
41
+ const helpers_1 = require("./helpers");
42
+ class Application extends foundation_1.Application {
43
+ constructor(basePath = process.cwd()) {
44
+ super(basePath);
45
+ this.isTerminating = false;
46
+ (0, helpers_1.setApp)(this);
47
+ // Initialize Core Components
48
+ this.router = new router_1.Router(this.getContainer());
49
+ // Register within container
50
+ this.instance(router_1.Router, this.router);
51
+ // Register Core Framework Provider
52
+ this.register(FrameworkServiceProvider_1.FrameworkServiceProvider);
53
+ }
54
+ version() {
55
+ return Application.VERSION;
56
+ }
57
+ /**
58
+ * Map a GET route.
59
+ */
60
+ get(path, handler) {
61
+ return router_1.Route.get(path, handler);
62
+ }
63
+ /**
64
+ * Map a POST route.
65
+ */
66
+ post(path, handler) {
67
+ return router_1.Route.post(path, handler);
68
+ }
69
+ /**
70
+ * Map a PUT route.
71
+ */
72
+ put(path, handler) {
73
+ return router_1.Route.put(path, handler);
74
+ }
75
+ patch(path, handler) {
76
+ return router_1.Route.patch(path, handler);
77
+ }
78
+ /**
79
+ * Map a DELETE route.
80
+ */
81
+ delete(path, handler) {
82
+ return router_1.Route.delete(path, handler);
83
+ }
84
+ options(path, handler) {
85
+ return router_1.Route.options(path, handler);
86
+ }
87
+ match(methods, path, handler) {
88
+ return router_1.Route.match(methods, path, handler);
89
+ }
90
+ /**
91
+ * Start the HTTP server.
92
+ */
93
+ async listen(port = 3000) {
94
+ if (!this.isBooted()) {
95
+ await this.boot();
96
+ }
97
+ const http = await Promise.resolve().then(() => __importStar(require('node:http')));
98
+ const { Request: ArikaRequest, Response: ArikaResponse } = await Promise.resolve().then(() => __importStar(require('@arikajs/http')));
99
+ const { Kernel } = await Promise.resolve().then(() => __importStar(require('./http/Kernel')));
100
+ const { ObjectPool } = await Promise.resolve().then(() => __importStar(require('@arikajs/foundation')));
101
+ // Resolve Kernel
102
+ const kernel = this.make(Kernel);
103
+ // Initialize Object Pools
104
+ const requestPool = new ObjectPool(() => new ArikaRequest(this, null), (obj) => obj.reset(null));
105
+ const responsePool = new ObjectPool(() => new ArikaResponse(null), (obj) => obj.reset(null));
106
+ const { RawResponse } = await Promise.resolve().then(() => __importStar(require('@arikajs/http')));
107
+ this.server = http.createServer((req, res) => {
108
+ // ── ULTRA FAST PATH ──
109
+ const router = this.getRouter();
110
+ const matched = router.match(req.method, req.url);
111
+ if (matched) {
112
+ const dispatcher = router.getDispatcher();
113
+ const plan = dispatcher.executionPlans.get(matched.route);
114
+ // Routes with no middleware and no parameter binders
115
+ if (plan && !plan.hasMiddleware && dispatcher.parameterBinders.size === 0) {
116
+ const result = plan.handler(null, null, matched.params);
117
+ // Optimization: Use RawResponse to bypass ServerResponse machinery
118
+ const raw = new RawResponse(res);
119
+ const buffer = dispatcher.responseResolver.bufferCache.get(plan.route);
120
+ if (buffer) {
121
+ raw.sendUltra(buffer);
122
+ }
123
+ else {
124
+ // Fallback to standard resolver for first-time or complex results
125
+ const response = responsePool.acquire();
126
+ response.reset(res);
127
+ dispatcher.responseResolver.resolve(result, response, plan.route);
128
+ responsePool.release(response);
129
+ }
130
+ return;
131
+ }
132
+ }
133
+ // ── STANDARD PATH (Kernel/DI/Middleware) ──
134
+ const request = requestPool.acquire();
135
+ const response = responsePool.acquire();
136
+ request.reset(req);
137
+ response.reset(res);
138
+ const handleRequest = async () => {
139
+ try {
140
+ const finalResponse = await kernel.handle(request, response);
141
+ kernel.terminate(request, finalResponse);
142
+ }
143
+ catch (error) {
144
+ if (!res.headersSent) {
145
+ res.writeHead(500, { 'Content-Type': 'application/json' });
146
+ res.end(JSON.stringify({ error: 'Internal Server Error', message: error.message }));
147
+ }
148
+ }
149
+ finally {
150
+ requestPool.release(request);
151
+ responsePool.release(response);
152
+ }
153
+ };
154
+ handleRequest();
155
+ });
156
+ // Graceful shutdown
157
+ const shutdown = () => this.terminate();
158
+ process.on('SIGINT', shutdown);
159
+ process.on('SIGTERM', shutdown);
160
+ return new Promise((resolve) => {
161
+ this.server.listen(port, () => {
162
+ this.displayBanner(port);
163
+ resolve();
164
+ });
165
+ });
166
+ }
167
+ displayBanner(port) {
168
+ const env = this.config().get('app.env', 'development');
169
+ console.log(`\x1b[38;5;99m
170
+ _ _ _ _ ____
171
+ / \\ _ __(_) | ____ _ | / ___|
172
+ / _ \\ | '__| | |/ / _\` | | \\___ \\
173
+ / ___ \\| | | | < (_| | __| |___) |
174
+ /_/ \\_\\_| |_|_|\\_\\__,_| |____|____/
175
+ \x1b[0m`);
176
+ console.log(` \x1b[1mArikaJS Framework\x1b[0m \x1b[38;5;99mv${this.version()}\x1b[0m`);
177
+ console.log(` \x1b[90mEnvironment:\x1b[0m \x1b[33m${env}\x1b[0m`);
178
+ console.log(` \x1b[90mLocal URL:\x1b[0m \x1b[36mhttp://localhost:${port}\x1b[0m`);
179
+ console.log('');
180
+ }
181
+ /**
182
+ * Get the HTTP server callback for raw http.createServer() usage.
183
+ */
184
+ getCallback() {
185
+ if (!this.isBooted()) {
186
+ throw new Error('Application must be booted before calling getCallback()');
187
+ }
188
+ const { Kernel } = require('./http/Kernel');
189
+ const kernel = this.make(Kernel);
190
+ const { ObjectPool } = require('@arikajs/foundation');
191
+ const { Request: ArikaRequest, Response: ArikaResponse, RawResponse } = require('@arikajs/http');
192
+ const requestPool = new ObjectPool(() => new ArikaRequest(this, null), (obj) => obj.reset(null));
193
+ const responsePool = new ObjectPool(() => new ArikaResponse(null), (obj) => obj.reset(null));
194
+ return (req, res) => {
195
+ // ── ULTRA FAST PATH ──
196
+ const router = this.getRouter();
197
+ const matched = router.match(req.method, req.url);
198
+ if (matched) {
199
+ const dispatcher = router.getDispatcher();
200
+ const plan = dispatcher.executionPlans.get(matched.route);
201
+ if (plan && !plan.hasMiddleware && dispatcher.parameterBinders.size === 0) {
202
+ const result = plan.handler(null, null, matched.params);
203
+ const raw = new RawResponse(res);
204
+ const buffer = dispatcher.responseResolver.bufferCache.get(plan.route);
205
+ if (buffer) {
206
+ raw.sendUltra(buffer);
207
+ }
208
+ else {
209
+ const response = responsePool.acquire();
210
+ response.reset(res);
211
+ dispatcher.responseResolver.resolve(result, response, plan.route);
212
+ responsePool.release(response);
213
+ }
214
+ return;
215
+ }
216
+ }
217
+ // ── STANDARD PATH ──
218
+ const request = requestPool.acquire();
219
+ const response = responsePool.acquire();
220
+ request.reset(req);
221
+ response.reset(res);
222
+ const handleRequest = async () => {
223
+ try {
224
+ const finalResponse = await kernel.handle(request, response);
225
+ kernel.terminate(request, finalResponse);
226
+ }
227
+ catch (error) {
228
+ if (!res.headersSent) {
229
+ res.writeHead(500, { 'Content-Type': 'application/json' });
230
+ res.end(JSON.stringify({ error: 'Internal Server Error', message: error.message }));
231
+ }
232
+ }
233
+ finally {
234
+ requestPool.release(request);
235
+ responsePool.release(response);
236
+ }
237
+ };
238
+ handleRequest();
239
+ };
240
+ }
241
+ /**
242
+ * Gracefully terminate the application.
243
+ */
244
+ async terminate() {
245
+ if (this.isTerminating)
246
+ return;
247
+ this.isTerminating = true;
248
+ if (this.server) {
249
+ // Close all active connections to speed up shutdown (Node 18.2+)
250
+ if (typeof this.server.closeAllConnections === 'function') {
251
+ this.server.closeAllConnections();
252
+ }
253
+ // Force close idle connections
254
+ if (typeof this.server.closeIdleConnections === 'function') {
255
+ this.server.closeIdleConnections();
256
+ }
257
+ await new Promise((resolve) => {
258
+ // Set a timeout to force resolve if server doesn't close in time
259
+ const timeout = setTimeout(() => {
260
+ logging_1.Log.warning('HTTP server forced to close due to timeout.');
261
+ resolve();
262
+ }, 1000);
263
+ this.server.close(() => {
264
+ clearTimeout(timeout);
265
+ logging_1.Log.info('HTTP server closed.');
266
+ resolve();
267
+ });
268
+ });
269
+ }
270
+ // Close database connections
271
+ if (this.has('db')) {
272
+ try {
273
+ const db = this.make('db');
274
+ if (typeof db.closeAll === 'function') {
275
+ await db.closeAll();
276
+ }
277
+ }
278
+ catch (e) { }
279
+ }
280
+ // Potential for other service termination (Queues, etc.)
281
+ // Remove signal listeners to prevent double triggers during exit
282
+ process.removeAllListeners('SIGINT');
283
+ process.removeAllListeners('SIGTERM');
284
+ // If we are in a testing or specific environment, we might not want to exit
285
+ if (process.env.NODE_ENV !== 'test') {
286
+ // Give a short delay for logs to flush before exiting
287
+ setTimeout(() => {
288
+ process.exit(0);
289
+ }, 50);
290
+ }
291
+ }
292
+ /**
293
+ * Get the router instance.
294
+ */
295
+ getRouter() {
296
+ return this.router;
297
+ }
298
+ }
299
+ exports.Application = Application;
300
+ Application.VERSION = '0.0.4';
301
+ //# sourceMappingURL=Application.js.map