@cloudpss/fetch 0.4.34 → 0.5.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.
@@ -0,0 +1,33 @@
1
+ export declare const fetch: typeof globalThis.fetch;
2
+ export declare const Headers: {
3
+ new (init?: HeadersInit | undefined): Headers;
4
+ prototype: Headers;
5
+ };
6
+ export declare const Response: {
7
+ new (body?: BodyInit | null | undefined, init?: ResponseInit | undefined): Response;
8
+ prototype: Response;
9
+ error(): Response;
10
+ json(data: any, init?: ResponseInit | undefined): Response;
11
+ redirect(url: string | URL, status?: number | undefined): Response;
12
+ };
13
+ export declare const Request: {
14
+ new (input: RequestInfo | URL, init?: RequestInit | undefined): Request;
15
+ prototype: Request;
16
+ };
17
+ export declare const File: {
18
+ new (fileBits: BlobPart[], fileName: string, options?: FilePropertyBag | undefined): File;
19
+ prototype: File;
20
+ };
21
+ export declare const FormData: {
22
+ new (form?: HTMLFormElement | undefined, submitter?: HTMLElement | null | undefined): FormData;
23
+ prototype: FormData;
24
+ };
25
+ export declare const WebSocket: {
26
+ new (url: string | URL, protocols?: string | string[] | undefined): WebSocket;
27
+ prototype: WebSocket;
28
+ readonly CONNECTING: 0;
29
+ readonly OPEN: 1;
30
+ readonly CLOSING: 2;
31
+ readonly CLOSED: 3;
32
+ };
33
+ export default fetch;
@@ -0,0 +1,12 @@
1
+ if (typeof globalThis == 'undefined' || typeof globalThis.fetch != 'function') {
2
+ throw new TypeError(`globalThis or fetch is not defined on the global object, you should load polyfill of fetch.`);
3
+ }
4
+ export const fetch = globalThis.fetch;
5
+ export const Headers = globalThis.Headers;
6
+ export const Response = globalThis.Response;
7
+ export const Request = globalThis.Request;
8
+ export const File = globalThis.File;
9
+ export const FormData = globalThis.FormData;
10
+ export const WebSocket = globalThis.WebSocket;
11
+ export default fetch;
12
+ //# sourceMappingURL=impl-browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impl-browser.js","sourceRoot":"","sources":["../src/impl-browser.ts"],"names":[],"mappings":"AAAA,IAAI,OAAO,UAAU,IAAI,WAAW,IAAI,OAAO,UAAU,CAAC,KAAK,IAAI,UAAU,EAAE;IAC3E,MAAM,IAAI,SAAS,CAAC,6FAA6F,CAAC,CAAC;CACtH;AAED,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;AACtC,MAAM,CAAC,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;AAC1C,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC;AAC5C,MAAM,CAAC,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;AAC1C,MAAM,CAAC,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC;AACpC,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC;AAC5C,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC;AAE9C,eAAe,KAAK,CAAC"}
@@ -0,0 +1,38 @@
1
+ /** 自动支持代理的 fetch */
2
+ export declare function fetch(url: RequestInfo | URL, init?: RequestInit): Promise<Response>;
3
+ export declare const Headers: {
4
+ new (init?: HeadersInit | undefined): Headers;
5
+ prototype: Headers;
6
+ };
7
+ export declare const Response: {
8
+ new (body?: BodyInit | null | undefined, init?: ResponseInit | undefined): Response;
9
+ prototype: Response;
10
+ error(): Response;
11
+ json(data: any, init?: ResponseInit | undefined): Response;
12
+ redirect(url: string | URL, status?: number | undefined): Response;
13
+ };
14
+ export declare const Request: {
15
+ new (input: RequestInfo | URL, init?: RequestInit | undefined): Request;
16
+ prototype: Request;
17
+ };
18
+ export declare const File: {
19
+ new (fileBits: BlobPart[], fileName: string, options?: FilePropertyBag | undefined): File;
20
+ prototype: File;
21
+ };
22
+ export declare const FormData: {
23
+ new (form?: HTMLFormElement | undefined, submitter?: HTMLElement | null | undefined): FormData;
24
+ prototype: FormData;
25
+ };
26
+ declare const WebSocket_base: {
27
+ new (url: string | URL, protocols?: string | string[] | undefined): globalThis.WebSocket;
28
+ prototype: globalThis.WebSocket;
29
+ readonly CONNECTING: 0;
30
+ readonly OPEN: 1;
31
+ readonly CLOSING: 2;
32
+ readonly CLOSED: 3;
33
+ };
34
+ /** 自动支持代理的 WebSocket */
35
+ export declare class WebSocket extends WebSocket_base {
36
+ constructor(url: string, protocols?: string | string[], headers?: HeadersInit);
37
+ }
38
+ export default fetch;
@@ -0,0 +1,76 @@
1
+ var _a, _b;
2
+ import { debuglog } from 'node:util';
3
+ import { fetch as nodeFetch, Headers as NodeHeaders, Response as NodeResponse, Request as NodeRequest, WebSocket as NodeWebSocket, File as NodeFile, FormData as NodeFormData, } from 'undici';
4
+ import { Dispatcher, ProxyAgent, Agent } from 'undici';
5
+ import DispatcherBase from 'undici/lib/dispatcher-base.js';
6
+ import symbols from 'undici/lib/core/symbols.js';
7
+ import { getProxyForUrl } from 'proxy-from-env';
8
+ const logger = debuglog('cloudpss/fetch');
9
+ const kAgents = Symbol('kAgents');
10
+ const kAgent = Symbol('kAgent');
11
+ /** 实现代理功能 */
12
+ class AutoProxyAgent extends DispatcherBase {
13
+ constructor() {
14
+ super(...arguments);
15
+ this[_a] = new Map();
16
+ this[_b] = new Agent();
17
+ }
18
+ /** 根据请求连接到代理 */
19
+ [(_a = kAgents, _b = kAgent, symbols.kDispatch)](options, handler) {
20
+ const { origin } = options;
21
+ const proxy = origin ? getProxyForUrl(String(origin)) : undefined;
22
+ logger(`auto proxy: to %s via %s`, origin, proxy);
23
+ if (!proxy) {
24
+ return this[kAgent].dispatch(options, handler);
25
+ }
26
+ let agent = this[kAgents].get(proxy);
27
+ if (!agent) {
28
+ agent = new ProxyAgent(proxy);
29
+ this[kAgents].set(proxy, agent);
30
+ }
31
+ return agent.dispatch(options, handler);
32
+ }
33
+ /** @inheritdoc */
34
+ async [symbols.kClose]() {
35
+ const tasks = [];
36
+ for (const agent of this[kAgents].values()) {
37
+ tasks.push(agent.close());
38
+ }
39
+ tasks.push(this[kAgent].close());
40
+ await Promise.all(tasks);
41
+ }
42
+ /** @inheritdoc */
43
+ async [symbols.kDestroy](err) {
44
+ if (err == null)
45
+ err = null;
46
+ const tasks = [];
47
+ for (const agent of this[kAgents].values()) {
48
+ tasks.push(agent.destroy(err));
49
+ }
50
+ tasks.push(this[kAgent].destroy(err));
51
+ await Promise.all(tasks);
52
+ }
53
+ }
54
+ const dispatcher = new AutoProxyAgent();
55
+ /** 自动支持代理的 fetch */
56
+ export function fetch(url, init) {
57
+ return nodeFetch(url, { ...init, dispatcher });
58
+ }
59
+ export const Headers = NodeHeaders;
60
+ export const Response = NodeResponse;
61
+ export const Request = NodeRequest;
62
+ export const File = NodeFile;
63
+ export const FormData = NodeFormData;
64
+ /** 自动支持代理的 WebSocket */
65
+ export class WebSocket extends NodeWebSocket {
66
+ constructor(url, protocols, headers) {
67
+ const options = {
68
+ dispatcher,
69
+ protocols,
70
+ headers,
71
+ };
72
+ super(url, options);
73
+ }
74
+ }
75
+ export default fetch;
76
+ //# sourceMappingURL=impl-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impl-node.js","sourceRoot":"","sources":["../src/impl-node.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,17 +1,2 @@
1
- export declare const fetch: typeof globalThis.fetch;
2
- export declare const Headers: {
3
- new (init?: HeadersInit | undefined): Headers;
4
- prototype: Headers;
5
- };
6
- export declare const Response: {
7
- new (body?: BodyInit | null | undefined, init?: ResponseInit | undefined): Response;
8
- prototype: Response;
9
- error(): Response;
10
- json(data: any, init?: ResponseInit | undefined): Response;
11
- redirect(url: string | URL, status?: number | undefined): Response;
12
- };
13
- export declare const Request: {
14
- new (input: RequestInfo | URL, init?: RequestInit | undefined): Request;
15
- prototype: Request;
16
- };
17
- export default fetch;
1
+ export { File, FormData, fetch, Request, Response, Headers, WebSocket } from '#impl';
2
+ export { connected, disconnected, WEB_SOCKET_STATUS_CODES } from './ws-utils.js';
package/dist/index.js CHANGED
@@ -1,17 +1,3 @@
1
- import nodeFetch, { Headers as NodeHeaders, Response as NodeResponse, Request as NodeRequest } from 'node-fetch';
2
- import { agent } from '@cloudpss/proxy-agent';
3
- /** 生成 fetch */
4
- function makeFetch() {
5
- if (agent) {
6
- return function fetch(url, init) {
7
- return nodeFetch(url, { ...init, agent });
8
- };
9
- }
10
- return nodeFetch;
11
- }
12
- export const fetch = makeFetch();
13
- export const Headers = NodeHeaders;
14
- export const Response = NodeResponse;
15
- export const Request = NodeRequest;
16
- export default fetch;
1
+ export { File, FormData, fetch, Request, Response, Headers, WebSocket } from '#impl';
2
+ export { connected, disconnected, WEB_SOCKET_STATUS_CODES } from './ws-utils.js';
17
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,EAAE,EAAE,OAAO,IAAI,WAAW,EAAE,QAAQ,IAAI,YAAY,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,YAAY,CAAC;AACjH,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE9C,eAAe;AACf,SAAS,SAAS;IACd,IAAI,KAAK,EAAE;QACP,OAAO,SAAS,KAAK,CAAC,GAAsB,EAAE,IAAkB;YAC5D,OAAO,SAAS,CACZ,GAAsB,EACtB,EAAE,GAAG,IAAI,EAAE,KAAK,EAAqB,CACR,CAAC;QACtC,CAAC,CAAC;KACL;IACD,OAAO,SAAoC,CAAC;AAChD,CAAC;AAED,MAAM,CAAC,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;AACjC,MAAM,CAAC,MAAM,OAAO,GAAG,WAAmD,CAAC;AAC3E,MAAM,CAAC,MAAM,QAAQ,GAAG,YAAqD,CAAC;AAC9E,MAAM,CAAC,MAAM,OAAO,GAAG,WAAmD,CAAC;AAE3E,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACrF,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,133 @@
1
+ export declare enum WEB_SOCKET_STATUS_CODES {
2
+ /** Status codes in the range 0-999 are not used. */
3
+ /**
4
+ 1000 indicates a normal closure, meaning that the purpose for
5
+ which the connection was established has been fulfilled.
6
+ */
7
+ NORMAL_CLOSURE = 1000,
8
+ /**
9
+ * 1001 indicates that an endpoint is "going away", such as a server
10
+ * going down or a browser having navigated away from a page.
11
+ */
12
+ GOING_AWAY = 1001,
13
+ /**
14
+ * 1002 indicates that an endpoint is terminating the connection due
15
+ * to a protocol error.
16
+ */
17
+ PROTOCOL_ERROR = 1002,
18
+ /**
19
+ * 1003 indicates that an endpoint is terminating the connection
20
+ * because it has received a type of data it cannot accept (e.g., an
21
+ * endpoint that understands only text data MAY send this if it
22
+ * receives a binary message).
23
+ */
24
+ UNSUPPORTED_DATA = 1003,
25
+ /** Reserved. The specific meaning might be defined in the future. */
26
+ RESERVED = 1004,
27
+ /**
28
+ * 1005 is a reserved value and MUST NOT be set as a status code in a
29
+ * Close control frame by an endpoint. It is designated for use in
30
+ * applications expecting a status code to indicate that no status
31
+ * code was actually present.
32
+ */
33
+ NO_STATUS_RECEIVED = 1005,
34
+ /**
35
+ * 1006 is a reserved value and MUST NOT be set as a status code in a
36
+ * Close control frame by an endpoint. It is designated for use in
37
+ * applications expecting a status code to indicate that the
38
+ * connection was closed abnormally, e.g., without sending or
39
+ * receiving a Close control frame.
40
+ */
41
+ ABNORMAL_CLOSURE = 1006,
42
+ /**
43
+ * 1007 indicates that an endpoint is terminating the connection
44
+ * because it has received data within a message that was not
45
+ * consistent with the type of the message (e.g., non-UTF-8 [RFC3629]
46
+ * data within a text message).
47
+ */
48
+ INVALID_FRAME_PAYLOAD_DATA = 1007,
49
+ /**
50
+ * 1008 indicates that an endpoint is terminating the connection
51
+ * because it has received a message that violates its policy. This
52
+ * is a generic status code that can be returned when there is no
53
+ * other more suitable status code (e.g., 1003 or 1009) or if there
54
+ * is a need to hide specific details about the policy.
55
+ */
56
+ POLICY_VIOLATION = 1008,
57
+ /**
58
+ * 1009 indicates that an endpoint is terminating the connection
59
+ * because it has received a message that is too big for it to
60
+ * process.
61
+ */
62
+ MESSAGE_TOO_BIG = 1009,
63
+ /**
64
+ * 1010 indicates that an endpoint (client) is terminating the
65
+ * connection because it has expected the server to negotiate one or
66
+ * more extension, but the server didn't return them in the response
67
+ * message of the WebSocket handshake. The list of extensions that
68
+ * are needed SHOULD appear in the /reason/ part of the Close frame.
69
+ * Note that this status code is not used by the server, because it
70
+ * can fail the WebSocket handshake instead.
71
+ */
72
+ MISSING_EXTENSION = 1010,
73
+ /**
74
+ * 1011 indicates that a server is terminating the connection because
75
+ * it encountered an unexpected condition that prevented it from
76
+ * fulfilling the request.
77
+ */
78
+ INTERNAL_ERROR = 1011,
79
+ /**
80
+ * 1012 indicates that the service is restarted. A client may
81
+ * reconnect, and if it chooses to do, should reconnect using a
82
+ * randomized delay of 5 - 30s.
83
+ * @deprecated
84
+ */
85
+ SERVICE_RESTART = 1012,
86
+ /**
87
+ * 1013 indicates that the service is experiencing overload. A client
88
+ * should only connect to a different IP (when there are multiple for
89
+ * the target) or reconnect to the same IP upon user action.
90
+ * @deprecated
91
+ */
92
+ TRY_AGAIN_LATER = 1013,
93
+ /**
94
+ * 1014 is a reserved value and MUST NOT be set as a status code in a
95
+ * Close control frame by an endpoint. It is designated for use in
96
+ * applications expecting a status code to indicate that the
97
+ * connection was closed due to a failure to perform a TLS handshake
98
+ * (e.g., the server certificate can't be verified).
99
+ * @deprecated
100
+ */
101
+ BAD_GATEWAY = 1014,
102
+ /**
103
+ * 1015 is a reserved value and MUST NOT be set as a status code in a
104
+ * Close control frame by an endpoint. It is designated for use in
105
+ * applications expecting a status code to indicate that the
106
+ * connection was closed due to a failure to perform a TLS handshake
107
+ * (e.g., the server certificate can't be verified).
108
+ */
109
+ TLS_HANDSHAKE = 1015,
110
+ /**
111
+ * Status codes in the range 1000-2999 are reserved for definition by
112
+ * this protocol, its future revisions, and extensions specified in a
113
+ * permanent and readily available public specification.
114
+ */
115
+ /**
116
+ * Status codes in the range 3000-3999 are reserved for use by
117
+ * libraries, frameworks, and applications. These status codes are
118
+ * registered directly with IANA. The interpretation of these codes
119
+ * is undefined by this protocol.
120
+ */
121
+ LIBRARY = 3000,
122
+ /**
123
+ * Status codes in the range 4000-4999 are reserved for private use
124
+ * and thus can't be registered. Such codes can be used by prior
125
+ * agreements between WebSocket applications. The interpretation of
126
+ * these codes is undefined by this protocol.
127
+ */
128
+ APPLICATION = 4000
129
+ }
130
+ /** 等待连接建立 */
131
+ export declare function connected(socket: WebSocket): Promise<void>;
132
+ /** 等待连接断开 */
133
+ export declare function disconnected(socket: WebSocket): Promise<void>;
@@ -0,0 +1,202 @@
1
+ export var WEB_SOCKET_STATUS_CODES;
2
+ (function (WEB_SOCKET_STATUS_CODES) {
3
+ /** Status codes in the range 0-999 are not used. */
4
+ /**
5
+ 1000 indicates a normal closure, meaning that the purpose for
6
+ which the connection was established has been fulfilled.
7
+ */
8
+ WEB_SOCKET_STATUS_CODES[WEB_SOCKET_STATUS_CODES["NORMAL_CLOSURE"] = 1000] = "NORMAL_CLOSURE";
9
+ /**
10
+ * 1001 indicates that an endpoint is "going away", such as a server
11
+ * going down or a browser having navigated away from a page.
12
+ */
13
+ WEB_SOCKET_STATUS_CODES[WEB_SOCKET_STATUS_CODES["GOING_AWAY"] = 1001] = "GOING_AWAY";
14
+ /**
15
+ * 1002 indicates that an endpoint is terminating the connection due
16
+ * to a protocol error.
17
+ */
18
+ WEB_SOCKET_STATUS_CODES[WEB_SOCKET_STATUS_CODES["PROTOCOL_ERROR"] = 1002] = "PROTOCOL_ERROR";
19
+ /**
20
+ * 1003 indicates that an endpoint is terminating the connection
21
+ * because it has received a type of data it cannot accept (e.g., an
22
+ * endpoint that understands only text data MAY send this if it
23
+ * receives a binary message).
24
+ */
25
+ WEB_SOCKET_STATUS_CODES[WEB_SOCKET_STATUS_CODES["UNSUPPORTED_DATA"] = 1003] = "UNSUPPORTED_DATA";
26
+ /** Reserved. The specific meaning might be defined in the future. */
27
+ WEB_SOCKET_STATUS_CODES[WEB_SOCKET_STATUS_CODES["RESERVED"] = 1004] = "RESERVED";
28
+ /**
29
+ * 1005 is a reserved value and MUST NOT be set as a status code in a
30
+ * Close control frame by an endpoint. It is designated for use in
31
+ * applications expecting a status code to indicate that no status
32
+ * code was actually present.
33
+ */
34
+ WEB_SOCKET_STATUS_CODES[WEB_SOCKET_STATUS_CODES["NO_STATUS_RECEIVED"] = 1005] = "NO_STATUS_RECEIVED";
35
+ /**
36
+ * 1006 is a reserved value and MUST NOT be set as a status code in a
37
+ * Close control frame by an endpoint. It is designated for use in
38
+ * applications expecting a status code to indicate that the
39
+ * connection was closed abnormally, e.g., without sending or
40
+ * receiving a Close control frame.
41
+ */
42
+ WEB_SOCKET_STATUS_CODES[WEB_SOCKET_STATUS_CODES["ABNORMAL_CLOSURE"] = 1006] = "ABNORMAL_CLOSURE";
43
+ /**
44
+ * 1007 indicates that an endpoint is terminating the connection
45
+ * because it has received data within a message that was not
46
+ * consistent with the type of the message (e.g., non-UTF-8 [RFC3629]
47
+ * data within a text message).
48
+ */
49
+ WEB_SOCKET_STATUS_CODES[WEB_SOCKET_STATUS_CODES["INVALID_FRAME_PAYLOAD_DATA"] = 1007] = "INVALID_FRAME_PAYLOAD_DATA";
50
+ /**
51
+ * 1008 indicates that an endpoint is terminating the connection
52
+ * because it has received a message that violates its policy. This
53
+ * is a generic status code that can be returned when there is no
54
+ * other more suitable status code (e.g., 1003 or 1009) or if there
55
+ * is a need to hide specific details about the policy.
56
+ */
57
+ WEB_SOCKET_STATUS_CODES[WEB_SOCKET_STATUS_CODES["POLICY_VIOLATION"] = 1008] = "POLICY_VIOLATION";
58
+ /**
59
+ * 1009 indicates that an endpoint is terminating the connection
60
+ * because it has received a message that is too big for it to
61
+ * process.
62
+ */
63
+ WEB_SOCKET_STATUS_CODES[WEB_SOCKET_STATUS_CODES["MESSAGE_TOO_BIG"] = 1009] = "MESSAGE_TOO_BIG";
64
+ /**
65
+ * 1010 indicates that an endpoint (client) is terminating the
66
+ * connection because it has expected the server to negotiate one or
67
+ * more extension, but the server didn't return them in the response
68
+ * message of the WebSocket handshake. The list of extensions that
69
+ * are needed SHOULD appear in the /reason/ part of the Close frame.
70
+ * Note that this status code is not used by the server, because it
71
+ * can fail the WebSocket handshake instead.
72
+ */
73
+ WEB_SOCKET_STATUS_CODES[WEB_SOCKET_STATUS_CODES["MISSING_EXTENSION"] = 1010] = "MISSING_EXTENSION";
74
+ /**
75
+ * 1011 indicates that a server is terminating the connection because
76
+ * it encountered an unexpected condition that prevented it from
77
+ * fulfilling the request.
78
+ */
79
+ WEB_SOCKET_STATUS_CODES[WEB_SOCKET_STATUS_CODES["INTERNAL_ERROR"] = 1011] = "INTERNAL_ERROR";
80
+ /**
81
+ * 1012 indicates that the service is restarted. A client may
82
+ * reconnect, and if it chooses to do, should reconnect using a
83
+ * randomized delay of 5 - 30s.
84
+ * @deprecated
85
+ */
86
+ WEB_SOCKET_STATUS_CODES[WEB_SOCKET_STATUS_CODES["SERVICE_RESTART"] = 1012] = "SERVICE_RESTART";
87
+ /**
88
+ * 1013 indicates that the service is experiencing overload. A client
89
+ * should only connect to a different IP (when there are multiple for
90
+ * the target) or reconnect to the same IP upon user action.
91
+ * @deprecated
92
+ */
93
+ WEB_SOCKET_STATUS_CODES[WEB_SOCKET_STATUS_CODES["TRY_AGAIN_LATER"] = 1013] = "TRY_AGAIN_LATER";
94
+ /**
95
+ * 1014 is a reserved value and MUST NOT be set as a status code in a
96
+ * Close control frame by an endpoint. It is designated for use in
97
+ * applications expecting a status code to indicate that the
98
+ * connection was closed due to a failure to perform a TLS handshake
99
+ * (e.g., the server certificate can't be verified).
100
+ * @deprecated
101
+ */
102
+ WEB_SOCKET_STATUS_CODES[WEB_SOCKET_STATUS_CODES["BAD_GATEWAY"] = 1014] = "BAD_GATEWAY";
103
+ /**
104
+ * 1015 is a reserved value and MUST NOT be set as a status code in a
105
+ * Close control frame by an endpoint. It is designated for use in
106
+ * applications expecting a status code to indicate that the
107
+ * connection was closed due to a failure to perform a TLS handshake
108
+ * (e.g., the server certificate can't be verified).
109
+ */
110
+ WEB_SOCKET_STATUS_CODES[WEB_SOCKET_STATUS_CODES["TLS_HANDSHAKE"] = 1015] = "TLS_HANDSHAKE";
111
+ /**
112
+ * Status codes in the range 1000-2999 are reserved for definition by
113
+ * this protocol, its future revisions, and extensions specified in a
114
+ * permanent and readily available public specification.
115
+ */
116
+ /**
117
+ * Status codes in the range 3000-3999 are reserved for use by
118
+ * libraries, frameworks, and applications. These status codes are
119
+ * registered directly with IANA. The interpretation of these codes
120
+ * is undefined by this protocol.
121
+ */
122
+ WEB_SOCKET_STATUS_CODES[WEB_SOCKET_STATUS_CODES["LIBRARY"] = 3000] = "LIBRARY";
123
+ /**
124
+ * Status codes in the range 4000-4999 are reserved for private use
125
+ * and thus can't be registered. Such codes can be used by prior
126
+ * agreements between WebSocket applications. The interpretation of
127
+ * these codes is undefined by this protocol.
128
+ */
129
+ WEB_SOCKET_STATUS_CODES[WEB_SOCKET_STATUS_CODES["APPLICATION"] = 4000] = "APPLICATION";
130
+ })(WEB_SOCKET_STATUS_CODES || (WEB_SOCKET_STATUS_CODES = {}));
131
+ /** 等待连接建立 */
132
+ export async function connected(socket) {
133
+ switch (socket.readyState) {
134
+ case socket.CONNECTING:
135
+ return new Promise((resolve, reject) => {
136
+ const onOpen = () => {
137
+ resolve();
138
+ cleanUp();
139
+ };
140
+ const onError = (ev) => {
141
+ const error = ev.error ?? new Error(`Failed to connect`);
142
+ reject(error);
143
+ cleanUp();
144
+ };
145
+ const cleanUp = () => {
146
+ socket.removeEventListener('open', onOpen);
147
+ socket.removeEventListener('error', onError);
148
+ };
149
+ socket.addEventListener('open', onOpen);
150
+ socket.addEventListener('error', onError);
151
+ });
152
+ case socket.OPEN:
153
+ return;
154
+ case socket.CLOSING:
155
+ throw new Error(`Socket is closing.`);
156
+ case socket.CLOSED:
157
+ throw new Error(`Socket is closed.`);
158
+ default:
159
+ throw new Error(`Socket is in unknown state.`);
160
+ }
161
+ }
162
+ /** 等待连接断开 */
163
+ export async function disconnected(socket) {
164
+ switch (socket.readyState) {
165
+ case socket.CONNECTING:
166
+ await connected(socket);
167
+ return await disconnected(socket);
168
+ case socket.OPEN:
169
+ case socket.CLOSING:
170
+ return new Promise((resolve, reject) => {
171
+ const onClose = (ev) => {
172
+ const code = ev.code;
173
+ const reason = ev.reason || WEB_SOCKET_STATUS_CODES[code] || '';
174
+ if (code !== WEB_SOCKET_STATUS_CODES.NORMAL_CLOSURE) {
175
+ const error = new Error(reason);
176
+ error.code = code;
177
+ reject(error);
178
+ }
179
+ else {
180
+ resolve();
181
+ }
182
+ cleanUp();
183
+ };
184
+ const onError = (ev) => {
185
+ const error = ev.error ?? new Error(`Connection error`);
186
+ reject(error);
187
+ cleanUp();
188
+ };
189
+ const cleanUp = () => {
190
+ socket.removeEventListener('close', onClose);
191
+ socket.removeEventListener('error', onError);
192
+ };
193
+ socket.addEventListener('close', onClose);
194
+ socket.addEventListener('error', onError);
195
+ });
196
+ case socket.CLOSED:
197
+ throw new Error(`Socket is closed.`);
198
+ default:
199
+ throw new Error(`Socket is in unknown state.`);
200
+ }
201
+ }
202
+ //# sourceMappingURL=ws-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-utils.js","sourceRoot":"","sources":["../src/ws-utils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,19 +1,30 @@
1
1
  {
2
2
  "name": "@cloudpss/fetch",
3
- "version": "0.4.34",
3
+ "version": "0.5.0",
4
4
  "author": "CloudPSS",
5
5
  "license": "MIT",
6
+ "keywords": [
7
+ "fetch",
8
+ "websocket"
9
+ ],
6
10
  "type": "module",
7
11
  "sideEffects": false,
12
+ "engines": {
13
+ "node": ">=16.8.0"
14
+ },
8
15
  "main": "dist/index.js",
9
16
  "module": "dist/index.js",
10
17
  "types": "dist/index.d.ts",
11
- "browser": "dist/index-browser.js",
12
- "exports": {
13
- "types": "./dist/index.d.ts",
14
- "browser": "./dist/index-browser.js",
15
- "node": "./dist/index.js",
16
- "default": "./dist/index-browser.js"
18
+ "browser": {
19
+ "./dist/impl.js": "./dist/impl-browser.js"
20
+ },
21
+ "exports": "./dist/index.js",
22
+ "imports": {
23
+ "#impl": {
24
+ "browser": "./dist/impl-browser.js",
25
+ "node": "./dist/impl-node.js",
26
+ "default": "./dist/impl-browser.js"
27
+ }
17
28
  },
18
29
  "scripts": {
19
30
  "start": "yarn clean && tsc --watch",
@@ -23,7 +34,10 @@
23
34
  "test": "echo 'no test'"
24
35
  },
25
36
  "dependencies": {
26
- "@cloudpss/proxy-agent": "~0.4.34",
27
- "node-fetch": "^3.3.2"
37
+ "proxy-from-env": "^1.1.0",
38
+ "undici": "^5.27.0"
39
+ },
40
+ "devDependencies": {
41
+ "@types/proxy-from-env": "^1.0.3"
28
42
  }
29
43
  }
@@ -0,0 +1,13 @@
1
+ if (typeof globalThis == 'undefined' || typeof globalThis.fetch != 'function') {
2
+ throw new TypeError(`globalThis or fetch is not defined on the global object, you should load polyfill of fetch.`);
3
+ }
4
+
5
+ export const fetch = globalThis.fetch;
6
+ export const Headers = globalThis.Headers;
7
+ export const Response = globalThis.Response;
8
+ export const Request = globalThis.Request;
9
+ export const File = globalThis.File;
10
+ export const FormData = globalThis.FormData;
11
+ export const WebSocket = globalThis.WebSocket;
12
+
13
+ export default fetch;
@@ -0,0 +1,90 @@
1
+ import { debuglog } from 'node:util';
2
+ import type { RequestInfo as NodeRequestInfo, RequestInit as NodeRequestInit, WebSocketInit } from 'undici';
3
+ import {
4
+ fetch as nodeFetch,
5
+ Headers as NodeHeaders,
6
+ Response as NodeResponse,
7
+ Request as NodeRequest,
8
+ WebSocket as NodeWebSocket,
9
+ File as NodeFile,
10
+ FormData as NodeFormData,
11
+ } from 'undici';
12
+ import { Dispatcher, ProxyAgent, Agent } from 'undici';
13
+ import DispatcherBase from 'undici/lib/dispatcher-base.js';
14
+ import symbols from 'undici/lib/core/symbols.js';
15
+ import { getProxyForUrl } from 'proxy-from-env';
16
+
17
+ const logger = debuglog('cloudpss/fetch');
18
+ const kAgents = Symbol('kAgents');
19
+ const kAgent = Symbol('kAgent');
20
+
21
+ /** 实现代理功能 */
22
+ class AutoProxyAgent extends DispatcherBase {
23
+ private readonly [kAgents] = new Map<string, ProxyAgent>();
24
+ private readonly [kAgent] = new Agent();
25
+ /** 根据请求连接到代理 */
26
+ override [symbols.kDispatch](options: Dispatcher.DispatchOptions, handler: Dispatcher.DispatchHandlers): boolean {
27
+ const { origin } = options;
28
+ const proxy = origin ? getProxyForUrl(String(origin)) : undefined;
29
+ logger(`auto proxy: to %s via %s`, origin, proxy);
30
+ if (!proxy) {
31
+ return this[kAgent].dispatch(options, handler);
32
+ }
33
+ let agent = this[kAgents].get(proxy);
34
+ if (!agent) {
35
+ agent = new ProxyAgent(proxy);
36
+ this[kAgents].set(proxy, agent);
37
+ }
38
+ return agent.dispatch(options, handler);
39
+ }
40
+
41
+ /** @inheritdoc */
42
+ override async [symbols.kClose](): Promise<void> {
43
+ const tasks = [];
44
+ for (const agent of this[kAgents].values()) {
45
+ tasks.push(agent.close());
46
+ }
47
+ tasks.push(this[kAgent].close());
48
+ await Promise.all(tasks);
49
+ }
50
+
51
+ /** @inheritdoc */
52
+ override async [symbols.kDestroy](err?: Error | null): Promise<void> {
53
+ if (err == null) err = null;
54
+ const tasks = [];
55
+ for (const agent of this[kAgents].values()) {
56
+ tasks.push(agent.destroy(err));
57
+ }
58
+ tasks.push(this[kAgent].destroy(err));
59
+ await Promise.all(tasks);
60
+ }
61
+ }
62
+
63
+ const dispatcher = new AutoProxyAgent();
64
+
65
+ /** 自动支持代理的 fetch */
66
+ export function fetch(url: RequestInfo | URL, init?: RequestInit): Promise<Response> {
67
+ return nodeFetch(
68
+ url as NodeRequestInfo,
69
+ { ...init, dispatcher } as NodeRequestInit,
70
+ ) as unknown as Promise<Response>;
71
+ }
72
+ export const Headers = NodeHeaders as typeof globalThis.Headers;
73
+ export const Response = NodeResponse as unknown as typeof globalThis.Response;
74
+ export const Request = NodeRequest as unknown as typeof globalThis.Request;
75
+ export const File = NodeFile as unknown as typeof globalThis.File;
76
+ export const FormData = NodeFormData as unknown as typeof globalThis.FormData;
77
+
78
+ /** 自动支持代理的 WebSocket */
79
+ export class WebSocket extends (NodeWebSocket as unknown as typeof globalThis.WebSocket) {
80
+ constructor(url: string, protocols?: string | string[], headers?: HeadersInit) {
81
+ const options: WebSocketInit = {
82
+ dispatcher,
83
+ protocols,
84
+ headers,
85
+ };
86
+ super(url, options as unknown as string[]);
87
+ }
88
+ }
89
+
90
+ export default fetch;
package/src/index.ts CHANGED
@@ -1,23 +1,2 @@
1
- import type { RequestInfo as NodeRequestInfo, RequestInit as NodeRequestInit } from 'node-fetch';
2
- import nodeFetch, { Headers as NodeHeaders, Response as NodeResponse, Request as NodeRequest } from 'node-fetch';
3
- import { agent } from '@cloudpss/proxy-agent';
4
-
5
- /** 生成 fetch */
6
- function makeFetch(): typeof globalThis.fetch {
7
- if (agent) {
8
- return function fetch(url: RequestInfo | URL, init?: RequestInit): Promise<Response> {
9
- return nodeFetch(
10
- url as NodeRequestInfo,
11
- { ...init, agent } as NodeRequestInit,
12
- ) as unknown as Promise<Response>;
13
- };
14
- }
15
- return nodeFetch as unknown as typeof fetch;
16
- }
17
-
18
- export const fetch = makeFetch();
19
- export const Headers = NodeHeaders as unknown as typeof globalThis.Headers;
20
- export const Response = NodeResponse as unknown as typeof globalThis.Response;
21
- export const Request = NodeRequest as unknown as typeof globalThis.Request;
22
-
23
- export default fetch;
1
+ export { File, FormData, fetch, Request, Response, Headers, WebSocket } from '#impl';
2
+ export { connected, disconnected, WEB_SOCKET_STATUS_CODES } from './ws-utils.js';
@@ -0,0 +1,26 @@
1
+ /* eslint-disable jsdoc/require-jsdoc */
2
+
3
+ declare module 'undici/lib/core/symbols.js' {
4
+ const kClose: unique symbol;
5
+ const kDestroy: unique symbol;
6
+ const kDispatch: unique symbol;
7
+
8
+ export = {
9
+ kClose,
10
+ kDestroy,
11
+ kDispatch,
12
+ };
13
+ }
14
+
15
+ declare module 'undici/lib/dispatcher-base.js' {
16
+ import { Dispatcher } from 'undici';
17
+ import { kDestroy, kClose, kDispatch } from 'undici/lib/core/symbols.js';
18
+ class DispatcherBase extends Dispatcher {
19
+ // Should not error.
20
+ protected [kDestroy](err?: Error | null): Promise<void>;
21
+ // Should not error.
22
+ protected [kClose](): Promise<void>;
23
+ protected [kDispatch](options: Dispatcher.DispatchOptions, handler: Dispatcher.DispatchHandlers): boolean;
24
+ }
25
+ export = DispatcherBase;
26
+ }
@@ -0,0 +1,204 @@
1
+ export enum WEB_SOCKET_STATUS_CODES {
2
+ /** Status codes in the range 0-999 are not used. */
3
+
4
+ /**
5
+ 1000 indicates a normal closure, meaning that the purpose for
6
+ which the connection was established has been fulfilled.
7
+ */
8
+ NORMAL_CLOSURE = 1000,
9
+ /**
10
+ * 1001 indicates that an endpoint is "going away", such as a server
11
+ * going down or a browser having navigated away from a page.
12
+ */
13
+ GOING_AWAY = 1001,
14
+ /**
15
+ * 1002 indicates that an endpoint is terminating the connection due
16
+ * to a protocol error.
17
+ */
18
+ PROTOCOL_ERROR = 1002,
19
+ /**
20
+ * 1003 indicates that an endpoint is terminating the connection
21
+ * because it has received a type of data it cannot accept (e.g., an
22
+ * endpoint that understands only text data MAY send this if it
23
+ * receives a binary message).
24
+ */
25
+ UNSUPPORTED_DATA = 1003,
26
+ /** Reserved. The specific meaning might be defined in the future. */
27
+ RESERVED = 1004,
28
+ /**
29
+ * 1005 is a reserved value and MUST NOT be set as a status code in a
30
+ * Close control frame by an endpoint. It is designated for use in
31
+ * applications expecting a status code to indicate that no status
32
+ * code was actually present.
33
+ */
34
+ NO_STATUS_RECEIVED = 1005,
35
+ /**
36
+ * 1006 is a reserved value and MUST NOT be set as a status code in a
37
+ * Close control frame by an endpoint. It is designated for use in
38
+ * applications expecting a status code to indicate that the
39
+ * connection was closed abnormally, e.g., without sending or
40
+ * receiving a Close control frame.
41
+ */
42
+ ABNORMAL_CLOSURE = 1006,
43
+ /**
44
+ * 1007 indicates that an endpoint is terminating the connection
45
+ * because it has received data within a message that was not
46
+ * consistent with the type of the message (e.g., non-UTF-8 [RFC3629]
47
+ * data within a text message).
48
+ */
49
+ INVALID_FRAME_PAYLOAD_DATA = 1007,
50
+ /**
51
+ * 1008 indicates that an endpoint is terminating the connection
52
+ * because it has received a message that violates its policy. This
53
+ * is a generic status code that can be returned when there is no
54
+ * other more suitable status code (e.g., 1003 or 1009) or if there
55
+ * is a need to hide specific details about the policy.
56
+ */
57
+ POLICY_VIOLATION = 1008,
58
+ /**
59
+ * 1009 indicates that an endpoint is terminating the connection
60
+ * because it has received a message that is too big for it to
61
+ * process.
62
+ */
63
+ MESSAGE_TOO_BIG = 1009,
64
+ /**
65
+ * 1010 indicates that an endpoint (client) is terminating the
66
+ * connection because it has expected the server to negotiate one or
67
+ * more extension, but the server didn't return them in the response
68
+ * message of the WebSocket handshake. The list of extensions that
69
+ * are needed SHOULD appear in the /reason/ part of the Close frame.
70
+ * Note that this status code is not used by the server, because it
71
+ * can fail the WebSocket handshake instead.
72
+ */
73
+ MISSING_EXTENSION = 1010,
74
+ /**
75
+ * 1011 indicates that a server is terminating the connection because
76
+ * it encountered an unexpected condition that prevented it from
77
+ * fulfilling the request.
78
+ */
79
+ INTERNAL_ERROR = 1011,
80
+ /**
81
+ * 1012 indicates that the service is restarted. A client may
82
+ * reconnect, and if it chooses to do, should reconnect using a
83
+ * randomized delay of 5 - 30s.
84
+ * @deprecated
85
+ */
86
+ SERVICE_RESTART = 1012,
87
+ /**
88
+ * 1013 indicates that the service is experiencing overload. A client
89
+ * should only connect to a different IP (when there are multiple for
90
+ * the target) or reconnect to the same IP upon user action.
91
+ * @deprecated
92
+ */
93
+ TRY_AGAIN_LATER = 1013,
94
+ /**
95
+ * 1014 is a reserved value and MUST NOT be set as a status code in a
96
+ * Close control frame by an endpoint. It is designated for use in
97
+ * applications expecting a status code to indicate that the
98
+ * connection was closed due to a failure to perform a TLS handshake
99
+ * (e.g., the server certificate can't be verified).
100
+ * @deprecated
101
+ */
102
+ BAD_GATEWAY = 1014,
103
+ /**
104
+ * 1015 is a reserved value and MUST NOT be set as a status code in a
105
+ * Close control frame by an endpoint. It is designated for use in
106
+ * applications expecting a status code to indicate that the
107
+ * connection was closed due to a failure to perform a TLS handshake
108
+ * (e.g., the server certificate can't be verified).
109
+ */
110
+ TLS_HANDSHAKE = 1015,
111
+
112
+ /**
113
+ * Status codes in the range 1000-2999 are reserved for definition by
114
+ * this protocol, its future revisions, and extensions specified in a
115
+ * permanent and readily available public specification.
116
+ */
117
+
118
+ /**
119
+ * Status codes in the range 3000-3999 are reserved for use by
120
+ * libraries, frameworks, and applications. These status codes are
121
+ * registered directly with IANA. The interpretation of these codes
122
+ * is undefined by this protocol.
123
+ */
124
+ LIBRARY = 3000,
125
+ /**
126
+ * Status codes in the range 4000-4999 are reserved for private use
127
+ * and thus can't be registered. Such codes can be used by prior
128
+ * agreements between WebSocket applications. The interpretation of
129
+ * these codes is undefined by this protocol.
130
+ */
131
+ APPLICATION = 4000,
132
+ }
133
+
134
+ /** 等待连接建立 */
135
+ export async function connected(socket: WebSocket): Promise<void> {
136
+ switch (socket.readyState) {
137
+ case socket.CONNECTING:
138
+ return new Promise((resolve, reject) => {
139
+ const onOpen = (): void => {
140
+ resolve();
141
+ cleanUp();
142
+ };
143
+ const onError = (ev: ErrorEvent | Event): void => {
144
+ const error = ((ev as ErrorEvent).error as Error) ?? new Error(`Failed to connect`);
145
+ reject(error);
146
+ cleanUp();
147
+ };
148
+ const cleanUp = (): void => {
149
+ socket.removeEventListener('open', onOpen);
150
+ socket.removeEventListener('error', onError);
151
+ };
152
+ socket.addEventListener('open', onOpen);
153
+ socket.addEventListener('error', onError);
154
+ });
155
+ case socket.OPEN:
156
+ return;
157
+ case socket.CLOSING:
158
+ throw new Error(`Socket is closing.`);
159
+ case socket.CLOSED:
160
+ throw new Error(`Socket is closed.`);
161
+ default:
162
+ throw new Error(`Socket is in unknown state.`);
163
+ }
164
+ }
165
+
166
+ /** 等待连接断开 */
167
+ export async function disconnected(socket: WebSocket): Promise<void> {
168
+ switch (socket.readyState) {
169
+ case socket.CONNECTING:
170
+ await connected(socket);
171
+ return await disconnected(socket);
172
+ case socket.OPEN:
173
+ case socket.CLOSING:
174
+ return new Promise((resolve, reject) => {
175
+ const onClose = (ev: CloseEvent): void => {
176
+ const code = ev.code as WEB_SOCKET_STATUS_CODES;
177
+ const reason = ev.reason || WEB_SOCKET_STATUS_CODES[code] || '';
178
+ if (code !== WEB_SOCKET_STATUS_CODES.NORMAL_CLOSURE) {
179
+ const error = new Error(reason);
180
+ (error as Error & { code: number }).code = code;
181
+ reject(error);
182
+ } else {
183
+ resolve();
184
+ }
185
+ cleanUp();
186
+ };
187
+ const onError = (ev: ErrorEvent | Event): void => {
188
+ const error = ((ev as ErrorEvent).error as Error) ?? new Error(`Connection error`);
189
+ reject(error);
190
+ cleanUp();
191
+ };
192
+ const cleanUp = (): void => {
193
+ socket.removeEventListener('close', onClose);
194
+ socket.removeEventListener('error', onError);
195
+ };
196
+ socket.addEventListener('close', onClose);
197
+ socket.addEventListener('error', onError);
198
+ });
199
+ case socket.CLOSED:
200
+ throw new Error(`Socket is closed.`);
201
+ default:
202
+ throw new Error(`Socket is in unknown state.`);
203
+ }
204
+ }
package/tsconfig.json CHANGED
@@ -2,6 +2,9 @@
2
2
  "extends": "../../tsconfig",
3
3
  "include": ["./src/"],
4
4
  "compilerOptions": {
5
- "outDir": "./dist"
5
+ "outDir": "./dist",
6
+ "paths": {
7
+ "#impl": ["./src/impl-node.ts", "./src/impl-browser.ts"]
8
+ }
6
9
  }
7
10
  }
