@whatwg-node/node-fetch 0.1.1-alpha-20230210102023-48114dc → 0.2.0-alpha-20230210093840-06aaaf0

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/Headers.d.ts CHANGED
@@ -1,13 +1,7 @@
1
1
  export type PonyfillHeadersInit = [string, string][] | Record<string, string | string[] | undefined> | Headers;
2
2
  export declare class PonyfillHeaders implements Headers {
3
- private headersInit?;
4
3
  private map;
5
- private mapIsBuilt;
6
- private objectNormalizedKeysOfHeadersInit;
7
- private objectOriginalKeysOfHeadersInit;
8
- constructor(headersInit?: PonyfillHeadersInit | undefined);
9
- private _get;
10
- private getMap;
4
+ constructor(headersInit?: PonyfillHeadersInit);
11
5
  append(name: string, value: string): void;
12
6
  get(name: string): string | null;
13
7
  has(name: string): boolean;
package/URL.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import FastUrl from "fast-url-parser";
2
+ import { PonyfillURLSearchParams } from "./URLSearchParams";
3
+ export declare class PonyfillURL extends FastUrl implements URL {
4
+ constructor(url: string, base?: string | URL);
5
+ get origin(): string;
6
+ private _searchParams?;
7
+ get searchParams(): PonyfillURLSearchParams;
8
+ get username(): string;
9
+ set username(value: string);
10
+ get password(): string;
11
+ set password(value: string);
12
+ toString(): string;
13
+ toJSON(): string;
14
+ }
@@ -0,0 +1,17 @@
1
+ export declare class PonyfillURLSearchParams implements URLSearchParams {
2
+ private params;
3
+ constructor(init?: string | string[][] | Record<string, string> | URLSearchParams);
4
+ append(name: string, value: string): void;
5
+ delete(name: string): void;
6
+ get(name: string): string | null;
7
+ getAll(name: string): string[];
8
+ has(name: string): boolean;
9
+ set(name: string, value: string): void;
10
+ sort(): void;
11
+ toString(): string;
12
+ keys(): IterableIterator<string>;
13
+ entries(): IterableIterator<[string, string]>;
14
+ values(): IterableIterator<string>;
15
+ [Symbol.iterator](): IterableIterator<[string, string]>;
16
+ forEach(callback: (value: string, key: string, parent: URLSearchParams) => void): void;
17
+ }
package/index.d.ts CHANGED
@@ -11,3 +11,5 @@ export { PonyfillAbortSignal as AbortSignal } from './AbortSignal';
11
11
  export { PonyfillAbortError as AbortError } from './AbortError';
12
12
  export { PonyfillBlob as Blob } from './Blob';
13
13
  export { PonyfillTextEncoder as TextEncoder, PonyfillTextDecoder as TextDecoder, PonyfillBtoa as btoa, } from './TextEncoderDecoder';
14
+ export { PonyfillURL as URL } from './URL';
15
+ export { PonyfillURLSearchParams as URLSearchParams } from './URLSearchParams';
package/index.js CHANGED
@@ -11,6 +11,8 @@ const stream = require('stream');
11
11
  const url = require('url');
12
12
  const events = require('@whatwg-node/events');
13
13
  const busboy = _interopDefault(require('busboy'));
14
+ const FastUrl = _interopDefault(require('fast-url-parser'));
15
+ const FastQuerystring = _interopDefault(require('fast-querystring'));
14
16
 
15
17
  // Will be removed after v14 reaches EOL
16
18
  class PonyfillAbortError extends Error {
@@ -797,7 +799,7 @@ function processBodyInit(bodyInit) {
797
799
  },
798
800
  };
799
801
  }
