@putiikkipalvelu/storefront-sdk 0.2.2 → 0.2.4
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 +60 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +43 -37
- package/dist/index.d.ts +43 -37
- package/dist/index.js +51 -57
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -91,7 +91,7 @@ interface FeatureFlags {
|
|
|
91
91
|
reviewsEnabled: boolean;
|
|
92
92
|
}
|
|
93
93
|
/** Campaign type */
|
|
94
|
-
type CampaignType = "
|
|
94
|
+
type CampaignType = "BUY_X_PAY_Y";
|
|
95
95
|
/**
|
|
96
96
|
* Store campaign (promotion)
|
|
97
97
|
*/
|
|
@@ -116,24 +116,9 @@ interface Campaign {
|
|
|
116
116
|
createdAt: string;
|
|
117
117
|
/** Last update timestamp (ISO 8601) */
|
|
118
118
|
updatedAt: string;
|
|
119
|
-
/** Free shipping campaign details (if type is FREE_SHIPPING) */
|
|
120
|
-
FreeShippingCampaign: FreeShippingCampaign | null;
|
|
121
119
|
/** Buy X Pay Y campaign details (if type is BUY_X_PAY_Y) */
|
|
122
120
|
BuyXPayYCampaign: BuyXPayYCampaign | null;
|
|
123
121
|
}
|
|
124
|
-
/**
|
|
125
|
-
* Free shipping campaign details
|
|
126
|
-
*/
|
|
127
|
-
interface FreeShippingCampaign {
|
|
128
|
-
/** Unique identifier */
|
|
129
|
-
id: string;
|
|
130
|
-
/** Parent campaign ID */
|
|
131
|
-
campaignId: string;
|
|
132
|
-
/** Minimum spend in cents to qualify for free shipping */
|
|
133
|
-
minimumSpend: number;
|
|
134
|
-
/** Shipping methods eligible for free shipping */
|
|
135
|
-
shipmentMethods: ShipmentMethod[];
|
|
136
|
-
}
|
|
137
122
|
/**
|
|
138
123
|
* Buy X Pay Y campaign details (e.g., "Buy 3, Pay 2")
|
|
139
124
|
*/
|
|
@@ -152,18 +137,19 @@ interface BuyXPayYCampaign {
|
|
|
152
137
|
/**
|
|
153
138
|
* Shipit shipping method details
|
|
154
139
|
* Represents a shipping service synced from the Shipit API
|
|
140
|
+
* Supports multiple carriers in a single method for multi-carrier shipping
|
|
155
141
|
*/
|
|
156
142
|
interface ShipitShippingMethod {
|
|
157
143
|
/** Unique ID */
|
|
158
144
|
id: string;
|
|
159
|
-
/** Shipit service
|
|
160
|
-
|
|
145
|
+
/** Shipit service identifiers for all selected carriers */
|
|
146
|
+
serviceIds: string[];
|
|
161
147
|
/** Service name */
|
|
162
148
|
name: string;
|
|
163
|
-
/** Carrier
|
|
164
|
-
|
|
165
|
-
/** Carrier logo
|
|
166
|
-
|
|
149
|
+
/** Carrier names (e.g., ["Posti", "Matkahuolto"]) */
|
|
150
|
+
carriers: string[];
|
|
151
|
+
/** Carrier logo URLs */
|
|
152
|
+
logos: string[];
|
|
167
153
|
/** Whether pickup is included */
|
|
168
154
|
pickUpIncluded: boolean;
|
|
169
155
|
/** Whether home delivery is available */
|
|
@@ -184,16 +170,16 @@ interface ShipitShippingMethod {
|
|
|
184
170
|
length: number;
|
|
185
171
|
/** Package width in cm */
|
|
186
172
|
width: number;
|
|
187
|
-
/** Package weight in kg */
|
|
173
|
+
/** Package weight in kg @deprecated Use maxWeight instead */
|
|
188
174
|
weight: number;
|
|
175
|
+
/** Maximum package weight in kg for this shipping tier */
|
|
176
|
+
maxWeight: number;
|
|
189
177
|
/** Service type */
|
|
190
178
|
type: string;
|
|
191
179
|
/** Shipit price in cents */
|
|
192
180
|
price: number;
|
|
193
|
-
/** Whether pickup point
|
|
194
|
-
|
|
195
|
-
/** Whether only parcel locker delivery is available */
|
|
196
|
-
onlyParchelLocker: boolean;
|
|
181
|
+
/** Whether to show pickup point selector (true) or home delivery only (false) */
|
|
182
|
+
showPickupPoints: boolean;
|
|
197
183
|
/** Reference to parent shipment method */
|
|
198
184
|
shipmentMethodId: string;
|
|
199
185
|
/** Created timestamp */
|
|
@@ -275,6 +261,8 @@ interface ProductVariationListing {
|
|
|
275
261
|
* Full product variation (for product detail page)
|
|
276
262
|
*/
|
|
277
263
|
interface ProductVariation extends ProductVariationListing {
|
|
264
|
+
/** Variation weight in kg (null = use product weight) */
|
|
265
|
+
weight: number | null;
|
|
278
266
|
/** Available quantity (null = unlimited) */
|
|
279
267
|
quantity: number | null;
|
|
280
268
|
/** Stock keeping unit */
|
|
@@ -323,6 +311,8 @@ interface Product {
|
|
|
323
311
|
* Used by: /product/{slug}
|
|
324
312
|
*/
|
|
325
313
|
interface ProductDetail extends Omit<Product, "variations"> {
|
|
314
|
+
/** Product weight in kg (for shipping calculations) */
|
|
315
|
+
weight: number;
|
|
326
316
|
/** Stock keeping unit */
|
|
327
317
|
sku: string | null;
|
|
328
318
|
/** SEO meta title */
|
|
@@ -1699,6 +1689,13 @@ type CartResource = ReturnType<typeof createCartResource>;
|
|
|
1699
1689
|
* Methods for fetching shipment methods and pickup locations.
|
|
1700
1690
|
*/
|
|
1701
1691
|
|
|
1692
|
+
/**
|
|
1693
|
+
* Options for fetching shipment methods with weight-based filtering
|
|
1694
|
+
*/
|
|
1695
|
+
interface GetMethodsOptions extends FetchOptions {
|
|
1696
|
+
/** Cart items - weight will be calculated automatically */
|
|
1697
|
+
cartItems?: CartItem[];
|
|
1698
|
+
}
|
|
1702
1699
|
/**
|
|
1703
1700
|
* Shipping resource for fetching shipment methods and pickup locations
|
|
1704
1701
|
*/
|
|
@@ -1707,7 +1704,7 @@ declare function createShippingResource(fetcher: Fetcher): {
|
|
|
1707
1704
|
* Get all available shipment methods for the store.
|
|
1708
1705
|
* Returns methods without pickup locations - use `getWithLocations` for postal code specific data.
|
|
1709
1706
|
*
|
|
1710
|
-
* @param options - Fetch options
|
|
1707
|
+
* @param options - Fetch options including optional cartItems for weight-based filtering
|
|
1711
1708
|
* @returns Available shipment methods
|
|
1712
1709
|
*
|
|
1713
1710
|
* @example
|
|
@@ -1718,14 +1715,22 @@ declare function createShippingResource(fetcher: Fetcher): {
|
|
|
1718
1715
|
* console.log(`${method.name}: ${method.price / 100}€`);
|
|
1719
1716
|
* });
|
|
1720
1717
|
* ```
|
|
1718
|
+
*
|
|
1719
|
+
* @example Weight-based filtering
|
|
1720
|
+
* ```typescript
|
|
1721
|
+
* // Pass cart items - SDK calculates weight automatically
|
|
1722
|
+
* const { shipmentMethods } = await client.shipping.getMethods({
|
|
1723
|
+
* cartItems: cartItems
|
|
1724
|
+
* });
|
|
1725
|
+
* ```
|
|
1721
1726
|
*/
|
|
1722
|
-
getMethods(options?:
|
|
1727
|
+
getMethods(options?: GetMethodsOptions): Promise<ShipmentMethodsResponse>;
|
|
1723
1728
|
/**
|
|
1724
1729
|
* Get shipment methods with pickup locations for a specific postal code.
|
|
1725
1730
|
* Calls the Shipit API to fetch nearby pickup points (parcel lockers, etc.)
|
|
1726
1731
|
*
|
|
1727
1732
|
* @param postalCode - Customer's postal code (e.g., "00100")
|
|
1728
|
-
* @param options - Fetch options
|
|
1733
|
+
* @param options - Fetch options including optional cartItems for weight-based filtering
|
|
1729
1734
|
* @returns Shipment methods and nearby pickup locations with pricing
|
|
1730
1735
|
*
|
|
1731
1736
|
* @example
|
|
@@ -1741,16 +1746,17 @@ declare function createShippingResource(fetcher: Fetcher): {
|
|
|
1741
1746
|
* });
|
|
1742
1747
|
* ```
|
|
1743
1748
|
*
|
|
1744
|
-
* @example
|
|
1749
|
+
* @example Weight-based filtering with postal code
|
|
1745
1750
|
* ```typescript
|
|
1746
|
-
* const { pricedLocations } = await client.shipping.getWithLocations(
|
|
1747
|
-
*
|
|
1748
|
-
*
|
|
1749
|
-
* loc => loc.carrier === "Posti"
|
|
1751
|
+
* const { shipmentMethods, pricedLocations } = await client.shipping.getWithLocations(
|
|
1752
|
+
* "00100",
|
|
1753
|
+
* { cartItems: cartItems }
|
|
1750
1754
|
* );
|
|
1755
|
+
*
|
|
1756
|
+
* // Only shows methods that support the cart's total weight
|
|
1751
1757
|
* ```
|
|
1752
1758
|
*/
|
|
1753
|
-
getWithLocations(postalCode: string, options?:
|
|
1759
|
+
getWithLocations(postalCode: string, options?: GetMethodsOptions): Promise<ShipmentMethodsWithLocationsResponse>;
|
|
1754
1760
|
};
|
|
1755
1761
|
/**
|
|
1756
1762
|
* Type for the shipping resource
|
|
@@ -2466,4 +2472,4 @@ declare class VerificationRequiredError extends StorefrontError {
|
|
|
2466
2472
|
constructor(message: string, customerId: string);
|
|
2467
2473
|
}
|
|
2468
2474
|
|
|
2469
|
-
export { type AddToCartParams, type AddToWishlistResponse, AuthError, type BuyXPayYCampaign, type CalculatedCartItem, type Campaign, type CampaignType, type CartCalculationResult, type CartItem, type CartResponse, type CartSessionOptions, type CartValidationChanges, type CartValidationResponse, type Category, type CategoryReference, type CategoryResponse, type CheckoutCustomerData, type CheckoutErrorCode, type CheckoutErrorDetails, type CheckoutOptions, type CheckoutParams, type CheckoutShipmentMethod, type ConfirmationItemType, type ConfirmationOrderCustomerData, type ConfirmationOrderLineItem, type ConfirmationOrderShipmentMethod, type Customer, type CustomerOrder, type DeleteAccountResponse, type FeatureFlags, type FetchOptions, type ForgotPasswordResponse, type
|
|
2475
|
+
export { type AddToCartParams, type AddToWishlistResponse, AuthError, type BuyXPayYCampaign, type CalculatedCartItem, type Campaign, type CampaignType, type CartCalculationResult, type CartItem, type CartResponse, type CartSessionOptions, type CartValidationChanges, type CartValidationResponse, type Category, type CategoryReference, type CategoryResponse, type CheckoutCustomerData, type CheckoutErrorCode, type CheckoutErrorDetails, type CheckoutOptions, type CheckoutParams, type CheckoutShipmentMethod, type ConfirmationItemType, type ConfirmationOrderCustomerData, type ConfirmationOrderLineItem, type ConfirmationOrderShipmentMethod, type Customer, type CustomerOrder, type DeleteAccountResponse, type FeatureFlags, type FetchOptions, type ForgotPasswordResponse, type FreeShippingStatus, type GetOrdersResponse, type GetUserResponse, type LoginOptions, type LoginResponse, type LoginVerificationRequiredResponse, type LogoutResponse, NotFoundError, type Order, type OrderLineItem, type OrderProductInfo, type OrderShipmentMethod, type OrderStatus, type PaymentConfig, type PaytrailCheckoutResponse, type PaytrailGroup, type PaytrailProvider, type PickupLocation, type PriceInfo, type Product, type ProductCountResponse, type ProductDetail, type ProductListParams, type ProductListResponse, type ProductSortOption, type ProductVariation, type ProductVariationListing, RateLimitError, type RegisterData, type RegisterResponse, type RemoveFromCartParams, type RemoveFromWishlistResponse, type ResendVerificationResponse, type ResetPasswordResponse, type ShipitShippingMethod, type ShipmentMethod, type ShipmentMethodsResponse, type ShipmentMethodsWithLocationsResponse, type StoreConfig, type StoreInfo, type StoreSeo, type StorefrontClient, type StorefrontClientConfig, StorefrontError, type StripeCheckoutResponse, type UpdateCartQuantityParams, type UpdateProfileData, type UpdateProfileResponse, ValidationError, type VariationOption, VerificationRequiredError, type VerifyEmailResponse, type WishlistItem, type WishlistProduct, type WishlistResponse, type WishlistVariation, type WishlistVariationOption, calculateCartWithCampaigns, createStorefrontClient, getPriceInfo, isSaleActive };
|
package/dist/index.js
CHANGED
|
@@ -611,13 +611,19 @@ function createCartResource(fetcher) {
|
|
|
611
611
|
}
|
|
612
612
|
|
|
613
613
|
// src/resources/shipping.ts
|
|
614
|
+
function calculateCartWeight(items) {
|
|
615
|
+
return items.reduce((total, item) => {
|
|
616
|
+
const itemWeight = item.variation?.weight ?? item.product.weight ?? 0.5;
|
|
617
|
+
return total + itemWeight * item.cartQuantity;
|
|
618
|
+
}, 0);
|
|
619
|
+
}
|
|
614
620
|
function createShippingResource(fetcher) {
|
|
615
621
|
return {
|
|
616
622
|
/**
|
|
617
623
|
* Get all available shipment methods for the store.
|
|
618
624
|
* Returns methods without pickup locations - use `getWithLocations` for postal code specific data.
|
|
619
625
|
*
|
|
620
|
-
* @param options - Fetch options
|
|
626
|
+
* @param options - Fetch options including optional cartItems for weight-based filtering
|
|
621
627
|
* @returns Available shipment methods
|
|
622
628
|
*
|
|
623
629
|
* @example
|
|
@@ -628,22 +634,34 @@ function createShippingResource(fetcher) {
|
|
|
628
634
|
* console.log(`${method.name}: ${method.price / 100}€`);
|
|
629
635
|
* });
|
|
630
636
|
* ```
|
|
637
|
+
*
|
|
638
|
+
* @example Weight-based filtering
|
|
639
|
+
* ```typescript
|
|
640
|
+
* // Pass cart items - SDK calculates weight automatically
|
|
641
|
+
* const { shipmentMethods } = await client.shipping.getMethods({
|
|
642
|
+
* cartItems: cartItems
|
|
643
|
+
* });
|
|
644
|
+
* ```
|
|
631
645
|
*/
|
|
632
646
|
async getMethods(options) {
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
647
|
+
const params = new URLSearchParams();
|
|
648
|
+
if (options?.cartItems?.length) {
|
|
649
|
+
const cartWeight = calculateCartWeight(options.cartItems);
|
|
650
|
+
params.set("cartWeight", cartWeight.toString());
|
|
651
|
+
}
|
|
652
|
+
const queryString = params.toString();
|
|
653
|
+
const url = `/api/storefront/v1/shipment-methods${queryString ? `?${queryString}` : ""}`;
|
|
654
|
+
return fetcher.request(url, {
|
|
655
|
+
method: "GET",
|
|
656
|
+
...options
|
|
657
|
+
});
|
|
640
658
|
},
|
|
641
659
|
/**
|
|
642
660
|
* Get shipment methods with pickup locations for a specific postal code.
|
|
643
661
|
* Calls the Shipit API to fetch nearby pickup points (parcel lockers, etc.)
|
|
644
662
|
*
|
|
645
663
|
* @param postalCode - Customer's postal code (e.g., "00100")
|
|
646
|
-
* @param options - Fetch options
|
|
664
|
+
* @param options - Fetch options including optional cartItems for weight-based filtering
|
|
647
665
|
* @returns Shipment methods and nearby pickup locations with pricing
|
|
648
666
|
*
|
|
649
667
|
* @example
|
|
@@ -659,23 +677,28 @@ function createShippingResource(fetcher) {
|
|
|
659
677
|
* });
|
|
660
678
|
* ```
|
|
661
679
|
*
|
|
662
|
-
* @example
|
|
680
|
+
* @example Weight-based filtering with postal code
|
|
663
681
|
* ```typescript
|
|
664
|
-
* const { pricedLocations } = await client.shipping.getWithLocations(
|
|
665
|
-
*
|
|
666
|
-
*
|
|
667
|
-
* loc => loc.carrier === "Posti"
|
|
682
|
+
* const { shipmentMethods, pricedLocations } = await client.shipping.getWithLocations(
|
|
683
|
+
* "00100",
|
|
684
|
+
* { cartItems: cartItems }
|
|
668
685
|
* );
|
|
686
|
+
*
|
|
687
|
+
* // Only shows methods that support the cart's total weight
|
|
669
688
|
* ```
|
|
670
689
|
*/
|
|
671
690
|
async getWithLocations(postalCode, options) {
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
)
|
|
691
|
+
const params = new URLSearchParams();
|
|
692
|
+
if (options?.cartItems?.length) {
|
|
693
|
+
const cartWeight = calculateCartWeight(options.cartItems);
|
|
694
|
+
params.set("cartWeight", cartWeight.toString());
|
|
695
|
+
}
|
|
696
|
+
const queryString = params.toString();
|
|
697
|
+
const url = `/api/storefront/v1/shipment-methods/${encodeURIComponent(postalCode)}${queryString ? `?${queryString}` : ""}`;
|
|
698
|
+
return fetcher.request(url, {
|
|
699
|
+
method: "GET",
|
|
700
|
+
...options
|
|
701
|
+
});
|
|
679
702
|
}
|
|
680
703
|
};
|
|
681
704
|
}
|
|
@@ -1448,9 +1471,6 @@ function getPriceInfo(product, variation) {
|
|
|
1448
1471
|
|
|
1449
1472
|
// src/utils/cart-calculations.ts
|
|
1450
1473
|
function calculateCartWithCampaigns(items, campaigns) {
|
|
1451
|
-
const freeShippingCampaign = campaigns.find(
|
|
1452
|
-
(c) => c.type === "FREE_SHIPPING" && c.isActive
|
|
1453
|
-
);
|
|
1454
1474
|
const buyXPayYCampaign = campaigns.find(
|
|
1455
1475
|
(c) => c.type === "BUY_X_PAY_Y" && c.isActive
|
|
1456
1476
|
);
|
|
@@ -1458,6 +1478,11 @@ function calculateCartWithCampaigns(items, campaigns) {
|
|
|
1458
1478
|
const priceInfo = getPriceInfo(product, variation);
|
|
1459
1479
|
return total + priceInfo.effectivePrice * cartQuantity;
|
|
1460
1480
|
}, 0);
|
|
1481
|
+
const freeShipping = {
|
|
1482
|
+
isEligible: false,
|
|
1483
|
+
minimumSpend: 0,
|
|
1484
|
+
remainingAmount: 0
|
|
1485
|
+
};
|
|
1461
1486
|
if (!buyXPayYCampaign?.BuyXPayYCampaign) {
|
|
1462
1487
|
const calculatedItems2 = items.map((item) => ({
|
|
1463
1488
|
item,
|
|
@@ -1465,16 +1490,12 @@ function calculateCartWithCampaigns(items, campaigns) {
|
|
|
1465
1490
|
freeQuantity: 0,
|
|
1466
1491
|
totalQuantity: item.cartQuantity
|
|
1467
1492
|
}));
|
|
1468
|
-
const freeShipping2 = calculateFreeShipping(
|
|
1469
|
-
originalTotal,
|
|
1470
|
-
freeShippingCampaign
|
|
1471
|
-
);
|
|
1472
1493
|
return {
|
|
1473
1494
|
calculatedItems: calculatedItems2,
|
|
1474
1495
|
cartTotal: originalTotal,
|
|
1475
1496
|
originalTotal,
|
|
1476
1497
|
totalSavings: 0,
|
|
1477
|
-
freeShipping
|
|
1498
|
+
freeShipping
|
|
1478
1499
|
};
|
|
1479
1500
|
}
|
|
1480
1501
|
const { buyQuantity, payQuantity, applicableCategories } = buyXPayYCampaign.BuyXPayYCampaign;
|
|
@@ -1505,16 +1526,12 @@ function calculateCartWithCampaigns(items, campaigns) {
|
|
|
1505
1526
|
freeQuantity: 0,
|
|
1506
1527
|
totalQuantity: item.cartQuantity
|
|
1507
1528
|
}));
|
|
1508
|
-
const freeShipping2 = calculateFreeShipping(
|
|
1509
|
-
originalTotal,
|
|
1510
|
-
freeShippingCampaign
|
|
1511
|
-
);
|
|
1512
1529
|
return {
|
|
1513
1530
|
calculatedItems: calculatedItems2,
|
|
1514
1531
|
cartTotal: originalTotal,
|
|
1515
1532
|
originalTotal,
|
|
1516
1533
|
totalSavings: 0,
|
|
1517
|
-
freeShipping
|
|
1534
|
+
freeShipping
|
|
1518
1535
|
};
|
|
1519
1536
|
}
|
|
1520
1537
|
eligibleUnits.sort((a, b) => a.price - b.price);
|
|
@@ -1541,7 +1558,6 @@ function calculateCartWithCampaigns(items, campaigns) {
|
|
|
1541
1558
|
};
|
|
1542
1559
|
});
|
|
1543
1560
|
const cartTotal = originalTotal - totalSavings;
|
|
1544
|
-
const freeShipping = calculateFreeShipping(cartTotal, freeShippingCampaign);
|
|
1545
1561
|
return {
|
|
1546
1562
|
calculatedItems,
|
|
1547
1563
|
cartTotal,
|
|
@@ -1550,28 +1566,6 @@ function calculateCartWithCampaigns(items, campaigns) {
|
|
|
1550
1566
|
freeShipping
|
|
1551
1567
|
};
|
|
1552
1568
|
}
|
|
1553
|
-
function calculateFreeShipping(cartTotal, campaign) {
|
|
1554
|
-
if (!campaign?.FreeShippingCampaign) {
|
|
1555
|
-
return {
|
|
1556
|
-
isEligible: false,
|
|
1557
|
-
minimumSpend: 0,
|
|
1558
|
-
remainingAmount: 0
|
|
1559
|
-
};
|
|
1560
|
-
}
|
|
1561
|
-
const minimumSpend = campaign.FreeShippingCampaign.minimumSpend;
|
|
1562
|
-
const isEligible = cartTotal >= minimumSpend;
|
|
1563
|
-
const remainingAmount = isEligible ? 0 : minimumSpend - cartTotal;
|
|
1564
|
-
const eligibleShipmentMethodIds = campaign.FreeShippingCampaign.shipmentMethods?.map(
|
|
1565
|
-
(method) => method.id
|
|
1566
|
-
);
|
|
1567
|
-
return {
|
|
1568
|
-
isEligible,
|
|
1569
|
-
minimumSpend,
|
|
1570
|
-
remainingAmount,
|
|
1571
|
-
campaignName: campaign.name,
|
|
1572
|
-
eligibleShipmentMethodIds
|
|
1573
|
-
};
|
|
1574
|
-
}
|
|
1575
1569
|
export {
|
|
1576
1570
|
AuthError,
|
|
1577
1571
|
NotFoundError,
|