@odata2ts/http-client-fetch 0.1.0 → 0.2.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/CHANGELOG.md +7 -0
- package/README.md +12 -7
- package/lib/{FetchODataClient.d.ts → FetchClient.d.ts} +2 -2
- package/lib/{FetchODataClient.js → FetchClient.js} +8 -8
- package/lib/FetchClient.js.map +1 -0
- package/lib/{FetchODataClientError.d.ts → FetchClientError.d.ts} +1 -1
- package/lib/{FetchODataClientError.js → FetchClientError.js} +4 -4
- package/lib/FetchClientError.js.map +1 -0
- package/lib/index.d.ts +2 -2
- package/lib/index.js +4 -4
- package/lib/index.js.map +1 -1
- package/package.json +3 -3
- package/lib/FetchODataClient.js.map +0 -1
- package/lib/FetchODataClientError.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,13 @@
|
|
|
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.2.0](https://github.com/odata2ts/http-client/compare/@odata2ts/http-client-fetch@0.1.0...@odata2ts/http-client-fetch@0.2.0) (2023-06-03)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* switch to http-client-api ([52d1b86](https://github.com/odata2ts/http-client/commit/52d1b868ee82dbaf45486da6b22fdcf4c773dfb8))
|
|
11
|
+
* switch to http-client-api ([5a6da23](https://github.com/odata2ts/http-client/commit/5a6da23053b3ea5adb866bb7e30b469f1b8ed260))
|
|
12
|
+
|
|
6
13
|
# 0.1.0 (2023-05-29)
|
|
7
14
|
|
|
8
15
|
### Features
|
package/README.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
[](https://www.npmjs.com/package/@odata2ts/http-client-fetch)
|
|
2
2
|
|
|
3
|
-
# Fetch
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
# Fetch HTTP Client
|
|
4
|
+
|
|
5
|
+
Fetch based HTTP client for [odata2ts](https://github.com/odata2ts/odata2ts).
|
|
6
|
+
This client uses - as its name suggests - [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
|
|
6
7
|
for realizing the HTTP communication.
|
|
7
8
|
|
|
8
9
|
It supports:
|
|
@@ -10,6 +11,8 @@ It supports:
|
|
|
10
11
|
- request configuration
|
|
11
12
|
- automatic CSRF token handling
|
|
12
13
|
|
|
14
|
+
Works also for Node.js v18+, but is still marked as **experimental**.
|
|
15
|
+
|
|
13
16
|
## Installation
|
|
14
17
|
|
|
15
18
|
Install package `@odata2ts/http-client-fetch` as runtime dependency:
|
|
@@ -19,27 +22,29 @@ npm install --save @odata2ts/http-client-fetch
|
|
|
19
22
|
```
|
|
20
23
|
|
|
21
24
|
## Documentation
|
|
22
|
-
|
|
25
|
+
|
|
26
|
+
[Fetch Client Documentation](https://odata2ts.github.io/docs/odata-client/http-client/fetch)
|
|
23
27
|
|
|
24
28
|
Main documentation for the odata2ts eco system:
|
|
25
29
|
[https://odata2ts.github.io](https://odata2ts.github.io/)
|
|
26
30
|
|
|
27
31
|
## Tests
|
|
32
|
+
|
|
28
33
|
See folder [test](https://github.com/odata2ts/http-client/tree/main/packages/fetch/test)
|
|
29
34
|
for unit tests.
|
|
30
35
|
|
|
31
36
|
See folder [int-test](https://github.com/odata2ts/http-client/tree/main/packages/fetch/int-test) for
|
|
32
37
|
integration tests.
|
|
33
38
|
|
|
34
|
-
|
|
35
39
|
## Support, Feedback, Contributing
|
|
36
40
|
|
|
37
|
-
This project is open to feature requests, suggestions, bug reports, usage questions etc.
|
|
38
|
-
via [GitHub issues](https://github.com/odata2ts/http-client/issues).
|
|
41
|
+
This project is open to feature requests, suggestions, bug reports, usage questions etc.
|
|
42
|
+
via [GitHub issues](https://github.com/odata2ts/http-client/issues).
|
|
39
43
|
|
|
40
44
|
Contributions and feedback are encouraged and always welcome.
|
|
41
45
|
|
|
42
46
|
See the [contribution guidelines](https://github.com/odata2ts/http-client/blob/main/CONTRIBUTING.md) for further information.
|
|
43
47
|
|
|
44
48
|
## License
|
|
49
|
+
|
|
45
50
|
MIT - see [License](./LICENSE).
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HttpResponseModel,
|
|
1
|
+
import { HttpResponseModel, ODataHttpClient } from "@odata2ts/http-client-api";
|
|
2
2
|
import { FetchRequestConfig } from "./FetchRequestConfig";
|
|
3
3
|
export type ErrorMessageRetriever = (errorResponse: any) => string | undefined;
|
|
4
4
|
export interface ClientOptions {
|
|
@@ -7,7 +7,7 @@ export interface ClientOptions {
|
|
|
7
7
|
}
|
|
8
8
|
export declare const getV2OrV4ErrorMessage: ErrorMessageRetriever;
|
|
9
9
|
export declare const DEFAULT_ERROR_MESSAGE = "No error message!";
|
|
10
|
-
export declare class
|
|
10
|
+
export declare class FetchClient implements ODataHttpClient<FetchRequestConfig> {
|
|
11
11
|
private clientOptions?;
|
|
12
12
|
private readonly config;
|
|
13
13
|
private csrfToken;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.FetchClient = exports.DEFAULT_ERROR_MESSAGE = exports.getV2OrV4ErrorMessage = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const
|
|
5
|
+
const FetchClientError_1 = require("./FetchClientError");
|
|
6
6
|
const FetchRequestConfig_1 = require("./FetchRequestConfig");
|
|
7
7
|
const getV2OrV4ErrorMessage = (errorResponse) => {
|
|
8
8
|
var _a;
|
|
@@ -18,7 +18,7 @@ function buildErrorMessage(prefix, error) {
|
|
|
18
18
|
const msg = typeof error === "string" ? error : error === null || error === void 0 ? void 0 : error.message;
|
|
19
19
|
return prefix + (msg || exports.DEFAULT_ERROR_MESSAGE);
|
|
20
20
|
}
|
|
21
|
-
class
|
|
21
|
+
class FetchClient {
|
|
22
22
|
constructor(config, clientOptions) {
|
|
23
23
|
var _a;
|
|
24
24
|
this.clientOptions = clientOptions;
|
|
@@ -69,7 +69,7 @@ class FetchODataClient {
|
|
|
69
69
|
response = yield fetch(url, mergedConfig);
|
|
70
70
|
}
|
|
71
71
|
catch (fetchError) {
|
|
72
|
-
throw new
|
|
72
|
+
throw new FetchClientError_1.FetchClientError(buildErrorMessage(FETCH_FAILURE_MESSAGE, fetchError), undefined, fetchError);
|
|
73
73
|
}
|
|
74
74
|
// error response
|
|
75
75
|
if (!response.ok) {
|
|
@@ -83,7 +83,7 @@ class FetchODataClient {
|
|
|
83
83
|
}
|
|
84
84
|
let data = yield this.getResponseBody(response, false);
|
|
85
85
|
const errMsg = this.retrieveErrorMessage(data);
|
|
86
|
-
throw new
|
|
86
|
+
throw new FetchClientError_1.FetchClientError(buildErrorMessage(RESPONSE_FAILURE_MESSAGE, errMsg), response.status, new Error(errMsg || exports.DEFAULT_ERROR_MESSAGE), response);
|
|
87
87
|
}
|
|
88
88
|
const data = yield this.getResponseBody(response, true);
|
|
89
89
|
// header
|
|
@@ -110,7 +110,7 @@ class FetchODataClient {
|
|
|
110
110
|
}
|
|
111
111
|
catch (error) {
|
|
112
112
|
if (isFailedJsonFatal) {
|
|
113
|
-
throw new
|
|
113
|
+
throw new FetchClientError_1.FetchClientError(buildErrorMessage(JSON_RETRIEVAL_FAILURE_MESSAGE, error), response.status, error);
|
|
114
114
|
}
|
|
115
115
|
return undefined;
|
|
116
116
|
}
|
|
@@ -144,5 +144,5 @@ class FetchODataClient {
|
|
|
144
144
|
return this.sendRequest(url, { method: "DELETE" }, requestConfig);
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
|
-
exports.
|
|
148
|
-
//# sourceMappingURL=
|
|
147
|
+
exports.FetchClient = FetchClient;
|
|
148
|
+
//# sourceMappingURL=FetchClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FetchClient.js","sourceRoot":"","sources":["../src/FetchClient.ts"],"names":[],"mappings":"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","sourcesContent":["import { HttpResponseModel, ODataHttpClient } from \"@odata2ts/http-client-api\";\n\nimport { FetchClientError } from \"./FetchClientError\";\nimport { FetchRequestConfig, getDefaultConfig, mergeFetchConfig } from \"./FetchRequestConfig\";\n\nexport type ErrorMessageRetriever = (errorResponse: any) => string | undefined;\n\nexport interface ClientOptions {\n useCsrfProtection?: boolean;\n csrfTokenFetchUrl?: string;\n}\n\nexport const getV2OrV4ErrorMessage: ErrorMessageRetriever = (errorResponse: any): string | undefined => {\n const eMsg = errorResponse?.error?.message;\n return typeof eMsg?.value === \"string\" ? eMsg.value : eMsg;\n};\n\nexport const DEFAULT_ERROR_MESSAGE = \"No error message!\";\nconst FETCH_FAILURE_MESSAGE = \"OData request failed entirely: \";\nconst JSON_RETRIEVAL_FAILURE_MESSAGE = \"Retrieving JSON body from OData response failed: \";\nconst RESPONSE_FAILURE_MESSAGE = \"OData server responded with error: \";\n\nfunction buildErrorMessage(prefix: string, error: any) {\n const msg = typeof error === \"string\" ? error : (error as Error)?.message;\n return prefix + (msg || DEFAULT_ERROR_MESSAGE);\n}\n\nexport class FetchClient implements ODataHttpClient<FetchRequestConfig> {\n private readonly config: RequestInit;\n private csrfToken: string | undefined;\n private retrieveErrorMessage: ErrorMessageRetriever = getV2OrV4ErrorMessage;\n\n constructor(config?: FetchRequestConfig, private clientOptions?: ClientOptions) {\n this.config = getDefaultConfig(config);\n if (clientOptions && clientOptions.useCsrfProtection && !clientOptions.csrfTokenFetchUrl?.trim()) {\n throw new Error(\n \"When automatic CSRF token fetching is activated, the URL must be supplied with attribute [csrfTokenFetchUrl]!\"\n );\n }\n }\n\n public setErrorMessageRetriever(getErrorMsg: ErrorMessageRetriever) {\n this.retrieveErrorMessage = getErrorMsg;\n }\n\n private async setupSecurityToken() {\n if (!this.csrfToken) {\n this.csrfToken = await this.fetchSecurityToken();\n }\n return this.csrfToken;\n }\n\n private async fetchSecurityToken(): Promise<string | undefined> {\n const fetchUrl = this.clientOptions!.csrfTokenFetchUrl!;\n const response = await this.get(fetchUrl, { headers: { \"x-csrf-token\": \"Fetch\" } });\n\n return response.headers[\"x-csrf-token\"];\n }\n\n private async sendRequest<ResponseType>(\n url: string,\n config: RequestInit,\n requestConfig?: FetchRequestConfig\n ): Promise<HttpResponseModel<ResponseType>> {\n // noinspection SuspiciousTypeOfGuard\n if (typeof url !== \"string\") {\n throw new Error(\"Value for URL must be provided!\");\n }\n\n const mergedConfig = mergeFetchConfig(this.config, requestConfig, config);\n\n // setup automatic CSRF token handling\n if (\n this.clientOptions?.useCsrfProtection &&\n mergedConfig.method &&\n [\"POST\", \"PUT\", \"PATCH\", \"DELETE\"].includes(mergedConfig.method.toUpperCase())\n ) {\n const csrfToken = await this.setupSecurityToken();\n if (typeof csrfToken === \"string\") {\n mergedConfig.headers.set(\"x-csrf-token\", csrfToken);\n }\n }\n\n // the actual request\n let response: Response;\n try {\n response = await fetch(url, mergedConfig);\n } catch (fetchError) {\n throw new FetchClientError(buildErrorMessage(FETCH_FAILURE_MESSAGE, fetchError), undefined, fetchError as Error);\n }\n\n // error response\n if (!response.ok) {\n // automatic CSRF token handling\n if (\n this.clientOptions?.useCsrfProtection &&\n response.status === 403 &&\n response.headers.get(\"x-csrf-token\") === \"Required\"\n ) {\n // csrf token expired, let's reset it and perform the original request again\n this.csrfToken = undefined;\n return this.sendRequest<ResponseType>(url, config, requestConfig);\n }\n\n let data = await this.getResponseBody(response, false);\n const errMsg = this.retrieveErrorMessage(data);\n\n throw new FetchClientError(\n buildErrorMessage(RESPONSE_FAILURE_MESSAGE, errMsg),\n response.status,\n new Error(errMsg || DEFAULT_ERROR_MESSAGE),\n response\n );\n }\n\n const data = await this.getResponseBody(response, true);\n\n // header\n // Impl Note: No entries prop available, otherwise as one liner Array.from(response.headers.entries)\n const headers: { [key: string]: string } = {};\n response.headers.forEach((value, key) => {\n headers[key] = value;\n });\n\n return {\n status: response.status,\n statusText: response.statusText,\n headers,\n data,\n };\n }\n\n private async getResponseBody(response: Response, isFailedJsonFatal: boolean) {\n if (response.status === 204) {\n return undefined;\n }\n try {\n return await response.json();\n } catch (error) {\n if (isFailedJsonFatal) {\n throw new FetchClientError(\n buildErrorMessage(JSON_RETRIEVAL_FAILURE_MESSAGE, error),\n response.status,\n error as Error\n );\n }\n return undefined;\n }\n }\n\n private prepareData(data: any): string {\n return JSON.stringify(data);\n }\n\n public get<ResponseModel>(\n url: string,\n requestConfig?: FetchRequestConfig\n ): Promise<HttpResponseModel<ResponseModel>> {\n return this.sendRequest<ResponseModel>(url, { method: \"GET\" }, requestConfig);\n }\n public post<ResponseModel>(\n url: string,\n data: any,\n requestConfig?: FetchRequestConfig\n ): Promise<HttpResponseModel<ResponseModel>> {\n return this.sendRequest<ResponseModel>(url, { body: this.prepareData(data), method: \"POST\" }, requestConfig);\n }\n public put<ResponseModel>(\n url: string,\n data: any,\n requestConfig?: FetchRequestConfig\n ): Promise<HttpResponseModel<ResponseModel>> {\n return this.sendRequest<ResponseModel>(url, { body: this.prepareData(data), method: \"PUT\" }, requestConfig);\n }\n public patch<ResponseModel>(\n url: string,\n data: any,\n requestConfig?: FetchRequestConfig\n ): Promise<HttpResponseModel<ResponseModel>> {\n return this.sendRequest<ResponseModel>(url, { body: this.prepareData(data), method: \"PATCH\" }, requestConfig);\n }\n public merge<ResponseModel>(\n url: string,\n data: any,\n requestConfig?: FetchRequestConfig\n ): Promise<HttpResponseModel<ResponseModel>> {\n return this.sendRequest<ResponseModel>(\n url,\n {\n body: this.prepareData(data),\n method: \"POST\",\n headers: {\n \"X-Http-Method\": \"MERGE\",\n },\n },\n requestConfig\n );\n }\n public delete(url: string, requestConfig?: FetchRequestConfig): Promise<HttpResponseModel<void>> {\n return this.sendRequest<void>(url, { method: \"DELETE\" }, requestConfig);\n }\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
class
|
|
3
|
+
exports.FetchClientError = void 0;
|
|
4
|
+
class FetchClientError extends Error {
|
|
5
5
|
constructor(message, status, cause, response) {
|
|
6
6
|
// @ts-ignore: fetch requires lib "dom" or "webworker", but then the "cause" property becomes unknown to TS
|
|
7
7
|
super(message, { cause });
|
|
@@ -11,5 +11,5 @@ class FetchODataClientError extends Error {
|
|
|
11
11
|
this.name = this.constructor.name;
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
-
exports.
|
|
15
|
-
//# sourceMappingURL=
|
|
14
|
+
exports.FetchClientError = FetchClientError;
|
|
15
|
+
//# sourceMappingURL=FetchClientError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FetchClientError.js","sourceRoot":"","sources":["../src/FetchClientError.ts"],"names":[],"mappings":";;;AAAA,MAAa,gBAAiB,SAAQ,KAAK;IACzC,YACE,OAAe,EACC,MAAe,EACf,KAAa,EACb,QAAmB;QAEnC,2GAA2G;QAC3G,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QALV,WAAM,GAAN,MAAM,CAAS;QACf,UAAK,GAAL,KAAK,CAAQ;QACb,aAAQ,GAAR,QAAQ,CAAW;QAInC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IACpC,CAAC;CACF;AAXD,4CAWC","sourcesContent":["export class FetchClientError extends Error {\n constructor(\n message: string,\n public readonly status?: number,\n public readonly cause?: Error,\n public readonly response?: Response\n ) {\n // @ts-ignore: fetch requires lib \"dom\" or \"webworker\", but then the \"cause\" property becomes unknown to TS\n super(message, { cause });\n this.name = this.constructor.name;\n }\n}\n"]}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from "./
|
|
2
|
-
export {
|
|
1
|
+
export * from "./FetchClient";
|
|
2
|
+
export { FetchClientError } from "./FetchClientError";
|
|
3
3
|
export { FetchRequestConfig } from "./FetchRequestConfig";
|
package/lib/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.FetchClientError = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
tslib_1.__exportStar(require("./
|
|
6
|
-
var
|
|
7
|
-
Object.defineProperty(exports, "
|
|
5
|
+
tslib_1.__exportStar(require("./FetchClient"), exports);
|
|
6
|
+
var FetchClientError_1 = require("./FetchClientError");
|
|
7
|
+
Object.defineProperty(exports, "FetchClientError", { enumerable: true, get: function () { return FetchClientError_1.FetchClientError; } });
|
|
8
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,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAAA,wDAA8B;AAC9B,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA","sourcesContent":["export * from \"./FetchClient\";\nexport { FetchClientError } from \"./FetchClientError\";\nexport { FetchRequestConfig } from \"./FetchRequestConfig\";\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@odata2ts/http-client-fetch",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"odata2ts"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@odata2ts/
|
|
34
|
+
"@odata2ts/http-client-api": "^0.1.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@odata2ts/odata-core": "^0.3.7",
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"typescript": "5.0.4"
|
|
45
45
|
},
|
|
46
46
|
"types": "./lib/index.d.ts",
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "a93b726286ef9a118fda63b0e7900d6b3e739dd2"
|
|
48
48
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"FetchODataClient.js","sourceRoot":"","sources":["../src/FetchODataClient.ts"],"names":[],"mappings":"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","sourcesContent":["import { HttpResponseModel, ODataClient } from \"@odata2ts/odata-client-api\";\r\n\r\nimport { FetchODataClientError } from \"./FetchODataClientError\";\r\nimport { FetchRequestConfig, getDefaultConfig, mergeFetchConfig } from \"./FetchRequestConfig\";\r\n\r\nexport type ErrorMessageRetriever = (errorResponse: any) => string | undefined;\r\n\r\nexport interface ClientOptions {\r\n useCsrfProtection?: boolean;\r\n csrfTokenFetchUrl?: string;\r\n}\r\n\r\nexport const getV2OrV4ErrorMessage: ErrorMessageRetriever = (errorResponse: any): string | undefined => {\r\n const eMsg = errorResponse?.error?.message;\r\n return typeof eMsg?.value === \"string\" ? eMsg.value : eMsg;\r\n};\r\n\r\nexport const DEFAULT_ERROR_MESSAGE = \"No error message!\";\r\nconst FETCH_FAILURE_MESSAGE = \"OData request failed entirely: \";\r\nconst JSON_RETRIEVAL_FAILURE_MESSAGE = \"Retrieving JSON body from OData response failed: \";\r\nconst RESPONSE_FAILURE_MESSAGE = \"OData server responded with error: \";\r\n\r\nfunction buildErrorMessage(prefix: string, error: any) {\r\n const msg = typeof error === \"string\" ? error : (error as Error)?.message;\r\n return prefix + (msg || DEFAULT_ERROR_MESSAGE);\r\n}\r\n\r\nexport class FetchODataClient implements ODataClient<FetchRequestConfig> {\r\n private readonly config: RequestInit;\r\n private csrfToken: string | undefined;\r\n private retrieveErrorMessage: ErrorMessageRetriever = getV2OrV4ErrorMessage;\r\n\r\n constructor(config?: FetchRequestConfig, private clientOptions?: ClientOptions) {\r\n this.config = getDefaultConfig(config);\r\n if (clientOptions && clientOptions.useCsrfProtection && !clientOptions.csrfTokenFetchUrl?.trim()) {\r\n throw new Error(\r\n \"When automatic CSRF token fetching is activated, the URL must be supplied with attribute [csrfTokenFetchUrl]!\"\r\n );\r\n }\r\n }\r\n\r\n public setErrorMessageRetriever(getErrorMsg: ErrorMessageRetriever) {\r\n this.retrieveErrorMessage = getErrorMsg;\r\n }\r\n\r\n private async setupSecurityToken() {\r\n if (!this.csrfToken) {\r\n this.csrfToken = await this.fetchSecurityToken();\r\n }\r\n return this.csrfToken;\r\n }\r\n\r\n private async fetchSecurityToken(): Promise<string | undefined> {\r\n const fetchUrl = this.clientOptions!.csrfTokenFetchUrl!;\r\n const response = await this.get(fetchUrl, { headers: { \"x-csrf-token\": \"Fetch\" } });\r\n\r\n return response.headers[\"x-csrf-token\"];\r\n }\r\n\r\n private async sendRequest<ResponseType>(\r\n url: string,\r\n config: RequestInit,\r\n requestConfig?: FetchRequestConfig\r\n ): Promise<HttpResponseModel<ResponseType>> {\r\n // noinspection SuspiciousTypeOfGuard\r\n if (typeof url !== \"string\") {\r\n throw new Error(\"Value for URL must be provided!\");\r\n }\r\n\r\n const mergedConfig = mergeFetchConfig(this.config, requestConfig, config);\r\n\r\n // setup automatic CSRF token handling\r\n if (\r\n this.clientOptions?.useCsrfProtection &&\r\n mergedConfig.method &&\r\n [\"POST\", \"PUT\", \"PATCH\", \"DELETE\"].includes(mergedConfig.method.toUpperCase())\r\n ) {\r\n const csrfToken = await this.setupSecurityToken();\r\n if (typeof csrfToken === \"string\") {\r\n mergedConfig.headers.set(\"x-csrf-token\", csrfToken);\r\n }\r\n }\r\n\r\n // the actual request\r\n let response: Response;\r\n try {\r\n response = await fetch(url, mergedConfig);\r\n } catch (fetchError) {\r\n throw new FetchODataClientError(\r\n buildErrorMessage(FETCH_FAILURE_MESSAGE, fetchError),\r\n undefined,\r\n fetchError as Error\r\n );\r\n }\r\n\r\n // error response\r\n if (!response.ok) {\r\n // automatic CSRF token handling\r\n if (\r\n this.clientOptions?.useCsrfProtection &&\r\n response.status === 403 &&\r\n response.headers.get(\"x-csrf-token\") === \"Required\"\r\n ) {\r\n // csrf token expired, let's reset it and perform the original request again\r\n this.csrfToken = undefined;\r\n return this.sendRequest<ResponseType>(url, config, requestConfig);\r\n }\r\n\r\n let data = await this.getResponseBody(response, false);\r\n const errMsg = this.retrieveErrorMessage(data);\r\n\r\n throw new FetchODataClientError(\r\n buildErrorMessage(RESPONSE_FAILURE_MESSAGE, errMsg),\r\n response.status,\r\n new Error(errMsg || DEFAULT_ERROR_MESSAGE),\r\n response\r\n );\r\n }\r\n\r\n const data = await this.getResponseBody(response, true);\r\n\r\n // header\r\n // Impl Note: No entries prop available, otherwise as one liner Array.from(response.headers.entries)\r\n const headers: { [key: string]: string } = {};\r\n response.headers.forEach((value, key) => {\r\n headers[key] = value;\r\n });\r\n\r\n return {\r\n status: response.status,\r\n statusText: response.statusText,\r\n headers,\r\n data,\r\n };\r\n }\r\n\r\n private async getResponseBody(response: Response, isFailedJsonFatal: boolean) {\r\n if (response.status === 204) {\r\n return undefined;\r\n }\r\n try {\r\n return await response.json();\r\n } catch (error) {\r\n if (isFailedJsonFatal) {\r\n throw new FetchODataClientError(\r\n buildErrorMessage(JSON_RETRIEVAL_FAILURE_MESSAGE, error),\r\n response.status,\r\n error as Error\r\n );\r\n }\r\n return undefined;\r\n }\r\n }\r\n\r\n private prepareData(data: any): string {\r\n return JSON.stringify(data);\r\n }\r\n\r\n public get<ResponseModel>(\r\n url: string,\r\n requestConfig?: FetchRequestConfig\r\n ): Promise<HttpResponseModel<ResponseModel>> {\r\n return this.sendRequest<ResponseModel>(url, { method: \"GET\" }, requestConfig);\r\n }\r\n public post<ResponseModel>(\r\n url: string,\r\n data: any,\r\n requestConfig?: FetchRequestConfig\r\n ): Promise<HttpResponseModel<ResponseModel>> {\r\n return this.sendRequest<ResponseModel>(url, { body: this.prepareData(data), method: \"POST\" }, requestConfig);\r\n }\r\n public put<ResponseModel>(\r\n url: string,\r\n data: any,\r\n requestConfig?: FetchRequestConfig\r\n ): Promise<HttpResponseModel<ResponseModel>> {\r\n return this.sendRequest<ResponseModel>(url, { body: this.prepareData(data), method: \"PUT\" }, requestConfig);\r\n }\r\n public patch<ResponseModel>(\r\n url: string,\r\n data: any,\r\n requestConfig?: FetchRequestConfig\r\n ): Promise<HttpResponseModel<ResponseModel>> {\r\n return this.sendRequest<ResponseModel>(url, { body: this.prepareData(data), method: \"PATCH\" }, requestConfig);\r\n }\r\n public merge<ResponseModel>(\r\n url: string,\r\n data: any,\r\n requestConfig?: FetchRequestConfig\r\n ): Promise<HttpResponseModel<ResponseModel>> {\r\n return this.sendRequest<ResponseModel>(\r\n url,\r\n {\r\n body: this.prepareData(data),\r\n method: \"POST\",\r\n headers: {\r\n \"X-Http-Method\": \"MERGE\",\r\n },\r\n },\r\n requestConfig\r\n );\r\n }\r\n public delete(url: string, requestConfig?: FetchRequestConfig): Promise<HttpResponseModel<void>> {\r\n return this.sendRequest<void>(url, { method: \"DELETE\" }, requestConfig);\r\n }\r\n}\r\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"FetchODataClientError.js","sourceRoot":"","sources":["../src/FetchODataClientError.ts"],"names":[],"mappings":";;;AAAA,MAAa,qBAAsB,SAAQ,KAAK;IAC9C,YACE,OAAe,EACC,MAAe,EACf,KAAa,EACb,QAAmB;QAEnC,2GAA2G;QAC3G,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QALV,WAAM,GAAN,MAAM,CAAS;QACf,UAAK,GAAL,KAAK,CAAQ;QACb,aAAQ,GAAR,QAAQ,CAAW;QAInC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IACpC,CAAC;CACF;AAXD,sDAWC","sourcesContent":["export class FetchODataClientError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly status?: number,\r\n public readonly cause?: Error,\r\n public readonly response?: Response\r\n ) {\r\n // @ts-ignore: fetch requires lib \"dom\" or \"webworker\", but then the \"cause\" property becomes unknown to TS\r\n super(message, { cause });\r\n this.name = this.constructor.name;\r\n }\r\n}\r\n"]}
|