@sixtyninecommerce/client 0.23.1 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (299) hide show
  1. package/README.md +25 -0
  2. package/dist/admin/forms.js +19 -0
  3. package/dist/admin/forms.js.map +1 -1
  4. package/dist/admin/http.d.ts +9 -0
  5. package/dist/admin/http.d.ts.map +1 -1
  6. package/dist/admin/http.js +3 -0
  7. package/dist/admin/http.js.map +1 -1
  8. package/dist/admin/index.d.ts +63 -0
  9. package/dist/admin/index.d.ts.map +1 -1
  10. package/dist/admin/index.js +67 -0
  11. package/dist/admin/index.js.map +1 -1
  12. package/dist/admin/redirects.d.ts +6 -0
  13. package/dist/admin/redirects.d.ts.map +1 -1
  14. package/dist/admin/redirects.js +12 -0
  15. package/dist/admin/redirects.js.map +1 -1
  16. package/dist/admin/types.d.ts +63 -0
  17. package/dist/admin/types.d.ts.map +1 -1
  18. package/dist/cache-tags.d.ts +19 -0
  19. package/dist/cache-tags.d.ts.map +1 -1
  20. package/dist/cache-tags.js +19 -0
  21. package/dist/cache-tags.js.map +1 -1
  22. package/dist/client.d.ts +17 -0
  23. package/dist/client.d.ts.map +1 -1
  24. package/dist/client.js +17 -0
  25. package/dist/client.js.map +1 -1
  26. package/dist/commerce/age-verification.js +3 -3
  27. package/dist/commerce/age-verification.js.map +1 -1
  28. package/dist/commerce/branding.js +7 -0
  29. package/dist/commerce/branding.js.map +1 -1
  30. package/dist/commerce/cart.js +25 -0
  31. package/dist/commerce/cart.js.map +1 -1
  32. package/dist/commerce/checkout.d.ts +68 -0
  33. package/dist/commerce/checkout.d.ts.map +1 -1
  34. package/dist/commerce/checkout.js +83 -0
  35. package/dist/commerce/checkout.js.map +1 -1
  36. package/dist/commerce/customer.d.ts +58 -0
  37. package/dist/commerce/customer.d.ts.map +1 -1
  38. package/dist/commerce/customer.js +65 -0
  39. package/dist/commerce/customer.js.map +1 -1
  40. package/dist/commerce/index.d.ts +17 -1
  41. package/dist/commerce/index.d.ts.map +1 -1
  42. package/dist/commerce/pickup-location-parser.d.ts +18 -0
  43. package/dist/commerce/pickup-location-parser.d.ts.map +1 -1
  44. package/dist/commerce/pickup-location-parser.js +28 -0
  45. package/dist/commerce/pickup-location-parser.js.map +1 -1
  46. package/dist/commerce/placement-error.d.ts +52 -0
  47. package/dist/commerce/placement-error.d.ts.map +1 -1
  48. package/dist/commerce/placement-error.js +87 -0
  49. package/dist/commerce/placement-error.js.map +1 -1
  50. package/dist/commerce/products.d.ts +48 -0
  51. package/dist/commerce/products.d.ts.map +1 -1
  52. package/dist/commerce/products.js +95 -2
  53. package/dist/commerce/products.js.map +1 -1
  54. package/dist/commerce/queries.d.ts +114 -27
  55. package/dist/commerce/queries.d.ts.map +1 -1
  56. package/dist/commerce/queries.js +219 -1
  57. package/dist/commerce/queries.js.map +1 -1
  58. package/dist/commerce/quotes.js +33 -0
  59. package/dist/commerce/quotes.js.map +1 -1
  60. package/dist/commerce/saved-lists.d.ts +7 -7
  61. package/dist/commerce/saved-lists.d.ts.map +1 -1
  62. package/dist/commerce/saved-lists.js +1 -1
  63. package/dist/commerce/search.js +3 -0
  64. package/dist/commerce/search.js.map +1 -1
  65. package/dist/commerce/shipping.js +3 -3
  66. package/dist/commerce/shipping.js.map +1 -1
  67. package/dist/commerce/stock-notifications.d.ts +11 -0
  68. package/dist/commerce/stock-notifications.d.ts.map +1 -1
  69. package/dist/commerce/stock-notifications.js +11 -0
  70. package/dist/commerce/stock-notifications.js.map +1 -1
  71. package/dist/commerce/subscriptions.d.ts +32 -8
  72. package/dist/commerce/subscriptions.d.ts.map +1 -1
  73. package/dist/commerce/subscriptions.js +90 -2
  74. package/dist/commerce/subscriptions.js.map +1 -1
  75. package/dist/commerce/vat-validation.js +4 -4
  76. package/dist/commerce/vat-validation.js.map +1 -1
  77. package/dist/constants.d.ts +31 -0
  78. package/dist/constants.d.ts.map +1 -1
  79. package/dist/constants.js +32 -0
  80. package/dist/constants.js.map +1 -1
  81. package/dist/content/asset-urls.d.ts +50 -0
  82. package/dist/content/asset-urls.d.ts.map +1 -1
  83. package/dist/content/asset-urls.js +92 -0
  84. package/dist/content/asset-urls.js.map +1 -1
  85. package/dist/content/assets.d.ts +15 -0
  86. package/dist/content/assets.d.ts.map +1 -1
  87. package/dist/content/assets.js +15 -0
  88. package/dist/content/assets.js.map +1 -1
  89. package/dist/content/collection-pages.d.ts +5 -0
  90. package/dist/content/collection-pages.d.ts.map +1 -1
  91. package/dist/content/collection-pages.js +8 -0
  92. package/dist/content/collection-pages.js.map +1 -1
  93. package/dist/content/collections.d.ts +14 -0
  94. package/dist/content/collections.d.ts.map +1 -1
  95. package/dist/content/collections.js +16 -0
  96. package/dist/content/collections.js.map +1 -1
  97. package/dist/content/filtered-products.d.ts +18 -0
  98. package/dist/content/filtered-products.d.ts.map +1 -1
  99. package/dist/content/filtered-products.js +16 -0
  100. package/dist/content/filtered-products.js.map +1 -1
  101. package/dist/content/form-field-types.d.ts +6 -0
  102. package/dist/content/form-field-types.d.ts.map +1 -1
  103. package/dist/content/form-field-types.js +12 -0
  104. package/dist/content/form-field-types.js.map +1 -1
  105. package/dist/content/forms.d.ts +16 -0
  106. package/dist/content/forms.d.ts.map +1 -1
  107. package/dist/content/forms.js +23 -0
  108. package/dist/content/forms.js.map +1 -1
  109. package/dist/content/items.d.ts +26 -0
  110. package/dist/content/items.d.ts.map +1 -1
  111. package/dist/content/items.js +33 -0
  112. package/dist/content/items.js.map +1 -1
  113. package/dist/content/resolve.js +6 -0
  114. package/dist/content/resolve.js.map +1 -1
  115. package/dist/content/sitemap.d.ts +5 -0
  116. package/dist/content/sitemap.d.ts.map +1 -1
  117. package/dist/content/sitemap.js +5 -0
  118. package/dist/content/sitemap.js.map +1 -1
  119. package/dist/core/context.js +6 -0
  120. package/dist/core/context.js.map +1 -1
  121. package/dist/core/headers.js +2 -0
  122. package/dist/core/headers.js.map +1 -1
  123. package/dist/core/http.d.ts +8 -0
  124. package/dist/core/http.d.ts.map +1 -1
  125. package/dist/core/http.js +89 -1
  126. package/dist/core/http.js.map +1 -1
  127. package/dist/credit/credit-status.js +2 -2
  128. package/dist/credit/credit-status.js.map +1 -1
  129. package/dist/credit/payment-terms.js +2 -2
  130. package/dist/credit/payment-terms.js.map +1 -1
  131. package/dist/currency/exchange.d.ts +11 -0
  132. package/dist/currency/exchange.d.ts.map +1 -1
  133. package/dist/currency/exchange.js +11 -0
  134. package/dist/currency/exchange.js.map +1 -1
  135. package/dist/errors.d.ts +50 -2
  136. package/dist/errors.d.ts.map +1 -1
  137. package/dist/errors.js +50 -3
  138. package/dist/errors.js.map +1 -1
  139. package/dist/events/envelope.d.ts +36 -0
  140. package/dist/events/envelope.d.ts.map +1 -1
  141. package/dist/events/envelope.js +12 -0
  142. package/dist/events/envelope.js.map +1 -1
  143. package/dist/events/index.d.ts +13 -0
  144. package/dist/events/index.d.ts.map +1 -1
  145. package/dist/events/index.js +13 -0
  146. package/dist/events/index.js.map +1 -1
  147. package/dist/events/payloads.d.ts +19 -0
  148. package/dist/events/payloads.d.ts.map +1 -1
  149. package/dist/events/payloads.js +12 -0
  150. package/dist/events/payloads.js.map +1 -1
  151. package/dist/index.d.ts +8 -1
  152. package/dist/index.d.ts.map +1 -1
  153. package/dist/index.js +7 -0
  154. package/dist/index.js.map +1 -1
  155. package/dist/media/index.js +2 -0
  156. package/dist/media/index.js.map +1 -1
  157. package/dist/media/urls.d.ts +52 -0
  158. package/dist/media/urls.d.ts.map +1 -1
  159. package/dist/media/urls.js +38 -0
  160. package/dist/media/urls.js.map +1 -1
  161. package/dist/media/video.d.ts +16 -0
  162. package/dist/media/video.d.ts.map +1 -1
  163. package/dist/media/video.js +16 -0
  164. package/dist/media/video.js.map +1 -1
  165. package/dist/next/artifact-handler.d.ts +22 -0
  166. package/dist/next/artifact-handler.d.ts.map +1 -1
  167. package/dist/next/artifact-handler.js +22 -0
  168. package/dist/next/artifact-handler.js.map +1 -1
  169. package/dist/next/event-revalidate-handler.d.ts +67 -0
  170. package/dist/next/event-revalidate-handler.d.ts.map +1 -1
  171. package/dist/next/event-revalidate-handler.js +48 -0
  172. package/dist/next/event-revalidate-handler.js.map +1 -1
  173. package/dist/next/index.d.ts +6 -0
  174. package/dist/next/index.d.ts.map +1 -1
  175. package/dist/next/index.js +6 -0
  176. package/dist/next/index.js.map +1 -1
  177. package/dist/next/json-ld.d.ts +9 -0
  178. package/dist/next/json-ld.d.ts.map +1 -1
  179. package/dist/next/json-ld.js +9 -0
  180. package/dist/next/json-ld.js.map +1 -1
  181. package/dist/next/metadata.d.ts +18 -0
  182. package/dist/next/metadata.d.ts.map +1 -1
  183. package/dist/next/metadata.js +21 -0
  184. package/dist/next/metadata.js.map +1 -1
  185. package/dist/next/redirect-middleware.d.ts +39 -0
  186. package/dist/next/redirect-middleware.d.ts.map +1 -1
  187. package/dist/next/redirect-middleware.js +32 -0
  188. package/dist/next/redirect-middleware.js.map +1 -1
  189. package/dist/next/revalidate-handler.d.ts +30 -0
  190. package/dist/next/revalidate-handler.d.ts.map +1 -1
  191. package/dist/next/revalidate-handler.js +22 -0
  192. package/dist/next/revalidate-handler.js.map +1 -1
  193. package/dist/order-scope.d.ts +27 -0
  194. package/dist/order-scope.d.ts.map +1 -1
  195. package/dist/order-scope.js +29 -0
  196. package/dist/order-scope.js.map +1 -1
  197. package/dist/pricing/format.d.ts +17 -0
  198. package/dist/pricing/format.d.ts.map +1 -1
  199. package/dist/pricing/format.js +19 -0
  200. package/dist/pricing/format.js.map +1 -1
  201. package/dist/pricing/index.d.ts +8 -1
  202. package/dist/pricing/index.d.ts.map +1 -1
  203. package/dist/pricing/index.js +18 -2
  204. package/dist/pricing/index.js.map +1 -1
  205. package/dist/pricing/tax-display.d.ts +77 -0
  206. package/dist/pricing/tax-display.d.ts.map +1 -1
  207. package/dist/pricing/tax-display.js +85 -0
  208. package/dist/pricing/tax-display.js.map +1 -1
  209. package/dist/pricing/tiers.d.ts +9 -0
  210. package/dist/pricing/tiers.d.ts.map +1 -1
  211. package/dist/pricing/tiers.js +9 -0
  212. package/dist/pricing/tiers.js.map +1 -1
  213. package/dist/pricing/validation.d.ts +56 -1
  214. package/dist/pricing/validation.d.ts.map +1 -1
  215. package/dist/pricing/validation.js +61 -0
  216. package/dist/pricing/validation.js.map +1 -1
  217. package/dist/redirects/index.d.ts +1 -0
  218. package/dist/redirects/index.d.ts.map +1 -1
  219. package/dist/redirects/index.js +1 -0
  220. package/dist/redirects/index.js.map +1 -1
  221. package/dist/redirects/store.d.ts +20 -0
  222. package/dist/redirects/store.d.ts.map +1 -1
  223. package/dist/redirects/store.js +57 -0
  224. package/dist/redirects/store.js.map +1 -1
  225. package/dist/redirects/types.d.ts +24 -0
  226. package/dist/redirects/types.d.ts.map +1 -1
  227. package/dist/redirects/types.js +1 -0
  228. package/dist/redirects/types.js.map +1 -1
  229. package/dist/revalidation/event-plan.d.ts +48 -0
  230. package/dist/revalidation/event-plan.d.ts.map +1 -1
  231. package/dist/revalidation/event-plan.js +61 -0
  232. package/dist/revalidation/event-plan.js.map +1 -1
  233. package/dist/revalidation/event-verify.d.ts +25 -0
  234. package/dist/revalidation/event-verify.d.ts.map +1 -1
  235. package/dist/revalidation/event-verify.js +27 -0
  236. package/dist/revalidation/event-verify.js.map +1 -1
  237. package/dist/revalidation/types.d.ts +20 -0
  238. package/dist/revalidation/types.d.ts.map +1 -1
  239. package/dist/revalidation/types.js +10 -0
  240. package/dist/revalidation/types.js.map +1 -1
  241. package/dist/revalidation/url-context.d.ts +25 -0
  242. package/dist/revalidation/url-context.d.ts.map +1 -1
  243. package/dist/revalidation/url-context.js +17 -0
  244. package/dist/revalidation/url-context.js.map +1 -1
  245. package/dist/revalidation/verify.d.ts +8 -0
  246. package/dist/revalidation/verify.d.ts.map +1 -1
  247. package/dist/revalidation/verify.js +8 -0
  248. package/dist/revalidation/verify.js.map +1 -1
  249. package/dist/seo/ai.d.ts +17 -0
  250. package/dist/seo/ai.d.ts.map +1 -1
  251. package/dist/seo/ai.js +12 -0
  252. package/dist/seo/ai.js.map +1 -1
  253. package/dist/seo/alternates.js +13 -0
  254. package/dist/seo/alternates.js.map +1 -1
  255. package/dist/seo/artifacts.d.ts +13 -0
  256. package/dist/seo/artifacts.d.ts.map +1 -1
  257. package/dist/seo/artifacts.js +19 -0
  258. package/dist/seo/artifacts.js.map +1 -1
  259. package/dist/seo/canonical.d.ts +15 -0
  260. package/dist/seo/canonical.d.ts.map +1 -1
  261. package/dist/seo/canonical.js +24 -0
  262. package/dist/seo/canonical.js.map +1 -1
  263. package/dist/seo/index.js +6 -0
  264. package/dist/seo/index.js.map +1 -1
  265. package/dist/seo/json-ld.d.ts +13 -0
  266. package/dist/seo/json-ld.d.ts.map +1 -1
  267. package/dist/seo/json-ld.js +32 -0
  268. package/dist/seo/json-ld.js.map +1 -1
  269. package/dist/seo/locale-tag.d.ts +31 -0
  270. package/dist/seo/locale-tag.d.ts.map +1 -1
  271. package/dist/seo/locale-tag.js +31 -0
  272. package/dist/seo/locale-tag.js.map +1 -1
  273. package/dist/seo/meta-tags.d.ts +29 -0
  274. package/dist/seo/meta-tags.d.ts.map +1 -1
  275. package/dist/seo/meta-tags.js +28 -0
  276. package/dist/seo/meta-tags.js.map +1 -1
  277. package/dist/seo/metadata-parser.d.ts +24 -0
  278. package/dist/seo/metadata-parser.d.ts.map +1 -1
  279. package/dist/seo/metadata-parser.js +38 -0
  280. package/dist/seo/metadata-parser.js.map +1 -1
  281. package/dist/seo/metadata-types.d.ts +16 -0
  282. package/dist/seo/metadata-types.d.ts.map +1 -1
  283. package/dist/seo/product-path.d.ts +96 -0
  284. package/dist/seo/product-path.d.ts.map +1 -1
  285. package/dist/seo/product-path.js +96 -0
  286. package/dist/seo/product-path.js.map +1 -1
  287. package/dist/seo/robots.d.ts +17 -0
  288. package/dist/seo/robots.d.ts.map +1 -1
  289. package/dist/seo/robots.js +12 -0
  290. package/dist/seo/robots.js.map +1 -1
  291. package/dist/seo/types.d.ts +39 -0
  292. package/dist/seo/types.d.ts.map +1 -1
  293. package/dist/seo/url-builder.d.ts +31 -0
  294. package/dist/seo/url-builder.d.ts.map +1 -1
  295. package/dist/seo/url-builder.js +36 -0
  296. package/dist/seo/url-builder.js.map +1 -1
  297. package/dist/types.d.ts +1283 -2
  298. package/dist/types.d.ts.map +1 -1
  299. package/package.json +1 -1
