@venizia/ignis-docs 0.0.8 → 0.2.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 +7 -7
- package/content/best-practices/api-usage-examples.md +15 -12
- package/content/best-practices/architectural-patterns.md +70 -78
- package/content/best-practices/architecture-decisions.md +91 -60
- package/content/best-practices/code-style-standards/advanced-patterns.md +56 -44
- package/content/best-practices/code-style-standards/constants-configuration.md +11 -11
- package/content/best-practices/code-style-standards/control-flow.md +5 -2
- package/content/best-practices/code-style-standards/documentation.md +13 -13
- package/content/best-practices/code-style-standards/function-patterns.md +9 -10
- package/content/best-practices/code-style-standards/index.md +1 -1
- package/content/best-practices/code-style-standards/naming-conventions.md +10 -8
- package/content/best-practices/code-style-standards/route-definitions.md +30 -12
- package/content/best-practices/code-style-standards/tooling.md +8 -5
- package/content/best-practices/code-style-standards/type-safety.md +13 -12
- package/content/best-practices/common-pitfalls.md +56 -37
- package/content/best-practices/contribution-workflow.md +13 -14
- package/content/best-practices/data-modeling.md +46 -22
- package/content/best-practices/deployment-strategies.md +28 -27
- package/content/best-practices/error-handling.md +48 -24
- package/content/best-practices/index.md +5 -5
- package/content/best-practices/performance-optimization.md +40 -31
- package/content/best-practices/security-guidelines.md +52 -23
- package/content/best-practices/testing-strategies.md +65 -51
- package/content/best-practices/troubleshooting-tips.md +24 -24
- package/content/extensions/components/{swagger.md → api-reference.md} +40 -31
- package/content/extensions/components/authentication/api.md +19 -19
- package/content/extensions/components/authentication/errors.md +7 -7
- package/content/extensions/components/authentication/index.md +10 -8
- package/content/extensions/components/authentication/usage.md +101 -6
- package/content/extensions/components/authorization/api.md +45 -25
- package/content/extensions/components/authorization/errors.md +6 -6
- package/content/extensions/components/authorization/index.md +11 -10
- package/content/extensions/components/authorization/usage.md +21 -21
- package/content/extensions/components/health-check.md +1 -1
- package/content/extensions/components/index.md +5 -5
- package/content/extensions/components/mail/errors.md +15 -15
- package/content/extensions/components/mail/index.md +1 -2
- package/content/extensions/components/mail/usage.md +1 -1
- package/content/extensions/components/request-tracker.md +1 -1
- package/content/extensions/components/socket-io/api.md +9 -9
- package/content/extensions/components/socket-io/errors.md +5 -5
- package/content/extensions/components/socket-io/index.md +8 -8
- package/content/extensions/components/socket-io/usage.md +1 -1
- package/content/extensions/components/static-asset/api.md +17 -4
- package/content/extensions/components/static-asset/errors.md +4 -4
- package/content/extensions/components/static-asset/index.md +26 -28
- package/content/extensions/components/static-asset/usage.md +13 -12
- package/content/extensions/components/template/index.md +2 -2
- package/content/extensions/components/template/setup-page.md +1 -1
- package/content/extensions/components/websocket/api.md +3 -3
- package/content/extensions/components/websocket/errors.md +5 -5
- package/content/extensions/components/websocket/index.md +5 -5
- package/content/extensions/components/websocket/usage.md +3 -3
- package/content/extensions/helpers/cron/index.md +2 -2
- package/content/extensions/helpers/crypto/index.md +1 -1
- package/content/extensions/helpers/env/index.md +27 -12
- package/content/extensions/helpers/error/index.md +81 -25
- package/content/extensions/helpers/index.md +2 -3
- package/content/extensions/helpers/inversion/index.md +15 -7
- package/content/extensions/helpers/kafka/compile-binary.md +92 -0
- package/content/extensions/helpers/kafka/examples.md +1 -1
- package/content/extensions/helpers/kafka/index.md +3 -0
- package/content/extensions/helpers/logger/index.md +32 -2
- package/content/extensions/helpers/network/index.md +6 -0
- package/content/extensions/helpers/queue/index.md +14 -17
- package/content/extensions/helpers/redis/index.md +548 -323
- package/content/extensions/helpers/socket-io/index.md +14 -10
- package/content/extensions/helpers/storage/api.md +44 -8
- package/content/extensions/helpers/storage/index.md +43 -7
- package/content/extensions/helpers/template/index.md +6 -3
- package/content/extensions/helpers/types/index.md +11 -8
- package/content/extensions/helpers/websocket/api.md +9 -9
- package/content/extensions/helpers/websocket/index.md +7 -7
- package/content/extensions/helpers/worker-thread/index.md +2 -2
- package/content/extensions/index.md +3 -4
- package/content/extensions/src-details/mcp-server.md +18 -24
- package/content/guides/core-concepts/application/bootstrapping.md +11 -14
- package/content/guides/core-concepts/application/index.md +3 -3
- package/content/guides/core-concepts/components.md +19 -10
- package/content/guides/core-concepts/dependency-injection.md +6 -3
- package/content/guides/core-concepts/grpc-controllers.md +6 -5
- package/content/guides/core-concepts/persistent/datasources.md +42 -43
- package/content/guides/core-concepts/persistent/index.md +16 -7
- package/content/guides/core-concepts/persistent/models.md +24 -20
- package/content/guides/core-concepts/persistent/postgres-drivers.md +201 -0
- package/content/guides/core-concepts/persistent/repositories.md +40 -23
- package/content/guides/core-concepts/persistent/search-meilisearch.md +185 -0
- package/content/guides/core-concepts/persistent/search-typesense.md +431 -0
- package/content/guides/core-concepts/persistent/transactions.md +61 -25
- package/content/guides/core-concepts/rest-controllers.md +12 -9
- package/content/guides/core-concepts/services.md +330 -60
- package/content/guides/get-started/5-minute-quickstart.md +15 -15
- package/content/guides/get-started/philosophy.md +36 -36
- package/content/guides/get-started/setup.md +3 -3
- package/content/guides/index.md +3 -3
- package/content/guides/migrations/redis-helpers-migration.md +177 -0
- package/content/guides/migrations/scoped-rbac-migration.md +17 -17
- package/content/guides/migrations/unified-connectors-migration.md +113 -0
- package/content/guides/reference/glossary.md +19 -12
- package/content/guides/reference/mcp-docs-server.md +22 -18
- package/content/guides/tutorials/building-a-crud-api.md +37 -44
- package/content/guides/tutorials/complete-installation.md +17 -17
- package/content/guides/tutorials/ecommerce-api.md +163 -124
- package/content/guides/tutorials/realtime-chat.md +181 -135
- package/content/guides/tutorials/testing.md +65 -523
- package/content/index.md +2 -180
- package/content/public/apple-touch-icon.png +0 -0
- package/content/public/og-image.png +0 -0
- package/content/public/site.webmanifest +11 -0
- package/content/references/base/application.md +4 -5
- package/content/references/base/bootstrapping.md +18 -5
- package/content/references/base/components.md +149 -120
- package/content/references/base/connectors.md +178 -0
- package/content/references/base/controllers.md +41 -30
- package/content/references/base/datasources.md +163 -92
- package/content/references/base/dependency-injection.md +34 -22
- package/content/references/base/filter-system/application-usage.md +17 -14
- package/content/references/base/filter-system/array-operators.md +7 -2
- package/content/references/base/filter-system/comparison-operators.md +3 -0
- package/content/references/base/filter-system/default-filter.md +89 -71
- package/content/references/base/filter-system/fields-order-pagination.md +22 -22
- package/content/references/base/filter-system/index.md +6 -3
- package/content/references/base/filter-system/json-filtering.md +20 -1
- package/content/references/base/filter-system/list-operators.md +1 -1
- package/content/references/base/filter-system/logical-operators.md +33 -1
- package/content/references/base/filter-system/null-operators.md +30 -1
- package/content/references/base/filter-system/quick-reference.md +23 -4
- package/content/references/base/filter-system/tips.md +5 -5
- package/content/references/base/filter-system/use-cases.md +12 -12
- package/content/references/base/grpc-controllers.md +13 -13
- package/content/references/base/index.md +24 -12
- package/content/references/base/middlewares.md +265 -327
- package/content/references/base/models.md +63 -49
- package/content/references/base/providers.md +136 -130
- package/content/references/base/repositories/advanced.md +59 -58
- package/content/references/base/repositories/index.md +115 -91
- package/content/references/base/repositories/mixins.md +55 -291
- package/content/references/base/repositories/relations.md +54 -64
- package/content/references/base/repositories/soft-deletable.md +31 -30
- package/content/references/base/services.md +296 -93
- package/content/references/configuration/environment-variables.md +49 -31
- package/content/references/configuration/index.md +6 -6
- package/content/references/index.md +17 -12
- package/content/references/quick-reference.md +65 -106
- package/content/references/utilities/crypto.md +65 -23
- package/content/references/utilities/index.md +3 -3
- package/content/references/utilities/jsx.md +6 -4
- package/content/references/utilities/module.md +68 -20
- package/content/references/utilities/parse.md +4 -14
- package/content/references/utilities/promise.md +9 -7
- package/content/references/utilities/schema.md +5 -3
- package/dist/mcp-server/common/guards.d.ts +8 -0
- package/dist/mcp-server/common/guards.d.ts.map +1 -0
- package/dist/mcp-server/common/guards.js +14 -0
- package/dist/mcp-server/common/guards.js.map +1 -0
- package/dist/mcp-server/common/index.d.ts +1 -0
- package/dist/mcp-server/common/index.d.ts.map +1 -1
- package/dist/mcp-server/common/index.js +1 -0
- package/dist/mcp-server/common/index.js.map +1 -1
- package/dist/mcp-server/helpers/docs.helper.d.ts.map +1 -1
- package/dist/mcp-server/helpers/docs.helper.js +4 -2
- package/dist/mcp-server/helpers/docs.helper.js.map +1 -1
- package/dist/mcp-server/helpers/github.helper.js +1 -1
- package/dist/mcp-server/index.js +7 -2
- package/dist/mcp-server/index.js.map +1 -1
- package/dist/mcp-server/tools/base.tool.d.ts +6 -2
- package/dist/mcp-server/tools/base.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/base.tool.js.map +1 -1
- package/dist/mcp-server/tools/docs/search-documents.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.js +4 -1
- package/dist/mcp-server/tools/github/search-code.tool.js.map +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js +3 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js.map +1 -1
- package/package.json +9 -9
- package/content/extensions/helpers/testing/index.md +0 -510
- package/content/references/base/middleware.md +0 -347
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Glossary for Beginners
|
|
2
2
|
|
|
3
|
-
Quick reference for key terms in
|
|
3
|
+
Quick reference for key terms in IGNIS documentation.
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
## Core Framework Terms
|
|
@@ -37,9 +37,16 @@ const TodoRoutes = {
|
|
|
37
37
|
|
|
38
38
|
@controller({ path: '/todos' })
|
|
39
39
|
export class TodoController extends BaseRestController {
|
|
40
|
+
constructor(
|
|
41
|
+
@inject({ key: 'repositories.TodoRepository' })
|
|
42
|
+
private repository: TodoRepository,
|
|
43
|
+
) {
|
|
44
|
+
super({ scope: TodoController.name });
|
|
45
|
+
}
|
|
46
|
+
|
|
40
47
|
@get({ configs: TodoRoutes.GET_ALL })
|
|
41
48
|
async getAll(c: TRouteContext) {
|
|
42
|
-
const todos = await this.repository.find({});
|
|
49
|
+
const todos = await this.repository.find({ filter: {} });
|
|
43
50
|
return c.json(todos, HTTP.ResultCodes.RS_2.Ok);
|
|
44
51
|
}
|
|
45
52
|
}
|
|
@@ -64,7 +71,7 @@ Annotations starting with `@` that add behavior to classes/methods.
|
|
|
64
71
|
| `@repository` | Marks class as repository |
|
|
65
72
|
| `@datasource` | Marks class as datasource |
|
|
66
73
|
| `@inject` | Requests dependency from container |
|
|
67
|
-
| `@get`, `@post`, `@patch`, `@
|
|
74
|
+
| `@get`, `@post`, `@put`, `@patch`, `@del` | HTTP route handlers |
|
|
68
75
|
|
|
69
76
|
### Dependency Injection (DI)
|
|
70
77
|
Classes receive dependencies from an external container instead of creating them internally. Benefits: testable, flexible, maintainable.
|
|
@@ -111,7 +118,7 @@ class TodoRepository extends DefaultCRUDRepository<typeof Todo.schema> {}
|
|
|
111
118
|
|
|
112
119
|
| Term | Description |
|
|
113
120
|
|------|-------------|
|
|
114
|
-
| **ORM** | Tool to work with databases using code instead of raw SQL.
|
|
121
|
+
| **ORM** | Tool to work with databases using code instead of raw SQL. IGNIS uses Drizzle ORM. |
|
|
115
122
|
| **Drizzle ORM** | Type-safe ORM library. [Docs](https://orm.drizzle.team/) |
|
|
116
123
|
| **Schema** | Table structure definition using Drizzle syntax |
|
|
117
124
|
| **Migration** | Script that creates/modifies tables. Version control for database structure. |
|
|
@@ -129,7 +136,7 @@ export const todoTable = pgTable('Todo', {
|
|
|
129
136
|
// Relations
|
|
130
137
|
export const userRelations = createRelations({
|
|
131
138
|
source: userTable,
|
|
132
|
-
relations: [{
|
|
139
|
+
relations: [{ name: 'posts', type: 'many', schema: postTable, metadata: {} }],
|
|
133
140
|
});
|
|
134
141
|
|
|
135
142
|
// Query with relations
|
|
@@ -181,15 +188,15 @@ await repository.find({
|
|
|
181
188
|
| Method | URL | Action |
|
|
182
189
|
|--------|-----|--------|
|
|
183
190
|
| GET | `/todos` | List all |
|
|
184
|
-
| GET | `/todos
|
|
191
|
+
| GET | `/todos/{id}` | Get one |
|
|
185
192
|
| POST | `/todos` | Create |
|
|
186
|
-
| PATCH | `/todos
|
|
187
|
-
| DELETE | `/todos
|
|
193
|
+
| PATCH | `/todos/{id}` | Update |
|
|
194
|
+
| DELETE | `/todos/{id}` | Delete |
|
|
188
195
|
|
|
189
196
|
```typescript
|
|
190
197
|
const TodoRoutes = {
|
|
191
198
|
GET_ALL: { method: HTTP.Methods.GET, path: '/', responses: jsonResponse({ schema: z.array(z.any()) }) },
|
|
192
|
-
GET_BY_ID: { method: HTTP.Methods.GET, path: '
|
|
199
|
+
GET_BY_ID: { method: HTTP.Methods.GET, path: '/{id}', request: { params: z.object({ id: z.string() }) }, responses: jsonResponse({ schema: z.any() }) },
|
|
193
200
|
CREATE: { method: HTTP.Methods.POST, path: '/', request: { body: jsonContent({ schema: z.any() }) }, responses: jsonResponse({ schema: z.any() }) },
|
|
194
201
|
} as const;
|
|
195
202
|
|
|
@@ -215,14 +222,14 @@ class TodoController extends BaseRestController {
|
|
|
215
222
|
| Term | Description |
|
|
216
223
|
|------|-------------|
|
|
217
224
|
| **Endpoint** | URL path that API responds to (e.g., `GET /todos`) |
|
|
218
|
-
| **Route Parameter** | Variable in URL
|
|
225
|
+
| **Route Parameter** | Variable in URL wrapped in braces (e.g., `{id}` in OpenAPI route configs) |
|
|
219
226
|
| **Request Body** | JSON data sent with POST/PATCH requests |
|
|
220
|
-
| **OpenAPI/Swagger** | Auto-generated API docs at `/doc/explorer` (default path via
|
|
227
|
+
| **OpenAPI/Swagger** | Auto-generated API docs at `/doc/explorer` (default path via ApiReferenceComponent) |
|
|
221
228
|
|
|
222
229
|
|
|
223
230
|
## Environment & Configuration
|
|
224
231
|
|
|
225
|
-
Environment variables store configuration outside code (in `.env` files).
|
|
232
|
+
Environment variables store configuration outside code (in `.env` files). IGNIS uses `APP_ENV_` prefix to avoid system conflicts.
|
|
226
233
|
|
|
227
234
|
```bash
|
|
228
235
|
# .env file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Getting Started with
|
|
1
|
+
# Getting Started with IGNIS Docs MCP Server
|
|
2
2
|
|
|
3
|
-
> **What is this?** An MCP (Model Context Protocol) server that lets AI assistants access
|
|
3
|
+
> **What is this?** An MCP (Model Context Protocol) server that lets AI assistants access IGNIS framework documentation in real-time. Your AI gets the latest docs instead of outdated training data.
|
|
4
4
|
|
|
5
5
|
## What You'll Need
|
|
6
6
|
|
|
@@ -210,14 +210,14 @@ Restart your Claude Code session (close terminal and reopen), then test:
|
|
|
210
210
|
|
|
211
211
|
```bash
|
|
212
212
|
# In your Claude Code session, ask:
|
|
213
|
-
Can you search the
|
|
213
|
+
Can you search the IGNIS docs for "dependency injection"?
|
|
214
214
|
```
|
|
215
215
|
|
|
216
216
|
**Expected behavior:**
|
|
217
217
|
|
|
218
218
|
- Claude Code should use the `searchDocs` tool
|
|
219
219
|
- You'll see a message like: `[Using tool: searchDocs]`
|
|
220
|
-
- Results from
|
|
220
|
+
- Results from IGNIS documentation appear
|
|
221
221
|
|
|
222
222
|
**If it doesn't work:**
|
|
223
223
|
|
|
@@ -231,16 +231,16 @@ Once working, try these queries:
|
|
|
231
231
|
|
|
232
232
|
```
|
|
233
233
|
# Search documentation
|
|
234
|
-
"How do I create a controller in
|
|
234
|
+
"How do I create a controller in IGNIS?"
|
|
235
235
|
|
|
236
236
|
# Get specific guide
|
|
237
237
|
"Show me the complete Building a CRUD API guide"
|
|
238
238
|
|
|
239
239
|
# Browse topics
|
|
240
|
-
"What helpers are available in
|
|
240
|
+
"What helpers are available in IGNIS?"
|
|
241
241
|
|
|
242
242
|
# Get code examples
|
|
243
|
-
"Show me an example of dependency injection in
|
|
243
|
+
"Show me an example of dependency injection in IGNIS"
|
|
244
244
|
```
|
|
245
245
|
|
|
246
246
|
## VS Code Setup
|
|
@@ -275,7 +275,7 @@ The configuration location depends on which extension you're using:
|
|
|
275
275
|
|
|
276
276
|
### Add MCP Server Configuration
|
|
277
277
|
|
|
278
|
-
Open the config file for your extension and add the
|
|
278
|
+
Open the config file for your extension and add the IGNIS docs server:
|
|
279
279
|
|
|
280
280
|
**If you installed globally:**
|
|
281
281
|
|
|
@@ -324,7 +324,7 @@ Reload the window: `Cmd/Ctrl + Shift + P` → "Developer: Reload Window"
|
|
|
324
324
|
Open your AI assistant in VS Code and ask:
|
|
325
325
|
|
|
326
326
|
```
|
|
327
|
-
Can you search the
|
|
327
|
+
Can you search the IGNIS docs for "dependency injection"?
|
|
328
328
|
```
|
|
329
329
|
|
|
330
330
|
The assistant should use the MCP tools to access and return documentation.
|
|
@@ -439,9 +439,9 @@ Once configured, you can ask your AI assistant:
|
|
|
439
439
|
### Example 1: Search Documentation
|
|
440
440
|
|
|
441
441
|
```
|
|
442
|
-
You: "How do I set up dependency injection in
|
|
442
|
+
You: "How do I set up dependency injection in IGNIS?"
|
|
443
443
|
AI: [Uses searchDocs tool, finds relevant pages]
|
|
444
|
-
AI: "Based on the
|
|
444
|
+
AI: "Based on the IGNIS documentation..."
|
|
445
445
|
```
|
|
446
446
|
|
|
447
447
|
### Example 2: Get Specific Guide
|
|
@@ -463,9 +463,9 @@ AI: "The Helpers category contains: Redis, Logger, Queue..."
|
|
|
463
463
|
|
|
464
464
|
## Local Development Setup
|
|
465
465
|
|
|
466
|
-
For contributors or those developing
|
|
466
|
+
For contributors or those developing IGNIS itself:
|
|
467
467
|
|
|
468
|
-
### 1. Clone the
|
|
468
|
+
### 1. Clone the IGNIS repository
|
|
469
469
|
|
|
470
470
|
```bash
|
|
471
471
|
git clone https://github.com/venizia-ai/ignis.git
|
|
@@ -481,7 +481,11 @@ bun install
|
|
|
481
481
|
### 3. Run the MCP server in dev mode
|
|
482
482
|
|
|
483
483
|
```bash
|
|
484
|
-
|
|
484
|
+
# From the repo root
|
|
485
|
+
bun run mcp:dev
|
|
486
|
+
|
|
487
|
+
# Or from docs/wiki
|
|
488
|
+
cd docs/wiki && bun run mcp:dev
|
|
485
489
|
```
|
|
486
490
|
|
|
487
491
|
### 4. Configure your AI tool
|
|
@@ -495,7 +499,7 @@ Use absolute paths in your config:
|
|
|
495
499
|
"mcpServers": {
|
|
496
500
|
"ignis-docs-dev": {
|
|
497
501
|
"command": "bun",
|
|
498
|
-
"args": ["run", "/absolute/path/to/ignis/
|
|
502
|
+
"args": ["run", "/absolute/path/to/ignis/docs/wiki/mcp-server/index.ts"]
|
|
499
503
|
}
|
|
500
504
|
}
|
|
501
505
|
}
|
|
@@ -508,7 +512,7 @@ Use absolute paths in your config:
|
|
|
508
512
|
"mcpServers": {
|
|
509
513
|
"ignis-docs-dev": {
|
|
510
514
|
"command": "bun",
|
|
511
|
-
"args": ["run", "C:\\absolute\\path\\to\\ignis\\
|
|
515
|
+
"args": ["run", "C:\\absolute\\path\\to\\ignis\\docs\\wiki\\mcp-server\\index.ts"]
|
|
512
516
|
}
|
|
513
517
|
}
|
|
514
518
|
}
|
|
@@ -539,7 +543,7 @@ cat ~/.config/claude-code/config.json | python -m json.tool
|
|
|
539
543
|
**Test 3: AI tool recognizes MCP server**
|
|
540
544
|
|
|
541
545
|
- Restart your AI tool COMPLETELY (quit and reopen)
|
|
542
|
-
- Ask: `Can you search the
|
|
546
|
+
- Ask: `Can you search the IGNIS docs for "controller"?`
|
|
543
547
|
- Look for: `[Using tool: searchDocs]`
|
|
544
548
|
|
|
545
549
|
|
|
@@ -755,7 +759,7 @@ If this works, the issue is specific to `@venizia/ignis-docs`.
|
|
|
755
759
|
|
|
756
760
|
## What's Next?
|
|
757
761
|
|
|
758
|
-
- **Learn the Tools:** Read the [Deep Dive Guide](/extensions/src-details/mcp-server) to understand all
|
|
762
|
+
- **Learn the Tools:** Read the [Deep Dive Guide](/extensions/src-details/mcp-server) to understand all 10 available tools
|
|
759
763
|
- **Advanced Usage:** Explore how to chain tools for complex documentation queries
|
|
760
764
|
- **Contribute:** Help improve the docs or add new features
|
|
761
765
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Building a CRUD API: A Step-by-Step Tutorial
|
|
2
2
|
|
|
3
|
-
Build a complete, database-backed REST API for managing todos. This guide covers Models, DataSources, Repositories, and Controllers - the core building blocks of
|
|
3
|
+
Build a complete, database-backed REST API for managing todos. This guide covers Models, DataSources, Repositories, and Controllers - the core building blocks of IGNIS applications.
|
|
4
4
|
|
|
5
5
|
**Time to Complete:** ~45 minutes
|
|
6
6
|
|
|
@@ -21,16 +21,16 @@ Build a complete, database-backed REST API for managing todos. This guide covers
|
|
|
21
21
|
**Endpoints:**
|
|
22
22
|
- `POST /todos` - Create todo
|
|
23
23
|
- `GET /todos` - List all todos
|
|
24
|
-
- `GET /todos
|
|
25
|
-
- `PATCH /todos
|
|
26
|
-
- `DELETE /todos
|
|
24
|
+
- `GET /todos/{id}` - Get single todo
|
|
25
|
+
- `PATCH /todos/{id}` - Update todo
|
|
26
|
+
- `DELETE /todos/{id}` - Delete todo
|
|
27
27
|
|
|
28
28
|
### Architecture Flow
|
|
29
29
|
|
|
30
30
|
Here's how a request flows through your application:
|
|
31
31
|
|
|
32
32
|
```
|
|
33
|
-
HTTP Request (GET /api/todos
|
|
33
|
+
HTTP Request (GET /api/todos/{id})
|
|
34
34
|
│
|
|
35
35
|
▼
|
|
36
36
|
┌─────────────────┐
|
|
@@ -66,9 +66,9 @@ HTTP Request (GET /api/todos/:id)
|
|
|
66
66
|
| **Model** | Defines what the data looks like |
|
|
67
67
|
|
|
68
68
|
**Benefits of this separation:**
|
|
69
|
-
- **Testable**
|
|
70
|
-
- **Maintainable**
|
|
71
|
-
- **Flexible**
|
|
69
|
+
- **Testable** - Mock repository in tests
|
|
70
|
+
- **Maintainable** - Clear responsibility for each layer
|
|
71
|
+
- **Flexible** - Change database without touching business logic
|
|
72
72
|
|
|
73
73
|
## Step 1: Install Database Dependencies
|
|
74
74
|
|
|
@@ -90,10 +90,10 @@ Create `src/models/todo.model.ts`:
|
|
|
90
90
|
// src/models/todo.model.ts
|
|
91
91
|
import {
|
|
92
92
|
BaseEntity,
|
|
93
|
-
createRelations,
|
|
94
93
|
generateIdColumnDefs,
|
|
95
94
|
generateTzColumnDefs,
|
|
96
95
|
model,
|
|
96
|
+
TRelationConfig,
|
|
97
97
|
TTableObject,
|
|
98
98
|
} from '@venizia/ignis';
|
|
99
99
|
import { boolean, pgTable, text } from 'drizzle-orm/pg-core';
|
|
@@ -108,21 +108,16 @@ export const todoTable = pgTable('Todo', {
|
|
|
108
108
|
isCompleted: boolean('is_completed').default(false),
|
|
109
109
|
});
|
|
110
110
|
|
|
111
|
-
// 2. Define
|
|
112
|
-
export const todoRelations = createRelations({
|
|
113
|
-
source: todoTable,
|
|
114
|
-
relations: [],
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
// 3. Define the TypeScript type for a Todo object
|
|
111
|
+
// 2. Define the TypeScript type for a Todo object
|
|
118
112
|
export type TTodoSchema = typeof todoTable;
|
|
119
113
|
export type TTodo = TTableObject<TTodoSchema>;
|
|
120
114
|
|
|
121
|
-
//
|
|
115
|
+
// 3. Create the Entity class, decorated with @model
|
|
122
116
|
@model({ type: 'entity' })
|
|
123
117
|
export class Todo extends BaseEntity<typeof Todo.schema> {
|
|
124
118
|
static override schema = todoTable;
|
|
125
|
-
|
|
119
|
+
// 4. Define relations (empty array for now, but the resolver is still required)
|
|
120
|
+
static override relations = (): TRelationConfig[] => [];
|
|
126
121
|
static override TABLE_NAME = 'Todo';
|
|
127
122
|
}
|
|
128
123
|
```
|
|
@@ -149,7 +144,7 @@ const password = process.env.APP_ENV_DB_PASSWORD;
|
|
|
149
144
|
const password = Bun.env.APP_ENV_DB_PASSWORD;
|
|
150
145
|
```
|
|
151
146
|
|
|
152
|
-
|
|
147
|
+
IGNIS uses `APP_ENV_` prefix to prevent conflicts with system variables.
|
|
153
148
|
|
|
154
149
|
### Create `.env` File
|
|
155
150
|
|
|
@@ -184,7 +179,7 @@ import {
|
|
|
184
179
|
datasource,
|
|
185
180
|
ValueOrPromise,
|
|
186
181
|
} from '@venizia/ignis';
|
|
187
|
-
import {
|
|
182
|
+
import { NodePostgresDriver } from '@venizia/ignis/postgres/node-postgres';
|
|
188
183
|
import { Pool } from 'pg';
|
|
189
184
|
|
|
190
185
|
interface IDSConfigs {
|
|
@@ -200,15 +195,14 @@ interface IDSConfigs {
|
|
|
200
195
|
*
|
|
201
196
|
* How it works:
|
|
202
197
|
* 1. @repository decorator binds model to datasource
|
|
203
|
-
* 2.
|
|
204
|
-
* 3.
|
|
198
|
+
* 2. getSchema() auto-discovers all bound models when the driver/connector are wired
|
|
199
|
+
* 3. Naming NodePostgresDriver in @datasource is what wires the driver and Drizzle connector
|
|
205
200
|
*/
|
|
206
|
-
@datasource({ driver:
|
|
201
|
+
@datasource({ driver: NodePostgresDriver })
|
|
207
202
|
export class PostgresDataSource extends BaseDataSource<IDSConfigs> {
|
|
208
203
|
constructor() {
|
|
209
204
|
super({
|
|
210
205
|
name: PostgresDataSource.name,
|
|
211
|
-
// Driver is read from @datasource decorator - no need to pass here!
|
|
212
206
|
config: {
|
|
213
207
|
host: process.env.APP_ENV_POSTGRES_HOST ?? 'localhost',
|
|
214
208
|
port: +(process.env.APP_ENV_POSTGRES_PORT ?? 5432),
|
|
@@ -221,19 +215,18 @@ export class PostgresDataSource extends BaseDataSource<IDSConfigs> {
|
|
|
221
215
|
}
|
|
222
216
|
|
|
223
217
|
override configure(): ValueOrPromise<void> {
|
|
224
|
-
// getSchema() auto-discovers models from @repository bindings
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
// Log discovered schema for debugging
|
|
228
|
-
const schemaKeys = Object.keys(schema);
|
|
218
|
+
// getSchema() auto-discovers models from @repository bindings; log it for debugging
|
|
219
|
+
const schemaKeys = Object.keys(this.getSchema());
|
|
229
220
|
this.logger.debug(
|
|
230
221
|
'[configure] Auto-discovered schema | Schema + Relations (%s): %o',
|
|
231
222
|
schemaKeys.length,
|
|
232
223
|
schemaKeys,
|
|
233
224
|
);
|
|
234
225
|
|
|
235
|
-
|
|
236
|
-
|
|
226
|
+
// The client must land on this.client - a local would leave beginTransaction() with nothing
|
|
227
|
+
// to resolve a driver from, and it would throw `No driver and no client`. NodePostgresDriver
|
|
228
|
+
// named in @datasource above is what wires the driver and Drizzle connector from it.
|
|
229
|
+
this.client = new Pool(this.settings);
|
|
237
230
|
}
|
|
238
231
|
}
|
|
239
232
|
```
|
|
@@ -242,7 +235,7 @@ export class PostgresDataSource extends BaseDataSource<IDSConfigs> {
|
|
|
242
235
|
- Schema is auto-discovered from `@repository` decorators - no manual registration needed
|
|
243
236
|
- Uses `getSchema()` for lazy schema resolution (resolves when all models are loaded)
|
|
244
237
|
- Uses environment variables for connection config
|
|
245
|
-
-
|
|
238
|
+
- `configure()` only assigns `this.client` - the base class wires the driver and connector from `@datasource({ driver })`; implements `getConnectionString()` for URL generation
|
|
246
239
|
|
|
247
240
|
> **Deep Dive:** See [DataSources Reference](/references/base/datasources) for advanced configuration and multiple database support.
|
|
248
241
|
|
|
@@ -296,9 +289,9 @@ export class TodoRepository extends DefaultCRUDRepository<typeof Todo.schema> {
|
|
|
296
289
|
Dependency Injection (DI) is a design pattern where objects receive their dependencies from outside rather than creating them internally. Instead of `new Repository()` inside a controller, you declare "I need a Repository" using `@inject`, and the framework provides it automatically.
|
|
297
290
|
|
|
298
291
|
**Benefits:**
|
|
299
|
-
- **Testable**
|
|
300
|
-
- **Flexible**
|
|
301
|
-
- **Maintainable**
|
|
292
|
+
- **Testable** - Replace real services with mocks in tests
|
|
293
|
+
- **Flexible** - Swap implementations without changing code
|
|
294
|
+
- **Maintainable** - Dependencies are explicit and centralized
|
|
302
295
|
|
|
303
296
|
[Learn more →](/guides/core-concepts/dependency-injection)
|
|
304
297
|
:::
|
|
@@ -361,13 +354,13 @@ export * from './todo.controller';
|
|
|
361
354
|
| Method | Path | Description |
|
|
362
355
|
|--------|------|-------------|
|
|
363
356
|
| GET | `/todos` | List all todos (find) |
|
|
364
|
-
| GET | `/todos
|
|
357
|
+
| GET | `/todos/{id}` | Get todo by ID (findById) |
|
|
365
358
|
| GET | `/todos/find-one` | Find one todo by filter (findOne) |
|
|
366
359
|
| GET | `/todos/count` | Count todos (count) |
|
|
367
360
|
| POST | `/todos` | Create todo (create) |
|
|
368
|
-
| PATCH | `/todos
|
|
361
|
+
| PATCH | `/todos/{id}` | Update todo by ID (updateById) |
|
|
369
362
|
| PATCH | `/todos` | Update multiple todos by filter (updateBy) |
|
|
370
|
-
| DELETE | `/todos
|
|
363
|
+
| DELETE | `/todos/{id}` | Delete todo by ID (deleteById) |
|
|
371
364
|
| DELETE | `/todos` | Delete multiple todos by filter (deleteBy) |
|
|
372
365
|
|
|
373
366
|
> **Deep Dive:** See [ControllerFactory Reference](/references/base/controllers#controllerfactory) for customization options.
|
|
@@ -378,7 +371,7 @@ Update `src/application.ts` to register all components:
|
|
|
378
371
|
|
|
379
372
|
```typescript
|
|
380
373
|
// src/application.ts
|
|
381
|
-
import { BaseApplication, IApplicationConfigs, IApplicationInfo,
|
|
374
|
+
import { BaseApplication, IApplicationConfigs, IApplicationInfo, ApiReferenceComponent, ValueOrPromise } from '@venizia/ignis';
|
|
382
375
|
import { HelloController } from './controllers/hello';
|
|
383
376
|
import packageJson from '../package.json';
|
|
384
377
|
|
|
@@ -403,8 +396,8 @@ export class Application extends BaseApplication {
|
|
|
403
396
|
setupMiddlewares(): ValueOrPromise<void> {}
|
|
404
397
|
|
|
405
398
|
preConfigure(): ValueOrPromise<void> {
|
|
406
|
-
// 1. Register
|
|
407
|
-
this.component(
|
|
399
|
+
// 1. Register ApiReferenceComponent for API docs
|
|
400
|
+
this.component(ApiReferenceComponent);
|
|
408
401
|
|
|
409
402
|
// 2. Register datasource
|
|
410
403
|
this.dataSource(PostgresDataSource);
|
|
@@ -481,7 +474,7 @@ Add these scripts to your `package.json`:
|
|
|
481
474
|
|
|
482
475
|
### Run the Migration
|
|
483
476
|
|
|
484
|
-
For development, use `push`
|
|
477
|
+
For development, use `push` - it reads your schema and applies changes directly to the database:
|
|
485
478
|
|
|
486
479
|
```bash
|
|
487
480
|
bun run db:push
|
|
@@ -516,7 +509,7 @@ Test the API endpoints:
|
|
|
516
509
|
# Create a todo
|
|
517
510
|
curl -X POST http://localhost:3000/api/todos \
|
|
518
511
|
-H "Content-Type: application/json" \
|
|
519
|
-
-d '{"title":"Learn
|
|
512
|
+
-d '{"title":"Learn IGNIS","description":"Complete tutorial"}'
|
|
520
513
|
|
|
521
514
|
# Get all todos
|
|
522
515
|
curl http://localhost:3000/api/todos
|
|
@@ -616,7 +609,7 @@ path: { base: '/api', isStrict: true }, // All routes start with /api
|
|
|
616
609
|
# Make sure you include the header:
|
|
617
610
|
curl -X POST http://localhost:3000/api/todos \
|
|
618
611
|
-H "Content-Type: application/json" \ # ← This line!
|
|
619
|
-
-d '{"title":"Learn
|
|
612
|
+
-d '{"title":"Learn IGNIS"}'
|
|
620
613
|
```
|
|
621
614
|
|
|
622
615
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Complete Installation
|
|
2
2
|
|
|
3
|
-
This guide walks you through creating a new web application with
|
|
3
|
+
This guide walks you through creating a new web application with IGNIS and setting up a professional development environment.
|
|
4
4
|
|
|
5
5
|
**Time to Complete:** ~20 minutes
|
|
6
6
|
|
|
@@ -26,7 +26,7 @@ bun add hono @hono/zod-openapi @scalar/hono-api-reference @venizia/ignis @venizi
|
|
|
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
|
|
29
|
+
- `@venizia/ignis` - Core IGNIS framework (application, controllers, repositories, DI)
|
|
30
30
|
- `@venizia/ignis-helpers` - Utilities (HTTP constants, logger, environment helpers)
|
|
31
31
|
|
|
32
32
|
### Development Dependencies
|
|
@@ -39,7 +39,7 @@ bun add -d typescript @types/bun @venizia/dev-configs eslint prettier tsc-alias
|
|
|
39
39
|
- Centralized ESLint configuration
|
|
40
40
|
- Centralized Prettier configuration
|
|
41
41
|
- Shared TypeScript base configs
|
|
42
|
-
- Consistent code style across all
|
|
42
|
+
- Consistent code style across all IGNIS projects
|
|
43
43
|
|
|
44
44
|
> **Note:** Database dependencies (drizzle-orm, pg, etc.) will be added later in the [CRUD Tutorial](./building-a-crud-api.md).
|
|
45
45
|
|
|
@@ -167,7 +167,7 @@ Each controller gets its own folder: `definitions.ts` for route configs and Zod
|
|
|
167
167
|
Create `src/application.ts` - this is where you configure and register all your application resources:
|
|
168
168
|
|
|
169
169
|
```typescript
|
|
170
|
-
import { BaseApplication, IApplicationConfigs, IApplicationInfo,
|
|
170
|
+
import { BaseApplication, IApplicationConfigs, IApplicationInfo, ApiReferenceComponent, ValueOrPromise } from '@venizia/ignis';
|
|
171
171
|
import { HelloController } from './controllers';
|
|
172
172
|
import packageJson from '../package.json';
|
|
173
173
|
|
|
@@ -188,7 +188,7 @@ export class Application extends BaseApplication {
|
|
|
188
188
|
// return {
|
|
189
189
|
// name: 'my-app',
|
|
190
190
|
// version: '1.0.0',
|
|
191
|
-
// description: 'My
|
|
191
|
+
// description: 'My IGNIS application',
|
|
192
192
|
// };
|
|
193
193
|
}
|
|
194
194
|
|
|
@@ -212,8 +212,8 @@ export class Application extends BaseApplication {
|
|
|
212
212
|
|
|
213
213
|
// Hook 3: Register your resources (THIS IS THE MOST IMPORTANT ONE)
|
|
214
214
|
preConfigure(): ValueOrPromise<void> {
|
|
215
|
-
// Register
|
|
216
|
-
this.component(
|
|
215
|
+
// Register ApiReferenceComponent for API documentation at /doc/explorer
|
|
216
|
+
this.component(ApiReferenceComponent);
|
|
217
217
|
|
|
218
218
|
// As your app grows, you'll add:
|
|
219
219
|
// this.dataSource(PostgresDataSource); // Database connection
|
|
@@ -234,9 +234,9 @@ export class Application extends BaseApplication {
|
|
|
234
234
|
|
|
235
235
|
> [!NOTE] IApplicationInfo
|
|
236
236
|
> **Required fields in `package.json`:**
|
|
237
|
-
> - `name`
|
|
238
|
-
> - `version`
|
|
239
|
-
> - `description`
|
|
237
|
+
> - `name` - App name (shown in API docs title)
|
|
238
|
+
> - `version` - App version (shown in API docs)
|
|
239
|
+
> - `description` - App description (shown in API docs)
|
|
240
240
|
>
|
|
241
241
|
> **No proper `package.json`?** Use static app info instead (see Option 2 in code above).
|
|
242
242
|
>
|
|
@@ -262,7 +262,7 @@ export class Application extends BaseApplication {
|
|
|
262
262
|
|
|
263
263
|
Each controller lives in its own folder with separate files for definitions, logic, and exports.
|
|
264
264
|
|
|
265
|
-
Create `src/controllers/hello/definitions.ts`
|
|
265
|
+
Create `src/controllers/hello/definitions.ts` - route configs and schemas:
|
|
266
266
|
|
|
267
267
|
```typescript
|
|
268
268
|
import { jsonContent } from '@venizia/ignis';
|
|
@@ -285,7 +285,7 @@ export const helloRouteConfigs = {
|
|
|
285
285
|
} as const;
|
|
286
286
|
```
|
|
287
287
|
|
|
288
|
-
Create `src/controllers/hello/hello.controller.ts`
|
|
288
|
+
Create `src/controllers/hello/hello.controller.ts` - the controller class:
|
|
289
289
|
|
|
290
290
|
```typescript
|
|
291
291
|
import { BaseRestController, controller, api } from '@venizia/ignis';
|
|
@@ -311,13 +311,13 @@ export class HelloController extends BaseRestController {
|
|
|
311
311
|
}
|
|
312
312
|
```
|
|
313
313
|
|
|
314
|
-
Create `src/controllers/hello/index.ts`
|
|
314
|
+
Create `src/controllers/hello/index.ts` - barrel export:
|
|
315
315
|
|
|
316
316
|
```typescript
|
|
317
317
|
export * from './hello.controller';
|
|
318
318
|
```
|
|
319
319
|
|
|
320
|
-
Create `src/controllers/index.ts`
|
|
320
|
+
Create `src/controllers/index.ts` - export all controllers:
|
|
321
321
|
|
|
322
322
|
```typescript
|
|
323
323
|
export * from './hello';
|
|
@@ -327,7 +327,7 @@ export * from './hello';
|
|
|
327
327
|
|
|
328
328
|
| Pattern | Description |
|
|
329
329
|
|---------|-------------|
|
|
330
|
-
| `definitions.ts` | Route configs, Zod schemas, and constants
|
|
330
|
+
| `definitions.ts` | Route configs, Zod schemas, and constants - keeps controller file clean |
|
|
331
331
|
| `@controller` | Registers the class as a controller with a base path |
|
|
332
332
|
| `@api` | Defines a route with `method` specified in configs |
|
|
333
333
|
| `@get`, `@post`, etc. | Shorthand decorators that auto-set the HTTP method (recommended) |
|
|
@@ -425,11 +425,11 @@ Response:
|
|
|
425
425
|
|
|
426
426
|
Open `http://localhost:3000/doc/explorer` to see interactive Swagger UI with your endpoints.
|
|
427
427
|
|
|
428
|
-
Congratulations! You have successfully created and configured your first application with the `
|
|
428
|
+
Congratulations! You have successfully created and configured your first application with the `IGNIS` framework.
|
|
429
429
|
|
|
430
430
|
## Continue Your Journey
|
|
431
431
|
|
|
432
|
-
You now have a working
|
|
432
|
+
You now have a working IGNIS application!
|
|
433
433
|
|
|
434
434
|
**Next steps:**
|
|
435
435
|
|