@reblu/site-contracts 1.5.0 → 1.6.1
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/CHANGELOG.md +18 -0
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @reblu/site-contracts
|
|
2
2
|
|
|
3
|
+
## 1.6.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 59ccb29: Fix `<CookieBanner>` rendering an empty title/description and three blank buttons when a tenant left a nexus cookie-banner copy field unset (persisted as `""`, not `null`). A blank or whitespace-only `texts` override now falls back to the SDK's default copy for that key instead of winning the merge. Add `cookieBannerToConsentTexts` (`@reblu/site-next/consent`) to map the `/api/site/analytics` `cookieBanner` contract shape onto `texts` directly, dropping `null` and blank fields. `@reblu/site-contracts` now also exports the standalone `CookieBanner` type.
|
|
8
|
+
|
|
9
|
+
## 1.6.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 21feec3: REB-836 — checkout hardening: Stripe redirect-origin check + stable checkout error codes.
|
|
14
|
+
- `@reblu/site-contracts`: re-exports the new `ShopErrorCode` type (type-only, `z.infer` from base-api's `shopErrorCodeSchema`, no Zod reaches the published `.d.ts`) — nine values: `STOCK_CHANGED`, `PRICE_CHANGED`, `PRODUCT_UNAVAILABLE`, `DISCOUNT_INVALID`, `SHIPPING_UNAVAILABLE`, `INVALID_INPUT`, `STORE_DISABLED`, `PAYMENT_PROVIDER_ERROR`, and `INTERNAL_ERROR` (added in a native-review follow-up to distinguish an unexpected, non-Stripe failure — reported as HTTP 500 — from a Stripe failure, reported as 400 or, for a transient/5xx Stripe error, 503). This is the shop write endpoints' (`checkout`/`validateCart`/`applyDiscount`) new optional error-body `code` field.
|
|
15
|
+
- `@reblu/site-client`: (1) `shop.checkout()` now validates the returned Stripe Checkout URL is `https:` on an allowed host (default `checkout.stripe.com`, injectable via the new `RebluClientConfig.checkoutRedirectHosts`) before ever returning it, throwing the new `UnsafeCheckoutRedirectError` otherwise — exported alongside `isSafeCheckoutRedirectUrl` and `DEFAULT_CHECKOUT_REDIRECT_HOSTS`. (2) `ApiError.body` (`ApiErrorBody`/`ApiErrorDetails`) gains the optional `code` and `details.productIds` fields.
|
|
16
|
+
- `@reblu/site-next`: (1) `createShopCheckoutRoute` re-checks the Checkout URL server-side before responding to the browser (502 `unsafe_redirect` when it fails the check) — new `ShopCheckoutRouteOptions.allowedRedirectHosts`/`unsafeRedirectMessage`. (2) Native-review follow-up: that same route now strips `content-encoding`/`content-length`/`transfer-encoding` from its re-serialized response instead of forwarding them from the upstream proxy response, fixing a "browser tries to gunzip already-decoded JSON" failure mode.
|
|
17
|
+
- `@reblu/site-blocks`: adds `DEFAULT_SHOP_ERROR_MESSAGES` (a default Spanish message per `ShopErrorCode`, including `INTERNAL_ERROR`'s "Ha ocurrido un error inesperado. Inténtalo de nuevo en unos minutos.") and `getShopErrorMessage(code, overrides?, fallback?)`, which a SITE can override per code without restating the others.
|
|
18
|
+
|
|
19
|
+
All new fields/exports are additive and optional (REB-788) — a SITE that ignores `code`/`checkoutRedirectHosts` keeps working unchanged. The base-api side of this change (the `ShopErrorCode` schema itself, `checkout.service.ts`'s Stripe-vs-internal error classification, and `apiError()`'s options-object signature) is unpublished — it ships with the next base-api deploy, not through these changesets.
|
|
20
|
+
|
|
3
21
|
## 1.5.0
|
|
4
22
|
|
|
5
23
|
### Minor Changes
|
package/dist/index.d.cts
CHANGED
|
@@ -63,6 +63,8 @@ export type ContactFormMode = "NOT_CONFIGURED" | "DISABLED" | "DB_ONLY" | "WEBHO
|
|
|
63
63
|
|
|
64
64
|
export type ContactFormSubmission = { id: string; createdAt: string;}
|
|
65
65
|
|
|
66
|
+
export type CookieBanner = { enabled: boolean; title: string | null; body: string | null; acceptLabel: string | null; rejectLabel: string | null; manageLabel: string | null; policyUrl: string | null;}
|
|
67
|
+
|
|
66
68
|
export type Cta = { id: string; slot: "hero" | "blog-end" | "services" | "contact" | "sticky-mobile" | "footer"; label: string; href: string; sortOrder: number; abVariant: string | null; analyticsId: string;}
|
|
67
69
|
|
|
68
70
|
export type CustomFieldDefinition = { id: string; entityType: "page" | "product"; key: string; label: string; valueType: "boolean" | "text" | "select" | "multiselect"; options: { value: string; label: string; }[]; isFilterable: boolean; showInDetail: boolean; unit: string | null; sortOrder: number;}
|
|
@@ -151,6 +153,8 @@ export type ShopDiscountApplication = { valid: boolean; discount: number;
|
|
|
151
153
|
|
|
152
154
|
export type ShopEmailCheck = { exists: boolean;}
|
|
153
155
|
|
|
156
|
+
export type ShopErrorCode = "STOCK_CHANGED" | "PRICE_CHANGED" | "PRODUCT_UNAVAILABLE" | "DISCOUNT_INVALID" | "SHIPPING_UNAVAILABLE" | "INVALID_INPUT" | "STORE_DISABLED" | "PAYMENT_PROVIDER_ERROR" | "INTERNAL_ERROR"
|
|
157
|
+
|
|
154
158
|
export type ShopFacets = { taxonomies: { key: string; label: string; showAsBadge: boolean; selectionMode: "single" | "multiple"; terms: { slug: string; name: string; count: number; }[]; }[]; attributes: { key: string; label: string; valueType: "boolean" | "text" | "select" | "multiselect"; options: { value: string; label: string; count: number; }[]; }[]; price: { min: number; max: number; }; onSale: { count: number; };}
|
|
155
159
|
|
|
156
160
|
export type ShopInventoryRef = { stockQuantity: number; reservedQuantity: number; lowStockThreshold: number | null;}
|
package/dist/index.d.ts
CHANGED
|
@@ -63,6 +63,8 @@ export type ContactFormMode = "NOT_CONFIGURED" | "DISABLED" | "DB_ONLY" | "WEBHO
|
|
|
63
63
|
|
|
64
64
|
export type ContactFormSubmission = { id: string; createdAt: string;}
|
|
65
65
|
|
|
66
|
+
export type CookieBanner = { enabled: boolean; title: string | null; body: string | null; acceptLabel: string | null; rejectLabel: string | null; manageLabel: string | null; policyUrl: string | null;}
|
|
67
|
+
|
|
66
68
|
export type Cta = { id: string; slot: "hero" | "blog-end" | "services" | "contact" | "sticky-mobile" | "footer"; label: string; href: string; sortOrder: number; abVariant: string | null; analyticsId: string;}
|
|
67
69
|
|
|
68
70
|
export type CustomFieldDefinition = { id: string; entityType: "page" | "product"; key: string; label: string; valueType: "boolean" | "text" | "select" | "multiselect"; options: { value: string; label: string; }[]; isFilterable: boolean; showInDetail: boolean; unit: string | null; sortOrder: number;}
|
|
@@ -151,6 +153,8 @@ export type ShopDiscountApplication = { valid: boolean; discount: number;
|
|
|
151
153
|
|
|
152
154
|
export type ShopEmailCheck = { exists: boolean;}
|
|
153
155
|
|
|
156
|
+
export type ShopErrorCode = "STOCK_CHANGED" | "PRICE_CHANGED" | "PRODUCT_UNAVAILABLE" | "DISCOUNT_INVALID" | "SHIPPING_UNAVAILABLE" | "INVALID_INPUT" | "STORE_DISABLED" | "PAYMENT_PROVIDER_ERROR" | "INTERNAL_ERROR"
|
|
157
|
+
|
|
154
158
|
export type ShopFacets = { taxonomies: { key: string; label: string; showAsBadge: boolean; selectionMode: "single" | "multiple"; terms: { slug: string; name: string; count: number; }[]; }[]; attributes: { key: string; label: string; valueType: "boolean" | "text" | "select" | "multiselect"; options: { value: string; label: string; count: number; }[]; }[]; price: { min: number; max: number; }; onSale: { count: number; };}
|
|
155
159
|
|
|
156
160
|
export type ShopInventoryRef = { stockQuantity: number; reservedQuantity: number; lowStockThreshold: number | null;}
|
package/package.json
CHANGED