@theshelf/http 0.3.1 → 0.4.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 +30 -35
- package/dist/Http.d.ts +3 -6
- package/dist/Http.js +53 -33
- package/dist/definitions/interfaces.d.ts +1 -0
- package/dist/drivers/Fetch.d.ts +1 -0
- package/dist/drivers/Fetch.js +1 -0
- package/dist/drivers/Mapped.d.ts +16 -0
- package/dist/drivers/Mapped.js +51 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +8 -6
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
|
-
# HTTP | The Shelf
|
|
2
|
+
# HTTP core | The Shelf
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
This package contains the definition of the http clients.
|
|
5
5
|
|
|
6
6
|
## Installation
|
|
7
7
|
|
|
@@ -9,49 +9,22 @@ The HTTP package provides a universal interaction layer with an HTTP client inpl
|
|
|
9
9
|
npm install @theshelf/http
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
## Drivers
|
|
13
|
-
|
|
14
|
-
Currently, there is only one driver available:
|
|
15
|
-
|
|
16
|
-
* **Fetch** - Node.js fetch implementation.
|
|
17
|
-
|
|
18
12
|
## How to use
|
|
19
13
|
|
|
20
14
|
The basic set up looks like this.
|
|
21
15
|
|
|
22
16
|
```ts
|
|
23
|
-
import Http, { FetchDriver
|
|
17
|
+
import Http, { FetchDriver } from '@theshelf/http';
|
|
24
18
|
|
|
25
|
-
const driver = new
|
|
19
|
+
const driver = new FetchDriver();
|
|
26
20
|
const http = new Http(driver);
|
|
27
21
|
|
|
28
22
|
// Perform operations with the http instance
|
|
29
23
|
```
|
|
30
24
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
#### Fetch driver
|
|
34
|
-
|
|
35
|
-
No configuration options.
|
|
36
|
-
|
|
37
|
-
### Operations
|
|
25
|
+
## Operations
|
|
38
26
|
|
|
39
27
|
```ts
|
|
40
|
-
import { HTTP_METHODS } from '@theshelf/http';
|
|
41
|
-
|
|
42
|
-
// Set a cached response
|
|
43
|
-
const response: Response = new Response();
|
|
44
|
-
http.setCache(HTTP_METHODS.GET, url, response);
|
|
45
|
-
|
|
46
|
-
// Get a cached response
|
|
47
|
-
const response: Response | undefined = http.getCache(HTTP_METHODS.GET, url);
|
|
48
|
-
|
|
49
|
-
// Remove a cached response
|
|
50
|
-
http.removeCache(HTTP_METHODS.GET, url)
|
|
51
|
-
|
|
52
|
-
// Clear all cache
|
|
53
|
-
http.clearCache()
|
|
54
|
-
|
|
55
28
|
// Perform a GET request
|
|
56
29
|
const response: Response = await http.get(url);
|
|
57
30
|
|
|
@@ -80,10 +53,32 @@ const headers: Record<string, string> = { };
|
|
|
80
53
|
const response: Response = await http.head(url, headers);
|
|
81
54
|
```
|
|
82
55
|
|
|
83
|
-
|
|
56
|
+
## Response model
|
|
84
57
|
|
|
85
58
|
The result of every request is a standard [ECMAScript Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) object.
|
|
86
59
|
|
|
87
|
-
|
|
60
|
+
## Drivers
|
|
61
|
+
|
|
62
|
+
There are two drivers available.
|
|
63
|
+
|
|
64
|
+
### Fetch
|
|
65
|
+
|
|
66
|
+
This driver implements the [Node.js fetch](https://nodejs.org/api/globals.html#fetch) API.
|
|
67
|
+
|
|
68
|
+
### Mapped
|
|
69
|
+
|
|
70
|
+
In-memory http client (suited for testing). It doesn't have any configuration options, but has an additional operation.
|
|
88
71
|
|
|
89
|
-
|
|
72
|
+
```ts
|
|
73
|
+
// Add a mapping
|
|
74
|
+
driver.setMapping(method, url, response);
|
|
75
|
+
|
|
76
|
+
// Get a mapping
|
|
77
|
+
const response: Response | undefined = driver.getMapping(method, url);
|
|
78
|
+
|
|
79
|
+
// Remove a mapping
|
|
80
|
+
driver.removeMapping(method, url);
|
|
81
|
+
|
|
82
|
+
// Remove all mappings
|
|
83
|
+
driver.clearMappings();
|
|
84
|
+
```
|
package/dist/Http.d.ts
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
+
import type Logger from '@theshelf/logging';
|
|
1
2
|
import type { Driver } from './definitions/interfaces.js';
|
|
2
|
-
export default class Http
|
|
3
|
+
export default class Http {
|
|
3
4
|
#private;
|
|
4
|
-
constructor(driver: Driver);
|
|
5
|
-
setCache(method: string, url: string, response: Response): void;
|
|
6
|
-
getCache(method: string, url: string): Response | undefined;
|
|
7
|
-
removeCache(method: string, url: string): void;
|
|
8
|
-
clearCache(): void;
|
|
5
|
+
constructor(driver: Driver, logger?: Logger);
|
|
9
6
|
get(url: string, headers?: Record<string, string> | undefined): Promise<Response>;
|
|
10
7
|
post(url: string, body: unknown, headers?: Record<string, string> | undefined): Promise<Response>;
|
|
11
8
|
put(url: string, body: unknown, headers?: Record<string, string> | undefined): Promise<Response>;
|
package/dist/Http.js
CHANGED
|
@@ -1,50 +1,70 @@
|
|
|
1
|
-
import { HttpMethods } from './definitions/constants.js';
|
|
2
1
|
export default class Http {
|
|
3
2
|
#driver;
|
|
4
|
-
#
|
|
5
|
-
|
|
3
|
+
#logger;
|
|
4
|
+
#logPrefix;
|
|
5
|
+
constructor(driver, logger) {
|
|
6
6
|
this.#driver = driver;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const id = this.#createCacheId(method, url);
|
|
10
|
-
this.#cache.set(id, response);
|
|
11
|
-
}
|
|
12
|
-
getCache(method, url) {
|
|
13
|
-
const id = this.#createCacheId(method, url);
|
|
14
|
-
return this.#cache.get(id);
|
|
15
|
-
}
|
|
16
|
-
removeCache(method, url) {
|
|
17
|
-
const id = this.#createCacheId(method, url);
|
|
18
|
-
this.#cache.delete(id);
|
|
19
|
-
}
|
|
20
|
-
clearCache() {
|
|
21
|
-
this.#cache.clear();
|
|
7
|
+
this.#logger = logger?.for(Http.name);
|
|
8
|
+
this.#logPrefix = `${this.#driver.name} ->`;
|
|
22
9
|
}
|
|
23
10
|
async get(url, headers) {
|
|
24
|
-
|
|
25
|
-
|
|
11
|
+
this.#logger?.debug(this.#logPrefix, 'Getting', url);
|
|
12
|
+
try {
|
|
13
|
+
return await this.#driver.get(url, headers);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
this.#logger?.error(this.#logPrefix, 'Get', url, 'failed with error', error);
|
|
17
|
+
throw error;
|
|
18
|
+
}
|
|
26
19
|
}
|
|
27
20
|
async post(url, body, headers) {
|
|
28
|
-
|
|
29
|
-
|
|
21
|
+
this.#logger?.debug(this.#logPrefix, 'Posting', url);
|
|
22
|
+
try {
|
|
23
|
+
return await this.#driver.post(url, body, headers);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
this.#logger?.error(this.#logPrefix, 'Post', url, 'failed with error', error);
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
30
29
|
}
|
|
31
30
|
async put(url, body, headers) {
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
this.#logger?.debug(this.#logPrefix, 'Putting', url);
|
|
32
|
+
try {
|
|
33
|
+
return await this.#driver.put(url, body, headers);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
this.#logger?.error(this.#logPrefix, 'Put', url, 'failed with error', error);
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
34
39
|
}
|
|
35
40
|
async patch(url, body, headers) {
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
this.#logger?.debug(this.#logPrefix, 'Patching', url);
|
|
42
|
+
try {
|
|
43
|
+
return await this.#driver.patch(url, body, headers);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
this.#logger?.error(this.#logPrefix, 'Patch', url, 'failed with error', error);
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
38
49
|
}
|
|
39
50
|
async delete(url, headers) {
|
|
40
|
-
|
|
41
|
-
|
|
51
|
+
this.#logger?.debug(this.#logPrefix, 'Deleting', url);
|
|
52
|
+
try {
|
|
53
|
+
return await this.#driver.delete(url, headers);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
this.#logger?.error(this.#logPrefix, 'Delete', url, 'failed with error', error);
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
42
59
|
}
|
|
43
60
|
async head(url, headers) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
61
|
+
this.#logger?.debug(this.#logPrefix, 'Heading', url);
|
|
62
|
+
try {
|
|
63
|
+
return await this.#driver.head(url, headers);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
this.#logger?.error(this.#logPrefix, 'Head', url, 'failed with error', error);
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
49
69
|
}
|
|
50
70
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export interface Driver {
|
|
2
|
+
get name(): string;
|
|
2
3
|
get(url: string, headers?: Record<string, string>): Promise<Response>;
|
|
3
4
|
post(url: string, body: unknown, headers?: Record<string, string>): Promise<Response>;
|
|
4
5
|
put(url: string, body: unknown, headers?: Record<string, string>): Promise<Response>;
|
package/dist/drivers/Fetch.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Driver } from '../definitions/interfaces.js';
|
|
2
2
|
export default class Fetch implements Driver {
|
|
3
|
+
get name(): string;
|
|
3
4
|
get(url: string, headers?: Record<string, string> | undefined): Promise<Response>;
|
|
4
5
|
post(url: string, body: unknown, headers?: Record<string, string> | undefined): Promise<Response>;
|
|
5
6
|
put(url: string, body: unknown, headers?: Record<string, string> | undefined): Promise<Response>;
|
package/dist/drivers/Fetch.js
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { HttpMethod } from '../definitions/constants.js';
|
|
2
|
+
import type { Driver } from '../definitions/interfaces.js';
|
|
3
|
+
export default class Mapped implements Driver {
|
|
4
|
+
#private;
|
|
5
|
+
get name(): string;
|
|
6
|
+
setMapping(method: HttpMethod, url: string, response: Response): void;
|
|
7
|
+
getMapping(method: HttpMethod, url: string): Response | undefined;
|
|
8
|
+
removeMapping(method: HttpMethod, url: string): void;
|
|
9
|
+
get(url: string, headers?: Record<string, string> | undefined): Promise<Response>;
|
|
10
|
+
post(url: string, body: unknown, headers?: Record<string, string> | undefined): Promise<Response>;
|
|
11
|
+
put(url: string, body: unknown, headers?: Record<string, string> | undefined): Promise<Response>;
|
|
12
|
+
patch(url: string, body: unknown, headers?: Record<string, string> | undefined): Promise<Response>;
|
|
13
|
+
delete(url: string, headers?: Record<string, string> | undefined): Promise<Response>;
|
|
14
|
+
head(url: string, headers?: Record<string, string> | undefined): Promise<Response>;
|
|
15
|
+
clear(): void;
|
|
16
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/* eslint @typescript-eslint/no-unused-vars: "off" */
|
|
2
|
+
import { HttpMethods } from '../definitions/constants.js';
|
|
3
|
+
export default class Mapped {
|
|
4
|
+
#mappings = new Map();
|
|
5
|
+
get name() { return Mapped.name; }
|
|
6
|
+
setMapping(method, url, response) {
|
|
7
|
+
const id = this.#createCacheId(method, url);
|
|
8
|
+
this.#mappings.set(id, response);
|
|
9
|
+
}
|
|
10
|
+
getMapping(method, url) {
|
|
11
|
+
const id = this.#createCacheId(method, url);
|
|
12
|
+
return this.#mappings.get(id)?.clone();
|
|
13
|
+
}
|
|
14
|
+
removeMapping(method, url) {
|
|
15
|
+
const id = this.#createCacheId(method, url);
|
|
16
|
+
this.#mappings.delete(id);
|
|
17
|
+
}
|
|
18
|
+
async get(url, headers) {
|
|
19
|
+
return this.getMapping(HttpMethods.GET, url)
|
|
20
|
+
?? this.#createNotMappedResponse();
|
|
21
|
+
}
|
|
22
|
+
async post(url, body, headers) {
|
|
23
|
+
return this.getMapping(HttpMethods.POST, url)
|
|
24
|
+
?? this.#createNotMappedResponse();
|
|
25
|
+
}
|
|
26
|
+
async put(url, body, headers) {
|
|
27
|
+
return this.getMapping(HttpMethods.PUT, url)
|
|
28
|
+
?? this.#createNotMappedResponse();
|
|
29
|
+
}
|
|
30
|
+
async patch(url, body, headers) {
|
|
31
|
+
return this.getMapping(HttpMethods.PATCH, url)
|
|
32
|
+
?? this.#createNotMappedResponse();
|
|
33
|
+
}
|
|
34
|
+
async delete(url, headers) {
|
|
35
|
+
return this.getMapping(HttpMethods.DELETE, url)
|
|
36
|
+
?? this.#createNotMappedResponse();
|
|
37
|
+
}
|
|
38
|
+
async head(url, headers) {
|
|
39
|
+
return this.getMapping(HttpMethods.HEAD, url)
|
|
40
|
+
?? this.#createNotMappedResponse();
|
|
41
|
+
}
|
|
42
|
+
clear() {
|
|
43
|
+
this.#mappings.clear();
|
|
44
|
+
}
|
|
45
|
+
#createCacheId(method, url) {
|
|
46
|
+
return `${method.toUpperCase()} ${url}`;
|
|
47
|
+
}
|
|
48
|
+
#createNotMappedResponse() {
|
|
49
|
+
return new Response('Not mapped', { status: 404 });
|
|
50
|
+
}
|
|
51
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,5 +2,6 @@ export * from './definitions/constants.js';
|
|
|
2
2
|
export type * from './definitions/constants.js';
|
|
3
3
|
export type * from './definitions/interfaces.js';
|
|
4
4
|
export { default as HttpError } from './errors/HttpError.js';
|
|
5
|
+
export { default as MappedDriver } from './drivers/Mapped.js';
|
|
5
6
|
export { default as FetchDriver } from './drivers/Fetch.js';
|
|
6
7
|
export { default } from './Http.js';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from './definitions/constants.js';
|
|
2
2
|
export { default as HttpError } from './errors/HttpError.js';
|
|
3
|
+
export { default as MappedDriver } from './drivers/Mapped.js';
|
|
3
4
|
export { default as FetchDriver } from './drivers/Fetch.js';
|
|
4
5
|
export { default } from './Http.js';
|
package/package.json
CHANGED
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theshelf/http",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
7
7
|
"url": "git+https://github.com/MaskingTechnology/theshelf.git"
|
|
8
8
|
},
|
|
9
|
+
"license": "MIT",
|
|
9
10
|
"scripts": {
|
|
10
11
|
"build": "tsc",
|
|
11
12
|
"clean": "rimraf dist",
|
|
12
|
-
"test": "vitest run",
|
|
13
|
-
"test-coverage": "vitest run --coverage",
|
|
14
13
|
"lint": "eslint",
|
|
15
|
-
"review": "npm run build && npm run lint
|
|
14
|
+
"review": "npm run build && npm run lint",
|
|
16
15
|
"prepublishOnly": "npm run clean && npm run build"
|
|
17
16
|
},
|
|
18
17
|
"files": [
|
|
19
18
|
"README.md",
|
|
20
19
|
"dist"
|
|
21
20
|
],
|
|
22
|
-
"types": "dist/index.d.ts",
|
|
23
|
-
"exports": "./dist/index.js"
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"exports": "./dist/index.js",
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"@theshelf/logging": "^0.4.0"
|
|
25
|
+
}
|
|
24
26
|
}
|