@venizia/ignis-docs 0.0.7 → 0.0.8-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/dist/mcp-server/common/paths.d.ts +4 -2
- package/dist/mcp-server/common/paths.d.ts.map +1 -1
- package/dist/mcp-server/common/paths.js +8 -6
- package/dist/mcp-server/common/paths.js.map +1 -1
- package/dist/mcp-server/tools/docs/get-document-content.tool.d.ts +1 -1
- package/dist/mcp-server/tools/docs/get-document-content.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/docs/get-document-content.tool.js +7 -7
- package/dist/mcp-server/tools/docs/get-document-metadata.tool.js +3 -3
- package/dist/mcp-server/tools/docs/get-package-overview.tool.d.ts +1 -1
- package/dist/mcp-server/tools/docs/get-package-overview.tool.js +1 -1
- package/package.json +1 -1
- package/wiki/best-practices/api-usage-examples.md +9 -9
- package/wiki/best-practices/architectural-patterns.md +19 -3
- package/wiki/best-practices/architecture-decisions.md +6 -6
- package/wiki/best-practices/code-style-standards/advanced-patterns.md +1 -1
- package/wiki/best-practices/code-style-standards/control-flow.md +1 -1
- package/wiki/best-practices/code-style-standards/function-patterns.md +2 -2
- package/wiki/best-practices/code-style-standards/index.md +2 -2
- package/wiki/best-practices/code-style-standards/naming-conventions.md +1 -1
- package/wiki/best-practices/code-style-standards/route-definitions.md +4 -4
- package/wiki/best-practices/data-modeling.md +1 -1
- package/wiki/best-practices/deployment-strategies.md +1 -1
- package/wiki/best-practices/error-handling.md +2 -2
- package/wiki/best-practices/performance-optimization.md +3 -3
- package/wiki/best-practices/security-guidelines.md +2 -2
- package/wiki/best-practices/troubleshooting-tips.md +1 -1
- package/wiki/{references → extensions}/components/authentication/api.md +12 -20
- package/wiki/{references → extensions}/components/authentication/errors.md +1 -1
- package/wiki/{references → extensions}/components/authentication/index.md +5 -8
- package/wiki/{references → extensions}/components/authentication/usage.md +20 -36
- package/wiki/{references → extensions}/components/authorization/api.md +62 -13
- package/wiki/{references → extensions}/components/authorization/errors.md +12 -7
- package/wiki/{references → extensions}/components/authorization/index.md +93 -6
- package/wiki/{references → extensions}/components/authorization/usage.md +42 -4
- package/wiki/{references → extensions}/components/health-check.md +5 -4
- package/wiki/{references → extensions}/components/index.md +2 -0
- package/wiki/{references → extensions}/components/mail/index.md +1 -1
- package/wiki/{references → extensions}/components/request-tracker.md +1 -1
- package/wiki/{references → extensions}/components/socket-io/api.md +2 -2
- package/wiki/{references → extensions}/components/socket-io/errors.md +2 -0
- package/wiki/{references → extensions}/components/socket-io/index.md +24 -20
- package/wiki/{references → extensions}/components/socket-io/usage.md +2 -2
- package/wiki/{references → extensions}/components/static-asset/api.md +14 -15
- package/wiki/{references → extensions}/components/static-asset/errors.md +3 -1
- package/wiki/{references → extensions}/components/static-asset/index.md +158 -89
- package/wiki/{references → extensions}/components/static-asset/usage.md +8 -5
- package/wiki/{references → extensions}/components/swagger.md +3 -3
- package/wiki/{references → extensions}/components/template/index.md +4 -4
- package/wiki/{references → extensions}/components/template/setup-page.md +1 -1
- package/wiki/{references → extensions}/components/template/single-page.md +1 -1
- package/wiki/{references → extensions}/components/websocket/api.md +7 -6
- package/wiki/{references → extensions}/components/websocket/errors.md +17 -3
- package/wiki/{references → extensions}/components/websocket/index.md +17 -11
- package/wiki/{references → extensions}/components/websocket/usage.md +2 -2
- package/wiki/{references → extensions}/helpers/crypto/index.md +1 -1
- package/wiki/{references → extensions}/helpers/env/index.md +9 -5
- package/wiki/{references → extensions}/helpers/error/index.md +2 -7
- package/wiki/{references → extensions}/helpers/index.md +18 -6
- package/wiki/{references → extensions}/helpers/kafka/admin.md +13 -1
- package/wiki/{references → extensions}/helpers/kafka/consumer.md +28 -28
- package/wiki/{references → extensions}/helpers/kafka/examples.md +19 -19
- package/wiki/{references → extensions}/helpers/kafka/index.md +51 -48
- package/wiki/{references → extensions}/helpers/kafka/producer.md +18 -18
- package/wiki/{references → extensions}/helpers/kafka/schema-registry.md +25 -25
- package/wiki/{references → extensions}/helpers/logger/index.md +2 -2
- package/wiki/{references → extensions}/helpers/queue/index.md +400 -4
- package/wiki/{references → extensions}/helpers/storage/api.md +170 -10
- package/wiki/{references → extensions}/helpers/storage/index.md +44 -8
- package/wiki/{references → extensions}/helpers/template/index.md +1 -1
- package/wiki/{references → extensions}/helpers/testing/index.md +4 -4
- package/wiki/{references → extensions}/helpers/types/index.md +63 -16
- package/wiki/{references → extensions}/helpers/websocket/index.md +1 -1
- package/wiki/extensions/index.md +48 -0
- package/wiki/guides/core-concepts/application/bootstrapping.md +55 -37
- package/wiki/guides/core-concepts/application/index.md +95 -35
- package/wiki/guides/core-concepts/components-guide.md +23 -19
- package/wiki/guides/core-concepts/components.md +34 -10
- package/wiki/guides/core-concepts/dependency-injection.md +99 -34
- package/wiki/guides/core-concepts/grpc-controllers.md +295 -0
- package/wiki/guides/core-concepts/persistent/datasources.md +27 -8
- package/wiki/guides/core-concepts/persistent/models.md +43 -1
- package/wiki/guides/core-concepts/persistent/repositories.md +75 -8
- package/wiki/guides/core-concepts/persistent/transactions.md +38 -8
- package/wiki/guides/core-concepts/{controllers.md → rest-controllers.md} +30 -33
- package/wiki/guides/core-concepts/services.md +19 -5
- package/wiki/guides/get-started/5-minute-quickstart.md +6 -7
- package/wiki/guides/get-started/philosophy.md +1 -1
- package/wiki/guides/index.md +2 -2
- package/wiki/guides/reference/glossary.md +7 -7
- package/wiki/guides/reference/mcp-docs-server.md +1 -1
- package/wiki/guides/tutorials/building-a-crud-api.md +2 -2
- package/wiki/guides/tutorials/complete-installation.md +17 -14
- package/wiki/guides/tutorials/ecommerce-api.md +18 -18
- package/wiki/guides/tutorials/realtime-chat.md +8 -8
- package/wiki/guides/tutorials/testing.md +2 -2
- package/wiki/index.md +4 -3
- package/wiki/references/base/application.md +341 -21
- package/wiki/references/base/bootstrapping.md +43 -13
- package/wiki/references/base/components.md +259 -8
- package/wiki/references/base/controllers.md +556 -253
- package/wiki/references/base/datasources.md +159 -79
- package/wiki/references/base/dependency-injection.md +299 -48
- package/wiki/references/base/filter-system/application-usage.md +18 -2
- package/wiki/references/base/filter-system/array-operators.md +14 -6
- package/wiki/references/base/filter-system/comparison-operators.md +9 -3
- package/wiki/references/base/filter-system/default-filter.md +28 -3
- package/wiki/references/base/filter-system/fields-order-pagination.md +17 -13
- package/wiki/references/base/filter-system/index.md +169 -11
- package/wiki/references/base/filter-system/json-filtering.md +51 -18
- package/wiki/references/base/filter-system/list-operators.md +4 -3
- package/wiki/references/base/filter-system/logical-operators.md +7 -2
- package/wiki/references/base/filter-system/null-operators.md +50 -0
- package/wiki/references/base/filter-system/quick-reference.md +82 -243
- package/wiki/references/base/filter-system/range-operators.md +7 -1
- package/wiki/references/base/filter-system/tips.md +34 -7
- package/wiki/references/base/filter-system/use-cases.md +6 -5
- package/wiki/references/base/grpc-controllers.md +984 -0
- package/wiki/references/base/index.md +32 -24
- package/wiki/references/base/middleware.md +347 -0
- package/wiki/references/base/models.md +390 -46
- package/wiki/references/base/providers.md +14 -14
- package/wiki/references/base/repositories/advanced.md +84 -69
- package/wiki/references/base/repositories/index.md +447 -12
- package/wiki/references/base/repositories/mixins.md +103 -98
- package/wiki/references/base/repositories/relations.md +129 -45
- package/wiki/references/base/repositories/soft-deletable.md +104 -23
- package/wiki/references/base/services.md +94 -14
- package/wiki/references/index.md +12 -10
- package/wiki/references/quick-reference.md +98 -65
- package/wiki/references/utilities/crypto.md +21 -4
- package/wiki/references/utilities/date.md +25 -7
- package/wiki/references/utilities/index.md +26 -24
- package/wiki/references/utilities/jsx.md +54 -54
- package/wiki/references/utilities/module.md +8 -6
- package/wiki/references/utilities/parse.md +16 -9
- package/wiki/references/utilities/performance.md +22 -7
- package/wiki/references/utilities/promise.md +19 -16
- package/wiki/references/utilities/request.md +48 -26
- package/wiki/references/utilities/schema.md +69 -6
- package/wiki/references/utilities/statuses.md +131 -140
- /package/wiki/{references → extensions}/components/mail/api.md +0 -0
- /package/wiki/{references → extensions}/components/mail/errors.md +0 -0
- /package/wiki/{references → extensions}/components/mail/usage.md +0 -0
- /package/wiki/{references → extensions}/components/template/api-page.md +0 -0
- /package/wiki/{references → extensions}/components/template/errors-page.md +0 -0
- /package/wiki/{references → extensions}/components/template/usage-page.md +0 -0
- /package/wiki/{references → extensions}/helpers/cron/index.md +0 -0
- /package/wiki/{references → extensions}/helpers/inversion/index.md +0 -0
- /package/wiki/{references → extensions}/helpers/network/api.md +0 -0
- /package/wiki/{references → extensions}/helpers/network/index.md +0 -0
- /package/wiki/{references → extensions}/helpers/redis/index.md +0 -0
- /package/wiki/{references → extensions}/helpers/socket-io/api.md +0 -0
- /package/wiki/{references → extensions}/helpers/socket-io/index.md +0 -0
- /package/wiki/{references → extensions}/helpers/template/single-page.md +0 -0
- /package/wiki/{references → extensions}/helpers/uid/index.md +0 -0
- /package/wiki/{references → extensions}/helpers/websocket/api.md +0 -0
- /package/wiki/{references → extensions}/helpers/worker-thread/index.md +0 -0
- /package/wiki/{references → extensions}/src-details/mcp-server.md +0 -0
|
@@ -7,6 +7,7 @@ Unified file storage abstraction with interchangeable backends for S3-compatible
|
|
|
7
7
|
| Class | Extends | Backend | Implements |
|
|
8
8
|
|-------|---------|---------|------------|
|
|
9
9
|
| **MinioHelper** | `BaseStorageHelper` | S3-compatible (MinIO) | `IStorageHelper` |
|
|
10
|
+
| **BunS3Helper** | `BaseStorageHelper` | S3-compatible (Bun-native) | `IStorageHelper` |
|
|
10
11
|
| **DiskHelper** | `BaseStorageHelper` | Local filesystem | `IStorageHelper` |
|
|
11
12
|
| **MemoryStorageHelper** | `BaseHelper` | In-memory key-value | -- |
|
|
12
13
|
|
|
@@ -19,6 +20,9 @@ import { DiskHelper, MemoryStorageHelper } from '@venizia/ignis-helpers';
|
|
|
19
20
|
// MinIO storage (separate export path)
|
|
20
21
|
import { MinioHelper } from '@venizia/ignis-helpers/minio';
|
|
21
22
|
|
|
23
|
+
// Bun S3 storage (separate export path, Bun runtime only)
|
|
24
|
+
import { BunS3Helper } from '@venizia/ignis-helpers/bun-s3';
|
|
25
|
+
|
|
22
26
|
// Types
|
|
23
27
|
import type {
|
|
24
28
|
IStorageHelper,
|
|
@@ -32,6 +36,7 @@ import type {
|
|
|
32
36
|
IListObjectsOptions,
|
|
33
37
|
} from '@venizia/ignis-helpers';
|
|
34
38
|
import type { IMinioHelperOptions } from '@venizia/ignis-helpers/minio';
|
|
39
|
+
import type { IBunS3HelperOptions } from '@venizia/ignis-helpers/bun-s3';
|
|
35
40
|
```
|
|
36
41
|
|
|
37
42
|
## Creating an Instance
|
|
@@ -70,8 +75,38 @@ interface IMinioHelperOptions extends IStorageHelperOptions, ClientOptions {}
|
|
|
70
75
|
| `scope` | `string` | `'MinioHelper'` | Logger scope name. |
|
|
71
76
|
| `identifier` | `string` | `'MinioHelper'` | Helper identifier. |
|
|
72
77
|
|
|
73
|
-
> [!
|
|
74
|
-
> The underlying `minio.Client` is
|
|
78
|
+
> [!NOTE]
|
|
79
|
+
> The underlying `minio.Client` is stored as a private property. Use the `IStorageHelper` methods for all operations. If you need direct minio SDK access, extend `MinioHelper` in a subclass.
|
|
80
|
+
|
|
81
|
+
### Bun S3 Storage
|
|
82
|
+
|
|
83
|
+
`BunS3Helper` provides S3-compatible storage using Bun's native `S3Client` for high-performance object operations. Bucket management operations (list, create, delete) use AWS Signature V4 signed requests, while object operations use Bun's native S3 API.
|
|
84
|
+
|
|
85
|
+
> [!IMPORTANT]
|
|
86
|
+
> `BunS3Helper` requires the **Bun runtime**. It uses Bun's built-in `S3Client` class which is not available in Node.js.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { BunS3Helper } from '@venizia/ignis-helpers/bun-s3';
|
|
90
|
+
|
|
91
|
+
const storage = new BunS3Helper({
|
|
92
|
+
accessKey: 'minioadmin',
|
|
93
|
+
secretKey: 'minioadmin',
|
|
94
|
+
endpoint: 'http://localhost:9000',
|
|
95
|
+
region: 'us-east-1',
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
#### IBunS3HelperOptions
|
|
100
|
+
|
|
101
|
+
| Option | Type | Default | Description |
|
|
102
|
+
|--------|------|---------|-------------|
|
|
103
|
+
| `accessKey` | `string` | -- | S3 access key credential. |
|
|
104
|
+
| `secretKey` | `string` | -- | S3 secret key credential. |
|
|
105
|
+
| `endpoint` | `string` | -- | S3-compatible endpoint URL (e.g., `'http://localhost:9000'`). |
|
|
106
|
+
| `region` | `string` | `'us-east-1'` | AWS region for signing. |
|
|
107
|
+
| `sessionToken` | `string` | -- | Optional session token for temporary credentials. |
|
|
108
|
+
| `scope` | `string` | `'BunS3Helper'` | Logger scope name. |
|
|
109
|
+
| `identifier` | `string` | `'BunS3Helper'` | Helper identifier. |
|
|
75
110
|
|
|
76
111
|
### Disk Storage
|
|
77
112
|
|
|
@@ -130,7 +165,7 @@ const cache = MemoryStorageHelper.newInstance<{ counter: number; name: string }>
|
|
|
130
165
|
|
|
131
166
|
## Usage
|
|
132
167
|
|
|
133
|
-
`DiskHelper` and `
|
|
168
|
+
`DiskHelper`, `MinioHelper`, and `BunS3Helper` implement the same `IStorageHelper` interface, making them interchangeable. All examples below apply to all three unless noted otherwise.
|
|
134
169
|
|
|
135
170
|
### Uploading Files
|
|
136
171
|
|
|
@@ -156,7 +191,7 @@ console.log(results);
|
|
|
156
191
|
|
|
157
192
|
#### Custom Name and Link Normalization
|
|
158
193
|
|
|
159
|
-
By default, file names are lowercased with spaces replaced by underscores. The default link prefix differs by backend: MinioHelper
|
|
194
|
+
By default, file names are lowercased with spaces replaced by underscores. The default link prefix differs by backend: MinioHelper and BunS3Helper use `/static-assets/{bucket}/{name}`, DiskHelper uses `/static-resources/{bucket}/{name}`. Override either with custom functions:
|
|
160
195
|
|
|
161
196
|
```typescript
|
|
162
197
|
const results = await storage.upload({
|
|
@@ -195,7 +230,7 @@ const results = await storage.upload({
|
|
|
195
230
|
```
|
|
196
231
|
|
|
197
232
|
> [!WARNING]
|
|
198
|
-
> DiskHelper uses `/static-resources/` as the default link prefix, while MinioHelper
|
|
233
|
+
> DiskHelper uses `/static-resources/` as the default link prefix, while MinioHelper and BunS3Helper use `/static-assets/`. Provide a `normalizeLinkFn` if you need consistent links across storage backends.
|
|
199
234
|
|
|
200
235
|
### Downloading Files
|
|
201
236
|
|
|
@@ -252,7 +287,7 @@ console.log(stat);
|
|
|
252
287
|
```
|
|
253
288
|
|
|
254
289
|
> [!NOTE]
|
|
255
|
-
> DiskHelper populates `metadata.mimetype` using the `getMimeType()` extension-based lookup. It does not return `etag` or `versionId`. MinioHelper returns full metadata from the MinIO server including the original upload metadata, `etag`, and `versionId`.
|
|
290
|
+
> DiskHelper populates `metadata.mimetype` using the `getMimeType()` extension-based lookup. It does not return `etag` or `versionId`. MinioHelper returns full metadata from the MinIO server including the original upload metadata, `etag`, and `versionId`. BunS3Helper returns `metadata` with `contentType` and `mimetype` from the S3 stat response, plus `etag` and `lastModified`.
|
|
256
291
|
|
|
257
292
|
### Listing Files
|
|
258
293
|
|
|
@@ -299,7 +334,7 @@ await storage.removeObjects({
|
|
|
299
334
|
```
|
|
300
335
|
|
|
301
336
|
> [!NOTE]
|
|
302
|
-
> DiskHelper's `removeObject()` throws if the file does not exist. DiskHelper's `removeObjects()` processes deletions sequentially. MinioHelper's `removeObjects()` delegates to the minio SDK's batch removal.
|
|
337
|
+
> DiskHelper's `removeObject()` throws if the file does not exist. DiskHelper's `removeObjects()` processes deletions sequentially. MinioHelper's `removeObjects()` delegates to the minio SDK's batch removal. BunS3Helper's `removeObjects()` deletes in parallel via `Promise.all()`.
|
|
303
338
|
|
|
304
339
|
### Bucket Operations
|
|
305
340
|
|
|
@@ -408,6 +443,7 @@ class FileService {
|
|
|
408
443
|
// Swap backends without changing service code
|
|
409
444
|
const devService = new FileService(new DiskHelper({ basePath: './files' }));
|
|
410
445
|
const prodService = new FileService(new MinioHelper({ /* ... */ }));
|
|
446
|
+
const bunService = new FileService(new BunS3Helper({ /* ... */ }));
|
|
411
447
|
```
|
|
412
448
|
|
|
413
449
|
#### Environment-Based Selection
|
|
@@ -574,7 +610,7 @@ try {
|
|
|
574
610
|
- [Queue Helper](../queue/) -- Message queue processing
|
|
575
611
|
|
|
576
612
|
- **References:**
|
|
577
|
-
- [Static Asset Component](/
|
|
613
|
+
- [Static Asset Component](/extensions/components/static-asset/) -- Serving stored files via HTTP
|
|
578
614
|
- [Request Utilities](/references/utilities/request) -- `parseMultipartBody` for file uploads
|
|
579
615
|
- [API Reference](./api) -- Full method signatures and types
|
|
580
616
|
|
|
@@ -54,7 +54,7 @@ Use **GitHub-style only**:
|
|
|
54
54
|
|----------|---------|
|
|
55
55
|
| [Single Page](./single-page) | Tier 1 template -- one file per helper |
|
|
56
56
|
|
|
57
|
-
Tier 2 follows the same two-page pattern as [Component Tier 2](
|
|
57
|
+
Tier 2 follows the same two-page pattern as [Component Tier 2](../../components/template/).
|
|
58
58
|
|
|
59
59
|
## Source Paths
|
|
60
60
|
|
|
@@ -270,14 +270,14 @@ The `_execute()` method on `TestCaseHandler` calls `assert.equal(validateRs, Tes
|
|
|
270
270
|
|
|
271
271
|
```
|
|
272
272
|
BaseTestCaseHandler (abstract)
|
|
273
|
-
|
|
274
|
-
|
|
273
|
+
+-- TestCaseHandler (abstract) -- execute(), getValidator(), validate()
|
|
274
|
+
+-- Your concrete handler
|
|
275
275
|
|
|
276
276
|
BaseTestPlan (abstract)
|
|
277
|
-
|
|
277
|
+
+-- TestPlan -- newInstance()
|
|
278
278
|
|
|
279
279
|
TestDescribe -- withTestPlan(), run()
|
|
280
|
-
|
|
280
|
+
+-- AppTestDescribe
|
|
281
281
|
```
|
|
282
282
|
|
|
283
283
|
### ITestPlanOptions
|
|
@@ -43,17 +43,16 @@ import type {
|
|
|
43
43
|
TObjectFromFieldMappings,
|
|
44
44
|
TInjectionGetter,
|
|
45
45
|
IConfigurable,
|
|
46
|
-
TPermissionEffect,
|
|
47
46
|
} from '@venizia/ignis-helpers';
|
|
48
47
|
|
|
49
48
|
// Resolver functions
|
|
50
49
|
import { resolveValue, resolveValueAsync, resolveClass } from '@venizia/ignis-helpers';
|
|
51
50
|
|
|
52
51
|
// Constants
|
|
53
|
-
import { Defaults, RuntimeModules, DataTypes, HTTP, MimeTypes } from '@venizia/ignis-helpers';
|
|
52
|
+
import { Defaults, RuntimeModules, DataTypes, HTTP, GRPC, MimeTypes } from '@venizia/ignis-helpers';
|
|
54
53
|
|
|
55
54
|
// Derived constant types
|
|
56
|
-
import type { TRuntimeModule, TMimeTypes, THttpMethod, THttpResultCode } from '@venizia/ignis-helpers';
|
|
55
|
+
import type { TRuntimeModule, TMimeTypes, THttpMethod, THttpResultCode, TGrpcMethod, TGrpcResultCode } from '@venizia/ignis-helpers';
|
|
57
56
|
|
|
58
57
|
// JSX types (re-exported from hono/jsx)
|
|
59
58
|
import type { Child, FC, PropsWithChildren } from '@venizia/ignis-helpers';
|
|
@@ -306,14 +305,6 @@ interface IConfigurable<Options extends object = any, Result = any> {
|
|
|
306
305
|
|
|
307
306
|
Interface for components that require explicit initialization. Used by helpers and components that expose a `configure()` lifecycle method.
|
|
308
307
|
|
|
309
|
-
### Domain Types
|
|
310
|
-
|
|
311
|
-
```typescript
|
|
312
|
-
type TPermissionEffect = 'allow' | 'deny';
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
Permission effect for authorization rules.
|
|
316
|
-
|
|
317
308
|
### JSX Types
|
|
318
309
|
|
|
319
310
|
Re-exported from `hono/jsx` for convenience when building JSX-based views:
|
|
@@ -355,7 +346,7 @@ class RuntimeModules {
|
|
|
355
346
|
type TRuntimeModule = TConstValue<typeof RuntimeModules>; // 'node' | 'bun'
|
|
356
347
|
```
|
|
357
348
|
|
|
358
|
-
Runtime detection utility. `detect()` returns `'bun'` if
|
|
349
|
+
Runtime detection utility. `detect()` returns `'bun'` if `typeof Bun !== 'undefined'`, `'node'` otherwise. `isBun()` and `isNode()` are convenience methods that call `detect()` internally.
|
|
359
350
|
|
|
360
351
|
#### DataTypes
|
|
361
352
|
|
|
@@ -404,7 +395,7 @@ The `HTTP` class groups all HTTP-related constants into nested objects.
|
|
|
404
395
|
|----------|-------|
|
|
405
396
|
| `HTTP.HeaderValues.APPLICATION_JSON` | `'application/json'` |
|
|
406
397
|
| `HTTP.HeaderValues.APPLICATION_FORM_URLENCODED` | `'application/x-www-form-urlencoded'` |
|
|
407
|
-
| `HTTP.HeaderValues.
|
|
398
|
+
| `HTTP.HeaderValues.APPLICATION_OCTET_STREAM` | `'application/octet-stream'` |
|
|
408
399
|
| `HTTP.HeaderValues.MULTIPART_FORM_DATA` | `'multipart/form-data'` |
|
|
409
400
|
| `HTTP.HeaderValues.TEXT_PLAIN` | `'text/plain'` |
|
|
410
401
|
|
|
@@ -483,6 +474,65 @@ type THttpMethod = ValueOf<typeof HTTP.Methods>; // 'get' | 'post' | 'put'
|
|
|
483
474
|
type THttpResultCode = ValueOf<typeof HTTP.ResultCodes>; // 0 | 1 | -199 | { Ok: 200, ... } | ...
|
|
484
475
|
```
|
|
485
476
|
|
|
477
|
+
#### GRPC
|
|
478
|
+
|
|
479
|
+
gRPC protocol constants for headers, methods, content types, and status codes.
|
|
480
|
+
|
|
481
|
+
```typescript
|
|
482
|
+
import { GRPC } from '@venizia/ignis-helpers';
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
| Property | Type | Description |
|
|
486
|
+
|----------|------|-------------|
|
|
487
|
+
| `GRPC.Methods.UNARY` | `'unary'` | Single request, single response |
|
|
488
|
+
| `GRPC.Methods.SERVER_STREAMING` | `'server_streaming'` | Single request, stream of responses |
|
|
489
|
+
| `GRPC.Methods.CLIENT_STREAMING` | `'client_streaming'` | Stream of requests, single response |
|
|
490
|
+
| `GRPC.Methods.BIDI_STREAMING` | `'bidi_streaming'` | Bidirectional streaming |
|
|
491
|
+
| `GRPC.Headers.CONTENT_TYPE` | `'content-type'` | HTTP content type header |
|
|
492
|
+
| `GRPC.Headers.TE` | `'te'` | Transfer encoding header |
|
|
493
|
+
| `GRPC.Headers.USER_AGENT` | `'user-agent'` | User agent header |
|
|
494
|
+
| `GRPC.Headers.GRPC_TIMEOUT` | `'grpc-timeout'` | gRPC timeout header |
|
|
495
|
+
| `GRPC.Headers.GRPC_ENCODING` | `'grpc-encoding'` | gRPC encoding header |
|
|
496
|
+
| `GRPC.Headers.GRPC_ACCEPT_ENCODING` | `'grpc-accept-encoding'` | gRPC accepted encodings header |
|
|
497
|
+
| `GRPC.Headers.GRPC_MESSAGE_TYPE` | `'grpc-message-type'` | gRPC message type header |
|
|
498
|
+
| `GRPC.Headers.GRPC_STATUS` | `'grpc-status'` | gRPC status code header |
|
|
499
|
+
| `GRPC.Headers.GRPC_MESSAGE` | `'grpc-message'` | gRPC error message header |
|
|
500
|
+
| `GRPC.Headers.GRPC_STATUS_DETAILS_BIN` | `'grpc-status-details-bin'` | gRPC binary status details header |
|
|
501
|
+
| `GRPC.Headers.GRPC_PREVIOUS_RPC_ATTEMPTS` | `'grpc-previous-rpc-attempts'` | gRPC previous RPC attempts header |
|
|
502
|
+
| `GRPC.Headers.GRPC_RETRY_PUSHBACK_MS` | `'grpc-retry-pushback-ms'` | gRPC retry pushback milliseconds header |
|
|
503
|
+
| `GRPC.Headers.GRPC_TRACE_BIN` | `'grpc-trace-bin'` | gRPC binary trace context header |
|
|
504
|
+
| `GRPC.Headers.GRPC_TAGS_BIN` | `'grpc-tags-bin'` | gRPC binary tags header |
|
|
505
|
+
| `GRPC.HeaderValues.GRPC` | `'application/grpc'` | Standard gRPC content type |
|
|
506
|
+
| `GRPC.HeaderValues.GRPC_PROTO` | `'application/grpc+proto'` | gRPC Protobuf content type |
|
|
507
|
+
| `GRPC.HeaderValues.GRPC_JSON` | `'application/grpc+json'` | gRPC JSON content type |
|
|
508
|
+
| `GRPC.HeaderValues.GRPC_WEB` | `'application/grpc-web'` | gRPC-Web content type |
|
|
509
|
+
| `GRPC.HeaderValues.GRPC_WEB_PROTO` | `'application/grpc-web+proto'` | gRPC-Web Protobuf content type |
|
|
510
|
+
| `GRPC.HeaderValues.GRPC_WEB_JSON` | `'application/grpc-web+json'` | gRPC-Web JSON content type |
|
|
511
|
+
| `GRPC.HeaderValues.GRPC_WEB_TEXT` | `'application/grpc-web-text'` | gRPC-Web text content type |
|
|
512
|
+
| `GRPC.ResultCodes.OK` | `0` | Success |
|
|
513
|
+
| `GRPC.ResultCodes.CANCELLED` | `1` | Operation cancelled |
|
|
514
|
+
| `GRPC.ResultCodes.UNKNOWN` | `2` | Unknown error |
|
|
515
|
+
| `GRPC.ResultCodes.INVALID_ARGUMENT` | `3` | Invalid argument |
|
|
516
|
+
| `GRPC.ResultCodes.DEADLINE_EXCEEDED` | `4` | Deadline exceeded |
|
|
517
|
+
| `GRPC.ResultCodes.NOT_FOUND` | `5` | Not found |
|
|
518
|
+
| `GRPC.ResultCodes.ALREADY_EXISTS` | `6` | Already exists |
|
|
519
|
+
| `GRPC.ResultCodes.PERMISSION_DENIED` | `7` | Permission denied |
|
|
520
|
+
| `GRPC.ResultCodes.RESOURCE_EXHAUSTED` | `8` | Resource exhausted |
|
|
521
|
+
| `GRPC.ResultCodes.FAILED_PRECONDITION` | `9` | Failed precondition |
|
|
522
|
+
| `GRPC.ResultCodes.ABORTED` | `10` | Operation aborted |
|
|
523
|
+
| `GRPC.ResultCodes.OUT_OF_RANGE` | `11` | Out of range |
|
|
524
|
+
| `GRPC.ResultCodes.UNIMPLEMENTED` | `12` | Unimplemented |
|
|
525
|
+
| `GRPC.ResultCodes.INTERNAL` | `13` | Internal server error |
|
|
526
|
+
| `GRPC.ResultCodes.UNAVAILABLE` | `14` | Service unavailable |
|
|
527
|
+
| `GRPC.ResultCodes.DATA_LOSS` | `15` | Unrecoverable data loss |
|
|
528
|
+
| `GRPC.ResultCodes.UNAUTHENTICATED` | `16` | Unauthenticated |
|
|
529
|
+
|
|
530
|
+
```typescript
|
|
531
|
+
// Derived types
|
|
532
|
+
type TGrpcMethod = ValueOf<typeof GRPC.Methods>;
|
|
533
|
+
type TGrpcResultCode = ValueOf<typeof GRPC.ResultCodes>;
|
|
534
|
+
```
|
|
535
|
+
|
|
486
536
|
#### MimeTypes
|
|
487
537
|
|
|
488
538
|
```typescript
|
|
@@ -507,6 +557,3 @@ Content type classification constants.
|
|
|
507
557
|
- **References:**
|
|
508
558
|
- [Repository Mixins](/references/base/repositories/mixins) - Uses mixin types
|
|
509
559
|
- [Utilities Index](/references/utilities/index) - Type utilities
|
|
510
|
-
|
|
511
|
-
- **Best Practices:**
|
|
512
|
-
- [Architectural Patterns](/best-practices/architectural-patterns) - TypeScript patterns
|
|
@@ -571,4 +571,4 @@ Thrown during `configure()` when a Redis client fails to reach `ready` status. C
|
|
|
571
571
|
- [Socket.IO Helper](../socket-io/) -- Socket.IO-based alternative with Node.js support
|
|
572
572
|
- [Redis Helper](../redis/) -- `RedisHelper` used for cross-instance messaging
|
|
573
573
|
- [Crypto Helper](../crypto/) -- ECDH key exchange for WebSocket encryption
|
|
574
|
-
- [WebSocket Component](/
|
|
574
|
+
- [WebSocket Component](/extensions/components/websocket/) -- Component-level lifecycle integration
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Extensions
|
|
2
|
+
|
|
3
|
+
Extensions are optional packages and built-in modules that add functionality on top of the Ignis core framework. They are organized into two categories:
|
|
4
|
+
|
|
5
|
+
## Components
|
|
6
|
+
|
|
7
|
+
Components are self-contained feature modules that plug into your application via the `this.component()` registration method. Each component encapsulates its own bindings, controllers, and configuration.
|
|
8
|
+
|
|
9
|
+
| Component | Description | Key Features |
|
|
10
|
+
| :--- | :--- | :--- |
|
|
11
|
+
| [Authentication](./components/authentication/) | Identity verification | JWT, Basic, JWKS strategies |
|
|
12
|
+
| [Authorization](./components/authorization/) | Access control | Casbin-based RBAC, per-route policies |
|
|
13
|
+
| [Health Check](./components/health-check) | Liveness & readiness | `/health`, `/health/live`, `/health/ready` |
|
|
14
|
+
| [Mail](./components/mail/) | Email delivery | Nodemailer, Mailgun, queue support |
|
|
15
|
+
| [Request Tracker](./components/request-tracker) | Request tracing | `x-request-id` header, body parsing |
|
|
16
|
+
| [Socket.IO](./components/socket-io/) | Real-time (Socket.IO) | Redis adapter, room-based messaging |
|
|
17
|
+
| [Static Asset](./components/static-asset/) | File management | Upload/download, MinIO, Disk, BunS3 |
|
|
18
|
+
| [Swagger](./components/swagger) | API docs | OpenAPI UI, Swagger UI, Scalar UI |
|
|
19
|
+
| [WebSocket](./components/websocket/) | Real-time (native) | Bun native WebSocket, encryption |
|
|
20
|
+
|
|
21
|
+
## Helpers
|
|
22
|
+
|
|
23
|
+
Helpers are standalone utility classes for infrastructure concerns. They extend `BaseHelper` for scoped logging and are typically used via dependency injection.
|
|
24
|
+
|
|
25
|
+
| Helper | Description | Peer Dependencies |
|
|
26
|
+
| :--- | :--- | :--- |
|
|
27
|
+
| [Cron](./helpers/cron/) | Scheduled tasks | `cron` |
|
|
28
|
+
| [Crypto](./helpers/crypto/) | Encryption/signing | Built-in |
|
|
29
|
+
| [Environment](./helpers/env/) | Env var management | Built-in |
|
|
30
|
+
| [Error](./helpers/error/) | Error utilities | Built-in |
|
|
31
|
+
| [Inversion](./helpers/inversion/) | DI container | Built-in |
|
|
32
|
+
| [Logger](./helpers/logger/) | Logging | `winston` |
|
|
33
|
+
| [Network](./helpers/network/) | HTTP/TCP/UDP clients | `axios` (optional) |
|
|
34
|
+
| [Kafka](./helpers/kafka/) | Kafka messaging | `@platformatic/kafka` |
|
|
35
|
+
| [Queue](./helpers/queue/) | Job queues | `bullmq`, `mqtt` (optional) |
|
|
36
|
+
| [Redis](./helpers/redis/) | Redis client | `ioredis` |
|
|
37
|
+
| [Socket.IO](./helpers/socket-io/) | Socket.IO server | `socket.io` |
|
|
38
|
+
| [Storage](./helpers/storage/) | File storage | `minio` (optional) |
|
|
39
|
+
| [Testing](./helpers/testing/) | Test utilities | Built-in |
|
|
40
|
+
| [Types](./helpers/types/) | Shared types | Built-in |
|
|
41
|
+
| [UID](./helpers/uid/) | Snowflake IDs | Built-in |
|
|
42
|
+
| [WebSocket](./helpers/websocket/) | WebSocket server | Built-in |
|
|
43
|
+
| [Worker Thread](./helpers/worker-thread/) | Worker pools | Built-in |
|
|
44
|
+
|
|
45
|
+
## See Also
|
|
46
|
+
|
|
47
|
+
- [Core API](/references/) -- Base framework abstractions
|
|
48
|
+
- [Guides](/guides/) -- Getting started and tutorials
|
|
@@ -12,24 +12,22 @@ Bootstrapping is the process of automatically discovering and loading applicatio
|
|
|
12
12
|
|
|
13
13
|
```typescript
|
|
14
14
|
export class Application extends BaseApplication {
|
|
15
|
-
|
|
16
|
-
super(configs);
|
|
17
|
-
|
|
15
|
+
preConfigure() {
|
|
18
16
|
// Manual registration - tedious and error-prone
|
|
19
17
|
this.dataSource(PostgresDataSource);
|
|
20
18
|
this.dataSource(MongoDataSource);
|
|
21
|
-
|
|
19
|
+
|
|
22
20
|
this.repository(UserRepository);
|
|
23
21
|
this.repository(ProductRepository);
|
|
24
22
|
this.repository(OrderRepository);
|
|
25
23
|
this.repository(CustomerRepository);
|
|
26
24
|
// ... 50+ more repositories
|
|
27
|
-
|
|
25
|
+
|
|
28
26
|
this.service(AuthService);
|
|
29
27
|
this.service(UserService);
|
|
30
28
|
this.service(ProductService);
|
|
31
29
|
// ... 50+ more services
|
|
32
|
-
|
|
30
|
+
|
|
33
31
|
this.controller(AuthController);
|
|
34
32
|
this.controller(UserController);
|
|
35
33
|
this.controller(ProductController);
|
|
@@ -48,7 +46,8 @@ export class Application extends BaseApplication {
|
|
|
48
46
|
|
|
49
47
|
```typescript
|
|
50
48
|
export const appConfigs: IApplicationConfigs = {
|
|
51
|
-
|
|
49
|
+
// ... other config
|
|
50
|
+
path: { base: '/', isStrict: true },
|
|
52
51
|
bootOptions: {
|
|
53
52
|
datasources: { dirs: ['datasources'] },
|
|
54
53
|
repositories: { dirs: ['repositories'] },
|
|
@@ -58,8 +57,7 @@ export const appConfigs: IApplicationConfigs = {
|
|
|
58
57
|
};
|
|
59
58
|
|
|
60
59
|
export class Application extends BaseApplication {
|
|
61
|
-
|
|
62
|
-
super(appConfigs);
|
|
60
|
+
preConfigure() {
|
|
63
61
|
// That's it! Everything auto-discovered and registered
|
|
64
62
|
}
|
|
65
63
|
}
|
|
@@ -97,6 +95,8 @@ protected override getDefaultExtensions(): string[] {
|
|
|
97
95
|
}
|
|
98
96
|
```
|
|
99
97
|
|
|
98
|
+
The `configure()` method merges user-provided options with defaults: `dirs`, `extensions`, `isNested` (defaults to `true`), and optional `glob` override.
|
|
99
|
+
|
|
100
100
|
#### Phase 2: Discover
|
|
101
101
|
|
|
102
102
|
Booters scan the filesystem for matching files:
|
|
@@ -206,7 +206,7 @@ const bootOptions: IBootOptions = {
|
|
|
206
206
|
|
|
207
207
|
## Built-in Booters
|
|
208
208
|
|
|
209
|
-
The framework provides four built-in booters
|
|
209
|
+
The framework provides four built-in booters. They are registered automatically by `BaseApplication.registerBooters()`:
|
|
210
210
|
|
|
211
211
|
### DatasourceBooter
|
|
212
212
|
|
|
@@ -215,6 +215,7 @@ The framework provides four built-in booters:
|
|
|
215
215
|
| Directories | `['datasources']` |
|
|
216
216
|
| Extensions | `['.datasource.js']` |
|
|
217
217
|
| Binding Key | `datasources.{ClassName}` |
|
|
218
|
+
| Binding Scope | **Singleton** |
|
|
218
219
|
|
|
219
220
|
**Discovers:**
|
|
220
221
|
- `datasources/postgres.datasource.js` → `PostgresDataSource`
|
|
@@ -227,6 +228,7 @@ The framework provides four built-in booters:
|
|
|
227
228
|
| Directories | `['repositories']` |
|
|
228
229
|
| Extensions | `['.repository.js']` |
|
|
229
230
|
| Binding Key | `repositories.{ClassName}` |
|
|
231
|
+
| Binding Scope | Transient |
|
|
230
232
|
|
|
231
233
|
**Discovers:**
|
|
232
234
|
- `repositories/user.repository.js` → `UserRepository`
|
|
@@ -239,6 +241,7 @@ The framework provides four built-in booters:
|
|
|
239
241
|
| Directories | `['services']` |
|
|
240
242
|
| Extensions | `['.service.js']` |
|
|
241
243
|
| Binding Key | `services.{ClassName}` |
|
|
244
|
+
| Binding Scope | Transient |
|
|
242
245
|
|
|
243
246
|
**Discovers:**
|
|
244
247
|
- `services/auth.service.js` → `AuthService`
|
|
@@ -251,6 +254,7 @@ The framework provides four built-in booters:
|
|
|
251
254
|
| Directories | `['controllers']` |
|
|
252
255
|
| Extensions | `['.controller.js']` |
|
|
253
256
|
| Binding Key | `controllers.{ClassName}` |
|
|
257
|
+
| Binding Scope | Transient |
|
|
254
258
|
|
|
255
259
|
**Discovers:**
|
|
256
260
|
- `controllers/auth.controller.js` → `AuthController`
|
|
@@ -258,7 +262,15 @@ The framework provides four built-in booters:
|
|
|
258
262
|
|
|
259
263
|
## Execution Order
|
|
260
264
|
|
|
261
|
-
|
|
265
|
+
The `Bootstrapper` orchestrates all booters. It discovers booters via `findByTag({ tag: 'booter' })` and runs each phase sequentially across all booters:
|
|
266
|
+
|
|
267
|
+
```
|
|
268
|
+
Phase: CONFIGURE → DatasourceBooter → RepositoryBooter → ServiceBooter → ControllerBooter
|
|
269
|
+
Phase: DISCOVER → DatasourceBooter → RepositoryBooter → ServiceBooter → ControllerBooter
|
|
270
|
+
Phase: LOAD → DatasourceBooter → RepositoryBooter → ServiceBooter → ControllerBooter
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
The default registration order in `BaseApplication.registerBooters()` ensures dependency order:
|
|
262
274
|
|
|
263
275
|
```
|
|
264
276
|
1. DatasourceBooter → Datasources must be available first
|
|
@@ -271,37 +283,44 @@ This ensures dependencies are available when artifacts are constructed.
|
|
|
271
283
|
|
|
272
284
|
## When Boot Runs
|
|
273
285
|
|
|
274
|
-
###
|
|
286
|
+
### Integrated Boot
|
|
275
287
|
|
|
276
|
-
Boot runs
|
|
288
|
+
Boot runs as part of `BaseApplication` when `bootOptions` is configured. `BaseApplication.registerBooters()` is called during `initialize()`:
|
|
277
289
|
|
|
278
290
|
```typescript
|
|
279
291
|
const app = new Application();
|
|
280
|
-
await app.start(); // initialize() → boot() → start
|
|
292
|
+
await app.start(); // initialize() → registerBooters() + boot() → start HTTP server
|
|
281
293
|
```
|
|
282
294
|
|
|
283
295
|
### Manual Boot
|
|
284
296
|
|
|
285
|
-
Explicitly
|
|
297
|
+
Explicitly call `boot()` on the application:
|
|
286
298
|
|
|
287
299
|
```typescript
|
|
288
300
|
const app = new Application();
|
|
289
|
-
await app.boot(
|
|
290
|
-
phases: ['configure', 'discover', 'load'],
|
|
291
|
-
booters: ['ControllerBooter', 'ServiceBooter'] // only these booters
|
|
292
|
-
});
|
|
301
|
+
const report = await app.boot();
|
|
293
302
|
```
|
|
294
303
|
|
|
295
|
-
###
|
|
304
|
+
### Using BootMixin (Alternative)
|
|
296
305
|
|
|
297
|
-
|
|
306
|
+
For custom container classes that are not `BaseApplication`, use the `BootMixin`:
|
|
298
307
|
|
|
299
308
|
```typescript
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
309
|
+
import { BootMixin } from '@venizia/ignis-boot';
|
|
310
|
+
import { Container } from '@venizia/ignis-inversion';
|
|
311
|
+
|
|
312
|
+
class MyApp extends BootMixin(Container) {
|
|
313
|
+
bootOptions = {
|
|
314
|
+
controllers: { dirs: ['controllers'] },
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const app = new MyApp();
|
|
319
|
+
await app.boot();
|
|
303
320
|
```
|
|
304
321
|
|
|
322
|
+
The `BootMixin` auto-registers all four default booters and the `Bootstrapper` in its constructor.
|
|
323
|
+
|
|
305
324
|
## File Naming Conventions
|
|
306
325
|
|
|
307
326
|
Follow these conventions for auto-discovery:
|
|
@@ -434,8 +453,8 @@ bootOptions: {
|
|
|
434
453
|
Create custom booters for new artifact types:
|
|
435
454
|
|
|
436
455
|
```typescript
|
|
437
|
-
import { BaseArtifactBooter,
|
|
438
|
-
import { inject } from '@venizia/ignis-inversion';
|
|
456
|
+
import { BaseArtifactBooter, IApplication, IBootOptions } from '@venizia/ignis-boot';
|
|
457
|
+
import { BindingKeys, inject } from '@venizia/ignis-inversion';
|
|
439
458
|
|
|
440
459
|
export class MiddlewareBooter extends BaseArtifactBooter {
|
|
441
460
|
constructor(
|
|
@@ -443,10 +462,10 @@ export class MiddlewareBooter extends BaseArtifactBooter {
|
|
|
443
462
|
@inject({ key: '@app/instance' }) private app: IApplication,
|
|
444
463
|
@inject({ key: '@app/boot-options' }) bootOptions: IBootOptions,
|
|
445
464
|
) {
|
|
446
|
-
super({
|
|
447
|
-
scope: MiddlewareBooter.name,
|
|
448
|
-
root,
|
|
449
|
-
artifactOptions: bootOptions.middlewares ?? {}
|
|
465
|
+
super({
|
|
466
|
+
scope: MiddlewareBooter.name,
|
|
467
|
+
root,
|
|
468
|
+
artifactOptions: bootOptions.middlewares ?? {}
|
|
450
469
|
});
|
|
451
470
|
}
|
|
452
471
|
|
|
@@ -460,7 +479,8 @@ export class MiddlewareBooter extends BaseArtifactBooter {
|
|
|
460
479
|
|
|
461
480
|
protected async bind(): Promise<void> {
|
|
462
481
|
for (const cls of this.loadedClasses) {
|
|
463
|
-
|
|
482
|
+
const key = BindingKeys.build({ namespace: 'middlewares', key: cls.name });
|
|
483
|
+
this.app.bind({ key }).toClass(cls).setTags('middlewares');
|
|
464
484
|
}
|
|
465
485
|
}
|
|
466
486
|
}
|
|
@@ -470,11 +490,9 @@ export class MiddlewareBooter extends BaseArtifactBooter {
|
|
|
470
490
|
|
|
471
491
|
```typescript
|
|
472
492
|
export class Application extends BaseApplication {
|
|
473
|
-
override
|
|
474
|
-
// Register custom booter
|
|
493
|
+
override preConfigure() {
|
|
494
|
+
// Register custom booter before boot runs
|
|
475
495
|
this.booter(MiddlewareBooter);
|
|
476
|
-
|
|
477
|
-
await super.initialize();
|
|
478
496
|
}
|
|
479
497
|
}
|
|
480
498
|
```
|
|
@@ -537,7 +555,7 @@ this.booter(CustomRepositoryBooter); // after datasource
|
|
|
537
555
|
|
|
538
556
|
```bash
|
|
539
557
|
# From project root
|
|
540
|
-
|
|
558
|
+
bunx glob "your-pattern/**/*.controller.js"
|
|
541
559
|
```
|
|
542
560
|
|
|
543
561
|
## Best Practices
|
|
@@ -562,7 +580,7 @@ npx glob "your-pattern/**/*.controller.js"
|
|
|
562
580
|
|
|
563
581
|
- **Related Concepts:**
|
|
564
582
|
- [Application Overview](./index) - Main application class
|
|
565
|
-
- [Controllers](/guides/core-concepts/controllers) - Auto-discovered controllers
|
|
583
|
+
- [Controllers](/guides/core-concepts/rest-controllers) - Auto-discovered controllers
|
|
566
584
|
- [Services](/guides/core-concepts/services) - Auto-discovered services
|
|
567
585
|
- [Repositories](/guides/core-concepts/persistent/repositories) - Auto-discovered repositories
|
|
568
586
|
|