@venizia/ignis-docs 0.0.2 → 0.0.4-0
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.
- package/README.md +1 -1
- package/package.json +4 -2
- package/wiki/best-practices/api-usage-examples.md +591 -0
- package/wiki/best-practices/architectural-patterns.md +415 -0
- package/wiki/best-practices/architecture-decisions.md +488 -0
- package/wiki/{get-started/best-practices → best-practices}/code-style-standards.md +647 -182
- package/wiki/{get-started/best-practices → best-practices}/common-pitfalls.md +109 -4
- package/wiki/{get-started/best-practices → best-practices}/contribution-workflow.md +34 -7
- package/wiki/best-practices/data-modeling.md +376 -0
- package/wiki/best-practices/deployment-strategies.md +698 -0
- package/wiki/best-practices/index.md +27 -0
- package/wiki/best-practices/performance-optimization.md +196 -0
- package/wiki/best-practices/security-guidelines.md +218 -0
- package/wiki/{get-started/best-practices → best-practices}/troubleshooting-tips.md +97 -1
- package/wiki/changelogs/2025-12-16-initial-architecture.md +1 -1
- package/wiki/changelogs/2025-12-16-model-repo-datasource-refactor.md +1 -1
- package/wiki/changelogs/2025-12-17-refactor.md +1 -1
- package/wiki/changelogs/2025-12-18-performance-optimizations.md +5 -5
- package/wiki/changelogs/2025-12-18-repository-validation-security.md +13 -7
- package/wiki/changelogs/2025-12-26-nested-relations-and-generics.md +86 -0
- package/wiki/changelogs/2025-12-26-transaction-support.md +57 -0
- package/wiki/changelogs/2025-12-29-dynamic-binding-registration.md +104 -0
- package/wiki/changelogs/2025-12-29-snowflake-uid-helper.md +100 -0
- package/wiki/changelogs/2025-12-30-repository-enhancements.md +214 -0
- package/wiki/changelogs/2025-12-31-json-path-filtering-array-operators.md +214 -0
- package/wiki/changelogs/2025-12-31-string-id-custom-generator.md +137 -0
- package/wiki/changelogs/2026-01-02-default-filter-and-repository-mixins.md +418 -0
- package/wiki/changelogs/index.md +8 -1
- package/wiki/changelogs/planned-schema-migrator.md +2 -10
- package/wiki/{get-started/core-concepts → guides/core-concepts/application}/bootstrapping.md +18 -5
- package/wiki/{get-started/core-concepts/application.md → guides/core-concepts/application/index.md} +47 -104
- package/wiki/guides/core-concepts/components-guide.md +509 -0
- package/wiki/guides/core-concepts/components.md +122 -0
- package/wiki/{get-started → guides}/core-concepts/controllers.md +30 -13
- package/wiki/{get-started → guides}/core-concepts/dependency-injection.md +97 -0
- package/wiki/guides/core-concepts/persistent/datasources.md +179 -0
- package/wiki/guides/core-concepts/persistent/index.md +119 -0
- package/wiki/guides/core-concepts/persistent/models.md +241 -0
- package/wiki/guides/core-concepts/persistent/repositories.md +219 -0
- package/wiki/guides/core-concepts/persistent/transactions.md +170 -0
- package/wiki/{get-started → guides}/core-concepts/services.md +26 -3
- package/wiki/{get-started → guides/get-started}/5-minute-quickstart.md +59 -14
- package/wiki/guides/get-started/philosophy.md +682 -0
- package/wiki/guides/get-started/setup.md +157 -0
- package/wiki/guides/index.md +89 -0
- package/wiki/guides/reference/glossary.md +243 -0
- package/wiki/{get-started → guides/reference}/mcp-docs-server.md +0 -10
- package/wiki/{get-started → guides/tutorials}/building-a-crud-api.md +134 -132
- package/wiki/{get-started/quickstart.md → guides/tutorials/complete-installation.md} +107 -71
- package/wiki/guides/tutorials/ecommerce-api.md +1399 -0
- package/wiki/guides/tutorials/realtime-chat.md +1261 -0
- package/wiki/guides/tutorials/testing.md +723 -0
- package/wiki/index.md +176 -37
- package/wiki/references/base/application.md +27 -0
- package/wiki/references/base/bootstrapping.md +30 -26
- package/wiki/references/base/components.md +532 -31
- package/wiki/references/base/controllers.md +136 -38
- package/wiki/references/base/datasources.md +108 -5
- package/wiki/references/base/dependency-injection.md +39 -3
- package/wiki/references/base/filter-system/application-usage.md +224 -0
- package/wiki/references/base/filter-system/array-operators.md +132 -0
- package/wiki/references/base/filter-system/comparison-operators.md +109 -0
- package/wiki/references/base/filter-system/default-filter.md +428 -0
- package/wiki/references/base/filter-system/fields-order-pagination.md +155 -0
- package/wiki/references/base/filter-system/index.md +127 -0
- package/wiki/references/base/filter-system/json-filtering.md +197 -0
- package/wiki/references/base/filter-system/list-operators.md +71 -0
- package/wiki/references/base/filter-system/logical-operators.md +156 -0
- package/wiki/references/base/filter-system/null-operators.md +58 -0
- package/wiki/references/base/filter-system/pattern-matching.md +108 -0
- package/wiki/references/base/filter-system/quick-reference.md +431 -0
- package/wiki/references/base/filter-system/range-operators.md +63 -0
- package/wiki/references/base/filter-system/tips.md +190 -0
- package/wiki/references/base/filter-system/use-cases.md +452 -0
- package/wiki/references/base/index.md +90 -0
- package/wiki/references/base/middlewares.md +602 -0
- package/wiki/references/base/models.md +215 -23
- package/wiki/references/base/providers.md +732 -0
- package/wiki/references/base/repositories/advanced.md +555 -0
- package/wiki/references/base/repositories/index.md +228 -0
- package/wiki/references/base/repositories/mixins.md +331 -0
- package/wiki/references/base/repositories/relations.md +486 -0
- package/wiki/references/base/repositories.md +40 -549
- package/wiki/references/base/services.md +28 -4
- package/wiki/references/components/authentication.md +22 -2
- package/wiki/references/components/health-check.md +12 -0
- package/wiki/references/components/index.md +23 -0
- package/wiki/references/components/mail.md +687 -0
- package/wiki/references/components/request-tracker.md +16 -0
- package/wiki/references/components/socket-io.md +18 -0
- package/wiki/references/components/static-asset.md +14 -26
- package/wiki/references/components/swagger.md +17 -0
- package/wiki/references/configuration/environment-variables.md +427 -0
- package/wiki/references/configuration/index.md +73 -0
- package/wiki/references/helpers/cron.md +14 -0
- package/wiki/references/helpers/crypto.md +15 -0
- package/wiki/references/helpers/env.md +16 -0
- package/wiki/references/helpers/error.md +17 -0
- package/wiki/references/helpers/index.md +15 -0
- package/wiki/references/helpers/inversion.md +24 -4
- package/wiki/references/helpers/logger.md +19 -0
- package/wiki/references/helpers/network.md +11 -0
- package/wiki/references/helpers/queue.md +19 -0
- package/wiki/references/helpers/redis.md +21 -0
- package/wiki/references/helpers/socket-io.md +24 -5
- package/wiki/references/helpers/storage.md +18 -10
- package/wiki/references/helpers/testing.md +18 -0
- package/wiki/references/helpers/types.md +167 -0
- package/wiki/references/helpers/uid.md +167 -0
- package/wiki/references/helpers/worker-thread.md +16 -0
- package/wiki/references/index.md +177 -0
- package/wiki/references/quick-reference.md +634 -0
- package/wiki/references/src-details/boot.md +3 -3
- package/wiki/references/src-details/dev-configs.md +0 -4
- package/wiki/references/src-details/docs.md +2 -2
- package/wiki/references/src-details/index.md +86 -0
- package/wiki/references/src-details/inversion.md +1 -6
- package/wiki/references/src-details/mcp-server.md +3 -15
- package/wiki/references/utilities/index.md +86 -10
- package/wiki/references/utilities/jsx.md +577 -0
- package/wiki/references/utilities/request.md +0 -2
- package/wiki/references/utilities/statuses.md +740 -0
- package/wiki/changelogs/planned-transaction-support.md +0 -216
- package/wiki/get-started/best-practices/api-usage-examples.md +0 -266
- package/wiki/get-started/best-practices/architectural-patterns.md +0 -170
- package/wiki/get-started/best-practices/data-modeling.md +0 -177
- package/wiki/get-started/best-practices/deployment-strategies.md +0 -121
- package/wiki/get-started/best-practices/performance-optimization.md +0 -88
- package/wiki/get-started/best-practices/security-guidelines.md +0 -99
- package/wiki/get-started/core-concepts/components.md +0 -98
- package/wiki/get-started/core-concepts/persistent.md +0 -543
- package/wiki/get-started/index.md +0 -65
- package/wiki/get-started/philosophy.md +0 -296
- package/wiki/get-started/prerequisites.md +0 -113
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Controllers Reference
|
|
3
|
+
description: Technical reference for controller classes and API endpoints
|
|
4
|
+
difficulty: beginner
|
|
5
|
+
---
|
|
6
|
+
|
|
1
7
|
# Deep Dive: Controllers
|
|
2
8
|
|
|
3
9
|
Technical reference for controller classes - the foundation for creating API endpoints in Ignis.
|
|
@@ -86,8 +92,8 @@ For convenience, `Ignis` provides decorator shortcuts for each HTTP method: Thes
|
|
|
86
92
|
import { get, post, z, jsonContent, jsonResponse, Authentication, TRouteContext, HTTP } from '@venizia/ignis';
|
|
87
93
|
|
|
88
94
|
// Define route configs as const for full type inference
|
|
89
|
-
const
|
|
90
|
-
|
|
95
|
+
const UserRoutes = {
|
|
96
|
+
LIST_USERS: {
|
|
91
97
|
path: '/',
|
|
92
98
|
method: 'get',
|
|
93
99
|
responses: jsonResponse({
|
|
@@ -95,7 +101,7 @@ const USER_ROUTES = {
|
|
|
95
101
|
schema: z.array(z.object({ id: z.string(), name: z.string() })),
|
|
96
102
|
}),
|
|
97
103
|
},
|
|
98
|
-
|
|
104
|
+
GET_USER: {
|
|
99
105
|
path: '/:id',
|
|
100
106
|
method: 'get',
|
|
101
107
|
request: {
|
|
@@ -106,7 +112,7 @@ const USER_ROUTES = {
|
|
|
106
112
|
schema: z.object({ id: z.string(), name: z.string() }),
|
|
107
113
|
}),
|
|
108
114
|
},
|
|
109
|
-
|
|
115
|
+
CREATE_USER: {
|
|
110
116
|
path: '/',
|
|
111
117
|
method: 'post',
|
|
112
118
|
authStrategies: [Authentication.STRATEGY_JWT], // Secure this endpoint
|
|
@@ -123,26 +129,26 @@ const USER_ROUTES = {
|
|
|
123
129
|
|
|
124
130
|
// ... inside a controller class
|
|
125
131
|
|
|
126
|
-
@get({ configs:
|
|
127
|
-
getAllUsers(c: TRouteContext<typeof
|
|
132
|
+
@get({ configs: UserRoutes.LIST_USERS })
|
|
133
|
+
getAllUsers(c: TRouteContext<typeof UserRoutes.LIST_USERS>) { // Return type is automatically inferred
|
|
128
134
|
return c.json([{ id: '1', name: 'John Doe' }], HTTP.ResultCodes.RS_2.Ok);
|
|
129
135
|
}
|
|
130
136
|
|
|
131
|
-
@get({ configs:
|
|
132
|
-
getUserById(c: TRouteContext<typeof
|
|
137
|
+
@get({ configs: UserRoutes.GET_USER })
|
|
138
|
+
getUserById(c: TRouteContext<typeof UserRoutes.GET_USER>) { // Return type is automatically inferred
|
|
133
139
|
const { id } = c.req.valid('param'); // id is typed as string
|
|
134
140
|
return c.json({ id, name: 'John Doe' }, HTTP.ResultCodes.RS_2.Ok);
|
|
135
141
|
}
|
|
136
142
|
|
|
137
|
-
@post({ configs:
|
|
138
|
-
createUser(c: TRouteContext<typeof
|
|
143
|
+
@post({ configs: UserRoutes.CREATE_USER })
|
|
144
|
+
createUser(c: TRouteContext<typeof UserRoutes.CREATE_USER>) { // Return type is automatically inferred
|
|
139
145
|
const { name } = c.req.valid('json'); // name is typed as string
|
|
140
146
|
const newUser = { id: '2', name };
|
|
141
147
|
return c.json(newUser, HTTP.ResultCodes.RS_2.Created); // Return type is validated
|
|
142
148
|
}
|
|
143
149
|
```
|
|
144
150
|
|
|
145
|
-
**Example using shared `
|
|
151
|
+
**Example using shared `RouteConfigs`:**
|
|
146
152
|
|
|
147
153
|
For better organization, you can define all your route configurations in a constant and reference them in your decorators. This approach also allows you to get a typed context for your handler.
|
|
148
154
|
|
|
@@ -150,8 +156,8 @@ For better organization, you can define all your route configurations in a const
|
|
|
150
156
|
import { api, BaseController, controller, TRouteContext, jsonContent, jsonResponse, HTTP } from '@venizia/ignis';
|
|
151
157
|
import { z } from 'hono/zod-openapi';
|
|
152
158
|
|
|
153
|
-
const
|
|
154
|
-
|
|
159
|
+
const RouteConfigs = {
|
|
160
|
+
PING: {
|
|
155
161
|
method: HTTP.Methods.POST,
|
|
156
162
|
path: '/ping',
|
|
157
163
|
request: {
|
|
@@ -167,9 +173,9 @@ const HEALTH_CHECK_ROUTES = {
|
|
|
167
173
|
|
|
168
174
|
@controller({ path: '/health' })
|
|
169
175
|
export class HealthCheckController extends BaseController {
|
|
170
|
-
|
|
171
|
-
@api({ configs:
|
|
172
|
-
ping(c: TRouteContext<typeof
|
|
176
|
+
|
|
177
|
+
@api({ configs: RouteConfigs.PING })
|
|
178
|
+
ping(c: TRouteContext<typeof RouteConfigs.PING>) { // Return type is automatically inferred
|
|
173
179
|
const { message } = c.req.valid('json');
|
|
174
180
|
return c.json({ pong: message }, HTTP.ResultCodes.RS_2.Ok);
|
|
175
181
|
}
|
|
@@ -258,17 +264,17 @@ request: {
|
|
|
258
264
|
The `defineRouteConfigs` function is a simple helper for creating a typed object containing multiple route configurations. This is particularly useful for organizing all of a controller's route definitions in a single, type-checked constant.
|
|
259
265
|
|
|
260
266
|
```typescript
|
|
261
|
-
import { defineRouteConfigs, HTTP, jsonResponse, z } from '@venizia/ignis';
|
|
267
|
+
import { defineRouteConfigs, HTTP, jsonResponse, jsonContent, z } from '@venizia/ignis';
|
|
262
268
|
|
|
263
|
-
const
|
|
264
|
-
|
|
269
|
+
const RouteConfigs = defineRouteConfigs({
|
|
270
|
+
ROOT: {
|
|
265
271
|
method: HTTP.Methods.GET,
|
|
266
272
|
path: '/',
|
|
267
273
|
responses: jsonResponse({
|
|
268
274
|
schema: z.object({ status: z.string() }),
|
|
269
275
|
}),
|
|
270
276
|
},
|
|
271
|
-
|
|
277
|
+
PING: {
|
|
272
278
|
method: HTTP.Methods.POST,
|
|
273
279
|
path: '/ping',
|
|
274
280
|
request: {
|
|
@@ -318,27 +324,94 @@ This factory method returns a `BaseController` class that is already set up with
|
|
|
318
324
|
| `controller.readonly` | `boolean` | If `true`, only read operations (find, findOne, findById, count) are generated. Write operations are excluded. Defaults to `false`. |
|
|
319
325
|
| `controller.isStrict` | `boolean` | If `true`, query parameters like `where` will be strictly validated. Defaults to `true`. |
|
|
320
326
|
| `controller.defaultLimit`| `number` | The default limit for `find` operations. Defaults to `10`. |
|
|
321
|
-
| `
|
|
322
|
-
| `
|
|
327
|
+
| `authStrategies` | `Array<TAuthStrategy>` | Auth strategies applied to all routes (unless overridden per-route). |
|
|
328
|
+
| `routes` | `TRoutesConfig` | Per-route configuration combining schema and auth. See routes configuration below. |
|
|
323
329
|
|
|
324
|
-
###
|
|
330
|
+
### Routes Configuration
|
|
325
331
|
|
|
326
|
-
The `
|
|
332
|
+
The `routes` option provides a unified way to configure both schema overrides and authentication for each endpoint:
|
|
327
333
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
|
331
|
-
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
|
339
|
-
|
|
|
340
|
-
| `
|
|
341
|
-
| `
|
|
334
|
+
```typescript
|
|
335
|
+
type TRouteAuthConfig =
|
|
336
|
+
| { skipAuth: true }
|
|
337
|
+
| { skipAuth?: false; authStrategies: Array<TAuthStrategy> };
|
|
338
|
+
|
|
339
|
+
type TReadRouteConfig = TRouteAuthConfig & { schema?: z.ZodObject };
|
|
340
|
+
type TWriteRouteConfig = TReadRouteConfig & { requestBody?: z.ZodObject };
|
|
341
|
+
type TDeleteRouteConfig = TRouteAuthConfig & { schema?: z.ZodObject };
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
| Route | Type | Description |
|
|
345
|
+
| :--- | :--- | :--- |
|
|
346
|
+
| `count` | `TReadRouteConfig` | Config for count endpoint |
|
|
347
|
+
| `find` | `TReadRouteConfig` | Config for find endpoint |
|
|
348
|
+
| `findOne` | `TReadRouteConfig` | Config for findOne endpoint |
|
|
349
|
+
| `findById` | `TReadRouteConfig` | Config for findById endpoint |
|
|
350
|
+
| `create` | `TWriteRouteConfig` | Config for create endpoint (supports `requestBody`) |
|
|
351
|
+
| `updateById` | `TWriteRouteConfig` | Config for updateById endpoint (supports `requestBody`) |
|
|
352
|
+
| `updateBy` | `TWriteRouteConfig` | Config for updateBy endpoint (supports `requestBody`) |
|
|
353
|
+
| `deleteById` | `TDeleteRouteConfig` | Config for deleteById endpoint |
|
|
354
|
+
| `deleteBy` | `TDeleteRouteConfig` | Config for deleteBy endpoint |
|
|
355
|
+
|
|
356
|
+
### Auth Resolution Priority
|
|
357
|
+
|
|
358
|
+
When resolving authentication for a route, the following priority applies:
|
|
359
|
+
|
|
360
|
+
1. **Endpoint `skipAuth: true`** → No auth (ignores controller `authStrategies`)
|
|
361
|
+
2. **Endpoint `authStrategies`** → Override controller (empty array = no auth)
|
|
362
|
+
3. **Controller `authStrategies`** → Default fallback
|
|
363
|
+
|
|
364
|
+
### Authentication Examples
|
|
365
|
+
|
|
366
|
+
```typescript
|
|
367
|
+
// 1. JWT auth on ALL routes
|
|
368
|
+
const UserController = ControllerFactory.defineCrudController({
|
|
369
|
+
entity: UserEntity,
|
|
370
|
+
repository: { name: 'UserRepository' },
|
|
371
|
+
controller: { name: 'UserController', basePath: '/users' },
|
|
372
|
+
authStrategies: ['jwt'],
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
// 2. JWT auth on all, but skip for public read endpoints
|
|
376
|
+
const ProductController = ControllerFactory.defineCrudController({
|
|
377
|
+
entity: ProductEntity,
|
|
378
|
+
repository: { name: 'ProductRepository' },
|
|
379
|
+
controller: { name: 'ProductController', basePath: '/products' },
|
|
380
|
+
authStrategies: ['jwt'],
|
|
381
|
+
routes: {
|
|
382
|
+
find: { skipAuth: true },
|
|
383
|
+
findById: { skipAuth: true },
|
|
384
|
+
count: { skipAuth: true },
|
|
385
|
+
},
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
// 3. No controller auth, require JWT only for write operations
|
|
389
|
+
const ArticleController = ControllerFactory.defineCrudController({
|
|
390
|
+
entity: ArticleEntity,
|
|
391
|
+
repository: { name: 'ArticleRepository' },
|
|
392
|
+
controller: { name: 'ArticleController', basePath: '/articles' },
|
|
393
|
+
routes: {
|
|
394
|
+
create: { authStrategies: ['jwt'] },
|
|
395
|
+
updateById: { authStrategies: ['jwt'] },
|
|
396
|
+
deleteById: { authStrategies: ['jwt'] },
|
|
397
|
+
},
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
// 4. Custom schema with auth configuration
|
|
401
|
+
const OrderController = ControllerFactory.defineCrudController({
|
|
402
|
+
entity: OrderEntity,
|
|
403
|
+
repository: { name: 'OrderRepository' },
|
|
404
|
+
controller: { name: 'OrderController', basePath: '/orders' },
|
|
405
|
+
authStrategies: ['jwt'],
|
|
406
|
+
routes: {
|
|
407
|
+
find: { schema: CustomOrderListSchema, skipAuth: true },
|
|
408
|
+
create: {
|
|
409
|
+
schema: CustomOrderResponseSchema,
|
|
410
|
+
requestBody: CustomOrderCreateSchema,
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
});
|
|
414
|
+
```
|
|
342
415
|
|
|
343
416
|
### Example
|
|
344
417
|
|
|
@@ -385,3 +458,28 @@ export class ConfigurationController extends _ConfigurationController {
|
|
|
385
458
|
```
|
|
386
459
|
|
|
387
460
|
By leveraging these structured configuration options and the `ControllerFactory`, you ensure that your API is not only functional but also well-documented, easy to validate, and rapidly deployable for standard CRUD operations.
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
## See Also
|
|
465
|
+
|
|
466
|
+
- **Related References:**
|
|
467
|
+
- [Services](./services.md) - Business logic layer called by controllers
|
|
468
|
+
- [Repositories](./repositories/) - Data access layer for CRUD operations
|
|
469
|
+
- [Middlewares](./middlewares.md) - Request/response middleware
|
|
470
|
+
- [Application](./application.md) - Application setup and controller mounting
|
|
471
|
+
- [Dependency Injection](./dependency-injection.md) - DI patterns and injection
|
|
472
|
+
|
|
473
|
+
- **Guides:**
|
|
474
|
+
- [Building Your First API](/guides/getting-started/first-api.md)
|
|
475
|
+
- [Controllers Guide](/guides/core-concepts/controllers.md)
|
|
476
|
+
- [Routing and Decorators](/guides/core-concepts/routing.md)
|
|
477
|
+
|
|
478
|
+
- **Best Practices:**
|
|
479
|
+
- [API Design Patterns](/best-practices/architecture/api-design.md)
|
|
480
|
+
- [Error Handling](/best-practices/architecture/error-handling.md)
|
|
481
|
+
- [Request Validation](/best-practices/security/input-validation.md)
|
|
482
|
+
|
|
483
|
+
- **External Resources:**
|
|
484
|
+
- [OpenAPI Specification](https://swagger.io/specification/)
|
|
485
|
+
- [HTTP Methods](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods)
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: DataSources Reference
|
|
3
|
+
description: Technical reference for DataSource classes and database connections
|
|
4
|
+
difficulty: intermediate
|
|
5
|
+
---
|
|
6
|
+
|
|
1
7
|
# Deep Dive: DataSources
|
|
2
8
|
|
|
3
9
|
Technical reference for DataSource classes - managing database connections in Ignis.
|
|
@@ -8,15 +14,17 @@ Technical reference for DataSource classes - managing database connections in Ig
|
|
|
8
14
|
|
|
9
15
|
| Class/Interface | Purpose | Key Members |
|
|
10
16
|
|-----------------|---------|-------------|
|
|
11
|
-
| **IDataSource** | Contract for all datasources | `name`, `settings`, `connector`, `getSchema()`, `configure()` |
|
|
17
|
+
| **IDataSource** | Contract for all datasources | `name`, `settings`, `connector`, `getSchema()`, `configure()`, `beginTransaction()` |
|
|
12
18
|
| **AbstractDataSource** | Base implementation with logging | Extends `BaseHelper` |
|
|
13
|
-
| **BaseDataSource** | Concrete class to extend | Auto-discovery, driver from decorator |
|
|
19
|
+
| **BaseDataSource** | Concrete class to extend | Auto-discovery, driver from decorator, transaction support |
|
|
20
|
+
| **ITransaction** | Transaction object | `connector`, `isActive`, `commit()`, `rollback()` |
|
|
21
|
+
| **IsolationLevels** | Isolation level constants | `READ_COMMITTED`, `REPEATABLE_READ`, `SERIALIZABLE` |
|
|
14
22
|
|
|
15
23
|
## `IDataSource` Interface
|
|
16
24
|
|
|
17
25
|
Contract for all datasource classes in the framework.
|
|
18
26
|
|
|
19
|
-
**File:** `packages/core/src/base/datasources/types.ts`
|
|
27
|
+
**File:** `packages/core/src/base/datasources/common/types.ts`
|
|
20
28
|
|
|
21
29
|
### Properties & Methods
|
|
22
30
|
|
|
@@ -24,10 +32,14 @@ Contract for all datasource classes in the framework.
|
|
|
24
32
|
|--------|------|-------------|
|
|
25
33
|
| `name` | `string` | Datasource name |
|
|
26
34
|
| `settings` | `object` | Configuration object |
|
|
27
|
-
| `connector` | `
|
|
28
|
-
| `
|
|
35
|
+
| `connector` | `TNodePostgresConnector` | Database connector instance (Drizzle) |
|
|
36
|
+
| `schema` | `Schema` | Combined Drizzle schema (auto-discovered or manual) |
|
|
37
|
+
| `getSchema()` | Method | Returns combined Drizzle schema |
|
|
38
|
+
| `getSettings()` | Method | Returns connection settings |
|
|
39
|
+
| `getConnector()` | Method | Returns the Drizzle connector |
|
|
29
40
|
| `configure()` | Method | Initializes the `connector` |
|
|
30
41
|
| `getConnectionString()` | Method | Returns connection string |
|
|
42
|
+
| `beginTransaction(opts?)` | Method | Starts a new database transaction |
|
|
31
43
|
|
|
32
44
|
## `AbstractDataSource` & `BaseDataSource`
|
|
33
45
|
|
|
@@ -264,4 +276,95 @@ export class PostgresDataSource extends BaseDataSource<TNodePostgresConnector, I
|
|
|
264
276
|
| `getConnector()` | Returns the Drizzle connector |
|
|
265
277
|
| `hasDiscoverableModels()` | Returns `true` if there are models registered for this datasource |
|
|
266
278
|
|
|
279
|
+
## Transaction Support
|
|
280
|
+
|
|
281
|
+
DataSources provide built-in transaction management through the `beginTransaction()` method. This allows you to perform atomic operations across multiple repositories.
|
|
282
|
+
|
|
283
|
+
### Transaction Types
|
|
284
|
+
|
|
285
|
+
**File:** `packages/core/src/base/datasources/common/types.ts`
|
|
286
|
+
|
|
287
|
+
| Type | Description |
|
|
288
|
+
|------|-------------|
|
|
289
|
+
| `ITransaction<Schema>` | Transaction object with `commit()`, `rollback()`, and `connector` |
|
|
290
|
+
| `ITransactionOptions` | Options for starting a transaction (e.g., `isolationLevel`) |
|
|
291
|
+
| `TIsolationLevel` | Union type: `'READ COMMITTED'` \| `'REPEATABLE READ'` \| `'SERIALIZABLE'` |
|
|
292
|
+
| `IsolationLevels` | Static class with isolation level constants and validation |
|
|
293
|
+
|
|
294
|
+
### ITransaction Interface
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
interface ITransaction<Schema> {
|
|
298
|
+
connector: TNodePostgresTransactionConnector<Schema>;
|
|
299
|
+
isActive: boolean;
|
|
300
|
+
isolationLevel: TIsolationLevel;
|
|
301
|
+
|
|
302
|
+
commit(): Promise<void>;
|
|
303
|
+
rollback(): Promise<void>;
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Isolation Levels
|
|
308
|
+
|
|
309
|
+
Use the `IsolationLevels` static class for type-safe isolation level constants:
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
import { IsolationLevels } from '@venizia/ignis';
|
|
313
|
+
|
|
314
|
+
// Available levels
|
|
315
|
+
IsolationLevels.READ_COMMITTED // Default - prevents dirty reads
|
|
316
|
+
IsolationLevels.REPEATABLE_READ // Consistent reads within transaction
|
|
317
|
+
IsolationLevels.SERIALIZABLE // Strictest isolation
|
|
318
|
+
|
|
319
|
+
// Validation
|
|
320
|
+
IsolationLevels.isValid('READ COMMITTED'); // true
|
|
321
|
+
IsolationLevels.isValid('INVALID'); // false
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Usage Example
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
// Start transaction from datasource or repository
|
|
328
|
+
const tx = await dataSource.beginTransaction({
|
|
329
|
+
isolationLevel: IsolationLevels.SERIALIZABLE
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
try {
|
|
333
|
+
// Use tx.connector for operations
|
|
334
|
+
await tx.connector.insert(userTable).values({ name: 'Alice' });
|
|
335
|
+
await tx.connector.insert(profileTable).values({ userId: '...', bio: 'Hello' });
|
|
336
|
+
|
|
337
|
+
await tx.commit();
|
|
338
|
+
} catch (error) {
|
|
339
|
+
await tx.rollback();
|
|
340
|
+
throw error;
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
> **Note:** For most use cases, prefer using `repository.beginTransaction()` which provides a higher-level API. See [Repositories Reference](./repositories.md#transactions) for details.
|
|
345
|
+
|
|
267
346
|
This architecture ensures that datasources are configured consistently and that the fully-initialized Drizzle connector, aware of all schemas and relations, is available to repositories for querying.
|
|
347
|
+
|
|
348
|
+
## See Also
|
|
349
|
+
|
|
350
|
+
- **Related Concepts:**
|
|
351
|
+
- [DataSources Guide](/guides/core-concepts/persistent/datasources) - Creating DataSources tutorial
|
|
352
|
+
- [Repositories](/guides/core-concepts/persistent/repositories) - Using DataSources for database access
|
|
353
|
+
- [Models](/guides/core-concepts/persistent/models) - Entity schemas loaded by DataSource
|
|
354
|
+
- [Transactions](/guides/core-concepts/persistent/transactions) - Multi-operation database transactions
|
|
355
|
+
|
|
356
|
+
- **References:**
|
|
357
|
+
- [Repositories API](/references/base/repositories/) - Data access layer
|
|
358
|
+
- [Environment Variables](/references/configuration/environment-variables) - Configuration management
|
|
359
|
+
|
|
360
|
+
- **External Resources:**
|
|
361
|
+
- [Drizzle ORM Documentation](https://orm.drizzle.team/) - ORM configuration
|
|
362
|
+
- [node-postgres Documentation](https://node-postgres.com/) - Connection pooling guide
|
|
363
|
+
|
|
364
|
+
- **Best Practices:**
|
|
365
|
+
- [Performance Optimization](/best-practices/performance-optimization) - Connection pool tuning
|
|
366
|
+
- [Security Guidelines](/best-practices/security-guidelines) - Database credential management
|
|
367
|
+
|
|
368
|
+
- **Tutorials:**
|
|
369
|
+
- [Complete Installation](/guides/tutorials/complete-installation) - Database setup
|
|
370
|
+
- [Building a CRUD API](/guides/tutorials/building-a-crud-api) - DataSource configuration
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Dependency Injection Reference
|
|
3
|
+
description: Technical reference for the DI system in IGNIS
|
|
4
|
+
difficulty: advanced
|
|
5
|
+
---
|
|
6
|
+
|
|
1
7
|
# Deep Dive: Dependency Injection
|
|
2
8
|
|
|
3
9
|
Technical reference for the DI system in Ignis - managing resource lifecycles and dependency resolution.
|
|
@@ -18,6 +24,15 @@ Technical reference for the DI system in Ignis - managing resource lifecycles an
|
|
|
18
24
|
| **MetadataRegistry** | Stores decorator metadata | Singleton accessed via `getInstance()` |
|
|
19
25
|
| **Boot System** | Automatic artifact discovery and binding | Integrates with Container via tags and bindings |
|
|
20
26
|
|
|
27
|
+
## Prerequisites
|
|
28
|
+
|
|
29
|
+
Before reading this document, you should understand:
|
|
30
|
+
|
|
31
|
+
- [TypeScript Decorators](https://www.typescriptlang.org/docs/handbook/decorators.html) - How decorators work in TypeScript
|
|
32
|
+
- [IGNIS Application basics](./application.md) - Application lifecycle and initialization
|
|
33
|
+
- [Services](./services.md) and [Controllers](./controllers.md) - Basic understanding of IGNIS architecture
|
|
34
|
+
- Inversion of Control (IoC) pattern - [Martin Fowler's article](https://martinfowler.com/articles/injection.html)
|
|
35
|
+
|
|
21
36
|
## `Container` Class
|
|
22
37
|
|
|
23
38
|
Heart of the DI system - registry managing all application resources.
|
|
@@ -161,8 +176,8 @@ app.bind({ key: 'controllers.UserController' }).toClass(UserController);
|
|
|
161
176
|
@injectable()
|
|
162
177
|
class UserController {
|
|
163
178
|
constructor(
|
|
164
|
-
@inject({ key: 'services.UserService' })
|
|
165
|
-
private
|
|
179
|
+
@inject({ key: 'services.UserService' })
|
|
180
|
+
private _userService: UserService // Auto-injected!
|
|
166
181
|
) {}
|
|
167
182
|
}
|
|
168
183
|
```
|
|
@@ -174,4 +189,25 @@ class UserController {
|
|
|
174
189
|
- **Extensible**: Custom booters integrate seamlessly via tags
|
|
175
190
|
- **Type-safe**: Full TypeScript support throughout boot process
|
|
176
191
|
|
|
177
|
-
> **Learn More:** See [Bootstrapping Concepts](/
|
|
192
|
+
> **Learn More:** See [Bootstrapping Concepts](/guides/core-concepts/application/bootstrapping) and [Boot Package Reference](/references/src-details/boot.md)
|
|
193
|
+
|
|
194
|
+
## See Also
|
|
195
|
+
|
|
196
|
+
- **Related Concepts:**
|
|
197
|
+
- [Dependency Injection Guide](/guides/core-concepts/dependency-injection) - DI fundamentals tutorial
|
|
198
|
+
- [Application](/guides/core-concepts/application/) - Application extends Container
|
|
199
|
+
- [Controllers](/guides/core-concepts/controllers) - Use DI for injecting services
|
|
200
|
+
- [Services](/guides/core-concepts/services) - Use DI for injecting repositories
|
|
201
|
+
- [Providers](/references/base/providers) - Factory pattern for dynamic injection
|
|
202
|
+
|
|
203
|
+
- **References:**
|
|
204
|
+
- [Inversion Helper](/references/helpers/inversion) - DI container utilities
|
|
205
|
+
- [Bootstrapping API](/references/base/bootstrapping) - Auto-discovery and DI
|
|
206
|
+
- [Glossary](/guides/reference/glossary#dependency-injection-di) - DI concepts explained
|
|
207
|
+
|
|
208
|
+
- **Tutorials:**
|
|
209
|
+
- [Testing](/guides/tutorials/testing) - Unit testing with mocked dependencies
|
|
210
|
+
- [Building a CRUD API](/guides/tutorials/building-a-crud-api) - DI in practice
|
|
211
|
+
|
|
212
|
+
- **Best Practices:**
|
|
213
|
+
- [Architectural Patterns](/best-practices/architectural-patterns) - DI patterns and anti-patterns
|