800
- if (bodyInit instanceof URLSearchParams) {
802
+ if ('sort' in bodyInit) {
801
803
  const contentType = 'application/x-www-form-urlencoded;charset=UTF-8';
802
804
  return {
803
805
  bodyType: BodyInitType.String,
@@ -838,66 +840,19 @@ function isHeadersLike(headers) {
838
840
  }
839
841
  class PonyfillHeaders {
840
842
  constructor(headersInit) {
841
- this.headersInit = headersInit;
842
843
  this.map = new Map();
843
- this.mapIsBuilt = false;
844
- this.objectNormalizedKeysOfHeadersInit = [];
845
- this.objectOriginalKeysOfHeadersInit = [];
846
- }
847
- // perf: we don't need to build `this.map` for Requests, as we can access the headers directly
848
- _get(key) {
849
- // If the map is built, reuse it
850
- if (this.mapIsBuilt) {
851
- return this.map.get(key.toLowerCase()) || null;
852
- }
853
- // If the map is not built, try to get the value from the this.headersInit
854
- if (this.headersInit == null) {
855
- return null;
856
- }
857
- const normalized = key.toLowerCase();
858
- if (Array.isArray(this.headersInit)) {
859
- return this.headersInit.find(header => header[0] === normalized);
860
- }
861
- else if (isHeadersLike(this.headersInit)) {
862
- return this.headersInit.get(normalized);
863
- }
864
- else {
865
- const initValue = this.headersInit[key] || this.headersInit[normalized];
866
- if (initValue != null) {
867
- return initValue;
868
- }
869
- if (!this.objectNormalizedKeysOfHeadersInit.length) {
870
- Object.keys(this.headersInit).forEach(k => {
871
- this.objectOriginalKeysOfHeadersInit.push(k);
872
- this.objectNormalizedKeysOfHeadersInit.push(k.toLowerCase());
873
- });
874
- }
875
- const index = this.objectNormalizedKeysOfHeadersInit.indexOf(normalized);
876
- if (index === -1) {
877
- return null;
878
- }
879
- const originalKey = this.objectOriginalKeysOfHeadersInit[index];
880
- return this.headersInit[originalKey];
881
- }
882
- }
883
- // perf: Build the map of headers lazily, only when we need to access all headers or write to it.
884
- // I could do a getter here, but I'm too lazy to type `getter`.
885
- getMap() {
886
- if (this.mapIsBuilt) {
887
- return this.map;
888
- }
889
- if (this.headersInit != null) {
890
- if (Array.isArray(this.headersInit)) {
891
- this.map = new Map(this.headersInit);
844
+ if (headersInit != null) {
845
+ if (Array.isArray(headersInit)) {
846
+ this.map = new Map(headersInit);
892
847
  }
893
- else if (isHeadersLike(this.headersInit)) {
894
- this.headersInit.forEach((value, key) => {
848
+ else if (isHeadersLike(headersInit)) {
849
+ headersInit.forEach((value, key) => {
895
850
  this.map.set(key, value);
896
851
  });
897
852
  }
898
853
  else {
899
- for (const initKey in this.headersInit) {
900
- const initValue = this.headersInit[initKey];
854
+ for (const initKey in headersInit) {
855
+ const initValue = headersInit[initKey];
901
856
  if (initValue != null) {
902
857
  const normalizedValue = Array.isArray(initValue) ? initValue.join(', ') : initValue;
903
858
  const normalizedKey = initKey.toLowerCase();
@@ -906,48 +861,39 @@ class PonyfillHeaders {
906
861
  }
907
862
  }
908
863
  }
909
- this.mapIsBuilt = true;
910
- return this.map;
911
864
  }
912
865
  append(name, value) {
913
866
  const key = name.toLowerCase();
914
- const existingValue = this.getMap().get(key);
867
+ const existingValue = this.map.get(key);
915
868
  const finalValue = existingValue ? `${existingValue}, ${value}` : value;
916
- this.getMap().set(key, finalValue);
869
+ this.map.set(key, finalValue);
917
870
  }
918
871
  get(name) {
919
872
  const key = name.toLowerCase();
920
- const value = this._get(key);
921
- if (value == null) {
922
- return null;
923
- }
924
- if (Array.isArray(value)) {
925
- return value.join(', ');
926
- }
927
- return value;
873
+ return this.map.get(key) || null;
928
874
  }
929
875
  has(name) {
930
876
  const key = name.toLowerCase();
931
- return !!this._get(key); // we might need to check if header exists and not just check if it's not nullable
877
+ return this.map.has(key);
932
878
  }
933
879
  set(name, value) {
934
880
  const key = name.toLowerCase();
935
- this.getMap().set(key, value);
881
+ this.map.set(key, value);
936
882
  }
937
883
  delete(name) {
938
884
  const key = name.toLowerCase();
939
- this.getMap().delete(key);
885
+ this.map.delete(key);
940
886
  }
941
887
  forEach(callback) {
942
- this.getMap().forEach((value, key) => {
888
+ this.map.forEach((value, key) => {
943
889
  callback(value, key, this);
944
890
  });
945
891
  }
946
892
  entries() {
947
- return this.getMap().entries();
893
+ return this.map.entries();
948
894
  }
949
895
  [Symbol.iterator]() {
950
- return this.getMap().entries();
896
+ return this.map.entries();
951
897
  }
952
898
  }
953
899
 
@@ -963,7 +909,7 @@ class PonyfillRequest extends PonyfillBody {
963
909
  if (typeof input === 'string') {
964
910
  url = input;
965
911
  }
966
- else if (input instanceof URL) {
912
+ else if ('href' in input) {
967
913
  url = input.toString();
968
914
  }
969
915
  else if (isRequest(input)) {
@@ -1084,6 +1030,150 @@ class PonyfillResponse extends PonyfillBody {
1084
1030
  }
1085
1031
  }
1086
1032
 
1033
+ class PonyfillURLSearchParams {
1034
+ constructor(init) {
1035
+ if (init) {
1036
+ if (typeof init === 'string') {
1037
+ this.params = FastQuerystring.parse(init);
1038
+ }
1039
+ else if (Array.isArray(init)) {
1040
+ this.params = {};
1041
+ for (const [key, value] of init) {
1042
+ this.params[key] = value;
1043
+ }
1044
+ }
1045
+ else if ('entries' in init) {
1046
+ this.params = {};
1047
+ for (const [key, value] of init.entries()) {
1048
+ this.params[key] = value;
1049
+ }
1050
+ }
1051
+ else {
1052
+ this.params = init;
1053
+ }
1054
+ }
1055
+ else {
1056
+ this.params = {};
1057
+ }
1058
+ }
1059
+ append(name, value) {
1060
+ const existingValue = this.params[name];
1061
+ const finalValue = existingValue ? `${existingValue},${value}` : value;
1062
+ this.params[name] = finalValue;
1063
+ }
1064
+ delete(name) {
1065
+ delete this.params[name];
1066
+ }
1067
+ get(name) {
1068
+ const value = this.params[name];
1069
+ if (Array.isArray(value)) {
1070
+ return value[0] || null;
1071
+ }
1072
+ return value || null;
1073
+ }
1074
+ getAll(name) {
1075
+ const value = this.params[name];
1076
+ if (!Array.isArray(value)) {
1077
+ return value ? [value] : [];
1078
+ }
1079
+ return value;
1080
+ }
1081
+ has(name) {
1082
+ return name in this.params;
1083
+ }
1084
+ set(name, value) {
1085
+ this.params[name] = value;
1086
+ }
1087
+ sort() {
1088
+ const sortedKeys = Object.keys(this.params).sort();
1089
+ const sortedParams = {};
1090
+ for (const key of sortedKeys) {
1091
+ sortedParams[key] = this.params[key];
1092
+ }
1093
+ this.params = sortedParams;
1094
+ }
1095
+ toString() {
1096
+ return FastQuerystring.stringify(this.params);
1097
+ }
1098
+ *keys() {
1099
+ for (const key in this.params) {
1100
+ yield key;
1101
+ }
1102
+ }
1103
+ *entries() {
1104
+ for (const key in this.keys()) {
1105
+ const value = this.params[key];
1106
+ if (Array.isArray(value)) {
1107
+ for (const item of value) {
1108
+ yield [key, item];
1109
+ }
1110
+ }
1111
+ yield [key, value];
1112
+ }
1113
+ }
1114
+ *values() {
1115
+ for (const [, value] of this) {
1116
+ yield value;
1117
+ }
1118
+ }
1119
+ [Symbol.iterator]() {
1120
+ return this.entries();
1121
+ }
1122
+ forEach(callback) {
1123
+ for (const [key, value] of this) {
1124
+ callback(value, key, this);
1125
+ }
1126
+ }
1127
+ }
1128
+
1129
+ FastUrl.queryString = FastQuerystring;
1130
+ class PonyfillURL extends FastUrl {
1131
+ constructor(url, base) {
1132
+ super();
1133
+ if (url.startsWith('data:')) {
1134
+ this.protocol = 'data:';
1135
+ this.pathname = url.slice('data:'.length);
1136
+ return;
1137
+ }
1138
+ this.parse(url, false);
1139
+ if (base) {
1140
+ const baseParsed = typeof base === 'string' ? new PonyfillURL(base) : base;
1141
+ this.protocol = this.protocol || baseParsed.protocol;
1142
+ this.host = this.host || baseParsed.host;
1143
+ this.pathname = this.pathname || baseParsed.pathname;
1144
+ }
1145
+ }
1146
+ get origin() {
1147
+ return `${this.protocol}//${this.host}`;
1148
+ }
1149
+ get searchParams() {
1150
+ if (!this._searchParams) {
1151
+ this._searchParams = new PonyfillURLSearchParams(this.query);
1152
+ }
1153
+ return this._searchParams;
1154
+ }
1155
+ get username() {
1156
+ var _a;
1157
+ return ((_a = this.auth) === null || _a === void 0 ? void 0 : _a.split(':')[0]) || '';
1158
+ }
1159
+ set username(value) {
1160
+ this.auth = `${value}:${this.password}`;
1161
+ }
1162
+ get password() {
1163
+ var _a;
1164
+ return ((_a = this.auth) === null || _a === void 0 ? void 0 : _a.split(':')[1]) || '';
1165
+ }
1166
+ set password(value) {
1167
+ this.auth = `${this.username}:${value}`;
1168
+ }
1169
+ toString() {
1170
+ return this.format();
1171
+ }
1172
+ toJSON() {
1173
+ return this.toString();
1174
+ }
1175
+ }
1176
+
1087
1177
  function getResponseForFile(url$1) {
1088
1178
  const path = url.fileURLToPath(url$1);
1089
1179
  const readable = fs.createReadStream(path);
@@ -1100,14 +1190,14 @@ function getRequestFnForProtocol(protocol) {
1100
1190
  }
1101
1191
  const BASE64_SUFFIX = ';base64';
1102
1192
  function fetchPonyfill(info, init) {
1103
- if (typeof info === 'string' || info instanceof URL) {
1193
+ if (typeof info === 'string' || 'href' in info) {
1104
1194
  const ponyfillRequest = new PonyfillRequest(info, init);
1105
1195
  return fetchPonyfill(ponyfillRequest);
1106
1196
  }
1107
1197
  const fetchRequest = info;
1108
1198
  return new Promise((resolve, reject) => {
1109
1199
  try {
1110
- const url = new URL(fetchRequest.url, 'http://localhost');
1200
+ const url = new PonyfillURL(fetchRequest.url, 'http://localhost');
1111
1201
  if (url.protocol === 'data:') {
1112
1202
  const [mimeType = 'text/plain', ...datas] = url.pathname.split(',');
1113
1203
  const data = decodeURIComponent(datas.join(','));
@@ -1133,7 +1223,7 @@ function fetchPonyfill(info, init) {
1133
1223
  return;
1134
1224
  }
1135
1225
  if (url.protocol === 'file:') {
1136
- const response = getResponseForFile(url);
1226
+ const response = getResponseForFile(fetchRequest.url);
1137
1227
  resolve(response);
1138
1228
  return;
1139
1229
  }
@@ -1150,7 +1240,7 @@ function fetchPonyfill(info, init) {
1150
1240
  reject(new PonyfillAbortError(reason));
1151
1241
  };
1152
1242
  fetchRequest.signal.addEventListener('abort', abortListener);
1153
- const nodeRequest = requestFn(url, {
1243
+ const nodeRequest = requestFn(fetchRequest.url, {
1154
1244
  // signal: fetchRequest.signal will be added when v14 reaches EOL
1155
1245
  method: fetchRequest.method,
1156
1246
  headers: nodeHeaders,
@@ -1164,7 +1254,7 @@ function fetchPonyfill(info, init) {
1164
1254
  return;
1165
1255
  }
1166
1256
  if (fetchRequest.redirect === 'follow') {
1167
- const redirectedUrl = new URL(nodeResponse.headers.location, url);
1257
+ const redirectedUrl = new PonyfillURL(nodeResponse.headers.location, url);
1168
1258
  const redirectResponse$ = fetchPonyfill(redirectedUrl, info);
1169
1259
  resolve(redirectResponse$.then(redirectResponse => {
1170
1260
  redirectResponse.redirected = true;
@@ -1244,5 +1334,7 @@ exports.Request = PonyfillRequest;
1244
1334
  exports.Response = PonyfillResponse;
1245
1335
  exports.TextDecoder = PonyfillTextDecoder;
1246
1336
  exports.TextEncoder = PonyfillTextEncoder;
1337
+ exports.URL = PonyfillURL;
1338
+ exports.URLSearchParams = PonyfillURLSearchParams;
1247
1339
  exports.btoa = PonyfillBtoa;
1248
1340
  exports.fetch = fetchPonyfill;
package/index.mjs CHANGED
@@ -5,6 +5,8 @@ import { Readable } from 'stream';
5
5
  import { fileURLToPath } from 'url';
6
6
  import { EventTarget, CustomEvent } from '@whatwg-node/events';
7
7
  import busboy from 'busboy';
8
+ import FastUrl from 'fast-url-parser';
9
+ import FastQuerystring from 'fast-querystring';
8
10
 
9
11
  // Will be removed after v14 reaches EOL
10
12
  class PonyfillAbortError extends Error {
@@ -791,7 +793,7 @@ function processBodyInit(bodyInit) {
791
793
  },
792
794
  };
793
795
  }
794
- if (bodyInit instanceof URLSearchParams) {
796
+ if ('sort' in bodyInit) {
795
797
  const contentType = 'application/x-www-form-urlencoded;charset=UTF-8';
796
798
  return {
797
799
  bodyType: BodyInitType.String,
@@ -832,66 +834,19 @@ function isHeadersLike(headers) {
832
834
  }
833
835
  class PonyfillHeaders {
834
836
  constructor(headersInit) {
835
- this.headersInit = headersInit;
836
837
  this.map = new Map();
837
- this.mapIsBuilt = false;
838
- this.objectNormalizedKeysOfHeadersInit = [];
839
- this.objectOriginalKeysOfHeadersInit = [];
840
- }
841
- // perf: we don't need to build `this.map` for Requests, as we can access the headers directly
842
- _get(key) {
843
- // If the map is built, reuse it
844
- if (this.mapIsBuilt) {
845
- return this.map.get(key.toLowerCase()) || null;
846
- }
847
- // If the map is not built, try to get the value from the this.headersInit
848
- if (this.headersInit == null) {
849
- return null;
850
- }
851
- const normalized = key.toLowerCase();
852
- if (Array.isArray(this.headersInit)) {
853
- return this.headersInit.find(header => header[0] === normalized);
854
- }
855
- else if (isHeadersLike(this.headersInit)) {
856
- return this.headersInit.get(normalized);
857
- }
858
- else {
859
- const initValue = this.headersInit[key] || this.headersInit[normalized];
860
- if (initValue != null) {
861
- return initValue;
862
- }
863
- if (!this.objectNormalizedKeysOfHeadersInit.length) {
864
- Object.keys(this.headersInit).forEach(k => {
865
- this.objectOriginalKeysOfHeadersInit.push(k);
866
- this.objectNormalizedKeysOfHeadersInit.push(k.toLowerCase());
867
- });
868
- }
869
- const index = this.objectNormalizedKeysOfHeadersInit.indexOf(normalized);
870
- if (index === -1) {
871
- return null;
872
- }
873
- const originalKey = this.objectOriginalKeysOfHeadersInit[index];
874
- return this.headersInit[originalKey];
875
- }
876
- }
877
- // perf: Build the map of headers lazily, only when we need to access all headers or write to it.
878
- // I could do a getter here, but I'm too lazy to type `getter`.
879
- getMap() {
880
- if (this.mapIsBuilt) {
881
- return this.map;
882
- }
883
- if (this.headersInit != null) {
884
- if (Array.isArray(this.headersInit)) {
885
- this.map = new Map(this.headersInit);
838
+ if (headersInit != null) {
839
+ if (Array.isArray(headersInit)) {
840
+ this.map = new Map(headersInit);
886
841
  }
887
- else if (isHeadersLike(this.headersInit)) {
888
- this.headersInit.forEach((value, key) => {
842
+ else if (isHeadersLike(headersInit)) {
843
+ headersInit.forEach((value, key) => {
889
844
  this.map.set(key, value);
890
845
  });
891
846
  }
892
847
  else {
893
- for (const initKey in this.headersInit) {
894
- const initValue = this.headersInit[initKey];
848
+ for (const initKey in headersInit) {
849
+ const initValue = headersInit[initKey];
895
850
  if (initValue != null) {
896
851
  const normalizedValue = Array.isArray(initValue) ? initValue.join(', ') : initValue;
897
852
  const normalizedKey = initKey.toLowerCase();
@@ -900,48 +855,39 @@ class PonyfillHeaders {
900
855
  }
901
856
  }
902
857
  }
903
- this.mapIsBuilt = true;
904
- return this.map;
905
858
  }
906
859
  append(name, value) {
907
860
  const key = name.toLowerCase();
908
- const existingValue = this.getMap().get(key);
861
+ const existingValue = this.map.get(key);
909
862
  const finalValue = existingValue ? `${existingValue}, ${value}` : value;
910
- this.getMap().set(key, finalValue);
863
+ this.map.set(key, finalValue);
911
864
  }
912
865
  get(name) {
913
866
  const key = name.toLowerCase();
914
- const value = this._get(key);
915
- if (value == null) {
916
- return null;
917
- }
918
- if (Array.isArray(value)) {
919
- return value.join(', ');
920
- }
921
- return value;
867
+ return this.map.get(key) || null;
922
868
  }
923
869
  has(name) {
924
870
  const key = name.toLowerCase();
925
- return !!this._get(key); // we might need to check if header exists and not just check if it's not nullable
871
+ return this.map.has(key);
926
872
  }
927
873
  set(name, value) {
928
874
  const key = name.toLowerCase();
929
- this.getMap().set(key, value);
875
+ this.map.set(key, value);
930
876
  }
931
877
  delete(name) {
932
878
  const key = name.toLowerCase();
933
- this.getMap().delete(key);
879
+ this.map.delete(key);
934
880
  }
935
881
  forEach(callback) {
936
- this.getMap().forEach((value, key) => {
882
+ this.map.forEach((value, key) => {
937
883
  callback(value, key, this);
938
884
  });
939
885
  }
940
886
  entries() {
941
- return this.getMap().entries();
887
+ return this.map.entries();
942
888
  }
943
889
  [Symbol.iterator]() {
944
- return this.getMap().entries();
890
+ return this.map.entries();
945
891
  }
946
892
  }
947
893
 
@@ -957,7 +903,7 @@ class PonyfillRequest extends PonyfillBody {
957
903
  if (typeof input === 'string') {
958
904
  url = input;
959
905
  }
960
- else if (input instanceof URL) {
906
+ else if ('href' in input) {
961
907
  url = input.toString();
962
908
  }
963
909
  else if (isRequest(input)) {
@@ -1078,6 +1024,150 @@ class PonyfillResponse extends PonyfillBody {
1078
1024
  }
1079
1025
  }
1080
1026
 
1027
+ class PonyfillURLSearchParams {
1028
+ constructor(init) {
1029
+ if (init) {
1030
+ if (typeof init === 'string') {
1031
+ this.params = FastQuerystring.parse(init);
1032
+ }
1033
+ else if (Array.isArray(init)) {
1034
+ this.params = {};
1035
+ for (const [key, value] of init) {
1036
+ this.params[key] = value;
1037
+ }
1038
+ }
1039
+ else if ('entries' in init) {
1040
+ this.params = {};
1041
+ for (const [key, value] of init.entries()) {
1042
+ this.params[key] = value;
1043
+ }
1044
+ }
1045
+ else {
1046
+ this.params = init;
1047
+ }
1048
+ }
1049
+ else {
1050
+ this.params = {};
1051
+ }
1052
+ }
1053
+ append(name, value) {
1054
+ const existingValue = this.params[name];
1055
+ const finalValue = existingValue ? `${existingValue},${value}` : value;
1056
+ this.params[name] = finalValue;
1057
+ }
1058
+ delete(name) {
1059
+ delete this.params[name];
1060
+ }
1061
+ get(name) {
1062
+ const value = this.params[name];
1063
+ if (Array.isArray(value)) {
1064
+ return value[0] || null;
1065
+ }
1066
+ return value || null;
1067
+ }
1068
+ getAll(name) {
1069
+ const value = this.params[name];
1070
+ if (!Array.isArray(value)) {
1071
+ return value ? [value] : [];
1072
+ }
1073
+ return value;
1074
+ }
1075
+ has(name) {
1076
+ return name in this.params;
1077
+ }
1078
+ set(name, value) {
1079
+ this.params[name] = value;
1080
+ }
1081
+ sort() {
1082
+ const sortedKeys = Object.keys(this.params).sort();
1083
+ const sortedParams = {};
1084
+ for (const key of sortedKeys) {
1085
+ sortedParams[key] = this.params[key];
1086
+ }
1087
+ this.params = sortedParams;
1088
+ }
1089
+ toString() {
1090
+ return FastQuerystring.stringify(this.params);
1091
+ }
1092
+ *keys() {
1093
+ for (const key in this.params) {
1094
+ yield key;
1095
+ }
1096
+ }
1097
+ *entries() {
1098
+ for (const key in this.keys()) {
1099
+ const value = this.params[key];
1100
+ if (Array.isArray(value)) {
1101
+ for (const item of value) {
1102
+ yield [key, item];
1103
+ }
1104
+ }
1105
+ yield [key, value];
1106
+ }
1107
+ }
1108
+ *values() {
1109
+ for (const [, value] of this) {
1110
+ yield value;
1111
+ }
1112
+ }
1113
+ [Symbol.iterator]() {
1114
+ return this.entries();
1115
+ }
1116
+ forEach(callback) {
1117
+ for (const [key, value] of this) {
1118
+ callback(value, key, this);
1119
+ }
1120
+ }
1121
+ }
1122
+
1123
+ FastUrl.queryString = FastQuerystring;
1124
+ class PonyfillURL extends FastUrl {
1125
+ constructor(url, base) {
1126
+ super();
1127
+ if (url.startsWith('data:')) {
1128
+ this.protocol = 'data:';
1129
+ this.pathname = url.slice('data:'.length);
1130
+ return;
1131
+ }
1132
+ this.parse(url, false);
1133
+ if (base) {
1134
+ const baseParsed = typeof base === 'string' ? new PonyfillURL(base) : base;
1135
+ this.protocol = this.protocol || baseParsed.protocol;
1136
+ this.host = this.host || baseParsed.host;
1137
+ this.pathname = this.pathname || baseParsed.pathname;
1138
+ }
1139
+ }
1140
+ get origin() {
1141
+ return `${this.protocol}//${this.host}`;
1142
+ }
1143
+ get searchParams() {
1144
+ if (!this._searchParams) {
1145
+ this._searchParams = new PonyfillURLSearchParams(this.query);
1146
+ }
1147
+ return this._searchParams;
1148
+ }
1149
+ get username() {
1150
+ var _a;
1151
+ return ((_a = this.auth) === null || _a === void 0 ? void 0 : _a.split(':')[0]) || '';
1152
+ }
1153
+ set username(value) {
1154
+ this.auth = `${value}:${this.password}`;
1155
+ }
1156
+ get password() {
1157
+ var _a;
1158
+ return ((_a = this.auth) === null || _a === void 0 ? void 0 : _a.split(':')[1]) || '';
1159
+ }
1160
+ set password(value) {
1161
+ this.auth = `${this.username}:${value}`;
1162
+ }
1163
+ toString() {
1164
+ return this.format();
1165
+ }
1166
+ toJSON() {
1167
+ return this.toString();
1168
+ }
1169
+ }
1170
+
1081
1171
  function getResponseForFile(url) {
1082
1172
  const path = fileURLToPath(url);
1083
1173
  const readable = createReadStream(path);
@@ -1094,14 +1184,14 @@ function getRequestFnForProtocol(protocol) {
1094
1184
  }
1095
1185
  const BASE64_SUFFIX = ';base64';
1096
1186
  function fetchPonyfill(info, init) {
1097
- if (typeof info === 'string' || info instanceof URL) {
1187
+ if (typeof info === 'string' || 'href' in info) {
1098
1188
  const ponyfillRequest = new PonyfillRequest(info, init);
1099
1189
  return fetchPonyfill(ponyfillRequest);
1100
1190
  }
1101
1191
  const fetchRequest = info;
1102
1192
  return new Promise((resolve, reject) => {
1103
1193
  try {
1104
- const url = new URL(fetchRequest.url, 'http://localhost');
1194
+ const url = new PonyfillURL(fetchRequest.url, 'http://localhost');
1105
1195
  if (url.protocol === 'data:') {
1106
1196
  const [mimeType = 'text/plain', ...datas] = url.pathname.split(',');
1107
1197
  const data = decodeURIComponent(datas.join(','));
@@ -1127,7 +1217,7 @@ function fetchPonyfill(info, init) {
1127
1217
  return;
1128
1218
  }
1129
1219
  if (url.protocol === 'file:') {
1130
- const response = getResponseForFile(url);
1220
+ const response = getResponseForFile(fetchRequest.url);
1131
1221
  resolve(response);
1132
1222
  return;
1133
1223
  }
@@ -1144,7 +1234,7 @@ function fetchPonyfill(info, init) {
1144
1234
  reject(new PonyfillAbortError(reason));
1145
1235
  };
1146
1236
  fetchRequest.signal.addEventListener('abort', abortListener);
1147
- const nodeRequest = requestFn(url, {
1237
+ const nodeRequest = requestFn(fetchRequest.url, {
1148
1238
  // signal: fetchRequest.signal will be added when v14 reaches EOL
1149
1239
  method: fetchRequest.method,
1150
1240
  headers: nodeHeaders,
@@ -1158,7 +1248,7 @@ function fetchPonyfill(info, init) {
1158
1248
  return;
1159
1249
  }
1160
1250
  if (fetchRequest.redirect === 'follow') {
1161
- const redirectedUrl = new URL(nodeResponse.headers.location, url);
1251
+ const redirectedUrl = new PonyfillURL(nodeResponse.headers.location, url);
1162
1252
  const redirectResponse$ = fetchPonyfill(redirectedUrl, info);
1163
1253
  resolve(redirectResponse$.then(redirectResponse => {
1164
1254
  redirectResponse.redirected = true;
@@ -1225,4 +1315,4 @@ function PonyfillBtoa(input) {
1225
1315
  return Buffer.from(input, 'binary').toString('base64');
1226
1316
  }
1227
1317
 
1228
- export { PonyfillAbortController as AbortController, PonyfillAbortError as AbortError, PonyfillAbortSignal as AbortSignal, PonyfillBlob as Blob, PonyfillBody as Body, PonyfillFile as File, PonyfillFormData as FormData, PonyfillHeaders as Headers, PonyfillReadableStream as ReadableStream, PonyfillRequest as Request, PonyfillResponse as Response, PonyfillTextDecoder as TextDecoder, PonyfillTextEncoder as TextEncoder, PonyfillBtoa as btoa, fetchPonyfill as fetch };
1318
+ export { PonyfillAbortController as AbortController, PonyfillAbortError as AbortError, PonyfillAbortSignal as AbortSignal, PonyfillBlob as Blob, PonyfillBody as Body, PonyfillFile as File, PonyfillFormData as FormData, PonyfillHeaders as Headers, PonyfillReadableStream as ReadableStream, PonyfillRequest as Request, PonyfillResponse as Response, PonyfillTextDecoder as TextDecoder, PonyfillTextEncoder as TextEncoder, PonyfillURL as URL, PonyfillURLSearchParams as URLSearchParams, PonyfillBtoa as btoa, fetchPonyfill as fetch };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whatwg-node/node-fetch",
3
- "version": "0.1.1-alpha-20230210102023-48114dc",
3
+ "version": "0.2.0-alpha-20230210093840-06aaaf0",
4
4
  "description": "Fetch API implementation for Node",
5
5
  "sideEffects": false,
6
6
  "peerDependencies": {
@@ -9,6 +9,8 @@
9
9
  "dependencies": {
10
10
  "@whatwg-node/events": "^0.0.2",
11
11
  "busboy": "^1.6.0",
12
+ "fast-querystring": "^1.1.1",
13
+ "fast-url-parser": "^1.1.3",
12
14
  "tslib": "^2.3.1"
13
15
  },
14
16
  "repository": {