@venizia/ignis-docs 0.0.7 → 0.0.8-1

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 (172) hide show
  1. package/dist/mcp-server/common/paths.d.ts +4 -2
  2. package/dist/mcp-server/common/paths.d.ts.map +1 -1
  3. package/dist/mcp-server/common/paths.js +8 -6
  4. package/dist/mcp-server/common/paths.js.map +1 -1
  5. package/dist/mcp-server/helpers/docs.helper.d.ts.map +1 -1
  6. package/dist/mcp-server/helpers/docs.helper.js +1 -1
  7. package/dist/mcp-server/helpers/docs.helper.js.map +1 -1
  8. package/dist/mcp-server/tools/base.tool.d.ts +1 -1
  9. package/dist/mcp-server/tools/docs/get-document-content.tool.d.ts +1 -1
  10. package/dist/mcp-server/tools/docs/get-document-content.tool.d.ts.map +1 -1
  11. package/dist/mcp-server/tools/docs/get-document-content.tool.js +7 -7
  12. package/dist/mcp-server/tools/docs/get-document-metadata.tool.js +3 -3
  13. package/dist/mcp-server/tools/docs/get-package-overview.tool.d.ts +1 -1
  14. package/dist/mcp-server/tools/docs/get-package-overview.tool.js +1 -1
  15. package/dist/mcp-server/tools/docs/search-documents.tool.d.ts +1 -1
  16. package/dist/mcp-server/tools/docs/search-documents.tool.js +1 -1
  17. package/dist/mcp-server/tools/docs/search-documents.tool.js.map +1 -1
  18. package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
  19. package/dist/mcp-server/tools/github/list-project-files.tool.js +1 -1
  20. package/dist/mcp-server/tools/github/list-project-files.tool.js.map +1 -1
  21. package/dist/mcp-server/tools/github/search-code.tool.d.ts +1 -1
  22. package/dist/mcp-server/tools/github/search-code.tool.js +1 -1
  23. package/dist/mcp-server/tools/github/search-code.tool.js.map +1 -1
  24. package/package.json +9 -9
  25. package/wiki/best-practices/api-usage-examples.md +9 -9
  26. package/wiki/best-practices/architectural-patterns.md +19 -3
  27. package/wiki/best-practices/architecture-decisions.md +6 -6
  28. package/wiki/best-practices/code-style-standards/advanced-patterns.md +1 -1
  29. package/wiki/best-practices/code-style-standards/control-flow.md +1 -1
  30. package/wiki/best-practices/code-style-standards/function-patterns.md +2 -2
  31. package/wiki/best-practices/code-style-standards/index.md +2 -2
  32. package/wiki/best-practices/code-style-standards/naming-conventions.md +1 -1
  33. package/wiki/best-practices/code-style-standards/route-definitions.md +4 -4
  34. package/wiki/best-practices/data-modeling.md +1 -1
  35. package/wiki/best-practices/deployment-strategies.md +1 -1
  36. package/wiki/best-practices/error-handling.md +2 -2
  37. package/wiki/best-practices/performance-optimization.md +3 -3
  38. package/wiki/best-practices/security-guidelines.md +2 -2
  39. package/wiki/best-practices/troubleshooting-tips.md +1 -1
  40. package/wiki/{references → extensions}/components/authentication/api.md +12 -20
  41. package/wiki/{references → extensions}/components/authentication/errors.md +1 -1
  42. package/wiki/{references → extensions}/components/authentication/index.md +5 -8
  43. package/wiki/{references → extensions}/components/authentication/usage.md +20 -36
  44. package/wiki/{references → extensions}/components/authorization/api.md +62 -13
  45. package/wiki/{references → extensions}/components/authorization/errors.md +12 -7
  46. package/wiki/{references → extensions}/components/authorization/index.md +93 -6
  47. package/wiki/{references → extensions}/components/authorization/usage.md +42 -4
  48. package/wiki/{references → extensions}/components/health-check.md +5 -4
  49. package/wiki/{references → extensions}/components/index.md +2 -0
  50. package/wiki/{references → extensions}/components/mail/index.md +1 -1
  51. package/wiki/{references → extensions}/components/request-tracker.md +1 -1
  52. package/wiki/{references → extensions}/components/socket-io/api.md +2 -2
  53. package/wiki/{references → extensions}/components/socket-io/errors.md +2 -0
  54. package/wiki/{references → extensions}/components/socket-io/index.md +24 -20
  55. package/wiki/{references → extensions}/components/socket-io/usage.md +2 -2
  56. package/wiki/{references → extensions}/components/static-asset/api.md +14 -15
  57. package/wiki/{references → extensions}/components/static-asset/errors.md +3 -1
  58. package/wiki/{references → extensions}/components/static-asset/index.md +158 -89
  59. package/wiki/{references → extensions}/components/static-asset/usage.md +8 -5
  60. package/wiki/{references → extensions}/components/swagger.md +3 -3
  61. package/wiki/{references → extensions}/components/template/index.md +4 -4
  62. package/wiki/{references → extensions}/components/template/setup-page.md +1 -1
  63. package/wiki/{references → extensions}/components/template/single-page.md +1 -1
  64. package/wiki/{references → extensions}/components/websocket/api.md +7 -6
  65. package/wiki/{references → extensions}/components/websocket/errors.md +17 -3
  66. package/wiki/{references → extensions}/components/websocket/index.md +17 -11
  67. package/wiki/{references → extensions}/components/websocket/usage.md +2 -2
  68. package/wiki/{references → extensions}/helpers/crypto/index.md +1 -1
  69. package/wiki/{references → extensions}/helpers/env/index.md +9 -5
  70. package/wiki/{references → extensions}/helpers/error/index.md +2 -7
  71. package/wiki/{references → extensions}/helpers/index.md +18 -6
  72. package/wiki/{references → extensions}/helpers/kafka/admin.md +13 -1
  73. package/wiki/{references → extensions}/helpers/kafka/consumer.md +32 -31
  74. package/wiki/{references → extensions}/helpers/kafka/examples.md +20 -20
  75. package/wiki/{references → extensions}/helpers/kafka/index.md +61 -54
  76. package/wiki/{references → extensions}/helpers/kafka/producer.md +21 -20
  77. package/wiki/{references → extensions}/helpers/kafka/schema-registry.md +25 -25
  78. package/wiki/{references → extensions}/helpers/logger/index.md +2 -2
  79. package/wiki/{references → extensions}/helpers/queue/index.md +400 -4
  80. package/wiki/{references → extensions}/helpers/storage/api.md +170 -10
  81. package/wiki/{references → extensions}/helpers/storage/index.md +44 -8
  82. package/wiki/{references → extensions}/helpers/template/index.md +1 -1
  83. package/wiki/{references → extensions}/helpers/testing/index.md +4 -4
  84. package/wiki/{references → extensions}/helpers/types/index.md +63 -16
  85. package/wiki/{references → extensions}/helpers/websocket/index.md +1 -1
  86. package/wiki/extensions/index.md +48 -0
  87. package/wiki/guides/core-concepts/application/bootstrapping.md +55 -37
  88. package/wiki/guides/core-concepts/application/index.md +95 -35
  89. package/wiki/guides/core-concepts/components-guide.md +23 -19
  90. package/wiki/guides/core-concepts/components.md +34 -10
  91. package/wiki/guides/core-concepts/dependency-injection.md +99 -34
  92. package/wiki/guides/core-concepts/grpc-controllers.md +295 -0
  93. package/wiki/guides/core-concepts/persistent/datasources.md +37 -19
  94. package/wiki/guides/core-concepts/persistent/index.md +6 -6
  95. package/wiki/guides/core-concepts/persistent/models.md +50 -6
  96. package/wiki/guides/core-concepts/persistent/repositories.md +83 -8
  97. package/wiki/guides/core-concepts/persistent/transactions.md +39 -8
  98. package/wiki/guides/core-concepts/{controllers.md → rest-controllers.md} +32 -35
  99. package/wiki/guides/core-concepts/services.md +19 -6
  100. package/wiki/guides/get-started/5-minute-quickstart.md +17 -17
  101. package/wiki/guides/get-started/philosophy.md +1 -1
  102. package/wiki/guides/index.md +2 -2
  103. package/wiki/guides/reference/glossary.md +7 -7
  104. package/wiki/guides/reference/mcp-docs-server.md +1 -1
  105. package/wiki/guides/tutorials/building-a-crud-api.md +45 -39
  106. package/wiki/guides/tutorials/complete-installation.md +74 -51
  107. package/wiki/guides/tutorials/ecommerce-api.md +39 -30
  108. package/wiki/guides/tutorials/realtime-chat.md +12 -13
  109. package/wiki/guides/tutorials/testing.md +2 -2
  110. package/wiki/index.md +4 -3
  111. package/wiki/references/base/application.md +341 -21
  112. package/wiki/references/base/bootstrapping.md +43 -13
  113. package/wiki/references/base/components.md +259 -8
  114. package/wiki/references/base/controllers.md +556 -253
  115. package/wiki/references/base/datasources.md +159 -79
  116. package/wiki/references/base/dependency-injection.md +299 -48
  117. package/wiki/references/base/filter-system/application-usage.md +18 -2
  118. package/wiki/references/base/filter-system/array-operators.md +14 -6
  119. package/wiki/references/base/filter-system/comparison-operators.md +9 -3
  120. package/wiki/references/base/filter-system/default-filter.md +28 -3
  121. package/wiki/references/base/filter-system/fields-order-pagination.md +17 -13
  122. package/wiki/references/base/filter-system/index.md +169 -11
  123. package/wiki/references/base/filter-system/json-filtering.md +51 -18
  124. package/wiki/references/base/filter-system/list-operators.md +4 -3
  125. package/wiki/references/base/filter-system/logical-operators.md +7 -2
  126. package/wiki/references/base/filter-system/null-operators.md +50 -0
  127. package/wiki/references/base/filter-system/quick-reference.md +82 -243
  128. package/wiki/references/base/filter-system/range-operators.md +7 -1
  129. package/wiki/references/base/filter-system/tips.md +34 -7
  130. package/wiki/references/base/filter-system/use-cases.md +6 -5
  131. package/wiki/references/base/grpc-controllers.md +984 -0
  132. package/wiki/references/base/index.md +32 -24
  133. package/wiki/references/base/middleware.md +347 -0
  134. package/wiki/references/base/models.md +390 -46
  135. package/wiki/references/base/providers.md +14 -14
  136. package/wiki/references/base/repositories/advanced.md +195 -69
  137. package/wiki/references/base/repositories/index.md +447 -12
  138. package/wiki/references/base/repositories/mixins.md +103 -98
  139. package/wiki/references/base/repositories/relations.md +129 -45
  140. package/wiki/references/base/repositories/soft-deletable.md +104 -23
  141. package/wiki/references/base/services.md +94 -14
  142. package/wiki/references/index.md +12 -10
  143. package/wiki/references/quick-reference.md +98 -65
  144. package/wiki/references/utilities/crypto.md +21 -4
  145. package/wiki/references/utilities/date.md +25 -7
  146. package/wiki/references/utilities/index.md +26 -24
  147. package/wiki/references/utilities/jsx.md +54 -54
  148. package/wiki/references/utilities/module.md +8 -6
  149. package/wiki/references/utilities/parse.md +16 -9
  150. package/wiki/references/utilities/performance.md +22 -7
  151. package/wiki/references/utilities/promise.md +19 -16
  152. package/wiki/references/utilities/request.md +48 -26
  153. package/wiki/references/utilities/schema.md +69 -6
  154. package/wiki/references/utilities/statuses.md +131 -140
  155. /package/wiki/{references → extensions}/components/mail/api.md +0 -0
  156. /package/wiki/{references → extensions}/components/mail/errors.md +0 -0
  157. /package/wiki/{references → extensions}/components/mail/usage.md +0 -0
  158. /package/wiki/{references → extensions}/components/template/api-page.md +0 -0
  159. /package/wiki/{references → extensions}/components/template/errors-page.md +0 -0
  160. /package/wiki/{references → extensions}/components/template/usage-page.md +0 -0
  161. /package/wiki/{references → extensions}/helpers/cron/index.md +0 -0
  162. /package/wiki/{references → extensions}/helpers/inversion/index.md +0 -0
  163. /package/wiki/{references → extensions}/helpers/network/api.md +0 -0
  164. /package/wiki/{references → extensions}/helpers/network/index.md +0 -0
  165. /package/wiki/{references → extensions}/helpers/redis/index.md +0 -0
  166. /package/wiki/{references → extensions}/helpers/socket-io/api.md +0 -0
  167. /package/wiki/{references → extensions}/helpers/socket-io/index.md +0 -0
  168. /package/wiki/{references → extensions}/helpers/template/single-page.md +0 -0
  169. /package/wiki/{references → extensions}/helpers/uid/index.md +0 -0
  170. /package/wiki/{references → extensions}/helpers/websocket/api.md +0 -0
  171. /package/wiki/{references → extensions}/helpers/worker-thread/index.md +0 -0
  172. /package/wiki/{references → extensions}/src-details/mcp-server.md +0 -0
