@getanyapi/sdk 0.9.2 → 0.9.5
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 +21 -4
- package/dist/index.cjs +149 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -7
- package/dist/index.d.ts +15 -7
- package/dist/index.js +149 -18
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -65,6 +65,8 @@ interface RequestOptions {
|
|
|
65
65
|
signal?: AbortSignal;
|
|
66
66
|
/** Override the client maxRetries for this call. */
|
|
67
67
|
maxRetries?: number;
|
|
68
|
+
/** Override the generated Idempotency-Key for this billed POST. */
|
|
69
|
+
idempotencyKey?: string;
|
|
68
70
|
}
|
|
69
71
|
/**
|
|
70
72
|
* Client construction options. See SPEC 2.1.
|
|
@@ -76,10 +78,12 @@ interface ClientOptions {
|
|
|
76
78
|
baseUrl?: string;
|
|
77
79
|
/** Custom fetch implementation. Defaults to globalThis.fetch. */
|
|
78
80
|
fetch?: typeof fetch;
|
|
79
|
-
/** Max retry attempts for retryable failures (429 + network). Default 2. */
|
|
81
|
+
/** Max retry attempts for retryable failures (429 + retry-safe network). Default 2. */
|
|
80
82
|
maxRetries?: number;
|
|
81
83
|
/** Per-request timeout in milliseconds. Default 60000. */
|
|
82
84
|
timeoutMs?: number;
|
|
85
|
+
/** Send Idempotency-Key on billed POSTs. Default "auto"; use "off" as a kill switch. */
|
|
86
|
+
idempotency?: "auto" | "off";
|
|
83
87
|
}
|
|
84
88
|
/**
|
|
85
89
|
* Account profile returned by /v1/me (internal-only fields dropped). See SPEC 2.7.
|
|
@@ -209,6 +213,7 @@ declare class AnyAPI$1 implements ClientCore {
|
|
|
209
213
|
private readonly fetchImpl;
|
|
210
214
|
private readonly maxRetries;
|
|
211
215
|
private readonly timeoutMs;
|
|
216
|
+
private readonly idempotency;
|
|
212
217
|
/**
|
|
213
218
|
* The network seam the generated per-platform namespaces target. The base client IS a
|
|
214
219
|
* ClientCore (it implements `run`), so the generated subclass hands `this._core` to each
|
|
@@ -245,6 +250,7 @@ declare class AnyAPI$1 implements ClientCore {
|
|
|
245
250
|
timeoutMs: number;
|
|
246
251
|
maxRetries: number;
|
|
247
252
|
signal?: AbortSignal;
|
|
253
|
+
idempotencyKey?: string;
|
|
248
254
|
}): Promise<T>;
|
|
249
255
|
/** Internal accessor for GET helpers in account.ts (same base URL / machinery). */
|
|
250
256
|
protected get gatewayBaseUrl(): string;
|
|
@@ -290,7 +296,9 @@ declare class AnyAPIError extends Error {
|
|
|
290
296
|
readonly status: number;
|
|
291
297
|
/** The x-request-id response header when present, else undefined. */
|
|
292
298
|
readonly requestId?: string;
|
|
293
|
-
|
|
299
|
+
/** Stable gateway error code when the JSON body includes one, else undefined. */
|
|
300
|
+
readonly code?: string;
|
|
301
|
+
constructor(message: string, status: number, requestId?: string, code?: string);
|
|
294
302
|
}
|
|
295
303
|
/** HTTP 400. */
|
|
296
304
|
declare class BadRequestError extends AnyAPIError {
|
|
@@ -3982,7 +3990,7 @@ interface EmailFindData {
|
|
|
3982
3990
|
*/
|
|
3983
3991
|
interface EmailVerifyInput {
|
|
3984
3992
|
/**
|
|
3985
|
-
* The email address to verify (e.g. jane.doe@acme.com).
|
|
3993
|
+
* The email address to verify (e.g. jane.doe@acme.com). Exactly one @, a dotted domain, no whitespace or angle brackets. Addresses on reserved, never-deliverable TLDs (.invalid, .test, .example, .localhost, .local, .internal, .blink) and HTML/JSON escape artifacts (a u003e prefix) are rejected locally with no charge.
|
|
3986
3994
|
*/
|
|
3987
3995
|
email: string;
|
|
3988
3996
|
}
|
|
@@ -4021,7 +4029,7 @@ interface EmailVerifyItem {
|
|
|
4021
4029
|
*/
|
|
4022
4030
|
interface EmailVerifyData {
|
|
4023
4031
|
/**
|
|
4024
|
-
* Verification records: the email address with its deliverability verdict and
|
|
4032
|
+
* Verification records: the email address with its deliverability verdict and the domain, mailbox, and reputation signals behind it. A record is returned for every syntactically valid address, including ones the verdict marks undeliverable. Populated whenever the provider has data for the entity.
|
|
4025
4033
|
*/
|
|
4026
4034
|
items: EmailVerifyItem[];
|
|
4027
4035
|
}
|
|
@@ -4046,7 +4054,7 @@ declare class EmailNamespace {
|
|
|
4046
4054
|
/**
|
|
4047
4055
|
* Email Verifier
|
|
4048
4056
|
*
|
|
4049
|
-
* Verify
|
|
4057
|
+
* Verify an email address for deliverability: a status verdict (valid, risky, or invalid) with domain, mailbox, catch-all, disposable, and role signals plus a confidence score. Malformed addresses are rejected by the input schema with no charge; every syntactically valid address returns a billed verdict, including undeliverable ones.
|
|
4050
4058
|
*
|
|
4051
4059
|
* Price: $0 per request plus $0.0008 per result (maximum $0.0008).
|
|
4052
4060
|
*
|
|
@@ -4364,7 +4372,7 @@ interface FacebookCommentRepliesData {
|
|
|
4364
4372
|
*/
|
|
4365
4373
|
interface FacebookCompanyAdsInput {
|
|
4366
4374
|
/**
|
|
4367
|
-
* Company name to search (e.g. "nike").
|
|
4375
|
+
* Company name to search (e.g. "nike"). Exact-match and case-sensitive against the Meta Ad Library index; an advertiser with no indexed page returns found:false.
|
|
4368
4376
|
*/
|
|
4369
4377
|
companyName?: string;
|
|
4370
4378
|
/**
|
|
@@ -24764,7 +24772,7 @@ declare class AnyAPI extends AnyAPI$1 {
|
|
|
24764
24772
|
* result type from the SkuMap; any other string returns RunResult<unknown>.
|
|
24765
24773
|
*/
|
|
24766
24774
|
run<K extends keyof SkuMap>(slug: K, input: SkuMap[K]["input"], options?: RequestOptions): Promise<SkuMap[K]["result"]>;
|
|
24767
|
-
run<S extends string
|
|
24775
|
+
run<T = unknown, S extends string = string>(slug: S extends keyof SkuMap ? never : S, input: unknown, options?: RequestOptions): Promise<RunResult<T>>;
|
|
24768
24776
|
/**
|
|
24769
24777
|
* Typed methods for the ahrefs platform.
|
|
24770
24778
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -65,6 +65,8 @@ interface RequestOptions {
|
|
|
65
65
|
signal?: AbortSignal;
|
|
66
66
|
/** Override the client maxRetries for this call. */
|
|
67
67
|
maxRetries?: number;
|
|
68
|
+
/** Override the generated Idempotency-Key for this billed POST. */
|
|
69
|
+
idempotencyKey?: string;
|
|
68
70
|
}
|
|
69
71
|
/**
|
|
70
72
|
* Client construction options. See SPEC 2.1.
|
|
@@ -76,10 +78,12 @@ interface ClientOptions {
|
|
|
76
78
|
baseUrl?: string;
|
|
77
79
|
/** Custom fetch implementation. Defaults to globalThis.fetch. */
|
|
78
80
|
fetch?: typeof fetch;
|
|
79
|
-
/** Max retry attempts for retryable failures (429 + network). Default 2. */
|
|
81
|
+
/** Max retry attempts for retryable failures (429 + retry-safe network). Default 2. */
|
|
80
82
|
maxRetries?: number;
|
|
81
83
|
/** Per-request timeout in milliseconds. Default 60000. */
|
|
82
84
|
timeoutMs?: number;
|
|
85
|
+
/** Send Idempotency-Key on billed POSTs. Default "auto"; use "off" as a kill switch. */
|
|
86
|
+
idempotency?: "auto" | "off";
|
|
83
87
|
}
|
|
84
88
|
/**
|
|
85
89
|
* Account profile returned by /v1/me (internal-only fields dropped). See SPEC 2.7.
|
|
@@ -209,6 +213,7 @@ declare class AnyAPI$1 implements ClientCore {
|
|
|
209
213
|
private readonly fetchImpl;
|
|
210
214
|
private readonly maxRetries;
|
|
211
215
|
private readonly timeoutMs;
|
|
216
|
+
private readonly idempotency;
|
|
212
217
|
/**
|
|
213
218
|
* The network seam the generated per-platform namespaces target. The base client IS a
|
|
214
219
|
* ClientCore (it implements `run`), so the generated subclass hands `this._core` to each
|
|
@@ -245,6 +250,7 @@ declare class AnyAPI$1 implements ClientCore {
|
|
|
245
250
|
timeoutMs: number;
|
|
246
251
|
maxRetries: number;
|
|
247
252
|
signal?: AbortSignal;
|
|
253
|
+
idempotencyKey?: string;
|
|
248
254
|
}): Promise<T>;
|
|
249
255
|
/** Internal accessor for GET helpers in account.ts (same base URL / machinery). */
|
|
250
256
|
protected get gatewayBaseUrl(): string;
|
|
@@ -290,7 +296,9 @@ declare class AnyAPIError extends Error {
|
|
|
290
296
|
readonly status: number;
|
|
291
297
|
/** The x-request-id response header when present, else undefined. */
|
|
292
298
|
readonly requestId?: string;
|
|
293
|
-
|
|
299
|
+
/** Stable gateway error code when the JSON body includes one, else undefined. */
|
|
300
|
+
readonly code?: string;
|
|
301
|
+
constructor(message: string, status: number, requestId?: string, code?: string);
|
|
294
302
|
}
|
|
295
303
|
/** HTTP 400. */
|
|
296
304
|
declare class BadRequestError extends AnyAPIError {
|
|
@@ -3982,7 +3990,7 @@ interface EmailFindData {
|
|
|
3982
3990
|
*/
|
|
3983
3991
|
interface EmailVerifyInput {
|
|
3984
3992
|
/**
|
|
3985
|
-
* The email address to verify (e.g. jane.doe@acme.com).
|
|
3993
|
+
* The email address to verify (e.g. jane.doe@acme.com). Exactly one @, a dotted domain, no whitespace or angle brackets. Addresses on reserved, never-deliverable TLDs (.invalid, .test, .example, .localhost, .local, .internal, .blink) and HTML/JSON escape artifacts (a u003e prefix) are rejected locally with no charge.
|
|
3986
3994
|
*/
|
|
3987
3995
|
email: string;
|
|
3988
3996
|
}
|
|
@@ -4021,7 +4029,7 @@ interface EmailVerifyItem {
|
|
|
4021
4029
|
*/
|
|
4022
4030
|
interface EmailVerifyData {
|
|
4023
4031
|
/**
|
|
4024
|
-
* Verification records: the email address with its deliverability verdict and
|
|
4032
|
+
* Verification records: the email address with its deliverability verdict and the domain, mailbox, and reputation signals behind it. A record is returned for every syntactically valid address, including ones the verdict marks undeliverable. Populated whenever the provider has data for the entity.
|
|
4025
4033
|
*/
|
|
4026
4034
|
items: EmailVerifyItem[];
|
|
4027
4035
|
}
|
|
@@ -4046,7 +4054,7 @@ declare class EmailNamespace {
|
|
|
4046
4054
|
/**
|
|
4047
4055
|
* Email Verifier
|
|
4048
4056
|
*
|
|
4049
|
-
* Verify
|
|
4057
|
+
* Verify an email address for deliverability: a status verdict (valid, risky, or invalid) with domain, mailbox, catch-all, disposable, and role signals plus a confidence score. Malformed addresses are rejected by the input schema with no charge; every syntactically valid address returns a billed verdict, including undeliverable ones.
|
|
4050
4058
|
*
|
|
4051
4059
|
* Price: $0 per request plus $0.0008 per result (maximum $0.0008).
|
|
4052
4060
|
*
|
|
@@ -4364,7 +4372,7 @@ interface FacebookCommentRepliesData {
|
|
|
4364
4372
|
*/
|
|
4365
4373
|
interface FacebookCompanyAdsInput {
|
|
4366
4374
|
/**
|
|
4367
|
-
* Company name to search (e.g. "nike").
|
|
4375
|
+
* Company name to search (e.g. "nike"). Exact-match and case-sensitive against the Meta Ad Library index; an advertiser with no indexed page returns found:false.
|
|
4368
4376
|
*/
|
|
4369
4377
|
companyName?: string;
|
|
4370
4378
|
/**
|
|
@@ -24764,7 +24772,7 @@ declare class AnyAPI extends AnyAPI$1 {
|
|
|
24764
24772
|
* result type from the SkuMap; any other string returns RunResult<unknown>.
|
|
24765
24773
|
*/
|
|
24766
24774
|
run<K extends keyof SkuMap>(slug: K, input: SkuMap[K]["input"], options?: RequestOptions): Promise<SkuMap[K]["result"]>;
|
|
24767
|
-
run<S extends string
|
|
24775
|
+
run<T = unknown, S extends string = string>(slug: S extends keyof SkuMap ? never : S, input: unknown, options?: RequestOptions): Promise<RunResult<T>>;
|
|
24768
24776
|
/**
|
|
24769
24777
|
* Typed methods for the ahrefs platform.
|
|
24770
24778
|
*/
|
package/dist/index.js
CHANGED
|
@@ -4,13 +4,18 @@ var AnyAPIError = class extends Error {
|
|
|
4
4
|
status;
|
|
5
5
|
/** The x-request-id response header when present, else undefined. */
|
|
6
6
|
requestId;
|
|
7
|
-
|
|
7
|
+
/** Stable gateway error code when the JSON body includes one, else undefined. */
|
|
8
|
+
code;
|
|
9
|
+
constructor(message, status, requestId, code) {
|
|
8
10
|
super(message);
|
|
9
11
|
this.name = new.target.name;
|
|
10
12
|
this.status = status;
|
|
11
13
|
if (requestId !== void 0) {
|
|
12
14
|
this.requestId = requestId;
|
|
13
15
|
}
|
|
16
|
+
if (code !== void 0) {
|
|
17
|
+
this.code = code;
|
|
18
|
+
}
|
|
14
19
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
15
20
|
}
|
|
16
21
|
};
|
|
@@ -32,25 +37,72 @@ var ConnectionError = class extends AnyAPIError {
|
|
|
32
37
|
};
|
|
33
38
|
var TimeoutError = class extends AnyAPIError {
|
|
34
39
|
};
|
|
35
|
-
function errorFromStatus(status, message, requestId) {
|
|
40
|
+
function errorFromStatus(status, message, requestId, code) {
|
|
36
41
|
switch (status) {
|
|
37
42
|
case 400:
|
|
38
|
-
return new BadRequestError(message, status, requestId);
|
|
43
|
+
return new BadRequestError(message, status, requestId, code);
|
|
39
44
|
case 401:
|
|
40
|
-
return new AuthenticationError(message, status, requestId);
|
|
45
|
+
return new AuthenticationError(message, status, requestId, code);
|
|
41
46
|
case 402:
|
|
42
|
-
return new InsufficientBalanceError(message, status, requestId);
|
|
47
|
+
return new InsufficientBalanceError(message, status, requestId, code);
|
|
43
48
|
case 404:
|
|
44
|
-
return new NotFoundError(message, status, requestId);
|
|
49
|
+
return new NotFoundError(message, status, requestId, code);
|
|
45
50
|
case 429:
|
|
46
|
-
return new RateLimitedError(message, status, requestId);
|
|
51
|
+
return new RateLimitedError(message, status, requestId, code);
|
|
47
52
|
case 502:
|
|
48
|
-
return new UpstreamError(message, status, requestId);
|
|
53
|
+
return new UpstreamError(message, status, requestId, code);
|
|
49
54
|
default:
|
|
50
|
-
return new AnyAPIError(message, status, requestId);
|
|
55
|
+
return new AnyAPIError(message, status, requestId, code);
|
|
51
56
|
}
|
|
52
57
|
}
|
|
53
58
|
|
|
59
|
+
// src/core/idempotency.ts
|
|
60
|
+
var MAX_IDEMPOTENCY_KEY_BYTES = 255;
|
|
61
|
+
function generateIdempotencyKey() {
|
|
62
|
+
let runtimeCrypto;
|
|
63
|
+
try {
|
|
64
|
+
runtimeCrypto = globalThis.crypto;
|
|
65
|
+
} catch {
|
|
66
|
+
runtimeCrypto = void 0;
|
|
67
|
+
}
|
|
68
|
+
if (typeof runtimeCrypto?.randomUUID === "function") {
|
|
69
|
+
try {
|
|
70
|
+
return runtimeCrypto.randomUUID();
|
|
71
|
+
} catch {
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (typeof runtimeCrypto?.getRandomValues === "function") {
|
|
75
|
+
try {
|
|
76
|
+
const bytes = runtimeCrypto.getRandomValues(new Uint8Array(16));
|
|
77
|
+
return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
78
|
+
} catch {
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return Array.from(
|
|
82
|
+
{ length: 4 },
|
|
83
|
+
() => Math.floor(Math.random() * 4294967296).toString(16).padStart(8, "0")
|
|
84
|
+
).join("");
|
|
85
|
+
}
|
|
86
|
+
function validateIdempotencyKey(key) {
|
|
87
|
+
if (key.length === 0 || key.length > MAX_IDEMPOTENCY_KEY_BYTES || [...key].some((char) => {
|
|
88
|
+
const code = char.charCodeAt(0);
|
|
89
|
+
return code < 33 || code > 126;
|
|
90
|
+
})) {
|
|
91
|
+
throw new TypeError(
|
|
92
|
+
"idempotencyKey must be 1-255 bytes of visible ASCII (0x21-0x7e)"
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function pageIdempotencyKey(key, pageNumber) {
|
|
97
|
+
validateIdempotencyKey(key);
|
|
98
|
+
const suffix = `-p${pageNumber}`;
|
|
99
|
+
const prefixLength = MAX_IDEMPOTENCY_KEY_BYTES - suffix.length;
|
|
100
|
+
if (prefixLength < 1) {
|
|
101
|
+
throw new TypeError("pagination page number is too large for an idempotency key");
|
|
102
|
+
}
|
|
103
|
+
return `${key.slice(0, prefixLength)}${suffix}`;
|
|
104
|
+
}
|
|
105
|
+
|
|
54
106
|
// src/core/account.ts
|
|
55
107
|
var DEFAULT_BASE_URL = "https://api.getanyapi.com";
|
|
56
108
|
function malformed(path) {
|
|
@@ -359,14 +411,18 @@ async function agentSignup(options = {}) {
|
|
|
359
411
|
const text = await response.text().catch(() => "");
|
|
360
412
|
if (response.status !== 200) {
|
|
361
413
|
let message = `request failed with status ${response.status}`;
|
|
414
|
+
let code;
|
|
362
415
|
try {
|
|
363
416
|
const parsed2 = JSON.parse(text);
|
|
364
417
|
if (typeof parsed2.error === "string" && parsed2.error !== "") {
|
|
365
418
|
message = parsed2.error;
|
|
366
419
|
}
|
|
420
|
+
if (typeof parsed2.code === "string" && parsed2.code !== "") {
|
|
421
|
+
code = parsed2.code;
|
|
422
|
+
}
|
|
367
423
|
} catch {
|
|
368
424
|
}
|
|
369
|
-
throw errorFromStatus(response.status, message, requestId);
|
|
425
|
+
throw errorFromStatus(response.status, message, requestId, code);
|
|
370
426
|
}
|
|
371
427
|
const parsed = JSON.parse(text);
|
|
372
428
|
return {
|
|
@@ -383,6 +439,18 @@ var DEFAULT_TIMEOUT_MS = 6e4;
|
|
|
383
439
|
var DEFAULT_MAX_RETRIES = 2;
|
|
384
440
|
var RETRY_BASE_DELAY_MS = 500;
|
|
385
441
|
var RETRY_MAX_DELAY_MS = 8e3;
|
|
442
|
+
var PRE_SEND_NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
443
|
+
"EADDRNOTAVAIL",
|
|
444
|
+
"EAI_AGAIN",
|
|
445
|
+
"EAI_NODATA",
|
|
446
|
+
"EAI_NONAME",
|
|
447
|
+
"ECONNREFUSED",
|
|
448
|
+
"EHOSTUNREACH",
|
|
449
|
+
"ENETUNREACH",
|
|
450
|
+
"ENOTFOUND",
|
|
451
|
+
"UND_ERR_CONNECT_TIMEOUT",
|
|
452
|
+
"ConnectionRefused"
|
|
453
|
+
]);
|
|
386
454
|
function envApiKey() {
|
|
387
455
|
try {
|
|
388
456
|
if (typeof process !== "undefined" && process?.env) {
|
|
@@ -467,6 +535,33 @@ function isTimeoutSignal(timeoutSignal, callerSignal) {
|
|
|
467
535
|
}
|
|
468
536
|
return callerSignal?.aborted !== true || timeoutSignal.aborted;
|
|
469
537
|
}
|
|
538
|
+
function isDefinitelyPreSendConnectionError(error) {
|
|
539
|
+
const seen = /* @__PURE__ */ new Set();
|
|
540
|
+
const visit = (value) => {
|
|
541
|
+
if (typeof value !== "object" && typeof value !== "function" || value === null) {
|
|
542
|
+
return false;
|
|
543
|
+
}
|
|
544
|
+
if (seen.has(value)) {
|
|
545
|
+
return false;
|
|
546
|
+
}
|
|
547
|
+
seen.add(value);
|
|
548
|
+
const candidate = value;
|
|
549
|
+
if (typeof candidate.code === "string" && PRE_SEND_NETWORK_ERROR_CODES.has(candidate.code)) {
|
|
550
|
+
return true;
|
|
551
|
+
}
|
|
552
|
+
if (candidate.code === "ETIMEDOUT" && candidate.syscall === "connect") {
|
|
553
|
+
return true;
|
|
554
|
+
}
|
|
555
|
+
if (candidate.code === "UND_ERR_SOCKET" && candidate.socket?.bytesWritten === 0) {
|
|
556
|
+
return true;
|
|
557
|
+
}
|
|
558
|
+
if (Array.isArray(candidate.errors) && candidate.errors.length > 0) {
|
|
559
|
+
return candidate.errors.some((item) => visit(item)) || visit(candidate.cause);
|
|
560
|
+
}
|
|
561
|
+
return visit(candidate.cause);
|
|
562
|
+
};
|
|
563
|
+
return visit(error);
|
|
564
|
+
}
|
|
470
565
|
function buildUrl(baseUrl, slug, options) {
|
|
471
566
|
const base = baseUrl.replace(/\/+$/, "");
|
|
472
567
|
const url = new URL(`${base}/v1/run/${slug}`);
|
|
@@ -485,13 +580,21 @@ function messageFromBody(body, status) {
|
|
|
485
580
|
if (body) {
|
|
486
581
|
try {
|
|
487
582
|
const parsed = JSON.parse(body);
|
|
583
|
+
const code = typeof parsed.code === "string" && parsed.code !== "" ? parsed.code : void 0;
|
|
488
584
|
if (typeof parsed.error === "string" && parsed.error !== "") {
|
|
489
|
-
return
|
|
585
|
+
return {
|
|
586
|
+
message: parsed.error,
|
|
587
|
+
...code !== void 0 ? { code } : {}
|
|
588
|
+
};
|
|
490
589
|
}
|
|
590
|
+
return {
|
|
591
|
+
message: `request failed with status ${status}`,
|
|
592
|
+
...code !== void 0 ? { code } : {}
|
|
593
|
+
};
|
|
491
594
|
} catch {
|
|
492
595
|
}
|
|
493
596
|
}
|
|
494
|
-
return `request failed with status ${status}
|
|
597
|
+
return { message: `request failed with status ${status}` };
|
|
495
598
|
}
|
|
496
599
|
var AnyAPI = class {
|
|
497
600
|
apiKey;
|
|
@@ -499,6 +602,7 @@ var AnyAPI = class {
|
|
|
499
602
|
fetchImpl;
|
|
500
603
|
maxRetries;
|
|
501
604
|
timeoutMs;
|
|
605
|
+
idempotency;
|
|
502
606
|
/**
|
|
503
607
|
* The network seam the generated per-platform namespaces target. The base client IS a
|
|
504
608
|
* ClientCore (it implements `run`), so the generated subclass hands `this._core` to each
|
|
@@ -521,6 +625,11 @@ var AnyAPI = class {
|
|
|
521
625
|
this.fetchImpl = resolvedFetch;
|
|
522
626
|
this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
523
627
|
this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
628
|
+
const idempotency = options.idempotency ?? "auto";
|
|
629
|
+
if (idempotency !== "auto" && idempotency !== "off") {
|
|
630
|
+
throw new TypeError('idempotency must be "auto" or "off"');
|
|
631
|
+
}
|
|
632
|
+
this.idempotency = idempotency;
|
|
524
633
|
}
|
|
525
634
|
/**
|
|
526
635
|
* Generic run for any SKU by slug (the untyped network seam + the string fallback). The
|
|
@@ -528,13 +637,15 @@ var AnyAPI = class {
|
|
|
528
637
|
* base signature is the fallback that returns RunResult<unknown> for an unknown slug.
|
|
529
638
|
*/
|
|
530
639
|
run(slug, input, options) {
|
|
640
|
+
const body = JSON.stringify(input ?? {});
|
|
531
641
|
return this.request(
|
|
532
642
|
"POST",
|
|
533
643
|
buildUrl(this.baseUrl, slug, options),
|
|
534
644
|
{
|
|
535
|
-
body
|
|
645
|
+
body,
|
|
536
646
|
timeoutMs: options?.timeoutMs ?? this.timeoutMs,
|
|
537
647
|
maxRetries: options?.maxRetries ?? this.maxRetries,
|
|
648
|
+
...options?.idempotencyKey !== void 0 ? { idempotencyKey: options.idempotencyKey } : {},
|
|
538
649
|
...options?.signal ? { signal: options.signal } : {}
|
|
539
650
|
}
|
|
540
651
|
);
|
|
@@ -599,6 +710,12 @@ var AnyAPI = class {
|
|
|
599
710
|
if (this.apiKey) {
|
|
600
711
|
headers["Authorization"] = `Bearer ${this.apiKey}`;
|
|
601
712
|
}
|
|
713
|
+
const billedPost = method === "POST" && opts.body !== void 0;
|
|
714
|
+
if (billedPost && this.idempotency === "auto") {
|
|
715
|
+
const key = opts.idempotencyKey ?? generateIdempotencyKey();
|
|
716
|
+
validateIdempotencyKey(key);
|
|
717
|
+
headers["Idempotency-Key"] = key;
|
|
718
|
+
}
|
|
602
719
|
let attempt = 0;
|
|
603
720
|
for (; ; ) {
|
|
604
721
|
const { signal, timeoutSignal } = composeSignal(
|
|
@@ -624,7 +741,9 @@ var AnyAPI = class {
|
|
|
624
741
|
err instanceof Error ? err.message : "connection failed",
|
|
625
742
|
0
|
|
626
743
|
);
|
|
627
|
-
|
|
744
|
+
const requestMayBeBilled = method === "POST" && opts.body !== void 0;
|
|
745
|
+
const safeToRetry = !requestMayBeBilled || isDefinitelyPreSendConnectionError(err);
|
|
746
|
+
if (safeToRetry && attempt < opts.maxRetries) {
|
|
628
747
|
await sleep(backoffDelay(attempt), opts.signal);
|
|
629
748
|
attempt += 1;
|
|
630
749
|
continue;
|
|
@@ -645,7 +764,7 @@ var AnyAPI = class {
|
|
|
645
764
|
}
|
|
646
765
|
}
|
|
647
766
|
const body = await response.text().catch(() => "");
|
|
648
|
-
const message = messageFromBody(body, response.status);
|
|
767
|
+
const { message, code } = messageFromBody(body, response.status);
|
|
649
768
|
if (response.status === 429 && attempt < opts.maxRetries) {
|
|
650
769
|
const retryAfter = parseRetryAfter(response.headers.get("retry-after"));
|
|
651
770
|
const delay = retryAfter ?? backoffDelay(attempt);
|
|
@@ -653,7 +772,7 @@ var AnyAPI = class {
|
|
|
653
772
|
attempt += 1;
|
|
654
773
|
continue;
|
|
655
774
|
}
|
|
656
|
-
throw errorFromStatus(response.status, message, requestId);
|
|
775
|
+
throw errorFromStatus(response.status, message, requestId, code);
|
|
657
776
|
}
|
|
658
777
|
}
|
|
659
778
|
/** Internal accessor for GET helpers in account.ts (same base URL / machinery). */
|
|
@@ -698,12 +817,14 @@ function paginate(core, slug, input, itemsField, bare, options) {
|
|
|
698
817
|
const maxItems = options?.maxItems;
|
|
699
818
|
async function* walkPages() {
|
|
700
819
|
let cursor;
|
|
820
|
+
let pageNumber = 1;
|
|
701
821
|
for (; ; ) {
|
|
702
822
|
const pageInput = { ...input };
|
|
703
823
|
if (cursor !== void 0) {
|
|
704
824
|
pageInput["cursor"] = cursor;
|
|
705
825
|
}
|
|
706
|
-
const
|
|
826
|
+
const pageOptions = optionsForPage(wireOptions, pageNumber);
|
|
827
|
+
const result = await core.run(slug, pageInput, pageOptions);
|
|
707
828
|
yield result;
|
|
708
829
|
const data = pageData(result, bare);
|
|
709
830
|
if (data === null) {
|
|
@@ -714,6 +835,7 @@ function paginate(core, slug, input, itemsField, bare, options) {
|
|
|
714
835
|
return;
|
|
715
836
|
}
|
|
716
837
|
cursor = next;
|
|
838
|
+
pageNumber += 1;
|
|
717
839
|
}
|
|
718
840
|
}
|
|
719
841
|
async function* walkItems() {
|
|
@@ -745,6 +867,15 @@ function paginate(core, slug, input, itemsField, bare, options) {
|
|
|
745
867
|
};
|
|
746
868
|
return paginator;
|
|
747
869
|
}
|
|
870
|
+
function optionsForPage(options, pageNumber) {
|
|
871
|
+
if (options?.idempotencyKey === void 0) {
|
|
872
|
+
return options;
|
|
873
|
+
}
|
|
874
|
+
return {
|
|
875
|
+
...options,
|
|
876
|
+
idempotencyKey: pageIdempotencyKey(options.idempotencyKey, pageNumber)
|
|
877
|
+
};
|
|
878
|
+
}
|
|
748
879
|
function stripMaxItems(options) {
|
|
749
880
|
if (!options) {
|
|
750
881
|
return void 0;
|
|
@@ -1322,7 +1453,7 @@ var EmailNamespace = class {
|
|
|
1322
1453
|
/**
|
|
1323
1454
|
* Email Verifier
|
|
1324
1455
|
*
|
|
1325
|
-
* Verify
|
|
1456
|
+
* Verify an email address for deliverability: a status verdict (valid, risky, or invalid) with domain, mailbox, catch-all, disposable, and role signals plus a confidence score. Malformed addresses are rejected by the input schema with no charge; every syntactically valid address returns a billed verdict, including undeliverable ones.
|
|
1326
1457
|
*
|
|
1327
1458
|
* Price: $0 per request plus $0.0008 per result (maximum $0.0008).
|
|
1328
1459
|
*
|