1 |
|
2 |
|
3 | import { __assign, __awaiter, __generator } from "tslib";
|
4 | import AbortController from "abort-controller";
|
5 | import FormData from "form-data";
|
6 | import { HttpHeaders } from "./httpHeaders";
|
7 | import { RestError } from "./restError";
|
8 | import { Transform } from "stream";
|
9 | var FetchHttpClient = (function () {
|
10 | function FetchHttpClient() {
|
11 | }
|
12 | FetchHttpClient.prototype.sendRequest = function (httpRequest) {
|
13 | return __awaiter(this, void 0, void 0, function () {
|
14 | var abortController, abortListener, formData, requestForm_1, appendFormValue, _i, _a, formKey, formValue, j, contentType, body, loadedBytes_1, uploadReportStream, platformSpecificRequestInit, requestInit, operationResponse, response, headers, _b, _c, onDownloadProgress_1, responseBody, loadedBytes_2, downloadReportStream, length_1, error_1, fetchError, uploadStreamDone, downloadStreamDone;
|
15 | return __generator(this, function (_d) {
|
16 | switch (_d.label) {
|
17 | case 0:
|
18 | if (!httpRequest && typeof httpRequest !== "object") {
|
19 | throw new Error("'httpRequest' (WebResource) cannot be null or undefined and must be of type object.");
|
20 | }
|
21 | abortController = new AbortController();
|
22 | if (httpRequest.abortSignal) {
|
23 | if (httpRequest.abortSignal.aborted) {
|
24 | throw new RestError("The request was aborted", RestError.REQUEST_ABORTED_ERROR, undefined, httpRequest);
|
25 | }
|
26 | abortListener = function (event) {
|
27 | if (event.type === "abort") {
|
28 | abortController.abort();
|
29 | }
|
30 | };
|
31 | httpRequest.abortSignal.addEventListener("abort", abortListener);
|
32 | }
|
33 | if (httpRequest.timeout) {
|
34 | setTimeout(function () {
|
35 | abortController.abort();
|
36 | }, httpRequest.timeout);
|
37 | }
|
38 | if (httpRequest.formData) {
|
39 | formData = httpRequest.formData;
|
40 | requestForm_1 = new FormData();
|
41 | appendFormValue = function (key, value) {
|
42 |
|
43 | if (typeof value === "function") {
|
44 | value = value();
|
45 | }
|
46 | if (value && value.hasOwnProperty("value") && value.hasOwnProperty("options")) {
|
47 | requestForm_1.append(key, value.value, value.options);
|
48 | }
|
49 | else {
|
50 | requestForm_1.append(key, value);
|
51 | }
|
52 | };
|
53 | for (_i = 0, _a = Object.keys(formData); _i < _a.length; _i++) {
|
54 | formKey = _a[_i];
|
55 | formValue = formData[formKey];
|
56 | if (Array.isArray(formValue)) {
|
57 | for (j = 0; j < formValue.length; j++) {
|
58 | appendFormValue(formKey, formValue[j]);
|
59 | }
|
60 | }
|
61 | else {
|
62 | appendFormValue(formKey, formValue);
|
63 | }
|
64 | }
|
65 | httpRequest.body = requestForm_1;
|
66 | httpRequest.formData = undefined;
|
67 | contentType = httpRequest.headers.get("Content-Type");
|
68 | if (contentType && contentType.indexOf("multipart/form-data") !== -1) {
|
69 | if (typeof requestForm_1.getBoundary === "function") {
|
70 | httpRequest.headers.set("Content-Type", "multipart/form-data; boundary=" + requestForm_1.getBoundary());
|
71 | }
|
72 | else {
|
73 |
|
74 | httpRequest.headers.remove("Content-Type");
|
75 | }
|
76 | }
|
77 | }
|
78 | body = httpRequest.body
|
79 | ? typeof httpRequest.body === "function"
|
80 | ? httpRequest.body()
|
81 | : httpRequest.body
|
82 | : undefined;
|
83 | if (httpRequest.onUploadProgress && httpRequest.body) {
|
84 | loadedBytes_1 = 0;
|
85 | uploadReportStream = new Transform({
|
86 | transform: function (chunk, _encoding, callback) {
|
87 | loadedBytes_1 += chunk.length;
|
88 | httpRequest.onUploadProgress({ loadedBytes: loadedBytes_1 });
|
89 | callback(undefined, chunk);
|
90 | },
|
91 | });
|
92 | if (isReadableStream(body)) {
|
93 | body.pipe(uploadReportStream);
|
94 | }
|
95 | else {
|
96 | uploadReportStream.end(body);
|
97 | }
|
98 | body = uploadReportStream;
|
99 | }
|
100 | return [4 , this.prepareRequest(httpRequest)];
|
101 | case 1:
|
102 | platformSpecificRequestInit = _d.sent();
|
103 | requestInit = __assign({ body: body, headers: httpRequest.headers.rawHeaders(), method: httpRequest.method, signal: abortController.signal, redirect: "manual" }, platformSpecificRequestInit);
|
104 | _d.label = 2;
|
105 | case 2:
|
106 | _d.trys.push([2, 8, 9, 10]);
|
107 | return [4 , this.fetch(httpRequest.url, requestInit)];
|
108 | case 3:
|
109 | response = _d.sent();
|
110 | headers = parseHeaders(response.headers);
|
111 | _b = {
|
112 | headers: headers,
|
113 | request: httpRequest,
|
114 | status: response.status,
|
115 | readableStreamBody: httpRequest.streamResponseBody
|
116 | ? response.body
|
117 | : undefined
|
118 | };
|
119 | if (!!httpRequest.streamResponseBody) return [3 , 5];
|
120 | return [4 , response.text()];
|
121 | case 4:
|
122 | _c = _d.sent();
|
123 | return [3 , 6];
|
124 | case 5:
|
125 | _c = undefined;
|
126 | _d.label = 6;
|
127 | case 6:
|
128 | operationResponse = (_b.bodyAsText = _c,
|
129 | _b.redirected = response.redirected,
|
130 | _b.url = response.url,
|
131 | _b);
|
132 | onDownloadProgress_1 = httpRequest.onDownloadProgress;
|
133 | if (onDownloadProgress_1) {
|
134 | responseBody = response.body || undefined;
|
135 | if (isReadableStream(responseBody)) {
|
136 | loadedBytes_2 = 0;
|
137 | downloadReportStream = new Transform({
|
138 | transform: function (chunk, _encoding, callback) {
|
139 | loadedBytes_2 += chunk.length;
|
140 | onDownloadProgress_1({ loadedBytes: loadedBytes_2 });
|
141 | callback(undefined, chunk);
|
142 | },
|
143 | });
|
144 | responseBody.pipe(downloadReportStream);
|
145 | operationResponse.readableStreamBody = downloadReportStream;
|
146 | }
|
147 | else {
|
148 | length_1 = parseInt(headers.get("Content-Length")) || undefined;
|
149 | if (length_1) {
|
150 |
|
151 | onDownloadProgress_1({ loadedBytes: length_1 });
|
152 | }
|
153 | }
|
154 | }
|
155 | return [4 , this.processRequest(operationResponse)];
|
156 | case 7:
|
157 | _d.sent();
|
158 | return [2 , operationResponse];
|
159 | case 8:
|
160 | error_1 = _d.sent();
|
161 | fetchError = error_1;
|
162 | if (fetchError.code === "ENOTFOUND") {
|
163 | throw new RestError(fetchError.message, RestError.REQUEST_SEND_ERROR, undefined, httpRequest);
|
164 | }
|
165 | else if (fetchError.type === "aborted") {
|
166 | throw new RestError("The request was aborted", RestError.REQUEST_ABORTED_ERROR, undefined, httpRequest);
|
167 | }
|
168 | throw fetchError;
|
169 | case 9:
|
170 |
|
171 | if (httpRequest.abortSignal && abortListener) {
|
172 | uploadStreamDone = Promise.resolve();
|
173 | if (isReadableStream(body)) {
|
174 | uploadStreamDone = isStreamComplete(body);
|
175 | }
|
176 | downloadStreamDone = Promise.resolve();
|
177 | if (isReadableStream(operationResponse === null || operationResponse === void 0 ? void 0 : operationResponse.readableStreamBody)) {
|
178 | downloadStreamDone = isStreamComplete(operationResponse.readableStreamBody);
|
179 | }
|
180 | Promise.all([uploadStreamDone, downloadStreamDone])
|
181 | .then(function () {
|
182 | var _a;
|
183 | (_a = httpRequest.abortSignal) === null || _a === void 0 ? void 0 : _a.removeEventListener("abort", abortListener);
|
184 | return;
|
185 | })
|
186 | .catch(function (_e) { });
|
187 | }
|
188 | return [7 ];
|
189 | case 10: return [2 ];
|
190 | }
|
191 | });
|
192 | });
|
193 | };
|
194 | return FetchHttpClient;
|
195 | }());
|
196 | export { FetchHttpClient };
|
197 | function isReadableStream(body) {
|
198 | return body && typeof body.pipe === "function";
|
199 | }
|
200 | function isStreamComplete(stream) {
|
201 | return new Promise(function (resolve) {
|
202 | stream.on("close", resolve);
|
203 | stream.on("end", resolve);
|
204 | stream.on("error", resolve);
|
205 | });
|
206 | }
|
207 | export function parseHeaders(headers) {
|
208 | var httpHeaders = new HttpHeaders();
|
209 | headers.forEach(function (value, key) {
|
210 | httpHeaders.set(key, value);
|
211 | });
|
212 | return httpHeaders;
|
213 | }
|
214 |
|
\ | No newline at end of file |