commerce-kit 0.0.41 → 0.1.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 +112 -44
- package/dist/index.d.ts +406 -4
- package/dist/index.js +240 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,75 +1,143 @@
|
|
|
1
1
|
# commerce-kit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
TypeScript SDK for building e-commerce apps. Works with Stripe and YNS APIs through a clean, unified interface. Built for Next.js, but plays nice with whatever you're using.
|
|
4
4
|
|
|
5
5
|
Built by [Your Next Store](https://yournextstore.com).
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
9
|
+
- **Multi-provider**: Switch between Stripe and YNS without changing code
|
|
10
|
+
- **GraphQL support**: Field selection for YNS, REST for Stripe
|
|
11
|
+
- **Type-safe**: Full TypeScript with provider-specific types
|
|
12
|
+
- **Tree-shakeable**: Only bundle what you use
|
|
13
|
+
- **Zero config**: Works out of the box, customize when needed
|
|
14
14
|
|
|
15
|
-
##
|
|
16
|
-
|
|
17
|
-
Install the package via npm:
|
|
15
|
+
## Install
|
|
18
16
|
|
|
19
17
|
```bash
|
|
20
18
|
npm install commerce-kit
|
|
21
19
|
```
|
|
22
20
|
|
|
23
|
-
##
|
|
24
|
-
|
|
25
|
-
`commerce-kit` is intended for use with Next.js applications. Here's a simple example of how to use it to fetch and display products:
|
|
21
|
+
## Quick start
|
|
26
22
|
|
|
27
23
|
```tsx
|
|
28
24
|
import * as Commerce from "commerce-kit";
|
|
29
25
|
import { formatMoney } from "commerce-kit/currencies";
|
|
30
|
-
import Image from "next/image";
|
|
31
|
-
import Link from "next/link";
|
|
32
26
|
|
|
27
|
+
// Configure once
|
|
28
|
+
Commerce.configure({
|
|
29
|
+
provider: "stripe", // or "yns"
|
|
30
|
+
stripe: { secretKey: process.env.STRIPE_SECRET_KEY }
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Use everywhere
|
|
33
34
|
export async function ProductList() {
|
|
34
|
-
const products = await Commerce.
|
|
35
|
+
const products = await Commerce.product.browse({ first: 6 });
|
|
35
36
|
|
|
36
37
|
return (
|
|
37
|
-
<
|
|
38
|
-
{products.map((product) => (
|
|
39
|
-
<
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
<Image src={product.images[0]} width={300} height={300} alt={product.name} />
|
|
44
|
-
)}
|
|
45
|
-
<h2>{product.name}</h2>
|
|
46
|
-
{product.default_price.unit_amount && (
|
|
47
|
-
<p>
|
|
48
|
-
{formatMoney({
|
|
49
|
-
amount: product.default_price.unit_amount,
|
|
50
|
-
currency: product.default_price.currency,
|
|
51
|
-
locale: "en-US",
|
|
52
|
-
})}
|
|
53
|
-
</p>
|
|
54
|
-
)}
|
|
55
|
-
</article>
|
|
56
|
-
</Link>
|
|
57
|
-
</li>
|
|
38
|
+
<div>
|
|
39
|
+
{products.data.map((product) => (
|
|
40
|
+
<div key={product.id}>
|
|
41
|
+
<h2>{product.name}</h2>
|
|
42
|
+
<p>{formatMoney({ amount: product.price, currency: product.currency })}</p>
|
|
43
|
+
</div>
|
|
58
44
|
))}
|
|
59
|
-
</
|
|
45
|
+
</div>
|
|
60
46
|
);
|
|
61
47
|
}
|
|
62
48
|
```
|
|
63
49
|
|
|
64
|
-
##
|
|
50
|
+
## API
|
|
51
|
+
|
|
52
|
+
### Products
|
|
53
|
+
```tsx
|
|
54
|
+
// Browse with filters
|
|
55
|
+
const products = await Commerce.product.browse({
|
|
56
|
+
first: 10,
|
|
57
|
+
category: "electronics",
|
|
58
|
+
fields: ["id", "name", "price"] // GraphQL field selection (YNS only)
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Get single product
|
|
62
|
+
const product = await Commerce.product.get({ slug: "awesome-laptop" });
|
|
63
|
+
|
|
64
|
+
// Search
|
|
65
|
+
const results = await Commerce.product.search({ query: "macbook" });
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Cart
|
|
69
|
+
```tsx
|
|
70
|
+
// Add to cart
|
|
71
|
+
const cart = await Commerce.cart.add({
|
|
72
|
+
variantId: "variant_123",
|
|
73
|
+
quantity: 2
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Update quantity
|
|
77
|
+
await Commerce.cart.update({
|
|
78
|
+
cartId: cart.cartId,
|
|
79
|
+
variantId: "variant_123",
|
|
80
|
+
quantity: 3
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Get cart
|
|
84
|
+
const cartData = await Commerce.cart.get({ cartId: cart.cartId });
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Provider switching
|
|
88
|
+
```tsx
|
|
89
|
+
// Override provider per call
|
|
90
|
+
const stripeProducts = await Commerce.product.browse({
|
|
91
|
+
first: 10,
|
|
92
|
+
_provider: "stripe"
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Or use scoped instances
|
|
96
|
+
const yns = Commerce.withProvider("yns");
|
|
97
|
+
const stripe = Commerce.withProvider("stripe");
|
|
98
|
+
|
|
99
|
+
const ynsProducts = await yns.product.browse({ first: 10 });
|
|
100
|
+
const stripeProducts = await stripe.product.browse({ first: 10 });
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Providers
|
|
104
|
+
|
|
105
|
+
### YNS
|
|
106
|
+
```tsx
|
|
107
|
+
Commerce.configure({
|
|
108
|
+
provider: "yns",
|
|
109
|
+
yns: {
|
|
110
|
+
endpoint: "https://api.yournextstore.com",
|
|
111
|
+
token: process.env.YNS_API_TOKEN
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Stripe
|
|
117
|
+
```tsx
|
|
118
|
+
Commerce.configure({
|
|
119
|
+
provider: "stripe",
|
|
120
|
+
stripe: {
|
|
121
|
+
secretKey: process.env.STRIPE_SECRET_KEY,
|
|
122
|
+
tagPrefix: "my-store" // optional
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Migration
|
|
128
|
+
|
|
129
|
+
Old way (still works):
|
|
130
|
+
```tsx
|
|
131
|
+
const products = await Commerce.productBrowse({ first: 6 });
|
|
132
|
+
```
|
|
65
133
|
|
|
66
|
-
|
|
134
|
+
New way (recommended):
|
|
135
|
+
```tsx
|
|
136
|
+
const products = await Commerce.product.browse({ first: 6 });
|
|
137
|
+
```
|
|
67
138
|
|
|
68
|
-
|
|
69
|
-
- **WARN** – Something that should be reviewed eventually.
|
|
70
|
-
- **LOG** – Details on regular operations.
|
|
71
|
-
- **DEBUG** – Debug information, including `time` and `timeEnd` function outputs.
|
|
139
|
+
Same data, better DX, provider flexibility, GraphQL field selection.
|
|
72
140
|
|
|
73
141
|
## License
|
|
74
142
|
|
|
75
|
-
|
|
143
|
+
AGPL-3.0 – see LICENSE.md
|
package/dist/index.d.ts
CHANGED
|
@@ -2,9 +2,10 @@ import Stripe from 'stripe';
|
|
|
2
2
|
import { z, TypeOf } from 'zod';
|
|
3
3
|
import { CartMetadata, MappedCart } from './internal.js';
|
|
4
4
|
export { MappedProduct, MappedShippingRate } from './internal.js';
|
|
5
|
+
export { formatMoney } from './currencies.js';
|
|
5
6
|
|
|
6
|
-
type Cart = NonNullable<Awaited<ReturnType<typeof cartGet>>>;
|
|
7
|
-
type Order = NonNullable<Awaited<ReturnType<typeof orderGet>>>;
|
|
7
|
+
type Cart$1 = NonNullable<Awaited<ReturnType<typeof cartGet>>>;
|
|
8
|
+
type Order$1 = NonNullable<Awaited<ReturnType<typeof orderGet>>>;
|
|
8
9
|
declare function cartAdd({ productId, cartId }: {
|
|
9
10
|
productId: string;
|
|
10
11
|
cartId?: string;
|
|
@@ -125,7 +126,7 @@ declare function cartCreate({ productId }?: {
|
|
|
125
126
|
cartId?: string;
|
|
126
127
|
}): Promise<Stripe.Response<Stripe.PaymentIntent>>;
|
|
127
128
|
declare function cartAddOptimistic({ cart, add }: {
|
|
128
|
-
cart?: Cart | null;
|
|
129
|
+
cart?: Cart$1 | null;
|
|
129
130
|
add: string | undefined;
|
|
130
131
|
}): Promise<{
|
|
131
132
|
cart: {
|
|
@@ -761,6 +762,369 @@ declare const contextGet: () => Promise<{
|
|
|
761
762
|
publishableKey: string | undefined;
|
|
762
763
|
}>;
|
|
763
764
|
|
|
765
|
+
interface BaseProvider {
|
|
766
|
+
productBrowse(params: ProductBrowseParams): Promise<ProductBrowseResult>;
|
|
767
|
+
productGet(params: ProductGetParams): Promise<Product | null>;
|
|
768
|
+
productSearch?(params: ProductSearchParams): Promise<ProductSearchResult>;
|
|
769
|
+
cartAdd(params: CartAddParams): Promise<{
|
|
770
|
+
cartId: string;
|
|
771
|
+
}>;
|
|
772
|
+
cartUpdate(params: CartUpdateParams): Promise<{
|
|
773
|
+
cartId: string;
|
|
774
|
+
}>;
|
|
775
|
+
cartClear(params: CartClearParams): Promise<{
|
|
776
|
+
cartId: string;
|
|
777
|
+
}>;
|
|
778
|
+
cartGet(params: CartGetParams): Promise<Cart | null>;
|
|
779
|
+
orderGet?(params: OrderGetParams): Promise<Order | null>;
|
|
780
|
+
orderList?(params: OrderListParams): Promise<OrderListResult>;
|
|
781
|
+
}
|
|
782
|
+
interface StripeProviderConfig {
|
|
783
|
+
secretKey?: string;
|
|
784
|
+
tagPrefix?: string;
|
|
785
|
+
}
|
|
786
|
+
interface YnsProviderConfig {
|
|
787
|
+
endpoint: string;
|
|
788
|
+
token: string;
|
|
789
|
+
}
|
|
790
|
+
interface CommerceConfig {
|
|
791
|
+
provider: "stripe" | "yns";
|
|
792
|
+
stripe?: StripeProviderConfig;
|
|
793
|
+
yns?: YnsProviderConfig;
|
|
794
|
+
}
|
|
795
|
+
interface Product {
|
|
796
|
+
id: string;
|
|
797
|
+
name: string;
|
|
798
|
+
slug?: string;
|
|
799
|
+
summary?: string;
|
|
800
|
+
images: string[];
|
|
801
|
+
active: boolean;
|
|
802
|
+
price: number;
|
|
803
|
+
currency: string;
|
|
804
|
+
stock?: number;
|
|
805
|
+
}
|
|
806
|
+
interface Cart {
|
|
807
|
+
id: string;
|
|
808
|
+
customerId?: string;
|
|
809
|
+
items: CartItem[];
|
|
810
|
+
total: number;
|
|
811
|
+
currency: string;
|
|
812
|
+
createdAt: string;
|
|
813
|
+
updatedAt: string;
|
|
814
|
+
}
|
|
815
|
+
interface CartItem {
|
|
816
|
+
id: string;
|
|
817
|
+
productId: string;
|
|
818
|
+
variantId?: string;
|
|
819
|
+
quantity: number;
|
|
820
|
+
price: number;
|
|
821
|
+
}
|
|
822
|
+
interface Order {
|
|
823
|
+
id: string;
|
|
824
|
+
customerId?: string;
|
|
825
|
+
items: CartItem[];
|
|
826
|
+
total: number;
|
|
827
|
+
currency: string;
|
|
828
|
+
status: string;
|
|
829
|
+
createdAt: string;
|
|
830
|
+
updatedAt: string;
|
|
831
|
+
}
|
|
832
|
+
interface ProductBrowseParams {
|
|
833
|
+
first?: number;
|
|
834
|
+
offset?: number;
|
|
835
|
+
category?: string;
|
|
836
|
+
query?: string;
|
|
837
|
+
active?: boolean;
|
|
838
|
+
orderBy?: string;
|
|
839
|
+
orderDirection?: "asc" | "desc";
|
|
840
|
+
fields?: string[];
|
|
841
|
+
_provider?: "stripe" | "yns";
|
|
842
|
+
}
|
|
843
|
+
interface ProductGetParams {
|
|
844
|
+
slug?: string;
|
|
845
|
+
id?: string;
|
|
846
|
+
fields?: string[];
|
|
847
|
+
_provider?: "stripe" | "yns";
|
|
848
|
+
}
|
|
849
|
+
interface ProductSearchParams {
|
|
850
|
+
query: string;
|
|
851
|
+
limit?: number;
|
|
852
|
+
fields?: string[];
|
|
853
|
+
_provider?: "stripe" | "yns";
|
|
854
|
+
}
|
|
855
|
+
interface CartAddParams {
|
|
856
|
+
variantId: string;
|
|
857
|
+
cartId?: string;
|
|
858
|
+
quantity?: number;
|
|
859
|
+
subscriptionId?: string;
|
|
860
|
+
_provider?: "stripe" | "yns";
|
|
861
|
+
}
|
|
862
|
+
interface CartUpdateParams {
|
|
863
|
+
cartId: string;
|
|
864
|
+
variantId: string;
|
|
865
|
+
quantity: number;
|
|
866
|
+
_provider?: "stripe" | "yns";
|
|
867
|
+
}
|
|
868
|
+
interface CartClearParams {
|
|
869
|
+
cartId: string;
|
|
870
|
+
_provider?: "stripe" | "yns";
|
|
871
|
+
}
|
|
872
|
+
interface CartGetParams {
|
|
873
|
+
cartId: string;
|
|
874
|
+
_provider?: "stripe" | "yns";
|
|
875
|
+
}
|
|
876
|
+
interface OrderGetParams {
|
|
877
|
+
orderId: string;
|
|
878
|
+
_provider?: "stripe" | "yns";
|
|
879
|
+
}
|
|
880
|
+
interface OrderListParams {
|
|
881
|
+
customerId?: string;
|
|
882
|
+
limit?: number;
|
|
883
|
+
offset?: number;
|
|
884
|
+
_provider?: "stripe" | "yns";
|
|
885
|
+
}
|
|
886
|
+
interface ProductBrowseResult {
|
|
887
|
+
data: Product[];
|
|
888
|
+
meta: {
|
|
889
|
+
count: number;
|
|
890
|
+
offset: number;
|
|
891
|
+
limit: number;
|
|
892
|
+
hasMore: boolean;
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
interface ProductSearchResult {
|
|
896
|
+
data: Product[];
|
|
897
|
+
total: number;
|
|
898
|
+
}
|
|
899
|
+
interface OrderListResult {
|
|
900
|
+
data: Order[];
|
|
901
|
+
meta: {
|
|
902
|
+
count: number;
|
|
903
|
+
offset: number;
|
|
904
|
+
limit: number;
|
|
905
|
+
hasMore: boolean;
|
|
906
|
+
};
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
/**
|
|
910
|
+
* Configure the Commerce SDK with provider settings
|
|
911
|
+
*/
|
|
912
|
+
declare function configure(config: CommerceConfig): void;
|
|
913
|
+
|
|
914
|
+
/**
|
|
915
|
+
* Cart resource operations
|
|
916
|
+
*/
|
|
917
|
+
declare const cart: {
|
|
918
|
+
/**
|
|
919
|
+
* Add item to cart
|
|
920
|
+
*
|
|
921
|
+
* @example
|
|
922
|
+
* ```typescript
|
|
923
|
+
* import { cart } from "commerce-kit";
|
|
924
|
+
*
|
|
925
|
+
* // Add to existing cart
|
|
926
|
+
* const result = await cart.add({
|
|
927
|
+
* variantId: "variant_123",
|
|
928
|
+
* cartId: "cart_abc",
|
|
929
|
+
* quantity: 2
|
|
930
|
+
* });
|
|
931
|
+
*
|
|
932
|
+
* // Create new cart if no cartId provided
|
|
933
|
+
* const newCart = await cart.add({
|
|
934
|
+
* variantId: "variant_456"
|
|
935
|
+
* });
|
|
936
|
+
*
|
|
937
|
+
* // Override provider
|
|
938
|
+
* const stripeCart = await cart.add({
|
|
939
|
+
* variantId: "price_123",
|
|
940
|
+
* cartId: "pi_456",
|
|
941
|
+
* _provider: "stripe"
|
|
942
|
+
* });
|
|
943
|
+
* ```
|
|
944
|
+
*/
|
|
945
|
+
add(params: CartAddParams): Promise<{
|
|
946
|
+
cartId: string;
|
|
947
|
+
}>;
|
|
948
|
+
/**
|
|
949
|
+
* Update item quantity in cart
|
|
950
|
+
*
|
|
951
|
+
* @example
|
|
952
|
+
* ```typescript
|
|
953
|
+
* import { cart } from "commerce-kit";
|
|
954
|
+
*
|
|
955
|
+
* // Update quantity
|
|
956
|
+
* const result = await cart.update({
|
|
957
|
+
* cartId: "cart_123",
|
|
958
|
+
* variantId: "variant_456",
|
|
959
|
+
* quantity: 3
|
|
960
|
+
* });
|
|
961
|
+
*
|
|
962
|
+
* // Set quantity to 0 to remove item
|
|
963
|
+
* const removed = await cart.update({
|
|
964
|
+
* cartId: "cart_123",
|
|
965
|
+
* variantId: "variant_456",
|
|
966
|
+
* quantity: 0
|
|
967
|
+
* });
|
|
968
|
+
* ```
|
|
969
|
+
*/
|
|
970
|
+
update(params: CartUpdateParams): Promise<{
|
|
971
|
+
cartId: string;
|
|
972
|
+
}>;
|
|
973
|
+
/**
|
|
974
|
+
* Clear all items from cart
|
|
975
|
+
*
|
|
976
|
+
* @example
|
|
977
|
+
* ```typescript
|
|
978
|
+
* import { cart } from "commerce-kit";
|
|
979
|
+
*
|
|
980
|
+
* const result = await cart.clear({
|
|
981
|
+
* cartId: "cart_123"
|
|
982
|
+
* });
|
|
983
|
+
* ```
|
|
984
|
+
*/
|
|
985
|
+
clear(params: CartClearParams): Promise<{
|
|
986
|
+
cartId: string;
|
|
987
|
+
}>;
|
|
988
|
+
/**
|
|
989
|
+
* Get cart details with all items
|
|
990
|
+
*
|
|
991
|
+
* @example
|
|
992
|
+
* ```typescript
|
|
993
|
+
* import { cart } from "commerce-kit";
|
|
994
|
+
*
|
|
995
|
+
* const cartData = await cart.get({
|
|
996
|
+
* cartId: "cart_123"
|
|
997
|
+
* });
|
|
998
|
+
*
|
|
999
|
+
* if (cartData) {
|
|
1000
|
+
* console.log(`Cart has ${cartData.items.length} items`);
|
|
1001
|
+
* console.log(`Total: ${cartData.total} ${cartData.currency}`);
|
|
1002
|
+
* }
|
|
1003
|
+
* ```
|
|
1004
|
+
*/
|
|
1005
|
+
get(params: CartGetParams): Promise<Cart | null>;
|
|
1006
|
+
};
|
|
1007
|
+
|
|
1008
|
+
/**
|
|
1009
|
+
* Order resource operations
|
|
1010
|
+
*/
|
|
1011
|
+
declare const order: {
|
|
1012
|
+
/**
|
|
1013
|
+
* Get a single order by ID
|
|
1014
|
+
*
|
|
1015
|
+
* @example
|
|
1016
|
+
* ```typescript
|
|
1017
|
+
* import { order } from "commerce-kit";
|
|
1018
|
+
*
|
|
1019
|
+
* const orderData = await order.get({
|
|
1020
|
+
* orderId: "order_123"
|
|
1021
|
+
* });
|
|
1022
|
+
*
|
|
1023
|
+
* if (orderData) {
|
|
1024
|
+
* console.log(`Order status: ${orderData.status}`);
|
|
1025
|
+
* console.log(`Order total: ${orderData.total} ${orderData.currency}`);
|
|
1026
|
+
* }
|
|
1027
|
+
* ```
|
|
1028
|
+
*/
|
|
1029
|
+
get(params: OrderGetParams): Promise<Order | null>;
|
|
1030
|
+
/**
|
|
1031
|
+
* List orders with optional filtering and pagination
|
|
1032
|
+
*
|
|
1033
|
+
* @example
|
|
1034
|
+
* ```typescript
|
|
1035
|
+
* import { order } from "commerce-kit";
|
|
1036
|
+
*
|
|
1037
|
+
* // List all orders
|
|
1038
|
+
* const orders = await order.list({
|
|
1039
|
+
* limit: 20,
|
|
1040
|
+
* offset: 0
|
|
1041
|
+
* });
|
|
1042
|
+
*
|
|
1043
|
+
* // List orders for specific customer
|
|
1044
|
+
* const customerOrders = await order.list({
|
|
1045
|
+
* customerId: "customer_123",
|
|
1046
|
+
* limit: 10
|
|
1047
|
+
* });
|
|
1048
|
+
*
|
|
1049
|
+
* console.log(`Found ${orders.meta.count} orders`);
|
|
1050
|
+
* ```
|
|
1051
|
+
*/
|
|
1052
|
+
list(params?: OrderListParams): Promise<OrderListResult>;
|
|
1053
|
+
};
|
|
1054
|
+
|
|
1055
|
+
/**
|
|
1056
|
+
* Product resource operations
|
|
1057
|
+
*/
|
|
1058
|
+
declare const product: {
|
|
1059
|
+
/**
|
|
1060
|
+
* Browse/list products with optional filtering and pagination
|
|
1061
|
+
*
|
|
1062
|
+
* @example
|
|
1063
|
+
* ```typescript
|
|
1064
|
+
* import { product } from "commerce-kit";
|
|
1065
|
+
*
|
|
1066
|
+
* const products = await product.browse({
|
|
1067
|
+
* first: 10,
|
|
1068
|
+
* category: "electronics"
|
|
1069
|
+
* });
|
|
1070
|
+
*
|
|
1071
|
+
* // With GraphQL field selection (YNS only)
|
|
1072
|
+
* const productsWithFields = await product.browse({
|
|
1073
|
+
* first: 5,
|
|
1074
|
+
* fields: ["id", "name", "price", "images"]
|
|
1075
|
+
* });
|
|
1076
|
+
*
|
|
1077
|
+
* // Override provider for specific call
|
|
1078
|
+
* const stripeProducts = await product.browse({
|
|
1079
|
+
* first: 10,
|
|
1080
|
+
* _provider: "stripe"
|
|
1081
|
+
* });
|
|
1082
|
+
* ```
|
|
1083
|
+
*/
|
|
1084
|
+
browse(params?: ProductBrowseParams): Promise<ProductBrowseResult>;
|
|
1085
|
+
/**
|
|
1086
|
+
* Get a single product by slug or ID
|
|
1087
|
+
*
|
|
1088
|
+
* @example
|
|
1089
|
+
* ```typescript
|
|
1090
|
+
* import { product } from "commerce-kit";
|
|
1091
|
+
*
|
|
1092
|
+
* const productData = await product.get({ slug: "awesome-product" });
|
|
1093
|
+
*
|
|
1094
|
+
* // With GraphQL field selection (YNS only)
|
|
1095
|
+
* const productWithFields = await product.get({
|
|
1096
|
+
* slug: "awesome-product",
|
|
1097
|
+
* fields: ["id", "name", "price", "category.name"]
|
|
1098
|
+
* });
|
|
1099
|
+
*
|
|
1100
|
+
* // Get by ID instead of slug
|
|
1101
|
+
* const productById = await product.get({ id: "prod_123" });
|
|
1102
|
+
* ```
|
|
1103
|
+
*/
|
|
1104
|
+
get(params: ProductGetParams): Promise<Product | null>;
|
|
1105
|
+
/**
|
|
1106
|
+
* Search products by query string
|
|
1107
|
+
*
|
|
1108
|
+
* @example
|
|
1109
|
+
* ```typescript
|
|
1110
|
+
* import { product } from "commerce-kit";
|
|
1111
|
+
*
|
|
1112
|
+
* const searchResults = await product.search({
|
|
1113
|
+
* query: "laptop computer",
|
|
1114
|
+
* limit: 20
|
|
1115
|
+
* });
|
|
1116
|
+
*
|
|
1117
|
+
* // With field selection
|
|
1118
|
+
* const searchWithFields = await product.search({
|
|
1119
|
+
* query: "smartphone",
|
|
1120
|
+
* fields: ["id", "name", "price"],
|
|
1121
|
+
* limit: 10
|
|
1122
|
+
* });
|
|
1123
|
+
* ```
|
|
1124
|
+
*/
|
|
1125
|
+
search(params: ProductSearchParams): Promise<ProductSearchResult>;
|
|
1126
|
+
};
|
|
1127
|
+
|
|
764
1128
|
declare const provider: ({ tags, revalidate, cache, tagPrefix, secretKey, }: {
|
|
765
1129
|
tags?: NextFetchRequestConfig["tags"];
|
|
766
1130
|
revalidate?: NextFetchRequestConfig["revalidate"];
|
|
@@ -769,4 +1133,42 @@ declare const provider: ({ tags, revalidate, cache, tagPrefix, secretKey, }: {
|
|
|
769
1133
|
secretKey: string | undefined;
|
|
770
1134
|
}) => Stripe;
|
|
771
1135
|
|
|
772
|
-
|
|
1136
|
+
/**
|
|
1137
|
+
* Create a scoped Commerce instance with a specific provider
|
|
1138
|
+
*
|
|
1139
|
+
* @example
|
|
1140
|
+
* ```typescript
|
|
1141
|
+
* import { withProvider } from "commerce-kit";
|
|
1142
|
+
*
|
|
1143
|
+
* const ynsCommerce = withProvider("yns");
|
|
1144
|
+
* const stripeCommerce = withProvider("stripe");
|
|
1145
|
+
*
|
|
1146
|
+
* const ynsProducts = await ynsCommerce.product.browse({ first: 10 });
|
|
1147
|
+
* const stripeProducts = await stripeCommerce.product.browse({ first: 10 });
|
|
1148
|
+
* ```
|
|
1149
|
+
*/
|
|
1150
|
+
declare function withProvider(provider: "stripe" | "yns"): {
|
|
1151
|
+
product: {
|
|
1152
|
+
browse(params: any): Promise<ProductBrowseResult>;
|
|
1153
|
+
get(params: any): Promise<Product | null>;
|
|
1154
|
+
search(params: any): Promise<ProductSearchResult>;
|
|
1155
|
+
};
|
|
1156
|
+
cart: {
|
|
1157
|
+
add(params: any): Promise<{
|
|
1158
|
+
cartId: string;
|
|
1159
|
+
}>;
|
|
1160
|
+
update(params: any): Promise<{
|
|
1161
|
+
cartId: string;
|
|
1162
|
+
}>;
|
|
1163
|
+
clear(params: any): Promise<{
|
|
1164
|
+
cartId: string;
|
|
1165
|
+
}>;
|
|
1166
|
+
get(params: any): Promise<Cart | null>;
|
|
1167
|
+
};
|
|
1168
|
+
order: {
|
|
1169
|
+
get(params: any): Promise<Order | null>;
|
|
1170
|
+
list(params?: any): Promise<OrderListResult>;
|
|
1171
|
+
};
|
|
1172
|
+
};
|
|
1173
|
+
|
|
1174
|
+
export { type AddressSchema, type BaseProvider, type Cart$1 as Cart, type CartAddParams, type CartClearParams, type CartGetParams, type CartUpdateParams, type Cart as CommerceCart, type CartItem as CommerceCartItem, type CommerceConfig, type Order as CommerceOrder, MappedCart, type Order$1 as Order, type Product, type ProductBrowseParams, type ProductGetParams, type ProductsFromMetadata, accountGet, calculateCartTotalNet, calculateCartTotalNetWithoutShipping, calculateCartTotalPossiblyWithTax, cart, cartAdd, cartAddOptimistic, cartChangeQuantity, cartCount, cartCreate, cartGet, cartSaveBillingAddress, cartSaveEmail, cartSaveShipping, cartSaveTax, cartSetQuantity, cartUpdateQuantity, categoryBrowse, configure, contextGet, fileGet, getAddressSchema, getCartWithProductsById, getProductsFromCart, getProductsFromMetadata, order, orderGet, product, productBrowse, productGet, productGetById, productReviewAdd, productReviewBrowse, provider, shippingBrowse, shippingGet, taxDefaultGet, updatePaymentIntent, withProvider };
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,247 @@
|
|
|
1
|
-
import{revalidateTag as P}from"next/cache";import R from"stripe";import{z as S}from"zod";import{neon as pt}from"@neondatabase/serverless";var T;process.env.DATABASE_URL&&(T=pt(process.env.DATABASE_URL));var lt=process.env.STRIPE_SECRET_KEY,mt=process.env.STRIPE_CURRENCY,y={StripeSecretKey:lt,StripeCurrency:mt};import{z as c}from"zod";function b(t,e){if(!t)throw new Error(e)}var H=async t=>{try{return[null,await t]}catch(e){return[e instanceof Error?e:new Error(String(e)),null]}},N=t=>{if(t==null)return 0;if(typeof t=="number")return t;let e=Number.parseInt(t,10);return Number.isNaN(e)?0:e},Y=t=>{if(t==null)return null;try{return JSON.parse(t)}catch{return null}};var ft=t=>t.toString().replace(/\\/g,"\\\\").replace(/"/g,'\\"'),V=t=>Object.entries(t).map(([e,n])=>`${e}:"${ft(n)}"`).join(" AND ").trim();function q(t){return t.toSorted((e,n)=>{let a=Number(e.metadata.order),o=Number(n.metadata.order);return Number.isNaN(a)&&Number.isNaN(o)||a===o?n.updated-e.updated:Number.isNaN(a)?1:Number.isNaN(o)?-1:a-o})}var gt=c.object({category:c.string().optional(),order:c.coerce.number().optional(),slug:c.string(),variant:c.string().optional(),stock:c.coerce.number().optional().transform(t=>t===void 0?Number.POSITIVE_INFINITY:t),digitalAsset:c.string().optional(),preview:c.string().optional()});function O({default_price:t,marketing_features:e,...n}){return b(t,"Product must have a default price"),b(typeof t=="object","Product default price must be an object"),{...n,default_price:t,marketing_features:e.map(a=>a.name).filter(Boolean),metadata:gt.parse(n.metadata)}}function yt(t){return!!(t.active&&!t.deleted&&t.default_price)}function W(t){return{...t,data:t.data.filter(yt)}}function K(t){return t.data.map(O)}function Z(t){return t}function tt(t){return t.data.map(Z)}function Q(t){return t.filter((e,n,a)=>n===a.findIndex(o=>o.metadata.slug===e.metadata.slug))}var et=t=>!t.deleted&&t.active,F=c.object({shippingRateId:c.string().optional(),taxCalculationId:c.string().optional(),taxCalculationExp:c.string().optional(),taxId:c.string().optional(),couponCode:c.string().optional(),taxedAmount:c.string().optional(),"billingAddress.city":c.string().optional(),"billingAddress.country":c.string().optional(),"billingAddress.line1":c.string().optional(),"billingAddress.line2":c.string().optional(),"billingAddress.name":c.string().optional(),"billingAddress.postalCode":c.string().optional(),"billingAddress.state":c.string().optional(),netAmount:c.string().optional(),taxBreakdown0:c.string().optional(),taxBreakdown1:c.string().optional(),taxBreakdown2:c.string().optional(),taxBreakdown3:c.string().optional(),taxBreakdown4:c.string().optional(),taxBreakdown5:c.string().optional()}).and(c.record(c.string(),c.string())),rt=c.object({taxType:c.string(),taxPercentage:c.string(),taxAmount:c.number()});function z(t){let e=t.payment_method;b(typeof e!="string","Payment method should not be a string");let n=t.customer;b(typeof n!="string"&&!n?.deleted,"Customer should not be a string");let a=F.parse(t.metadata),o=Object.entries(a).filter(([r])=>r.startsWith("taxBreakdown")).map(([r,i])=>{let u=rt.safeParse(Y(String(i)));return u.success?u.data:null}).filter(Boolean);return{...t,metadata:a,customer:n,payment_method:e,taxBreakdown:o}}function nt({payment_method:t,latest_charge:e,...n}){b(typeof t=="object","Payment method is missing from order"),b(typeof e=="object","Latest charge is missing from order");let a=F.parse(n.metadata),o=Object.entries(a).filter(([r])=>r.startsWith("taxBreakdown")).map(([r,i])=>{let u=rt.safeParse(Y(String(i)));return u.success?u.data:null}).filter(Boolean);return{...n,payment_method:t,latest_charge:e,taxBreakdown:o,metadata:a}}var v={DEBUG:0,LOG:1,WARN:2,ERROR:3},ht="LOG",xt=process.env.LOG_LEVEL&&process.env.LOG_LEVEL in v?process.env.LOG_LEVEL:ht,B=v[xt],d={time(t){B>v.DEBUG||console.time(t)},timeEnd(t){B>v.DEBUG||console.timeEnd(t)},log(...t){B>v.LOG||console.log(...t)},dir(t,e){B>v.LOG||console.dir(t,e)},warn(...t){B>v.WARN||console.warn(...t)},error(...t){B>v.ERROR||console.error(...t)}};var _=t=>t.filter(Boolean),x={accountGetById:{tags:({accountId:t})=>_(["account",t&&`account-${t}`]),revalidate:()=>{}},cartGetById:{tags:({cartId:t})=>_(["cart",`cart-${t}`]),revalidate:()=>{}},createTaxCalculation:{tags:({cartId:t})=>_(["tax-calculations",`tax-calculations-${t}`]),revalidate:()=>{}},fileGetById:{tags:({fileId:t})=>_(["files",`file-${t}`]),revalidate:()=>{}},orderGetById:{tags:({orderId:t})=>_(["order",`order-${t}`]),revalidate:()=>{}},productBrowse:{tags:({category:t})=>_(["product",t&&`category-${t}`]),revalidate:()=>{}},productGetById:{tags:({productId:t})=>_(["product",`product-${t}`]),revalidate:()=>{}},productGetBySlug:{tags:({productSlug:t})=>_(["product",`product-${t}`]),revalidate:()=>{}},shippingBrowse:{tags:()=>_(["shipping"]),revalidate:()=>{}},shippingGetById:{tags:({shippingId:t})=>_(["shipping",`shipping-${t}`]),revalidate:()=>{}},taxDefaultGet:{tags:()=>_(["tax-settings"]),revalidate:()=>{}}};import at from"stripe";var wt=(t,e)=>!t||!e?t:[...t,`prefix-${e}`,...t.map(n=>`${e}-${n}`)],m=({tags:t,revalidate:e,cache:n,tagPrefix:a,secretKey:o})=>{let r=o??y.StripeSecretKey;if(!r)throw new Error("Missing `secretKey` parameter and `STRIPE_SECRET_KEY` env variable.");let i=wt(t,a);return new at(r,{typescript:!0,apiVersion:"2025-08-27.basil",httpClient:at.createFetchHttpClient(((f,s)=>fetch(f,{...s,cache:n??s?.cache,next:{tags:i??s?.next?.tags,revalidate:e??s?.next?.revalidate}}))),appInfo:{name:"Commerce SDK",version:"beta",url:"https://yournextstore.com",partner_id:"CONS-003378"}})};var l=async()=>{let t={stripeAccount:void 0,storeId:void 0,secretKey:void 0,publishableKey:void 0};return await global?.__ynsFindStripeAccount?.()??t};var j=1e3;function oe({productId:t,cartId:e}){return e?Ct({cartId:e,productId:t,operation:"INCREASE",clearTaxCalculation:!0}):_t({productId:t})}async function Ct({productId:t,cartId:e,operation:n,clearTaxCalculation:a}){let[o,r]=await Promise.all([k(t),ct(e)]);if(!o)throw new Error(`Product not found: ${t}`);if(!r)throw new Error(`Cart not found: ${e}`);if(o.metadata.stock<=0)throw Error(`Product ${t} is out of stock`);if(!y.StripeCurrency)throw new Error("Missing `STRIPE_CURRENCY` env variable");if(y.StripeCurrency.toLowerCase()!==o.default_price.currency.toLowerCase())throw new Error(`Product currency ${o.default_price.currency} does not match cart currency ${y.StripeCurrency}`);let i=r.cart.metadata??{},s=N(i[t])+(n==="INCREASE"?1:-1);s<=0?i[t]="":i[t]=s.toString();let w=vt(r)+(o.default_price.unit_amount??0);try{return await E({paymentIntentId:e,data:{metadata:i,amount:w||j},clearTaxCalculation:a})}catch(h){d.error(h)}finally{P(`cart-${e}`)}}async function $(t){let{stripeAccount:e,storeId:n,secretKey:a}=await l(),o=m({secretKey:a,tagPrefix:n,tags:x.cartGetById.tags({cartId:t}),cache:"force-cache"});try{let r=await o.paymentIntents.retrieve(t,{expand:["payment_method","customer"]},{stripeAccount:e});if(it.includes(r.status)){let i=z(r);if(!i)return null;let u=await X(i.metadata),{metadata:{shippingRateId:f}}=i,s=f&&await L(f);return{cart:i,lines:u.map(({product:w,quantity:h})=>w?{product:w,quantity:h}:null).filter(Boolean),shippingRate:s||null}}}catch(r){if(d.error(r),r instanceof R.errors.StripeError&&r.code==="resource_missing")return null;throw r}}async function _t({productId:t}={}){let{stripeAccount:e,storeId:n,secretKey:a}=await l(),o=m({secretKey:a,tagPrefix:n,cache:"no-cache"});if(!y.StripeCurrency)throw new Error("Missing `STRIPE_CURRENCY` env variable");try{let r=t?await k(t):null;if(r&&r.metadata.stock<=0)throw Error(`Product ${t} is out of stock`);return await o.paymentIntents.create({currency:y.StripeCurrency,amount:r?.default_price.unit_amount||j,automatic_payment_methods:{enabled:!0},metadata:{...r&&{[r.id]:"1"}}},{stripeAccount:e})}catch(r){throw d.error(r),r}}async function ie({cart:t,add:e}){if(!e)return t;let n=await k(e);if(!n)return d.warn(`Product not found: ${e}`),t;let o=(t?.lines.find(i=>i.product.id===e)?t.lines:[...t?.lines??[],{product:n,quantity:0}]).map(i=>i.product.id===e?{...i,quantity:i.quantity+1}:i),r=t?U(t)+(n.default_price.unit_amount??0):n.default_price.unit_amount??0;return{...t,cart:{...t?.cart,amount:r},lines:o}}async function se({cartId:t,productId:e,quantity:n}){let[a,o]=await Promise.all([J(e),$(t)]);if(!a)throw new Error(`Product not found: ${e}`);if(!o)throw new Error(`Cart not found: ${t}`);if(y.StripeCurrency?.toLowerCase()!==a.default_price.currency.toLowerCase())throw new Error(`Product currency ${a.default_price.currency} does not match cart currency ${y.StripeCurrency}`);let r=o.cart.metadata??{};n<=0?r[e]="":r[e]=n.toString();let i=U(o)+(a.default_price.unit_amount??0);try{return await E({paymentIntentId:t,data:{metadata:r,amount:i||j}})}catch(u){d.error(u)}finally{P(`cart-${t}`)}}async function J(t){let{stripeAccount:e,storeId:n,secretKey:a}=await l(),o=m({secretKey:a,tagPrefix:n,tags:x.productGetById.tags({productId:t}),cache:"force-cache"});try{let r=await o.products.retrieve(t,{expand:["default_price"]},{stripeAccount:e});return O(r)}catch(r){if(r instanceof R.errors.StripeError&&r.code==="resource_missing")return null;throw r}}async function ce({slug:t}){let{stripeAccount:e,storeId:n,secretKey:a}=await l(),r=await m({secretKey:a,tagPrefix:n,tags:x.productGetBySlug.tags({productSlug:t}),cache:"force-cache"}).products.search({query:V({active:!0,'metadata["slug"]':t}),expand:["data.default_price"]},{stripeAccount:e});if(r.data.length>1&&r.data.some(i=>!i.metadata.variant))throw new Error(`Multiple products found with the same slug (${t}) but no variant set.`);return await Promise.allSettled(r.data.map(i=>J(i.id))),q(K(W(r)))}async function St(t){let{stripeAccount:e,storeId:n,secretKey:a}=await l();if(t.filter?.category){let i=t.filter?.category,f=await m({secretKey:a,tagPrefix:n,tags:x.productBrowse.tags({category:i}),cache:"force-cache"}).products.search({limit:100,query:V({active:!0,'metadata["category"]':i}),expand:["data.default_price"]},{stripeAccount:e});return q(Q(K(W(f)))).slice(t.offset||0,t.first)}let r=await m({secretKey:a,tagPrefix:n,tags:x.productBrowse.tags({}),cache:"force-cache"}).products.list({limit:100,active:!0,expand:["data.default_price"]},{stripeAccount:e});return q(Q(K(W(r))).filter(et)).slice(t.offset||0,t.first)}async function ue(){let{stripeAccount:t,storeId:e,secretKey:n}=await l(),o=await m({secretKey:n,tagPrefix:e,tags:x.shippingBrowse.tags(),cache:"force-cache"}).shippingRates.list({active:!0},{stripeAccount:t});return tt(o)}async function L(t){let{stripeAccount:e,storeId:n,secretKey:a}=await l(),o=m({secretKey:a,tagPrefix:n,tags:x.shippingGetById.tags({shippingId:t}),cache:"force-cache"});try{let r=await o.shippingRates.retrieve(t,{},{stripeAccount:e});return r}catch(r){if(d.error(r),r instanceof R.errors.StripeError&&r.code==="resource_missing")return null;throw r}}async function de(){let e=(await St({first:100})).map(a=>a.metadata.category).filter(Boolean),n=new Set(e);return Array.from(n)}async function pe(t){let{stripeAccount:e,storeId:n,secretKey:a}=await l(),o=m({secretKey:a,tagPrefix:n,tags:x.fileGetById.tags({fileId:t}),cache:"force-cache"});try{return await o.fileLinks.create({file:t},{stripeAccount:e})}catch(r){if(d.error(r),r instanceof R.errors.StripeError&&r.code==="resource_missing")return null;throw r}}async function le(){let{stripeAccount:t,storeId:e,secretKey:n}=await l(),a=m({secretKey:n,tagPrefix:e,tags:x.accountGetById.tags({}),cache:"force-cache"});try{let[o,r]=await H(a.accounts.retrieve({expand:["settings.branding.logo"]},{stripeAccount:t})),i=r?.settings?.branding.logo??null;return!i||typeof i=="string"?{account:r,logo:null}:{account:r,logo:i}}catch(o){if(d.error(o),o instanceof R.errors.StripeError&&o.code==="resource_missing")return null;throw o}}async function bt(t){let{stripeAccount:e,storeId:n,secretKey:a}=await l(),o=m({secretKey:a,tagPrefix:n,tags:x.orderGetById.tags({orderId:t}),cache:"force-cache"});try{let r=await o.paymentIntents.retrieve(t,{expand:["payment_method","latest_charge","customer"]},{stripeAccount:e});return nt(r)}catch(r){if(r instanceof R.errors.StripeError&&r.code==="resource_missing")return null;throw r}}async function me(t){let e=await bt(t);if(!e)return null;let n=st(e.metadata),a=await Promise.all(n.map(async([i,u])=>({product:await k(i),quantity:u}))),{metadata:{shippingRateId:o}}=e,r=o&&await L(o);return{order:e,lines:a.map(({product:i,quantity:u})=>i?{product:i,quantity:u}:null).filter(Boolean),shippingRate:r||null}}var k=async t=>{let{stripeAccount:e,storeId:n,secretKey:a}=await l(),o=m({secretKey:a,tagPrefix:n,tags:x.productGetById.tags({productId:t}),cache:"force-cache"});try{let r=await o.products.retrieve(t,{expand:["default_price"]},{stripeAccount:e});return O(r)}catch(r){if(r instanceof R.errors.StripeError&&r.code==="resource_missing")return null;throw r}},it=["requires_action","requires_confirmation","requires_capture","requires_payment_method"],st=t=>Object.entries(t??{}).filter(([e])=>e.startsWith("prod_")).map(([e,n])=>[e,N(n)]).filter(([,e])=>e&&Number.isFinite(e)&&e>0),Rt=async t=>{let{stripeAccount:e,storeId:n,secretKey:a}=await l(),o=m({secretKey:a,tagPrefix:n,tags:x.cartGetById.tags({cartId:t}),cache:"force-cache"});try{let r=await o.paymentIntents.retrieve(t,{expand:["payment_method"]},{stripeAccount:e}),i=typeof r.customer=="string"?await ut(r.customer):null;if(it.includes(r.status))return z({...r,customer:i})}catch(r){if(d.error(r),r instanceof R.errors.StripeError&&r.code==="resource_missing")return null;throw r}};async function X(t){let e=st(t);return await Promise.all(e.map(async([a,o])=>({product:await k(a),quantity:o})))}var ct=async t=>{let e=await Rt(t);if(!e)return null;let n=await X(e.metadata),{metadata:{shippingRateId:a}}=e,o=a&&await L(a);return{cart:e,lines:n.map(({product:r,quantity:i})=>r?{product:r,quantity:i}:null).filter(Boolean),shippingRate:o||null}},vt=t=>t?t.cart.metadata?.taxCalculationId?t.cart.amount:(t.shippingRate?.fixed_amount?.amount??0)+t.lines.reduce((e,{product:n,quantity:a})=>e+(n.default_price?.unit_amount??0)*a,0):0,Pt=["billingAddress.country","billingAddress.postalCode","billingAddress.state","taxId","shippingRateId","couponCode"];function Et({oldCart:t,data:e,mergedMetadata:n,lines:a}){if(!process.env.ENABLE_STRIPE_TAX)return!1;let o=Date.now(),r=n.taxCalculationExp?Number.parseInt(n.taxCalculationExp,10)*1e3:null;if(!r||o>=r)return!0;let i=t.cart.metadata.netAmount||t.cart.amount,u=e.amount,f=Pt.some(p=>!n[p]&&!t.cart.metadata[p]?!1:n[p]!==t.cart.metadata[p]),s=a.length!==t.lines.length||a.some(p=>{let C=t.lines.find(A=>A.product.id===p.product?.id);return p.product?.default_price.unit_amount!==C?.product.default_price.unit_amount||p.quantity!==C?.quantity});return u&&i!==u||f||s}var fe=t=>S.object({name:S.string({message:t.nameRequired}).min(1,t.nameRequired),city:S.string({message:t.cityRequired}).min(1,t.cityRequired),country:S.string({message:t.countryRequired}).min(1,t.countryRequired),line1:S.string({message:t.line1Required}).min(1,t.line1Required),line2:S.string().optional().nullable().default(""),postalCode:S.string({message:t.postalCodeRequired}).min(1,t.postalCodeRequired),state:S.string().optional().nullable().default(""),phone:S.string().optional().nullable().default(""),taxId:S.string().optional().nullable().default(""),email:S.string().optional().nullable().default("")}),At=async({lineItems:t,billingAddress:e,cartId:n,shippingRateId:a,taxId:o})=>{if(!process.env.ENABLE_STRIPE_TAX)return null;if(!y.StripeCurrency)throw new Error("Missing `STRIPE_CURRENCY` env variable");let{stripeAccount:r,storeId:i,secretKey:u}=await l(),f=m({secretKey:u,tagPrefix:i,tags:x.createTaxCalculation.tags({cartId:n}),cache:"force-cache"});if(!e?.country)return null;let s=a?await L(a):null,w=typeof s?.tax_code=="string"?s.tax_code:s?.tax_code?.id,h=await Bt(),p=y.StripeCurrency==="usd"||y.StripeCurrency==="cad"?"exclusive":"inclusive",C=h.defaults.tax_behavior==="inferred_by_currency"?p:h.defaults.tax_behavior??p;h.defaults.tax_behavior||d.warn(`Tax behavior not set in Stripe settings. Inferring from currency ${y.StripeCurrency}: ${p}.`),d.time(`createTaxCalculation ${n}`);let A=await f.tax.calculations.create({expand:["line_items"],line_items:t.map(M=>({...M,tax_behavior:M.tax_behavior??C})),currency:y.StripeCurrency,shipping_cost:s?.active&&s?.fixed_amount?{amount:s.fixed_amount.amount,tax_behavior:s.tax_behavior==="inclusive"?"inclusive":s.tax_behavior==="exclusive"?"exclusive":C,tax_code:w??h.defaults.tax_code??void 0}:void 0,customer_details:{tax_ids:o?[{type:"eu_vat",value:o}]:void 0,address_source:"billing",address:{country:e.country,city:e?.city,line1:e?.line1,line2:e?.line2,postal_code:e?.postalCode,state:e?.state}}},{stripeAccount:r});return d.timeEnd(`createTaxCalculation ${n}`),console.log(JSON.stringify(A).length),A},ot={taxBreakdown0:"",taxBreakdown1:"",taxBreakdown2:"",taxBreakdown3:"",taxBreakdown4:"",taxBreakdown5:""};async function ut(t){let{stripeAccount:e,storeId:n,secretKey:a}=await l(),o=m({secretKey:a,tagPrefix:n,tags:["customers",`customers-${t}`],cache:"force-cache"});try{let r=await o.customers.retrieve(t,{},{stripeAccount:e});return r.deleted?null:r}catch(r){if(d.error(r),r instanceof R.errors.StripeError&&r.code==="resource_missing")return null;throw r}}function It(t,e){return e.coupon.amount_off?Math.max(t-e.coupon.amount_off,0):e.coupon.percent_off?Math.floor(t*(1-e.coupon.percent_off/100)):t}var E=async({paymentIntentId:t,data:e,customerOverride:n,clearTaxCalculation:a})=>{let{stripeAccount:o,storeId:r,secretKey:i}=await l(),u=await ct(t);b(u,`Cart not found: ${t}`);let f=e.amount?e.amount.toString():null,s=F.parse({...u.cart.metadata,...e.metadata});d.time("getProductsFromMetadata");let w=await X(s);d.timeEnd("getProductsFromMetadata");let h=!a&&Et({oldCart:u,data:e,mergedMetadata:s,lines:w});console.log({shouldRecalculateTax:h});let p=h?await At({cartId:t,taxId:s.taxId??null,shippingRateId:s.shippingRateId??null,billingAddress:{country:s["billingAddress.country"]??"",city:s["billingAddress.city"]??"",line1:s["billingAddress.line1"]??"",line2:s["billingAddress.line2"]??"",name:s["billingAddress.name"]??"",postalCode:s["billingAddress.postalCode"]??"",state:s["billingAddress.state"]??""},lineItems:w.map(({product:g,quantity:G})=>{if(g?.default_price.unit_amount)return{product:g.id,reference:[g.metadata.slug,g.metadata.variant].filter(Boolean).join("-"),quantity:G,amount:g.default_price.unit_amount*G,tax_behavior:g.default_price.tax_behavior==="exclusive"?"exclusive":g.default_price.tax_behavior==="inclusive"?"inclusive":void 0,tax_code:g.tax_code?typeof g.tax_code=="string"?g.tax_code:g.tax_code.id:void 0}}).filter(Boolean)}):null,C=n??(e.customer?await ut(e.customer):u.cart.customer);console.log({customer:C});let A=m({secretKey:i,tagPrefix:r,cache:"no-cache"});d.time(`paymentIntents.update ${t}`);let M=p&&Object.fromEntries(p.tax_breakdown.map(g=>({taxType:g.tax_rate_details.tax_type,taxPercentage:g.tax_rate_details.percentage_decimal,taxAmount:g.amount})).map((g,G)=>[`taxBreakdown${G}`,JSON.stringify(g)])),I=p?p.amount_total:e.amount,D=I&&C?.discount?.coupon.valid?It(I,C.discount):I;console.log({"discount.coupon.amount_off":C?.discount?.coupon.amount_off,"discount.coupon.percent_off":C?.discount?.coupon.percent_off,discountedAmount:D,taxedAmount:I,"taxCalculation.amount_total":p?.amount_total,"data.amount":e.amount,netAmount:f});let dt=await A.paymentIntents.update(t,{...e,...D&&{amount:D},metadata:{...s,...f&&{netAmount:f},...I&&{taxedAmount:I},...p?{...ot,...M,taxCalculationId:p.id,taxCalculationExp:p?.expires_at}:{...a&&{...ot,taxCalculationId:"",taxCalculationExp:""}}}},{stripeAccount:o});return d.timeEnd(`paymentIntents.update ${t}`),dt},U=t=>t?t.cart.metadata?.taxCalculationId?t.cart.amount:(t.shippingRate?.fixed_amount?.amount??0)+Tt(t):0,Tt=t=>t?t.lines.reduce((e,{product:n,quantity:a})=>e+(n.default_price?.unit_amount??0)*a,0):0;async function ge({productId:t,cartId:e,operation:n,clearTaxCalculation:a}){let[o,r]=await Promise.all([J(t),$(e)]);if(!o)throw new Error(`Product not found: ${t}`);if(!r)throw new Error(`Cart not found: ${e}`);if(y.StripeCurrency?.toLowerCase()!==o.default_price.currency.toLowerCase())throw new Error(`Product currency ${o.default_price.currency} does not match cart currency ${y.StripeCurrency}`);let i=r.cart.metadata??{},s=N(i[t])+(n==="INCREASE"?1:-1);s<=0?i[t]="":i[t]=s.toString();let w=U(r)+(o.default_price.unit_amount??0);try{return await E({paymentIntentId:e,data:{metadata:i,amount:w||j},clearTaxCalculation:a})}catch(h){d.error(h)}finally{P(`cart-${e}`)}}var ye=async({cartId:t,email:e})=>{let n=await $(t);if(!n)throw new Error(`Cart not found: ${t}`);try{return await E({paymentIntentId:t,data:{metadata:{...n.cart.metadata,email:e}}})}catch(a){d.error(a)}finally{P(`cart-${t}`)}},he=async({cartId:t,taxId:e})=>{let n=await $(t);if(!n)throw new Error(`Cart not found: ${t}`);try{return await E({paymentIntentId:t,data:{metadata:{...n.cart.metadata,taxId:e}}})}catch(a){d.error(a)}finally{P(`cart-${t}`)}};async function xe({cartId:t,shippingRateId:e}){let n=await $(t);if(!n)throw new Error(`Cart not found: ${t}`);d.time(`cartSaveShipping ${t}`);let a=await L(e);if(d.timeEnd(`cartSaveShipping ${t}`),!a)throw new Error(`Shipping rate not found: ${e}`);try{d.time(`updatePaymentIntent ${t}`);let o=await E({paymentIntentId:t,data:{metadata:{...n.cart.metadata,shippingRateId:e},amount:U({...n,shippingRate:a})}});return d.timeEnd(`updatePaymentIntent ${t}`),o}catch(o){d.error(o)}finally{P(`cart-${t}`)}}async function we({cartId:t,billingAddress:e}){if(!await $(t))throw new Error(`Cart not found: ${t}`);try{return await E({paymentIntentId:t,data:{metadata:{"billingAddress.name":e.name,"billingAddress.phone":e.phone,"billingAddress.city":e.city,"billingAddress.country":e.country,"billingAddress.line1":e.line1,"billingAddress.line2":e.line2??"","billingAddress.postalCode":e.postalCode,"billingAddress.state":e.state??"","billingAddress.email":e.email??""}}})}catch(a){d.error(a)}finally{P(`cart-${t}`)}}async function Bt(){let{stripeAccount:t,storeId:e,secretKey:n}=await l();return await m({secretKey:n,tagPrefix:e,tags:["tax-settings"],cache:"force-cache"}).tax.settings.retrieve({},{stripeAccount:t})}function Ce(t){return Object.entries(t??{}).filter(([e])=>e.startsWith("prod_")).map(([e,n])=>[e,N(n)]).filter(([,e])=>e&&Number.isFinite(e)&&e>0).length}async function _e(t){if(!T)return null;let{storeId:e}=await l();return await T`
|
|
1
|
+
var Wt=Object.defineProperty;var P=(t,e)=>()=>(t&&(e=t(t=0)),e);var mt=(t,e)=>{for(var r in e)Wt(t,r,{get:e[r],enumerable:!0})};import{neon as Kt}from"@neondatabase/serverless";var G,ft=P(()=>{"use strict";process.env.DATABASE_URL&&(G=Kt(process.env.DATABASE_URL))});var Qt,Vt,h,H=P(()=>{"use strict";Qt=process.env.STRIPE_SECRET_KEY,Vt=process.env.STRIPE_CURRENCY,h={StripeSecretKey:Qt,StripeCurrency:Vt}});function v(t,e){if(!t)throw new Error(e)}var gt,yt,q,Z,F=P(()=>{"use strict";gt=t=>{v(Number.isInteger(t),"Value must be an integer")},yt=async t=>{try{return[null,await t]}catch(e){return[e instanceof Error?e:new Error(String(e)),null]}},q=t=>{if(t==null)return 0;if(typeof t=="number")return t;let e=Number.parseInt(t,10);return Number.isNaN(e)?0:e},Z=t=>{if(t==null)return null;try{return JSON.parse(t)}catch{return null}}});var jt,tt,et=P(()=>{"use strict";jt=t=>t.toString().replace(/\\/g,"\\\\").replace(/"/g,'\\"'),tt=t=>Object.entries(t).map(([e,r])=>`${e}:"${jt(r)}"`).join(" AND ").trim()});import{z as c}from"zod";function U(t){return t.toSorted((e,r)=>{let n=Number(e.metadata.order),o=Number(r.metadata.order);return Number.isNaN(n)&&Number.isNaN(o)||n===o?r.updated-e.updated:Number.isNaN(n)?1:Number.isNaN(o)?-1:n-o})}function Y({default_price:t,marketing_features:e,...r}){return v(t,"Product must have a default price"),v(typeof t=="object","Product default price must be an object"),{...r,default_price:t,marketing_features:e.map(n=>n.name).filter(Boolean),metadata:Jt.parse(r.metadata)}}function zt(t){return!!(t.active&&!t.deleted&&t.default_price)}function W(t){return{...t,data:t.data.filter(zt)}}function K(t){return t.data.map(Y)}function ht(t){return t}function wt(t){return t.data.map(ht)}function rt(t){return t.filter((e,r,n)=>r===n.findIndex(o=>o.metadata.slug===e.metadata.slug))}function at(t){let e=t.payment_method;v(typeof e!="string","Payment method should not be a string");let r=t.customer;v(typeof r!="string"&&!r?.deleted,"Customer should not be a string");let n=Q.parse(t.metadata),o=Object.entries(n).filter(([a])=>a.startsWith("taxBreakdown")).map(([a,i])=>{let u=Pt.safeParse(Z(String(i)));return u.success?u.data:null}).filter(Boolean);return{...t,metadata:n,customer:r,payment_method:e,taxBreakdown:o}}function Ct({payment_method:t,latest_charge:e,...r}){v(typeof t=="object","Payment method is missing from order"),v(typeof e=="object","Latest charge is missing from order");let n=Q.parse(r.metadata),o=Object.entries(n).filter(([a])=>a.startsWith("taxBreakdown")).map(([a,i])=>{let u=Pt.safeParse(Z(String(i)));return u.success?u.data:null}).filter(Boolean);return{...r,payment_method:t,latest_charge:e,taxBreakdown:o,metadata:n}}var Jt,xt,Q,Pt,vt=P(()=>{"use strict";F();et();Jt=c.object({category:c.string().optional(),order:c.coerce.number().optional(),slug:c.string(),variant:c.string().optional(),stock:c.coerce.number().optional().transform(t=>t===void 0?Number.POSITIVE_INFINITY:t),digitalAsset:c.string().optional(),preview:c.string().optional()});xt=t=>!t.deleted&&t.active,Q=c.object({shippingRateId:c.string().optional(),taxCalculationId:c.string().optional(),taxCalculationExp:c.string().optional(),taxId:c.string().optional(),couponCode:c.string().optional(),taxedAmount:c.string().optional(),"billingAddress.city":c.string().optional(),"billingAddress.country":c.string().optional(),"billingAddress.line1":c.string().optional(),"billingAddress.line2":c.string().optional(),"billingAddress.name":c.string().optional(),"billingAddress.postalCode":c.string().optional(),"billingAddress.state":c.string().optional(),netAmount:c.string().optional(),taxBreakdown0:c.string().optional(),taxBreakdown1:c.string().optional(),taxBreakdown2:c.string().optional(),taxBreakdown3:c.string().optional(),taxBreakdown4:c.string().optional(),taxBreakdown5:c.string().optional()}).and(c.record(c.string(),c.string())),Pt=c.object({taxType:c.string(),taxPercentage:c.string(),taxAmount:c.number()})});var R,Xt,Ht,N,d,St=P(()=>{"use strict";R={DEBUG:0,LOG:1,WARN:2,ERROR:3},Xt="LOG",Ht=process.env.LOG_LEVEL&&process.env.LOG_LEVEL in R?process.env.LOG_LEVEL:Xt,N=R[Ht],d={time(t){N>R.DEBUG||console.time(t)},timeEnd(t){N>R.DEBUG||console.timeEnd(t)},log(...t){N>R.LOG||console.log(...t)},dir(t,e){N>R.LOG||console.dir(t,e)},warn(...t){N>R.WARN||console.warn(...t)},error(...t){N>R.ERROR||console.error(...t)}}});var I,x,It=P(()=>{"use strict";I=t=>t.filter(Boolean),x={accountGetById:{tags:({accountId:t})=>I(["account",t&&`account-${t}`]),revalidate:()=>{}},cartGetById:{tags:({cartId:t})=>I(["cart",`cart-${t}`]),revalidate:()=>{}},createTaxCalculation:{tags:({cartId:t})=>I(["tax-calculations",`tax-calculations-${t}`]),revalidate:()=>{}},fileGetById:{tags:({fileId:t})=>I(["files",`file-${t}`]),revalidate:()=>{}},orderGetById:{tags:({orderId:t})=>I(["order",`order-${t}`]),revalidate:()=>{}},productBrowse:{tags:({category:t})=>I(["product",t&&`category-${t}`]),revalidate:()=>{}},productGetById:{tags:({productId:t})=>I(["product",`product-${t}`]),revalidate:()=>{}},productGetBySlug:{tags:({productSlug:t})=>I(["product",`product-${t}`]),revalidate:()=>{}},shippingBrowse:{tags:()=>I(["shipping"]),revalidate:()=>{}},shippingGetById:{tags:({shippingId:t})=>I(["shipping",`shipping-${t}`]),revalidate:()=>{}},taxDefaultGet:{tags:()=>I(["tax-settings"]),revalidate:()=>{}}}});import _t from"stripe";var Zt,f,nt=P(()=>{"use strict";H();Zt=(t,e)=>!t||!e?t:[...t,`prefix-${e}`,...t.map(r=>`${e}-${r}`)],f=({tags:t,revalidate:e,cache:r,tagPrefix:n,secretKey:o})=>{let a=o??h.StripeSecretKey;if(!a)throw new Error("Missing `secretKey` parameter and `STRIPE_SECRET_KEY` env variable.");let i=Zt(t,n);return new _t(a,{typescript:!0,apiVersion:"2025-08-27.basil",httpClient:_t.createFetchHttpClient(((g,s)=>fetch(g,{...s,cache:r??s?.cache,next:{tags:i??s?.next?.tags,revalidate:e??s?.next?.revalidate}}))),appInfo:{name:"Commerce SDK",version:"beta",url:"https://yournextstore.com",partner_id:"CONS-003378"}})}});var m,bt=P(()=>{"use strict";m=async()=>{let t={stripeAccount:void 0,storeId:void 0,secretKey:void 0,publishableKey:void 0};return await global?.__ynsFindStripeAccount?.()??t}});import{revalidateTag as A}from"next/cache";import b from"stripe";import{z as _}from"zod";function Et({productId:t,cartId:e}){return e?ot({cartId:e,productId:t,operation:"INCREASE",clearTaxCalculation:!0}):te({productId:t})}async function ot({productId:t,cartId:e,operation:r,clearTaxCalculation:n}){let[o,a]=await Promise.all([k(t),Tt(e)]);if(!o)throw new Error(`Product not found: ${t}`);if(!a)throw new Error(`Cart not found: ${e}`);if(o.metadata.stock<=0)throw Error(`Product ${t} is out of stock`);if(!h.StripeCurrency)throw new Error("Missing `STRIPE_CURRENCY` env variable");if(h.StripeCurrency.toLowerCase()!==o.default_price.currency.toLowerCase())throw new Error(`Product currency ${o.default_price.currency} does not match cart currency ${h.StripeCurrency}`);let i=a.cart.metadata??{},s=q(i[t])+(r==="INCREASE"?1:-1);s<=0?i[t]="":i[t]=s.toString();let C=ae(a)+(o.default_price.unit_amount??0);try{return await B({paymentIntentId:e,data:{metadata:i,amount:C||V},clearTaxCalculation:n})}catch(w){d.error(w)}finally{A(`cart-${e}`)}}async function E(t){let{stripeAccount:e,storeId:r,secretKey:n}=await m(),o=f({secretKey:n,tagPrefix:r,tags:x.cartGetById.tags({cartId:t}),cache:"force-cache"});try{let a=await o.paymentIntents.retrieve(t,{expand:["payment_method","customer"]},{stripeAccount:e});if(Bt.includes(a.status)){let i=at(a);if(!i)return null;let u=await st(i.metadata),{metadata:{shippingRateId:g}}=i,s=g&&await O(g);return{cart:i,lines:u.map(({product:C,quantity:w})=>C?{product:C,quantity:w}:null).filter(Boolean),shippingRate:s||null}}}catch(a){if(d.error(a),a instanceof b.errors.StripeError&&a.code==="resource_missing")return null;throw a}}async function te({productId:t}={}){let{stripeAccount:e,storeId:r,secretKey:n}=await m(),o=f({secretKey:n,tagPrefix:r,cache:"no-cache"});if(!h.StripeCurrency)throw new Error("Missing `STRIPE_CURRENCY` env variable");try{let a=t?await k(t):null;if(a&&a.metadata.stock<=0)throw Error(`Product ${t} is out of stock`);return await o.paymentIntents.create({currency:h.StripeCurrency,amount:a?.default_price.unit_amount||V,automatic_payment_methods:{enabled:!0},metadata:{...a&&{[a.id]:"1"}}},{stripeAccount:e})}catch(a){throw d.error(a),a}}async function Ze({cart:t,add:e}){if(!e)return t;let r=await k(e);if(!r)return d.warn(`Product not found: ${e}`),t;let o=(t?.lines.find(i=>i.product.id===e)?t.lines:[...t?.lines??[],{product:r,quantity:0}]).map(i=>i.product.id===e?{...i,quantity:i.quantity+1}:i),a=t?j(t)+(r.default_price.unit_amount??0):r.default_price.unit_amount??0;return{...t,cart:{...t?.cart,amount:a},lines:o}}async function tr({cartId:t,productId:e,quantity:r}){let[n,o]=await Promise.all([L(e),E(t)]);if(!n)throw new Error(`Product not found: ${e}`);if(!o)throw new Error(`Cart not found: ${t}`);if(h.StripeCurrency?.toLowerCase()!==n.default_price.currency.toLowerCase())throw new Error(`Product currency ${n.default_price.currency} does not match cart currency ${h.StripeCurrency}`);let a=o.cart.metadata??{};r<=0?a[e]="":a[e]=r.toString();let i=j(o)+(n.default_price.unit_amount??0);try{return await B({paymentIntentId:t,data:{metadata:a,amount:i||V}})}catch(u){d.error(u)}finally{A(`cart-${t}`)}}async function L(t){let{stripeAccount:e,storeId:r,secretKey:n}=await m(),o=f({secretKey:n,tagPrefix:r,tags:x.productGetById.tags({productId:t}),cache:"force-cache"});try{let a=await o.products.retrieve(t,{expand:["default_price"]},{stripeAccount:e});return Y(a)}catch(a){if(a instanceof b.errors.StripeError&&a.code==="resource_missing")return null;throw a}}async function At({slug:t}){let{stripeAccount:e,storeId:r,secretKey:n}=await m(),a=await f({secretKey:n,tagPrefix:r,tags:x.productGetBySlug.tags({productSlug:t}),cache:"force-cache"}).products.search({query:tt({active:!0,'metadata["slug"]':t}),expand:["data.default_price"]},{stripeAccount:e});if(a.data.length>1&&a.data.some(i=>!i.metadata.variant))throw new Error(`Multiple products found with the same slug (${t}) but no variant set.`);return await Promise.allSettled(a.data.map(i=>L(i.id))),U(K(W(a)))}async function it(t){let{stripeAccount:e,storeId:r,secretKey:n}=await m();if(t.filter?.category){let i=t.filter?.category,g=await f({secretKey:n,tagPrefix:r,tags:x.productBrowse.tags({category:i}),cache:"force-cache"}).products.search({limit:100,query:tt({active:!0,'metadata["category"]':i}),expand:["data.default_price"]},{stripeAccount:e});return U(rt(K(W(g)))).slice(t.offset||0,t.first)}let a=await f({secretKey:n,tagPrefix:r,tags:x.productBrowse.tags({}),cache:"force-cache"}).products.list({limit:100,active:!0,expand:["data.default_price"]},{stripeAccount:e});return U(rt(K(W(a))).filter(xt)).slice(t.offset||0,t.first)}async function er(){let{stripeAccount:t,storeId:e,secretKey:r}=await m(),o=await f({secretKey:r,tagPrefix:e,tags:x.shippingBrowse.tags(),cache:"force-cache"}).shippingRates.list({active:!0},{stripeAccount:t});return wt(o)}async function O(t){let{stripeAccount:e,storeId:r,secretKey:n}=await m(),o=f({secretKey:n,tagPrefix:r,tags:x.shippingGetById.tags({shippingId:t}),cache:"force-cache"});try{let a=await o.shippingRates.retrieve(t,{},{stripeAccount:e});return a}catch(a){if(d.error(a),a instanceof b.errors.StripeError&&a.code==="resource_missing")return null;throw a}}async function rr(){let e=(await it({first:100})).map(n=>n.metadata.category).filter(Boolean),r=new Set(e);return Array.from(r)}async function ar(t){let{stripeAccount:e,storeId:r,secretKey:n}=await m(),o=f({secretKey:n,tagPrefix:r,tags:x.fileGetById.tags({fileId:t}),cache:"force-cache"});try{return await o.fileLinks.create({file:t},{stripeAccount:e})}catch(a){if(d.error(a),a instanceof b.errors.StripeError&&a.code==="resource_missing")return null;throw a}}async function nr(){let{stripeAccount:t,storeId:e,secretKey:r}=await m(),n=f({secretKey:r,tagPrefix:e,tags:x.accountGetById.tags({}),cache:"force-cache"});try{let[o,a]=await yt(n.accounts.retrieve({expand:["settings.branding.logo"]},{stripeAccount:t})),i=a?.settings?.branding.logo??null;return!i||typeof i=="string"?{account:a,logo:null}:{account:a,logo:i}}catch(o){if(d.error(o),o instanceof b.errors.StripeError&&o.code==="resource_missing")return null;throw o}}async function ee(t){let{stripeAccount:e,storeId:r,secretKey:n}=await m(),o=f({secretKey:n,tagPrefix:r,tags:x.orderGetById.tags({orderId:t}),cache:"force-cache"});try{let a=await o.paymentIntents.retrieve(t,{expand:["payment_method","latest_charge","customer"]},{stripeAccount:e});return Ct(a)}catch(a){if(a instanceof b.errors.StripeError&&a.code==="resource_missing")return null;throw a}}async function or(t){let e=await ee(t);if(!e)return null;let r=$t(e.metadata),n=await Promise.all(r.map(async([i,u])=>({product:await k(i),quantity:u}))),{metadata:{shippingRateId:o}}=e,a=o&&await O(o);return{order:e,lines:n.map(({product:i,quantity:u})=>i?{product:i,quantity:u}:null).filter(Boolean),shippingRate:a||null}}async function st(t){let e=$t(t);return await Promise.all(e.map(async([n,o])=>({product:await k(n),quantity:o})))}function oe({oldCart:t,data:e,mergedMetadata:r,lines:n}){if(!process.env.ENABLE_STRIPE_TAX)return!1;let o=Date.now(),a=r.taxCalculationExp?Number.parseInt(r.taxCalculationExp,10)*1e3:null;if(!a||o>=a)return!0;let i=t.cart.metadata.netAmount||t.cart.amount,u=e.amount,g=ne.some(l=>!r[l]&&!t.cart.metadata[l]?!1:r[l]!==t.cart.metadata[l]),s=n.length!==t.lines.length||n.some(l=>{let S=t.lines.find($=>$.product.id===l.product?.id);return l.product?.default_price.unit_amount!==S?.product.default_price.unit_amount||l.quantity!==S?.quantity});return u&&i!==u||g||s}async function Gt(t){let{stripeAccount:e,storeId:r,secretKey:n}=await m(),o=f({secretKey:n,tagPrefix:r,tags:["customers",`customers-${t}`],cache:"force-cache"});try{let a=await o.customers.retrieve(t,{},{stripeAccount:e});return a.deleted?null:a}catch(a){if(d.error(a),a instanceof b.errors.StripeError&&a.code==="resource_missing")return null;throw a}}function se(t,e){return e.coupon.amount_off?Math.max(t-e.coupon.amount_off,0):e.coupon.percent_off?Math.floor(t*(1-e.coupon.percent_off/100)):t}async function sr({productId:t,cartId:e,operation:r,clearTaxCalculation:n}){let[o,a]=await Promise.all([L(t),E(e)]);if(!o)throw new Error(`Product not found: ${t}`);if(!a)throw new Error(`Cart not found: ${e}`);if(h.StripeCurrency?.toLowerCase()!==o.default_price.currency.toLowerCase())throw new Error(`Product currency ${o.default_price.currency} does not match cart currency ${h.StripeCurrency}`);let i=a.cart.metadata??{},s=q(i[t])+(r==="INCREASE"?1:-1);s<=0?i[t]="":i[t]=s.toString();let C=j(a)+(o.default_price.unit_amount??0);try{return await B({paymentIntentId:e,data:{metadata:i,amount:C||V},clearTaxCalculation:n})}catch(w){d.error(w)}finally{A(`cart-${e}`)}}async function dr({cartId:t,shippingRateId:e}){let r=await E(t);if(!r)throw new Error(`Cart not found: ${t}`);d.time(`cartSaveShipping ${t}`);let n=await O(e);if(d.timeEnd(`cartSaveShipping ${t}`),!n)throw new Error(`Shipping rate not found: ${e}`);try{d.time(`updatePaymentIntent ${t}`);let o=await B({paymentIntentId:t,data:{metadata:{...r.cart.metadata,shippingRateId:e},amount:j({...r,shippingRate:n})}});return d.timeEnd(`updatePaymentIntent ${t}`),o}catch(o){d.error(o)}finally{A(`cart-${t}`)}}async function pr({cartId:t,billingAddress:e}){if(!await E(t))throw new Error(`Cart not found: ${t}`);try{return await B({paymentIntentId:t,data:{metadata:{"billingAddress.name":e.name,"billingAddress.phone":e.phone,"billingAddress.city":e.city,"billingAddress.country":e.country,"billingAddress.line1":e.line1,"billingAddress.line2":e.line2??"","billingAddress.postalCode":e.postalCode,"billingAddress.state":e.state??"","billingAddress.email":e.email??""}}})}catch(n){d.error(n)}finally{A(`cart-${t}`)}}async function ue(){let{stripeAccount:t,storeId:e,secretKey:r}=await m();return await f({secretKey:r,tagPrefix:e,tags:["tax-settings"],cache:"force-cache"}).tax.settings.retrieve({},{stripeAccount:t})}function lr(t){return Object.entries(t??{}).filter(([e])=>e.startsWith("prod_")).map(([e,r])=>[e,q(r)]).filter(([,e])=>e&&Number.isFinite(e)&&e>0).length}async function mr(t){if(!G)return null;let{storeId:e}=await m();return await G`
|
|
2
2
|
select * from reviews
|
|
3
3
|
where product_id = ${t.productId} and store_id = ${e}
|
|
4
4
|
order by created_at desc
|
|
5
5
|
limit ${t.first??100}
|
|
6
6
|
offset ${t.offset??0}
|
|
7
|
-
`}async function
|
|
7
|
+
`}async function fr(t){if(!G)return null;let{storeId:e}=await m();return await G`
|
|
8
8
|
insert into reviews (store_id, product_id, author, email, content, rating, created_at, updated_at)
|
|
9
9
|
values (${e}, ${t.productId}, ${t.author}, ${t.email}, ${t.content}, ${t.rating}, now(), now())
|
|
10
|
-
`}var
|
|
10
|
+
`}var V,k,Bt,$t,re,Tt,ae,ne,ir,ie,Rt,B,j,ce,cr,ur,gr,ct=P(()=>{"use strict";ft();H();vt();St();It();nt();et();F();bt();V=1e3;k=async t=>{let{stripeAccount:e,storeId:r,secretKey:n}=await m(),o=f({secretKey:n,tagPrefix:r,tags:x.productGetById.tags({productId:t}),cache:"force-cache"});try{let a=await o.products.retrieve(t,{expand:["default_price"]},{stripeAccount:e});return Y(a)}catch(a){if(a instanceof b.errors.StripeError&&a.code==="resource_missing")return null;throw a}},Bt=["requires_action","requires_confirmation","requires_capture","requires_payment_method"],$t=t=>Object.entries(t??{}).filter(([e])=>e.startsWith("prod_")).map(([e,r])=>[e,q(r)]).filter(([,e])=>e&&Number.isFinite(e)&&e>0),re=async t=>{let{stripeAccount:e,storeId:r,secretKey:n}=await m(),o=f({secretKey:n,tagPrefix:r,tags:x.cartGetById.tags({cartId:t}),cache:"force-cache"});try{let a=await o.paymentIntents.retrieve(t,{expand:["payment_method"]},{stripeAccount:e}),i=typeof a.customer=="string"?await Gt(a.customer):null;if(Bt.includes(a.status))return at({...a,customer:i})}catch(a){if(d.error(a),a instanceof b.errors.StripeError&&a.code==="resource_missing")return null;throw a}};Tt=async t=>{let e=await re(t);if(!e)return null;let r=await st(e.metadata),{metadata:{shippingRateId:n}}=e,o=n&&await O(n);return{cart:e,lines:r.map(({product:a,quantity:i})=>a?{product:a,quantity:i}:null).filter(Boolean),shippingRate:o||null}},ae=t=>t?t.cart.metadata?.taxCalculationId?t.cart.amount:(t.shippingRate?.fixed_amount?.amount??0)+t.lines.reduce((e,{product:r,quantity:n})=>e+(r.default_price?.unit_amount??0)*n,0):0,ne=["billingAddress.country","billingAddress.postalCode","billingAddress.state","taxId","shippingRateId","couponCode"];ir=t=>_.object({name:_.string({message:t.nameRequired}).min(1,t.nameRequired),city:_.string({message:t.cityRequired}).min(1,t.cityRequired),country:_.string({message:t.countryRequired}).min(1,t.countryRequired),line1:_.string({message:t.line1Required}).min(1,t.line1Required),line2:_.string().optional().nullable().default(""),postalCode:_.string({message:t.postalCodeRequired}).min(1,t.postalCodeRequired),state:_.string().optional().nullable().default(""),phone:_.string().optional().nullable().default(""),taxId:_.string().optional().nullable().default(""),email:_.string().optional().nullable().default("")}),ie=async({lineItems:t,billingAddress:e,cartId:r,shippingRateId:n,taxId:o})=>{if(!process.env.ENABLE_STRIPE_TAX)return null;if(!h.StripeCurrency)throw new Error("Missing `STRIPE_CURRENCY` env variable");let{stripeAccount:a,storeId:i,secretKey:u}=await m(),g=f({secretKey:u,tagPrefix:i,tags:x.createTaxCalculation.tags({cartId:r}),cache:"force-cache"});if(!e?.country)return null;let s=n?await O(n):null,C=typeof s?.tax_code=="string"?s.tax_code:s?.tax_code?.id,w=await ue(),l=h.StripeCurrency==="usd"||h.StripeCurrency==="cad"?"exclusive":"inclusive",S=w.defaults.tax_behavior==="inferred_by_currency"?l:w.defaults.tax_behavior??l;w.defaults.tax_behavior||d.warn(`Tax behavior not set in Stripe settings. Inferring from currency ${h.StripeCurrency}: ${l}.`),d.time(`createTaxCalculation ${r}`);let $=await g.tax.calculations.create({expand:["line_items"],line_items:t.map(M=>({...M,tax_behavior:M.tax_behavior??S})),currency:h.StripeCurrency,shipping_cost:s?.active&&s?.fixed_amount?{amount:s.fixed_amount.amount,tax_behavior:s.tax_behavior==="inclusive"?"inclusive":s.tax_behavior==="exclusive"?"exclusive":S,tax_code:C??w.defaults.tax_code??void 0}:void 0,customer_details:{tax_ids:o?[{type:"eu_vat",value:o}]:void 0,address_source:"billing",address:{country:e.country,city:e?.city,line1:e?.line1,line2:e?.line2,postal_code:e?.postalCode,state:e?.state}}},{stripeAccount:a});return d.timeEnd(`createTaxCalculation ${r}`),console.log(JSON.stringify($).length),$},Rt={taxBreakdown0:"",taxBreakdown1:"",taxBreakdown2:"",taxBreakdown3:"",taxBreakdown4:"",taxBreakdown5:""};B=async({paymentIntentId:t,data:e,customerOverride:r,clearTaxCalculation:n})=>{let{stripeAccount:o,storeId:a,secretKey:i}=await m(),u=await Tt(t);v(u,`Cart not found: ${t}`);let g=e.amount?e.amount.toString():null,s=Q.parse({...u.cart.metadata,...e.metadata});d.time("getProductsFromMetadata");let C=await st(s);d.timeEnd("getProductsFromMetadata");let w=!n&&oe({oldCart:u,data:e,mergedMetadata:s,lines:C});console.log({shouldRecalculateTax:w});let l=w?await ie({cartId:t,taxId:s.taxId??null,shippingRateId:s.shippingRateId??null,billingAddress:{country:s["billingAddress.country"]??"",city:s["billingAddress.city"]??"",line1:s["billingAddress.line1"]??"",line2:s["billingAddress.line2"]??"",name:s["billingAddress.name"]??"",postalCode:s["billingAddress.postalCode"]??"",state:s["billingAddress.state"]??""},lineItems:C.map(({product:y,quantity:D})=>{if(y?.default_price.unit_amount)return{product:y.id,reference:[y.metadata.slug,y.metadata.variant].filter(Boolean).join("-"),quantity:D,amount:y.default_price.unit_amount*D,tax_behavior:y.default_price.tax_behavior==="exclusive"?"exclusive":y.default_price.tax_behavior==="inclusive"?"inclusive":void 0,tax_code:y.tax_code?typeof y.tax_code=="string"?y.tax_code:y.tax_code.id:void 0}}).filter(Boolean)}):null,S=r??(e.customer?await Gt(e.customer):u.cart.customer);console.log({customer:S});let $=f({secretKey:i,tagPrefix:a,cache:"no-cache"});d.time(`paymentIntents.update ${t}`);let M=l&&Object.fromEntries(l.tax_breakdown.map(y=>({taxType:y.tax_rate_details.tax_type,taxPercentage:y.tax_rate_details.percentage_decimal,taxAmount:y.amount})).map((y,D)=>[`taxBreakdown${D}`,JSON.stringify(y)])),T=l?l.amount_total:e.amount,X=T&&S?.discount?.coupon.valid?se(T,S.discount):T;console.log({"discount.coupon.amount_off":S?.discount?.coupon.amount_off,"discount.coupon.percent_off":S?.discount?.coupon.percent_off,discountedAmount:X,taxedAmount:T,"taxCalculation.amount_total":l?.amount_total,"data.amount":e.amount,netAmount:g});let Yt=await $.paymentIntents.update(t,{...e,...X&&{amount:X},metadata:{...s,...g&&{netAmount:g},...T&&{taxedAmount:T},...l?{...Rt,...M,taxCalculationId:l.id,taxCalculationExp:l?.expires_at}:{...n&&{...Rt,taxCalculationId:"",taxCalculationExp:""}}}},{stripeAccount:o});return d.timeEnd(`paymentIntents.update ${t}`),Yt},j=t=>t?t.cart.metadata?.taxCalculationId?t.cart.amount:(t.shippingRate?.fixed_amount?.amount??0)+ce(t):0,ce=t=>t?t.lines.reduce((e,{product:r,quantity:n})=>e+(r.default_price?.unit_amount??0)*n,0):0;cr=async({cartId:t,email:e})=>{let r=await E(t);if(!r)throw new Error(`Cart not found: ${t}`);try{return await B({paymentIntentId:t,data:{metadata:{...r.cart.metadata,email:e}}})}catch(n){d.error(n)}finally{A(`cart-${t}`)}},ur=async({cartId:t,taxId:e})=>{let r=await E(t);if(!r)throw new Error(`Cart not found: ${t}`);try{return await B({paymentIntentId:t,data:{metadata:{...r.cart.metadata,taxId:e}}})}catch(n){d.error(n)}finally{A(`cart-${t}`)}};gr=m});var Nt={};mt(Nt,{StripeProvider:()=>J,createStripeProvider:()=>pe});function pe(t){return new J(t)}var J,qt=P(()=>{"use strict";ct();J=class{constructor(e){this.config=e}mapStripeProduct(e){let r=e.default_price?.unit_amount||0,n=e.default_price?.currency||"usd";return{id:e.id,name:e.name,slug:e.metadata?.slug,summary:e.description,images:e.images||[],active:e.active,price:r/100,currency:n.toUpperCase(),stock:Number.parseInt(e.metadata?.stock||"0",10),stripeId:e.id,metadata:e.metadata||{}}}async productBrowse(e){let r=await it({first:e.first||10,...e}),n=r.data.map(o=>this.mapStripeProduct(o));return{data:n,meta:{count:r.totalCount||n.length,offset:e.offset||0,limit:e.first||10,hasMore:n.length===(e.first||10)}}}async productGet(e){if(e.fields&&console.warn("GraphQL field selection not supported for Stripe provider. Ignoring 'fields' parameter."),e.slug){let r=await At({slug:e.slug});return r?this.mapStripeProduct(r):null}if(e.id){let r=await L(e.id);return r?this.mapStripeProduct(r):null}throw new Error("Either slug or id is required for productGet")}async cartAdd(e){return{cartId:(await Et({productId:e.variantId,cartId:e.cartId}))?.id||e.cartId||""}}async cartUpdate(e){let r=e.quantity>0?"INCREASE":"DECREASE";return{cartId:(await ot({cartId:e.cartId,productId:e.variantId,operation:r}))?.id||e.cartId}}async cartClear(e){throw new Error("Cart clear not yet implemented for Stripe provider")}async cartGet(e){let r=await E(e.cartId);if(!r)return null;let n=r.lines.map(a=>({id:a.product?.id||"",productId:a.product?.id||"",variantId:a.product?.id,quantity:a.quantity,price:(a.product?.default_price?.unit_amount||0)/100})),o=n.reduce((a,i)=>a+i.price*i.quantity,0);return{id:r.cart.id,customerId:r.cart.customer,items:n,total:o,currency:r.cart.currency?.toUpperCase()||"USD",createdAt:new Date(r.cart.created*1e3).toISOString(),updatedAt:new Date().toISOString()}}}});function kt(t){return!t||t.length===0?dt:`
|
|
11
|
+
query ProductQuery($slug: String!) {
|
|
12
|
+
product(slug: $slug) {
|
|
13
|
+
${t.join(`
|
|
14
|
+
`)}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
`}function Mt(t){return!t||t.length===0?ut:`
|
|
18
|
+
query ProductsQuery(
|
|
19
|
+
$offset: Int
|
|
20
|
+
$limit: Int
|
|
21
|
+
$category: String
|
|
22
|
+
$query: String
|
|
23
|
+
$active: Boolean
|
|
24
|
+
$excludeBundles: Boolean
|
|
25
|
+
$orderBy: String
|
|
26
|
+
$orderDirection: String
|
|
27
|
+
) {
|
|
28
|
+
products(
|
|
29
|
+
offset: $offset
|
|
30
|
+
limit: $limit
|
|
31
|
+
category: $category
|
|
32
|
+
query: $query
|
|
33
|
+
active: $active
|
|
34
|
+
excludeBundles: $excludeBundles
|
|
35
|
+
orderBy: $orderBy
|
|
36
|
+
orderDirection: $orderDirection
|
|
37
|
+
) {
|
|
38
|
+
data {
|
|
39
|
+
${t.join(`
|
|
40
|
+
`)}
|
|
41
|
+
}
|
|
42
|
+
meta {
|
|
43
|
+
count
|
|
44
|
+
offset
|
|
45
|
+
limit
|
|
46
|
+
hasMore
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
`}var Lt,ut,dt,le,Ot,Dt=P(()=>{"use strict";Lt=`
|
|
51
|
+
fragment ProductFragment on Product {
|
|
52
|
+
id
|
|
53
|
+
name
|
|
54
|
+
slug
|
|
55
|
+
summary
|
|
56
|
+
images
|
|
57
|
+
active
|
|
58
|
+
type
|
|
59
|
+
createdAt
|
|
60
|
+
updatedAt
|
|
61
|
+
category {
|
|
62
|
+
id
|
|
63
|
+
name
|
|
64
|
+
slug
|
|
65
|
+
description
|
|
66
|
+
image
|
|
67
|
+
}
|
|
68
|
+
variants {
|
|
69
|
+
id
|
|
70
|
+
price
|
|
71
|
+
originalPrice
|
|
72
|
+
prePromotionPrice
|
|
73
|
+
stock
|
|
74
|
+
shippable
|
|
75
|
+
attributes
|
|
76
|
+
combinations {
|
|
77
|
+
id
|
|
78
|
+
variantValue {
|
|
79
|
+
id
|
|
80
|
+
value
|
|
81
|
+
colorValue
|
|
82
|
+
variantType {
|
|
83
|
+
id
|
|
84
|
+
label
|
|
85
|
+
type
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
collections {
|
|
91
|
+
id
|
|
92
|
+
name
|
|
93
|
+
slug
|
|
94
|
+
description
|
|
95
|
+
image
|
|
96
|
+
active
|
|
97
|
+
}
|
|
98
|
+
bundleProducts {
|
|
99
|
+
id
|
|
100
|
+
quantity
|
|
101
|
+
position
|
|
102
|
+
variant {
|
|
103
|
+
id
|
|
104
|
+
price
|
|
105
|
+
originalPrice
|
|
106
|
+
stock
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
bundleDiscountPercentage
|
|
110
|
+
}
|
|
111
|
+
`,ut=`
|
|
112
|
+
query ProductsQuery(
|
|
113
|
+
$offset: Int
|
|
114
|
+
$limit: Int
|
|
115
|
+
$category: String
|
|
116
|
+
$query: String
|
|
117
|
+
$active: Boolean
|
|
118
|
+
$excludeBundles: Boolean
|
|
119
|
+
$orderBy: String
|
|
120
|
+
$orderDirection: String
|
|
121
|
+
) {
|
|
122
|
+
products(
|
|
123
|
+
offset: $offset
|
|
124
|
+
limit: $limit
|
|
125
|
+
category: $category
|
|
126
|
+
query: $query
|
|
127
|
+
active: $active
|
|
128
|
+
excludeBundles: $excludeBundles
|
|
129
|
+
orderBy: $orderBy
|
|
130
|
+
orderDirection: $orderDirection
|
|
131
|
+
) {
|
|
132
|
+
data {
|
|
133
|
+
...ProductFragment
|
|
134
|
+
}
|
|
135
|
+
meta {
|
|
136
|
+
count
|
|
137
|
+
offset
|
|
138
|
+
limit
|
|
139
|
+
hasMore
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
${Lt}
|
|
144
|
+
`,dt=`
|
|
145
|
+
query ProductQuery($slug: String!) {
|
|
146
|
+
product(slug: $slug) {
|
|
147
|
+
...ProductFragment
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
${Lt}
|
|
151
|
+
`,le=`
|
|
152
|
+
fragment CartFragment on Cart {
|
|
153
|
+
id
|
|
154
|
+
customerId
|
|
155
|
+
storeId
|
|
156
|
+
shippingId
|
|
157
|
+
couponId
|
|
158
|
+
billingAddressId
|
|
159
|
+
shippingAddressId
|
|
160
|
+
stripePaymentIntentId
|
|
161
|
+
checkoutSessionId
|
|
162
|
+
addonData
|
|
163
|
+
createdAt
|
|
164
|
+
updatedAt
|
|
165
|
+
customer {
|
|
166
|
+
id
|
|
167
|
+
email
|
|
168
|
+
userId
|
|
169
|
+
user {
|
|
170
|
+
id
|
|
171
|
+
email
|
|
172
|
+
name
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
coupon {
|
|
176
|
+
code
|
|
177
|
+
type
|
|
178
|
+
value
|
|
179
|
+
startDate
|
|
180
|
+
endDate
|
|
181
|
+
}
|
|
182
|
+
lineItems {
|
|
183
|
+
id
|
|
184
|
+
cartId
|
|
185
|
+
productVariantId
|
|
186
|
+
subscriptionId
|
|
187
|
+
quantity
|
|
188
|
+
createdAt
|
|
189
|
+
updatedAt
|
|
190
|
+
productVariant {
|
|
191
|
+
id
|
|
192
|
+
price
|
|
193
|
+
originalPrice
|
|
194
|
+
stock
|
|
195
|
+
shippable
|
|
196
|
+
attributes
|
|
197
|
+
}
|
|
198
|
+
subscription {
|
|
199
|
+
id
|
|
200
|
+
name
|
|
201
|
+
price
|
|
202
|
+
interval
|
|
203
|
+
intervalCount
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
billingAddress {
|
|
207
|
+
id
|
|
208
|
+
name
|
|
209
|
+
company
|
|
210
|
+
line1
|
|
211
|
+
line2
|
|
212
|
+
city
|
|
213
|
+
state
|
|
214
|
+
postalCode
|
|
215
|
+
country
|
|
216
|
+
phone
|
|
217
|
+
type
|
|
218
|
+
}
|
|
219
|
+
shippingAddress {
|
|
220
|
+
id
|
|
221
|
+
name
|
|
222
|
+
company
|
|
223
|
+
line1
|
|
224
|
+
line2
|
|
225
|
+
city
|
|
226
|
+
state
|
|
227
|
+
postalCode
|
|
228
|
+
country
|
|
229
|
+
phone
|
|
230
|
+
type
|
|
231
|
+
}
|
|
232
|
+
shipping {
|
|
233
|
+
id
|
|
234
|
+
name
|
|
235
|
+
price
|
|
236
|
+
minValue
|
|
237
|
+
maxValue
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
`,Ot=`
|
|
241
|
+
query CartQuery($id: String!) {
|
|
242
|
+
cart(id: $id) {
|
|
243
|
+
...CartFragment
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
${le}
|
|
247
|
+
`});var Ft={};mt(Ft,{YnsProvider:()=>z,createYnsProvider:()=>me});function me(t){return new z(t)}var z,Ut=P(()=>{"use strict";Dt();z=class{config;constructor(e){this.config=e}async graphqlRequest(e,r){let n=await fetch(`${this.config.endpoint}/api/graphql`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.token}`},body:JSON.stringify({query:e,variables:r})});if(!n.ok)throw new Error(`YNS GraphQL request failed: ${n.status} ${n.statusText}`);let o=await n.json();if(o.errors)throw new Error(`YNS GraphQL errors: ${JSON.stringify(o.errors)}`);return o.data}async restRequest(e,r="GET",n){let o=await fetch(`${this.config.endpoint}/api${e}`,{method:r,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.token}`},body:n?JSON.stringify(n):void 0});if(!o.ok)throw new Error(`YNS REST request failed: ${o.status} ${o.statusText}`);return o.json()}mapYnsProduct(e){return{id:e.id,name:e.name,slug:e.slug,summary:e.summary,images:e.images||[],active:e.active,price:e.variants?.[0]?.price?Number.parseFloat(e.variants[0].price):0,currency:"USD",stock:e.variants?.[0]?.stock,category:e.category,variants:e.variants?.map(r=>({id:r.id,price:Number.parseFloat(r.price),stock:r.stock,attributes:r.attributes}))||[]}}mapYnsCart(e){let r=e.lineItems?.map(o=>({id:o.id,productId:o.productVariant?.id||"",variantId:o.productVariantId,quantity:o.quantity,price:Number.parseFloat(o.productVariant?.price||"0")}))||[],n=r.reduce((o,a)=>o+a.price*a.quantity,0);return{id:e.id,customerId:e.customerId,items:r,total:n,currency:"USD",createdAt:e.createdAt,updatedAt:e.updatedAt}}async productBrowse(e){let r=e.fields?Mt(e.fields):ut,n={offset:e.offset||0,limit:e.first||e.offset||10,category:e.category,query:e.query,active:e.active,excludeBundles:!1,orderBy:e.orderBy,orderDirection:e.orderDirection},o=await this.graphqlRequest(r,n);return{data:o.products.data.map(a=>this.mapYnsProduct(a)),meta:o.products.meta}}async productGet(e){if(!e.slug&&!e.id)throw new Error("Either slug or id is required for productGet");let r=e.fields?kt(e.fields):dt,n={slug:e.slug},o=await this.graphqlRequest(r,n);return o.product?this.mapYnsProduct(o.product):null}async cartAdd(e){let r={variantId:e.variantId,cartId:e.cartId,subscriptionId:e.subscriptionId};return await this.restRequest("/cart","POST",r)}async cartUpdate(e){let r={variantId:e.variantId,quantity:e.quantity};return await this.restRequest(`/cart/${e.cartId}`,"PUT",r)}async cartClear(e){return await this.restRequest(`/cart/${e.cartId}`,"DELETE")}async cartGet(e){let r=await this.graphqlRequest(Ot,{id:e.cartId});return r.cart?this.mapYnsCart(r.cart):null}}});ct();var pt=null,lt=new Map;function fe(t){pt=t,lt.clear()}function ge(){if(!pt)throw new Error("Commerce SDK not configured. Call Commerce.configure() with your provider settings first.");return pt}async function ye(t){let e=ge(),r=t||e.provider,n=lt.get(r);if(n)return n;let o;switch(r){case"stripe":{let{createStripeProvider:a}=await Promise.resolve().then(()=>(qt(),Nt));o=a(e.stripe||{});break}case"yns":{if(!e.yns)throw new Error("YNS provider configuration is required when using YNS provider");let{createYnsProvider:a}=await Promise.resolve().then(()=>(Ut(),Ft));o=a(e.yns);break}default:throw new Error(`Unsupported provider: ${r}`)}return lt.set(r,o),o}async function p(t){return ye(t?._provider)}F();var he=t=>(v(t.length===3,"currency needs to be a 3-letter code"),Pe[t.toUpperCase()]??2);var we=({amount:t,currency:e})=>{gt(t);let r=he(e),n=10**r;return Number.parseFloat((t/n).toFixed(r))},xe=({amount:t,currency:e,locale:r="en-US"})=>{let n=we({amount:t,currency:e});return new Intl.NumberFormat(r,{style:"currency",currency:e}).format(n)},Pe={BIF:0,CLP:0,DJF:0,GNF:0,JPY:0,KMF:0,KRW:0,MGA:0,PYG:0,RWF:0,UGX:0,VND:0,VUV:0,XAF:0,XOF:0,XPF:0,BHD:3,JOD:3,KWD:3,OMR:3,TND:3};var Ce={async add(t){return(await p(t)).cartAdd(t)},async update(t){return(await p(t)).cartUpdate(t)},async clear(t){return(await p(t)).cartClear(t)},async get(t){return(await p(t)).cartGet(t)}};var ve={async get(t){let e=await p(t);if(!e.orderGet)throw new Error("Order retrieval is not supported by the current provider");return e.orderGet(t)},async list(t={}){let e=await p(t);if(!e.orderList)throw new Error("Order listing is not supported by the current provider");return e.orderList(t)}};var Se={async browse(t={}){return(await p(t)).productBrowse(t)},async get(t){return(await p(t)).productGet(t)},async search(t){let e=await p(t);if(!e.productSearch)throw new Error("Product search is not supported by the current provider");return e.productSearch(t)}};nt();function Ie(t){return{product:{async browse(e){return(await p({_provider:t})).productBrowse({...e,_provider:t})},async get(e){return(await p({_provider:t})).productGet({...e,_provider:t})},async search(e){let r=await p({_provider:t});if(!r.productSearch)throw new Error(`Product search is not supported by ${t} provider`);return r.productSearch({...e,_provider:t})}},cart:{async add(e){return(await p({_provider:t})).cartAdd({...e,_provider:t})},async update(e){return(await p({_provider:t})).cartUpdate({...e,_provider:t})},async clear(e){return(await p({_provider:t})).cartClear({...e,_provider:t})},async get(e){return(await p({_provider:t})).cartGet({...e,_provider:t})}},order:{async get(e){let r=await p({_provider:t});if(!r.orderGet)throw new Error(`Order retrieval is not supported by ${t} provider`);return r.orderGet({...e,_provider:t})},async list(e={}){let r=await p({_provider:t});if(!r.orderList)throw new Error(`Order listing is not supported by ${t} provider`);return r.orderList({...e,_provider:t})}}}}export{nr as accountGet,ae as calculateCartTotalNet,ce as calculateCartTotalNetWithoutShipping,j as calculateCartTotalPossiblyWithTax,Ce as cart,Et as cartAdd,Ze as cartAddOptimistic,sr as cartChangeQuantity,lr as cartCount,te as cartCreate,E as cartGet,pr as cartSaveBillingAddress,cr as cartSaveEmail,dr as cartSaveShipping,ur as cartSaveTax,tr as cartSetQuantity,ot as cartUpdateQuantity,rr as categoryBrowse,fe as configure,gr as contextGet,ar as fileGet,xe as formatMoney,ir as getAddressSchema,Tt as getCartWithProductsById,$t as getProductsFromCart,st as getProductsFromMetadata,ve as order,or as orderGet,Se as product,it as productBrowse,At as productGet,L as productGetById,fr as productReviewAdd,mr as productReviewBrowse,f as provider,er as shippingBrowse,O as shippingGet,ue as taxDefaultGet,B as updatePaymentIntent,Ie as withProvider};
|