@reblu/site-contracts 1.2.0 → 1.4.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/CHANGELOG.md +67 -0
- package/dist/index.d.cts +10 -2
- package/dist/index.d.ts +10 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# @reblu/site-contracts
|
|
2
2
|
|
|
3
|
+
## 1.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 87b7fa0: Add typed `Config.openingHours` (REB-826): `ConfigOpeningHours`,
|
|
8
|
+
`ConfigOpeningHoursRange`, `ConfigOpeningHoursDay`.
|
|
9
|
+
|
|
10
|
+
Additive: a new optional-shaped (`null` when not configured) field on the
|
|
11
|
+
existing `Config` type. A SITE build that has not migrated its `Config` type
|
|
12
|
+
yet keeps working unchanged — the extra field is simply ignored at runtime.
|
|
13
|
+
Replaces the previous untyped convention of stashing opening hours inside
|
|
14
|
+
`Config.metadata`.
|
|
15
|
+
|
|
16
|
+
## 1.3.0
|
|
17
|
+
|
|
18
|
+
### Minor Changes
|
|
19
|
+
|
|
20
|
+
- baa36cf: Expose each taxonomy axis's selection mode on `ShopFacets` (REB-809).
|
|
21
|
+
|
|
22
|
+
`ShopFacets.taxonomies[].selectionMode` is a new required field: `'single' |
|
|
23
|
+
'multiple'`, mirroring REB-801's per-axis `TaxonomySelectionMode`. It reflects
|
|
24
|
+
how many terms a PRODUCT may carry on that axis, not how many the SITE
|
|
25
|
+
storefront filter may select at once — `GET /api/site/shop/products`'s
|
|
26
|
+
`taxonomy[<key>]` param still accepts only one term slug per axis regardless
|
|
27
|
+
of this value (see `@reblu/site-blocks`'s `ShopFilters` docs).
|
|
28
|
+
|
|
29
|
+
Additive: a new required field on the existing `ShopFacets` shape, populated
|
|
30
|
+
for every axis. A SITE build that has not migrated its `ShopFacets` type yet
|
|
31
|
+
keeps working unchanged — the extra field is simply ignored at runtime.
|
|
32
|
+
|
|
3
33
|
## 1.2.0
|
|
4
34
|
|
|
5
35
|
### Minor Changes
|
|
@@ -20,6 +50,43 @@
|
|
|
20
50
|
new exported type. The existing `validationFieldLabel` field is unchanged and
|
|
21
51
|
still present for a SITE build that has not migrated to the new array yet.
|
|
22
52
|
|
|
53
|
+
- 7ff47d7: Add the cookie-consent fields to `Analytics` (REB-642). _Entry added after
|
|
54
|
+
publishing (REB-787): these fields shipped in 1.2.0, but no changeset
|
|
55
|
+
targeted this package, so the generated notes above left them out._
|
|
56
|
+
|
|
57
|
+
`GET /api/site/analytics` now also returns what a SITE needs to run the
|
|
58
|
+
`@reblu/site-next/consent` banner. There is still one request, and the root
|
|
59
|
+
layout already makes it:
|
|
60
|
+
- `consentRequired: boolean`: `true` when the tenant has a valid GA4 or
|
|
61
|
+
Clarity id (computed from the already-validated `gaId`/`clarityId`, so an
|
|
62
|
+
id that fails validation never requires a banner). reCAPTCHA is excluded
|
|
63
|
+
on purpose because it is strictly necessary. `false` means no configured
|
|
64
|
+
vendor needs consent, so the SITE can skip the banner.
|
|
65
|
+
`<ConsentedAnalytics>` does not read this field.
|
|
66
|
+
- `cookiePolicyVersion: string | null`: a content hash of the tenant's cookie
|
|
67
|
+
policy. It is the same algorithm as `cookiePolicyVersion()` in
|
|
68
|
+
`@reblu/site-next/consent-server` on the same text, and a shared test
|
|
69
|
+
vector keeps the two identical. Pass it to
|
|
70
|
+
`<ConsentProvider policyVersion>`. When the tenant edits the policy in
|
|
71
|
+
nexus, the hash changes and visitors are asked again. `null` means no
|
|
72
|
+
policy is stored.
|
|
73
|
+
- `cookieBanner`: the banner copy the tenant edits in nexus:
|
|
74
|
+
`{ enabled, title, body, acceptLabel, rejectLabel, manageLabel, policyUrl }`.
|
|
75
|
+
A `null` text field means the SDK default applies. Map `body` to the
|
|
76
|
+
banner's `description` text and `policyUrl` to `policyHref`. The buttons
|
|
77
|
+
and categories are fixed and have no field here.
|
|
78
|
+
- `cookieInventory`: `{ vendor, category }[]`, where `category` is
|
|
79
|
+
`'necessary' | 'analytics' | 'marketing'`. It lists only the vendors this
|
|
80
|
+
SITE actually loads, and is meant for the cookie-policy table.
|
|
81
|
+
|
|
82
|
+
**Consumer note:** the four fields are required on the `Analytics` type.
|
|
83
|
+
Runtime responses always include them, but code that builds an `Analytics`
|
|
84
|
+
object by hand (for example test fixtures) must now set them. A neutral
|
|
85
|
+
fixture is `consentRequired: false`, `cookiePolicyVersion: null`,
|
|
86
|
+
`cookieBanner: { enabled: true, title: null, body: null, acceptLabel: null,
|
|
87
|
+
rejectLabel: null, manageLabel: null, policyUrl: null }`,
|
|
88
|
+
`cookieInventory: []`.
|
|
89
|
+
|
|
23
90
|
## 1.1.0
|
|
24
91
|
|
|
25
92
|
### Minor Changes
|
package/dist/index.d.cts
CHANGED
|
@@ -39,7 +39,7 @@ export type BlogSlug = { slug: string; updatedAt: string;}
|
|
|
39
39
|
|
|
40
40
|
export type BlogTag = { id: string; name: string; slug: string; color: string;}
|
|
41
41
|
|
|
42
|
-
export type Config = { siteName: string; siteDescription: string | null; language: string | null; contactEmail: string | null; keywords: string[]; businessType: string | null; isSetupComplete: boolean; logoLightExpandedUrl: string | null; logoDarkExpandedUrl: string | null; logoLightSmallUrl: string | null; logoDarkSmallUrl: string | null; ogImageUrl: string | null; owner: { name: string | null; email: string | null; jobTitle: string | null; }; business: { name: string | null; }; address: { street: string | null; city: string | null; region: string | null; postalCode: string | null; country: string | null; telephone: string | null; lat: number | null; lng: number | null; } | null; fiscal: { taxId: string | null; taxIdKind: "NIF" | "CIF" | null; legalName: string | null; registry: { name: string; number: string; } | null; } | null; social: { linkedin: string | null; twitter: string | null; facebook: string | null; instagram: string | null; youtube: string | null; } | null; metadata: unknown; contactFormMode: "NOT_CONFIGURED" | "DISABLED" | "DB_ONLY" | "WEBHOOK" | "RESEND"; features: Record<string, unknown>;}
|
|
42
|
+
export type Config = { siteName: string; siteDescription: string | null; language: string | null; contactEmail: string | null; keywords: string[]; businessType: string | null; isSetupComplete: boolean; logoLightExpandedUrl: string | null; logoDarkExpandedUrl: string | null; logoLightSmallUrl: string | null; logoDarkSmallUrl: string | null; ogImageUrl: string | null; owner: { name: string | null; email: string | null; jobTitle: string | null; }; business: { name: string | null; }; address: { street: string | null; city: string | null; region: string | null; postalCode: string | null; country: string | null; telephone: string | null; lat: number | null; lng: number | null; } | null; fiscal: { taxId: string | null; taxIdKind: "NIF" | "CIF" | null; legalName: string | null; registry: { name: string; number: string; } | null; } | null; social: { linkedin: string | null; twitter: string | null; facebook: string | null; instagram: string | null; youtube: string | null; } | null; metadata: unknown; openingHours: { ranges: { days: ("MON" | "TUE" | "WED" | "THU" | "FRI" | "SAT" | "SUN")[]; opens: string; closes: string; }[]; note?: string | undefined; } | null; contactFormMode: "NOT_CONFIGURED" | "DISABLED" | "DB_ONLY" | "WEBHOOK" | "RESEND"; features: Record<string, unknown>;}
|
|
43
43
|
|
|
44
44
|
export type ConfigAddress = { street: string | null; city: string | null; region: string | null; postalCode: string | null; country: string | null; telephone: string | null; lat: number | null; lng: number | null;}
|
|
45
45
|
|
|
@@ -47,6 +47,12 @@ export type ConfigFiscal = { taxId: string | null; taxIdKind: "NIF" | "CIF
|
|
|
47
47
|
|
|
48
48
|
export type ConfigFiscalRegistry = { name: string; number: string;}
|
|
49
49
|
|
|
50
|
+
export type ConfigOpeningHours = { ranges: { days: ("MON" | "TUE" | "WED" | "THU" | "FRI" | "SAT" | "SUN")[]; opens: string; closes: string; }[]; note?: string | undefined;}
|
|
51
|
+
|
|
52
|
+
export type ConfigOpeningHoursDay = "MON" | "TUE" | "WED" | "THU" | "FRI" | "SAT" | "SUN"
|
|
53
|
+
|
|
54
|
+
export type ConfigOpeningHoursRange = { days: ("MON" | "TUE" | "WED" | "THU" | "FRI" | "SAT" | "SUN")[]; opens: string; closes: string;}
|
|
55
|
+
|
|
50
56
|
export type ConfigSocial = { linkedin: string | null; twitter: string | null; facebook: string | null; instagram: string | null; youtube: string | null;}
|
|
51
57
|
|
|
52
58
|
export type ConfigTaxIdKind = "NIF" | "CIF"
|
|
@@ -145,7 +151,7 @@ export type ShopDiscountApplication = { valid: boolean; discount: number;
|
|
|
145
151
|
|
|
146
152
|
export type ShopEmailCheck = { exists: boolean;}
|
|
147
153
|
|
|
148
|
-
export type ShopFacets = { taxonomies: { key: string; label: string; showAsBadge: boolean; 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; };}
|
|
154
|
+
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; };}
|
|
149
155
|
|
|
150
156
|
export type ShopInventoryRef = { stockQuantity: number; reservedQuantity: number; lowStockThreshold: number | null;}
|
|
151
157
|
|
|
@@ -171,6 +177,8 @@ export type ShopSort = "price_asc" | "price_desc" | "newest" | "on_sale"
|
|
|
171
177
|
|
|
172
178
|
export type ShopTaxRateRef = { rate: number; type: "IVA" | "IGIC" | "RETENTION" | "OTHER"; isExempt: boolean;}
|
|
173
179
|
|
|
180
|
+
export type ShopTaxonomySelectionMode = "single" | "multiple"
|
|
181
|
+
|
|
174
182
|
export type ShopTaxonomyTermRef = { taxonomyKey: string; taxonomyLabel: string; showAsBadge: boolean; slug: string; name: string; imageUrl: string | null;}
|
|
175
183
|
|
|
176
184
|
export type ShopValidateCartInput = { items: { productId: string; quantity: number; variantId?: string | null | undefined; }[];}
|
package/dist/index.d.ts
CHANGED
|
@@ -39,7 +39,7 @@ export type BlogSlug = { slug: string; updatedAt: string;}
|
|
|
39
39
|
|
|
40
40
|
export type BlogTag = { id: string; name: string; slug: string; color: string;}
|
|
41
41
|
|
|
42
|
-
export type Config = { siteName: string; siteDescription: string | null; language: string | null; contactEmail: string | null; keywords: string[]; businessType: string | null; isSetupComplete: boolean; logoLightExpandedUrl: string | null; logoDarkExpandedUrl: string | null; logoLightSmallUrl: string | null; logoDarkSmallUrl: string | null; ogImageUrl: string | null; owner: { name: string | null; email: string | null; jobTitle: string | null; }; business: { name: string | null; }; address: { street: string | null; city: string | null; region: string | null; postalCode: string | null; country: string | null; telephone: string | null; lat: number | null; lng: number | null; } | null; fiscal: { taxId: string | null; taxIdKind: "NIF" | "CIF" | null; legalName: string | null; registry: { name: string; number: string; } | null; } | null; social: { linkedin: string | null; twitter: string | null; facebook: string | null; instagram: string | null; youtube: string | null; } | null; metadata: unknown; contactFormMode: "NOT_CONFIGURED" | "DISABLED" | "DB_ONLY" | "WEBHOOK" | "RESEND"; features: Record<string, unknown>;}
|
|
42
|
+
export type Config = { siteName: string; siteDescription: string | null; language: string | null; contactEmail: string | null; keywords: string[]; businessType: string | null; isSetupComplete: boolean; logoLightExpandedUrl: string | null; logoDarkExpandedUrl: string | null; logoLightSmallUrl: string | null; logoDarkSmallUrl: string | null; ogImageUrl: string | null; owner: { name: string | null; email: string | null; jobTitle: string | null; }; business: { name: string | null; }; address: { street: string | null; city: string | null; region: string | null; postalCode: string | null; country: string | null; telephone: string | null; lat: number | null; lng: number | null; } | null; fiscal: { taxId: string | null; taxIdKind: "NIF" | "CIF" | null; legalName: string | null; registry: { name: string; number: string; } | null; } | null; social: { linkedin: string | null; twitter: string | null; facebook: string | null; instagram: string | null; youtube: string | null; } | null; metadata: unknown; openingHours: { ranges: { days: ("MON" | "TUE" | "WED" | "THU" | "FRI" | "SAT" | "SUN")[]; opens: string; closes: string; }[]; note?: string | undefined; } | null; contactFormMode: "NOT_CONFIGURED" | "DISABLED" | "DB_ONLY" | "WEBHOOK" | "RESEND"; features: Record<string, unknown>;}
|
|
43
43
|
|
|
44
44
|
export type ConfigAddress = { street: string | null; city: string | null; region: string | null; postalCode: string | null; country: string | null; telephone: string | null; lat: number | null; lng: number | null;}
|
|
45
45
|
|
|
@@ -47,6 +47,12 @@ export type ConfigFiscal = { taxId: string | null; taxIdKind: "NIF" | "CIF
|
|
|
47
47
|
|
|
48
48
|
export type ConfigFiscalRegistry = { name: string; number: string;}
|
|
49
49
|
|
|
50
|
+
export type ConfigOpeningHours = { ranges: { days: ("MON" | "TUE" | "WED" | "THU" | "FRI" | "SAT" | "SUN")[]; opens: string; closes: string; }[]; note?: string | undefined;}
|
|
51
|
+
|
|
52
|
+
export type ConfigOpeningHoursDay = "MON" | "TUE" | "WED" | "THU" | "FRI" | "SAT" | "SUN"
|
|
53
|
+
|
|
54
|
+
export type ConfigOpeningHoursRange = { days: ("MON" | "TUE" | "WED" | "THU" | "FRI" | "SAT" | "SUN")[]; opens: string; closes: string;}
|
|
55
|
+
|
|
50
56
|
export type ConfigSocial = { linkedin: string | null; twitter: string | null; facebook: string | null; instagram: string | null; youtube: string | null;}
|
|
51
57
|
|
|
52
58
|
export type ConfigTaxIdKind = "NIF" | "CIF"
|
|
@@ -145,7 +151,7 @@ export type ShopDiscountApplication = { valid: boolean; discount: number;
|
|
|
145
151
|
|
|
146
152
|
export type ShopEmailCheck = { exists: boolean;}
|
|
147
153
|
|
|
148
|
-
export type ShopFacets = { taxonomies: { key: string; label: string; showAsBadge: boolean; 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; };}
|
|
154
|
+
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; };}
|
|
149
155
|
|
|
150
156
|
export type ShopInventoryRef = { stockQuantity: number; reservedQuantity: number; lowStockThreshold: number | null;}
|
|
151
157
|
|
|
@@ -171,6 +177,8 @@ export type ShopSort = "price_asc" | "price_desc" | "newest" | "on_sale"
|
|
|
171
177
|
|
|
172
178
|
export type ShopTaxRateRef = { rate: number; type: "IVA" | "IGIC" | "RETENTION" | "OTHER"; isExempt: boolean;}
|
|
173
179
|
|
|
180
|
+
export type ShopTaxonomySelectionMode = "single" | "multiple"
|
|
181
|
+
|
|
174
182
|
export type ShopTaxonomyTermRef = { taxonomyKey: string; taxonomyLabel: string; showAsBadge: boolean; slug: string; name: string; imageUrl: string | null;}
|
|
175
183
|
|
|
176
184
|
export type ShopValidateCartInput = { items: { productId: string; quantity: number; variantId?: string | null | undefined; }[];}
|
package/package.json
CHANGED