@@ -11,8 +11,8 @@ Build your first Ignis API endpoint in 5 minutes. No database, no complex setup
11
11
  ```bash
12
12
  mkdir my-app && cd my-app
13
13
  bun init -y
14
- bun add hono @hono/zod-openapi @scalar/hono-api-reference @venizia/ignis
15
- bun add -d typescript @types/bun @venizia/dev-configs
14
+ bun add hono @hono/zod-openapi @scalar/hono-api-reference @venizia/ignis @venizia/ignis-helpers
15
+ bun add -d typescript @types/bun @venizia/dev-configs eslint prettier tsc-alias
16
16
  ```
17
17
 
18
18
  ## Step 2: Configure Development Tools (30 seconds)
@@ -81,7 +81,7 @@ Create `src/index.ts`:
81
81
  import { z } from "@hono/zod-openapi";
82
82
  import {
83
83
  BaseApplication,
84
- BaseController,
84
+ BaseRestController,
85
85
  controller,
86
86
  get,
87
87
  IApplicationInfo,
@@ -94,21 +94,18 @@ import appInfo from "./../package.json";
94
94
 
95
95
  // 1. Define a controller
96
96
  @controller({ path: "/hello" })
97
- class HelloController extends BaseController {
97
+ class HelloController extends BaseRestController {
98
98
  constructor() {
99
99
  super({ scope: "HelloController", path: "/hello" });
100
100
  }
101
101
 
102
- // NOTE: This is a function that must be overridden.
103
- override binding() {
104
- // Bind dependencies here (if needed)
105
- // Extra binding routes with functional way, use `bindRoute` or `defineRoute`
106
- }
102
+ // Override binding() to register custom routes via bindRoute() or defineRoute().
103
+ // For decorator-based routes (@get, @post), this can be empty.
104
+ override binding() {}
107
105
 
108
106
  @get({
109
107
  configs: {
110
108
  path: "/",
111
- method: HTTP.Methods.GET,
112
109
  responses: {
113
110
  [HTTP.ResultCodes.RS_2.Ok]: jsonContent({
114
111
  description: "Says hello",
@@ -153,9 +150,11 @@ const app = new App({
153
150
  host: "0.0.0.0",
154
151
  port: 3000,
155
152
  path: { base: "/api", isStrict: false },
153
+ debug: { shouldShowRoutes: true }, // Prints all registered routes on startup
156
154
  },
157
155
  });
158
156
 
157
+ // start() runs the full lifecycle: preConfigure → register resources → setupMiddlewares → HTTP server
159
158
  app.start();
160
159
  ```
161
160
 
@@ -178,10 +177,11 @@ Update `package.json` to add build scripts:
178
177
  "server:prod": "NODE_ENV=production bun run dist/index.js"
179
178
  },
180
179
  "dependencies": {
181
- "hono": "^4.4.12",
180
+ "hono": "^4.12.1",
182
181
  "@hono/zod-openapi": "latest",
183
182
  "@scalar/hono-api-reference": "latest",
184
- "@venizia/ignis": "latest"
183
+ "@venizia/ignis": "latest",
184
+ "@venizia/ignis-helpers": "latest"
185
185
  },
186
186
  "devDependencies": {
187
187
  "typescript": "^5.5.3",
@@ -235,13 +235,13 @@ Open `http://localhost:3000/doc/explorer` to see interactive Swagger UI document
235
235
 
236
236
  | Component | What It Does |
237
237
  |-----------|--------------|
238
- | `@controller` | Registers a class as an API controller at `/api/hello` |
239
- | `@get` | Defines a GET endpoint with OpenAPI metadata |
238
+ | `@controller` | Registers a class as an API controller at `/api/hello`. Supports `transport` field for REST (default) or gRPC |
239
+ | `@get` | Defines a GET endpoint with OpenAPI metadata (auto-sets HTTP method) |
240
240
  | `Zod schema` | Validates request/response and auto-generates OpenAPI docs |
241
- | `BaseController` | Provides lifecycle hooks and route binding capabilities |
241
+ | `BaseRestController` | Provides lifecycle hooks, route binding, and OpenAPI integration for REST controllers |
242
242
  | `BaseApplication` | Manages dependency injection, middleware, and server startup |
243
243
  | `SwaggerComponent` | Generates interactive API docs at `/doc/explorer` |
244
- | `app.start()` | Boots the DI container and starts HTTP server on port 3000 |
244
+ | `app.start()` | Runs the full lifecycle (preConfigure → register resources → middlewares) then starts HTTP server on port 3000 |
245
245
 
246
246
  ### Why Development Configs?
247
247
 
@@ -296,7 +296,7 @@ You might wonder why we set up TypeScript, ESLint, and Prettier configs in a "qu
296
296
  },
297
297
  })
298
298
  async greet(c: Context) {
299
- const { name } = await c.req.json();
299
+ const { name } = c.req.valid('json');
300
300
  return c.json({ greeting: `Hello, ${name}!` }, HTTP.ResultCodes.RS_2.Ok);
301
301
  }
302
302
  ```
@@ -13,7 +13,7 @@ Ignis combines the structured, enterprise-grade development experience of **Loop
13
13
 
14
14
  ## The Framework Landscape
15
15
 
16
- When building REST APIs with Node.js/Bun, developers choose from three categories of frameworks:
16
+ When building REST APIs and server applications with Node.js/Bun, developers choose from three categories of frameworks:
17
17
 
18
18
  <div class="landscape-grid">
19
19
 
@@ -1,6 +1,6 @@
1
1
  # Getting Started with Ignis
2
2
 
3
- Welcome to Ignis — a TypeScript framework that combines enterprise architecture patterns with Hono's blazing performance. Whether you're building a SaaS backend, REST API, or microservice, these guides will take you from installation to production-ready code with type-safe database operations, auto-generated OpenAPI docs, and clean dependency injection.
3
+ Welcome to Ignis — a TypeScript framework that combines enterprise architecture patterns with Hono's blazing performance. Whether you're building a SaaS backend, REST API, gRPC service, or microservice, these guides will take you from installation to production-ready code with type-safe database operations, auto-generated OpenAPI docs, and clean dependency injection.
4
4
 
5
5
  <div class="guide-cards">
6
6
 
@@ -63,7 +63,7 @@ Welcome to Ignis — a TypeScript framework that combines enterprise architectur
63
63
  <span class="stage-num">3</span>
64
64
  <h4>Understand the Framework</h4>
65
65
  </div>
66
- <p><a href="./core-concepts/application">Application</a> → <a href="./core-concepts/controllers">Controllers</a> → <a href="./core-concepts/services">Services</a> → <a href="./core-concepts/dependency-injection">DI</a></p>
66
+ <p><a href="./core-concepts/application">Application</a> → <a href="./core-concepts/rest-controllers">Controllers</a> → <a href="./core-concepts/services">Services</a> → <a href="./core-concepts/dependency-injection">DI</a></p>
67
67
  <span class="stage-desc">Deep dive into core concepts and architecture patterns</span>
68
68
  </div>
69
69
 
@@ -8,7 +8,7 @@ Quick reference for key terms in Ignis documentation.
8
8
  | Term | Description |
9
9
  |------|-------------|
10
10
  | **Application** | Main entry point extending `BaseApplication`. Registers all components. |
11
- | **Controller** | Handles HTTP requests, defines API endpoints (`@controller`, `@get`, `@post`) |
11
+ | **Controller** | Handles HTTP/gRPC requests, defines API endpoints. REST controllers extend `BaseRestController`, gRPC controllers extend `BaseGrpcController`. Uses `@controller`, `@get`, `@post` decorators |
12
12
  | **Service** | Contains business logic between controllers and repositories |
13
13
  | **Repository** | Database operations for one entity (`find`, `create`, `updateById`, etc.) |
14
14
  | **DataSource** | Database connection configuration (host, port, credentials) |
@@ -36,7 +36,7 @@ const TodoRoutes = {
36
36
  } as const;
37
37
 
38
38
  @controller({ path: '/todos' })
39
- export class TodoController extends BaseController {
39
+ export class TodoController extends BaseRestController {
40
40
  @get({ configs: TodoRoutes.GET_ALL })
41
41
  async getAll(c: TRouteContext) {
42
42
  const todos = await this.repository.find({});
@@ -49,7 +49,7 @@ export class TodoController extends BaseController {
49
49
  export class TodoRepository extends DefaultCRUDRepository<typeof Todo.schema> {}
50
50
  ```
51
51
 
52
- **Related:** [Application](../core-concepts/application/) | [Controllers](../core-concepts/controllers) | [Services](../core-concepts/services) | [Repositories](../../references/base/repositories/)
52
+ **Related:** [Application](../core-concepts/application/) | [Controllers](../core-concepts/rest-controllers) | [Services](../core-concepts/services) | [Repositories](../../references/base/repositories/)
53
53
 
54
54
 
55
55
  ## TypeScript & Pattern Terms
@@ -59,7 +59,7 @@ Annotations starting with `@` that add behavior to classes/methods.
59
59
 
60
60
  | Decorator | Purpose |
61
61
  |-----------|---------|
62
- | `@controller` | Marks class as controller |
62
+ | `@controller` | Marks class as controller. Supports `transport` field (`'rest'` default, `'grpc'`) |
63
63
  | `@model` | Marks class as model/entity |
64
64
  | `@repository` | Marks class as repository |
65
65
  | `@datasource` | Marks class as datasource |
@@ -164,7 +164,7 @@ await repository.find({
164
164
  | Operator | Meaning | Example |
165
165
  |----------|---------|---------|
166
166
  | `eq` | Equal | `{ status: { eq: 'active' } }` |
167
- | `ne` | Not equal | `{ status: { ne: 'deleted' } }` |
167
+ | `neq` | Not equal | `{ status: { neq: 'deleted' } }` |
168
168
  | `gt`, `gte` | Greater than (or equal) | `{ age: { gte: 18 } }` |
169
169
  | `lt`, `lte` | Less than (or equal) | `{ price: { lt: 100 } }` |
170
170
  | `like`, `ilike` | Pattern match | `{ name: { like: '%john%' } }` |
@@ -194,7 +194,7 @@ const TodoRoutes = {
194
194
  } as const;
195
195
 
196
196
  @controller({ path: '/todos' })
197
- class TodoController {
197
+ class TodoController extends BaseRestController {
198
198
  @get({ configs: TodoRoutes.GET_ALL })
199
199
  async getAll(c: TRouteContext) { ... }
200
200
 
@@ -217,7 +217,7 @@ class TodoController {
217
217
  | **Endpoint** | URL path that API responds to (e.g., `GET /todos`) |
218
218
  | **Route Parameter** | Variable in URL marked with `:` (e.g., `:id`) |
219
219
  | **Request Body** | JSON data sent with POST/PATCH requests |
220
- | **OpenAPI/Swagger** | Auto-generated API docs at `/docs` |
220
+ | **OpenAPI/Swagger** | Auto-generated API docs at `/doc/explorer` (default path via SwaggerComponent) |
221
221
 
222
222
 
223
223
  ## Environment & Configuration
@@ -755,7 +755,7 @@ If this works, the issue is specific to `@venizia/ignis-docs`.
755
755
 
756
756
  ## What's Next?
757
757
 
758
- - **Learn the Tools:** Read the [Deep Dive Guide](/references/src-details/mcp-server) to understand all 5 available tools
758
+ - **Learn the Tools:** Read the [Deep Dive Guide](/extensions/src-details/mcp-server) to understand all 5 available tools
759
759
  - **Advanced Usage:** Explore how to chain tools for complex documentation queries
760
760
  - **Contribute:** Help improve the docs or add new features
761
761
 
@@ -74,10 +74,10 @@ HTTP Request (GET /api/todos/:id)
74
74
 
75
75
  ```bash
76
76
  # Add database packages
77
- bun add drizzle-orm drizzle-zod pg lodash
77
+ bun add drizzle-orm drizzle-zod pg
78
78
 
79
79
  # Add dev dependencies for migrations
80
- bun add -d drizzle-kit @types/pg @types/lodash
80
+ bun add -d drizzle-kit @types/pg
81
81
  ```
82
82
 
83
83
  ## Step 2: Define the Model
@@ -182,7 +182,6 @@ Create `src/datasources/postgres.datasource.ts`:
182
182
  import {
183
183
  BaseDataSource,
184
184
  datasource,
185
- TNodePostgresConnector,
186
185
  ValueOrPromise,
187
186
  } from '@venizia/ignis';
188
187
  import { drizzle } from 'drizzle-orm/node-postgres';
@@ -205,7 +204,7 @@ interface IDSConfigs {
205
204
  * 3. Drizzle is initialized with the auto-discovered schema
206
205
  */
207
206
  @datasource({ driver: 'node-postgres' })
208
- export class PostgresDataSource extends BaseDataSource<TNodePostgresConnector, IDSConfigs> {
207
+ export class PostgresDataSource extends BaseDataSource<IDSConfigs> {
209
208
  constructor() {
210
209
  super({
211
210
  name: PostgresDataSource.name,
@@ -243,7 +242,7 @@ export class PostgresDataSource extends BaseDataSource<TNodePostgresConnector, I
243
242
  - Schema is auto-discovered from `@repository` decorators - no manual registration needed
244
243
  - Uses `getSchema()` for lazy schema resolution (resolves when all models are loaded)
245
244
  - Uses environment variables for connection config
246
- - Implements connection lifecycle methods (`connect()`, `disconnect()`)
245
+ - Implements `configure()` for connection setup and `getConnectionString()` for URL generation
247
246
 
248
247
  > **Deep Dive:** See [DataSources Reference](/references/base/datasources) for advanced configuration and multiple database support.
249
248
 
@@ -306,24 +305,18 @@ Dependency Injection (DI) is a design pattern where objects receive their depend
306
305
 
307
306
  `ControllerFactory` generates a full CRUD controller with automatic validation and OpenAPI docs.
308
307
 
309
- Create `src/controllers/todo.controller.ts`:
308
+ Create `src/controllers/todo/definitions.ts`:
310
309
 
311
310
  ```typescript
312
- // src/controllers/todo.controller.ts
311
+ // src/controllers/todo/definitions.ts
313
312
  import { Todo } from '@/models/todo.model';
314
313
  import { TodoRepository } from '@/repositories/todo.repository';
315
- import {
316
- BindingKeys,
317
- BindingNamespaces,
318
- controller,
319
- ControllerFactory,
320
- inject,
321
- } from '@venizia/ignis';
314
+ import { ControllerFactory } from '@venizia/ignis';
322
315
 
323
- const BASE_PATH = '/todos';
316
+ export const BASE_PATH = '/todos';
324
317
 
325
- // 1. The factory generates a controller class with all CRUD routes
326
- const _Controller = ControllerFactory.defineCrudController({
318
+ // The factory generates a controller class with all CRUD routes
319
+ export const _Controller = ControllerFactory.defineCrudController({
327
320
  repository: { name: TodoRepository.name },
328
321
  controller: {
329
322
  name: 'TodoController',
@@ -331,8 +324,17 @@ const _Controller = ControllerFactory.defineCrudController({
331
324
  },
332
325
  entity: () => Todo, // The entity is used to generate OpenAPI schemas
333
326
  });
327
+ ```
328
+
329
+ Create `src/controllers/todo/todo.controller.ts`:
334
330
 
335
- // 2. Extend the generated controller to inject the repository
331
+ ```typescript
332
+ // src/controllers/todo/todo.controller.ts
333
+ import { TodoRepository } from '@/repositories/todo.repository';
334
+ import { BindingKeys, BindingNamespaces, controller, inject } from '@venizia/ignis';
335
+ import { BASE_PATH, _Controller } from './definitions';
336
+
337
+ // Extend the generated controller to inject the repository
336
338
  @controller({ path: BASE_PATH })
337
339
  export class TodoController extends _Controller {
338
340
  constructor(
@@ -349,6 +351,12 @@ export class TodoController extends _Controller {
349
351
  }
350
352
  ```
351
353
 
354
+ Create `src/controllers/todo/index.ts`:
355
+
356
+ ```typescript
357
+ export * from './todo.controller';
358
+ ```
359
+
352
360
  **Auto-generated Endpoints:**
353
361
  | Method | Path | Description |
354
362
  |--------|------|-------------|
@@ -371,13 +379,13 @@ Update `src/application.ts` to register all components:
371
379
  ```typescript
372
380
  // src/application.ts
373
381
  import { BaseApplication, IApplicationConfigs, IApplicationInfo, SwaggerComponent, ValueOrPromise } from '@venizia/ignis';
374
- import { HelloController } from './controllers/hello.controller';
382
+ import { HelloController } from './controllers/hello';
375
383
  import packageJson from '../package.json';
376
384
 
377
385
  // Import our new components
378
386
  import { PostgresDataSource } from './datasources/postgres.datasource';
379
387
  import { TodoRepository } from './repositories/todo.repository';
380
- import { TodoController } from './controllers/todo.controller';
388
+ import { TodoController } from './controllers/todo';
381
389
 
382
390
  export const appConfigs: IApplicationConfigs = {
383
391
  host: process.env.HOST ?? '0.0.0.0',
@@ -413,6 +421,9 @@ export class Application extends BaseApplication {
413
421
  }
414
422
  ```
415
423
 
424
+ > [!IMPORTANT] Registration Order
425
+ > Register in this order: **DataSources → Repositories → Services → Controllers**. DataSources must exist before Repositories that reference them. The framework resolves dependencies during initialization, so registering out of order will cause "Binding not found" errors.
426
+
416
427
  ## Step 7: Run Database Migration
417
428
 
418
429
  ### Understanding Database Migrations
@@ -462,32 +473,27 @@ Add these scripts to your `package.json`:
462
473
 
463
474
  ```json
464
475
  "scripts": {
465
- "migrate:dev": "NODE_ENV=development drizzle-kit migrate --config=src/migration.ts",
466
- "generate-migration:dev": "NODE_ENV=development drizzle-kit generate --config=src/migration.ts"
476
+ "db:push": "NODE_ENV=development drizzle-kit push --config=src/migration.ts",
477
+ "db:generate": "NODE_ENV=development drizzle-kit generate --config=src/migration.ts",
478
+ "db:migrate": "NODE_ENV=development drizzle-kit migrate --config=src/migration.ts"
467
479
  }
468
480
  ```
469
481
 
470
482
  ### Run the Migration
471
483
 
484
+ For development, use `push` — it reads your schema and applies changes directly to the database:
485
+
472
486
  ```bash
473
- bun run migrate:dev
487
+ bun run db:push
474
488
  ```
475
489
 
476
490
  **What happens when you run this:**
477
491
 
478
492
  1. **Reads** `src/models/todo.model.ts` to see what your schema looks like
479
- 2. **Generates SQL** to create the `Todo` table
480
- 3. **Connects** to your PostgreSQL database
481
- 4. **Executes** the SQL to create the table
482
- 5. **Saves** migration files to `./migration/` folder (for version control)
493
+ 2. **Compares** it against the current database state
494
+ 3. **Generates and executes** the SQL to create/update tables
483
495
 
484
- **Expected output:**
485
- ```
486
- Reading schema...
487
- Generating migration...
488
- Executing migration...
489
- ✓ Done!
490
- ```
496
+ > **Production workflow:** Use `db:generate` to create versioned migration files, then `db:migrate` to apply them. This gives you version control and rollback capability. `push` is simpler but skips the migration file step.
491
497
 
492
498
  **Verify it worked:**
493
499
  ```bash
@@ -574,7 +580,7 @@ sudo service postgresql start # Linux
574
580
 
575
581
  **Fix:**
576
582
  ```bash
577
- bun run migrate:dev
583
+ bun run db:push
578
584
  ```
579
585
 
580
586
  **Verify the table exists:**
@@ -598,7 +604,7 @@ this.controller(TodoController); // ← Make sure this is here!
598
604
  path: { base: '/api', isStrict: true }, // All routes start with /api
599
605
  ```
600
606
 
601
- **Debug:** Set `debug.showRoutes: true` in appConfigs to see all registered routes on startup.
607
+ **Debug:** Set `debug: { shouldShowRoutes: true }` in appConfigs to see all registered routes on startup.
602
608
 
603
609
 
604
610
  ### Error: "Invalid JSON" when creating todo
@@ -629,9 +635,9 @@ Now that you've built the Todo API, try building a **User** feature on your own!
629
635
  |:----:|------|
630
636
  | 1 | Create `src/models/user.model.ts` |
631
637
  | 2 | Create `src/repositories/user.repository.ts` (auto-registers User with PostgresDataSource) |
632
- | 3 | Create `src/controllers/user.controller.ts` |
638
+ | 3 | Create `src/controllers/user/` (definitions.ts, user.controller.ts, index.ts) |
633
639
  | 4 | Register repository and controller in `application.ts` |
634
- | 5 | Run migration: `bun run migrate:dev` |
640
+ | 5 | Push schema: `bun run db:push` |
635
641
  | 6 | Test with curl |
636
642
 
637
643
  **Hint:** Follow the exact same pattern as `Todo`. The only changes are the model name and fields!
@@ -695,7 +701,7 @@ You now have a fully functional CRUD API! Here's what to explore next:
695
701
  3. [Components](../core-concepts/components.md) - Build reusable modules
696
702
 
697
703
  **Add Features:**
698
- 1. [Authentication](/references/components/authentication/) - Add JWT authentication
704
+ 1. [Authentication](/extensions/components/authentication/) - Add JWT authentication
699
705
  2. [Custom Routes](/best-practices/api-usage-examples.md) - Beyond CRUD operations
700
706
  3. [Relationships](../core-concepts/persistent/) - Link todos to users
701
707
 
@@ -19,15 +19,15 @@ bun init -y
19
19
  ### Production Dependencies
20
20
 
21
21
  ```bash
22
- bun add hono @hono/zod-openapi @scalar/hono-api-reference @venizia/ignis dotenv-flow
22
+ bun add hono @hono/zod-openapi @scalar/hono-api-reference @venizia/ignis @venizia/ignis-helpers
23
23
  ```
24
24
 
25
25
  **What each package does:**
26
26
  - `hono` - High-performance web framework
27
27
  - `@hono/zod-openapi` - OpenAPI schema generation with Zod validation
28
28
  - `@scalar/hono-api-reference` - Interactive API documentation UI
29
- - `@venizia/ignis` - Core Ignis framework
30
- - `dotenv-flow` - Environment variable management
29
+ - `@venizia/ignis` - Core Ignis framework (application, controllers, repositories, DI)
30
+ - `@venizia/ignis-helpers` - Utilities (HTTP constants, logger, environment helpers)
31
31
 
32
32
  ### Development Dependencies
33
33
 
@@ -121,7 +121,7 @@ This setup might seem verbose compared to minimal frameworks. The trade-off: ~50
121
121
  ### Create Project Structure
122
122
 
123
123
  ```bash
124
- mkdir -p src/{common,components,configurations,controllers,datasources,helpers,models/{entities,requests,responses},repositories,services,utilities}
124
+ mkdir -p src/{common,components,configurations,controllers/hello,datasources,helpers,models/{entities,requests,responses},repositories,services,utilities}
125
125
  ```
126
126
 
127
127
  Your structure will look like:
@@ -137,7 +137,10 @@ src/
137
137
  │ └── index.ts # App configuration files
138
138
  ├── controllers/
139
139
  │ ├── index.ts # Export all controllers
140
- │ └── hello.controller.ts
140
+ │ └── hello/
141
+ │ ├── definitions.ts # Route configs, schemas, constants
142
+ │ ├── hello.controller.ts
143
+ │ └── index.ts # Barrel export
141
144
  ├── datasources/
142
145
  │ └── index.ts # Database connections
143
146
  ├── helpers/
@@ -155,6 +158,8 @@ src/
155
158
  └── index.ts # Utility functions
156
159
  ```
157
160
 
161
+ Each controller gets its own folder: `definitions.ts` for route configs and Zod schemas, the controller file itself, and an `index.ts` barrel export. This keeps things organized as controllers grow with custom routes, validations, and transformations.
162
+
158
163
  > **Note:** For this guide, we only use `controllers/`. Other folders will be used in the [CRUD Tutorial](./building-a-crud-api.md) when you add database support.
159
164
 
160
165
  ### Create Application Class
@@ -163,7 +168,7 @@ Create `src/application.ts` - this is where you configure and register all your
163
168
 
164
169
  ```typescript
165
170
  import { BaseApplication, IApplicationConfigs, IApplicationInfo, SwaggerComponent, ValueOrPromise } from '@venizia/ignis';
166
- import { HelloController } from './controllers/hello.controller';
171
+ import { HelloController } from './controllers';
167
172
  import packageJson from '../package.json';
168
173
 
169
174
  // Define application configurations
@@ -239,86 +244,97 @@ export class Application extends BaseApplication {
239
244
 
240
245
  **Key takeaway:** You'll mostly work in `preConfigure()` when building your app. The other hooks are there when you need them.
241
246
 
242
- **Application Lifecycle Hooks:**
247
+ **Application Lifecycle Hooks (execution order):**
243
248
  | Hook | Purpose | Usage |
244
249
  |------|---------|-------|
245
250
  | `getAppInfo()` | Application metadata | Required - used for API docs |
246
- | `staticConfigure()` | Static file serving | Optional |
247
- | `setupMiddlewares()` | Global middlewares | Optional |
248
- | `preConfigure()` | **Register resources** | **Main hook** - register controllers, services, etc. |
251
+ | `staticConfigure()` | Static file serving | Optional - runs before DI registration |
252
+ | `preConfigure()` | **Register resources** | **Main hook** - register controllers, services, components, etc. |
253
+ | `registerDataSources()` | Configure datasources | Auto - discovers and configures bound datasources |
254
+ | `registerComponents()` | Configure components | Auto - discovers and configures bound components |
255
+ | `registerControllers()` | Configure controllers | Auto - mounts REST/gRPC routes |
249
256
  | `postConfigure()` | Post-initialization | Optional - seed data, background jobs |
257
+ | `setupMiddlewares()` | Global middlewares | Optional - runs after `initialize()`, before server starts |
250
258
 
251
259
  > **Deep Dive:** See [Application Class Reference](../core-concepts/application/) for detailed lifecycle documentation.
252
260
 
253
261
  ### Create Controller
254
262
 
255
- Create `src/controllers/hello.controller.ts` - controllers handle HTTP requests and return responses:
263
+ Each controller lives in its own folder with separate files for definitions, logic, and exports.
264
+
265
+ Create `src/controllers/hello/definitions.ts` — route configs and schemas:
256
266
 
257
267
  ```typescript
258
- import {
259
- BaseController,
260
- controller,
261
- api,
262
- jsonContent,
263
- } from '@venizia/ignis';
268
+ import { jsonContent } from '@venizia/ignis';
264
269
  import { HTTP } from '@venizia/ignis-helpers';
265
270
  import { z } from '@hono/zod-openapi';
266
- import { Context } from 'hono';
267
271
 
268
- const BASE_PATH = '/hello';
272
+ export const BASE_PATH = '/hello';
273
+
274
+ export const helloRouteConfigs = {
275
+ sayHello: {
276
+ method: HTTP.Methods.GET,
277
+ path: '/',
278
+ responses: {
279
+ [HTTP.ResultCodes.RS_2.Ok]: jsonContent({
280
+ description: 'A simple hello message',
281
+ schema: z.object({ message: z.string() }),
282
+ }),
283
+ },
284
+ },
285
+ } as const;
286
+ ```
287
+
288
+ Create `src/controllers/hello/hello.controller.ts` — the controller class:
289
+
290
+ ```typescript
291
+ import { BaseRestController, controller, api } from '@venizia/ignis';
292
+ import { HTTP } from '@venizia/ignis-helpers';
293
+ import { Context } from 'hono';
294
+ import { BASE_PATH, helloRouteConfigs } from './definitions';
269
295
 
270
- // The @controller decorator registers this class as a controller
271
296
  // All routes in this controller will be under /api/hello (remember path.base: '/api')
272
297
  @controller({ path: BASE_PATH })
273
- export class HelloController extends BaseController {
298
+ export class HelloController extends BaseRestController {
274
299
  constructor() {
275
300
  super({ scope: HelloController.name, path: BASE_PATH });
276
301
  }
277
302
 
278
- // Required: Override binding() to register routes or dependencies
279
- override binding() {
280
- // Option 1: Use bindRoute() or defineRoute() for programmatic route registration
281
- // this.bindRoute({ method: 'get', path: '/programmatic', handler: this.myHandler });
282
-
283
- // Option 2: Use @api decorator on methods (shown below) - recommended
284
- }
303
+ // Override binding() to register custom routes via bindRoute() or defineRoute().
304
+ // For decorator-based routes (@api, @get, @post), this can be empty.
305
+ override binding() {}
285
306
 
286
- // The @api decorator defines a route (prefer @api with method over @get/@post)
287
- @api({
288
- configs: {
289
- method: HTTP.Methods.GET,
290
- path: '/',
291
- // This 'responses' config does two things:
292
- // 1. Generates OpenAPI/Swagger documentation automatically
293
- // 2. Validates that your handler returns the correct shape
294
- responses: {
295
- [HTTP.ResultCodes.RS_2.Ok]: jsonContent({
296
- description: 'A simple hello message',
297
- schema: z.object({ message: z.string() }),
298
- }),
299
- },
300
- },
301
- })
307
+ @api({ configs: helloRouteConfigs.sayHello })
302
308
  sayHello(c: Context) {
303
309
  return c.json({ message: 'Hello, World!' }, HTTP.ResultCodes.RS_2.Ok);
304
310
  }
305
-
306
- // For authenticated endpoints, add 'authStrategies':
307
- // @api({ configs: { method: HTTP.Methods.GET, path: '/secure', authStrategies: [Authentication.STRATEGY_JWT] } })
308
311
  }
309
312
  ```
310
313
 
314
+ Create `src/controllers/hello/index.ts` — barrel export:
315
+
316
+ ```typescript
317
+ export * from './hello.controller';
318
+ ```
319
+
320
+ Create `src/controllers/index.ts` — export all controllers:
321
+
322
+ ```typescript
323
+ export * from './hello';
324
+ ```
325
+
311
326
  **Controller Patterns:**
312
327
 
313
328
  | Pattern | Description |
314
329
  |---------|-------------|
330
+ | `definitions.ts` | Route configs, Zod schemas, and constants — keeps controller file clean |
315
331
  | `@controller` | Registers the class as a controller with a base path |
316
- | `@api` | Defines a route with `method` specified (recommended) |
317
- | `@get`, `@post`, etc. | Shorthand decorators (also work) |
318
- | `binding()` | Required override use `bindRoute()` or `defineRoute()` for programmatic routes |
332
+ | `@api` | Defines a route with `method` specified in configs |
333
+ | `@get`, `@post`, etc. | Shorthand decorators that auto-set the HTTP method (recommended) |
334
+ | `binding()` | Override for programmatic routes via `bindRoute()` / `defineRoute()`. Empty for decorator-based routes |
319
335
  | Zod schemas | Provide automatic validation and OpenAPI docs |
320
336
 
321
- > **Deep Dive:** See [Controllers Reference](../core-concepts/controllers.md) for advanced routing patterns and validation.
337
+ > **Deep Dive:** See [Controllers Reference](../core-concepts/rest-controllers.md) for advanced routing patterns and validation.
322
338
 
323
339
  ### Create Entry Point
324
340
 
@@ -338,6 +354,10 @@ const main = async () => {
338
354
 
339
355
  const applicationName = process.env.APP_ENV_APPLICATION_NAME?.toUpperCase() ?? 'My-App';
340
356
  logger.info('[main] Getting ready to start up %s Application...', applicationName);
357
+
358
+ // start() runs the full lifecycle automatically:
359
+ // staticConfigure → preConfigure → registerDataSources → registerComponents
360
+ // → registerControllers → postConfigure → setupMiddlewares → HTTP server
341
361
  await application.start();
342
362
  return application;
343
363
  };
@@ -345,6 +365,9 @@ const main = async () => {
345
365
  export default main();
346
366
  ```
347
367
 
368
+ > [!TIP]
369
+ > `start()` runs the full lifecycle internally. You only need the explicit `init()` → `boot()` → `start()` sequence when using **auto-discovery** (glob-based booters) to discover controllers/repositories from the filesystem. For manual registration (as shown here), `start()` alone is sufficient.
370
+
348
371
  ## 5. Run Your Application
349
372
 
350
373
  Add common application scripts to your `package.json`: