where-is-ip 0.1.0 → 0.2.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.
package/README.md CHANGED
@@ -49,7 +49,7 @@ Import the ESM bundle from jsDelivr.
49
49
  ```ts
50
50
  export interface GeoIpResult {
51
51
  ip: string;
52
- countryCode: string | null;
52
+ countryCode: string;
53
53
  countryName: string | null;
54
54
  region: string | null;
55
55
  city: string | null;
@@ -71,6 +71,5 @@ Providers are tried in table order with a 2-second timeout per attempt.
71
71
  | [IP2Location.io](https://www.ip2location.io/) | `ip2location` | ✓ | ✓ | — |
72
72
  | [IP Info](https://ip-info.com/) | `ip-info` | ✓ | ✓ | ✓ |
73
73
  | [IPinfo](https://ipinfo.io/) | `ipinfo` | ✓ | ✓ | ✓ |
74
- | [ipapi.is](https://ipapi.is/) | `ipapi-is` | ✓ | ✓ | ✓ |
75
74
  | [Country.is](https://country.is/) | `country-is` | ✓ | ✓ | ✓ |
76
75
  | [Cloudflare Trace](https://www.cloudflare.com/) | `cloudflare` | — | ✓ | ✓ |
package/dist/index.cjs CHANGED
@@ -179,24 +179,6 @@ var ip2location = withSelfLookup({
179
179
  }
180
180
  });
181
181
 
182
- // src/providers/ipapi-is.ts
183
- var ipapiIs = withSelfLookup({
184
- name: "ipapi-is",
185
- async lookup(ip) {
186
- const url = ip ? `https://api.ipapi.is/?q=${encodeURIComponent(ip)}` : "https://api.ipapi.is/";
187
- const data = await fetchJson(url);
188
- if (data.is_bogon === true) throw new Error("IP address is not publicly routable");
189
- return normalizeLocation({
190
- ip: data.ip,
191
- countryName: data.country,
192
- region: data.region,
193
- city: data.city,
194
- latitude: data.lat,
195
- longitude: data.lon
196
- });
197
- }
198
- });
199
-
200
182
  // src/providers/ipinfo.ts
201
183
  var ipinfo = withSelfLookup({
202
184
  name: "ipinfo",
@@ -240,7 +222,6 @@ var providers = [
240
222
  ip2location,
241
223
  ipInfo,
242
224
  ipinfo,
243
- ipapiIs,
244
225
  countryIs,
245
226
  cloudflare
246
227
  ];
@@ -258,11 +239,12 @@ async function lookup(ip) {
258
239
  try {
259
240
  const attempt = address === void 0 ? provider.lookupSelf?.() : provider.lookup?.(address);
260
241
  if (!attempt) continue;
261
- const { ip: detectedIp, ...location } = await attempt;
262
- if (!location.countryCode && !location.countryName) {
263
- throw new Error("Response did not include a country");
242
+ const { ip: detectedIp, countryCode, ...location } = await attempt;
243
+ if (!countryCode) {
244
+ errors.push(new Error(`${provider.name} response did not include a country code`));
245
+ continue;
264
246
  }
265
- return { ip: address ?? normalizeIp(detectedIp), ...location, provider: provider.name };
247
+ return { ip: address ?? normalizeIp(detectedIp), countryCode, ...location, provider: provider.name };
266
248
  } catch (cause) {
267
249
  errors.push(new Error(`${provider.name} lookup failed`, { cause }));
268
250
  }
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  export interface GeoIpResult {
2
2
  ip: string;
3
- countryCode: string | null;
3
+ countryCode: string;
4
4
  countryName: string | null;
5
5
  region: string | null;
6
6
  city: string | null;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export interface GeoIpResult {
2
2
  ip: string;
3
- countryCode: string | null;
3
+ countryCode: string;
4
4
  countryName: string | null;
5
5
  region: string | null;
6
6
  city: string | null;
package/dist/index.js CHANGED
@@ -153,24 +153,6 @@ var ip2location = withSelfLookup({
153
153
  }
154
154
  });
155
155
 
156
- // src/providers/ipapi-is.ts
157
- var ipapiIs = withSelfLookup({
158
- name: "ipapi-is",
159
- async lookup(ip) {
160
- const url = ip ? `https://api.ipapi.is/?q=${encodeURIComponent(ip)}` : "https://api.ipapi.is/";
161
- const data = await fetchJson(url);
162
- if (data.is_bogon === true) throw new Error("IP address is not publicly routable");
163
- return normalizeLocation({
164
- ip: data.ip,
165
- countryName: data.country,
166
- region: data.region,
167
- city: data.city,
168
- latitude: data.lat,
169
- longitude: data.lon
170
- });
171
- }
172
- });
173
-
174
156
  // src/providers/ipinfo.ts
175
157
  var ipinfo = withSelfLookup({
176
158
  name: "ipinfo",
@@ -214,7 +196,6 @@ var providers = [
214
196
  ip2location,
215
197
  ipInfo,
216
198
  ipinfo,
217
- ipapiIs,
218
199
  countryIs,
219
200
  cloudflare
220
201
  ];
@@ -232,11 +213,12 @@ async function lookup(ip) {
232
213
  try {
233
214
  const attempt = address === void 0 ? provider.lookupSelf?.() : provider.lookup?.(address);
234
215
  if (!attempt) continue;
235
- const { ip: detectedIp, ...location } = await attempt;
236
- if (!location.countryCode && !location.countryName) {
237
- throw new Error("Response did not include a country");
216
+ const { ip: detectedIp, countryCode, ...location } = await attempt;
217
+ if (!countryCode) {
218
+ errors.push(new Error(`${provider.name} response did not include a country code`));
219
+ continue;
238
220
  }
239
- return { ip: address ?? normalizeIp(detectedIp), ...location, provider: provider.name };
221
+ return { ip: address ?? normalizeIp(detectedIp), countryCode, ...location, provider: provider.name };
240
222
  } catch (cause) {
241
223
  errors.push(new Error(`${provider.name} lookup failed`, { cause }));
242
224
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "where-is-ip",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Look up IP locations with native fetch and automatic fallback between keyless providers.",
5
5
  "license": "MIT",
6
6
  "repository": {