@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,4 +1,29 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
title: Network - Full Reference
|
|
3
|
+
description: Complete reference for every network helper class - HTTP fetchers, TCP/TLS socket client and server, UDP client - and every option and type
|
|
4
|
+
difficulty: intermediate
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Network - Full Reference
|
|
8
|
+
|
|
9
|
+
Exhaustive reference for `BaseNetworkRequest` and its fetchers, the TCP/TLS client-server hierarchy, `NetworkUdpClient`, and every option type. For a readable introduction and the most common tasks, start with the [Network overview](/extensions/helpers/network/).
|
|
10
|
+
|
|
11
|
+
**Files:**
|
|
12
|
+
|
|
13
|
+
- [`packages/helpers/src/modules/network/http-request/base-network-request.helper.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/network/http-request/base-network-request.helper.ts) - `BaseNetworkRequest`
|
|
14
|
+
- [`packages/helpers/src/modules/network/http-request/fetcher/base-fetcher.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/network/http-request/fetcher/base-fetcher.ts) - `IFetchable`, `IRequestOptions`, `AbstractNetworkFetchableHelper`
|
|
15
|
+
- [`packages/helpers/src/modules/network/http-request/fetcher/node-fetcher.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/network/http-request/fetcher/node-fetcher.ts) - `NodeFetcher`, `NodeFetchNetworkRequest`
|
|
16
|
+
- [`packages/helpers/src/modules/network/http-request/fetcher/axios-fetcher.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/network/http-request/fetcher/axios-fetcher.ts) - `AxiosFetcher`, `AxiosNetworkRequest` (`@venizia/ignis-helpers/axios` sub-path)
|
|
17
|
+
- [`packages/helpers/src/modules/network/http-request/types.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/network/http-request/types.ts) - `TFetcherVariant`, `TFetcherResponse`, `TFetcherWorker`
|
|
18
|
+
- [`packages/helpers/src/modules/network/tcp-socket/base-tcp-server.helper.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/network/tcp-socket/base-tcp-server.helper.ts) - `BaseNetworkTcpServer`, `ITcpSocketClient`, `ITcpSocketServerOptions`
|
|
19
|
+
- [`packages/helpers/src/modules/network/tcp-socket/base-tcp-client.helper.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/network/tcp-socket/base-tcp-client.helper.ts) - `BaseNetworkTcpClient`, `INetworkTcpClientProps`
|
|
20
|
+
- [`packages/helpers/src/modules/network/tcp-socket/network-tcp-server.helper.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/network/tcp-socket/network-tcp-server.helper.ts) - `NetworkTcpServer`
|
|
21
|
+
- [`packages/helpers/src/modules/network/tcp-socket/network-tcp-client.helper.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/network/tcp-socket/network-tcp-client.helper.ts) - `NetworkTcpClient`
|
|
22
|
+
- [`packages/helpers/src/modules/network/tcp-socket/network-tls-tcp-server.helper.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/network/tcp-socket/network-tls-tcp-server.helper.ts) - `NetworkTlsTcpServer`
|
|
23
|
+
- [`packages/helpers/src/modules/network/tcp-socket/network-tls-tcp-client.helper.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/network/tcp-socket/network-tls-tcp-client.helper.ts) - `NetworkTlsTcpClient`
|
|
24
|
+
- [`packages/helpers/src/modules/network/udp-socket/network-udp-client.helper.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/network/udp-socket/network-udp-client.helper.ts) - `NetworkUdpClient`, `INetworkUdpClientProps`
|
|
25
|
+
- [`packages/helpers/src/common/redact.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/common/redact.ts) - `redactSecrets`, `redactUrlCredentials`
|
|
26
|
+
- [`packages/helpers/src/common/constants/http.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/common/constants/http.ts) - `HTTP.Methods`, `THttpMethod`
|
|
2
27
|
|
|
3
28
|
## Architecture
|
|
4
29
|
|
|
@@ -9,21 +34,21 @@ BaseHelper
|
|
|
9
34
|
│ └── NodeFetchNetworkRequest (T = 'node-fetch')
|
|
10
35
|
│
|
|
11
36
|
├── BaseNetworkTcpServer<ServerOpts, ServerType, ClientType>
|
|
12
|
-
│ ├── NetworkTcpServer (net.
|
|
13
|
-
│ └── NetworkTlsTcpServer (tls.
|
|
37
|
+
│ ├── NetworkTcpServer (net.createServer, net.Socket)
|
|
38
|
+
│ └── NetworkTlsTcpServer (tls.createServer, tls.TLSSocket)
|
|
14
39
|
│
|
|
15
40
|
├── BaseNetworkTcpClient<ClientOpts, ClientType>
|
|
16
|
-
│ ├── NetworkTcpClient (net.
|
|
17
|
-
│ └── NetworkTlsTcpClient (tls.
|
|
41
|
+
│ ├── NetworkTcpClient (net.connect, net.Socket)
|
|
42
|
+
│ └── NetworkTlsTcpClient (tls.connect, tls.TLSSocket)
|
|
18
43
|
│
|
|
19
44
|
└── NetworkUdpClient
|
|
20
45
|
|
|
21
|
-
AbstractNetworkFetchableHelper<V, RQ, RS> (implements IFetchable)
|
|
46
|
+
AbstractNetworkFetchableHelper<V, RQ, RS> (implements IFetchable, NOT a BaseHelper)
|
|
22
47
|
├── AxiosFetcher (V = 'axios')
|
|
23
48
|
└── NodeFetcher (V = 'node-fetch')
|
|
24
49
|
```
|
|
25
50
|
|
|
26
|
-
All classes that extend `BaseHelper` inherit scoped logging via `this.logger`.
|
|
51
|
+
All classes that extend `BaseHelper` inherit scoped logging via `this.logger`. `AbstractNetworkFetchableHelper` and its two fetchers do **not** extend `BaseHelper` - they accept an optional `logger` parameter per call instead (see the Request Logging & Redaction section under HTTP Request API).
|
|
27
52
|
|
|
28
53
|
---
|
|
29
54
|
|
|
@@ -68,10 +93,10 @@ getRequestUrl(opts: {
|
|
|
68
93
|
|
|
69
94
|
| Parameter | Type | Description |
|
|
70
95
|
|-----------|------|-------------|
|
|
71
|
-
| `baseUrl` | `string` | Overrides the instance's base URL. Falls back to `this.baseUrl
|
|
96
|
+
| `baseUrl` | `string` | Overrides the instance's base URL. Falls back to `this.baseUrl`. An explicit empty string does **not** fall back - it throws |
|
|
72
97
|
| `paths` | `string[]` | Path segments to append. Each is prefixed with `/` if missing |
|
|
73
98
|
|
|
74
|
-
**Throws:** `
|
|
99
|
+
**Throws:** `ApplicationError` (via `getError`, `statusCode: 500`) with message `'[getRequestUrl] Invalid configuration for third party request base url!'` when both `opts.baseUrl` and `this.baseUrl` resolve to empty.
|
|
75
100
|
|
|
76
101
|
**Example:**
|
|
77
102
|
|
|
@@ -85,7 +110,7 @@ client.getRequestUrl({ baseUrl: 'https://other.api.com', paths: ['health'] });
|
|
|
85
110
|
|
|
86
111
|
##### `getRequestPath(opts)`
|
|
87
112
|
|
|
88
|
-
Joins path segments, ensuring each starts with `/`.
|
|
113
|
+
Joins path segments, ensuring each starts with `/`. An empty `paths` array joins to `''`.
|
|
89
114
|
|
|
90
115
|
```typescript
|
|
91
116
|
getRequestPath(opts: { paths: Array<string> }): string
|
|
@@ -108,7 +133,7 @@ getNetworkService(): IFetchable<T, IRequestOptions, TFetcherResponse<T>>
|
|
|
108
133
|
|
|
109
134
|
##### `getWorker()`
|
|
110
135
|
|
|
111
|
-
Returns the raw HTTP client from the fetcher (`AxiosInstance` for Axios, `typeof fetch` for Node Fetch).
|
|
136
|
+
Returns the raw HTTP client from the fetcher (`AxiosInstance` for Axios, `typeof fetch` for Node Fetch). Delegates to `fetcher.getWorker()`.
|
|
112
137
|
|
|
113
138
|
```typescript
|
|
114
139
|
getWorker(): TFetcherWorker<T>
|
|
@@ -130,24 +155,43 @@ interface IFetchable<
|
|
|
130
155
|
put(opts: RQ, logger?: any): Promise<RS>;
|
|
131
156
|
patch(opts: RQ, logger?: any): Promise<RS>;
|
|
132
157
|
delete(opts: RQ, logger?: any): Promise<RS>;
|
|
158
|
+
query(opts: RQ, logger?: any): Promise<RS>;
|
|
159
|
+
|
|
133
160
|
getWorker(): TFetcherWorker<V>;
|
|
134
161
|
}
|
|
135
162
|
```
|
|
136
163
|
|
|
137
|
-
All HTTP method shortcuts (`get`, `post`, `put`, `patch`, `delete`) delegate to `send()` with the `method` field set accordingly.
|
|
164
|
+
All HTTP method shortcuts (`get`, `post`, `put`, `patch`, `delete`, `query`) delegate to `send()` with the `method` field set accordingly. `query` sends the HTTP `QUERY` method ([RFC 9110/10008](https://www.ietf.org/archive/id/draft-ietf-httpbis-safe-method-w-body-10.html)) - a `GET`-semantics request that carries a body, useful for search payloads too large for a query string.
|
|
138
165
|
|
|
139
166
|
### IRequestOptions
|
|
140
167
|
|
|
141
168
|
```typescript
|
|
142
169
|
interface IRequestOptions {
|
|
143
170
|
url: string;
|
|
144
|
-
|
|
145
|
-
|
|
171
|
+
method?: THttpMethod;
|
|
172
|
+
params?: AnyObject;
|
|
146
173
|
timeout?: number;
|
|
147
174
|
[extra: symbol | string]: any;
|
|
148
175
|
}
|
|
149
176
|
```
|
|
150
177
|
|
|
178
|
+
### HTTP.Methods - the const-class every fetcher dispatches on
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
HTTP.Methods = {
|
|
182
|
+
GET: 'get', POST: 'post', PUT: 'put', PATCH: 'patch',
|
|
183
|
+
DELETE: 'delete', HEAD: 'head', OPTIONS: 'options', QUERY: 'query',
|
|
184
|
+
} as const;
|
|
185
|
+
|
|
186
|
+
type THttpMethod = ValueOf<typeof HTTP.Methods> | Uppercase<ValueOf<typeof HTTP.Methods>>;
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
> [!IMPORTANT]
|
|
190
|
+
> - **Every `HTTP.Methods` token is lowercase.** `@hono/zod-openapi` route definitions accept no other case.
|
|
191
|
+
> - **Both fetchers accept either case on input** (`method: 'post'` or `method: 'POST'`) but always call `method.toUpperCase()` immediately before dispatching to their transport.
|
|
192
|
+
> - **This is not cosmetic.** Node's undici (the `fetch` implementation on Node, not Bun) auto-normalizes only `DELETE`/`GET`/`HEAD`/`OPTIONS`/`POST`/`PUT` and sends any other token (`PATCH`, `QUERY`) through verbatim - a lowercase `patch` would reach the server unchanged and most servers reject it.
|
|
193
|
+
> - **Bun and Axios hide the bug.** Bun's `fetch` and Axios (via `node:http`) uppercase every method themselves, so the bug surfaces only once the app runs on Node with undici.
|
|
194
|
+
|
|
151
195
|
---
|
|
152
196
|
|
|
153
197
|
### AbstractNetworkFetchableHelper
|
|
@@ -160,7 +204,7 @@ abstract class AbstractNetworkFetchableHelper<
|
|
|
160
204
|
> implements IFetchable<V, RQ, RS>
|
|
161
205
|
```
|
|
162
206
|
|
|
163
|
-
Abstract base for fetcher implementations. Provides convenience HTTP method wrappers and protocol detection.
|
|
207
|
+
Abstract base for fetcher implementations. Provides convenience HTTP method wrappers and protocol detection. Does **not** extend `BaseHelper` - it has no `this.logger`.
|
|
164
208
|
|
|
165
209
|
#### Constructor
|
|
166
210
|
|
|
@@ -178,49 +222,22 @@ Subclasses must implement the actual request dispatch.
|
|
|
178
222
|
abstract send(opts: RQ, logger?: any): Promise<RS>;
|
|
179
223
|
```
|
|
180
224
|
|
|
181
|
-
##### `get(opts, logger?)`
|
|
225
|
+
##### `get(opts, logger?)` / `post(opts, logger?)` / `put(opts, logger?)` / `patch(opts, logger?)` / `delete(opts, logger?)` / `query(opts, logger?)`
|
|
182
226
|
|
|
183
227
|
```typescript
|
|
184
228
|
get(opts: RQ, logger?: any): Promise<RS>
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
Calls `send()` with `method: 'get'`.
|
|
188
|
-
|
|
189
|
-
##### `post(opts, logger?)`
|
|
190
|
-
|
|
191
|
-
```typescript
|
|
192
229
|
post(opts: RQ, logger?: any): Promise<RS>
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
Calls `send()` with `method: 'post'`.
|
|
196
|
-
|
|
197
|
-
##### `put(opts, logger?)`
|
|
198
|
-
|
|
199
|
-
```typescript
|
|
200
230
|
put(opts: RQ, logger?: any): Promise<RS>
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
Calls `send()` with `method: 'put'`.
|
|
204
|
-
|
|
205
|
-
##### `patch(opts, logger?)`
|
|
206
|
-
|
|
207
|
-
```typescript
|
|
208
231
|
patch(opts: RQ, logger?: any): Promise<RS>
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
Calls `send()` with `method: 'patch'`.
|
|
212
|
-
|
|
213
|
-
##### `delete(opts, logger?)`
|
|
214
|
-
|
|
215
|
-
```typescript
|
|
216
232
|
delete(opts: RQ, logger?: any): Promise<RS>
|
|
233
|
+
query(opts: RQ, logger?: any): Promise<RS>
|
|
217
234
|
```
|
|
218
235
|
|
|
219
|
-
|
|
236
|
+
Each calls `send()` with `method` set to the matching `HTTP.Methods` token (`get` → `HTTP.Methods.GET`, ... `query` → `HTTP.Methods.QUERY`). Any other field on `opts` (`body`, `headers`, `params`, ...) passes through untouched.
|
|
220
237
|
|
|
221
238
|
##### `getProtocol(url)`
|
|
222
239
|
|
|
223
|
-
Returns `'http'`
|
|
240
|
+
Returns `HTTP.Protocols.HTTP` (`'http'`) if `url` starts with `'http:'`, otherwise `HTTP.Protocols.HTTPS` (`'https'`).
|
|
224
241
|
|
|
225
242
|
```typescript
|
|
226
243
|
getProtocol(url: string): 'http' | 'https'
|
|
@@ -228,7 +245,7 @@ getProtocol(url: string): 'http' | 'https'
|
|
|
228
245
|
|
|
229
246
|
##### `getWorker()`
|
|
230
247
|
|
|
231
|
-
Returns the underlying HTTP client instance.
|
|
248
|
+
Returns the underlying HTTP client instance (set by the concrete fetcher's constructor).
|
|
232
249
|
|
|
233
250
|
```typescript
|
|
234
251
|
getWorker(): TFetcherWorker<V>
|
|
@@ -258,12 +275,14 @@ constructor(opts: {
|
|
|
258
275
|
})
|
|
259
276
|
```
|
|
260
277
|
|
|
278
|
+
`opts.logger`, if provided, logs `'Creating new network request worker instance! Name: %s'` once at construction time - unrelated to the per-call `logger` argument on `send()`.
|
|
279
|
+
|
|
261
280
|
#### IAxiosRequestOptions
|
|
262
281
|
|
|
263
282
|
```typescript
|
|
264
283
|
interface IAxiosRequestOptions extends AxiosRequestConfig, IRequestOptions {
|
|
265
284
|
url: string;
|
|
266
|
-
method?:
|
|
285
|
+
method?: THttpMethod;
|
|
267
286
|
params?: AnyObject;
|
|
268
287
|
body?: AnyObject; // Mapped to Axios `data`
|
|
269
288
|
headers?: AnyObject;
|
|
@@ -271,7 +290,9 @@ interface IAxiosRequestOptions extends AxiosRequestConfig, IRequestOptions {
|
|
|
271
290
|
```
|
|
272
291
|
|
|
273
292
|
> [!NOTE]
|
|
274
|
-
>
|
|
293
|
+
> - **`body` maps to Axios's `data`** field internally.
|
|
294
|
+
> - **Query `params` are serialized** using `node:querystring` via Axios's `paramsSerializer`.
|
|
295
|
+
> - **HTTPS gets an `https.Agent` automatically**, with `rejectUnauthorized` defaulting to `false` - override it per request with `rejectUnauthorized: true`.
|
|
275
296
|
|
|
276
297
|
#### Methods
|
|
277
298
|
|
|
@@ -281,7 +302,11 @@ interface IAxiosRequestOptions extends AxiosRequestConfig, IRequestOptions {
|
|
|
281
302
|
override send<T = any>(opts: IAxiosRequestOptions, logger?: any): Promise<AxiosResponse<T>>
|
|
282
303
|
```
|
|
283
304
|
|
|
284
|
-
Dispatches the request via the internal `axios` instance.
|
|
305
|
+
Dispatches the request via the internal `axios` instance.
|
|
306
|
+
|
|
307
|
+
- `method` defaults to `HTTP.Methods.GET` and is uppercased before dispatch.
|
|
308
|
+
- HTTPS URLs automatically get an `https.Agent` configured.
|
|
309
|
+
- If `logger` is passed, logs `'URL: %s | Props: %s'` at `info` level with the assembled request config run through `redactSecrets()`.
|
|
285
310
|
|
|
286
311
|
---
|
|
287
312
|
|
|
@@ -291,7 +316,7 @@ Dispatches the request via the internal `axios` instance. For HTTPS URLs, automa
|
|
|
291
316
|
class AxiosNetworkRequest extends BaseNetworkRequest<'axios'>
|
|
292
317
|
```
|
|
293
318
|
|
|
294
|
-
Pre-configured HTTP client using Axios.
|
|
319
|
+
Pre-configured HTTP client using Axios. Import only from the sub-path - `import { AxiosNetworkRequest } from '@venizia/ignis-helpers/axios'`.
|
|
295
320
|
|
|
296
321
|
#### Constructor
|
|
297
322
|
|
|
@@ -317,7 +342,7 @@ interface IAxiosNetworkRequestOptions {
|
|
|
317
342
|
| `validateStatus` | `(status) => status < 500` |
|
|
318
343
|
| `timeout` | `60000` (1 minute) |
|
|
319
344
|
|
|
320
|
-
User-provided values in `networkOptions` override all defaults.
|
|
345
|
+
User-provided values in `networkOptions` override all defaults. `networkOptions.baseUrl` maps to Axios's `baseURL`.
|
|
321
346
|
|
|
322
347
|
---
|
|
323
348
|
|
|
@@ -331,7 +356,7 @@ class NodeFetcher extends AbstractNetworkFetchableHelper<
|
|
|
331
356
|
>
|
|
332
357
|
```
|
|
333
358
|
|
|
334
|
-
Native `fetch
|
|
359
|
+
Native `fetch`-based fetcher implementation.
|
|
335
360
|
|
|
336
361
|
#### Constructor
|
|
337
362
|
|
|
@@ -348,7 +373,8 @@ constructor(opts: {
|
|
|
348
373
|
```typescript
|
|
349
374
|
interface INodeFetchRequestOptions extends RequestInit, IRequestOptions {
|
|
350
375
|
url: string;
|
|
351
|
-
|
|
376
|
+
method?: THttpMethod;
|
|
377
|
+
params?: AnyObject;
|
|
352
378
|
}
|
|
353
379
|
```
|
|
354
380
|
|
|
@@ -360,7 +386,14 @@ interface INodeFetchRequestOptions extends RequestInit, IRequestOptions {
|
|
|
360
386
|
override async send(opts: INodeFetchRequestOptions, logger?: any): Promise<Response>
|
|
361
387
|
```
|
|
362
388
|
|
|
363
|
-
Dispatches the request using the native `fetch` API.
|
|
389
|
+
Dispatches the request using the native `fetch` API. Behavior:
|
|
390
|
+
|
|
391
|
+
- `method` defaults to `HTTP.Methods.GET` and is uppercased before dispatch.
|
|
392
|
+
- Query `params` are serialized with `node:querystring` and appended to `url` - with `?` if the URL carries no query string yet, `&` if it already does (never a double `?`).
|
|
393
|
+
- If `timeout` is provided, an internal `AbortController` aborts the request after that many milliseconds.
|
|
394
|
+
- The internal timeout signal is **composed**, never substituted, with a caller-supplied `signal`: `AbortSignal.any([signal, timeoutController.signal])` when both are present - so a caller aborting its own signal still cancels the request even while a timeout is also armed.
|
|
395
|
+
- The timer is cleared as soon as the request settles.
|
|
396
|
+
- If `logger` is passed, logs `'URL: %s | Props: %s | Timeout: %s'` at `info` level with the request config run through `redactSecrets()`.
|
|
364
397
|
|
|
365
398
|
---
|
|
366
399
|
|
|
@@ -370,7 +403,7 @@ Dispatches the request using the native `fetch` API. If `timeout` is provided, c
|
|
|
370
403
|
class NodeFetchNetworkRequest extends BaseNetworkRequest<'node-fetch'>
|
|
371
404
|
```
|
|
372
405
|
|
|
373
|
-
Pre-configured HTTP client using native `fetch`.
|
|
406
|
+
Pre-configured HTTP client using native `fetch`. Exported from the root barrel - no extra dependency.
|
|
374
407
|
|
|
375
408
|
#### Constructor
|
|
376
409
|
|
|
@@ -393,7 +426,36 @@ interface INodeFetchNetworkRequestOptions {
|
|
|
393
426
|
|---------|---------|
|
|
394
427
|
| `headers['content-type']` | `'application/json; charset=utf-8'` |
|
|
395
428
|
|
|
396
|
-
If `headers` is a `Headers` instance, it is converted to a plain object via `Object.fromEntries()` before merging.
|
|
429
|
+
If `headers` is a `Headers` instance, it is converted to a plain object via `Object.fromEntries(headers.entries())` before merging with the default.
|
|
430
|
+
|
|
431
|
+
> [!WARNING] `timeout` is per-call, not per-instance
|
|
432
|
+
> `networkOptions` is `RequestInit`, which has no `timeout` field - passing one there has no effect on request cancellation. `NodeFetcher.send()` only reads `timeout` from the arguments of each individual `send()`/`get()`/... call. Pass it every time you need an abort:
|
|
433
|
+
>
|
|
434
|
+
> ```typescript
|
|
435
|
+
> await this.getNetworkService().send({ url: '/slow-endpoint', method: 'get', timeout: 5000 });
|
|
436
|
+
> ```
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
### Request Logging & Redaction
|
|
441
|
+
|
|
442
|
+
Neither fetcher logs anything by default - `send()` and every shortcut accept an **optional** `logger` as the second argument, and the log call is guarded with `logger?.for(...)`. Pass one (typically `this.logger` from a `BaseHelper` subclass, or `this.logger` on a class extending `BaseNetworkRequest`) to get an `info`-level line per request:
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
await this.getNetworkService().post({ url, body }, this.logger);
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
Whenever a logger is passed, the assembled request config - `url`, `method`, `headers`, `body`/`data`, and any other options - is run through `redactSecrets()` **before** the log line is written. Redaction matches by key name, case-insensitively, at any depth, against `SECRET_KEY_PATTERN`:
|
|
449
|
+
|
|
450
|
+
| Key group | Matched spellings |
|
|
451
|
+
|-----------|--------------------|
|
|
452
|
+
| Options-object (camelCase) | `pass`, `password`, `passphrase`, `secret`, `token`, `apiKey`, `accessKey`, `secretKey`, `privateKey`, `key`, `cert`, `ca`, `pfx`, `credentials`, `authorization`, `auth`, `jwtSecret`, `applicationSecret`, `connectionString` |
|
|
453
|
+
| Options-object (snake_case) | `api_key`, `access_key`, `secret_key`, `private_key` |
|
|
454
|
+
| HTTP header spellings | `cookie`, `set-cookie`, `proxy-authorization`, `www-authenticate`, and any `(x-)?(api\|auth\|access\|secret\|session\|csrf\|xsrf)-(key\|token\|secret\|id)` pattern (e.g. `x-api-key`, `x-auth-token`, `x-csrf-token`) |
|
|
455
|
+
|
|
456
|
+
Source: [`redact.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/common/redact.ts) `SECRET_KEY_PATTERN`.
|
|
457
|
+
|
|
458
|
+
A matched value is replaced with `'[REDACTED]'`; `Buffer`/typed-array values under a non-matching key are summarized as `'[Binary N bytes]'` rather than serialized. There is nothing to configure beyond passing the logger - you never call `redactSecrets()` yourself at the call site.
|
|
397
459
|
|
|
398
460
|
---
|
|
399
461
|
|
|
@@ -417,9 +479,9 @@ Abstract TCP server with client tracking, authentication flow, and event delegat
|
|
|
417
479
|
constructor(opts: ITcpSocketServerOptions<SocketServerOptions, SocketServerType, SocketClientType>)
|
|
418
480
|
```
|
|
419
481
|
|
|
420
|
-
**Throws:** `
|
|
482
|
+
**Throws:** `ApplicationError` with message `'TCP Server | Invalid authenticate duration | Required duration for authenticateOptions'` when `authenticateOptions.required` is `true` and `duration` is missing, `0`, or negative.
|
|
421
483
|
|
|
422
|
-
The constructor
|
|
484
|
+
The constructor calls `configure()`, which creates the server via `createServerFn` and starts listening.
|
|
423
485
|
|
|
424
486
|
#### Protected Properties
|
|
425
487
|
|
|
@@ -430,13 +492,16 @@ The constructor automatically calls `configure()`, which creates the server and
|
|
|
430
492
|
| `authenticateOptions` | `{ required: boolean; duration?: number }` | Auth settings |
|
|
431
493
|
| `clients` | `Record<string, ITcpSocketClient<SocketClientType>>` | Connected client registry |
|
|
432
494
|
| `server` | `SocketServerType` | The underlying server instance |
|
|
433
|
-
| `extraEvents` | `Record<string, (opts) => void
|
|
495
|
+
| `extraEvents` | `Record<string, (opts) => ValueOrPromise<void>>` | Additional per-client socket events to register |
|
|
496
|
+
|
|
497
|
+
- **Hooks never crash the process.** `onClientData`, `onClientConnected`, `onClientClose`, `onClientError`, `onServerReady`, `onServerError`, and each `extraEvents` entry all run through an internal `invokeHook()` wrapper.
|
|
498
|
+
- **Why it exists.** A hook throwing synchronously inside a raw `net`/`tls` event listener would otherwise be an uncaught exception that crashes the process; `invokeHook()` catches it and logs instead.
|
|
434
499
|
|
|
435
500
|
#### Methods
|
|
436
501
|
|
|
437
502
|
##### `configure()`
|
|
438
503
|
|
|
439
|
-
Creates the server using `createServerFn` and starts listening. Called automatically by the constructor.
|
|
504
|
+
Creates the server using `createServerFn`, registers a server-level `error` listener (routed to `onServerError`, never left to crash the process), and starts listening. Called automatically by the constructor.
|
|
440
505
|
|
|
441
506
|
```typescript
|
|
442
507
|
configure(): void
|
|
@@ -444,39 +509,29 @@ configure(): void
|
|
|
444
509
|
|
|
445
510
|
##### `onNewConnection(opts)`
|
|
446
511
|
|
|
447
|
-
Handles a new client connection
|
|
512
|
+
Handles a new client connection:
|
|
513
|
+
|
|
514
|
+
- Assigns a unique ID via `getUID()`.
|
|
515
|
+
- Registers `data`/`error`/`close`/`extraEvents` listeners on the socket.
|
|
516
|
+
- Tracks the client in the `clients` registry.
|
|
517
|
+
- Invokes `onClientConnected`.
|
|
518
|
+
- Starts the authentication kick-timer when `authenticateOptions.required` is `true`.
|
|
448
519
|
|
|
449
520
|
```typescript
|
|
450
521
|
onNewConnection(opts: { socket: SocketClientType }): void
|
|
451
522
|
```
|
|
452
523
|
|
|
453
|
-
##### `getClients()`
|
|
454
|
-
|
|
455
|
-
Returns all connected clients as a record keyed by client ID.
|
|
524
|
+
##### `getClients()` / `getClient(opts)` / `getServer()`
|
|
456
525
|
|
|
457
526
|
```typescript
|
|
458
527
|
getClients(): Record<string, ITcpSocketClient<SocketClientType>>
|
|
459
|
-
```
|
|
460
|
-
|
|
461
|
-
##### `getClient(opts)`
|
|
462
|
-
|
|
463
|
-
Returns a specific connected client by ID, or `undefined` if not found.
|
|
464
|
-
|
|
465
|
-
```typescript
|
|
466
528
|
getClient(opts: { id: string }): ITcpSocketClient<SocketClientType> | undefined
|
|
467
|
-
```
|
|
468
|
-
|
|
469
|
-
##### `getServer()`
|
|
470
|
-
|
|
471
|
-
Returns the underlying server instance.
|
|
472
|
-
|
|
473
|
-
```typescript
|
|
474
529
|
getServer(): SocketServerType
|
|
475
530
|
```
|
|
476
531
|
|
|
477
532
|
##### `doAuthenticate(opts)`
|
|
478
533
|
|
|
479
|
-
Transitions a client's authentication state. Sets `authenticatedAt`
|
|
534
|
+
Transitions a client's authentication state. Sets `storage.authenticatedAt` when the state becomes `'authenticated'` and clears the pending kick-timer; clears `authenticatedAt` for the other two states.
|
|
480
535
|
|
|
481
536
|
```typescript
|
|
482
537
|
doAuthenticate(opts: {
|
|
@@ -487,12 +542,38 @@ doAuthenticate(opts: {
|
|
|
487
542
|
|
|
488
543
|
##### `emit(opts)`
|
|
489
544
|
|
|
490
|
-
Writes data to a specific client's socket.
|
|
545
|
+
Writes data to a specific client's socket. Never throws - each failure case logs and returns instead:
|
|
546
|
+
|
|
547
|
+
| Condition | Log level |
|
|
548
|
+
|-----------|-----------|
|
|
549
|
+
| Client not found for `clientId` | `error` |
|
|
550
|
+
| Socket not writable | `error` |
|
|
551
|
+
| Payload empty (`!payload?.length`) | `info` |
|
|
491
552
|
|
|
492
553
|
```typescript
|
|
493
554
|
emit(opts: { clientId: string; payload: Buffer | string }): void
|
|
494
555
|
```
|
|
495
556
|
|
|
557
|
+
##### `shutdown()`
|
|
558
|
+
|
|
559
|
+
Tears the server down completely and resolves even while clients are still attached.
|
|
560
|
+
|
|
561
|
+
```typescript
|
|
562
|
+
async shutdown(): Promise<void>
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
**Order of operations:**
|
|
566
|
+
|
|
567
|
+
1. Clears every client's pending authenticate kick-timer.
|
|
568
|
+
2. Destroys every client socket.
|
|
569
|
+
3. Empties the `clients` registry.
|
|
570
|
+
4. Calls `server.close()` and awaits its callback.
|
|
571
|
+
|
|
572
|
+
- **Why this order.** `server.close()` alone never resolves while a socket is still attached, so a caller reaching through `getServer().close()` on a busy server hangs forever.
|
|
573
|
+
- **Idempotent.** A second call is a no-op that resolves cleanly.
|
|
574
|
+
- **Safe on a server that never finished `listen()`.** Logs the resulting `ERR_SERVER_NOT_RUNNING` rather than throwing.
|
|
575
|
+
- **After `shutdown()`**, new connection attempts are refused.
|
|
576
|
+
|
|
496
577
|
---
|
|
497
578
|
|
|
498
579
|
### ITcpSocketClient
|
|
@@ -506,6 +587,7 @@ interface ITcpSocketClient<SocketClientType> {
|
|
|
506
587
|
storage: {
|
|
507
588
|
connectedAt: dayjs.Dayjs;
|
|
508
589
|
authenticatedAt: dayjs.Dayjs | null;
|
|
590
|
+
authenticateTimeout?: ReturnType<typeof setTimeout> | null;
|
|
509
591
|
[additionField: symbol | string]: any;
|
|
510
592
|
};
|
|
511
593
|
}
|
|
@@ -527,14 +609,12 @@ Plain TCP server using `net.createServer`.
|
|
|
527
609
|
constructor(opts: Omit<ITcpSocketServerOptions, 'createServerFn'>)
|
|
528
610
|
```
|
|
529
611
|
|
|
530
|
-
The `createServerFn` is pre-set to `net.createServer`.
|
|
612
|
+
The `createServerFn` is pre-set to `net.createServer`. `scope` is hardcoded to `'NetworkTcpServer'`, overriding any `opts.scope`.
|
|
531
613
|
|
|
532
614
|
#### Static Methods
|
|
533
615
|
|
|
534
616
|
##### `newInstance(opts)`
|
|
535
617
|
|
|
536
|
-
Factory method that creates a new `NetworkTcpServer`.
|
|
537
|
-
|
|
538
618
|
```typescript
|
|
539
619
|
static newInstance(
|
|
540
620
|
opts: Omit<ITcpSocketServerOptions, 'createServerFn'>
|
|
@@ -554,10 +634,10 @@ TLS-encrypted TCP server using `tls.createServer`.
|
|
|
554
634
|
#### Constructor
|
|
555
635
|
|
|
556
636
|
```typescript
|
|
557
|
-
constructor(opts: Omit<ITcpSocketServerOptions, 'createServerFn'>)
|
|
637
|
+
constructor(opts: Omit<ITcpSocketServerOptions<TlsOptions, tls.Server, TLSSocket>, 'createServerFn'>)
|
|
558
638
|
```
|
|
559
639
|
|
|
560
|
-
The `createServerFn` is pre-set to `tls.createServer`.
|
|
640
|
+
The `createServerFn` is pre-set to `tls.createServer`. `scope` is hardcoded to `'NetworkTlsTcpServer'`. Pass TLS certificates and keys in `serverOptions` (type `TlsOptions` from `node:tls`). Every method, including `shutdown()`, is identical to `NetworkTcpServer`.
|
|
561
641
|
|
|
562
642
|
#### Static Methods
|
|
563
643
|
|
|
@@ -565,7 +645,7 @@ The `createServerFn` is pre-set to `tls.createServer`. The `scope` is set to `'N
|
|
|
565
645
|
|
|
566
646
|
```typescript
|
|
567
647
|
static newInstance(
|
|
568
|
-
opts: Omit<ITcpSocketServerOptions, 'createServerFn'>
|
|
648
|
+
opts: Omit<ITcpSocketServerOptions<TlsOptions, tls.Server, TLSSocket>, 'createServerFn'>
|
|
569
649
|
): NetworkTlsTcpServer
|
|
570
650
|
```
|
|
571
651
|
|
|
@@ -588,21 +668,34 @@ Abstract TCP client with auto-reconnect, encoding support, and lifecycle hooks.
|
|
|
588
668
|
constructor(opts: INetworkTcpClientProps<SocketClientOptions, SocketClientType>)
|
|
589
669
|
```
|
|
590
670
|
|
|
671
|
+
Does **not** call `connect()` automatically - construction only stores options; call `connect({ resetReconnectCounter })` explicitly.
|
|
672
|
+
|
|
591
673
|
#### Protected Properties
|
|
592
674
|
|
|
593
675
|
| Property | Type | Description |
|
|
594
676
|
|----------|------|-------------|
|
|
595
|
-
| `client` | `SocketClientType \| null` | The underlying socket, or `null` when disconnected |
|
|
677
|
+
| `client` | `SocketClientType \| null` | The underlying socket, or `null`/`undefined` when disconnected |
|
|
596
678
|
| `options` | `SocketClientOptions` | Connection options |
|
|
597
679
|
| `reconnect` | `boolean` | Whether auto-reconnect is enabled (default: `false`) |
|
|
598
680
|
| `retry` | `{ maxReconnect: number; currentReconnect: number }` | Reconnect state. `maxReconnect` defaults to `5` |
|
|
599
681
|
| `encoding` | `BufferEncoding \| undefined` | Socket encoding |
|
|
600
682
|
|
|
683
|
+
##### `getLoggableOptions()`
|
|
684
|
+
|
|
685
|
+
```typescript
|
|
686
|
+
protected getLoggableOptions(): unknown
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
Returns `redactSecrets(this.options)`. A TLS client's `options` **is** its private key material (`key`/`cert`/`passphrase`), so every internal log call uses this instead of logging `this.options` directly - otherwise the key would be written to every log file and aggregator downstream.
|
|
690
|
+
|
|
601
691
|
#### Methods
|
|
602
692
|
|
|
603
693
|
##### `connect(opts)`
|
|
604
694
|
|
|
605
|
-
Establishes the connection
|
|
695
|
+
Establishes the connection:
|
|
696
|
+
|
|
697
|
+
- No-op with a log line if already connected (`isConnected()`) or if `options` is empty.
|
|
698
|
+
- Otherwise, destroys any stale `client` first, creates the socket via `createClientFn`, registers `data`/`close`/`error` listeners, and applies `encoding` if set.
|
|
606
699
|
|
|
607
700
|
```typescript
|
|
608
701
|
connect(opts: { resetReconnectCounter: boolean }): void
|
|
@@ -610,11 +703,11 @@ connect(opts: { resetReconnectCounter: boolean }): void
|
|
|
610
703
|
|
|
611
704
|
| Parameter | Type | Description |
|
|
612
705
|
|-----------|------|-------------|
|
|
613
|
-
| `resetReconnectCounter` | `boolean` | If `true`, resets `retry.currentReconnect` to `0` |
|
|
706
|
+
| `resetReconnectCounter` | `boolean` | If `true`, resets `retry.currentReconnect` to `0` before connecting |
|
|
614
707
|
|
|
615
708
|
##### `disconnect()`
|
|
616
709
|
|
|
617
|
-
Destroys the socket, clears the reconnect timeout, and sets `client` to `null`.
|
|
710
|
+
Destroys the socket, clears the reconnect timeout, and sets `client` to `null`. No-op with a log line if `client` is not set.
|
|
618
711
|
|
|
619
712
|
```typescript
|
|
620
713
|
disconnect(): void
|
|
@@ -630,7 +723,7 @@ forceReconnect(): void
|
|
|
630
723
|
|
|
631
724
|
##### `isConnected()`
|
|
632
725
|
|
|
633
|
-
Returns a truthy value if
|
|
726
|
+
Returns a truthy value if `client` exists and its `readyState` is not `'closed'`.
|
|
634
727
|
|
|
635
728
|
```typescript
|
|
636
729
|
isConnected(): SocketClientType | null | undefined
|
|
@@ -638,7 +731,7 @@ isConnected(): SocketClientType | null | undefined
|
|
|
638
731
|
|
|
639
732
|
##### `emit(opts)`
|
|
640
733
|
|
|
641
|
-
Writes data to the server.
|
|
734
|
+
Writes data to the server. Logs and returns without throwing if `client` is not initialized or the payload is empty.
|
|
642
735
|
|
|
643
736
|
```typescript
|
|
644
737
|
emit(opts: { payload: Buffer | string }): void
|
|
@@ -646,43 +739,36 @@ emit(opts: { payload: Buffer | string }): void
|
|
|
646
739
|
|
|
647
740
|
##### `getClient()`
|
|
648
741
|
|
|
649
|
-
Returns the underlying socket instance, or `null`/`undefined` if not connected.
|
|
650
|
-
|
|
651
742
|
```typescript
|
|
652
743
|
getClient(): SocketClientType | null | undefined
|
|
653
744
|
```
|
|
654
745
|
|
|
655
|
-
##### `handleConnected()`
|
|
656
|
-
|
|
657
|
-
Default connection handler. Logs the connection and resets the reconnect counter.
|
|
658
|
-
|
|
659
|
-
```typescript
|
|
660
|
-
handleConnected(): void
|
|
661
|
-
```
|
|
662
|
-
|
|
663
|
-
##### `handleData(_opts)`
|
|
746
|
+
##### `handleConnected()` / `handleData(_opts)` / `handleClosed()` / `handleError(error)`
|
|
664
747
|
|
|
665
|
-
Default
|
|
748
|
+
Default handlers used when the matching `onConnected`/`onData`/`onClosed`/`onError` option is omitted.
|
|
666
749
|
|
|
667
750
|
```typescript
|
|
668
|
-
|
|
751
|
+
handleConnected(): void // Logs, resets retry.currentReconnect to 0
|
|
752
|
+
handleData(_opts: { identifier: string; message: string | Buffer }): void // No-op
|
|
753
|
+
handleClosed(): void // Logs the closure
|
|
754
|
+
handleError(error: any): void // Logs; schedules a reconnect if eligible
|
|
669
755
|
```
|
|
670
756
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
Default close handler. Logs the closure.
|
|
674
|
-
|
|
675
|
-
```typescript
|
|
676
|
-
handleClosed(): void
|
|
677
|
-
```
|
|
757
|
+
**Reconnect gate on `handleError`:**
|
|
678
758
|
|
|
679
|
-
|
|
759
|
+
| Condition | Result |
|
|
760
|
+
|-----------|--------|
|
|
761
|
+
| `reconnect` is `false` | No reconnect - the first guard returns immediately |
|
|
762
|
+
| `retry.currentReconnect >= retry.maxReconnect` | No reconnect - the first guard returns immediately |
|
|
763
|
+
| `maxReconnect === -1` | **No reconnect, ever.** `currentReconnect` starts at `0`, and `0 >= -1` is already true, so the first guard returns before any attempt is made |
|
|
764
|
+
| `reconnect` is `true` and `currentReconnect < maxReconnect` (with `maxReconnect >= 0`) | Reconnect scheduled |
|
|
680
765
|
|
|
681
|
-
|
|
766
|
+
> [!IMPORTANT]
|
|
767
|
+
> - **`maxReconnect: -1` does not mean unlimited reconnects - it disables reconnection entirely.** This is the opposite of the common "`-1` = unlimited" convention elsewhere in the framework (e.g. Redis retry).
|
|
768
|
+
> - **A second guard further down the method is dead code.** `if (maxReconnect > -1 && currentReconnect >= maxReconnect)` can never be true: by the time control reaches it, the first guard has already ruled out `currentReconnect >= maxReconnect`.
|
|
769
|
+
> - Source: [`base-tcp-client.helper.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/network/tcp-socket/base-tcp-client.helper.ts).
|
|
682
770
|
|
|
683
|
-
|
|
684
|
-
handleError(error: any): void
|
|
685
|
-
```
|
|
771
|
+
The reconnect delay is a **fixed 5000 ms** - there is no backoff growth on the TCP/TLS client, unlike the Redis helper's exponential strategy.
|
|
686
772
|
|
|
687
773
|
---
|
|
688
774
|
|
|
@@ -702,7 +788,7 @@ constructor(
|
|
|
702
788
|
)
|
|
703
789
|
```
|
|
704
790
|
|
|
705
|
-
The `createClientFn` is pre-set to `net.connect`.
|
|
791
|
+
The `createClientFn` is pre-set to `net.connect`. `scope` is hardcoded to `'NetworkTcpClient'`.
|
|
706
792
|
|
|
707
793
|
#### Static Methods
|
|
708
794
|
|
|
@@ -732,7 +818,7 @@ constructor(
|
|
|
732
818
|
)
|
|
733
819
|
```
|
|
734
820
|
|
|
735
|
-
The `createClientFn` is pre-set to `tls.connect`.
|
|
821
|
+
The `createClientFn` is pre-set to `tls.connect`. `scope` is hardcoded to `'NetworkTlsTcpClient'`. Pass TLS certificates and keys in `options` (type `ConnectionOptions` from `node:tls`). Every method is identical to `NetworkTcpClient`.
|
|
736
822
|
|
|
737
823
|
#### Static Methods
|
|
738
824
|
|
|
@@ -754,7 +840,7 @@ static newInstance(
|
|
|
754
840
|
class NetworkUdpClient extends BaseHelper
|
|
755
841
|
```
|
|
756
842
|
|
|
757
|
-
UDP datagram client with multicast support, using `node:dgram` internally (
|
|
843
|
+
UDP datagram client with multicast support, using `node:dgram` internally (`type: 'udp4'`). No client/server split - one class handles both send and receive. `scope` is always hardcoded to `'NetworkUdpClient'` (no `scope` option exists on `INetworkUdpClientProps`).
|
|
758
844
|
|
|
759
845
|
#### Constructor
|
|
760
846
|
|
|
@@ -762,41 +848,12 @@ UDP datagram client with multicast support, using `node:dgram` internally (UDP4)
|
|
|
762
848
|
constructor(opts: INetworkUdpClientProps)
|
|
763
849
|
```
|
|
764
850
|
|
|
765
|
-
|
|
766
|
-
interface INetworkUdpClientProps {
|
|
767
|
-
identifier: string;
|
|
768
|
-
host?: string;
|
|
769
|
-
port: number;
|
|
770
|
-
reuseAddr?: boolean;
|
|
771
|
-
multicastAddress?: {
|
|
772
|
-
groups?: Array<string>;
|
|
773
|
-
interface?: string;
|
|
774
|
-
};
|
|
775
|
-
onConnected?: (opts: { identifier: string; host?: string; port: number }) => void;
|
|
776
|
-
onData?: (opts: {
|
|
777
|
-
identifier: string;
|
|
778
|
-
message: string | Buffer;
|
|
779
|
-
remoteInfo: dgram.RemoteInfo;
|
|
780
|
-
}) => void;
|
|
781
|
-
onClosed?: (opts: { identifier: string; host?: string; port: number }) => void;
|
|
782
|
-
onError?: (opts: { identifier: string; host?: string; port: number; error: Error }) => void;
|
|
783
|
-
onBind?: (opts: {
|
|
784
|
-
identifier: string;
|
|
785
|
-
socket: dgram.Socket;
|
|
786
|
-
host?: string;
|
|
787
|
-
port: number;
|
|
788
|
-
reuseAddr?: boolean;
|
|
789
|
-
multicastAddress?: { groups?: Array<string>; interface?: string };
|
|
790
|
-
}) => ValueOrPromise<void>;
|
|
791
|
-
}
|
|
792
|
-
```
|
|
851
|
+
Construction only stores options; call `connect()` explicitly to bind the socket.
|
|
793
852
|
|
|
794
853
|
#### Static Methods
|
|
795
854
|
|
|
796
855
|
##### `newInstance(opts)`
|
|
797
856
|
|
|
798
|
-
Factory method that creates a new `NetworkUdpClient`.
|
|
799
|
-
|
|
800
857
|
```typescript
|
|
801
858
|
static newInstance(opts: INetworkUdpClientProps): NetworkUdpClient
|
|
802
859
|
```
|
|
@@ -805,17 +862,19 @@ static newInstance(opts: INetworkUdpClientProps): NetworkUdpClient
|
|
|
805
862
|
|
|
806
863
|
##### `connect()`
|
|
807
864
|
|
|
808
|
-
Creates a `dgram.Socket` (type
|
|
865
|
+
- Creates a `dgram.Socket` (`type: 'udp4'`, `reuseAddr` from options), registers `close`/`error`/`listening`/`message` listeners, then binds to `port`/`host`.
|
|
866
|
+
- Each listener routes through an internal `invokeHook()` wrapper (same synchronous-throw guard as the TCP server).
|
|
867
|
+
- `onBind` fires after binding completes - the place to join multicast groups via `socket.addMembership(group, iface)`.
|
|
809
868
|
|
|
810
869
|
```typescript
|
|
811
870
|
connect(): void
|
|
812
871
|
```
|
|
813
872
|
|
|
814
|
-
|
|
873
|
+
No-op with a log line if `client` is already set, or if `port` is not a non-negative integer (`Number.isInteger(port) && port >= 0`) - port `0` is a valid "OS assigns a free port" request and is accepted.
|
|
815
874
|
|
|
816
875
|
##### `disconnect()`
|
|
817
876
|
|
|
818
|
-
Closes the
|
|
877
|
+
Closes the socket and sets `client` to `null`. No-op with a log line if `client` is not set.
|
|
819
878
|
|
|
820
879
|
```typescript
|
|
821
880
|
disconnect(): void
|
|
@@ -823,7 +882,7 @@ disconnect(): void
|
|
|
823
882
|
|
|
824
883
|
##### `isConnected()`
|
|
825
884
|
|
|
826
|
-
Returns the underlying socket if
|
|
885
|
+
Returns the underlying socket if bound, or `null`/`undefined` otherwise.
|
|
827
886
|
|
|
828
887
|
```typescript
|
|
829
888
|
isConnected(): dgram.Socket | null | undefined
|
|
@@ -831,45 +890,25 @@ isConnected(): dgram.Socket | null | undefined
|
|
|
831
890
|
|
|
832
891
|
##### `getClient()`
|
|
833
892
|
|
|
834
|
-
Returns the underlying `dgram.Socket` instance, or `null`/`undefined` if not connected.
|
|
835
|
-
|
|
836
893
|
```typescript
|
|
837
894
|
getClient(): dgram.Socket | null | undefined
|
|
838
895
|
```
|
|
839
896
|
|
|
840
|
-
##### `handleConnected()`
|
|
841
|
-
|
|
842
|
-
Default connection handler. Logs the bind success with host, port, and multicast address.
|
|
843
|
-
|
|
844
|
-
```typescript
|
|
845
|
-
handleConnected(): void
|
|
846
|
-
```
|
|
847
|
-
|
|
848
|
-
##### `handleData(opts)`
|
|
849
|
-
|
|
850
|
-
Default data handler. Logs the received message and remote info.
|
|
851
|
-
|
|
852
|
-
```typescript
|
|
853
|
-
handleData(opts: {
|
|
854
|
-
identifier: string;
|
|
855
|
-
message: string | Buffer;
|
|
856
|
-
remoteInfo: dgram.RemoteInfo;
|
|
857
|
-
}): void
|
|
858
|
-
```
|
|
897
|
+
##### `handleConnected()` / `handleData(opts)` / `handleClosed()` / `handleError(opts)`
|
|
859
898
|
|
|
860
|
-
|
|
899
|
+
Default handlers used when the matching `onConnected`/`onData`/`onClosed`/`onError` option is omitted:
|
|
861
900
|
|
|
862
|
-
|
|
901
|
+
| Handler | Log level | Logged context |
|
|
902
|
+
|---------|-----------|-----------------|
|
|
903
|
+
| `handleConnected` | `info` | `host`, `port`, `multicastAddress` |
|
|
904
|
+
| `handleClosed` | `info` | `host`, `port`, `multicastAddress` |
|
|
905
|
+
| `handleData` | `info` | `host`, `port` only - no `multicastAddress` |
|
|
906
|
+
| `handleError` | `error` | `host`, `port` only - no `multicastAddress` |
|
|
863
907
|
|
|
864
908
|
```typescript
|
|
909
|
+
handleConnected(): void
|
|
910
|
+
handleData(opts: { identifier: string; message: string | Buffer; remoteInfo: dgram.RemoteInfo }): void
|
|
865
911
|
handleClosed(): void
|
|
866
|
-
```
|
|
867
|
-
|
|
868
|
-
##### `handleError(opts)`
|
|
869
|
-
|
|
870
|
-
Default error handler. Logs the error with host and port.
|
|
871
|
-
|
|
872
|
-
```typescript
|
|
873
912
|
handleError(opts: { identifier: string; error: Error }): void
|
|
874
913
|
```
|
|
875
914
|
|
|
@@ -877,24 +916,24 @@ handleError(opts: { identifier: string; error: Error }): void
|
|
|
877
916
|
|
|
878
917
|
## Types Reference
|
|
879
918
|
|
|
880
|
-
### TFetcherVariant
|
|
919
|
+
### TFetcherVariant / TFetcherResponse / TFetcherWorker
|
|
881
920
|
|
|
882
921
|
```typescript
|
|
883
922
|
type TFetcherVariant = 'node-fetch' | 'axios';
|
|
884
|
-
```
|
|
885
|
-
|
|
886
|
-
### TFetcherResponse
|
|
887
923
|
|
|
888
|
-
```typescript
|
|
889
924
|
type TFetcherResponse<T extends TFetcherVariant> =
|
|
890
925
|
T extends 'node-fetch' ? Response : AxiosResponse;
|
|
926
|
+
|
|
927
|
+
type TFetcherWorker<T extends TFetcherVariant> =
|
|
928
|
+
T extends 'axios' ? AxiosInstance : typeof fetch;
|
|
891
929
|
```
|
|
892
930
|
|
|
893
|
-
###
|
|
931
|
+
### THttpMethod
|
|
894
932
|
|
|
895
933
|
```typescript
|
|
896
|
-
type
|
|
897
|
-
|
|
934
|
+
type THttpMethod = ValueOf<typeof HTTP.Methods> | Uppercase<ValueOf<typeof HTTP.Methods>>;
|
|
935
|
+
// 'get' | 'post' | 'put' | 'patch' | 'delete' | 'head' | 'options' | 'query'
|
|
936
|
+
// | 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'QUERY'
|
|
898
937
|
```
|
|
899
938
|
|
|
900
939
|
### ITcpSocketServerOptions
|
|
@@ -907,25 +946,32 @@ interface ITcpSocketServerOptions<
|
|
|
907
946
|
> {
|
|
908
947
|
scope?: string;
|
|
909
948
|
identifier: string;
|
|
949
|
+
|
|
910
950
|
serverOptions: Partial<SocketServerOptions>;
|
|
911
951
|
listenOptions: Partial<ListenOptions>;
|
|
912
952
|
authenticateOptions: { required: boolean; duration?: number };
|
|
953
|
+
|
|
913
954
|
extraEvents?: Record<
|
|
914
955
|
string,
|
|
915
956
|
(opts: { id: string; socket: SocketClientType; args: any }) => ValueOrPromise<void>
|
|
916
957
|
>;
|
|
958
|
+
|
|
917
959
|
createServerFn: (
|
|
918
960
|
options: Partial<SocketServerOptions>,
|
|
919
961
|
connectionListener: (socket: SocketClientType) => void,
|
|
920
962
|
) => SocketServerType;
|
|
963
|
+
|
|
921
964
|
onServerReady?: (opts: { server: SocketServerType }) => void;
|
|
922
965
|
onClientConnected?: (opts: { id: string; socket: SocketClientType }) => void;
|
|
923
966
|
onClientData?: (opts: { id: string; socket: SocketClientType; data: Buffer | string }) => void;
|
|
924
967
|
onClientClose?: (opts: { id: string; socket: SocketClientType }) => void;
|
|
925
968
|
onClientError?: (opts: { id: string; socket: SocketClientType; error: Error }) => void;
|
|
969
|
+
onServerError?: (opts: { server: SocketServerType; error: Error }) => void;
|
|
926
970
|
}
|
|
927
971
|
```
|
|
928
972
|
|
|
973
|
+
`onServerError` fires when the underlying `net`/`tls` server emits `'error'` (for example `EADDRINUSE` from a port already in use) - without this listener the event is unhandled and takes the whole process down; with it, the error is routed here and the process keeps running.
|
|
974
|
+
|
|
929
975
|
### INetworkTcpClientProps
|
|
930
976
|
|
|
931
977
|
```typescript
|
|
@@ -981,6 +1027,6 @@ interface INetworkUdpClientProps {
|
|
|
981
1027
|
}
|
|
982
1028
|
```
|
|
983
1029
|
|
|
984
|
-
## See
|
|
1030
|
+
## See also
|
|
985
1031
|
|
|
986
|
-
- [
|
|
1032
|
+
- [Network overview](/extensions/helpers/network/) - introduction and the most common tasks
|