@@ -1,9 +1,86 @@
1
+ /**
2
+ * Which tax figure a shopper sees: incl. (`gross`) or excl. (`net`) tax.
3
+ *
4
+ * `Channel.pricesIncludeTax` is a STORAGE mode — it says which of `price` /
5
+ * `priceWithTax` the merchant typed in, not which one this shopper should be
6
+ * quoted. Those differ in real shops: US sales tax varies by state and even by
7
+ * district, so a US shopper must never be quoted a tax-inclusive price, and
8
+ * Dutch B2B buyers work in ex-VAT numbers, while Dutch consumers keep seeing
9
+ * the gross price the law requires. One channel, three audiences.
10
+ *
11
+ * So the engine resolves the mode per request and exposes it as
12
+ * `Query.activeTaxDisplayMode` — that query is the authority, and
13
+ * `client.pricing.getTaxDisplayMode()` is how a storefront reads it. The pure
14
+ * helpers below mirror the engine's rules
15
+ * (`services/vendure/src/tax-display/tax-display-policy.ts`) RULE FOR RULE so a
16
+ * client can preview a mode — a "who sees what" table, an SSR guess before the
17
+ * first round-trip — without one. Change one, change both.
18
+ *
19
+ * The channel policy behind it (three `public: true` Channel customFields, all
20
+ * defaulting to today's behaviour):
21
+ *
22
+ * taxDisplayDefault channel | gross | net (default `channel`)
23
+ * taxDisplayB2b inherit | gross | net (default `inherit`)
24
+ * taxExclusiveCountries JSON ["US"] (default empty)
25
+ */
1
26
  import type { StoreContext, TaxDisplayInputs, TaxDisplayMode, TaxDisplayPolicy } from '../types.js';
