@parseapi/sdk 1.7.0 → 1.9.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 +103 -13
- package/dist/index.cjs +61 -23
- package/dist/index.d.cts +459 -38
- package/dist/index.d.ts +459 -38
- package/dist/index.js +61 -23
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
var VERSION = "1.
|
|
2
|
+
var VERSION = "1.9.0";
|
|
3
3
|
var API_VERSION = "2.0.0";
|
|
4
4
|
var DEFAULT_BASE_URL = "https://api.parseapi.com";
|
|
5
5
|
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
@@ -15,13 +15,16 @@ var ParseAPIError = class extends Error {
|
|
|
15
15
|
docs;
|
|
16
16
|
/** Send this if you contact support */
|
|
17
17
|
requestId;
|
|
18
|
-
|
|
18
|
+
/** Original Retry-After response header, when supplied. */
|
|
19
|
+
retryAfter;
|
|
20
|
+
constructor(status, code, message, docs, requestId, retryAfter = null) {
|
|
19
21
|
super(message);
|
|
20
22
|
this.name = "ParseAPIError";
|
|
21
23
|
this.status = status;
|
|
22
24
|
this.code = code;
|
|
23
25
|
this.docs = docs;
|
|
24
26
|
this.requestId = requestId;
|
|
27
|
+
this.retryAfter = retryAfter;
|
|
25
28
|
}
|
|
26
29
|
};
|
|
27
30
|
function tariffSelection(result, opts) {
|
|
@@ -30,6 +33,7 @@ function tariffSelection(result, opts) {
|
|
|
30
33
|
}
|
|
31
34
|
return result;
|
|
32
35
|
}
|
|
36
|
+
var requestControls = (opts) => ({ signal: opts?.signal, timeoutMs: opts?.timeoutMs, retries: opts?.retries });
|
|
33
37
|
function env(name) {
|
|
34
38
|
return typeof process !== "undefined" ? process.env?.[name] : void 0;
|
|
35
39
|
}
|
|
@@ -66,16 +70,20 @@ function metered(path, query) {
|
|
|
66
70
|
}
|
|
67
71
|
function retryDelayMs(attempt, retryAfter) {
|
|
68
72
|
if (retryAfter) {
|
|
69
|
-
const
|
|
70
|
-
if (
|
|
71
|
-
|
|
73
|
+
const value = retryAfter.trim();
|
|
74
|
+
if (/^[0-9]+(?:\.[0-9]+)?$/.test(value)) {
|
|
75
|
+
const seconds = Number(value);
|
|
76
|
+
return seconds > RETRY_AFTER_CAP_MS / 1e3 ? null : seconds * 1e3;
|
|
72
77
|
}
|
|
73
|
-
if (
|
|
74
|
-
const date = Date.parse(
|
|
75
|
-
if (Number.isFinite(date))
|
|
78
|
+
if (/^[A-Za-z]{3,9},? /.test(value)) {
|
|
79
|
+
const date = Date.parse(value);
|
|
80
|
+
if (Number.isFinite(date)) {
|
|
81
|
+
const delay = Math.max(date - Date.now(), 0);
|
|
82
|
+
return delay > RETRY_AFTER_CAP_MS ? null : delay;
|
|
83
|
+
}
|
|
76
84
|
}
|
|
77
85
|
}
|
|
78
|
-
return Math.random() * 250 * 2 ** attempt;
|
|
86
|
+
return Math.random() * Math.min(250 * 2 ** Math.min(attempt, 16), RETRY_AFTER_CAP_MS);
|
|
79
87
|
}
|
|
80
88
|
function parseAPI(apiKey, options = {}) {
|
|
81
89
|
const key = apiKey || env("PARSEAPI_KEY");
|
|
@@ -108,7 +116,7 @@ function parseAPI(apiKey, options = {}) {
|
|
|
108
116
|
const onAbort = () => controller.abort(signal.reason);
|
|
109
117
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
110
118
|
const timer = setTimeout(() => controller.abort(new DOMException("Request timed out", "TimeoutError")), attemptTimeout);
|
|
111
|
-
let
|
|
119
|
+
let retryDelay;
|
|
112
120
|
try {
|
|
113
121
|
let res;
|
|
114
122
|
try {
|
|
@@ -134,8 +142,8 @@ function parseAPI(apiKey, options = {}) {
|
|
|
134
142
|
res = void 0;
|
|
135
143
|
}
|
|
136
144
|
}
|
|
137
|
-
if (res
|
|
138
|
-
|
|
145
|
+
if (res) retryDelay = retryDelayMs(attempt, res.headers.get("Retry-After"));
|
|
146
|
+
if (res && RETRY_STATUS.has(res.status) && attempt < retries && retryDelay !== null) {
|
|
139
147
|
await res.body?.cancel().catch(() => {
|
|
140
148
|
});
|
|
141
149
|
} else if (res) {
|
|
@@ -152,14 +160,15 @@ function parseAPI(apiKey, options = {}) {
|
|
|
152
160
|
typeof body2.code === "string" ? body2.code : "unknown_error",
|
|
153
161
|
typeof body2.message === "string" ? body2.message : `Request failed with status ${res.status}`,
|
|
154
162
|
typeof body2.docs === "string" ? body2.docs : null,
|
|
155
|
-
typeof body2.request_id === "string" ? body2.request_id : null
|
|
163
|
+
typeof body2.request_id === "string" ? body2.request_id : null,
|
|
164
|
+
res.headers.get("Retry-After")
|
|
156
165
|
);
|
|
157
166
|
}
|
|
158
167
|
} finally {
|
|
159
168
|
clearTimeout(timer);
|
|
160
169
|
signal?.removeEventListener("abort", onAbort);
|
|
161
170
|
}
|
|
162
|
-
await sleep(retryDelayMs(attempt,
|
|
171
|
+
await sleep(retryDelay ?? retryDelayMs(attempt, null), signal);
|
|
163
172
|
}
|
|
164
173
|
}
|
|
165
174
|
const enc = encodeURIComponent;
|
|
@@ -173,6 +182,12 @@ function parseAPI(apiKey, options = {}) {
|
|
|
173
182
|
for (const [name, value2] of Object.entries(query)) url.searchParams.set(name, String(value2));
|
|
174
183
|
return !numericJson && url.href.length <= 8e3 ? request("/elevation", query, void 0, opts) : request("/elevation", void 0, void 0, opts, { [selector]: coordinates, ...sampling });
|
|
175
184
|
}
|
|
185
|
+
const industry = Object.assign(
|
|
186
|
+
(code, opts) => request(`/industry/${enc(code)}`, deepQuery(opts), void 0, opts),
|
|
187
|
+
{
|
|
188
|
+
search: (query, opts) => request("/industry", { q: query, limit: opts?.limit, ...deepQuery(opts) }, void 0, opts)
|
|
189
|
+
}
|
|
190
|
+
);
|
|
176
191
|
return {
|
|
177
192
|
/** Estimate task access, capacity and additional charges. Requires a secret key. Reserves no units or money and does not enforce the supplied budget. */
|
|
178
193
|
preflight: (task, opts) => request("/preflight", void 0, void 0, opts, task),
|
|
@@ -245,7 +260,17 @@ function parseAPI(apiKey, options = {}) {
|
|
|
245
260
|
search: (query, opts) => request("/address", { q: query, country: opts?.country, postal: opts?.postal, city: opts?.city, state: opts?.state, ip: opts?.ip }, void 0, opts)
|
|
246
261
|
}
|
|
247
262
|
),
|
|
248
|
-
company: (
|
|
263
|
+
company: Object.assign(
|
|
264
|
+
(number, opts) => request(`/company/${enc(number)}`, { country: opts?.country, ...deepQuery(opts) }, void 0, opts),
|
|
265
|
+
{
|
|
266
|
+
/** Look up a stable directory ID. Requested deep belongs to this profile. */
|
|
267
|
+
id: (id, opts) => request(`/company/id/${enc(id)}`, deepQuery(opts), void 0, requestControls(opts)),
|
|
268
|
+
/** Return candidates without selecting a match. Use one selector, country, exact industry, filters. */
|
|
269
|
+
search: (opts) => request("/company", { q: opts.query, domain: opts.domain, ticker: opts.ticker, identifier: opts.identifier, country: opts.country, industry: opts.industry, industry_type: opts.industry_type, exchange: opts.exchange, authority: opts.authority, limit: opts.limit, cursor: opts.cursor, ...deepQuery(opts) }, void 0, requestControls(opts)),
|
|
270
|
+
/** Describe the directory edition and its counts. Counts do not establish complete country coverage. */
|
|
271
|
+
coverage: (opts) => request("/company/directory/coverage", void 0, void 0, requestControls(opts))
|
|
272
|
+
}
|
|
273
|
+
),
|
|
249
274
|
/**
|
|
250
275
|
* Parse an email and check its format and domain.
|
|
251
276
|
* `deep: true` explicitly requests a metered deliverability check using included checks or enabled on-demand usage.
|
|
@@ -258,8 +283,16 @@ function parseAPI(apiKey, options = {}) {
|
|
|
258
283
|
from: opts?.from,
|
|
259
284
|
...deepQuery(opts)
|
|
260
285
|
}, void 0, opts),
|
|
286
|
+
// Keep existing callers on their established HTTP contracts.
|
|
261
287
|
iban: (iban, opts) => request(`/iban/${enc(iban)}`, { country: opts?.country, ...deepQuery(opts) }, void 0, opts),
|
|
288
|
+
bin: (bin, opts) => request(`/bin/${enc(bin)}`, { deep: opts?.deep }, void 0, opts),
|
|
262
289
|
npi: (npi, opts) => request(`/npi/${enc(npi)}`, deepQuery(opts), void 0, opts),
|
|
290
|
+
bank: (iban, opts) => request("/bank", void 0, void 0, opts, { iban, country: opts?.country, deep: opts?.deep }),
|
|
291
|
+
/** Check US routing/account syntax using POST. Does not verify ownership, existence or ACH eligibility. */
|
|
292
|
+
bankUsAch: (input, opts) => request("/bank", void 0, void 0, opts, { format: "us_ach", country: "US", routing: input.routing, account: input.account }),
|
|
293
|
+
/** Describe supported input fields and check scope; this does not establish country directory coverage. */
|
|
294
|
+
bankRequirements: (country, opts) => request("/bank/requirements", { country, format: opts?.format }, void 0, opts),
|
|
295
|
+
provider: (npi, opts) => request(`/provider/${enc(npi)}`, deepQuery(opts), void 0, opts),
|
|
263
296
|
/** Parse a phone number and its formats. Pass country for national numbers when needed. Deep adds numbering-plan geography. */
|
|
264
297
|
phone: (number, opts) => request(`/phone/${enc(number)}`, { country: opts?.country, ...deepQuery(opts) }, void 0, opts),
|
|
265
298
|
/** Request a metered carrier lookup. No automatic retries by default. */
|
|
@@ -274,8 +307,13 @@ function parseAPI(apiKey, options = {}) {
|
|
|
274
307
|
domain: (domain, opts) => request(`/domain/${enc(domain)}`, deepQuery(opts), void 0, opts),
|
|
275
308
|
asn: (asn, opts) => request(`/asn/${enc(asn)}`, void 0, void 0, opts),
|
|
276
309
|
mac: (mac, opts) => request(`/mac/${enc(mac)}`, void 0, void 0, opts),
|
|
277
|
-
/** Look up a
|
|
278
|
-
|
|
310
|
+
/** Look up a 2-11 digit card prefix. Keep leading zeros in the input string. */
|
|
311
|
+
card: async (bin, opts) => {
|
|
312
|
+
if (typeof bin !== "string" || bin.length > 64 || !/^[0-9]{2,11}$/.test(bin.replace(/[ \t\r\n-]/g, ""))) {
|
|
313
|
+
throw new TypeError("parseAPI: Card requires a string containing 2 to 11 digits. Send a prefix only.");
|
|
314
|
+
}
|
|
315
|
+
return request(`/card/${enc(bin)}`, deepQuery(opts), void 0, opts);
|
|
316
|
+
},
|
|
279
317
|
/** Parse a measurement or convert it to `to`. Without `to`, use its type's canonical unit. Invalid input is plain data with `valid: false`. */
|
|
280
318
|
measure: Object.assign(
|
|
281
319
|
(measure, opts) => request(`/measure/${enc(measure)}`, { to: opts?.to, locale: opts?.locale, system: opts?.system }, void 0, opts),
|
|
@@ -288,14 +326,14 @@ function parseAPI(apiKey, options = {}) {
|
|
|
288
326
|
dns: (domain, opts) => request(`/dns/${enc(domain)}`, { type: opts?.type }, void 0, opts),
|
|
289
327
|
mx: (domain, opts) => request(`/mx/${enc(domain)}`, void 0, void 0, opts),
|
|
290
328
|
useragent: (ua, opts) => request("/useragent", deepQuery(opts), { "User-Agent": ua }, opts),
|
|
329
|
+
/** Identify a vehicle by VIN. Paid deep adds specifications and model-level recall campaigns. */
|
|
330
|
+
vehicle: (vin, opts) => request(`/vehicle/${enc(vin)}`, deepQuery(opts), void 0, opts),
|
|
331
|
+
/** Compatibility entry for VIN callers. */
|
|
291
332
|
vin: (vin, opts) => request(`/vin/${enc(vin)}`, deepQuery(opts), void 0, opts),
|
|
292
333
|
/** US NAICS 2022 definitions and hierarchy. */
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
search: (query, opts) => request("/naics", { q: query, limit: opts?.limit, ...deepQuery(opts) }, void 0, opts)
|
|
297
|
-
}
|
|
298
|
-
),
|
|
334
|
+
industry,
|
|
335
|
+
/** Compatibility name for industry. */
|
|
336
|
+
naics: industry,
|
|
299
337
|
/** Look up the general US duty schedule line. Paid deep adds units and the special and other schedule columns. Add origin with deep to resolve country-specific measures. Without origin, schedule detail remains available and origin-dependent fields are null. A null effective rate is not a zero rate. */
|
|
300
338
|
tariff: Object.assign(
|
|
301
339
|
(code, opts) => request(`/tariff/${enc(code)}`, { origin: opts?.origin, edition: opts?.edition, date: opts?.date, ...deepQuery(opts) }, void 0, opts).then((result) => tariffSelection(result, opts)),
|