vpndetection 5.1.0 → 5.2.1

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
@@ -62,7 +62,7 @@ Usage counts against the anniversary of your subscription, not the calendar mont
62
62
 
63
63
  ### Batch lookup
64
64
 
65
- Look up many addresses at once. Bogons and cached answers are handled locally, and everything else goes to the batch endpoint in chunks of up to 1000 addresses, in parallel:
65
+ Look up as many addresses as you like in one call. Bogons and cached answers are handled locally, and the rest go to the batch endpoint in chunks of up to 1000, in parallel:
66
66
 
67
67
  ```js
68
68
  const results = await client.lookupBatch(['45.83.91.1', '8.8.8.8', '1.1.1.1']);
@@ -78,10 +78,10 @@ for (const [ip, result] of results) {
78
78
 
79
79
  Results are keyed by address, in the order you first listed each one, so duplicates in your list collapse into a single entry and one address failing never loses the rest: it carries its error as its value, with the status the API would have given that address on its own.
80
80
 
81
- How many chunks are in flight at once, and how many times a failed chunk is retried, are configurable per call:
81
+ How many chunks are in flight at once, how many times a failed chunk is retried, and how long each request may take are configurable per call:
82
82
 
83
83
  ```js
84
- const results = await client.lookupBatch(manyIps, { concurrency: 4, retries: 4 });
84
+ const results = await client.lookupBatch(manyIps, { concurrency: 4, retries: 4, timeoutMs: 10_000 });
85
85
  ```
86
86
 
87
87
  ### Caching
@@ -150,6 +150,18 @@ try {
150
150
 
151
151
  Note that `rate_limited` and `quota_exceeded` both arrive as HTTP 429 and are not the same thing. A rate limit is when the API faces extreme traffic bursts and so retrying later works; but a spent quota needs your allowance raised or the window to roll over. The library retries rate limits for you, but not if your quota is exceeded.
152
152
 
153
+ ### Timeouts
154
+
155
+ A request that hasn't finished after 30 seconds is abandoned and surfaces as a retryable `network` error. The limit applies to each attempt, so a call that gets retried can take longer in total. Set it for the client, or for a single lookup:
156
+
157
+ ```js
158
+ const client = new VPNDetection({ timeoutMs: 10_000 });
159
+
160
+ const result = await client.lookup('45.83.91.1', { timeoutMs: 2000 });
161
+ ```
162
+
163
+ A database transfer is exempt, because a large one takes minutes.
164
+
153
165
  ### Database downloads
154
166
 
155
167
  If your key carries the `db.download` scope, the licensed databases are available through `client.database`. `download` fetches one to a path, streaming it straight to disk so that nothing bigger than a chunk is ever held in memory:
@@ -178,6 +190,27 @@ import { DATABASE_FORMATS } from 'vpndetection';
178
190
  DATABASE_FORMATS.includes(fromTheCommandLine); // ['csvgz', 'mmdb']
179
191
  ```
180
192
 
193
+ ### Sign in with OAuth (device flow)
194
+
195
+ A program running on the person's own machine can let them sign in with a browser and pick one of their API keys, instead of asking them to paste it:
196
+
197
+ ```js
198
+ const client = new VPNDetection();
199
+
200
+ const device = await client.oauth.deviceAuthorization('your-client-id', {
201
+ scope: 'account.read apikeys.read apikeys.reveal',
202
+ });
203
+ console.log(`Open ${device.verification_uri} and enter ${device.user_code}`);
204
+
205
+ const token = await client.oauth.pollDeviceToken('your-client-id', device);
206
+ if (token.apikey === undefined) {
207
+ throw new Error("no API key came back: none was picked, or it can't be shown again");
208
+ }
209
+ const keyed = new VPNDetection({ apiKey: token.apikey });
210
+ ```
211
+
212
+ A denied sign-in rejects with `OauthAccessDeniedError` and a code that ran out with `OauthExpiredTokenError`. Client IDs are issued on request from support@vpndetection.io, and `client.oauth.revoke('your-client-id', token.refresh_token)` signs the machine out again.
213
+
181
214
  ### Absent is not false
182
215
 
183
216
  Only `ip` and `isVpn` come back on every plan. A field your plan does not include is `undefined`, which means "not in your plan" rather than "checked, and no".
package/dist/client.d.ts CHANGED
@@ -2,6 +2,7 @@ import type { Writable } from 'node:stream';
2
2
  import type { Client } from './generated/client/index.js';
3
3
  import type { Entitlement, Database, DatabaseFormat, DatabaseMetadata, DbChecksums, Download } from './generated/types.gen.js';
4
4
  import { VPNDetectionError } from './errors.js';
5
+ import { OauthApi } from './oauth.js';
5
6
  import { type Result } from './types.js';
6
7
  /**
7
8
  * Where `download` puts the bytes: a path to write, or a stream you opened
@@ -18,6 +19,11 @@ export interface CacheOptions {
18
19
  export interface DownloadsOptions {
19
20
  /** How many attempts to return, newest first. The API clamps this to 200. */
20
21
  limit?: number;
22
+ /**
23
+ * How long one attempt may take before it is abandoned, in milliseconds, for
24
+ * THIS call only. Defaults to the client's `timeoutMs`.
25
+ */
26
+ timeoutMs?: number;
21
27
  }
