@parseapi/sdk 1.11.4 → 1.12.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
@@ -41,6 +41,34 @@ Preflight accepts Email, Domain, DNS, MX and Country, with at most 20 rows and 1
41
41
 
42
42
  Check `permitted`, `cost.status`, `capacity` and the optional `budget.within_maximum` together. Unknown values remain null. Capacity can change with concurrent work. Preflight reserves no units or money, performs no paid checks and does not enforce the supplied budget. It uses the normal request rate limit. Estimates allow up to three attempts per ordinary lookup and one per Email Deep lookup. Extra retries or calls require a new estimate. Subscription fees, tax and model costs are excluded.
43
43
 
44
+ ## Bulk files
45
+
46
+ Use `createBulkClient` for whole files. It uses the website origin separately from the lookup client's API origin.
47
+
48
+ ```ts
49
+ import { createBulkClient } from '@parseapi/sdk';
50
+
51
+ const bulk = createBulkClient(process.env.PARSEAPI_KEY);
52
+ const upload = await bulk.upload({ filename: 'customers.csv', file_size: csvBytes.byteLength });
53
+ await fetch(upload.upload_url, {
54
+ method: 'PUT', headers: upload.upload_headers, body: csvBytes,
55
+ });
56
+ await bulk.preview(upload.id); // Confirm the completed upload and request analysis.
57
+ const progress = await bulk.status(upload.id);
58
+ ```
59
+
60
+ `csvBytes` comes from your application. Convert Excel or Numbers to CSV before creating the upload. File contents transfer directly to private storage and are never sent through MCP.
61
+
62
+ Analysis may take time. Poll `status` until `job.status` is `quoted`. Then call `bulk.preview(id, { checks: ['email', 'phone', 'ip'] })` to select operations present in the file, or omit `checks` to retain the detected selection. A changed selection requests analysis again. Repeat status and preview until the response includes a current `quote`.
63
+
64
+ After the user approves the work and maximum USD cost, call `bulk.start(id, { quote_id: preview.quote.id, max_cost_cents })`. The server enforces that ceiling and returns any payment or setup action. A positive ceiling does not authorize a saved-card charge. Reuse the same job and quote when recovering a start request.
65
+
66
+ When processing finishes, `bulk.result(id)` returns a short-lived private `download_url`. Fetch that URL directly without adding an API key header. All methods return bounded JSON metadata and preserve nullable and future server fields. They never retry automatically. If upload creation has an uncertain outcome, check the account before creating another job.
67
+
68
+ Existing Bulk job URLs remain shareable. Treat job IDs and download URLs as file-access capabilities.
69
+
70
+ Options are `webUrl`, `timeoutMs` and `fetch`. `PARSEAPI_WEB_URL` can set the website origin. HTTPS origins and HTTP loopback origins are accepted. Lookup `baseUrl` and `PARSEAPI_BASE_URL` stay independent.
71
+
44
72
  ## Weather from a postal code
45
73
 
46
74
  Start with the postal code, then pass its coordinates to weather. Reuse the client from the example above.
package/dist/index.cjs CHANGED
@@ -20,13 +20,176 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ BULK_CHECKS: () => BULK_CHECKS,
24
+ BulkAPIError: () => ParseAPIError,
23
25
  EmojiCatalog: () => EmojiCatalog,
24
26
  EmojiCatalogError: () => EmojiCatalogError,
25
27
  ParseAPIError: () => ParseAPIError,
28
+ createBulkClient: () => createBulkClient,
26
29
  parseAPI: () => parseAPI
27
30
  });
28
31
  module.exports = __toCommonJS(index_exports);
29
32
 
