@usethrottle/cart 3.5.0 → 3.6.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/dist/index.cjs CHANGED
@@ -21,10 +21,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  CartClient: () => CartClient,
24
+ CartNotFoundError: () => CartNotFoundError,
25
+ CartNotOpenError: () => CartNotOpenError,
24
26
  CartSessionClient: () => CartSessionClient,
25
27
  StorefrontQuoteClient: () => StorefrontQuoteClient,
26
28
  ThrottleApiError: () => ThrottleApiError,
27
29
  ThrottleError: () => import_errors2.ThrottleError,
30
+ cartErrorFromResponse: () => cartErrorFromResponse,
28
31
  isThrottleError: () => import_errors2.isThrottleError
29
32
  });
30
33
  module.exports = __toCommonJS(index_exports);
@@ -38,6 +41,27 @@ var ThrottleApiError = class extends import_errors.ThrottleError {
38
41
  this.name = "ThrottleApiError";
39
42
  }
40
43
  };
44
+ var CartNotOpenError = class extends ThrottleApiError {
45
+ constructor(args) {
46
+ super({ code: "cart_not_open", statusCode: args.statusCode ?? 409, message: args.message, details: args.details });
47
+ this.name = "CartNotOpenError";
48
+ }
49
+ };
50
+ var CartNotFoundError = class extends ThrottleApiError {
51
+ constructor(args) {
52
+ super({ code: "cart_not_found", statusCode: args.statusCode ?? 404, message: args.message, details: args.details });
53
+ this.name = "CartNotFoundError";
54
+ }
55
+ };
56
+ function cartErrorFromResponse(args) {
57
+ if (args.statusCode === 409 && args.code === "cart_not_open") {
58
+ return new CartNotOpenError({ message: args.message, statusCode: args.statusCode, details: args.details });
59
+ }
60
+ if (args.statusCode === 404 && (args.code === "cart_not_found" || args.code === "not_found")) {
61
+ return new CartNotFoundError({ message: args.message, statusCode: args.statusCode, details: args.details });
62
+ }
63
+ return new ThrottleApiError(args);
64
+ }
41
65
 
42
66
  // src/client.ts
43
67
  function segment(value) {
@@ -68,7 +92,7 @@ var CartClient = class {
68
92
  });
69
93
  const json = await res.json().catch(() => ({}));
