@venizia/ignis-docs 0.2.0 → 0.2.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 +14 -14
- package/content/best-practices/api-usage-examples.md +39 -19
- package/content/best-practices/architectural-patterns.md +22 -11
- package/content/best-practices/architecture-decisions.md +29 -16
- package/content/best-practices/code-style-standards/advanced-patterns.md +43 -31
- package/content/best-practices/code-style-standards/constants-configuration.md +19 -4
- package/content/best-practices/code-style-standards/control-flow.md +33 -1
- package/content/best-practices/code-style-standards/documentation.md +28 -8
- package/content/best-practices/code-style-standards/function-patterns.md +15 -4
- package/content/best-practices/code-style-standards/index.md +7 -2
- package/content/best-practices/code-style-standards/naming-conventions.md +26 -2
- package/content/best-practices/code-style-standards/route-definitions.md +9 -5
- package/content/best-practices/code-style-standards/tooling.md +14 -1
- package/content/best-practices/code-style-standards/type-safety.md +39 -6
- package/content/best-practices/common-pitfalls.md +59 -35
- package/content/best-practices/contribution-workflow.md +6 -2
- package/content/best-practices/data-modeling.md +78 -62
- package/content/best-practices/deployment-strategies.md +56 -19
- package/content/best-practices/error-handling.md +182 -93
- package/content/best-practices/index.md +6 -0
- package/content/best-practices/performance-optimization.md +26 -13
- package/content/best-practices/security-guidelines.md +35 -9
- package/content/best-practices/testing-strategies.md +7 -2
- package/content/best-practices/troubleshooting-tips.md +27 -17
- package/content/extensions/components/api-reference.md +107 -322
- package/content/extensions/components/authentication/api.md +454 -603
- package/content/extensions/components/authentication/errors.md +121 -498
- package/content/extensions/components/authentication/index.md +88 -801
- package/content/extensions/components/authentication/usage.md +207 -956
- package/content/extensions/components/authorization/api.md +736 -656
- package/content/extensions/components/authorization/errors.md +168 -206
- package/content/extensions/components/authorization/index.md +82 -797
- package/content/extensions/components/authorization/usage.md +194 -527
- package/content/extensions/components/health-check.md +71 -243
- package/content/extensions/components/mail/api.md +504 -287
- package/content/extensions/components/mail/errors.md +73 -61
- package/content/extensions/components/mail/index.md +96 -467
- package/content/extensions/components/mail/usage.md +130 -172
- package/content/extensions/components/request-tracker.md +66 -173
- package/content/extensions/components/socket-io/api.md +195 -13
- package/content/extensions/components/socket-io/errors.md +3 -3
- package/content/extensions/components/socket-io/index.md +50 -337
- package/content/extensions/components/socket-io/usage.md +143 -26
- package/content/extensions/components/static-asset/api.md +410 -142
- package/content/extensions/components/static-asset/errors.md +110 -53
- package/content/extensions/components/static-asset/index.md +79 -608
- package/content/extensions/components/static-asset/usage.md +180 -300
- package/content/extensions/components/websocket/api.md +275 -399
- package/content/extensions/components/websocket/errors.md +47 -56
- package/content/extensions/components/websocket/index.md +74 -407
- package/content/extensions/components/websocket/usage.md +110 -341
- package/content/extensions/helpers/cron/index.md +51 -160
- package/content/extensions/helpers/crypto/index.md +62 -483
- package/content/extensions/helpers/crypto/reference.md +456 -0
- package/content/extensions/helpers/env/index.md +60 -178
- package/content/extensions/helpers/error/index.md +221 -207
- package/content/extensions/helpers/inversion/index.md +65 -556
- package/content/extensions/helpers/inversion/reference.md +522 -0
- package/content/extensions/helpers/kafka/admin.md +20 -1
- package/content/extensions/helpers/kafka/compile-binary.md +41 -35
- package/content/extensions/helpers/kafka/consumer.md +54 -20
- package/content/extensions/helpers/kafka/examples.md +21 -16
- package/content/extensions/helpers/kafka/index.md +80 -610
- package/content/extensions/helpers/kafka/producer.md +134 -5
- package/content/extensions/helpers/kafka/schema-registry.md +45 -70
- package/content/extensions/helpers/logger/hf-logger.md +193 -0
- package/content/extensions/helpers/logger/index.md +64 -563
- package/content/extensions/helpers/logger/pino.md +85 -0
- package/content/extensions/helpers/logger/reference.md +746 -0
- package/content/extensions/helpers/network/api.md +241 -195
- package/content/extensions/helpers/network/index.md +72 -530
- package/content/extensions/helpers/queue/index.md +72 -900
- package/content/extensions/helpers/queue/reference.md +467 -0
- package/content/extensions/helpers/redis/index.md +73 -645
- package/content/extensions/helpers/redis/reference.md +727 -0
- package/content/extensions/helpers/secrets/index.md +66 -0
- package/content/extensions/helpers/socket-io/api.md +305 -203
- package/content/extensions/helpers/socket-io/index.md +66 -432
- package/content/extensions/helpers/storage/api.md +564 -462
- package/content/extensions/helpers/storage/index.md +77 -573
- package/content/extensions/helpers/types/index.md +66 -499
- package/content/extensions/helpers/types/reference.md +650 -0
- package/content/extensions/helpers/uid/index.md +58 -227
- package/content/extensions/helpers/websocket/api.md +329 -216
- package/content/extensions/helpers/websocket/index.md +65 -503
- package/content/extensions/helpers/worker-thread/index.md +58 -396
- package/content/extensions/helpers/worker-thread/reference.md +428 -0
- package/content/guides/core-concepts/persistent/models.md +1 -1
- package/content/guides/core-concepts/persistent/search-typesense.md +3 -3
- package/content/guides/core-concepts/persistent/transactions.md +1 -1
- package/content/guides/core-concepts/secrets-vault.md +177 -0
- package/content/guides/core-concepts/services.md +1 -1
- package/content/guides/migrations/redis-helpers-migration.md +1 -1
- package/content/guides/migrations/unified-connectors-migration.md +2 -2
- package/content/guides/tutorials/ecommerce-api.md +3 -8
- package/content/references/base/application.md +1 -1
- package/content/references/base/connectors.md +79 -136
- package/content/references/base/datasources-reference.md +599 -0
- package/content/references/base/datasources.md +84 -444
- package/content/references/base/dependency-injection.md +17 -39
- package/content/references/base/filter-system/application-usage.md +69 -121
- package/content/references/base/filter-system/array-operators.md +12 -0
- package/content/references/base/filter-system/comparison-operators.md +12 -0
- package/content/references/base/filter-system/default-filter.md +136 -348
- package/content/references/base/filter-system/fields-order-pagination.md +38 -16
- package/content/references/base/filter-system/index.md +106 -257
- package/content/references/base/filter-system/json-filtering.md +12 -2
- package/content/references/base/filter-system/list-operators.md +16 -2
- package/content/references/base/filter-system/logical-operators.md +13 -0
- package/content/references/base/filter-system/null-operators.md +13 -0
- package/content/references/base/filter-system/pattern-matching.md +12 -0
- package/content/references/base/filter-system/quick-reference.md +11 -2
- package/content/references/base/filter-system/range-operators.md +12 -0
- package/content/references/base/filter-system/tips.md +70 -133
- package/content/references/base/filter-system/use-cases.md +156 -233
- package/content/references/base/middlewares.md +35 -21
- package/content/references/base/models-reference.md +886 -0
- package/content/references/base/models.md +80 -1452
- package/content/references/base/repositories/advanced.md +156 -192
- package/content/references/base/repositories/index.md +77 -650
- package/content/references/base/repositories/mixins.md +22 -18
- package/content/references/base/repositories/relations.md +123 -171
- package/content/references/base/repositories/soft-deletable.md +58 -56
- package/content/references/base/secrets.md +263 -0
- package/content/references/base/services.md +2 -2
- package/content/references/configuration/environment-variables.md +48 -4
- package/content/references/configuration/index.md +49 -31
- package/content/references/quick-reference.md +3 -16
- package/content/references/utilities/crypto.md +35 -76
- package/content/references/utilities/date.md +33 -73
- package/content/references/utilities/index.md +1 -1
- package/content/references/utilities/jsx-reference.md +298 -0
- package/content/references/utilities/jsx.md +82 -525
- package/content/references/utilities/module.md +29 -62
- package/content/references/utilities/parse.md +34 -64
- package/content/references/utilities/performance.md +33 -58
- package/content/references/utilities/promise.md +28 -62
- package/content/references/utilities/request.md +57 -218
- package/content/references/utilities/schema.md +43 -137
- package/content/references/utilities/statuses-reference.md +361 -0
- package/content/references/utilities/statuses.md +63 -667
- package/package.json +8 -8
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Configuration Reference
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
How IGNIS applications read configuration - the `APP_ENV_` variable convention, the `EnvironmentKeys` constants, and where to look up every value.
|
|
4
4
|
|
|
5
5
|
## Quick Reference
|
|
6
6
|
|
|
@@ -14,22 +14,20 @@ Configuration options and environment variables for IGNIS applications.
|
|
|
14
14
|
| Storage | MinIO/S3 file storage (application-level convention) | `APP_ENV_MINIO_HOST`, `APP_ENV_MINIO_ACCESS_KEY` |
|
|
15
15
|
| Mail | SMTP email sending (application-level convention) | `APP_ENV_MAIL_HOST`, `APP_ENV_MAIL_USER` |
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
**Full list:** [Environment Variables Reference](./environment-variables.md) - every `APP_ENV_*` variable, its default, and whether it's required.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
## In one example
|
|
20
|
+
|
|
21
|
+
IGNIS uses the `APP_ENV_` prefix to avoid conflicts with system variables. Create a `.env` file in your project root:
|
|
20
22
|
|
|
21
23
|
```bash
|
|
22
24
|
# ✅ IGNIS variables
|
|
23
25
|
APP_ENV_POSTGRES_HOST=localhost
|
|
24
26
|
|
|
25
|
-
# ❌ Might conflict with system
|
|
27
|
+
# ❌ Might conflict with system variables
|
|
26
28
|
POSTGRES_HOST=localhost
|
|
27
29
|
```
|
|
28
30
|
|
|
29
|
-
## Quick Start
|
|
30
|
-
|
|
31
|
-
Create a `.env` file in your project root:
|
|
32
|
-
|
|
33
31
|
```bash
|
|
34
32
|
# .env
|
|
35
33
|
APP_ENV_APPLICATION_NAME=my-app
|
|
@@ -39,26 +37,38 @@ APP_ENV_POSTGRES_HOST=localhost
|
|
|
39
37
|
APP_ENV_POSTGRES_DATABASE=my_database
|
|
40
38
|
```
|
|
41
39
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
- [Environment Variables](./environment-variables.md) - Complete reference of all `APP_ENV_*` variables
|
|
45
|
-
|
|
46
|
-
## Configuration Patterns
|
|
47
|
-
|
|
48
|
-
### 1. Accessing Variables
|
|
40
|
+
Read a value either directly or through the `applicationEnvironment` helper:
|
|
49
41
|
|
|
50
42
|
```typescript
|
|
51
43
|
// 1. Direct access
|
|
52
44
|
const host = process.env.APP_ENV_POSTGRES_HOST;
|
|
53
45
|
|
|
54
|
-
// 2. Using helper (recommended)
|
|
46
|
+
// 2. Using the helper (recommended)
|
|
55
47
|
import { applicationEnvironment } from '@venizia/ignis-helpers';
|
|
56
48
|
import { EnvironmentKeys } from '@venizia/ignis';
|
|
57
49
|
const host = applicationEnvironment.get<string>(EnvironmentKeys.APP_ENV_POSTGRES_HOST);
|
|
58
50
|
```
|
|
59
51
|
|
|
60
|
-
|
|
52
|
+
## How it works
|
|
53
|
+
|
|
54
|
+
- **One prefix, layered files.** Everything IGNIS reads is prefixed `APP_ENV_` (configurable - see the [Environment Variables Reference](./environment-variables.md#custom-environment-prefix)). Layer `.env`, `.env.local`, and `.env.{NODE_ENV}` the same way any dotenv-based tool does.
|
|
55
|
+
- **`applicationEnvironment` snapshots `process.env` once at import.** It's built from whatever is in `process.env` when `@venizia/ignis-helpers` loads - values arriving after that (e.g., set programmatically at runtime) won't appear in `.keys()` unless merged in explicitly (secret hydration does this - see below).
|
|
56
|
+
- **Startup validation is fail-closed on emptiness, not absence.** IGNIS iterates every `APP_ENV_*` key that IS set and throws if its value is empty; it does not require a variable to exist at all. Bypass with `ALLOW_EMPTY_ENV_VALUE=true`. Component-level checks (e.g., the authentication component's `jwtSecret` check) cover values that must be present.
|
|
57
|
+
- **Secrets don't have to live in a file.** IGNIS can hydrate `APP_ENV_*` keys from a vault at boot, before datasources are configured - see [Secrets & Vault](./environment-variables.md#secrets-vault).
|
|
58
|
+
|
|
59
|
+
## Common tasks
|
|
60
|
+
|
|
61
|
+
### Access a variable in code
|
|
62
|
+
Prefer `applicationEnvironment.get()` over `process.env` directly - it stays in sync when secrets are hydrated from a vault.
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { applicationEnvironment } from '@venizia/ignis-helpers';
|
|
66
|
+
import { EnvironmentKeys } from '@venizia/ignis';
|
|
61
67
|
|
|
68
|
+
const dbHost = applicationEnvironment.get<string>(EnvironmentKeys.APP_ENV_POSTGRES_HOST);
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Add a per-environment file
|
|
62
72
|
```
|
|
63
73
|
project/
|
|
64
74
|
├── .env # Default (development)
|
|
@@ -67,14 +77,18 @@ project/
|
|
|
67
77
|
└── .env.example # Template (committed)
|
|
68
78
|
```
|
|
69
79
|
|
|
70
|
-
###
|
|
71
|
-
|
|
72
|
-
|
|
80
|
+
### Bypass startup validation during local prototyping
|
|
81
|
+
```bash
|
|
82
|
+
ALLOW_EMPTY_ENV_VALUE=true
|
|
83
|
+
```
|
|
84
|
+
Not recommended once real secrets are wired in - see [Validation](./environment-variables.md#validation).
|
|
73
85
|
|
|
74
|
-
|
|
86
|
+
### Look up every variable's default and requirement
|
|
87
|
+
See the [Environment Variables Reference](./environment-variables.md) for the full table, grouped by Application, Server, Database, Authentication, Logging, Storage, Mail, and Secrets & Vault.
|
|
75
88
|
|
|
76
|
-
##
|
|
89
|
+
## Reference
|
|
77
90
|
|
|
91
|
+
### EnvironmentKeys class
|
|
78
92
|
```typescript
|
|
79
93
|
import { EnvironmentKeys } from '@venizia/ignis';
|
|
80
94
|
```
|
|
@@ -82,7 +96,7 @@ import { EnvironmentKeys } from '@venizia/ignis';
|
|
|
82
96
|
| Constant | Description |
|
|
83
97
|
|----------|-------------|
|
|
84
98
|
| `APP_ENV_APPLICATION_NAME` | Application display name |
|
|
85
|
-
| `APP_ENV_APPLICATION_TIMEZONE` | Application timezone (e.g., 'Asia/Ho_Chi_Minh') |
|
|
99
|
+
| `APP_ENV_APPLICATION_TIMEZONE` | Application timezone (e.g., `'Asia/Ho_Chi_Minh'`) |
|
|
86
100
|
| `APP_ENV_APPLICATION_SECRET` | Application-wide secret key |
|
|
87
101
|
| `APP_ENV_JWT_SECRET` | JWT signing secret |
|
|
88
102
|
| `APP_ENV_JWT_EXPIRES_IN` | JWT token expiration |
|
|
@@ -92,8 +106,8 @@ import { EnvironmentKeys } from '@venizia/ignis';
|
|
|
92
106
|
| `APP_ENV_APPLICATION_DS_AUTHORIZE` | DataSource name for authorization |
|
|
93
107
|
| `APP_ENV_APPLICATION_DS_OAUTH2` | DataSource name for OAuth2 |
|
|
94
108
|
| `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) |
|
|
109
|
+
| `APP_ENV_SERVER_HOST` | HTTP server host (e.g., `'0.0.0.0'`) |
|
|
110
|
+
| `APP_ENV_SERVER_PORT` | HTTP server port (e.g., `3000`) |
|
|
97
111
|
| `APP_ENV_SERVER_BASE_PATH` | Base URL path prefix |
|
|
98
112
|
| `APP_ENV_DATASOURCE_NAME` | Default datasource name |
|
|
99
113
|
| `APP_ENV_POSTGRES_HOST` | PostgreSQL host |
|
|
@@ -102,11 +116,15 @@ import { EnvironmentKeys } from '@venizia/ignis';
|
|
|
102
116
|
| `APP_ENV_POSTGRES_PASSWORD` | PostgreSQL password |
|
|
103
117
|
| `APP_ENV_POSTGRES_DATABASE` | PostgreSQL database name |
|
|
104
118
|
|
|
105
|
-
|
|
119
|
+
## See also
|
|
106
120
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
121
|
+
- [Environment Variables Reference](./environment-variables.md) - complete variable list, defaults, and the Secrets & Vault section
|
|
122
|
+
- [Secrets & Vault Guide](/guides/core-concepts/secrets-vault) - setup walkthrough
|
|
123
|
+
- [Secrets & Vault Reference](/references/base/secrets) - full provider API
|
|
124
|
+
- [DataSources Guide](/guides/core-concepts/persistent/datasources) - wiring `APP_ENV_POSTGRES_*` into a DataSource
|
|
110
125
|
|
|
111
|
-
|
|
112
|
-
|
|
126
|
+
**Files:**
|
|
127
|
+
|
|
128
|
+
- [`packages/core/src/common/environments.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core/src/common/environments.ts) - `EnvironmentKeys`
|
|
129
|
+
- [`packages/helpers/src/modules/env/app-env.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/env/app-env.ts) - `applicationEnvironment`, `Environment`, `ApplicationEnvironment`
|
|
130
|
+
- [`packages/core/src/base/applications/abstract.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core/src/base/applications/abstract.ts) - `validateEnvs()`, host/port resolution
|
|
@@ -81,9 +81,8 @@ class GreeterController extends BaseGrpcController {
|
|
|
81
81
|
### BaseService
|
|
82
82
|
|
|
83
83
|
```typescript
|
|
84
|
-
import { BaseService
|
|
84
|
+
import { BaseService } from '@venizia/ignis';
|
|
85
85
|
|
|
86
|
-
@injectable({})
|
|
87
86
|
class UserService extends BaseService {
|
|
88
87
|
constructor() {
|
|
89
88
|
super({ scope: UserService.name });
|
|
@@ -308,17 +307,6 @@ const users = await userRepository.find({
|
|
|
308
307
|
|
|
309
308
|
## Dependency Injection
|
|
310
309
|
|
|
311
|
-
### Injectable Decorator
|
|
312
|
-
|
|
313
|
-
```typescript
|
|
314
|
-
import { injectable } from '@venizia/ignis';
|
|
315
|
-
|
|
316
|
-
@injectable({})
|
|
317
|
-
class MyService extends BaseService {
|
|
318
|
-
// ...
|
|
319
|
-
}
|
|
320
|
-
```
|
|
321
|
-
|
|
322
310
|
### Inject Decorator
|
|
323
311
|
|
|
324
312
|
```typescript
|
|
@@ -368,7 +356,6 @@ import {
|
|
|
368
356
|
|
|
369
357
|
// DI
|
|
370
358
|
inject,
|
|
371
|
-
injectable,
|
|
372
359
|
|
|
373
360
|
// Utilities
|
|
374
361
|
jsonResponse,
|
|
@@ -513,7 +500,7 @@ if (Statuses.isCompleted(order.status)) {
|
|
|
513
500
|
|
|
514
501
|
```typescript
|
|
515
502
|
import {
|
|
516
|
-
|
|
503
|
+
AppErrorMiddleware,
|
|
517
504
|
notFoundHandler,
|
|
518
505
|
RequestSpyMiddleware,
|
|
519
506
|
emojiFavicon,
|
|
@@ -529,7 +516,7 @@ app.use(requestSpy.value());
|
|
|
529
516
|
app.use(emojiFavicon({ icon: '🚀' }));
|
|
530
517
|
|
|
531
518
|
// Error handling (register last)
|
|
532
|
-
app.onError(
|
|
519
|
+
app.onError(new AppErrorMiddleware({ logger: app.logger }).value());
|
|
533
520
|
|
|
534
521
|
// 404 handler
|
|
535
522
|
app.notFound(notFoundHandler({ logger: app.logger }));
|
|
@@ -1,98 +1,57 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
:::
|
|
8
|
-
|
|
9
|
-
## `hash`
|
|
10
|
-
|
|
11
|
-
Creates a hash or HMAC digest of a string and returns it as a text-encoded string.
|
|
12
|
-
|
|
13
|
-
### Signature
|
|
14
|
-
|
|
15
|
-
```typescript
|
|
16
|
-
hash(
|
|
17
|
-
text: string,
|
|
18
|
-
options: {
|
|
19
|
-
algorithm: 'SHA256' | 'MD5';
|
|
20
|
-
secret?: string;
|
|
21
|
-
outputType: BinaryToTextEncoding; // 'hex' | 'base64' | 'base64url' | 'latin1'
|
|
22
|
-
},
|
|
23
|
-
): string
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
**Parameters**
|
|
27
|
-
|
|
28
|
-
| Parameter | Type | Description |
|
|
29
|
-
|-----------|------|-------------|
|
|
30
|
-
| `text` | `string` | The input string to hash. |
|
|
31
|
-
| `options.algorithm` | `'SHA256' \| 'MD5'` | Hashing algorithm. |
|
|
32
|
-
| `options.secret` | `string` (optional) | Secret key for HMAC. Only used when `algorithm` is `'SHA256'`. |
|
|
33
|
-
| `options.outputType` | `BinaryToTextEncoding` | Encoding of the output string - typically `'hex'` or `'base64'`. |
|
|
1
|
+
---
|
|
2
|
+
title: Crypto Utility
|
|
3
|
+
description: Stateless MD5 and HMAC-SHA256 hashing built on node:crypto
|
|
4
|
+
difficulty: beginner
|
|
5
|
+
lastUpdated: 2026-07-16
|
|
6
|
+
---
|
|
34
7
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
| Algorithm | `secret` provided | Result |
|
|
38
|
-
|-----------|-------------------|--------|
|
|
39
|
-
| `'MD5'` | ignored | MD5 digest of `text` |
|
|
40
|
-
| `'SHA256'` | yes | HMAC-SHA256 of `text` signed with `secret` |
|
|
41
|
-
| `'SHA256'` | no / `undefined` | `text` returned unchanged (no-op) |
|
|
42
|
-
| any other | - | `text` returned unchanged (no-op) |
|
|
43
|
-
|
|
44
|
-
The SHA256 pass-through is intentional: it lets callers skip hashing conditionally (for example, when a secret is not yet configured) without adding an extra `if` at the call site. If you need an unconditional SHA256 hash without a secret, use MD5 or the full [Crypto helper](/extensions/helpers/crypto/).
|
|
8
|
+
# Crypto Utility
|
|
45
9
|
|
|
46
|
-
|
|
10
|
+
A single stateless `hash` function for lightweight MD5 digests and HMAC-SHA256 signatures, with no external dependencies beyond Node's built-in `node:crypto`.
|
|
47
11
|
|
|
48
|
-
|
|
12
|
+
## In one example
|
|
49
13
|
|
|
50
14
|
```typescript
|
|
51
15
|
import { hash } from '@venizia/ignis-helpers';
|
|
52
16
|
|
|
53
17
|
const digest = hash('user@example.com', { algorithm: 'MD5', outputType: 'hex' });
|
|
54
18
|
// => 'b58996c504c5638798eb6b511e6f49af'
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
**MD5 digest (base64) - useful for HTTP ETags**
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
const etag = hash(JSON.stringify(payload), { algorithm: 'MD5', outputType: 'base64' });
|
|
61
|
-
// => 'tYlsUExWOHeY62a1EW9Jr...'
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
**HMAC-SHA256 - signing a webhook payload**
|
|
65
|
-
|
|
66
|
-
```typescript
|
|
67
|
-
import { hash } from '@venizia/ignis-helpers';
|
|
68
19
|
|
|
69
20
|
const signature = hash(rawBody, {
|
|
70
21
|
algorithm: 'SHA256',
|
|
71
22
|
secret: process.env.WEBHOOK_SECRET,
|
|
72
23
|
outputType: 'hex',
|
|
73
24
|
});
|
|
74
|
-
|
|
75
|
-
// Compare against the value in the X-Hub-Signature-256 header
|
|
76
|
-
const expected = `sha256=${signature}`;
|
|
25
|
+
// Compare against the X-Hub-Signature-256 header: `sha256=${signature}`
|
|
77
26
|
```
|
|
78
27
|
|
|
79
|
-
|
|
28
|
+
## Functions
|
|
80
29
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
30
|
+
| Function | Signature | What it does |
|
|
31
|
+
|----------|-----------|---------------|
|
|
32
|
+
| `hash` | `hash(text: string, options: { algorithm: 'SHA256' \| 'MD5'; secret?: string; outputType: BinaryToTextEncoding }): string` | Creates an MD5 digest or an HMAC-SHA256 signature of `text`, encoded via `outputType` (`'hex'`, `'base64'`, `'base64url'`, `'latin1'`). |
|
|
33
|
+
|
|
34
|
+
## Behavior
|
|
35
|
+
|
|
36
|
+
| Algorithm | `secret` provided | Result |
|
|
37
|
+
|-----------|-------------------|--------|
|
|
38
|
+
| `'MD5'` | ignored | MD5 digest of `text` |
|
|
39
|
+
| `'SHA256'` | yes | HMAC-SHA256 of `text` signed with `secret` |
|
|
40
|
+
| `'SHA256'` | no / `undefined` | `text` returned unchanged (no-op) |
|
|
41
|
+
| any other value | - | `text` returned unchanged (no-op) |
|
|
42
|
+
|
|
43
|
+
## Notes
|
|
44
|
+
|
|
45
|
+
- **The SHA256 pass-through is intentional.** It lets callers skip hashing conditionally (for example, when a secret is not yet configured) without an extra `if` at the call site.
|
|
46
|
+
- **Need an unconditional SHA256 hash with no secret?** Use `'MD5'`, or reach for the full [Crypto helper](/extensions/helpers/crypto/).
|
|
47
|
+
- **Typical uses:** cache keys or ETags from response bodies (MD5), webhook signature verification (HMAC-SHA256), API request signing (HMAC-SHA256), anonymising PII before logging (MD5).
|
|
48
|
+
- **Out of scope:** encryption, decryption, and asymmetric operations (AES, RSA, ECDH) - see the [Crypto helper](/extensions/helpers/crypto/) instead.
|
|
88
49
|
|
|
89
|
-
##
|
|
50
|
+
## See also
|
|
90
51
|
|
|
91
|
-
|
|
52
|
+
- [Crypto helper](/extensions/helpers/crypto/) - full AES / RSA / ECDH encryption
|
|
53
|
+
- [Utilities Overview](/references/utilities/) - all utility functions
|
|
92
54
|
|
|
93
|
-
|
|
94
|
-
- Verifying webhook signatures (HMAC-SHA256)
|
|
95
|
-
- Signing API requests with a shared secret (HMAC-SHA256)
|
|
96
|
-
- Anonymising personally identifiable data before storing in logs (MD5)
|
|
55
|
+
**Files:**
|
|
97
56
|
|
|
98
|
-
|
|
57
|
+
- [`packages/helpers/src/utilities/crypto.utility.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/utilities/crypto.utility.ts)
|
|
@@ -1,90 +1,50 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
---
|
|
2
|
+
title: Date Utility
|
|
3
|
+
description: Pre-configured dayjs re-export plus sleep, weekday, timezone, and high-resolution timing helpers
|
|
4
|
+
difficulty: beginner
|
|
5
|
+
lastUpdated: 2026-07-16
|
|
6
|
+
---
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
# Date Utility
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
A pre-configured `dayjs` re-export, plus small standalone helpers for sleeping, weekday math, timezone conversion, and high-resolution timing.
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
## In one example
|
|
10
13
|
|
|
11
14
|
```typescript
|
|
12
|
-
import { dayjs } from '@venizia/ignis-helpers';
|
|
13
|
-
|
|
14
|
-
// Get the current date and time
|
|
15
|
-
const now = dayjs();
|
|
16
|
-
|
|
17
|
-
// Format a date
|
|
18
|
-
const formatted = now.format('YYYY-MM-DD HH:mm:ss');
|
|
19
|
-
```
|
|
15
|
+
import { dayjs, sleep, getDateTz } from '@venizia/ignis-helpers';
|
|
20
16
|
|
|
21
|
-
|
|
17
|
+
const now = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
|
22
18
|
|
|
23
|
-
|
|
19
|
+
await sleep(2000); // pause for 2 seconds
|
|
24
20
|
|
|
25
|
-
|
|
26
|
-
import { sleep } from '@venizia/ignis-helpers';
|
|
27
|
-
|
|
28
|
-
async function myAsyncFunction() {
|
|
29
|
-
console.log('Start');
|
|
30
|
-
await sleep(2000); // Wait for 2 seconds
|
|
31
|
-
console.log('End');
|
|
32
|
-
}
|
|
21
|
+
const tokyoTime = getDateTz({ date: '2023-10-27T10:00:00Z', timezone: 'Asia/Tokyo' });
|
|
33
22
|
```
|
|
34
23
|
|
|
35
|
-
##
|
|
36
|
-
|
|
37
|
-
- **`isWeekday(date)`**: Checks if a given date is a weekday (Monday to Friday). Accepts a `string` or `dayjs.Dayjs` instance.
|
|
38
|
-
- **`getPreviousWeekday(opts?)`**: Returns the previous weekday from a given date. If no date is provided, defaults to today.
|
|
39
|
-
- **`getNextWeekday(opts?)`**: Returns the next weekday from a given date. If no date is provided, defaults to today.
|
|
24
|
+
## Functions
|
|
40
25
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
26
|
+
| Function | Signature | What it does |
|
|
27
|
+
|----------|-----------|---------------|
|
|
28
|
+
| `dayjs` | re-exported `dayjs` object | The `dayjs` factory, pre-loaded with plugins - use it exactly like raw `dayjs`. |
|
|
29
|
+
| `sleep` | `sleep(ms: number): Promise<void>` | Resolves after `ms` milliseconds (`setTimeout` wrapped in a Promise). |
|
|
30
|
+
| `isWeekday` | `isWeekday(date: string \| dayjs.Dayjs): boolean` | `true` when `date` falls Monday through Friday (ISO weekday 1-5). |
|
|
31
|
+
| `getPreviousWeekday` | `getPreviousWeekday(opts?: { date?: string \| dayjs.Dayjs }): dayjs.Dayjs` | Walks backward a day at a time from `date` (default: today) until it lands on a weekday. |
|
|
32
|
+
| `getNextWeekday` | `getNextWeekday(opts?: { date?: string \| dayjs.Dayjs }): dayjs.Dayjs` | Walks forward a day at a time from `date` (default: today) until it lands on a weekday. |
|
|
33
|
+
| `getDateTz` | `getDateTz(opts: { date: string; timezone: string; useClientTz?: boolean; timeOffset?: number }): dayjs.Dayjs` | Parses `date` and converts it to `timezone`, optionally shifting by `timeOffset` hours. |
|
|
34
|
+
| `hrTime` | `hrTime(): number` | High-resolution seconds from `process.hrtime()`, rounded to 9 decimal places - for benchmarking. |
|
|
45
35
|
|
|
46
|
-
|
|
47
|
-
const nextBusinessDay = getNextWeekday({ date: '2026-03-13' });
|
|
48
|
-
```
|
|
36
|
+
## Notes
|
|
49
37
|
|
|
50
|
-
|
|
38
|
+
- **Plugins loaded once at module import:** `CustomParseFormat`, `UTC`, `Timezone`, `Weekday`, `IsoWeek`.
|
|
39
|
+
- **Default timezone is `Asia/Ho_Chi_Minh`**, set via `dayjs.tz.setDefault()` at module load. Override with the `APP_ENV_APPLICATION_TIMEZONE` environment variable - it is read once, so changing it at runtime needs a restart.
|
|
40
|
+
- **`getPreviousWeekday` / `getNextWeekday` are day-by-day loops**, not calendar lookups. They call `isWeekday()` after each step, so the worst case (stepping over a weekend) is only 2-3 iterations.
|
|
41
|
+
- **`getDateTz`'s `useClientTz`** defaults to `false` and controls whether `dayjs().tz()` keeps the original wall-clock time or converts it - see the [Day.js Timezone plugin docs](https://day.js.org/docs/en/timezone/timezone) for the exact semantics.
|
|
51
42
|
|
|
52
|
-
|
|
43
|
+
## See also
|
|
53
44
|
|
|
54
|
-
|
|
45
|
+
- [Utilities Overview](/references/utilities/) - all utility functions
|
|
46
|
+
- [Day.js documentation](https://day.js.org/docs/en/installation/installation) - underlying date library
|
|
55
47
|
|
|
56
|
-
|
|
57
|
-
- `date` (string): The date string to parse.
|
|
58
|
-
- `timezone` (string): The IANA timezone name.
|
|
59
|
-
- `useClientTz` (boolean, optional): Whether to keep the client's timezone. Defaults to `false`.
|
|
60
|
-
- `timeOffset` (number, optional): Number of hours to add to the result. Defaults to `0`.
|
|
48
|
+
**Files:**
|
|
61
49
|
|
|
62
|
-
|
|
63
|
-
import { getDateTz } from '@venizia/ignis-helpers';
|
|
64
|
-
|
|
65
|
-
const tokyoTime = getDateTz({
|
|
66
|
-
date: '2023-10-27T10:00:00Z',
|
|
67
|
-
timezone: 'Asia/Tokyo',
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
// With hour offset
|
|
71
|
-
const offsetTime = getDateTz({
|
|
72
|
-
date: '2023-10-27T10:00:00Z',
|
|
73
|
-
timezone: 'Asia/Tokyo',
|
|
74
|
-
timeOffset: 2, // Add 2 hours
|
|
75
|
-
});
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
## `hrTime`
|
|
79
|
-
|
|
80
|
-
The `hrTime` function returns a high-resolution time measurement in seconds using `process.hrtime()`, useful for performance benchmarking. The result is rounded to 9 decimal places.
|
|
81
|
-
|
|
82
|
-
```typescript
|
|
83
|
-
import { hrTime } from '@venizia/ignis-helpers';
|
|
84
|
-
|
|
85
|
-
const start = hrTime();
|
|
86
|
-
// ... some long-running operation
|
|
87
|
-
const end = hrTime();
|
|
88
|
-
|
|
89
|
-
console.log(`Operation took ${end - start} seconds.`);
|
|
90
|
-
```
|
|
50
|
+
- [`packages/helpers/src/utilities/date.utility.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/utilities/date.utility.ts)
|
|
@@ -22,7 +22,7 @@ Pure, standalone functions providing common, reusable logic for the IGNIS framew
|
|
|
22
22
|
### Data Processing
|
|
23
23
|
|
|
24
24
|
- [**Crypto**](./crypto.md) - Simple, stateless cryptographic functions for hashing (SHA256 HMAC, MD5)
|
|
25
|
-
- [**Parse**](./parse.md) - Functions for parsing and converting data types safely (integers, floats, booleans, camelCase,
|
|
25
|
+
- [**Parse**](./parse.md) - Functions for parsing and converting data types safely (integers, floats, booleans, camelCase, array-to-map)
|
|
26
26
|
- [**Schema**](./schema.md) - Helpers for creating Zod schemas for OpenAPI request/response validation
|
|
27
27
|
- [**Statuses**](./statuses.md) - Standardized status code constants for entity lifecycle management
|
|
28
28
|
|