exisjs 0.7.12 → 0.7.13

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 (116) hide show
  1. package/README.md +195 -39
  2. package/dist/config/types.d.ts +2 -2
  3. package/dist/config/types.d.ts.map +1 -1
  4. package/dist/decorators/params.d.ts +21 -0
  5. package/dist/decorators/params.d.ts.map +1 -1
  6. package/dist/decorators/params.js +21 -1
  7. package/dist/decorators/params.js.map +1 -1
  8. package/dist/di/container.d.ts +15 -6
  9. package/dist/di/container.d.ts.map +1 -1
  10. package/dist/di/container.js +26 -3
  11. package/dist/di/container.js.map +1 -1
  12. package/dist/di/index.d.ts +1 -1
  13. package/dist/di/index.d.ts.map +1 -1
  14. package/dist/di/index.js.map +1 -1
  15. package/dist/di/inject.d.ts +2 -1
  16. package/dist/di/inject.d.ts.map +1 -1
  17. package/dist/di/inject.js +2 -1
  18. package/dist/di/inject.js.map +1 -1
  19. package/dist/docs/BENCHMARKS.md +4 -4
  20. package/dist/docs/content/README.md +43 -44
  21. package/dist/docs/content/boundaries.mdx +138 -61
  22. package/dist/docs/content/cli/commands.mdx +151 -128
  23. package/dist/docs/content/cli/overview.mdx +61 -47
  24. package/dist/docs/content/cli/usage.mdx +107 -30
  25. package/dist/docs/content/config.mdx +145 -158
  26. package/dist/docs/content/controllers.mdx +193 -464
  27. package/dist/docs/content/cron.mdx +183 -69
  28. package/dist/docs/content/decorators.mdx +449 -154
  29. package/dist/docs/content/errors.mdx +202 -305
  30. package/dist/docs/content/exisjs-mcp.mdx +59 -49
  31. package/dist/docs/content/installation.mdx +243 -157
  32. package/dist/docs/content/introduction.mdx +220 -48
  33. package/dist/docs/content/middleware.mdx +171 -497
  34. package/dist/docs/content/modules.mdx +141 -83
  35. package/dist/docs/content/providers.mdx +216 -180
  36. package/dist/docs/content/requests.mdx +168 -488
  37. package/dist/docs/content/responses.mdx +200 -533
  38. package/dist/docs/content/routing.mdx +235 -598
  39. package/dist/docs/content/security.mdx +233 -57
  40. package/dist/docs/content/structure.mdx +151 -240
  41. package/dist/docs/content/swagger.mdx +192 -91
  42. package/dist/docs/content/testing.mdx +205 -74
  43. package/dist/docs/content/validation.mdx +479 -341
  44. package/dist/docs/reference/README.md +34 -2
  45. package/dist/docs/reference/config.mdx +277 -75
  46. package/dist/docs/reference/context.mdx +197 -106
  47. package/dist/docs/reference/cron.mdx +266 -152
  48. package/dist/docs/reference/database.mdx +135 -53
  49. package/dist/docs/reference/decorators.mdx +234 -116
  50. package/dist/docs/reference/di.mdx +146 -112
  51. package/dist/docs/reference/error.mdx +155 -178
  52. package/dist/docs/reference/exis.mdx +141 -70
  53. package/dist/docs/reference/logger.mdx +110 -126
  54. package/dist/docs/reference/middleware.mdx +235 -158
  55. package/dist/docs/reference/plugin.mdx +136 -64
  56. package/dist/docs/reference/router.mdx +275 -293
  57. package/dist/docs/reference/sanitize.mdx +91 -87
  58. package/dist/docs/reference/swagger.mdx +280 -100
  59. package/dist/docs/reference/testing.mdx +223 -89
  60. package/dist/docs/reference/validator.mdx +194 -206
  61. package/dist/lib/start-server.js +3 -8
  62. package/dist/lib/start-server.js.map +1 -1
  63. package/dist/module/module.d.ts +6 -3
  64. package/dist/module/module.d.ts.map +1 -1
  65. package/dist/module/module.js +17 -3
  66. package/dist/module/module.js.map +1 -1
  67. package/dist/router/controller-registrar.d.ts.map +1 -1
  68. package/dist/router/controller-registrar.js +26 -4
  69. package/dist/router/controller-registrar.js.map +1 -1
  70. package/dist/server/app.d.ts +3 -1
  71. package/dist/server/app.d.ts.map +1 -1
  72. package/dist/server/app.js +24 -8
  73. package/dist/server/app.js.map +1 -1
  74. package/dist/server/request.d.ts +2 -0
  75. package/dist/server/request.d.ts.map +1 -1
  76. package/dist/server/request.js +11 -0
  77. package/dist/server/request.js.map +1 -1
  78. package/dist/swagger/generator.d.ts.map +1 -1
  79. package/dist/swagger/generator.js +130 -10
  80. package/dist/swagger/generator.js.map +1 -1
  81. package/dist/telemetry/index.d.ts +12 -0
  82. package/dist/telemetry/index.d.ts.map +1 -0
  83. package/dist/telemetry/index.js +121 -0
  84. package/dist/telemetry/index.js.map +1 -0
  85. package/dist/testing/client.d.ts +1 -0
  86. package/dist/testing/client.d.ts.map +1 -1
  87. package/dist/testing/client.js +4 -1
  88. package/dist/testing/client.js.map +1 -1
  89. package/dist/testing/index.d.ts.map +1 -1
  90. package/dist/testing/index.js +11 -4
  91. package/dist/testing/index.js.map +1 -1
  92. package/dist/validator/builder.d.ts +26 -1
  93. package/dist/validator/builder.d.ts.map +1 -1
  94. package/dist/validator/builder.js +31 -0
  95. package/dist/validator/builder.js.map +1 -1
  96. package/dist/validator/engine.d.ts +23 -0
  97. package/dist/validator/engine.d.ts.map +1 -1
  98. package/dist/validator/engine.js +228 -31
  99. package/dist/validator/engine.js.map +1 -1
  100. package/dist/validator/index.d.ts +8 -4
  101. package/dist/validator/index.d.ts.map +1 -1
  102. package/dist/validator/index.js +4 -1
  103. package/dist/validator/index.js.map +1 -1
  104. package/dist/validator/tex-types.d.ts +15 -0
  105. package/dist/validator/tex-types.d.ts.map +1 -1
  106. package/dist/validator/tex-types.js +102 -0
  107. package/dist/validator/tex-types.js.map +1 -1
  108. package/dist/validator/tex.d.ts +1 -1
  109. package/dist/validator/tex.d.ts.map +1 -1
  110. package/dist/validator/tex.js +3 -1
  111. package/dist/validator/tex.js.map +1 -1
  112. package/dist/validator/types.d.ts +1 -0
  113. package/dist/validator/types.d.ts.map +1 -1
  114. package/package.json +46 -14
  115. package/dist/docs/content/dataloader.mdx +0 -170
  116. package/dist/docs/reference/dataloader.mdx +0 -91