33
+ // src/errors.ts
34
+ var ParseAPIError = class extends Error {
35
+ /** HTTP status */
36
+ status;
37
+ /** Machine-readable error code, e.g. 'not_found', 'invalid_api_key', 'rate_limited' */
38
+ code;
39
+ /** Link to the docs section for this error */
40
+ docs;
41
+ /** Send this if you contact support */
42
+ requestId;
43
+ /** Original Retry-After response header, when supplied. */
44
+ retryAfter;
45
+ constructor(status, code, message, docs = null, requestId = null, retryAfter = null) {
46
+ super(message);
47
+ this.name = "ParseAPIError";
48
+ this.status = status;
49
+ this.code = code;
50
+ this.docs = docs;
51
+ this.requestId = requestId;
52
+ this.retryAfter = retryAfter;
53
+ }
54
+ };
55
+
56
+ // src/bulk.ts
57
+ var BULK_CHECKS = ["email", "phone", "carrier", "caller", "hlr", "ip", "domain", "useragent", "country", "postal", "address", "name", "date"];
58
+ var MAX_RESPONSE_BYTES = 256 * 1024;
59
+ var jobId = /^job_[23456789abcdefghjkmnpqrstuvwxyz]{14}$/;
60
+ var invalidResponse = () => new ParseAPIError(502, "invalid_api_response", "The Bulk service returned an invalid response.");
61
+ function origin(value) {
62
+ let url;
63
+ try {
64
+ url = new URL(value);
65
+ } catch {
66
+ throw new TypeError("ParseAPI Bulk webUrl must be an HTTPS origin.");
67
+ }
68
+ const loopback = url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "[::1]";
69
+ if (url.protocol !== "https:" && !(url.protocol === "http:" && loopback) || url.username || url.password || url.pathname !== "/" || url.search || url.hash) {
70
+ throw new TypeError("ParseAPI Bulk webUrl must be an HTTPS origin, or HTTP on loopback.");
71
+ }
72
+ return url.origin;
73
+ }
74
+ async function boundedJson(response) {
75
+ const length = response.headers.get("content-length");
76
+ if (length && /^\d+$/.test(length) && Number(length) > MAX_RESPONSE_BYTES) {
77
+ await response.body?.cancel().catch(() => {
78
+ });
79
+ throw invalidResponse();
80
+ }
81
+ if (!response.body) throw invalidResponse();
82
+ const reader = response.body.getReader();
83
+ const decoder = new TextDecoder();
84
+ let size = 0, text = "";
85
+ try {
86
+ while (true) {
87
+ const part = await reader.read();
88
+ if (part.done) break;
89
+ size += part.value.byteLength;
90
+ if (size > MAX_RESPONSE_BYTES) {
91
+ await reader.cancel().catch(() => {
92
+ });
93
+ throw invalidResponse();
94
+ }
95
+ text += decoder.decode(part.value, { stream: true });
96
+ }
97
+ text += decoder.decode();
98
+ } finally {
99
+ reader.releaseLock();
100
+ }
101
+ try {
102
+ const data = JSON.parse(text);
103
+ if (data && typeof data === "object" && !Array.isArray(data)) return data;
104
+ } catch {
105
+ }
106
+ throw invalidResponse();
107
+ }
108
+ function object(value) {
109
+ return value !== null && typeof value === "object" && !Array.isArray(value);
110
+ }
111
+ function createBulkClient(apiKey, options = {}) {
112
+ const key = apiKey || (typeof process !== "undefined" ? process.env.PARSEAPI_KEY : void 0);
113
+ if (!key) throw new Error("createBulkClient: missing API key. Pass one or set PARSEAPI_KEY.");
114
+ const webUrl = origin(options.webUrl ?? (typeof process !== "undefined" ? process.env.PARSEAPI_WEB_URL : void 0) ?? "https://parseapi.com");
115
+ const timeout = options.timeoutMs ?? 1e4;
116
+ if (!Number.isSafeInteger(timeout) || timeout <= 0) throw new TypeError("ParseAPI Bulk timeoutMs must be a positive integer.");
117
+ const doFetch = options.fetch ?? fetch;
118
+ function path(id) {
119
+ if (typeof id !== "string" || !jobId.test(id)) throw new TypeError("ParseAPI Bulk requires a valid job ID.");
120
+ return `/api/agent/bulk/${id}`;
121
+ }
122
+ async function request(path2, input, controls) {
123
+ const signal = controls?.signal;
124
+ signal?.throwIfAborted();
125
+ const controller = new AbortController();
126
+ const onAbort = () => controller.abort(signal?.reason);
127
+ signal?.addEventListener("abort", onAbort, { once: true });
128
+ const timer = setTimeout(() => controller.abort(new DOMException("Request timed out", "TimeoutError")), timeout);
129
+ try {
130
+ const response = await doFetch(`${webUrl}${path2}`, {
131
+ method: input === void 0 ? "GET" : "POST",
132
+ redirect: "manual",
133
+ credentials: "omit",
134
+ headers: { "X-API-Key": key, "Parse-Version": "2.0.0", "Accept": "application/json", ...input === void 0 ? {} : { "Content-Type": "application/json" } },
135
+ ...input === void 0 ? {} : { body: JSON.stringify(input) },
136
+ signal: controller.signal
137
+ });
138
+ signal?.throwIfAborted();
139
+ if (response.status >= 300 && response.status < 400) {
140
+ await response.body?.cancel().catch(() => {
141
+ });
142
+ throw new ParseAPIError(response.status, "unexpected_redirect", "The Bulk service returned an unexpected redirect.");
143
+ }
144
+ const data = await boundedJson(response);
145
+ signal?.throwIfAborted();
146
+ if (!response.ok) throw new ParseAPIError(
147
+ response.status,
148
+ typeof data.code === "string" ? data.code : "bulk_request_failed",
149
+ typeof data.message === "string" ? data.message : typeof data.error === "string" ? data.error : `Bulk request failed with status ${response.status}`,
150
+ typeof data.docs === "string" ? data.docs : null,
151
+ typeof data.request_id === "string" ? data.request_id : null,
152
+ response.headers.get("retry-after")
153
+ );
154
+ return data;
155
+ } finally {
156
+ clearTimeout(timer);
157
+ signal?.removeEventListener("abort", onAbort);
158
+ }
159
+ }
160
+ async function workflow(target, id, input, controls) {
161
+ const data = await request(target, input, controls);
162
+ if (!object(data.job) || data.job.id !== id || typeof data.job.status !== "string") throw invalidResponse();
163
+ return data;
164
+ }
165
+ return {
166
+ upload: async (input, controls) => {
167
+ if (!object(input) || typeof input.filename !== "string" || !input.filename.trim() || input.filename.length > 200 || !Number.isSafeInteger(input.file_size) || input.file_size <= 0) throw new TypeError("Provide a filename and positive file_size in bytes.");
168
+ if (input.country !== void 0 && (typeof input.country !== "string" || !/^[A-Za-z]{2}$/.test(input.country))) throw new TypeError("Bulk country must be an ISO2 code.");
169
+ if (input.lang !== void 0 && (typeof input.lang !== "string" || input.lang.length < 2 || input.lang.length > 64)) throw new TypeError("Provide a valid Bulk display language.");
170
+ const data = await request("/api/agent/bulk", { filename: input.filename, file_size: input.file_size, ...input.country === void 0 ? {} : { country: input.country }, ...input.lang === void 0 ? {} : { lang: input.lang } }, controls);
171
+ if (typeof data.id !== "string" || !jobId.test(data.id) || typeof data.upload_url !== "string" || data.upload_method !== "PUT" || typeof data.upload_expires_at !== "string" || !object(data.upload_headers) || Object.values(data.upload_headers).some((value) => typeof value !== "string")) throw invalidResponse();
172
+ return data;
173
+ },
174
+ preview: async (id, input = {}, controls) => {
175
+ if (!object(input) || input.checks !== void 0 && (!Array.isArray(input.checks) || input.checks.length < 1 || input.checks.length > BULK_CHECKS.length || input.checks.some((check) => !BULK_CHECKS.includes(check)) || new Set(input.checks).size !== input.checks.length)) throw new TypeError("Provide distinct public Bulk checks.");
176
+ const data = await workflow(`${path(id)}/preview`, id, input.checks === void 0 ? {} : { checks: input.checks }, controls);
177
+ if (data.quote !== null && (!object(data.quote) || typeof data.quote.id !== "string" || data.quote.currency !== "USD" || !Number.isSafeInteger(data.quote.cost_cents) || data.quote.cost_cents < 0 || data.quote.expires_at !== null && typeof data.quote.expires_at !== "string")) throw invalidResponse();
178
+ return data;
179
+ },
180
+ start: (id, input, controls) => {
181
+ if (!object(input) || typeof input.quote_id !== "string" || !input.quote_id || input.quote_id.length > 512 || !Number.isSafeInteger(input.max_cost_cents) || input.max_cost_cents < 0) throw new TypeError("Provide the current quote_id and approved max_cost_cents.");
182
+ return workflow(`${path(id)}/start`, id, { quote_id: input.quote_id, max_cost_cents: input.max_cost_cents }, controls);
183
+ },
184
+ status: (id, controls) => workflow(path(id), id, void 0, controls),
185
+ result: async (id, controls) => {
186
+ const data = await request(`${path(id)}/result`, void 0, controls);
187
+ if (data.id !== id || typeof data.download_url !== "string" || typeof data.expires_at !== "string") throw invalidResponse();
188
+ return data;
189
+ }
190
+ };
191
+ }
192
+
30
193
  // src/emoji-catalog.ts
