exisjs 0.5.10 → 0.5.11

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 (157) hide show
  1. package/dist/auth/index.d.ts +3 -1
  2. package/dist/auth/index.d.ts.map +1 -1
  3. package/dist/auth/index.js +4 -1
  4. package/dist/auth/index.js.map +1 -1
  5. package/dist/auth/oauth/core.d.ts +96 -0
  6. package/dist/auth/oauth/core.d.ts.map +1 -0
  7. package/dist/auth/oauth/core.js +203 -0
  8. package/dist/auth/oauth/core.js.map +1 -0
  9. package/dist/auth/oauth/index.d.ts +45 -0
  10. package/dist/auth/oauth/index.d.ts.map +1 -0
  11. package/dist/auth/oauth/index.js +64 -0
  12. package/dist/auth/oauth/index.js.map +1 -0
  13. package/dist/auth/oauth/middleware.d.ts +63 -0
  14. package/dist/auth/oauth/middleware.d.ts.map +1 -0
  15. package/dist/auth/oauth/middleware.js +164 -0
  16. package/dist/auth/oauth/middleware.js.map +1 -0
  17. package/dist/auth/oauth/providers/custom.d.ts +41 -0
  18. package/dist/auth/oauth/providers/custom.d.ts.map +1 -0
  19. package/dist/auth/oauth/providers/custom.js +204 -0
  20. package/dist/auth/oauth/providers/custom.js.map +1 -0
  21. package/dist/auth/oauth/providers/discord.d.ts +23 -0
  22. package/dist/auth/oauth/providers/discord.d.ts.map +1 -0
  23. package/dist/auth/oauth/providers/discord.js +130 -0
  24. package/dist/auth/oauth/providers/discord.js.map +1 -0
  25. package/dist/auth/oauth/providers/facebook.d.ts +28 -0
  26. package/dist/auth/oauth/providers/facebook.d.ts.map +1 -0
  27. package/dist/auth/oauth/providers/facebook.js +124 -0
  28. package/dist/auth/oauth/providers/facebook.js.map +1 -0
  29. package/dist/auth/oauth/providers/github.d.ts +25 -0
  30. package/dist/auth/oauth/providers/github.d.ts.map +1 -0
  31. package/dist/auth/oauth/providers/github.js +132 -0
  32. package/dist/auth/oauth/providers/github.js.map +1 -0
  33. package/dist/auth/oauth/providers/google.d.ts +23 -0
  34. package/dist/auth/oauth/providers/google.d.ts.map +1 -0
  35. package/dist/auth/oauth/providers/google.js +134 -0
  36. package/dist/auth/oauth/providers/google.js.map +1 -0
  37. package/dist/auth/oauth/providers/microsoft.d.ts +28 -0
  38. package/dist/auth/oauth/providers/microsoft.d.ts.map +1 -0
  39. package/dist/auth/oauth/providers/microsoft.js +136 -0
  40. package/dist/auth/oauth/providers/microsoft.js.map +1 -0
  41. package/dist/auth/oauth/types.d.ts +158 -0
  42. package/dist/auth/oauth/types.d.ts.map +1 -0
  43. package/dist/auth/oauth/types.js +4 -0
  44. package/dist/auth/oauth/types.js.map +1 -0
  45. package/dist/cli/commands/dev.d.ts.map +1 -1
  46. package/dist/cli/commands/dev.js +0 -1
  47. package/dist/cli/commands/dev.js.map +1 -1
  48. package/dist/database/adapters/mongodb.d.ts +58 -0
  49. package/dist/database/adapters/mongodb.d.ts.map +1 -0
  50. package/dist/database/adapters/mongodb.js +264 -0
  51. package/dist/database/adapters/mongodb.js.map +1 -0
  52. package/dist/database/adapters/mysql.d.ts +27 -0
  53. package/dist/database/adapters/mysql.d.ts.map +1 -0
  54. package/dist/database/adapters/mysql.js +188 -0
  55. package/dist/database/adapters/mysql.js.map +1 -0
  56. package/dist/database/adapters/postgres.d.ts +28 -0
  57. package/dist/database/adapters/postgres.d.ts.map +1 -0
  58. package/dist/database/adapters/postgres.js +174 -0
  59. package/dist/database/adapters/postgres.js.map +1 -0
  60. package/dist/database/adapters/sqlite.d.ts +27 -0
  61. package/dist/database/adapters/sqlite.d.ts.map +1 -0
  62. package/dist/database/adapters/sqlite.js +149 -0
  63. package/dist/database/adapters/sqlite.js.map +1 -0
  64. package/dist/database/index.d.ts +42 -0
  65. package/dist/database/index.d.ts.map +1 -0
  66. package/dist/database/index.js +58 -0
  67. package/dist/database/index.js.map +1 -0
  68. package/dist/database/manager.d.ts +114 -0
  69. package/dist/database/manager.d.ts.map +1 -0
  70. package/dist/database/manager.js +269 -0
  71. package/dist/database/manager.js.map +1 -0
  72. package/dist/database/migration.d.ts +57 -0
  73. package/dist/database/migration.d.ts.map +1 -0
  74. package/dist/database/migration.js +329 -0
  75. package/dist/database/migration.js.map +1 -0
  76. package/dist/database/query-builder.d.ts +89 -0
  77. package/dist/database/query-builder.d.ts.map +1 -0
  78. package/dist/database/query-builder.js +353 -0
  79. package/dist/database/query-builder.js.map +1 -0
  80. package/dist/database/types.d.ts +184 -0
  81. package/dist/database/types.d.ts.map +1 -0
  82. package/dist/database/types.js +4 -0
  83. package/dist/database/types.js.map +1 -0
  84. package/dist/docs/ARCHITECTURE.md +349 -0
  85. package/dist/docs/BENCHMARKS.md +36 -0
  86. package/dist/docs/README.md +34 -0
  87. package/dist/docs/content/README.md +44 -0
  88. package/dist/docs/content/adapters.mdx +199 -0
  89. package/dist/docs/content/cache.mdx +239 -0
  90. package/dist/docs/content/circuit-breaker.mdx +130 -0
  91. package/dist/docs/content/cli/commands.mdx +214 -0
  92. package/dist/docs/content/cli/overview.mdx +92 -0
  93. package/dist/docs/content/cli/usage.mdx +61 -0
  94. package/dist/docs/content/config.mdx +214 -0
  95. package/dist/docs/content/controllers.mdx +241 -0
  96. package/dist/docs/content/cron.mdx +109 -0
  97. package/dist/docs/content/database.mdx +209 -0
  98. package/dist/docs/content/dataloader.mdx +170 -0
  99. package/dist/docs/content/decorators.mdx +204 -0
  100. package/dist/docs/content/errors.mdx +344 -0
  101. package/dist/docs/content/gateways.mdx +376 -0
  102. package/dist/docs/content/installation.mdx +210 -0
  103. package/dist/docs/content/introduction.mdx +96 -0
  104. package/dist/docs/content/middleware.mdx +441 -0
  105. package/dist/docs/content/modules.mdx +144 -0
  106. package/dist/docs/content/oauth.mdx +179 -0
  107. package/dist/docs/content/providers.mdx +147 -0
  108. package/dist/docs/content/queues.mdx +177 -0
  109. package/dist/docs/content/requests.mdx +293 -0
  110. package/dist/docs/content/responses.mdx +271 -0
  111. package/dist/docs/content/routing.mdx +541 -0
  112. package/dist/docs/content/rpc.mdx +146 -0
  113. package/dist/docs/content/security.mdx +294 -0
  114. package/dist/docs/content/sse.mdx +159 -0
  115. package/dist/docs/content/structure.mdx +116 -0
  116. package/dist/docs/content/testing.mdx +139 -0
  117. package/dist/docs/content/validation.mdx +249 -0
  118. package/dist/docs/content/websockets.mdx +289 -0
  119. package/dist/docs/integrations/README.md +23 -0
  120. package/dist/docs/integrations/jwt.mdx +151 -0
  121. package/dist/docs/integrations/mongo.mdx +183 -0
  122. package/dist/docs/integrations/observability.mdx +125 -0
  123. package/dist/docs/integrations/openai.mdx +108 -0
  124. package/dist/docs/integrations/postgres.mdx +190 -0
  125. package/dist/docs/integrations/posthog.mdx +122 -0
  126. package/dist/docs/integrations/redis.mdx +141 -0
  127. package/dist/docs/integrations/resend.mdx +117 -0
  128. package/dist/docs/integrations/s3.mdx +122 -0
  129. package/dist/docs/integrations/swagger.mdx +113 -0
  130. package/dist/docs/reference/README.md +3 -0
  131. package/dist/docs/reference/adapters.mdx +130 -0
  132. package/dist/docs/reference/auth.mdx +183 -0
  133. package/dist/docs/reference/cache.mdx +132 -0
  134. package/dist/docs/reference/circuit-breaker.mdx +71 -0
  135. package/dist/docs/reference/config.mdx +118 -0
  136. package/dist/docs/reference/context.mdx +168 -0
  137. package/dist/docs/reference/dataloader.mdx +91 -0
  138. package/dist/docs/reference/decorators.mdx +293 -0
  139. package/dist/docs/reference/di.mdx +123 -0
  140. package/dist/docs/reference/error.mdx +170 -0
  141. package/dist/docs/reference/exis.mdx +124 -0
  142. package/dist/docs/reference/middleware.mdx +304 -0
  143. package/dist/docs/reference/plugin.mdx +113 -0
  144. package/dist/docs/reference/queue.mdx +155 -0
  145. package/dist/docs/reference/router.mdx +248 -0
  146. package/dist/docs/reference/sanitize.mdx +130 -0
  147. package/dist/docs/reference/storage.mdx +116 -0
  148. package/dist/docs/reference/swagger.mdx +132 -0
  149. package/dist/docs/reference/testing.mdx +145 -0
  150. package/dist/docs/reference/validator.mdx +186 -0
  151. package/dist/index.d.ts +4 -0
  152. package/dist/index.d.ts.map +1 -1
  153. package/dist/index.js +10 -1
  154. package/dist/index.js.map +1 -1
  155. package/dist/server/bootstrapper.js +1 -1
  156. package/dist/server/bootstrapper.js.map +1 -1
  157. package/package.json +8 -1