70
94
  if (!res.ok) {
71
- throw new ThrottleApiError({
95
+ throw cartErrorFromResponse({
72
96
  code: json?.error?.code ?? "unknown_error",
73
97
  message: json?.error?.message ?? `HTTP ${res.status}`,
74
98
  statusCode: res.status,
@@ -282,7 +306,7 @@ var CartSessionClient = class {
282
306
  });
283
307
  const json = await res.json().catch(() => ({}));
284
308
  if (!res.ok) {
285
- throw new ThrottleApiError({
309
+ throw cartErrorFromResponse({
286
310
  code: json?.error?.code ?? "unknown_error",
287
311
  message: json?.error?.message ?? `HTTP ${res.status}`,
288
312
  statusCode: res.status,
@@ -298,9 +322,12 @@ var CartSessionClient = class {
298
322
  // Annotate the CommonJS export names for ESM import in node:
299
323
  0 && (module.exports = {
300
324
  CartClient,
325
+ CartNotFoundError,
326
+ CartNotOpenError,
301
327
  CartSessionClient,
302
328
  StorefrontQuoteClient,
303
329
  ThrottleApiError,
304
330
  ThrottleError,
331
+ cartErrorFromResponse,
305
332
  isThrottleError
306
333
  });
package/dist/index.d.cts CHANGED
@@ -1,6 +1,26 @@
1
1
  import { ThrottleError } from '@usethrottle/errors';
2
2
  export { ThrottleError, isThrottleError } from '@usethrottle/errors';
3
3
 
4
+ /**
5
+ * Canonical address shape used everywhere the Cart API accepts or returns an
6
+ * address. Required fields (`addressLine1`, `city`, `countryCode`) are validated
7
+ * at write time — sending non-canonical keys (`line1`, `state`, `country`, …) is
8
+ * rejected with a did-you-mean hint instead of silently stored and failing later
9
+ * at checkout. Field names match {@link ShippingTaxAddress}.
10
+ */
11
+ interface CartAddress {
12
+ firstName?: string;
13
+ lastName?: string;
14
+ addressLine1: string;
15
+ addressLine2?: string;
16
+ city: string;
17
+ stateProvince?: string;
18
+ postalCode?: string;
19
+ /** ISO-3166-1 alpha-2 country code, e.g. "US". */
20
+ countryCode: string;
21
+ phone?: string;
22
+ email?: string;
23
+ }
4
24
  interface Cart {
5
25
  id: string;
6
26
  workspaceId: string;
@@ -14,8 +34,8 @@ interface Cart {
14
34
  shippingTotal: number;
15
35
  total: number;
16
36
  netN: number | null;
17
- billingAddress: Record<string, unknown> | null;
18
- shippingAddress: Record<string, unknown> | null;
37
+ billingAddress: CartAddress | null;
38
+ shippingAddress: CartAddress | null;
19
39
  notes: string | null;
20
40
  expiresAt: string | null;
21
41
  externalRef?: {
@@ -99,8 +119,8 @@ interface CreateCartInput {
99
119
  }
100
120
  interface UpdateCartInput {
101
121
  customerId?: string;
102
- billingAddress?: Record<string, unknown>;
103
- shippingAddress?: Record<string, unknown>;
122
+ billingAddress?: CartAddress;
123
+ shippingAddress?: CartAddress;
104
124
  notes?: string;
105
125
  netN?: number | null;
106
126
  metadata?: Record<string, unknown>;
@@ -480,5 +500,43 @@ declare class ThrottleApiError extends ThrottleError {
480
500
  details?: Record<string, unknown>;
481
501
  });
482
502
  }
503
+ /**
504
+ * Thrown when an operation targets a cart that is no longer `open` (HTTP 409,
505
+ * `cart_not_open`). A cart leaves `open` when it is converted by a completed
506
+ * order (terminal — start a new cart) or abandoned. Catch this to branch on a
507
+ * stale cart and rebuild from the last-known line items instead of sniffing
508
+ * `error.code`.
509
+ *
510
+ * Subclass of {@link ThrottleApiError} (and therefore {@link ThrottleError}), so
511
+ * existing `instanceof ThrottleApiError` / `.code` checks keep working.
512
+ */
513
+ declare class CartNotOpenError extends ThrottleApiError {
514
+ constructor(args: {
515
+ message: string;
516
+ statusCode?: number;
517
+ details?: Record<string, unknown>;
518
+ });
519
+ }
520
+ /**
521
+ * Thrown when a cart cannot be found for the request's environment (HTTP 404).
522
+ * Subclass of {@link ThrottleApiError}.
523
+ */
524
+ declare class CartNotFoundError extends ThrottleApiError {
525
+ constructor(args: {
526
+ message: string;
527
+ statusCode?: number;
528
+ details?: Record<string, unknown>;
529
+ });
530
+ }
531
+ /**
532
+ * Map a raw API error envelope to the most specific Cart SDK error class.
533
+ * Falls back to {@link ThrottleApiError} for everything unrecognised.
534
+ */
535
+ declare function cartErrorFromResponse(args: {
536
+ code: string;
537
+ message: string;
538
+ statusCode: number;
539
+ details?: Record<string, unknown>;
540
+ }): ThrottleApiError;
483
541
 
484
- export { type AddLineItemInput, type AppliedDiscount, type Cart, CartClient, type CartEvent, type CartSession, CartSessionClient, type CartSessionClientOptions, type CheckoutHandoff, type CheckoutHandoffInput, type CheckoutInput, type CreateCartInput, type CreateCartSessionInput, type ExternalShippingTaxSnapshotInput, type LineItem, type Order, type SelectShippingInput, type SelectedShipping, type ShippingTaxAddress, type ShippingTaxCalculationResponse, type ShippingTaxCartCalculateInput, type ShippingTaxMethod, type ShippingTaxQuoteInput, type ShippingTaxQuoteItem, StorefrontQuoteClient, type TaxLine, type TaxLineInput, ThrottleApiError, type UpdateCartInput, type UpdateLineItemInput };
542
+ export { type AddLineItemInput, type AppliedDiscount, type Cart, type CartAddress, CartClient, type CartEvent, CartNotFoundError, CartNotOpenError, type CartSession, CartSessionClient, type CartSessionClientOptions, type CheckoutHandoff, type CheckoutHandoffInput, type CheckoutInput, type CreateCartInput, type CreateCartSessionInput, type ExternalShippingTaxSnapshotInput, type LineItem, type Order, type SelectShippingInput, type SelectedShipping, type ShippingTaxAddress, type ShippingTaxCalculationResponse, type ShippingTaxCartCalculateInput, type ShippingTaxMethod, type ShippingTaxQuoteInput, type ShippingTaxQuoteItem, StorefrontQuoteClient, type TaxLine, type TaxLineInput, ThrottleApiError, type UpdateCartInput, type UpdateLineItemInput, cartErrorFromResponse };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,26 @@
1
1
  import { ThrottleError } from '@usethrottle/errors';
2
2
  export { ThrottleError, isThrottleError } from '@usethrottle/errors';
3
3
 
4
+ /**
5
+ * Canonical address shape used everywhere the Cart API accepts or returns an
6
+ * address. Required fields (`addressLine1`, `city`, `countryCode`) are validated
7
+ * at write time — sending non-canonical keys (`line1`, `state`, `country`, …) is
8
+ * rejected with a did-you-mean hint instead of silently stored and failing later
9
+ * at checkout. Field names match {@link ShippingTaxAddress}.
10
+ */
11
+ interface CartAddress {
12
+ firstName?: string;
13
+ lastName?: string;
14
+ addressLine1: string;
15
+ addressLine2?: string;
16
+ city: string;
17
+ stateProvince?: string;
18
+ postalCode?: string;
19
+ /** ISO-3166-1 alpha-2 country code, e.g. "US". */
20
+ countryCode: string;
21
+ phone?: string;
22
+ email?: string;
23
+ }
4
24
  interface Cart {
5
25
  id: string;
6
26
  workspaceId: string;
@@ -14,8 +34,8 @@ interface Cart {
14
34
  shippingTotal: number;
15
35
  total: number;
16
36
  netN: number | null;
17
- billingAddress: Record<string, unknown> | null;
18
- shippingAddress: Record<string, unknown> | null;
37
+ billingAddress: CartAddress | null;
38
+ shippingAddress: CartAddress | null;
19
39
  notes: string | null;
20
40
  expiresAt: string | null;
21
41
  externalRef?: {
@@ -99,8 +119,8 @@ interface CreateCartInput {
99
119
  }
100
120
  interface UpdateCartInput {
101
121
  customerId?: string;
102
- billingAddress?: Record<string, unknown>;
103
- shippingAddress?: Record<string, unknown>;
122
+ billingAddress?: CartAddress;
123
+ shippingAddress?: CartAddress;
104
124
  notes?: string;
105
125
  netN?: number | null;
106
126
  metadata?: Record<string, unknown>;
@@ -480,5 +500,43 @@ declare class ThrottleApiError extends ThrottleError {
480
500
  details?: Record<string, unknown>;
481
501
  });
482
502
  }
503
+ /**
504
+ * Thrown when an operation targets a cart that is no longer `open` (HTTP 409,
505
+ * `cart_not_open`). A cart leaves `open` when it is converted by a completed
506
+ * order (terminal — start a new cart) or abandoned. Catch this to branch on a
507
+ * stale cart and rebuild from the last-known line items instead of sniffing
508
+ * `error.code`.
509
+ *
510
+ * Subclass of {@link ThrottleApiError} (and therefore {@link ThrottleError}), so
511
+ * existing `instanceof ThrottleApiError` / `.code` checks keep working.
512
+ */
513
+ declare class CartNotOpenError extends ThrottleApiError {
514
+ constructor(args: {
515
+ message: string;
516
+ statusCode?: number;
517
+ details?: Record<string, unknown>;
518
+ });
519
+ }
520
+ /**
521
+ * Thrown when a cart cannot be found for the request's environment (HTTP 404).
522
+ * Subclass of {@link ThrottleApiError}.
523
+ */
524
+ declare class CartNotFoundError extends ThrottleApiError {
525
+ constructor(args: {
526
+ message: string;
527
+ statusCode?: number;
528
+ details?: Record<string, unknown>;
529
+ });
530
+ }
531
+ /**
532
+ * Map a raw API error envelope to the most specific Cart SDK error class.
533
+ * Falls back to {@link ThrottleApiError} for everything unrecognised.
534
+ */
535
+ declare function cartErrorFromResponse(args: {
536
+ code: string;
537
+ message: string;
538
+ statusCode: number;
539
+ details?: Record<string, unknown>;
540
+ }): ThrottleApiError;
483
541
 
484
- export { type AddLineItemInput, type AppliedDiscount, type Cart, CartClient, type CartEvent, type CartSession, CartSessionClient, type CartSessionClientOptions, type CheckoutHandoff, type CheckoutHandoffInput, type CheckoutInput, type CreateCartInput, type CreateCartSessionInput, type ExternalShippingTaxSnapshotInput, type LineItem, type Order, type SelectShippingInput, type SelectedShipping, type ShippingTaxAddress, type ShippingTaxCalculationResponse, type ShippingTaxCartCalculateInput, type ShippingTaxMethod, type ShippingTaxQuoteInput, type ShippingTaxQuoteItem, StorefrontQuoteClient, type TaxLine, type TaxLineInput, ThrottleApiError, type UpdateCartInput, type UpdateLineItemInput };
542
+ export { type AddLineItemInput, type AppliedDiscount, type Cart, type CartAddress, CartClient, type CartEvent, CartNotFoundError, CartNotOpenError, type CartSession, CartSessionClient, type CartSessionClientOptions, type CheckoutHandoff, type CheckoutHandoffInput, type CheckoutInput, type CreateCartInput, type CreateCartSessionInput, type ExternalShippingTaxSnapshotInput, type LineItem, type Order, type SelectShippingInput, type SelectedShipping, type ShippingTaxAddress, type ShippingTaxCalculationResponse, type ShippingTaxCartCalculateInput, type ShippingTaxMethod, type ShippingTaxQuoteInput, type ShippingTaxQuoteItem, StorefrontQuoteClient, type TaxLine, type TaxLineInput, ThrottleApiError, type UpdateCartInput, type UpdateLineItemInput, cartErrorFromResponse };
package/dist/index.js CHANGED
@@ -7,6 +7,27 @@ var ThrottleApiError = class extends ThrottleError {
7
7
  this.name = "ThrottleApiError";
8
8
  }
9
9
  };
10
+ var CartNotOpenError = class extends ThrottleApiError {
11
+ constructor(args) {
12
+ super({ code: "cart_not_open", statusCode: args.statusCode ?? 409, message: args.message, details: args.details });
13
+ this.name = "CartNotOpenError";
14
+ }
15
+ };
16
+ var CartNotFoundError = class extends ThrottleApiError {
17
+ constructor(args) {
18
+ super({ code: "cart_not_found", statusCode: args.statusCode ?? 404, message: args.message, details: args.details });
19
+ this.name = "CartNotFoundError";
20
+ }
21
+ };
22
+ function cartErrorFromResponse(args) {
23
+ if (args.statusCode === 409 && args.code === "cart_not_open") {
24
+ return new CartNotOpenError({ message: args.message, statusCode: args.statusCode, details: args.details });
25
+ }
26
+ if (args.statusCode === 404 && (args.code === "cart_not_found" || args.code === "not_found")) {
27
+ return new CartNotFoundError({ message: args.message, statusCode: args.statusCode, details: args.details });
28
+ }
29
+ return new ThrottleApiError(args);
30
+ }
10
31
 
11
32
  // src/client.ts
12
33
  function segment(value) {
@@ -37,7 +58,7 @@ var CartClient = class {
37
58
  });
38
59
  const json = await res.json().catch(() => ({}));
39
60
  if (!res.ok) {
40
- throw new ThrottleApiError({
61
+ throw cartErrorFromResponse({
41
62
  code: json?.error?.code ?? "unknown_error",
42
63
  message: json?.error?.message ?? `HTTP ${res.status}`,
43
64
  statusCode: res.status,
@@ -251,7 +272,7 @@ var CartSessionClient = class {
251
272
  });
252
273
  const json = await res.json().catch(() => ({}));
253
274
  if (!res.ok) {
254
- throw new ThrottleApiError({
275
+ throw cartErrorFromResponse({
255
276
  code: json?.error?.code ?? "unknown_error",
256
277
  message: json?.error?.message ?? `HTTP ${res.status}`,
257
278
  statusCode: res.status,
@@ -266,9 +287,12 @@ var CartSessionClient = class {
266
287
  };
267
288
  export {
268
289
  CartClient,
290
+ CartNotFoundError,
291
+ CartNotOpenError,
269
292
  CartSessionClient,
270
293
  StorefrontQuoteClient,
271
294
  ThrottleApiError,
272
295
  ThrottleError2 as ThrottleError,
296
+ cartErrorFromResponse,
273
297
  isThrottleError
274
298
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usethrottle/cart",
3
- "version": "3.5.0",
3
+ "version": "3.6.0",
4
4
  "description": "Typed REST client for the Throttle Cart API.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",