27
+ /** Every channel reads this until a merchant changes something. */
2
28
  export declare const DEFAULT_TAX_DISPLAY_POLICY: TaxDisplayPolicy;
29
+ /**
30
+ * The resolved mode for the active shopper. Public, anonymous-safe, and it
31
+ * never errors server-side — a lookup failure there falls back to the channel
32
+ * default rather than failing the request.
33
+ *
34
+ * The answer depends on the request's identity, so the SDK sends it with the
35
+ * same `Authorization` / `x-order-scope` headers as every other call.
36
+ */
3
37
  export declare const ACTIVE_TAX_DISPLAY_MODE = "\n query ActiveTaxDisplayMode {\n activeTaxDisplayMode\n }\n";
38
+ /**
39
+ * Resolve the mode for one shopper — the engine's rule, offline.
40
+ *
41
+ * Precedence — country, then B2B, then the default — and the order is the
42
+ * point. A US dealer is a US shopper first: their state's sales tax is the
43
+ * reason the price cannot be quoted gross, and that reason does not go away
44
+ * because they also happen to be a trade account.
45
+ *
46
+ * This is a PREVIEW. `getTaxDisplayMode()` is what a storefront renders from;
47
+ * only the server knows the shopper's resolved country (active order shipping
48
+ * address, else their default shipping address).
49
+ */
4
50
  export declare function resolveTaxDisplayMode(policy: TaxDisplayPolicy, inputs: TaxDisplayInputs): TaxDisplayMode;