31
194
  var EmojiCatalogError = class extends Error {
32
195
  constructor(code, message) {
@@ -285,34 +448,13 @@ var EmojiCatalog = class {
285
448
  };
286
449
 
287
450
  // src/index.ts
288
- var VERSION = "1.11.4";
451
+ var VERSION = "1.12.0";
289
452
  var API_VERSION = "2.0.0";
290
453
  var DEFAULT_BASE_URL = "https://api.parseapi.com";
291
454
  var DEFAULT_TIMEOUT_MS = 1e4;
292
455
  var DEFAULT_RETRIES = 2;
293
456
  var RETRY_STATUS = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
294
457
  var RETRY_AFTER_CAP_MS = 5e3;
295
- var ParseAPIError = class extends Error {
296
- /** HTTP status */
297
- status;
298
- /** Machine-readable error code, e.g. 'not_found', 'invalid_api_key', 'rate_limited' */
299
- code;
300
- /** Link to the docs section for this error */
301
- docs;
302
- /** Send this if you contact support */
303
- requestId;
304
- /** Original Retry-After response header, when supplied. */
305
- retryAfter;
306
- constructor(status, code, message, docs, requestId, retryAfter = null) {
307
- super(message);
308
- this.name = "ParseAPIError";
309
- this.status = status;
310
- this.code = code;
311
- this.docs = docs;
312
- this.requestId = requestId;
313
- this.retryAfter = retryAfter;
314
- }
315
- };
316
458
  var requestControls = (opts) => ({ signal: opts?.signal, timeoutMs: opts?.timeoutMs, retries: opts?.retries });
317
459
  function env(name) {
318
460
  return typeof process !== "undefined" ? process.env?.[name] : void 0;
@@ -744,9 +886,12 @@ function cityCollectionQuery(opts) {
744
886
  }
745
887
  // Annotate the CommonJS export names for ESM import in node:
746
888
  0 && (module.exports = {
889
+ BULK_CHECKS,
890
+ BulkAPIError,
747
891
  EmojiCatalog,
748
892
  EmojiCatalogError,
749
893
  ParseAPIError,
894
+ createBulkClient,
750
895
  parseAPI
751
896
  });
752
897
  /*! You found Dev. https://parseapi.com/dev */
package/dist/index.d.cts CHANGED
@@ -1549,6 +1549,96 @@ interface CityNearbyCoordinates extends CityCollection {
1549
1549
  unit: string;
1550
1550
  }
1551
1551
 
1552
+ /** Every non-2xx response from the API. Branch on `code`, never on `message`. */
1553
+ declare class ParseAPIError extends Error {
1554
+ /** HTTP status */
1555
+ readonly status: number;
1556
+ /** Machine-readable error code, e.g. 'not_found', 'invalid_api_key', 'rate_limited' */
1557
+ readonly code: string;
1558
+ /** Link to the docs section for this error */
1559
+ readonly docs: string | null;
1560
+ /** Send this if you contact support */
1561
+ readonly requestId: string | null;
1562
+ /** Original Retry-After response header, when supplied. */
1563
+ readonly retryAfter: string | null;
1564
+ candidates?: CityAmbiguityCandidate[];
1565
+ constructor(status: number, code: string, message: string, docs?: string | null, requestId?: string | null, retryAfter?: string | null);
1566
+ }
1567
+
1568
+ /** Account-owned file workflows. File bytes travel directly to the returned upload URL. */
1569
+ interface BulkClientOptions {
1570
+ /** ParseAPI website origin. Separate from the lookup client's baseUrl. */
1571
+ webUrl?: string;
1572
+ /** Request timeout in milliseconds. Defaults to 10000. */
1573
+ timeoutMs?: number;
1574
+ /** Custom fetch implementation for this client. */
1575
+ fetch?: typeof fetch;
1576
+ }
1577
+ interface BulkRequestOptions {
1578
+ signal?: AbortSignal;
1579
+ }
1580
+ interface BulkUploadInput {
1581
+ filename: string;
1582
+ file_size: number;
1583
+ country?: string;
1584
+ lang?: string;
1585
+ }
1586
+ interface BulkPreviewInput {
1587
+ checks?: string[];
1588
+ }
1589
+ interface BulkStartInput {
1590
+ quote_id: string;
1591
+ max_cost_cents: number;
1592
+ }
1593
+ /** Public checks supported by the current file workflow. */
1594
+ declare const BULK_CHECKS: readonly ["email", "phone", "carrier", "caller", "hlr", "ip", "domain", "useragent", "country", "postal", "address", "name", "date"];
1595
+ interface BulkUpload {
1596
+ id: string;
1597
+ rail: string;
1598
+ upload_url: string;
1599
+ upload_headers: Record<string, string>;
1600
+ upload_method: 'PUT';
1601
+ upload_expires_at: string;
1602
+ [key: string]: unknown;
1603
+ }
1604
+ /** Status and previews retain server fields, including unknown and nullable results. */
1605
+ interface BulkJob {
1606
+ id: string;
1607
+ status: string;
1608
+ [key: string]: unknown;
1609
+ }
1610
+ interface BulkStatus {
1611
+ job: BulkJob;
1612
+ poll_after_seconds?: number | null;
1613
+ [key: string]: unknown;
1614
+ }
1615
+ interface BulkQuote {
1616
+ id: string;
1617
+ currency: 'USD';
1618
+ cost_cents: number;
1619
+ expires_at: string | null;
1620
+ [key: string]: unknown;
1621
+ }
1622
+ interface BulkPreview extends BulkStatus {
1623
+ quote: BulkQuote | null;
1624
+ }
1625
+ /** A short-lived download capability. Fetch this URL without an API key header. */
1626
+ interface BulkResult {
1627
+ id: string;
1628
+ download_url: string;
1629
+ expires_at: string;
1630
+ [key: string]: unknown;
1631
+ }
1632
+ interface BulkClient {
1633
+ upload(input: BulkUploadInput, options?: BulkRequestOptions): Promise<BulkUpload>;
1634
+ preview(id: string, input?: BulkPreviewInput, options?: BulkRequestOptions): Promise<BulkPreview>;
1635
+ start(id: string, input: BulkStartInput, options?: BulkRequestOptions): Promise<BulkStatus>;
1636
+ status(id: string, options?: BulkRequestOptions): Promise<BulkStatus>;
1637
+ result(id: string, options?: BulkRequestOptions): Promise<BulkResult>;
1638
+ }
1639
+ /** Create a Bulk client. Requests are never retried automatically, including upload creation. */
1640
+ declare function createBulkClient(apiKey?: string, options?: BulkClientOptions): BulkClient;
1641
+
1552
1642
  /** A proposed task contains operation counts, never lookup inputs. */
1553
1643
  interface PreflightOperation {
1554
1644
  operation: 'email' | 'domain' | 'dns' | 'mx' | 'country' | 'vat' | 'carrier' | 'caller' | 'hlr' | 'ip' | 'phone' | 'postal';
@@ -1774,21 +1864,6 @@ declare class EmojiCatalog {
1774
1864
  private filtered;
1775
1865
  }
1776
1866
 
1777
- /** Every non-2xx response from the API. Branch on `code`, never on `message`. */
1778
- declare class ParseAPIError extends Error {
1779
- /** HTTP status */
1780
- readonly status: number;
1781
- /** Machine-readable error code, e.g. 'not_found', 'invalid_api_key', 'rate_limited' */
1782
- readonly code: string;
1783
- /** Link to the docs section for this error */
1784
- readonly docs: string | null;
1785
- /** Send this if you contact support */
1786
- readonly requestId: string | null;
1787
- /** Original Retry-After response header, when supplied. */
1788
- readonly retryAfter: string | null;
1789
- candidates?: CityAmbiguityCandidate[];
1790
- constructor(status: number, code: string, message: string, docs: string | null, requestId: string | null, retryAfter?: string | null);
1791
- }
1792
1867
  /** Optional output language for supported display fields. Input parsing stays unchanged. */
1793
1868
  interface LanguageOption {
1794
1869
  lang?: string;
@@ -2275,4 +2350,4 @@ interface CityNearbyCall {
2275
2350
  (name: string, opts: CityNearbyOptions): Promise<CityNearby | CityCollection>;
2276
2351
  }
2277
2352
 
2278
- export { type Address, type AddressOptions, type AddressSearch, type AddressSearchOptions, type AddressSuggestion, type AgentTask, type AgentTaskInput, type AgentTaskLookupInput, type AgentTaskResult, type Asn, type AsnOptions, type Bin, type BinOptions, type Caller, type CallerOptions, type Card, type CardDeep, type CardOptions, type Carrier, type CarrierDeep, type CarrierOptions, type City, type CityAmbiguityCandidate, type CityAncestorsOptions, type CityCollection, type CityCollectionFilters, type CityDeep, type CityDistance, type CityDistanceOptions, type CityGrain, type CityIdCall, type CityIdOptions, type CityList, type CityListOptions, type CityLookupCall, type CityMatch, type CityNearby, type CityNearbyCall, type CityNearbyCoordinates, type CityNearbyCoordinatesOptions, type CityNearbyOptions, type CityNearest, type CityNearestCall, type CityNearestOptions, type CityOptions, type CityPagingOptions, type CityParent, type CityRelations, type CityRelationsOptions, type CityResource, type CityResponseOptions, type CityScopeOptions, type CitySearch, type CitySearchCall, type CitySearchOptions, type CitySort, type Company, type CompanyCandidate, type CompanyCountry, type CompanyCoverage, type CompanyCoverageOptions, type CompanyDeep, type CompanyEmailAddress, type CompanyIdOptions, type CompanyMatch, type CompanyOptions, type CompanyPhoneNumber, type CompanyProfile, type CompanyProfileAddress, type CompanyProfileDeep, type CompanyProfileDomain, type CompanyProfileEmail, type CompanyProfileEmployees, type CompanyProfileFounding, type CompanyProfileIdentifier, type CompanyProfileIndustry, type CompanyProfileJurisdiction, type CompanyProfileListing, type CompanyProfilePhone, type CompanyProfileRegistration, type CompanyProfileRegistrationAddress, type CompanyProfileRegistrationLegalForm, type CompanyProfileSource, type CompanyProfileWebsite, type CompanySearch, type CompanySearchOptions, type CompanySocialProfile, type Continent, type ContinentCountries, type ContinentCountriesOptions, type ContinentCountryItem, type ContinentOptions, type Country, type CountryDeep, type CountryElevationPoint, type CountryEmergency, type CountryOptions, type CountryStateItem, type CountryStates, type CountryStatesOptions, type DateInfo, type DateInfoDeep, type DateOptions, type DateTodayOptions, type Deep, type District, type DistrictDeep, type DistrictOptions, type Dns, type DnsOptions, type DnsRecord, type Domain, type DomainDeep, type DomainOptions, type DomainRegistration, type Elevation, type ElevationLocations, type ElevationOptions, type Email, type EmailDeep, type EmailOptions, type Emoji, type EmojiArtwork, type EmojiArtworkSource, type EmojiBrowse, type EmojiBrowseOptions, EmojiCatalog, type EmojiCatalogConvertOptions, type EmojiCatalogData, EmojiCatalogError, type EmojiCatalogLocalization, type EmojiCatalogLookupOptions, type EmojiCatalogOptions, type EmojiCatalogParseOptions, type EmojiCatalogRegexOptions, type EmojiCatalogScope, type EmojiCatalogSearchFacts, type EmojiCatalogSearchOptions, type EmojiCategories, type EmojiCategory, type EmojiConversion, type EmojiConvertOptions, type EmojiDeep, type EmojiMetadata, type EmojiNativeSearchFacts, type EmojiNotice, type EmojiOptions, type EmojiParse, type EmojiParseOptions, type EmojiPosition, type EmojiSearch, type EmojiSearchOptions, type EmojiShortcodeSourceMetadata, type EmojiSkin, type EmojiSource, type EmojiUnresolved, type EmojiVariant, type Hlr, type HlrDeep, type HlrOptions, type Holiday, type HolidayDate, type HolidayDateOptions, type HolidayOptions, type HolidayYear, type Industry, type IndustryChild, type IndustryCorrection, type IndustryDeep, type IndustryExclusion, type IndustryMatch, type IndustryOptions, type IndustrySearch, type IndustrySearchItem, type IndustrySearchOptions, type Ip, type IpDeep, type IpOptions, type IpSelfOptions, type Language, type LanguageDeep, type LanguageOption, type LanguageOptions, type Mx, type MxOptions, type MxRecord, type Naics, type NaicsChild, type NaicsCorrection, type NaicsDeep, type NaicsExclusion, type NaicsMatch, type NaicsOptions, type NaicsSearch, type NaicsSearchItem, type NaicsSearchOptions, type Name, type NameDeep, type NameOptions, type ParseAPIClient, ParseAPIError, type ParseAPIOptions, type Phone, type PhoneDeep, type PhoneOptions, type Point, type PointCity, type PointDeep, type PointOptions, type Postal, type PostalDeep, type PostalDistance, type PostalDistanceEnd, type PostalDistanceOptions, type PostalLocality, type PostalMetro, type PostalMetrosDeep, type PostalNearby, type PostalNearbyItem, type PostalNearbyOptions, type PostalOptions, type Preflight, type PreflightCost, type PreflightEmailCapacity, type PreflightOperation, type PreflightOperationEstimate, type PreflightPooledCapacity, type PreflightSpendCapacity, type PreflightTask, type PropertyTax, type RequestOptions, type Stack, type StackOptions, type StackTechnology, type State, type StateDeep, type StateDistrictDeep, type StateDistrictItem, type StateDistricts, type StateDistrictsOptions, type StateOptions, type Time, type TimeAtOptions, type TimeLocation, type TimeLocationCandidate, type TimeLocationInput, type TimeOptions, type TimeResolution, type TimeResolutionAlternative, type TimeSeason, type TimeTransition, type TimeTransitionState, type TimeZoneEntry, type TimeZones, type TimeZonesOptions, type Timezone, type TimezoneAtOptions, type TimezoneConversionTarget, type TimezoneConversionTargetDeep, type TimezoneDeep, type TimezoneNextDst, type TimezoneOptions, type Useragent, type UseragentBrowserBrand, type UseragentBrowserDeep, type UseragentDeep, type UseragentDeviceDeep, type UseragentEngineDeep, type UseragentOptions, type UseragentOsDeep, type Weather, type WeatherAir, type WeatherAlert, type WeatherCurrent, type WeatherCurrentDeep, type WeatherDay, type WeatherDeep, type WeatherForecastPeriod, type WeatherHistory, type WeatherHour, type WeatherMinute, type WeatherOptions, type WeatherStation, parseAPI };
2353
+ export { type Address, type AddressOptions, type AddressSearch, type AddressSearchOptions, type AddressSuggestion, type AgentTask, type AgentTaskInput, type AgentTaskLookupInput, type AgentTaskResult, type Asn, type AsnOptions, BULK_CHECKS, type Bin, type BinOptions, ParseAPIError as BulkAPIError, type BulkClient, type BulkClientOptions, type BulkJob, type BulkPreview, type BulkPreviewInput, type BulkQuote, type BulkRequestOptions, type BulkResult, type BulkStartInput, type BulkStatus, type BulkUpload, type BulkUploadInput, type Caller, type CallerOptions, type Card, type CardDeep, type CardOptions, type Carrier, type CarrierDeep, type CarrierOptions, type City, type CityAmbiguityCandidate, type CityAncestorsOptions, type CityCollection, type CityCollectionFilters, type CityDeep, type CityDistance, type CityDistanceOptions, type CityGrain, type CityIdCall, type CityIdOptions, type CityList, type CityListOptions, type CityLookupCall, type CityMatch, type CityNearby, type CityNearbyCall, type CityNearbyCoordinates, type CityNearbyCoordinatesOptions, type CityNearbyOptions, type CityNearest, type CityNearestCall, type CityNearestOptions, type CityOptions, type CityPagingOptions, type CityParent, type CityRelations, type CityRelationsOptions, type CityResource, type CityResponseOptions, type CityScopeOptions, type CitySearch, type CitySearchCall, type CitySearchOptions, type CitySort, type Company, type CompanyCandidate, type CompanyCountry, type CompanyCoverage, type CompanyCoverageOptions, type CompanyDeep, type CompanyEmailAddress, type CompanyIdOptions, type CompanyMatch, type CompanyOptions, type CompanyPhoneNumber, type CompanyProfile, type CompanyProfileAddress, type CompanyProfileDeep, type CompanyProfileDomain, type CompanyProfileEmail, type CompanyProfileEmployees, type CompanyProfileFounding, type CompanyProfileIdentifier, type CompanyProfileIndustry, type CompanyProfileJurisdiction, type CompanyProfileListing, type CompanyProfilePhone, type CompanyProfileRegistration, type CompanyProfileRegistrationAddress, type CompanyProfileRegistrationLegalForm, type CompanyProfileSource, type CompanyProfileWebsite, type CompanySearch, type CompanySearchOptions, type CompanySocialProfile, type Continent, type ContinentCountries, type ContinentCountriesOptions, type ContinentCountryItem, type ContinentOptions, type Country, type CountryDeep, type CountryElevationPoint, type CountryEmergency, type CountryOptions, type CountryStateItem, type CountryStates, type CountryStatesOptions, type DateInfo, type DateInfoDeep, type DateOptions, type DateTodayOptions, type Deep, type District, type DistrictDeep, type DistrictOptions, type Dns, type DnsOptions, type DnsRecord, type Domain, type DomainDeep, type DomainOptions, type DomainRegistration, type Elevation, type ElevationLocations, type ElevationOptions, type Email, type EmailDeep, type EmailOptions, type Emoji, type EmojiArtwork, type EmojiArtworkSource, type EmojiBrowse, type EmojiBrowseOptions, EmojiCatalog, type EmojiCatalogConvertOptions, type EmojiCatalogData, EmojiCatalogError, type EmojiCatalogLocalization, type EmojiCatalogLookupOptions, type EmojiCatalogOptions, type EmojiCatalogParseOptions, type EmojiCatalogRegexOptions, type EmojiCatalogScope, type EmojiCatalogSearchFacts, type EmojiCatalogSearchOptions, type EmojiCategories, type EmojiCategory, type EmojiConversion, type EmojiConvertOptions, type EmojiDeep, type EmojiMetadata, type EmojiNativeSearchFacts, type EmojiNotice, type EmojiOptions, type EmojiParse, type EmojiParseOptions, type EmojiPosition, type EmojiSearch, type EmojiSearchOptions, type EmojiShortcodeSourceMetadata, type EmojiSkin, type EmojiSource, type EmojiUnresolved, type EmojiVariant, type Hlr, type HlrDeep, type HlrOptions, type Holiday, type HolidayDate, type HolidayDateOptions, type HolidayOptions, type HolidayYear, type Industry, type IndustryChild, type IndustryCorrection, type IndustryDeep, type IndustryExclusion, type IndustryMatch, type IndustryOptions, type IndustrySearch, type IndustrySearchItem, type IndustrySearchOptions, type Ip, type IpDeep, type IpOptions, type IpSelfOptions, type Language, type LanguageDeep, type LanguageOption, type LanguageOptions, type Mx, type MxOptions, type MxRecord, type Naics, type NaicsChild, type NaicsCorrection, type NaicsDeep, type NaicsExclusion, type NaicsMatch, type NaicsOptions, type NaicsSearch, type NaicsSearchItem, type NaicsSearchOptions, type Name, type NameDeep, type NameOptions, type ParseAPIClient, ParseAPIError, type ParseAPIOptions, type Phone, type PhoneDeep, type PhoneOptions, type Point, type PointCity, type PointDeep, type PointOptions, type Postal, type PostalDeep, type PostalDistance, type PostalDistanceEnd, type PostalDistanceOptions, type PostalLocality, type PostalMetro, type PostalMetrosDeep, type PostalNearby, type PostalNearbyItem, type PostalNearbyOptions, type PostalOptions, type Preflight, type PreflightCost, type PreflightEmailCapacity, type PreflightOperation, type PreflightOperationEstimate, type PreflightPooledCapacity, type PreflightSpendCapacity, type PreflightTask, type PropertyTax, type RequestOptions, type Stack, type StackOptions, type StackTechnology, type State, type StateDeep, type StateDistrictDeep, type StateDistrictItem, type StateDistricts, type StateDistrictsOptions, type StateOptions, type Time, type TimeAtOptions, type TimeLocation, type TimeLocationCandidate, type TimeLocationInput, type TimeOptions, type TimeResolution, type TimeResolutionAlternative, type TimeSeason, type TimeTransition, type TimeTransitionState, type TimeZoneEntry, type TimeZones, type TimeZonesOptions, type Timezone, type TimezoneAtOptions, type TimezoneConversionTarget, type TimezoneConversionTargetDeep, type TimezoneDeep, type TimezoneNextDst, type TimezoneOptions, type Useragent, type UseragentBrowserBrand, type UseragentBrowserDeep, type UseragentDeep, type UseragentDeviceDeep, type UseragentEngineDeep, type UseragentOptions, type UseragentOsDeep, type Weather, type WeatherAir, type WeatherAlert, type WeatherCurrent, type WeatherCurrentDeep, type WeatherDay, type WeatherDeep, type WeatherForecastPeriod, type WeatherHistory, type WeatherHour, type WeatherMinute, type WeatherOptions, type WeatherStation, createBulkClient, parseAPI };
package/dist/index.d.ts CHANGED
@@ -1549,6 +1549,96 @@ interface CityNearbyCoordinates extends CityCollection {
1549
1549
  unit: string;
1550
1550
  }
1551
1551
 
1552
+ /** Every non-2xx response from the API. Branch on `code`, never on `message`. */
1553
+ declare class ParseAPIError extends Error {
1554
+ /** HTTP status */
1555
+ readonly status: number;
1556
+ /** Machine-readable error code, e.g. 'not_found', 'invalid_api_key', 'rate_limited' */
1557
+ readonly code: string;
1558
+ /** Link to the docs section for this error */
1559
+ readonly docs: string | null;
1560
+ /** Send this if you contact support */
1561
+ readonly requestId: string | null;
1562
+ /** Original Retry-After response header, when supplied. */
1563
+ readonly retryAfter: string | null;
1564
+ candidates?: CityAmbiguityCandidate[];
1565
+ constructor(status: number, code: string, message: string, docs?: string | null, requestId?: string | null, retryAfter?: string | null);
1566
+ }
1567
+
1568
+ /** Account-owned file workflows. File bytes travel directly to the returned upload URL. */
1569
+ interface BulkClientOptions {
1570
+ /** ParseAPI website origin. Separate from the lookup client's baseUrl. */
1571
+ webUrl?: string;
1572
+ /** Request timeout in milliseconds. Defaults to 10000. */
1573
+ timeoutMs?: number;
1574
+ /** Custom fetch implementation for this client. */
1575
+ fetch?: typeof fetch;
1576
+ }
1577
+ interface BulkRequestOptions {
1578
+ signal?: AbortSignal;
1579
+ }
1580
+ interface BulkUploadInput {
1581
+ filename: string;
1582
+ file_size: number;
1583
+ country?: string;
1584
+ lang?: string;
1585
+ }
1586
+ interface BulkPreviewInput {
1587
+ checks?: string[];
1588
+ }
1589
+ interface BulkStartInput {
1590
+ quote_id: string;
1591
+ max_cost_cents: number;
1592
+ }
1593
+ /** Public checks supported by the current file workflow. */
1594
+ declare const BULK_CHECKS: readonly ["email", "phone", "carrier", "caller", "hlr", "ip", "domain", "useragent", "country", "postal", "address", "name", "date"];
1595
+ interface BulkUpload {
1596
+ id: string;
1597
+ rail: string;
1598
+ upload_url: string;
1599
+ upload_headers: Record<string, string>;
1600
+ upload_method: 'PUT';
1601
+ upload_expires_at: string;
1602
+ [key: string]: unknown;
1603
+ }
1604
+ /** Status and previews retain server fields, including unknown and nullable results. */
1605
+ interface BulkJob {
1606
+ id: string;
1607
+ status: string;
1608
+ [key: string]: unknown;
1609
+ }
1610
+ interface BulkStatus {
1611
+ job: BulkJob;
1612
+ poll_after_seconds?: number | null;
1613
+ [key: string]: unknown;
1614
+ }
1615
+ interface BulkQuote {
1616
+ id: string;
1617
+ currency: 'USD';
1618
+ cost_cents: number;
1619
+ expires_at: string | null;
1620
+ [key: string]: unknown;
1621
+ }
1622
+ interface BulkPreview extends BulkStatus {
1623
+ quote: BulkQuote | null;
1624
+ }
1625
+ /** A short-lived download capability. Fetch this URL without an API key header. */
1626
+ interface BulkResult {
1627
+ id: string;
1628
+ download_url: string;
1629
+ expires_at: string;
1630
+ [key: string]: unknown;
1631
+ }
1632
+ interface BulkClient {
1633
+ upload(input: BulkUploadInput, options?: BulkRequestOptions): Promise<BulkUpload>;
1634
+ preview(id: string, input?: BulkPreviewInput, options?: BulkRequestOptions): Promise<BulkPreview>;
1635
+ start(id: string, input: BulkStartInput, options?: BulkRequestOptions): Promise<BulkStatus>;
1636
+ status(id: string, options?: BulkRequestOptions): Promise<BulkStatus>;
1637
+ result(id: string, options?: BulkRequestOptions): Promise<BulkResult>;
1638
+ }
1639
+ /** Create a Bulk client. Requests are never retried automatically, including upload creation. */
1640
+ declare function createBulkClient(apiKey?: string, options?: BulkClientOptions): BulkClient;
1641
+
1552
1642
  /** A proposed task contains operation counts, never lookup inputs. */
1553
1643
  interface PreflightOperation {
1554
1644
  operation: 'email' | 'domain' | 'dns' | 'mx' | 'country' | 'vat' | 'carrier' | 'caller' | 'hlr' | 'ip' | 'phone' | 'postal';
@@ -1774,21 +1864,6 @@ declare class EmojiCatalog {
1774
1864
  private filtered;
1775
1865
  }
1776
1866
 
1777
- /** Every non-2xx response from the API. Branch on `code`, never on `message`. */
1778
- declare class ParseAPIError extends Error {
1779
- /** HTTP status */
1780
- readonly status: number;
1781
- /** Machine-readable error code, e.g. 'not_found', 'invalid_api_key', 'rate_limited' */
1782
- readonly code: string;
1783
- /** Link to the docs section for this error */
1784
- readonly docs: string | null;
1785
- /** Send this if you contact support */
1786
- readonly requestId: string | null;
1787
- /** Original Retry-After response header, when supplied. */
1788
- readonly retryAfter: string | null;
1789
- candidates?: CityAmbiguityCandidate[];
1790
- constructor(status: number, code: string, message: string, docs: string | null, requestId: string | null, retryAfter?: string | null);
1791
- }
1792
1867
  /** Optional output language for supported display fields. Input parsing stays unchanged. */
1793
1868
  interface LanguageOption {
1794
1869
  lang?: string;
@@ -2275,4 +2350,4 @@ interface CityNearbyCall {
2275
2350
  (name: string, opts: CityNearbyOptions): Promise<CityNearby | CityCollection>;
2276
2351
  }
2277
2352
 
2278
- export { type Address, type AddressOptions, type AddressSearch, type AddressSearchOptions, type AddressSuggestion, type AgentTask, type AgentTaskInput, type AgentTaskLookupInput, type AgentTaskResult, type Asn, type AsnOptions, type Bin, type BinOptions, type Caller, type CallerOptions, type Card, type CardDeep, type CardOptions, type Carrier, type CarrierDeep, type CarrierOptions, type City, type CityAmbiguityCandidate, type CityAncestorsOptions, type CityCollection, type CityCollectionFilters, type CityDeep, type CityDistance, type CityDistanceOptions, type CityGrain, type CityIdCall, type CityIdOptions, type CityList, type CityListOptions, type CityLookupCall, type CityMatch, type CityNearby, type CityNearbyCall, type CityNearbyCoordinates, type CityNearbyCoordinatesOptions, type CityNearbyOptions, type CityNearest, type CityNearestCall, type CityNearestOptions, type CityOptions, type CityPagingOptions, type CityParent, type CityRelations, type CityRelationsOptions, type CityResource, type CityResponseOptions, type CityScopeOptions, type CitySearch, type CitySearchCall, type CitySearchOptions, type CitySort, type Company, type CompanyCandidate, type CompanyCountry, type CompanyCoverage, type CompanyCoverageOptions, type CompanyDeep, type CompanyEmailAddress, type CompanyIdOptions, type CompanyMatch, type CompanyOptions, type CompanyPhoneNumber, type CompanyProfile, type CompanyProfileAddress, type CompanyProfileDeep, type CompanyProfileDomain, type CompanyProfileEmail, type CompanyProfileEmployees, type CompanyProfileFounding, type CompanyProfileIdentifier, type CompanyProfileIndustry, type CompanyProfileJurisdiction, type CompanyProfileListing, type CompanyProfilePhone, type CompanyProfileRegistration, type CompanyProfileRegistrationAddress, type CompanyProfileRegistrationLegalForm, type CompanyProfileSource, type CompanyProfileWebsite, type CompanySearch, type CompanySearchOptions, type CompanySocialProfile, type Continent, type ContinentCountries, type ContinentCountriesOptions, type ContinentCountryItem, type ContinentOptions, type Country, type CountryDeep, type CountryElevationPoint, type CountryEmergency, type CountryOptions, type CountryStateItem, type CountryStates, type CountryStatesOptions, type DateInfo, type DateInfoDeep, type DateOptions, type DateTodayOptions, type Deep, type District, type DistrictDeep, type DistrictOptions, type Dns, type DnsOptions, type DnsRecord, type Domain, type DomainDeep, type DomainOptions, type DomainRegistration, type Elevation, type ElevationLocations, type ElevationOptions, type Email, type EmailDeep, type EmailOptions, type Emoji, type EmojiArtwork, type EmojiArtworkSource, type EmojiBrowse, type EmojiBrowseOptions, EmojiCatalog, type EmojiCatalogConvertOptions, type EmojiCatalogData, EmojiCatalogError, type EmojiCatalogLocalization, type EmojiCatalogLookupOptions, type EmojiCatalogOptions, type EmojiCatalogParseOptions, type EmojiCatalogRegexOptions, type EmojiCatalogScope, type EmojiCatalogSearchFacts, type EmojiCatalogSearchOptions, type EmojiCategories, type EmojiCategory, type EmojiConversion, type EmojiConvertOptions, type EmojiDeep, type EmojiMetadata, type EmojiNativeSearchFacts, type EmojiNotice, type EmojiOptions, type EmojiParse, type EmojiParseOptions, type EmojiPosition, type EmojiSearch, type EmojiSearchOptions, type EmojiShortcodeSourceMetadata, type EmojiSkin, type EmojiSource, type EmojiUnresolved, type EmojiVariant, type Hlr, type HlrDeep, type HlrOptions, type Holiday, type HolidayDate, type HolidayDateOptions, type HolidayOptions, type HolidayYear, type Industry, type IndustryChild, type IndustryCorrection, type IndustryDeep, type IndustryExclusion, type IndustryMatch, type IndustryOptions, type IndustrySearch, type IndustrySearchItem, type IndustrySearchOptions, type Ip, type IpDeep, type IpOptions, type IpSelfOptions, type Language, type LanguageDeep, type LanguageOption, type LanguageOptions, type Mx, type MxOptions, type MxRecord, type Naics, type NaicsChild, type NaicsCorrection, type NaicsDeep, type NaicsExclusion, type NaicsMatch, type NaicsOptions, type NaicsSearch, type NaicsSearchItem, type NaicsSearchOptions, type Name, type NameDeep, type NameOptions, type ParseAPIClient, ParseAPIError, type ParseAPIOptions, type Phone, type PhoneDeep, type PhoneOptions, type Point, type PointCity, type PointDeep, type PointOptions, type Postal, type PostalDeep, type PostalDistance, type PostalDistanceEnd, type PostalDistanceOptions, type PostalLocality, type PostalMetro, type PostalMetrosDeep, type PostalNearby, type PostalNearbyItem, type PostalNearbyOptions, type PostalOptions, type Preflight, type PreflightCost, type PreflightEmailCapacity, type PreflightOperation, type PreflightOperationEstimate, type PreflightPooledCapacity, type PreflightSpendCapacity, type PreflightTask, type PropertyTax, type RequestOptions, type Stack, type StackOptions, type StackTechnology, type State, type StateDeep, type StateDistrictDeep, type StateDistrictItem, type StateDistricts, type StateDistrictsOptions, type StateOptions, type Time, type TimeAtOptions, type TimeLocation, type TimeLocationCandidate, type TimeLocationInput, type TimeOptions, type TimeResolution, type TimeResolutionAlternative, type TimeSeason, type TimeTransition, type TimeTransitionState, type TimeZoneEntry, type TimeZones, type TimeZonesOptions, type Timezone, type TimezoneAtOptions, type TimezoneConversionTarget, type TimezoneConversionTargetDeep, type TimezoneDeep, type TimezoneNextDst, type TimezoneOptions, type Useragent, type UseragentBrowserBrand, type UseragentBrowserDeep, type UseragentDeep, type UseragentDeviceDeep, type UseragentEngineDeep, type UseragentOptions, type UseragentOsDeep, type Weather, type WeatherAir, type WeatherAlert, type WeatherCurrent, type WeatherCurrentDeep, type WeatherDay, type WeatherDeep, type WeatherForecastPeriod, type WeatherHistory, type WeatherHour, type WeatherMinute, type WeatherOptions, type WeatherStation, parseAPI };
2353
+ export { type Address, type AddressOptions, type AddressSearch, type AddressSearchOptions, type AddressSuggestion, type AgentTask, type AgentTaskInput, type AgentTaskLookupInput, type AgentTaskResult, type Asn, type AsnOptions, BULK_CHECKS, type Bin, type BinOptions, ParseAPIError as BulkAPIError, type BulkClient, type BulkClientOptions, type BulkJob, type BulkPreview, type BulkPreviewInput, type BulkQuote, type BulkRequestOptions, type BulkResult, type BulkStartInput, type BulkStatus, type BulkUpload, type BulkUploadInput, type Caller, type CallerOptions, type Card, type CardDeep, type CardOptions, type Carrier, type CarrierDeep, type CarrierOptions, type City, type CityAmbiguityCandidate, type CityAncestorsOptions, type CityCollection, type CityCollectionFilters, type CityDeep, type CityDistance, type CityDistanceOptions, type CityGrain, type CityIdCall, type CityIdOptions, type CityList, type CityListOptions, type CityLookupCall, type CityMatch, type CityNearby, type CityNearbyCall, type CityNearbyCoordinates, type CityNearbyCoordinatesOptions, type CityNearbyOptions, type CityNearest, type CityNearestCall, type CityNearestOptions, type CityOptions, type CityPagingOptions, type CityParent, type CityRelations, type CityRelationsOptions, type CityResource, type CityResponseOptions, type CityScopeOptions, type CitySearch, type CitySearchCall, type CitySearchOptions, type CitySort, type Company, type CompanyCandidate, type CompanyCountry, type CompanyCoverage, type CompanyCoverageOptions, type CompanyDeep, type CompanyEmailAddress, type CompanyIdOptions, type CompanyMatch, type CompanyOptions, type CompanyPhoneNumber, type CompanyProfile, type CompanyProfileAddress, type CompanyProfileDeep, type CompanyProfileDomain, type CompanyProfileEmail, type CompanyProfileEmployees, type CompanyProfileFounding, type CompanyProfileIdentifier, type CompanyProfileIndustry, type CompanyProfileJurisdiction, type CompanyProfileListing, type CompanyProfilePhone, type CompanyProfileRegistration, type CompanyProfileRegistrationAddress, type CompanyProfileRegistrationLegalForm, type CompanyProfileSource, type CompanyProfileWebsite, type CompanySearch, type CompanySearchOptions, type CompanySocialProfile, type Continent, type ContinentCountries, type ContinentCountriesOptions, type ContinentCountryItem, type ContinentOptions, type Country, type CountryDeep, type CountryElevationPoint, type CountryEmergency, type CountryOptions, type CountryStateItem, type CountryStates, type CountryStatesOptions, type DateInfo, type DateInfoDeep, type DateOptions, type DateTodayOptions, type Deep, type District, type DistrictDeep, type DistrictOptions, type Dns, type DnsOptions, type DnsRecord, type Domain, type DomainDeep, type DomainOptions, type DomainRegistration, type Elevation, type ElevationLocations, type ElevationOptions, type Email, type EmailDeep, type EmailOptions, type Emoji, type EmojiArtwork, type EmojiArtworkSource, type EmojiBrowse, type EmojiBrowseOptions, EmojiCatalog, type EmojiCatalogConvertOptions, type EmojiCatalogData, EmojiCatalogError, type EmojiCatalogLocalization, type EmojiCatalogLookupOptions, type EmojiCatalogOptions, type EmojiCatalogParseOptions, type EmojiCatalogRegexOptions, type EmojiCatalogScope, type EmojiCatalogSearchFacts, type EmojiCatalogSearchOptions, type EmojiCategories, type EmojiCategory, type EmojiConversion, type EmojiConvertOptions, type EmojiDeep, type EmojiMetadata, type EmojiNativeSearchFacts, type EmojiNotice, type EmojiOptions, type EmojiParse, type EmojiParseOptions, type EmojiPosition, type EmojiSearch, type EmojiSearchOptions, type EmojiShortcodeSourceMetadata, type EmojiSkin, type EmojiSource, type EmojiUnresolved, type EmojiVariant, type Hlr, type HlrDeep, type HlrOptions, type Holiday, type HolidayDate, type HolidayDateOptions, type HolidayOptions, type HolidayYear, type Industry, type IndustryChild, type IndustryCorrection, type IndustryDeep, type IndustryExclusion, type IndustryMatch, type IndustryOptions, type IndustrySearch, type IndustrySearchItem, type IndustrySearchOptions, type Ip, type IpDeep, type IpOptions, type IpSelfOptions, type Language, type LanguageDeep, type LanguageOption, type LanguageOptions, type Mx, type MxOptions, type MxRecord, type Naics, type NaicsChild, type NaicsCorrection, type NaicsDeep, type NaicsExclusion, type NaicsMatch, type NaicsOptions, type NaicsSearch, type NaicsSearchItem, type NaicsSearchOptions, type Name, type NameDeep, type NameOptions, type ParseAPIClient, ParseAPIError, type ParseAPIOptions, type Phone, type PhoneDeep, type PhoneOptions, type Point, type PointCity, type PointDeep, type PointOptions, type Postal, type PostalDeep, type PostalDistance, type PostalDistanceEnd, type PostalDistanceOptions, type PostalLocality, type PostalMetro, type PostalMetrosDeep, type PostalNearby, type PostalNearbyItem, type PostalNearbyOptions, type PostalOptions, type Preflight, type PreflightCost, type PreflightEmailCapacity, type PreflightOperation, type PreflightOperationEstimate, type PreflightPooledCapacity, type PreflightSpendCapacity, type PreflightTask, type PropertyTax, type RequestOptions, type Stack, type StackOptions, type StackTechnology, type State, type StateDeep, type StateDistrictDeep, type StateDistrictItem, type StateDistricts, type StateDistrictsOptions, type StateOptions, type Time, type TimeAtOptions, type TimeLocation, type TimeLocationCandidate, type TimeLocationInput, type TimeOptions, type TimeResolution, type TimeResolutionAlternative, type TimeSeason, type TimeTransition, type TimeTransitionState, type TimeZoneEntry, type TimeZones, type TimeZonesOptions, type Timezone, type TimezoneAtOptions, type TimezoneConversionTarget, type TimezoneConversionTargetDeep, type TimezoneDeep, type TimezoneNextDst, type TimezoneOptions, type Useragent, type UseragentBrowserBrand, type UseragentBrowserDeep, type UseragentDeep, type UseragentDeviceDeep, type UseragentEngineDeep, type UseragentOptions, type UseragentOsDeep, type Weather, type WeatherAir, type WeatherAlert, type WeatherCurrent, type WeatherCurrentDeep, type WeatherDay, type WeatherDeep, type WeatherForecastPeriod, type WeatherHistory, type WeatherHour, type WeatherMinute, type WeatherOptions, type WeatherStation, createBulkClient, parseAPI };
package/dist/index.js CHANGED
@@ -1,3 +1,163 @@
1
+ // src/errors.ts
2
+ var ParseAPIError = class extends Error {
3
+ /** HTTP status */
4
+ status;
5
+ /** Machine-readable error code, e.g. 'not_found', 'invalid_api_key', 'rate_limited' */
6
+ code;
7
+ /** Link to the docs section for this error */
8
+ docs;
9
+ /** Send this if you contact support */
10
+ requestId;
11
+ /** Original Retry-After response header, when supplied. */
12
+ retryAfter;
13
+ constructor(status, code, message, docs = null, requestId = null, retryAfter = null) {
14
+ super(message);
15
+ this.name = "ParseAPIError";
16
+ this.status = status;
17
+ this.code = code;
18
+ this.docs = docs;
19
+ this.requestId = requestId;
20
+ this.retryAfter = retryAfter;
21
+ }
22
+ };
23
+
24
+ // src/bulk.ts
25
+ var BULK_CHECKS = ["email", "phone", "carrier", "caller", "hlr", "ip", "domain", "useragent", "country", "postal", "address", "name", "date"];
26
+ var MAX_RESPONSE_BYTES = 256 * 1024;
27
+ var jobId = /^job_[23456789abcdefghjkmnpqrstuvwxyz]{14}$/;
28
+ var invalidResponse = () => new ParseAPIError(502, "invalid_api_response", "The Bulk service returned an invalid response.");
29
+ function origin(value) {
30
+ let url;
31
+ try {
32
+ url = new URL(value);
33
+ } catch {
34
+ throw new TypeError("ParseAPI Bulk webUrl must be an HTTPS origin.");
35
+ }
36
+ const loopback = url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "[::1]";
37
+ if (url.protocol !== "https:" && !(url.protocol === "http:" && loopback) || url.username || url.password || url.pathname !== "/" || url.search || url.hash) {
38
+ throw new TypeError("ParseAPI Bulk webUrl must be an HTTPS origin, or HTTP on loopback.");
39
+ }
40
+ return url.origin;
41
+ }
42
+ async function boundedJson(response) {
43
+ const length = response.headers.get("content-length");
44
+ if (length && /^\d+$/.test(length) && Number(length) > MAX_RESPONSE_BYTES) {
45
+ await response.body?.cancel().catch(() => {
46
+ });
47
+ throw invalidResponse();
48
+ }
49
+ if (!response.body) throw invalidResponse();
50
+ const reader = response.body.getReader();
51
+ const decoder = new TextDecoder();
52
+ let size = 0, text = "";
53
+ try {
54
+ while (true) {
55
+ const part = await reader.read();
56
+ if (part.done) break;
57
+ size += part.value.byteLength;
58
+ if (size > MAX_RESPONSE_BYTES) {
59
+ await reader.cancel().catch(() => {
60
+ });
61
+ throw invalidResponse();
62
+ }
63
+ text += decoder.decode(part.value, { stream: true });
64
+ }
65
+ text += decoder.decode();
66
+ } finally {
67
+ reader.releaseLock();
68
+ }
69
+ try {
70
+ const data = JSON.parse(text);
71
+ if (data && typeof data === "object" && !Array.isArray(data)) return data;
72
+ } catch {
73
+ }
74
+ throw invalidResponse();
75
+ }
76
+ function object(value) {
77
+ return value !== null && typeof value === "object" && !Array.isArray(value);
78
+ }
79
+ function createBulkClient(apiKey, options = {}) {
80
+ const key = apiKey || (typeof process !== "undefined" ? process.env.PARSEAPI_KEY : void 0);
81
+ if (!key) throw new Error("createBulkClient: missing API key. Pass one or set PARSEAPI_KEY.");
82
+ const webUrl = origin(options.webUrl ?? (typeof process !== "undefined" ? process.env.PARSEAPI_WEB_URL : void 0) ?? "https://parseapi.com");
83
+ const timeout = options.timeoutMs ?? 1e4;
84
+ if (!Number.isSafeInteger(timeout) || timeout <= 0) throw new TypeError("ParseAPI Bulk timeoutMs must be a positive integer.");
85
+ const doFetch = options.fetch ?? fetch;
86
+ function path(id) {
87
+ if (typeof id !== "string" || !jobId.test(id)) throw new TypeError("ParseAPI Bulk requires a valid job ID.");
88
+ return `/api/agent/bulk/${id}`;
89
+ }
90
+ async function request(path2, input, controls) {
91
+ const signal = controls?.signal;
92
+ signal?.throwIfAborted();
93
+ const controller = new AbortController();
94
+ const onAbort = () => controller.abort(signal?.reason);
95
+ signal?.addEventListener("abort", onAbort, { once: true });
96
+ const timer = setTimeout(() => controller.abort(new DOMException("Request timed out", "TimeoutError")), timeout);
97
+ try {
98
+ const response = await doFetch(`${webUrl}${path2}`, {
99
+ method: input === void 0 ? "GET" : "POST",
100
+ redirect: "manual",
101
+ credentials: "omit",
102
+ headers: { "X-API-Key": key, "Parse-Version": "2.0.0", "Accept": "application/json", ...input === void 0 ? {} : { "Content-Type": "application/json" } },
103
+ ...input === void 0 ? {} : { body: JSON.stringify(input) },
104
+ signal: controller.signal
105
+ });
106
+ signal?.throwIfAborted();
107
+ if (response.status >= 300 && response.status < 400) {
108
+ await response.body?.cancel().catch(() => {
109
+ });
110
+ throw new ParseAPIError(response.status, "unexpected_redirect", "The Bulk service returned an unexpected redirect.");
111
+ }
112
+ const data = await boundedJson(response);
113
+ signal?.throwIfAborted();
114
+ if (!response.ok) throw new ParseAPIError(
115
+ response.status,
116
+ typeof data.code === "string" ? data.code : "bulk_request_failed",
117
+ typeof data.message === "string" ? data.message : typeof data.error === "string" ? data.error : `Bulk request failed with status ${response.status}`,
118
+ typeof data.docs === "string" ? data.docs : null,
119
+ typeof data.request_id === "string" ? data.request_id : null,
120
+ response.headers.get("retry-after")
121
+ );
122
+ return data;
123
+ } finally {
124
+ clearTimeout(timer);
125
+ signal?.removeEventListener("abort", onAbort);
126
+ }
127
+ }
128
+ async function workflow(target, id, input, controls) {
129
+ const data = await request(target, input, controls);
130
+ if (!object(data.job) || data.job.id !== id || typeof data.job.status !== "string") throw invalidResponse();
131
+ return data;
132
+ }
133
+ return {
134
+ upload: async (input, controls) => {
135
+ if (!object(input) || typeof input.filename !== "string" || !input.filename.trim() || input.filename.length > 200 || !Number.isSafeInteger(input.file_size) || input.file_size <= 0) throw new TypeError("Provide a filename and positive file_size in bytes.");
136
+ if (input.country !== void 0 && (typeof input.country !== "string" || !/^[A-Za-z]{2}$/.test(input.country))) throw new TypeError("Bulk country must be an ISO2 code.");
137
+ if (input.lang !== void 0 && (typeof input.lang !== "string" || input.lang.length < 2 || input.lang.length > 64)) throw new TypeError("Provide a valid Bulk display language.");
138
+ const data = await request("/api/agent/bulk", { filename: input.filename, file_size: input.file_size, ...input.country === void 0 ? {} : { country: input.country }, ...input.lang === void 0 ? {} : { lang: input.lang } }, controls);
139
+ if (typeof data.id !== "string" || !jobId.test(data.id) || typeof data.upload_url !== "string" || data.upload_method !== "PUT" || typeof data.upload_expires_at !== "string" || !object(data.upload_headers) || Object.values(data.upload_headers).some((value) => typeof value !== "string")) throw invalidResponse();
140
+ return data;
141
+ },
142
+ preview: async (id, input = {}, controls) => {
143
+ if (!object(input) || input.checks !== void 0 && (!Array.isArray(input.checks) || input.checks.length < 1 || input.checks.length > BULK_CHECKS.length || input.checks.some((check) => !BULK_CHECKS.includes(check)) || new Set(input.checks).size !== input.checks.length)) throw new TypeError("Provide distinct public Bulk checks.");
144
+ const data = await workflow(`${path(id)}/preview`, id, input.checks === void 0 ? {} : { checks: input.checks }, controls);
145
+ if (data.quote !== null && (!object(data.quote) || typeof data.quote.id !== "string" || data.quote.currency !== "USD" || !Number.isSafeInteger(data.quote.cost_cents) || data.quote.cost_cents < 0 || data.quote.expires_at !== null && typeof data.quote.expires_at !== "string")) throw invalidResponse();
146
+ return data;
147
+ },
148
+ start: (id, input, controls) => {
149
+ if (!object(input) || typeof input.quote_id !== "string" || !input.quote_id || input.quote_id.length > 512 || !Number.isSafeInteger(input.max_cost_cents) || input.max_cost_cents < 0) throw new TypeError("Provide the current quote_id and approved max_cost_cents.");
150
+ return workflow(`${path(id)}/start`, id, { quote_id: input.quote_id, max_cost_cents: input.max_cost_cents }, controls);
151
+ },
152
+ status: (id, controls) => workflow(path(id), id, void 0, controls),
153
+ result: async (id, controls) => {
154
+ const data = await request(`${path(id)}/result`, void 0, controls);
155
+ if (data.id !== id || typeof data.download_url !== "string" || typeof data.expires_at !== "string") throw invalidResponse();
156
+ return data;
157
+ }
158
+ };
159
+ }
160
+
1
161
  // src/emoji-catalog.ts
2
162
  var EmojiCatalogError = class extends Error {
3
163
  constructor(code, message) {
@@ -256,34 +416,13 @@ var EmojiCatalog = class {
256
416
  };
257
417
 
258
418
  // src/index.ts
259
- var VERSION = "1.11.4";
419
+ var VERSION = "1.12.0";
260
420
  var API_VERSION = "2.0.0";
261
421
  var DEFAULT_BASE_URL = "https://api.parseapi.com";
262
422
  var DEFAULT_TIMEOUT_MS = 1e4;
263
423
  var DEFAULT_RETRIES = 2;
264
424
  var RETRY_STATUS = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
265
425
  var RETRY_AFTER_CAP_MS = 5e3;
266
- var ParseAPIError = class extends Error {
267
- /** HTTP status */
268
- status;
269
- /** Machine-readable error code, e.g. 'not_found', 'invalid_api_key', 'rate_limited' */
270
- code;
271
- /** Link to the docs section for this error */
272
- docs;
273
- /** Send this if you contact support */
274
- requestId;
275
- /** Original Retry-After response header, when supplied. */
276
- retryAfter;
277
- constructor(status, code, message, docs, requestId, retryAfter = null) {
278
- super(message);
279
- this.name = "ParseAPIError";
280
- this.status = status;
281
- this.code = code;
282
- this.docs = docs;
283
- this.requestId = requestId;
284
- this.retryAfter = retryAfter;
285
- }
286
- };
287
426
  var requestControls = (opts) => ({ signal: opts?.signal, timeoutMs: opts?.timeoutMs, retries: opts?.retries });
288
427
  function env(name) {
289
428
  return typeof process !== "undefined" ? process.env?.[name] : void 0;
@@ -714,9 +853,12 @@ function cityCollectionQuery(opts) {
714
853
  };
715
854
  }
716
855
  export {
856
+ BULK_CHECKS,
857
+ ParseAPIError as BulkAPIError,
717
858
  EmojiCatalog,
718
859
  EmojiCatalogError,
719
860
  ParseAPIError,
861
+ createBulkClient,
720
862
  parseAPI
721
863
  };
722
864
  /*! You found Dev. https://parseapi.com/dev */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parseapi/sdk",
3
- "version": "1.11.4",
3
+ "version": "1.12.0",
4
4
  "description": "Official ParseAPI client for Node and TypeScript. One key, minimal JSON, fast.",
5
5
  "keywords": [
6
6
  "parseapi",