@zernio/node 0.2.784 → 0.2.786

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/dist/index.d.mts CHANGED
@@ -1529,11 +1529,39 @@ declare const Late: typeof Zernio;
1529
1529
  /**
1530
1530
  * Base error class for Zernio API errors
1531
1531
  */
1532
+ /**
1533
+ * The canonical error envelope the API returns. Everything but `error` is
1534
+ * optional, and every field is surfaced on ZernioApiError: dropping any of them
1535
+ * leaves callers unable to tell apart failures the API distinguishes. For a
1536
+ * Meta pass-through in particular, `platformError.subcode` is the only thing
1537
+ * that separates a closed messaging window from a blocked recipient, since both
1538
+ * arrive as code `platform_api_error`.
1539
+ */
1540
+ interface ZernioErrorBody {
1541
+ error?: string;
1542
+ message?: string;
1543
+ type?: string;
1544
+ code?: string;
1545
+ param?: string;
1546
+ platform?: string;
1547
+ platformError?: Record<string, unknown>;
1548
+ details?: Record<string, unknown>;
1549
+ }
1532
1550
  declare class ZernioApiError extends Error {
1533
1551
  readonly statusCode: number;
1534
1552
  readonly code?: string;
1535
1553
  readonly details?: Record<string, unknown>;
1536
- constructor(message: string, statusCode: number, code?: string, details?: Record<string, unknown>);
1554
+ /** Error class, e.g. invalid_request_error, platform_error, rate_limit_error. */
1555
+ readonly type?: string;
1556
+ /** The request field that caused the error, when the API names one. */
1557
+ readonly param?: string;
1558
+ /** Upstream platform, present when type is platform_error. */
1559
+ readonly platform?: string;
1560
+ /** The upstream platform's own payload, verbatim (Meta: code, subcode, fbtrace_id). */
1561
+ readonly platformError?: Record<string, unknown>;
1562
+ /** The parsed response body exactly as the API sent it, for anything not modelled above. */
1563
+ readonly body?: ZernioErrorBody;
1564
+ constructor(message: string, statusCode: number, code?: string, details?: Record<string, unknown>, body?: ZernioErrorBody);
1537
1565
  /**
1538
1566
  * Check if this is a rate limit error
1539
1567
  */
@@ -1568,7 +1596,7 @@ declare class RateLimitError extends ZernioApiError {
1568
1596
  readonly limit?: number;
1569
1597
  readonly remaining?: number;
1570
1598
  readonly resetAt?: Date;
1571
- constructor(message: string, limit?: number, remaining?: number, resetAt?: Date);
1599
+ constructor(message: string, limit?: number, remaining?: number, resetAt?: Date, body?: ZernioErrorBody);
1572
1600
  /**
1573
1601
  * Get seconds until rate limit resets
1574
1602
  */
@@ -1579,17 +1607,12 @@ declare class RateLimitError extends ZernioApiError {
1579
1607
  */
1580
1608
  declare class ValidationError extends ZernioApiError {
1581
1609
  readonly fields?: Record<string, string[]>;
1582
- constructor(message: string, fields?: Record<string, string[]>);
1610
+ constructor(message: string, fields?: Record<string, string[]>, body?: ZernioErrorBody);
1583
1611
  }
1584
1612
  /**
1585
1613
  * Parse an error response from the API
1586
1614
  */
1587
- declare function parseApiError(response: Response, body?: {
1588
- error?: string;
1589
- message?: string;
1590
- code?: string;
1591
- details?: Record<string, unknown>;
1592
- }): ZernioApiError;
1615
+ declare function parseApiError(response: Response, body?: ZernioErrorBody): ZernioApiError;
1593
1616
 
1594
1617
  type AccountsListResponse = {
1595
1618
  accounts: Array<SocialAccount>;
@@ -7421,6 +7444,10 @@ type PhoneNumberStockWatch = {
7421
7444
  * The watched number type, or null when the watch covers every type in the country.
7422
7445
  */
7423
7446
  numberType: ('local' | 'mobile' | 'national' | 'toll_free') | null;
7447
+ /**
7448
+ * The watched area code (NDC), or null when the watch covers every area.
7449
+ */
7450
+ areaCode?: (string) | null;
7424
7451
  createdAt: string;
7425
7452
  };
7426
7453
  /**
@@ -11258,6 +11285,14 @@ type WebhookPayloadPhoneNumberStockAvailable = {
11258
11285
  */
11259
11286
  availableCount: number;
11260
11287
  }>;
11288
+ /**
11289
+ * Set when the watch named an area: the area code (NDC) that is back in stock.
11290
+ */
11291
+ areaCode?: string;
11292
+ /**
11293
+ * The name of that area, when known.
11294
+ */
11295
+ areaName?: string;
11261
11296
  };
11262
11297
  /**
11263
11298
  * UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.
@@ -24695,7 +24730,7 @@ type ReplyToInboxReviewResponse = ({
24695
24730
  };
24696
24731
  platform?: string;
24697
24732
  });
24698
- type ReplyToInboxReviewError = ({
24733
+ type ReplyToInboxReviewError = (ErrorResponse | {
24699
24734
  error?: string;
24700
24735
  } | unknown);
24701
24736
  type DeleteInboxReviewReplyData = {
@@ -27300,6 +27335,24 @@ type CheckPhoneNumberAvailabilityResponse = ({
27300
27335
  */
27301
27336
  count?: number;
27302
27337
  }>;
27338
+ /**
27339
+ * Areas that had stock in the last 90 days and have none now. Pass one as `areaCode` with `preOrder: true` on the KYC submit when `preOrderable` is true, or watch it with POST /v1/phone-numbers/stock-watches.
27340
+ *
27341
+ */
27342
+ soldOutAreas?: Array<{
27343
+ /**
27344
+ * Area code (national destination code).
27345
+ */
27346
+ ndc?: string;
27347
+ /**
27348
+ * Area name.
27349
+ */
27350
+ name?: string;
27351
+ /**
27352
+ * Whether this area can be pre-ordered: the carrier sources a number in it (usually 2 to 4 weeks, never guaranteed).
27353
+ */
27354
+ preOrderable?: boolean;
27355
+ }>;
27303
27356
  });
