brainerce 1.38.0 → 1.39.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
@@ -1526,10 +1526,19 @@ fields.forEach((field) => {
1526
1526
  // field.required: whether customer must fill this in
1527
1527
  // field.minLength, field.maxLength: validation for text fields
1528
1528
  // field.minValue, field.maxValue: validation for number fields
1529
- // field.enumValues: allowed options for dropdown fields
1529
+ // field.enumValues: CustomizationFieldOption[] for SELECT/MULTI_SELECT
1530
+ // each option: { label: string, value: string, swatchColor?: string, swatchImageUrl?: string }
1531
+ // use option.value for metadata submission, option.label for display
1530
1532
  // field.defaultValue: default value to pre-fill
1531
1533
  });
1532
1534
 
1535
+ // Render SELECT options using label/value (not string[] anymore):
1536
+ for (const option of field.enumValues ?? []) {
1537
+ // option.label → show to user (e.g. "Gold")
1538
+ // option.value → submit in metadata (e.g. "gold")
1539
+ // option.swatchColor → hex color for color swatch UI, if set
1540
+ }
1541
+
1533
1542
  // Customer fills in values, then add to cart with metadata
1534
1543
  await client.addToCart(cartId, {
1535
1544
  productId: product.id,
@@ -1537,10 +1546,23 @@ await client.addToCart(cartId, {
1537
1546
  metadata: {
1538
1547
  cake_text: 'Happy Birthday!', // TEXT field
1539
1548
  font_color: '#FF0000', // COLOR field
1549
+ frame_color: 'gold', // SELECT — use option.value
1540
1550
  },
1541
1551
  });
1542
1552
  ```
1543
1553
 
1554
+ **Display customizations in cart/checkout — no extra API call needed:**
1555
+
1556
+ `CartItem` and `CheckoutLineItem` both include a `customizations` object with resolved labels. Use it directly — no need to call `getProduct()` per item.
1557
+
1558
+ ```typescript
1559
+ // Works for CartItem, CheckoutLineItem, and OrderItem — same shape
1560
+ const summary = Object.values(item.customizations ?? {})
1561
+ .map(c => `${c.label}: ${Array.isArray(c.value) ? c.value.join(', ') : c.value}`)
1562
+ .join(' | ');
1563
+ // e.g. "Frame color: Gold | Add-ons: Gift wrap, Engraving"
1564
+ ```
1565
+
1544
1566
  **For IMAGE/GALLERY fields**, upload the file first:
1545
1567
 
1546
1568
  ```typescript
@@ -3550,6 +3572,26 @@ await client.createZoneShippingRate('zone_id', {
3550
3572
  });
3551
3573
  ```
3552
3574
 
3575
+ ### App Store Shipping (Shippo)
3576
+
3577
+ Once a merchant installs the Shippo app from the Brainerce App Store and connects their own
3578
+ Shippo account, live carrier rates appear automatically at checkout. Billing goes directly
3579
+ to the merchant's Shippo account.
3580
+
3581
+ ```typescript
3582
+ // After an order is placed, purchase a shipping label:
3583
+ const label = await admin.createShippingLabel(orderId, {
3584
+ shippoRateObjectId: 'rate_8f123456789abcdef', // Shippo rate.object_id from checkout rates
3585
+ });
3586
+
3587
+ console.log(label.labelUrl); // PDF label URL for printing
3588
+ console.log(label.trackingNumber); // Auto-populated on the order
3589
+ console.log(label.carrier); // e.g. 'USPS', 'UPS', 'FedEx'
3590
+ ```
3591
+
3592
+ The `trackingNumber` is stored on the `Order` automatically — customers see it in their
3593
+ order history without any extra integration work.
3594
+
3553
3595
  ### Tax Configuration
3554
3596
 
3555
3597
  `rate` is a **whole percentage** (`7.25` = 7.25%, not `0.0725`). A rate may target
package/dist/index.d.mts CHANGED
@@ -1806,6 +1806,20 @@ interface CartItem {
1806
1806
  notes?: string | null;
1807
1807
  /** Optional metadata for this line item */
1808
1808
  metadata?: Record<string, unknown> | null;
1809
+ /**
1810
+ * Resolved customer input field values with merchant-defined labels.
1811
+ * Mirrors `OrderItem.customizations` — same shape, live (not order-frozen).
1812
+ * Present only when the item has at least one customization value set.
1813
+ *
1814
+ * @example
1815
+ * // Display "Color: Silver / Size: 45" without an extra getProduct() call:
1816
+ * Object.entries(item.customizations ?? {}).map(([, c]) => `${c.label}: ${c.value}`)
1817
+ */
1818
+ customizations?: Record<string, {
1819
+ label: string;
1820
+ value: string | string[];
1821
+ type: string;
1822
+ }>;
1809
1823
  /**
1810
1824
  * Per-line modifier breakdown — present when the line was added with
1811
1825
  * modifier `selections`. Snapshot taken at add-time; immutable to catalog
@@ -2326,6 +2340,20 @@ interface CheckoutLineItem {
2326
2340
  notes?: string | null;
2327
2341
  /** Custom metadata including customer input field values */
2328
2342
  metadata?: Record<string, unknown> | null;
2343
+ /**
2344
+ * Resolved customer input field values with merchant-defined labels.
2345
+ * Mirrors `OrderItem.customizations` — same shape, live (not order-frozen).
2346
+ * Present only when the item has at least one customization value set.
2347
+ *
2348
+ * @example
2349
+ * // Render "Color: Silver / Ring size: 45" in your checkout summary:
2350
+ * Object.entries(item.customizations ?? {}).map(([, c]) => `${c.label}: ${c.value}`)
2351
+ */
2352
+ customizations?: Record<string, {
2353
+ label: string;
2354
+ value: string | string[];
2355
+ type: string;
2356
+ }>;
2329
2357
  }
2330
2358
  /**
2331
2359
  * Represents an available shipping rate/method for checkout.
@@ -3983,7 +4011,8 @@ interface MetafieldDefinition {
3983
4011
  maxLength?: number | null;
3984
4012
  minValue?: number | null;
3985
4013
  maxValue?: number | null;
3986
- enumValues?: string[] | null;
4014
+ /** Allowed values for SELECT / MULTI_SELECT fields, with optional swatch metadata. */
4015
+ enumValues?: CustomizationFieldOption[] | null;
3987
4016
  defaultValue?: string | null;
3988
4017
  position: number;
3989
4018
  isActive: boolean;
@@ -4067,7 +4096,8 @@ interface PublicMetafieldDefinition {
4067
4096
  * Pair with `getProducts({ metafields: { [key]: [...] } })`.
4068
4097
  */
4069
4098
  filterable?: boolean;
4070
- enumValues?: string[];
4099
+ /** Allowed values for SELECT / MULTI_SELECT fields, with optional swatch metadata. */
4100
+ enumValues?: CustomizationFieldOption[];
4071
4101
  minLength?: number | null;
4072
4102
  maxLength?: number | null;
4073
4103
  minValue?: number | null;
@@ -4075,6 +4105,20 @@ interface PublicMetafieldDefinition {
4075
4105
  defaultValue?: string | null;
4076
4106
  position: number;
4077
4107
  }
4108
+ /**
4109
+ * A single selectable option for a SELECT or MULTI_SELECT customization field.
4110
+ * Legacy string-only `enumValues` arrays are automatically promoted to this shape.
4111
+ */
4112
+ interface CustomizationFieldOption {
4113
+ /** Human-readable label shown in the storefront UI (e.g., "Rose Gold"). */
4114
+ label: string;
4115
+ /** Value stored in `CartItem.metadata` and carried through to `OrderItem.customizations`. */
4116
+ value: string;
4117
+ /** Optional CSS hex color for rendering a color swatch (e.g., "#B76E79"). */
4118
+ swatchColor?: string | null;
4119
+ /** Optional image URL for rendering a texture/image swatch. */
4120
+ swatchImageUrl?: string | null;
4121
+ }
4078
4122
  /**
4079
4123
  * Customer-facing input field definition assigned to a specific product.
4080
4124
  * Returned in product responses to tell the storefront which input fields to render.
@@ -4090,7 +4134,11 @@ interface ProductCustomizationField {
4090
4134
  maxLength?: number | null;
4091
4135
  minValue?: number | null;
4092
4136
  maxValue?: number | null;
4093
- enumValues?: string[];
4137
+ /**
4138
+ * Allowed values for SELECT / MULTI_SELECT fields.
4139
+ * Each option includes a label, value, and optional swatch color/image.
4140
+ */
4141
+ enumValues?: CustomizationFieldOption[];
4094
4142
  defaultValue?: string | null;
4095
4143
  position: number;
4096
4144
  }
@@ -5972,6 +6020,29 @@ declare class BrainerceClient {
5972
6020
  * ```
5973
6021
  */
5974
6022
  updateOrderShipping(orderId: string, data: UpdateOrderShippingDto): Promise<Order>;
6023
+ /**
6024
+ * Create a shipping label for an order via the installed App Store shipping app.
6025
+ * Pass the rate ID returned from checkout rate shopping. Billing goes directly
6026
+ * to the merchant's carrier account — Brainerce is not a billing intermediary.
6027
+ *
6028
+ * @example
6029
+ * ```typescript
6030
+ * const label = await client.createShippingLabel('order_abc', {
6031
+ * rateId: 'rate_8f123456789abcdef',
6032
+ * });
6033
+ * console.log('Label URL:', label.labelUrl);
6034
+ * console.log('Tracking:', label.trackingNumber);
6035
+ * ```
6036
+ */
6037
+ createShippingLabel(orderId: string, data: {
6038
+ rateId: string;
6039
+ parcel?: Record<string, string>;
6040
+ }): Promise<{
6041
+ shipmentId: string;
6042
+ labelUrl: string;
6043
+ trackingNumber: string;
6044
+ carrier: string;
6045
+ }>;
5975
6046
  /**
5976
6047
  * Cancel an order
5977
6048
  * Works for Shopify and WooCommerce orders that haven't been fulfilled
package/dist/index.d.ts CHANGED
@@ -1806,6 +1806,20 @@ interface CartItem {
1806
1806
  notes?: string | null;
1807
1807
  /** Optional metadata for this line item */
1808
1808
  metadata?: Record<string, unknown> | null;
1809
+ /**
1810
+ * Resolved customer input field values with merchant-defined labels.
1811
+ * Mirrors `OrderItem.customizations` — same shape, live (not order-frozen).
1812
+ * Present only when the item has at least one customization value set.
1813
+ *
1814
+ * @example
1815
+ * // Display "Color: Silver / Size: 45" without an extra getProduct() call:
1816
+ * Object.entries(item.customizations ?? {}).map(([, c]) => `${c.label}: ${c.value}`)
1817
+ */
1818
+ customizations?: Record<string, {
1819
+ label: string;
1820
+ value: string | string[];
1821
+ type: string;
1822
+ }>;
1809
1823
  /**
1810
1824
  * Per-line modifier breakdown — present when the line was added with
1811
1825
  * modifier `selections`. Snapshot taken at add-time; immutable to catalog
@@ -2326,6 +2340,20 @@ interface CheckoutLineItem {
2326
2340
  notes?: string | null;
2327
2341
  /** Custom metadata including customer input field values */
2328
2342
  metadata?: Record<string, unknown> | null;
2343
+ /**
2344
+ * Resolved customer input field values with merchant-defined labels.
2345
+ * Mirrors `OrderItem.customizations` — same shape, live (not order-frozen).
2346
+ * Present only when the item has at least one customization value set.
2347
+ *
2348
+ * @example
2349
+ * // Render "Color: Silver / Ring size: 45" in your checkout summary:
2350
+ * Object.entries(item.customizations ?? {}).map(([, c]) => `${c.label}: ${c.value}`)
2351
+ */
2352
+ customizations?: Record<string, {
2353
+ label: string;
2354
+ value: string | string[];
2355
+ type: string;
2356
+ }>;
2329
2357
  }
2330
2358
  /**
2331
2359
  * Represents an available shipping rate/method for checkout.
@@ -3983,7 +4011,8 @@ interface MetafieldDefinition {
3983
4011
  maxLength?: number | null;
3984
4012
  minValue?: number | null;
3985
4013
  maxValue?: number | null;
3986
- enumValues?: string[] | null;
4014
+ /** Allowed values for SELECT / MULTI_SELECT fields, with optional swatch metadata. */
4015
+ enumValues?: CustomizationFieldOption[] | null;
3987
4016
  defaultValue?: string | null;
3988
4017
  position: number;
3989
4018
  isActive: boolean;
@@ -4067,7 +4096,8 @@ interface PublicMetafieldDefinition {
4067
4096
  * Pair with `getProducts({ metafields: { [key]: [...] } })`.
4068
4097
  */
4069
4098
  filterable?: boolean;
4070
- enumValues?: string[];
4099
+ /** Allowed values for SELECT / MULTI_SELECT fields, with optional swatch metadata. */
4100
+ enumValues?: CustomizationFieldOption[];
4071
4101
  minLength?: number | null;
4072
4102
  maxLength?: number | null;
4073
4103
  minValue?: number | null;
@@ -4075,6 +4105,20 @@ interface PublicMetafieldDefinition {
4075
4105
  defaultValue?: string | null;
4076
4106
  position: number;
4077
4107
  }
4108
+ /**
4109
+ * A single selectable option for a SELECT or MULTI_SELECT customization field.
4110
+ * Legacy string-only `enumValues` arrays are automatically promoted to this shape.
4111
+ */
4112
+ interface CustomizationFieldOption {
4113
+ /** Human-readable label shown in the storefront UI (e.g., "Rose Gold"). */
4114
+ label: string;
4115
+ /** Value stored in `CartItem.metadata` and carried through to `OrderItem.customizations`. */
4116
+ value: string;
4117
+ /** Optional CSS hex color for rendering a color swatch (e.g., "#B76E79"). */
4118
+ swatchColor?: string | null;
4119
+ /** Optional image URL for rendering a texture/image swatch. */
4120
+ swatchImageUrl?: string | null;
4121
+ }
4078
4122
  /**
4079
4123
  * Customer-facing input field definition assigned to a specific product.
4080
4124
  * Returned in product responses to tell the storefront which input fields to render.
@@ -4090,7 +4134,11 @@ interface ProductCustomizationField {
4090
4134
  maxLength?: number | null;
4091
4135
  minValue?: number | null;
4092
4136
  maxValue?: number | null;
4093
- enumValues?: string[];
4137
+ /**
4138
+ * Allowed values for SELECT / MULTI_SELECT fields.
4139
+ * Each option includes a label, value, and optional swatch color/image.
4140
+ */
4141
+ enumValues?: CustomizationFieldOption[];
4094
4142
  defaultValue?: string | null;
4095
4143
  position: number;
4096
4144
  }
@@ -5972,6 +6020,29 @@ declare class BrainerceClient {
5972
6020
  * ```
5973
6021
  */
5974
6022
  updateOrderShipping(orderId: string, data: UpdateOrderShippingDto): Promise<Order>;
6023
+ /**
6024
+ * Create a shipping label for an order via the installed App Store shipping app.
6025
+ * Pass the rate ID returned from checkout rate shopping. Billing goes directly
6026
+ * to the merchant's carrier account — Brainerce is not a billing intermediary.
6027
+ *
6028
+ * @example
6029
+ * ```typescript
6030
+ * const label = await client.createShippingLabel('order_abc', {
6031
+ * rateId: 'rate_8f123456789abcdef',
6032
+ * });
6033
+ * console.log('Label URL:', label.labelUrl);
6034
+ * console.log('Tracking:', label.trackingNumber);
6035
+ * ```
6036
+ */
6037
+ createShippingLabel(orderId: string, data: {
6038
+ rateId: string;
6039
+ parcel?: Record<string, string>;
6040
+ }): Promise<{
6041
+ shipmentId: string;
6042
+ labelUrl: string;
6043
+ trackingNumber: string;
6044
+ carrier: string;
6045
+ }>;
5975
6046
  /**
5976
6047
  * Cancel an order
5977
6048
  * Works for Shopify and WooCommerce orders that haven't been fulfilled
package/dist/index.js CHANGED
@@ -1805,6 +1805,27 @@ var BrainerceClient = class {
1805
1805
  data
1806
1806
  );
1807
1807
  }
1808
+ /**
1809
+ * Create a shipping label for an order via the installed App Store shipping app.
1810
+ * Pass the rate ID returned from checkout rate shopping. Billing goes directly
1811
+ * to the merchant's carrier account — Brainerce is not a billing intermediary.
1812
+ *
1813
+ * @example
1814
+ * ```typescript
1815
+ * const label = await client.createShippingLabel('order_abc', {
1816
+ * rateId: 'rate_8f123456789abcdef',
1817
+ * });
1818
+ * console.log('Label URL:', label.labelUrl);
1819
+ * console.log('Tracking:', label.trackingNumber);
1820
+ * ```
1821
+ */
1822
+ async createShippingLabel(orderId, data) {
1823
+ return this.request(
1824
+ "POST",
1825
+ `/api/v1/orders/${encodePathSegment(orderId)}/shipments/app-label`,
1826
+ data
1827
+ );
1828
+ }
1808
1829
  /**
1809
1830
  * Cancel an order
1810
1831
  * Works for Shopify and WooCommerce orders that haven't been fulfilled
package/dist/index.mjs CHANGED
@@ -1735,6 +1735,27 @@ var BrainerceClient = class {
1735
1735
  data
1736
1736
  );
1737
1737
  }
1738
+ /**
1739
+ * Create a shipping label for an order via the installed App Store shipping app.
1740
+ * Pass the rate ID returned from checkout rate shopping. Billing goes directly
1741
+ * to the merchant's carrier account — Brainerce is not a billing intermediary.
1742
+ *
1743
+ * @example
1744
+ * ```typescript
1745
+ * const label = await client.createShippingLabel('order_abc', {
1746
+ * rateId: 'rate_8f123456789abcdef',
1747
+ * });
1748
+ * console.log('Label URL:', label.labelUrl);
1749
+ * console.log('Tracking:', label.trackingNumber);
1750
+ * ```
1751
+ */
1752
+ async createShippingLabel(orderId, data) {
1753
+ return this.request(
1754
+ "POST",
1755
+ `/api/v1/orders/${encodePathSegment(orderId)}/shipments/app-label`,
1756
+ data
1757
+ );
1758
+ }
1738
1759
  /**
1739
1760
  * Cancel an order
1740
1761
  * Works for Shopify and WooCommerce orders that haven't been fulfilled
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brainerce",
3
- "version": "1.38.0",
3
+ "version": "1.39.0",
4
4
  "description": "Official SDK for building e-commerce storefronts with Brainerce Platform. Perfect for vibe-coded sites, AI-built stores (Cursor, Lovable, v0), and custom storefronts.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",