51
+ /**
52
+ * Read the policy off `activeChannel.customFields`. LENIENT by design: an
53
+ * unreadable value degrades to the pre-policy default rather than throwing
54
+ * while a catalogue page renders. The dashboard's write-side validation is what
55
+ * stops a bad value being stored.
56
+ */
5
57
  export declare function parseTaxDisplayPolicy(fields: unknown): TaxDisplayPolicy;
58
+ /**
59
+ * The tax-exclusive country list, normalised to upper-case alpha-2 with
60
+ * duplicates dropped. Anything unreadable is an EMPTY list — the rule is
61
+ * opt-in, so falling open means "no country override", never "every country".
62
+ */
6
63
  export declare function parseTaxExclusiveCountries(raw: unknown): readonly string[];
64
+ /**
65
+ * Map the Shop API enum (`GROSS` / `NET`, upper-case like `OrderScope`) to the
66
+ * SDK's lower-case union. Returns `null` for anything else — an engine that
67
+ * predates the enum, a null, a typo — so the caller can fall back to the
68
+ * channel storage mode instead of rendering a guess.
69
+ */
7
70
  export declare function taxDisplayModeFromEnum(value: unknown): TaxDisplayMode | null;
71
+ /**
72
+ * Identity fingerprint of the current request context — the cache key for a
73
+ * resolved mode.
74
+ *
75
+ * The mode is a function of WHO is asking: the session (`Authorization`) and
76
+ * the storefront scope (`x-order-scope`) are the two things the SDK can change
77
+ * mid-session that also change the answer. Sign in, sign out, or switch to the
78
+ * trade portal and the stamp changes, so the next read re-resolves instead of
79
+ * showing the previous shopper's mode.
80
+ *
81
+ * A country change is the one non-identity input that can flip the mode; it is
82
+ * handled by clearing the cache in `setShippingAddress`, since the stamp cannot
83
+ * see it.
84
+ */
8
85
  export declare function identityStamp(ctx: Pick<StoreContext, 'authToken' | 'orderScope'>): string;
9
86
  //# sourceMappingURL=tax-display.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tax-display.d.ts","sourceRoot":"","sources":["../../src/pricing/tax-display.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EACV,YAAY,EAGZ,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAYrB,eAAO,MAAM,0BAA0B,EAAE,gBAIxC,CAAC;AAUF,eAAO,MAAM,uBAAuB,sEAInC,CAAC;AAyBF,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,gBAAgB,GACvB,cAAc,CAShB;AAQD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,gBAAgB,CAWvE;AAOD,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAoB1E;AAQD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAM5E;AAgBD,wBAAgB,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,YAAY,EAAE,WAAW,GAAG,YAAY,CAAC,GAAG,MAAM,CAEzF"}
