@ikas/code-components-mcp 1.4.0-beta.23 → 1.4.0-beta.231

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 (94) hide show
  1. package/data/framework.json +191 -78
  2. package/data/migration.json +10 -4
  3. package/data/section-templates/account-info-section/children/AccountFavorites/ikas-config-snippet.json +13 -0
  4. package/data/section-templates/account-info-section/children/AccountOrders/index.tsx +1 -1
  5. package/data/section-templates/account-info-section/ikas-config-snippet.json +19 -0
  6. package/data/section-templates/add-to-cart/ikas-config-snippet.json +17 -0
  7. package/data/section-templates/add-to-cart/index.tsx +16 -2
  8. package/data/section-templates/add-to-cart/sub-components/QuantitySelector/index.tsx +11 -3
  9. package/data/section-templates/add-to-cart/utils/cartLimits.ts +24 -0
  10. package/data/section-templates/blog-home-section/ikas-config-snippet.json +2 -0
  11. package/data/section-templates/blog-home-section/index.tsx +2 -1
  12. package/data/section-templates/blog-post-section/ikas-config-snippet.json +2 -0
  13. package/data/section-templates/blog-post-section/index.tsx +3 -2
  14. package/data/section-templates/bundle-products/hooks/useBundleProducts.ts +7 -6
  15. package/data/section-templates/bundle-products/ikas-config-snippet.json +20 -0
  16. package/data/section-templates/cart-section/components/EmptyState/index.tsx +1 -1
  17. package/data/section-templates/cart-section/sub-components/CartItem/index.tsx +66 -24
  18. package/data/section-templates/cart-section/sub-components/CartItem/styles.css +14 -0
  19. package/data/section-templates/cart-section/sub-components/QuantitySelector/index.tsx +11 -3
  20. package/data/section-templates/cart-section/utils/cartLimits.ts +24 -0
  21. package/data/section-templates/cart-section/utils/cartLineLimits.ts +100 -0
  22. package/data/section-templates/category-images-section/children/CategoryImageItem/ikas-config-snippet.json +4 -0
  23. package/data/section-templates/category-images-section/ikas-config-snippet.json +15 -0
  24. package/data/section-templates/category-list-section/children/CardProductName/ikas-config-snippet.json +2 -1
  25. package/data/section-templates/category-list-section/ikas-config-snippet.json +21 -0
  26. package/data/section-templates/category-list-section/index.tsx +2 -1
  27. package/data/section-templates/component-renderer/additional/ProductDetail/index.tsx +5 -1
  28. package/data/section-templates/component-renderer/ikas-config-snippet.json +13 -0
  29. package/data/section-templates/favorites/ikas-config-snippet.json +18 -1
  30. package/data/section-templates/features-section/ikas-config-snippet.json +13 -0
  31. package/data/section-templates/footer-section/ikas-config-snippet.json +15 -0
  32. package/data/section-templates/forgot-password-section/components/ForgotPasswordForm/index.tsx +1 -1
  33. package/data/section-templates/header-section/children/Announcements/ikas-config-snippet.json +7 -0
  34. package/data/section-templates/header-section/children/CookieBar/ikas-config-snippet.json +3 -0
  35. package/data/section-templates/header-section/children/Navbar/components/CartSidebar/index.tsx +2 -1
  36. package/data/section-templates/header-section/children/Navbar/components/SearchModal/index.tsx +2 -1
  37. package/data/section-templates/header-section/children/Navbar/ikas-config-snippet.json +27 -0
  38. package/data/section-templates/header-section/children/Navbar/index.tsx +6 -5
  39. package/data/section-templates/header-section/ikas-config-snippet.json +13 -0
  40. package/data/section-templates/header-section/sub-components/CartItem/index.tsx +66 -24
  41. package/data/section-templates/header-section/sub-components/CartItem/styles.css +14 -0
  42. package/data/section-templates/header-section/sub-components/QuantitySelector/index.tsx +11 -3
  43. package/data/section-templates/header-section/utils/cartLimits.ts +24 -0
  44. package/data/section-templates/header-section/utils/cartLineLimits.ts +100 -0
  45. package/data/section-templates/hero-slider-section/children/HeroSliderItem/ikas-config-snippet.json +18 -0
  46. package/data/section-templates/hero-slider-section/children/HeroSliderItem/index.tsx +12 -7
  47. package/data/section-templates/hero-slider-section/ikas-config-snippet.json +13 -0
  48. package/data/section-templates/image-handling/ikas-config-snippet.json +53 -0
  49. package/data/section-templates/image-handling/index.tsx +5 -1
  50. package/data/section-templates/login-section/ikas-config-snippet.json +2 -0
  51. package/data/section-templates/navigation/components/CartSidebar/index.tsx +2 -1
  52. package/data/section-templates/navigation/components/SearchModal/index.tsx +2 -1
  53. package/data/section-templates/navigation/ikas-config-snippet.json +27 -0
  54. package/data/section-templates/navigation/index.tsx +6 -5
  55. package/data/section-templates/navigation/sub-components/CartItem/index.tsx +66 -24
  56. package/data/section-templates/navigation/sub-components/CartItem/styles.css +14 -0
  57. package/data/section-templates/navigation/sub-components/QuantitySelector/index.tsx +11 -3
  58. package/data/section-templates/navigation/utils/cartLimits.ts +24 -0
  59. package/data/section-templates/navigation/utils/cartLineLimits.ts +100 -0
  60. package/data/section-templates/product-detail-section/children/ProductDetailAddToCart/ikas-config-snippet.json +17 -0
  61. package/data/section-templates/product-detail-section/children/ProductDetailAddToCart/index.tsx +16 -2
  62. package/data/section-templates/product-detail-section/children/ProductDetailBackInStock/components/BackInStockForm/index.tsx +92 -0
  63. package/data/section-templates/product-detail-section/children/ProductDetailBackInStock/ikas-config-snippet.json +175 -0
  64. package/data/section-templates/product-detail-section/children/ProductDetailBackInStock/index.tsx +141 -0
  65. package/data/section-templates/product-detail-section/children/ProductDetailBackInStock/styles.css +47 -0
  66. package/data/section-templates/product-detail-section/children/ProductDetailBackInStock/types.ts +25 -0
  67. package/data/section-templates/product-detail-section/children/ProductDetailBundleFurniture/ikas-config-snippet.json +18 -0
  68. package/data/section-templates/product-detail-section/children/ProductDetailBundleProduct/ikas-config-snippet.json +20 -0
  69. package/data/section-templates/product-detail-section/children/ProductDetailDescription/ikas-config-snippet.json +27 -0
  70. package/data/section-templates/product-detail-section/children/ProductDetailFeatures/ikas-config-snippet.json +29 -0
  71. package/data/section-templates/product-detail-section/children/ProductDetailNameFavorite/ikas-config-snippet.json +18 -1
  72. package/data/section-templates/product-detail-section/children/ProductDetailOffer/ikas-config-snippet.json +20 -0
  73. package/data/section-templates/product-detail-section/children/ProductDetailOptionSet/ikas-config-snippet.json +16 -0
  74. package/data/section-templates/product-detail-section/children/ProductDetailPrices/ikas-config-snippet.json +16 -0
  75. package/data/section-templates/product-detail-section/children/ProductDetailProductGroup/ikas-config-snippet.json +16 -0
  76. package/data/section-templates/product-detail-section/children/ProductDetailSku/ikas-config-snippet.json +16 -0
  77. package/data/section-templates/product-detail-section/children/ProductDetailVariant/ikas-config-snippet.json +17 -0
  78. package/data/section-templates/product-detail-section/hooks/useBundleProducts.ts +7 -6
  79. package/data/section-templates/product-detail-section/ikas-config-snippet.json +53 -0
  80. package/data/section-templates/product-detail-section/index.tsx +5 -1
  81. package/data/section-templates/product-detail-section/sub-components/Modal/index.tsx +120 -0
  82. package/data/section-templates/product-detail-section/sub-components/Modal/styles.css +70 -0
  83. package/data/section-templates/product-detail-section/sub-components/QuantitySelector/index.tsx +11 -3
  84. package/data/section-templates/product-detail-section/utils/cartLimits.ts +24 -0
  85. package/data/section-templates/product-pricing/ikas-config-snippet.json +16 -0
  86. package/data/section-templates/product-slider-section/children/CardProductName/ikas-config-snippet.json +2 -1
  87. package/data/section-templates/product-slider-section/ikas-config-snippet.json +17 -0
  88. package/data/section-templates/register-section/ikas-config-snippet.json +2 -0
  89. package/data/section-templates/variant-selection/ikas-config-snippet.json +17 -0
  90. package/data/storefront-api.json +1046 -80
  91. package/data/storefront-types.json +9868 -6037
  92. package/dist/index.js +2578 -257
  93. package/dist/index.js.map +1 -1
  94. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  {
2
- "generatedAt": "2026-06-04T10:14:50.852Z",
2
+ "generatedAt": "2026-10-22T10:54:07.787Z",
3
3
  "functions": [
4
4
  {
5
5
  "name": "apiListProductBrand",
@@ -43,6 +43,20 @@
43
43
  "IkasStorefrontWidgetSettings"
44
44
  ]
45
45
  },
46
+ {
47
+ "name": "apiGetLoyaltyProgram",
48
+ "signature": "async function apiGetLoyaltyProgram(): Promise<APIResponse<IkasLoyaltyProgram>>",
49
+ "description": "",
50
+ "params": [],
51
+ "returnType": "Promise<APIResponse<IkasLoyaltyProgram>>",
52
+ "categories": [],
53
+ "related": [],
54
+ "isAsync": true,
55
+ "isClass": false,
56
+ "parameterTypes": [
57
+ "IkasLoyaltyProgram"
58
+ ]
59
+ },
46
60
  {
47
61
  "name": "apiListEarningMethods",
48
62
  "signature": "async function apiListEarningMethods(): Promise<APIResponse<IkasLoyaltyProgramEarningMethod[]>>",
@@ -167,7 +181,7 @@
167
181
  "name": "getAttributeDetailValues",
168
182
  "displayName": "getValues",
169
183
  "signature": "function getAttributeDetailValues(attributeDetail: IkasProductAttributeDetail): IkasProductAttributeValue[]",
170
- "description": "Retrieves the attribute values for a product attribute detail, merging variant and product-level attributes.",
184
+ "description": "Retrieves the attribute values for a product attribute detail, merging variant and product-level attributes.\nThis is how a PRODUCT_ATTRIBUTE code-component prop is consumed: that prop hands you the\nIkasProductAttributeDetail wrapper ({ product, attributePropValue }), never the attribute value itself, so\nreading `prop.value` silently yields nothing — call this function instead.",
171
185
  "params": [
172
186
  {
173
187
  "name": "attributeDetail",
@@ -195,7 +209,7 @@
195
209
  "name": "getAttributeListValues",
196
210
  "displayName": "getValues",
197
211
  "signature": "function getAttributeListValues(list: IkasProductAttributeList): IkasProductAttributeMap[]",
198
- "description": "Retrieves grouped attribute values for a product attribute list, combining variant and product-level attributes.",
212
+ "description": "Retrieves grouped attribute values for a product attribute list, combining variant and product-level attributes.\nThis is how a PRODUCT_ATTRIBUTE_LIST code-component prop is consumed: that prop hands you a single\nIkasProductAttributeList wrapper ({ product, attributeListPropValue }) — never an array — so mapping over the\nprop is a runtime error; call this function and iterate the returned { attribute, values } maps instead.",
199
213
  "params": [
200
214
  {
201
215
  "name": "list",
@@ -2761,16 +2775,16 @@
2761
2775
  {
2762
2776
  "name": "getDefaultSrc",
2763
2777
  "signature": "function getDefaultSrc(image: IkasImage): string",
2764
- "description": "Returns the default source URL for an image at 1080px resolution.",
2778
+ "description": "Returns the default source URL for an image OR video at 1080px resolution.\n\nProduct media items (IkasProductImage) can be videos. ALWAYS check `item.isVideo`\nand render a `<video src={getDefaultSrc(item)}>` instead of an `<img>` when it is true.\nNever assume every media item is an image.",
2765
2779
  "params": [
2766
2780
  {
2767
2781
  "name": "image",
2768
2782
  "description": "- The image object to generate the default source URL for."
2769
2783
  }
2770
2784
  ],
2771
- "returns": "The CDN URL string for the image at 1080px size.",
2785
+ "returns": "The CDN URL string for the image or video at 1080px size.",
2772
2786
  "returnType": "string",
2773
- "example": "```typescript\nimport { getDefaultSrc } from \"@ikas/bp-storefront\";\n\nconst src = getDefaultSrc(image);\nconsole.log(src); // \"https://cdn.example.com/images/.../1080/image.webp\"\n```",
2787
+ "example": "```typescript\nimport { getDefaultSrc, createMediaSrcset } from \"@ikas/bp-storefront\";\n\n// Product images can be videos — ALWAYS branch on isVideo when mapping media:\n{product.images.map((item, i) =>\n item.isVideo ? (\n <video key={i} src={getDefaultSrc(item)} muted playsInline preload=\"metadata\">\n <track kind=\"captions\" />\n </video>\n ) : (\n <img key={i} src={getDefaultSrc(item)} srcSet={createMediaSrcset(item)} alt={`Product ${i + 1}`} />\n )\n)}\n```",
2774
2788
  "categories": [
2775
2789
  "Image"
2776
2790
  ],
@@ -2788,16 +2802,16 @@
2788
2802
  {
2789
2803
  "name": "getThumbnailSrc",
2790
2804
  "signature": "function getThumbnailSrc(image: IkasImage): string",
2791
- "description": "Returns the thumbnail source URL for an image at 180px resolution.",
2805
+ "description": "Returns the thumbnail source URL for an IMAGE at 180px resolution.\n\nVIDEOS HAVE NO 180px THUMBNAIL and no poster URL. When `image.isVideo === true` the size is\nIGNORED and this returns the same full-size .mp4 as `getDefaultSrc(image)` — so using it in a\nthumbnail-sized box (swatch, cart line, order line) downloads the whole video instead of a\n180px webp. Nothing looks broken, which makes it a silent performance regression.\n\nBranch on `item.isVideo` first and only pass images here. For the video branch in a small,\nstatic context render `<video src={getDefaultSrc(item)} preload=\"metadata\" muted playsInline>`\nwith no `autoPlay`: the browser fetches only the first frame and holds it as a stand-in poster.",
2792
2806
  "params": [
2793
2807
  {
2794
2808
  "name": "image",
2795
- "description": "- The image object to generate the thumbnail source URL for."
2809
+ "description": "- The image object to generate the thumbnail source URL for. Videos ignore the size."
2796
2810
  }
2797
2811
  ],
2798
- "returns": "The CDN URL string for the image at 180px size.",
2812
+ "returns": "The CDN URL string: a 180px image, or — for `isVideo` items — the original .mp4.",
2799
2813
  "returnType": "string",
2800
- "example": "```typescript\nimport { getThumbnailSrc } from \"@ikas/bp-storefront\";\n\nconst thumbnailSrc = getThumbnailSrc(image);\nconsole.log(thumbnailSrc); // \"https://cdn.example.com/images/.../180/image.webp\"\n```",
2814
+ "example": "```typescript\nimport { getThumbnailSrc, getDefaultSrc } from \"@ikas/bp-storefront\";\n\n// Thumbnail rail — branch on isVideo per item (no autoPlay: first frame acts as the poster):\n{product.images.map((item, i) =>\n item.isVideo ? (\n <video key={i} src={getDefaultSrc(item)} muted playsInline preload=\"metadata\">\n <track kind=\"captions\" />\n </video>\n ) : (\n <img key={i} src={getThumbnailSrc(item)} sizes=\"112px\" alt={`Thumb ${i + 1}`} />\n )\n)}\n```",
2801
2815
  "categories": [
2802
2816
  "Image"
2803
2817
  ],
@@ -2815,7 +2829,7 @@
2815
2829
  {
2816
2830
  "name": "getSrc",
2817
2831
  "signature": "function getSrc(image: IkasImage, size: number): string",
2818
- "description": "Generates the full CDN source URL for an image or video at the specified size, handling both legacy path-based and merchant-scoped ID formats.",
2832
+ "description": "Generates the full CDN source URL for an image or video at the specified size, handling both legacy path-based and merchant-scoped ID formats.\n\nNOTE: For videos (`image.isVideo === true`) the `size` argument is IGNORED — the original .mp4 is always returned.\nSo `getSrc(item, 240)` and `getDefaultSrc(item)` produce the identical URL for a video. PREFER `getDefaultSrc(item)`\nfor video `src` (no size param) — do NOT pass an arbitrary size like `getSrc(item, 240)`, it is misleading.",
2819
2833
  "params": [
2820
2834
  {
2821
2835
  "name": "image",
@@ -2823,12 +2837,12 @@
2823
2837
  },
2824
2838
  {
2825
2839
  "name": "size",
2826
- "description": "- The desired image width in pixels for the generated URL."
2840
+ "description": "- The desired image width in pixels. Ignored for videos."
2827
2841
  }
2828
2842
  ],
2829
2843
  "returns": "The full CDN URL string for the image or video.",
2830
2844
  "returnType": "string",
2831
- "example": "```typescript\nimport { getSrc } from \"@ikas/bp-storefront\";\n\nconst src = getSrc(image, 640);\nconsole.log(src); // \"https://cdn.example.com/images/.../640/image.webp\"\n```",
2845
+ "example": "```typescript\nimport { getSrc, getDefaultSrc } from \"@ikas/bp-storefront\";\n\nconst src = getSrc(image, 640);\nconsole.log(src); // \"https://cdn.example.com/images/.../640/image.webp\"\n\n// For a video, use getDefaultSrc (size is ignored anyway):\n<video src={getDefaultSrc(item)} muted playsInline preload=\"metadata\" />\n```",
2832
2846
  "categories": [
2833
2847
  "Image"
2834
2848
  ],
@@ -2846,7 +2860,7 @@
2846
2860
  {
2847
2861
  "name": "createMediaSrcset",
2848
2862
  "signature": "function createMediaSrcset(image?: IkasImage | null): string",
2849
- "description": "Generates a complete responsive `srcset` string for an image across all standard sizes (180–3840px).",
2863
+ "description": "Generates a complete responsive `srcset` string for an image across all standard sizes (180–3840px).\n\nsrcset applies to `<img>` only — video media (`item.isVideo === true`) has no srcset\nand must be rendered with `<video src={getDefaultSrc(item)}>`. When mapping product\nimages, branch on `item.isVideo` first, then only use createMediaSrcset on the image branch.",
2850
2864
  "params": [
2851
2865
  {
2852
2866
  "name": "image",
@@ -2855,7 +2869,7 @@
2855
2869
  ],
2856
2870
  "returns": "A srcset string like `\"url 180w, url 360w, ...\"`, or an empty string if no image is provided.",
2857
2871
  "returnType": "string",
2858
- "example": "```typescript\nimport { createMediaSrcset, getDefaultSrc } from \"@ikas/bp-storefront\";\n\n<img\n src={getDefaultSrc(image)}\n srcSet={createMediaSrcset(image)}\n sizes=\"(max-width: 768px) 100vw, 50vw\"\n alt=\"Product\"\n/>\n```",
2872
+ "example": "```typescript\nimport { createMediaSrcset, getDefaultSrc } from \"@ikas/bp-storefront\";\n\n// Product images can be videos — ALWAYS branch on isVideo when mapping media:\n{product.images.map((item, i) =>\n item.isVideo ? (\n <video key={i} src={getDefaultSrc(item)} muted playsInline preload=\"metadata\">\n <track kind=\"captions\" />\n </video>\n ) : (\n <img\n key={i}\n src={getDefaultSrc(item)}\n srcSet={createMediaSrcset(item)}\n sizes=\"(max-width: 768px) 100vw, 50vw\"\n alt={`Product ${i + 1}`}\n />\n )\n)}\n```",
2859
2873
  "categories": [
2860
2874
  "Image"
2861
2875
  ],
@@ -3085,6 +3099,35 @@
3085
3099
  "IkasOrderGiftPackageLine"
3086
3100
  ]
3087
3101
  },
3102
+ {
3103
+ "name": "getIkasOrderGiftCardTotalPrice",
3104
+ "displayName": "getGiftCardTotalPrice",
3105
+ "signature": "function getIkasOrderGiftCardTotalPrice(order: IkasOrder): number",
3106
+ "description": "Returns the total amount covered by the gift cards (and store credits) applied to the order or cart.\n\nThis is a derived value, the API does not return it: it sums `amount` over `order.giftCardLines`.\nSubtract it from `order.totalFinalPrice` to get the amount still due.",
3107
+ "params": [
3108
+ {
3109
+ "name": "order",
3110
+ "description": "- The IkasOrder or IkasCart holding the gift card lines"
3111
+ }
3112
+ ],
3113
+ "returns": "The summed gift card amount, or 0 when no gift card is applied",
3114
+ "returnType": "number",
3115
+ "example": "```typescript\nimport { getIkasOrderGiftCardTotalPrice } from \"@ikas/bp-storefront\";\n\nconst giftCardTotal = getIkasOrderGiftCardTotalPrice(cart);\nconst remainingPrice = cart.totalFinalPrice - giftCardTotal;\n```",
3116
+ "categories": [
3117
+ "Order",
3118
+ "Cart"
3119
+ ],
3120
+ "related": [
3121
+ "removeGiftCardLine",
3122
+ "saveCouponCode"
3123
+ ],
3124
+ "isAsync": false,
3125
+ "isClass": false,
3126
+ "parameterTypes": [
3127
+ "IkasOrderGiftCardTotalPrice",
3128
+ "IkasOrder"
3129
+ ]
3130
+ },
3088
3131
  {
3089
3132
  "name": "getIkasOrderDistinctItemCount",
3090
3133
  "displayName": "getDistinctItemCount",
@@ -3177,14 +3220,14 @@
3177
3220
  "name": "getIkasOrderRefundableItems",
3178
3221
  "displayName": "getRefundableItems",
3179
3222
  "signature": "function getIkasOrderRefundableItems(order: IkasOrder): IkasOrderLineItem[]",
3180
- "description": "Returns order line items that are eligible for refund based on item status and the merchant's refund day limit settings.",
3223
+ "description": "Returns order line items that are eligible for refund, based on the refundable lines returned by the API for the order.",
3181
3224
  "params": [
3182
3225
  {
3183
3226
  "name": "order",
3184
3227
  "description": "- The IkasOrder to retrieve refundable items from"
3185
3228
  }
3186
3229
  ],
3187
- "returns": "An array of order line items eligible for refund, or an empty array if refunds are disabled",
3230
+ "returns": "An array of order line items eligible for refund, or an empty array if refundable lines are not loaded",
3188
3231
  "returnType": "IkasOrderLineItem[]",
3189
3232
  "example": "```typescript\nimport { getIkasOrderRefundableItems } from \"@ikas/bp-storefront\";\nconst refundableItems = getIkasOrderRefundableItems(order);\n```",
3190
3233
  "categories": [
@@ -3193,7 +3236,8 @@
3193
3236
  ],
3194
3237
  "related": [
3195
3238
  "isIkasOrderRefundable",
3196
- "getIkasOrderRefundedItems"
3239
+ "getIkasOrderRefundedItems",
3240
+ "getIkasOrderRefundReasons"
3197
3241
  ],
3198
3242
  "isAsync": false,
3199
3243
  "isClass": false,
@@ -3203,6 +3247,189 @@
3203
3247
  "IkasOrderLineItem"
3204
3248
  ]
3205
3249
  },
3250
+ {
3251
+ "name": "getIkasOrderRefundReasonId",
3252
+ "displayName": "getRefundReasonId",
3253
+ "signature": "function getIkasOrderRefundReasonId(order: IkasOrder): string | null",
3254
+ "description": "Returns the selected refund reason id for the order's refund request.",
3255
+ "params": [
3256
+ {
3257
+ "name": "order",
3258
+ "description": "- The IkasOrder to read the selected refund reason id from"
3259
+ }
3260
+ ],
3261
+ "returns": "The selected refund reason id, or null if none is selected",
3262
+ "returnType": "string | null",
3263
+ "example": "```typescript\nimport { getIkasOrderRefundReasonId } from \"@ikas/bp-storefront\";\nconst refundReasonId = getIkasOrderRefundReasonId(order);\n```",
3264
+ "categories": [
3265
+ "Order",
3266
+ "Payment"
3267
+ ],
3268
+ "related": [
3269
+ "setIkasOrderRefundReasonId",
3270
+ "getIkasOrderRefundReasons"
3271
+ ],
3272
+ "isAsync": false,
3273
+ "isClass": false,
3274
+ "parameterTypes": [
3275
+ "IkasOrderRefundReasonId",
3276
+ "IkasOrder"
3277
+ ]
3278
+ },
3279
+ {
3280
+ "name": "setIkasOrderRefundReasonId",
3281
+ "displayName": "setRefundReasonId",
3282
+ "signature": "function setIkasOrderRefundReasonId(order: IkasOrder, value: string | null): void",
3283
+ "description": "Sets the selected refund reason id that will be sent with the order's refund request.",
3284
+ "params": [
3285
+ {
3286
+ "name": "order",
3287
+ "description": "- The IkasOrder to set the refund reason id on"
3288
+ },
3289
+ {
3290
+ "name": "value",
3291
+ "description": "- The id of one of the reasons returned by getIkasOrderRefundReasons, or null to clear it"
3292
+ }
3293
+ ],
3294
+ "returnType": "void",
3295
+ "example": "```typescript\nimport { setIkasOrderRefundReasonId, getIkasOrderRefundReasons } from \"@ikas/bp-storefront\";\nconst [firstReason] = getIkasOrderRefundReasons(order);\nsetIkasOrderRefundReasonId(order, firstReason?.id || null);\n```",
3296
+ "categories": [
3297
+ "Order",
3298
+ "Payment"
3299
+ ],
3300
+ "related": [
3301
+ "getIkasOrderRefundReasonId",
3302
+ "getIkasOrderRefundReasons",
3303
+ "refundOrder"
3304
+ ],
3305
+ "isAsync": false,
3306
+ "isClass": false,
3307
+ "parameterTypes": [
3308
+ "IkasOrderRefundReasonId",
3309
+ "IkasOrder"
3310
+ ]
3311
+ },
3312
+ {
3313
+ "name": "getIkasOrderRefundReason",
3314
+ "displayName": "getRefundReason",
3315
+ "signature": "function getIkasOrderRefundReason(order: IkasOrder): string | null",
3316
+ "description": "Returns the free-text refund reason written by the customer for the order's refund request.",
3317
+ "params": [
3318
+ {
3319
+ "name": "order",
3320
+ "description": "- The IkasOrder to read the refund reason note from"
3321
+ }
3322
+ ],
3323
+ "returns": "The refund reason note, or null if none is set",
3324
+ "returnType": "string | null",
3325
+ "example": "```typescript\nimport { getIkasOrderRefundReason } from \"@ikas/bp-storefront\";\nconst reason = getIkasOrderRefundReason(order);\n```",
3326
+ "categories": [
3327
+ "Order",
3328
+ "Payment"
3329
+ ],
3330
+ "related": [
3331
+ "setIkasOrderRefundReason",
3332
+ "getIkasOrderRefundReasonId"
3333
+ ],
3334
+ "isAsync": false,
3335
+ "isClass": false,
3336
+ "parameterTypes": [
3337
+ "IkasOrderRefundReason",
3338
+ "IkasOrder"
3339
+ ]
3340
+ },
3341
+ {
3342
+ "name": "setIkasOrderRefundReason",
3343
+ "displayName": "setRefundReason",
3344
+ "signature": "function setIkasOrderRefundReason(order: IkasOrder, value: string | null): void",
3345
+ "description": "Sets the free-text refund reason that will be sent with the order's refund request.",
3346
+ "params": [
3347
+ {
3348
+ "name": "order",
3349
+ "description": "- The IkasOrder to set the refund reason note on"
3350
+ },
3351
+ {
3352
+ "name": "value",
3353
+ "description": "- The refund reason note, or null to clear it"
3354
+ }
3355
+ ],
3356
+ "returnType": "void",
3357
+ "example": "```typescript\nimport { setIkasOrderRefundReason } from \"@ikas/bp-storefront\";\nsetIkasOrderRefundReason(order, \"The product arrived damaged\");\n```",
3358
+ "categories": [
3359
+ "Order",
3360
+ "Payment"
3361
+ ],
3362
+ "related": [
3363
+ "getIkasOrderRefundReason",
3364
+ "setIkasOrderRefundReasonId",
3365
+ "refundOrder"
3366
+ ],
3367
+ "isAsync": false,
3368
+ "isClass": false,
3369
+ "parameterTypes": [
3370
+ "IkasOrderRefundReason",
3371
+ "IkasOrder"
3372
+ ]
3373
+ },
3374
+ {
3375
+ "name": "getIkasOrderRefundReasons",
3376
+ "displayName": "getRefundReasons",
3377
+ "signature": "function getIkasOrderRefundReasons(order: IkasOrder): IkasOrderRefundReason[]",
3378
+ "description": "Returns the refund reasons the customer can choose from, with titles translated to the current locale.",
3379
+ "params": [
3380
+ {
3381
+ "name": "order",
3382
+ "description": "- The IkasOrder to get refund reasons for"
3383
+ }
3384
+ ],
3385
+ "returns": "An array of refund reasons with localized titles, or an empty array if refundable lines are not loaded",
3386
+ "returnType": "IkasOrderRefundReason[]",
3387
+ "example": "```typescript\nimport { getIkasOrderRefundReasons } from \"@ikas/bp-storefront\";\nconst reasons = getIkasOrderRefundReasons(order);\nreasons.forEach(reason => console.log(reason.id, reason.title));\n```",
3388
+ "categories": [
3389
+ "Order",
3390
+ "Payment"
3391
+ ],
3392
+ "related": [
3393
+ "setIkasOrderRefundReasonId",
3394
+ "getIkasOrderRefundableItems"
3395
+ ],
3396
+ "isAsync": false,
3397
+ "isClass": false,
3398
+ "parameterTypes": [
3399
+ "IkasOrderRefundReasons",
3400
+ "IkasOrder",
3401
+ "IkasOrderRefundReason"
3402
+ ]
3403
+ },
3404
+ {
3405
+ "name": "getIkasOrderReturnMethodDescription",
3406
+ "displayName": "getReturnMethodDescription",
3407
+ "signature": "function getIkasOrderReturnMethodDescription(order: IkasOrder): string | null",
3408
+ "description": "Returns the merchant's return method description for the current locale.",
3409
+ "params": [
3410
+ {
3411
+ "name": "order",
3412
+ "description": "- The IkasOrder to get the return method description for"
3413
+ }
3414
+ ],
3415
+ "returns": "The return method description for the current locale, or null if none exists",
3416
+ "returnType": "string | null",
3417
+ "example": "```typescript\nimport { getIkasOrderReturnMethodDescription } from \"@ikas/bp-storefront\";\nconst description = getIkasOrderReturnMethodDescription(order);\n```",
3418
+ "categories": [
3419
+ "Order",
3420
+ "Payment"
3421
+ ],
3422
+ "related": [
3423
+ "getIkasOrderRefundReasons",
3424
+ "getIkasOrderRefundableItems"
3425
+ ],
3426
+ "isAsync": false,
3427
+ "isClass": false,
3428
+ "parameterTypes": [
3429
+ "IkasOrderReturnMethodDescription",
3430
+ "IkasOrder"
3431
+ ]
3432
+ },
3206
3433
  {
3207
3434
  "name": "isIkasOrderRefundable",
3208
3435
  "displayName": "isRefundable",
@@ -4628,7 +4855,7 @@
4628
4855
  "name": "getIkasProductAttrributeProductIds",
4629
4856
  "displayName": "getProductIds",
4630
4857
  "signature": "function getIkasProductAttrributeProductIds(value: IkasProductAttributeValue): string[]",
4631
- "description": "Extracts and returns the product IDs from a PRODUCT-type attribute value's JSON string.",
4858
+ "description": "Extracts and returns the product IDs from a PRODUCT-type attribute value's JSON string.\nNOTE: the export name really is misspelled — \"Attrribute\" with a double r. It is kept as-is because\nrenaming a published export would break every theme that imports it, so import it VERBATIM; the\ncorrectly spelled `getIkasProductAttributeProductIds` does not exist and will not compile. This is\nnot a documentation typo to report or \"fix\". In the blueprint editor the display alias is\n`getProductIds`, which hides the misspelling; only direct TypeScript imports see it.",
4632
4859
  "params": [
4633
4860
  {
4634
4861
  "name": "value",
@@ -5696,6 +5923,34 @@
5696
5923
  "IkasProductStockLocations"
5697
5924
  ]
5698
5925
  },
5926
+ {
5927
+ "name": "updateProductPrices",
5928
+ "displayName": "updatePrices",
5929
+ "signature": "async function updateProductPrices(product: IkasProduct): Promise<void>",
5930
+ "description": "Re-fetch the latest variant prices of a product and apply them in place.\nUseful when the page is served from cache but prices change frequently (e.g. gold prices),\ncall it once the product is mounted on the browser.",
5931
+ "params": [
5932
+ {
5933
+ "name": "product",
5934
+ "description": "- The product to refresh prices for (modified in place)"
5935
+ }
5936
+ ],
5937
+ "returns": "void",
5938
+ "returnType": "Promise<void>",
5939
+ "example": "```typescript\nimport { updateProductPrices } from \"@ikas/bp-storefront\";\n\nuseEffect(() => {\n updateProductPrices(product);\n}, [product]);\n```",
5940
+ "categories": [
5941
+ "Product",
5942
+ "Pricing"
5943
+ ],
5944
+ "related": [
5945
+ "updateProductListPrices",
5946
+ "getProductVariantFormattedFinalPrice"
5947
+ ],
5948
+ "isAsync": true,
5949
+ "isClass": false,
5950
+ "parameterTypes": [
5951
+ "IkasProduct"
5952
+ ]
5953
+ },
5699
5954
  {
5700
5955
  "name": "getProductOptionSet",
5701
5956
  "signature": "async function getProductOptionSet(product: IkasProduct): Promise<boolean>",
@@ -7310,16 +7565,16 @@
7310
7565
  "name": "getProductVariantMainImage",
7311
7566
  "displayName": "getMainImage",
7312
7567
  "signature": "function getProductVariantMainImage(variant: IkasProductVariant): IkasProductImage | undefined",
7313
- "description": "Get the main/primary image for a product variant.",
7568
+ "description": "Get the main/primary media item for a product variant.\n\nThe returned IkasProductImage may be a video (`isVideo === true`) — branch on it\nand render `<video>` instead of `<img>`.",
7314
7569
  "params": [
7315
7570
  {
7316
7571
  "name": "variant",
7317
7572
  "description": "- The product variant"
7318
7573
  }
7319
7574
  ],
7320
- "returns": "The first IkasProductImage of the variant, or undefined if no images. Access `.image` to get the IkasImage for CDN helpers.",
7575
+ "returns": "The first IkasProductImage of the variant, or undefined if no images. Check `.isVideo` to decide between `<video>` and `<img>`, and access `.image` to get the IkasImage for CDN helpers.",
7321
7576
  "returnType": "IkasProductImage | undefined",
7322
- "example": "```typescript\nimport { getProductVariantMainImage, getSelectedProductVariant, getDefaultSrc } from \"@ikas/bp-storefront\";\nimport { IkasProduct } from \"@ikas/bp-storefront\";\n\nfunction ProductImage({ product }: { product: IkasProduct }) {\n const variant = getSelectedProductVariant(product);\n const productImage = getProductVariantMainImage(variant);\n const image = productImage?.image;\n\n if (!image) {\n return <div className=\"no-image\">No image available</div>;\n }\n\n return <img src={getDefaultSrc(image)} alt={product.name} />;\n}\n```",
7577
+ "example": "```typescript\nimport { getProductVariantMainImage, getSelectedProductVariant, getDefaultSrc, createMediaSrcset } from \"@ikas/bp-storefront\";\nimport { IkasProduct } from \"@ikas/bp-storefront\";\n\nfunction ProductImage({ product }: { product: IkasProduct }) {\n const variant = getSelectedProductVariant(product);\n const productImage = getProductVariantMainImage(variant);\n const image = productImage?.image;\n\n if (!image) {\n return <div className=\"no-image\">No image available</div>;\n }\n\n // Media can be a video — branch on isVideo:\n return productImage.isVideo ? (\n <video src={getDefaultSrc(image)} muted playsInline loop>\n <track kind=\"captions\" />\n </video>\n ) : (\n <img src={getDefaultSrc(image)} srcSet={createMediaSrcset(image)} alt={product.name} />\n );\n}\n```",
7323
7578
  "categories": [
7324
7579
  "ProductDetail",
7325
7580
  "ProductList"
@@ -7597,14 +7852,14 @@
7597
7852
  "name": "getProductVariantAppliedCampaignAmount",
7598
7853
  "displayName": "getAppliedCampaignAmount",
7599
7854
  "signature": "function getProductVariantAppliedCampaignAmount(variant: IkasProductVariant): IkasAppliedCampaignAmount | null",
7600
- "description": "Get the applied campaign discount amount details for a product variant, including type and formatted value.",
7855
+ "description": "Get the applied campaign discount amount details for a product variant, including type and formatted value.\n\nHow the discount value is interpreted depends on `campaign.type`:\n- `\"FIXED_AMOUNT\"` → the value is an absolute money amount, returned in `formattedPrice` (e.g. \"$10.00\"); `discountPercentage` stays null.\n- `\"RATIO\"` → the value is a percentage, returned in `discountPercentage` (e.g. \"10\" for 10% off); `formattedPrice` stays null.\n\nBoth fixed and tiered campaigns are supported. For a tiered-discount campaign\n(`campaign.fixedDiscount` is null and the discount lives in `campaign.tieredDiscount.rules`),\nthe first tier's amount (`campaign.tieredDiscount.rules[0].amount`) is used, matching the storefront runtime.",
7601
7856
  "params": [
7602
7857
  {
7603
7858
  "name": "variant",
7604
7859
  "description": "- The product variant to check for applied campaigns"
7605
7860
  }
7606
7861
  ],
7607
- "returns": "An object with campaign type, formatted price, and discount percentage, or null if no campaign is applied",
7862
+ "returns": "An object `{ type, formattedPrice, discountPercentage }` — `formattedPrice` is set for FIXED_AMOUNT campaigns, `discountPercentage` for RATIO campaigns (fixed and tiered alike); the other field stays null. Returns null if no campaign is applied.",
7608
7863
  "returnType": "IkasAppliedCampaignAmount | null",
7609
7864
  "example": "```typescript\nimport { getProductVariantAppliedCampaignAmount, getSelectedProductVariant } from \"@ikas/bp-storefront\";\nimport { IkasProduct } from \"@ikas/bp-storefront\";\n\nfunction CampaignInfo({ product }: { product: IkasProduct }) {\n const variant = getSelectedProductVariant(product);\n const campaignAmount = getProductVariantAppliedCampaignAmount(variant);\n\n if (!campaignAmount) return null;\n\n return (\n <div>\n {campaignAmount.type === \"RATIO\"\n ? `${campaignAmount.discountPercentage}% off`\n : `${campaignAmount.formattedPrice} off`}\n </div>\n );\n}\n```",
7610
7865
  "categories": [
@@ -7999,6 +8254,36 @@
7999
8254
  "IkasProductVariant"
8000
8255
  ]
8001
8256
  },
8257
+ {
8258
+ "name": "getProductVariantTieredDiscountProducts",
8259
+ "displayName": "getTieredDiscountProducts",
8260
+ "signature": "function getProductVariantTieredDiscountProducts(variant: IkasProductVariant): IkasTieredDiscountProduct[]",
8261
+ "description": "Get the tiered-discount breakdown for a product variant, one entry per discount tier.\n\nA tiered discount defines multiple quantity tiers (`campaign.tieredDiscount.rules`), each with its own\namount and quantity range. This resolves every tier against the variant's price and returns the\nper-tier sell/final prices (both raw numbers and formatted strings), matching the storefront runtime.\nThe raw rules are `IkasProductTieredDiscountRule` (ranges may be null); this function returns the\nresolved `IkasTieredDiscountProduct` with normalized `{ min, max }` — use the resolved shape, not the raw rule.\n\n`sellPrice`/`finalPrice` (and their `formatted*` variants) are PER UNIT; the `*WithQuantity` fields are the\ntier total for buying the minimum quantity. A `\"FIXED_AMOUNT\"` discount is applied only to that total, so\nper-unit `finalPrice` equals `sellPrice` and the saving shows only in `finalPriceWithQuantity`.\n\nThe discount `amount` is interpreted by `campaign.type`: `\"RATIO\"` treats it as a percentage,\n`\"FIXED_AMOUNT\"` as an absolute money amount subtracted from the tier total. `amount`/`type` are\ninformational — the discount is already applied in the resolved `*Price` fields, so prefer those over\nrecomputing it yourself.\n\n`lineItemQuantityRange.min`/`max` are normalized numbers where `0` means \"unbounded\". In particular\n`max === 0` marks an open-ended top tier (e.g. \"6+\" with no upper limit) — render it as \"min+\" rather\nthan \"min–max\", and never treat `max` as a real quantity when it is `0`.\n\nEach tier's `salesChannelIds` lists the channels it targets (empty/null = all channels). Filter tiers\nagainst `IkasStorefrontConfig.salesChannelId` so only those valid for the current storefront are shown.\n\nReturns an empty array when the variant has no tiered-discount campaign, when a\n`PRODUCT_AND_VARIANT` filter excludes this variant, or when no tier defines a quantity range.",
8262
+ "params": [
8263
+ {
8264
+ "name": "variant",
8265
+ "description": "- The product variant to resolve tiered discounts for"
8266
+ }
8267
+ ],
8268
+ "returns": "An array of tier objects (`amount`, `lineItemQuantityRange`, `type`, sell/final prices with their formatted variants, `salesChannelIds`), or an empty array if no tiered discount applies",
8269
+ "returnType": "IkasTieredDiscountProduct[]",
8270
+ "example": "```typescript\nimport {\n getProductVariantTieredDiscountProducts,\n getSelectedProductVariant,\n IkasStorefrontConfig,\n} from \"@ikas/bp-storefront\";\nimport { IkasProduct } from \"@ikas/bp-storefront\";\n\nfunction TieredDiscountTable({ product }: { product: IkasProduct }) {\n const variant = getSelectedProductVariant(product);\n const tiers = getProductVariantTieredDiscountProducts(variant);\n const salesChannelId = IkasStorefrontConfig.salesChannelId;\n\n if (!tiers.length) return null;\n\n return (\n <ul>\n {tiers.map((tier, i) => {\n // A tier applies when it targets no channels or includes the current one\n const scoped =\n !tier.salesChannelIds?.length ||\n (!!salesChannelId && tier.salesChannelIds.includes(salesChannelId));\n if (!scoped) return null;\n\n return (\n <li key={i}>\n Buy {tier.lineItemQuantityRange.min}+ → {tier.formattedFinalPriceWithQuantity}{\" \"}\n <s>{tier.formattedSellPriceWithQuantity}</s>\n </li>\n );\n })}\n </ul>\n );\n}\n```",
8271
+ "categories": [
8272
+ "Pricing",
8273
+ "ProductVariant"
8274
+ ],
8275
+ "related": [
8276
+ "getProductVariantAppliedCampaignAmount",
8277
+ "getProductVariantCampaignOffersDiscountPercentage",
8278
+ "getProductVariantFinalPrice"
8279
+ ],
8280
+ "isAsync": false,
8281
+ "isClass": false,
8282
+ "parameterTypes": [
8283
+ "IkasProductVariant",
8284
+ "IkasTieredDiscountProduct"
8285
+ ]
8286
+ },
8002
8287
  {
8003
8288
  "name": "getProductVariantIsBackInStockEnabled",
8004
8289
  "displayName": "isBackInStockEnabled",
@@ -9095,6 +9380,34 @@
9095
9380
  "IkasProductList"
9096
9381
  ]
9097
9382
  },
9383
+ {
9384
+ "name": "updateProductListPrices",
9385
+ "displayName": "updatePrices",
9386
+ "signature": "async function updateProductListPrices(list: IkasProductList): Promise<void>",
9387
+ "description": "Re-fetches the latest variant prices of the products in the list and applies them in place.\nUseful when the page is served from cache but prices change frequently (e.g. gold prices),\ncall it once the list is mounted on the browser.",
9388
+ "params": [
9389
+ {
9390
+ "name": "list",
9391
+ "description": "- The product list to refresh prices for"
9392
+ }
9393
+ ],
9394
+ "returns": "void",
9395
+ "returnType": "Promise<void>",
9396
+ "example": "```typescript\nimport { updateProductListPrices } from \"@ikas/bp-storefront\";\n\nuseEffect(() => {\n updateProductListPrices(productList);\n}, [productList]);\n```",
9397
+ "categories": [
9398
+ "ProductList",
9399
+ "Pricing"
9400
+ ],
9401
+ "related": [
9402
+ "updateProductPrices",
9403
+ "getProductListPage"
9404
+ ],
9405
+ "isAsync": true,
9406
+ "isClass": false,
9407
+ "parameterTypes": [
9408
+ "IkasProductList"
9409
+ ]
9410
+ },
9098
9411
  {
9099
9412
  "name": "setSortType",
9100
9413
  "signature": "async function setSortType(list: IkasProductList, sortType: IkasProductListSortType): Promise<void>",
@@ -9556,7 +9869,7 @@
9556
9869
  "name": "initAddressForm",
9557
9870
  "displayName": "init",
9558
9871
  "signature": "async function initAddressForm(addressForm: AddressForm, address?: IkasCustomerAddress): Promise<void>",
9559
- "description": "Initializes an address form with default or existing address values, loads location data, and configures field settings.",
9872
+ "description": "Initializes an address form with default or existing address values, loads location data, and configures field settings.\n\nAlso resolves `addressForm.addressFormat` for the selected country. That is an\n`AddressFormItem[][]` describing which fields the country uses and how they group into rows\n(outer array = rows, inner array = fields sharing a row), and it is the only correct source\nfor laying out an address form -- a hardcoded field list will be wrong for most countries.\nIt is empty until this promise resolves, and `setAddressFormCountry` re-resolves it, so\nrender from it rather than copying it into local state.",
9560
9873
  "params": [
9561
9874
  {
9562
9875
  "name": "addressForm",
@@ -9569,7 +9882,7 @@
9569
9882
  ],
9570
9883
  "returns": "A promise that resolves once the form is fully initialized, including country/state/city lists, field settings, checkout settings, and shipping zones.",
9571
9884
  "returnType": "Promise<void>",
9572
- "example": "```typescript\nimport { initAddressForm } from \"@ikas/bp-storefront\";\n\n// Initialize an empty address form\nawait initAddressForm(addressForm);\n\n// Initialize with an existing customer address for editing\nawait initAddressForm(addressForm, existingAddress);\n```",
9885
+ "example": "```tsx\nimport { useEffect, useState } from \"preact/hooks\";\nimport {\n type AddressForm,\n type AddressFormItem,\n initAddressForm,\n setAddressFormFirstName,\n setAddressFormLastName,\n setAddressFormIdentityNumber,\n setAddressFormAddressLine1,\n setAddressFormAddressLine2,\n setAddressFormPostalCode,\n setAddressFormPhone,\n} from \"@ikas/bp-storefront\";\n\n// Initialize an empty address form\nawait initAddressForm(addressForm);\n\n// Initialize with an existing customer address for editing\nawait initAddressForm(addressForm, existingAddress);\n\n// addressFormat is empty until init resolves, so gate the render on it.\nconst [isLoading, setIsLoading] = useState(true);\nuseEffect(() => {\n initAddressForm(addressForm, address).then(() => setIsLoading(false));\n}, []);\n\n// Every addressFormat key has a matching setter, each taking (addressForm, value).\n// The location keys (country, state, city, district, region) are omitted here: they\n// render as selects fed by addressForm.countryOptions / stateOptions / cityOptions /\n// districtOptions / regionOptions, and must fall back to a text input when the field\n// isFreeText or has no options.\nconst SETTERS: Partial<Record<AddressFormItem, (form: AddressForm, value: string) => void>> = {\n firstName: setAddressFormFirstName,\n lastName: setAddressFormLastName,\n identityNumber: setAddressFormIdentityNumber,\n addressLine1: setAddressFormAddressLine1,\n addressLine2: setAddressFormAddressLine2,\n postalCode: setAddressFormPostalCode,\n phone: setAddressFormPhone,\n};\n\n// Render the country's own layout: outer array = rows, inner array = fields in that row.\n(addressForm.addressFormat ?? []).map((row) => {\n // A field the country does not use is absent from the form object entirely.\n const keys = row.filter((key) => addressForm[key] != null);\n if (!keys.length) return null;\n\n return (\n <div className=\"address-row\" key={keys.join(\"-\")}>\n {keys.map((key) => {\n // Each entry is an IkasFormItem: value, label, placeholder, hasError, message.\n const field = addressForm[key];\n if (!field) return null; // already guaranteed by the filter above; narrows the type\n return (\n <label key={key}>\n {field.label}\n <input\n value={field.value ?? \"\"}\n placeholder={field.placeholder}\n onInput={(e) => SETTERS[key]?.(addressForm, e.currentTarget.value)}\n />\n {field.hasError && <small>{field.message}</small>}\n </label>\n );\n })}\n </div>\n );\n})\n```",
9573
9886
  "categories": [
9574
9887
  "Address",
9575
9888
  "Form",
@@ -10717,101 +11030,183 @@
10717
11030
  "isClass": false
10718
11031
  },
10719
11032
  {
10720
- "name": "initForgotPasswordForm",
11033
+ "name": "initDeactivateCustomerForm",
10721
11034
  "displayName": "init",
10722
- "signature": "function initForgotPasswordForm(forgotPasswordForm: ForgotPasswordForm): void",
10723
- "description": "Initializes the forgot password form with default email field values, labels, and placeholders.",
11035
+ "signature": "function initDeactivateCustomerForm(deactivateCustomerForm: DeactivateCustomerForm): void",
11036
+ "description": "Initializes the deactivate customer form with default password field values, labels, and placeholders.",
10724
11037
  "params": [
10725
11038
  {
10726
- "name": "forgotPasswordForm",
10727
- "description": "- The forgot password form model to initialize"
11039
+ "name": "deactivateCustomerForm",
11040
+ "description": "- The deactivate customer form model to initialize"
10728
11041
  }
10729
11042
  ],
10730
11043
  "returns": "void",
10731
11044
  "returnType": "void",
10732
- "example": "```typescript\nimport { initForgotPasswordForm } from \"@ikas/bp-storefront\";\ninitForgotPasswordForm(forgotPasswordForm);\n```",
11045
+ "example": "```typescript\nimport { initDeactivateCustomerForm } from \"@ikas/bp-storefront\";\ninitDeactivateCustomerForm(deactivateCustomerForm);\n```",
10733
11046
  "categories": [
10734
11047
  "Validation",
10735
- "ForgotPassword",
11048
+ "DeactivateCustomer",
10736
11049
  "Form"
10737
11050
  ],
10738
11051
  "related": [
10739
- "setForgotPasswordFormEmail",
10740
- "submitForgotPasswordForm"
11052
+ "setDeactivateCustomerFormPassword",
11053
+ "submitDeactivateCustomerForm"
10741
11054
  ],
10742
11055
  "isAsync": false,
10743
11056
  "isClass": false
10744
11057
  },
10745
11058
  {
10746
- "name": "setForgotPasswordFormEmail",
10747
- "displayName": "setEmail",
10748
- "signature": "function setForgotPasswordFormEmail(forgotPasswordForm: ForgotPasswordForm, value: string): void",
10749
- "description": "Sets the email value on the forgot password form and re-validates if the form has already been submitted.",
11059
+ "name": "setDeactivateCustomerFormPassword",
11060
+ "displayName": "setPassword",
11061
+ "signature": "function setDeactivateCustomerFormPassword(deactivateCustomerForm: DeactivateCustomerForm, value: string): void",
11062
+ "description": "Sets the password value on the deactivate customer form and re-validates if the form has already been submitted.",
10750
11063
  "params": [
10751
11064
  {
10752
- "name": "forgotPasswordForm",
10753
- "description": "- The forgot password form model to update"
11065
+ "name": "deactivateCustomerForm",
11066
+ "description": "- The deactivate customer form model to update"
10754
11067
  },
10755
11068
  {
10756
11069
  "name": "value",
10757
- "description": "- The new email address string to set"
11070
+ "description": "- The new password string to set"
10758
11071
  }
10759
11072
  ],
10760
11073
  "returns": "void",
10761
11074
  "returnType": "void",
10762
- "example": "```typescript\nimport { setForgotPasswordFormEmail } from \"@ikas/bp-storefront\";\nsetForgotPasswordFormEmail(forgotPasswordForm, \"user@example.com\");\n```",
11075
+ "example": "```typescript\nimport { setDeactivateCustomerFormPassword } from \"@ikas/bp-storefront\";\nsetDeactivateCustomerFormPassword(deactivateCustomerForm, \"mySecurePassword123\");\n```",
10763
11076
  "categories": [
10764
11077
  "Validation",
10765
- "ForgotPassword",
11078
+ "DeactivateCustomer",
10766
11079
  "Form"
10767
11080
  ],
10768
11081
  "related": [
10769
- "initForgotPasswordForm",
10770
- "submitForgotPasswordForm"
11082
+ "initDeactivateCustomerForm",
11083
+ "submitDeactivateCustomerForm"
10771
11084
  ],
10772
11085
  "isAsync": false,
10773
11086
  "isClass": false
10774
11087
  },
10775
11088
  {
10776
- "name": "submitForgotPasswordForm",
11089
+ "name": "submitDeactivateCustomerForm",
10777
11090
  "displayName": "submit",
10778
- "signature": "async function submitForgotPasswordForm(forgotPasswordForm: ForgotPasswordForm): Promise<boolean>",
10779
- "description": "Validates and submits the forgot password form, sending a password reset request for the provided email address.",
11091
+ "signature": "async function submitDeactivateCustomerForm(deactivateCustomerForm: DeactivateCustomerForm): Promise<boolean>",
11092
+ "description": "Validates and submits the deactivate customer form, deleting the current customer's account after password verification.\nThe customer session is not cleared automatically, call `logout` after a successful submission.",
10780
11093
  "params": [
10781
11094
  {
10782
- "name": "forgotPasswordForm",
10783
- "description": "- The forgot password form model to submit"
11095
+ "name": "deactivateCustomerForm",
11096
+ "description": "- The deactivate customer form model to submit"
10784
11097
  }
10785
11098
  ],
10786
- "returns": "A promise that resolves to true if the password reset email was sent successfully, or false on validation error or API failure",
11099
+ "returns": "A promise that resolves to true if the account was deactivated successfully, or false on validation error or API failure",
10787
11100
  "returnType": "Promise<boolean>",
10788
- "example": "```typescript\nimport { submitForgotPasswordForm } from \"@ikas/bp-storefront\";\nconst success = await submitForgotPasswordForm(forgotPasswordForm);\nif (success) {\n console.log(\"Password reset email sent!\");\n}\n```",
11101
+ "example": "```typescript\nimport { customerStore, logout, submitDeactivateCustomerForm } from \"@ikas/bp-storefront\";\nconst success = await submitDeactivateCustomerForm(deactivateCustomerForm);\nif (success) {\n await logout(customerStore);\n}\n```",
10789
11102
  "categories": [
10790
11103
  "Validation",
10791
- "ForgotPassword",
11104
+ "DeactivateCustomer",
10792
11105
  "Form"
10793
11106
  ],
10794
11107
  "related": [
10795
- "initForgotPasswordForm",
10796
- "setForgotPasswordFormEmail"
11108
+ "initDeactivateCustomerForm",
11109
+ "setDeactivateCustomerFormPassword"
10797
11110
  ],
10798
11111
  "isAsync": true,
10799
11112
  "isClass": false
10800
11113
  },
10801
11114
  {
10802
- "name": "initLoginForm",
11115
+ "name": "initForgotPasswordForm",
10803
11116
  "displayName": "init",
10804
- "signature": "function initLoginForm(loginForm: LoginForm): void",
10805
- "description": "Initializes the login form with default email and password field values, labels, and placeholders.",
11117
+ "signature": "function initForgotPasswordForm(forgotPasswordForm: ForgotPasswordForm): void",
11118
+ "description": "Initializes the forgot password form with default email field values, labels, and placeholders.",
10806
11119
  "params": [
10807
11120
  {
10808
- "name": "loginForm",
10809
- "description": "- The login form model to initialize"
11121
+ "name": "forgotPasswordForm",
11122
+ "description": "- The forgot password form model to initialize"
10810
11123
  }
10811
11124
  ],
10812
11125
  "returns": "void",
10813
11126
  "returnType": "void",
10814
- "example": "```typescript\nimport { initLoginForm } from \"@ikas/bp-storefront\";\ninitLoginForm(loginForm);\n```",
11127
+ "example": "```typescript\nimport { initForgotPasswordForm } from \"@ikas/bp-storefront\";\ninitForgotPasswordForm(forgotPasswordForm);\n```",
11128
+ "categories": [
11129
+ "Validation",
11130
+ "ForgotPassword",
11131
+ "Form"
11132
+ ],
11133
+ "related": [
11134
+ "setForgotPasswordFormEmail",
11135
+ "submitForgotPasswordForm"
11136
+ ],
11137
+ "isAsync": false,
11138
+ "isClass": false
11139
+ },
11140
+ {
11141
+ "name": "setForgotPasswordFormEmail",
11142
+ "displayName": "setEmail",
11143
+ "signature": "function setForgotPasswordFormEmail(forgotPasswordForm: ForgotPasswordForm, value: string): void",
11144
+ "description": "Sets the email value on the forgot password form and re-validates if the form has already been submitted.",
11145
+ "params": [
11146
+ {
11147
+ "name": "forgotPasswordForm",
11148
+ "description": "- The forgot password form model to update"
11149
+ },
11150
+ {
11151
+ "name": "value",
11152
+ "description": "- The new email address string to set"
11153
+ }
11154
+ ],
11155
+ "returns": "void",
11156
+ "returnType": "void",
11157
+ "example": "```typescript\nimport { setForgotPasswordFormEmail } from \"@ikas/bp-storefront\";\nsetForgotPasswordFormEmail(forgotPasswordForm, \"user@example.com\");\n```",
11158
+ "categories": [
11159
+ "Validation",
11160
+ "ForgotPassword",
11161
+ "Form"
11162
+ ],
11163
+ "related": [
11164
+ "initForgotPasswordForm",
11165
+ "submitForgotPasswordForm"
11166
+ ],
11167
+ "isAsync": false,
11168
+ "isClass": false
11169
+ },
11170
+ {
11171
+ "name": "submitForgotPasswordForm",
11172
+ "displayName": "submit",
11173
+ "signature": "async function submitForgotPasswordForm(forgotPasswordForm: ForgotPasswordForm): Promise<boolean>",
11174
+ "description": "Validates and submits the forgot password form, sending a password reset request for the provided email address.",
11175
+ "params": [
11176
+ {
11177
+ "name": "forgotPasswordForm",
11178
+ "description": "- The forgot password form model to submit"
11179
+ }
11180
+ ],
11181
+ "returns": "A promise that resolves to true if the password reset email was sent successfully, or false on validation error or API failure",
11182
+ "returnType": "Promise<boolean>",
11183
+ "example": "```typescript\nimport { submitForgotPasswordForm } from \"@ikas/bp-storefront\";\nconst success = await submitForgotPasswordForm(forgotPasswordForm);\nif (success) {\n console.log(\"Password reset email sent!\");\n}\n```",
11184
+ "categories": [
11185
+ "Validation",
11186
+ "ForgotPassword",
11187
+ "Form"
11188
+ ],
11189
+ "related": [
11190
+ "initForgotPasswordForm",
11191
+ "setForgotPasswordFormEmail"
11192
+ ],
11193
+ "isAsync": true,
11194
+ "isClass": false
11195
+ },
11196
+ {
11197
+ "name": "initLoginForm",
11198
+ "displayName": "init",
11199
+ "signature": "function initLoginForm(loginForm: LoginForm): void",
11200
+ "description": "Initializes the login form with default email and password field values, labels, and placeholders.",
11201
+ "params": [
11202
+ {
11203
+ "name": "loginForm",
11204
+ "description": "- The login form model to initialize"
11205
+ }
11206
+ ],
11207
+ "returns": "void",
11208
+ "returnType": "void",
11209
+ "example": "```typescript\nimport { initLoginForm } from \"@ikas/bp-storefront\";\ninitLoginForm(loginForm);\n```",
10815
11210
  "categories": [
10816
11211
  "Validation",
10817
11212
  "Login",
@@ -12502,7 +12897,7 @@
12502
12897
  {
12503
12898
  "name": "setLocalization",
12504
12899
  "signature": "function setLocalization(baseStore: BaseStore, localeOption: IkasLocaleOption): void",
12505
- "description": "Switches the storefront to the routing associated with `localeOption` and redirects the browser\nto the equivalent URL under that routing.\n\nReads the routing directly from `localeOption.routing`, then performs a full-page redirect via\n`window.location.replace`. For CATEGORY/BRAND/PRODUCT pages, the localized slug from the page's\nmetadata translations is used when available; otherwise the visitor stays on the current path\n(with the current routing prefix swapped for the new one). Query string and hash are preserved.",
12900
+ "description": "Switches the storefront to the routing associated with `localeOption` and redirects the browser\nto the equivalent URL under that routing.\n\nReads the routing directly from `localeOption.routing`, then performs a full-page redirect via\n`window.location.replace`. For CATEGORY/BRAND/PRODUCT pages, the localized slug from the page's\nmetadata translations is used when available; otherwise the visitor stays on the current path\n(with the current routing prefix swapped for the new one). Query string and hash are preserved.\n\nWhich one: `setLocalization` backs a country/region picker (`baseStore.localeOptions`, one entry per country;\nthe routing it leads to sets the language and the currency together). `setLanguage` backs a language-only picker\n(`baseStore.languageOptions`, one entry per routing). Both only switch the routing, so a header needs one of\nthem, not both side by side.",
12506
12901
  "params": [
12507
12902
  {
12508
12903
  "name": "baseStore",
@@ -12530,7 +12925,7 @@
12530
12925
  {
12531
12926
  "name": "setLanguage",
12532
12927
  "signature": "function setLanguage(baseStore: BaseStore, language: IkasLanguageOption): void",
12533
- "description": "Switches the storefront to the routing identified by `language` and redirects the browser to\nthe equivalent URL under that routing.\n\nLooks up the routing by `language.id`, then performs a full-page redirect via\n`window.location.replace`. For CATEGORY/BRAND/PRODUCT pages, the localized slug from the\npage's metadata translations is used when available; otherwise the visitor stays on the\ncurrent path (with the current routing prefix swapped for the new one). Query string and\nhash are preserved.",
12928
+ "description": "Switches the storefront to the routing identified by `language` and redirects the browser to\nthe equivalent URL under that routing.\n\nLooks up the routing by `language.id`, then performs a full-page redirect via\n`window.location.replace`. For CATEGORY/BRAND/PRODUCT pages, the localized slug from the\npage's metadata translations is used when available; otherwise the visitor stays on the\ncurrent path (with the current routing prefix swapped for the new one). Query string and\nhash are preserved.\n\nWhich one: see `setLocalization` — a language-only picker uses this, a country/region picker (language and\ncurrency together) uses `setLocalization`; a header needs one of them, not both.",
12534
12929
  "params": [
12535
12930
  {
12536
12931
  "name": "baseStore",
@@ -12559,11 +12954,27 @@
12559
12954
  "name": "bs_searchProductById",
12560
12955
  "displayName": "searchProductById",
12561
12956
  "signature": "async function bs_searchProductById(baseStore: BaseStore, params: { productId: string }): Promise<{\n isSuccess: boolean;\n product: IkasProduct | null;\n}>",
12562
- "description": "",
12563
- "params": [],
12957
+ "description": "Fetches a single product by id and returns it as a full `IkasProduct`.\n\nUse this when a lightweight reference (e.g. a cart line's `IkasOrderLineVariant`, which carries\nneither `salesChannels` nor `stock`) needs product-level data: the returned product includes\n`salesChannels` filtered to the active sales channel (with `minQuantityPerCart` /\n`maxQuantityPerCart`) and per-variant `stock` (summed over the sales channel's configured\nstock locations). `selectedVariantValues` is seeded from the first active variant (or the\nfirst variant when none is active). For multiple ids, prefer `bs_searchProductsById` — one\nbatched request.",
12958
+ "params": [
12959
+ {
12960
+ "name": "baseStore",
12961
+ "description": "- The base store instance"
12962
+ },
12963
+ {
12964
+ "name": "params",
12965
+ "description": "- `{ productId }` — id of the product to fetch"
12966
+ }
12967
+ ],
12968
+ "returns": "`{ isSuccess, product }` — `product` is null when not found or on failure",
12564
12969
  "returnType": "Promise<{\n isSuccess: boolean;\n product: IkasProduct | null;\n}>",
12565
- "categories": [],
12566
- "related": [],
12970
+ "example": "```tsx\nimport { baseStore, bs_searchProductById, IkasStorefrontConfig } from \"@ikas/bp-storefront\";\n\nconst { isSuccess, product } = await bs_searchProductById(baseStore, { productId });\nif (isSuccess && product) {\n const channel = product.salesChannels?.find(sc => sc.id === IkasStorefrontConfig.salesChannelId);\n console.log(channel?.maxQuantityPerCart);\n}\n```",
12971
+ "categories": [
12972
+ "Product",
12973
+ "Search"
12974
+ ],
12975
+ "related": [
12976
+ "bs_searchProductsById"
12977
+ ],
12567
12978
  "isAsync": true,
12568
12979
  "isClass": false,
12569
12980
  "parameterTypes": [
@@ -12574,11 +12985,29 @@
12574
12985
  "name": "bs_searchProductsById",
12575
12986
  "displayName": "searchProductsById",
12576
12987
  "signature": "async function bs_searchProductsById(baseStore: BaseStore, params: { productIds: string[] }): Promise<{\n isSuccess: boolean;\n products: IkasProduct[] | null;\n}>",
12577
- "description": "",
12578
- "params": [],
12988
+ "description": "Batch-fetches products by id in a single request and returns them as full `IkasProduct` objects.\n\nThe go-to function when cart lines (or any lightweight reference) need product-level data they\ndo not carry: `IkasOrderLineVariant` has neither `salesChannels` nor `stock`, while the products\nreturned here include `salesChannels` filtered to the active sales channel (with\n`minQuantityPerCart` / `maxQuantityPerCart`) and per-variant `stock` (summed over the sales\nchannel's configured stock locations). Collect the distinct `productId`s of the lines and\nfetch them in ONE call instead of one request per line. Called with an empty `productIds`,\nit returns `{ isSuccess: true, products: [] }` without a network request.",
12989
+ "params": [
12990
+ {
12991
+ "name": "baseStore",
12992
+ "description": "- The base store instance"
12993
+ },
12994
+ {
12995
+ "name": "params",
12996
+ "description": "- `{ productIds }` — product ids to fetch (deduplicate before calling)"
12997
+ }
12998
+ ],
12999
+ "returns": "`{ isSuccess, products }` — `products` is null on failure",
12579
13000
  "returnType": "Promise<{\n isSuccess: boolean;\n products: IkasProduct[] | null;\n}>",
12580
- "categories": [],
12581
- "related": [],
13001
+ "example": "```tsx\nimport { baseStore, bs_searchProductsById, cartStore, IkasStorefrontConfig } from \"@ikas/bp-storefront\";\n\n// Enforce per-cart quantity limits on cart lines:\nconst productIds = [\n ...new Set(\n (cartStore.cart?.orderLineItems ?? [])\n .map(item => item.variant.productId)\n .filter((id): id is string => !!id)\n ),\n];\nconst { products } = await bs_searchProductsById(baseStore, { productIds });\nconst maxByProductId = new Map<string, number | null>();\nfor (const p of products ?? []) {\n const channel = p.salesChannels?.find(sc => sc.id === IkasStorefrontConfig.salesChannelId);\n maxByProductId.set(p.id, channel?.maxQuantityPerCart ?? null);\n}\n```",
13002
+ "categories": [
13003
+ "Product",
13004
+ "Cart",
13005
+ "Search"
13006
+ ],
13007
+ "related": [
13008
+ "bs_searchProductById",
13009
+ "changeItemQuantity"
13010
+ ],
12582
13011
  "isAsync": true,
12583
13012
  "isClass": false,
12584
13013
  "parameterTypes": [
@@ -12616,7 +13045,7 @@
12616
13045
  "name": "addItemToCart",
12617
13046
  "displayName": "addVariantToCart",
12618
13047
  "signature": "async function addItemToCart(variant: IkasProductVariant, product: IkasProduct, initialQuantity: number = 1, options?: AddItemOptions): Promise<IkasCartOperationResult>",
12619
- "description": "Add a product variant to the shopping cart.",
13048
+ "description": "Add a product variant to the shopping cart.\n\nClamps the quantity to the sales channel's `minQuantityPerCart`/`maxQuantityPerCart` only\nwhen it creates a new cart line. When the variant already has a line in the cart, the add\nis delegated to `changeItemQuantity` (existing quantity + `initialQuantity`) with no\nclient-side clamp — a quantity past `maxQuantityPerCart` is then rejected by the API with\nthe `MAX_QUANTITY_PER_CART_LIMIT_REACHED` code in `result.response.errorCodes`, never as a\n`validationError`. See `changeItemQuantity` for the handling pattern.",
12620
13049
  "params": [
12621
13050
  {
12622
13051
  "name": "variant",
@@ -12692,7 +13121,7 @@
12692
13121
  "name": "changeItemQuantity",
12693
13122
  "displayName": "changeQuantityOnCart",
12694
13123
  "signature": "async function changeItemQuantity(item: IkasOrderLineItem, quantity: number, offers?: IkasProductOffer[], product?: IkasProduct): Promise<IkasCartOperationResult>",
12695
- "description": "Change the quantity of an item in the cart.\nUse quantity=0 to remove the item.",
13124
+ "description": "Change the quantity of an item in the cart.\nUse quantity=0 to remove the item.\n\nPerforms no client-side clamping or validation: a quantity above the sales channel's\n`maxQuantityPerCart` is rejected by the API with the `MAX_QUANTITY_PER_CART_LIMIT_REACHED`\ncode in `result.response.errorCodes` (never as a `validationError`). Prevent violations in\nthe stepper and treat the error code as the fallback.",
12696
13125
  "params": [
12697
13126
  {
12698
13127
  "name": "item",
@@ -12713,7 +13142,7 @@
12713
13142
  ],
12714
13143
  "returns": "Result with success flag",
12715
13144
  "returnType": "Promise<IkasCartOperationResult>",
12716
- "example": "```typescript\nimport { cartStore, changeItemQuantity } from \"@ikas/bp-storefront\";\n\n// Increment quantity\nasync function handleIncrement(itemId: string) {\n const item = cartStore.cart?.orderLineItems.find(i => i.id === itemId);\n if (item) {\n const result = await changeItemQuantity(item, item.quantity + 1);\n if (!result.success) {\n showToast(\"Failed to update quantity\");\n }\n }\n}\n\n// Decrement quantity\nasync function handleDecrement(itemId: string) {\n const item = cartStore.cart?.orderLineItems.find(i => i.id === itemId);\n if (item && item.quantity > 1) {\n await changeItemQuantity(item, item.quantity - 1);\n }\n}\n```",
13145
+ "example": "```typescript\nimport { APIErrorCode, cartStore, changeItemQuantity } from \"@ikas/bp-storefront\";\n\n// Increment quantity\nasync function handleIncrement(itemId: string) {\n const item = cartStore.cart?.orderLineItems.find(i => i.id === itemId);\n if (item) {\n const result = await changeItemQuantity(item, item.quantity + 1);\n if (!result.success) {\n const limitHit = result.response?.errorCodes?.includes(\n APIErrorCode.MAX_QUANTITY_PER_CART_LIMIT_REACHED\n );\n showToast(limitHit ? \"Per-cart quantity limit reached\" : \"Failed to update quantity\");\n }\n }\n}\n\n// Decrement quantity\nasync function handleDecrement(itemId: string) {\n const item = cartStore.cart?.orderLineItems.find(i => i.id === itemId);\n if (item && item.quantity > 1) {\n await changeItemQuantity(item, item.quantity - 1);\n }\n}\n```",
12717
13146
  "categories": [
12718
13147
  "Cart"
12719
13148
  ],
@@ -13022,6 +13451,37 @@
13022
13451
  "IkasCartOperationResult"
13023
13452
  ]
13024
13453
  },
13454
+ {
13455
+ "name": "removeGiftCardLine",
13456
+ "signature": "async function removeGiftCardLine(cart: IkasCart, giftCardId?: string | null): Promise<IkasCartOperationResult>",
13457
+ "description": "Remove a gift card (or store credit) line from the cart.\n\nGift cards are applied through `saveCouponCode` with the gift card code, and the applied\ncards are listed on `cart.giftCardLines`. Pass the `giftCardId` of the line to remove; when\nomitted, every gift card line is removed from the cart.",
13458
+ "params": [
13459
+ {
13460
+ "name": "cart",
13461
+ "description": "- The cart object"
13462
+ },
13463
+ {
13464
+ "name": "giftCardId",
13465
+ "description": "- The gift card to remove, or null/undefined to remove all of them"
13466
+ }
13467
+ ],
13468
+ "returns": "Result with success flag",
13469
+ "returnType": "Promise<IkasCartOperationResult>",
13470
+ "example": "```typescript\nimport { cartStore, removeGiftCardLine } from \"@ikas/bp-storefront\";\n\nasync function handleRemoveGiftCard(giftCardId: string) {\n if (!cartStore.cart) return;\n\n const result = await removeGiftCardLine(cartStore.cart, giftCardId);\n if (result.success) {\n showToast(\"Gift card removed\");\n }\n}\n```",
13471
+ "categories": [
13472
+ "Cart"
13473
+ ],
13474
+ "related": [
13475
+ "saveCouponCode",
13476
+ "getIkasOrderGiftCardTotalPrice"
13477
+ ],
13478
+ "isAsync": true,
13479
+ "isClass": false,
13480
+ "parameterTypes": [
13481
+ "IkasCart",
13482
+ "IkasCartOperationResult"
13483
+ ]
13484
+ },
13025
13485
  {
13026
13486
  "name": "getCart",
13027
13487
  "signature": "async function getCart(): Promise<void>",
@@ -13301,6 +13761,171 @@
13301
13761
  "IkasCustomerStore"
13302
13762
  ]
13303
13763
  },
13764
+ {
13765
+ "name": "milesSmilesBind",
13766
+ "signature": "async function milesSmilesBind(customerStore: IkasCustomerStore, redirect?: string | null): Promise<MilesSmilesBindResult>",
13767
+ "description": "Start the Turkish Airlines Miles&Smiles account bind flow for the logged-in customer.\nOpens the THY login page in a popup; once THY confirms, the browser is sent to the\nikas bind callback and lands back on `redirect` with `milesSmilesStatus` query params\n(see handleMilesSmilesBind). Binding is required before miles can be spent at checkout.",
13768
+ "params": [
13769
+ {
13770
+ "name": "customerStore",
13771
+ "description": "- The customer store instance (customer must be logged in)"
13772
+ },
13773
+ {
13774
+ "name": "redirect",
13775
+ "description": "- Relative store path to land on after bind, e.g. \"/account\" or \"/checkout?id=...&step=payment\""
13776
+ }
13777
+ ],
13778
+ "returns": "`isSuccess: true` when the bind hand-off started; otherwise an `errorCode`\nsuch as \"AUTHORIZATION_REQUIRED\" or \"MILES_SMILES_LOGIN_CANCELLED_OR_FAILED\"",
13779
+ "returnType": "Promise<MilesSmilesBindResult>",
13780
+ "example": "```typescript\nimport { customerStore, milesSmilesBind } from \"@ikas/bp-storefront\";\n\nasync function onLinkClick() {\n const result = await milesSmilesBind(customerStore, \"/account\");\n if (!result.isSuccess) showToast(result.errorCode || \"UNEXPECTED_ERROR\");\n}\n```",
13781
+ "categories": [
13782
+ "Customer",
13783
+ "Miles&Smiles"
13784
+ ],
13785
+ "related": [
13786
+ "handleMilesSmilesBind",
13787
+ "getMilesSmilesLink",
13788
+ "unlinkMilesSmiles",
13789
+ "getMilesSmilesDetails"
13790
+ ],
13791
+ "isAsync": true,
13792
+ "isClass": false,
13793
+ "parameterTypes": [
13794
+ "IkasCustomerStore"
13795
+ ]
13796
+ },
13797
+ {
13798
+ "name": "handleMilesSmilesBind",
13799
+ "signature": "function handleMilesSmilesBind(clear: boolean = true): HandleMilesSmilesBindReturnType | null",
13800
+ "description": "Read the Miles&Smiles bind result from the current URL after THY redirects back\n(`?milesSmilesStatus=success` or `?milesSmilesStatus=fail&milesSmilesError=CODE`).\nCall this on the landing page (account or checkout). The params are removed from the\nURL so a refresh does not repeat the same message.",
13801
+ "params": [
13802
+ {
13803
+ "name": "clear",
13804
+ "description": "- Remove the params from the URL with history.replaceState (default: true)"
13805
+ }
13806
+ ],
13807
+ "returns": "The landing result, or null when the URL carries no bind result",
13808
+ "returnType": "HandleMilesSmilesBindReturnType | null",
13809
+ "example": "```typescript\nimport { handleMilesSmilesBind } from \"@ikas/bp-storefront\";\n\nuseEffect(() => {\n const result = handleMilesSmilesBind();\n if (result?.status === \"success\") showToast(\"Miles&Smiles account linked\");\n if (result?.status === \"fail\") showToast(result.errorCode || \"Bind failed\");\n}, []);\n```",
13810
+ "categories": [
13811
+ "Customer",
13812
+ "Miles&Smiles"
13813
+ ],
13814
+ "related": [
13815
+ "milesSmilesBind",
13816
+ "getMilesSmilesLink"
13817
+ ],
13818
+ "isAsync": false,
13819
+ "isClass": false
13820
+ },
13821
+ {
13822
+ "name": "getMilesSmilesLink",
13823
+ "signature": "async function getMilesSmilesLink(customerStore: IkasCustomerStore): Promise<APIResponse<ExternalAccountLink | null>>",
13824
+ "description": "Get the customer's durable Miles&Smiles link (TK membership number and link date).\nA link does not guarantee a live checkout session; when getMilesSmilesDetails returns\nMILES_SMILES_LOGIN_REQUIRED, run milesSmilesBind again.",
13825
+ "params": [
13826
+ {
13827
+ "name": "customerStore",
13828
+ "description": "- The customer store instance"
13829
+ }
13830
+ ],
13831
+ "returns": "API response whose data is the link, or null when not linked",
13832
+ "returnType": "Promise<APIResponse<ExternalAccountLink | null>>",
13833
+ "example": "```typescript\nimport { customerStore, getMilesSmilesLink } from \"@ikas/bp-storefront\";\n\nconst response = await getMilesSmilesLink(customerStore);\nconst tkNumber = response.data?.externalId;\n```",
13834
+ "categories": [
13835
+ "Customer",
13836
+ "Miles&Smiles"
13837
+ ],
13838
+ "related": [
13839
+ "milesSmilesBind",
13840
+ "unlinkMilesSmiles"
13841
+ ],
13842
+ "isAsync": true,
13843
+ "isClass": false,
13844
+ "parameterTypes": [
13845
+ "IkasCustomerStore"
13846
+ ]
13847
+ },
13848
+ {
13849
+ "name": "unlinkMilesSmiles",
13850
+ "signature": "async function unlinkMilesSmiles(customerStore: IkasCustomerStore): Promise<APIResponse<boolean>>",
13851
+ "description": "Remove the customer's Miles&Smiles link. Also clears the server-side checkout\nsession token, so miles cannot be spent until the customer binds again.",
13852
+ "params": [
13853
+ {
13854
+ "name": "customerStore",
13855
+ "description": "- The customer store instance"
13856
+ }
13857
+ ],
13858
+ "returns": "API response whose data is true on success",
13859
+ "returnType": "Promise<APIResponse<boolean>>",
13860
+ "example": "```typescript\nimport { customerStore, unlinkMilesSmiles } from \"@ikas/bp-storefront\";\n\nconst response = await unlinkMilesSmiles(customerStore);\nif (response.isSuccess) showToast(\"Miles&Smiles link removed\");\n```",
13861
+ "categories": [
13862
+ "Customer",
13863
+ "Miles&Smiles"
13864
+ ],
13865
+ "related": [
13866
+ "milesSmilesBind",
13867
+ "getMilesSmilesLink"
13868
+ ],
13869
+ "isAsync": true,
13870
+ "isClass": false,
13871
+ "parameterTypes": [
13872
+ "IkasCustomerStore"
13873
+ ]
13874
+ },
13875
+ {
13876
+ "name": "getMilesSmilesDetails",
13877
+ "signature": "async function getMilesSmilesDetails(customerStore: IkasCustomerStore): Promise<APIResponse<MilesSmilesDetailsResponse | undefined>>",
13878
+ "description": "Get the Miles&Smiles balance and member details for the payment step.\nRequires a recent bind; MILES_SMILES_LOGIN_REQUIRED means the short-lived session\nexpired and milesSmilesBind should be run again. MILES_SMILES_NOT_ENABLED and\nPAYMENT_GATEWAY_NOT_FOUND mean the Miles UI should be hidden.",
13879
+ "params": [
13880
+ {
13881
+ "name": "customerStore",
13882
+ "description": "- The customer store instance"
13883
+ }
13884
+ ],
13885
+ "returns": "API response whose data holds availableMiles, memberId, firstName and lastName",
13886
+ "returnType": "Promise<APIResponse<MilesSmilesDetailsResponse | undefined>>",
13887
+ "example": "```typescript\nimport { customerStore, getMilesSmilesDetails } from \"@ikas/bp-storefront\";\n\nconst response = await getMilesSmilesDetails(customerStore);\nif (response.errorCodes.includes(\"MILES_SMILES_LOGIN_REQUIRED\")) {\n await milesSmilesBind(customerStore, window.location.pathname + window.location.search);\n} else if (response.data) {\n console.log(\"Available miles:\", response.data.availableMiles);\n}\n```",
13888
+ "categories": [
13889
+ "Customer",
13890
+ "Miles&Smiles"
13891
+ ],
13892
+ "related": [
13893
+ "milesSmilesBind",
13894
+ "getMilesSmilesLink"
13895
+ ],
13896
+ "isAsync": true,
13897
+ "isClass": false,
13898
+ "parameterTypes": [
13899
+ "IkasCustomerStore"
13900
+ ]
13901
+ },
13902
+ {
13903
+ "name": "isMilesSmilesTransaction",
13904
+ "signature": "function isMilesSmilesTransaction(transaction: IkasOrderTransaction): boolean",
13905
+ "description": "Check whether an order transaction is the Miles&Smiles leg of a multi-tender payment.\nSuch rows are written on the synthetic MILES_SMILES gateway and are not refundable from the storefront.",
13906
+ "params": [
13907
+ {
13908
+ "name": "transaction",
13909
+ "description": "- The order transaction to check"
13910
+ }
13911
+ ],
13912
+ "returns": "True when the transaction is a Miles&Smiles SALE",
13913
+ "returnType": "boolean",
13914
+ "example": "```typescript\nimport { isMilesSmilesTransaction } from \"@ikas/bp-storefront\";\n\nconst label = isMilesSmilesTransaction(tx) ? \"Miles&Smiles\" : tx.paymentGatewayName;\n```",
13915
+ "categories": [
13916
+ "Customer",
13917
+ "Orders",
13918
+ "Miles&Smiles"
13919
+ ],
13920
+ "related": [
13921
+ "getOrderTransactions"
13922
+ ],
13923
+ "isAsync": false,
13924
+ "isClass": false,
13925
+ "parameterTypes": [
13926
+ "IkasOrderTransaction"
13927
+ ]
13928
+ },
13304
13929
  {
13305
13930
  "name": "deleteCustomerAddress",
13306
13931
  "signature": "async function deleteCustomerAddress(customerStore: IkasCustomerStore, address: IkasCustomerAddress): Promise<boolean>",
@@ -13333,6 +13958,44 @@
13333
13958
  "IkasCustomerAddress"
13334
13959
  ]
13335
13960
  },
13961
+ {
13962
+ "name": "createRefundRequest",
13963
+ "signature": "async function createRefundRequest(customerStore: IkasCustomerStore, order: IkasOrder, email?: string | null): Promise<IkasRefundRequestResult>",
13964
+ "description": "Submit a refund request for an order based on the refund quantities set on each line item,\nalong with the selected refund reason id and refund reason note set on the order.",
13965
+ "params": [
13966
+ {
13967
+ "name": "customerStore",
13968
+ "description": "- The customer store instance"
13969
+ },
13970
+ {
13971
+ "name": "order",
13972
+ "description": "- The order to request a refund for"
13973
+ },
13974
+ {
13975
+ "name": "email",
13976
+ "description": "- Optional email address for guest order refunds"
13977
+ }
13978
+ ],
13979
+ "returns": "Object with isSuccess flag, errorCode on failure and the not allowed lines for REFUND_NOT_ALLOWED",
13980
+ "returnType": "Promise<IkasRefundRequestResult>",
13981
+ "example": "```typescript\nimport { customerStore, createRefundRequest, getOrder } from \"@ikas/bp-storefront\";\n\nasync function handleRefundRequest(orderId: string) {\n const order = await getOrder(customerStore, orderId);\n if (!order) return;\n\n const result = await createRefundRequest(customerStore, order);\n if (result.isSuccess) {\n showToast(\"Refund request submitted\");\n } else if (result.errorCode === \"REFUND_REASON_REQUIRED\") {\n showToast(\"Please select a refund reason\");\n } else {\n showToast(\"Refund request failed\");\n }\n}\n```",
13982
+ "categories": [
13983
+ "Customer"
13984
+ ],
13985
+ "related": [
13986
+ "refundOrder",
13987
+ "getOrder",
13988
+ "setIkasOrderRefundReasonId",
13989
+ "setIkasOrderRefundReason"
13990
+ ],
13991
+ "isAsync": true,
13992
+ "isClass": false,
13993
+ "parameterTypes": [
13994
+ "IkasCustomerStore",
13995
+ "IkasOrder",
13996
+ "IkasRefundRequestResult"
13997
+ ]
13998
+ },
13336
13999
  {
13337
14000
  "name": "refundOrder",
13338
14001
  "signature": "async function refundOrder(customerStore: IkasCustomerStore, order: IkasOrder, email?: string | null): Promise<boolean>",
@@ -13358,6 +14021,7 @@
13358
14021
  "Customer"
13359
14022
  ],
13360
14023
  "related": [
14024
+ "createRefundRequest",
13361
14025
  "getOrder",
13362
14026
  "getOrders",
13363
14027
  "getOrderRefundSettings"
@@ -13743,6 +14407,36 @@
13743
14407
  "IkasOrderTransaction"
13744
14408
  ]
13745
14409
  },
14410
+ {
14411
+ "name": "getOrderTransactionsWithPrices",
14412
+ "signature": "async function getOrderTransactionsWithPrices(customerStore: IkasCustomerStore, params: GetOrderTransactionsWithPricesParams): Promise<ListOrderTransactionWithPricesResponse | null>",
14413
+ "description": "Retrieve an order's payment transactions together with its payment totals\n(charged, refunded, remaining balance and refundable amounts).",
14414
+ "params": [
14415
+ {
14416
+ "name": "customerStore",
14417
+ "description": "- The customer store instance"
14418
+ },
14419
+ {
14420
+ "name": "params",
14421
+ "description": "- Parameters containing the orderId"
14422
+ }
14423
+ ],
14424
+ "returns": "The order's transactions with price totals, or null if unavailable",
14425
+ "returnType": "Promise<ListOrderTransactionWithPricesResponse | null>",
14426
+ "example": "```typescript\nimport { customerStore, getOrderTransactionsWithPrices } from \"@ikas/bp-storefront\";\n\nasync function loadPaymentSummary(orderId: string) {\n const result = await getOrderTransactionsWithPrices(customerStore, { orderId });\n if (result) {\n console.log(\"Charged:\", result.chargedAmount, \"Remaining:\", result.remainingBalance);\n }\n}\n```",
14427
+ "categories": [
14428
+ "Customer"
14429
+ ],
14430
+ "related": [
14431
+ "getOrderTransactions",
14432
+ "getOrder"
14433
+ ],
14434
+ "isAsync": true,
14435
+ "isClass": false,
14436
+ "parameterTypes": [
14437
+ "IkasCustomerStore"
14438
+ ]
14439
+ },
13746
14440
  {
13747
14441
  "name": "getFavoriteProducts",
13748
14442
  "signature": "async function getFavoriteProducts(customerStore: IkasCustomerStore): Promise<IkasProduct[]>",
@@ -13922,7 +14616,8 @@
13922
14616
  ],
13923
14617
  "related": [
13924
14618
  "hasCustomer",
13925
- "logout"
14619
+ "logout",
14620
+ "getDeactivateCustomerForm"
13926
14621
  ],
13927
14622
  "isAsync": true,
13928
14623
  "isClass": false,
@@ -14493,6 +15188,58 @@
14493
15188
  "IkasCustomerStore"
14494
15189
  ]
14495
15190
  },
15191
+ {
15192
+ "name": "getDeactivateCustomerForm",
15193
+ "signature": "function getDeactivateCustomerForm(customerStore: IkasCustomerStore): DeactivateCustomerForm",
15194
+ "description": "Get or initialize the deactivate customer form with validation for deleting the current customer's account.",
15195
+ "params": [
15196
+ {
15197
+ "name": "customerStore",
15198
+ "description": "- The customer store instance"
15199
+ }
15200
+ ],
15201
+ "returns": "The deactivate customer form object with validated fields",
15202
+ "returnType": "DeactivateCustomerForm",
15203
+ "example": "```typescript\nimport {\n customerStore,\n getDeactivateCustomerForm,\n setDeactivateCustomerFormPassword,\n submitDeactivateCustomerForm,\n logout,\n} from \"@ikas/bp-storefront\";\n\nfunction DeleteAccountPage() {\n const form = getDeactivateCustomerForm(customerStore);\n\n const handleSubmit = async () => {\n const isSuccess = await submitDeactivateCustomerForm(form);\n if (isSuccess) {\n await logout(customerStore);\n Router.navigateToPage(\"INDEX\");\n }\n };\n\n return (\n <form>\n <input\n type=\"password\"\n value={form.password.value}\n onChange={e => setDeactivateCustomerFormPassword(form, e.target.value)}\n />\n <button onClick={handleSubmit}>Delete Account</button>\n </form>\n );\n}\n```",
15204
+ "categories": [
15205
+ "Customer",
15206
+ "Account"
15207
+ ],
15208
+ "related": [
15209
+ "clearDeactivateCustomerForm",
15210
+ "deactivateCustomer"
15211
+ ],
15212
+ "isAsync": false,
15213
+ "isClass": false,
15214
+ "parameterTypes": [
15215
+ "IkasCustomerStore"
15216
+ ]
15217
+ },
15218
+ {
15219
+ "name": "clearDeactivateCustomerForm",
15220
+ "signature": "function clearDeactivateCustomerForm(customerStore: IkasCustomerStore): void",
15221
+ "description": "Clear the cached deactivate customer form, forcing a fresh form on next retrieval.",
15222
+ "params": [
15223
+ {
15224
+ "name": "customerStore",
15225
+ "description": "- The customer store instance"
15226
+ }
15227
+ ],
15228
+ "returnType": "void",
15229
+ "example": "```typescript\nimport { customerStore, clearDeactivateCustomerForm } from \"@ikas/bp-storefront\";\n\nfunction handleDeactivateCustomerReset() {\n clearDeactivateCustomerForm(customerStore);\n}\n```",
15230
+ "categories": [
15231
+ "Customer",
15232
+ "Account"
15233
+ ],
15234
+ "related": [
15235
+ "getDeactivateCustomerForm"
15236
+ ],
15237
+ "isAsync": false,
15238
+ "isClass": false,
15239
+ "parameterTypes": [
15240
+ "IkasCustomerStore"
15241
+ ]
15242
+ },
14496
15243
  {
14497
15244
  "name": "getForgotPasswordForm",
14498
15245
  "signature": "function getForgotPasswordForm(customerStore: IkasCustomerStore): ForgotPasswordForm",
@@ -14862,7 +15609,7 @@
14862
15609
  {
14863
15610
  "name": "getEmptyAddressForm",
14864
15611
  "signature": "function getEmptyAddressForm(customerStore: IkasCustomerStore): AddressForm",
14865
- "description": "Create and return a new, empty address form with validation, wrapped in MobX observability.",
15612
+ "description": "Create and return a new, empty address form with validation, wrapped in MobX observability.\n\nUse this to create an address; use `getIkasCustomerAddressForm(address)` to edit an existing\none. It starts `initAddressForm` internally but does not await it, so await `initAddressForm`\nyourself when you need to know that the country layout (`addressFormat`) and the country/state/\ncity lists are ready to render.",
14866
15613
  "params": [
14867
15614
  {
14868
15615
  "name": "customerStore",
@@ -14871,14 +15618,16 @@
14871
15618
  ],
14872
15619
  "returns": "A new observable address form object with validated fields",
14873
15620
  "returnType": "AddressForm",
14874
- "example": "```typescript\nimport { customerStore, getEmptyAddressForm, saveCustomer } from \"@ikas/bp-storefront\";\n\nfunction AddAddressPage() {\n const form = getEmptyAddressForm(customerStore);\n\n const handleSave = async () => {\n const customer = { ...customerStore.customer! };\n customer.addresses = [...(customer.addresses || []), formToAddress(form)];\n await saveCustomer(customerStore, customer);\n };\n\n return (\n <form>\n <input\n value={form.addressLine1.value}\n onChange={e => form.addressLine1.value = e.target.value}\n />\n <button onClick={handleSave}>Save Address</button>\n </form>\n );\n}\n```",
15621
+ "example": "```tsx\nimport {\n customerStore,\n getEmptyAddressForm,\n initAddressForm,\n setAddressFormAddressLine1,\n submitAddressForm,\n} from \"@ikas/bp-storefront\";\n\n// Create the form once, then await init before rendering the country-driven layout.\nconst [form] = useState(() => getEmptyAddressForm(customerStore));\nconst [isLoading, setIsLoading] = useState(true);\nuseEffect(() => {\n initAddressForm(form).then(() => setIsLoading(false));\n}, []);\n\n// Always go through the setters. Assigning `form.addressLine1.value` directly skips\n// re-validation and the dependent-field resets the location setters perform.\nsetAddressFormAddressLine1(form, \"123 Main Street\");\n\n// submitAddressForm validates and saves the address onto the customer itself --\n// do not hand-build a customer object and call saveCustomer for this.\nconst ok = await submitAddressForm(form);\n```",
14875
15622
  "categories": [
14876
15623
  "Customer",
14877
15624
  "Address"
14878
15625
  ],
14879
15626
  "related": [
14880
- "deleteCustomerAddress",
14881
- "saveCustomer"
15627
+ "initAddressForm",
15628
+ "submitAddressForm",
15629
+ "getIkasCustomerAddressForm",
15630
+ "deleteCustomerAddress"
14882
15631
  ],
14883
15632
  "isAsync": false,
14884
15633
  "isClass": false,
@@ -14967,6 +15716,20 @@
14967
15716
  "isClass": true,
14968
15717
  "className": "I18n"
14969
15718
  },
15719
+ {
15720
+ "name": "t",
15721
+ "signature": "function t(key: K & (K extends `ikas:${string}` ? IkasTextKey : unknown), [params]: UiTextArgs<[K][K extends unknown ? 0 : never]>): string",
15722
+ "description": "The project's UI text `key` in the store's language, its `{{param}}`s filled; the key itself when no text has it.\n`ikas:<key>` reads the store's common texts instead (`t(\"ikas:validation.required\")`).\nTypes only: the code component build binds it to the project's own texts (this shared runtime has no `t`).",
15723
+ "params": [],
15724
+ "returnType": "string",
15725
+ "categories": [],
15726
+ "related": [],
15727
+ "isAsync": false,
15728
+ "isClass": false,
15729
+ "parameterTypes": [
15730
+ "IkasTextKey"
15731
+ ]
15732
+ },
14970
15733
  {
14971
15734
  "name": "Router.navigate",
14972
15735
  "signature": "static Router.navigate(path: string, shallow: boolean = false, newTab: boolean = false): void",
@@ -15116,6 +15879,128 @@
15116
15879
  "isClass": true,
15117
15880
  "className": "Router"
15118
15881
  },
15882
+ {
15883
+ "name": "withRoutePrefix",
15884
+ "signature": "function withRoutePrefix(path: string): string",
15885
+ "description": "Put the visitor's storefront routing in front of a path you wrote yourself.\n\nEntity links (`getProductHref`, `getIkasOrderHref`, …) and LINK props already carry the prefix.\nA literal path in your own markup does not: `href=\"/cart\"` sends a visitor browsing `/en` to the\ndefault language. Wrap it, and a store with no extra routings gets the path back unchanged.\n\nIdempotent — a path that already starts with a supported routing segment is returned as-is.\nAnything that is not a path on this storefront — an absolute URL, `mailto:`, `tel:` — is returned\nuntouched, so a merchant-authored prop can be wrapped without checking it first.",
15886
+ "params": [
15887
+ {
15888
+ "name": "path",
15889
+ "description": "- A path on this storefront, starting with `/`"
15890
+ }
15891
+ ],
15892
+ "returns": "The path under the current routing (e.g. `/cart` → `/en/cart`)",
15893
+ "returnType": "string",
15894
+ "example": "```tsx\nimport { Router, withRoutePrefix } from \"@ikas/bp-storefront\";\n\n// Correct href for crawlers, middle-click and open-in-new-tab...\n<a href={withRoutePrefix(\"/cart\")} onClick={e => {\n e.preventDefault();\n Router.navigateToPage(\"CART\"); // ...and this prefixes on its own.\n}}>Cart</a>\n```",
15895
+ "categories": [
15896
+ "Navigation"
15897
+ ],
15898
+ "related": [
15899
+ "navigate",
15900
+ "navigateToPage"
15901
+ ],
15902
+ "isAsync": false,
15903
+ "isClass": false
15904
+ },
15905
+ {
15906
+ "name": "registerThemeSettingValues",
15907
+ "signature": "function registerThemeSettingValues(values: Record<string, any> | null): void",
15908
+ "description": "Register the live global-variable object (`_g_`) so `getThemeSetting`/`getThemeSettings`\nreturn actual runtime values (constants, computed getters, and in-editor edits) instead\nof the serialized design-time defaults. Called by generated code, not by component authors.",
15909
+ "params": [],
15910
+ "returnType": "void",
15911
+ "categories": [],
15912
+ "related": [],
15913
+ "isAsync": false,
15914
+ "isClass": false
15915
+ },
15916
+ {
15917
+ "name": "getThemeSettings",
15918
+ "signature": "function getThemeSettings(): ThemeSetting[]",
15919
+ "description": "All global variables (Theme Settings) defined for the theme.",
15920
+ "params": [],
15921
+ "returnType": "ThemeSetting[]",
15922
+ "categories": [],
15923
+ "related": [],
15924
+ "isAsync": false,
15925
+ "isClass": false
15926
+ },
15927
+ {
15928
+ "name": "getThemeSetting",
15929
+ "signature": "function getThemeSetting(name: string): ThemeSetting | undefined",
15930
+ "description": "A single global variable by its stable key (`variableName`, e.g. `_6Q0KV7VGGM`).\nDiscover keys via (each item carries a human `displayName`).\nThe returned `value` is the live blueprint value when available, else the default.\nIts shape is discriminated by `type` (see ); note an\nIMAGE setting's value is an image REFERENCE (no `.url`) — resolve with\n`getDefaultSrc`/`getSrc`. An ENUM setting's `value` is one of its enum's option VALUES\n(or null) and the setting also carries `enumTypeId` and `options` (`{ label: value }`);\nin a code component prefer the typed `themeValue(\"_key\")` from `./global-types`, which\nnarrows the value to the enum's union.",
15931
+ "params": [],
15932
+ "returnType": "ThemeSetting | undefined",
15933
+ "categories": [],
15934
+ "related": [],
15935
+ "isAsync": false,
15936
+ "isClass": false
15937
+ },
15938
+ {
15939
+ "name": "getThemeSettingValue",
15940
+ "signature": "function getThemeSettingValue(name: string): any",
15941
+ "description": "Convenience: the resolved value of a global variable, or `undefined` if not found.",
15942
+ "params": [],
15943
+ "returnType": "any",
15944
+ "categories": [],
15945
+ "related": [],
15946
+ "isAsync": false,
15947
+ "isClass": false
15948
+ },
15949
+ {
15950
+ "name": "getThemeColors",
15951
+ "signature": "function getThemeColors(): RuntimeDesignToken[]",
15952
+ "description": "Theme color tokens. Each carries a resolved value and a `var(--id)` CSS reference.",
15953
+ "params": [],
15954
+ "returnType": "RuntimeDesignToken[]",
15955
+ "categories": [],
15956
+ "related": [],
15957
+ "isAsync": false,
15958
+ "isClass": false
15959
+ },
15960
+ {
15961
+ "name": "getThemeTypography",
15962
+ "signature": "function getThemeTypography(): RuntimeTypographyToken[]",
15963
+ "description": "Theme typography tokens (text styles). Apply `className` or read `resolved` CSS values.",
15964
+ "params": [],
15965
+ "returnType": "RuntimeTypographyToken[]",
15966
+ "categories": [],
15967
+ "related": [],
15968
+ "isAsync": false,
15969
+ "isClass": false
15970
+ },
15971
+ {
15972
+ "name": "getThemeBreakpoints",
15973
+ "signature": "function getThemeBreakpoints(): RuntimeBreakpointToken[]",
15974
+ "description": "Theme responsive breakpoints (`{ id, width }`).",
15975
+ "params": [],
15976
+ "returnType": "RuntimeBreakpointToken[]",
15977
+ "categories": [],
15978
+ "related": [],
15979
+ "isAsync": false,
15980
+ "isClass": false
15981
+ },
15982
+ {
15983
+ "name": "getThemeKeyframes",
15984
+ "signature": "function getThemeKeyframes(): RuntimeKeyframeToken[]",
15985
+ "description": "Theme keyframe/transition animations. Use `ref` as the CSS animation name.",
15986
+ "params": [],
15987
+ "returnType": "RuntimeKeyframeToken[]",
15988
+ "categories": [],
15989
+ "related": [],
15990
+ "isAsync": false,
15991
+ "isClass": false
15992
+ },
15993
+ {
15994
+ "name": "getThemeColorSchemes",
15995
+ "signature": "function getThemeColorSchemes(): RuntimeThemeColorSchemes",
15996
+ "description": "Theme color schemes (palettes). Returns two PARALLEL lists with different jobs:\n- `schemes`: the color SLOTS as `{ id }` only — no colors and no display label live here at\n runtime. A slot's human name is authoring-only (read it via the CLI/MCP `list-theme-globals`\n or the editor); at runtime identify a slot solely by its `id`.\n- `values`: the actual palettes. A palette's colors live in its `colorsByScheme`\n map, keyed by slot id → `{ resolved, cssVar }`.\n\nTo render swatches, iterate `values[].colorsByScheme` (the source of truth for\ncolors), NOT the top-level `schemes` array — `schemes` carries slot ids only, so\niterating it renders empty:\n\n const { values } = getThemeColorSchemes();\n values.forEach(palette =>\n Object.entries(palette.colorsByScheme).forEach(([slotId, { resolved, cssVar }]) => {\n // slotId → stable slot key, cssVar → live var() ref (prefer this), resolved → hex snapshot\n })\n );",
15997
+ "params": [],
15998
+ "returnType": "RuntimeThemeColorSchemes",
15999
+ "categories": [],
16000
+ "related": [],
16001
+ "isAsync": false,
16002
+ "isClass": false
16003
+ },
15119
16004
  {
15120
16005
  "name": "isBrowser",
15121
16006
  "signature": "function isBrowser(yes?: () => void, no?: () => void): void",
@@ -15142,6 +16027,38 @@
15142
16027
  "IkasComponentRendererProps"
15143
16028
  ]
15144
16029
  },
16030
+ {
16031
+ "name": "formatCurrency",
16032
+ "signature": "function formatCurrency(price: number, currencyCode: string, currencySymbol: string | null): string",
16033
+ "description": "Format a free-standing amount with the merchant's currency format settings. Use this for\namounts that are NOT tied to a model (remaining amount to free shipping, gift wrap threshold,\nbulk discount limits, cart limit warnings). For model-bound prices, prefer the\n`get*FormattedPrice` helpers — they call this function internally.\n\nApplies the merchant's `currencyFormats` entry for the given currency code (symbol,\nsymbolPosition, thousandSeparator, decimalSeparator, omitZeroDecimal). Behavior details:\nalways two decimal places, and a space between the symbol and the number. `omitZeroDecimal`\ndrops the fraction only when it is exactly `00`.\n\nDo NOT use `Intl.NumberFormat` for currency — it falls back to the browser locale and\nproduces a format that conflicts with platform-formatted prices on the same screen.",
16034
+ "params": [
16035
+ {
16036
+ "name": "price",
16037
+ "description": "- The amount to format"
16038
+ },
16039
+ {
16040
+ "name": "currencyCode",
16041
+ "description": "- Currency code used to look up the merchant format settings (e.g. \"TRY\", \"USD\")"
16042
+ },
16043
+ {
16044
+ "name": "currencySymbol",
16045
+ "description": "- Fallback symbol used when the merchant has no format entry for the code.\nAlways pass the symbol from the model you took the amount from (e.g. `cart.currencySymbol`) —\npassing `null` can render the amount with no symbol at all."
16046
+ }
16047
+ ],
16048
+ "returns": "The amount formatted with the merchant's currency format (e.g. \"₺ 1,950.00\")",
16049
+ "returnType": "string",
16050
+ "example": "```typescript\nimport { cartStore, formatCurrency } from \"@ikas/bp-storefront\";\n\nfunction FreeShippingBar({ threshold }: { threshold: number }) {\n const cart = cartStore.cart;\n if (!cart) return null;\n\n const remaining = threshold - cart.totalFinalPrice;\n if (remaining <= 0) return <span>Free shipping unlocked!</span>;\n\n return <span>Add {formatCurrency(remaining, cart.currencyCode, cart.currencySymbol)} more for free shipping</span>;\n}\n```",
16051
+ "categories": [
16052
+ "Pricing"
16053
+ ],
16054
+ "related": [
16055
+ "getProductVariantFormattedFinalPrice",
16056
+ "getOrderLineItemFormattedFinalPrice",
16057
+ "getIkasOrderFormattedTotalFinalPrice"
16058
+ ],
16059
+ "isAsync": false,
16060
+ "isClass": false
16061
+ },
15145
16062
  {
15146
16063
  "name": "httpRequest",
15147
16064
  "signature": "async function httpRequest(url: string, method: HttpMethod, body?: Record<string, any>, headers?: Record<string, string>): Promise<FetchResponse>",
@@ -15196,6 +16113,55 @@
15196
16113
  "related": [],
15197
16114
  "isAsync": false,
15198
16115
  "isClass": false
16116
+ },
16117
+ {
16118
+ "name": "PayWithIkas",
16119
+ "signature": "function PayWithIkas({ product, quantity = 1, className, style }: PayWithIkasProps): VNode<ClassAttributes<HTMLIFrameElement> & { ref: MutableRef<HTMLIFrameElement | null>; title: string; ... 4 more ...; style: { ...; }; }> | null",
16120
+ "description": "\"Pay with ikas\" (Hızlı Öde) fast-checkout button for the product detail page.\nDrop-in Preact component that renders the pay-with-ikas checkout iframe and\nwires up its whole message protocol, so a theme gets the one-click \"Hızlı Öde\"\nflow without owning any of the plumbing. Use it next to the add-to-cart button\non the product detail page.\n\nThe pay-with-ikas URL is read from `IkasStorefrontConfig.getPayWithIkasUrl()`;\nwhen the merchant has not enabled Pay with ikas the component renders nothing.\nThe add-to-cart-enabled state is tracked reactively via mobx `autorun`, so the\niframe stays in sync as the product's availability changes (e.g. variant\nselection). Clicking \"Hızlı Öde\" creates a temporary cart via\n`createPayWithIkasSession` and redirects to the returned pay URL.",
16121
+ "params": [
16122
+ {
16123
+ "name": "product",
16124
+ "description": "- The product to fast-checkout via Pay with ikas"
16125
+ },
16126
+ {
16127
+ "name": "quantity",
16128
+ "description": "- Quantity to purchase (defaults to 1)"
16129
+ },
16130
+ {
16131
+ "name": "className",
16132
+ "description": "- Optional CSS class applied to the iframe"
16133
+ },
16134
+ {
16135
+ "name": "style",
16136
+ "description": "- Optional inline styles applied to the iframe"
16137
+ }
16138
+ ],
16139
+ "returnType": "VNode<ClassAttributes<HTMLIFrameElement> & { ref: MutableRef<HTMLIFrameElement | null>; title: string; ... 4 more ...; style: { ...; }; }> | null",
16140
+ "example": "```tsx\nimport { PayWithIkas } from \"@ikas/bp-storefront\";\n\n// On the product detail page, alongside the add-to-cart button:\n<PayWithIkas product={product} quantity={quantity} />\n```",
16141
+ "categories": [
16142
+ "ProductDetail",
16143
+ "Checkout"
16144
+ ],
16145
+ "related": [
16146
+ "createPayWithIkasSession",
16147
+ "isAddToCartEnabled"
16148
+ ],
16149
+ "isAsync": false,
16150
+ "isClass": false,
16151
+ "parameterTypes": [
16152
+ "IkasProps"
16153
+ ]
16154
+ },
16155
+ {
16156
+ "name": "normalizeSvg",
16157
+ "signature": "function normalizeSvg(svg: string, options: NormalizeSvgOptions): string",
16158
+ "description": "Isomorphic, DOM-free normalization of a raw SVG markup string for render.\nSafe to call in SSR, browser, and node — pure string transforms only.",
16159
+ "params": [],
16160
+ "returnType": "string",
16161
+ "categories": [],
16162
+ "related": [],
16163
+ "isAsync": false,
16164
+ "isClass": false
15199
16165
  }
15200
16166
  ],
15201
16167
  "codeExamples": []