@@ -1,18 +0,0 @@
1
- declare const _fetch: typeof fetch;
2
- declare const _Headers: {
3
- new (init?: HeadersInit | undefined): Headers;
4
- prototype: Headers;
5
- };
6
- declare const _Response: {
7
- new (body?: BodyInit | null | undefined, init?: ResponseInit | undefined): Response;
8
- prototype: Response;
9
- error(): Response;
10
- json(data: any, init?: ResponseInit | undefined): Response;
11
- redirect(url: string | URL, status?: number | undefined): Response;
12
- };
13
- declare const _Request: {
14
- new (input: RequestInfo | URL, init?: RequestInit | undefined): Request;
15
- prototype: Request;
16
- };
17
- export { _fetch as fetch, _Headers as Headers, _Response as Response, _Request as Request };
18
- export default fetch;
@@ -1,10 +0,0 @@
1
- if (typeof fetch != 'function') {
2
- throw new TypeError(`fetch is not defined on the global object, you should load polyfill of fetch.`);
3
- }
4
- const _fetch = fetch;
5
- const _Headers = Headers;
6
- const _Response = Response;
7
- const _Request = Request;
8
- export { _fetch as fetch, _Headers as Headers, _Response as Response, _Request as Request };
9
- export default fetch;
10
- //# sourceMappingURL=index-browser.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-browser.js","sourceRoot":"","sources":["../src/index-browser.ts"],"names":[],"mappings":"AAAA,IAAI,OAAO,KAAK,IAAI,UAAU,EAAE;IAC5B,MAAM,IAAI,SAAS,CAAC,+EAA+E,CAAC,CAAC;CACxG;AAED,MAAM,MAAM,GAAG,KAAK,CAAC;AACrB,MAAM,QAAQ,GAAG,OAAO,CAAC;AACzB,MAAM,SAAS,GAAG,QAAQ,CAAC;AAC3B,MAAM,QAAQ,GAAG,OAAO,CAAC;AACzB,OAAO,EAAE,MAAM,IAAI,KAAK,EAAE,QAAQ,IAAI,OAAO,EAAE,SAAS,IAAI,QAAQ,EAAE,QAAQ,IAAI,OAAO,EAAE,CAAC;AAE5F,eAAe,KAAK,CAAC"}
@@ -1,11 +0,0 @@
1
- if (typeof fetch != 'function') {
2
- throw new TypeError(`fetch is not defined on the global object, you should load polyfill of fetch.`);
3
- }
4
-
5
- const _fetch = fetch;
6
- const _Headers = Headers;
7
- const _Response = Response;
8
- const _Request = Request;
9
- export { _fetch as fetch, _Headers as Headers, _Response as Response, _Request as Request };
10
-
11
- export default fetch;