22
28
  export interface Options {
23
29
  /**
@@ -68,6 +74,11 @@ export declare class VPNDetection {
68
74
  private readonly timeoutMs;
69
75
  /** The licensed dataset downloads, for keys that carry the `db.download` scope. */
70
76
  readonly database: DatabaseApi;
77
+ /**
78
+ * Sign a person in with the OAuth device flow, so a program on their own
79
+ * machine can be handed one of their API keys. Needs no API key.
80
+ */
81
+ readonly oauth: OauthApi;
71
82
  constructor(options?: Options);
72
83
  /**
73
84
  * Whether an address is private, loopback, link-local, documentation,
@@ -129,7 +140,8 @@ export declare class VPNDetection {
129
140
  * error as its value, so one bad entry cannot lose the rest of the answers:
130
141
  * the API reports a per-entry failure with the status the single lookup
131
142
  * would have answered, and a chunk that fails as a whole marks every
132
- * address in it.
143
+ * address in it. A per-call `concurrency` below 1 is refused as
144
+ * `bad_request` before anything is sent.
133
145
  */
134
146
  lookupBatch(ips: Iterable<string>, options?: BatchOptions): Promise<Map<string, Result | VPNDetectionError>>;
135
147
  private lookupChunk;
package/dist/client.js CHANGED
@@ -1,10 +1,11 @@
1
1
  import { LRUCache } from 'lru-cache';
2
2
  import pLimit from 'p-limit';
3
- import pRetry from 'p-retry';
4
3
  import { createClient, createConfig } from './generated/client/index.js';
5
4
  import { myEntitlement, databaseChecksum, databaseMetadata, downloadDatabase as downloadRedirect, listDatabases, listDownloads, lookupBatch, lookupIp, lookupMyIp, } from './generated/sdk.gen.js';
6
5
  import { bogonResult, isBogon } from './bogon.js';
7
6
  import { errorFromEntry, errorFromResponse, VPNDetectionError } from './errors.js';
7
+ import { OauthApi } from './oauth.js';
8
+ import { asError, deadline, unwrap, withRetry } from './transport.js';
8
9
  import { DATABASE_FORMATS, toResult } from './types.js';
9
10
  export const DEFAULT_BASE_URL = 'https://api.vpndetection.io';
10
11
  // Matches the other SDKs, whose HTTP clients default to 30s. Node's global
@@ -28,6 +29,11 @@ export class VPNDetection {
28
29
  timeoutMs;
29
30
  /** The licensed dataset downloads, for keys that carry the `db.download` scope. */
30
31
  database;
32
+ /**
33
+ * Sign a person in with the OAuth device flow, so a program on their own
34
+ * machine can be handed one of their API keys. Needs no API key.
35
+ */
36
+ oauth;
31
37
  constructor(options = {}) {
32
38
  // Resolved once, because the download path calls object storage
33
39
  // directly rather than through the generated client and has to reach
@@ -46,6 +52,7 @@ export class VPNDetection {
46
52
  this.retries = options.retries ?? 2;
47
53
  this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
48
54
  this.database = new DatabaseApi(this.client, this.retries, this.timeoutMs, fetchImpl);
55
+ this.oauth = new OauthApi(this.client, this.retries, this.timeoutMs);
49
56
  }
50
57
  /**
51
58
  * Whether an address is private, loopback, link-local, documentation,
@@ -143,9 +150,15 @@ export class VPNDetection {
143
150
  * error as its value, so one bad entry cannot lose the rest of the answers:
144
151
  * the API reports a per-entry failure with the status the single lookup
145
152
  * would have answered, and a chunk that fails as a whole marks every
146
- * address in it.
153
+ * address in it. A per-call `concurrency` below 1 is refused as
154
+ * `bad_request` before anything is sent.
147
155
  */
148
156
  async lookupBatch(ips, options = {}) {
157
+ const concurrency = options.concurrency;
158
+ if (concurrency !== undefined && !(concurrency >= 1 && (Number.isInteger(concurrency)
159
+ || concurrency === Infinity))) {
160
+ throw new VPNDetectionError('bad_request', `concurrency must be a whole number of at least 1, got ${concurrency}`);
161
+ }
149
162
  const unique = [...new Set(ips)];
150
163
  const out = new Map();
151
164
  const pending = [];
@@ -163,9 +176,7 @@ export class VPNDetection {
163
176
  }
164
177
  // A per-call concurrency gets its own limiter; without one the call
165
178
  // would share the instance's budget and silently ignore the override.
166
- const limit = options.concurrency === undefined
167
- ? this.limit
168
- : pLimit(options.concurrency);
179
+ const limit = concurrency === undefined ? this.limit : pLimit(concurrency);
169
180
  const chunks = [];
170
181
  for (let i = 0; i < pending.length; i += BATCH_MAX) {
171
182
  chunks.push(pending.slice(i, i + BATCH_MAX));
@@ -271,8 +282,9 @@ export class DatabaseApi {
271
282
  * and its absence answers nothing.
272
283
  */
273
284
  async downloads(options = {}) {
285
+ const timeoutMs = options.timeoutMs ?? this.timeoutMs;
274
286
  return withRetry(this.retries, async () => {
275
- const res = await deadline(this.timeoutMs, (signal) => listDownloads({
287
+ const res = await deadline(timeoutMs, (signal) => listDownloads({
276
288
  client: this.client,
277
289
  ...(options.limit === undefined ? {} : { query: { limit: options.limit } }),
278
290
  signal: signal,
@@ -423,70 +435,4 @@ function assertFormat(format) {
423
435
  }
424
436
  throw new VPNDetectionError('bad_request', `invalid format ${JSON.stringify(format)}; must be one of ${DATABASE_FORMATS.join(', ')}`);
425
437
  }
426
- function unwrap(res) {
427
- if (res.response === undefined) {
428
- throw new VPNDetectionError('network', 'no response from the API');
429
- }
430
- if (!res.response.ok) {
431
- throw errorFromResponse(res.response.status, res.response.headers, res.error ?? res.data);
432
- }
433
- return res.data;
434
- }
435
- // p-retry owns the backoff schedule; the extra sleep here is what honors a
436
- // server-supplied Retry-After, which p-retry has no way to know about. A 429
437
- // carrying that header is the only 429 worth retrying, which is why the wait
438
- // and the retry decision both key off the same field.
439
- /**
440
- * Bound one attempt, and report an expiry as our own error rather than the
441
- * runtime's `TimeoutError`, whose message says nothing about which call gave up.
442
- *
443
- * The signal is built per call, so a retried request gets a fresh budget - the
444
- * same per-attempt semantics the Go and Python clients have.
445
- */
446
- async function deadline(timeoutMs, fn) {
447
- const controller = new AbortController();
448
- let timer;
449
- // Raced, not left to the signal alone: aborting releases the socket, but only
450
- // a transport that HONORS the signal then settles, and a substituted `fetch`
451
- // need not. Clearing the timer stops the losing side rejecting into nothing.
452
- const expiry = new Promise((_, reject) => {
453
- timer = setTimeout(() => {
454
- controller.abort();
455
- reject(new VPNDetectionError('network', `request timed out after ${timeoutMs}ms`));
456
- }, timeoutMs);
457
- });
458
- try {
459
- return await Promise.race([fn(controller.signal), expiry]);
460
- }
461
- finally {
462
- clearTimeout(timer);
463
- }
464
- }
465
- async function withRetry(retries, fn) {
466
- try {
467
- return await pRetry(fn, {
468
- retries: retries,
469
- shouldRetry: ({ error }) => !(error instanceof VPNDetectionError) || error.retryable,
470
- onFailedAttempt: async ({ error }) => {
471
- const seconds = error instanceof VPNDetectionError ? error.retryAfterSeconds : undefined;
472
- if (seconds !== undefined && seconds > 0) {
473
- await new Promise((r) => setTimeout(r, seconds * 1000));
474
- }
475
- },
476
- });
477
- }
478
- catch (err) {
479
- throw asError(err);
480
- }
481
- }
482
- function asError(err) {
483
- if (err instanceof VPNDetectionError) {
484
- return err;
485
- }
486
- const cause = err?.cause;
487
- if (cause instanceof VPNDetectionError) {
488
- return cause;
489
- }
490
- return new VPNDetectionError('network', err instanceof Error ? err.message : String(err));
491
- }
492
438
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/errors.d.ts CHANGED
@@ -16,6 +16,34 @@ export declare class VPNDetectionError extends Error {
16
16
  /** Whether retrying this exact request could succeed. */
17
17
  get retryable(): boolean;
18
18
  }
19
+ /**
20
+ * The authorization server refusing an OAuth request: a 4xx whose body names an
21
+ * OAuth error code. Never retryable as it stands.
22
+ *
23
+ * `kind` follows the status like any other failure's. A 401 here means the
24
+ * client ID is not registered, never the API key, which OAuth requests do not
25
+ * carry. The two codes a sign-in ends on have their own subclasses.
26
+ */
27
+ export declare class OauthError extends VPNDetectionError {
28
+ /** The server's code, such as `authorization_pending` or `invalid_grant`, kept as sent. */
29
+ readonly errorCode: string;
30
+ /** The server's explanation, when it sent one. */
31
+ readonly errorDescription?: string;
32
+ constructor(errorCode: string, errorDescription?: string, status?: number);
33
+ get retryable(): boolean;
34
+ }
35
+ /** The person refused the sign-in. Its device code is spent, so a new attempt starts over. */
36
+ export declare class OauthAccessDeniedError extends OauthError {
37
+ constructor(errorDescription?: string, status?: number);
38
+ }
39
+ /**
40
+ * The device code is no longer valid: it expired, or was already used or
41
+ * refused. A poll that outlives the code raises this itself, with no `status`.
42
+ */
43
+ export declare class OauthExpiredTokenError extends OauthError {
44
+ constructor(errorDescription?: string, status?: number);
45
+ }
46
+ export declare function oauthErrorFrom(errorCode: string, errorDescription: string | undefined, status: number): OauthError;
19
47
  export declare function errorFromResponse(status: number, headers: {
20
48
  get(name: string): string | null;
21
49
  }, body: unknown): VPNDetectionError;
package/dist/errors.js CHANGED
@@ -14,6 +14,56 @@ export class VPNDetectionError extends Error {
14
14
  return this.kind === 'rate_limited' || this.kind === 'server_error' || this.kind === 'network';
15
15
  }
16
16
  }
17
+ /**
18
+ * The authorization server refusing an OAuth request: a 4xx whose body names an
19
+ * OAuth error code. Never retryable as it stands.
20
+ *
21
+ * `kind` follows the status like any other failure's. A 401 here means the
22
+ * client ID is not registered, never the API key, which OAuth requests do not
23
+ * carry. The two codes a sign-in ends on have their own subclasses.
24
+ */
25
+ export class OauthError extends VPNDetectionError {
26
+ /** The server's code, such as `authorization_pending` or `invalid_grant`, kept as sent. */
27
+ errorCode;
28
+ /** The server's explanation, when it sent one. */
29
+ errorDescription;
30
+ constructor(errorCode, errorDescription, status) {
31
+ super(status === undefined ? 'bad_request' : errorFromResponse(status, NO_HEADERS, undefined).kind, errorDescription === undefined ? errorCode : `${errorCode}: ${errorDescription}`, status);
32
+ this.name = 'OauthError';
33
+ this.errorCode = errorCode;
34
+ this.errorDescription = errorDescription;
35
+ }
36
+ get retryable() {
37
+ return false;
38
+ }
39
+ }
40
+ /** The person refused the sign-in. Its device code is spent, so a new attempt starts over. */
41
+ export class OauthAccessDeniedError extends OauthError {
42
+ constructor(errorDescription, status) {
43
+ super('access_denied', errorDescription, status);
44
+ this.name = 'OauthAccessDeniedError';
45
+ }
46
+ }
47
+ /**
48
+ * The device code is no longer valid: it expired, or was already used or
49
+ * refused. A poll that outlives the code raises this itself, with no `status`.
50
+ */
51
+ export class OauthExpiredTokenError extends OauthError {
52
+ constructor(errorDescription, status) {
53
+ super('expired_token', errorDescription, status);
54
+ this.name = 'OauthExpiredTokenError';
55
+ }
56
+ }
57
+ export function oauthErrorFrom(errorCode, errorDescription, status) {
58
+ if (errorCode === 'access_denied') {
59
+ return new OauthAccessDeniedError(errorDescription, status);
60
+ }
61
+ if (errorCode === 'expired_token') {
62
+ return new OauthExpiredTokenError(errorDescription, status);
63
+ }
64
+ return new OauthError(errorCode, errorDescription, status);
65
+ }
66
+ const NO_HEADERS = { get: () => null };
17
67
  export function errorFromResponse(status, headers, body) {
18
68
  const message = messageOf(body) ?? `request failed with status ${status}`;
19
69
  const retryAfter = parseRetryAfter(headers.get('retry-after'));
@@ -47,7 +97,7 @@ export function errorFromResponse(status, headers, body) {
47
97
  * is a spent allowance, which is the only kind the API puts in an entry.
48
98
  */
49
99
  export function errorFromEntry(entry) {
50
- return errorFromResponse(entry.status, { get: () => null }, { error: entry.error });
100
+ return errorFromResponse(entry.status, NO_HEADERS, { error: entry.error });
51
101
  }
52
102
  // The two APIs behind this host answer with different envelopes: the lookup
53
103
  // endpoint uses `error`, the database endpoints use `rc`. Both are read here so
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -62,7 +62,7 @@ export declare const lookupBatch: <ThrowOnError extends boolean = false>(options
62
62
  /**
63
63
  * List
64
64
  *
65
- * Every database this organization may SEE, with where its licence stands.
65
+ * Every database this organization may SEE, with where its license stands.
66
66
  * Not just the ones you hold: a customer with one grant should be able to
67
67
  * tell what else is published without asking. `standing` is the
68
68
  * difference - `licensed`, `expired`, or `unlicensed` for one never
@@ -90,7 +90,7 @@ export const lookupBatch = (options) => (options.client ?? client).post({
90
90
  /**
91
91
  * List
92
92
  *
93
- * Every database this organization may SEE, with where its licence stands.
93
+ * Every database this organization may SEE, with where its license stands.
94
94
  * Not just the ones you hold: a customer with one grant should be able to
95
95
  * tell what else is published without asking. `standing` is the
96
96
  * difference - `licensed`, `expired`, or `unlicensed` for one never
@@ -252,7 +252,7 @@ export type DatabaseFormatSize = {
252
252
  bytes: number | null;
253
253
  };
254
254
  /**
255
- * One database FAMILY your organization is licensed for. A license covers
255
+ * One database FAMILY, with your organization's license beside it. A license covers
256
256
  * the family, while a download names a specific version, so the ids you
257
257
  * pass to the download and checksum endpoints come from `versions`.
258
258
  *
@@ -567,9 +567,14 @@ export type OauthMetadata = {
567
567
  grant_types_supported?: Array<string>;
568
568
  code_challenge_methods_supported?: Array<string>;
569
569
  /**
570
- * A client_id may be an https URL serving your client metadata.
570
+ * Always `none`. Every client is public and has no secret.
571
571
  */
572
- client_id_metadata_document_supported?: boolean;
572
+ token_endpoint_auth_methods_supported?: Array<string>;
573
+ /**
574
+ * RFC 9207. A redirect back from the authorization endpoint carries `iss`.
575
+ */
576
+ authorization_response_iss_parameter_supported?: boolean;
577
+ service_documentation?: string;
573
578
  };
574
579
  export type DeviceAuthorizationRequest = {
575
580
  client_id: string;
@@ -596,6 +601,9 @@ export type DeviceAuthorization = {
596
601
  * The same page with the code already filled in.
597
602
  */
598
603
  verification_uri_complete?: string;
604
+ /**
605
+ * Seconds until both codes expire.
606
+ */
599
607
  expires_in: number;
600
608
  /**
601
609
  * Seconds between polls.
@@ -603,26 +611,77 @@ export type DeviceAuthorization = {
603
611
  interval: number;
604
612
  };
605
613
  export type TokenRequest = {
614
+ /**
615
+ * `urn:ietf:params:oauth:grant-type:device_code`, `authorization_code` or `refresh_token`.
616
+ */
606
617
  grant_type: string;
607
618
  client_id: string;
619
+ /**
620
+ * Required by the device code grant.
621
+ */
608
622
  device_code?: string;
623
+ /**
624
+ * Required by the authorization code grant.
625
+ */
609
626
  code?: string;
627
+ /**
628
+ * Required by the authorization code grant.
629
+ */
610
630
  code_verifier?: string;
631
+ /**
632
+ * Authorization code grant: the `redirect_uri` the code was issued against, exactly.
633
+ */
611
634
  redirect_uri?: string;
635
+ /**
636
+ * Required by the refresh token grant.
637
+ */
612
638
  refresh_token?: string;
613
639
  };
614
640
  export type TokenResponse = {
615
641
  access_token: string;
642
+ /**
643
+ * Always `Bearer`.
644
+ */
616
645
  token_type: string;
646
+ /**
647
+ * Seconds until the access token expires.
648
+ */
617
649
  expires_in: number;
650
+ /**
651
+ * Always returned. A refresh consumes the token it presents, so keep this one.
652
+ */
618
653
  refresh_token?: string;
619
654
  /**
620
655
  * What was actually granted, which may be narrower than what was asked for.
621
656
  */
622
657
  scope?: string;
658
+ /**
659
+ * Not part of OAuth. The ID of the API key the person picked when they
660
+ * approved, returned by every grant while this authorization may still
661
+ * read that key back. Absent when no key was picked, or when the
662
+ * person's role no longer allows reading keys back.
663
+ *
664
+ */
665
+ 'mslm:apikey_id'?: string;
666
+ /**
667
+ * Not part of OAuth. The API key itself, so a device ends up holding an
668
+ * ordinary key. Returned by the device code and authorization code
669
+ * grants only, never by a refresh, and only alongside
670
+ * `mslm:apikey_id`. Absent when that key's secret cannot be read back,
671
+ * which is the case for a key created before keys could be shown again
672
+ * in the console; a rotated key can be.
673
+ *
674
+ */
675
+ 'mslm:apikey'?: string;
623
676
  };
624
677
  export type RevokeRequest = {
678
+ /**
679
+ * An access token or a refresh token.
680
+ */
625
681
  token: string;
682
+ /**
683
+ * Accepted and not checked.
684
+ */
626
685
  client_id?: string;
627
686
  };
628
687
  export type OauthError = {
@@ -907,6 +966,9 @@ export type ListDownloadsData = {
907
966
  body?: never;
908
967
  path?: never;
909
968
  query?: {
969
+ /**
970
+ * How many attempts to return. Clamped to 1 through 200.
971
+ */
910
972
  limit?: number;
911
973
  };
912
974
  url: '/api/v1/database/downloads';
@@ -1222,11 +1284,16 @@ export type OauthDeviceAuthorizationData = {
1222
1284
  };
1223
1285
  export type OauthDeviceAuthorizationErrors = {
1224
1286
  /**
1225
- * `invalid_request`, `invalid_client`, `unauthorized_client`, or
1226
- * `slow_down` when this address has started too many authorizations.
1287
+ * `invalid_request`, `unauthorized_client` when the client may not use
1288
+ * the device flow, or `slow_down` when this address has started too
1289
+ * many authorizations.
1227
1290
  *
1228
1291
  */
1229
1292
  400: OauthError;
1293
+ /**
1294
+ * `invalid_client`: the `client_id` is not registered.
1295
+ */
1296
+ 401: OauthError;
1230
1297
  };
1231
1298
  export type OauthDeviceAuthorizationError = OauthDeviceAuthorizationErrors[keyof OauthDeviceAuthorizationErrors];
1232
1299
  export type OauthDeviceAuthorizationResponses = {
@@ -1276,9 +1343,18 @@ export type OauthTokenErrors = {
1276
1343
  /**
1277
1344
  * An RFC 6749 error. `authorization_pending` and `slow_down` are
1278
1345
  * normal answers while polling a device authorization, not failures.
1346
+ * `access_denied` means the person refused, and `expired_token` that
1347
+ * the device code is no longer valid: it expired, or it was already
1348
+ * exchanged or refused. `invalid_grant` means the code, device code or
1349
+ * refresh token is not valid for this `client_id`. `slow_down` also
1350
+ * answers any grant when this address sends too many requests.
1279
1351
  *
1280
1352
  */
1281
1353
  400: OauthError;
1354
+ /**
1355
+ * `invalid_client`: the `client_id` is not registered.
1356
+ */
1357
+ 401: OauthError;
1282
1358
  };
1283
1359
  export type OauthTokenError = OauthTokenErrors[keyof OauthTokenErrors];
1284
1360
  export type OauthTokenResponses = {
package/dist/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  export { VPNDetection, DatabaseApi, DEFAULT_BASE_URL } from './client.js';
2
2
  export type { Options, CacheOptions, LookupOptions, BatchOptions, DownloadsOptions, DownloadDestination, } from './client.js';
3
+ export { OauthApi } from './oauth.js';
4
+ export type { OauthOptions, DeviceAuthorizationOptions, PollDeviceTokenOptions, OauthMetadata, DeviceAuthorization, TokenResponse, } from './oauth.js';
3
5
  export { isBogon } from './bogon.js';
4
- export { VPNDetectionError } from './errors.js';
6
+ export { VPNDetectionError, OauthError, OauthAccessDeniedError, OauthExpiredTokenError, } from './errors.js';
5
7
  export type { ErrorKind } from './errors.js';
6
8
  export type { Result, VpnDetail, ClassDetail, ProxyDetail, LookupResponse, } from './types.js';
7
9
  export { DATABASE_FORMATS, STANDINGS, LICENSE_TYPES } from './types.js';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export { VPNDetection, DatabaseApi, DEFAULT_BASE_URL } from './client.js';
2
+ export { OauthApi } from './oauth.js';
2
3
  export { isBogon } from './bogon.js';
3
- export { VPNDetectionError } from './errors.js';
4
+ export { VPNDetectionError, OauthError, OauthAccessDeniedError, OauthExpiredTokenError, } from './errors.js';
4
5
  export { DATABASE_FORMATS, STANDINGS, LICENSE_TYPES } from './types.js';
5
6
  //# 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":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAK1E,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAKhD,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAK1E,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAKtC,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EACH,iBAAiB,EAAE,UAAU,EAAE,sBAAsB,EAAE,sBAAsB,GAChF,MAAM,aAAa,CAAC;AAKrB,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,118 @@
1
+ import type { Client } from './generated/client/index.js';
2
+ /** Per-call overrides for one OAuth request. Anything omitted falls back to the client's setting. */
3
+ export interface OauthOptions {
4
+ /** How long one attempt may take before it is abandoned, in milliseconds. */
5
+ timeoutMs?: number;
6
+ }
7
+ /** What a device sign-in asks for. A member left out is left out of the request, never sent empty. */
8
+ export interface DeviceAuthorizationOptions extends OauthOptions {
9
+ /** Space-delimited scopes, sent as given. The server narrows them to what the client may ask for. */
10
+ scope?: string;
11
+ /** The API the tokens are meant for. */
12
+ resource?: string;
13
+ }
14
+ export interface PollDeviceTokenOptions {
15
+ /** How long EACH request of the poll may take, in milliseconds. Never bounds the poll as a whole. */
16
+ timeoutMs?: number;
17
+ /** Aborting it stops the wait and any request in flight, and the poll rejects with its reason. */
18
+ signal?: AbortSignal;
19
+ }
20
+ /** The authorization server's discovery document. No call here needs it: each builds on the base URL. */
21
+ export interface OauthMetadata {
22
+ issuer: string;
23
+ authorization_endpoint: string;
24
+ token_endpoint: string;
25
+ device_authorization_endpoint?: string;
26
+ revocation_endpoint?: string;
27
+ scopes_supported?: string[];
28
+ response_types_supported?: string[];
29
+ grant_types_supported?: string[];
30
+ code_challenge_methods_supported?: string[];
31
+ token_endpoint_auth_methods_supported?: string[];
32
+ authorization_response_iss_parameter_supported?: boolean;
33
+ service_documentation?: string;
34
+ }
35
+ /** A started device sign-in. `expires_in` and `interval` are seconds. */
36
+ export interface DeviceAuthorization {
37
+ device_code: string;
38
+ /** What the person types in at `verification_uri`. */
39
+ user_code: string;
40
+ verification_uri: string;
41
+ /** `verification_uri` with the code already in it, for a program that can open a browser. */
42
+ verification_uri_complete?: string;
43
+ expires_in: number;
44
+ interval: number;
45
+ }
46
+ /**
47
+ * What a completed sign-in or a refresh hands back.
48
+ *
49
+ * `apikey_id` is set when the person picked one of their API keys and may still
50
+ * read it back. `apikey`, the key itself, also needs a sign-in rather than a
51
+ * refresh and a key whose secret can be shown again, so `apikey_id` without
52
+ * `apikey` is normal. An empty `scope` is present.
53
+ */
54
+ export interface TokenResponse {
55
+ access_token: string;
56
+ token_type: string;
57
+ expires_in: number;
58
+ /** Spent by the refresh that presents it, so keep the one each refresh returns. */
59
+ refresh_token?: string;
60
+ scope?: string;
61
+ apikey_id?: string;
62
+ apikey?: string;
63
+ }
64
+ /**
65
+ * Signs a person in on their own machine with the OAuth device flow, so a
66
+ * program can be handed one of their API keys instead of asking them to paste
67
+ * it. Reached through `client.oauth`.
68
+ *
69
+ * Every call takes a client ID, issued on request from support@vpndetection.io.
70
+ * None of these requests carries the client's API key, and none needs one.
71
+ */
72
+ export declare class OauthApi {
73
+ private readonly client;
74
+ private readonly retries;
75
+ private readonly timeoutMs;
76
+ private clock;
77
+ constructor(client: Client, retries: number, timeoutMs: number);
78
+ metadata(options?: OauthOptions): Promise<OauthMetadata>;
79
+ /**
80
+ * Start a device sign-in: show the person `user_code` and `verification_uri`,
81
+ * then hand the answer to `pollDeviceToken`. It consumes nothing, so it is
82
+ * retried like a lookup; a refusal such as `slow_down` is an `OauthError`.
83
+ */
84
+ deviceAuthorization(clientId: string, options?: DeviceAuthorizationOptions): Promise<DeviceAuthorization>;
85
+ /**
86
+ * Ask once whether the person has approved a device sign-in. Until they do,
87
+ * it rejects with an `OauthError` coded `authorization_pending`;
88
+ * `pollDeviceToken` is the loop around it.
89
+ *
90
+ * Never retried: an approved code is spent by the answer carrying the tokens,
91
+ * so a retry after a lost response could only lose them.
92
+ */
93
+ exchangeDeviceCode(clientId: string, deviceCode: string, options?: OauthOptions): Promise<TokenResponse>;
94
+ /**
95
+ * Trade a refresh token for a new pair. The old one is spent whatever happens
96
+ * next, so this is never retried. A refresh names the key the person picked
97
+ * (`apikey_id`) but never reveals it again (`apikey`).
98
+ */
99
+ exchangeRefreshToken(clientId: string, refreshToken: string, options?: OauthOptions): Promise<TokenResponse>;
100
+ /**
101
+ * End a token. A refresh token ends the whole sign-in and every token it
102
+ * issued, which is how a program signs the machine out; an access token ends
103
+ * only itself. The server answers the same for any token, known or not.
104
+ */
105
+ revoke(clientId: string, token: string, options?: OauthOptions): Promise<void>;
106
+ /**
107
+ * Wait for the person to approve a device sign-in, and return its tokens.
108
+ *
109
+ * Waits `device.interval` seconds (5 when that is below 1) before EVERY
110
+ * request, the first included, and 5 more for the rest of the call each time
111
+ * the server answers `slow_down`. Ends at the first answer that is neither:
112
+ * a denial rejects with `OauthAccessDeniedError`, a code that ran out with
113
+ * `OauthExpiredTokenError` - as does outliving `device.expires_in`, counted
114
+ * from this call, with no `status` - and any other failure as it came.
115
+ */
116
+ pollDeviceToken(clientId: string, device: DeviceAuthorization, options?: PollDeviceTokenOptions): Promise<TokenResponse>;
117
+ private exchange;
118
+ }
package/dist/oauth.js ADDED
@@ -0,0 +1,240 @@
1
+ import { oauthDeviceAuthorization, oauthMetadata, oauthRevoke, oauthToken, } from './generated/sdk.gen.js';
2
+ import { errorFromResponse, OauthError, oauthErrorFrom, OauthExpiredTokenError, VPNDetectionError, } from './errors.js';
3
+ import { asError, deadline, withRetry } from './transport.js';
4
+ /**
5
+ * Signs a person in on their own machine with the OAuth device flow, so a
6
+ * program can be handed one of their API keys instead of asking them to paste
7
+ * it. Reached through `client.oauth`.
8
+ *
9
+ * Every call takes a client ID, issued on request from support@vpndetection.io.
10
+ * None of these requests carries the client's API key, and none needs one.
11
+ */
12
+ export class OauthApi {
13
+ client;
14
+ retries;
15
+ timeoutMs;
16
+ // The poll's wait and its deadline, which tests replace together.
17
+ clock = { now: () => performance.now(), sleep: sleep };
18
+ constructor(client, retries, timeoutMs) {
19
+ this.client = client;
20
+ this.retries = retries;
21
+ this.timeoutMs = timeoutMs;
22
+ }
23
+ async metadata(options = {}) {
24
+ return withRetry(this.retries, async () => {
25
+ const res = await deadline(options.timeoutMs ?? this.timeoutMs, (signal) => oauthMetadata({
26
+ client: this.client, signal: signal,
27
+ }));
28
+ return decode(res, METADATA);
29
+ });
30
+ }
31
+ /**
32
+ * Start a device sign-in: show the person `user_code` and `verification_uri`,
33
+ * then hand the answer to `pollDeviceToken`. It consumes nothing, so it is
34
+ * retried like a lookup; a refusal such as `slow_down` is an `OauthError`.
35
+ */
36
+ async deviceAuthorization(clientId, options = {}) {
37
+ const body = {
38
+ client_id: clientId,
39
+ scope: options.scope || undefined,
40
+ resource: options.resource || undefined,
41
+ };
42
+ const timeoutMs = options.timeoutMs ?? this.timeoutMs;
43
+ return withRetry(this.retries, async () => {
44
+ const res = await deadline(timeoutMs, (signal) => oauthDeviceAuthorization({
45
+ client: this.client, body: body, signal: signal,
46
+ }));
47
+ return decode(res, DEVICE_AUTHORIZATION);
48
+ });
49
+ }
50
+ /**
51
+ * Ask once whether the person has approved a device sign-in. Until they do,
52
+ * it rejects with an `OauthError` coded `authorization_pending`;
53
+ * `pollDeviceToken` is the loop around it.
54
+ *
55
+ * Never retried: an approved code is spent by the answer carrying the tokens,
56
+ * so a retry after a lost response could only lose them.
57
+ */
58
+ async exchangeDeviceCode(clientId, deviceCode, options = {}) {
59
+ return this.exchange({
60
+ grant_type: DEVICE_CODE_GRANT, device_code: deviceCode, client_id: clientId,
61
+ }, options.timeoutMs);
62
+ }
63
+ /**
64
+ * Trade a refresh token for a new pair. The old one is spent whatever happens
65
+ * next, so this is never retried. A refresh names the key the person picked
66
+ * (`apikey_id`) but never reveals it again (`apikey`).
67
+ */
68
+ async exchangeRefreshToken(clientId, refreshToken, options = {}) {
69
+ return this.exchange({
70
+ grant_type: 'refresh_token', refresh_token: refreshToken, client_id: clientId,
71
+ }, options.timeoutMs);
72
+ }
73
+ /**
74
+ * End a token. A refresh token ends the whole sign-in and every token it
75
+ * issued, which is how a program signs the machine out; an access token ends
76
+ * only itself. The server answers the same for any token, known or not.
77
+ */
78
+ async revoke(clientId, token, options = {}) {
79
+ await withRetry(this.retries, async () => {
80
+ const res = await deadline(options.timeoutMs ?? this.timeoutMs, (signal) => oauthRevoke({
81
+ client: this.client,
82
+ body: { token: token, client_id: clientId },
83
+ // The answer says nothing, so it is read as text and dropped rather than parsed.
84
+ parseAs: 'text',
85
+ signal: signal,
86
+ }));
87
+ throwIfFailed(res);
88
+ });
89
+ }
90
+ /**
91
+ * Wait for the person to approve a device sign-in, and return its tokens.
92
+ *
93
+ * Waits `device.interval` seconds (5 when that is below 1) before EVERY
94
+ * request, the first included, and 5 more for the rest of the call each time
95
+ * the server answers `slow_down`. Ends at the first answer that is neither:
96
+ * a denial rejects with `OauthAccessDeniedError`, a code that ran out with
97
+ * `OauthExpiredTokenError` - as does outliving `device.expires_in`, counted
98
+ * from this call, with no `status` - and any other failure as it came.
99
+ */
100
+ async pollDeviceToken(clientId, device, options = {}) {
101
+ let interval = device.interval >= 1 ? device.interval : 5;
102
+ const expires = this.clock.now() + device.expires_in * 1000;
103
+ for (;;) {
104
+ await this.clock.sleep(interval * 1000, options.signal);
105
+ if (this.clock.now() >= expires) {
106
+ throw new OauthExpiredTokenError();
107
+ }
108
+ try {
109
+ return await this.exchange({
110
+ grant_type: DEVICE_CODE_GRANT, device_code: device.device_code, client_id: clientId,
111
+ }, options.timeoutMs, options.signal);
112
+ }
113
+ catch (err) {
114
+ if (!(err instanceof OauthError)) {
115
+ throw err;
116
+ }
117
+ // RFC 8628: slow_down widens the interval for every later request, not just the next.
118
+ if (err.errorCode === 'slow_down') {
119
+ interval += 5;
120
+ }
121
+ else if (err.errorCode !== 'authorization_pending') {
122
+ throw err;
123
+ }
124
+ }
125
+ }
126
+ }
127
+ async exchange(form, timeoutMs, cancel) {
128
+ const res = await deadline(timeoutMs ?? this.timeoutMs, (signal) => oauthToken({
129
+ client: this.client, body: form, signal: signal,
130
+ }), cancel);
131
+ return decode(res, TOKEN_RESPONSE);
132
+ }
133
+ }
134
+ const DEVICE_CODE_GRANT = 'urn:ietf:params:oauth:grant-type:device_code';
135
+ const METADATA = {
136
+ issuer: { type: 'string', required: true },
137
+ authorization_endpoint: { type: 'string', required: true },
138
+ token_endpoint: { type: 'string', required: true },
139
+ device_authorization_endpoint: { type: 'string' },
140
+ revocation_endpoint: { type: 'string' },
141
+ scopes_supported: { type: 'string[]' },
142
+ response_types_supported: { type: 'string[]' },
143
+ grant_types_supported: { type: 'string[]' },
144
+ code_challenge_methods_supported: { type: 'string[]' },
145
+ token_endpoint_auth_methods_supported: { type: 'string[]' },
146
+ authorization_response_iss_parameter_supported: { type: 'boolean' },
147
+ service_documentation: { type: 'string' },
148
+ };
149
+ const DEVICE_AUTHORIZATION = {
150
+ device_code: { type: 'string', required: true },
151
+ user_code: { type: 'string', required: true },
152
+ verification_uri: { type: 'string', required: true },
153
+ verification_uri_complete: { type: 'string' },
154
+ expires_in: { type: 'number', required: true },
155
+ interval: { type: 'number', required: true },
156
+ };
157
+ const TOKEN_RESPONSE = {
158
+ access_token: { type: 'string', required: true },
159
+ token_type: { type: 'string', required: true },
160
+ expires_in: { type: 'number', required: true },
161
+ refresh_token: { type: 'string' },
162
+ scope: { type: 'string' },
163
+ apikey_id: { type: 'string', wire: 'mslm:apikey_id' },
164
+ apikey: { type: 'string', wire: 'mslm:apikey' },
165
+ };
166
+ // Only the declared members are copied, on PRESENCE, so an absent one stays
167
+ // absent and an empty `scope` stays present. Anything else the server sends is
168
+ // dropped rather than surfaced untyped.
169
+ function decode(res, members) {
170
+ const status = throwIfFailed(res).status;
171
+ if (res.error !== undefined) {
172
+ // A 2xx the generated client could not parse, which reports it here.
173
+ throw asError(res.error);
174
+ }
175
+ const body = res.data;
176
+ if (!isObject(body)) {
177
+ throw new VPNDetectionError('server_error', 'the answer was not a JSON object', status);
178
+ }
179
+ const out = {};
180
+ for (const [name, member] of Object.entries(members)) {
181
+ const wire = member.wire ?? name;
182
+ const value = body[wire];
183
+ if (value === undefined || value === null) {
184
+ if (member.required) {
185
+ throw new VPNDetectionError('server_error', `the answer carried no ${wire}`, status);
186
+ }
187
+ continue;
188
+ }
189
+ if (!hasType(value, member.type)) {
190
+ throw new VPNDetectionError('server_error', `the answer's ${wire} is not a ${member.type}`, status);
191
+ }
192
+ out[name] = value;
193
+ }
194
+ return out;
195
+ }
196
+ // Only a 4xx whose body is a JSON object with a STRING `error` is an OAuth
197
+ // refusal. Every 5xx, whatever it says, is the server failing, and is retried
198
+ // wherever the operation retries.
199
+ function throwIfFailed(res) {
200
+ if (res.response === undefined) {
201
+ throw new VPNDetectionError('network', 'no response from the API');
202
+ }
203
+ const { status, ok, headers } = res.response;
204
+ if (ok) {
205
+ return res.response;
206
+ }
207
+ const body = res.error;
208
+ if (status >= 400 && status < 500 && isObject(body) && typeof body.error === 'string') {
209
+ const description = typeof body.error_description === 'string' ? body.error_description : undefined;
210
+ throw oauthErrorFrom(body.error, description, status);
211
+ }
212
+ throw errorFromResponse(status, headers, body);
213
+ }
214
+ function isObject(value) {
215
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
216
+ }
217
+ function hasType(value, type) {
218
+ if (type === 'string[]') {
219
+ return Array.isArray(value) && value.every((item) => typeof item === 'string');
220
+ }
221
+ return typeof value === type;
222
+ }
223
+ function sleep(ms, signal) {
224
+ return new Promise((resolve, reject) => {
225
+ if (signal?.aborted) {
226
+ reject(signal.reason);
227
+ return;
228
+ }
229
+ const onAbort = () => {
230
+ clearTimeout(timer);
231
+ reject(signal?.reason);
232
+ };
233
+ const timer = setTimeout(() => {
234
+ signal?.removeEventListener('abort', onAbort);
235
+ resolve();
236
+ }, ms);
237
+ signal?.addEventListener('abort', onAbort, { once: true });
238
+ });
239
+ }
240
+ //# sourceMappingURL=oauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { VPNDetectionError } from './errors.js';
2
+ export interface Res {
3
+ data?: unknown;
4
+ error?: unknown;
5
+ response?: Response;
6
+ }
7
+ export declare function unwrap<T>(res: Res): T;
8
+ /**
9
+ * Bound one attempt, and report an expiry as our own error rather than the
10
+ * runtime's `TimeoutError`, whose message says nothing about which call gave up.
11
+ *
12
+ * The signal is built per call, so a retried request gets a fresh budget - the
13
+ * same per-attempt semantics the Go and Python clients have. Aborting `cancel`
14
+ * ends the attempt at once, rejecting with its reason.
15
+ */
16
+ export declare function deadline<T>(timeoutMs: number, fn: (signal: AbortSignal) => Promise<T>, cancel?: AbortSignal): Promise<T>;
17
+ export declare function withRetry<T>(retries: number, fn: () => Promise<T>): Promise<T>;
18
+ export declare function asError(err: unknown): VPNDetectionError;
@@ -0,0 +1,82 @@
1
+ import pRetry from 'p-retry';
2
+ import { errorFromResponse, VPNDetectionError } from './errors.js';
3
+ export function unwrap(res) {
4
+ if (res.response === undefined) {
5
+ throw new VPNDetectionError('network', 'no response from the API');
6
+ }
7
+ if (!res.response.ok) {
8
+ throw errorFromResponse(res.response.status, res.response.headers, res.error ?? res.data);
9
+ }
10
+ return res.data;
11
+ }
12
+ /**
13
+ * Bound one attempt, and report an expiry as our own error rather than the
14
+ * runtime's `TimeoutError`, whose message says nothing about which call gave up.
15
+ *
16
+ * The signal is built per call, so a retried request gets a fresh budget - the
17
+ * same per-attempt semantics the Go and Python clients have. Aborting `cancel`
18
+ * ends the attempt at once, rejecting with its reason.
19
+ */
20
+ export async function deadline(timeoutMs, fn, cancel) {
21
+ cancel?.throwIfAborted();
22
+ const controller = new AbortController();
23
+ let timer;
24
+ let stop;
25
+ // Raced, not left to the signal alone: aborting releases the socket, but only
26
+ // a transport that HONORS the signal then settles, and a substituted `fetch`
27
+ // need not. Clearing the timer stops the losing side rejecting into nothing.
28
+ const expiry = new Promise((_, reject) => {
29
+ timer = setTimeout(() => {
30
+ controller.abort();
31
+ reject(new VPNDetectionError('network', `request timed out after ${timeoutMs}ms`));
32
+ }, timeoutMs);
33
+ if (cancel !== undefined) {
34
+ stop = () => {
35
+ controller.abort(cancel.reason);
36
+ reject(cancel.reason);
37
+ };
38
+ cancel.addEventListener('abort', stop, { once: true });
39
+ }
40
+ });
41
+ try {
42
+ return await Promise.race([fn(controller.signal), expiry]);
43
+ }
44
+ finally {
45
+ clearTimeout(timer);
46
+ if (stop !== undefined) {
47
+ cancel?.removeEventListener('abort', stop);
48
+ }
49
+ }
50
+ }
51
+ // p-retry owns the backoff schedule; the extra sleep here is what honors a
52
+ // server-supplied Retry-After, which p-retry has no way to know about. A 429
53
+ // carrying that header is the only 429 worth retrying, which is why the wait
54
+ // and the retry decision both key off the same field.
55
+ export async function withRetry(retries, fn) {
56
+ try {
57
+ return await pRetry(fn, {
58
+ retries: retries,
59
+ shouldRetry: ({ error }) => !(error instanceof VPNDetectionError) || error.retryable,
60
+ onFailedAttempt: async ({ error }) => {
61
+ const seconds = error instanceof VPNDetectionError ? error.retryAfterSeconds : undefined;
62
+ if (seconds !== undefined && seconds > 0) {
63
+ await new Promise((r) => setTimeout(r, seconds * 1000));
64
+ }
65
+ },
66
+ });
67
+ }
68
+ catch (err) {
69
+ throw asError(err);
70
+ }
71
+ }
72
+ export function asError(err) {
73
+ if (err instanceof VPNDetectionError) {
74
+ return err;
75
+ }
76
+ const cause = err?.cause;
77
+ if (cause instanceof VPNDetectionError) {
78
+ return cause;
79
+ }
80
+ return new VPNDetectionError('network', err instanceof Error ? err.message : String(err));
81
+ }
82
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vpndetection",
3
- "version": "5.1.0",
3
+ "version": "5.2.1",
4
4
  "description": "Official Node.js client library for the VPNDetection API. Detect VPNs, proxies, Tor, hosting and CDN IPs.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -55,10 +55,10 @@
55
55
  },
56
56
  "devDependencies": {
57
57
  "@hey-api/openapi-ts": "^0.99.0",
58
- "@mslmio/eslint-config": "^1.0.1",
58
+ "@mslmio/eslint-config": "^1.1.0",
59
59
  "@types/node": "^26.2.0",
60
- "eslint": "^9.39.0",
61
- "typescript": "^5.9.3"
60
+ "eslint": "^10.10.0",
61
+ "typescript": "^6.0.3"
62
62
  },
63
63
  "scripts": {
64
64
  "build": "rm -rf dist && openapi-ts && tsc",