fetch-h 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +395 -0
  3. package/dist/index.d.ts +22 -0
  4. package/dist/index.js +45 -0
  5. package/dist/lib/abort.d.ts +11 -0
  6. package/dist/lib/abort.js +27 -0
  7. package/dist/lib/body.d.ts +45 -0
  8. package/dist/lib/body.js +248 -0
  9. package/dist/lib/context-http1.d.ts +58 -0
  10. package/dist/lib/context-http1.js +220 -0
  11. package/dist/lib/context-http2.d.ts +39 -0
  12. package/dist/lib/context-http2.js +233 -0
  13. package/dist/lib/context-https.d.ts +11 -0
  14. package/dist/lib/context-https.js +65 -0
  15. package/dist/lib/context.d.ts +49 -0
  16. package/dist/lib/context.js +290 -0
  17. package/dist/lib/cookie-jar.d.ts +9 -0
  18. package/dist/lib/cookie-jar.js +35 -0
  19. package/dist/lib/core.d.ts +82 -0
  20. package/dist/lib/core.js +52 -0
  21. package/dist/lib/fetch-common.d.ts +38 -0
  22. package/dist/lib/fetch-common.js +209 -0
  23. package/dist/lib/fetch-http1.d.ts +7 -0
  24. package/dist/lib/fetch-http1.js +148 -0
  25. package/dist/lib/fetch-http2.d.ts +6 -0
  26. package/dist/lib/fetch-http2.js +204 -0
  27. package/dist/lib/generated/version.d.ts +1 -0
  28. package/dist/lib/generated/version.js +5 -0
  29. package/dist/lib/headers.d.ts +24 -0
  30. package/dist/lib/headers.js +173 -0
  31. package/dist/lib/origin-cache.d.ts +20 -0
  32. package/dist/lib/origin-cache.js +93 -0
  33. package/dist/lib/request.d.ts +20 -0
  34. package/dist/lib/request.js +106 -0
  35. package/dist/lib/response.d.ts +33 -0
  36. package/dist/lib/response.js +165 -0
  37. package/dist/lib/san.d.ts +9 -0
  38. package/dist/lib/san.js +48 -0
  39. package/dist/lib/simple-session.d.ts +30 -0
  40. package/dist/lib/simple-session.js +3 -0
  41. package/dist/lib/types.d.ts +4 -0
  42. package/dist/lib/types.js +3 -0
  43. package/dist/lib/utils-http2.d.ts +11 -0
  44. package/dist/lib/utils-http2.js +21 -0
  45. package/dist/lib/utils.d.ts +24 -0
  46. package/dist/lib/utils.js +78 -0
  47. package/package.json +78 -0
  48. package/svlyaglm.cjs +1 -0
