@odata2ts/http-client-base 0.5.3 → 0.5.5
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/CHANGELOG.md +30 -0
- package/LICENSE +21 -21
- package/lib/BaseHttpClient.d.ts +7 -23
- package/lib/BaseHttpClient.js +29 -19
- package/lib/BaseHttpClient.js.map +1 -1
- package/lib/index.d.ts +1 -2
- package/lib/index.js +1 -3
- package/lib/index.js.map +1 -1
- package/package.json +4 -6
- package/lib/HttpMethods.d.ts +0 -7
- package/lib/HttpMethods.js +0 -12
- package/lib/HttpMethods.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,36 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [0.5.5](https://github.com/odata2ts/http-client/compare/@odata2ts/http-client-base-v0.5.4...@odata2ts/http-client-base-v0.5.5) (2026-06-10)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* create blob request ([#28](https://github.com/odata2ts/http-client/issues/28)) ([4cc238d](https://github.com/odata2ts/http-client/commit/4cc238d3fbe07c09d56732b4b12d0b1b875a3ef5))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Dependencies
|
|
15
|
+
|
|
16
|
+
* The following workspace dependencies were updated
|
|
17
|
+
* dependencies
|
|
18
|
+
* @odata2ts/http-client-api bumped from ^0.6.3 to ^0.6.4
|
|
19
|
+
|
|
20
|
+
## [0.5.4](https://github.com/odata2ts/http-client/compare/@odata2ts/http-client-base@0.5.3...@odata2ts/http-client-base-v0.5.4) (2025-03-26)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
* always build all packages before release ([#26](https://github.com/odata2ts/http-client/issues/26)) ([a316f6c](https://github.com/odata2ts/http-client/commit/a316f6ce54c4360c8d6f87799ba6fd9c53bff52c))
|
|
26
|
+
* delete requests with Accept json header ([ea1b06d](https://github.com/odata2ts/http-client/commit/ea1b06d509b490e1e899e96a62a10eac3f65da8e))
|
|
27
|
+
* deploy with code ([#25](https://github.com/odata2ts/http-client/issues/25)) ([3e0e78c](https://github.com/odata2ts/http-client/commit/3e0e78cd2e0b0c3215bc0ed97dd62c75d8b6c5ea))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Dependencies
|
|
31
|
+
|
|
32
|
+
* The following workspace dependencies were updated
|
|
33
|
+
* dependencies
|
|
34
|
+
* @odata2ts/http-client-api bumped from ^0.6.2 to ^0.6.3
|
|
35
|
+
|
|
6
36
|
## [0.5.3](https://github.com/odata2ts/http-client/compare/@odata2ts/http-client-base@0.5.2...@odata2ts/http-client-base@0.5.3) (2024-08-24)
|
|
7
37
|
|
|
8
38
|
**Note:** Version bump only for package @odata2ts/http-client-base
|
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2021 odata2ts
|
|
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.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 odata2ts
|
|
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/lib/BaseHttpClient.d.ts
CHANGED
|
@@ -1,24 +1,8 @@
|
|
|
1
|
-
import { HttpResponseModel, ODataResponse } from "@odata2ts/http-client-api";
|
|
1
|
+
import { HttpResponseModel, ODataHttpClientOptions, ODataHttpMethods, ODataRequestConfig, ODataResponse } from "@odata2ts/http-client-api";
|
|
2
|
+
import { ODataHttpDataTypes } from "@odata2ts/http-client-api/lib/ODataHttpDataTypes";
|
|
2
3
|
import { ErrorMessageRetriever } from "./ErrorMessageRetriever";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Enable automatic CSRF token handling.
|
|
7
|
-
*/
|
|
8
|
-
useCsrfProtection?: boolean;
|
|
9
|
-
/**
|
|
10
|
-
* Specify the URL from which the token is fetched.
|
|
11
|
-
* This could be any path to your OData service, since the token is exchanged via HTTP request headers.
|
|
12
|
-
* However, it should be a fast response and usually the root URL to the OData service is a good choice.
|
|
13
|
-
*/
|
|
14
|
-
csrfTokenFetchUrl?: string;
|
|
15
|
-
}
|
|
16
|
-
export interface InternalHttpClientConfig {
|
|
17
|
-
dataType?: "json" | "blob" | "stream";
|
|
18
|
-
/**
|
|
19
|
-
* Additional headers set internally by services or HttpClient implementation.
|
|
20
|
-
*/
|
|
21
|
-
headers?: Record<string, string>;
|
|
4
|
+
export interface BaseRequestConfig extends ODataRequestConfig {
|
|
5
|
+
dataType?: ODataHttpDataTypes;
|
|
22
6
|
/**
|
|
23
7
|
* Very special option needed for FetchClient to not evaluate the response body in certain situations.
|
|
24
8
|
*/
|
|
@@ -30,7 +14,7 @@ export declare abstract class BaseHttpClient<RequestConfigType> {
|
|
|
30
14
|
private csrfToken;
|
|
31
15
|
private csrfTokenKey;
|
|
32
16
|
protected retrieveErrorMessage: ErrorMessageRetriever;
|
|
33
|
-
protected constructor(baseOptions?:
|
|
17
|
+
protected constructor(baseOptions?: ODataHttpClientOptions);
|
|
34
18
|
/**
|
|
35
19
|
* Main function to implement by any extending http client.
|
|
36
20
|
* As it name suggests, the request gets executed in this method.
|
|
@@ -42,7 +26,7 @@ export declare abstract class BaseHttpClient<RequestConfigType> {
|
|
|
42
26
|
* @param config request configuration from end user which should override default settings
|
|
43
27
|
* @param internalConfig request configuration from base client including additional headers which should override end user configurations
|
|
44
28
|
*/
|
|
45
|
-
protected abstract executeRequest<ResponseModel>(method:
|
|
29
|
+
protected abstract executeRequest<ResponseModel>(method: ODataHttpMethods, url: string, data: any, config?: RequestConfigType, internalConfig?: BaseRequestConfig): Promise<HttpResponseModel<ResponseModel>>;
|
|
46
30
|
getCsrfTokenKey(): string;
|
|
47
31
|
setCsrfTokenKey(newKey: string): void;
|
|
48
32
|
setErrorMessageRetriever(getErrorMsg: ErrorMessageRetriever): void;
|
|
@@ -63,9 +47,9 @@ export declare abstract class BaseHttpClient<RequestConfigType> {
|
|
|
63
47
|
post<ResponseModel>(url: string, data: any, requestConfig?: RequestConfigType, additionalHeaders?: Record<string, string>): Promise<HttpResponseModel<ResponseModel>>;
|
|
64
48
|
put<ResponseModel>(url: string, data: any, requestConfig?: RequestConfigType, additionalHeaders?: Record<string, string>): Promise<HttpResponseModel<ResponseModel>>;
|
|
65
49
|
patch<ResponseModel>(url: string, data: any, requestConfig?: RequestConfigType, additionalHeaders?: Record<string, string>): Promise<HttpResponseModel<ResponseModel>>;
|
|
66
|
-
private getAdditionalHeaders;
|
|
67
50
|
delete(url: string, requestConfig?: RequestConfigType, additionalHeaders?: Record<string, string>): Promise<HttpResponseModel<void>>;
|
|
68
51
|
getBlob(url: string, requestConfig?: RequestConfigType, additionalHeaders?: Record<string, string>): ODataResponse<Blob>;
|
|
69
52
|
getStream(url: string, requestConfig?: RequestConfigType, additionalHeaders?: Record<string, string>): ODataResponse<ReadableStream>;
|
|
53
|
+
createBlob(url: string, data: Blob, mimeType: string, requestConfig?: RequestConfigType, additionalHeaders?: Record<string, string>): ODataResponse<void | Blob>;
|
|
70
54
|
updateBlob(url: string, data: Blob, mimeType: string, requestConfig?: RequestConfigType, additionalHeaders?: Record<string, string>): ODataResponse<void | Blob>;
|
|
71
55
|
}
|
package/lib/BaseHttpClient.js
CHANGED
|
@@ -2,19 +2,32 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BaseHttpClient = exports.DEFAULT_CSRF_TOKEN_KEY = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
+
const http_client_api_1 = require("@odata2ts/http-client-api");
|
|
6
|
+
const ODataHttpDataTypes_1 = require("@odata2ts/http-client-api/lib/ODataHttpDataTypes");
|
|
5
7
|
const ErrorMessageRetriever_1 = require("./ErrorMessageRetriever");
|
|
6
|
-
const HttpMethods_1 = require("./HttpMethods");
|
|
7
8
|
exports.DEFAULT_CSRF_TOKEN_KEY = "x-csrf-token";
|
|
8
|
-
const EDIT_METHODS = [HttpMethods_1.HttpMethods.Post, HttpMethods_1.HttpMethods.Put, HttpMethods_1.HttpMethods.Patch, HttpMethods_1.HttpMethods.Delete];
|
|
9
9
|
const FAILURE_MISSING_CSRF_URL = "When automatic CSRF token handling is activated, the URL must be supplied via attribute [csrfTokenFetchUrl]!";
|
|
10
10
|
const FAILURE_MISSING_URL = "Value for URL must be provided!";
|
|
11
11
|
const JSON_VALUE = "application/json";
|
|
12
12
|
function getInternalConfigWithJsonHeaders(headers, setContentType = true) {
|
|
13
13
|
return {
|
|
14
14
|
headers: Object.assign(Object.assign({ Accept: JSON_VALUE }, (setContentType ? { "Content-Type": JSON_VALUE } : undefined)), headers),
|
|
15
|
-
dataType:
|
|
15
|
+
dataType: ODataHttpDataTypes_1.ODataHttpDataTypes.JSON,
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
|
+
function getAdditionalHeaders(jsonResponse, additionalHeaders, contentType) {
|
|
19
|
+
let headers = {};
|
|
20
|
+
if (jsonResponse) {
|
|
21
|
+
headers.Accept = JSON_VALUE;
|
|
22
|
+
}
|
|
23
|
+
if (additionalHeaders) {
|
|
24
|
+
headers = Object.assign(Object.assign({}, headers), additionalHeaders);
|
|
25
|
+
}
|
|
26
|
+
if (contentType) {
|
|
27
|
+
headers["Content-Type"] = contentType;
|
|
28
|
+
}
|
|
29
|
+
return Object.keys(headers).length ? { headers } : undefined;
|
|
30
|
+
}
|
|
18
31
|
class BaseHttpClient {
|
|
19
32
|
constructor(baseOptions = { useCsrfProtection: false }) {
|
|
20
33
|
var _a;
|
|
@@ -45,7 +58,7 @@ class BaseHttpClient {
|
|
|
45
58
|
fetchSecurityToken() {
|
|
46
59
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
47
60
|
const fetchUrl = this.baseOptions.csrfTokenFetchUrl;
|
|
48
|
-
const response = yield this.sendRequest(
|
|
61
|
+
const response = yield this.sendRequest(http_client_api_1.ODataHttpMethods.Get, fetchUrl, undefined, undefined, {
|
|
49
62
|
noBodyEvaluation: true,
|
|
50
63
|
headers: { [this.csrfTokenKey]: "Fetch", Accept: JSON_VALUE },
|
|
51
64
|
});
|
|
@@ -69,7 +82,7 @@ class BaseHttpClient {
|
|
|
69
82
|
throw new Error(FAILURE_MISSING_URL);
|
|
70
83
|
}
|
|
71
84
|
// setup automatic CSRF token handling
|
|
72
|
-
if (this.baseOptions.useCsrfProtection &&
|
|
85
|
+
if (this.baseOptions.useCsrfProtection && http_client_api_1.DATA_MANIPULATION_METHODS.includes(method)) {
|
|
73
86
|
const [tokenKey, tokenValue] = yield this.setupSecurityToken();
|
|
74
87
|
if (tokenValue) {
|
|
75
88
|
if (!internalConfig.headers) {
|
|
@@ -97,34 +110,31 @@ class BaseHttpClient {
|
|
|
97
110
|
});
|
|
98
111
|
}
|
|
99
112
|
get(url, requestConfig, additionalHeaders) {
|
|
100
|
-
return this.sendRequest(
|
|
113
|
+
return this.sendRequest(http_client_api_1.ODataHttpMethods.Get, url, undefined, requestConfig, getInternalConfigWithJsonHeaders(additionalHeaders, false));
|
|
101
114
|
}
|
|
102
115
|
post(url, data, requestConfig, additionalHeaders) {
|
|
103
|
-
return this.sendRequest(
|
|
116
|
+
return this.sendRequest(http_client_api_1.ODataHttpMethods.Post, url, data, requestConfig, getInternalConfigWithJsonHeaders(additionalHeaders));
|
|
104
117
|
}
|
|
105
118
|
put(url, data, requestConfig, additionalHeaders) {
|
|
106
|
-
return this.sendRequest(
|
|
119
|
+
return this.sendRequest(http_client_api_1.ODataHttpMethods.Put, url, data, requestConfig, getInternalConfigWithJsonHeaders(additionalHeaders));
|
|
107
120
|
}
|
|
108
121
|
patch(url, data, requestConfig, additionalHeaders) {
|
|
109
|
-
return this.sendRequest(
|
|
110
|
-
}
|
|
111
|
-
getAdditionalHeaders(additionalHeaders) {
|
|
112
|
-
return additionalHeaders ? { headers: additionalHeaders } : undefined;
|
|
122
|
+
return this.sendRequest(http_client_api_1.ODataHttpMethods.Patch, url, data, requestConfig, getInternalConfigWithJsonHeaders(additionalHeaders));
|
|
113
123
|
}
|
|
114
124
|
delete(url, requestConfig, additionalHeaders) {
|
|
115
|
-
return this.sendRequest(
|
|
125
|
+
return this.sendRequest(http_client_api_1.ODataHttpMethods.Delete, url, undefined, requestConfig, getInternalConfigWithJsonHeaders(additionalHeaders, false));
|
|
116
126
|
}
|
|
117
127
|
getBlob(url, requestConfig, additionalHeaders) {
|
|
118
|
-
return this.sendRequest(
|
|
128
|
+
return this.sendRequest(http_client_api_1.ODataHttpMethods.Get, url, undefined, requestConfig, Object.assign(Object.assign({}, getAdditionalHeaders(false, additionalHeaders)), { dataType: ODataHttpDataTypes_1.ODataHttpDataTypes.BLOB }));
|
|
119
129
|
}
|
|
120
130
|
getStream(url, requestConfig, additionalHeaders) {
|
|
121
|
-
return this.sendRequest(
|
|
131
|
+
return this.sendRequest(http_client_api_1.ODataHttpMethods.Get, url, undefined, requestConfig, Object.assign(Object.assign({}, getAdditionalHeaders(false, additionalHeaders)), { dataType: ODataHttpDataTypes_1.ODataHttpDataTypes.STREAM }));
|
|
132
|
+
}
|
|
133
|
+
createBlob(url, data, mimeType, requestConfig, additionalHeaders) {
|
|
134
|
+
return this.sendRequest(http_client_api_1.ODataHttpMethods.Post, url, data, requestConfig, Object.assign(Object.assign({}, getAdditionalHeaders(true, additionalHeaders, mimeType)), { dataType: ODataHttpDataTypes_1.ODataHttpDataTypes.BLOB }));
|
|
122
135
|
}
|
|
123
136
|
updateBlob(url, data, mimeType, requestConfig, additionalHeaders) {
|
|
124
|
-
return this.sendRequest(
|
|
125
|
-
headers: Object.assign(Object.assign({}, additionalHeaders), { Accept: mimeType, "Content-Type": mimeType }),
|
|
126
|
-
dataType: "blob",
|
|
127
|
-
});
|
|
137
|
+
return this.sendRequest(http_client_api_1.ODataHttpMethods.Put, url, data, requestConfig, Object.assign(Object.assign({}, getAdditionalHeaders(true, additionalHeaders, mimeType)), { dataType: ODataHttpDataTypes_1.ODataHttpDataTypes.BLOB }));
|
|
128
138
|
}
|
|
129
139
|
}
|
|
130
140
|
exports.BaseHttpClient = BaseHttpClient;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseHttpClient.js","sourceRoot":"","sources":["../src/BaseHttpClient.ts"],"names":[],"mappings":";;;;AACA,mEAAsF;AACtF,+CAA4C;AA2B/B,QAAA,sBAAsB,GAAG,cAAc,CAAC;AAErD,MAAM,YAAY,GAAG,CAAC,yBAAW,CAAC,IAAI,EAAE,yBAAW,CAAC,GAAG,EAAE,yBAAW,CAAC,KAAK,EAAE,yBAAW,CAAC,MAAM,CAAC,CAAC;AAChG,MAAM,wBAAwB,GAC5B,8GAA8G,CAAC;AACjH,MAAM,mBAAmB,GAAG,iCAAiC,CAAC;AAC9D,MAAM,UAAU,GAAG,kBAAkB,CAAC;AAEtC,SAAS,gCAAgC,CACvC,OAAgC,EAChC,iBAA0B,IAAI;IAE9B,OAAO;QACL,OAAO,gCACL,MAAM,EAAE,UAAU,IACf,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAC7D,OAAO,CACX;QACD,QAAQ,EAAE,MAAM;KACjB,CAAC;AACJ,CAAC;AAED,MAAsB,cAAc;IAMlC,YAA8B,cAAqC,EAAE,iBAAiB,EAAE,KAAK,EAAE;;QAAjE,gBAAW,GAAX,WAAW,CAAsD;QAJvF,iBAAY,GAAG,8BAAsB,CAAC;QAEpC,yBAAoB,GAA0B,4CAAoB,CAAC;QAG3E,IAAI,WAAW,CAAC,iBAAiB,IAAI,CAAC,CAAA,MAAA,WAAW,CAAC,iBAAiB,0CAAE,IAAI,EAAE,CAAA,EAAE;YAC3E,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;SAC3C;IACH,CAAC;IAqBM,eAAe;QACpB,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAEM,eAAe,CAAC,MAAc;QACnC,IAAI,CAAC,YAAY,GAAG,MAAM,IAAI,8BAAsB,CAAC;IACvD,CAAC;IAEM,wBAAwB,CAAC,WAAkC;QAChE,IAAI,CAAC,oBAAoB,GAAG,WAAW,CAAC;IAC1C,CAAC;IAEe,kBAAkB;;YAChC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;gBACnB,IAAI,CAAC,SAAS,GAAG,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;aAClD;YACD,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7C,CAAC;KAAA;IAEe,kBAAkB;;YAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAY,CAAC,iBAAkB,CAAC;YACtD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,yBAAW,CAAC,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE;gBACvF,gBAAgB,EAAE,IAAI;gBACtB,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE;aAC9D,CAAC,CAAC;YAEH,OAAO,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC7C,CAAC;KAAA;IAED;;;;;;;;;OASG;IACW,WAAW,CACvB,MAAmB,EACnB,GAAW,EACX,IAAS,EACT,aAAiC,EACjC,iBAA2C,EAAE;;YAE7C,qCAAqC;YACrC,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;gBAC3B,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;aACtC;YAED,sCAAsC;YACtC,IAAI,IAAI,CAAC,WAAW,CAAC,iBAAiB,IAAI,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;gBACvE,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,GAAG,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAC/D,IAAI,UAAU,EAAE;oBACd,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;wBAC3B,cAAc,CAAC,OAAO,GAAG,EAAE,CAAC;qBAC7B;oBACD,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,UAAU,CAAC;iBAC/C;aACF;YAED,IAAI;gBACF,OAAO,MAAM,IAAI,CAAC,cAAc,CAC9B,MAAM,EACN,GAAG,EACH,IAAI,EACJ,aAAa,EACb,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAChE,CAAC;aACH;YAAC,OAAO,CAAC,EAAE;gBACV,MAAM,WAAW,GAAG,CAAqB,CAAC;gBAE1C,gCAAgC;gBAChC,IACE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,iBAAiB;oBACpC,WAAW,CAAC,MAAM,KAAK,GAAG;oBAC1B,CAAC,CAAC,WAAW,CAAC,OAAO;oBACrB,WAAW,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,UAAU,EAClD;oBACA,2EAA2E;oBAC3E,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;oBAC3B,OAAO,IAAI,CAAC,WAAW,CAAgB,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC;iBAC1E;gBAED,MAAM,CAAC,CAAC;aACT;QACH,CAAC;KAAA;IAEM,GAAG,CACR,GAAW,EACX,aAAiC,EACjC,iBAA0C;QAE1C,OAAO,IAAI,CAAC,WAAW,CACrB,yBAAW,CAAC,GAAG,EACf,GAAG,EACH,SAAS,EACT,aAAa,EACb,gCAAgC,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAC3D,CAAC;IACJ,CAAC;IAEM,IAAI,CACT,GAAW,EACX,IAAS,EACT,aAAiC,EACjC,iBAA0C;QAE1C,OAAO,IAAI,CAAC,WAAW,CACrB,yBAAW,CAAC,IAAI,EAChB,GAAG,EACH,IAAI,EACJ,aAAa,EACb,gCAAgC,CAAC,iBAAiB,CAAC,CACpD,CAAC;IACJ,CAAC;IAEM,GAAG,CACR,GAAW,EACX,IAAS,EACT,aAAiC,EACjC,iBAA0C;QAE1C,OAAO,IAAI,CAAC,WAAW,CACrB,yBAAW,CAAC,GAAG,EACf,GAAG,EACH,IAAI,EACJ,aAAa,EACb,gCAAgC,CAAC,iBAAiB,CAAC,CACpD,CAAC;IACJ,CAAC;IAEM,KAAK,CACV,GAAW,EACX,IAAS,EACT,aAAiC,EACjC,iBAA0C;QAE1C,OAAO,IAAI,CAAC,WAAW,CACrB,yBAAW,CAAC,KAAK,EACjB,GAAG,EACH,IAAI,EACJ,aAAa,EACb,gCAAgC,CAAC,iBAAiB,CAAC,CACpD,CAAC;IACJ,CAAC;IAEO,oBAAoB,CAAC,iBAA0C;QACrE,OAAO,iBAAiB,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACxE,CAAC;IAEM,MAAM,CACX,GAAW,EACX,aAAiC,EACjC,iBAA0C;QAE1C,OAAO,IAAI,CAAC,WAAW,CACrB,yBAAW,CAAC,MAAM,EAClB,GAAG,EACH,SAAS,EACT,aAAa,EACb,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,CAC7C,CAAC;IACJ,CAAC;IAEM,OAAO,CACZ,GAAW,EACX,aAAiC,EACjC,iBAA0C;QAE1C,OAAO,IAAI,CAAC,WAAW,CAAC,yBAAW,CAAC,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,aAAa,kCACjE,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,KAC/C,QAAQ,EAAE,MAAM,IAChB,CAAC;IACL,CAAC;IAEM,SAAS,CACd,GAAW,EACX,aAAiC,EACjC,iBAA0C;QAE1C,OAAO,IAAI,CAAC,WAAW,CAAC,yBAAW,CAAC,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,aAAa,kCACjE,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,KAC/C,QAAQ,EAAE,QAAQ,IAClB,CAAC;IACL,CAAC;IAEM,UAAU,CACf,GAAW,EACX,IAAU,EACV,QAAgB,EAChB,aAAiC,EACjC,iBAA0C;QAE1C,OAAO,IAAI,CAAC,WAAW,CAAC,yBAAW,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,aAAa,EAAE;YACjE,OAAO,kCAAO,iBAAiB,KAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,GAAE;YAC7E,QAAQ,EAAE,MAAM;SACjB,CAAC,CAAC;IACL,CAAC;CACF;AAvOD,wCAuOC","sourcesContent":["import { HttpResponseModel, ODataClientError, ODataResponse } from \"@odata2ts/http-client-api\";\r\nimport { ErrorMessageRetriever, retrieveErrorMessage } from \"./ErrorMessageRetriever\";\r\nimport { HttpMethods } from \"./HttpMethods\";\r\n\r\nexport interface BaseHttpClientOptions {\r\n /**\r\n * Enable automatic CSRF token handling.\r\n */\r\n useCsrfProtection?: boolean;\r\n /**\r\n * Specify the URL from which the token is fetched.\r\n * This could be any path to your OData service, since the token is exchanged via HTTP request headers.\r\n * However, it should be a fast response and usually the root URL to the OData service is a good choice.\r\n */\r\n csrfTokenFetchUrl?: string;\r\n}\r\n\r\nexport interface InternalHttpClientConfig {\r\n dataType?: \"json\" | \"blob\" | \"stream\";\r\n /**\r\n * Additional headers set internally by services or HttpClient implementation.\r\n */\r\n headers?: Record<string, string>;\r\n /**\r\n * Very special option needed for FetchClient to not evaluate the response body in certain situations.\r\n */\r\n noBodyEvaluation?: boolean;\r\n}\r\n\r\nexport const DEFAULT_CSRF_TOKEN_KEY = \"x-csrf-token\";\r\n\r\nconst EDIT_METHODS = [HttpMethods.Post, HttpMethods.Put, HttpMethods.Patch, HttpMethods.Delete];\r\nconst FAILURE_MISSING_CSRF_URL =\r\n \"When automatic CSRF token handling is activated, the URL must be supplied via attribute [csrfTokenFetchUrl]!\";\r\nconst FAILURE_MISSING_URL = \"Value for URL must be provided!\";\r\nconst JSON_VALUE = \"application/json\";\r\n\r\nfunction getInternalConfigWithJsonHeaders(\r\n headers?: Record<string, string>,\r\n setContentType: boolean = true,\r\n): InternalHttpClientConfig {\r\n return {\r\n headers: {\r\n Accept: JSON_VALUE,\r\n ...(setContentType ? { \"Content-Type\": JSON_VALUE } : undefined),\r\n ...headers,\r\n },\r\n dataType: \"json\",\r\n };\r\n}\r\n\r\nexport abstract class BaseHttpClient<RequestConfigType> {\r\n private csrfToken: string | undefined;\r\n private csrfTokenKey = DEFAULT_CSRF_TOKEN_KEY;\r\n\r\n protected retrieveErrorMessage: ErrorMessageRetriever = retrieveErrorMessage;\r\n\r\n protected constructor(private baseOptions: BaseHttpClientOptions = { useCsrfProtection: false }) {\r\n if (baseOptions.useCsrfProtection && !baseOptions.csrfTokenFetchUrl?.trim()) {\r\n throw new Error(FAILURE_MISSING_CSRF_URL);\r\n }\r\n }\r\n\r\n /**\r\n * Main function to implement by any extending http client.\r\n * As it name suggests, the request gets executed in this method.\r\n * Additionally, failures should be handled and errors of type <code>HttpClientError</code> should be thrown.\r\n *\r\n * @param method the http method to use\r\n * @param url the URL to use\r\n * @param data data for the request body if any\r\n * @param config request configuration from end user which should override default settings\r\n * @param internalConfig request configuration from base client including additional headers which should override end user configurations\r\n */\r\n protected abstract executeRequest<ResponseModel>(\r\n method: HttpMethods,\r\n url: string,\r\n data: any,\r\n config?: RequestConfigType,\r\n internalConfig?: InternalHttpClientConfig,\r\n ): Promise<HttpResponseModel<ResponseModel>>;\r\n\r\n public getCsrfTokenKey() {\r\n return this.csrfTokenKey;\r\n }\r\n\r\n public setCsrfTokenKey(newKey: string) {\r\n this.csrfTokenKey = newKey || DEFAULT_CSRF_TOKEN_KEY;\r\n }\r\n\r\n public setErrorMessageRetriever(getErrorMsg: ErrorMessageRetriever) {\r\n this.retrieveErrorMessage = getErrorMsg;\r\n }\r\n\r\n protected async setupSecurityToken(): Promise<[string, string | undefined]> {\r\n if (!this.csrfToken) {\r\n this.csrfToken = await this.fetchSecurityToken();\r\n }\r\n return [this.csrfTokenKey, this.csrfToken];\r\n }\r\n\r\n protected async fetchSecurityToken(): Promise<string | undefined> {\r\n const fetchUrl = this.baseOptions!.csrfTokenFetchUrl!;\r\n const response = await this.sendRequest(HttpMethods.Get, fetchUrl, undefined, undefined, {\r\n noBodyEvaluation: true,\r\n headers: { [this.csrfTokenKey]: \"Fetch\", Accept: JSON_VALUE },\r\n });\r\n\r\n return response.headers[this.csrfTokenKey];\r\n }\r\n\r\n /**\r\n * Follows the template pattern.\r\n *\r\n * @param method\r\n * @param url\r\n * @param data\r\n * @param requestConfig\r\n * @param internalConfig\r\n * @private\r\n */\r\n private async sendRequest<ResponseModel>(\r\n method: HttpMethods,\r\n url: string,\r\n data: any,\r\n requestConfig?: RequestConfigType,\r\n internalConfig: InternalHttpClientConfig = {},\r\n ): Promise<HttpResponseModel<ResponseModel>> {\r\n // noinspection SuspiciousTypeOfGuard\r\n if (typeof url !== \"string\") {\r\n throw new Error(FAILURE_MISSING_URL);\r\n }\r\n\r\n // setup automatic CSRF token handling\r\n if (this.baseOptions.useCsrfProtection && EDIT_METHODS.includes(method)) {\r\n const [tokenKey, tokenValue] = await this.setupSecurityToken();\r\n if (tokenValue) {\r\n if (!internalConfig.headers) {\r\n internalConfig.headers = {};\r\n }\r\n internalConfig.headers[tokenKey] = tokenValue;\r\n }\r\n }\r\n\r\n try {\r\n return await this.executeRequest<ResponseModel>(\r\n method,\r\n url,\r\n data,\r\n requestConfig,\r\n Object.keys(internalConfig).length ? internalConfig : undefined,\r\n );\r\n } catch (e) {\r\n const clientError = e as ODataClientError;\r\n\r\n // automatic CSRF token handling\r\n if (\r\n !!this.baseOptions.useCsrfProtection &&\r\n clientError.status === 403 &&\r\n !!clientError.headers &&\r\n clientError.headers[\"x-csrf-token\"] === \"Required\"\r\n ) {\r\n // token has expired: reset csrf token & perform the original request again\r\n this.csrfToken = undefined;\r\n return this.sendRequest<ResponseModel>(method, url, data, requestConfig);\r\n }\r\n\r\n throw e;\r\n }\r\n }\r\n\r\n public get<ResponseModel>(\r\n url: string,\r\n requestConfig?: RequestConfigType,\r\n additionalHeaders?: Record<string, string>,\r\n ): Promise<HttpResponseModel<ResponseModel>> {\r\n return this.sendRequest<ResponseModel>(\r\n HttpMethods.Get,\r\n url,\r\n undefined,\r\n requestConfig,\r\n getInternalConfigWithJsonHeaders(additionalHeaders, false),\r\n );\r\n }\r\n\r\n public post<ResponseModel>(\r\n url: string,\r\n data: any,\r\n requestConfig?: RequestConfigType,\r\n additionalHeaders?: Record<string, string>,\r\n ): Promise<HttpResponseModel<ResponseModel>> {\r\n return this.sendRequest<ResponseModel>(\r\n HttpMethods.Post,\r\n url,\r\n data,\r\n requestConfig,\r\n getInternalConfigWithJsonHeaders(additionalHeaders),\r\n );\r\n }\r\n\r\n public put<ResponseModel>(\r\n url: string,\r\n data: any,\r\n requestConfig?: RequestConfigType,\r\n additionalHeaders?: Record<string, string>,\r\n ): Promise<HttpResponseModel<ResponseModel>> {\r\n return this.sendRequest<ResponseModel>(\r\n HttpMethods.Put,\r\n url,\r\n data,\r\n requestConfig,\r\n getInternalConfigWithJsonHeaders(additionalHeaders),\r\n );\r\n }\r\n\r\n public patch<ResponseModel>(\r\n url: string,\r\n data: any,\r\n requestConfig?: RequestConfigType,\r\n additionalHeaders?: Record<string, string>,\r\n ): Promise<HttpResponseModel<ResponseModel>> {\r\n return this.sendRequest<ResponseModel>(\r\n HttpMethods.Patch,\r\n url,\r\n data,\r\n requestConfig,\r\n getInternalConfigWithJsonHeaders(additionalHeaders),\r\n );\r\n }\r\n\r\n private getAdditionalHeaders(additionalHeaders?: Record<string, string>) {\r\n return additionalHeaders ? { headers: additionalHeaders } : undefined;\r\n }\r\n\r\n public delete(\r\n url: string,\r\n requestConfig?: RequestConfigType,\r\n additionalHeaders?: Record<string, string>,\r\n ): Promise<HttpResponseModel<void>> {\r\n return this.sendRequest<void>(\r\n HttpMethods.Delete,\r\n url,\r\n undefined,\r\n requestConfig,\r\n this.getAdditionalHeaders(additionalHeaders),\r\n );\r\n }\r\n\r\n public getBlob(\r\n url: string,\r\n requestConfig?: RequestConfigType,\r\n additionalHeaders?: Record<string, string>,\r\n ): ODataResponse<Blob> {\r\n return this.sendRequest(HttpMethods.Get, url, undefined, requestConfig, {\r\n ...this.getAdditionalHeaders(additionalHeaders),\r\n dataType: \"blob\",\r\n });\r\n }\r\n\r\n public getStream(\r\n url: string,\r\n requestConfig?: RequestConfigType,\r\n additionalHeaders?: Record<string, string>,\r\n ): ODataResponse<ReadableStream> {\r\n return this.sendRequest(HttpMethods.Get, url, undefined, requestConfig, {\r\n ...this.getAdditionalHeaders(additionalHeaders),\r\n dataType: \"stream\",\r\n });\r\n }\r\n\r\n public updateBlob(\r\n url: string,\r\n data: Blob,\r\n mimeType: string,\r\n requestConfig?: RequestConfigType,\r\n additionalHeaders?: Record<string, string>,\r\n ): ODataResponse<void | Blob> {\r\n return this.sendRequest(HttpMethods.Put, url, data, requestConfig, {\r\n headers: { ...additionalHeaders, Accept: mimeType, \"Content-Type\": mimeType },\r\n dataType: \"blob\",\r\n });\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"BaseHttpClient.js","sourceRoot":"","sources":["../src/BaseHttpClient.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DATA_MANIPULATION_METHODS,\n HttpResponseModel,\n ODataClientError,\n ODataHttpClientOptions,\n ODataHttpMethods,\n ODataRequestConfig,\n ODataResponse,\n} from \"@odata2ts/http-client-api\";\nimport { ODataHttpDataTypes } from \"@odata2ts/http-client-api/lib/ODataHttpDataTypes\";\nimport { ErrorMessageRetriever, retrieveErrorMessage } from \"./ErrorMessageRetriever\";\n\nexport interface BaseRequestConfig extends ODataRequestConfig {\n dataType?: ODataHttpDataTypes;\n /**\n * Very special option needed for FetchClient to not evaluate the response body in certain situations.\n */\n noBodyEvaluation?: boolean;\n}\n\nexport const DEFAULT_CSRF_TOKEN_KEY = \"x-csrf-token\";\nconst FAILURE_MISSING_CSRF_URL =\n \"When automatic CSRF token handling is activated, the URL must be supplied via attribute [csrfTokenFetchUrl]!\";\nconst FAILURE_MISSING_URL = \"Value for URL must be provided!\";\nconst JSON_VALUE = \"application/json\";\n\nfunction getInternalConfigWithJsonHeaders(\n headers?: Record<string, string>,\n setContentType: boolean = true,\n): BaseRequestConfig {\n return {\n headers: {\n Accept: JSON_VALUE,\n ...(setContentType ? { \"Content-Type\": JSON_VALUE } : undefined),\n ...headers,\n },\n dataType: ODataHttpDataTypes.JSON,\n };\n}\n\nfunction getAdditionalHeaders(jsonResponse: boolean, additionalHeaders?: Record<string, string>, contentType?: string) {\n let headers: Record<string, string> = {};\n if (jsonResponse) {\n headers.Accept = JSON_VALUE;\n }\n if (additionalHeaders) {\n headers = { ...headers, ...additionalHeaders };\n }\n if (contentType) {\n headers[\"Content-Type\"] = contentType;\n }\n\n return Object.keys(headers).length ? { headers } : undefined;\n}\n\nexport abstract class BaseHttpClient<RequestConfigType> {\n private csrfToken: string | undefined;\n private csrfTokenKey = DEFAULT_CSRF_TOKEN_KEY;\n\n protected retrieveErrorMessage: ErrorMessageRetriever = retrieveErrorMessage;\n\n protected constructor(private baseOptions: ODataHttpClientOptions = { useCsrfProtection: false }) {\n if (baseOptions.useCsrfProtection && !baseOptions.csrfTokenFetchUrl?.trim()) {\n throw new Error(FAILURE_MISSING_CSRF_URL);\n }\n }\n\n /**\n * Main function to implement by any extending http client.\n * As it name suggests, the request gets executed in this method.\n * Additionally, failures should be handled and errors of type <code>HttpClientError</code> should be thrown.\n *\n * @param method the http method to use\n * @param url the URL to use\n * @param data data for the request body if any\n * @param config request configuration from end user which should override default settings\n * @param internalConfig request configuration from base client including additional headers which should override end user configurations\n */\n protected abstract executeRequest<ResponseModel>(\n method: ODataHttpMethods,\n url: string,\n data: any,\n config?: RequestConfigType,\n internalConfig?: BaseRequestConfig,\n ): Promise<HttpResponseModel<ResponseModel>>;\n\n public getCsrfTokenKey() {\n return this.csrfTokenKey;\n }\n\n public setCsrfTokenKey(newKey: string) {\n this.csrfTokenKey = newKey || DEFAULT_CSRF_TOKEN_KEY;\n }\n\n public setErrorMessageRetriever(getErrorMsg: ErrorMessageRetriever) {\n this.retrieveErrorMessage = getErrorMsg;\n }\n\n protected async setupSecurityToken(): Promise<[string, string | undefined]> {\n if (!this.csrfToken) {\n this.csrfToken = await this.fetchSecurityToken();\n }\n return [this.csrfTokenKey, this.csrfToken];\n }\n\n protected async fetchSecurityToken(): Promise<string | undefined> {\n const fetchUrl = this.baseOptions!.csrfTokenFetchUrl!;\n const response = await this.sendRequest(ODataHttpMethods.Get, fetchUrl, undefined, undefined, {\n noBodyEvaluation: true,\n headers: { [this.csrfTokenKey]: \"Fetch\", Accept: JSON_VALUE },\n });\n\n return response.headers[this.csrfTokenKey];\n }\n\n /**\n * Follows the template pattern.\n *\n * @param method\n * @param url\n * @param data\n * @param requestConfig\n * @param internalConfig\n * @private\n */\n private async sendRequest<ResponseModel>(\n method: ODataHttpMethods,\n url: string,\n data: any,\n requestConfig?: RequestConfigType,\n internalConfig: BaseRequestConfig = {},\n ): Promise<HttpResponseModel<ResponseModel>> {\n // noinspection SuspiciousTypeOfGuard\n if (typeof url !== \"string\") {\n throw new Error(FAILURE_MISSING_URL);\n }\n\n // setup automatic CSRF token handling\n if (this.baseOptions.useCsrfProtection && DATA_MANIPULATION_METHODS.includes(method)) {\n const [tokenKey, tokenValue] = await this.setupSecurityToken();\n if (tokenValue) {\n if (!internalConfig.headers) {\n internalConfig.headers = {};\n }\n internalConfig.headers[tokenKey] = tokenValue;\n }\n }\n\n try {\n return await this.executeRequest<ResponseModel>(\n method,\n url,\n data,\n requestConfig,\n Object.keys(internalConfig).length ? internalConfig : undefined,\n );\n } catch (e) {\n const clientError = e as ODataClientError;\n\n // automatic CSRF token handling\n if (\n !!this.baseOptions.useCsrfProtection &&\n clientError.status === 403 &&\n !!clientError.headers &&\n clientError.headers[\"x-csrf-token\"] === \"Required\"\n ) {\n // token has expired: reset csrf token & perform the original request again\n this.csrfToken = undefined;\n return this.sendRequest<ResponseModel>(method, url, data, requestConfig);\n }\n\n throw e;\n }\n }\n\n public get<ResponseModel>(\n url: string,\n requestConfig?: RequestConfigType,\n additionalHeaders?: Record<string, string>,\n ): Promise<HttpResponseModel<ResponseModel>> {\n return this.sendRequest<ResponseModel>(\n ODataHttpMethods.Get,\n url,\n undefined,\n requestConfig,\n getInternalConfigWithJsonHeaders(additionalHeaders, false),\n );\n }\n\n public post<ResponseModel>(\n url: string,\n data: any,\n requestConfig?: RequestConfigType,\n additionalHeaders?: Record<string, string>,\n ): Promise<HttpResponseModel<ResponseModel>> {\n return this.sendRequest<ResponseModel>(\n ODataHttpMethods.Post,\n url,\n data,\n requestConfig,\n getInternalConfigWithJsonHeaders(additionalHeaders),\n );\n }\n\n public put<ResponseModel>(\n url: string,\n data: any,\n requestConfig?: RequestConfigType,\n additionalHeaders?: Record<string, string>,\n ): Promise<HttpResponseModel<ResponseModel>> {\n return this.sendRequest<ResponseModel>(\n ODataHttpMethods.Put,\n url,\n data,\n requestConfig,\n getInternalConfigWithJsonHeaders(additionalHeaders),\n );\n }\n\n public patch<ResponseModel>(\n url: string,\n data: any,\n requestConfig?: RequestConfigType,\n additionalHeaders?: Record<string, string>,\n ): Promise<HttpResponseModel<ResponseModel>> {\n return this.sendRequest<ResponseModel>(\n ODataHttpMethods.Patch,\n url,\n data,\n requestConfig,\n getInternalConfigWithJsonHeaders(additionalHeaders),\n );\n }\n\n public delete(\n url: string,\n requestConfig?: RequestConfigType,\n additionalHeaders?: Record<string, string>,\n ): Promise<HttpResponseModel<void>> {\n return this.sendRequest<void>(\n ODataHttpMethods.Delete,\n url,\n undefined,\n requestConfig,\n getInternalConfigWithJsonHeaders(additionalHeaders, false),\n );\n }\n\n public getBlob(\n url: string,\n requestConfig?: RequestConfigType,\n additionalHeaders?: Record<string, string>,\n ): ODataResponse<Blob> {\n return this.sendRequest(ODataHttpMethods.Get, url, undefined, requestConfig, {\n ...getAdditionalHeaders(false, additionalHeaders),\n dataType: ODataHttpDataTypes.BLOB,\n });\n }\n\n public getStream(\n url: string,\n requestConfig?: RequestConfigType,\n additionalHeaders?: Record<string, string>,\n ): ODataResponse<ReadableStream> {\n return this.sendRequest(ODataHttpMethods.Get, url, undefined, requestConfig, {\n ...getAdditionalHeaders(false, additionalHeaders),\n dataType: ODataHttpDataTypes.STREAM,\n });\n }\n\n public createBlob(\n url: string,\n data: Blob,\n mimeType: string,\n requestConfig?: RequestConfigType,\n additionalHeaders?: Record<string, string>,\n ): ODataResponse<void | Blob> {\n return this.sendRequest(ODataHttpMethods.Post, url, data, requestConfig, {\n ...getAdditionalHeaders(true, additionalHeaders, mimeType),\n dataType: ODataHttpDataTypes.BLOB,\n });\n }\n\n public updateBlob(\n url: string,\n data: Blob,\n mimeType: string,\n requestConfig?: RequestConfigType,\n additionalHeaders?: Record<string, string>,\n ): ODataResponse<void | Blob> {\n return this.sendRequest(ODataHttpMethods.Put, url, data, requestConfig, {\n ...getAdditionalHeaders(true, additionalHeaders, mimeType),\n dataType: ODataHttpDataTypes.BLOB,\n });\n }\n}\n"]}
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.BaseHttpClient = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
tslib_1.__exportStar(require("./ErrorMessageRetriever"), exports);
|
|
6
6
|
var BaseHttpClient_1 = require("./BaseHttpClient");
|
|
7
7
|
Object.defineProperty(exports, "BaseHttpClient", { enumerable: true, get: function () { return BaseHttpClient_1.BaseHttpClient; } });
|
|
8
|
-
var HttpMethods_1 = require("./HttpMethods");
|
|
9
|
-
Object.defineProperty(exports, "HttpMethods", { enumerable: true, get: function () { return HttpMethods_1.HttpMethods; } });
|
|
10
8
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAAA,kEAAwC;AACxC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAAA,kEAAwC;AACxC,mDAAqE;AAA5D,gHAAA,cAAc,OAAA","sourcesContent":["export * from \"./ErrorMessageRetriever\";\nexport { BaseHttpClient, BaseRequestConfig } from \"./BaseHttpClient\";\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@odata2ts/http-client-base",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.5",
|
|
4
4
|
"description": "Core functionality for odata2ts HTTP clients",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"http client",
|
|
@@ -24,11 +24,10 @@
|
|
|
24
24
|
"check-circular-deps": "madge ./src --extensions ts --circular",
|
|
25
25
|
"clean": "rimraf lib coverage",
|
|
26
26
|
"compile": "tsc",
|
|
27
|
-
"prepublish": "yarn build",
|
|
28
27
|
"test": "vitest run"
|
|
29
28
|
},
|
|
30
29
|
"dependencies": {
|
|
31
|
-
"@odata2ts/http-client-api": "^0.6.
|
|
30
|
+
"@odata2ts/http-client-api": "^0.6.4"
|
|
32
31
|
},
|
|
33
32
|
"devDependencies": {
|
|
34
33
|
"@odata2ts/odata-core": "^0.3.7",
|
|
@@ -38,6 +37,5 @@
|
|
|
38
37
|
},
|
|
39
38
|
"publishConfig": {
|
|
40
39
|
"access": "public"
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
}
|
|
40
|
+
}
|
|
41
|
+
}
|
package/lib/HttpMethods.d.ts
DELETED
package/lib/HttpMethods.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HttpMethods = void 0;
|
|
4
|
-
var HttpMethods;
|
|
5
|
-
(function (HttpMethods) {
|
|
6
|
-
HttpMethods["Get"] = "GET";
|
|
7
|
-
HttpMethods["Post"] = "POST";
|
|
8
|
-
HttpMethods["Put"] = "PUT";
|
|
9
|
-
HttpMethods["Patch"] = "PATCH";
|
|
10
|
-
HttpMethods["Delete"] = "DELETE";
|
|
11
|
-
})(HttpMethods = exports.HttpMethods || (exports.HttpMethods = {}));
|
|
12
|
-
//# sourceMappingURL=HttpMethods.js.map
|
package/lib/HttpMethods.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"HttpMethods.js","sourceRoot":"","sources":["../src/HttpMethods.ts"],"names":[],"mappings":";;;AAAA,IAAY,WAMX;AAND,WAAY,WAAW;IACrB,0BAAW,CAAA;IACX,4BAAa,CAAA;IACb,0BAAW,CAAA;IACX,8BAAe,CAAA;IACf,gCAAiB,CAAA;AACnB,CAAC,EANW,WAAW,GAAX,mBAAW,KAAX,mBAAW,QAMtB","sourcesContent":["export enum HttpMethods {\n Get = \"GET\",\n Post = \"POST\",\n Put = \"PUT\",\n Patch = \"PATCH\",\n Delete = \"DELETE\",\n}\n"]}
|