@tstdl/base 0.93.139 → 0.93.141
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 +166 -0
- package/ai/genkit/multi-region.plugin.js +5 -3
- package/ai/genkit/tests/multi-region.test.d.ts +1 -0
- package/ai/genkit/tests/multi-region.test.js +5 -2
- package/ai/parser/parser.js +2 -2
- package/ai/prompts/build.js +1 -0
- package/ai/prompts/instructions-formatter.d.ts +15 -2
- package/ai/prompts/instructions-formatter.js +36 -31
- package/ai/prompts/prompt-builder.js +5 -5
- package/ai/prompts/steering.d.ts +3 -2
- package/ai/prompts/steering.js +3 -1
- package/ai/tests/instructions-formatter.test.js +1 -0
- package/api/README.md +403 -0
- package/api/client/client.js +7 -13
- package/api/client/tests/api-client.test.js +10 -10
- package/api/default-error-handlers.js +1 -1
- package/api/response.d.ts +2 -2
- package/api/response.js +22 -33
- package/api/server/api-controller.d.ts +1 -1
- package/api/server/api-controller.js +3 -3
- package/api/server/api-request-token.provider.d.ts +1 -0
- package/api/server/api-request-token.provider.js +1 -0
- package/api/server/middlewares/allowed-methods.middleware.js +2 -1
- package/api/server/middlewares/content-type.middleware.js +2 -1
- package/api/types.d.ts +3 -2
- package/application/README.md +240 -0
- package/application/application.d.ts +1 -1
- package/application/application.js +3 -3
- package/application/providers.d.ts +20 -2
- package/application/providers.js +34 -7
- package/audit/README.md +267 -0
- package/audit/module.d.ts +5 -0
- package/audit/module.js +9 -1
- package/authentication/README.md +288 -0
- package/authentication/client/authentication.service.d.ts +12 -11
- package/authentication/client/authentication.service.js +21 -21
- package/authentication/client/http-client.middleware.js +2 -2
- package/authentication/server/module.d.ts +5 -0
- package/authentication/server/module.js +9 -1
- package/authentication/tests/authentication.api-controller.test.js +1 -1
- package/authentication/tests/authentication.api-request-token.provider.test.js +1 -1
- package/authentication/tests/authentication.client-error-handling.test.js +2 -1
- package/authentication/tests/authentication.client-service-refresh.test.js +5 -3
- package/authentication/tests/authentication.client-service.test.js +1 -1
- package/browser/README.md +401 -0
- package/cancellation/README.md +156 -0
- package/cancellation/tests/coverage.test.d.ts +1 -0
- package/cancellation/tests/coverage.test.js +49 -0
- package/cancellation/tests/leak.test.js +24 -29
- package/cancellation/tests/token.test.d.ts +1 -0
- package/cancellation/tests/token.test.js +136 -0
- package/cancellation/token.d.ts +53 -177
- package/cancellation/token.js +132 -208
- package/circuit-breaker/postgres/module.d.ts +1 -0
- package/circuit-breaker/postgres/module.js +5 -1
- package/context/README.md +174 -0
- package/cookie/README.md +161 -0
- package/css/README.md +157 -0
- package/data-structures/README.md +320 -0
- package/decorators/README.md +140 -0
- package/distributed-loop/README.md +231 -0
- package/distributed-loop/distributed-loop.js +1 -1
- package/document-management/README.md +403 -0
- package/document-management/server/configure.js +5 -1
- package/document-management/server/module.d.ts +1 -1
- package/document-management/server/module.js +1 -1
- package/document-management/server/services/document-management-ancillary.service.js +1 -1
- package/document-management/server/services/document-management.service.js +9 -7
- package/document-management/tests/ai-config-hierarchy.test.js +0 -5
- package/document-management/tests/document-management-ai-overrides.test.js +0 -1
- package/document-management/tests/document-management-core.test.js +2 -7
- package/document-management/tests/document-management.api.test.js +6 -7
- package/document-management/tests/document-statistics.service.test.js +11 -12
- package/document-management/tests/document-validation-ai-overrides.test.js +0 -1
- package/document-management/tests/document.service.test.js +3 -3
- package/document-management/tests/enum-helpers.test.js +2 -3
- package/dom/README.md +213 -0
- package/enumerable/README.md +259 -0
- package/enumeration/README.md +121 -0
- package/errors/README.md +267 -0
- package/examples/document-management/main.d.ts +1 -0
- package/examples/document-management/main.js +14 -11
- package/file/README.md +191 -0
- package/formats/README.md +210 -0
- package/function/README.md +144 -0
- package/http/README.md +318 -0
- package/http/client/adapters/undici.adapter.js +1 -1
- package/http/client/http-client-request.d.ts +6 -5
- package/http/client/http-client-request.js +8 -9
- package/http/server/node/node-http-server.js +1 -2
- package/image-service/README.md +137 -0
- package/injector/README.md +491 -0
- package/intl/README.md +113 -0
- package/json-path/README.md +182 -0
- package/jsx/README.md +154 -0
- package/key-value-store/README.md +191 -0
- package/key-value-store/postgres/module.d.ts +1 -0
- package/key-value-store/postgres/module.js +5 -1
- package/lock/README.md +249 -0
- package/lock/postgres/module.d.ts +1 -0
- package/lock/postgres/module.js +5 -1
- package/lock/web/web-lock.js +119 -47
- package/logger/README.md +287 -0
- package/mail/README.md +256 -0
- package/mail/module.d.ts +5 -1
- package/mail/module.js +11 -6
- package/memory/README.md +144 -0
- package/message-bus/README.md +244 -0
- package/message-bus/message-bus-base.js +1 -1
- package/module/README.md +182 -0
- package/module/module.d.ts +1 -1
- package/module/module.js +77 -17
- package/module/modules/web-server.module.js +3 -4
- package/notification/server/module.d.ts +1 -0
- package/notification/server/module.js +5 -1
- package/notification/tests/notification-flow.test.js +2 -2
- package/notification/tests/notification-type.service.test.js +24 -15
- package/object-storage/README.md +300 -0
- package/openid-connect/README.md +274 -0
- package/orm/README.md +423 -0
- package/orm/decorators.d.ts +5 -1
- package/orm/decorators.js +1 -1
- package/orm/server/drizzle/schema-converter.js +17 -30
- package/orm/server/encryption.d.ts +0 -1
- package/orm/server/encryption.js +1 -4
- package/orm/server/index.d.ts +1 -6
- package/orm/server/index.js +1 -6
- package/orm/server/migration.d.ts +19 -0
- package/orm/server/migration.js +72 -0
- package/orm/server/repository.d.ts +1 -1
- package/orm/server/transaction.d.ts +5 -10
- package/orm/server/transaction.js +22 -26
- package/orm/server/transactional.js +3 -3
- package/orm/tests/database-migration.test.d.ts +1 -0
- package/orm/tests/database-migration.test.js +82 -0
- package/orm/tests/encryption.test.js +3 -4
- package/orm/utils.d.ts +17 -2
- package/orm/utils.js +49 -1
- package/package.json +9 -6
- package/password/README.md +164 -0
- package/pdf/README.md +246 -0
- package/polyfills.js +1 -0
- package/pool/README.md +198 -0
- package/process/README.md +237 -0
- package/promise/README.md +252 -0
- package/promise/cancelable-promise.js +1 -1
- package/random/README.md +193 -0
- package/rate-limit/postgres/module.d.ts +1 -0
- package/rate-limit/postgres/module.js +5 -1
- package/reflection/README.md +305 -0
- package/reflection/decorator-data.js +11 -12
- package/rpc/README.md +386 -0
- package/rxjs-utils/README.md +262 -0
- package/schema/README.md +342 -0
- package/serializer/README.md +342 -0
- package/signals/implementation/README.md +134 -0
- package/sse/README.md +278 -0
- package/task-queue/README.md +293 -0
- package/task-queue/postgres/drizzle/{0000_simple_invisible_woman.sql → 0000_wakeful_sunspot.sql} +22 -14
- package/task-queue/postgres/drizzle/meta/0000_snapshot.json +160 -82
- package/task-queue/postgres/drizzle/meta/_journal.json +2 -2
- package/task-queue/postgres/module.d.ts +1 -0
- package/task-queue/postgres/module.js +5 -1
- package/task-queue/postgres/schemas.d.ts +9 -6
- package/task-queue/postgres/schemas.js +4 -3
- package/task-queue/postgres/task-queue.d.ts +4 -13
- package/task-queue/postgres/task-queue.js +462 -355
- package/task-queue/postgres/task.model.d.ts +12 -5
- package/task-queue/postgres/task.model.js +51 -25
- package/task-queue/task-context.d.ts +2 -2
- package/task-queue/task-context.js +8 -8
- package/task-queue/task-queue.d.ts +53 -19
- package/task-queue/task-queue.js +121 -55
- package/task-queue/tests/cascading-cancellations.test.d.ts +1 -0
- package/task-queue/tests/cascading-cancellations.test.js +38 -0
- package/task-queue/tests/complex.test.js +45 -229
- package/task-queue/tests/coverage-branch.test.d.ts +1 -0
- package/task-queue/tests/coverage-branch.test.js +407 -0
- package/task-queue/tests/coverage-enhancement.test.d.ts +1 -0
- package/task-queue/tests/coverage-enhancement.test.js +144 -0
- package/task-queue/tests/dag-dependencies.test.d.ts +1 -0
- package/task-queue/tests/dag-dependencies.test.js +41 -0
- package/task-queue/tests/dependencies.test.js +28 -26
- package/task-queue/tests/extensive-dependencies.test.js +64 -139
- package/task-queue/tests/fan-out-spawning.test.d.ts +1 -0
- package/task-queue/tests/fan-out-spawning.test.js +53 -0
- package/task-queue/tests/idempotent-replacement.test.d.ts +1 -0
- package/task-queue/tests/idempotent-replacement.test.js +61 -0
- package/task-queue/tests/missing-idempotent-tasks.test.d.ts +1 -0
- package/task-queue/tests/missing-idempotent-tasks.test.js +38 -0
- package/task-queue/tests/queue.test.js +128 -8
- package/task-queue/tests/worker.test.js +39 -16
- package/task-queue/tests/zombie-parent.test.d.ts +1 -0
- package/task-queue/tests/zombie-parent.test.js +45 -0
- package/task-queue/tests/zombie-recovery.test.d.ts +1 -0
- package/task-queue/tests/zombie-recovery.test.js +51 -0
- package/templates/README.md +287 -0
- package/test5.js +5 -5
- package/testing/README.md +157 -0
- package/testing/integration-setup.d.ts +4 -4
- package/testing/integration-setup.js +54 -29
- package/text/README.md +346 -0
- package/text/localization.service.js +2 -2
- package/threading/README.md +238 -0
- package/types/README.md +311 -0
- package/utils/README.md +322 -0
- package/utils/async-iterable-helpers/observable-iterable.d.ts +1 -1
- package/utils/async-iterable-helpers/observable-iterable.js +4 -8
- package/utils/async-iterable-helpers/take-until.js +4 -4
- package/utils/backoff.js +89 -30
- package/utils/file-reader.js +1 -2
- package/utils/retry-with-backoff.js +1 -1
- package/utils/timer.d.ts +1 -1
- package/utils/timer.js +5 -7
- package/utils/timing.d.ts +1 -1
- package/utils/timing.js +2 -4
- package/utils/z-base32.d.ts +1 -0
- package/utils/z-base32.js +1 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# @tstdl/base/formats
|
|
2
|
+
|
|
3
|
+
A comprehensive utility module for locale-aware formatting of numbers, dates, times, currencies, and names. It leverages the standard `Intl` API with aggressive memoization to ensure high performance in rendering-heavy applications.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [✨ Features](#-features)
|
|
8
|
+
- [Core Concepts](#core-concepts)
|
|
9
|
+
- [🚀 Basic Usage](#-basic-usage)
|
|
10
|
+
- [🔧 Advanced Topics](#-advanced-topics)
|
|
11
|
+
- [📚 API](#-api)
|
|
12
|
+
|
|
13
|
+
## ✨ Features
|
|
14
|
+
|
|
15
|
+
- **Locale-Aware**: Defaults to `de-DE` (German) but fully configurable.
|
|
16
|
+
- **High Performance**: Uses memoization to cache `Intl.NumberFormat` and `Intl.DateTimeFormat` instances, avoiding expensive instantiation costs.
|
|
17
|
+
- **Type Safety**: Fully typed in TypeScript.
|
|
18
|
+
- **Rich Set of Formatters**:
|
|
19
|
+
- Integers, Decimals, Percentages.
|
|
20
|
+
- Currencies (with and without cents, specific Euro helpers).
|
|
21
|
+
- Dates (Short, Medium, Long, Numeric) and Times.
|
|
22
|
+
- Person Names (First/Last name handling).
|
|
23
|
+
- **Numeric Date Support**: Utilities to format dates stored as integers (e.g., `20231231`).
|
|
24
|
+
|
|
25
|
+
## Core Concepts
|
|
26
|
+
|
|
27
|
+
### Global Configuration
|
|
28
|
+
|
|
29
|
+
The module operates with a global locale setting (defaulting to `de-DE`). This is designed for applications that typically run in a single locale context (like a server-side renderer or a client-side SPA). You can configure this once at startup.
|
|
30
|
+
|
|
31
|
+
### Memoization
|
|
32
|
+
|
|
33
|
+
Creating `Intl.NumberFormat` or `Intl.DateTimeFormat` instances can be slow. This module creates these formatters once per locale/option combination and reuses them. This makes functions like `formatDecimal` or `formatDate` safe to use inside tight loops or render functions.
|
|
34
|
+
|
|
35
|
+
## 🚀 Basic Usage
|
|
36
|
+
|
|
37
|
+
### Configuration
|
|
38
|
+
|
|
39
|
+
Set the locale at the entry point of your application.
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { configureFormats } from '@tstdl/base/formats';
|
|
43
|
+
|
|
44
|
+
// Set to US English
|
|
45
|
+
configureFormats({ locale: 'en-US' });
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Number Formatting
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { formatInteger, formatDecimal, formatPercent } from '@tstdl/base/formats';
|
|
52
|
+
|
|
53
|
+
// Assuming locale is de-DE
|
|
54
|
+
console.log(formatInteger(12345.67));
|
|
55
|
+
// Output: "12.346" (rounded)
|
|
56
|
+
|
|
57
|
+
console.log(formatDecimal(12345.6789));
|
|
58
|
+
// Output: "12.345,68" (default 2 fraction digits)
|
|
59
|
+
|
|
60
|
+
console.log(formatDecimal(12345.6789, { minimumFractionDigits: 3, maximumFractionDigits: 4 }));
|
|
61
|
+
// Output: "12.345,679" (min 3, max 4 fraction digits)
|
|
62
|
+
|
|
63
|
+
console.log(formatPercent(0.1234));
|
|
64
|
+
// Output: "12,34 %"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Currency Formatting
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import { formatEuro, formatCurrency, formatCurrencyWithoutCents } from '@tstdl/base/formats';
|
|
71
|
+
|
|
72
|
+
console.log(formatEuro(1500.5));
|
|
73
|
+
// Output: "1.500,50 €"
|
|
74
|
+
|
|
75
|
+
console.log(formatCurrency(1500.5, 'USD'));
|
|
76
|
+
// Output: "1.500,50 $" (Format depends on locale, symbol depends on currency)
|
|
77
|
+
|
|
78
|
+
console.log(formatCurrencyWithoutCents(1500.5, 'EUR'));
|
|
79
|
+
// Output: "1.501 €" (Rounded)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Date and Time Formatting
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
import { formatDate, formatDateShort, formatTimeShort } from '@tstdl/base/formats';
|
|
86
|
+
|
|
87
|
+
const date = new Date('2023-10-05T14:30:00');
|
|
88
|
+
|
|
89
|
+
console.log(formatDate(date));
|
|
90
|
+
// Output: "05.10.2023" (Standard date format for de-DE)
|
|
91
|
+
|
|
92
|
+
console.log(formatDateShort(date));
|
|
93
|
+
// Output: "05.10.2023"
|
|
94
|
+
|
|
95
|
+
// formatTimeShort expects milliseconds for the time portion
|
|
96
|
+
// (Internally often used with durations or specific times of day)
|
|
97
|
+
console.log(formatTimeShort(date));
|
|
98
|
+
// Output: "14:30"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## 🔧 Advanced Topics
|
|
102
|
+
|
|
103
|
+
### Formatting Person Names
|
|
104
|
+
|
|
105
|
+
The `formatPersonName` helper handles objects with `firstName` and `lastName` properties, dealing with nulls and formatting preferences.
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { formatPersonName } from '@tstdl/base/formats';
|
|
109
|
+
|
|
110
|
+
const user = { firstName: 'John', lastName: 'Doe' };
|
|
111
|
+
const incompleteUser = { firstName: null, lastName: 'Doe' };
|
|
112
|
+
|
|
113
|
+
console.log(formatPersonName(user));
|
|
114
|
+
// Output: "John Doe"
|
|
115
|
+
|
|
116
|
+
console.log(formatPersonName(user, { lastNameFirst: true }));
|
|
117
|
+
// Output: "Doe, John"
|
|
118
|
+
|
|
119
|
+
console.log(formatPersonName(incompleteUser));
|
|
120
|
+
// Output: "Doe"
|
|
121
|
+
|
|
122
|
+
console.log(formatPersonName(null, { fallback: 'Anonymous' }));
|
|
123
|
+
// Output: "Anonymous"
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Numeric Dates
|
|
127
|
+
|
|
128
|
+
Often databases store dates as integers (e.g., `20231231`) for indexing efficiency. The `formatNumericDate` function handles this conversion automatically.
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
import { formatNumericDate } from '@tstdl/base/formats';
|
|
132
|
+
|
|
133
|
+
// Formats integer 20231231 as a date
|
|
134
|
+
console.log(formatNumericDate(20231231));
|
|
135
|
+
// Output: "31.12.2023"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Custom Number Formatting
|
|
139
|
+
|
|
140
|
+
You can pass standard `Intl.NumberFormatOptions` to `formatNumber` for one-off requirements that aren't covered by the standard helpers.
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
import { formatNumber } from '@tstdl/base/formats';
|
|
144
|
+
|
|
145
|
+
console.log(
|
|
146
|
+
formatNumber(1234.567, {
|
|
147
|
+
style: 'unit',
|
|
148
|
+
unit: 'kilometer',
|
|
149
|
+
maximumFractionDigits: 1,
|
|
150
|
+
}),
|
|
151
|
+
);
|
|
152
|
+
// Output: "1.234,6 km"
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## 📚 API
|
|
156
|
+
|
|
157
|
+
### Configuration
|
|
158
|
+
|
|
159
|
+
| Function | Description |
|
|
160
|
+
| :-------------------------- | :--------------------------------------------------------------------------------------- |
|
|
161
|
+
| `configureFormats(options)` | Sets the global locale used by all formatters. Default is `de-DE`. Can be a static string or a provider function. |
|
|
162
|
+
|
|
163
|
+
### Number Formatters
|
|
164
|
+
|
|
165
|
+
| Function | Description |
|
|
166
|
+
| :----------------------------- | :-------------------------------------------------------------- |
|
|
167
|
+
| `formatNumber(value, format?)` | Formats a number using optional `Intl.NumberFormatOptions`. |
|
|
168
|
+
| `formatInteger(value, format?)` | Formats as an integer (0 fraction digits). |
|
|
169
|
+
| `formatDecimal(value, format?)` | Formats as a decimal. Default min/max fraction digits is 2. |
|
|
170
|
+
| `formatPercent(value, format?)` | Formats a ratio (0-1) as a percentage (0-100%). |
|
|
171
|
+
|
|
172
|
+
### Currency Formatters
|
|
173
|
+
|
|
174
|
+
| Function | Description |
|
|
175
|
+
| :-------------------------------------------- | :------------------------------------------------------- |
|
|
176
|
+
| `formatCurrency(value, currency, format?)` | Formats value as currency (e.g., 'EUR', 'USD'). |
|
|
177
|
+
| `formatCurrencyWithoutCents(value, currency, format?)` | Formats currency rounded to the nearest integer. |
|
|
178
|
+
| `formatEuro(value, format?)` | Shortcut for `formatCurrency(value, 'EUR')`. |
|
|
179
|
+
| `formatEuroWithoutCents(value, format?)` | Shortcut for `formatCurrencyWithoutCents(value, 'EUR')`. |
|
|
180
|
+
|
|
181
|
+
### Date & Time Formatters
|
|
182
|
+
|
|
183
|
+
| Function | Description |
|
|
184
|
+
| :------------------------------------ | :------------------------------------------------------------------------- |
|
|
185
|
+
| `formatDateTime(value, format?)` | Formats a `Date`, timestamp or `DateTime` object using optional `Intl.DateTimeFormatOptions`. |
|
|
186
|
+
| `formatDate(dateOrTimestamp, format?)` | Formats using `dateShort` options (numeric day, month, 2-digit year). |
|
|
187
|
+
| `formatDateShort(value, format?)` | Alias for `formatDate`. |
|
|
188
|
+
| `formatTimeShort(value, format?)` | Formats a time value to `HH:MM`. |
|
|
189
|
+
| `formatNumericDate(numericDate, options?)` | Converts a `YYYYMMDD` integer to a formatted date string (`dateShort`). |
|
|
190
|
+
| `formatNumericDateShort(numericDate, options?)` | Alias for `formatNumericDate`. |
|
|
191
|
+
| `formatNumericDateLong(numericDate, options?)` | Converts a `YYYYMMDD` integer to a long date format (`dateLong`). |
|
|
192
|
+
|
|
193
|
+
### Utilities
|
|
194
|
+
|
|
195
|
+
| Function | Description |
|
|
196
|
+
| :----------------------------------- | :--------------------------------------------------------------------------------------------------------- |
|
|
197
|
+
| `formatPersonName(person, options?)` | Formats a name from an object `{ firstName?, lastName? }`. Options include `lastNameFirst` and `fallback`. |
|
|
198
|
+
|
|
199
|
+
### Constants (Format Options)
|
|
200
|
+
|
|
201
|
+
The module exports standard `Intl` configuration objects used internally. These can be useful if you need to instantiate your own formatters with the same styles.
|
|
202
|
+
|
|
203
|
+
- `integerFormat`
|
|
204
|
+
- `decimalFormat`
|
|
205
|
+
- `decimal1Format`
|
|
206
|
+
- `dateTimeNumeric`, `dateTimeShort`, `dateTimeLong`
|
|
207
|
+
- `dateShort`, `dateMedium`, `dateLong`
|
|
208
|
+
- `timeShort`
|
|
209
|
+
- `currencyFormat`, `currencyFormatWithoutCents`
|
|
210
|
+
- `percentFormat`
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Function
|
|
2
|
+
|
|
3
|
+
A utility module providing tools for function manipulation and debugging. It currently focuses on transparently wrapping functions to log execution details, arguments, and return values.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [✨ Features](#-features)
|
|
8
|
+
- [Core Concepts](#core-concepts)
|
|
9
|
+
- [🚀 Basic Usage](#-basic-usage)
|
|
10
|
+
- [🔧 Advanced Topics](#-advanced-topics)
|
|
11
|
+
- [Custom Logger](#custom-logger)
|
|
12
|
+
- [Enabling Stack Traces](#enabling-stack-traces)
|
|
13
|
+
- [📚 API](#-api)
|
|
14
|
+
|
|
15
|
+
## ✨ Features
|
|
16
|
+
|
|
17
|
+
- **Transparent Logging**: Wrap any function to automatically log when it is called and what it returns.
|
|
18
|
+
- **Argument Formatting**: Automatically formats primitive arguments and arrays for readable log output.
|
|
19
|
+
- **Custom Loggers**: Integrate with the `@tstdl/base/logger` or any compatible logger interface.
|
|
20
|
+
- **Stack Traces**: Optionally print stack traces on every call for deep debugging.
|
|
21
|
+
- **Metadata Control**: Override the function name used in logs for better context.
|
|
22
|
+
|
|
23
|
+
## Core Concepts
|
|
24
|
+
|
|
25
|
+
The `function` module provides high-order functions that take an existing function and return a new one with added behavior.
|
|
26
|
+
|
|
27
|
+
### Function Wrapping
|
|
28
|
+
|
|
29
|
+
The primary utility, `wrapLog`, acts as a functional decorator. It intercepts calls to the target function, logs the arguments, executes the original function, and then logs the result. This is particularly useful for debugging complex logic flows or inspecting data transformations without modifying the original source code with temporary `console.log` statements.
|
|
30
|
+
|
|
31
|
+
## 🚀 Basic Usage
|
|
32
|
+
|
|
33
|
+
The most common use case is wrapping a function to see its inputs and outputs in the console.
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { wrapLog } from '@tstdl/base/function';
|
|
37
|
+
|
|
38
|
+
function calculateSum(a: number, b: number): number {
|
|
39
|
+
return a + b;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Wrap the function. By default, it uses console.log (via console.log.bind(console))
|
|
43
|
+
const loggedCalculateSum = wrapLog(calculateSum);
|
|
44
|
+
|
|
45
|
+
// Execute the wrapped function
|
|
46
|
+
loggedCalculateSum(5, 10);
|
|
47
|
+
|
|
48
|
+
// Console Output:
|
|
49
|
+
// [call: calculateSum(5, 10)]
|
|
50
|
+
// [return: calculateSum => 15]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 🔧 Advanced Topics
|
|
54
|
+
|
|
55
|
+
### Custom Logger
|
|
56
|
+
|
|
57
|
+
You can direct the output to a specific logger instance (e.g., from `@tstdl/base/logger`) instead of `console.log`. The wrapper uses the `trace` method of the logger.
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { wrapLog } from '@tstdl/base/function';
|
|
61
|
+
import { Logger } from '@tstdl/base/logger';
|
|
62
|
+
import { inject } from '@tstdl/base/injector';
|
|
63
|
+
|
|
64
|
+
class MathService {
|
|
65
|
+
private logger = inject(Logger, 'MathService');
|
|
66
|
+
|
|
67
|
+
add(a: number, b: number): number {
|
|
68
|
+
return a + b;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
constructor() {
|
|
72
|
+
// Replace the method with a logged version using the service's logger
|
|
73
|
+
this.add = wrapLog(this.add.bind(this), {
|
|
74
|
+
logger: this.logger,
|
|
75
|
+
fnName: 'MathService.add', // Custom name for clearer logs
|
|
76
|
+
}) as any;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Enabling Stack Traces
|
|
82
|
+
|
|
83
|
+
For debugging call chains, you can enable the `trace` option. This will output a stack trace every time the function is called.
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
import { wrapLog } from '@tstdl/base/function';
|
|
87
|
+
|
|
88
|
+
function criticalOperation() {
|
|
89
|
+
// ... logic
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const debugOperation = wrapLog(criticalOperation, {
|
|
93
|
+
trace: true,
|
|
94
|
+
logResult: false, // Only log the call and trace, ignore the return value
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
debugOperation();
|
|
98
|
+
// Output:
|
|
99
|
+
// [call: criticalOperation()]
|
|
100
|
+
// Trace: ... (stack trace)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## 📚 API
|
|
104
|
+
|
|
105
|
+
### Functions
|
|
106
|
+
|
|
107
|
+
| Function | Description |
|
|
108
|
+
| :---------------------- | :--------------------------------------------------------------- |
|
|
109
|
+
| `wrapLog(fn, options?)` | Wraps a function to log its calls, arguments, and return values. |
|
|
110
|
+
|
|
111
|
+
### Types
|
|
112
|
+
|
|
113
|
+
| Type | Description |
|
|
114
|
+
| :--------------- | :---------------------------------- |
|
|
115
|
+
| `WrapLogOptions` | Configuration object for `wrapLog`. |
|
|
116
|
+
|
|
117
|
+
#### WrapLogOptions
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
type WrapLogOptions = {
|
|
121
|
+
/**
|
|
122
|
+
* The name to use in log messages. Defaults to fn.name.
|
|
123
|
+
*/
|
|
124
|
+
fnName?: string;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Whether to log the return value of the function.
|
|
128
|
+
* Default: true
|
|
129
|
+
*/
|
|
130
|
+
logResult?: boolean;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* A Logger instance to use. If not provided, defaults to console.log.
|
|
134
|
+
* The wrapper calls logger.trace().
|
|
135
|
+
*/
|
|
136
|
+
logger?: Logger;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Whether to print a stack trace (console.trace) on execution.
|
|
140
|
+
* Default: false
|
|
141
|
+
*/
|
|
142
|
+
trace?: boolean;
|
|
143
|
+
};
|
|
144
|
+
```
|
package/http/README.md
ADDED
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
# @tstdl/base/http
|
|
2
|
+
|
|
3
|
+
A powerful, isomorphic, middleware-based HTTP client and server library for TypeScript. This module provides a comprehensive suite of tools for handling HTTP communication, featuring a flexible client with a middleware pipeline and a modern, async-iterable-based server abstraction.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [✨ Features](#-features)
|
|
8
|
+
- [Core Concepts](#core-concepts)
|
|
9
|
+
- [HTTP Client](#http-client)
|
|
10
|
+
- [HTTP Server](#http-server)
|
|
11
|
+
- [Isomorphic Utilities](#isomorphic-utilities)
|
|
12
|
+
- [🚀 Basic Usage](#-basic-usage)
|
|
13
|
+
- [Client Setup](#client-setup)
|
|
14
|
+
- [Making Requests](#making-requests)
|
|
15
|
+
- [Server Setup](#server-setup)
|
|
16
|
+
- [Handling Requests](#handling-requests)
|
|
17
|
+
- [🔧 Advanced Topics](#-advanced-topics)
|
|
18
|
+
- [Client Middleware](#client-middleware)
|
|
19
|
+
- [Streaming Data](#streaming-data)
|
|
20
|
+
- [Error Handling](#error-handling)
|
|
21
|
+
- [Automatic Parameter Mapping](#automatic-parameter-mapping)
|
|
22
|
+
- [📚 API](#-api)
|
|
23
|
+
|
|
24
|
+
## ✨ Features
|
|
25
|
+
|
|
26
|
+
- **Isomorphic Design:** Shared abstractions for client and server, with specific adapters for different environments (e.g., `undici` for Node.js).
|
|
27
|
+
- **Middleware-Driven Client:** Intercept and modify requests/responses using a flexible async middleware pipeline for concerns like logging, authentication, and caching.
|
|
28
|
+
- **Pluggable Client Adapter:** The `HttpClientAdapter` allows swapping the underlying HTTP engine. `UndiciHttpClientAdapter` is provided for high-performance Node.js applications.
|
|
29
|
+
- **Modern Server Abstraction:** The `HttpServer` uses an async iterator pattern (`for await...of`) for elegant and efficient request handling.
|
|
30
|
+
- **Advanced Body Handling:** Seamlessly works with JSON, text, forms (`x-www-form-urlencoded`), `FormData`, binary (`Uint8Array`, `Blob`), and `ReadableStream`.
|
|
31
|
+
- **Automatic Parameter Mapping:** Intelligently maps request parameters to URL path segments, query strings, or the request body.
|
|
32
|
+
- **Typed API:** Strongly typed interfaces for requests, responses, headers, and query parameters to catch errors at compile time.
|
|
33
|
+
- **Utility Classes:** Helpers like `HttpHeaders`, `HttpQuery`, and `HttpForm` simplify common tasks.
|
|
34
|
+
|
|
35
|
+
## Core Concepts
|
|
36
|
+
|
|
37
|
+
### HTTP Client
|
|
38
|
+
|
|
39
|
+
The client is designed around three main components: `HttpClient`, `HttpClientAdapter`, and `HttpClientMiddleware`.
|
|
40
|
+
|
|
41
|
+
- **`HttpClient`**: The primary interface for making requests. It manages configuration, default headers, and the middleware pipeline. It offers convenience methods like `getJson()`, `post()`, etc. The flow of a request is: `HttpClient` -> `Middleware Chain` -> `HttpClientAdapter`.
|
|
42
|
+
- **`HttpClientAdapter`**: The "engine" that performs the actual HTTP call. The library is decoupled from any specific implementation. For Node.js, the `UndiciHttpClientAdapter` is provided, which uses the high-performance `undici` library.
|
|
43
|
+
- **`HttpClientMiddleware`**: A function that intercepts a request before it's sent and the response after it's received. Middleware is composed into a pipeline.
|
|
44
|
+
|
|
45
|
+
### HTTP Server
|
|
46
|
+
|
|
47
|
+
The server implementation is based on the `HttpServer` abstract class.
|
|
48
|
+
|
|
49
|
+
- **`HttpServer`**: An async iterable that yields a `HttpServerRequestContext` for each incoming connection. This design promotes a clean, modern loop for processing requests (`for await (const context of server)`).
|
|
50
|
+
- **`HttpServerRequestContext`**: Encapsulates the `request` (incoming) and a `respond` function (outgoing).
|
|
51
|
+
- **`NodeHttpServer`**: The default implementation of `HttpServer` for Node.js, built on top of the native `node:http` module.
|
|
52
|
+
|
|
53
|
+
### Isomorphic Utilities
|
|
54
|
+
|
|
55
|
+
- **`HttpHeaders`**: A map-like class for managing HTTP headers with typed getters for common headers (e.g., `contentType`, `contentLength`).
|
|
56
|
+
- **`HttpBody`**: A unified interface for reading request/response bodies. It supports reading as JSON, text, buffer, or stream, regardless of the source (Node stream, Blob, etc.).
|
|
57
|
+
|
|
58
|
+
## 🚀 Basic Usage
|
|
59
|
+
|
|
60
|
+
### Client Setup
|
|
61
|
+
|
|
62
|
+
To use the client in a Node.js environment, you need to configure the `UndiciHttpClientAdapter`.
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { HttpClient, configureHttpClient } from '@tstdl/base/http';
|
|
66
|
+
import { configureUndiciHttpClientAdapter } from '@tstdl/base/http/undici';
|
|
67
|
+
import { Injector } from '@tstdl/base/injector';
|
|
68
|
+
|
|
69
|
+
// 1. Configure the adapter (Node.js specific)
|
|
70
|
+
configureUndiciHttpClientAdapter({ register: true });
|
|
71
|
+
|
|
72
|
+
// 2. Configure the client (optional base URL)
|
|
73
|
+
configureHttpClient({
|
|
74
|
+
baseUrl: 'https://api.example.com',
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// 3. Resolve the client
|
|
78
|
+
const httpClient = Injector.resolve(HttpClient);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Making Requests
|
|
82
|
+
|
|
83
|
+
The `HttpClient` provides methods for standard HTTP verbs (`get`, `post`, `put`, `patch`, `delete`, `head`).
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
// GET JSON
|
|
87
|
+
type User = { id: number; name: string };
|
|
88
|
+
const user = await httpClient.getJson<User>('/users/1');
|
|
89
|
+
console.log(user.name);
|
|
90
|
+
|
|
91
|
+
// POST JSON
|
|
92
|
+
const newUser = { name: 'Alice' };
|
|
93
|
+
const createdUser = await httpClient.postJson<User>('/users', {
|
|
94
|
+
body: { json: newUser },
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// GET with Query Parameters
|
|
98
|
+
// Result: GET /search?q=typescript&limit=10
|
|
99
|
+
const results = await httpClient.getJson('/search', {
|
|
100
|
+
query: { q: 'typescript', limit: 10 },
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Server Setup
|
|
105
|
+
|
|
106
|
+
Configure and run the `NodeHttpServer`.
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
import { HttpServer } from '@tstdl/base/http/server';
|
|
110
|
+
import { configureNodeHttpServer } from '@tstdl/base/http/node';
|
|
111
|
+
import { Injector } from '@tstdl/base/injector';
|
|
112
|
+
|
|
113
|
+
// 1. Register the Node.js server implementation
|
|
114
|
+
configureNodeHttpServer();
|
|
115
|
+
|
|
116
|
+
// 2. Resolve the server
|
|
117
|
+
const httpServer = Injector.resolve(HttpServer);
|
|
118
|
+
|
|
119
|
+
// 3. Start listening
|
|
120
|
+
await httpServer.listen(3000);
|
|
121
|
+
console.log('Server listening on port 3000');
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Handling Requests
|
|
125
|
+
|
|
126
|
+
Use the async iterator pattern to handle incoming requests sequentially or concurrently.
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import { HttpServerResponse } from '@tstdl/base/http/server';
|
|
130
|
+
|
|
131
|
+
// Loop through incoming requests
|
|
132
|
+
for await (const context of httpServer) {
|
|
133
|
+
const { request, respond } = context;
|
|
134
|
+
|
|
135
|
+
// Handle request asynchronously
|
|
136
|
+
(async () => {
|
|
137
|
+
try {
|
|
138
|
+
if (request.url.pathname === '/hello') {
|
|
139
|
+
await respond(
|
|
140
|
+
new HttpServerResponse({
|
|
141
|
+
statusCode: 200,
|
|
142
|
+
body: { text: 'Hello World!' },
|
|
143
|
+
}),
|
|
144
|
+
);
|
|
145
|
+
} else {
|
|
146
|
+
await respond(
|
|
147
|
+
new HttpServerResponse({
|
|
148
|
+
statusCode: 404,
|
|
149
|
+
statusMessage: 'Not Found',
|
|
150
|
+
}),
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
} catch (error) {
|
|
154
|
+
console.error(error);
|
|
155
|
+
await respond(new HttpServerResponse({ statusCode: 500 }));
|
|
156
|
+
} finally {
|
|
157
|
+
// Ensure the connection is closed if needed (handled by respond usually)
|
|
158
|
+
await context.close();
|
|
159
|
+
}
|
|
160
|
+
})();
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## 🔧 Advanced Topics
|
|
165
|
+
|
|
166
|
+
### Client Middleware
|
|
167
|
+
|
|
168
|
+
Middleware allows you to intercept requests and responses. This is useful for authentication, logging, or modifying headers.
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
import { HttpClient, configureHttpClient, type HttpClientMiddleware, type HttpClientMiddlewareContext, type HttpClientMiddlewareNext } from '@tstdl/base/http';
|
|
172
|
+
import { configureUndiciHttpClientAdapter } from '@tstdl/base/http/undici';
|
|
173
|
+
import { Injector } from '@tstdl/base/injector';
|
|
174
|
+
|
|
175
|
+
const authMiddleware: HttpClientMiddleware = async (context: HttpClientMiddlewareContext, next: HttpClientMiddlewareNext) => {
|
|
176
|
+
// Pre-request logic
|
|
177
|
+
context.request.headers.set('Authorization', 'Bearer my-token');
|
|
178
|
+
|
|
179
|
+
// Execute next middleware / adapter
|
|
180
|
+
await next();
|
|
181
|
+
|
|
182
|
+
// Post-response logic
|
|
183
|
+
if (context.response?.statusCode === 401) {
|
|
184
|
+
console.warn('Unauthorized request!');
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
configureUndiciHttpClientAdapter({ register: true });
|
|
189
|
+
configureHttpClient({
|
|
190
|
+
middleware: [authMiddleware],
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
const client = Injector.resolve(HttpClient);
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Streaming Data
|
|
197
|
+
|
|
198
|
+
Both the client and server support streaming, which is essential for large files or real-time data.
|
|
199
|
+
|
|
200
|
+
**Client Streaming (Download):**
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
const stream = httpClient.getBinaryStream('/large-file.zip');
|
|
204
|
+
// stream is a ReadableStream<Uint8Array>
|
|
205
|
+
|
|
206
|
+
for await (const chunk of stream) {
|
|
207
|
+
console.log(`Received chunk of size: ${chunk.length}`);
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Server Streaming (Response):**
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
import { HttpServerResponse } from '@tstdl/base/http/server';
|
|
215
|
+
import { readableStreamFromPromise } from '@tstdl/base/utils/stream';
|
|
216
|
+
|
|
217
|
+
// ... inside request loop
|
|
218
|
+
await respond(
|
|
219
|
+
new HttpServerResponse({
|
|
220
|
+
statusCode: 200,
|
|
221
|
+
headers: { 'Content-Type': 'text/plain' },
|
|
222
|
+
body: {
|
|
223
|
+
// Create a stream that yields data
|
|
224
|
+
stream: readableStreamFromPromise(async function* () {
|
|
225
|
+
yield new TextEncoder().encode('Chunk 1\n');
|
|
226
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
227
|
+
yield new TextEncoder().encode('Chunk 2\n');
|
|
228
|
+
}),
|
|
229
|
+
},
|
|
230
|
+
}),
|
|
231
|
+
);
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Error Handling
|
|
235
|
+
|
|
236
|
+
The `HttpClient` automatically throws an `HttpError` for non-2xx responses if `throwOnNon200` is true (default).
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
import { HttpError, HttpErrorReason } from '@tstdl/base/http';
|
|
240
|
+
|
|
241
|
+
try {
|
|
242
|
+
await httpClient.get('/non-existent');
|
|
243
|
+
} catch (error) {
|
|
244
|
+
if (error instanceof HttpError) {
|
|
245
|
+
console.log('Reason:', error.reason); // e.g., HttpErrorReason.StatusCode
|
|
246
|
+
console.log('Status:', error.response?.statusCode); // 404
|
|
247
|
+
|
|
248
|
+
// Access the response body if needed
|
|
249
|
+
const body = await error.responseInstance?.body.readAsText();
|
|
250
|
+
console.log('Error Body:', body);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Automatic Parameter Mapping
|
|
256
|
+
|
|
257
|
+
The `HttpClientRequest` can automatically map a `parameters` object to the URL path, query string, or body based on the URL pattern and HTTP method.
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
// URL: /users/:userId
|
|
261
|
+
// Method: GET
|
|
262
|
+
// Result: GET /users/123?details=true
|
|
263
|
+
await httpClient.getJson('/users/:userId', {
|
|
264
|
+
parameters: {
|
|
265
|
+
userId: 123, // Mapped to URL path because :userId exists
|
|
266
|
+
details: true, // Mapped to Query because it's GET and not in URL path
|
|
267
|
+
},
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
// URL: /users
|
|
271
|
+
// Method: POST
|
|
272
|
+
// Result: POST /users with JSON body { name: 'Bob' }
|
|
273
|
+
await httpClient.postJson('/users', {
|
|
274
|
+
parameters: {
|
|
275
|
+
name: 'Bob', // Mapped to Body because it's POST and no URL params match
|
|
276
|
+
},
|
|
277
|
+
});
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## 📚 API
|
|
281
|
+
|
|
282
|
+
### Configuration Functions
|
|
283
|
+
|
|
284
|
+
| Function | Description |
|
|
285
|
+
| :------------------------------------------ | :------------------------------------------------------------------- |
|
|
286
|
+
| `configureHttpClient(config)` | Configures the global `HttpClient` options, adapter, and middleware. |
|
|
287
|
+
| `configureUndiciHttpClientAdapter(options)` | Configures and registers the `UndiciHttpClientAdapter` (Node.js). |
|
|
288
|
+
| `configureNodeHttpServer(config)` | Registers the `NodeHttpServer` as the default `HttpServer`. |
|
|
289
|
+
|
|
290
|
+
### Client
|
|
291
|
+
|
|
292
|
+
| Class | Description |
|
|
293
|
+
| :------------------------ | :-------------------------------------------------------------------------------- |
|
|
294
|
+
| `HttpClient` | Main service for making HTTP requests. |
|
|
295
|
+
| `HttpClientRequest` | Represents an outgoing request. Handles parameter mapping and body normalization. |
|
|
296
|
+
| `HttpClientResponse` | Represents an incoming response. Provides access to status, headers, and body. |
|
|
297
|
+
| `HttpClientAdapter` | Abstract base class for HTTP adapters. |
|
|
298
|
+
| `UndiciHttpClientAdapter` | Adapter implementation using `undici` (Node.js). |
|
|
299
|
+
|
|
300
|
+
### Server
|
|
301
|
+
|
|
302
|
+
| Class | Description |
|
|
303
|
+
| :------------------- | :---------------------------------------------------------------- |
|
|
304
|
+
| `HttpServer` | Abstract base class for HTTP servers. Implements `AsyncIterable`. |
|
|
305
|
+
| `NodeHttpServer` | Server implementation using `node:http`. |
|
|
306
|
+
| `HttpServerRequest` | Represents an incoming request on the server. |
|
|
307
|
+
| `HttpServerResponse` | Represents an outgoing response from the server. |
|
|
308
|
+
|
|
309
|
+
### Shared / Utilities
|
|
310
|
+
|
|
311
|
+
| Class | Description |
|
|
312
|
+
| :------------- | :----------------------------------------------------------------------- |
|
|
313
|
+
| `HttpHeaders` | Typed wrapper around HTTP headers. |
|
|
314
|
+
| `HttpBody` | Helper to read request/response bodies as Text, JSON, Buffer, or Stream. |
|
|
315
|
+
| `HttpQuery` | Helper for managing URL query parameters. |
|
|
316
|
+
| `HttpForm` | Helper for `application/x-www-form-urlencoded` data. |
|
|
317
|
+
| `HttpError` | Error thrown when requests fail or return non-success status codes. |
|
|
318
|
+
| `CookieParser` | Utility to parse `Cookie` headers. |
|
|
@@ -53,7 +53,7 @@ let UndiciHttpClientAdapter = class UndiciHttpClientAdapter extends HttpClientAd
|
|
|
53
53
|
try {
|
|
54
54
|
const response = await request(httpClientRequest.url, {
|
|
55
55
|
method: httpClientRequest.method,
|
|
56
|
-
signal: httpClientRequest.abortSignal
|
|
56
|
+
signal: httpClientRequest.cancellationSignal.abortSignal,
|
|
57
57
|
headers: httpClientRequest.headers.asNormalizedObject(),
|
|
58
58
|
body,
|
|
59
59
|
headersTimeout: httpClientRequest.timeout,
|