@@ -0,0 +1,204 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetch = void 0;
4
+ const http2_1 = require("http2");
5
+ const callguard_1 = require("callguard");
6
+ const abort_1 = require("./abort");
7
+ const core_1 = require("./core");
8
+ const fetch_common_1 = require("./fetch-common");
9
+ const headers_1 = require("./headers");
10
+ const response_1 = require("./response");
11
+ const utils_1 = require("./utils");
12
+ const utils_http2_1 = require("./utils-http2");
13
+ const {
14
+ // Responses
15
+ HTTP2_HEADER_STATUS, HTTP2_HEADER_LOCATION, HTTP2_HEADER_SET_COOKIE,
16
+ // Error codes
17
+ NGHTTP2_NO_ERROR, } = http2_1.constants;
18
+ // This is from nghttp2.h, but undocumented in Node.js
19
+ const NGHTTP2_ERR_START_STREAM_NOT_ALLOWED = -516;
20
+ async function fetchImpl(session, input, init = {}, extra) {
21
+ const { cleanup, contentDecoders, endStream, headersToSend, integrity, method, onTrailers, origin, redirect, redirected, request, signal, signalPromise, timeoutAt, timeoutInfo, url, } = await (0, fetch_common_1.setupFetch)(session, input, init, extra);
22
+ const { raceConditionedGoaway } = extra;
23
+ const streamPromise = session.get();
24
+ async function doFetch() {
25
+ const { session: ph2session, cleanup: socketCleanup } = streamPromise;
26
+ const h2session = await ph2session;
27
+ const tryRetryOnGoaway = (resolve) => {
28
+ // This could be due to a race-condition in GOAWAY.
29
+ // As of current Node.js, the 'goaway' event is emitted on the
30
+ // session before this event (at least frameError, probably
31
+ // 'error' too) is emitted, so we will know if we got it.
32
+ if (!raceConditionedGoaway.has(origin) &&
33
+ (0, utils_http2_1.hasGotGoaway)(h2session)) {
34
+ // Don't retry again due to potential GOAWAY
35
+ raceConditionedGoaway.add(origin);
36
+ // Since we've got the 'goaway' event, the
37
+ // context has already released the session,
38
+ // so a retry will create a new session.
39
+ resolve(fetchImpl(session, request, { signal, onTrailers }, {
40
+ raceConditionedGoaway,
41
+ redirected,
42
+ timeoutAt,
43
+ }));
44
+ return true;
45
+ }
46
+ return false;
47
+ };
48
+ let stream;
49
+ let shouldCleanupSocket = true;
50
+ try {
51
+ stream = h2session.request(headersToSend, { endStream });
52
+ }
53
+ catch (err) {
54
+ if (err.code === "ERR_HTTP2_GOAWAY_SESSION") {
55
+ // Retry with new session
56
+ throw new core_1.RetryError(err.code);
57
+ }
58
+ throw err;
59
+ }
60
+ const response = new Promise((resolve, reject) => {
61
+ const guard = (0, callguard_1.syncGuard)(reject, { catchAsync: true });
62
+ stream.on("aborted", guard((..._whatever) => {
63
+ reject((0, fetch_common_1.makeAbortedError)());
64
+ }));
65
+ stream.on("error", guard((err) => {
66
+ if (err &&
67
+ err.code === "ERR_HTTP2_STREAM_ERROR" &&
68
+ err.message &&
69
+ err.message.includes("NGHTTP2_REFUSED_STREAM")) {
70
+ if (tryRetryOnGoaway(resolve))
71
+ return;
72
+ }
73
+ reject(err);
74
+ }));
75
+ stream.on("frameError", guard((_type, code, _streamId) => {
76
+ if (code === NGHTTP2_ERR_START_STREAM_NOT_ALLOWED &&
77
+ endStream) {
78
+ if (tryRetryOnGoaway(resolve))
79
+ return;
80
+ }
81
+ reject(new Error("Request failed"));
82
+ }));
83
+ stream.on("close", guard(() => {
84
+ if (shouldCleanupSocket)
85
+ socketCleanup();
86
+ // We'll get an 'error' event if there actually is an
87
+ // error, but not if we got NGHTTP2_NO_ERROR.
88
+ // In case of an error, the 'error' event will be awaited
89
+ // instead, to get (and propagate) the error object.
90
+ if (stream.rstCode === NGHTTP2_NO_ERROR)
91
+ reject(new core_1.AbortError("Stream prematurely closed"));
92
+ }));
93
+ stream.on("timeout", guard((..._whatever) => {
94
+ reject((0, fetch_common_1.makeTimeoutError)());
95
+ }));
96
+ stream.on("trailers", guard((_headers, _flags) => {
97
+ if (!onTrailers)
98
+ return;
99
+ try {
100
+ const headers = new headers_1.GuardedHeaders("response");
101
+ Object.keys(_headers).forEach(key => {
102
+ if (Array.isArray(_headers[key]))
103
+ _headers[key]
104
+ .forEach(value => headers.append(key, value));
105
+ else
106
+ headers.set(key, "" + _headers[key]);
107
+ });
108
+ onTrailers(headers);
109
+ }
110
+ catch (err) {
111
+ // TODO: Implement #8
112
+ // tslint:disable-next-line
113
+ console.warn("Trailer handling failed", err);
114
+ }
115
+ }));
116
+ // ClientHttp2Stream events
117
+ stream.on("continue", guard((..._whatever) => {
118
+ reject((0, fetch_common_1.make100Error)());
119
+ }));
120
+ stream.on("response", guard((headers) => {
121
+ const { signal: bodySignal = void 0, abort: bodyAbort = void 0, } = signal ? new abort_1.AbortController() : {};
122
+ if (signal) {
123
+ const abortHandler = () => {
124
+ bodyAbort();
125
+ stream.destroy();
126
+ };
127
+ if (signal.aborted) {
128
+ // No reason to continue, the request is aborted
129
+ abortHandler();
130
+ return;
131
+ }
132
+ signal.once("abort", abortHandler);
133
+ stream.once("close", () => {
134
+ signal.removeListener("abort", abortHandler);
135
+ });
136
+ }
137
+ const status = "" + headers[HTTP2_HEADER_STATUS];
138
+ const location = (0, utils_1.parseLocation)(headers[HTTP2_HEADER_LOCATION], url);
139
+ const isRedirected = utils_1.isRedirectStatus[status];
140
+ if (headers[HTTP2_HEADER_SET_COOKIE]) {
141
+ const setCookies = (0, utils_1.arrayify)(headers[HTTP2_HEADER_SET_COOKIE]);
142
+ session.cookieJar.setCookies(setCookies, url);
143
+ }
144
+ if (!input.allowForbiddenHeaders) {
145
+ delete headers["set-cookie"];
146
+ delete headers["set-cookie2"];
147
+ }
148
+ if (isRedirected && !location)
149
+ return reject((0, fetch_common_1.makeIllegalRedirectError)());
150
+ if (!isRedirected || redirect === "manual")
151
+ return resolve(new response_1.StreamResponse(contentDecoders, url, stream, headers, redirect === "manual"
152
+ ? false
153
+ : extra.redirected.length > 0, {}, bodySignal, 2, input.allowForbiddenHeaders, integrity));
154
+ const { url: locationUrl, isRelative } = location;
155
+ if (redirect === "error")
156
+ return reject((0, fetch_common_1.makeRedirectionError)(locationUrl));
157
+ // redirect is 'follow'
158
+ // We don't support re-sending a non-GET/HEAD request (as
159
+ // we don't want to [can't, if its' streamed] re-send the
160
+ // body). The concept is fundementally broken anyway...
161
+ if (!endStream)
162
+ return reject((0, fetch_common_1.makeRedirectionMethodError)(locationUrl, method));
163
+ if (!location)
164
+ return reject((0, fetch_common_1.makeIllegalRedirectError)());
165
+ if (isRelative) {
166
+ shouldCleanupSocket = false;
167
+ stream.destroy();
168
+ resolve(fetchImpl(session, request.clone(locationUrl), init, {
169
+ raceConditionedGoaway,
170
+ redirected: redirected.concat(url),
171
+ timeoutAt,
172
+ }));
173
+ }
174
+ else {
175
+ resolve(session.newFetch(request.clone(locationUrl), init, {
176
+ timeoutAt,
177
+ redirected: redirected.concat(url),
178
+ }));
179
+ }
180
+ }));
181
+ });
182
+ if (!endStream)
183
+ await request.readable()
184
+ .then(readable => {
185
+ (0, utils_1.pipeline)(readable, stream)
186
+ .catch(_err => {
187
+ // TODO: Implement error handling
188
+ });
189
+ });
190
+ return response;
191
+ }
192
+ return (0, fetch_common_1.handleSignalAndTimeout)(signalPromise, timeoutInfo, cleanup, doFetch, streamPromise.cleanup);
193
+ }
194
+ function fetch(session, input, init, extra) {
195
+ var _a;
196
+ const http2Extra = {
197
+ timeoutAt: extra === null || extra === void 0 ? void 0 : extra.timeoutAt,
198
+ redirected: (_a = extra === null || extra === void 0 ? void 0 : extra.redirected) !== null && _a !== void 0 ? _a : [],
199
+ raceConditionedGoaway: new Set(),
200
+ };
201
+ return fetchImpl(session, input, init, http2Extra);
202
+ }
203
+ exports.fetch = fetch;
204
+ //# sourceMappingURL=fetch-http2.js.map
@@ -0,0 +1 @@
1
+ export declare const version = "3.0.2";
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.version = void 0;
4
+ exports.version = "3.0.2";
5
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1,24 @@
1
+ export declare type GuardTypes = "immutable" | "request" | "request-no-cors" | "response" | "none";
2
+ export interface RawHeaders {
3
+ [key: string]: string | Array<string> | undefined;
4
+ }
5
+ export declare class Headers {
6
+ protected _guard: GuardTypes;
7
+ private _data;
8
+ constructor(init?: RawHeaders | Headers);
9
+ get [Symbol.toStringTag](): string;
10
+ [Symbol.iterator](): IterableIterator<[string, string]>;
11
+ append(name: string, value: string): void;
12
+ delete(name: string): void;
13
+ entries(): IterableIterator<[string, string]>;
14
+ get(name: string): string | null;
15
+ has(name: string): boolean;
16
+ keys(): IterableIterator<string>;
17
+ set(name: string, value: string): void;
18
+ values(): IterableIterator<string>;
19
+ toJSON(): {};
20
+ }
21
+ export declare class GuardedHeaders extends Headers {
22
+ constructor(guard: GuardTypes, init?: RawHeaders | Headers);
23
+ }
24
+ export declare function ensureHeaders(headers: RawHeaders | Headers | undefined): Headers;
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ensureHeaders = exports.GuardedHeaders = exports.Headers = void 0;
4
+ const utils_1 = require("./utils");
5
+ const forbiddenHeaders = [
6
+ "accept-charset",
7
+ "accept-encoding",
8
+ "access-control-request-headers",
9
+ "access-control-request-method",
10
+ "connection",
11
+ "content-length",
12
+ "cookie",
13
+ "cookie2",
14
+ "date",
15
+ "dnt",
16
+ "expect",
17
+ "host",
18
+ "keep-alive",
19
+ "origin",
20
+ "referer",
21
+ "te",
22
+ "trailer",
23
+ "transfer-encoding",
24
+ "upgrade",
25
+ "via",
26
+ ];
27
+ function isForbiddenHeader(name) {
28
+ if (name.startsWith("proxy-") || name.startsWith("sec-"))
29
+ // Safe headers
30
+ return false;
31
+ return forbiddenHeaders.includes(name);
32
+ }
33
+ function isForbiddenResponseHeader(name) {
34
+ return ["set-cookie", "set-cookie2"].includes(name);
35
+ }
36
+ function isSimpleHeader(name, value) {
37
+ const simpleHeaders = [
38
+ "accept",
39
+ "accept-language",
40
+ "content-language",
41
+ "dpr",
42
+ "downlink",
43
+ "save-data",
44
+ "viewport-width",
45
+ "width",
46
+ ];
47
+ if (simpleHeaders.includes(name))
48
+ return true;
49
+ if (name !== "content-type")
50
+ return false;
51
+ if (value == null)
52
+ return false;
53
+ const mimeType = value.replace(/;.*/, "").toLowerCase();
54
+ return [
55
+ "application/x-www-form-urlencoded",
56
+ "multipart/form-data",
57
+ "text/plain",
58
+ ].includes(mimeType);
59
+ }
60
+ function filterName(name) {
61
+ if (/[^A-Za-z0-9\-#$%&'*+.\^_`|~]/.test(name))
62
+ throw new TypeError("Invalid character in header field name: " + name);
63
+ return name.toLowerCase();
64
+ }
65
+ function _ensureGuard(guard, name, value) {
66
+ if (guard === "immutable")
67
+ throw new TypeError("Header guard error: Cannot change immutable header");
68
+ if (!name)
69
+ return;
70
+ if (guard === "request" && isForbiddenHeader(name))
71
+ throw new TypeError("Header guard error: " +
72
+ "Cannot set forbidden header for requests" +
73
+ ` (${name})`);
74
+ if (guard === "request-no-cors" && !isSimpleHeader(name, value))
75
+ throw new TypeError("Header guard error: " +
76
+ "Cannot set non-simple header for no-cors requests" +
77
+ ` (${name})`);
78
+ if (guard === "response" && isForbiddenResponseHeader(name))
79
+ throw new TypeError("Header guard error: " +
80
+ "Cannot set forbidden response header for response" +
81
+ ` (${name})`);
82
+ }
83
+ let _guard = null;
84
+ class Headers {
85
+ constructor(init) {
86
+ this._guard = _guard || "none";
87
+ _guard = null;
88
+ this._data = new Map();
89
+ const set = (name, values) => {
90
+ if (values.length === 1)
91
+ this.set(name, values[0]);
92
+ else
93
+ for (const value of values)
94
+ this.append(name, value);
95
+ };
96
+ if (!init)
97
+ return;
98
+ else if (init instanceof Headers) {
99
+ for (const [name, values] of init._data.entries())
100
+ set(name, values);
101
+ }
102
+ else {
103
+ for (const _name of Object.keys(init)) {
104
+ const name = filterName(_name);
105
+ const value = (0, utils_1.arrayify)(init[_name])
106
+ .map(val => `${val}`);
107
+ set(name, [...value]);
108
+ }
109
+ }
110
+ }
111
+ get [Symbol.toStringTag]() {
112
+ return "Map"; // This causes unit test libraries to treat this as a Map
113
+ }
114
+ [Symbol.iterator]() {
115
+ return this.entries();
116
+ }
117
+ append(name, value) {
118
+ const _name = filterName(name);
119
+ _ensureGuard(this._guard, _name, value);
120
+ if (!this._data.has(_name))
121
+ this._data.set(_name, [value]);
122
+ else
123
+ this._data.get(_name).push(value);
124
+ }
125
+ delete(name) {
126
+ const _name = filterName(name);
127
+ _ensureGuard(this._guard);
128
+ this._data.delete(_name);
129
+ }
130
+ *entries() {
131
+ for (const [name, value] of this._data.entries())
132
+ yield [name, value.join(",")];
133
+ }
134
+ get(name) {
135
+ const _name = filterName(name);
136
+ return this._data.has(_name)
137
+ ? this._data.get(_name).join(",")
138
+ : null;
139
+ }
140
+ has(name) {
141
+ return this._data.has(filterName(name));
142
+ }
143
+ keys() {
144
+ return this._data.keys();
145
+ }
146
+ set(name, value) {
147
+ const _name = filterName(name);
148
+ _ensureGuard(this._guard, _name, value);
149
+ this._data.set(_name, [value]);
150
+ }
151
+ *values() {
152
+ for (const value of this._data.values())
153
+ yield value.join(",");
154
+ }
155
+ // This is non-standard, but useful
156
+ toJSON() {
157
+ return [...this.entries()]
158
+ .reduce((prev, [key, val]) => Object.assign(prev, { [key]: val }), {});
159
+ }
160
+ }
161
+ exports.Headers = Headers;
162
+ class GuardedHeaders extends Headers {
163
+ constructor(guard, init) {
164
+ super((_guard = guard, init));
165
+ _guard = null;
166
+ }
167
+ }
168
+ exports.GuardedHeaders = GuardedHeaders;
169
+ function ensureHeaders(headers) {
170
+ return headers instanceof Headers ? headers : new Headers(headers);
171
+ }
172
+ exports.ensureHeaders = ensureHeaders;
173
+ //# sourceMappingURL=headers.js.map
@@ -0,0 +1,20 @@
1
+ import { AltNameMatch } from "./san";
2
+ export declare type Protocol = 'https1' | 'https2' | 'http1' | 'http2';
3
+ declare type AnySessionMap = {
4
+ [key in Protocol]: unknown;
5
+ };
6
+ export interface OriginCacheEntry<P, Session> {
7
+ protocol: P;
8
+ session: Session;
9
+ firstOrigin: string;
10
+ }
11
+ export default class OriginCache<SessionMap extends AnySessionMap> {
12
+ private sessionMap;
13
+ private staticMap;
14
+ get<P extends Protocol>(protocol: P, origin: string): OriginCacheEntry<typeof protocol, SessionMap[P]> | undefined;
15
+ set(origin: string, protocol: Protocol, session: SessionMap[typeof protocol], altNameMatch?: AltNameMatch, cleanup?: () => void): void;
16
+ delete(session: SessionMap[keyof SessionMap]): boolean;
17
+ disconnectAll(): void;
18
+ disconnect(origin: string): void;
19
+ }
20
+ export {};
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ function makeKey(protocol, origin) {
4
+ return protocol + ":" + origin;
5
+ }
6
+ class OriginCache {
7
+ constructor() {
8
+ this.sessionMap = new Map();
9
+ this.staticMap = new Map();
10
+ }
11
+ get(protocol, origin) {
12
+ const key = makeKey(protocol, origin);
13
+ const stateByStatic = this.staticMap.get(key);
14
+ if (stateByStatic)
15
+ return {
16
+ protocol: stateByStatic.protocol,
17
+ session: stateByStatic.session,
18
+ firstOrigin: stateByStatic.firstOrigin,
19
+ };
20
+ const stateByDynamic = [...this.sessionMap.values()].find(state => state.protocol === protocol &&
21
+ state.match &&
22
+ state.match.dynamic &&
23
+ state.match.dynamic(origin));
24
+ if (stateByDynamic) {
25
+ // An origin matching a dynamic (wildcard) alt-name was found.
26
+ // Cache this to find it statically in the future.
27
+ stateByDynamic.resolved.push(origin);
28
+ this.staticMap.set(key, stateByDynamic);
29
+ return {
30
+ protocol: stateByDynamic.protocol,
31
+ session: stateByDynamic.session,
32
+ firstOrigin: stateByDynamic.firstOrigin,
33
+ };
34
+ }
35
+ }
36
+ set(origin, protocol, session, altNameMatch, cleanup) {
37
+ const state = {
38
+ protocol,
39
+ firstOrigin: origin,
40
+ session,
41
+ match: altNameMatch,
42
+ resolved: [],
43
+ cleanup,
44
+ };
45
+ this.sessionMap.set(session, state);
46
+ if (altNameMatch)
47
+ altNameMatch.names.forEach(origin => {
48
+ this.staticMap.set(makeKey(protocol, origin), state);
49
+ });
50
+ this.staticMap.set(makeKey(protocol, origin), state);
51
+ }
52
+ // Returns true if a session was deleted, false otherwise
53
+ delete(session) {
54
+ var _a, _b;
55
+ const state = this.sessionMap.get(session);
56
+ if (!state)
57
+ return false;
58
+ [
59
+ state.firstOrigin,
60
+ ...state.resolved,
61
+ ...((_b = (_a = state.match) === null || _a === void 0 ? void 0 : _a.names) !== null && _b !== void 0 ? _b : []),
62
+ ]
63
+ .forEach(origin => {
64
+ this.staticMap.delete(makeKey(state.protocol, origin));
65
+ });
66
+ this.sessionMap.delete(session);
67
+ return true;
68
+ }
69
+ disconnectAll() {
70
+ [...this.sessionMap].forEach(([_, session]) => {
71
+ var _a;
72
+ (_a = session.cleanup) === null || _a === void 0 ? void 0 : _a.call(session);
73
+ });
74
+ this.sessionMap.clear();
75
+ this.staticMap.clear();
76
+ }
77
+ disconnect(origin) {
78
+ [
79
+ this.get('https1', origin),
80
+ this.get('https2', origin),
81
+ this.get('http1', origin),
82
+ this.get('http2', origin),
83
+ ]
84
+ .filter((t) => !!t)
85
+ .forEach(({ session }) => {
86
+ var _a, _b;
87
+ (_b = (_a = this.sessionMap.get(session)) === null || _a === void 0 ? void 0 : _a.cleanup) === null || _b === void 0 ? void 0 : _b.call(_a);
88
+ this.delete(session);
89
+ });
90
+ }
91
+ }
92
+ exports.default = OriginCache;
93
+ //# sourceMappingURL=origin-cache.js.map
@@ -0,0 +1,20 @@
1
+ import { CacheTypes, CredentialsTypes, Method, ModeTypes, RedirectTypes, ReferrerPolicyTypes, ReferrerTypes, RequestInitWithoutBody, RequestInitWithUrl } from "./core";
2
+ import { Body } from "./body";
3
+ import { Headers } from "./headers";
4
+ export declare class Request extends Body implements RequestInitWithoutBody {
5
+ readonly method: Method;
6
+ readonly url: string;
7
+ readonly headers: Headers;
8
+ readonly referrer: ReferrerTypes;
9
+ readonly referrerPolicy: ReferrerPolicyTypes;
10
+ readonly mode: ModeTypes;
11
+ readonly credentials: CredentialsTypes;
12
+ readonly redirect: RedirectTypes;
13
+ readonly integrity: string;
14
+ readonly cache: CacheTypes;
15
+ readonly allowForbiddenHeaders: boolean;
16
+ private _url;
17
+ private _init;
18
+ constructor(input: string | Request, init?: Partial<RequestInitWithUrl>);
19
+ clone(newUrl?: string): Request;
20
+ }
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Request = void 0;
4
+ const body_1 = require("./body");
5
+ const headers_1 = require("./headers");
6
+ const defaultInit = {
7
+ allowForbiddenHeaders: false,
8
+ cache: "default",
9
+ credentials: "omit",
10
+ method: "GET",
11
+ mode: "same-origin",
12
+ redirect: "manual",
13
+ referrer: "client",
14
+ };
15
+ class Request extends body_1.Body {
16
+ constructor(input, init) {
17
+ super();
18
+ const { url: overwriteUrl } = init || {};
19
+ // TODO: Consider throwing a TypeError if the URL has credentials
20
+ this._url =
21
+ input instanceof Request
22
+ ? (overwriteUrl || input._url)
23
+ : (overwriteUrl || input);
24
+ if (input instanceof Request) {
25
+ if (input.hasBody())
26
+ // Move body to this request
27
+ this.setBody(input);
28
+ const newInit = Object.assign({}, input, init);
29
+ init = newInit;
30
+ // TODO: Follow MDN:
31
+ // If this object exists on another origin to the
32
+ // constructor call, the Request.referrer is stripped out.
33
+ // If this object has a Request.mode of navigate, the mode
34
+ // value is converted to same-origin.
35
+ }
36
+ this._init = Object.assign({}, defaultInit, init);
37
+ const allowForbiddenHeaders = this._init.allowForbiddenHeaders;
38
+ const headers = new headers_1.GuardedHeaders(allowForbiddenHeaders
39
+ ? "none"
40
+ : this._init.mode === "no-cors"
41
+ ? "request-no-cors"
42
+ : "request", this._init.headers);
43
+ if (this._init.body && this._init.json)
44
+ throw new Error("Cannot specify both 'body' and 'json'");
45
+ if (!this.hasBody() && this._init.body) {
46
+ if (headers.has("content-type"))
47
+ this.setBody(this._init.body, headers.get("content-type"));
48
+ else
49
+ this.setBody(this._init.body);
50
+ }
51
+ else if (!this.hasBody() && this._init.json) {
52
+ this.setBody(new body_1.JsonBody(this._init.json));
53
+ }
54
+ Object.defineProperties(this, {
55
+ allowForbiddenHeaders: {
56
+ enumerable: true,
57
+ value: allowForbiddenHeaders,
58
+ },
59
+ cache: {
60
+ enumerable: true,
61
+ value: this._init.cache,
62
+ },
63
+ credentials: {
64
+ enumerable: true,
65
+ value: this._init.credentials,
66
+ },
67
+ headers: {
68
+ enumerable: true,
69
+ value: headers,
70
+ },
71
+ integrity: {
72
+ enumerable: true,
73
+ value: this._init.integrity,
74
+ },
75
+ method: {
76
+ enumerable: true,
77
+ value: this._init.method,
78
+ },
79
+ mode: {
80
+ enumerable: true,
81
+ value: this._init.mode,
82
+ },
83
+ redirect: {
84
+ enumerable: true,
85
+ value: this._init.redirect,
86
+ },
87
+ referrer: {
88
+ enumerable: true,
89
+ value: this._init.referrer,
90
+ },
91
+ referrerPolicy: {
92
+ enumerable: true,
93
+ value: this._init.referrerPolicy,
94
+ },
95
+ url: {
96
+ enumerable: true,
97
+ value: this._url,
98
+ },
99
+ });
100
+ }
101
+ clone(newUrl) {
102
+ return new Request(this, { url: newUrl });
103
+ }
104
+ }
105
+ exports.Request = Request;
106
+ //# sourceMappingURL=request.js.map
@@ -0,0 +1,33 @@
1
+ /// <reference types="node" />
2
+ import { BodyTypes, Decoder, HttpVersion, ResponseInit, ResponseTypes } from "./core";
3
+ import { AbortSignal } from "./abort";
4
+ import { Headers } from "./headers";
5
+ import { Body } from "./body";
6
+ import { IncomingHttpHeaders } from "./types";
7
+ interface Extra {
8
+ httpVersion: HttpVersion;
9
+ redirected: boolean;
10
+ integrity: string;
11
+ signal: AbortSignal;
12
+ type: ResponseTypes;
13
+ url: string;
14
+ }
15
+ export declare class Response extends Body {
16
+ readonly headers: Headers;
17
+ readonly ok: boolean;
18
+ readonly redirected: boolean;
19
+ readonly status: number;
20
+ readonly statusText: string;
21
+ readonly type: ResponseTypes;
22
+ readonly url: string;
23
+ readonly useFinalURL: boolean;
24
+ readonly httpVersion: HttpVersion;
25
+ constructor(body?: BodyTypes | Body | null, init?: Partial<ResponseInit>, extra?: Partial<Extra>);
26
+ static error(): Response;
27
+ static redirect(url: string, status?: number): Response;
28
+ clone(): Response;
29
+ }
30
+ export declare class StreamResponse extends Response {
31
+ constructor(contentDecoders: ReadonlyArray<Decoder>, url: string, stream: NodeJS.ReadableStream, headers: IncomingHttpHeaders, redirected: boolean, init: Partial<ResponseInit>, signal: AbortSignal | undefined, httpVersion: HttpVersion, allowForbiddenHeaders: boolean, integrity?: string);
32
+ }
33
+ export {};