@personizely/shopify-hydrogen 1.0.0 → 1.0.2

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.
Files changed (73) hide show
  1. package/dist/index.cjs +399 -0
  2. package/dist/index.cjs.map +1 -0
  3. package/dist/index.d.cts +342 -0
  4. package/dist/index.d.cts.map +1 -0
  5. package/dist/index.d.mts +342 -0
  6. package/dist/index.d.mts.map +1 -0
  7. package/dist/index.d.ts +342 -10
  8. package/dist/index.mjs +277 -0
  9. package/dist/index.mjs.map +1 -0
  10. package/package.json +14 -4
  11. package/dist/classes/Adapter.d.ts +0 -33
  12. package/dist/classes/Adapter.d.ts.map +0 -1
  13. package/dist/classes/Adapter.js +0 -126
  14. package/dist/classes/Adapter.js.map +0 -1
  15. package/dist/classes/Cart.d.ts +0 -29
  16. package/dist/classes/Cart.d.ts.map +0 -1
  17. package/dist/classes/Cart.js +0 -272
  18. package/dist/classes/Cart.js.map +0 -1
  19. package/dist/components/PersonizelyProvider.d.ts +0 -36
  20. package/dist/components/PersonizelyProvider.d.ts.map +0 -1
  21. package/dist/components/PersonizelyProvider.js +0 -118
  22. package/dist/components/PersonizelyProvider.js.map +0 -1
  23. package/dist/graphql/queries/cart.d.ts +0 -7
  24. package/dist/graphql/queries/cart.d.ts.map +0 -1
  25. package/dist/graphql/queries/cart.js +0 -142
  26. package/dist/graphql/queries/cart.js.map +0 -1
  27. package/dist/graphql/queries/customer.d.ts +0 -5
  28. package/dist/graphql/queries/customer.d.ts.map +0 -1
  29. package/dist/graphql/queries/customer.js +0 -72
  30. package/dist/graphql/queries/customer.js.map +0 -1
  31. package/dist/graphql/queries/product.d.ts +0 -5
  32. package/dist/graphql/queries/product.d.ts.map +0 -1
  33. package/dist/graphql/queries/product.js +0 -114
  34. package/dist/graphql/queries/product.js.map +0 -1
  35. package/dist/hooks/useCartAdd.d.ts +0 -3
  36. package/dist/hooks/useCartAdd.d.ts.map +0 -1
  37. package/dist/hooks/useCartAdd.js +0 -18
  38. package/dist/hooks/useCartAdd.js.map +0 -1
  39. package/dist/hooks/useCheckout.d.ts +0 -2
  40. package/dist/hooks/useCheckout.d.ts.map +0 -1
  41. package/dist/hooks/useCheckout.js +0 -12
  42. package/dist/hooks/useCheckout.js.map +0 -1
  43. package/dist/hooks/usePageContext.d.ts +0 -3
  44. package/dist/hooks/usePageContext.d.ts.map +0 -1
  45. package/dist/hooks/usePageContext.js +0 -6
  46. package/dist/hooks/usePageContext.js.map +0 -1
  47. package/dist/hooks/usePersonizely.d.ts +0 -3
  48. package/dist/hooks/usePersonizely.d.ts.map +0 -1
  49. package/dist/hooks/usePersonizely.js +0 -11
  50. package/dist/hooks/usePersonizely.js.map +0 -1
  51. package/dist/index.d.ts.map +0 -1
  52. package/dist/index.js +0 -8
  53. package/dist/index.js.map +0 -1
  54. package/dist/types/index.d.ts +0 -170
  55. package/dist/types/index.d.ts.map +0 -1
  56. package/dist/types/index.js +0 -2
  57. package/dist/types/index.js.map +0 -1
  58. package/dist/types/interfaces.d.ts +0 -35
  59. package/dist/types/interfaces.d.ts.map +0 -1
  60. package/dist/types/interfaces.js +0 -2
  61. package/dist/types/interfaces.js.map +0 -1
  62. package/dist/utils/cookies.d.ts +0 -4
  63. package/dist/utils/cookies.d.ts.map +0 -1
  64. package/dist/utils/cookies.js +0 -33
  65. package/dist/utils/cookies.js.map +0 -1
  66. package/dist/utils/id.d.ts +0 -3
  67. package/dist/utils/id.d.ts.map +0 -1
  68. package/dist/utils/id.js +0 -7
  69. package/dist/utils/id.js.map +0 -1
  70. package/dist/utils/storefront-client.d.ts +0 -15
  71. package/dist/utils/storefront-client.d.ts.map +0 -1
  72. package/dist/utils/storefront-client.js +0 -39
  73. package/dist/utils/storefront-client.js.map +0 -1