@@ -0,0 +1,123 @@
1
+ ---
2
+ title: "Dependency Injection"
3
+ description: "API Reference for ExisJS Dependency Injection (`exisjs/di`)."
4
+ ---
5
+
6
+ # Dependency Injection (`exisjs/di`)
7
+
8
+ ExisJS ships with a powerful, built-in Inversion of Control (IoC) Container.
9
+
10
+ It fully supports standard Class-Based constructor injection (similar to NestJS or Angular) but also introduces a highly optimized `inject()` function that allows perfectly typed, deeply nested dependency injection inside purely functional architectures.
11
+
12
+ ---
13
+
14
+ ## Providing Dependencies
15
+
16
+ Before a dependency can be injected, it must be provided to the application container. This is typically done in your plugins or the global `server.ts` file using `app.provide()`.
17
+
18
+ ### Provider Types
19
+
20
+ ExisJS supports four types of providers:
21
+
22
+ **1. Value Providers**
23
+ Provide static, pre-instantiated values or configuration objects.
24
+ ```typescript
25
+ app.provide('API_KEY', { useValue: 'sk_live_123' })
26
+ ```
27
+
28
+ **2. Class Providers**
29
+ Provide a class constructor. ExisJS will automatically instantiate it the first time it is resolved.
30
+ ```typescript
31
+ app.provide('UserService', { useClass: UserService })
32
+ ```
33
+
34
+ **3. Factory Providers**
35
+ Provide a synchronous or asynchronous function to generate the value dynamically.
36
+ ```typescript
37
+ app.provide('Database', {
38
+ useFactory: async () => {
39
+ const db = new DatabaseConnection()
40
+ await db.connect()
41
+ return db
42
+ }
43
+ })
44
+ ```
45
+
46
+ **4. Direct Injection**
47
+ If you pass an undecorated Class or object directly, ExisJS will attempt to resolve it automatically.
48
+ ```typescript
49
+ app.provide(AuthService, AuthService)
50
+ ```
51
+
52
+ ---
53
+
54
+ ## Scopes (`singleton` vs `request`)
55
+
56
+ By default, all providers in ExisJS are **Singletons**. They are instantiated once and cached for the lifetime of the application.
57
+
58
+ If you need a new instance of a dependency for *every single incoming HTTP request*, you can change the scope to `request`.
59
+
60
+ ```typescript
61
+ app.provide('TraceLogger', {
62
+ useClass: RequestScopedLogger,
63
+ scope: 'request'
64
+ })
65
+ ```
66
+
67
+ > [!WARNING]
68
+ > Request-scoped providers can severely impact application performance because they force the engine to allocate new memory and construct new classes on every single HTTP request. Only use `request` scope when strictly necessary.
69
+
70
+ ---
71
+
72
+ ## Injecting Dependencies
73
+
74
+ ### 1. Functional Injection (`inject()`)
75
+
76
+ The true superpower of ExisJS is the `inject()` hook.
77
+
78
+ Powered by Node.js `AsyncLocalStorage`, `inject()` can be called from **anywhere** within a request lifecycle (Controllers, Middlewares, nested utility functions) without needing to explicitly pass the `app` or `req` objects down the call chain!
79
+
80
+ ```typescript filename="src/http/users/route.ts"
81
+ import { route } from 'exisjs/router'
82
+ import { inject } from 'exisjs/di'
83
+ import { Database } from '../db' // The class definition
84
+
85
+ export default controller({
86
+ getUsers: route.get('/', {
87
+ async handle() {
88
+ // Magically resolves the correct instance from the global container!
89
+ // Type is automatically inferred as `Database`.
90
+ const db = inject(Database)
91
+
92
+ const apiKey = inject<string>('API_KEY')
93
+
94
+ return db.query('SELECT * FROM users')
95
+ }
96
+ })
97
+ })
98
+ ```
99
+
100
+ > [!NOTE]
101
+ > `inject()` relies on the active execution context. If you call `inject()` outside of an active HTTP request or application lifecycle hook (e.g., in a background `setInterval` without context), it will throw an error.
102
+
103
+ ### 2. Using `inject()` in Classes (OOP)
104
+
105
+ Unlike other frameworks like NestJS, ExisJS does **not** rely on slow, metadata-heavy Constructor Injection.
106
+
107
+ Instead, you use the exact same blazingly fast `inject()` function directly inside your Controller methods! This completely eliminates the need for `@Inject()` decorators or massive constructor boilerplate.
108
+
109
+ ```typescript filename="src/http/users/route.ts"
110
+ import { Controller, Get } from 'exisjs/decorators'
111
+ import { inject } from 'exisjs/di'
112
+ import { Database } from '../db'
113
+
114
+ @Controller('/users')
115
+ export default class UserController {
116
+ @Get('/')
117
+ async getUsers() {
118
+ // Inject dependencies perfectly cleanly right where you need them!
119
+ const db = inject(Database)
120
+ return db.query('SELECT * FROM users')
121
+ }
122
+ }
123
+ ```
@@ -0,0 +1,170 @@
1
+ ---
2
+ title: "Error Handling"
3
+ description: "API Reference for ExisJS built-in Error Handling (`exisjs/error`)."
4
+ ---
5
+
6
+ # Error Handling (`exisjs/error`)
7
+
8
+ ExisJS provides a rich set of predefined, highly optimized HTTP Error classes and a global error handler that automatically intercepts errors, formats them into a standard JSON shape, and prevents sensitive stack traces from leaking into production.
9
+
10
+ ---
11
+
12
+ ## Standard Exceptions
13
+
14
+ You can throw these predefined exceptions from anywhere in your application (Controllers, Gateways, Services, or Middlewares). ExisJS will automatically catch them and map them to the correct HTTP status code.
15
+
16
+ ### Using Factory Methods (Recommended)
17
+
18
+ The base `HttpError` class provides static factory methods for every standard HTTP error, making it extremely clean to throw errors inline:
19
+
20
+ **Class-Based (OOP)**
21
+ ```typescript filename="src/http/users/route.ts"
22
+ import { Controller, Get, Param } from 'exisjs/decorators'
23
+ import { HttpError } from 'exisjs/error'
24
+
25
+ @Controller('/users')
26
+ export default class UserController {
27
+ @Get('/:id')
28
+ async getUser(@Param('id') id: string) {
29
+ const user = await db.users.find(id)
30
+
31
+ if (!user) throw HttpError.notFound('User could not be found')
32
+ if (user.isBanned) throw HttpError.forbidden('User account is suspended')
33
+
34
+ return user
35
+ }
36
+ }
37
+ ```
38
+
39
+ **Functional**
40
+ ```typescript filename="src/http/users/route.ts"
41
+ import { controller, route } from 'exisjs/router'
42
+ import { HttpError } from 'exisjs/error'
43
+
44
+ export default controller({
45
+ getUser: route.get('/:id', {
46
+ async handle(ctx) {
47
+ const user = await db.users.find(ctx.params.id)
48
+
49
+ if (!user) throw HttpError.notFound('User could not be found')
50
+ if (user.isBanned) throw HttpError.forbidden('User account is suspended')
51
+
52
+ return user
53
+ }
54
+ })
55
+ })
56
+ ```
57
+
58
+ ### Supported Factory Methods
59
+ - `HttpError.badRequest(msg, details?)` (400)
60
+ - `HttpError.unauthorized(msg?)` (401)
61
+ - `HttpError.forbidden(msg?)` (403)
62
+ - `HttpError.notFound(resource?)` (404)
63
+ - `HttpError.conflict(msg)` (409)
64
+ - `HttpError.unprocessable(msg, details?)` (422)
65
+ - `HttpError.tooManyRequests(msg?)` (429)
66
+ - `HttpError.internal(msg?)` (500)
67
+ - `HttpError.serviceUnavailable(msg?)` (503)
68
+
69
+ ### `HttpError` Properties
70
+
71
+ If you catch an `HttpError` or intercept it, you have access to the following properties:
72
+ - **`statusCode`** `(number)`: The HTTP status code.
73
+ - **`code`** `(string)`: The unique uppercase error code (e.g., `'NOT_FOUND'`).
74
+ - **`message`** `(string)`: The human-readable message.
75
+ - **`details`** `(unknown)`: Optional metadata attached to the error.
76
+ - **`isOperational`** `(boolean)`: Always `true` for `HttpError`s. Used by the global error handler to determine if an error was intentionally thrown vs an unexpected crash.
77
+ - **`toJSON()`**: Serializes the error into the strictly typed ExisJS `{ success: false, error: ... }` response shape.
78
+
79
+ ---
80
+
81
+ ## Direct Class Instantiation
82
+
83
+ If you prefer class instantiation (common in NestJS workflows), you can directly instantiate the error classes or their `Exception` aliases.
84
+
85
+ ```typescript filename="src/services/auth.ts"
86
+ import { UnauthorizedError, ConflictException } from 'exisjs/error'
87
+
88
+ export function verifyToken(token: string) {
89
+ if (!isValid(token)) {
90
+ throw new UnauthorizedError('Invalid or expired token')
91
+ }
92
+ }
93
+
94
+ export function createUser(email: string) {
95
+ if (db.exists(email)) {
96
+ throw new ConflictException('Email already exists')
97
+ }
98
+ }
99
+ ```
100
+
101
+ ### Supported Classes
102
+ - `BadRequestError` / `BadRequestException`
103
+ - `UnauthorizedError` / `UnauthorizedException`
104
+ - `ForbiddenError` / `ForbiddenException`
105
+ - `NotFoundError` / `NotFoundException`
106
+ - `ConflictError` / `ConflictException`
107
+ - `UnprocessableError` / `UnprocessableException`
108
+ - `RateLimitError` / `RateLimitException`
109
+ - `InternalError` / `InternalException`
110
+
111
+ ---
112
+
113
+ ## Custom Errors
114
+
115
+ You can easily create your own custom domain errors by extending the base `HttpError` class.
116
+
117
+ ```typescript filename="src/errors/payment.ts"
118
+ import { HttpError } from 'exisjs/error'
119
+
120
+ export class InsufficientFundsError extends HttpError {
121
+ constructor(currentBalance: number) {
122
+ super(
123
+ 'Insufficient funds to complete this transaction',
124
+ 402, // Payment Required
125
+ 'INSUFFICIENT_FUNDS', // Custom Error Code
126
+ { currentBalance } // Extra details attached to the response
127
+ )
128
+ }
129
+ }
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Global Error Handler
135
+
136
+ ExisJS uses a highly sophisticated global error handler out of the box, generated via `createErrorHandler(isDev)`.
137
+
138
+ ### Automatic Features:
139
+ 1. **JSON Standardization**: Automatically formats all errors into a strict `{ success: false, error: { code, message, details? } }` shape.
140
+ 2. **Third-Party Integrations**: Natively catches and normalizes schema validation errors from **Zod**, **Yup**, and the **ExisJS built-in validator**.
141
+ 3. **Syntax Guard**: Catches malformed JSON payloads (SyntaxErrors) in the request body gracefully.
142
+ 4. **Dev vs Prod Modes**: If `isDev` is true, unexpected internal errors (500) will attach stack traces to the response. In production, stack traces are completely stripped to prevent security leaks.
143
+ 5. **HTML Error Pages**: In Dev mode, if a request accepts `text/html`, the error handler renders a beautiful, stylized HTML error page displaying the stack trace directly in the browser.
144
+
145
+ ### Overriding the Global Handler
146
+
147
+ If you need to intercept errors before they reach the client (e.g., to send them to Sentry or Datadog), you can provide a custom global error handler:
148
+
149
+ ```typescript filename="src/server.ts"
150
+ import { exis } from 'exisjs'
151
+ import { HttpError } from 'exisjs/error'
152
+
153
+ const app = exis()
154
+
155
+ app.use((err, req, res, next) => {
156
+ // Log unexpected errors to Sentry
157
+ if (!(err instanceof HttpError) || err.statusCode >= 500) {
158
+ Sentry.captureException(err)
159
+ }
160
+
161
+ // Pass it down to the default ExisJS error handler
162
+ next(err)
163
+ })
164
+ ```
165
+
166
+ ### Express Compatibility (`asyncHandler`)
167
+
168
+ ExisJS natively intercepts and handles Promise rejections at the core routing level.
169
+
170
+ Unlike Express, you do **not** need to wrap your routes in an `asyncHandler`. However, for strict compatibility with older Express middleware ecosystems, `exisjs/error` does export an `asyncHandler` wrapper. Note that using it in ExisJS is entirely redundant and merely adds unnecessary Promise allocations.
@@ -0,0 +1,124 @@
1
+ ---
2
+ title: "exis()"
3
+ description: "API Reference for the exis() application builder."
4
+ ---
5
+
6
+ # Application Instance (exis)
7
+
8
+ The `exis()` function is the primary entry point for configuring and booting your ExisJS application. It defines your core configuration, middleware, plugins, and lifecycle hooks.
9
+
10
+ It returns a configured `App` instance that the CLI or deployment platform will automatically discover and run. The framework's auto-discovery mechanism effortlessly handles both **Functional** and **Class-Based (OOP)** routes inside your `src/http` directory.
11
+
12
+ ## Usage
13
+
14
+ ExisJS supports both Functional and Class-Based (OOP) paradigms for configuring your application entry point.
15
+
16
+ ### 1. Functional Setup
17
+
18
+ ```typescript filename="src/http/server.ts"
19
+ import { exis } from 'exisjs'
20
+ import { cors } from 'exisjs/middleware'
21
+
22
+ export default exis({
23
+ port: 3000,
24
+ helmet: true,
25
+ cors: {
26
+ origin: '*',
27
+ },
28
+ middlewares: [
29
+ cors()
30
+ ],
31
+ async onStart(app) {
32
+ app.log.info("Server is starting up!")
33
+ }
34
+ })
35
+ ```
36
+
37
+ ---
38
+
39
+ ### 2. Class-Based Setup (OOP)
40
+
41
+ If you prefer an Object-Oriented approach, you can define your application entry point using the `@Server()` decorator.
42
+
43
+ ```typescript filename="src/http/server.ts"
44
+ import { Server } from 'exisjs/decorators'
45
+ import type { App } from 'exisjs'
46
+
47
+ @Server({
48
+ plugins: [
49
+ // You can register plugins or configuration directly in the decorator options
50
+ ]
51
+ })
52
+ export default class RootServer {
53
+ async onStart(app: App) {
54
+ app.log.info("Server is starting up!")
55
+ }
56
+
57
+ async onClose(app: App) {
58
+ app.log.info("Server is shutting down!")
59
+ }
60
+ }
61
+ ```
62
+
63
+ ---
64
+
65
+ ## Configuration Options
66
+
67
+ The `exis()` function takes an `ExisConfig` object.
68
+
69
+ ### `port`
70
+ - **Type**: `number`
71
+ - **Default**: `3000` (or `process.env.PORT`)
72
+ - The port the server will listen on during development or manual instantiation.
73
+
74
+ ### `host`
75
+ - **Type**: `string`
76
+ - **Default**: `'0.0.0.0'` (or `process.env.HOST`)
77
+ - The host the server will bind to.
78
+
79
+ ### `env`
80
+ - **Type**: `'development' | 'production' | 'test'`
81
+ - **Default**: Auto-detected via `NODE_ENV`.
82
+ - The current environment of the application.
83
+
84
+ ### `logger`
85
+ - **Type**: `boolean | LoggerConfig`
86
+ - **Default**: `true`
87
+ - Toggles the built-in Pino logger. You can pass a custom configuration object to set the log level, redact sensitive fields, or output JSON.
88
+
89
+ ### `helmet`
90
+ - **Type**: `boolean`
91
+ - **Default**: `true`
92
+ - Automatically applies security headers to every response. Set to `false` to disable.
93
+
94
+ ### `cors`
95
+ - **Type**: `boolean | CorsConfig`
96
+ - **Default**: `false`
97
+ - Automatically injects CORS headers into the request pipeline. You can pass a configuration object to specify allowed origins, methods, and credentials.
98
+
99
+ ### `compression`
100
+ - **Type**: `boolean`
101
+ - **Default**: `true` (if applicable)
102
+ - Automatically compresses HTTP responses (gzip/brotli).
103
+
104
+ ### `middlewares`
105
+ - **Type**: `Handler[]`
106
+ - **Default**: `[]`
107
+ - An array of global middleware functions that will run on every single request.
108
+
109
+ ### `plugins`
110
+ - **Type**: `ExisPlugin[]`
111
+ - **Default**: `[]`
112
+ - An array of ExisJS plugins to register.
113
+
114
+ ---
115
+
116
+ ## Lifecycle Hooks
117
+
118
+ You can define async hooks that execute at specific stages of the application's lifecycle.
119
+
120
+ ### `onStart(app: App)`
121
+ Fired after configuration is loaded but before the server starts accepting connections. This is the ideal place to connect to databases, initialize singletons, or run startup migrations.
122
+
123
+ ### `onClose(app: App)`
124
+ Fired when the server receives a shutdown signal (e.g., `SIGINT`, `SIGTERM`). Use this to gracefully close database connections, flush analytics events, or tear down background workers.