@@ -1,25 +1,66 @@
1
1
  ---
2
- title: "Database"
3
- description: "API Reference for ExisJS Database Lifecycle & Transactions (exisjs/database)."
2
+ title: "exisjs/database"
3
+ description: "API Reference for ExisJS database lifecycle management, health monitoring, universal transactions, and ORM interoperability."
4
+ nextUrl: "/docs/reference/logger"
5
+ nextTitle: "Logger Reference"
4
6
  ---
5
7
 
6
- # Database (`exisjs/database`)
8
+ # `exisjs/database`
7
9
 
8
- ExisJS provides a unified, database-agnostic lifecycle and transaction layer. It enables automatic connection management, multi-database health checks, graceful zero-downtime teardowns, and ORM-agnostic transaction runners.
10
+ The `exisjs/database` module provides a database-agnostic lifecycle coordinator, health probe runner, universal ACID transaction executor, and connection pool configuration utilities.
9
11
 
10
12
  ---
11
13
 
12
- ## 1. Lifecycle Management
14
+ ## Module Exports
13
15
 
14
- ### `registerDatabase(app, options)` or `registerDatabase(options)`
16
+ ```typescript
17
+ import {
18
+ registerDatabase,
19
+ DatabaseManager,
20
+ withTransaction,
21
+ modernUpdateOptions,
22
+ mongoPoolOptions,
23
+ } from 'exisjs/database'
24
+
25
+ import type {
26
+ DatabaseRegistration,
27
+ DatabaseHealthInfo,
28
+ DatabaseHealthStatus,
29
+ TransactionOptions,
30
+ ModernUpdateOptions,
31
+ MongoPoolConfig,
32
+ } from 'exisjs/database'
33
+ ```
34
+
35
+ ---
36
+
37
+ ## 1. Lifecycle & Health Coordination
38
+
39
+ ### `registerDatabase(appOrOptions, maybeOptions?)`
40
+
41
+ Registers a database client into the application lifecycle, executing `connect()` on server start and `disconnect()` during graceful teardown (`SIGTERM`, `SIGINT`, or `app.close()`).
42
+
43
+ ```typescript
44
+ function registerDatabase(
45
+ app: App,
46
+ registration: DatabaseRegistration
47
+ ): void
48
+
49
+ function registerDatabase(
50
+ registration: DatabaseRegistration
51
+ ): void
52
+ ```
53
+
54
+ #### `DatabaseRegistration` Interface
15
55
 
