@venizia/ignis-docs 0.0.6-3 → 0.0.7-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +125 -388
- package/dist/mcp-server/common/config.d.ts +0 -21
- package/dist/mcp-server/common/config.d.ts.map +1 -1
- package/dist/mcp-server/common/config.js +1 -36
- package/dist/mcp-server/common/config.js.map +1 -1
- package/dist/mcp-server/helpers/docs.helper.d.ts +0 -24
- package/dist/mcp-server/helpers/docs.helper.d.ts.map +1 -1
- package/dist/mcp-server/helpers/docs.helper.js +0 -25
- package/dist/mcp-server/helpers/docs.helper.js.map +1 -1
- package/dist/mcp-server/helpers/github.helper.d.ts +0 -13
- package/dist/mcp-server/helpers/github.helper.d.ts.map +1 -1
- package/dist/mcp-server/helpers/github.helper.js +3 -20
- package/dist/mcp-server/helpers/github.helper.js.map +1 -1
- package/dist/mcp-server/index.js +0 -20
- package/dist/mcp-server/index.js.map +1 -1
- package/dist/mcp-server/tools/base.tool.d.ts +2 -79
- package/dist/mcp-server/tools/base.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/base.tool.js +1 -38
- package/dist/mcp-server/tools/base.tool.js.map +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 +0 -9
- package/dist/mcp-server/tools/docs/get-document-content.tool.js.map +1 -1
- package/dist/mcp-server/tools/docs/get-document-metadata.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/docs/get-document-metadata.tool.js +0 -9
- package/dist/mcp-server/tools/docs/get-document-metadata.tool.js.map +1 -1
- package/dist/mcp-server/tools/docs/get-package-overview.tool.d.ts +0 -6
- package/dist/mcp-server/tools/docs/get-package-overview.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/docs/get-package-overview.tool.js +1 -24
- package/dist/mcp-server/tools/docs/get-package-overview.tool.js.map +1 -1
- package/dist/mcp-server/tools/docs/list-categories.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/docs/list-categories.tool.js +0 -9
- package/dist/mcp-server/tools/docs/list-categories.tool.js.map +1 -1
- package/dist/mcp-server/tools/docs/list-documents.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/docs/list-documents.tool.js +0 -9
- package/dist/mcp-server/tools/docs/list-documents.tool.js.map +1 -1
- package/dist/mcp-server/tools/docs/search-documents.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/docs/search-documents.tool.js +0 -9
- package/dist/mcp-server/tools/docs/search-documents.tool.js.map +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.js +0 -9
- package/dist/mcp-server/tools/github/list-project-files.tool.js.map +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 +1 -13
- package/dist/mcp-server/tools/github/search-code.tool.js.map +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.d.ts +0 -4
- package/dist/mcp-server/tools/github/verify-dependencies.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js +1 -18
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js.map +1 -1
- package/dist/mcp-server/tools/github/view-source-file.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/view-source-file.tool.js +0 -9
- package/dist/mcp-server/tools/github/view-source-file.tool.js.map +1 -1
- package/dist/mcp-server/tools/index.d.ts.map +1 -1
- package/dist/mcp-server/tools/index.js +0 -2
- package/dist/mcp-server/tools/index.js.map +1 -1
- package/package.json +1 -1
- package/wiki/best-practices/api-usage-examples.md +7 -5
- package/wiki/best-practices/code-style-standards/advanced-patterns.md +1 -1
- package/wiki/best-practices/code-style-standards/constants-configuration.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 +1 -1
- package/wiki/best-practices/common-pitfalls.md +1 -1
- package/wiki/best-practices/data-modeling.md +33 -1
- package/wiki/best-practices/error-handling.md +7 -4
- package/wiki/best-practices/performance-optimization.md +1 -1
- package/wiki/best-practices/security-guidelines.md +5 -4
- package/wiki/guides/core-concepts/components-guide.md +1 -1
- package/wiki/guides/core-concepts/controllers.md +14 -8
- package/wiki/guides/core-concepts/persistent/models.md +32 -0
- package/wiki/guides/core-concepts/services.md +2 -1
- package/wiki/guides/get-started/5-minute-quickstart.md +1 -1
- package/wiki/guides/tutorials/building-a-crud-api.md +2 -1
- package/wiki/guides/tutorials/complete-installation.md +2 -2
- package/wiki/guides/tutorials/ecommerce-api.md +3 -3
- package/wiki/guides/tutorials/realtime-chat.md +7 -6
- package/wiki/index.md +2 -1
- package/wiki/references/base/application.md +28 -0
- package/wiki/references/base/components.md +2 -1
- package/wiki/references/base/controllers.md +31 -4
- package/wiki/references/base/datasources.md +6 -2
- package/wiki/references/base/dependency-injection.md +31 -0
- package/wiki/references/base/filter-system/fields-order-pagination.md +8 -1
- package/wiki/references/base/middlewares.md +2 -1
- package/wiki/references/base/models.md +144 -2
- package/wiki/references/base/repositories/advanced.md +2 -2
- package/wiki/references/base/repositories/index.md +24 -1
- package/wiki/references/base/repositories/soft-deletable.md +213 -0
- package/wiki/references/base/services.md +2 -1
- package/wiki/references/components/authentication/api.md +525 -205
- package/wiki/references/components/authentication/errors.md +502 -105
- package/wiki/references/components/authentication/index.md +388 -75
- package/wiki/references/components/authentication/usage.md +575 -247
- package/wiki/references/components/authorization/usage.md +62 -0
- package/wiki/references/components/health-check.md +2 -1
- package/wiki/references/components/socket-io/index.md +9 -4
- package/wiki/references/components/socket-io/usage.md +1 -1
- package/wiki/references/components/static-asset/index.md +3 -5
- package/wiki/references/components/swagger.md +2 -1
- package/wiki/references/configuration/environment-variables.md +2 -1
- package/wiki/references/configuration/index.md +40 -1
- package/wiki/references/helpers/error/index.md +1 -1
- package/wiki/references/helpers/inversion/index.md +1 -1
- package/wiki/references/helpers/redis/index.md +2 -9
- package/wiki/references/quick-reference.md +3 -5
- package/wiki/references/utilities/crypto.md +2 -2
- package/wiki/references/utilities/date.md +5 -5
- package/wiki/references/utilities/index.md +3 -11
- package/wiki/references/utilities/jsx.md +4 -2
- package/wiki/references/utilities/module.md +1 -1
- package/wiki/references/utilities/parse.md +24 -4
- package/wiki/references/utilities/performance.md +2 -2
- package/wiki/references/utilities/promise.md +4 -4
- package/wiki/references/utilities/request.md +2 -2
- package/wiki/references/utilities/schema.md +17 -8
|
@@ -689,6 +689,68 @@ const customRole = AuthorizationRole.build({ name: 'editor', priority: 100, deli
|
|
|
689
689
|
customRole.identifier; // '100-editor'
|
|
690
690
|
```
|
|
691
691
|
|
|
692
|
+
## Model-Based Resource References
|
|
693
|
+
|
|
694
|
+
Instead of hardcoding resource strings, use `AUTHORIZATION_SUBJECT` from your model classes. When a model declares `authorize.principal` in `@model` settings, the decorator auto-populates `AUTHORIZATION_SUBJECT`:
|
|
695
|
+
|
|
696
|
+
```typescript
|
|
697
|
+
import { BaseEntity, model, generateIdColumnDefs } from '@venizia/ignis';
|
|
698
|
+
import { pgTable, text } from 'drizzle-orm/pg-core';
|
|
699
|
+
|
|
700
|
+
@model({
|
|
701
|
+
type: 'entity',
|
|
702
|
+
settings: {
|
|
703
|
+
authorize: { principal: 'article' },
|
|
704
|
+
},
|
|
705
|
+
})
|
|
706
|
+
export class Article extends BaseEntity<typeof Article.schema> {
|
|
707
|
+
static override schema = pgTable('Article', {
|
|
708
|
+
...generateIdColumnDefs({ id: { dataType: 'string' } }),
|
|
709
|
+
title: text('title').notNull(),
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
// Article.AUTHORIZATION_SUBJECT === 'article'
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
Use it in route configs for type-safe, refactor-friendly resource references:
|
|
717
|
+
|
|
718
|
+
```typescript
|
|
719
|
+
import { AuthorizationActions } from '@venizia/ignis';
|
|
720
|
+
import { Article } from '../models/entities/article.model';
|
|
721
|
+
|
|
722
|
+
// Instead of: resource: 'article'
|
|
723
|
+
authorize: {
|
|
724
|
+
action: AuthorizationActions.READ,
|
|
725
|
+
resource: Article.AUTHORIZATION_SUBJECT,
|
|
726
|
+
}
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
### Querying All Principals
|
|
730
|
+
|
|
731
|
+
Use `MetadataRegistry` to retrieve all registered authorization principals at runtime:
|
|
732
|
+
|
|
733
|
+
```typescript
|
|
734
|
+
import { MetadataRegistry } from '@venizia/ignis';
|
|
735
|
+
|
|
736
|
+
const registry = MetadataRegistry.getInstance();
|
|
737
|
+
|
|
738
|
+
// Flat array of principal names — ideal for Casbin policy setup
|
|
739
|
+
const principals = registry.getAuthorizeModelPrincipals({ format: 'array' });
|
|
740
|
+
// ['article', 'user', 'configuration']
|
|
741
|
+
|
|
742
|
+
// Record of model name → principal
|
|
743
|
+
const principalMap = registry.getAuthorizeModelPrincipals({ format: 'record' });
|
|
744
|
+
// { Article: 'article', User: 'user', Configuration: 'configuration' }
|
|
745
|
+
|
|
746
|
+
// Full settings with model registry entries (framework-level)
|
|
747
|
+
const settings = registry.getAuthorizeModelSettings({ format: 'array' });
|
|
748
|
+
// [{ name: 'Article', authorize: { principal: 'article' }, entry: IModelRegistryEntry }]
|
|
749
|
+
```
|
|
750
|
+
|
|
751
|
+
> [!TIP]
|
|
752
|
+
> Defining `authorize.principal` on the model makes the model the single source of truth for its authorization subject. This eliminates string duplication across route configs and policy setup.
|
|
753
|
+
|
|
692
754
|
## See Also
|
|
693
755
|
|
|
694
756
|
- [Setup & Configuration](./) -- Binding keys, options interfaces, and initial setup
|
|
@@ -214,8 +214,9 @@ The controller uses `this.definitions = RouteConfigs` to store route configurati
|
|
|
214
214
|
```typescript
|
|
215
215
|
import {
|
|
216
216
|
BaseController, IControllerOptions, TRouteContext,
|
|
217
|
-
api, jsonContent, jsonResponse,
|
|
217
|
+
api, jsonContent, jsonResponse, z,
|
|
218
218
|
} from '@venizia/ignis';
|
|
219
|
+
import { HTTP } from '@venizia/ignis-helpers';
|
|
219
220
|
|
|
220
221
|
const RouteConfigs = {
|
|
221
222
|
ROOT: {
|
|
@@ -18,9 +18,12 @@
|
|
|
18
18
|
import {
|
|
19
19
|
SocketIOComponent,
|
|
20
20
|
SocketIOBindingKeys,
|
|
21
|
+
} from '@venizia/ignis';
|
|
22
|
+
|
|
23
|
+
import {
|
|
21
24
|
SocketIOServerHelper,
|
|
22
25
|
RedisHelper,
|
|
23
|
-
} from '@venizia/ignis';
|
|
26
|
+
} from '@venizia/ignis-helpers';
|
|
24
27
|
|
|
25
28
|
import {
|
|
26
29
|
SocketIOClientHelper,
|
|
@@ -70,11 +73,13 @@ import {
|
|
|
70
73
|
BaseApplication,
|
|
71
74
|
SocketIOComponent,
|
|
72
75
|
SocketIOBindingKeys,
|
|
73
|
-
|
|
76
|
+
ValueOrPromise,
|
|
77
|
+
} from '@venizia/ignis';
|
|
78
|
+
import { RedisHelper } from '@venizia/ignis-helpers';
|
|
79
|
+
import type {
|
|
74
80
|
TSocketIOAuthenticateFn,
|
|
75
81
|
TSocketIOValidateRoomFn,
|
|
76
82
|
TSocketIOClientConnectedFn,
|
|
77
|
-
ValueOrPromise,
|
|
78
83
|
} from '@venizia/ignis';
|
|
79
84
|
|
|
80
85
|
export class Application extends BaseApplication {
|
|
@@ -146,7 +151,7 @@ The `RedisHelper` is created with `autoConnect: false` because the server helper
|
|
|
146
151
|
You can use either `RedisHelper` (single Redis instance) or `RedisClusterHelper` (Redis Cluster mode). Both extend `DefaultRedisHelper`, which is the type the component validates against:
|
|
147
152
|
|
|
148
153
|
```typescript
|
|
149
|
-
import { RedisClusterHelper } from '@venizia/ignis';
|
|
154
|
+
import { RedisClusterHelper } from '@venizia/ignis-helpers';
|
|
150
155
|
|
|
151
156
|
// For Redis Cluster deployments
|
|
152
157
|
const redisHelper = new RedisClusterHelper({
|
|
@@ -13,10 +13,10 @@ import {
|
|
|
13
13
|
BaseService,
|
|
14
14
|
inject,
|
|
15
15
|
SocketIOBindingKeys,
|
|
16
|
-
SocketIOServerHelper,
|
|
17
16
|
CoreBindings,
|
|
18
17
|
BaseApplication,
|
|
19
18
|
} from '@venizia/ignis';
|
|
19
|
+
import { SocketIOServerHelper } from '@venizia/ignis-helpers';
|
|
20
20
|
|
|
21
21
|
export class NotificationService extends BaseService {
|
|
22
22
|
// Lazy getter pattern -- helper is bound AFTER server starts
|
|
@@ -17,9 +17,8 @@ import {
|
|
|
17
17
|
StaticAssetComponent,
|
|
18
18
|
StaticAssetComponentBindingKeys,
|
|
19
19
|
StaticAssetStorageTypes,
|
|
20
|
-
DiskHelper,
|
|
21
|
-
MinioHelper,
|
|
22
20
|
} from '@venizia/ignis';
|
|
21
|
+
import { DiskHelper, MinioHelper } from '@venizia/ignis-helpers';
|
|
23
22
|
import type {
|
|
24
23
|
TStaticAssetsComponentOptions,
|
|
25
24
|
TMetaLinkConfig,
|
|
@@ -46,12 +45,11 @@ import type {
|
|
|
46
45
|
```typescript
|
|
47
46
|
import {
|
|
48
47
|
BaseApplication,
|
|
49
|
-
DiskHelper,
|
|
50
|
-
MinioHelper,
|
|
51
48
|
StaticAssetComponentBindingKeys,
|
|
52
49
|
StaticAssetStorageTypes,
|
|
53
|
-
TStaticAssetsComponentOptions,
|
|
54
50
|
} from '@venizia/ignis';
|
|
51
|
+
import { DiskHelper, MinioHelper } from '@venizia/ignis-helpers';
|
|
52
|
+
import type { TStaticAssetsComponentOptions } from '@venizia/ignis';
|
|
55
53
|
|
|
56
54
|
export class Application extends BaseApplication {
|
|
57
55
|
preConfigure() {
|
|
@@ -67,7 +67,8 @@ To get the most out of the documentation, define your routes with `zod` schemas:
|
|
|
67
67
|
```typescript
|
|
68
68
|
// src/controllers/hello.controller.ts
|
|
69
69
|
import { z } from '@hono/zod-openapi';
|
|
70
|
-
import { BaseController, controller,
|
|
70
|
+
import { BaseController, controller, jsonContent, ValueOrPromise } from '@venizia/ignis';
|
|
71
|
+
import { HTTP } from '@venizia/ignis-helpers';
|
|
71
72
|
|
|
72
73
|
@controller({ path: '/hello' })
|
|
73
74
|
export class HelloController extends BaseController {
|
|
@@ -22,7 +22,8 @@ POSTGRES_HOST=localhost
|
|
|
22
22
|
const host = process.env.APP_ENV_POSTGRES_HOST;
|
|
23
23
|
|
|
24
24
|
// Using applicationEnvironment helper (recommended)
|
|
25
|
-
import { applicationEnvironment
|
|
25
|
+
import { applicationEnvironment } from '@venizia/ignis-helpers';
|
|
26
|
+
import { EnvironmentKeys } from '@venizia/ignis';
|
|
26
27
|
const host = applicationEnvironment.get<string>(EnvironmentKeys.APP_ENV_POSTGRES_HOST);
|
|
27
28
|
```
|
|
28
29
|
|
|
@@ -52,7 +52,8 @@ APP_ENV_POSTGRES_DATABASE=my_database
|
|
|
52
52
|
const host = process.env.APP_ENV_POSTGRES_HOST;
|
|
53
53
|
|
|
54
54
|
// 2. Using helper (recommended)
|
|
55
|
-
import { applicationEnvironment
|
|
55
|
+
import { applicationEnvironment } from '@venizia/ignis-helpers';
|
|
56
|
+
import { EnvironmentKeys } from '@venizia/ignis';
|
|
56
57
|
const host = applicationEnvironment.get<string>(EnvironmentKeys.APP_ENV_POSTGRES_HOST);
|
|
57
58
|
```
|
|
58
59
|
|
|
@@ -71,3 +72,41 @@ project/
|
|
|
71
72
|
Ignis validates required variables on startup. Missing values cause clear error messages.
|
|
72
73
|
|
|
73
74
|
> **Related:** [Environment Variables Reference](./environment-variables.md) | [DataSources Guide](../../guides/core-concepts/persistent/datasources)
|
|
75
|
+
|
|
76
|
+
## EnvironmentKeys Class
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { EnvironmentKeys } from '@venizia/ignis';
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
| Constant | Description |
|
|
83
|
+
|----------|-------------|
|
|
84
|
+
| `APP_ENV_APPLICATION_NAME` | Application display name |
|
|
85
|
+
| `APP_ENV_APPLICATION_TIMEZONE` | Application timezone (e.g., 'Asia/Ho_Chi_Minh') |
|
|
86
|
+
| `APP_ENV_APPLICATION_SECRET` | Application-wide secret key |
|
|
87
|
+
| `APP_ENV_JWT_SECRET` | JWT signing secret |
|
|
88
|
+
| `APP_ENV_JWT_EXPIRES_IN` | JWT token expiration |
|
|
89
|
+
| `APP_ENV_LOGGER_FOLDER_PATH` | Log file output directory |
|
|
90
|
+
| `APP_ENV_APPLICATION_ROLES` | Application role definitions |
|
|
91
|
+
| `APP_ENV_APPLICATION_DS_MIGRATION` | DataSource name for migrations |
|
|
92
|
+
| `APP_ENV_APPLICATION_DS_AUTHORIZE` | DataSource name for authorization |
|
|
93
|
+
| `APP_ENV_APPLICATION_DS_OAUTH2` | DataSource name for OAuth2 |
|
|
94
|
+
| `APP_ENV_OAUTH2_VIEW_FOLDER` | OAuth2 view templates folder |
|
|
95
|
+
| `APP_ENV_SERVER_HOST` | HTTP server host (e.g., '0.0.0.0') |
|
|
96
|
+
| `APP_ENV_SERVER_PORT` | HTTP server port (e.g., 3000) |
|
|
97
|
+
| `APP_ENV_SERVER_BASE_PATH` | Base URL path prefix |
|
|
98
|
+
| `APP_ENV_DATASOURCE_NAME` | Default datasource name |
|
|
99
|
+
| `APP_ENV_POSTGRES_HOST` | PostgreSQL host |
|
|
100
|
+
| `APP_ENV_POSTGRES_PORT` | PostgreSQL port |
|
|
101
|
+
| `APP_ENV_POSTGRES_USERNAME` | PostgreSQL username |
|
|
102
|
+
| `APP_ENV_POSTGRES_PASSWORD` | PostgreSQL password |
|
|
103
|
+
| `APP_ENV_POSTGRES_DATABASE` | PostgreSQL database name |
|
|
104
|
+
|
|
105
|
+
Usage:
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
import { applicationEnvironment } from '@venizia/ignis-helpers';
|
|
109
|
+
import { EnvironmentKeys } from '@venizia/ignis';
|
|
110
|
+
|
|
111
|
+
const dbHost = applicationEnvironment.get<string>(EnvironmentKeys.APP_ENV_POSTGRES_HOST);
|
|
112
|
+
```
|
|
@@ -20,7 +20,7 @@ import type { TError } from '@venizia/ignis-helpers';
|
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
> [!NOTE]
|
|
23
|
-
> `ApplicationError`, `getError`, `ErrorSchema`, and `TError` are also available from `@venizia/ignis-inversion
|
|
23
|
+
> `ApplicationError`, `getError`, `ErrorSchema`, and `TError` are also available from `@venizia/ignis-inversion`. Their types are re-exported through `@venizia/ignis` (via `export type *`), but for runtime usage, import directly from `@venizia/ignis-helpers` or `@venizia/ignis-inversion`.
|
|
24
24
|
|
|
25
25
|
## Creating an Instance
|
|
26
26
|
|
|
@@ -50,7 +50,7 @@ import type {
|
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
> [!NOTE]
|
|
53
|
-
> The framework package `@venizia/ignis` re-exports
|
|
53
|
+
> The framework package `@venizia/ignis` re-exports DI-specific symbols (`Binding`, `BindingKeys`, `BindingScopes`, `BindingValueTypes`, `IProvider`, `isClass`, `isClassProvider`, `isClassConstructor`, `TBindingScope`, `TBindingValueType`, `IBindingTag`) from `@venizia/ignis-inversion` and adds higher-level helpers (`app.controller()`, `app.service()`, etc.). All types from inversion are also available via type-only re-exports.
|
|
54
54
|
|
|
55
55
|
## Creating an Instance
|
|
56
56
|
|
|
@@ -20,21 +20,14 @@ import {
|
|
|
20
20
|
RedisClusterHelper,
|
|
21
21
|
} from '@venizia/ignis-helpers';
|
|
22
22
|
|
|
23
|
-
//
|
|
24
|
-
import {
|
|
25
|
-
DefaultRedisHelper,
|
|
26
|
-
RedisHelper,
|
|
27
|
-
RedisClusterHelper,
|
|
28
|
-
} from '@venizia/ignis';
|
|
29
|
-
|
|
30
|
-
// Types
|
|
23
|
+
// Types are also available from the core package (via type-only re-export)
|
|
31
24
|
import type {
|
|
32
25
|
IRedisHelperOptions,
|
|
33
26
|
IRedisClusterHelperOptions,
|
|
34
27
|
IRedisHelperCallbacks,
|
|
35
28
|
IRedisHelperProps,
|
|
36
29
|
IRedisClusterHelperProps,
|
|
37
|
-
} from '@venizia/ignis-helpers';
|
|
30
|
+
} from '@venizia/ignis-helpers'; // or from '@venizia/ignis'
|
|
38
31
|
```
|
|
39
32
|
|
|
40
33
|
## Creating an Instance
|
|
@@ -118,6 +118,7 @@ class User extends BaseEntity {
|
|
|
118
118
|
**Key Properties:**
|
|
119
119
|
- `static tableName` - Database table name
|
|
120
120
|
- `static schema` - Drizzle schema definition
|
|
121
|
+
- `static AUTHORIZATION_SUBJECT` - Authorization principal (auto-set from `@model` settings `authorize.principal`)
|
|
121
122
|
|
|
122
123
|
|
|
123
124
|
## Route Decorators
|
|
@@ -396,11 +397,8 @@ import { MinIOHelper } from '@venizia/ignis-helpers/minio';
|
|
|
396
397
|
### Dependency Injection
|
|
397
398
|
|
|
398
399
|
```typescript
|
|
399
|
-
import {
|
|
400
|
-
|
|
401
|
-
BindingKeys,
|
|
402
|
-
BindingNamespaces,
|
|
403
|
-
} from '@venizia/ignis-inversion';
|
|
400
|
+
import { Container, BindingKeys } from '@venizia/ignis-inversion';
|
|
401
|
+
import { BindingNamespaces } from '@venizia/ignis';
|
|
404
402
|
```
|
|
405
403
|
|
|
406
404
|
|
|
@@ -19,7 +19,7 @@ The `hash` function allows you to create a hash of a string using either `SHA256
|
|
|
19
19
|
**MD5 Hash**
|
|
20
20
|
|
|
21
21
|
```typescript
|
|
22
|
-
import { hash } from '@venizia/ignis';
|
|
22
|
+
import { hash } from '@venizia/ignis-helpers';
|
|
23
23
|
|
|
24
24
|
const md5Hash = hash('some text', { algorithm: 'MD5', outputType: 'hex' });
|
|
25
25
|
// => '552e21cd4cd99186789c2370c7482837'
|
|
@@ -28,7 +28,7 @@ const md5Hash = hash('some text', { algorithm: 'MD5', outputType: 'hex' });
|
|
|
28
28
|
**SHA256 HMAC**
|
|
29
29
|
|
|
30
30
|
```typescript
|
|
31
|
-
import { hash } from '@venizia/ignis';
|
|
31
|
+
import { hash } from '@venizia/ignis-helpers';
|
|
32
32
|
|
|
33
33
|
const sha256Hash = hash('some text', {
|
|
34
34
|
algorithm: 'SHA256',
|
|
@@ -7,7 +7,7 @@ The Date utility provides a set of functions for date and time manipulation, bui
|
|
|
7
7
|
The `dayjs` object is re-exported, so you can use it directly for any date and time operations. It is pre-configured with the following plugins: `CustomParseFormat`, `UTC`, `Timezone`, `Weekday`, and `IsoWeek`.
|
|
8
8
|
|
|
9
9
|
```typescript
|
|
10
|
-
import { dayjs } from '@venizia/ignis';
|
|
10
|
+
import { dayjs } from '@venizia/ignis-helpers';
|
|
11
11
|
|
|
12
12
|
// Get the current date and time
|
|
13
13
|
const now = dayjs();
|
|
@@ -21,7 +21,7 @@ const formatted = now.format('YYYY-MM-DD HH:mm:ss');
|
|
|
21
21
|
The `sleep` function pauses execution for a specified number of milliseconds.
|
|
22
22
|
|
|
23
23
|
```typescript
|
|
24
|
-
import { sleep } from '@venizia/ignis';
|
|
24
|
+
import { sleep } from '@venizia/ignis-helpers';
|
|
25
25
|
|
|
26
26
|
async function myAsyncFunction() {
|
|
27
27
|
console.log('Start');
|
|
@@ -37,7 +37,7 @@ async function myAsyncFunction() {
|
|
|
37
37
|
- **`getNextWeekday(opts)`**: Returns the next weekday from a given date.
|
|
38
38
|
|
|
39
39
|
```typescript
|
|
40
|
-
import { isWeekday, getPreviousWeekday } from '@venizia/ignis';
|
|
40
|
+
import { isWeekday, getPreviousWeekday } from '@venizia/ignis-helpers';
|
|
41
41
|
|
|
42
42
|
const isTodayWeekday = isWeekday(new Date());
|
|
43
43
|
|
|
@@ -49,7 +49,7 @@ const lastBusinessDay = getPreviousWeekday();
|
|
|
49
49
|
The `getDateTz` function allows you to get a `dayjs` object in a specific timezone, with an optional offset.
|
|
50
50
|
|
|
51
51
|
```typescript
|
|
52
|
-
import { getDateTz } from '@venizia/ignis';
|
|
52
|
+
import { getDateTz } from '@venizia/ignis-helpers';
|
|
53
53
|
|
|
54
54
|
const tokyoTime = getDateTz({
|
|
55
55
|
date: '2023-10-27T10:00:00Z',
|
|
@@ -62,7 +62,7 @@ const tokyoTime = getDateTz({
|
|
|
62
62
|
The `hrTime` function returns a high-resolution time measurement in seconds, useful for performance benchmarking.
|
|
63
63
|
|
|
64
64
|
```typescript
|
|
65
|
-
import { hrTime } from '@venizia/ignis';
|
|
65
|
+
import { hrTime } from '@venizia/ignis-helpers';
|
|
66
66
|
|
|
67
67
|
const start = hrTime();
|
|
68
68
|
// ... some long-running operation
|
|
@@ -43,19 +43,11 @@ Pure, standalone functions providing common, reusable logic for the Ignis framew
|
|
|
43
43
|
|
|
44
44
|
## Usage Pattern
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
Utilities are imported from `@venizia/ignis` (schema, JSX, and status helpers) or `@venizia/ignis-helpers` (runtime utilities):
|
|
47
47
|
|
|
48
48
|
```typescript
|
|
49
|
-
import {
|
|
50
|
-
|
|
51
|
-
compare,
|
|
52
|
-
formatDate,
|
|
53
|
-
toBoolean,
|
|
54
|
-
jsonContent,
|
|
55
|
-
jsonResponse,
|
|
56
|
-
htmlResponse,
|
|
57
|
-
Statuses,
|
|
58
|
-
} from '@venizia/ignis';
|
|
49
|
+
import { jsonContent, jsonResponse, htmlResponse, Statuses } from '@venizia/ignis';
|
|
50
|
+
import { hash, compare, formatDate, toBoolean } from '@venizia/ignis-helpers';
|
|
59
51
|
|
|
60
52
|
// Crypto
|
|
61
53
|
const hashed = await hash({ value: 'password123' });
|
|
@@ -184,7 +184,8 @@ export class PageController extends BaseController {
|
|
|
184
184
|
### HTML Email Preview
|
|
185
185
|
|
|
186
186
|
```typescript
|
|
187
|
-
import { BaseController, get, htmlResponse, TRouteContext,
|
|
187
|
+
import { BaseController, get, htmlResponse, TRouteContext, z } from '@venizia/ignis';
|
|
188
|
+
import { HTTP } from '@venizia/ignis-helpers';
|
|
188
189
|
|
|
189
190
|
const EmailRoutes = {
|
|
190
191
|
PREVIEW: {
|
|
@@ -222,7 +223,8 @@ export class EmailController extends BaseController {
|
|
|
222
223
|
### Documentation Page
|
|
223
224
|
|
|
224
225
|
```typescript
|
|
225
|
-
import { BaseController, get, htmlResponse, TRouteContext,
|
|
226
|
+
import { BaseController, get, htmlResponse, TRouteContext, z } from '@venizia/ignis';
|
|
227
|
+
import { HTTP } from '@venizia/ignis-helpers';
|
|
226
228
|
|
|
227
229
|
const DocsRoutes = {
|
|
228
230
|
GET_SECTION: {
|
|
@@ -17,7 +17,7 @@ The `validateModule` function checks if a list of modules can be resolved. If a
|
|
|
17
17
|
The `SwaggerComponent` uses `validateModule` to ensure that `@hono/swagger-ui` is installed before attempting to use it.
|
|
18
18
|
|
|
19
19
|
```typescript
|
|
20
|
-
import { validateModule } from '@venizia/ignis';
|
|
20
|
+
import { validateModule } from '@venizia/ignis-helpers';
|
|
21
21
|
|
|
22
22
|
export class SwaggerComponent extends BaseComponent {
|
|
23
23
|
// ...
|
|
@@ -15,7 +15,7 @@ The Parse utility provides a collection of functions for data type checking, con
|
|
|
15
15
|
- **`toStringDecimal(input, digit = 2)`**: Formats a number to a string with a specified number of decimal places, using locale-specific formatting.
|
|
16
16
|
|
|
17
17
|
```typescript
|
|
18
|
-
import { int, float, toBoolean } from '@venizia/ignis';
|
|
18
|
+
import { int, float, toBoolean } from '@venizia/ignis-helpers';
|
|
19
19
|
|
|
20
20
|
const myInt = int('1,000'); // => 1000
|
|
21
21
|
const myFloat = float('1,234.567', 2); // => 1234.57
|
|
@@ -28,7 +28,7 @@ const myBool = toBoolean('true'); // => true
|
|
|
28
28
|
- **`keysToCamel(object)`**: Recursively converts all keys in an object (and nested objects) to camelCase.
|
|
29
29
|
|
|
30
30
|
```typescript
|
|
31
|
-
import { toCamel, keysToCamel } from '@venizia/ignis';
|
|
31
|
+
import { toCamel, keysToCamel } from '@venizia/ignis-helpers';
|
|
32
32
|
|
|
33
33
|
const camelString = toCamel('my-snake_case-string');
|
|
34
34
|
// => 'mySnakeCaseString'
|
|
@@ -37,13 +37,33 @@ const camelObject = keysToCamel({ 'first-name': 'John', 'last_name': 'Doe' });
|
|
|
37
37
|
// => { firstName: 'John', lastName: 'Doe' }
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
## Number Parsing
|
|
41
|
+
|
|
42
|
+
- **`getNumberValue(input, opts?)`**: Parses a string to a number with locale support (US or EU format).
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { getNumberValue } from '@venizia/ignis-helpers';
|
|
46
|
+
|
|
47
|
+
// US format (default) — comma is thousands separator
|
|
48
|
+
getNumberValue('1,234.56', { method: 'float' }); // => 1234.56
|
|
49
|
+
getNumberValue('1,234', { method: 'int' }); // => 1234
|
|
50
|
+
|
|
51
|
+
// EU format — dot is thousands separator, comma is decimal
|
|
52
|
+
getNumberValue('1.234,56', { method: 'float', locale: 'eu' }); // => 1234.56
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
| Option | Type | Default | Description |
|
|
56
|
+
|--------|------|---------|-------------|
|
|
57
|
+
| `method` | `'int' \| 'float'` | `'int'` | Parse as integer or float |
|
|
58
|
+
| `locale` | `'us' \| 'eu'` | `'us'` | Number format locale |
|
|
59
|
+
|
|
40
60
|
## Array Transformation
|
|
41
61
|
|
|
42
62
|
- **`parseArrayToRecordWithKey(opts)`**: Transforms an array of objects into a record (plain object), using a specified property of the objects as keys.
|
|
43
63
|
- **`parseArrayToMapWithKey(arr, keyMap)`**: Transforms an array of objects into a `Map`, using a specified property of the objects as keys. This is useful for efficient lookups.
|
|
44
64
|
|
|
45
65
|
```typescript
|
|
46
|
-
import { parseArrayToMapWithKey } from '@venizia/ignis';
|
|
66
|
+
import { parseArrayToMapWithKey } from '@venizia/ignis-helpers';
|
|
47
67
|
|
|
48
68
|
const users = [
|
|
49
69
|
{ id: 1, name: 'Alice' },
|
|
@@ -62,7 +82,7 @@ const user = usersMap.get(1);
|
|
|
62
82
|
- **`getUID()`**: Generates a simple, short unique ID string.
|
|
63
83
|
|
|
64
84
|
```typescript
|
|
65
|
-
import { getUID } from '@venizia/ignis';
|
|
85
|
+
import { getUID } from '@venizia/ignis-helpers';
|
|
66
86
|
|
|
67
87
|
const uniqueId = getUID(); // => e.g., 'A1B2C3D4'
|
|
68
88
|
```
|
|
@@ -20,7 +20,7 @@ The `BaseApplication` uses this utility to measure the time taken to register co
|
|
|
20
20
|
|
|
21
21
|
```typescript
|
|
22
22
|
// Inside BaseApplication class
|
|
23
|
-
import { executeWithPerformanceMeasure } from '@venizia/ignis';
|
|
23
|
+
import { executeWithPerformanceMeasure } from '@venizia/ignis-helpers';
|
|
24
24
|
|
|
25
25
|
// ...
|
|
26
26
|
|
|
@@ -53,7 +53,7 @@ For more granular measurements, you can use the lower-level functions:
|
|
|
53
53
|
### Example
|
|
54
54
|
|
|
55
55
|
```typescript
|
|
56
|
-
import { getPerformanceCheckpoint, getExecutedPerformance } from '@venizia/ignis';
|
|
56
|
+
import { getPerformanceCheckpoint, getExecutedPerformance } from '@venizia/ignis-helpers';
|
|
57
57
|
|
|
58
58
|
const start = getPerformanceCheckpoint();
|
|
59
59
|
|
|
@@ -16,7 +16,7 @@ This function executes an array of asynchronous tasks concurrently, but with a s
|
|
|
16
16
|
### Example
|
|
17
17
|
|
|
18
18
|
```typescript
|
|
19
|
-
import { executePromiseWithLimit, sleep } from '@venizia/ignis';
|
|
19
|
+
import { executePromiseWithLimit, sleep } from '@venizia/ignis-helpers';
|
|
20
20
|
|
|
21
21
|
const tasks = [
|
|
22
22
|
() => sleep(1000).then(() => 'Task 1 done'),
|
|
@@ -43,7 +43,7 @@ console.log('All tasks finished:', results);
|
|
|
43
43
|
A type guard function to check if a given value is a Promise-like object (i.e., it has a `then` method).
|
|
44
44
|
|
|
45
45
|
```typescript
|
|
46
|
-
import { isPromiseLike } from '@venizia/ignis';
|
|
46
|
+
import { isPromiseLike } from '@venizia/ignis-helpers';
|
|
47
47
|
|
|
48
48
|
const a = Promise.resolve(1);
|
|
49
49
|
const b = 2;
|
|
@@ -62,7 +62,7 @@ if (isPromiseLike(b)) {
|
|
|
62
62
|
This function applies a transformation function to a value that might be a direct value or a Promise.
|
|
63
63
|
|
|
64
64
|
```typescript
|
|
65
|
-
import { transformValueOrPromise, isPromiseLike } from '@venizia/ignis';
|
|
65
|
+
import { transformValueOrPromise, isPromiseLike } from '@venizia/ignis-helpers';
|
|
66
66
|
|
|
67
67
|
const double = (n: number) => n * 2;
|
|
68
68
|
|
|
@@ -75,7 +75,7 @@ const result2 = await transformValueOrPromise(Promise.resolve(5), double); // =>
|
|
|
75
75
|
Safely retrieves a deeply nested property from an object using a dot-separated path string. It throws an error if any part of the path is null or undefined.
|
|
76
76
|
|
|
77
77
|
```typescript
|
|
78
|
-
import { getDeepProperty } from '@venizia/ignis';
|
|
78
|
+
import { getDeepProperty } from '@venizia/ignis-helpers';
|
|
79
79
|
|
|
80
80
|
const obj = { a: { b: { c: 'hello' } } };
|
|
81
81
|
|
|
@@ -31,8 +31,8 @@ The function returns a `Promise` that resolves to an array of `IParsedFile` obje
|
|
|
31
31
|
Here is an example of how to use `parseMultipartBody` in a controller to handle a file upload.
|
|
32
32
|
|
|
33
33
|
```typescript
|
|
34
|
-
import { BaseController, controller
|
|
35
|
-
import { parseMultipartBody } from '@venizia/ignis';
|
|
34
|
+
import { BaseController, controller } from '@venizia/ignis';
|
|
35
|
+
import { parseMultipartBody, HTTP } from '@venizia/ignis-helpers';
|
|
36
36
|
|
|
37
37
|
@controller({ path: '/files' })
|
|
38
38
|
export class FileController extends BaseController {
|
|
@@ -60,28 +60,37 @@ const schema = z.object({
|
|
|
60
60
|
|
|
61
61
|
## Predefined Schemas
|
|
62
62
|
|
|
63
|
-
The utility also provides several predefined schemas for common use cases.
|
|
64
|
-
|
|
65
63
|
- **`AnyObjectSchema`**: A flexible schema for any object (`z.object().catchall(z.any())`).
|
|
66
|
-
- **`IdParamsSchema`**: A schema for a numeric path parameter named `id`.
|
|
67
|
-
- **`UUIDParamsSchema`**: A schema for a UUID path parameter named `id`.
|
|
68
64
|
|
|
69
|
-
###
|
|
65
|
+
### Type Utilities
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { TAnyObjectSchema, TInferSchema } from '@venizia/ignis';
|
|
69
|
+
|
|
70
|
+
// TAnyObjectSchema = z.ZodObject<z.ZodRawShape>
|
|
71
|
+
// TInferSchema<T> = z.infer<T> — infer TypeScript type from a Zod schema
|
|
72
|
+
|
|
73
|
+
type UserType = TInferSchema<typeof UserSchema>;
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Custom ID Params
|
|
77
|
+
|
|
78
|
+
Use the `idParamsSchema()` helper (from controller utilities) to generate path parameter schemas:
|
|
70
79
|
|
|
71
80
|
```typescript
|
|
72
|
-
import {
|
|
81
|
+
import { idParamsSchema } from '@venizia/ignis';
|
|
73
82
|
|
|
74
83
|
this.defineRoute({
|
|
75
84
|
configs: {
|
|
76
85
|
path: '/{id}',
|
|
77
86
|
method: 'get',
|
|
78
87
|
request: {
|
|
79
|
-
params:
|
|
88
|
+
params: idParamsSchema({ idType: 'number' }),
|
|
80
89
|
},
|
|
81
90
|
// ...
|
|
82
91
|
},
|
|
83
92
|
handler: (c) => {
|
|
84
|
-
const { id } = c.req.valid('param');
|
|
93
|
+
const { id } = c.req.valid('param');
|
|
85
94
|
// ...
|
|
86
95
|
},
|
|
87
96
|
});
|