@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.
- package/README.md +574 -14
- package/dist/admin/http.d.ts.map +1 -1
- package/dist/admin/http.js.map +1 -1
- package/dist/admin/types.d.ts.map +1 -1
- package/dist/build-client.d.ts +9 -0
- package/dist/build-client.d.ts.map +1 -0
- package/dist/build-client.js +58 -0
- package/dist/build-client.js.map +1 -0
- package/dist/cache-tags.d.ts +35 -1
- package/dist/cache-tags.d.ts.map +1 -1
- package/dist/cache-tags.js +39 -1
- package/dist/cache-tags.js.map +1 -1
- package/dist/client.d.ts +25 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +9 -62
- package/dist/client.js.map +1 -1
- package/dist/commerce/age-verification.d.ts +7 -4
- package/dist/commerce/age-verification.d.ts.map +1 -1
- package/dist/commerce/age-verification.js +6 -4
- package/dist/commerce/age-verification.js.map +1 -1
- package/dist/commerce/arguments.d.ts +13 -0
- package/dist/commerce/arguments.d.ts.map +1 -0
- package/dist/commerce/arguments.js +19 -0
- package/dist/commerce/arguments.js.map +1 -0
- package/dist/commerce/branding.d.ts.map +1 -1
- package/dist/commerce/branding.js.map +1 -1
- package/dist/commerce/capabilities.d.ts +40 -0
- package/dist/commerce/capabilities.d.ts.map +1 -0
- package/dist/commerce/capabilities.js +41 -0
- package/dist/commerce/capabilities.js.map +1 -0
- package/dist/commerce/cart.d.ts +9 -12
- package/dist/commerce/cart.d.ts.map +1 -1
- package/dist/commerce/cart.js +6 -1
- package/dist/commerce/cart.js.map +1 -1
- package/dist/commerce/checkout.d.ts +95 -15
- package/dist/commerce/checkout.d.ts.map +1 -1
- package/dist/commerce/checkout.js +230 -10
- package/dist/commerce/checkout.js.map +1 -1
- package/dist/commerce/customer.d.ts +83 -38
- package/dist/commerce/customer.d.ts.map +1 -1
- package/dist/commerce/customer.js +149 -10
- package/dist/commerce/customer.js.map +1 -1
- package/dist/commerce/favorites.d.ts +2 -5
- package/dist/commerce/favorites.d.ts.map +1 -1
- package/dist/commerce/favorites.js.map +1 -1
- package/dist/commerce/index.d.ts +194 -133
- package/dist/commerce/index.d.ts.map +1 -1
- package/dist/commerce/index.js +15 -0
- package/dist/commerce/index.js.map +1 -1
- package/dist/commerce/order-states.d.ts +18 -0
- package/dist/commerce/order-states.d.ts.map +1 -0
- package/dist/commerce/order-states.js +30 -0
- package/dist/commerce/order-states.js.map +1 -0
- package/dist/commerce/parcel-pricing.d.ts +48 -0
- package/dist/commerce/parcel-pricing.d.ts.map +1 -0
- package/dist/commerce/parcel-pricing.js +39 -0
- package/dist/commerce/parcel-pricing.js.map +1 -0
- package/dist/commerce/parked-orders.d.ts +22 -0
- package/dist/commerce/parked-orders.d.ts.map +1 -0
- package/dist/commerce/parked-orders.js +47 -0
- package/dist/commerce/parked-orders.js.map +1 -0
- package/dist/commerce/payments.d.ts +12 -5
- package/dist/commerce/payments.d.ts.map +1 -1
- package/dist/commerce/payments.js +10 -1
- package/dist/commerce/payments.js.map +1 -1
- package/dist/commerce/placement-error.d.ts +17 -0
- package/dist/commerce/placement-error.d.ts.map +1 -1
- package/dist/commerce/placement-error.js.map +1 -1
- package/dist/commerce/products.d.ts +92 -38
- package/dist/commerce/products.d.ts.map +1 -1
- package/dist/commerce/products.js +157 -123
- package/dist/commerce/products.js.map +1 -1
- package/dist/commerce/queries.d.ts +216 -49
- package/dist/commerce/queries.d.ts.map +1 -1
- package/dist/commerce/queries.js +1347 -743
- package/dist/commerce/queries.js.map +1 -1
- package/dist/commerce/quotes.d.ts +5 -4
- package/dist/commerce/quotes.d.ts.map +1 -1
- package/dist/commerce/quotes.js +1 -36
- package/dist/commerce/quotes.js.map +1 -1
- package/dist/commerce/receipt-claim.d.ts +35 -0
- package/dist/commerce/receipt-claim.d.ts.map +1 -0
- package/dist/commerce/receipt-claim.js +66 -0
- package/dist/commerce/receipt-claim.js.map +1 -0
- package/dist/commerce/recommendations.d.ts +3 -3
- package/dist/commerce/recommendations.d.ts.map +1 -1
- package/dist/commerce/recommendations.js +3 -1
- package/dist/commerce/recommendations.js.map +1 -1
- package/dist/commerce/returns.d.ts +7 -6
- package/dist/commerce/returns.d.ts.map +1 -1
- package/dist/commerce/returns.js +24 -3
- package/dist/commerce/returns.js.map +1 -1
- package/dist/commerce/reviews.d.ts +24 -15
- package/dist/commerce/reviews.d.ts.map +1 -1
- package/dist/commerce/reviews.js +67 -50
- package/dist/commerce/reviews.js.map +1 -1
- package/dist/commerce/saved-lists.d.ts +15 -15
- package/dist/commerce/saved-lists.d.ts.map +1 -1
- package/dist/commerce/saved-lists.js +67 -56
- package/dist/commerce/saved-lists.js.map +1 -1
- package/dist/commerce/search.d.ts +3 -2
- package/dist/commerce/search.d.ts.map +1 -1
- package/dist/commerce/search.js +2 -2
- package/dist/commerce/search.js.map +1 -1
- package/dist/commerce/shipping.d.ts +11 -4
- package/dist/commerce/shipping.d.ts.map +1 -1
- package/dist/commerce/shipping.js +17 -2
- package/dist/commerce/shipping.js.map +1 -1
- package/dist/commerce/stock-notifications.d.ts +2 -0
- package/dist/commerce/stock-notifications.d.ts.map +1 -1
- package/dist/commerce/stock-notifications.js +2 -2
- package/dist/commerce/stock-notifications.js.map +1 -1
- package/dist/commerce/store-pickup.d.ts +37 -0
- package/dist/commerce/store-pickup.d.ts.map +1 -0
- package/dist/commerce/store-pickup.js +66 -0
- package/dist/commerce/store-pickup.js.map +1 -0
- package/dist/commerce/subscriptions.d.ts +35 -37
- package/dist/commerce/subscriptions.d.ts.map +1 -1
- package/dist/commerce/subscriptions.js +159 -120
- package/dist/commerce/subscriptions.js.map +1 -1
- package/dist/commerce/vat-validation.d.ts +6 -3
- package/dist/commerce/vat-validation.d.ts.map +1 -1
- package/dist/commerce/vat-validation.js +24 -19
- package/dist/commerce/vat-validation.js.map +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js.map +1 -1
- package/dist/content/assets.d.ts +5 -4
- package/dist/content/assets.d.ts.map +1 -1
- package/dist/content/assets.js.map +1 -1
- package/dist/content/collection-pages.d.ts +3 -2
- package/dist/content/collection-pages.d.ts.map +1 -1
- package/dist/content/collection-pages.js.map +1 -1
- package/dist/content/collections.d.ts +5 -4
- package/dist/content/collections.d.ts.map +1 -1
- package/dist/content/collections.js.map +1 -1
- package/dist/content/filtered-products.d.ts.map +1 -1
- package/dist/content/filtered-products.js.map +1 -1
- package/dist/content/form-field-types.d.ts +3 -3
- package/dist/content/form-field-types.d.ts.map +1 -1
- package/dist/content/form-field-types.js.map +1 -1
- package/dist/content/forms.d.ts +4 -3
- package/dist/content/forms.d.ts.map +1 -1
- package/dist/content/forms.js +3 -0
- package/dist/content/forms.js.map +1 -1
- package/dist/content/index.d.ts +18 -17
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/items.d.ts +5 -4
- package/dist/content/items.d.ts.map +1 -1
- package/dist/content/items.js +2 -0
- package/dist/content/items.js.map +1 -1
- package/dist/content/menus.d.ts +3 -2
- package/dist/content/menus.d.ts.map +1 -1
- package/dist/content/menus.js +7 -1
- package/dist/content/menus.js.map +1 -1
- package/dist/content/resolve.d.ts +3 -2
- package/dist/content/resolve.d.ts.map +1 -1
- package/dist/content/resolve.js +1 -1
- package/dist/content/resolve.js.map +1 -1
- package/dist/content/sitemap.d.ts +3 -2
- package/dist/content/sitemap.d.ts.map +1 -1
- package/dist/content/sitemap.js.map +1 -1
- package/dist/content/strings.d.ts +16 -2
- package/dist/content/strings.d.ts.map +1 -1
- package/dist/content/strings.js +32 -4
- package/dist/content/strings.js.map +1 -1
- package/dist/core/context.d.ts +127 -1
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +436 -45
- package/dist/core/context.js.map +1 -1
- package/dist/core/currency.d.ts +14 -0
- package/dist/core/currency.d.ts.map +1 -0
- package/dist/core/currency.js +52 -0
- package/dist/core/currency.js.map +1 -0
- package/dist/core/deprecation.d.ts +23 -0
- package/dist/core/deprecation.d.ts.map +1 -0
- package/dist/core/deprecation.js +81 -0
- package/dist/core/deprecation.js.map +1 -0
- package/dist/core/http.d.ts +15 -1
- package/dist/core/http.d.ts.map +1 -1
- package/dist/core/http.js +55 -3
- package/dist/core/http.js.map +1 -1
- package/dist/core/public-artifact.d.ts +72 -0
- package/dist/core/public-artifact.d.ts.map +1 -0
- package/dist/core/public-artifact.js +122 -0
- package/dist/core/public-artifact.js.map +1 -0
- package/dist/core/unknown-field-rejection.d.ts +18 -0
- package/dist/core/unknown-field-rejection.d.ts.map +1 -0
- package/dist/core/unknown-field-rejection.js +37 -0
- package/dist/core/unknown-field-rejection.js.map +1 -0
- package/dist/credit/credit-status.d.ts +2 -0
- package/dist/credit/credit-status.d.ts.map +1 -1
- package/dist/credit/credit-status.js +71 -19
- package/dist/credit/credit-status.js.map +1 -1
- package/dist/credit/index.d.ts +1 -1
- package/dist/credit/payment-terms.d.ts +3 -3
- package/dist/credit/payment-terms.d.ts.map +1 -1
- package/dist/credit/payment-terms.js +28 -24
- package/dist/credit/payment-terms.js.map +1 -1
- package/dist/currency/exchange.d.ts +7 -7
- package/dist/currency/exchange.d.ts.map +1 -1
- package/dist/currency/exchange.js +5 -1
- package/dist/currency/exchange.js.map +1 -1
- package/dist/errors.d.ts +17 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +13 -0
- package/dist/errors.js.map +1 -1
- package/dist/events/index.d.ts +20 -7
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +17 -5
- package/dist/events/index.js.map +1 -1
- package/dist/events/payloads.d.ts +7 -4
- package/dist/events/payloads.d.ts.map +1 -1
- package/dist/events/payloads.js +6 -3
- package/dist/events/payloads.js.map +1 -1
- package/dist/feeds/index.d.ts +5 -0
- package/dist/feeds/index.d.ts.map +1 -0
- package/dist/feeds/index.js +12 -0
- package/dist/feeds/index.js.map +1 -0
- package/dist/feeds/types.d.ts +18 -0
- package/dist/feeds/types.d.ts.map +1 -0
- package/dist/feeds/types.js +8 -0
- package/dist/feeds/types.js.map +1 -0
- package/dist/generated/cms.d.ts +2136 -0
- package/dist/generated/cms.d.ts.map +1 -0
- package/dist/generated/cms.js +4 -0
- package/dist/generated/cms.js.map +1 -0
- package/dist/generated/plugins.d.ts +550 -0
- package/dist/generated/plugins.d.ts.map +1 -0
- package/dist/generated/plugins.js +4 -0
- package/dist/generated/plugins.js.map +1 -0
- package/dist/generated/shop.d.ts +5663 -0
- package/dist/generated/shop.d.ts.map +1 -0
- package/dist/generated/shop.js +5 -0
- package/dist/generated/shop.js.map +1 -0
- package/dist/graphql-document.d.ts +29 -0
- package/dist/graphql-document.d.ts.map +1 -0
- package/dist/graphql-document.js +21 -0
- package/dist/graphql-document.js.map +1 -0
- package/dist/index.d.ts +10 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/media/urls.d.ts.map +1 -1
- package/dist/media/urls.js +12 -1
- package/dist/media/urls.js.map +1 -1
- package/dist/media/video.d.ts.map +1 -1
- package/dist/media/video.js.map +1 -1
- package/dist/multi-store.d.ts +200 -0
- package/dist/multi-store.d.ts.map +1 -0
- package/dist/multi-store.js +558 -0
- package/dist/multi-store.js.map +1 -0
- package/dist/navigation/routes.d.ts +4 -3
- package/dist/navigation/routes.d.ts.map +1 -1
- package/dist/navigation/routes.js.map +1 -1
- package/dist/next/artifact-handler.d.ts +21 -13
- package/dist/next/artifact-handler.d.ts.map +1 -1
- package/dist/next/artifact-handler.js +28 -66
- package/dist/next/artifact-handler.js.map +1 -1
- package/dist/next/event-revalidate-handler.d.ts +26 -6
- package/dist/next/event-revalidate-handler.d.ts.map +1 -1
- package/dist/next/event-revalidate-handler.js +126 -19
- package/dist/next/event-revalidate-handler.js.map +1 -1
- package/dist/next/feed-handler.d.ts +50 -0
- package/dist/next/feed-handler.d.ts.map +1 -0
- package/dist/next/feed-handler.js +61 -0
- package/dist/next/feed-handler.js.map +1 -0
- package/dist/next/index.d.ts +3 -1
- package/dist/next/index.d.ts.map +1 -1
- package/dist/next/index.js +1 -0
- package/dist/next/index.js.map +1 -1
- package/dist/next/metadata.d.ts.map +1 -1
- package/dist/next/metadata.js.map +1 -1
- package/dist/next/redirect-middleware.d.ts +5 -31
- package/dist/next/redirect-middleware.d.ts.map +1 -1
- package/dist/next/redirect-middleware.js +4 -46
- package/dist/next/redirect-middleware.js.map +1 -1
- package/dist/next/revalidate-handler.d.ts.map +1 -1
- package/dist/next/revalidate-handler.js.map +1 -1
- package/dist/pricing/index.d.ts.map +1 -1
- package/dist/pricing/index.js.map +1 -1
- package/dist/pricing/tax-display.js +1 -1
- package/dist/pricing/tax-display.js.map +1 -1
- package/dist/pricing/tiers.d.ts +3 -2
- package/dist/pricing/tiers.d.ts.map +1 -1
- package/dist/pricing/tiers.js.map +1 -1
- package/dist/pricing/validation.d.ts +88 -12
- package/dist/pricing/validation.d.ts.map +1 -1
- package/dist/pricing/validation.js +93 -12
- package/dist/pricing/validation.js.map +1 -1
- package/dist/redirects/index.d.ts.map +1 -1
- package/dist/redirects/index.js +2 -1
- package/dist/redirects/index.js.map +1 -1
- package/dist/redirects/store.d.ts.map +1 -1
- package/dist/redirects/store.js +6 -2
- package/dist/redirects/store.js.map +1 -1
- package/dist/redirects/types.d.ts +5 -2
- package/dist/redirects/types.d.ts.map +1 -1
- package/dist/revalidation/event-plan.d.ts +55 -4
- package/dist/revalidation/event-plan.d.ts.map +1 -1
- package/dist/revalidation/event-plan.js +115 -8
- package/dist/revalidation/event-plan.js.map +1 -1
- package/dist/revalidation/event-verify.d.ts +8 -37
- package/dist/revalidation/event-verify.d.ts.map +1 -1
- package/dist/revalidation/event-verify.js +7 -97
- package/dist/revalidation/event-verify.js.map +1 -1
- package/dist/revalidation/types.d.ts.map +1 -1
- package/dist/revalidation/url-context.d.ts +17 -0
- package/dist/revalidation/url-context.d.ts.map +1 -1
- package/dist/revalidation/url-context.js +35 -2
- package/dist/revalidation/url-context.js.map +1 -1
- package/dist/seo/ai.d.ts.map +1 -1
- package/dist/seo/ai.js.map +1 -1
- package/dist/seo/artifacts.d.ts +86 -4
- package/dist/seo/artifacts.d.ts.map +1 -1
- package/dist/seo/artifacts.js +115 -16
- package/dist/seo/artifacts.js.map +1 -1
- package/dist/seo/availability.d.ts +2 -2
- package/dist/seo/availability.d.ts.map +1 -1
- package/dist/seo/availability.js.map +1 -1
- package/dist/seo/index.d.ts +2 -0
- package/dist/seo/index.d.ts.map +1 -1
- package/dist/seo/index.js +3 -1
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/json-ld.d.ts.map +1 -1
- package/dist/seo/json-ld.js.map +1 -1
- package/dist/seo/meta-tags.d.ts.map +1 -1
- package/dist/seo/meta-tags.js.map +1 -1
- package/dist/seo/metadata-parser.d.ts.map +1 -1
- package/dist/seo/metadata-parser.js.map +1 -1
- package/dist/seo/metadata-types.d.ts.map +1 -1
- package/dist/seo/robots.d.ts.map +1 -1
- package/dist/seo/robots.js.map +1 -1
- package/dist/seo/types.d.ts +9 -2
- package/dist/seo/types.d.ts.map +1 -1
- package/dist/seo/url-builder.d.ts +5 -3
- package/dist/seo/url-builder.d.ts.map +1 -1
- package/dist/seo/url-builder.js +3 -1
- package/dist/seo/url-builder.js.map +1 -1
- package/dist/types.d.ts +1381 -2537
- package/dist/types.d.ts.map +1 -1
- package/dist/web/artifact-responder.d.ts +69 -0
- package/dist/web/artifact-responder.d.ts.map +1 -0
- package/dist/web/artifact-responder.js +90 -0
- package/dist/web/artifact-responder.js.map +1 -0
- package/dist/web/feed-responder.d.ts +72 -0
- package/dist/web/feed-responder.d.ts.map +1 -0
- package/dist/web/feed-responder.js +81 -0
- package/dist/web/feed-responder.js.map +1 -0
- package/dist/web/index.d.ts +23 -0
- package/dist/web/index.d.ts.map +1 -0
- package/dist/web/index.js +19 -0
- package/dist/web/index.js.map +1 -0
- package/dist/web/redirect-middleware.d.ts +76 -0
- package/dist/web/redirect-middleware.d.ts.map +1 -0
- package/dist/web/redirect-middleware.js +94 -0
- package/dist/web/redirect-middleware.js.map +1 -0
- package/dist/web/respond.d.ts +20 -0
- package/dist/web/respond.d.ts.map +1 -0
- package/dist/web/respond.js +52 -0
- package/dist/web/respond.js.map +1 -0
- 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.
|
|
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.
|
|
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",
|