16
- Registers a database connection into the application lifecycle. Automatically coordinates `connect()` during server boot and `disconnect()` during graceful shutdown (`SIGTERM`, `SIGINT`, or `app.close()`).
56
+ | Property | Type | Description |
57
+ | :--- | :--- | :--- |
58
+ | `name` | `string` | Unique identifier for the database connection (e.g. `'postgres'`, `'mongo'`). |
59
+ | `connect` | `() => Promise<void> \| void` | Asynchronous callback establishing client connection pools. |
60
+ | `disconnect` | `() => Promise<void> \| void` | Asynchronous callback to safely terminate open sockets and pools. |
61
+ | `healthCheck` / `isHealthy` | `() => Promise<boolean \| DatabaseHealthInfo> \| boolean \| DatabaseHealthInfo` | Optional callback returning health status boolean or detailed metrics. |
17
62
 
18
- #### Options (`DatabaseRegistration`)
19
- - `name` (`string`): Unique identifier for the database connection (e.g. `'postgres'`, `'mongodb'`).
20
- - `connect` (`() => Promise<void> | void`): Async callback to establish connections and connection pools.
21
- - `disconnect` (`() => Promise<void> | void`): Async callback to close connections gracefully.
22
- - `isHealthy` / `healthCheck` (`() => Promise<boolean | DatabaseHealthInfo> | boolean | DatabaseHealthInfo`): Optional health check callback returning `true` / `false` or detailed health info (`{ status: 'connected' | 'disconnected' | 'error', latencyMs?, error?, details? }`).
63
+ #### Example: Prisma Lifecycle Registration
23
64
 
24
65
  ```typescript filename="src/http/server.ts"
25
66
  import { exis } from 'exisjs'
@@ -31,7 +72,7 @@ const prisma = new PrismaClient()
31
72
  export default exis({
32
73
  async onStart(app) {
33
74
  registerDatabase(app, {
34
- name: 'prisma-postgres',
75
+ name: 'postgres',
35
76
  connect: async () => {
36
77
  await prisma.$connect()
37
78
  },
@@ -43,7 +84,7 @@ export default exis({
43
84
  return true
44
85
  },
45
86
  })
46
- }
87
+ },
47
88
  })
48
89
  ```
49
90
 
