Skip to content

Commit 3b718ae

Browse files
authored
fallback on cross-fetch if fetchApi is not available (#900)
1 parent 13b6ebe commit 3b718ae

File tree

2 files changed

+102
-42
lines changed

2 files changed

+102
-42
lines changed

.generator/src/generator/templates/http/isomorphic-fetch.j2

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { HttpLibrary, RequestContext, ResponseContext, ZstdCompressorCallback } from "./http";
2-
import fetch from "cross-fetch";
2+
import { fetch as crossFetch } from "cross-fetch";
33
import pako from "pako";
44
import bufferFrom from "buffer-from";
5-
import { isBrowser } from "../util";
5+
import { isBrowser, isNode } from "../util";
66

77
export class IsomorphicFetchHttpLibrary implements HttpLibrary {
88
public debug = false;
@@ -47,27 +47,57 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary {
4747
}
4848
}
4949

50-
const resultPromise = fetch(request.getUrl(), {
51-
method: method,
52-
body: body as any,
53-
headers: headers,
54-
signal: request.getHttpConfig().signal,
55-
}).then((resp: any) => {
56-
const headers: { [name: string]: string } = {};
57-
resp.headers.forEach((value: string, name: string) => {
58-
headers[name] = value;
50+
let resultPromise: Promise<ResponseContext>;
51+
52+
// On non-node environments, use native fetch if available.
53+
// `cross-fetch` incorrectly assumes all browsers have XHR available.
54+
// See https://github.com/lquixada/cross-fetch/issues/78
55+
// TODO: Remove once once above issue is resolved.
56+
if (!isNode && typeof fetch === "function") {
57+
resultPromise = fetch(request.getUrl(), {
58+
method: method,
59+
body: body as any,
60+
headers: headers,
61+
signal: request.getHttpConfig().signal,
62+
}).then((resp: any) => {
63+
const headers: { [name: string]: string } = {};
64+
resp.headers.forEach((value: string, name: string) => {
65+
headers[name] = value;
66+
});
67+
68+
const body = {
69+
text: () => resp.text(),
70+
binary: () => resp.buffer(),
71+
};
72+
const response = new ResponseContext(resp.status, headers, body);
73+
if (this.debug) {
74+
this.logResponse(response);
75+
}
76+
return response;
5977
});
78+
} else {
79+
resultPromise = crossFetch(request.getUrl(), {
80+
method: method,
81+
body: body as any,
82+
headers: headers,
83+
signal: request.getHttpConfig().signal,
84+
}).then((resp: any) => {
85+
const headers: { [name: string]: string } = {};
86+
resp.headers.forEach((value: string, name: string) => {
87+
headers[name] = value;
88+
});
6089

61-
const body = {
62-
text: () => resp.text(),
63-
binary: () => resp.buffer(),
64-
};
65-
const response = new ResponseContext(resp.status, headers, body);
66-
if (this.debug) {
67-
this.logResponse(response);
68-
}
69-
return response;
70-
});
90+
const body = {
91+
text: () => resp.text(),
92+
binary: () => resp.buffer(),
93+
};
94+
const response = new ResponseContext(resp.status, headers, body);
95+
if (this.debug) {
96+
this.logResponse(response);
97+
}
98+
return response;
99+
});
100+
}
71101

72102
return resultPromise;
73103
}

packages/datadog-api-client-common/http/isomorphic-fetch.ts

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import {
44
ResponseContext,
55
ZstdCompressorCallback,
66
} from "./http";
7-
import fetch from "cross-fetch";
7+
import { fetch as crossFetch } from "cross-fetch";
88
import pako from "pako";
99
import bufferFrom from "buffer-from";
10-
import { isBrowser } from "../util";
10+
import { isBrowser, isNode } from "../util";
1111

1212
export class IsomorphicFetchHttpLibrary implements HttpLibrary {
1313
public debug = false;
@@ -52,27 +52,57 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary {
5252
}
5353
}
5454

55-
const resultPromise = fetch(request.getUrl(), {
56-
method: method,
57-
body: body as any,
58-
headers: headers,
59-
signal: request.getHttpConfig().signal,
60-
}).then((resp: any) => {
61-
const headers: { [name: string]: string } = {};
62-
resp.headers.forEach((value: string, name: string) => {
63-
headers[name] = value;
55+
let resultPromise: Promise<ResponseContext>;
56+
57+
// On non-node environments, use native fetch if available.
58+
// `cross-fetch` incorrectly assumes all browsers have XHR available.
59+
// See https://github.com/lquixada/cross-fetch/issues/78
60+
// TODO: Remove once once above issue is resolved.
61+
if (!isNode && typeof fetch === "function") {
62+
resultPromise = fetch(request.getUrl(), {
63+
method: method,
64+
body: body as any,
65+
headers: headers,
66+
signal: request.getHttpConfig().signal,
67+
}).then((resp: any) => {
68+
const headers: { [name: string]: string } = {};
69+
resp.headers.forEach((value: string, name: string) => {
70+
headers[name] = value;
71+
});
72+
73+
const body = {
74+
text: () => resp.text(),
75+
binary: () => resp.buffer(),
76+
};
77+
const response = new ResponseContext(resp.status, headers, body);
78+
if (this.debug) {
79+
this.logResponse(response);
80+
}
81+
return response;
6482
});
83+
} else {
84+
resultPromise = crossFetch(request.getUrl(), {
85+
method: method,
86+
body: body as any,
87+
headers: headers,
88+
signal: request.getHttpConfig().signal,
89+
}).then((resp: any) => {
90+
const headers: { [name: string]: string } = {};
91+
resp.headers.forEach((value: string, name: string) => {
92+
headers[name] = value;
93+
});
6594

66-
const body = {
67-
text: () => resp.text(),
68-
binary: () => resp.buffer(),
69-
};
70-
const response = new ResponseContext(resp.status, headers, body);
71-
if (this.debug) {
72-
this.logResponse(response);
73-
}
74-
return response;
75-
});
95+
const body = {
96+
text: () => resp.text(),
97+
binary: () => resp.buffer(),
98+
};
99+
const response = new ResponseContext(resp.status, headers, body);
100+
if (this.debug) {
101+
this.logResponse(response);
102+
}
103+
return response;
104+
});
105+
}
76106

77107
return resultPromise;
78108
}

0 commit comments

Comments
 (0)