@sixtyninecommerce/client 0.30.0 → 0.32.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 (361) hide show
  1. package/README.md +574 -14
  2. package/dist/admin/http.d.ts.map +1 -1
  3. package/dist/admin/http.js.map +1 -1
  4. package/dist/admin/types.d.ts.map +1 -1
  5. package/dist/build-client.d.ts +9 -0
  6. package/dist/build-client.d.ts.map +1 -0
  7. package/dist/build-client.js +58 -0
  8. package/dist/build-client.js.map +1 -0
  9. package/dist/cache-tags.d.ts +35 -1
  10. package/dist/cache-tags.d.ts.map +1 -1
  11. package/dist/cache-tags.js +39 -1
  12. package/dist/cache-tags.js.map +1 -1
  13. package/dist/client.d.ts +25 -0
  14. package/dist/client.d.ts.map +1 -1
  15. package/dist/client.js +9 -62
  16. package/dist/client.js.map +1 -1
  17. package/dist/commerce/age-verification.d.ts +7 -4
  18. package/dist/commerce/age-verification.d.ts.map +1 -1
  19. package/dist/commerce/age-verification.js +6 -4
  20. package/dist/commerce/age-verification.js.map +1 -1
  21. package/dist/commerce/arguments.d.ts +13 -0
  22. package/dist/commerce/arguments.d.ts.map +1 -0
  23. package/dist/commerce/arguments.js +19 -0
  24. package/dist/commerce/arguments.js.map +1 -0
  25. package/dist/commerce/branding.d.ts.map +1 -1
  26. package/dist/commerce/branding.js.map +1 -1
  27. package/dist/commerce/capabilities.d.ts +40 -0
  28. package/dist/commerce/capabilities.d.ts.map +1 -0
  29. package/dist/commerce/capabilities.js +41 -0
  30. package/dist/commerce/capabilities.js.map +1 -0
  31. package/dist/commerce/cart.d.ts +9 -12
  32. package/dist/commerce/cart.d.ts.map +1 -1
  33. package/dist/commerce/cart.js +6 -1
  34. package/dist/commerce/cart.js.map +1 -1
  35. package/dist/commerce/checkout.d.ts +95 -15
  36. package/dist/commerce/checkout.d.ts.map +1 -1
  37. package/dist/commerce/checkout.js +230 -10
  38. package/dist/commerce/checkout.js.map +1 -1
  39. package/dist/commerce/customer.d.ts +83 -38
  40. package/dist/commerce/customer.d.ts.map +1 -1
  41. package/dist/commerce/customer.js +149 -10
  42. package/dist/commerce/customer.js.map +1 -1
  43. package/dist/commerce/favorites.d.ts +2 -5
  44. package/dist/commerce/favorites.d.ts.map +1 -1
  45. package/dist/commerce/favorites.js.map +1 -1
  46. package/dist/commerce/index.d.ts +194 -133
  47. package/dist/commerce/index.d.ts.map +1 -1
  48. package/dist/commerce/index.js +15 -0
  49. package/dist/commerce/index.js.map +1 -1
  50. package/dist/commerce/order-states.d.ts +18 -0
  51. package/dist/commerce/order-states.d.ts.map +1 -0
  52. package/dist/commerce/order-states.js +30 -0
  53. package/dist/commerce/order-states.js.map +1 -0
  54. package/dist/commerce/parcel-pricing.d.ts +48 -0
  55. package/dist/commerce/parcel-pricing.d.ts.map +1 -0
  56. package/dist/commerce/parcel-pricing.js +39 -0
  57. package/dist/commerce/parcel-pricing.js.map +1 -0
  58. package/dist/commerce/parked-orders.d.ts +22 -0
  59. package/dist/commerce/parked-orders.d.ts.map +1 -0
  60. package/dist/commerce/parked-orders.js +47 -0
  61. package/dist/commerce/parked-orders.js.map +1 -0
  62. package/dist/commerce/payments.d.ts +12 -5
  63. package/dist/commerce/payments.d.ts.map +1 -1
  64. package/dist/commerce/payments.js +10 -1
  65. package/dist/commerce/payments.js.map +1 -1
  66. package/dist/commerce/placement-error.d.ts +17 -0
  67. package/dist/commerce/placement-error.d.ts.map +1 -1
  68. package/dist/commerce/placement-error.js.map +1 -1
  69. package/dist/commerce/products.d.ts +92 -38
  70. package/dist/commerce/products.d.ts.map +1 -1
  71. package/dist/commerce/products.js +157 -123
  72. package/dist/commerce/products.js.map +1 -1
  73. package/dist/commerce/queries.d.ts +216 -49
  74. package/dist/commerce/queries.d.ts.map +1 -1
  75. package/dist/commerce/queries.js +1347 -743
  76. package/dist/commerce/queries.js.map +1 -1
  77. package/dist/commerce/quotes.d.ts +5 -4
  78. package/dist/commerce/quotes.d.ts.map +1 -1
  79. package/dist/commerce/quotes.js +1 -36
  80. package/dist/commerce/quotes.js.map +1 -1
  81. package/dist/commerce/receipt-claim.d.ts +35 -0
  82. package/dist/commerce/receipt-claim.d.ts.map +1 -0
  83. package/dist/commerce/receipt-claim.js +66 -0
  84. package/dist/commerce/receipt-claim.js.map +1 -0
  85. package/dist/commerce/recommendations.d.ts +3 -3
  86. package/dist/commerce/recommendations.d.ts.map +1 -1
  87. package/dist/commerce/recommendations.js +3 -1
  88. package/dist/commerce/recommendations.js.map +1 -1
  89. package/dist/commerce/returns.d.ts +7 -6
  90. package/dist/commerce/returns.d.ts.map +1 -1
  91. package/dist/commerce/returns.js +24 -3
  92. package/dist/commerce/returns.js.map +1 -1
  93. package/dist/commerce/reviews.d.ts +24 -15
  94. package/dist/commerce/reviews.d.ts.map +1 -1
  95. package/dist/commerce/reviews.js +67 -50
  96. package/dist/commerce/reviews.js.map +1 -1
  97. package/dist/commerce/saved-lists.d.ts +15 -15
  98. package/dist/commerce/saved-lists.d.ts.map +1 -1
  99. package/dist/commerce/saved-lists.js +67 -56
  100. package/dist/commerce/saved-lists.js.map +1 -1
  101. package/dist/commerce/search.d.ts +3 -2
  102. package/dist/commerce/search.d.ts.map +1 -1
  103. package/dist/commerce/search.js +2 -2
  104. package/dist/commerce/search.js.map +1 -1
  105. package/dist/commerce/shipping.d.ts +11 -4
  106. package/dist/commerce/shipping.d.ts.map +1 -1
  107. package/dist/commerce/shipping.js +17 -2
  108. package/dist/commerce/shipping.js.map +1 -1
  109. package/dist/commerce/stock-notifications.d.ts +2 -0
  110. package/dist/commerce/stock-notifications.d.ts.map +1 -1
  111. package/dist/commerce/stock-notifications.js +2 -2
  112. package/dist/commerce/stock-notifications.js.map +1 -1
  113. package/dist/commerce/store-pickup.d.ts +37 -0
  114. package/dist/commerce/store-pickup.d.ts.map +1 -0
  115. package/dist/commerce/store-pickup.js +66 -0
  116. package/dist/commerce/store-pickup.js.map +1 -0
  117. package/dist/commerce/subscriptions.d.ts +35 -37
  118. package/dist/commerce/subscriptions.d.ts.map +1 -1
  119. package/dist/commerce/subscriptions.js +159 -120
  120. package/dist/commerce/subscriptions.js.map +1 -1
  121. package/dist/commerce/vat-validation.d.ts +6 -3
  122. package/dist/commerce/vat-validation.d.ts.map +1 -1
  123. package/dist/commerce/vat-validation.js +24 -19
  124. package/dist/commerce/vat-validation.js.map +1 -1
  125. package/dist/constants.d.ts.map +1 -1
  126. package/dist/constants.js.map +1 -1
  127. package/dist/content/assets.d.ts +5 -4
  128. package/dist/content/assets.d.ts.map +1 -1
  129. package/dist/content/assets.js.map +1 -1
  130. package/dist/content/collection-pages.d.ts +3 -2
  131. package/dist/content/collection-pages.d.ts.map +1 -1
  132. package/dist/content/collection-pages.js.map +1 -1
  133. package/dist/content/collections.d.ts +5 -4
  134. package/dist/content/collections.d.ts.map +1 -1
  135. package/dist/content/collections.js.map +1 -1
  136. package/dist/content/filtered-products.d.ts.map +1 -1
  137. package/dist/content/filtered-products.js.map +1 -1
  138. package/dist/content/form-field-types.d.ts +3 -3
  139. package/dist/content/form-field-types.d.ts.map +1 -1
  140. package/dist/content/form-field-types.js.map +1 -1
  141. package/dist/content/forms.d.ts +4 -3
  142. package/dist/content/forms.d.ts.map +1 -1
  143. package/dist/content/forms.js +3 -0
  144. package/dist/content/forms.js.map +1 -1
  145. package/dist/content/index.d.ts +18 -17
  146. package/dist/content/index.d.ts.map +1 -1
  147. package/dist/content/items.d.ts +5 -4
  148. package/dist/content/items.d.ts.map +1 -1
  149. package/dist/content/items.js +2 -0
  150. package/dist/content/items.js.map +1 -1
  151. package/dist/content/menus.d.ts +3 -2
  152. package/dist/content/menus.d.ts.map +1 -1
  153. package/dist/content/menus.js +7 -1
  154. package/dist/content/menus.js.map +1 -1
  155. package/dist/content/resolve.d.ts +3 -2
  156. package/dist/content/resolve.d.ts.map +1 -1
  157. package/dist/content/resolve.js +1 -1
  158. package/dist/content/resolve.js.map +1 -1
  159. package/dist/content/sitemap.d.ts +3 -2
  160. package/dist/content/sitemap.d.ts.map +1 -1
  161. package/dist/content/sitemap.js.map +1 -1
  162. package/dist/content/strings.d.ts +16 -2
  163. package/dist/content/strings.d.ts.map +1 -1
  164. package/dist/content/strings.js +32 -4
  165. package/dist/content/strings.js.map +1 -1
  166. package/dist/core/context.d.ts +127 -1
  167. package/dist/core/context.d.ts.map +1 -1
  168. package/dist/core/context.js +436 -45
  169. package/dist/core/context.js.map +1 -1
  170. package/dist/core/currency.d.ts +14 -0
  171. package/dist/core/currency.d.ts.map +1 -0
  172. package/dist/core/currency.js +52 -0
  173. package/dist/core/currency.js.map +1 -0
  174. package/dist/core/deprecation.d.ts +23 -0
  175. package/dist/core/deprecation.d.ts.map +1 -0
  176. package/dist/core/deprecation.js +81 -0
  177. package/dist/core/deprecation.js.map +1 -0
  178. package/dist/core/http.d.ts +15 -1
  179. package/dist/core/http.d.ts.map +1 -1
  180. package/dist/core/http.js +55 -3
  181. package/dist/core/http.js.map +1 -1
  182. package/dist/core/public-artifact.d.ts +72 -0
  183. package/dist/core/public-artifact.d.ts.map +1 -0
  184. package/dist/core/public-artifact.js +122 -0
  185. package/dist/core/public-artifact.js.map +1 -0
  186. package/dist/core/unknown-field-rejection.d.ts +18 -0
  187. package/dist/core/unknown-field-rejection.d.ts.map +1 -0
  188. package/dist/core/unknown-field-rejection.js +37 -0
  189. package/dist/core/unknown-field-rejection.js.map +1 -0
  190. package/dist/credit/credit-status.d.ts +2 -0
  191. package/dist/credit/credit-status.d.ts.map +1 -1
  192. package/dist/credit/credit-status.js +71 -19
  193. package/dist/credit/credit-status.js.map +1 -1
  194. package/dist/credit/index.d.ts +1 -1
  195. package/dist/credit/payment-terms.d.ts +3 -3
  196. package/dist/credit/payment-terms.d.ts.map +1 -1
  197. package/dist/credit/payment-terms.js +28 -24
  198. package/dist/credit/payment-terms.js.map +1 -1
  199. package/dist/currency/exchange.d.ts +7 -7
  200. package/dist/currency/exchange.d.ts.map +1 -1
  201. package/dist/currency/exchange.js +5 -1
  202. package/dist/currency/exchange.js.map +1 -1
  203. package/dist/errors.d.ts +17 -0
  204. package/dist/errors.d.ts.map +1 -1
  205. package/dist/errors.js +13 -0
  206. package/dist/errors.js.map +1 -1
  207. package/dist/events/index.d.ts +20 -7
  208. package/dist/events/index.d.ts.map +1 -1
  209. package/dist/events/index.js +17 -5
  210. package/dist/events/index.js.map +1 -1
  211. package/dist/events/payloads.d.ts +7 -4
  212. package/dist/events/payloads.d.ts.map +1 -1
  213. package/dist/events/payloads.js +6 -3
  214. package/dist/events/payloads.js.map +1 -1
  215. package/dist/feeds/index.d.ts +5 -0
  216. package/dist/feeds/index.d.ts.map +1 -0
  217. package/dist/feeds/index.js +12 -0
  218. package/dist/feeds/index.js.map +1 -0
  219. package/dist/feeds/types.d.ts +18 -0
  220. package/dist/feeds/types.d.ts.map +1 -0
  221. package/dist/feeds/types.js +8 -0
  222. package/dist/feeds/types.js.map +1 -0
  223. package/dist/generated/cms.d.ts +2136 -0
  224. package/dist/generated/cms.d.ts.map +1 -0
  225. package/dist/generated/cms.js +4 -0
  226. package/dist/generated/cms.js.map +1 -0
  227. package/dist/generated/plugins.d.ts +550 -0
  228. package/dist/generated/plugins.d.ts.map +1 -0
  229. package/dist/generated/plugins.js +4 -0
  230. package/dist/generated/plugins.js.map +1 -0
  231. package/dist/generated/shop.d.ts +5663 -0
  232. package/dist/generated/shop.d.ts.map +1 -0
  233. package/dist/generated/shop.js +5 -0
  234. package/dist/generated/shop.js.map +1 -0
  235. package/dist/graphql-document.d.ts +29 -0
  236. package/dist/graphql-document.d.ts.map +1 -0
  237. package/dist/graphql-document.js +21 -0
  238. package/dist/graphql-document.js.map +1 -0
  239. package/dist/index.d.ts +10 -4
  240. package/dist/index.d.ts.map +1 -1
  241. package/dist/index.js +5 -2
  242. package/dist/index.js.map +1 -1
  243. package/dist/media/urls.d.ts.map +1 -1
  244. package/dist/media/urls.js +12 -1
  245. package/dist/media/urls.js.map +1 -1
  246. package/dist/media/video.d.ts.map +1 -1
  247. package/dist/media/video.js.map +1 -1
  248. package/dist/multi-store.d.ts +200 -0
  249. package/dist/multi-store.d.ts.map +1 -0
  250. package/dist/multi-store.js +558 -0
  251. package/dist/multi-store.js.map +1 -0
  252. package/dist/navigation/routes.d.ts +4 -3
  253. package/dist/navigation/routes.d.ts.map +1 -1
  254. package/dist/navigation/routes.js.map +1 -1
  255. package/dist/next/artifact-handler.d.ts +21 -13
  256. package/dist/next/artifact-handler.d.ts.map +1 -1
  257. package/dist/next/artifact-handler.js +28 -66
  258. package/dist/next/artifact-handler.js.map +1 -1
  259. package/dist/next/event-revalidate-handler.d.ts +26 -6
  260. package/dist/next/event-revalidate-handler.d.ts.map +1 -1
  261. package/dist/next/event-revalidate-handler.js +126 -19
  262. package/dist/next/event-revalidate-handler.js.map +1 -1
  263. package/dist/next/feed-handler.d.ts +50 -0
  264. package/dist/next/feed-handler.d.ts.map +1 -0
  265. package/dist/next/feed-handler.js +61 -0
  266. package/dist/next/feed-handler.js.map +1 -0
  267. package/dist/next/index.d.ts +3 -1
  268. package/dist/next/index.d.ts.map +1 -1
  269. package/dist/next/index.js +1 -0
  270. package/dist/next/index.js.map +1 -1
  271. package/dist/next/metadata.d.ts.map +1 -1
  272. package/dist/next/metadata.js.map +1 -1
  273. package/dist/next/redirect-middleware.d.ts +5 -31
  274. package/dist/next/redirect-middleware.d.ts.map +1 -1
  275. package/dist/next/redirect-middleware.js +4 -46
  276. package/dist/next/redirect-middleware.js.map +1 -1
  277. package/dist/next/revalidate-handler.d.ts.map +1 -1
  278. package/dist/next/revalidate-handler.js.map +1 -1
  279. package/dist/pricing/index.d.ts.map +1 -1
  280. package/dist/pricing/index.js.map +1 -1
  281. package/dist/pricing/tax-display.js +1 -1
  282. package/dist/pricing/tax-display.js.map +1 -1
  283. package/dist/pricing/tiers.d.ts +3 -2
  284. package/dist/pricing/tiers.d.ts.map +1 -1
  285. package/dist/pricing/tiers.js.map +1 -1
  286. package/dist/pricing/validation.d.ts +88 -12
  287. package/dist/pricing/validation.d.ts.map +1 -1
  288. package/dist/pricing/validation.js +93 -12
  289. package/dist/pricing/validation.js.map +1 -1
  290. package/dist/redirects/index.d.ts.map +1 -1
  291. package/dist/redirects/index.js +2 -1
  292. package/dist/redirects/index.js.map +1 -1
  293. package/dist/redirects/store.d.ts.map +1 -1
  294. package/dist/redirects/store.js +6 -2
  295. package/dist/redirects/store.js.map +1 -1
  296. package/dist/redirects/types.d.ts +5 -2
  297. package/dist/redirects/types.d.ts.map +1 -1
  298. package/dist/revalidation/event-plan.d.ts +55 -4
  299. package/dist/revalidation/event-plan.d.ts.map +1 -1
  300. package/dist/revalidation/event-plan.js +115 -8
  301. package/dist/revalidation/event-plan.js.map +1 -1
  302. package/dist/revalidation/event-verify.d.ts +8 -37
  303. package/dist/revalidation/event-verify.d.ts.map +1 -1
  304. package/dist/revalidation/event-verify.js +7 -97
  305. package/dist/revalidation/event-verify.js.map +1 -1
  306. package/dist/revalidation/types.d.ts.map +1 -1
  307. package/dist/revalidation/url-context.d.ts +17 -0
  308. package/dist/revalidation/url-context.d.ts.map +1 -1
  309. package/dist/revalidation/url-context.js +35 -2
  310. package/dist/revalidation/url-context.js.map +1 -1
  311. package/dist/seo/ai.d.ts.map +1 -1
  312. package/dist/seo/ai.js.map +1 -1
  313. package/dist/seo/artifacts.d.ts +86 -4
  314. package/dist/seo/artifacts.d.ts.map +1 -1
  315. package/dist/seo/artifacts.js +115 -16
  316. package/dist/seo/artifacts.js.map +1 -1
  317. package/dist/seo/availability.d.ts +2 -2
  318. package/dist/seo/availability.d.ts.map +1 -1
  319. package/dist/seo/availability.js.map +1 -1
  320. package/dist/seo/index.d.ts +2 -0
  321. package/dist/seo/index.d.ts.map +1 -1
  322. package/dist/seo/index.js +3 -1
  323. package/dist/seo/index.js.map +1 -1
  324. package/dist/seo/json-ld.d.ts.map +1 -1
  325. package/dist/seo/json-ld.js.map +1 -1
  326. package/dist/seo/meta-tags.d.ts.map +1 -1
  327. package/dist/seo/meta-tags.js.map +1 -1
  328. package/dist/seo/metadata-parser.d.ts.map +1 -1
  329. package/dist/seo/metadata-parser.js.map +1 -1
  330. package/dist/seo/metadata-types.d.ts.map +1 -1
  331. package/dist/seo/robots.d.ts.map +1 -1
  332. package/dist/seo/robots.js.map +1 -1
  333. package/dist/seo/types.d.ts +9 -2
  334. package/dist/seo/types.d.ts.map +1 -1
  335. package/dist/seo/url-builder.d.ts +5 -3
  336. package/dist/seo/url-builder.d.ts.map +1 -1
  337. package/dist/seo/url-builder.js +3 -1
  338. package/dist/seo/url-builder.js.map +1 -1
  339. package/dist/types.d.ts +1381 -2537
  340. package/dist/types.d.ts.map +1 -1
  341. package/dist/web/artifact-responder.d.ts +69 -0
  342. package/dist/web/artifact-responder.d.ts.map +1 -0
  343. package/dist/web/artifact-responder.js +90 -0
  344. package/dist/web/artifact-responder.js.map +1 -0
  345. package/dist/web/feed-responder.d.ts +72 -0
  346. package/dist/web/feed-responder.d.ts.map +1 -0
  347. package/dist/web/feed-responder.js +81 -0
  348. package/dist/web/feed-responder.js.map +1 -0
  349. package/dist/web/index.d.ts +23 -0
  350. package/dist/web/index.d.ts.map +1 -0
  351. package/dist/web/index.js +19 -0
  352. package/dist/web/index.js.map +1 -0
  353. package/dist/web/redirect-middleware.d.ts +76 -0
  354. package/dist/web/redirect-middleware.d.ts.map +1 -0
  355. package/dist/web/redirect-middleware.js +94 -0
  356. package/dist/web/redirect-middleware.js.map +1 -0
  357. package/dist/web/respond.d.ts +20 -0
  358. package/dist/web/respond.d.ts.map +1 -0
  359. package/dist/web/respond.js +52 -0
  360. package/dist/web/respond.js.map +1 -0
  361. package/package.json +18 -2
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Serve a platform-rendered product feed (Google Shopping, Meta, Pinterest,
3
+ * TikTok) on the storefront's own origin, from any Fetch-API server — the
4
+ * same fetch-and-serve shape as `createSeoArtifactResponder`, so a merchant
5
+ * centre only ever sees the storefront domain.
6
+ *
7
+ * Three deliberate behaviors, shared with `@sixtyninecommerce/client/next`'s
8
+ * `createProductFeedHandler`:
9
+ * - The inbound client User-Agent is NOT forwarded. Merchant centres crawl with
10
+ * bot UAs and the platform host is UA-filtered; it must see the storefront
11
+ * server, not Googlebot.
12
+ * - X-Robots-Tag from the platform host is dropped; Cache-Control is replaced
13
+ * with the storefront's own policy.
14
+ * - The upstream body is BUFFERED before the response is constructed. Streaming
15
+ * it looks cheaper, but the timeout spans the whole transfer: a feed still
16
+ * streaming when the deadline hits aborts MID-BODY, long after the 200 and
17
+ * its `Cache-Control` went out, and the CDN then caches truncated — therefore
18
+ * unparseable — XML for the full `s-maxage`. Buffering makes that same
19
+ * timeout a clean 503 + `Retry-After` that nothing caches. A gzipped catalog
20
+ * feed is a few MB; that is the right price for never serving half a feed.
21
+ */
22
+ import { readPublicArtifact } from '../core/public-artifact.js';
23
+ import { adapterClient } from '../multi-store.js';
24
+ import { failureResponse, notFoundResponse, publicArtifactResponse } from './respond.js';
25
+ export const DEFAULT_FEED_CACHE_CONTROL = 'public, max-age=300, s-maxage=1800, stale-while-revalidate=86400';
26
+ const DEFAULT_TIMEOUT_MS = 30_000;
27
+ /** `arrayBuffer`, not `text`: the bytes go out exactly as the platform encoded them. */
28
+ export function readFeedBytes(response) {
29
+ return response.arrayBuffer();
30
+ }
31
+ /** The responder both entry points build. Internal: the public factories fix the reader. */
32
+ export function buildProductFeedResponder(client, options, missingTokenMessage, read) {
33
+ const cacheControl = options?.cacheControl ?? DEFAULT_FEED_CACHE_CONTROL;
34
+ const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
35
+ return async (request, params) => {
36
+ try {
37
+ // A store router serves each request from the store it resolves to; a
38
+ // request that belongs to no store it serves is a plain 404.
39
+ const resolvedClient = await adapterClient(client, request);
40
+ if (!resolvedClient)
41
+ return notFoundResponse();
42
+ const token = options?.token ?? params?.token;
43
+ if (!token)
44
+ throw new Error(missingTokenMessage);
45
+ const url = resolvedClient.feeds.feedUrl(token);
46
+ const ifNoneMatch = request.headers.get('if-none-match');
47
+ const result = await read(resolvedClient)(url, {
48
+ ...(ifNoneMatch ? { ifNoneMatch } : {}),
49
+ timeoutMs,
50
+ });
51
+ return publicArtifactResponse(result, cacheControl, 'application/xml; charset=utf-8');
52
+ }
53
+ catch (error) {
54
+ return failureResponse(error);
55
+ }
56
+ };
57
+ }
58
+ /**
59
+ * A Fetch-API responder for a product feed. Uses the `fetch` you configured
60
+ * the client with.
61
+ *
62
+ * ```ts
63
+ * import { createProductFeedResponder } from '@sixtyninecommerce/client/web';
64
+ *
65
+ * // GET /product-feed.xml — one fixed feed
66
+ * const feed = createProductFeedResponder(getClient(), { token: process.env.GOOGLE_FEED_TOKEN });
67
+ * // GET /feeds/:token.xml — several feeds off one route
68
+ * const feeds = createProductFeedResponder(getClient());
69
+ * // feeds(request, { token })
70
+ * ```
71
+ *
72
+ * Several stores in one process: pass the store router and each request is
73
+ * proxied from the store it resolves to (a request no store serves is a `404`).
74
+ *
75
+ * Never throws per request: no token or an upstream failure is a `503` with
76
+ * `Retry-After`, an unknown feed a `404`.
77
+ */
78
+ export function createProductFeedResponder(client, options) {
79
+ return buildProductFeedResponder(client, options, 'createProductFeedResponder requires a feed token — pass options.token or params.token', (resolved) => (url, readOptions) => readPublicArtifact(resolved.context.fetch, url, readFeedBytes, readOptions));
80
+ }
81
+ //# sourceMappingURL=feed-responder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feed-responder.js","sourceRoot":"","sources":["../../src/web/feed-responder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAA2B,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACzF,OAAO,EAAE,aAAa,EAAyB,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAuBzF,MAAM,CAAC,MAAM,0BAA0B,GACrC,kEAAkE,CAAC;AAErE,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAUlC,wFAAwF;AACxF,MAAM,UAAU,aAAa,CAAC,QAAkB;IAC9C,OAAO,QAAQ,CAAC,WAAW,EAAE,CAAC;AAChC,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,yBAAyB,CACvC,MAAuE,EACvE,OAAgD,EAChD,mBAA2B,EAC3B,IAAqD;IAErD,MAAM,YAAY,GAAG,OAAO,EAAE,YAAY,IAAI,0BAA0B,CAAC;IACzE,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,kBAAkB,CAAC;IAE3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAqB,EAAE;QAClD,IAAI,CAAC;YACH,sEAAsE;YACtE,6DAA6D;YAC7D,MAAM,cAAc,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC5D,IAAI,CAAC,cAAc;gBAAE,OAAO,gBAAgB,EAAE,CAAC;YAC/C,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,MAAM,EAAE,KAAK,CAAC;YAC9C,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACjD,MAAM,GAAG,GAAG,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAChD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YACzD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,GAAG,EAAE;gBAC7C,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvC,SAAS;aACV,CAAC,CAAC;YACH,OAAO,sBAAsB,CAAC,MAAM,EAAE,YAAY,EAAE,gCAAgC,CAAC,CAAC;QACxF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,0BAA0B,CACxC,MAAuE,EACvE,OAAqC;IAErC,OAAO,yBAAyB,CAC9B,MAAM,EACN,OAAO,EACP,uFAAuF,EACvF,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,WAAW,EAAE,EAAE,CACjC,kBAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,aAAa,EAAE,WAAW,CAAC,CAC9E,CAAC;AACJ,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * `@sixtyninecommerce/client/web` — SEO artifacts, product feeds and redirects
3
+ * for ANY server that speaks the Fetch API (`Request` in, `Response` out): a
4
+ * `node:http` adapter, Remix / React Router, Astro, SvelteKit, Hono, Cloudflare
5
+ * Workers, Deno, Bun. No framework imports; `@sixtyninecommerce/client/next`
6
+ * wraps these same responders and adds Next's cache tags.
7
+ *
8
+ * Each one also takes a store router (`createStorefrontClient({ resolveStore })`)
9
+ * in place of a client and serves every request from the store it resolves to.
10
+ *
11
+ * Every responder is server-side: it holds the client, and a feed token is a
12
+ * shared secret. None sends a credential upstream — the platform files are
13
+ * public.
14
+ */
15
+ export type { SeoArtifact, SeoArtifactResult } from '../seo/artifacts.js';
16
+ export { isSitemapChildFile, SEO_ARTIFACTS } from '../seo/artifacts.js';
17
+ export type { SeoArtifactResponder, SeoArtifactResponderOptions } from './artifact-responder.js';
18
+ export { createSeoArtifactResponder, DEFAULT_ARTIFACT_CACHE_CONTROL, } from './artifact-responder.js';
19
+ export type { ProductFeedResponder, ProductFeedResponderOptions } from './feed-responder.js';
20
+ export { createProductFeedResponder, DEFAULT_FEED_CACHE_CONTROL } from './feed-responder.js';
21
+ export type { MultiStoreRedirectMiddleware, MultiStoreRedirectMiddlewareOptions, RedirectMiddleware, RedirectMiddlewareOptions, } from './redirect-middleware.js';
22
+ export { createRedirectMiddleware } from './redirect-middleware.js';
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/web/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACxE,YAAY,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACjG,OAAO,EACL,0BAA0B,EAC1B,8BAA8B,GAC/B,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAC7F,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAC7F,YAAY,EACV,4BAA4B,EAC5B,mCAAmC,EACnC,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * `@sixtyninecommerce/client/web` — SEO artifacts, product feeds and redirects
3
+ * for ANY server that speaks the Fetch API (`Request` in, `Response` out): a
4
+ * `node:http` adapter, Remix / React Router, Astro, SvelteKit, Hono, Cloudflare
5
+ * Workers, Deno, Bun. No framework imports; `@sixtyninecommerce/client/next`
6
+ * wraps these same responders and adds Next's cache tags.
7
+ *
8
+ * Each one also takes a store router (`createStorefrontClient({ resolveStore })`)
9
+ * in place of a client and serves every request from the store it resolves to.
10
+ *
11
+ * Every responder is server-side: it holds the client, and a feed token is a
12
+ * shared secret. None sends a credential upstream — the platform files are
13
+ * public.
14
+ */
15
+ export { isSitemapChildFile, SEO_ARTIFACTS } from '../seo/artifacts.js';
16
+ export { createSeoArtifactResponder, DEFAULT_ARTIFACT_CACHE_CONTROL, } from './artifact-responder.js';
17
+ export { createProductFeedResponder, DEFAULT_FEED_CACHE_CONTROL } from './feed-responder.js';
18
+ export { createRedirectMiddleware } from './redirect-middleware.js';
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/web/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAExE,OAAO,EACL,0BAA0B,EAC1B,8BAA8B,GAC/B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAO7F,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Middleware factory that applies the tenant's platform-managed redirects, for
3
+ * any Fetch-API server.
4
+ *
5
+ * Framework-neutral by design: it takes a `Request` and returns a plain
6
+ * `Response` — or `undefined`, meaning "carry on with normal routing" — which
7
+ * is exactly what a Next.js middleware, a Hono/Workers handler, a SvelteKit
8
+ * `handle` hook or a `node:http` adapter can use. `@sixtyninecommerce/client/next`
9
+ * re-exports this same function. It never throws — an unmatched path, a cold
10
+ * cache or an unreachable platform all resolve to `undefined`.
11
+ */
12
+ import { type MultiStoreClient } from '../multi-store.js';
13
+ import type { RedirectStore, RedirectStoreConfig } from '../redirects/types.js';
14
+ export interface RedirectMiddlewareOptions extends RedirectStoreConfig {
15
+ /**
16
+ * Carry the incoming query string onto the destination. Default true — a
17
+ * campaign link to a moved page should keep its `utm_*` params. Parameters
18
+ * the destination already sets win.
19
+ *
20
+ * NOTE: this applies to EXTERNAL `https://` destinations too, so the
21
+ * visitor's query string is handed to that third-party origin. If your URLs
22
+ * carry anything you would not want a destination site to see, set this to
23
+ * false — or split those rules onto a middleware instance that has.
24
+ */
25
+ preserveQuery?: boolean;
26
+ }
27
+ export interface RedirectMiddleware {
28
+ /** Returns a redirect Response, or undefined to fall through. */
29
+ (request: Request): Promise<Response | undefined>;
30
+ /** The underlying store — call `refresh()` from a revalidation webhook. */
31
+ readonly store: RedirectStore;
32
+ }
33
+ /** Options of a redirect middleware for several stores in one app. */
34
+ export interface MultiStoreRedirectMiddlewareOptions {
35
+ /** The store router (`createStorefrontClient({ resolveStore })`). */
36
+ client: MultiStoreClient;
37
+ /** See {@link RedirectMiddlewareOptions.preserveQuery}. Default true. */
38
+ preserveQuery?: boolean;
39
+ /**
40
+ * Called when a request's store could not be served — its channel could not
41
+ * be resolved, say — and when any of the router's stores fails to load its
42
+ * redirect map (the store keeps serving its last good map; this is the only
43
+ * signal). The request still falls through to normal routing. A request that
44
+ * belongs to no store (`STORE_NOT_RESOLVED`, …) is not reported.
45
+ */
46
+ onError?: (error: Error) => void;
47
+ }
48
+ /**
49
+ * A redirect middleware for several stores: each request is matched against
50
+ * the redirects of the store it resolves to. Each store's map is shared by its
51
+ * requests; refresh one with `(await client.forStore(code)).redirects.refresh()`.
52
+ */
53
+ export type MultiStoreRedirectMiddleware = (request: Request) => Promise<Response | undefined>;
54
+ /**
55
+ * Usage (any Fetch-API server — Next.js App Router: see
56
+ * `@sixtyninecommerce/client/next`):
57
+ * ```ts
58
+ * import { createRedirectMiddleware } from '@sixtyninecommerce/client/web';
59
+ *
60
+ * const redirects = createRedirectMiddleware({
61
+ * storeCode: process.env.STORE_CODE!,
62
+ * pluginsUrl: process.env.PLUGINS_URL,
63
+ * onError: (error) => console.error('[redirects]', error),
64
+ * });
65
+ *
66
+ * // Hono: app.use(async (c, next) => (await redirects(c.req.raw)) ?? next());
67
+ * // Or reuse an initialized client's store: createRedirectMiddleware({ store: client.redirects })
68
+ * // Several stores in one process: createRedirectMiddleware({ client: storeRouter, onError })
69
+ * ```
70
+ */
71
+ export declare function createRedirectMiddleware(options: MultiStoreRedirectMiddlewareOptions): MultiStoreRedirectMiddleware;
72
+ export declare function createRedirectMiddleware(options: RedirectMiddlewareOptions | {
73
+ store: RedirectStore;
74
+ preserveQuery?: boolean;
75
+ }): RedirectMiddleware;
76
+ //# sourceMappingURL=redirect-middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redirect-middleware.d.ts","sourceRoot":"","sources":["../../src/web/redirect-middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAkB,KAAK,gBAAgB,EAAmB,MAAM,mBAAmB,CAAC;AAE3F,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAGhF,MAAM,WAAW,yBAA0B,SAAQ,mBAAmB;IACpE;;;;;;;;;OASG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAGD,MAAM,WAAW,kBAAkB;IACjC,iEAAiE;IACjE,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;IAClD,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;CAC/B;AAGD,sEAAsE;AACtE,MAAM,WAAW,mCAAmC;IAClD,qEAAqE;IACrE,MAAM,EAAE,gBAAgB,CAAC;IACzB,yEAAyE;IACzE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAGD;;;;GAIG;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;AAsB/F;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,mCAAmC,GAC3C,4BAA4B,CAAC;AAChC,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,yBAAyB,GAAG;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GACrF,kBAAkB,CAAC"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Middleware factory that applies the tenant's platform-managed redirects, for
3
+ * any Fetch-API server.
4
+ *
5
+ * Framework-neutral by design: it takes a `Request` and returns a plain
6
+ * `Response` — or `undefined`, meaning "carry on with normal routing" — which
7
+ * is exactly what a Next.js middleware, a Hono/Workers handler, a SvelteKit
8
+ * `handle` hook or a `node:http` adapter can use. `@sixtyninecommerce/client/next`
9
+ * re-exports this same function. It never throws — an unmatched path, a cold
10
+ * cache or an unreachable platform all resolve to `undefined`.
11
+ */
12
+ import { isStoreRefusal, onRedirectError } from '../multi-store.js';
13
+ import { createRedirectStore } from '../redirects/store.js';
14
+ /**
15
+ * Build the destination URL against the request origin, so a stored path
16
+ * redirects on the storefront's own host and an absolute `https://` target
17
+ * leaves it.
18
+ */
19
+ function resolveTarget(to, request, preserveQuery) {
20
+ const requestUrl = new URL(request.url);
21
+ const target = new URL(to, requestUrl.origin);
22
+ if (preserveQuery) {
23
+ for (const [key, value] of requestUrl.searchParams) {
24
+ if (!target.searchParams.has(key)) {
25
+ target.searchParams.append(key, value);
26
+ }
27
+ }
28
+ }
29
+ return target.toString();
30
+ }
31
+ export function createRedirectMiddleware(options) {
32
+ const preserveQuery = options.preserveQuery ?? true;
33
+ if ('client' in options)
34
+ return multiStoreRedirects(options, preserveQuery);
35
+ const store = 'store' in options ? options.store : createRedirectStore(options);
36
+ const middleware = async (request) => {
37
+ let pathname;
38
+ try {
39
+ pathname = new URL(request.url).pathname;
40
+ }
41
+ catch {
42
+ return undefined;
43
+ }
44
+ const match = await store.match(pathname);
45
+ if (!match)
46
+ return undefined;
47
+ return new Response(null, {
48
+ status: match.status,
49
+ headers: { Location: resolveTarget(match.to, request, preserveQuery) },
50
+ });
51
+ };
52
+ return Object.assign(middleware, { store });
53
+ }
54
+ function multiStoreRedirects(options, preserveQuery) {
55
+ if (options.onError)
56
+ onRedirectError(options.client, options.onError);
57
+ return async (request) => {
58
+ let pathname;
59
+ try {
60
+ pathname = new URL(request.url).pathname;
61
+ }
62
+ catch {
63
+ return undefined;
64
+ }
65
+ let store;
66
+ try {
67
+ store = (await options.client.forRequest(request)).redirects;
68
+ }
69
+ catch (error) {
70
+ // Never throws, like the single-store middleware: a request no store
71
+ // serves is the page's to answer, and an outage must not take routing down.
72
+ if (!isStoreRefusal(error)) {
73
+ const failure = error instanceof Error ? error : new Error(String(error));
74
+ try {
75
+ options.onError?.(failure);
76
+ }
77
+ catch (listenerError) {
78
+ // A throwing logger must not turn "fall through" into a rejected
79
+ // middleware (a 500 on every page) — nor hide what it was handed.
80
+ console.warn(`[@sixtyninecommerce/client] the redirect onError handler threw while reporting: ${failure.message}`, listenerError);
81
+ }
82
+ }
83
+ return undefined;
84
+ }
85
+ const match = await store.match(pathname);
86
+ if (!match)
87
+ return undefined;
88
+ return new Response(null, {
89
+ status: match.status,
90
+ headers: { Location: resolveTarget(match.to, request, preserveQuery) },
91
+ });
92
+ };
93
+ }
94
+ //# sourceMappingURL=redirect-middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redirect-middleware.js","sourceRoot":"","sources":["../../src/web/redirect-middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Turn a public-artifact read into the `Response` a storefront serves. Shared
3
+ * by every `/web` responder and, through them, every `/next` handler, so the
4
+ * two entry points cannot drift on a status, a header or a body.
5
+ */
6
+ import { type PublicArtifactRead } from '../core/public-artifact.js';
7
+ export declare function notFoundResponse(): Response;
8
+ /**
9
+ * The `503` for a request that failed before or during the read. The body is
10
+ * the error's message: what a developer wiring the route needs to see (a
11
+ * missing feed token, a timeout), and never a credential — nothing on this
12
+ * path holds one.
13
+ */
14
+ export declare function failureResponse(error: unknown): Response;
15
+ /**
16
+ * `ETag` is echoed on a `304` as well as a `200` (RFC 9110 §15.4.5): a cache
17
+ * revalidating its copy keeps the validator it is told is still current.
18
+ */
19
+ export declare function publicArtifactResponse<Body extends string | ArrayBuffer>(result: PublicArtifactRead<Body>, cacheControl: string, defaultContentType: string): Response;
20
+ //# sourceMappingURL=respond.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"respond.d.ts","sourceRoot":"","sources":["../../src/web/respond.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAgC,KAAK,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEnG,wBAAgB,gBAAgB,IAAI,QAAQ,CAE3C;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAKxD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,SAAS,MAAM,GAAG,WAAW,EACtE,MAAM,EAAE,kBAAkB,CAAC,IAAI,CAAC,EAChC,YAAY,EAAE,MAAM,EACpB,kBAAkB,EAAE,MAAM,GACzB,QAAQ,CAuBV"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Turn a public-artifact read into the `Response` a storefront serves. Shared
3
+ * by every `/web` responder and, through them, every `/next` handler, so the
4
+ * two entry points cannot drift on a status, a header or a body.
5
+ */
6
+ import { ARTIFACT_RETRY_AFTER_SECONDS } from '../core/public-artifact.js';
7
+ export function notFoundResponse() {
8
+ return new Response('Not found', { status: 404, headers: { 'Content-Type': 'text/plain' } });
9
+ }
10
+ /**
11
+ * The `503` for a request that failed before or during the read. The body is
12
+ * the error's message: what a developer wiring the route needs to see (a
13
+ * missing feed token, a timeout), and never a credential — nothing on this
14
+ * path holds one.
15
+ */
16
+ export function failureResponse(error) {
17
+ return new Response(error instanceof Error ? error.message : 'Proxy failed', {
18
+ status: 503,
19
+ headers: { 'Content-Type': 'text/plain', 'Retry-After': String(ARTIFACT_RETRY_AFTER_SECONDS) },
20
+ });
21
+ }
22
+ /**
23
+ * `ETag` is echoed on a `304` as well as a `200` (RFC 9110 §15.4.5): a cache
24
+ * revalidating its copy keeps the validator it is told is still current.
25
+ */
26
+ export function publicArtifactResponse(result, cacheControl, defaultContentType) {
27
+ switch (result.status) {
28
+ case 200: {
29
+ const headers = {
30
+ 'Content-Type': result.contentType ?? defaultContentType,
31
+ 'Cache-Control': cacheControl,
32
+ };
33
+ if (result.etag)
34
+ headers.ETag = result.etag;
35
+ return new Response(result.body, { status: 200, headers });
36
+ }
37
+ case 304: {
38
+ const headers = { 'Cache-Control': cacheControl };
39
+ if (result.etag)
40
+ headers.ETag = result.etag;
41
+ return new Response(null, { status: 304, headers });
42
+ }
43
+ case 404:
44
+ return notFoundResponse();
45
+ case 503:
46
+ return new Response(result.error ?? 'Upstream unavailable', {
47
+ status: 503,
48
+ headers: { 'Content-Type': 'text/plain', 'Retry-After': String(result.retryAfterSeconds) },
49
+ });
50
+ }
51
+ }
52
+ //# sourceMappingURL=respond.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"respond.js","sourceRoot":"","sources":["../../src/web/respond.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,4BAA4B,EAA2B,MAAM,4BAA4B,CAAC;AAEnG,MAAM,UAAU,gBAAgB;IAC9B,OAAO,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC;AAC/F,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,OAAO,IAAI,QAAQ,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,EAAE;QAC3E,MAAM,EAAE,GAAG;QACX,OAAO,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,CAAC,4BAA4B,CAAC,EAAE;KAC/F,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAgC,EAChC,YAAoB,EACpB,kBAA0B;IAE1B,QAAQ,MAAM,CAAC,MAAM,EAAE,CAAC;QACtB,KAAK,GAAG,CAAC,CAAC,CAAC;YACT,MAAM,OAAO,GAA2B;gBACtC,cAAc,EAAE,MAAM,CAAC,WAAW,IAAI,kBAAkB;gBACxD,eAAe,EAAE,YAAY;aAC9B,CAAC;YACF,IAAI,MAAM,CAAC,IAAI;gBAAE,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YAC5C,OAAO,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QAC7D,CAAC;QACD,KAAK,GAAG,CAAC,CAAC,CAAC;YACT,MAAM,OAAO,GAA2B,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;YAC1E,IAAI,MAAM,CAAC,IAAI;gBAAE,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YAC5C,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,KAAK,GAAG;YACN,OAAO,gBAAgB,EAAE,CAAC;QAC5B,KAAK,GAAG;YACN,OAAO,IAAI,QAAQ,CAAC,MAAM,CAAC,KAAK,IAAI,sBAAsB,EAAE;gBAC1D,MAAM,EAAE,GAAG;gBACX,OAAO,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE;aAC3F,CAAC,CAAC;IACP,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sixtyninecommerce/client",
3
- "version": "0.30.0",
3
+ "version": "0.32.0",
4
4
  "description": "JavaScript/TypeScript client for sixtynine-commerce storefronts",