package/dist/index.cjs ADDED
@@ -0,0 +1,399 @@
1
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`react`);c=s(c);let l=require(`react-router`);function u(e){if(typeof document>`u`)return null;let t=e+`=`,n=document.cookie.split(`;`);for(let e=0;e<n.length;e++){let r=n[e];for(;r.charAt(0)===` `;)r=r.substring(1,r.length);if(r.indexOf(t)===0)return r.substring(t.length,r.length)}return null}function d(e,t,n,r=`/`){if(typeof document>`u`)return;let i=``;if(n){let e=new Date;e.setTime(e.getTime()+n*24*60*60*1e3),i=`; expires=`+e.toUTCString()}document.cookie=e+`=`+t+i+`; path=`+r}const f=`
2
+ fragment CartFragment on Cart {
3
+ id
4
+ checkoutUrl
5
+ totalQuantity
6
+ cost {
7
+ subtotalAmount {
8
+ amount
9
+ currencyCode
10
+ }
11
+ totalAmount {
12
+ amount
13
+ currencyCode
14
+ }
15
+ totalTaxAmount {
16
+ amount
17
+ currencyCode
18
+ }
19
+ }
20
+ lines(first: 100) {
21
+ nodes {
22
+ id
23
+ quantity
24
+ cost {
25
+ totalAmount {
26
+ amount
27
+ currencyCode
28
+ }
29
+ amountPerQuantity {
30
+ amount
31
+ currencyCode
32
+ }
33
+ }
34
+ merchandise {
35
+ ... on ProductVariant {
36
+ id
37
+ title
38
+ price {
39
+ amount
40
+ currencyCode
41
+ }
42
+ image {
43
+ url
44
+ altText
45
+ }
46
+ selectedOptions {
47
+ name
48
+ value
49
+ }
50
+ product {
51
+ id
52
+ handle
53
+ title
54
+ featuredImage {
55
+ url
56
+ altText
57
+ }
58
+ tags
59
+ }
60
+ }
61
+ }
62
+ attributes {
63
+ key
64
+ value
65
+ }
66
+ }
67
+ }
68
+ discountCodes {
69
+ code
70
+ applicable
71
+ }
72
+ attributes {
73
+ key
74
+ value
75
+ }
76
+ }
77
+ `,p=`
78
+ query getCart($cartId: ID!) {
79
+ cart(id: $cartId) {
80
+ ...CartFragment
81
+ }
82
+ }
83
+ ${f}
84
+ `,m=`
85
+ mutation cartLinesAdd($cartId: ID!, $lines: [CartLineInput!]!) {
86
+ cartLinesAdd(cartId: $cartId, lines: $lines) {
87
+ cart {
88
+ ...CartFragment
89
+ }
90
+ userErrors {
91
+ field
92
+ message
93
+ }
94
+ }
95
+ }
96
+ ${f}
97
+ `,h=`
98
+ mutation cartLinesUpdate($cartId: ID!, $lines: [CartLineUpdateInput!]!) {
99
+ cartLinesUpdate(cartId: $cartId, lines: $lines) {
100
+ cart {
101
+ ...CartFragment
102
+ }
103
+ userErrors {
104
+ field
105
+ message
106
+ }
107
+ }
108
+ }
109
+ ${f}
110
+ `,g=`
111
+ mutation cartLinesRemove($cartId: ID!, $lineIds: [ID!]!) {
112
+ cartLinesRemove(cartId: $cartId, lineIds: $lineIds) {
113
+ cart {
114
+ ...CartFragment
115
+ }
116
+ userErrors {
117
+ field
118
+ message
119
+ }
120
+ }
121
+ }
122
+ ${f}
123
+ `,_=`
124
+ mutation cartDiscountCodesUpdate($cartId: ID!, $discountCodes: [String!]!) {
125
+ cartDiscountCodesUpdate(cartId: $cartId, discountCodes: $discountCodes) {
126
+ cart {
127
+ ...CartFragment
128
+ }
129
+ userErrors {
130
+ field
131
+ message
132
+ }
133
+ }
134
+ }
135
+ ${f}
136
+ `,v=`
137
+ mutation cartAttributesUpdate($cartId: ID!, $attributes: [AttributeInput!]!) {
138
+ cartAttributesUpdate(cartId: $cartId, attributes: $attributes) {
139
+ cart {
140
+ ...CartFragment
141
+ }
142
+ userErrors {
143
+ field
144
+ message
145
+ }
146
+ }
147
+ }
148
+ ${f}
149
+ `;function y(e,t){return`gid://shopify/${t}/${e}`}function b(e){return Number(e.split(`/`).pop())}const x=`_ply_coupon`;var S=class{constructor(e,t,n){this.listeners=[],this.cart=null,this.storefrontClient=t,this.cartPromise=e,this.revalidate=n}updateCartData(e){this.cart=e,this.cartPromise=null}notifyListeners(){this.cart&&this.listeners.forEach(e=>{try{this.cart&&e(this.toCartData(this.cart))}catch(e){console.error(`Cart listener error:`,e)}})}isSynced(){return!!this.cart}onChange(e){return this.listeners.push(e),()=>{let t=this.listeners.indexOf(e);t>-1&&this.listeners.splice(t,1)}}async fetch(e=!0){return this.cart&&!e?this.toCartData(this.cart):this.cartPromise?(this.cart=await this.cartPromise,this.toCartData(this.cart)):this.cart?this.toCartData(this.cart):null}async update(e,t){if(!this.cart)throw Error(`Cart not initialized`);let n=this.cart.lines.nodes.map(e=>e.id);try{let r;switch(e){case`add`:r=await this.storefrontClient.mutate(m,{cartId:this.cart.id,lines:[{merchandiseId:y(t.id,`ProductVariant`),quantity:t.quantity||1,attributes:t.properties?Object.entries(t.properties).map(([e,t])=>({key:e,value:String(t)})):void 0}]}),r?.cartLinesAdd?.cart&&(this.cart=r.cartLinesAdd.cart,this.notifyListeners());break;case`update`:case`change`:if(t.updates){let e=[],n=[];Object.entries(t.updates).forEach(([t,r])=>{let i=this.cart.lines.nodes.find(e=>b(e.merchandise.id)===Number(t));i?e.push({id:i.id,quantity:Number(r)}):Number(r)>0&&n.push({merchandiseId:y(Number(t),`ProductVariant`),quantity:Number(r)})});let r=[];if(e.length>0&&r.push(this.storefrontClient.mutate(h,{cartId:this.cart.id,lines:e})),n.length>0&&r.push(this.storefrontClient.mutate(m,{cartId:this.cart.id,lines:n})),r.length>0){let e=await Promise.all(r),t=e[e.length-1];(t?.cartLinesUpdate?.cart||t?.cartLinesAdd?.cart)&&(this.cart=t.cartLinesUpdate?.cart||t.cartLinesAdd?.cart,this.notifyListeners())}}else t.id&&(r=await this.storefrontClient.mutate(h,{cartId:this.cart.id,lines:[{id:`gid://shopify/CartLine/${t.id}`,quantity:t.quantity}]}),r?.cartLinesUpdate?.cart&&(this.cart=r.cartLinesUpdate.cart,this.notifyListeners()));t.attributes&&this.cart&&(r=await this.storefrontClient.mutate(v,{cartId:this.cart.id,attributes:Object.entries(t.attributes).map(([e,t])=>({key:e,value:String(t)}))}),r?.cartAttributesUpdate?.cart&&(this.cart=r.cartAttributesUpdate.cart,this.notifyListeners())),t.discount&&this.cart&&(r=await this.storefrontClient.mutate(_,{cartId:this.cart.id,discountCodes:[t.discount]}),r?.cartDiscountCodesUpdate?.cart&&(this.cart=r.cartDiscountCodesUpdate.cart,this.notifyListeners()));break;case`clear`:r=await this.storefrontClient.mutate(g,{cartId:this.cart.id,lineIds:n}),r?.cartLinesRemove?.cart&&(this.cart=r.cartLinesRemove.cart,this.notifyListeners());break;default:console.warn(`Unknown cart action: ${e}`)}this.revalidate&&this.revalidate()}catch(e){throw console.error(`Cart update error:`,e),e}}async buy(e,t=1){if(!this.cart)return;let n=this.getCoupon(),r=this.cart.checkoutUrl||`/checkout`,i=n?`${r}?discount=${n}`:r;typeof window<`u`&&(window.location.href=i)}get(e){return this.cart?e?this.toCartData(this.cart)[e]:this.toCartData(this.cart):e?void 0:null}getToken(){return this.cart&&this.cart.id||null}getItemsIds(){return this.cart?this.cart.lines.nodes.map(e=>e.merchandise.product.id):[]}getCurrency(){return this.cart?this.cart.cost.totalAmount.currencyCode:`USD`}getValue(e){return this.cart?parseFloat(this.cart.cost.totalAmount.amount)*100:0}getSize(e=!1){return this.cart?e?new Set(this.cart.lines.nodes.map(e=>e.merchandise.product.id)).size:this.cart.totalQuantity:0}async fetchCollections(e=!1){return console.warn(`fetchCollections: Not implemented for Hydrogen. Use custom metafield query.`),{}}async applyCoupon(e,t){if(!this.cart)throw Error(`Cart not initialized`);d(x,e,t);try{let t=await this.storefrontClient.mutate(_,{cartId:this.cart.id,discountCodes:[e]});t?.cartDiscountCodesUpdate?.cart&&(this.cart=t.cartDiscountCodesUpdate.cart,this.notifyListeners()),this.revalidate&&this.revalidate()}catch(e){throw console.error(`Error applying coupon:`,e),e}}getCoupon(){return this.cart?this.cart.discountCodes&&this.cart.discountCodes.length>0?this.cart.discountCodes[0].code:u(x):null}toCartData(e){return{token:e.id,item_count:e.totalQuantity||0,items:(e.lines?.nodes||[]).map(e=>({id:b(e.id),product_id:b(e.merchandise.product.id),variant_id:b(e.merchandise.id),price:Number(e.merchandise.price.amount)*100,quantity:e.quantity})),total_price:Number(e.cost.totalAmount.amount)*100,discount_codes:e.discountCodes,attributes:e.attributes,note:e.note}}};const C=`
150
+ fragment ProductFragment on Product {
151
+ id
152
+ handle
153
+ title
154
+ description
155
+ descriptionHtml
156
+ productType
157
+ vendor
158
+ tags
159
+ availableForSale
160
+ requiresSellingPlan
161
+ priceRange {
162
+ minVariantPrice {
163
+ amount
164
+ currencyCode
165
+ }
166
+ maxVariantPrice {
167
+ amount
168
+ currencyCode
169
+ }
170
+ }
171
+ featuredImage {
172
+ id
173
+ url
174
+ altText
175
+ width
176
+ height
177
+ }
178
+ images(first: 10) {
179
+ nodes {
180
+ id
181
+ url
182
+ altText
183
+ width
184
+ height
185
+ }
186
+ }
187
+ variants(first: 100) {
188
+ nodes {
189
+ id
190
+ title
191
+ availableForSale
192
+ quantityAvailable
193
+ sellingPlanAllocations(first: 10) {
194
+ edges {
195
+ node {
196
+ sellingPlan {
197
+ id
198
+ }
199
+ }
200
+ }
201
+ }
202
+ sku
203
+ price {
204
+ amount
205
+ currencyCode
206
+ }
207
+ compareAtPrice {
208
+ amount
209
+ currencyCode
210
+ }
211
+ selectedOptions {
212
+ name
213
+ value
214
+ }
215
+ image {
216
+ id
217
+ url
218
+ altText
219
+ width
220
+ height
221
+ }
222
+ }
223
+ }
224
+ options {
225
+ id
226
+ name
227
+ values
228
+ }
229
+ collections(first: 10) {
230
+ nodes {
231
+ id
232
+ handle
233
+ title
234
+ }
235
+ }
236
+ }
237
+ `,w=`
238
+ query getProductByHandle($handle: String!) {
239
+ product(handle: $handle) {
240
+ ...ProductFragment
241
+ }
242
+ }
243
+ ${C}
244
+ `,T=`
245
+ query getProductById($id: ID!) {
246
+ product(id: $id) {
247
+ ...ProductFragment
248
+ }
249
+ }
250
+ ${C}
251
+ `,E=`
252
+ query getProductRecommendations($productId: ID!) {
253
+ productRecommendations(productId: $productId) {
254
+ ...ProductFragment
255
+ }
256
+ }
257
+ ${C}
258
+ `,D=`
259
+ fragment CustomerFragment on Customer {
260
+ id
261
+ email
262
+ phone
263
+ firstName
264
+ lastName
265
+ displayName
266
+ defaultAddress {
267
+ id
268
+ address1
269
+ address2
270
+ city
271
+ province
272
+ country
273
+ zip
274
+ }
275
+ }
276
+ `,O=`
277
+ fragment OrderFragment on Order {
278
+ id
279
+ orderNumber
280
+ processedAt
281
+ financialStatus
282
+ fulfillmentStatus
283
+ totalPrice {
284
+ amount
285
+ currencyCode
286
+ }
287
+ lineItems(first: 100) {
288
+ nodes {
289
+ title
290
+ quantity
291
+ variant {
292
+ id
293
+ title
294
+ price {
295
+ amount
296
+ currencyCode
297
+ }
298
+ image {
299
+ url
300
+ altText
301
+ }
302
+ }
303
+ }
304
+ }
305
+ }
306
+ `,k=`
307
+ query getCustomer($customerAccessToken: String!) {
308
+ customer(customerAccessToken: $customerAccessToken) {
309
+ ...CustomerFragment
310
+ }
311
+ }
312
+
313
+ fragment CustomerFragment on Customer {
314
+ id
315
+ email
316
+ phone
317
+ firstName
318
+ lastName
319
+ displayName
320
+ defaultAddress {
321
+ id
322
+ address1
323
+ address2
324
+ city
325
+ province
326
+ country
327
+ zip
328
+ }
329
+ }
330
+
331
+ `,A=`
332
+ query getCustomerOrders($customerAccessToken: String!, $first: Int = 20) {
333
+ customer(customerAccessToken: $customerAccessToken) {
334
+ id
335
+ orders(first: $first, sortKey: PROCESSED_AT, reverse: true) {
336
+ nodes {
337
+ ...OrderFragment
338
+ }
339
+ }
340
+ }
341
+ }
342
+
343
+ fragment OrderFragment on Order {
344
+ id
345
+ orderNumber
346
+ processedAt
347
+ financialStatus
348
+ fulfillmentStatus
349
+ totalPrice {
350
+ amount
351
+ currencyCode
352
+ }
353
+ lineItems(first: 100) {
354
+ nodes {
355
+ title
356
+ quantity
357
+ variant {
358
+ id
359
+ title
360
+ price {
361
+ amount
362
+ currencyCode
363
+ }
364
+ image {
365
+ url
366
+ altText
367
+ }
368
+ }
369
+ }
370
+ }
371
+ }
372
+
373
+ `;var j=class{constructor(e,t){this.customerAccessToken=null,this.client=t,this.methods=e.methods,this.currency={active:`USD`,base:`USD`,rate:1,...e.currency},this.locale=e.locale||`en-US`,this.market=e.market||null,this.pageContext={pageType:void 0,product:null,collection:null}}setCustomerAccessToken(e){this.customerAccessToken=e}async fetchProduct(e){let t=await this.client.query(w,{handle:e});if(!t.product)throw Error(`Product not found: ${e}`);return this.toProductData(t.product)}async fetchProductCollections(e,t){let n;if(t?n=await this.client.query(T,{id:`gid://shopify/Product/${t}`}):e&&(n=await this.client.query(w,{handle:e})),!n||!n.product)throw Error(`Product not found: ${t}`);return n.product.collections.nodes.map(e=>b(e.id))}async fetchRecommendations(e,t){return{intent:t,products:(await this.client.query(E,{productId:`gid://shopify/Product/${e}`,intent:t})).productRecommendations.map(e=>this.toProductData(e))||[]}}buildProductPath(e){return typeof this.methods?.builtProductPath==`function`?this.methods.builtProductPath(e):`/products/${e.handle}`}convertToBaseCurrency(e){return this.currency.rate/e}convertFromBaseCurrency(e){return this.currency.rate*e}formatMoney(e,t=!0){return typeof this.methods?.formatMoney==`function`?this.methods.formatMoney(e,t):new Intl.NumberFormat(this.locale,{style:`currency`,currency:this.currency.active,maximumFractionDigits:t?void 0:0}).format(e/100)}async getCustomer(){if(!this.customerAccessToken)return null;try{return(await this.client.query(`
374
+ query getCustomer($customerAccessToken: String!) {
375
+ customer(customerAccessToken: $customerAccessToken) {
376
+ ...CustomerFragment
377
+ }
378
+ }
379
+
380
+ fragment CustomerFragment on Customer {
381
+ id
382
+ email
383
+ phone
384
+ firstName
385
+ lastName
386
+ displayName
387
+ defaultAddress {
388
+ id
389
+ address1
390
+ address2
391
+ city
392
+ province
393
+ country
394
+ zip
395
+ }
396
+ }
397
+
398
+ `,{customerAccessToken:this.customerAccessToken})).customer||null}catch(e){return console.error(`Error fetching customer:`,e),null}}getPageContext(){return this.pageContext}setPageContext(e){e.product&&(e.product.id=b(String(e.product.id))),e.collection&&(e.collection.id=b(String(e.collection.id))),this.pageContext=e}getVisitorId(){return null}getMarket(){return this.market}getCurrencyRate(){return this.currency.rate}toProductData(e){return{id:b(e.id),handle:e.handle,title:e.title,available:e.availableForSale,requires_selling_plan:e.requiresSellingPlan,images:e.images.nodes.map(e=>e.url),variants:e.variants.nodes.map(e=>({id:b(e.id),title:e.title,available:e.availableForSale,price:Math.round(parseFloat(e.price.amount)*100),compare_at_price:e.compareAtPrice?Math.round(parseFloat(e.compareAtPrice.amount)*100):null,featured_image:e.image?{src:e.image.url}:null,selling_plan_allocations:e.sellingPlanAllocations?.edges?.map(e=>({selling_plan_id:e.node.sellingPlan.id}))||[]}))}}},M=class{constructor(e){this.storefrontAccessToken=e.storefrontAccessToken,this.shopDomain=e.shopDomain,this.apiVersion=e.apiVersion||`2024-01`,this.endpoint=`https://${this.shopDomain}/api/${this.apiVersion}/graphql.json`}async query(e,t){try{let n=await fetch(this.endpoint,{method:`POST`,headers:{"Content-Type":`application/json`,"X-Shopify-Storefront-Access-Token":this.storefrontAccessToken},body:JSON.stringify({query:e,variables:t})});if(!n.ok)throw Error(`Storefront API request failed: ${n.statusText}`);let r=await n.json();if(r.errors)throw Error(`GraphQL errors: ${JSON.stringify(r.errors)}`);return r.data}catch(e){throw console.error(`Storefront API error:`,e),e}}async mutate(e,t){return this.query(e,t)}};const N=(0,c.createContext)(null);function P({websiteApiKey:e,storefrontAccessToken:t,shopDomain:n,locale:r,currency:i,market:a,apiVersion:o,scriptBaseUrl:s,methods:u,children:d,customerAccessToken:f}){let p=(0,l.useMatches)().find(e=>e.id===`root`)?.loaderData?.cart,m=(0,l.useRevalidator)(),h=(0,c.useMemo)(()=>new M({storefrontAccessToken:t,shopDomain:n,apiVersion:o}),[t,n,o]),g=(0,c.useMemo)(()=>{let e=new j({locale:r,currency:i,market:a,methods:u},h);return f&&e.setCustomerAccessToken(f),e},[]),_=(0,c.useMemo)(()=>new S(p,h,m.revalidate),[]),v=(0,c.useRef)(null);(0,c.useEffect)(()=>{p.then(e=>{e&&e!==v.current&&(_.updateCartData(e),_.notifyListeners(),v.current=e)})},[p,_]);let y=(0,c.useRef)([]),b=(0,c.useRef)([]);(0,c.useEffect)(()=>{if(typeof window>`u`)return;window.__PLY_HYDROGEN_CONFIG__={cart:_,adapter:g,onCartAdd:e=>(y.current.push(e),()=>{let t=y.current.indexOf(e);t>-1&&y.current.splice(t,1)}),onCheckout:e=>(b.current.push(e),()=>{let t=b.current.indexOf(e);t>-1&&b.current.splice(t,1)})};let t=document.createElement(`script`);return t.src=`${s||`https://static.personizely.net`}/${e}.js`,document.head.appendChild(t),()=>{delete window.__PLY_HYDROGEN_CONFIG__,t&&t.remove()}},[]);let x=(0,c.useMemo)(()=>({cart:_,adapter:g,websiteApiKey:e,triggerCartAdd:async e=>{let t=!1;for(let n of y.current)try{await n(e)&&(t=!0)}catch(e){console.error(`Cart add callback error:`,e)}return t},triggerCheckout:async()=>{let e=!1;for(let t of b.current)try{await t()&&(e=!0)}catch(e){console.error(`Checkout callback error:`,e)}return e}}),[_,g,e]);return c.default.createElement(N.Provider,{value:x},d)}function F(){let e=(0,c.useContext)(N);if(!e)throw Error(`usePersonizely must be used within a PersonizelyProvider. Make sure your component is wrapped with <PersonizelyProvider>.`);return e}function I(){let e=F();return(0,c.useCallback)(async t=>typeof window>`u`?!1:await e.triggerCartAdd({...t,id:b(String(t.id)),variantId:b(String(t.variantId)),price:Number(t.price)*100}),[e])}function L(){let e=F();return(0,c.useCallback)(async()=>typeof window>`u`?!1:await e.triggerCheckout(),[e])}function R(e){F().adapter.setPageContext(e)}exports.Adapter=j,exports.Cart=S,exports.PersonizelyProvider=P,exports.useCartAdd=I,exports.useCheckout=L,exports.usePageContext=R,exports.usePersonizely=F;
399
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["result: any","linesToUpdate: any[]","linesToAdd: any[]","line","mutations: Promise<any>[]"],"sources":["../src/utils/cookies.ts","../src/graphql/queries/cart.ts","../src/utils/id.ts","../src/classes/Cart.ts","../src/graphql/queries/product.ts","../src/graphql/queries/customer.ts","../src/classes/Adapter.ts","../src/utils/storefront-client.ts","../src/components/PersonizelyProvider.tsx","../src/hooks/usePersonizely.ts","../src/hooks/useCartAdd.ts","../src/hooks/useCheckout.ts","../src/hooks/usePageContext.ts"],"sourcesContent":["/**\n * Cookie utilities for browser storage\n * Mirrors cookie helpers from snippet-manager\n */\n\n/**\n * Read a cookie value by name\n * @param name - Cookie name\n * @returns Cookie value or null if not found\n */\nexport function readCookie (name: string): string | null {\n if (typeof document === 'undefined') {\n return null\n }\n\n const nameEQ = name + '='\n const cookies = document.cookie.split(';')\n\n for (let i = 0; i < cookies.length; i++) {\n let cookie = cookies[i]\n while (cookie.charAt(0) === ' ') {\n cookie = cookie.substring(1, cookie.length)\n }\n if (cookie.indexOf(nameEQ) === 0) {\n return cookie.substring(nameEQ.length, cookie.length)\n }\n }\n\n return null\n}\n\n/**\n * Create/update a cookie\n * @param name - Cookie name\n * @param value - Cookie value\n * @param days - Expiration in days (optional, default: session cookie)\n * @param path - Cookie path (default: '/')\n */\nexport function createCookie (name: string,\n value: string,\n days?: number,\n path: string = '/'): void {\n if (typeof document === 'undefined') {\n return\n }\n\n let expires = ''\n if (days) {\n const date = new Date()\n date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000))\n expires = '; expires=' + date.toUTCString()\n }\n\n document.cookie = name + '=' + value + expires + '; path=' + path\n}\n\n/**\n * Delete a cookie by name\n * @param name - Cookie name\n * @param path - Cookie path (default: '/')\n */\nexport function deleteCookie (name: string, path: string = '/'): void {\n createCookie(name, '', -1, path)\n}\n","/**\n * GraphQL queries and mutations for cart operations\n */\n\nexport const CART_FRAGMENT = `\n fragment CartFragment on Cart {\n id\n checkoutUrl\n totalQuantity\n cost {\n subtotalAmount {\n amount\n currencyCode\n }\n totalAmount {\n amount\n currencyCode\n }\n totalTaxAmount {\n amount\n currencyCode\n }\n }\n lines(first: 100) {\n nodes {\n id\n quantity\n cost {\n totalAmount {\n amount\n currencyCode\n }\n amountPerQuantity {\n amount\n currencyCode\n }\n }\n merchandise {\n ... on ProductVariant {\n id\n title\n price {\n amount\n currencyCode\n }\n image {\n url\n altText\n }\n selectedOptions {\n name\n value\n }\n product {\n id\n handle\n title\n featuredImage {\n url\n altText\n }\n tags\n }\n }\n }\n attributes {\n key\n value\n }\n }\n }\n discountCodes {\n code\n applicable\n }\n attributes {\n key\n value\n }\n }\n`\n\nexport const GET_CART = `\n query getCart($cartId: ID!) {\n cart(id: $cartId) {\n ...CartFragment\n }\n }\n ${CART_FRAGMENT}\n`\n\n/**\n * Cart mutations\n */\n\nexport const CART_LINES_ADD = `\n mutation cartLinesAdd($cartId: ID!, $lines: [CartLineInput!]!) {\n cartLinesAdd(cartId: $cartId, lines: $lines) {\n cart {\n ...CartFragment\n }\n userErrors {\n field\n message\n }\n }\n }\n ${CART_FRAGMENT}\n`\n\nexport const CART_LINES_UPDATE = `\n mutation cartLinesUpdate($cartId: ID!, $lines: [CartLineUpdateInput!]!) {\n cartLinesUpdate(cartId: $cartId, lines: $lines) {\n cart {\n ...CartFragment\n }\n userErrors {\n field\n message\n }\n }\n }\n ${CART_FRAGMENT}\n`\n\nexport const CART_LINES_REMOVE = `\n mutation cartLinesRemove($cartId: ID!, $lineIds: [ID!]!) {\n cartLinesRemove(cartId: $cartId, lineIds: $lineIds) {\n cart {\n ...CartFragment\n }\n userErrors {\n field\n message\n }\n }\n }\n ${CART_FRAGMENT}\n`\n\nexport const CART_DISCOUNT_CODES_UPDATE = `\n mutation cartDiscountCodesUpdate($cartId: ID!, $discountCodes: [String!]!) {\n cartDiscountCodesUpdate(cartId: $cartId, discountCodes: $discountCodes) {\n cart {\n ...CartFragment\n }\n userErrors {\n field\n message\n }\n }\n }\n ${CART_FRAGMENT}\n`\n\nexport const CART_ATTRIBUTES_UPDATE = `\n mutation cartAttributesUpdate($cartId: ID!, $attributes: [AttributeInput!]!) {\n cartAttributesUpdate(cartId: $cartId, attributes: $attributes) {\n cart {\n ...CartFragment\n }\n userErrors {\n field\n message\n }\n }\n }\n ${CART_FRAGMENT}\n`\n","export function toGId (id: number, type: string): string {\n return `gid://shopify/${type}/${id}`\n}\n\nexport function toId (id: string): number {\n return Number(id.split('/').pop())\n}","import type { CartData, ICart } from '../types'\nimport { createCookie, readCookie } from '../utils/cookies'\nimport type { CartReturn } from '@shopify/hydrogen'\nimport { StorefrontClient } from '../utils/storefront-client'\nimport {\n CART_LINES_ADD,\n CART_LINES_UPDATE,\n CART_LINES_REMOVE,\n CART_DISCOUNT_CODES_UPDATE,\n CART_ATTRIBUTES_UPDATE\n} from '../graphql/queries/cart'\nimport { toGId, toId } from '../utils/id'\n\nconst COUPON_COOKIE_NAME = '_ply_coupon'\n\nexport class Cart implements ICart {\n private storefrontClient: StorefrontClient\n\n private listeners: Array<(cart: CartData) => void> = []\n\n private cart: CartReturn | null = null\n\n private cartPromise: Promise<CartReturn> | null\n\n private revalidate?: () => void\n\n constructor (cartPromise: Promise<CartReturn>, storefrontClient: StorefrontClient, revalidate?: () => void) {\n this.storefrontClient = storefrontClient\n this.cartPromise = cartPromise\n this.revalidate = revalidate\n }\n\n /**\n * Update internal cart data\n * Called by Provider when cart data changes from loader\n */\n updateCartData (cart: CartReturn): void {\n this.cart = cart\n this.cartPromise = null\n }\n\n /**\n * Notify all listeners of cart change\n * Called by Provider when cart updates\n */\n notifyListeners (): void {\n if (!this.cart) return\n\n this.listeners.forEach((listener) => {\n try {\n if (this.cart) {\n listener(this.toCartData(this.cart))\n }\n } catch (error) {\n console.error('Cart listener error:', error)\n }\n })\n }\n\n /**\n * Check if cart data is loaded and synced\n */\n isSynced (): boolean {\n return !!this.cart\n }\n\n /**\n * Register a callback to be called when cart changes\n * Returns a function to unregister the callback\n */\n onChange (callback: (cart: CartData) => void): () => void {\n this.listeners.push(callback)\n\n // Return unsubscribe function\n return () => {\n const index = this.listeners.indexOf(callback)\n if (index > -1) {\n this.listeners.splice(index, 1)\n }\n }\n }\n\n /**\n * Fetch current cart data\n * Returns cached cart data from loader (always fresh from React Router)\n */\n async fetch (force: boolean = true): Promise<CartData | null> {\n if (this.cart && !force) {\n return this.toCartData(this.cart)\n }\n\n if (this.cartPromise) {\n this.cart = await this.cartPromise\n return this.toCartData(this.cart)\n }\n\n if (!this.cart) return null\n\n return this.toCartData(this.cart)\n }\n\n /**\n * Update cart via Storefront API mutations\n * Actions: 'add', 'update', 'change', 'clear'\n */\n async update (action: string, data: any): Promise<void> {\n if (!this.cart) {\n throw new Error('Cart not initialized')\n }\n\n const lineIds = this.cart.lines.nodes.map((line: any) => line.id)\n\n try {\n let result: any\n\n switch (action) {\n case 'add':\n result = await this.storefrontClient.mutate(CART_LINES_ADD, {\n cartId: this.cart.id,\n lines: [{\n merchandiseId: toGId(data.id, 'ProductVariant'),\n quantity: data.quantity || 1,\n attributes: data.properties\n ? Object.entries(data.properties).map(([key, value]) => ({\n key,\n value: String(value)\n }))\n : undefined\n }]\n })\n\n // Update local cart immediately with mutation response\n if (result?.cartLinesAdd?.cart) {\n this.cart = result.cartLinesAdd.cart\n this.notifyListeners()\n }\n break\n\n case 'update':\n case 'change':\n // Handle Cart AJAX API format: { updates: { [variantId]: quantity }, attributes: {...} }\n if (data.updates) {\n // Separate into lines to update vs lines to add\n const linesToUpdate: any[] = []\n const linesToAdd: any[] = []\n\n Object.entries(data.updates).forEach(([variantId, quantity]) => {\n const line = this.cart!.lines.nodes.find((line: any) =>\n toId(line.merchandise.id) === Number(variantId))\n\n if (line) {\n linesToUpdate.push({\n id: line.id,\n quantity: Number(quantity)\n })\n } else if (Number(quantity) > 0) {\n // Line doesn't exist and quantity > 0 - add it\n linesToAdd.push({\n merchandiseId: toGId(Number(variantId), 'ProductVariant'),\n quantity: Number(quantity)\n })\n }\n })\n\n // Execute mutations in parallel\n const mutations: Promise<any>[] = []\n\n if (linesToUpdate.length > 0) {\n mutations.push(this.storefrontClient.mutate(CART_LINES_UPDATE, {\n cartId: this.cart.id,\n lines: linesToUpdate\n }))\n }\n\n if (linesToAdd.length > 0) {\n mutations.push(this.storefrontClient.mutate(CART_LINES_ADD, {\n cartId: this.cart.id,\n lines: linesToAdd\n }))\n }\n\n if (mutations.length > 0) {\n const results = await Promise.all(mutations)\n // Use the last result's cart (both mutations return the updated cart)\n const lastResult = results[results.length - 1]\n if (lastResult?.cartLinesUpdate?.cart || lastResult?.cartLinesAdd?.cart) {\n this.cart = lastResult.cartLinesUpdate?.cart || lastResult.cartLinesAdd?.cart\n this.notifyListeners()\n }\n }\n } else if (data.id) {\n // Handle single line item update\n result = await this.storefrontClient.mutate(CART_LINES_UPDATE, {\n cartId: this.cart.id,\n lines: [{\n id: `gid://shopify/CartLine/${data.id}`,\n quantity: data.quantity\n }]\n })\n\n // Update local cart immediately with mutation response\n if (result?.cartLinesUpdate?.cart) {\n this.cart = result.cartLinesUpdate.cart\n this.notifyListeners()\n }\n }\n\n // Handle cart-level attributes update\n if (data.attributes && this.cart) {\n result = await this.storefrontClient.mutate(CART_ATTRIBUTES_UPDATE, {\n cartId: this.cart.id,\n attributes: Object.entries(data.attributes).map(([key, value]) => ({\n key,\n value: String(value)\n }))\n })\n\n // Update local cart immediately\n if (result?.cartAttributesUpdate?.cart) {\n this.cart = result.cartAttributesUpdate.cart\n this.notifyListeners()\n }\n }\n\n // Handle discount update\n if (data.discount && this.cart) {\n result = await this.storefrontClient.mutate(CART_DISCOUNT_CODES_UPDATE, {\n cartId: this.cart.id,\n discountCodes: [data.discount]\n })\n\n // Update local cart immediately\n if (result?.cartDiscountCodesUpdate?.cart) {\n this.cart = result.cartDiscountCodesUpdate.cart\n this.notifyListeners()\n }\n }\n break\n\n case 'clear':\n result = await this.storefrontClient.mutate(CART_LINES_REMOVE, {\n cartId: this.cart.id,\n lineIds\n })\n\n // Update local cart immediately with mutation response\n if (result?.cartLinesRemove?.cart) {\n this.cart = result.cartLinesRemove.cart\n this.notifyListeners()\n }\n break\n\n default:\n console.warn(`Unknown cart action: ${action}`)\n }\n\n // Trigger revalidation to fetch fresh cart data from loader\n if (this.revalidate) {\n this.revalidate()\n }\n } catch (error) {\n console.error('Cart update error:', error)\n throw error\n }\n }\n\n /**\n * Quick buy - redirect to checkout with variant\n */\n async buy (_variantId: string, _quantity: number = 1): Promise<void> {\n if (!this.cart) return\n\n const coupon = this.getCoupon()\n const baseUrl = this.cart.checkoutUrl || '/checkout'\n const url = coupon ? `${baseUrl}?discount=${coupon}` : baseUrl\n\n if (typeof window !== 'undefined') {\n window.location.href = url\n }\n }\n\n /**\n * Get cart data or specific property\n */\n get (property?: string): any {\n if (!this.cart) {\n return property ? undefined : null\n }\n\n if (!property) {\n return this.toCartData(this.cart)\n }\n\n return (this.toCartData(this.cart) as any)[property]\n }\n\n /**\n * Get cart token/ID\n */\n getToken (): string | null {\n if (!this.cart) return null\n\n return this.cart.id || null\n }\n\n /**\n * Get array of product IDs in cart\n */\n getItemsIds (): string[] {\n if (!this.cart) {\n return []\n }\n\n return this.cart.lines.nodes.map(line => line.merchandise.product.id)\n }\n\n /**\n * Get cart currency code\n */\n getCurrency (): string {\n if (!this.cart) return 'USD'\n\n return this.cart.cost.totalAmount.currencyCode\n }\n\n /**\n * Get cart total value\n * For Hydrogen, currency conversion would need to be handled separately\n */\n getValue (_currency?: string): number {\n if (!this.cart) return 0\n\n return parseFloat(this.cart.cost.totalAmount.amount) * 100\n }\n\n /**\n * Get cart item count\n * @param distinct - Count distinct products instead of total quantity\n */\n getSize (distinct: boolean = false): number {\n if (!this.cart) return 0\n\n if (distinct) {\n const uniqueProductIds = new Set(this.cart.lines.nodes.map(line => line.merchandise.product.id))\n return uniqueProductIds.size\n }\n\n return this.cart.totalQuantity\n }\n\n /**\n * Fetch cart collections data\n * Requires custom implementation or metafield query\n */\n async fetchCollections (_force: boolean = false): Promise<any> {\n console.warn('fetchCollections: Not implemented for Hydrogen. Use custom metafield query.')\n return {}\n }\n\n /**\n * Apply discount code to cart\n */\n async applyCoupon (code: string, expiresIn?: number): Promise<void> {\n if (!this.cart) {\n throw new Error('Cart not initialized')\n }\n\n // Store in cookie\n createCookie(COUPON_COOKIE_NAME, code, expiresIn)\n\n try {\n const result = await this.storefrontClient.mutate(CART_DISCOUNT_CODES_UPDATE, {\n cartId: this.cart.id,\n discountCodes: [code]\n })\n\n // Update local cart immediately with mutation response\n if (result?.cartDiscountCodesUpdate?.cart) {\n this.cart = result.cartDiscountCodesUpdate.cart\n this.notifyListeners()\n }\n\n // Trigger revalidation to fetch fresh cart data from loader (backup)\n if (this.revalidate) {\n this.revalidate()\n }\n } catch (error) {\n console.error('Error applying coupon:', error)\n throw error\n }\n }\n\n /**\n * Get currently applied coupon code\n */\n getCoupon (): string | null {\n if (!this.cart) return null\n\n // First check cart discount codes\n if (this.cart.discountCodes && this.cart.discountCodes.length > 0) {\n return this.cart.discountCodes[0].code\n }\n\n // Fall back to cookie\n return readCookie(COUPON_COOKIE_NAME)\n }\n\n /**\n * Convert Hydrogen cart to CartData format\n * For compatibility with snippet-manager\n */\n private toCartData (cart: CartReturn): CartData {\n return {\n token: cart.id,\n item_count: cart.totalQuantity || 0,\n items: (cart.lines?.nodes || []).map(line => ({\n id: toId(line.id),\n product_id: toId(line.merchandise.product.id),\n variant_id: toId(line.merchandise.id),\n price: Number(line.merchandise.price.amount) * 100,\n quantity: line.quantity\n })),\n total_price: Number(cart.cost.totalAmount.amount) * 100,\n discount_codes: cart.discountCodes,\n attributes: cart.attributes,\n note: cart.note\n }\n }\n}\n","/**\n * GraphQL queries for product operations\n */\n\nexport const PRODUCT_FRAGMENT = `\n fragment ProductFragment on Product {\n id\n handle\n title\n description\n descriptionHtml\n productType\n vendor\n tags\n availableForSale\n requiresSellingPlan\n priceRange {\n minVariantPrice {\n amount\n currencyCode\n }\n maxVariantPrice {\n amount\n currencyCode\n }\n }\n featuredImage {\n id\n url\n altText\n width\n height\n }\n images(first: 10) {\n nodes {\n id\n url\n altText\n width\n height\n }\n }\n variants(first: 100) {\n nodes {\n id\n title\n availableForSale\n quantityAvailable\n sellingPlanAllocations(first: 10) {\n edges {\n node {\n sellingPlan {\n id\n }\n }\n }\n }\n sku\n price {\n amount\n currencyCode\n }\n compareAtPrice {\n amount\n currencyCode\n }\n selectedOptions {\n name\n value\n }\n image {\n id\n url\n altText\n width\n height\n }\n }\n }\n options {\n id\n name\n values\n }\n collections(first: 10) {\n nodes {\n id\n handle\n title\n }\n }\n }\n`\n\nexport const GET_PRODUCT_BY_HANDLE = `\n query getProductByHandle($handle: String!) {\n product(handle: $handle) {\n ...ProductFragment\n }\n }\n ${PRODUCT_FRAGMENT}\n`\n\nexport const GET_PRODUCT_BY_ID = `\n query getProductById($id: ID!) {\n product(id: $id) {\n ...ProductFragment\n }\n }\n ${PRODUCT_FRAGMENT}\n`\n\nexport const GET_PRODUCT_RECOMMENDATIONS = `\n query getProductRecommendations($productId: ID!) {\n productRecommendations(productId: $productId) {\n ...ProductFragment\n }\n }\n ${PRODUCT_FRAGMENT}\n`\n","/**\n * GraphQL queries for customer operations\n */\n\nexport const CUSTOMER_FRAGMENT = `\n fragment CustomerFragment on Customer {\n id\n email\n phone\n firstName\n lastName\n displayName\n defaultAddress {\n id\n address1\n address2\n city\n province\n country\n zip\n }\n }\n`\n\nexport const ORDER_FRAGMENT = `\n fragment OrderFragment on Order {\n id\n orderNumber\n processedAt\n financialStatus\n fulfillmentStatus\n totalPrice {\n amount\n currencyCode\n }\n lineItems(first: 100) {\n nodes {\n title\n quantity\n variant {\n id\n title\n price {\n amount\n currencyCode\n }\n image {\n url\n altText\n }\n }\n }\n }\n }\n`\n\nexport const GET_CUSTOMER = `\n query getCustomer($customerAccessToken: String!) {\n customer(customerAccessToken: $customerAccessToken) {\n ...CustomerFragment\n }\n }\n ${CUSTOMER_FRAGMENT}\n`\n\nexport const GET_CUSTOMER_ORDERS = `\n query getCustomerOrders($customerAccessToken: String!, $first: Int = 20) {\n customer(customerAccessToken: $customerAccessToken) {\n id\n orders(first: $first, sortKey: PROCESSED_AT, reverse: true) {\n nodes {\n ...OrderFragment\n }\n }\n }\n }\n ${ORDER_FRAGMENT}\n`\n","import type {\n IShopifyAdapter,\n Product,\n Customer,\n PageContext,\n PersonizelyConfig,\n PersonizelyConfigMethods,\n ProductData\n} from '../types'\nimport { StorefrontClient } from '../utils/storefront-client'\nimport {\n GET_PRODUCT_BY_HANDLE, GET_PRODUCT_BY_ID,\n GET_PRODUCT_RECOMMENDATIONS\n} from '../graphql/queries/product'\nimport { GET_CUSTOMER } from '../graphql/queries/customer'\nimport { toId } from '../utils/id'\n\nexport class Adapter implements IShopifyAdapter {\n private client: StorefrontClient\n\n private currency: {\n active: string\n base: string\n rate: number\n }\n\n private market: string | null\n\n private locale: string\n\n private pageContext: PageContext\n\n private methods?: PersonizelyConfigMethods\n\n private customerAccessToken: string | null = null\n\n constructor (config: PersonizelyConfig, storefrontClient: StorefrontClient) {\n this.client = storefrontClient\n\n this.methods = config.methods\n this.currency = { active: 'USD', base: 'USD', rate: 1, ...config.currency }\n this.locale = config.locale || 'en-US'\n this.market = config.market || null\n\n this.pageContext = {\n pageType: undefined,\n product: null,\n collection: null\n }\n }\n\n /**\n * Set customer access token for authenticated requests\n */\n setCustomerAccessToken (token: string | null): void {\n this.customerAccessToken = token\n }\n\n /**\n * Fetch product by handle from Storefront API\n */\n async fetchProduct (handle: string): Promise<ProductData> {\n const data = await this.client.query<{ product: Product }>(GET_PRODUCT_BY_HANDLE, { handle })\n\n if (!data.product) {\n throw new Error(`Product not found: ${handle}`)\n }\n\n return this.toProductData(data.product)\n }\n\n /**\n * Fetch product collections metadata\n */\n async fetchProductCollections (handle: string, productId: number): Promise<number[]> {\n let data\n if (productId) {\n data = await this.client.query<{ product: Product }>(GET_PRODUCT_BY_ID, { id: `gid://shopify/Product/${productId}` })\n } else if (handle) {\n data = await this.client.query<{ product: Product }>(GET_PRODUCT_BY_HANDLE, { handle })\n }\n\n if (!data || !data.product) {\n throw new Error(`Product not found: ${productId}`)\n }\n\n return data.product.collections.nodes.map(c => toId(c.id))\n }\n\n /**\n * Fetch product recommendations\n */\n async fetchRecommendations (productId: number, intent: string): Promise<{ products: ProductData[], intent: string }> {\n const data = await this.client.query<{ productRecommendations: Product[] }>(GET_PRODUCT_RECOMMENDATIONS, { productId: `gid://shopify/Product/${productId}`, intent })\n\n return {\n intent,\n products: data.productRecommendations.map(p => this.toProductData(p)) || []\n }\n }\n\n /**\n * Build product URL path\n */\n buildProductPath (product: { handle: string }): string {\n if (typeof this.methods?.builtProductPath !== 'function') return `/products/${product.handle}`\n\n return this.methods.builtProductPath(product)\n }\n\n /**\n * Convert currency amount\n */\n convertToBaseCurrency (amount: number): number {\n return this.currency.rate / amount\n }\n\n /**\n * Convert currency amount\n */\n convertFromBaseCurrency (amount: number): number {\n return this.currency.rate * amount\n }\n\n /**\n * Format money according to shop's format\n */\n formatMoney (amount: number, includeDecimals: boolean = true): string {\n if (typeof this.methods?.formatMoney !== 'function') return new Intl.NumberFormat(this.locale, {\n style: 'currency',\n currency: this.currency.active,\n maximumFractionDigits: includeDecimals ? undefined : 0\n }).format(amount / 100)\n\n return this.methods.formatMoney(amount, includeDecimals)\n }\n\n /**\n * Fetch customer data from Storefront API\n * Requires customer access token to be set\n */\n async getCustomer (): Promise<Customer | null> {\n if (!this.customerAccessToken) {\n return null\n }\n\n try {\n const data = await this.client.query<{ customer: Customer }>(GET_CUSTOMER, { customerAccessToken: this.customerAccessToken })\n\n return data.customer || null\n } catch (error) {\n console.error('Error fetching customer:', error)\n return null\n }\n }\n\n /**\n * Get current page context\n * Auto-detected from Remix router in Provider\n */\n getPageContext (): PageContext {\n return this.pageContext\n }\n\n setPageContext (context: Partial<PageContext>) {\n if (context.product) {\n context.product.id = toId(String(context.product.id))\n }\n if (context.collection) {\n context.collection.id = toId(String(context.collection.id))\n }\n this.pageContext = context\n }\n\n getVisitorId (): string | null {\n return null\n }\n\n /**\n * Get current market information\n */\n getMarket (): string | null {\n return this.market\n }\n\n /**\n * Get currency conversion rate\n * Note: Stub implementation\n */\n getCurrencyRate (): number {\n return this.currency.rate\n }\n\n /**\n * Transform Hydrogen Product to snippet-manager ProductData format\n */\n toProductData (product: Product): ProductData {\n return {\n id: toId(product.id),\n handle: product.handle,\n title: product.title,\n available: product.availableForSale,\n requires_selling_plan: product.requiresSellingPlan,\n images: product.images.nodes.map(img => img.url),\n variants: product.variants.nodes.map(variant => ({\n id: toId(variant.id),\n title: variant.title,\n available: variant.availableForSale,\n price: Math.round(parseFloat(variant.price.amount) * 100), // Convert to cents\n compare_at_price: variant.compareAtPrice\n ? Math.round(parseFloat(variant.compareAtPrice.amount) * 100)\n : null,\n featured_image: variant.image ? { src: variant.image.url } : null,\n selling_plan_allocations: variant.sellingPlanAllocations?.edges?.map(edge => ({\n selling_plan_id: edge.node.sellingPlan.id\n })) || []\n }))\n }\n }\n}\n","/**\n * Shopify Storefront API GraphQL client\n */\n\nexport type StorefrontClientConfig = {\n storefrontAccessToken: string\n shopDomain: string\n apiVersion?: string\n}\n\nexport class StorefrontClient {\n private storefrontAccessToken: string\n\n private shopDomain: string\n\n private apiVersion: string\n\n private endpoint: string\n\n constructor (config: StorefrontClientConfig) {\n this.storefrontAccessToken = config.storefrontAccessToken\n this.shopDomain = config.shopDomain\n this.apiVersion = config.apiVersion || '2024-01'\n this.endpoint = `https://${this.shopDomain}/api/${this.apiVersion}/graphql.json`\n }\n\n /**\n * Execute a GraphQL query against the Storefront API\n */\n async query<T = any>(query: string, variables?: Record<string, any>): Promise<T> {\n try {\n const response = await fetch(this.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Shopify-Storefront-Access-Token': this.storefrontAccessToken\n },\n body: JSON.stringify({\n query,\n variables\n })\n })\n\n if (!response.ok) {\n throw new Error(`Storefront API request failed: ${response.statusText}`)\n }\n\n const result = await response.json()\n\n if (result.errors) {\n throw new Error(`GraphQL errors: ${JSON.stringify(result.errors)}`)\n }\n\n return result.data as T\n } catch (error) {\n console.error('Storefront API error:', error)\n throw error\n }\n }\n\n /**\n * Execute a GraphQL mutation against the Storefront API\n */\n async mutate<T = any>(mutation: string, variables?: Record<string, any>): Promise<T> {\n return this.query<T>(mutation, variables)\n }\n}\n","import React, { createContext, useEffect, useMemo, useRef, ReactNode } from 'react'\nimport { useMatches, useRevalidator } from 'react-router'\nimport {\n PersonizelyConfigMethods,\n HydrogenConfig,\n CartAddProduct\n} from '../types'\nimport type { CartReturn } from '@shopify/hydrogen'\nimport { Cart } from '../classes/Cart'\nimport { Adapter } from '../classes/Adapter'\nimport { StorefrontClient } from '../utils/storefront-client'\n\ndeclare global {\n interface Window {\n __PLY_HYDROGEN_CONFIG__?: HydrogenConfig\n }\n}\n\nexport type PersonizelyContextType = {\n cart: Cart\n adapter: Adapter\n websiteApiKey: string\n triggerCartAdd: (product: CartAddProduct) => Promise<boolean>\n triggerCheckout: () => Promise<boolean>\n}\n\nexport const PersonizelyContext = createContext<PersonizelyContextType | null>(null)\n\nexport type PersonizelyProviderProps = {\n websiteApiKey: string\n storefrontAccessToken: string\n shopDomain: string\n apiVersion?: string\n scriptBaseUrl?: string\n locale?: string\n currency?: {\n rate: number\n active: string\n base: string\n }\n market?: string\n methods?: PersonizelyConfigMethods\n children: ReactNode\n /**\n * Optional: Customer access token for authenticated requests\n */\n customerAccessToken?: string | null\n}\n\nexport function PersonizelyProvider ({\n websiteApiKey,\n storefrontAccessToken,\n shopDomain,\n locale,\n currency,\n market,\n apiVersion,\n scriptBaseUrl,\n methods,\n children,\n customerAccessToken\n}: PersonizelyProviderProps) {\n const matches = useMatches()\n const rootMatch = matches.find(m => m.id === 'root')\n const localCart = (rootMatch?.loaderData as any)?.cart as Promise<CartReturn>\n const revalidator = useRevalidator()\n\n const storefrontClient = useMemo(() => {\n return new StorefrontClient({\n storefrontAccessToken,\n shopDomain,\n apiVersion\n })\n }, [storefrontAccessToken, shopDomain, apiVersion])\n\n const adapter = useMemo(() => {\n const adapterInstance = new Adapter({\n locale,\n currency,\n market,\n methods\n }, storefrontClient)\n\n if (customerAccessToken) {\n adapterInstance.setCustomerAccessToken(customerAccessToken)\n }\n\n return adapterInstance\n }, [])\n\n const cart = useMemo(() => new Cart(localCart, storefrontClient, revalidator.revalidate), [])\n\n // Update cart data when it changes from the loader\n const prevCartDataRef = useRef<CartReturn | null>(null)\n useEffect(() => {\n localCart.then((data) => {\n if (data && data !== prevCartDataRef.current) {\n cart.updateCartData(data)\n cart.notifyListeners()\n prevCartDataRef.current = data\n }\n })\n }, [localCart, cart])\n\n const cartAddCallbacksRef = useRef<Array<(product: CartAddProduct) => Promise<boolean>>>([])\n const checkoutCallbacksRef = useRef<Array<() => Promise<boolean>>>([])\n\n // Set up window.__PLY_HYDROGEN_CONFIG__ and load Personizely script\n useEffect(() => {\n if (typeof window === 'undefined') {\n return\n }\n\n window.__PLY_HYDROGEN_CONFIG__ = {\n cart,\n adapter,\n onCartAdd: (callback) => {\n cartAddCallbacksRef.current.push(callback)\n\n return () => {\n const index = cartAddCallbacksRef.current.indexOf(callback)\n if (index > -1) {\n cartAddCallbacksRef.current.splice(index, 1)\n }\n }\n },\n onCheckout: (callback) => {\n checkoutCallbacksRef.current.push(callback)\n\n return () => {\n const index = checkoutCallbacksRef.current.indexOf(callback)\n if (index > -1) {\n checkoutCallbacksRef.current.splice(index, 1)\n }\n }\n }\n }\n\n const script = document.createElement('script')\n const baseUrl = scriptBaseUrl || 'https://static.personizely.net'\n script.src = `${baseUrl}/${websiteApiKey}.js`\n document.head.appendChild(script)\n\n return () => {\n delete window.__PLY_HYDROGEN_CONFIG__\n if (script) {\n script.remove()\n }\n }\n }, [])\n\n const contextValue = useMemo(() => ({\n cart,\n adapter,\n websiteApiKey,\n triggerCartAdd: async (product: CartAddProduct): Promise<boolean> => {\n let shown = false\n for (const callback of cartAddCallbacksRef.current) {\n try {\n const result = await callback(product)\n if (result) {\n shown = true\n }\n } catch (error) {\n console.error('Cart add callback error:', error)\n }\n }\n return shown\n },\n triggerCheckout: async (): Promise<boolean> => {\n let shown = false\n for (const callback of checkoutCallbacksRef.current) {\n try {\n const result = await callback()\n if (result) {\n shown = true\n }\n } catch (error) {\n console.error('Checkout callback error:', error)\n }\n }\n return shown\n }\n }), [cart, adapter, websiteApiKey])\n\n return (\n <PersonizelyContext.Provider value={contextValue}>\n {children}\n </PersonizelyContext.Provider>\n )\n}\n","/**\n * usePersonizely - Access Personizely context\n */\n\nimport { useContext } from 'react'\nimport { PersonizelyContext, PersonizelyContextType } from '../components/PersonizelyProvider'\n\n/**\n * Hook to access Personizely context\n * Provides access to cart, adapter, and configuration\n *\n * @returns PersonizelyContextType\n * @throws Error if used outside PersonizelyProvider\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { cart, adapter } = usePersonizely()\n * // Use cart and adapter...\n * }\n * ```\n */\nexport function usePersonizely (): PersonizelyContextType {\n const context = useContext(PersonizelyContext)\n\n if (!context) {\n throw new Error('usePersonizely must be used within a PersonizelyProvider. ' +\n 'Make sure your component is wrapped with <PersonizelyProvider>.')\n }\n\n return context\n}\n","/**\n * useCartAdd - Hook to trigger Personizely cart add widgets\n */\n\nimport { useCallback } from 'react'\nimport type { CartAddProduct } from '../types'\nimport { usePersonizely } from './usePersonizely'\nimport { toId } from '../utils/id'\n\n/**\n * Hook to trigger Personizely cart add event\n * Call this when a product is being added to cart to show relevant widgets\n *\n * @returns Function to trigger cart add event\n *\n * @example\n * ```tsx\n * function ProductForm({ product, selectedVariant }) {\n * const triggerCartAdd = useCartAdd()\n *\n * const handleAddToCart = async () => {\n * const widgetShown = await triggerCartAdd({\n * id: product.id,\n * variantId: selectedVariant.id,\n * price: parseFloat(selectedVariant.price.amount),\n * quantity: 1,\n * handle: product.handle\n * })\n *\n * if (!widgetShown) {\n * await cart.linesAdd([{\n * merchandiseId: selectedVariant.id,\n * quantity: 1\n * }])\n * }\n * }\n *\n * return <button onClick={handleAddToCart}>Add to Cart</button>\n * }\n * ```\n */\nexport function useCartAdd () {\n const personizely = usePersonizely()\n\n return useCallback(async (product: CartAddProduct): Promise<boolean> => {\n if (typeof window === 'undefined') {\n return false\n }\n\n return await personizely.triggerCartAdd({\n ...product,\n id: toId(String(product.id)),\n variantId: toId(String(product.variantId)),\n price: Number(product.price) * 100\n })\n }, [personizely])\n}\n","/**\n * useCheckout - Hook to trigger Personizely checkout widgets\n */\n\nimport { useCallback } from 'react'\nimport { usePersonizely } from './usePersonizely'\n\n/**\n * Hook to trigger Personizely checkout event\n * Call this when proceeding to checkout to show relevant widgets\n *\n * @returns Function to trigger checkout event\n *\n * @example\n * ```tsx\n * function CheckoutButton() {\n * const triggerCheckout = useCheckout()\n *\n * const handleCheckout = async () => {\n * const widgetShown = await triggerCheckout()\n *\n * if (!widgetShown) {\n * window.location.href = cart.checkoutUrl\n * }\n * }\n *\n * return <button onClick={handleCheckout}>Checkout</button>\n * }\n * ```\n */\nexport function useCheckout () {\n const personizely = usePersonizely()\n\n return useCallback(async (): Promise<boolean> => {\n if (typeof window === 'undefined') {\n return false\n }\n\n return await personizely.triggerCheckout()\n }, [personizely])\n}\n","import { usePersonizely } from './usePersonizely'\nimport { PageContext } from '../types'\n\nexport function usePageContext (context: Partial<PageContext>) {\n const personizely = usePersonizely()\n\n personizely.adapter.setPageContext(context)\n}\n"],"mappings":"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"}