nestjs-httpf 0.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/LICENSE +21 -0
- package/README.md +324 -0
- package/dist/create-httpf-async-iterable.d.ts +2 -0
- package/dist/create-httpf-async-iterable.js +76 -0
- package/dist/create-httpf-async-iterable.js.map +1 -0
- package/dist/fx-async-iterable.interface.d.ts +2 -0
- package/dist/fx-async-iterable.interface.js +3 -0
- package/dist/fx-async-iterable.interface.js.map +1 -0
- package/dist/httpf-async-iterable.interface.d.ts +6 -0
- package/dist/httpf-async-iterable.interface.js +3 -0
- package/dist/httpf-async-iterable.interface.js.map +1 -0
- package/dist/httpf-module-option.interface.d.ts +16 -0
- package/dist/httpf-module-option.interface.js +3 -0
- package/dist/httpf-module-option.interface.js.map +1 -0
- package/dist/httpf.constants.d.ts +2 -0
- package/dist/httpf.constants.js +6 -0
- package/dist/httpf.constants.js.map +1 -0
- package/dist/httpf.module.d.ts +8 -0
- package/dist/httpf.module.js +91 -0
- package/dist/httpf.module.js.map +1 -0
- package/dist/httpf.service.d.ts +14 -0
- package/dist/httpf.service.js +83 -0
- package/dist/httpf.service.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +87 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020-2022 Kamil Mysliwiec
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
# nestjs-httpf
|
|
2
|
+
|
|
3
|
+
> Functional-style HTTP client for NestJS
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/nestjs-httpf)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Functional Style**: Handle complex API requests safely and declaratively
|
|
11
|
+
- **Language-Friendly**: Promise-based instead of Observable, enabling direct use of async/await
|
|
12
|
+
- **AsyncIterable-Based**: Leverages FxTS's [AsyncIterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_async_iterator_and_async_iterable_protocols) for efficient data processing through lazy evaluation and function composition
|
|
13
|
+
- **Retry Support**: Automatically retry failed requests
|
|
14
|
+
- **Error Handling**: Use `catchError` to treat errors as values instead of try-catch
|
|
15
|
+
- **FxTS Integration**: Access various helper functions from the [FxTS](https://fxts.dev/) library
|
|
16
|
+
- **Got-Based**: Uses the powerful and reliable [Got](https://github.com/sindresorhus/got) HTTP client
|
|
17
|
+
|
|
18
|
+
## Background
|
|
19
|
+
|
|
20
|
+
NestJS's built-in HTTP module provides an excellent way to safely handle complex API processing by applying RxJS's reactive programming. However, since it returns RxJS Observable objects, you need to extract values through operators like `firstValueFrom`, which can be cumbersome.
|
|
21
|
+
|
|
22
|
+
**nestjs-httpf** solves this inconvenience and allows you to handle asynchronous operations in a more language-friendly way:
|
|
23
|
+
|
|
24
|
+
- ✅ Directly work with Promises, enabling `await` usage
|
|
25
|
+
- ✅ Write asynchronous processing declaratively with functional style
|
|
26
|
+
- ✅ Compose functions with the FxTS library for various features
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install nestjs-httpf @fxts/core
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
or
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
yarn add nestjs-httpf @fxts/core
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
or
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pnpm add nestjs-httpf @fxts/core
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Quick Start
|
|
47
|
+
|
|
48
|
+
### 1. Register the Module
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
import { Module } from '@nestjs/common';
|
|
52
|
+
import { HttpfModule } from 'nestjs-httpf';
|
|
53
|
+
|
|
54
|
+
@Module({
|
|
55
|
+
imports: [HttpfModule],
|
|
56
|
+
})
|
|
57
|
+
export class AppModule {}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 2. Use in a Service
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { Injectable } from '@nestjs/common';
|
|
64
|
+
import { HttpfService } from 'nestjs-httpf';
|
|
65
|
+
|
|
66
|
+
@Injectable()
|
|
67
|
+
export class UserService {
|
|
68
|
+
constructor(private readonly httpfService: HttpfService) {}
|
|
69
|
+
|
|
70
|
+
async getUser(id: string) {
|
|
71
|
+
const user = await this.httpfService
|
|
72
|
+
.get<User>(`https://api.example.com/users/${id}`)
|
|
73
|
+
.map((response) => response.body)
|
|
74
|
+
.head();
|
|
75
|
+
|
|
76
|
+
return user;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Usage Examples
|
|
82
|
+
|
|
83
|
+
### Basic HTTP Requests
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
// GET request
|
|
87
|
+
const data = await this.httpfService
|
|
88
|
+
.get<{ message: string }>('https://api.example.com/hello')
|
|
89
|
+
.map((response) => response.body)
|
|
90
|
+
.head();
|
|
91
|
+
|
|
92
|
+
// POST request
|
|
93
|
+
const result = await this.httpfService
|
|
94
|
+
.post<{ id: string }>('https://api.example.com/users', {
|
|
95
|
+
json: { name: 'John', email: 'john@example.com' },
|
|
96
|
+
})
|
|
97
|
+
.map((response) => response.body)
|
|
98
|
+
.head();
|
|
99
|
+
|
|
100
|
+
// PUT request
|
|
101
|
+
await this.httpfService
|
|
102
|
+
.put('https://api.example.com/users/123', {
|
|
103
|
+
json: { name: 'Jane' },
|
|
104
|
+
})
|
|
105
|
+
.head();
|
|
106
|
+
|
|
107
|
+
// PATCH request
|
|
108
|
+
await this.httpfService
|
|
109
|
+
.patch('https://api.example.com/users/123', {
|
|
110
|
+
json: { email: 'jane@example.com' },
|
|
111
|
+
})
|
|
112
|
+
.head();
|
|
113
|
+
|
|
114
|
+
// DELETE request
|
|
115
|
+
await this.httpfService.delete('https://api.example.com/users/123').head();
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Error Handling
|
|
119
|
+
|
|
120
|
+
Use `catchError` to treat errors as values:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
const result = await this.httpfService
|
|
124
|
+
.get<User>('https://api.example.com/users/123')
|
|
125
|
+
.catchError((error) => ({
|
|
126
|
+
body: null,
|
|
127
|
+
statusCode: 500,
|
|
128
|
+
error: error.message,
|
|
129
|
+
}))
|
|
130
|
+
.map((response) => response.body)
|
|
131
|
+
.head();
|
|
132
|
+
|
|
133
|
+
// Transform and handle errors
|
|
134
|
+
const user = await this.httpfService
|
|
135
|
+
.get<User>('https://api.example.com/users/123')
|
|
136
|
+
.catchError((error) => {
|
|
137
|
+
console.error('Failed to fetch user:', error);
|
|
138
|
+
return { body: { id: '0', name: 'Unknown' } };
|
|
139
|
+
})
|
|
140
|
+
.map((response) => response.body)
|
|
141
|
+
.head();
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Retry
|
|
145
|
+
|
|
146
|
+
Automatically retry failed requests:
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
// Retry up to 3 times
|
|
150
|
+
const data = await this.httpfService
|
|
151
|
+
.get<Data>('https://api.example.com/unstable-endpoint')
|
|
152
|
+
.retry(3)
|
|
153
|
+
.map((response) => response.body)
|
|
154
|
+
.head();
|
|
155
|
+
|
|
156
|
+
// Using retry with catchError
|
|
157
|
+
const result = await this.httpfService
|
|
158
|
+
.get<Data>('https://api.example.com/data')
|
|
159
|
+
.retry(2)
|
|
160
|
+
.catchError((error) => ({
|
|
161
|
+
body: { fallback: true },
|
|
162
|
+
statusCode: 200,
|
|
163
|
+
}))
|
|
164
|
+
.map((response) => response.body)
|
|
165
|
+
.head();
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Using FxTS Methods
|
|
169
|
+
|
|
170
|
+
You can use various helper functions from FxTS:
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
// filter: Process only responses that match conditions
|
|
174
|
+
const successResponse = await this.httpfService
|
|
175
|
+
.get<Data>('https://api.example.com/data')
|
|
176
|
+
.filter((response) => response.statusCode === 200)
|
|
177
|
+
.map((response) => response.body)
|
|
178
|
+
.head();
|
|
179
|
+
|
|
180
|
+
// take: Get only the first N items
|
|
181
|
+
const items = await this.httpfService
|
|
182
|
+
.get<Item[]>('https://api.example.com/items')
|
|
183
|
+
.map((response) => response.body)
|
|
184
|
+
.take(5)
|
|
185
|
+
.toArray();
|
|
186
|
+
|
|
187
|
+
// Complex chaining
|
|
188
|
+
const processedData = await this.httpfService
|
|
189
|
+
.get<RawData>('https://api.example.com/data')
|
|
190
|
+
.retry(2)
|
|
191
|
+
.catchError(() => ({ body: [] }))
|
|
192
|
+
.filter((response) => response.statusCode === 200)
|
|
193
|
+
.map((response) => response.body)
|
|
194
|
+
.map((data) => data.map((item) => ({ ...item, processed: true })))
|
|
195
|
+
.head();
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Flattening Data with mergeMap
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
const allItems = await this.httpfService
|
|
202
|
+
.get<{ items: Item[] }>('https://api.example.com/data')
|
|
203
|
+
.map((response) => response.body)
|
|
204
|
+
.mergeMap((data) => data.items)
|
|
205
|
+
.toArray();
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Advanced Configuration
|
|
209
|
+
|
|
210
|
+
### Global Configuration
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
import { Module } from '@nestjs/common';
|
|
214
|
+
import { HttpfModule } from 'nestjs-httpf';
|
|
215
|
+
|
|
216
|
+
@Module({
|
|
217
|
+
imports: [
|
|
218
|
+
HttpfModule.register({
|
|
219
|
+
global: true,
|
|
220
|
+
timeout: 5000,
|
|
221
|
+
retry: {
|
|
222
|
+
limit: 2,
|
|
223
|
+
},
|
|
224
|
+
headers: {
|
|
225
|
+
'User-Agent': 'my-app/1.0.0',
|
|
226
|
+
},
|
|
227
|
+
}),
|
|
228
|
+
],
|
|
229
|
+
})
|
|
230
|
+
export class AppModule {}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Async Configuration
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
import { Module } from '@nestjs/common';
|
|
237
|
+
import { HttpfModule } from 'nestjs-httpf';
|
|
238
|
+
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
239
|
+
|
|
240
|
+
@Module({
|
|
241
|
+
imports: [
|
|
242
|
+
HttpfModule.registerAsync({
|
|
243
|
+
imports: [ConfigModule],
|
|
244
|
+
useFactory: async (configService: ConfigService) => ({
|
|
245
|
+
timeout: configService.get('HTTP_TIMEOUT'),
|
|
246
|
+
headers: {
|
|
247
|
+
'API-Key': configService.get('API_KEY'),
|
|
248
|
+
},
|
|
249
|
+
}),
|
|
250
|
+
inject: [ConfigService],
|
|
251
|
+
}),
|
|
252
|
+
],
|
|
253
|
+
})
|
|
254
|
+
export class AppModule {}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Configuration with useClass
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
import { Injectable } from '@nestjs/common';
|
|
261
|
+
import { HttpfModuleOptionsFactory, HttpfModuleOptions } from 'nestjs-httpf';
|
|
262
|
+
|
|
263
|
+
@Injectable()
|
|
264
|
+
class HttpConfigService implements HttpfModuleOptionsFactory {
|
|
265
|
+
createHttpOptions(): HttpfModuleOptions {
|
|
266
|
+
return {
|
|
267
|
+
timeout: 5000,
|
|
268
|
+
retry: {
|
|
269
|
+
limit: 3,
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
@Module({
|
|
276
|
+
imports: [
|
|
277
|
+
HttpfModule.registerAsync({
|
|
278
|
+
useClass: HttpConfigService,
|
|
279
|
+
}),
|
|
280
|
+
],
|
|
281
|
+
})
|
|
282
|
+
export class AppModule {}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## API Reference
|
|
286
|
+
|
|
287
|
+
### HttpfService
|
|
288
|
+
|
|
289
|
+
#### Methods
|
|
290
|
+
|
|
291
|
+
- `get<T>(url: string | URL, options?: OptionsOfJSONResponseBody): HttpfAsyncIterable<Response<T>>`
|
|
292
|
+
- `post<T>(url: string | URL, options?: OptionsOfJSONResponseBody): HttpfAsyncIterable<Response<T>>`
|
|
293
|
+
- `put<T>(url: string | URL, options?: OptionsOfJSONResponseBody): HttpfAsyncIterable<Response<T>>`
|
|
294
|
+
- `patch<T>(url: string | URL, options?: OptionsOfJSONResponseBody): HttpfAsyncIterable<Response<T>>`
|
|
295
|
+
- `delete<T>(url: string | URL, options?: OptionsOfJSONResponseBody): HttpfAsyncIterable<Response<T>>`
|
|
296
|
+
- `head<T>(url: string | URL, options?: OptionsOfJSONResponseBody): HttpfAsyncIterable<Response<T>>`
|
|
297
|
+
|
|
298
|
+
### HttpfAsyncIterable
|
|
299
|
+
|
|
300
|
+
`HttpfAsyncIterable` provides all FxTS methods along with the following additional methods:
|
|
301
|
+
|
|
302
|
+
#### Additional Methods
|
|
303
|
+
|
|
304
|
+
- `catchError<E>(handler: (error: unknown) => E): HttpfAsyncIterable<T | E>` - Catch errors and return a fallback value
|
|
305
|
+
- `retry(retries: number): HttpfAsyncIterable<T>` - Retry the specified number of times on failure
|
|
306
|
+
- `mergeMap<U>(mapper: (value: T) => Iterable<U>): HttpfAsyncIterable<U>` - Flatten values
|
|
307
|
+
|
|
308
|
+
#### FxTS Methods and Helper Functions
|
|
309
|
+
|
|
310
|
+
See the [FxTS documentation](https://fxts.dev/docs/index) for more information.
|
|
311
|
+
|
|
312
|
+
## License
|
|
313
|
+
|
|
314
|
+
[MIT](LICENSE)
|
|
315
|
+
|
|
316
|
+
## Contributing
|
|
317
|
+
|
|
318
|
+
Issues and pull requests are always welcome!
|
|
319
|
+
|
|
320
|
+
## Related Projects
|
|
321
|
+
|
|
322
|
+
- [NestJS](https://nestjs.com/) - Progressive Node.js framework
|
|
323
|
+
- [Got](https://github.com/sindresorhus/got) - Human-friendly and powerful HTTP request library
|
|
324
|
+
- [FxTS](https://fxts.dev/) - Functional library for TypeScript/JavaScript
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createHttpfAsyncIterable = createHttpfAsyncIterable;
|
|
4
|
+
const core_1 = require("@fxts/core");
|
|
5
|
+
function createHttpfAsyncIterable(source) {
|
|
6
|
+
const fxIterable = (0, core_1.fx)(source);
|
|
7
|
+
const handler = {
|
|
8
|
+
get(target, prop, receiver) {
|
|
9
|
+
if (prop === 'catchError') {
|
|
10
|
+
return function (errorHandler) {
|
|
11
|
+
const catchError = (async function* () {
|
|
12
|
+
try {
|
|
13
|
+
for await (const value of source) {
|
|
14
|
+
yield value;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
yield errorHandler(error);
|
|
19
|
+
}
|
|
20
|
+
})();
|
|
21
|
+
return createHttpfAsyncIterable(catchError);
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
if (prop === 'retry') {
|
|
25
|
+
return function (retries) {
|
|
26
|
+
const retry = (async function* () {
|
|
27
|
+
let attempt = 0;
|
|
28
|
+
let lastError;
|
|
29
|
+
while (attempt <= retries) {
|
|
30
|
+
try {
|
|
31
|
+
for await (const value of source) {
|
|
32
|
+
yield value;
|
|
33
|
+
}
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
lastError = error;
|
|
38
|
+
attempt++;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
throw lastError;
|
|
42
|
+
})();
|
|
43
|
+
return createHttpfAsyncIterable(retry);
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
if (prop === 'mergeMap') {
|
|
47
|
+
return function (mapper) {
|
|
48
|
+
const mergeMap = (async function* () {
|
|
49
|
+
for await (const value of source) {
|
|
50
|
+
for (const innerValue of mapper(value)) {
|
|
51
|
+
yield innerValue;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
})();
|
|
55
|
+
return createHttpfAsyncIterable(mergeMap);
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const value = Reflect.get(target, prop, receiver);
|
|
59
|
+
if (typeof value === 'function') {
|
|
60
|
+
return function (...args) {
|
|
61
|
+
const result = value.apply(target, args);
|
|
62
|
+
if (result &&
|
|
63
|
+
typeof result === 'object' &&
|
|
64
|
+
Symbol.asyncIterator in result &&
|
|
65
|
+
typeof result.map === 'function') {
|
|
66
|
+
return createHttpfAsyncIterable(result);
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
return value;
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
return new Proxy(fxIterable, handler);
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=create-httpf-async-iterable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-httpf-async-iterable.js","sourceRoot":"","sources":["../lib/create-httpf-async-iterable.ts"],"names":[],"mappings":";;AASA,4DAyFC;AAlGD,qCAAgC;AAShC,SAAgB,wBAAwB,CACtC,MAAwB;IAExB,MAAM,UAAU,GAAG,IAAA,SAAE,EAAC,MAAM,CAAC,CAAC;IAE9B,MAAM,OAAO,GAAqC;QAChD,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ;YACxB,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC1B,OAAO,UACL,YAAmC;oBAEnC,MAAM,UAAU,GAAG,CAAC,KAAK,SAAS,CAAC;wBACjC,IAAI,CAAC;4BACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gCACjC,MAAM,KAAK,CAAC;4BACd,CAAC;wBACH,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,MAAM,YAAY,CAAC,KAAK,CAAC,CAAC;wBAC5B,CAAC;oBACH,CAAC,CAAC,EAAE,CAAC;oBACL,OAAO,wBAAwB,CAAQ,UAAU,CAAC,CAAC;gBACrD,CAAC,CAAC;YACJ,CAAC;YAED,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;gBACrB,OAAO,UAAU,OAAe;oBAC9B,MAAM,KAAK,GAAG,CAAC,KAAK,SAAS,CAAC;wBAC5B,IAAI,OAAO,GAAG,CAAC,CAAC;wBAChB,IAAI,SAAkB,CAAC;wBACvB,OAAO,OAAO,IAAI,OAAO,EAAE,CAAC;4BAC1B,IAAI,CAAC;gCACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;oCACjC,MAAM,KAAK,CAAC;gCACd,CAAC;gCACD,OAAO;4BACT,CAAC;4BAAC,OAAO,KAAK,EAAE,CAAC;gCACf,SAAS,GAAG,KAAK,CAAC;gCAClB,OAAO,EAAE,CAAC;4BACZ,CAAC;wBACH,CAAC;wBACD,MAAM,SAAS,CAAC;oBAClB,CAAC,CAAC,EAAE,CAAC;oBACL,OAAO,wBAAwB,CAAI,KAAK,CAAC,CAAC;gBAC5C,CAAC,CAAC;YACJ,CAAC;YAED,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;gBACxB,OAAO,UACL,MAAiC;oBAEjC,MAAM,QAAQ,GAAG,CAAC,KAAK,SAAS,CAAC;wBAC/B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;4BACjC,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gCACvC,MAAM,UAAU,CAAC;4BACnB,CAAC;wBACH,CAAC;oBACH,CAAC,CAAC,EAAE,CAAC;oBACL,OAAO,wBAAwB,CAAI,QAAQ,CAAC,CAAC;gBAC/C,CAAC,CAAC;YACJ,CAAC;YAED,MAAM,KAAK,GAAY,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YAG3D,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;gBAChC,OAAO,UAAyB,GAAG,IAAe;oBAChD,MAAM,MAAM,GACV,KACD,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;oBAGtB,IACE,MAAM;wBACN,OAAO,MAAM,KAAK,QAAQ;wBAC1B,MAAM,CAAC,aAAa,IAAI,MAAM;wBAC9B,OAAQ,MAAmC,CAAC,GAAG,KAAK,UAAU,EAC9D,CAAC;wBACD,OAAO,wBAAwB,CAAC,MAAgC,CAAC,CAAC;oBACpE,CAAC;oBAED,OAAO,MAAM,CAAC;gBAChB,CAAC,CAAC;YACJ,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC;IAEF,OAAO,IAAI,KAAK,CAAC,UAAU,EAAE,OAAO,CAA0B,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fx-async-iterable.interface.js","sourceRoot":"","sources":["../lib/fx-async-iterable.interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { FxAsyncIterable } from './fx-async-iterable.interface';
|
|
2
|
+
export interface HttpfAsyncIterable<T> extends FxAsyncIterable<T> {
|
|
3
|
+
catchError<E>(handler: (error: unknown) => E): HttpfAsyncIterable<T | E>;
|
|
4
|
+
retry(retries: number): HttpfAsyncIterable<T>;
|
|
5
|
+
mergeMap<U>(mapper: (value: T) => Iterable<U>): HttpfAsyncIterable<U>;
|
|
6
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpf-async-iterable.interface.js","sourceRoot":"","sources":["../lib/httpf-async-iterable.interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { FactoryProvider, ModuleMetadata, Provider, Type } from '@nestjs/common';
|
|
2
|
+
import { Options } from 'got';
|
|
3
|
+
export interface HttpfModuleOptions extends Options {
|
|
4
|
+
global?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface HttpfModuleOptionsFactory {
|
|
7
|
+
createHttpOptions(): Promise<HttpfModuleOptions> | HttpfModuleOptions;
|
|
8
|
+
}
|
|
9
|
+
export interface HttpfModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
|
|
10
|
+
useExisting?: Type<HttpfModuleOptionsFactory>;
|
|
11
|
+
useClass?: Type<HttpfModuleOptionsFactory>;
|
|
12
|
+
useFactory?: (...args: any[]) => Promise<HttpfModuleOptions> | HttpfModuleOptions;
|
|
13
|
+
inject?: FactoryProvider['inject'];
|
|
14
|
+
extraProviders?: Provider[];
|
|
15
|
+
global?: boolean;
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpf-module-option.interface.js","sourceRoot":"","sources":["../lib/httpf-module-option.interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpf.constants.js","sourceRoot":"","sources":["../lib/httpf.constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,GAAG,GAAG,KAAK,CAAC;AACZ,QAAA,oBAAoB,GAAG,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { DynamicModule } from '@nestjs/common';
|
|
2
|
+
import { HttpfModuleAsyncOptions, HttpfModuleOptions } from './httpf-module-option.interface';
|
|
3
|
+
export declare class HttpfModule {
|
|
4
|
+
static register(config: HttpfModuleOptions): DynamicModule;
|
|
5
|
+
static registerAsync(options: HttpfModuleAsyncOptions): DynamicModule;
|
|
6
|
+
private static createAsyncProviders;
|
|
7
|
+
private static createAsyncOptionsProvider;
|
|
8
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var HttpfModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.HttpfModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const httpf_service_1 = require("./httpf.service");
|
|
13
|
+
const got_1 = require("got");
|
|
14
|
+
const httpf_constants_1 = require("./httpf.constants");
|
|
15
|
+
let HttpfModule = HttpfModule_1 = class HttpfModule {
|
|
16
|
+
static register(config) {
|
|
17
|
+
return {
|
|
18
|
+
module: HttpfModule_1,
|
|
19
|
+
global: config.global,
|
|
20
|
+
providers: [
|
|
21
|
+
{
|
|
22
|
+
provide: httpf_constants_1.GOT,
|
|
23
|
+
useValue: got_1.default.extend(config),
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
static registerAsync(options) {
|
|
29
|
+
return {
|
|
30
|
+
module: HttpfModule_1,
|
|
31
|
+
global: options.global,
|
|
32
|
+
imports: options.imports,
|
|
33
|
+
providers: [
|
|
34
|
+
...this.createAsyncProviders(options),
|
|
35
|
+
{
|
|
36
|
+
provide: httpf_constants_1.GOT,
|
|
37
|
+
useFactory: (config) => got_1.default.extend(config),
|
|
38
|
+
inject: [httpf_constants_1.HTTPF_MODULE_OPTIONS],
|
|
39
|
+
},
|
|
40
|
+
...(options.extraProviders || []),
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
static createAsyncProviders(options) {
|
|
45
|
+
if (options.useExisting || options.useFactory) {
|
|
46
|
+
return [this.createAsyncOptionsProvider(options)];
|
|
47
|
+
}
|
|
48
|
+
if (!options.useClass) {
|
|
49
|
+
throw new Error('Invalid configuration. Must provide useClass, useExisting or useFactory');
|
|
50
|
+
}
|
|
51
|
+
return [
|
|
52
|
+
this.createAsyncOptionsProvider(options),
|
|
53
|
+
{
|
|
54
|
+
provide: options.useClass,
|
|
55
|
+
useClass: options.useClass,
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
}
|
|
59
|
+
static createAsyncOptionsProvider(options) {
|
|
60
|
+
if (options.useFactory) {
|
|
61
|
+
return {
|
|
62
|
+
provide: httpf_constants_1.HTTPF_MODULE_OPTIONS,
|
|
63
|
+
useFactory: options.useFactory,
|
|
64
|
+
inject: options.inject || [],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const inject = options.useExisting || options.useClass;
|
|
68
|
+
if (!inject) {
|
|
69
|
+
throw new Error('Invalid configuration. Must provide useClass, useExisting or useFactory');
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
provide: httpf_constants_1.HTTPF_MODULE_OPTIONS,
|
|
73
|
+
useFactory: async (optionsFactory) => optionsFactory.createHttpOptions(),
|
|
74
|
+
inject: [inject],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
exports.HttpfModule = HttpfModule;
|
|
79
|
+
exports.HttpfModule = HttpfModule = HttpfModule_1 = __decorate([
|
|
80
|
+
(0, common_1.Module)({
|
|
81
|
+
providers: [
|
|
82
|
+
httpf_service_1.HttpfService,
|
|
83
|
+
{
|
|
84
|
+
provide: httpf_constants_1.GOT,
|
|
85
|
+
useValue: got_1.default,
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
exports: [httpf_service_1.HttpfService],
|
|
89
|
+
})
|
|
90
|
+
], HttpfModule);
|
|
91
|
+
//# sourceMappingURL=httpf.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpf.module.js","sourceRoot":"","sources":["../lib/httpf.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAiE;AACjE,mDAA+C;AAM/C,6BAAsB;AACtB,uDAA8D;AAYvD,IAAM,WAAW,mBAAjB,MAAM,WAAW;IACtB,MAAM,CAAC,QAAQ,CAAC,MAA0B;QACxC,OAAO;YACL,MAAM,EAAE,aAAW;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,qBAAG;oBACZ,QAAQ,EAAE,aAAG,CAAC,MAAM,CAAC,MAAM,CAAC;iBAC7B;aACF;SACF,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,aAAa,CAAC,OAAgC;QACnD,OAAO;YACL,MAAM,EAAE,aAAW;YACnB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,SAAS,EAAE;gBACT,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC;gBACrC;oBACE,OAAO,EAAE,qBAAG;oBACZ,UAAU,EAAE,CAAC,MAA0B,EAAE,EAAE,CAAC,aAAG,CAAC,MAAM,CAAC,MAAM,CAAC;oBAC9D,MAAM,EAAE,CAAC,sCAAoB,CAAC;iBAC/B;gBACD,GAAG,CAAC,OAAO,CAAC,cAAc,IAAI,EAAE,CAAC;aAClC;SACF,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,oBAAoB,CACjC,OAAgC;QAEhC,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YAC9C,OAAO,CAAC,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,yEAAyE,CAC1E,CAAC;QACJ,CAAC;QACD,OAAO;YACL,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC;YACxC;gBACE,OAAO,EAAE,OAAO,CAAC,QAAQ;gBACzB,QAAQ,EAAE,OAAO,CAAC,QAAQ;aAC3B;SACF,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,0BAA0B,CACvC,OAAgC;QAEhC,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YACvB,OAAO;gBACL,OAAO,EAAE,sCAAoB;gBAC7B,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;aAC7B,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC;QACvD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,yEAAyE,CAC1E,CAAC;QACJ,CAAC;QACD,OAAO;YACL,OAAO,EAAE,sCAAoB;YAC7B,UAAU,EAAE,KAAK,EAAE,cAAyC,EAAE,EAAE,CAC9D,cAAc,CAAC,iBAAiB,EAAE;YACpC,MAAM,EAAE,CAAC,MAAM,CAAC;SACjB,CAAC;IACJ,CAAC;CACF,CAAA;AA1EY,kCAAW;sBAAX,WAAW;IAVvB,IAAA,eAAM,EAAC;QACN,SAAS,EAAE;YACT,4BAAY;YACZ;gBACE,OAAO,EAAE,qBAAG;gBACZ,QAAQ,EAAE,aAAG;aACd;SACF;QACD,OAAO,EAAE,CAAC,4BAAY,CAAC;KACxB,CAAC;GACW,WAAW,CA0EvB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Got, OptionsOfJSONResponseBody, Response } from 'got';
|
|
2
|
+
import { HttpfAsyncIterable } from './httpf-async-iterable.interface';
|
|
3
|
+
import { createHttpfAsyncIterable } from './create-httpf-async-iterable';
|
|
4
|
+
export declare class HttpfService {
|
|
5
|
+
protected readonly httpClient: Got;
|
|
6
|
+
constructor(httpClient: Got);
|
|
7
|
+
get<T>(url: string | URL, options?: OptionsOfJSONResponseBody): HttpfAsyncIterable<Response<T>>;
|
|
8
|
+
post<T>(url: string | URL, options?: OptionsOfJSONResponseBody): HttpfAsyncIterable<Response<T>>;
|
|
9
|
+
patch<T>(url: string | URL, options?: OptionsOfJSONResponseBody): HttpfAsyncIterable<Response<T>>;
|
|
10
|
+
put<T>(url: string | URL, options?: OptionsOfJSONResponseBody): HttpfAsyncIterable<Response<T>>;
|
|
11
|
+
delete<T>(url: string | URL, options?: OptionsOfJSONResponseBody): HttpfAsyncIterable<Response<T>>;
|
|
12
|
+
head<T>(url: string | URL, options?: OptionsOfJSONResponseBody): HttpfAsyncIterable<Response<T>>;
|
|
13
|
+
}
|
|
14
|
+
export { HttpfAsyncIterable, createHttpfAsyncIterable };
|