5
5
  "homepage": "https://github.com/SIXTYNINE-digital/sixtynine-commerce-engine/tree/main/packages/storefront-client#readme",
6
6
  "repository": {
@@ -31,9 +31,17 @@
31
31
  "types": "./dist/next/index.d.ts",
32
32
  "import": "./dist/next/index.js"
33
33
  },
34
+ "./web": {
35
+ "types": "./dist/web/index.d.ts",
36
+ "import": "./dist/web/index.js"
37
+ },
34
38
  "./admin": {
35
39
  "types": "./dist/admin/index.d.ts",
36
40
  "import": "./dist/admin/index.js"
41
+ },
42
+ "./types": {
43
+ "types": "./dist/generated/shop.d.ts",
44
+ "import": "./dist/generated/shop.js"
37
45
  }
38
46
  },
39
47
  "license": "MIT",
@@ -52,10 +60,16 @@
52
60
  "access": "public"
53
61
  },
54
62
  "dependencies": {
55
- "@sixtyninecommerce/core": "^0.4.0"
63
+ "@sixtyninecommerce/core": "^0.6.0"
56
64
  },
57
65
  "devDependencies": {
66
+ "@graphql-codegen/add": "7.0.0",
67
+ "@graphql-codegen/cli": "7.0.0",
68
+ "@graphql-codegen/typescript": "5.0.10",
69
+ "@graphql-codegen/typescript-operations": "5.1.0",
58
70
  "@types/node": "22.19.7",
71
+ "graphql": "16.14.0",
72
+ "openapi-typescript": "7.13.0",
59
73
  "typescript": "5.9.3",
60
74
  "vitest": "4.1.6",
61
75
  "@sixtynine-digital/commerce-shared": "0.0.0"
@@ -64,6 +78,8 @@
64
78
  "build": "rm -rf dist && tsc -p tsconfig.build.json",
65
79
  "dev": "tsc -p tsconfig.build.json --watch",
66
80
  "typecheck": "tsc --noEmit",
81
+ "codegen": "graphql-codegen --config codegen.ts",
82
+ "codegen:check": "graphql-codegen --config codegen.ts --check",
67
83
  "test": "vitest run",
68
84
  "test:watch": "vitest",
69
85
  "test:unit": "vitest run",