27304
27357
  type CheckPhoneNumberAvailabilityError = (unknown | {
27305
27358
  error?: string;
@@ -27575,6 +27628,24 @@ type CheckWhatsAppNumberAvailabilityResponse = ({
27575
27628
  */
27576
27629
  count?: number;
27577
27630
  }>;
27631
+ /**
27632
+ * Areas that had stock in the last 90 days and have none now. Pass one as `areaCode` with `preOrder: true` on the KYC submit when `preOrderable` is true, or watch it with POST /v1/phone-numbers/stock-watches.
27633
+ *
27634
+ */
27635
+ soldOutAreas?: Array<{
27636
+ /**
27637
+ * Area code (national destination code).
27638
+ */
27639
+ ndc?: string;
27640
+ /**
27641
+ * Area name.
27642
+ */
27643
+ name?: string;
27644
+ /**
27645
+ * Whether this area can be pre-ordered: the carrier sources a number in it (usually 2 to 4 weeks, never guaranteed).
27646
+ */
27647
+ preOrderable?: boolean;
27648
+ }>;
27578
27649
  });
27579
27650
  type CheckWhatsAppNumberAvailabilityError = (unknown | {
27580
27651
  error?: string;
@@ -27686,6 +27757,10 @@ type SubmitPhoneNumberKycData = {
27686
27757
  * Area code (NDC) the number must be in. Hard constraint: an empty area pool fails with 409 code AREA_CODE_UNAVAILABLE instead of ordering from another area. Omit for any area. Options come from GET /v1/phone-numbers/availability (areaOptions); the purchase 202 kycUrl echoes the areaCode picked at purchase time so it can be passed here.
27687
27758
  */
27688
27759
  areaCode?: string;
27760
+ /**
27761
+ * With areaCode: pre-order that area when it has no stock (an area listed in soldOutAreas with preOrderable true) instead of failing with AREA_CODE_UNAVAILABLE. The carrier sources a number in that area.
27762
+ */
27763
+ preOrder?: boolean;
27689
27764
  /**
27690
27765
  * End user's legal first name. Required when the country has an action/ID-verification (Onfido) requirement.
27691
27766
  */
@@ -28450,6 +28525,10 @@ type SubmitWhatsAppNumberKycData = {
28450
28525
  * Area code (NDC) the number must be in. Hard constraint: an empty area pool fails with 409 code AREA_CODE_UNAVAILABLE instead of ordering from another area. Omit for any area. Options come from GET /v1/phone-numbers/availability (areaOptions); the purchase 202 kycUrl echoes the areaCode picked at purchase time so it can be passed here.
28451
28526
  */
28452
28527
  areaCode?: string;
28528
+ /**
28529
+ * With areaCode: pre-order that area when it has no stock (an area listed in soldOutAreas with preOrderable true) instead of failing with AREA_CODE_UNAVAILABLE. The carrier sources a number in that area.
28530
+ */
28531
+ preOrder?: boolean;
28453
28532
  /**
28454
28533
  * End user's legal first name. Required when the country has an action/ID-verification (Onfido) requirement.
28455
28534
  */
@@ -28836,6 +28915,10 @@ type CreatePhoneNumberStockWatchData = {
28836
28915
  * Narrow the watch to one number type. Omit to be notified when any type in the country is back.
28837
28916
  */
28838
28917
  numberType?: 'local' | 'mobile' | 'national' | 'toll_free';
28918
+ /**
28919
+ * Narrow the watch to one area code (NDC). Requires numberType.
28920
+ */
28921
+ areaCode?: string;
28839
28922
  };
28840
28923
  };
28841
28924
  type CreatePhoneNumberStockWatchResponse = (PhoneNumberStockWatch);
package/dist/index.d.ts CHANGED
@@ -1529,11 +1529,39 @@ declare const Late: typeof Zernio;
1529
1529
  /**
1530
1530
  * Base error class for Zernio API errors
1531
1531
  */
1532
+ /**
1533
+ * The canonical error envelope the API returns. Everything but `error` is
1534
+ * optional, and every field is surfaced on ZernioApiError: dropping any of them
1535
+ * leaves callers unable to tell apart failures the API distinguishes. For a
1536
+ * Meta pass-through in particular, `platformError.subcode` is the only thing
1537
+ * that separates a closed messaging window from a blocked recipient, since both
1538
+ * arrive as code `platform_api_error`.
1539
+ */
1540
+ interface ZernioErrorBody {
1541
+ error?: string;
1542
+ message?: string;
1543
+ type?: string;
1544
+ code?: string;
1545
+ param?: string;
1546
+ platform?: string;
1547
+ platformError?: Record<string, unknown>;
1548
+ details?: Record<string, unknown>;
1549
+ }
1532
1550
  declare class ZernioApiError extends Error {
1533
1551
  readonly statusCode: number;
1534
1552
  readonly code?: string;
1535
1553
  readonly details?: Record<string, unknown>;
1536
- constructor(message: string, statusCode: number, code?: string, details?: Record<string, unknown>);
1554
+ /** Error class, e.g. invalid_request_error, platform_error, rate_limit_error. */
1555
+ readonly type?: string;
1556
+ /** The request field that caused the error, when the API names one. */
1557
+ readonly param?: string;
1558
+ /** Upstream platform, present when type is platform_error. */
1559
+ readonly platform?: string;
1560
+ /** The upstream platform's own payload, verbatim (Meta: code, subcode, fbtrace_id). */
1561
+ readonly platformError?: Record<string, unknown>;
1562
+ /** The parsed response body exactly as the API sent it, for anything not modelled above. */
1563
+ readonly body?: ZernioErrorBody;
1564
+ constructor(message: string, statusCode: number, code?: string, details?: Record<string, unknown>, body?: ZernioErrorBody);
1537
1565
  /**
1538
1566
  * Check if this is a rate limit error
1539
1567
  */
@@ -1568,7 +1596,7 @@ declare class RateLimitError extends ZernioApiError {
1568
1596
  readonly limit?: number;
1569
1597
  readonly remaining?: number;
1570
1598
  readonly resetAt?: Date;
1571
- constructor(message: string, limit?: number, remaining?: number, resetAt?: Date);
1599
+ constructor(message: string, limit?: number, remaining?: number, resetAt?: Date, body?: ZernioErrorBody);
1572
1600
  /**
1573
1601
  * Get seconds until rate limit resets
1574
1602
  */
@@ -1579,17 +1607,12 @@ declare class RateLimitError extends ZernioApiError {
1579
1607
  */
1580
1608
  declare class ValidationError extends ZernioApiError {
1581
1609
  readonly fields?: Record<string, string[]>;
1582
- constructor(message: string, fields?: Record<string, string[]>);
1610
+ constructor(message: string, fields?: Record<string, string[]>, body?: ZernioErrorBody);
1583
1611
  }
1584
1612
  /**
1585
1613
  * Parse an error response from the API
1586
1614
  */
1587
- declare function parseApiError(response: Response, body?: {
1588
- error?: string;
1589
- message?: string;
1590
- code?: string;
1591
- details?: Record<string, unknown>;
1592
- }): ZernioApiError;
1615
+ declare function parseApiError(response: Response, body?: ZernioErrorBody): ZernioApiError;
1593
1616
 
1594
1617
  type AccountsListResponse = {
1595
1618
  accounts: Array<SocialAccount>;
@@ -7421,6 +7444,10 @@ type PhoneNumberStockWatch = {
7421
7444
  * The watched number type, or null when the watch covers every type in the country.
7422
7445
  */
7423
7446
  numberType: ('local' | 'mobile' | 'national' | 'toll_free') | null;
7447
+ /**
7448
+ * The watched area code (NDC), or null when the watch covers every area.
7449
+ */
7450
+ areaCode?: (string) | null;
7424
7451
  createdAt: string;
7425
7452
  };
7426
7453
  /**
@@ -11258,6 +11285,14 @@ type WebhookPayloadPhoneNumberStockAvailable = {
11258
11285
  */
11259
11286
  availableCount: number;
11260
11287
  }>;
11288
+ /**
11289
+ * Set when the watch named an area: the area code (NDC) that is back in stock.
11290
+ */
11291
+ areaCode?: string;
11292
+ /**
11293
+ * The name of that area, when known.
11294
+ */
11295
+ areaName?: string;
11261
11296
  };
11262
11297
  /**
11263
11298
  * UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.
@@ -24695,7 +24730,7 @@ type ReplyToInboxReviewResponse = ({
24695
24730
  };
24696
24731
  platform?: string;
24697
24732
  });
24698
- type ReplyToInboxReviewError = ({
24733
+ type ReplyToInboxReviewError = (ErrorResponse | {
24699
24734
  error?: string;
24700
24735
  } | unknown);
24701
24736
  type DeleteInboxReviewReplyData = {
@@ -27300,6 +27335,24 @@ type CheckPhoneNumberAvailabilityResponse = ({
27300
27335
  */
27301
27336
  count?: number;
27302
27337
  }>;
27338
+ /**
27339
+ * Areas that had stock in the last 90 days and have none now. Pass one as `areaCode` with `preOrder: true` on the KYC submit when `preOrderable` is true, or watch it with POST /v1/phone-numbers/stock-watches.
27340
+ *
27341
+ */
27342
+ soldOutAreas?: Array<{
27343
+ /**
27344
+ * Area code (national destination code).
27345
+ */
27346
+ ndc?: string;
27347
+ /**
27348
+ * Area name.
27349
+ */
27350
+ name?: string;
27351
+ /**
27352
+ * Whether this area can be pre-ordered: the carrier sources a number in it (usually 2 to 4 weeks, never guaranteed).
27353
+ */
27354
+ preOrderable?: boolean;
27355
+ }>;
27303
27356
  });
27304
27357
  type CheckPhoneNumberAvailabilityError = (unknown | {
27305
27358
  error?: string;
@@ -27575,6 +27628,24 @@ type CheckWhatsAppNumberAvailabilityResponse = ({
27575
27628
  */
27576
27629
  count?: number;
27577
27630
  }>;
27631
+ /**
27632
+ * Areas that had stock in the last 90 days and have none now. Pass one as `areaCode` with `preOrder: true` on the KYC submit when `preOrderable` is true, or watch it with POST /v1/phone-numbers/stock-watches.
27633
+ *
27634
+ */
27635
+ soldOutAreas?: Array<{
27636
+ /**
27637
+ * Area code (national destination code).
27638
+ */
27639
+ ndc?: string;
27640
+ /**
27641
+ * Area name.
27642
+ */
27643
+ name?: string;
27644
+ /**
27645
+ * Whether this area can be pre-ordered: the carrier sources a number in it (usually 2 to 4 weeks, never guaranteed).
27646
+ */
27647
+ preOrderable?: boolean;
27648
+ }>;
27578
27649
  });
27579
27650
  type CheckWhatsAppNumberAvailabilityError = (unknown | {
27580
27651
  error?: string;
@@ -27686,6 +27757,10 @@ type SubmitPhoneNumberKycData = {
27686
27757
  * Area code (NDC) the number must be in. Hard constraint: an empty area pool fails with 409 code AREA_CODE_UNAVAILABLE instead of ordering from another area. Omit for any area. Options come from GET /v1/phone-numbers/availability (areaOptions); the purchase 202 kycUrl echoes the areaCode picked at purchase time so it can be passed here.
27687
27758
  */
27688
27759
  areaCode?: string;
27760
+ /**
27761
+ * With areaCode: pre-order that area when it has no stock (an area listed in soldOutAreas with preOrderable true) instead of failing with AREA_CODE_UNAVAILABLE. The carrier sources a number in that area.
27762
+ */
27763
+ preOrder?: boolean;
27689
27764
  /**
27690
27765
  * End user's legal first name. Required when the country has an action/ID-verification (Onfido) requirement.
27691
27766
  */
@@ -28450,6 +28525,10 @@ type SubmitWhatsAppNumberKycData = {
28450
28525
  * Area code (NDC) the number must be in. Hard constraint: an empty area pool fails with 409 code AREA_CODE_UNAVAILABLE instead of ordering from another area. Omit for any area. Options come from GET /v1/phone-numbers/availability (areaOptions); the purchase 202 kycUrl echoes the areaCode picked at purchase time so it can be passed here.
28451
28526
  */
28452
28527
  areaCode?: string;
28528
+ /**
28529
+ * With areaCode: pre-order that area when it has no stock (an area listed in soldOutAreas with preOrderable true) instead of failing with AREA_CODE_UNAVAILABLE. The carrier sources a number in that area.
28530
+ */
28531
+ preOrder?: boolean;
28453
28532
  /**
28454
28533
  * End user's legal first name. Required when the country has an action/ID-verification (Onfido) requirement.
28455
28534
  */
@@ -28836,6 +28915,10 @@ type CreatePhoneNumberStockWatchData = {
28836
28915
  * Narrow the watch to one number type. Omit to be notified when any type in the country is back.
28837
28916
  */
28838
28917
  numberType?: 'local' | 'mobile' | 'national' | 'toll_free';
28918
+ /**
28919
+ * Narrow the watch to one area code (NDC). Requires numberType.
28920
+ */
28921
+ areaCode?: string;
28839
28922
  };
28840
28923
  };
28841
28924
  type CreatePhoneNumberStockWatchResponse = (PhoneNumberStockWatch);
package/dist/index.js CHANGED
@@ -36,7 +36,7 @@ module.exports = __toCommonJS(index_exports);
36
36
  // package.json
37
37
  var package_default = {
38
38
  name: "@zernio/node",
39
- version: "0.2.784",
39
+ version: "0.2.786",
40
40
  description: "The official Node.js library for the Zernio API",
41
41
  main: "dist/index.js",
42
42
  module: "dist/index.mjs",
@@ -4756,12 +4756,17 @@ var downloadTikTokVideo = (options) => {
4756
4756
 
4757
4757
  // src/errors.ts
4758
4758
  var ZernioApiError = class _ZernioApiError extends Error {
4759
- constructor(message, statusCode, code, details) {
4759
+ constructor(message, statusCode, code, details, body) {
4760
4760
  super(message);
4761
4761
  this.name = "ZernioApiError";
4762
4762
  this.statusCode = statusCode;
4763
4763
  this.code = code;
4764
4764
  this.details = details;
4765
+ this.type = body?.type;
4766
+ this.param = body?.param;
4767
+ this.platform = body?.platform;
4768
+ this.platformError = body?.platformError;
4769
+ this.body = body;
4765
4770
  if (Error.captureStackTrace) {
4766
4771
  Error.captureStackTrace(this, _ZernioApiError);
4767
4772
  }
@@ -4805,8 +4810,8 @@ var ZernioApiError = class _ZernioApiError extends Error {
4805
4810
  };
4806
4811
  var LateApiError = ZernioApiError;
4807
4812
  var RateLimitError = class extends ZernioApiError {
4808
- constructor(message, limit, remaining, resetAt) {
4809
- super(message, 429, "rate_limit_exceeded");
4813
+ constructor(message, limit, remaining, resetAt, body) {
4814
+ super(message, 429, body?.code ?? "rate_limit_exceeded", body?.details, body);
4810
4815
  this.name = "RateLimitError";
4811
4816
  this.limit = limit;
4812
4817
  this.remaining = remaining;
@@ -4821,8 +4826,8 @@ var RateLimitError = class extends ZernioApiError {
4821
4826
  }
4822
4827
  };
4823
4828
  var ValidationError = class extends ZernioApiError {
4824
- constructor(message, fields) {
4825
- super(message, 400, "validation_error", { fields });
4829
+ constructor(message, fields, body) {
4830
+ super(message, 400, body?.code ?? "validation_error", body?.details ?? { fields }, body);
4826
4831
  this.name = "ValidationError";
4827
4832
  this.fields = fields;
4828
4833
  }
@@ -4839,13 +4844,14 @@ function parseApiError(response, body) {
4839
4844
  message,
4840
4845
  limit ? parseInt(limit, 10) : void 0,
4841
4846
  remaining ? parseInt(remaining, 10) : void 0,
4842
- reset ? new Date(parseInt(reset, 10) * 1e3) : void 0
4847
+ reset ? new Date(parseInt(reset, 10) * 1e3) : void 0,
4848
+ body
4843
4849
  );
4844
4850
  }
4845
4851
  if (response.status === 400 && details?.fields) {
4846
- return new ValidationError(message, details.fields);
4852
+ return new ValidationError(message, details.fields, body);
4847
4853
  }
4848
- return new ZernioApiError(message, response.status, code, details);
4854
+ return new ZernioApiError(message, response.status, code, details, body);
4849
4855
  }
4850
4856
 
4851
4857
  // src/client.ts
package/dist/index.mjs CHANGED
@@ -5,7 +5,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
5
5
  // package.json
6
6
  var package_default = {
7
7
  name: "@zernio/node",
8
- version: "0.2.784",
8
+ version: "0.2.786",
9
9
  description: "The official Node.js library for the Zernio API",
10
10
  main: "dist/index.js",
11
11
  module: "dist/index.mjs",
@@ -4725,12 +4725,17 @@ var downloadTikTokVideo = (options) => {
4725
4725
 
4726
4726
  // src/errors.ts
4727
4727
  var ZernioApiError = class _ZernioApiError extends Error {
4728
- constructor(message, statusCode, code, details) {
4728
+ constructor(message, statusCode, code, details, body) {
4729
4729
  super(message);
4730
4730
  this.name = "ZernioApiError";
4731
4731
  this.statusCode = statusCode;
4732
4732
  this.code = code;
4733
4733
  this.details = details;
4734
+ this.type = body?.type;
4735
+ this.param = body?.param;
4736
+ this.platform = body?.platform;
4737
+ this.platformError = body?.platformError;
4738
+ this.body = body;
4734
4739
  if (Error.captureStackTrace) {
4735
4740
  Error.captureStackTrace(this, _ZernioApiError);
4736
4741
  }
@@ -4774,8 +4779,8 @@ var ZernioApiError = class _ZernioApiError extends Error {
4774
4779
  };
4775
4780
  var LateApiError = ZernioApiError;
4776
4781
  var RateLimitError = class extends ZernioApiError {
4777
- constructor(message, limit, remaining, resetAt) {
4778
- super(message, 429, "rate_limit_exceeded");
4782
+ constructor(message, limit, remaining, resetAt, body) {
4783
+ super(message, 429, body?.code ?? "rate_limit_exceeded", body?.details, body);
4779
4784
  this.name = "RateLimitError";
4780
4785
  this.limit = limit;
4781
4786
  this.remaining = remaining;
@@ -4790,8 +4795,8 @@ var RateLimitError = class extends ZernioApiError {
4790
4795
  }
4791
4796
  };
4792
4797
  var ValidationError = class extends ZernioApiError {
4793
- constructor(message, fields) {
4794
- super(message, 400, "validation_error", { fields });
4798
+ constructor(message, fields, body) {
4799
+ super(message, 400, body?.code ?? "validation_error", body?.details ?? { fields }, body);
4795
4800
  this.name = "ValidationError";
4796
4801
  this.fields = fields;
4797
4802
  }
@@ -4808,13 +4813,14 @@ function parseApiError(response, body) {
4808
4813
  message,
4809
4814
  limit ? parseInt(limit, 10) : void 0,
4810
4815
  remaining ? parseInt(remaining, 10) : void 0,
4811
- reset ? new Date(parseInt(reset, 10) * 1e3) : void 0
4816
+ reset ? new Date(parseInt(reset, 10) * 1e3) : void 0,
4817
+ body
4812
4818
  );
4813
4819
  }
4814
4820
  if (response.status === 400 && details?.fields) {
4815
- return new ValidationError(message, details.fields);
4821
+ return new ValidationError(message, details.fields, body);
4816
4822
  }
4817
- return new ZernioApiError(message, response.status, code, details);
4823
+ return new ZernioApiError(message, response.status, code, details, body);
4818
4824
  }
4819
4825
 
4820
4826
  // src/client.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zernio/node",
3
- "version": "0.2.784",
3
+ "version": "0.2.786",
4
4
  "description": "The official Node.js library for the Zernio API",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
package/src/errors.ts CHANGED
@@ -1,22 +1,57 @@
1
1
  /**
2
2
  * Base error class for Zernio API errors
3
3
  */
4
+ /**
5
+ * The canonical error envelope the API returns. Everything but `error` is
6
+ * optional, and every field is surfaced on ZernioApiError: dropping any of them
7
+ * leaves callers unable to tell apart failures the API distinguishes. For a
8
+ * Meta pass-through in particular, `platformError.subcode` is the only thing
9
+ * that separates a closed messaging window from a blocked recipient, since both
10
+ * arrive as code `platform_api_error`.
11
+ */
12
+ export interface ZernioErrorBody {
13
+ error?: string;
14
+ message?: string;
15
+ type?: string;
16
+ code?: string;
17
+ param?: string;
18
+ platform?: string;
19
+ platformError?: Record<string, unknown>;
20
+ details?: Record<string, unknown>;
21
+ }
22
+
4
23
  export class ZernioApiError extends Error {
5
24
  public readonly statusCode: number;
6
25
  public readonly code?: string;
7
26
  public readonly details?: Record<string, unknown>;
27
+ /** Error class, e.g. invalid_request_error, platform_error, rate_limit_error. */
28
+ public readonly type?: string;
29
+ /** The request field that caused the error, when the API names one. */
30
+ public readonly param?: string;
31
+ /** Upstream platform, present when type is platform_error. */
32
+ public readonly platform?: string;
33
+ /** The upstream platform's own payload, verbatim (Meta: code, subcode, fbtrace_id). */
34
+ public readonly platformError?: Record<string, unknown>;
35
+ /** The parsed response body exactly as the API sent it, for anything not modelled above. */
36
+ public readonly body?: ZernioErrorBody;
8
37
 
9
38
  constructor(
10
39
  message: string,
11
40
  statusCode: number,
12
41
  code?: string,
13
- details?: Record<string, unknown>
42
+ details?: Record<string, unknown>,
43
+ body?: ZernioErrorBody
14
44
  ) {
15
45
  super(message);
16
46
  this.name = 'ZernioApiError';
17
47
  this.statusCode = statusCode;
18
48
  this.code = code;
19
49
  this.details = details;
50
+ this.type = body?.type;
51
+ this.param = body?.param;
52
+ this.platform = body?.platform;
53
+ this.platformError = body?.platformError;
54
+ this.body = body;
20
55
 
21
56
  // Maintains proper stack trace for where error was thrown
22
57
  if (Error.captureStackTrace) {
@@ -82,9 +117,12 @@ export class RateLimitError extends ZernioApiError {
82
117
  message: string,
83
118
  limit?: number,
84
119
  remaining?: number,
85
- resetAt?: Date
120
+ resetAt?: Date,
121
+ body?: ZernioErrorBody
86
122
  ) {
87
- super(message, 429, 'rate_limit_exceeded');
123
+ // The envelope's own code wins when the API sent one: a Google Ads quota
124
+ // 429 and a Zernio rate limit are different failures.
125
+ super(message, 429, body?.code ?? 'rate_limit_exceeded', body?.details, body);
88
126
  this.name = 'RateLimitError';
89
127
  this.limit = limit;
90
128
  this.remaining = remaining;
@@ -106,8 +144,8 @@ export class RateLimitError extends ZernioApiError {
106
144
  export class ValidationError extends ZernioApiError {
107
145
  public readonly fields?: Record<string, string[]>;
108
146
 
109
- constructor(message: string, fields?: Record<string, string[]>) {
110
- super(message, 400, 'validation_error', { fields });
147
+ constructor(message: string, fields?: Record<string, string[]>, body?: ZernioErrorBody) {
148
+ super(message, 400, body?.code ?? 'validation_error', body?.details ?? { fields }, body);
111
149
  this.name = 'ValidationError';
112
150
  this.fields = fields;
113
151
  }
@@ -118,7 +156,7 @@ export class ValidationError extends ZernioApiError {
118
156
  */
119
157
  export function parseApiError(
120
158
  response: Response,
121
- body?: { error?: string; message?: string; code?: string; details?: Record<string, unknown> }
159
+ body?: ZernioErrorBody
122
160
  ): ZernioApiError {
123
161
  const message = body?.error || body?.message || response.statusText || 'Unknown error';
124
162
  const code = body?.code;
@@ -134,14 +172,15 @@ export function parseApiError(
134
172
  message,
135
173
  limit ? parseInt(limit, 10) : undefined,
136
174
  remaining ? parseInt(remaining, 10) : undefined,
137
- reset ? new Date(parseInt(reset, 10) * 1000) : undefined
175
+ reset ? new Date(parseInt(reset, 10) * 1000) : undefined,
176
+ body
138
177
  );
139
178
  }
140
179
 
141
180
  // Handle validation errors
142
181
  if (response.status === 400 && details?.fields) {
143
- return new ValidationError(message, details.fields as Record<string, string[]>);
182
+ return new ValidationError(message, details.fields as Record<string, string[]>, body);
144
183
  }
145
184
 
146
- return new ZernioApiError(message, response.status, code, details);
185
+ return new ZernioApiError(message, response.status, code, details, body);
147
186
  }
@@ -6642,6 +6642,11 @@ export const disableVoiceOnNumber = <ThrowOnError extends boolean = false>(optio
6642
6642
  * `preOrderable: true` does not need a watch: submit KYC and the carrier
6643
6643
  * sources the number to order.
6644
6644
  *
6645
+ * Pass `areaCode` (with `numberType`) to watch one sold-out area, for
6646
+ * example an entry of `soldOutAreas` from
6647
+ * GET /v1/phone-numbers/availability. Area stock is checked live on the
6648
+ * same 6h cadence.
6649
+ *
6645
6650
  */
6646
6651
  export const createPhoneNumberStockWatch = <ThrowOnError extends boolean = false>(options: OptionsLegacyParser<CreatePhoneNumberStockWatchData, ThrowOnError>) => {
6647
6652
  return (options?.client ?? client).post<CreatePhoneNumberStockWatchResponse, CreatePhoneNumberStockWatchError, ThrowOnError>({
@@ -6059,6 +6059,10 @@ export type PhoneNumberStockWatch = {
6059
6059
  * The watched number type, or null when the watch covers every type in the country.
6060
6060
  */
6061
6061
  numberType: ('local' | 'mobile' | 'national' | 'toll_free') | null;
6062
+ /**
6063
+ * The watched area code (NDC), or null when the watch covers every area.
6064
+ */
6065
+ areaCode?: (string) | null;
6062
6066
  createdAt: string;
6063
6067
  };
6064
6068
 
@@ -10042,6 +10046,14 @@ export type WebhookPayloadPhoneNumberStockAvailable = {
10042
10046
  */
10043
10047
  availableCount: number;
10044
10048
  }>;
10049
+ /**
10050
+ * Set when the watch named an area: the area code (NDC) that is back in stock.
10051
+ */
10052
+ areaCode?: string;
10053
+ /**
10054
+ * The name of that area, when known.
10055
+ */
10056
+ areaName?: string;
10045
10057
  };
10046
10058
  /**
10047
10059
  * UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.
@@ -24353,7 +24365,7 @@ export type ReplyToInboxReviewResponse = ({
24353
24365
  platform?: string;
24354
24366
  });
24355
24367
 
24356
- export type ReplyToInboxReviewError = ({
24368
+ export type ReplyToInboxReviewError = (ErrorResponse | {
24357
24369
  error?: string;
24358
24370
  } | unknown);
24359
24371
 
@@ -27179,6 +27191,24 @@ export type CheckPhoneNumberAvailabilityResponse = ({
27179
27191
  */
27180
27192
  count?: number;
27181
27193
  }>;
27194
+ /**
27195
+ * Areas that had stock in the last 90 days and have none now. Pass one as `areaCode` with `preOrder: true` on the KYC submit when `preOrderable` is true, or watch it with POST /v1/phone-numbers/stock-watches.
27196
+ *
27197
+ */
27198
+ soldOutAreas?: Array<{
27199
+ /**
27200
+ * Area code (national destination code).
27201
+ */
27202
+ ndc?: string;
27203
+ /**
27204
+ * Area name.
27205
+ */
27206
+ name?: string;
27207
+ /**
27208
+ * Whether this area can be pre-ordered: the carrier sources a number in it (usually 2 to 4 weeks, never guaranteed).
27209
+ */
27210
+ preOrderable?: boolean;
27211
+ }>;
27182
27212
  });
27183
27213
 
27184
27214
  export type CheckPhoneNumberAvailabilityError = (unknown | {
@@ -27468,6 +27498,24 @@ export type CheckWhatsAppNumberAvailabilityResponse = ({
27468
27498
  */
27469
27499
  count?: number;
27470
27500
  }>;
27501
+ /**
27502
+ * Areas that had stock in the last 90 days and have none now. Pass one as `areaCode` with `preOrder: true` on the KYC submit when `preOrderable` is true, or watch it with POST /v1/phone-numbers/stock-watches.
27503
+ *
27504
+ */
27505
+ soldOutAreas?: Array<{
27506
+ /**
27507
+ * Area code (national destination code).
27508
+ */
27509
+ ndc?: string;
27510
+ /**
27511
+ * Area name.
27512
+ */
27513
+ name?: string;
27514
+ /**
27515
+ * Whether this area can be pre-ordered: the carrier sources a number in it (usually 2 to 4 weeks, never guaranteed).
27516
+ */
27517
+ preOrderable?: boolean;
27518
+ }>;
27471
27519
  });
27472
27520
 
27473
27521
  export type CheckWhatsAppNumberAvailabilityError = (unknown | {
@@ -27584,6 +27632,10 @@ export type SubmitPhoneNumberKycData = {
27584
27632
  * Area code (NDC) the number must be in. Hard constraint: an empty area pool fails with 409 code AREA_CODE_UNAVAILABLE instead of ordering from another area. Omit for any area. Options come from GET /v1/phone-numbers/availability (areaOptions); the purchase 202 kycUrl echoes the areaCode picked at purchase time so it can be passed here.
27585
27633
  */
27586
27634
  areaCode?: string;
27635
+ /**
27636
+ * With areaCode: pre-order that area when it has no stock (an area listed in soldOutAreas with preOrderable true) instead of failing with AREA_CODE_UNAVAILABLE. The carrier sources a number in that area.
27637
+ */
27638
+ preOrder?: boolean;
27587
27639
  /**
27588
27640
  * End user's legal first name. Required when the country has an action/ID-verification (Onfido) requirement.
27589
27641
  */
@@ -28401,6 +28453,10 @@ export type SubmitWhatsAppNumberKycData = {
28401
28453
  * Area code (NDC) the number must be in. Hard constraint: an empty area pool fails with 409 code AREA_CODE_UNAVAILABLE instead of ordering from another area. Omit for any area. Options come from GET /v1/phone-numbers/availability (areaOptions); the purchase 202 kycUrl echoes the areaCode picked at purchase time so it can be passed here.
28402
28454
  */
28403
28455
  areaCode?: string;
28456
+ /**
28457
+ * With areaCode: pre-order that area when it has no stock (an area listed in soldOutAreas with preOrderable true) instead of failing with AREA_CODE_UNAVAILABLE. The carrier sources a number in that area.
28458
+ */
28459
+ preOrder?: boolean;
28404
28460
  /**
28405
28461
  * End user's legal first name. Required when the country has an action/ID-verification (Onfido) requirement.
28406
28462
  */
@@ -28814,6 +28870,10 @@ export type CreatePhoneNumberStockWatchData = {
28814
28870
  * Narrow the watch to one number type. Omit to be notified when any type in the country is back.
28815
28871
  */
28816
28872
  numberType?: 'local' | 'mobile' | 'national' | 'toll_free';
28873
+ /**
28874
+ * Narrow the watch to one area code (NDC). Requires numberType.
28875
+ */
28876
+ areaCode?: string;
28817
28877
  };
28818
28878
  };
28819
28879