@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
|
# MCP Docs Server: Deep Dive
|
|
2
2
|
|
|
3
|
-
This document provides a detailed look into the architecture, features, and internal workings of the
|
|
3
|
+
This document provides a detailed look into the architecture, features, and internal workings of the IGNIS Documentation MCP Server. For a guide on how to use the server, see the [MCP Docs Server Quickstart](/guides/reference/mcp-docs-server).
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -98,7 +98,7 @@ sequenceDiagram
|
|
|
98
98
|
participant Helper as GitHubHelper
|
|
99
99
|
participant API as GitHub API
|
|
100
100
|
|
|
101
|
-
AI->>MCP: searchCode("
|
|
101
|
+
AI->>MCP: searchCode("BaseRestController")
|
|
102
102
|
MCP->>Tool: Route to tool handler
|
|
103
103
|
Tool->>Helper: GitHubHelper.searchCode()
|
|
104
104
|
Helper->>API: GET /search/code
|
|
@@ -114,7 +114,7 @@ sequenceDiagram
|
|
|
114
114
|
|
|
115
115
|
### 1. Documentation Tools
|
|
116
116
|
|
|
117
|
-
Tools for accessing the
|
|
117
|
+
Tools for accessing the IGNIS Framework wiki and guide documentation.
|
|
118
118
|
|
|
119
119
|
| Tool | Purpose | Use Case |
|
|
120
120
|
|------|---------|----------|
|
|
@@ -158,11 +158,11 @@ Retrieves high-level information about specific framework packages.
|
|
|
158
158
|
|
|
159
159
|
### 2. Code & Project Tools
|
|
160
160
|
|
|
161
|
-
Tools for exploring the
|
|
161
|
+
Tools for exploring the IGNIS codebase, searching source code, and verifying dependencies via GitHub.
|
|
162
162
|
|
|
163
163
|
| Tool | Purpose | Use Case |
|
|
164
164
|
|------|---------|----------|
|
|
165
|
-
| `searchCode` | Search source code | "Find usages of
|
|
165
|
+
| `searchCode` | Search source code | "Find usages of BaseRestController" |
|
|
166
166
|
| `listProjectFiles` | List repo files | "Show me files in packages/core" |
|
|
167
167
|
| `viewSourceFile` | Read source code | "Read packages/core/src/index.ts" |
|
|
168
168
|
| `verifyDependencies` | Check package.json | "Check dependencies for @venizia/core" |
|
|
@@ -370,23 +370,17 @@ DEBUG=1 ignis-docs-mcp
|
|
|
370
370
|
All tools extend the `BaseTool` abstract class:
|
|
371
371
|
|
|
372
372
|
```typescript
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
TOutputSchema extends z.ZodType
|
|
376
|
-
> {
|
|
377
|
-
// Singleton pattern
|
|
378
|
-
static getInstance<T extends BaseTool>(this: new () => T): T {
|
|
379
|
-
// Returns cached instance or creates new one
|
|
380
|
-
}
|
|
373
|
+
import type { Tool } from '@mastra/core/tools';
|
|
374
|
+
import type { z } from 'zod';
|
|
381
375
|
|
|
382
|
-
|
|
376
|
+
export abstract class BaseTool<TInputSchema extends z.ZodType, TOutputSchema extends z.ZodType> {
|
|
383
377
|
abstract readonly id: string;
|
|
384
378
|
abstract readonly description: string;
|
|
385
379
|
abstract readonly inputSchema: TInputSchema;
|
|
386
380
|
abstract readonly outputSchema: TOutputSchema;
|
|
387
381
|
|
|
388
|
-
abstract execute(
|
|
389
|
-
abstract getTool():
|
|
382
|
+
abstract execute(opts: z.infer<TInputSchema>): Promise<z.infer<TOutputSchema>>;
|
|
383
|
+
abstract getTool(): Tool<z.input<TInputSchema>, z.infer<TOutputSchema>>;
|
|
390
384
|
}
|
|
391
385
|
```
|
|
392
386
|
|
|
@@ -397,9 +391,9 @@ export abstract class BaseTool<
|
|
|
397
391
|
Create `tools/my-new-tool.tool.ts`:
|
|
398
392
|
|
|
399
393
|
```typescript
|
|
394
|
+
import { createTool } from '@mastra/core/tools';
|
|
400
395
|
import { z } from 'zod';
|
|
401
|
-
import { BaseTool
|
|
402
|
-
import { DocsHelper } from '../helpers';
|
|
396
|
+
import { BaseTool } from '../base.tool';
|
|
403
397
|
|
|
404
398
|
// Define schemas
|
|
405
399
|
const InputSchema = z.object({
|
|
@@ -417,18 +411,18 @@ export class MyNewTool extends BaseTool<typeof InputSchema, typeof OutputSchema>
|
|
|
417
411
|
readonly inputSchema = InputSchema;
|
|
418
412
|
readonly outputSchema = OutputSchema;
|
|
419
413
|
|
|
420
|
-
async execute(
|
|
414
|
+
async execute(opts: z.infer<typeof InputSchema>) {
|
|
421
415
|
// Your logic here
|
|
422
416
|
return { result: 'output' };
|
|
423
417
|
}
|
|
424
418
|
|
|
425
|
-
getTool()
|
|
419
|
+
getTool() {
|
|
426
420
|
return createTool({
|
|
427
421
|
id: this.id,
|
|
428
422
|
description: this.description,
|
|
429
|
-
inputSchema:
|
|
430
|
-
outputSchema:
|
|
431
|
-
execute: async
|
|
423
|
+
inputSchema: this.inputSchema,
|
|
424
|
+
outputSchema: this.outputSchema,
|
|
425
|
+
execute: async input => this.execute(InputSchema.parse(input)),
|
|
432
426
|
});
|
|
433
427
|
}
|
|
434
428
|
}
|
|
@@ -611,7 +605,7 @@ DEBUG=docs:cache ignis-docs-mcp
|
|
|
611
605
|
|
|
612
606
|
### Contributing
|
|
613
607
|
|
|
614
|
-
Want to add features or fix bugs? See the main
|
|
608
|
+
Want to add features or fix bugs? See the main IGNIS repository:
|
|
615
609
|
|
|
616
610
|
- **Repository**: https://github.com/venizia-ai/ignis
|
|
617
611
|
- **Issues**: Report bugs or request features
|
|
@@ -283,23 +283,18 @@ This ensures dependencies are available when artifacts are constructed.
|
|
|
283
283
|
|
|
284
284
|
## When Boot Runs
|
|
285
285
|
|
|
286
|
-
###
|
|
286
|
+
### Explicit Boot (Standard Pattern)
|
|
287
287
|
|
|
288
|
-
Boot
|
|
288
|
+
Boot does NOT run automatically inside `start()`. Call `boot()` explicitly before `start()` - `boot()` calls `registerBooters()` (which registers the four built-in booters plus the `Bootstrapper`) and then runs all boot phases:
|
|
289
289
|
|
|
290
290
|
```typescript
|
|
291
|
-
const app = new Application();
|
|
292
|
-
|
|
291
|
+
const app = new Application({ scope: 'Application', config: appConfigs });
|
|
292
|
+
app.init(); // register core bindings
|
|
293
|
+
const report = await app.boot(); // registerBooters() → configure/discover/load
|
|
294
|
+
await app.start(); // initialize() → middlewares → HTTP server
|
|
293
295
|
```
|
|
294
296
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
Explicitly call `boot()` on the application:
|
|
298
|
-
|
|
299
|
-
```typescript
|
|
300
|
-
const app = new Application();
|
|
301
|
-
const report = await app.boot();
|
|
302
|
-
```
|
|
297
|
+
This is the pattern used by the production reference app (`examples/vert/src/index.ts`).
|
|
303
298
|
|
|
304
299
|
### Using BootMixin (Alternative)
|
|
305
300
|
|
|
@@ -488,10 +483,12 @@ export class MiddlewareBooter extends BaseArtifactBooter {
|
|
|
488
483
|
|
|
489
484
|
**Register Custom Booter:**
|
|
490
485
|
|
|
486
|
+
Register it in `registerBooters()` - NOT in `preConfigure()`. `boot()` runs before `start()`, so `preConfigure()` (which runs during `initialize()` inside `start()`) is too late for the bootstrapper to discover the booter:
|
|
487
|
+
|
|
491
488
|
```typescript
|
|
492
489
|
export class Application extends BaseApplication {
|
|
493
|
-
override
|
|
494
|
-
|
|
490
|
+
override async registerBooters() {
|
|
491
|
+
await super.registerBooters(); // built-in booters + bootstrapper
|
|
495
492
|
this.booter(MiddlewareBooter);
|
|
496
493
|
}
|
|
497
494
|
}
|
|
@@ -60,7 +60,7 @@ export class Application extends BaseApplication {
|
|
|
60
60
|
|
|
61
61
|
## Application Lifecycle
|
|
62
62
|
|
|
63
|
-
The `
|
|
63
|
+
The `IGNIS` application has a well-defined lifecycle, managed primarily by the `start()` and `initialize()` methods.
|
|
64
64
|
|
|
65
65
|
| Method | Description |
|
|
66
66
|
| :--- | :--- |
|
|
@@ -190,10 +190,10 @@ this.controller(UserController, {
|
|
|
190
190
|
The application detects the runtime automatically via `RuntimeModules.detect()`:
|
|
191
191
|
|
|
192
192
|
```typescript
|
|
193
|
-
// Bun (default)
|
|
193
|
+
// Bun (default) - uses Bun.serve
|
|
194
194
|
Bun.serve({ port, hostname, fetch: server.fetch })
|
|
195
195
|
|
|
196
|
-
// Node.js
|
|
196
|
+
// Node.js - requires @hono/node-server
|
|
197
197
|
import { serve } from '@hono/node-server'
|
|
198
198
|
serve({ fetch: server.fetch, port, hostname })
|
|
199
199
|
```
|
|
@@ -15,31 +15,40 @@ A single component can bundle everything needed for a specific domain--for examp
|
|
|
15
15
|
|
|
16
16
|
## Built-in Components
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
IGNIS includes ready-to-use components for common features. The following are exported from the main barrel (`@venizia/ignis`):
|
|
19
19
|
|
|
20
20
|
| Component | Description |
|
|
21
21
|
| :--- | :--- |
|
|
22
22
|
| **Authentication** | JWT + Basic auth strategies, token services, strategy registry |
|
|
23
23
|
| **Authorization** | Casbin-based RBAC, permission mapping, `authorize()` middleware |
|
|
24
|
-
| **HealthCheckComponent** | `GET /health`,
|
|
25
|
-
| **
|
|
24
|
+
| **HealthCheckComponent** | `GET /health`, `POST /health/ping` |
|
|
25
|
+
| **ApiReferenceComponent** | Swagger UI or Scalar UI for API documentation |
|
|
26
26
|
| **RequestTrackerComponent** | `x-request-id` header, request body parsing |
|
|
27
27
|
|
|
28
28
|
The following components require direct subpath imports:
|
|
29
29
|
|
|
30
30
|
| Component | Import From | Description |
|
|
31
31
|
| :--- | :--- | :--- |
|
|
32
|
-
| **MailComponent** | `@venizia/ignis/
|
|
33
|
-
| **SocketIOComponent** | `@venizia/ignis/
|
|
34
|
-
| **StaticAssetComponent** | `@venizia/ignis/
|
|
35
|
-
| **WebSocketComponent** | `@venizia/ignis/
|
|
32
|
+
| **MailComponent** | `@venizia/ignis/mail` | Nodemailer/Mailgun transporters with queue executors |
|
|
33
|
+
| **SocketIOComponent** | `@venizia/ignis/socket-io` | Socket.IO server with Redis adapter |
|
|
34
|
+
| **StaticAssetComponent** | `@venizia/ignis/static-asset` | File upload/download CRUD, MinIO/Disk storage |
|
|
35
|
+
| **WebSocketComponent** | `@venizia/ignis/websocket` | Native WebSocket support |
|
|
36
36
|
|
|
37
37
|
See the [**Built-in Components Reference**](../../extensions/components/) for detailed documentation.
|
|
38
38
|
|
|
39
39
|
## Creating a Simple Component
|
|
40
40
|
|
|
41
41
|
```typescript
|
|
42
|
-
import {
|
|
42
|
+
import {
|
|
43
|
+
BaseApplication,
|
|
44
|
+
BaseComponent,
|
|
45
|
+
BaseRestController,
|
|
46
|
+
Binding,
|
|
47
|
+
controller,
|
|
48
|
+
CoreBindings,
|
|
49
|
+
inject,
|
|
50
|
+
ValueOrPromise,
|
|
51
|
+
} from '@venizia/ignis';
|
|
43
52
|
|
|
44
53
|
// Define a service
|
|
45
54
|
class NotificationService {
|
|
@@ -98,7 +107,7 @@ Register components in your application's `preConfigure` method:
|
|
|
98
107
|
export class Application extends BaseApplication {
|
|
99
108
|
preConfigure(): ValueOrPromise<void> {
|
|
100
109
|
this.component(HealthCheckComponent);
|
|
101
|
-
this.component(
|
|
110
|
+
this.component(ApiReferenceComponent);
|
|
102
111
|
this.component(NotificationComponent);
|
|
103
112
|
}
|
|
104
113
|
}
|
|
@@ -139,7 +148,7 @@ export class Application extends BaseApplication {
|
|
|
139
148
|
- [BaseComponent API](/references/base/components) - Complete API reference
|
|
140
149
|
- [Authentication Component](/extensions/components/authentication/) - JWT authentication
|
|
141
150
|
- [Health Check Component](/extensions/components/health-check) - Health endpoints
|
|
142
|
-
- [Swagger Component](/extensions/components/
|
|
151
|
+
- [Swagger Component](/extensions/components/api-reference) - API documentation
|
|
143
152
|
- [Socket.IO Component](/extensions/components/socket-io/) - WebSocket support
|
|
144
153
|
|
|
145
154
|
- **Best Practices:**
|
|
@@ -4,7 +4,7 @@ Dependency Injection (DI) enables loosely coupled, testable code by automaticall
|
|
|
4
4
|
|
|
5
5
|
> **Deep Dive:** See [DI Reference](../../references/base/dependency-injection.md) for technical details on Container, Binding, and `@inject`.
|
|
6
6
|
|
|
7
|
-
> **Standalone Package:** The core DI container is available as the standalone `@venizia/ignis-inversion` package for use outside the
|
|
7
|
+
> **Standalone Package:** The core DI container is available as the standalone `@venizia/ignis-inversion` package for use outside the IGNIS framework. See [Inversion Package Reference](/extensions/helpers/inversion/) for details.
|
|
8
8
|
|
|
9
9
|
## Core Concepts
|
|
10
10
|
|
|
@@ -46,9 +46,12 @@ graph TD
|
|
|
46
46
|
|
|
47
47
|
When the container instantiates a class, it follows a two-phase process:
|
|
48
48
|
|
|
49
|
-
1. **Constructor injection** -- Reads `@inject` metadata from the class
|
|
49
|
+
1. **Constructor injection** -- Reads `@inject` metadata from the class by parameter index (no sort - the metadata is already index-keyed), resolves each dependency from the container, and passes them as constructor arguments.
|
|
50
50
|
2. **Property injection** -- After construction, reads property metadata and assigns each dependency to the decorated properties.
|
|
51
51
|
|
|
52
|
+
> [!IMPORTANT]
|
|
53
|
+
> Every constructor parameter of a container-instantiated class must carry `@inject`. Mixing decorated and undecorated parameters is refused - `instantiate()` throws `[ClassName] Constructor parameter N has no @inject`. See the [DI Reference](../../references/base/dependency-injection.md#instantiation-algorithm-two-phase) for the full rule and the `@repository` exception.
|
|
54
|
+
|
|
52
55
|
## Binding Dependencies
|
|
53
56
|
|
|
54
57
|
Before a dependency can be injected, it must be **bound** to the container. This is typically done in the `preConfigure` method of your `Application` class.
|
|
@@ -117,7 +120,7 @@ Tags are used by the container's `findByTag()` method to discover bindings by ca
|
|
|
117
120
|
|
|
118
121
|
## Injecting Dependencies
|
|
119
122
|
|
|
120
|
-
`
|
|
123
|
+
`IGNIS` provides the `@inject` decorator to request dependencies from the container.
|
|
121
124
|
|
|
122
125
|
### Constructor Injection (Recommended)
|
|
123
126
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# gRPC Controllers
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
IGNIS provides first-class support for gRPC via the [ConnectRPC](https://connectrpc.com/) protocol. gRPC controllers use Protobuf service definitions for strongly-typed RPC methods, and are served over the same Hono HTTP server as REST controllers.
|
|
4
4
|
|
|
5
5
|
> **Deep Dive:** See [gRPC Controllers Reference](../../references/base/grpc-controllers.md) for the complete API.
|
|
6
6
|
|
|
@@ -83,7 +83,7 @@ export class GreeterController extends BaseGrpcController {
|
|
|
83
83
|
|
|
84
84
|
## RPC Method Decorators
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
IGNIS provides a decorator for each gRPC method type:
|
|
87
87
|
|
|
88
88
|
- `@unary(opts)` -- Single request, single response. **This is the only supported method type** in the current version.
|
|
89
89
|
- `@serverStream(opts)` -- Decorator exists for metadata, but throws at runtime.
|
|
@@ -102,7 +102,7 @@ async sayHello(opts: { request: SayHelloRequest; context: TRouteContext }): Prom
|
|
|
102
102
|
@unary({
|
|
103
103
|
configs: {
|
|
104
104
|
name: 'getUser',
|
|
105
|
-
authenticate: { strategies: ['jwt'], mode: '
|
|
105
|
+
authenticate: { strategies: ['jwt'], mode: 'any' },
|
|
106
106
|
},
|
|
107
107
|
})
|
|
108
108
|
async getUser(opts: { request: GetUserRequest; context: TRouteContext }): Promise<GetUserResponse> { ... }
|
|
@@ -112,7 +112,7 @@ async getUser(opts: { request: GetUserRequest; context: TRouteContext }): Promis
|
|
|
112
112
|
configs: {
|
|
113
113
|
name: 'deleteUser',
|
|
114
114
|
authenticate: { strategies: ['jwt'] },
|
|
115
|
-
authorize: {
|
|
115
|
+
authorize: { action: 'delete', resource: 'user' },
|
|
116
116
|
},
|
|
117
117
|
})
|
|
118
118
|
async deleteUser(opts: { request: DeleteUserRequest; context: TRouteContext }): Promise<DeleteUserResponse> { ... }
|
|
@@ -255,7 +255,8 @@ plugins:
|
|
|
255
255
|
```
|
|
256
256
|
|
|
257
257
|
```bash
|
|
258
|
-
|
|
258
|
+
bun add -d @bufbuild/buf @bufbuild/protoc-gen-es
|
|
259
|
+
node_modules/.bin/buf generate src/controllers/greeter/proto
|
|
259
260
|
```
|
|
260
261
|
|
|
261
262
|
### 3. Use the generated types in your controller
|
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
A DataSource manages database connections and supports **schema auto-discovery** from repositories.
|
|
4
4
|
|
|
5
|
-
> [!NOTE]
|
|
6
|
-
>
|
|
5
|
+
> [!NOTE] Connectors
|
|
6
|
+
> This guide covers the **PostgreSQL connector** (`BasePostgresDataSource`, aliased as `BaseDataSource` for backward compatibility) - the primary relational engine and the one used by most applications. IGNIS also ships a **typesense connector** for full-text/vector search (see [Search & Typesense](./search-typesense)). Both implement the same engine-neutral `AbstractDataSource` contract - see [Connectors](/references/base/connectors) for the architecture.
|
|
7
7
|
|
|
8
8
|
## Creating a DataSource
|
|
9
9
|
|
|
10
10
|
```typescript
|
|
11
11
|
// src/datasources/postgres.datasource.ts
|
|
12
12
|
import {
|
|
13
|
-
|
|
13
|
+
BasePostgresDataSource,
|
|
14
14
|
datasource,
|
|
15
15
|
ValueOrPromise,
|
|
16
16
|
} from '@venizia/ignis';
|
|
17
|
-
import {
|
|
17
|
+
import { NodePostgresDriver } from '@venizia/ignis/postgres/node-postgres';
|
|
18
18
|
import { Pool } from 'pg';
|
|
19
19
|
|
|
20
20
|
interface IDSConfigs {
|
|
@@ -25,8 +25,8 @@ interface IDSConfigs {
|
|
|
25
25
|
password: string;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
@datasource({ driver:
|
|
29
|
-
export class PostgresDataSource extends
|
|
28
|
+
@datasource({ driver: NodePostgresDriver })
|
|
29
|
+
export class PostgresDataSource extends BasePostgresDataSource<IDSConfigs> {
|
|
30
30
|
constructor() {
|
|
31
31
|
super({
|
|
32
32
|
name: PostgresDataSource.name,
|
|
@@ -42,16 +42,11 @@ export class PostgresDataSource extends BaseDataSource<IDSConfigs> {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
override configure(): ValueOrPromise<void> {
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
const schema = Object.keys(this.getSchema());
|
|
46
|
+
this.logger.debug('[configure] Auto-discovered schema | Keys: %o', schema);
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
Object.keys(schema),
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
this.pool = new Pool(this.settings);
|
|
54
|
-
this.connector = drizzle({ client: this.pool, schema });
|
|
48
|
+
// That is all - naming NodePostgresDriver above is what wires the driver and connector.
|
|
49
|
+
this.client = new Pool(this.settings);
|
|
55
50
|
}
|
|
56
51
|
|
|
57
52
|
override getConnectionString(): ValueOrPromise<string> {
|
|
@@ -61,21 +56,24 @@ export class PostgresDataSource extends BaseDataSource<IDSConfigs> {
|
|
|
61
56
|
}
|
|
62
57
|
```
|
|
63
58
|
|
|
59
|
+
> [!NOTE] Driver seam: the raw client goes on `this.client`
|
|
60
|
+
> `this.client = new Pool(...)` is the short path: `configure()` builds only the client, and `getConnector()`/`beginTransaction()` lazily instantiate the class named in `@datasource({ driver })` over it - `NodePostgresDriver` here. There is no `pool` field - the raw-client slot is `client`, whatever the client happens to be. Naming the driver class (rather than a driver-name string) is what carries `pg` into the app's bundle - a bundler only packages a real value reference, never text. The alternative is to wire a driver yourself for a custom or third-party driver: `configure()` calls `this.useDriver({ driver, schema? })`, which assigns `this.driver` **and** builds `this.connector` in one step (so the half-wired state cannot exist), bypassing `@datasource({ driver })` entirely. See [Postgres Drivers & Supabase](./postgres-drivers) for `postgres-js` and Supabase.
|
|
61
|
+
|
|
64
62
|
**How auto-discovery works:**
|
|
65
63
|
|
|
66
64
|
1. `@repository` decorators register model-datasource bindings in the `MetadataRegistry`
|
|
67
|
-
2.
|
|
68
|
-
3. Drizzle is initialized with the complete schema (tables + Drizzle relations)
|
|
65
|
+
2. `getSchema()` invokes `discoverSchema()` which calls `MetadataRegistry.buildSchema({ dataSource })` to collect all bound models and their relations
|
|
66
|
+
3. The lazily-built Drizzle connector is initialized with the complete schema (tables + Drizzle relations)
|
|
69
67
|
|
|
70
|
-
You can disable auto-discovery per datasource via `@datasource({ driver:
|
|
68
|
+
You can disable auto-discovery per datasource via `@datasource({ driver: NodePostgresDriver, autoDiscovery: false })`.
|
|
71
69
|
|
|
72
70
|
## Manual Schema (Optional)
|
|
73
71
|
|
|
74
72
|
If you need explicit control, you can still provide schema manually:
|
|
75
73
|
|
|
76
74
|
```typescript
|
|
77
|
-
@datasource({ driver:
|
|
78
|
-
export class PostgresDataSource extends
|
|
75
|
+
@datasource({ driver: NodePostgresDriver })
|
|
76
|
+
export class PostgresDataSource extends BasePostgresDataSource<IDSConfigs> {
|
|
79
77
|
constructor() {
|
|
80
78
|
super({
|
|
81
79
|
name: PostgresDataSource.name,
|
|
@@ -93,16 +91,18 @@ export class PostgresDataSource extends BaseDataSource<IDSConfigs> {
|
|
|
93
91
|
## DataSource Hierarchy
|
|
94
92
|
|
|
95
93
|
```
|
|
96
|
-
AbstractDataSource extends BaseHelper
|
|
97
|
-
└──
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
94
|
+
AbstractDataSource extends BaseHelper # engine-neutral, src/base - no pool, no Drizzle
|
|
95
|
+
└── AbstractPostgresDataSource # connectors/postgres - adds pool, connector
|
|
96
|
+
└── BasePostgresDataSource (alias: BaseDataSource)
|
|
97
|
+
├── configure() # Assign this.client (abstract) - base wires driver + connector
|
|
98
|
+
├── getConnectionString() # Build connection URL (abstract)
|
|
99
|
+
├── getSchema() # Auto-discover from @repository bindings
|
|
100
|
+
├── discoverSchema() # Internal: reads MetadataRegistry
|
|
101
|
+
├── hasDiscoverableModels() # Check if any repos reference this DS
|
|
102
|
+
├── getCapabilities() # Returns { transactions: true }
|
|
103
|
+
├── beginTransaction(opts?) # Start transaction with isolation level
|
|
104
|
+
├── getConnector() # Get Drizzle connector
|
|
105
|
+
└── getSettings() # Get connection config
|
|
106
106
|
```
|
|
107
107
|
|
|
108
108
|
## Registering a DataSource
|
|
@@ -118,19 +118,19 @@ export class Application extends BaseApplication {
|
|
|
118
118
|
|
|
119
119
|
DataSources are bound as **singletons** to ensure connection pool sharing across the application.
|
|
120
120
|
|
|
121
|
-
## Supported
|
|
121
|
+
## Supported Engines
|
|
122
122
|
|
|
123
|
-
|
|
|
124
|
-
|
|
125
|
-
| `node-postgres` | `
|
|
126
|
-
| `
|
|
127
|
-
|
|
|
123
|
+
| Engine | Driver/Package | Import | Status |
|
|
124
|
+
|--------|---------|--------|--------|
|
|
125
|
+
| PostgreSQL | `node-postgres` (`pg`) | `@venizia/ignis` or `@venizia/ignis/postgres` | Supported, transactions + 3 isolation levels |
|
|
126
|
+
| Typesense (search) | `typesense` (optional peer) | `@venizia/ignis/typesense` (subpath-only) | Supported, no transactions/locks |
|
|
127
|
+
| MySQL / SQLite | - | - | Not planned; would be a new connector under `src/connectors/` |
|
|
128
128
|
|
|
129
129
|
## DataSource Template
|
|
130
130
|
|
|
131
131
|
```typescript
|
|
132
|
-
import {
|
|
133
|
-
import {
|
|
132
|
+
import { BasePostgresDataSource, datasource, ValueOrPromise } from '@venizia/ignis';
|
|
133
|
+
import { NodePostgresDriver } from '@venizia/ignis/postgres/node-postgres';
|
|
134
134
|
import { Pool } from 'pg';
|
|
135
135
|
|
|
136
136
|
interface IDSConfigs {
|
|
@@ -141,8 +141,8 @@ interface IDSConfigs {
|
|
|
141
141
|
password: string;
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
@datasource({ driver:
|
|
145
|
-
export class PostgresDataSource extends
|
|
144
|
+
@datasource({ driver: NodePostgresDriver })
|
|
145
|
+
export class PostgresDataSource extends BasePostgresDataSource<IDSConfigs> {
|
|
146
146
|
constructor() {
|
|
147
147
|
super({
|
|
148
148
|
name: PostgresDataSource.name,
|
|
@@ -157,9 +157,7 @@ export class PostgresDataSource extends BaseDataSource<IDSConfigs> {
|
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
override configure(): ValueOrPromise<void> {
|
|
160
|
-
|
|
161
|
-
this.pool = new Pool(this.settings);
|
|
162
|
-
this.connector = drizzle({ client: this.pool, schema });
|
|
160
|
+
this.client = new Pool(this.settings);
|
|
163
161
|
}
|
|
164
162
|
|
|
165
163
|
override getConnectionString(): ValueOrPromise<string> {
|
|
@@ -177,6 +175,7 @@ export class PostgresDataSource extends BaseDataSource<IDSConfigs> {
|
|
|
177
175
|
- [Repositories](/guides/core-concepts/persistent/repositories) - Use DataSources for database access
|
|
178
176
|
- [Models](/guides/core-concepts/persistent/models) - Entity schemas loaded by DataSource
|
|
179
177
|
- [Transactions](/guides/core-concepts/persistent/transactions) - Multi-operation database transactions
|
|
178
|
+
- [Search & Typesense](/guides/core-concepts/persistent/search-typesense) - The typesense connector
|
|
180
179
|
- [Application](/guides/core-concepts/application/) - Registering DataSources
|
|
181
180
|
|
|
182
181
|
- **References:**
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
The persistent layer manages data using [Drizzle ORM](https://orm.drizzle.team/) for type-safe database access and the Repository pattern for data abstraction.
|
|
4
4
|
|
|
5
|
+
> [!NOTE] Connectors
|
|
6
|
+
> This page and the ones below it focus on the **PostgreSQL connector** (Drizzle + relational tables), the default and most common engine. The persistence layer also ships a **typesense connector** for search (see [Search & Typesense](./search-typesense)). Both share the same engine-neutral `AbstractRepository`/`AbstractDataSource`/`AbstractEntity` contracts - see [Connectors](/references/base/connectors) for the architecture.
|
|
7
|
+
|
|
5
8
|
## Architecture Overview
|
|
6
9
|
|
|
7
10
|
```
|
|
@@ -27,14 +30,15 @@ The persistent layer manages data using [Drizzle ORM](https://orm.drizzle.team/)
|
|
|
27
30
|
| **Models** | Define data structure with Drizzle schemas and relations | [Models Guide](./models.md) |
|
|
28
31
|
| **DataSources** | Manage database connections with auto-discovery | [DataSources Guide](./datasources.md) |
|
|
29
32
|
| **Repositories** | Provide type-safe CRUD operations | [Repositories Guide](./repositories.md) |
|
|
30
|
-
| **Transactions** | Handle atomic multi-step operations | [Transactions Guide](./transactions.md) |
|
|
33
|
+
| **Transactions** | Handle atomic multi-step operations (PostgreSQL connector only) | [Transactions Guide](./transactions.md) |
|
|
34
|
+
| **Search & Typesense** | Full-text/faceted search over documents | [Search & Typesense Guide](./search-typesense.md) |
|
|
31
35
|
|
|
32
36
|
## Quick Example
|
|
33
37
|
|
|
34
38
|
```typescript
|
|
35
39
|
// 1. Define a Model
|
|
36
40
|
@model({ type: 'entity' })
|
|
37
|
-
export class User extends
|
|
41
|
+
export class User extends BasePostgresEntity<typeof User.schema> {
|
|
38
42
|
static override schema = pgTable('User', {
|
|
39
43
|
...generateIdColumnDefs({ id: { dataType: 'string' } }),
|
|
40
44
|
name: text('name').notNull(),
|
|
@@ -45,8 +49,8 @@ export class User extends BaseEntity<typeof User.schema> {
|
|
|
45
49
|
}
|
|
46
50
|
|
|
47
51
|
// 2. Create a DataSource
|
|
48
|
-
@datasource({ driver:
|
|
49
|
-
export class PostgresDataSource extends
|
|
52
|
+
@datasource({ driver: NodePostgresDriver })
|
|
53
|
+
export class PostgresDataSource extends BasePostgresDataSource<IDSConfigs> {
|
|
50
54
|
constructor() {
|
|
51
55
|
super({
|
|
52
56
|
name: PostgresDataSource.name,
|
|
@@ -61,9 +65,12 @@ export class PostgresDataSource extends BaseDataSource<IDSConfigs> {
|
|
|
61
65
|
}
|
|
62
66
|
|
|
63
67
|
override configure(): ValueOrPromise<void> {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
this.client = new Pool(this.settings); // NodePostgresDriver above wires the driver + connector
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
override getConnectionString(): ValueOrPromise<string> {
|
|
72
|
+
const { host, port, user, password, database } = this.settings;
|
|
73
|
+
return `postgresql://${user}:${password}@${host}:${port}/${database}`;
|
|
67
74
|
}
|
|
68
75
|
}
|
|
69
76
|
|
|
@@ -100,12 +107,14 @@ export class Application extends BaseApplication {
|
|
|
100
107
|
- [DataSources](./datasources) - Database connections
|
|
101
108
|
- [Repositories](./repositories) - Data access layer
|
|
102
109
|
- [Transactions](./transactions) - Atomic operations
|
|
110
|
+
- [Search & Typesense](./search-typesense) - The typesense connector
|
|
103
111
|
|
|
104
112
|
- **Related Concepts:**
|
|
105
113
|
- [Services](/guides/core-concepts/services) - Use repositories for business logic
|
|
106
114
|
- [Application](/guides/core-concepts/application/) - Registering persistent resources
|
|
107
115
|
|
|
108
116
|
- **References:**
|
|
117
|
+
- [Connectors API](/references/base/connectors) - Base-vs-connectors architecture
|
|
109
118
|
- [Models API](/references/base/models) - Complete models reference
|
|
110
119
|
- [DataSources API](/references/base/datasources) - Complete datasources reference
|
|
111
120
|
- [Repositories API](/references/base/repositories/) - Complete repositories reference
|