1
+ {"version":3,"file":"tax-display.d.ts","sourceRoot":"","sources":["../../src/pricing/tax-display.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EACV,YAAY,EAGZ,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAWrB,mEAAmE;AACnE,eAAO,MAAM,0BAA0B,EAAE,gBAIxC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,sEAInC,CAAC;AAaF;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,gBAAgB,GACvB,cAAc,CAShB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,gBAAgB,CAWvE;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAoB1E;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAM5E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,YAAY,EAAE,WAAW,GAAG,YAAY,CAAC,GAAG,MAAM,CAEzF"}
@@ -1,22 +1,76 @@
1
+ /**
2
+ * Which tax figure a shopper sees: incl. (`gross`) or excl. (`net`) tax.
3
+ *
4
+ * `Channel.pricesIncludeTax` is a STORAGE mode — it says which of `price` /
5
+ * `priceWithTax` the merchant typed in, not which one this shopper should be
6
+ * quoted. Those differ in real shops: US sales tax varies by state and even by
7
+ * district, so a US shopper must never be quoted a tax-inclusive price, and
8
+ * Dutch B2B buyers work in ex-VAT numbers, while Dutch consumers keep seeing
9
+ * the gross price the law requires. One channel, three audiences.
10
+ *
11
+ * So the engine resolves the mode per request and exposes it as
12
+ * `Query.activeTaxDisplayMode` — that query is the authority, and
13
+ * `client.pricing.getTaxDisplayMode()` is how a storefront reads it. The pure
14
+ * helpers below mirror the engine's rules
15
+ * (`services/vendure/src/tax-display/tax-display-policy.ts`) RULE FOR RULE so a
16
+ * client can preview a mode — a "who sees what" table, an SSR guess before the
17
+ * first round-trip — without one. Change one, change both.
18
+ *
19
+ * The channel policy behind it (three `public: true` Channel customFields, all
20
+ * defaulting to today's behaviour):
21
+ *
22
+ * taxDisplayDefault channel | gross | net (default `channel`)
23
+ * taxDisplayB2b inherit | gross | net (default `inherit`)
24
+ * taxExclusiveCountries JSON ["US"] (default empty)
25
+ */
26
+ /** ISO-3166 alpha-2: exactly two ASCII letters. */
1
27
  const ALPHA2 = /^[A-Za-z]{2}$/;
28
+ /** Channel-wide default. `channel` follows `Channel.pricesIncludeTax`. */
2
29
  const TAX_DISPLAY_DEFAULTS = ['channel', 'gross', 'net'];
30
+ /** B2B override. `inherit` leaves B2B shoppers on the channel default. */
3
31
  const TAX_DISPLAY_B2B_MODES = ['inherit', 'gross', 'net'];
32
+ /** Every channel reads this until a merchant changes something. */
4
33
  export const DEFAULT_TAX_DISPLAY_POLICY = {
5
34
  default: 'channel',
6
35
  b2b: 'inherit',
7
36
  countries: [],
8
37
  };
38
+ /**
39
+ * The resolved mode for the active shopper. Public, anonymous-safe, and it
40
+ * never errors server-side — a lookup failure there falls back to the channel
41
+ * default rather than failing the request.
42
+ *
43
+ * The answer depends on the request's identity, so the SDK sends it with the
44
+ * same `Authorization` / `x-order-scope` headers as every other call.
45
+ */
9
46
  export const ACTIVE_TAX_DISPLAY_MODE = `
10
47
  query ActiveTaxDisplayMode {
11
48
  activeTaxDisplayMode
12
49
  }
13
50
  `;
51
+ /**
52
+ * Trim and upper-case one country code, or `null` when it is not a plausible
53
+ * alpha-2 code. Applied to both the stored list and the country being judged,
54
+ * so `"us"` and `" US "` can never disagree with `"US"`.
55
+ */
14
56
  function normalizeCountryCode(raw) {
15
57
  if (typeof raw !== 'string')
16
58
  return null;
17
59
  const trimmed = raw.trim();
18
60
  return ALPHA2.test(trimmed) ? trimmed.toUpperCase() : null;
19
61
  }
62
+ /**
63
+ * Resolve the mode for one shopper — the engine's rule, offline.
64
+ *
65
+ * Precedence — country, then B2B, then the default — and the order is the
66
+ * point. A US dealer is a US shopper first: their state's sales tax is the
67
+ * reason the price cannot be quoted gross, and that reason does not go away
68
+ * because they also happen to be a trade account.
69
+ *
70
+ * This is a PREVIEW. `getTaxDisplayMode()` is what a storefront renders from;
71
+ * only the server knows the shopper's resolved country (active order shipping
72
+ * address, else their default shipping address).
73
+ */
20
74
  export function resolveTaxDisplayMode(policy, inputs) {
21
75
  const country = normalizeCountryCode(inputs.countryCode);
22
76
  if (country !== null && policy.countries.includes(country))
@@ -27,6 +81,12 @@ export function resolveTaxDisplayMode(policy, inputs) {
27
81
  return policy.default;
28
82
  return inputs.pricesIncludeTax ? 'gross' : 'net';
29
83
  }
84
+ /**
85
+ * Read the policy off `activeChannel.customFields`. LENIENT by design: an
86
+ * unreadable value degrades to the pre-policy default rather than throwing
87
+ * while a catalogue page renders. The dashboard's write-side validation is what
88
+ * stops a bad value being stored.
89
+ */
30
90
  export function parseTaxDisplayPolicy(fields) {
31
91
  const raw = (fields ?? {});
32
92
  return {
@@ -35,6 +95,11 @@ export function parseTaxDisplayPolicy(fields) {
35
95
  countries: parseTaxExclusiveCountries(raw.taxExclusiveCountries),
36
96
  };
37
97
  }
98
+ /**
99
+ * The tax-exclusive country list, normalised to upper-case alpha-2 with
100
+ * duplicates dropped. Anything unreadable is an EMPTY list — the rule is
101
+ * opt-in, so falling open means "no country override", never "every country".
102
+ */
38
103
  export function parseTaxExclusiveCountries(raw) {
39
104
  if (typeof raw !== 'string')
40
105
  return [];
@@ -59,6 +124,12 @@ export function parseTaxExclusiveCountries(raw) {
59
124
  }
60
125
  return codes;
61
126
  }
127
+ /**
128
+ * Map the Shop API enum (`GROSS` / `NET`, upper-case like `OrderScope`) to the
129
+ * SDK's lower-case union. Returns `null` for anything else — an engine that
130
+ * predates the enum, a null, a typo — so the caller can fall back to the
131
+ * channel storage mode instead of rendering a guess.
132
+ */
62
133
  export function taxDisplayModeFromEnum(value) {
63
134
  if (typeof value !== 'string')
64
135
  return null;
@@ -69,6 +140,20 @@ export function taxDisplayModeFromEnum(value) {
69
140
  return 'net';
70
141
  return null;
71
142
  }
143
+ /**
144
+ * Identity fingerprint of the current request context — the cache key for a
145
+ * resolved mode.
146
+ *
147
+ * The mode is a function of WHO is asking: the session (`Authorization`) and
148
+ * the storefront scope (`x-order-scope`) are the two things the SDK can change
149
+ * mid-session that also change the answer. Sign in, sign out, or switch to the
150
+ * trade portal and the stamp changes, so the next read re-resolves instead of
151
+ * showing the previous shopper's mode.
152
+ *
153
+ * A country change is the one non-identity input that can flip the mode; it is
154
+ * handled by clearing the cache in `setShippingAddress`, since the stamp cannot
155
+ * see it.
156
+ */
72
157
  export function identityStamp(ctx) {
73
158
  return `${ctx.authToken ?? ''}|${ctx.orderScope ?? ''}`;
74
159
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tax-display.js","sourceRoot":"","sources":["../../src/pricing/tax-display.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tax-display.js","sourceRoot":"","sources":["../../src/pricing/tax-display.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,13 @@
1
1
  import type { PriceTier, TierTableEntry, VariantPriceData } from '../types.js';
2
+ /**
3
+ * Find the active price tier for a given quantity.
4
+ * Tiers are matched by the highest minQuantity that does not exceed the given quantity.
5
+ * Returns null if no tiers or quantity is below all thresholds.
6
+ */
2
7
  export declare function getTierForQuantity(tiers: PriceTier[], quantity: number): PriceTier | null;
8
+ /**
9
+ * Build a tier table with savings percentages relative to the retail price.
10
+ * If no retail price is available, savings are computed relative to the variant's base price.
11
+ */
3
12
  export declare function computeTierTable(variant: VariantPriceData): TierTableEntry[];
4
13
  //# sourceMappingURL=tiers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tiers.d.ts","sourceRoot":"","sources":["../../src/pricing/tiers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAO/E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAYzF;AAMD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,cAAc,EAAE,CAkB5E"}
1
+ {"version":3,"file":"tiers.d.ts","sourceRoot":"","sources":["../../src/pricing/tiers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/E;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAYzF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,cAAc,EAAE,CAkB5E"}
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Find the active price tier for a given quantity.
3
+ * Tiers are matched by the highest minQuantity that does not exceed the given quantity.
4
+ * Returns null if no tiers or quantity is below all thresholds.
5
+ */
1
6
  export function getTierForQuantity(tiers, quantity) {
2
7
  if (!tiers.length)
3
8
  return null;
@@ -11,6 +16,10 @@ export function getTierForQuantity(tiers, quantity) {
11
16
  }
12
17
  return matched;
13
18
  }
19
+ /**
20
+ * Build a tier table with savings percentages relative to the retail price.
21
+ * If no retail price is available, savings are computed relative to the variant's base price.
22
+ */
14
23
  export function computeTierTable(variant) {
15
24
  const tiers = variant.priceTiers;
16
25
  if (!tiers?.length)
@@ -1 +1 @@
1
- {"version":3,"file":"tiers.js","sourceRoot":"","sources":["../../src/pricing/tiers.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,kBAAkB,CAAC,KAAkB,EAAE,QAAgB;IACrE,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAE/B,IAAI,OAAO,GAAqB,IAAI,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,QAAQ,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACjC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;gBACvD,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAMD,MAAM,UAAU,gBAAgB,CAAC,OAAyB;IACxD,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC;IACjC,IAAI,CAAC,KAAK,EAAE,MAAM;QAAE,OAAO,EAAE,CAAC;IAE9B,MAAM,cAAc,GAAG,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,KAAK,CAAC;IAC5D,IAAI,cAAc,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAEnC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1B,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,OAAO,EAAE,OAAO,CAAC,cAAc,EAAE,KAAK,IAAI,IAAI;QAC9C,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,iBAAiB,EACf,cAAc,GAAG,CAAC;YAChB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,cAAc,CAAC,GAAG,GAAG,CAAC;YACpE,CAAC,CAAC,IAAI;KACX,CAAC,CAAC,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"tiers.js","sourceRoot":"","sources":["../../src/pricing/tiers.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAkB,EAAE,QAAgB;IACrE,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAE/B,IAAI,OAAO,GAAqB,IAAI,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,QAAQ,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACjC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;gBACvD,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAyB;IACxD,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC;IACjC,IAAI,CAAC,KAAK,EAAE,MAAM;QAAE,OAAO,EAAE,CAAC;IAE9B,MAAM,cAAc,GAAG,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,KAAK,CAAC;IAC5D,IAAI,cAAc,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAEnC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1B,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,OAAO,EAAE,OAAO,CAAC,cAAc,EAAE,KAAK,IAAI,IAAI;QAC9C,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,iBAAiB,EACf,cAAc,GAAG,CAAC;YAChB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,cAAc,CAAC,GAAG,GAAG,CAAC;YACpE,CAAC,CAAC,IAAI;KACX,CAAC,CAAC,CAAC;AACN,CAAC"}
@@ -1,14 +1,69 @@
1
- import type { OrderValidationResult } from '../types.js';
1
+ import type { OrderableStockInput, OrderValidationResult } from '../types.js';
2
+ /**
3
+ * Validate an order against the channel's order minimums.
4
+ * Call before `transitionToArrangingPayment()` to provide early feedback.
5
+ *
6
+ * Pass the object from `getOrderConstraints()` straight through — its
7
+ * `minOrderAmountGross` / `minOrderQuantity` fields are read directly:
8
+ *
9
+ * ```ts
10
+ * const constraints = await client.checkout.getOrderConstraints();
11
+ * const result = client.pricing.validateOrderMinimums(order, constraints);
12
+ * ```
13
+ *
14
+ * The server enforces both minimums at the transition regardless, and its
15
+ * message may name the price list that binds ("Minimum order for Wholesale
16
+ * is …"), which the client cannot know. Display the server's message as-is on
17
+ * failure; these messages are for the pre-checkout shortfall hint.
18
+ */
2
19
  export declare function validateOrderMinimums(order: {
3
20
  totalWithTax: number;
4
21
  currencyCode: string;
5
22
  totalQuantity?: number;
23
+ /**
24
+ * Net (tax-exclusive) total, minor units. Only needed when the channel
25
+ * returns `minOrderAmountNet`; `subTotal` is preferred over `total` because
26
+ * the server compares line totals, which exclude shipping.
27
+ */
6
28
  subTotal?: number;
7
29
  total?: number;
8
30
  }, constraints: {
31
+ /** Minimum vs the GROSS order total, minor units. As returned by `getOrderConstraints()`. */
9
32
  minOrderAmountGross?: number | null;
33
+ /**
34
+ * Minimum vs the NET order total, minor units. Independent of the gross
35
+ * minimum — both bind. As returned by `getOrderConstraints()`.
36
+ */
10
37
  minOrderAmountNet?: number | null;
38
+ /** Minimum total item count. As returned by `getOrderConstraints()`. */
11
39
  minOrderQuantity?: number | null;
40
+ /** @deprecated Use `minOrderAmountGross` — the field `getOrderConstraints()` actually returns. */
12
41
  minOrderAmount?: number | null;
13
42
  }): OrderValidationResult;
43
+ export type { OrderableStockInput };
44
+ /**
45
+ * How many units of a variant the current shopper may put in the cart:
46
+ * `max(0, saleable) + backorderAllowance`.
47
+ *
48
+ * Returns `null` when the channel does not expose stock (`saleable == null`) —
49
+ * the storefront cannot know a ceiling then and should let the server decide,
50
+ * exactly as before backorders existed. A `null` allowance counts as 0, so a
51
+ * shopper the policy does not admit gets plain `saleable`.
52
+ */
53
+ export declare function maxOrderableQuantity(variant: OrderableStockInput): number | null;
54
+ /**
55
+ * Whether a variant is orderable only on backorder: nothing saleable, but an
56
+ * allowance. The signal to label "Backorder" instead of "Out of stock".
57
+ */
58
+ export declare function isBackorderOnly(variant: OrderableStockInput): boolean;
59
+ /**
60
+ * Units of a cart line physical stock will not cover — the "N on backorder"
61
+ * hint BEFORE placement, when `backorderedQuantity` is still 0 — computed the
62
+ * way the server stamps it at placement: `max(0, quantity − max(0, saleable))`.
63
+ *
64
+ * `null` when there is nothing to say: the channel hides stock
65
+ * (`saleable == null` — never read that as 0, or every in-stock line would
66
+ * be "on backorder"), or stock covers the line. Pass the line's variant.
67
+ */
68
+ export declare function backorderedQuantityForCart(variant: Pick<OrderableStockInput, 'saleable'>, quantity: number): number | null;
14
69
  //# sourceMappingURL=validation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/pricing/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAwB,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAoB/E,wBAAgB,qBAAqB,CACnC,KAAK,EAAE;IACL,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IAMvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,EACD,WAAW,EAAE;IAEX,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAKpC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAElC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEjC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,GACA,qBAAqB,CAgDvB"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/pricing/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAwB,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGpG;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE;IACL,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,EACD,WAAW,EAAE;IACX,6FAA6F;IAC7F,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,kGAAkG;IAClG,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,GACA,qBAAqB,CAgDvB;AAED,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAGhF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAErE;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAC9C,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CAIf"}
@@ -1,4 +1,21 @@
1
1
  import { formatPrice } from './format.js';
2
+ /**
3
+ * Validate an order against the channel's order minimums.
4
+ * Call before `transitionToArrangingPayment()` to provide early feedback.
5
+ *
6
+ * Pass the object from `getOrderConstraints()` straight through — its
7
+ * `minOrderAmountGross` / `minOrderQuantity` fields are read directly:
8
+ *
9
+ * ```ts
10
+ * const constraints = await client.checkout.getOrderConstraints();
11
+ * const result = client.pricing.validateOrderMinimums(order, constraints);
12
+ * ```
13
+ *
14
+ * The server enforces both minimums at the transition regardless, and its
15
+ * message may name the price list that binds ("Minimum order for Wholesale
16
+ * is …"), which the client cannot know. Display the server's message as-is on
17
+ * failure; these messages are for the pre-checkout shortfall hint.
18
+ */
2
19
  export function validateOrderMinimums(order, constraints) {
3
20
  const errors = [];
4
21
  const minAmount = constraints.minOrderAmountGross ?? constraints.minOrderAmount;
@@ -10,17 +27,25 @@ export function validateOrderMinimums(order, constraints) {
10
27
  actual: order.totalWithTax,
11
28
  });
12
29
  }
30
+ // A net minimum is checked separately, never folded into the gross one: the
31
+ // two are different bases and converting between them needs a tax rate the
32
+ // client does not have. Both can fail on the same cart.
13
33
  const minAmountNet = constraints.minOrderAmountNet;
14
34
  const netTotal = order.subTotal ?? order.total;
15
35
  if (minAmountNet != null && minAmountNet > 0 && netTotal != null && netTotal < minAmountNet) {
16
36
  errors.push({
17
37
  type: 'min_amount',
38
+ // Says "excl. tax" so the figure is not read against the gross total the
39
+ // buyer sees on screen, where it would look wrong.
18
40
  message: `Minimum order amount is ${formatPrice(minAmountNet, order.currencyCode)} excl. tax`,
19
41
  required: minAmountNet,
20
42
  actual: netTotal,
21
43
  });
22
44
  }
23
45
  const minQuantity = constraints.minOrderQuantity;
46
+ // `totalQuantity` is optional so a caller passing only totals still validates
47
+ // the amount. Skipping the quantity check when it is absent is correct;
48
+ // silently failing it against `undefined` would not be.
24
49
  if (minQuantity != null &&
25
50
  minQuantity > 0 &&
26
51
  order.totalQuantity != null &&
@@ -34,4 +59,40 @@ export function validateOrderMinimums(order, constraints) {
34
59
  }
35
60
  return { valid: errors.length === 0, errors };
36
61
  }
62
+ /**
63
+ * How many units of a variant the current shopper may put in the cart:
64
+ * `max(0, saleable) + backorderAllowance`.
65
+ *
66
+ * Returns `null` when the channel does not expose stock (`saleable == null`) —
67
+ * the storefront cannot know a ceiling then and should let the server decide,
68
+ * exactly as before backorders existed. A `null` allowance counts as 0, so a
69
+ * shopper the policy does not admit gets plain `saleable`.
70
+ */
71
+ export function maxOrderableQuantity(variant) {
72
+ if (variant.saleable == null)
73
+ return null;
74
+ return Math.max(0, variant.saleable) + Math.max(0, variant.backorderAllowance ?? 0);
75
+ }
76
+ /**
77
+ * Whether a variant is orderable only on backorder: nothing saleable, but an
78
+ * allowance. The signal to label "Backorder" instead of "Out of stock".
79
+ */
80
+ export function isBackorderOnly(variant) {
81
+ return (variant.saleable ?? 0) <= 0 && (variant.backorderAllowance ?? 0) > 0;
82
+ }
83
+ /**
84
+ * Units of a cart line physical stock will not cover — the "N on backorder"
85
+ * hint BEFORE placement, when `backorderedQuantity` is still 0 — computed the
86
+ * way the server stamps it at placement: `max(0, quantity − max(0, saleable))`.
87
+ *
88
+ * `null` when there is nothing to say: the channel hides stock
89
+ * (`saleable == null` — never read that as 0, or every in-stock line would
90
+ * be "on backorder"), or stock covers the line. Pass the line's variant.
91
+ */
92
+ export function backorderedQuantityForCart(variant, quantity) {
93
+ if (variant.saleable == null)
94
+ return null;
95
+ const units = Math.max(0, quantity - Math.max(0, variant.saleable));
96
+ return units > 0 ? units : null;
97
+ }
37
98
  //# sourceMappingURL=validation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/pricing/validation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAmB1C,MAAM,UAAU,qBAAqB,CACnC,KAWC,EACD,WAYC;IAED,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,MAAM,SAAS,GAAG,WAAW,CAAC,mBAAmB,IAAI,WAAW,CAAC,cAAc,CAAC;IAChF,IAAI,SAAS,IAAI,IAAI,IAAI,SAAS,GAAG,CAAC,IAAI,KAAK,CAAC,YAAY,GAAG,SAAS,EAAE,CAAC;QACzE,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,YAAY;YAClB,OAAO,EAAE,2BAA2B,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC,EAAE;YAChF,QAAQ,EAAE,SAAS;YACnB,MAAM,EAAE,KAAK,CAAC,YAAY;SAC3B,CAAC,CAAC;IACL,CAAC;IAKD,MAAM,YAAY,GAAG,WAAW,CAAC,iBAAiB,CAAC;IACnD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC;IAC/C,IAAI,YAAY,IAAI,IAAI,IAAI,YAAY,GAAG,CAAC,IAAI,QAAQ,IAAI,IAAI,IAAI,QAAQ,GAAG,YAAY,EAAE,CAAC;QAC5F,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,YAAY;YAGlB,OAAO,EAAE,2BAA2B,WAAW,CAAC,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC,YAAY;YAC7F,QAAQ,EAAE,YAAY;YACtB,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,WAAW,GAAG,WAAW,CAAC,gBAAgB,CAAC;IAIjD,IACE,WAAW,IAAI,IAAI;QACnB,WAAW,GAAG,CAAC;QACf,KAAK,CAAC,aAAa,IAAI,IAAI;QAC3B,KAAK,CAAC,aAAa,GAAG,WAAW,EACjC,CAAC;QACD,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,6BAA6B,WAAW,QAAQ;YACzD,QAAQ,EAAE,WAAW;YACrB,MAAM,EAAE,KAAK,CAAC,aAAa;SAC5B,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;AAChD,CAAC"}
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/pricing/validation.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import type { StoreContext } from '../types.js';
2
2
  import type { RedirectStore, RedirectStoreConfig } from './types.js';
3
+ /** Wire a redirect store from an initialized client's context. */
3
4
  export declare function createRedirectsModule(ctx: StoreContext, options?: Pick<RedirectStoreConfig, 'ttlMs' | 'timeoutMs' | 'onError'>): RedirectStore;
4
5
  export { createRedirectStore, normalizeLookupPath } from './store.js';
5
6
  export { REDIRECT_STATUS_CODES, type RedirectMatch, type RedirectRule, type RedirectSnapshot, type RedirectStatusCode, type RedirectStore, type RedirectStoreConfig, } from './types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/redirects/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGrE,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,YAAY,EACjB,OAAO,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,CAAC,GACrE,aAAa,CAOf;AAED,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EACL,qBAAqB,EACrB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,mBAAmB,GACzB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/redirects/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAErE,kEAAkE;AAClE,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,YAAY,EACjB,OAAO,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,CAAC,GACrE,aAAa,CAOf;AAED,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EACL,qBAAqB,EACrB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,mBAAmB,GACzB,MAAM,YAAY,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { createRedirectStore } from './store.js';
2
+ /** Wire a redirect store from an initialized client's context. */
2
3
  export function createRedirectsModule(ctx, options) {
3
4
  return createRedirectStore({
4
5
  storeCode: ctx.channel.code,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/redirects/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAIjD,MAAM,UAAU,qBAAqB,CACnC,GAAiB,EACjB,OAAsE;IAEtE,OAAO,mBAAmB,CAAC;QACzB,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI;QAC3B,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,GAAG,OAAO;KACX,CAAC,CAAC;AACL,CAAC;AAED,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EACL,qBAAqB,GAOtB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/redirects/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGjD,kEAAkE;AAClE,MAAM,UAAU,qBAAqB,CACnC,GAAiB,EACjB,OAAsE;IAEtE,OAAO,mBAAmB,CAAC;QACzB,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI;QAC3B,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,GAAG,OAAO;KACX,CAAC,CAAC;AACL,CAAC;AAED,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EACL,qBAAqB,GAOtB,MAAM,YAAY,CAAC"}
@@ -1,4 +1,24 @@
1
+ /**
2
+ * In-process redirect map for a storefront.
3
+ *
4
+ * Fetches the platform's public per-channel snapshot once per TTL and matches
5
+ * pathnames against it in memory, so a middleware costs a Map lookup rather
6
+ * than a network hop. Revalidation is ETag-conditional: an unchanged map comes
7
+ * back as a 304 with no body.
8
+ *
9
+ * Deliberately fail-open — a refresh failure keeps the last good map in service
10
+ * and reports through `onError` rather than throwing. A platform blip must not
11
+ * turn a tenant's working redirects into 404s.
12
+ *
13
+ * Only the FIRST load is awaited. Once a map exists, revalidation happens in the
14
+ * background and callers are served the current one: this runs in middleware
15
+ * ahead of every page render, so a slow platform must never become a slow store.
16
+ */
1
17
  import { type RedirectStore, type RedirectStoreConfig } from './types.js';
18
+ /**
19
+ * Match the platform's own source normalization: trailing slashes are stripped
20
+ * so `/a` and `/a/` are the same rule. The root path keeps its slash.
21
+ */
2
22
  export declare function normalizeLookupPath(pathname: string): string;
3
23
  export declare function createRedirectStore(config: RedirectStoreConfig): RedirectStore;
4
24
  //# sourceMappingURL=store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/redirects/store.ts"],"names":[],"mappings":"AAkBA,OAAO,EAML,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACzB,MAAM,YAAY,CAAC;AA2BpB,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAe5D;AAsCD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CA+J9E"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/redirects/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAML,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACzB,MAAM,YAAY,CAAC;AAuBpB;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAe5D;AAsCD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CA+J9E"}