@@ -51,45 +92,69 @@ export default exis({
51
92
 
52
93
  ### `DatabaseManager`
53
94
 
54
- Singleton registry managing all registered database adapters.
95
+ Static singleton registry coordinating all registered database adapters.
55
96
 
56
- - `DatabaseManager.register(options)`: Registers a database adapter.
57
- - `DatabaseManager.connectAll()`: Connects all registered databases concurrently.
58
- - `DatabaseManager.disconnectAll()`: Gracefully disconnects all databases concurrently.
59
- - `DatabaseManager.checkHealth()`: Runs health checks across all registered databases and returns `{ healthy: boolean, databases: Record<string, DatabaseHealthInfo> }`.
60
- - `DatabaseManager.clear()`: Clears all registered database adapters (useful for test tear-downs).
97
+ | Method | Signature | Description |
98
+ | :--- | :--- | :--- |
99
+ | `register(db)` | `(db: DatabaseRegistration) => void` | Adds a database adapter to the manager. |
100
+ | `connectAll()` | `() => Promise<void>` | Connects all registered database instances concurrently. |
101
+ | `disconnectAll()` | `() => Promise<void>` | Closes all database connections gracefully using `Promise.allSettled`. |
102
+ | `checkHealth()` | `() => Promise<{ healthy: boolean; databases: Record<string, DatabaseHealthInfo> }>` | Executes health checks across all registered databases and aggregates results. |
103
+ | `clear()` | `() => void` | Clears all registered database adapters (useful for test tear-downs). |
61
104
 
62
- ```typescript filename="src/http/health/route.ts"
63
- import { controller, route } from 'exisjs/router'
64
- import { DatabaseManager } from 'exisjs/database'
105
+ #### Health Output Structures
65
106
 
66
- export default controller({
67
- check: route.get('/health', async () => {
68
- const health = await DatabaseManager.checkHealth()
69
- return {
70
- status: health.healthy ? 'ok' : 'degraded',
71
- databases: health.databases,
72
- }
73
- })
74
- })
107
+ ```typescript
108
+ export type DatabaseHealthStatus =
109
+ | 'connected'
110
+ | 'connecting'
111
+ | 'disconnected'
112
+ | 'error'
113
+
114
+ export interface DatabaseHealthInfo {
115
+ name: string
116
+ status: DatabaseHealthStatus
117
+ latencyMs?: number
118
+ error?: string
119
+ details?: Record<string, any>
120
+ }
75
121
  ```
76
122
 
77
123
  ---
78
124
 
79
125
  ## 2. Universal Transaction Runner
80
126
 
81
- ### `withTransaction(client, callback)`
127
+ ### `withTransaction(clientOrConnection, callback, options?)`
82
128
 
83
- A duck-typed transaction runner that coordinates database transaction lifecycles, commits, rollbacks, and session cleanups. Compatible with **Mongoose**, **Prisma**, and **Drizzle**.
129
+ Executes operations within an ACID transaction. Automatically detects whether the supplied client is **Prisma**, **Drizzle**, **Knex**, **MongoDB**, or **Mongoose**, committing on completion and rolling back when errors occur.
84
130
 
85
- ```typescript filename="src/services/transfer.ts"
131
+ ```typescript
132
+ function withTransaction<T>(
133
+ clientOrConnection: any,
134
+ callback: (sessionOrTx: any) => Promise<T>,
135
+ options?: TransactionOptions
136
+ ): Promise<T>
137
+ ```
138
+
139
+ #### `TransactionOptions`
140
+
141
+ | Property | Type | Description |
142
+ | :--- | :--- | :--- |
143
+ | `maxRetries` | `number` | Maximum retry attempts for transient transaction errors. |
144
+ | `timeoutMs` | `number` | Transaction execution timeout threshold in milliseconds. |
145
+ | `readPreference` | `string` | MongoDB read preference (e.g. `'primary'`). |
146
+ | `readConcern` | `string \| { level: string }` | Isolation read concern level. |
147
+ | `writeConcern` | `{ w: number \| string; j?: boolean; wtimeout?: number }` | Transaction write acknowledgment settings. |
148
+
149
+ #### Example: Mongoose Transaction
150
+
151
+ ```typescript
86
152
  import { withTransaction } from 'exisjs/database'
87
153
  import mongoose from 'mongoose'
88
154
  import { Account } from '@/models/Account'
89
155
 
90
156
  export async function transferFunds(fromId: string, toId: string, amount: number) {
91
157
  return withTransaction(mongoose, async (session) => {
92
- // Session is automatically attached to MongoDB queries
93
158
  const sender = await Account.findByIdAndUpdate(
94
159
  fromId,
95
160
  { $inc: { balance: -amount } },
@@ -97,7 +162,6 @@ export async function transferFunds(fromId: string, toId: string, amount: number
97
162
  )
98
163
 
99
164
  if (!sender || sender.balance < 0) {
100
- // Throwing an error automatically aborts the transaction and rolls back
101
165
  throw new Error('Insufficient funds')
102
166
  }
103
167
 
@@ -112,41 +176,59 @@ export async function transferFunds(fromId: string, toId: string, amount: number
112
176
  }
113
177
  ```
114
178
 
115
- Works identically with Prisma:
179
+ #### Example: Prisma Transaction
180
+
116
181
  ```typescript
117
182
  import { withTransaction } from 'exisjs/database'
118
183
  import { prisma } from '@/lib/prisma'
119
184
 
120
- const result = await withTransaction(prisma, async (tx) => {
121
- return tx.user.create({ data: { name: 'Alice' } })
185
+ const user = await withTransaction(prisma, async (tx) => {
186
+ return tx.user.create({
187
+ data: { email: 'user@example.com' },
188
+ })
122
189
  })
123
190
  ```
124
191
 
125
192
  ---
126
193
 
127
- ## 3. Mongoose 8/9 Interop & Pooling
194
+ ## 3. Mongoose Utilities
128
195
 
129
196
  ### `modernUpdateOptions(options?)`
130
197
 
131
- Maps deprecated Mongoose options (such as `{ new: true }`) to standard modern options (`{ returnDocument: 'after' }`), eliminating console warnings when upgrading to Mongoose 8 and 9.
198
+ Maps legacy Mongoose options (such as `{ new: true }`) to standard modern options (`{ returnDocument: 'after' }`) to eliminate deprecation warnings in Mongoose 8 and 9.
199
+
200
+ ```typescript
201
+ function modernUpdateOptions<T extends ModernUpdateOptions>(
202
+ options?: T
203
+ ): T & { returnDocument?: 'before' | 'after' }
204
+ ```
132
205
 
133
206
  ```typescript
134
207
  import { modernUpdateOptions } from 'exisjs/database'
135
208
 
136
- // Passes { returnDocument: 'after' } warning-free
137
- User.findByIdAndUpdate(id, { $set: updateData }, modernUpdateOptions())
209
+ User.findByIdAndUpdate(id, { $set: updateData }, modernUpdateOptions({ new: true }))
138
210
  ```
139
211
 
140
- ### `mongoPoolOptions(customOptions?)`
212
+ ---
141
213
 
142
- Returns pre-configured, production-hardened MongoDB connection pool settings:
214
+ ### `mongoPoolOptions(overrides?)`
143
215
 
144
- ```typescript
145
- import { mongoPoolOptions } from 'exisjs/database'
146
- import mongoose from 'mongoose'
216
+ Generates production-hardened connection pool configuration defaults for MongoDB drivers and Mongoose.
147
217
 
148
- await mongoose.connect(process.env.MONGODB_URI!, mongoPoolOptions({
149
- maxPoolSize: 100,
150
- minPoolSize: 10,
151
- }))
218
+ ```typescript
219
+ function mongoPoolOptions(
220
+ overrides?: MongoPoolConfig
221
+ ): MongoPoolConfig
152
222
  ```
223
+
224
+ #### `MongoPoolConfig` Defaults
225
+
226
+ | Property | Default | Description |
227
+ | :--- | :--- | :--- |
228
+ | `maxPoolSize` | `50` | Maximum socket connections maintained in the pool. |
229
+ | `minPoolSize` | `5` | Minimum idle connections kept alive. |
230
+ | `serverSelectionTimeoutMS` | `5000` | Connection attempt timeout threshold in ms. |
231
+ | `socketTimeoutMS` | `45000` | Inactive socket timeout threshold in ms. |
232
+ | `heartbeatFrequencyMS` | `10000` | Health check probe interval in ms. |
233
+ | `autoIndex` | `false` (in prod) | Disables automatic index builds at runtime in production. |
234
+