@venizia/ignis-docs 0.0.8 → 0.1.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 +44 -20
- 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 +36 -28
- 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/examples.md +1 -1
- 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 +33 -27
- package/content/guides/core-concepts/persistent/index.md +16 -5
- package/content/guides/core-concepts/persistent/models.md +24 -20
- package/content/guides/core-concepts/persistent/postgres-drivers.md +167 -0
- package/content/guides/core-concepts/persistent/repositories.md +40 -23
- package/content/guides/core-concepts/persistent/search-meilisearch.md +183 -0
- package/content/guides/core-concepts/persistent/search-typesense.md +429 -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 +30 -33
- package/content/guides/tutorials/complete-installation.md +17 -17
- package/content/guides/tutorials/ecommerce-api.md +158 -119
- package/content/guides/tutorials/realtime-chat.md +176 -130
- 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 +154 -81
- 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 +46 -30
- 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,15 +2,15 @@
|
|
|
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';
|
|
@@ -26,7 +26,7 @@ interface IDSConfigs {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
@datasource({ driver: 'node-postgres' })
|
|
29
|
-
export class PostgresDataSource extends
|
|
29
|
+
export class PostgresDataSource extends BasePostgresDataSource<IDSConfigs> {
|
|
30
30
|
constructor() {
|
|
31
31
|
super({
|
|
32
32
|
name: PostgresDataSource.name,
|
|
@@ -50,8 +50,8 @@ export class PostgresDataSource extends BaseDataSource<IDSConfigs> {
|
|
|
50
50
|
Object.keys(schema),
|
|
51
51
|
);
|
|
52
52
|
|
|
53
|
-
this.
|
|
54
|
-
this.connector = drizzle({ client: this.
|
|
53
|
+
this.client = new Pool(this.settings);
|
|
54
|
+
this.connector = drizzle({ client: this.client, schema });
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
override getConnectionString(): ValueOrPromise<string> {
|
|
@@ -61,6 +61,9 @@ export class PostgresDataSource extends BaseDataSource<IDSConfigs> {
|
|
|
61
61
|
}
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
> [!NOTE] Driver seam: the raw client goes on `this.client`
|
|
65
|
+
> `this.client = new Pool(...)` is the short path: IGNIS resolves a `node-postgres` driver from that client on first use. There is no `pool` field - the raw-client slot is `client`, whatever the client happens to be. The alternative is to wire a driver yourself: `configure()` calls `this.useDriver({ driver, schema? })`, which assigns `this.driver` **and** builds `this.connector` in one step (so the half-wired state cannot exist). That is also how you select the `postgres-js` driver or run on Supabase. See [Postgres Drivers & Supabase](./postgres-drivers).
|
|
66
|
+
|
|
64
67
|
**How auto-discovery works:**
|
|
65
68
|
|
|
66
69
|
1. `@repository` decorators register model-datasource bindings in the `MetadataRegistry`
|
|
@@ -75,7 +78,7 @@ If you need explicit control, you can still provide schema manually:
|
|
|
75
78
|
|
|
76
79
|
```typescript
|
|
77
80
|
@datasource({ driver: 'node-postgres' })
|
|
78
|
-
export class PostgresDataSource extends
|
|
81
|
+
export class PostgresDataSource extends BasePostgresDataSource<IDSConfigs> {
|
|
79
82
|
constructor() {
|
|
80
83
|
super({
|
|
81
84
|
name: PostgresDataSource.name,
|
|
@@ -93,16 +96,18 @@ export class PostgresDataSource extends BaseDataSource<IDSConfigs> {
|
|
|
93
96
|
## DataSource Hierarchy
|
|
94
97
|
|
|
95
98
|
```
|
|
96
|
-
AbstractDataSource extends BaseHelper
|
|
97
|
-
└──
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
99
|
+
AbstractDataSource extends BaseHelper # engine-neutral, src/base - no pool, no Drizzle
|
|
100
|
+
└── AbstractPostgresDataSource # connectors/postgres - adds pool, connector
|
|
101
|
+
└── BasePostgresDataSource (alias: BaseDataSource)
|
|
102
|
+
├── configure() # Setup pool + Drizzle connector (abstract)
|
|
103
|
+
├── getConnectionString() # Build connection URL (abstract)
|
|
104
|
+
├── getSchema() # Auto-discover from @repository bindings
|
|
105
|
+
├── discoverSchema() # Internal: reads MetadataRegistry
|
|
106
|
+
├── hasDiscoverableModels() # Check if any repos reference this DS
|
|
107
|
+
├── getCapabilities() # Returns { transactions: true }
|
|
108
|
+
├── beginTransaction(opts?) # Start transaction with isolation level
|
|
109
|
+
├── getConnector() # Get Drizzle connector
|
|
110
|
+
└── getSettings() # Get connection config
|
|
106
111
|
```
|
|
107
112
|
|
|
108
113
|
## Registering a DataSource
|
|
@@ -118,18 +123,18 @@ export class Application extends BaseApplication {
|
|
|
118
123
|
|
|
119
124
|
DataSources are bound as **singletons** to ensure connection pool sharing across the application.
|
|
120
125
|
|
|
121
|
-
## Supported
|
|
126
|
+
## Supported Engines
|
|
122
127
|
|
|
123
|
-
|
|
|
124
|
-
|
|
125
|
-
| `node-postgres` | `
|
|
126
|
-
| `
|
|
127
|
-
|
|
|
128
|
+
| Engine | Driver/Package | Import | Status |
|
|
129
|
+
|--------|---------|--------|--------|
|
|
130
|
+
| PostgreSQL | `node-postgres` (`pg`) | `@venizia/ignis` or `@venizia/ignis/postgres` | Supported, transactions + 3 isolation levels |
|
|
131
|
+
| Typesense (search) | `typesense` (optional peer) | `@venizia/ignis/typesense` (subpath-only) | Supported, no transactions/locks |
|
|
132
|
+
| MySQL / SQLite | - | - | Not planned; would be a new connector under `src/connectors/` |
|
|
128
133
|
|
|
129
134
|
## DataSource Template
|
|
130
135
|
|
|
131
136
|
```typescript
|
|
132
|
-
import {
|
|
137
|
+
import { BasePostgresDataSource, datasource, ValueOrPromise } from '@venizia/ignis';
|
|
133
138
|
import { drizzle } from 'drizzle-orm/node-postgres';
|
|
134
139
|
import { Pool } from 'pg';
|
|
135
140
|
|
|
@@ -142,7 +147,7 @@ interface IDSConfigs {
|
|
|
142
147
|
}
|
|
143
148
|
|
|
144
149
|
@datasource({ driver: 'node-postgres' })
|
|
145
|
-
export class PostgresDataSource extends
|
|
150
|
+
export class PostgresDataSource extends BasePostgresDataSource<IDSConfigs> {
|
|
146
151
|
constructor() {
|
|
147
152
|
super({
|
|
148
153
|
name: PostgresDataSource.name,
|
|
@@ -158,8 +163,8 @@ export class PostgresDataSource extends BaseDataSource<IDSConfigs> {
|
|
|
158
163
|
|
|
159
164
|
override configure(): ValueOrPromise<void> {
|
|
160
165
|
const schema = this.getSchema();
|
|
161
|
-
this.
|
|
162
|
-
this.connector = drizzle({ client: this.
|
|
166
|
+
this.client = new Pool(this.settings);
|
|
167
|
+
this.connector = drizzle({ client: this.client, schema });
|
|
163
168
|
}
|
|
164
169
|
|
|
165
170
|
override getConnectionString(): ValueOrPromise<string> {
|
|
@@ -177,6 +182,7 @@ export class PostgresDataSource extends BaseDataSource<IDSConfigs> {
|
|
|
177
182
|
- [Repositories](/guides/core-concepts/persistent/repositories) - Use DataSources for database access
|
|
178
183
|
- [Models](/guides/core-concepts/persistent/models) - Entity schemas loaded by DataSource
|
|
179
184
|
- [Transactions](/guides/core-concepts/persistent/transactions) - Multi-operation database transactions
|
|
185
|
+
- [Search & Typesense](/guides/core-concepts/persistent/search-typesense) - The typesense connector
|
|
180
186
|
- [Application](/guides/core-concepts/application/) - Registering DataSources
|
|
181
187
|
|
|
182
188
|
- **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(),
|
|
@@ -46,7 +50,7 @@ export class User extends BaseEntity<typeof User.schema> {
|
|
|
46
50
|
|
|
47
51
|
// 2. Create a DataSource
|
|
48
52
|
@datasource({ driver: 'node-postgres' })
|
|
49
|
-
export class PostgresDataSource extends
|
|
53
|
+
export class PostgresDataSource extends BasePostgresDataSource<IDSConfigs> {
|
|
50
54
|
constructor() {
|
|
51
55
|
super({
|
|
52
56
|
name: PostgresDataSource.name,
|
|
@@ -62,8 +66,13 @@ export class PostgresDataSource extends BaseDataSource<IDSConfigs> {
|
|
|
62
66
|
|
|
63
67
|
override configure(): ValueOrPromise<void> {
|
|
64
68
|
const schema = this.getSchema();
|
|
65
|
-
this.
|
|
66
|
-
this.connector = drizzle({ client: this.
|
|
69
|
+
this.client = new Pool(this.settings);
|
|
70
|
+
this.connector = drizzle({ client: this.client, schema });
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
override getConnectionString(): ValueOrPromise<string> {
|
|
74
|
+
const { host, port, user, password, database } = this.settings;
|
|
75
|
+
return `postgresql://${user}:${password}@${host}:${port}/${database}`;
|
|
67
76
|
}
|
|
68
77
|
}
|
|
69
78
|
|
|
@@ -100,12 +109,14 @@ export class Application extends BaseApplication {
|
|
|
100
109
|
- [DataSources](./datasources) - Database connections
|
|
101
110
|
- [Repositories](./repositories) - Data access layer
|
|
102
111
|
- [Transactions](./transactions) - Atomic operations
|
|
112
|
+
- [Search & Typesense](./search-typesense) - The typesense connector
|
|
103
113
|
|
|
104
114
|
- **Related Concepts:**
|
|
105
115
|
- [Services](/guides/core-concepts/services) - Use repositories for business logic
|
|
106
116
|
- [Application](/guides/core-concepts/application/) - Registering persistent resources
|
|
107
117
|
|
|
108
118
|
- **References:**
|
|
119
|
+
- [Connectors API](/references/base/connectors) - Base-vs-connectors architecture
|
|
109
120
|
- [Models API](/references/base/models) - Complete models reference
|
|
110
121
|
- [DataSources API](/references/base/datasources) - Complete datasources reference
|
|
111
122
|
- [Repositories API](/references/base/repositories/) - Complete repositories reference
|