@reblu/site-contracts 1.27.0 → 1.29.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 CHANGED
@@ -1,5 +1,28 @@
1
1
  # @reblu/site-contracts
2
2
 
3
+ ## 1.29.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 9a83295: Guest course checkout (REB-1264). Additive only: every existing export behaves as before.
8
+ - `@reblu/site-contracts` exports `AcademyCheckoutRequest`, `AcademyCheckoutBilling`, `AcademyCheckoutSession` and `AcademyCheckoutErrorCode` (`POST /api/site/academy/checkout`).
9
+ - `@reblu/site-client` adds `client.academy.checkout(body, options?)` → `{ url, sessionId }` (Stripe URL re-checked like `shop.checkout()`); a refusal throws `AcademyCheckoutError` (an `ApiError`) with the stable `code` and `details`.
10
+ - `@reblu/site-next` adds `createAcademyCheckoutRoute()` in `./route-handlers`: forwards `x-reblu-visitor-ip`, fills `successUrl`/`cancelUrl` on `coursePath` and re-checks the Stripe URL. `createShopCheckoutRoute` now shares that code, unchanged in behaviour.
11
+ - `@reblu/site-blocks` adds the drop-in `CourseGuestCheckoutForm` (`./client`): name, surname, email, terms box, the course's consent box, optional full invoice, total and pay notice; it gives way to the request form on `ENROLLMENT_REQUEST_REQUIRED`. The root entry adds `courseSellsAsGuest` and `toAcademyCheckoutInvoiceFields`.
12
+
13
+ - 49f8f4b: New page content blocks (REB-1265..1268). Additive only: every existing block type renders exactly as before.
14
+ - `before_after` («Antes y después»): before/after image pairs with an opt-in text under them (`showCaption` + `caption`). `@reblu/site-blocks` adds the drop-in `BeforeAfterPairs` and renders the block in `PageBlocks`. `@reblu/site-contracts` exports `BeforeAfterData`.
15
+ - `chips` («Etiquetas»): a short list of texts shown as chips. Drop-in `ChipList`; type `ChipsData`.
16
+ - `icon_cards` («Tarjetas con icono»): a responsive grid of cards with an icon from a fixed, curated set, a title and a short text. Drop-in `IconCardGrid` and `CardIconSvg`, `CARD_ICON_NAMES`; types `IconCardsData` and `CardIcon`. `feature_list` is unchanged.
17
+ - `image_text` («Imagen y texto»): an image beside rich text, image left or right, configurable mobile order. Drop-in `ImageTextSplit`; type `ImageTextData`. `BlockRendererProps` gains an optional `headingId`, set only for `image_text`, which draws the section heading in its text column. The legacy `TEXT_IMAGE`/`IMAGE_TEXT` layouts are unchanged.
18
+ - `PageBlocks` renders `data.kicker` above the section heading for the new content blocks only.
19
+
20
+ ## 1.28.0
21
+
22
+ ### Minor Changes
23
+
24
+ - 275adaf: REB-1201: `TrustBadgeType` gains `'CONSUMER_ARBITRATION'` (adhesion to the consumer arbitration system) and `TrustBadge` gains an optional `adhesionNumber: string | null` — the official adhesion number of that badge, `null` for every other type. `client.trustBadges.list({ type: 'CONSUMER_ARBITRATION' })` fetches only it. A SITE with an exhaustive `Record<TrustBadgeType, …>` adds the new key.
25
+
3
26
  ## 1.27.0
4
27
 
5
28
  ### Minor Changes
package/README.md CHANGED
@@ -236,6 +236,21 @@ const deadline = (ack: DataRequestSubmission) => ack.slaDueAt
236
236
  The list is base-api's `dataRequestTypeSchema`: a compile-time check and a unit
237
237
  test fail the build if the two ever disagree.
238
238
 
239
+ ### Guest course checkout (REB-1264)
240
+
241
+ `AcademyCheckoutRequest` is the body of `POST /api/site/academy/checkout`
242
+ (name, email, terms, the course's consent box, optional full invoice in
243
+ `AcademyCheckoutBilling`, and the return URLs), `AcademyCheckoutSession` its
244
+ `{ url, sessionId }` answer, and `AcademyCheckoutErrorCode` the stable `code`
245
+ of every refusal — `ENROLLMENT_REQUEST_REQUIRED` means the course keeps the
246
+ request flow:
247
+
248
+ ```ts
249
+ import type { AcademyCheckoutErrorCode, AcademyCheckoutRequest } from '@reblu/site-contracts'
250
+
251
+ const useRequestForm = (code: AcademyCheckoutErrorCode) => code === 'ENROLLMENT_REQUEST_REQUIRED'
252
+ ```
253
+
239
254
  ## How the types stay correct
240
255
 
241
256
  The types are re-derived from the response schemas that live in the Reblu API
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;AAkFO,IAAM,kBAAA,GAAqB,OAAO,MAAA,CAAO;AAAA,EAC9C,QAAA;AAAA,EACA,eAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA,oBAAA;AAAA,EACA;AACF,CAAU","file":"index.cjs","sourcesContent":["/**\n * `@reblu/site-contracts` — public, dependency-free TypeScript types for the\n * Reblu SITE API (REB-414 / design doc §2).\n *\n * These types are the SDK-facing view of every `/api/site/*` response. They are\n * re-derived (`z.infer`) from the hand-authored response schemas that live in\n * base-api (`apps/base-api/src/lib/contracts/*.contract.ts`) and imported here\n * through the build-time-only `@reblu/base-api-contracts` type alias.\n *\n * Guarantees (enforced by the leakage guard tests):\n * - Everything below is `export type` — the import is erased at build time, so\n * NO Zod and NO Prisma reaches a consumer's runtime or `node_modules` graph.\n * The one exception is `DATA_REQUEST_TYPES` (REB-1005): a plain, import-free\n * array literal, the package's only runtime value.\n * - The published `.d.ts` is flattened and self-contained: the alias and\n * `z.infer` do not survive into the emitted declarations.\n * - Never re-exports an internal / Prisma-generated type — only the public\n * output DTOs base-api explicitly publishes.\n *\n * When base-api adds a new public contract type, add it to the matching group\n * below. The explicit list (over `export type *`) keeps the public surface a\n * reviewed, intentional decision and avoids leaking internal `*Schema` names.\n */\n\n// Envelope / pagination\nexport type { PaginationMeta } from '@reblu/base-api-contracts'\n\n// Analytics + shared contact-form mode\nexport type { Analytics, ContactFormMode } from '@reblu/base-api-contracts'\n\n// REB-845 — the tenant-editable cookie banner copy shape, standalone (not just\n// nested in `Analytics`), so `@reblu/site-next`'s `cookieBannerToConsentTexts`\n// can type its input against the real contract instead of a hand-rolled copy.\nexport type { CookieBanner } from '@reblu/base-api-contracts'\n\n// Site config\nexport type {\n Config,\n ConfigAddress,\n ConfigFiscal,\n ConfigFiscalRegistry,\n ConfigSocial,\n ConfigTaxIdKind,\n // REB-826 — typed opening hours.\n ConfigOpeningHours,\n ConfigOpeningHoursRange,\n ConfigOpeningHoursDay,\n} from '@reblu/base-api-contracts'\n\n// REB-871 — the resolved `seo` block on every detail response (pages, blog\n// posts, shop products, academy courses). `seo.title` is the FINAL page title.\nexport type { Seo } from '@reblu/base-api-contracts'\n\n// Contact form\nexport type { ContactFormSubmission, ContactFormInput } from '@reblu/base-api-contracts'\n// REB-1078 — the raw lead-origin touches a SITE sends in `metadata.attribution`\n// (contact form and `/api/site/leads`); base-api classifies the channel.\nexport type { LeadAttribution, LeadTouch } from '@reblu/base-api-contracts'\n\n// Leads\nexport type { LeadInput, LeadSubmission } from '@reblu/base-api-contracts'\n\n// GDPR data-subject requests (REB-77 endpoint, REB-980 SDK) — the public\n// `/derechos-rgpd` form body and its 72h acknowledgement.\nexport type {\n DataRequestInput,\n DataRequestSubmission,\n DataRequestType,\n} from '@reblu/base-api-contracts'\nimport type { DataRequestType } from '@reblu/base-api-contracts'\n\n/**\n * REB-1005 — every GDPR right a data subject can exercise, in base-api's order.\n * The ONE runtime value this package ships: server code (a SITE's Route\n * Handler, `@reblu/site-next`'s `createDataRequestRoute`) needs the list too,\n * and `@reblu/site-blocks` re-exports it as before.\n *\n * Single source: base-api's `dataRequestTypeSchema`. `satisfies` rejects a\n * member base-api does not know, `MissingDataRequestType` below rejects one it\n * knows and this list lacks, and `tests/unit/data-request-types.test.ts` pins\n * the order. Plain array literal, no import — the runtime stays dependency-free.\n */\nexport const DATA_REQUEST_TYPES = Object.freeze([\n 'ACCESS',\n 'RECTIFICATION',\n 'ERASURE',\n 'OBJECTION',\n 'PORTABILITY',\n 'RESTRICTION',\n 'AUTOMATED_DECISION',\n 'INFORMATION',\n] as const) satisfies readonly DataRequestType[]\n\n/** Compile error when base-api adds a right this list does not carry. */\ntype AssertNoneMissing<T extends never> = T\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ntype MissingDataRequestType = AssertNoneMissing<\n Exclude<DataRequestType, (typeof DATA_REQUEST_TYPES)[number]>\n>\n\n// Blog\nexport type {\n BlogAuthor,\n BlogAuthorDetail,\n BlogCategory,\n BlogCategoryWithCount,\n BlogTag,\n BlogPostListItem,\n BlogPostDetail,\n BlogPostPreview,\n BlogSlug,\n} from '@reblu/base-api-contracts'\n\n// Pages\nexport type {\n // The flexible pageType (service|custom|treatments|specialties|team|generic)\n // — REB-63: this is what `pages.list`'s `type` filter actually validates\n // against server-side (`pagesListParamsSchema`), not `LegacyPageType`.\n PageType,\n // Legacy DB page type (SERVICE|CUSTOM) — the `type`/`category` fields still\n // carried on each `PageListItem`/`PageDetail` for backward compat during the\n // REB-75 dual-read window. NOT the `pages.list` filter's value space anymore.\n LegacyPageType,\n PageContentMode,\n SectionLayout,\n PageCategoryRef,\n PageListItem,\n PageSectionImage,\n PageSection,\n PageDetail,\n PageSlug,\n // REB-63: `pages.list`'s sort param — same reasoning as AcademyCourseSort\n // below (a typo is a compile error instead of a silent no-op fallback).\n PagesListSort,\n // REB-869 — `pages.list`'s query, incl. `featured` (with `category`: that\n // category's featured pages, max 3, in their stored order).\n PagesListQuery,\n // REB-75 D-D — the typed block registry on `PageDetail.blocks[]`.\n BlockType,\n Block,\n // REB-849 — each block mirrors its parent section's heading/backgroundColor/\n // cta; REB-851 phase 1 — doctor_embed/specialty_embed blocks additionally\n // carry `resolved` (present only on those two block types).\n PageBlock,\n BlockCta,\n ResolvedEmbed,\n // REB-867 — slugs are unique per category: the embed reference shape\n // (`pageId`/`categorySlug`) and the 409 body of an ambiguous `GET /pages/[slug]`.\n EmbedReferenceData,\n PageAmbiguousSlugError,\n} from '@reblu/base-api-contracts'\n\n// Professional profile (REB-63) — pageType='team' only. Sector-agnostic\n// structured CV, same platform-shape/tenant-content split as CustomFieldDefinition.\n// REB-1099: `ProfessionalField` — a tenant-defined field (e.g. a registration\n// number) on the card (`ProfessionalSummary.fields`) and profile.\nexport type {\n ProfessionalField,\n ProfessionalSummary,\n ProfessionalProfile,\n ProfessionalCv,\n ProfessionalCvEntry,\n ProfessionalLanguage,\n ProfessionalLanguageLevel,\n ProfessionalSocialLink,\n ProfessionalSocialPlatform,\n} from '@reblu/base-api-contracts'\n\n// Custom-field registry (REB-475 / REB-75) — entity-agnostic, shared with pages/team\nexport type {\n CustomFieldValueType,\n CustomFieldEntityType,\n CustomFieldOption,\n CustomFieldDefinition,\n} from '@reblu/base-api-contracts'\n\n// Shop\nexport type {\n TaxType,\n ProductType,\n ShopConfig,\n // Store-wide product trust items (REB-858)\n ShopProductTrustIcon,\n ShopProductTrustItem,\n ShopTaxRateRef,\n ShopProductImage,\n ShopProductVideo,\n ShopProductCategoryRef,\n ShopInventoryRef,\n ShopCategory,\n ShopProductListItem,\n ShopProductVariant,\n ShopBundleComponent,\n ShopRelatedProduct,\n ShopProductDetail,\n // Taxonomy + attributes + facets (REB-474/475)\n ShopTaxonomyTermRef,\n ShopProductAttributes,\n // Per-axis selection mode (REB-809/REB-801)\n ShopTaxonomySelectionMode,\n ShopSort,\n ShopProductListParams,\n ShopFacets,\n // Write inputs (REB-438)\n ShopCartItemInput,\n ShopAddressInput,\n ShopBillingInput,\n ShopCheckoutInput,\n ShopValidateCartInput,\n ShopApplyDiscountInput,\n // Write responses (REB-438)\n ShopCheckoutSession,\n ShopCartValidationError,\n ShopCartValidationItem,\n ShopCartValidation,\n ShopDiscountApplication,\n // Automatic staff discount, additive on the write responses (REB-1131)\n ShopStaffAutoDiscount,\n // Order lookup (REB-829)\n ShopOrderItem,\n ShopOrder,\n // The order's invoice reference (REB-73)\n ShopOrderInvoice,\n // Stable, machine-readable write-endpoint error codes (REB-836)\n ShopErrorCode,\n // Single-step checkout (REB-1197 / REB-1198): delivery rules, pickup\n // points, resolved checkout copy, the terms version to accept, the\n // delivery choice and the pre-payment quote.\n ShopPickupLocation,\n ShopCheckoutDeliveryConfig,\n ShopCheckoutCopy,\n ShopTermsVersionRef,\n ShopFulfillmentInput,\n ShopQuoteInput,\n ShopQuoteLine,\n ShopQuote,\n} from '@reblu/base-api-contracts'\n\n// REB-834 — `POST /api/site/shop/check-email` is deprecated: it was an\n// account-enumeration oracle and now always answers `{ exists: false }`.\n// Kept (a minor may only deprecate); removed in the next major.\nexport type {\n /**\n * @deprecated REB-834 — `POST /api/site/shop/check-email` no longer reveals\n * whether an account exists. Do not call it; removed in the next major.\n */\n ShopCheckEmailInput,\n /**\n * @deprecated REB-834 — `exists` is always `false`. Never branch UI on it:\n * the checkout always offers «Iniciar sesión o continuar como invitado» and\n * the server links the order to an existing account after payment. Removed\n * in the next major.\n */\n ShopEmailCheck,\n} from '@reblu/base-api-contracts'\n\n// Academy (REB-507) — public course catalogue. `AcademyCourseSort` is the query\n// contract for the `sort` param, so the SDK can type it as a union instead of a\n// bare string (an unknown key is silently ignored server-side).\nexport type {\n AcademyCourseSort,\n // REB-547 — the documented catalogue query: q, sort, category, instructor\n // (a user id from `GET /api/site/academy/instructors`), free and the price\n // range in integer cents.\n AcademyCourseListQuery,\n AcademyCategoryPublic,\n AcademyLessonPublic,\n AcademyModulePublic,\n AcademyInstructorPublic,\n AcademyCourseSummary,\n AcademyCourseDetail,\n // REB-83 — tenant-configurable validation fields (drives the enrollment CTA form).\n AcademyValidationFieldPublic,\n // REB-1135 — a free-preview lesson, viewable by the public\n // (`GET /api/site/academy/courses/{slug}/lessons/{lessonSlug}`).\n AcademyLessonPreview,\n AcademyLessonPreviewVideo,\n // REB-1234 — tenant academy settings for the SITE\n // (`GET /api/site/academy/config`): which catalogue filters are switched on.\n AcademyConfigPublic,\n AcademyCatalogFiltersPublic,\n} from '@reblu/base-api-contracts'\n\n// Legal\nexport type { Legal, LegalTermsVersion } from '@reblu/base-api-contracts'\n// REB-1201 — the withdrawal form (`POST /api/site/withdrawal-requests`).\nexport type {\n WithdrawalRequestInput,\n WithdrawalRequestSubmission,\n} from '@reblu/base-api-contracts'\n\n// CTAs\nexport type { Cta } from '@reblu/base-api-contracts'\n\n// Trust badges\nexport type { TrustBadge, TrustBadgeType } from '@reblu/base-api-contracts'\n\n// SITE capability manifest (`/.well-known/reblu-site.json`) — REB-777.\n// Direction note (see `site-manifest.contract.ts` in base-api): this is the\n// one contract group a SITE produces and base-api consumes, the opposite of\n// every group above. The TYPE still flows through this same alias so the\n// SDK and nexus never describe two different shapes for it; the real Zod\n// validation stays in base-api only — this package never gains a Zod\n// runtime dependency.\nexport type {\n SiteManifest,\n SiteManifestSurfaceValue,\n SiteCapabilitySurfaceKey,\n} from '@reblu/base-api-contracts'\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;AAkFO,IAAM,kBAAA,GAAqB,OAAO,MAAA,CAAO;AAAA,EAC9C,QAAA;AAAA,EACA,eAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA,oBAAA;AAAA,EACA;AACF,CAAU","file":"index.cjs","sourcesContent":["/**\n * `@reblu/site-contracts` — public, dependency-free TypeScript types for the\n * Reblu SITE API (REB-414 / design doc §2).\n *\n * These types are the SDK-facing view of every `/api/site/*` response. They are\n * re-derived (`z.infer`) from the hand-authored response schemas that live in\n * base-api (`apps/base-api/src/lib/contracts/*.contract.ts`) and imported here\n * through the build-time-only `@reblu/base-api-contracts` type alias.\n *\n * Guarantees (enforced by the leakage guard tests):\n * - Everything below is `export type` — the import is erased at build time, so\n * NO Zod and NO Prisma reaches a consumer's runtime or `node_modules` graph.\n * The one exception is `DATA_REQUEST_TYPES` (REB-1005): a plain, import-free\n * array literal, the package's only runtime value.\n * - The published `.d.ts` is flattened and self-contained: the alias and\n * `z.infer` do not survive into the emitted declarations.\n * - Never re-exports an internal / Prisma-generated type — only the public\n * output DTOs base-api explicitly publishes.\n *\n * When base-api adds a new public contract type, add it to the matching group\n * below. The explicit list (over `export type *`) keeps the public surface a\n * reviewed, intentional decision and avoids leaking internal `*Schema` names.\n */\n\n// Envelope / pagination\nexport type { PaginationMeta } from '@reblu/base-api-contracts'\n\n// Analytics + shared contact-form mode\nexport type { Analytics, ContactFormMode } from '@reblu/base-api-contracts'\n\n// REB-845 — the tenant-editable cookie banner copy shape, standalone (not just\n// nested in `Analytics`), so `@reblu/site-next`'s `cookieBannerToConsentTexts`\n// can type its input against the real contract instead of a hand-rolled copy.\nexport type { CookieBanner } from '@reblu/base-api-contracts'\n\n// Site config\nexport type {\n Config,\n ConfigAddress,\n ConfigFiscal,\n ConfigFiscalRegistry,\n ConfigSocial,\n ConfigTaxIdKind,\n // REB-826 — typed opening hours.\n ConfigOpeningHours,\n ConfigOpeningHoursRange,\n ConfigOpeningHoursDay,\n} from '@reblu/base-api-contracts'\n\n// REB-871 — the resolved `seo` block on every detail response (pages, blog\n// posts, shop products, academy courses). `seo.title` is the FINAL page title.\nexport type { Seo } from '@reblu/base-api-contracts'\n\n// Contact form\nexport type { ContactFormSubmission, ContactFormInput } from '@reblu/base-api-contracts'\n// REB-1078 — the raw lead-origin touches a SITE sends in `metadata.attribution`\n// (contact form and `/api/site/leads`); base-api classifies the channel.\nexport type { LeadAttribution, LeadTouch } from '@reblu/base-api-contracts'\n\n// Leads\nexport type { LeadInput, LeadSubmission } from '@reblu/base-api-contracts'\n\n// GDPR data-subject requests (REB-77 endpoint, REB-980 SDK) — the public\n// `/derechos-rgpd` form body and its 72h acknowledgement.\nexport type {\n DataRequestInput,\n DataRequestSubmission,\n DataRequestType,\n} from '@reblu/base-api-contracts'\nimport type { DataRequestType } from '@reblu/base-api-contracts'\n\n/**\n * REB-1005 — every GDPR right a data subject can exercise, in base-api's order.\n * The ONE runtime value this package ships: server code (a SITE's Route\n * Handler, `@reblu/site-next`'s `createDataRequestRoute`) needs the list too,\n * and `@reblu/site-blocks` re-exports it as before.\n *\n * Single source: base-api's `dataRequestTypeSchema`. `satisfies` rejects a\n * member base-api does not know, `MissingDataRequestType` below rejects one it\n * knows and this list lacks, and `tests/unit/data-request-types.test.ts` pins\n * the order. Plain array literal, no import — the runtime stays dependency-free.\n */\nexport const DATA_REQUEST_TYPES = Object.freeze([\n 'ACCESS',\n 'RECTIFICATION',\n 'ERASURE',\n 'OBJECTION',\n 'PORTABILITY',\n 'RESTRICTION',\n 'AUTOMATED_DECISION',\n 'INFORMATION',\n] as const) satisfies readonly DataRequestType[]\n\n/** Compile error when base-api adds a right this list does not carry. */\ntype AssertNoneMissing<T extends never> = T\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ntype MissingDataRequestType = AssertNoneMissing<\n Exclude<DataRequestType, (typeof DATA_REQUEST_TYPES)[number]>\n>\n\n// Blog\nexport type {\n BlogAuthor,\n BlogAuthorDetail,\n BlogCategory,\n BlogCategoryWithCount,\n BlogTag,\n BlogPostListItem,\n BlogPostDetail,\n BlogPostPreview,\n BlogSlug,\n} from '@reblu/base-api-contracts'\n\n// Pages\nexport type {\n // The flexible pageType (service|custom|treatments|specialties|team|generic)\n // — REB-63: this is what `pages.list`'s `type` filter actually validates\n // against server-side (`pagesListParamsSchema`), not `LegacyPageType`.\n PageType,\n // Legacy DB page type (SERVICE|CUSTOM) — the `type`/`category` fields still\n // carried on each `PageListItem`/`PageDetail` for backward compat during the\n // REB-75 dual-read window. NOT the `pages.list` filter's value space anymore.\n LegacyPageType,\n PageContentMode,\n SectionLayout,\n PageCategoryRef,\n PageListItem,\n PageSectionImage,\n PageSection,\n PageDetail,\n PageSlug,\n // REB-63: `pages.list`'s sort param — same reasoning as AcademyCourseSort\n // below (a typo is a compile error instead of a silent no-op fallback).\n PagesListSort,\n // REB-869 — `pages.list`'s query, incl. `featured` (with `category`: that\n // category's featured pages, max 3, in their stored order).\n PagesListQuery,\n // REB-75 D-D — the typed block registry on `PageDetail.blocks[]`.\n BlockType,\n Block,\n // REB-849 — each block mirrors its parent section's heading/backgroundColor/\n // cta; REB-851 phase 1 — doctor_embed/specialty_embed blocks additionally\n // carry `resolved` (present only on those two block types).\n PageBlock,\n BlockCta,\n ResolvedEmbed,\n // REB-867 — slugs are unique per category: the embed reference shape\n // (`pageId`/`categorySlug`) and the 409 body of an ambiguous `GET /pages/[slug]`.\n EmbedReferenceData,\n PageAmbiguousSlugError,\n // REB-1265..1268 — `data` of the additive content blocks, for the\n // `@reblu/site-blocks` drop-in components that render them.\n BeforeAfterData,\n ChipsData,\n IconCardsData,\n // REB-1267 — the curated icon names of `icon_cards` (no uploads).\n CardIcon,\n ImageTextData,\n} from '@reblu/base-api-contracts'\n\n// Professional profile (REB-63) — pageType='team' only. Sector-agnostic\n// structured CV, same platform-shape/tenant-content split as CustomFieldDefinition.\n// REB-1099: `ProfessionalField` — a tenant-defined field (e.g. a registration\n// number) on the card (`ProfessionalSummary.fields`) and profile.\nexport type {\n ProfessionalField,\n ProfessionalSummary,\n ProfessionalProfile,\n ProfessionalCv,\n ProfessionalCvEntry,\n ProfessionalLanguage,\n ProfessionalLanguageLevel,\n ProfessionalSocialLink,\n ProfessionalSocialPlatform,\n} from '@reblu/base-api-contracts'\n\n// Custom-field registry (REB-475 / REB-75) — entity-agnostic, shared with pages/team\nexport type {\n CustomFieldValueType,\n CustomFieldEntityType,\n CustomFieldOption,\n CustomFieldDefinition,\n} from '@reblu/base-api-contracts'\n\n// Shop\nexport type {\n TaxType,\n ProductType,\n ShopConfig,\n // Store-wide product trust items (REB-858)\n ShopProductTrustIcon,\n ShopProductTrustItem,\n ShopTaxRateRef,\n ShopProductImage,\n ShopProductVideo,\n ShopProductCategoryRef,\n ShopInventoryRef,\n ShopCategory,\n ShopProductListItem,\n ShopProductVariant,\n ShopBundleComponent,\n ShopRelatedProduct,\n ShopProductDetail,\n // Taxonomy + attributes + facets (REB-474/475)\n ShopTaxonomyTermRef,\n ShopProductAttributes,\n // Per-axis selection mode (REB-809/REB-801)\n ShopTaxonomySelectionMode,\n ShopSort,\n ShopProductListParams,\n ShopFacets,\n // Write inputs (REB-438)\n ShopCartItemInput,\n ShopAddressInput,\n ShopBillingInput,\n ShopCheckoutInput,\n ShopValidateCartInput,\n ShopApplyDiscountInput,\n // Write responses (REB-438)\n ShopCheckoutSession,\n ShopCartValidationError,\n ShopCartValidationItem,\n ShopCartValidation,\n ShopDiscountApplication,\n // Automatic staff discount, additive on the write responses (REB-1131)\n ShopStaffAutoDiscount,\n // Order lookup (REB-829)\n ShopOrderItem,\n ShopOrder,\n // The order's invoice reference (REB-73)\n ShopOrderInvoice,\n // Stable, machine-readable write-endpoint error codes (REB-836)\n ShopErrorCode,\n // Single-step checkout (REB-1197 / REB-1198): delivery rules, pickup\n // points, resolved checkout copy, the terms version to accept, the\n // delivery choice and the pre-payment quote.\n ShopPickupLocation,\n ShopCheckoutDeliveryConfig,\n ShopCheckoutCopy,\n ShopTermsVersionRef,\n ShopFulfillmentInput,\n ShopQuoteInput,\n ShopQuoteLine,\n ShopQuote,\n} from '@reblu/base-api-contracts'\n\n// REB-834 — `POST /api/site/shop/check-email` is deprecated: it was an\n// account-enumeration oracle and now always answers `{ exists: false }`.\n// Kept (a minor may only deprecate); removed in the next major.\nexport type {\n /**\n * @deprecated REB-834 — `POST /api/site/shop/check-email` no longer reveals\n * whether an account exists. Do not call it; removed in the next major.\n */\n ShopCheckEmailInput,\n /**\n * @deprecated REB-834 — `exists` is always `false`. Never branch UI on it:\n * the checkout always offers «Iniciar sesión o continuar como invitado» and\n * the server links the order to an existing account after payment. Removed\n * in the next major.\n */\n ShopEmailCheck,\n} from '@reblu/base-api-contracts'\n\n// Academy (REB-507) — public course catalogue. `AcademyCourseSort` is the query\n// contract for the `sort` param, so the SDK can type it as a union instead of a\n// bare string (an unknown key is silently ignored server-side).\nexport type {\n AcademyCourseSort,\n // REB-547 — the documented catalogue query: q, sort, category, instructor\n // (a user id from `GET /api/site/academy/instructors`), free and the price\n // range in integer cents.\n AcademyCourseListQuery,\n AcademyCategoryPublic,\n AcademyLessonPublic,\n AcademyModulePublic,\n AcademyInstructorPublic,\n AcademyCourseSummary,\n AcademyCourseDetail,\n // REB-83 — tenant-configurable validation fields (drives the enrollment CTA form).\n AcademyValidationFieldPublic,\n // REB-1135 — a free-preview lesson, viewable by the public\n // (`GET /api/site/academy/courses/{slug}/lessons/{lessonSlug}`).\n AcademyLessonPreview,\n AcademyLessonPreviewVideo,\n // REB-1234 — tenant academy settings for the SITE\n // (`GET /api/site/academy/config`): which catalogue filters are switched on.\n AcademyConfigPublic,\n AcademyCatalogFiltersPublic,\n // REB-1264 — guest course checkout (`POST /api/site/academy/checkout`): a\n // course that needs no validation is bought in one step and the account is\n // created after payment. The body, its full-invoice block, the Stripe\n // session answer and the stable error codes.\n AcademyCheckoutRequest,\n AcademyCheckoutBilling,\n AcademyCheckoutSession,\n AcademyCheckoutErrorCode,\n} from '@reblu/base-api-contracts'\n\n// Legal\nexport type { Legal, LegalTermsVersion } from '@reblu/base-api-contracts'\n// REB-1201 — the withdrawal form (`POST /api/site/withdrawal-requests`).\nexport type {\n WithdrawalRequestInput,\n WithdrawalRequestSubmission,\n} from '@reblu/base-api-contracts'\n\n// CTAs\nexport type { Cta } from '@reblu/base-api-contracts'\n\n// Trust badges\nexport type { TrustBadge, TrustBadgeType } from '@reblu/base-api-contracts'\n\n// SITE capability manifest (`/.well-known/reblu-site.json`) — REB-777.\n// Direction note (see `site-manifest.contract.ts` in base-api): this is the\n// one contract group a SITE produces and base-api consumes, the opposite of\n// every group above. The TYPE still flows through this same alias so the\n// SDK and nexus never describe two different shapes for it; the real Zod\n// validation stays in base-api only — this package never gains a Zod\n// runtime dependency.\nexport type {\n SiteManifest,\n SiteManifestSurfaceValue,\n SiteCapabilitySurfaceKey,\n} from '@reblu/base-api-contracts'\n"]}
package/dist/index.d.cts CHANGED
@@ -8,6 +8,14 @@ export type AcademyCatalogFiltersPublic = { category: boolean; instructor:
8
8
 
9
9
  export type AcademyCategoryPublic = { id: string; name: string; slug: string; sortOrder: number;}
10
10
 
11
+ export type AcademyCheckoutBilling = { billingName?: string | undefined; billingNif?: string | undefined; billingIdType?: string | undefined; billingIdCountry?: string | undefined; billingAddress?: { street?: string | undefined; postalCode?: string | undefined; city?: string | undefined; region?: string | undefined; country?: string | undefined; } | undefined;}
12
+
13
+ export type AcademyCheckoutErrorCode = "INVALID_INPUT" | "RATE_LIMITED" | "COURSE_NOT_FOUND" | "SALES_CLOSED" | "ENROLLMENT_REQUEST_REQUIRED" | "INVOICING_NOT_READY" | "TERMS_NOT_ACCEPTED" | "TERMS_VERSION_CHANGED" | "CONSENT_REQUIRED" | "CONSENT_VERSION_CHANGED" | "INVALID_BILLING"
14
+
15
+ export type AcademyCheckoutRequest = { courseSlug: string; email: string; firstName: string; lastName: string; successUrl: string; cancelUrl: string; acceptsTerms?: boolean | undefined; termsVersionId?: string | undefined; acceptsWithdrawalWaiver?: boolean | undefined; withdrawalWaiverVersion?: string | undefined; wantsFullInvoice?: boolean | undefined; billing?: { billingName?: string | undefined; billingNif?: string | undefined; billingIdType?: string | undefined; billingIdCountry?: string | undefined; billingAddress?: { street?: string | undefined; postalCode?: string | undefined; city?: string | undefined; region?: string | undefined; country?: string | undefined; } | undefined; } | undefined;}
16
+
17
+ export type AcademyCheckoutSession = { url: string; sessionId: string;}
18
+
11
19
  export type AcademyConfigPublic = { catalogFilters: { category: boolean; instructor: boolean; price: boolean; };}
12
20
 
13
21
  export type AcademyCourseDetail = { id: string; slug: string; title: string; shortDescription: string | null; coverUrl: string | null; priceCents: number; accessMode: "IMMEDIATE" | "DRIP" | "COHORT"; category: { id: string; name: string; slug: string; sortOrder: number; } | null; description: string | null; modules: { id: string; title: string; description: string | null; lessons: { id: string; slug: string; title: string; isFreePreview: boolean; durationSeconds: number | null; hasVideo: boolean; }[]; }[]; instructors: { id: string; firstName: string | null; lastName: string | null; avatarUrl: string | null; }[]; salesEnabled: boolean; requiresValidation: boolean; validationFieldLabel: string | null; validationFields: { key: string; label: string; required: boolean; maxLength?: number | undefined; }[]; metaTitle?: string | null | undefined; seo?: { title: string; } | undefined; withdrawalWaiverRequired?: boolean | undefined; accessDurationMonths?: number | null | undefined; deliveryModality?: "DIGITAL_CONTENT" | "TRAINING_SERVICE" | "IN_PERSON" | "WEBINAR" | null | undefined; withdrawalConsent?: { kind: "DIGITAL_CONTENT_WAIVER" | "SERVICE_START_REQUEST"; text: string; version: string; } | null | undefined; refundGuarantee?: { basis: "LESSONS_OPENED" | "LESSONS_COMPLETED"; thresholdPercent: number | null; windowDays: number | null; } | null | undefined;}
@@ -32,11 +40,13 @@ export type AcademyValidationFieldPublic = { key: string; label: string;
32
40
 
33
41
  export type Analytics = { gaId: string | null; clarityId: string | null; recaptchaSiteKey: string | null; contactFormMode: "NOT_CONFIGURED" | "DISABLED" | "DB_ONLY" | "WEBHOOK" | "RESEND"; metaPixelId: string | null; metaVerificationContent: string | null; googleVerificationContent: string | null; consentRequired: boolean; cookiePolicyVersion: string | null; cookieBanner: { enabled: boolean; title: string | null; body: string | null; acceptLabel: string | null; rejectLabel: string | null; manageLabel: string | null; policyUrl: string | null; }; cookieInventory: { vendor: string; category: "necessary" | "analytics" | "marketing"; }[];}
34
42
 
35
- export type Block = { blockType: "hero"; data: { title: string; subtitle?: string | undefined; imageUrl?: string | undefined; ctaSlot?: string | undefined; };} | { blockType: "richtext"; data: { html: string; };} | { blockType: "faq"; data: { items: { q: string; a: string; }[]; };} | { blockType: "stats"; data: { items: { label: string; value: string; }[]; };} | { blockType: "testimonial"; data: { quote: string; author: string; role?: string | undefined; avatarUrl?: string | undefined; };} | { blockType: "cta"; data: { slot: string; };} | { blockType: "feature_list"; data: { items: { text: string; icon?: string | undefined; }[]; };} | { blockType: "gallery"; data: { images: { url: string; alt?: string | undefined; caption?: string | undefined; }[]; };} | { blockType: "page_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { blockType: "profile_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { blockType: "doctor_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { blockType: "specialty_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };}
43
+ export type BeforeAfterData = { pairs: { beforeUrl: string; afterUrl: string; alt?: string | undefined; }[]; kicker?: string | undefined; showCaption?: boolean | undefined; caption?: string | undefined;}
44
+
45
+ export type Block = { blockType: "hero"; data: { title: string; subtitle?: string | undefined; imageUrl?: string | undefined; ctaSlot?: string | undefined; };} | { blockType: "richtext"; data: { html: string; };} | { blockType: "faq"; data: { items: { q: string; a: string; }[]; };} | { blockType: "stats"; data: { items: { label: string; value: string; }[]; };} | { blockType: "testimonial"; data: { quote: string; author: string; role?: string | undefined; avatarUrl?: string | undefined; };} | { blockType: "cta"; data: { slot: string; };} | { blockType: "feature_list"; data: { items: { text: string; icon?: string | undefined; }[]; };} | { blockType: "gallery"; data: { images: { url: string; alt?: string | undefined; caption?: string | undefined; }[]; };} | { blockType: "page_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { blockType: "profile_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { blockType: "doctor_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { blockType: "specialty_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { blockType: "before_after"; data: { pairs: { beforeUrl: string; afterUrl: string; alt?: string | undefined; }[]; kicker?: string | undefined; showCaption?: boolean | undefined; caption?: string | undefined; };} | { blockType: "chips"; data: { items: string[]; kicker?: string | undefined; };} | { blockType: "icon_cards"; data: { items: { icon: "check" | "phone" | "star" | "heart" | "shield-check" | "sparkles" | "clock" | "calendar" | "user" | "users" | "mail" | "map-pin" | "leaf" | "droplet" | "sun" | "zap" | "award" | "target" | "lightbulb" | "smile" | "thumbs-up" | "info"; title: string; text?: string | undefined; }[]; kicker?: string | undefined; intro?: string | undefined; };} | { blockType: "image_text"; data: { imageUrl: string; imageSide: "left" | "right"; kicker?: string | undefined; alt?: string | undefined; mobileOrder?: "image_first" | "text_first" | undefined; html?: string | undefined; };}
36
46
 
37
47
  export type BlockCta = null | { label: string; url: string; isExternal: boolean; variant: string | null;}
38
48
 
39
- export type BlockType = "hero" | "page_embed" | "profile_embed" | "doctor_embed" | "specialty_embed" | "richtext" | "faq" | "stats" | "testimonial" | "cta" | "feature_list" | "gallery"
49
+ export type BlockType = "hero" | "page_embed" | "profile_embed" | "doctor_embed" | "specialty_embed" | "richtext" | "faq" | "stats" | "testimonial" | "cta" | "feature_list" | "gallery" | "before_after" | "chips" | "icon_cards" | "image_text"
40
50
 
41
51
  export type BlogAuthor = { firstName: string | null; lastName: string | null; avatarUrl: string | null;}
42
52
 
@@ -56,6 +66,10 @@ export type BlogSlug = { slug: string; updatedAt: string;}
56
66
 
57
67
  export type BlogTag = { id: string; name: string; slug: string; color: string;}
58
68
 
69
+ export type CardIcon = "check" | "phone" | "star" | "heart" | "shield-check" | "sparkles" | "clock" | "calendar" | "user" | "users" | "mail" | "map-pin" | "leaf" | "droplet" | "sun" | "zap" | "award" | "target" | "lightbulb" | "smile" | "thumbs-up" | "info"
70
+
71
+ export type ChipsData = { items: string[]; kicker?: string | undefined;}
72
+
59
73
  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>; seoTitleTemplate?: string | undefined; seoTitle?: string | null | undefined; seoDescription?: string | null | undefined; canonicalUrl?: string | null | undefined; contactInterest?: { label: string; options: string[]; } | null | undefined;}
60
74
 
61
75
  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;}
@@ -100,6 +114,10 @@ export type DataRequestType = "ACCESS" | "RECTIFICATION" | "ERASURE" | "OBJECTIO
100
114
 
101
115
  export type EmbedReferenceData = { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined;}
102
116
 
117
+ export type IconCardsData = { items: { icon: "check" | "phone" | "star" | "heart" | "shield-check" | "sparkles" | "clock" | "calendar" | "user" | "users" | "mail" | "map-pin" | "leaf" | "droplet" | "sun" | "zap" | "award" | "target" | "lightbulb" | "smile" | "thumbs-up" | "info"; title: string; text?: string | undefined; }[]; kicker?: string | undefined; intro?: string | undefined;}
118
+
119
+ export type ImageTextData = { imageUrl: string; imageSide: "left" | "right"; kicker?: string | undefined; alt?: string | undefined; mobileOrder?: "image_first" | "text_first" | undefined; html?: string | undefined;}
120
+
103
121
  export type LeadAttribution = { first?: { utm?: { source?: string | undefined; medium?: string | undefined; campaign?: string | undefined; content?: string | undefined; term?: string | undefined; } | undefined; clickIds?: string[] | undefined; referrer?: string | undefined; landingPath?: string | undefined; at?: string | undefined; } | undefined; last?: { utm?: { source?: string | undefined; medium?: string | undefined; campaign?: string | undefined; content?: string | undefined; term?: string | undefined; } | undefined; clickIds?: string[] | undefined; referrer?: string | undefined; landingPath?: string | undefined; at?: string | undefined; } | undefined;}
104
122
 
105
123
  export type LeadInput = { name: string; email?: string | undefined; phone?: string | undefined; businessName?: string | undefined; message?: string | undefined; source?: string | undefined; metadata?: { [x: string]: unknown; attribution?: { first?: { utm?: { source?: string | undefined; medium?: string | undefined; campaign?: string | undefined; content?: string | undefined; term?: string | undefined; } | undefined; clickIds?: string[] | undefined; referrer?: string | undefined; landingPath?: string | undefined; at?: string | undefined; } | undefined; last?: { utm?: { source?: string | undefined; medium?: string | undefined; campaign?: string | undefined; content?: string | undefined; term?: string | undefined; } | undefined; clickIds?: string[] | undefined; referrer?: string | undefined; landingPath?: string | undefined; at?: string | undefined; } | undefined; } | undefined; } | undefined;}
@@ -116,13 +134,13 @@ export type LegalTermsVersion = { id: string; version: number; publishe
116
134
 
117
135
  export type PageAmbiguousSlugError = { error: string; code: "ambiguous_slug"; candidates: { categorySlug: string | null; }[];}
118
136
 
119
- export type PageBlock = { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "hero"; data: { title: string; subtitle?: string | undefined; imageUrl?: string | undefined; ctaSlot?: string | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "richtext"; data: { html: string; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "faq"; data: { items: { q: string; a: string; }[]; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "stats"; data: { items: { label: string; value: string; }[]; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "testimonial"; data: { quote: string; author: string; role?: string | undefined; avatarUrl?: string | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "cta"; data: { slot: string; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "feature_list"; data: { items: { text: string; icon?: string | undefined; }[]; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "gallery"; data: { images: { url: string; alt?: string | undefined; caption?: string | undefined; }[]; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "page_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "profile_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "doctor_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "specialty_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };}
137
+ export type PageBlock = { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "hero"; data: { title: string; subtitle?: string | undefined; imageUrl?: string | undefined; ctaSlot?: string | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "richtext"; data: { html: string; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "faq"; data: { items: { q: string; a: string; }[]; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "stats"; data: { items: { label: string; value: string; }[]; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "testimonial"; data: { quote: string; author: string; role?: string | undefined; avatarUrl?: string | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "cta"; data: { slot: string; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "feature_list"; data: { items: { text: string; icon?: string | undefined; }[]; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "gallery"; data: { images: { url: string; alt?: string | undefined; caption?: string | undefined; }[]; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "page_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "profile_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "doctor_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "specialty_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "before_after"; data: { pairs: { beforeUrl: string; afterUrl: string; alt?: string | undefined; }[]; kicker?: string | undefined; showCaption?: boolean | undefined; caption?: string | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "chips"; data: { items: string[]; kicker?: string | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "icon_cards"; data: { items: { icon: "check" | "phone" | "star" | "heart" | "shield-check" | "sparkles" | "clock" | "calendar" | "user" | "users" | "mail" | "map-pin" | "leaf" | "droplet" | "sun" | "zap" | "award" | "target" | "lightbulb" | "smile" | "thumbs-up" | "info"; title: string; text?: string | undefined; }[]; kicker?: string | undefined; intro?: string | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "image_text"; data: { imageUrl: string; imageSide: "left" | "right"; kicker?: string | undefined; alt?: string | undefined; mobileOrder?: "image_first" | "text_first" | undefined; html?: string | undefined; };}
120
138
 
121
139
  export type PageCategoryRef = { name: string; slug: string;}
122
140
 
123
141
  export type PageContentMode = "BLOCKS" | "HTML"
124
142
 
125
- export type PageDetail = { slug: string; title: string; subtitle: string | null; excerpt: string | null; coverImageUrl: string | null; type: "SERVICE" | "CUSTOM"; pageType: "custom" | "service" | "treatments" | "specialties" | "team" | "generic"; contentMode: "BLOCKS" | "HTML"; customHtml: string | null; seoTitle: string | null; seoDescription: string | null; category: { name: string; slug: string; } | null; sections: { id: string; order: number; heading: string | null; contentHtml: string; layout: "TEXT" | "TEXT_IMAGE" | "IMAGE_TEXT" | "IMAGE_FULL" | "FEATURE_LIST" | "GALLERY" | "CTA_BLOCK"; backgroundColor: string | null; features: unknown; ctaLabel: string | null; ctaUrl: string | null; ctaIsExternal: boolean; ctaVariant: string | null; images: { url: string; alt: string; caption: string | null; order: number; }[]; }[]; blocks: ({ id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; } & ({ blockType: "hero"; data: { title: string; subtitle?: string | undefined; imageUrl?: string | undefined; ctaSlot?: string | undefined; }; } | { blockType: "richtext"; data: { html: string; }; } | { blockType: "faq"; data: { items: { q: string; a: string; }[]; }; } | { blockType: "stats"; data: { items: { label: string; value: string; }[]; }; } | { blockType: "testimonial"; data: { quote: string; author: string; role?: string | undefined; avatarUrl?: string | undefined; }; } | { blockType: "cta"; data: { slot: string; }; } | { blockType: "feature_list"; data: { items: { text: string; icon?: string | undefined; }[]; }; } | { blockType: "gallery"; data: { images: { url: string; alt?: string | undefined; caption?: string | undefined; }[]; }; } | { blockType: "page_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; }; } | { blockType: "profile_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; }; } | { blockType: "doctor_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; }; } | { blockType: "specialty_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; }; }))[]; jsonLd: unknown; professional: { role: string | null; socialLinks: { platform: "linkedin" | "twitter" | "facebook" | "instagram" | "website" | "other"; url: string; }[]; cv: { education: { id: string; title: string; organization: string | null; startYear: number | null; endYear: number | null; description: string | null; }[]; experience: { id: string; title: string; organization: string | null; startYear: number | null; endYear: number | null; description: string | null; }[]; certifications: { id: string; title: string; organization: string | null; startYear: number | null; endYear: number | null; description: string | null; }[]; memberships: { id: string; title: string; organization: string | null; startYear: number | null; endYear: number | null; description: string | null; }[]; languages: { language: string; level: "basic" | "conversational" | "fluent" | "native" | null; }[]; } | null; fields?: { label: string; value: string; showOnCard: boolean; }[] | undefined; } | null; seo?: { title: string; } | undefined;}
143
+ export type PageDetail = { slug: string; title: string; subtitle: string | null; excerpt: string | null; coverImageUrl: string | null; type: "SERVICE" | "CUSTOM"; pageType: "custom" | "service" | "treatments" | "specialties" | "team" | "generic"; contentMode: "BLOCKS" | "HTML"; customHtml: string | null; seoTitle: string | null; seoDescription: string | null; category: { name: string; slug: string; } | null; sections: { id: string; order: number; heading: string | null; contentHtml: string; layout: "TEXT" | "TEXT_IMAGE" | "IMAGE_TEXT" | "IMAGE_FULL" | "FEATURE_LIST" | "GALLERY" | "CTA_BLOCK"; backgroundColor: string | null; features: unknown; ctaLabel: string | null; ctaUrl: string | null; ctaIsExternal: boolean; ctaVariant: string | null; images: { url: string; alt: string; caption: string | null; order: number; }[]; }[]; blocks: ({ id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; } & ({ blockType: "hero"; data: { title: string; subtitle?: string | undefined; imageUrl?: string | undefined; ctaSlot?: string | undefined; }; } | { blockType: "richtext"; data: { html: string; }; } | { blockType: "faq"; data: { items: { q: string; a: string; }[]; }; } | { blockType: "stats"; data: { items: { label: string; value: string; }[]; }; } | { blockType: "testimonial"; data: { quote: string; author: string; role?: string | undefined; avatarUrl?: string | undefined; }; } | { blockType: "cta"; data: { slot: string; }; } | { blockType: "feature_list"; data: { items: { text: string; icon?: string | undefined; }[]; }; } | { blockType: "gallery"; data: { images: { url: string; alt?: string | undefined; caption?: string | undefined; }[]; }; } | { blockType: "page_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; }; } | { blockType: "profile_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; }; } | { blockType: "doctor_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; }; } | { blockType: "specialty_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; }; } | { blockType: "before_after"; data: { pairs: { beforeUrl: string; afterUrl: string; alt?: string | undefined; }[]; kicker?: string | undefined; showCaption?: boolean | undefined; caption?: string | undefined; }; } | { blockType: "chips"; data: { items: string[]; kicker?: string | undefined; }; } | { blockType: "icon_cards"; data: { items: { icon: "check" | "phone" | "star" | "heart" | "shield-check" | "sparkles" | "clock" | "calendar" | "user" | "users" | "mail" | "map-pin" | "leaf" | "droplet" | "sun" | "zap" | "award" | "target" | "lightbulb" | "smile" | "thumbs-up" | "info"; title: string; text?: string | undefined; }[]; kicker?: string | undefined; intro?: string | undefined; }; } | { blockType: "image_text"; data: { imageUrl: string; imageSide: "left" | "right"; kicker?: string | undefined; alt?: string | undefined; mobileOrder?: "image_first" | "text_first" | undefined; html?: string | undefined; }; }))[]; jsonLd: unknown; professional: { role: string | null; socialLinks: { platform: "linkedin" | "twitter" | "facebook" | "instagram" | "website" | "other"; url: string; }[]; cv: { education: { id: string; title: string; organization: string | null; startYear: number | null; endYear: number | null; description: string | null; }[]; experience: { id: string; title: string; organization: string | null; startYear: number | null; endYear: number | null; description: string | null; }[]; certifications: { id: string; title: string; organization: string | null; startYear: number | null; endYear: number | null; description: string | null; }[]; memberships: { id: string; title: string; organization: string | null; startYear: number | null; endYear: number | null; description: string | null; }[]; languages: { language: string; level: "basic" | "conversational" | "fluent" | "native" | null; }[]; } | null; fields?: { label: string; value: string; showOnCard: boolean; }[] | undefined; } | null; seo?: { title: string; } | undefined;}
126
144
 
127
145
  export type PageListItem = { slug: string; title: string; subtitle: string | null; excerpt: string | null; coverImageUrl: string | null; type: "SERVICE" | "CUSTOM"; pageType: "custom" | "service" | "treatments" | "specialties" | "team" | "generic"; order: number; seoTitle: string | null; seoDescription: string | null; category: { name: string; slug: string; } | null; professional: { role: string | null; fields?: { label: string; value: string; showOnCard: boolean; }[] | undefined; } | null;}
128
146
 
@@ -210,7 +228,7 @@ export type ShopDiscountApplication = { valid: boolean; discount: number;
210
228
  */
211
229
  export type ShopEmailCheck = { exists: boolean;}
212
230
 
213
- export type ShopErrorCode = "STOCK_CHANGED" | "PRICE_CHANGED" | "PRODUCT_UNAVAILABLE" | "DISCOUNT_INVALID" | "SHIPPING_UNAVAILABLE" | "INVALID_INPUT" | "STORE_DISABLED" | "PAYMENT_PROVIDER_ERROR" | "INTERNAL_ERROR" | "BILLING_DATA_REQUIRED" | "INVOICING_NOT_READY" | "FULL_INVOICE_UNAVAILABLE" | "DISCOUNT_LIMIT_REACHED" | "PICKUP_UNAVAILABLE" | "PICKUP_LOCATION_INVALID" | "SHIPPING_ADDRESS_REQUIRED" | "ORDER_TOO_HEAVY" | "TERMS_NOT_ACCEPTED" | "TERMS_VERSION_CHANGED" | "DELIVERY_UNAVAILABLE"
231
+ export type ShopErrorCode = "INVALID_INPUT" | "INVOICING_NOT_READY" | "TERMS_NOT_ACCEPTED" | "TERMS_VERSION_CHANGED" | "STOCK_CHANGED" | "PRICE_CHANGED" | "PRODUCT_UNAVAILABLE" | "DISCOUNT_INVALID" | "SHIPPING_UNAVAILABLE" | "STORE_DISABLED" | "PAYMENT_PROVIDER_ERROR" | "INTERNAL_ERROR" | "BILLING_DATA_REQUIRED" | "FULL_INVOICE_UNAVAILABLE" | "DISCOUNT_LIMIT_REACHED" | "PICKUP_UNAVAILABLE" | "PICKUP_LOCATION_INVALID" | "SHIPPING_ADDRESS_REQUIRED" | "ORDER_TOO_HEAVY" | "DELIVERY_UNAVAILABLE"
214
232
 
215
233
  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; };}
216
234
 
@@ -276,9 +294,9 @@ export type SiteManifestSurfaceValue = true | { path?: string | undefined;}
276
294
 
277
295
  export type TaxType = "IVA" | "IGIC" | "RETENTION" | "OTHER"
278
296
 
279
- export type TrustBadge = { id: string; name: string; logoUrl: string | null; url: string | null; type: "PARTNER" | "INSURANCE" | "SUBVENTION" | "CERTIFICATION" | "AWARD"; sortOrder: number;}
297
+ export type TrustBadge = { id: string; name: string; logoUrl: string | null; url: string | null; type: "PARTNER" | "INSURANCE" | "SUBVENTION" | "CERTIFICATION" | "AWARD" | "CONSUMER_ARBITRATION"; sortOrder: number; adhesionNumber?: string | null | undefined;}
280
298
 
281
- export type TrustBadgeType = "PARTNER" | "INSURANCE" | "SUBVENTION" | "CERTIFICATION" | "AWARD"
299
+ export type TrustBadgeType = "PARTNER" | "INSURANCE" | "SUBVENTION" | "CERTIFICATION" | "AWARD" | "CONSUMER_ARBITRATION"
282
300
 
283
301
  export type WithdrawalRequestInput = { orderReference: string; email: string; items: string; captcha: string; name?: string | undefined; reason?: string | undefined;}
284
302
 
package/dist/index.d.ts CHANGED
@@ -8,6 +8,14 @@ export type AcademyCatalogFiltersPublic = { category: boolean; instructor:
8
8
 
9
9
  export type AcademyCategoryPublic = { id: string; name: string; slug: string; sortOrder: number;}
10
10
 
11
+ export type AcademyCheckoutBilling = { billingName?: string | undefined; billingNif?: string | undefined; billingIdType?: string | undefined; billingIdCountry?: string | undefined; billingAddress?: { street?: string | undefined; postalCode?: string | undefined; city?: string | undefined; region?: string | undefined; country?: string | undefined; } | undefined;}
12
+
13
+ export type AcademyCheckoutErrorCode = "INVALID_INPUT" | "RATE_LIMITED" | "COURSE_NOT_FOUND" | "SALES_CLOSED" | "ENROLLMENT_REQUEST_REQUIRED" | "INVOICING_NOT_READY" | "TERMS_NOT_ACCEPTED" | "TERMS_VERSION_CHANGED" | "CONSENT_REQUIRED" | "CONSENT_VERSION_CHANGED" | "INVALID_BILLING"
14
+
15
+ export type AcademyCheckoutRequest = { courseSlug: string; email: string; firstName: string; lastName: string; successUrl: string; cancelUrl: string; acceptsTerms?: boolean | undefined; termsVersionId?: string | undefined; acceptsWithdrawalWaiver?: boolean | undefined; withdrawalWaiverVersion?: string | undefined; wantsFullInvoice?: boolean | undefined; billing?: { billingName?: string | undefined; billingNif?: string | undefined; billingIdType?: string | undefined; billingIdCountry?: string | undefined; billingAddress?: { street?: string | undefined; postalCode?: string | undefined; city?: string | undefined; region?: string | undefined; country?: string | undefined; } | undefined; } | undefined;}
16
+
17
+ export type AcademyCheckoutSession = { url: string; sessionId: string;}
18
+
11
19
  export type AcademyConfigPublic = { catalogFilters: { category: boolean; instructor: boolean; price: boolean; };}
12
20
 
13
21
  export type AcademyCourseDetail = { id: string; slug: string; title: string; shortDescription: string | null; coverUrl: string | null; priceCents: number; accessMode: "IMMEDIATE" | "DRIP" | "COHORT"; category: { id: string; name: string; slug: string; sortOrder: number; } | null; description: string | null; modules: { id: string; title: string; description: string | null; lessons: { id: string; slug: string; title: string; isFreePreview: boolean; durationSeconds: number | null; hasVideo: boolean; }[]; }[]; instructors: { id: string; firstName: string | null; lastName: string | null; avatarUrl: string | null; }[]; salesEnabled: boolean; requiresValidation: boolean; validationFieldLabel: string | null; validationFields: { key: string; label: string; required: boolean; maxLength?: number | undefined; }[]; metaTitle?: string | null | undefined; seo?: { title: string; } | undefined; withdrawalWaiverRequired?: boolean | undefined; accessDurationMonths?: number | null | undefined; deliveryModality?: "DIGITAL_CONTENT" | "TRAINING_SERVICE" | "IN_PERSON" | "WEBINAR" | null | undefined; withdrawalConsent?: { kind: "DIGITAL_CONTENT_WAIVER" | "SERVICE_START_REQUEST"; text: string; version: string; } | null | undefined; refundGuarantee?: { basis: "LESSONS_OPENED" | "LESSONS_COMPLETED"; thresholdPercent: number | null; windowDays: number | null; } | null | undefined;}
@@ -32,11 +40,13 @@ export type AcademyValidationFieldPublic = { key: string; label: string;
32
40
 
33
41
  export type Analytics = { gaId: string | null; clarityId: string | null; recaptchaSiteKey: string | null; contactFormMode: "NOT_CONFIGURED" | "DISABLED" | "DB_ONLY" | "WEBHOOK" | "RESEND"; metaPixelId: string | null; metaVerificationContent: string | null; googleVerificationContent: string | null; consentRequired: boolean; cookiePolicyVersion: string | null; cookieBanner: { enabled: boolean; title: string | null; body: string | null; acceptLabel: string | null; rejectLabel: string | null; manageLabel: string | null; policyUrl: string | null; }; cookieInventory: { vendor: string; category: "necessary" | "analytics" | "marketing"; }[];}
34
42
 
35
- export type Block = { blockType: "hero"; data: { title: string; subtitle?: string | undefined; imageUrl?: string | undefined; ctaSlot?: string | undefined; };} | { blockType: "richtext"; data: { html: string; };} | { blockType: "faq"; data: { items: { q: string; a: string; }[]; };} | { blockType: "stats"; data: { items: { label: string; value: string; }[]; };} | { blockType: "testimonial"; data: { quote: string; author: string; role?: string | undefined; avatarUrl?: string | undefined; };} | { blockType: "cta"; data: { slot: string; };} | { blockType: "feature_list"; data: { items: { text: string; icon?: string | undefined; }[]; };} | { blockType: "gallery"; data: { images: { url: string; alt?: string | undefined; caption?: string | undefined; }[]; };} | { blockType: "page_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { blockType: "profile_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { blockType: "doctor_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { blockType: "specialty_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };}
43
+ export type BeforeAfterData = { pairs: { beforeUrl: string; afterUrl: string; alt?: string | undefined; }[]; kicker?: string | undefined; showCaption?: boolean | undefined; caption?: string | undefined;}
44
+
45
+ export type Block = { blockType: "hero"; data: { title: string; subtitle?: string | undefined; imageUrl?: string | undefined; ctaSlot?: string | undefined; };} | { blockType: "richtext"; data: { html: string; };} | { blockType: "faq"; data: { items: { q: string; a: string; }[]; };} | { blockType: "stats"; data: { items: { label: string; value: string; }[]; };} | { blockType: "testimonial"; data: { quote: string; author: string; role?: string | undefined; avatarUrl?: string | undefined; };} | { blockType: "cta"; data: { slot: string; };} | { blockType: "feature_list"; data: { items: { text: string; icon?: string | undefined; }[]; };} | { blockType: "gallery"; data: { images: { url: string; alt?: string | undefined; caption?: string | undefined; }[]; };} | { blockType: "page_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { blockType: "profile_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { blockType: "doctor_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { blockType: "specialty_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { blockType: "before_after"; data: { pairs: { beforeUrl: string; afterUrl: string; alt?: string | undefined; }[]; kicker?: string | undefined; showCaption?: boolean | undefined; caption?: string | undefined; };} | { blockType: "chips"; data: { items: string[]; kicker?: string | undefined; };} | { blockType: "icon_cards"; data: { items: { icon: "check" | "phone" | "star" | "heart" | "shield-check" | "sparkles" | "clock" | "calendar" | "user" | "users" | "mail" | "map-pin" | "leaf" | "droplet" | "sun" | "zap" | "award" | "target" | "lightbulb" | "smile" | "thumbs-up" | "info"; title: string; text?: string | undefined; }[]; kicker?: string | undefined; intro?: string | undefined; };} | { blockType: "image_text"; data: { imageUrl: string; imageSide: "left" | "right"; kicker?: string | undefined; alt?: string | undefined; mobileOrder?: "image_first" | "text_first" | undefined; html?: string | undefined; };}
36
46
 
37
47
  export type BlockCta = null | { label: string; url: string; isExternal: boolean; variant: string | null;}
38
48
 
39
- export type BlockType = "hero" | "page_embed" | "profile_embed" | "doctor_embed" | "specialty_embed" | "richtext" | "faq" | "stats" | "testimonial" | "cta" | "feature_list" | "gallery"
49
+ export type BlockType = "hero" | "page_embed" | "profile_embed" | "doctor_embed" | "specialty_embed" | "richtext" | "faq" | "stats" | "testimonial" | "cta" | "feature_list" | "gallery" | "before_after" | "chips" | "icon_cards" | "image_text"
40
50
 
41
51
  export type BlogAuthor = { firstName: string | null; lastName: string | null; avatarUrl: string | null;}
42
52
 
@@ -56,6 +66,10 @@ export type BlogSlug = { slug: string; updatedAt: string;}
56
66
 
57
67
  export type BlogTag = { id: string; name: string; slug: string; color: string;}
58
68
 
69
+ export type CardIcon = "check" | "phone" | "star" | "heart" | "shield-check" | "sparkles" | "clock" | "calendar" | "user" | "users" | "mail" | "map-pin" | "leaf" | "droplet" | "sun" | "zap" | "award" | "target" | "lightbulb" | "smile" | "thumbs-up" | "info"
70
+
71
+ export type ChipsData = { items: string[]; kicker?: string | undefined;}
72
+
59
73
  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>; seoTitleTemplate?: string | undefined; seoTitle?: string | null | undefined; seoDescription?: string | null | undefined; canonicalUrl?: string | null | undefined; contactInterest?: { label: string; options: string[]; } | null | undefined;}
60
74
 
61
75
  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;}
@@ -100,6 +114,10 @@ export type DataRequestType = "ACCESS" | "RECTIFICATION" | "ERASURE" | "OBJECTIO
100
114
 
101
115
  export type EmbedReferenceData = { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined;}
102
116
 
117
+ export type IconCardsData = { items: { icon: "check" | "phone" | "star" | "heart" | "shield-check" | "sparkles" | "clock" | "calendar" | "user" | "users" | "mail" | "map-pin" | "leaf" | "droplet" | "sun" | "zap" | "award" | "target" | "lightbulb" | "smile" | "thumbs-up" | "info"; title: string; text?: string | undefined; }[]; kicker?: string | undefined; intro?: string | undefined;}
118
+
119
+ export type ImageTextData = { imageUrl: string; imageSide: "left" | "right"; kicker?: string | undefined; alt?: string | undefined; mobileOrder?: "image_first" | "text_first" | undefined; html?: string | undefined;}
120
+
103
121
  export type LeadAttribution = { first?: { utm?: { source?: string | undefined; medium?: string | undefined; campaign?: string | undefined; content?: string | undefined; term?: string | undefined; } | undefined; clickIds?: string[] | undefined; referrer?: string | undefined; landingPath?: string | undefined; at?: string | undefined; } | undefined; last?: { utm?: { source?: string | undefined; medium?: string | undefined; campaign?: string | undefined; content?: string | undefined; term?: string | undefined; } | undefined; clickIds?: string[] | undefined; referrer?: string | undefined; landingPath?: string | undefined; at?: string | undefined; } | undefined;}
104
122
 
105
123
  export type LeadInput = { name: string; email?: string | undefined; phone?: string | undefined; businessName?: string | undefined; message?: string | undefined; source?: string | undefined; metadata?: { [x: string]: unknown; attribution?: { first?: { utm?: { source?: string | undefined; medium?: string | undefined; campaign?: string | undefined; content?: string | undefined; term?: string | undefined; } | undefined; clickIds?: string[] | undefined; referrer?: string | undefined; landingPath?: string | undefined; at?: string | undefined; } | undefined; last?: { utm?: { source?: string | undefined; medium?: string | undefined; campaign?: string | undefined; content?: string | undefined; term?: string | undefined; } | undefined; clickIds?: string[] | undefined; referrer?: string | undefined; landingPath?: string | undefined; at?: string | undefined; } | undefined; } | undefined; } | undefined;}
@@ -116,13 +134,13 @@ export type LegalTermsVersion = { id: string; version: number; publishe
116
134
 
117
135
  export type PageAmbiguousSlugError = { error: string; code: "ambiguous_slug"; candidates: { categorySlug: string | null; }[];}
118
136
 
119
- export type PageBlock = { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "hero"; data: { title: string; subtitle?: string | undefined; imageUrl?: string | undefined; ctaSlot?: string | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "richtext"; data: { html: string; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "faq"; data: { items: { q: string; a: string; }[]; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "stats"; data: { items: { label: string; value: string; }[]; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "testimonial"; data: { quote: string; author: string; role?: string | undefined; avatarUrl?: string | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "cta"; data: { slot: string; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "feature_list"; data: { items: { text: string; icon?: string | undefined; }[]; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "gallery"; data: { images: { url: string; alt?: string | undefined; caption?: string | undefined; }[]; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "page_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "profile_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "doctor_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "specialty_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };}
137
+ export type PageBlock = { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "hero"; data: { title: string; subtitle?: string | undefined; imageUrl?: string | undefined; ctaSlot?: string | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "richtext"; data: { html: string; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "faq"; data: { items: { q: string; a: string; }[]; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "stats"; data: { items: { label: string; value: string; }[]; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "testimonial"; data: { quote: string; author: string; role?: string | undefined; avatarUrl?: string | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "cta"; data: { slot: string; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "feature_list"; data: { items: { text: string; icon?: string | undefined; }[]; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "gallery"; data: { images: { url: string; alt?: string | undefined; caption?: string | undefined; }[]; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "page_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "profile_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "doctor_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "specialty_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "before_after"; data: { pairs: { beforeUrl: string; afterUrl: string; alt?: string | undefined; }[]; kicker?: string | undefined; showCaption?: boolean | undefined; caption?: string | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "chips"; data: { items: string[]; kicker?: string | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "icon_cards"; data: { items: { icon: "check" | "phone" | "star" | "heart" | "shield-check" | "sparkles" | "clock" | "calendar" | "user" | "users" | "mail" | "map-pin" | "leaf" | "droplet" | "sun" | "zap" | "award" | "target" | "lightbulb" | "smile" | "thumbs-up" | "info"; title: string; text?: string | undefined; }[]; kicker?: string | undefined; intro?: string | undefined; };} | { id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; blockType: "image_text"; data: { imageUrl: string; imageSide: "left" | "right"; kicker?: string | undefined; alt?: string | undefined; mobileOrder?: "image_first" | "text_first" | undefined; html?: string | undefined; };}
120
138
 
121
139
  export type PageCategoryRef = { name: string; slug: string;}
122
140
 
123
141
  export type PageContentMode = "BLOCKS" | "HTML"
124
142
 
125
- export type PageDetail = { slug: string; title: string; subtitle: string | null; excerpt: string | null; coverImageUrl: string | null; type: "SERVICE" | "CUSTOM"; pageType: "custom" | "service" | "treatments" | "specialties" | "team" | "generic"; contentMode: "BLOCKS" | "HTML"; customHtml: string | null; seoTitle: string | null; seoDescription: string | null; category: { name: string; slug: string; } | null; sections: { id: string; order: number; heading: string | null; contentHtml: string; layout: "TEXT" | "TEXT_IMAGE" | "IMAGE_TEXT" | "IMAGE_FULL" | "FEATURE_LIST" | "GALLERY" | "CTA_BLOCK"; backgroundColor: string | null; features: unknown; ctaLabel: string | null; ctaUrl: string | null; ctaIsExternal: boolean; ctaVariant: string | null; images: { url: string; alt: string; caption: string | null; order: number; }[]; }[]; blocks: ({ id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; } & ({ blockType: "hero"; data: { title: string; subtitle?: string | undefined; imageUrl?: string | undefined; ctaSlot?: string | undefined; }; } | { blockType: "richtext"; data: { html: string; }; } | { blockType: "faq"; data: { items: { q: string; a: string; }[]; }; } | { blockType: "stats"; data: { items: { label: string; value: string; }[]; }; } | { blockType: "testimonial"; data: { quote: string; author: string; role?: string | undefined; avatarUrl?: string | undefined; }; } | { blockType: "cta"; data: { slot: string; }; } | { blockType: "feature_list"; data: { items: { text: string; icon?: string | undefined; }[]; }; } | { blockType: "gallery"; data: { images: { url: string; alt?: string | undefined; caption?: string | undefined; }[]; }; } | { blockType: "page_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; }; } | { blockType: "profile_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; }; } | { blockType: "doctor_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; }; } | { blockType: "specialty_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; }; }))[]; jsonLd: unknown; professional: { role: string | null; socialLinks: { platform: "linkedin" | "twitter" | "facebook" | "instagram" | "website" | "other"; url: string; }[]; cv: { education: { id: string; title: string; organization: string | null; startYear: number | null; endYear: number | null; description: string | null; }[]; experience: { id: string; title: string; organization: string | null; startYear: number | null; endYear: number | null; description: string | null; }[]; certifications: { id: string; title: string; organization: string | null; startYear: number | null; endYear: number | null; description: string | null; }[]; memberships: { id: string; title: string; organization: string | null; startYear: number | null; endYear: number | null; description: string | null; }[]; languages: { language: string; level: "basic" | "conversational" | "fluent" | "native" | null; }[]; } | null; fields?: { label: string; value: string; showOnCard: boolean; }[] | undefined; } | null; seo?: { title: string; } | undefined;}
143
+ export type PageDetail = { slug: string; title: string; subtitle: string | null; excerpt: string | null; coverImageUrl: string | null; type: "SERVICE" | "CUSTOM"; pageType: "custom" | "service" | "treatments" | "specialties" | "team" | "generic"; contentMode: "BLOCKS" | "HTML"; customHtml: string | null; seoTitle: string | null; seoDescription: string | null; category: { name: string; slug: string; } | null; sections: { id: string; order: number; heading: string | null; contentHtml: string; layout: "TEXT" | "TEXT_IMAGE" | "IMAGE_TEXT" | "IMAGE_FULL" | "FEATURE_LIST" | "GALLERY" | "CTA_BLOCK"; backgroundColor: string | null; features: unknown; ctaLabel: string | null; ctaUrl: string | null; ctaIsExternal: boolean; ctaVariant: string | null; images: { url: string; alt: string; caption: string | null; order: number; }[]; }[]; blocks: ({ id: string; order: number; heading?: string | null | undefined; backgroundColor?: string | null | undefined; cta?: { label: string; url: string; isExternal: boolean; variant: string | null; } | null | undefined; resolved?: { slug: string; title: string; excerpt: string | null; coverImageUrl: string | null; role: string | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; category?: { name: string; slug: string; } | null | undefined; } | null | undefined; } & ({ blockType: "hero"; data: { title: string; subtitle?: string | undefined; imageUrl?: string | undefined; ctaSlot?: string | undefined; }; } | { blockType: "richtext"; data: { html: string; }; } | { blockType: "faq"; data: { items: { q: string; a: string; }[]; }; } | { blockType: "stats"; data: { items: { label: string; value: string; }[]; }; } | { blockType: "testimonial"; data: { quote: string; author: string; role?: string | undefined; avatarUrl?: string | undefined; }; } | { blockType: "cta"; data: { slot: string; }; } | { blockType: "feature_list"; data: { items: { text: string; icon?: string | undefined; }[]; }; } | { blockType: "gallery"; data: { images: { url: string; alt?: string | undefined; caption?: string | undefined; }[]; }; } | { blockType: "page_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; }; } | { blockType: "profile_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; }; } | { blockType: "doctor_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; }; } | { blockType: "specialty_embed"; data: { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined; }; } | { blockType: "before_after"; data: { pairs: { beforeUrl: string; afterUrl: string; alt?: string | undefined; }[]; kicker?: string | undefined; showCaption?: boolean | undefined; caption?: string | undefined; }; } | { blockType: "chips"; data: { items: string[]; kicker?: string | undefined; }; } | { blockType: "icon_cards"; data: { items: { icon: "check" | "phone" | "star" | "heart" | "shield-check" | "sparkles" | "clock" | "calendar" | "user" | "users" | "mail" | "map-pin" | "leaf" | "droplet" | "sun" | "zap" | "award" | "target" | "lightbulb" | "smile" | "thumbs-up" | "info"; title: string; text?: string | undefined; }[]; kicker?: string | undefined; intro?: string | undefined; }; } | { blockType: "image_text"; data: { imageUrl: string; imageSide: "left" | "right"; kicker?: string | undefined; alt?: string | undefined; mobileOrder?: "image_first" | "text_first" | undefined; html?: string | undefined; }; }))[]; jsonLd: unknown; professional: { role: string | null; socialLinks: { platform: "linkedin" | "twitter" | "facebook" | "instagram" | "website" | "other"; url: string; }[]; cv: { education: { id: string; title: string; organization: string | null; startYear: number | null; endYear: number | null; description: string | null; }[]; experience: { id: string; title: string; organization: string | null; startYear: number | null; endYear: number | null; description: string | null; }[]; certifications: { id: string; title: string; organization: string | null; startYear: number | null; endYear: number | null; description: string | null; }[]; memberships: { id: string; title: string; organization: string | null; startYear: number | null; endYear: number | null; description: string | null; }[]; languages: { language: string; level: "basic" | "conversational" | "fluent" | "native" | null; }[]; } | null; fields?: { label: string; value: string; showOnCard: boolean; }[] | undefined; } | null; seo?: { title: string; } | undefined;}
126
144
 
127
145
  export type PageListItem = { slug: string; title: string; subtitle: string | null; excerpt: string | null; coverImageUrl: string | null; type: "SERVICE" | "CUSTOM"; pageType: "custom" | "service" | "treatments" | "specialties" | "team" | "generic"; order: number; seoTitle: string | null; seoDescription: string | null; category: { name: string; slug: string; } | null; professional: { role: string | null; fields?: { label: string; value: string; showOnCard: boolean; }[] | undefined; } | null;}
128
146
 
@@ -210,7 +228,7 @@ export type ShopDiscountApplication = { valid: boolean; discount: number;
210
228
  */
211
229
  export type ShopEmailCheck = { exists: boolean;}
212
230
 
213
- export type ShopErrorCode = "STOCK_CHANGED" | "PRICE_CHANGED" | "PRODUCT_UNAVAILABLE" | "DISCOUNT_INVALID" | "SHIPPING_UNAVAILABLE" | "INVALID_INPUT" | "STORE_DISABLED" | "PAYMENT_PROVIDER_ERROR" | "INTERNAL_ERROR" | "BILLING_DATA_REQUIRED" | "INVOICING_NOT_READY" | "FULL_INVOICE_UNAVAILABLE" | "DISCOUNT_LIMIT_REACHED" | "PICKUP_UNAVAILABLE" | "PICKUP_LOCATION_INVALID" | "SHIPPING_ADDRESS_REQUIRED" | "ORDER_TOO_HEAVY" | "TERMS_NOT_ACCEPTED" | "TERMS_VERSION_CHANGED" | "DELIVERY_UNAVAILABLE"
231
+ export type ShopErrorCode = "INVALID_INPUT" | "INVOICING_NOT_READY" | "TERMS_NOT_ACCEPTED" | "TERMS_VERSION_CHANGED" | "STOCK_CHANGED" | "PRICE_CHANGED" | "PRODUCT_UNAVAILABLE" | "DISCOUNT_INVALID" | "SHIPPING_UNAVAILABLE" | "STORE_DISABLED" | "PAYMENT_PROVIDER_ERROR" | "INTERNAL_ERROR" | "BILLING_DATA_REQUIRED" | "FULL_INVOICE_UNAVAILABLE" | "DISCOUNT_LIMIT_REACHED" | "PICKUP_UNAVAILABLE" | "PICKUP_LOCATION_INVALID" | "SHIPPING_ADDRESS_REQUIRED" | "ORDER_TOO_HEAVY" | "DELIVERY_UNAVAILABLE"
214
232
 
215
233
  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; };}
216
234
 
@@ -276,9 +294,9 @@ export type SiteManifestSurfaceValue = true | { path?: string | undefined;}
276
294
 
277
295
  export type TaxType = "IVA" | "IGIC" | "RETENTION" | "OTHER"
278
296
 
279
- export type TrustBadge = { id: string; name: string; logoUrl: string | null; url: string | null; type: "PARTNER" | "INSURANCE" | "SUBVENTION" | "CERTIFICATION" | "AWARD"; sortOrder: number;}
297
+ export type TrustBadge = { id: string; name: string; logoUrl: string | null; url: string | null; type: "PARTNER" | "INSURANCE" | "SUBVENTION" | "CERTIFICATION" | "AWARD" | "CONSUMER_ARBITRATION"; sortOrder: number; adhesionNumber?: string | null | undefined;}
280
298
 
281
- export type TrustBadgeType = "PARTNER" | "INSURANCE" | "SUBVENTION" | "CERTIFICATION" | "AWARD"
299
+ export type TrustBadgeType = "PARTNER" | "INSURANCE" | "SUBVENTION" | "CERTIFICATION" | "AWARD" | "CONSUMER_ARBITRATION"
282
300
 
283
301
  export type WithdrawalRequestInput = { orderReference: string; email: string; items: string; captcha: string; name?: string | undefined; reason?: string | undefined;}
284
302
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";AAkFO,IAAM,kBAAA,GAAqB,OAAO,MAAA,CAAO;AAAA,EAC9C,QAAA;AAAA,EACA,eAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA,oBAAA;AAAA,EACA;AACF,CAAU","file":"index.js","sourcesContent":["/**\n * `@reblu/site-contracts` — public, dependency-free TypeScript types for the\n * Reblu SITE API (REB-414 / design doc §2).\n *\n * These types are the SDK-facing view of every `/api/site/*` response. They are\n * re-derived (`z.infer`) from the hand-authored response schemas that live in\n * base-api (`apps/base-api/src/lib/contracts/*.contract.ts`) and imported here\n * through the build-time-only `@reblu/base-api-contracts` type alias.\n *\n * Guarantees (enforced by the leakage guard tests):\n * - Everything below is `export type` — the import is erased at build time, so\n * NO Zod and NO Prisma reaches a consumer's runtime or `node_modules` graph.\n * The one exception is `DATA_REQUEST_TYPES` (REB-1005): a plain, import-free\n * array literal, the package's only runtime value.\n * - The published `.d.ts` is flattened and self-contained: the alias and\n * `z.infer` do not survive into the emitted declarations.\n * - Never re-exports an internal / Prisma-generated type — only the public\n * output DTOs base-api explicitly publishes.\n *\n * When base-api adds a new public contract type, add it to the matching group\n * below. The explicit list (over `export type *`) keeps the public surface a\n * reviewed, intentional decision and avoids leaking internal `*Schema` names.\n */\n\n// Envelope / pagination\nexport type { PaginationMeta } from '@reblu/base-api-contracts'\n\n// Analytics + shared contact-form mode\nexport type { Analytics, ContactFormMode } from '@reblu/base-api-contracts'\n\n// REB-845 — the tenant-editable cookie banner copy shape, standalone (not just\n// nested in `Analytics`), so `@reblu/site-next`'s `cookieBannerToConsentTexts`\n// can type its input against the real contract instead of a hand-rolled copy.\nexport type { CookieBanner } from '@reblu/base-api-contracts'\n\n// Site config\nexport type {\n Config,\n ConfigAddress,\n ConfigFiscal,\n ConfigFiscalRegistry,\n ConfigSocial,\n ConfigTaxIdKind,\n // REB-826 — typed opening hours.\n ConfigOpeningHours,\n ConfigOpeningHoursRange,\n ConfigOpeningHoursDay,\n} from '@reblu/base-api-contracts'\n\n// REB-871 — the resolved `seo` block on every detail response (pages, blog\n// posts, shop products, academy courses). `seo.title` is the FINAL page title.\nexport type { Seo } from '@reblu/base-api-contracts'\n\n// Contact form\nexport type { ContactFormSubmission, ContactFormInput } from '@reblu/base-api-contracts'\n// REB-1078 — the raw lead-origin touches a SITE sends in `metadata.attribution`\n// (contact form and `/api/site/leads`); base-api classifies the channel.\nexport type { LeadAttribution, LeadTouch } from '@reblu/base-api-contracts'\n\n// Leads\nexport type { LeadInput, LeadSubmission } from '@reblu/base-api-contracts'\n\n// GDPR data-subject requests (REB-77 endpoint, REB-980 SDK) — the public\n// `/derechos-rgpd` form body and its 72h acknowledgement.\nexport type {\n DataRequestInput,\n DataRequestSubmission,\n DataRequestType,\n} from '@reblu/base-api-contracts'\nimport type { DataRequestType } from '@reblu/base-api-contracts'\n\n/**\n * REB-1005 — every GDPR right a data subject can exercise, in base-api's order.\n * The ONE runtime value this package ships: server code (a SITE's Route\n * Handler, `@reblu/site-next`'s `createDataRequestRoute`) needs the list too,\n * and `@reblu/site-blocks` re-exports it as before.\n *\n * Single source: base-api's `dataRequestTypeSchema`. `satisfies` rejects a\n * member base-api does not know, `MissingDataRequestType` below rejects one it\n * knows and this list lacks, and `tests/unit/data-request-types.test.ts` pins\n * the order. Plain array literal, no import — the runtime stays dependency-free.\n */\nexport const DATA_REQUEST_TYPES = Object.freeze([\n 'ACCESS',\n 'RECTIFICATION',\n 'ERASURE',\n 'OBJECTION',\n 'PORTABILITY',\n 'RESTRICTION',\n 'AUTOMATED_DECISION',\n 'INFORMATION',\n] as const) satisfies readonly DataRequestType[]\n\n/** Compile error when base-api adds a right this list does not carry. */\ntype AssertNoneMissing<T extends never> = T\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ntype MissingDataRequestType = AssertNoneMissing<\n Exclude<DataRequestType, (typeof DATA_REQUEST_TYPES)[number]>\n>\n\n// Blog\nexport type {\n BlogAuthor,\n BlogAuthorDetail,\n BlogCategory,\n BlogCategoryWithCount,\n BlogTag,\n BlogPostListItem,\n BlogPostDetail,\n BlogPostPreview,\n BlogSlug,\n} from '@reblu/base-api-contracts'\n\n// Pages\nexport type {\n // The flexible pageType (service|custom|treatments|specialties|team|generic)\n // — REB-63: this is what `pages.list`'s `type` filter actually validates\n // against server-side (`pagesListParamsSchema`), not `LegacyPageType`.\n PageType,\n // Legacy DB page type (SERVICE|CUSTOM) — the `type`/`category` fields still\n // carried on each `PageListItem`/`PageDetail` for backward compat during the\n // REB-75 dual-read window. NOT the `pages.list` filter's value space anymore.\n LegacyPageType,\n PageContentMode,\n SectionLayout,\n PageCategoryRef,\n PageListItem,\n PageSectionImage,\n PageSection,\n PageDetail,\n PageSlug,\n // REB-63: `pages.list`'s sort param — same reasoning as AcademyCourseSort\n // below (a typo is a compile error instead of a silent no-op fallback).\n PagesListSort,\n // REB-869 — `pages.list`'s query, incl. `featured` (with `category`: that\n // category's featured pages, max 3, in their stored order).\n PagesListQuery,\n // REB-75 D-D — the typed block registry on `PageDetail.blocks[]`.\n BlockType,\n Block,\n // REB-849 — each block mirrors its parent section's heading/backgroundColor/\n // cta; REB-851 phase 1 — doctor_embed/specialty_embed blocks additionally\n // carry `resolved` (present only on those two block types).\n PageBlock,\n BlockCta,\n ResolvedEmbed,\n // REB-867 — slugs are unique per category: the embed reference shape\n // (`pageId`/`categorySlug`) and the 409 body of an ambiguous `GET /pages/[slug]`.\n EmbedReferenceData,\n PageAmbiguousSlugError,\n} from '@reblu/base-api-contracts'\n\n// Professional profile (REB-63) — pageType='team' only. Sector-agnostic\n// structured CV, same platform-shape/tenant-content split as CustomFieldDefinition.\n// REB-1099: `ProfessionalField` — a tenant-defined field (e.g. a registration\n// number) on the card (`ProfessionalSummary.fields`) and profile.\nexport type {\n ProfessionalField,\n ProfessionalSummary,\n ProfessionalProfile,\n ProfessionalCv,\n ProfessionalCvEntry,\n ProfessionalLanguage,\n ProfessionalLanguageLevel,\n ProfessionalSocialLink,\n ProfessionalSocialPlatform,\n} from '@reblu/base-api-contracts'\n\n// Custom-field registry (REB-475 / REB-75) — entity-agnostic, shared with pages/team\nexport type {\n CustomFieldValueType,\n CustomFieldEntityType,\n CustomFieldOption,\n CustomFieldDefinition,\n} from '@reblu/base-api-contracts'\n\n// Shop\nexport type {\n TaxType,\n ProductType,\n ShopConfig,\n // Store-wide product trust items (REB-858)\n ShopProductTrustIcon,\n ShopProductTrustItem,\n ShopTaxRateRef,\n ShopProductImage,\n ShopProductVideo,\n ShopProductCategoryRef,\n ShopInventoryRef,\n ShopCategory,\n ShopProductListItem,\n ShopProductVariant,\n ShopBundleComponent,\n ShopRelatedProduct,\n ShopProductDetail,\n // Taxonomy + attributes + facets (REB-474/475)\n ShopTaxonomyTermRef,\n ShopProductAttributes,\n // Per-axis selection mode (REB-809/REB-801)\n ShopTaxonomySelectionMode,\n ShopSort,\n ShopProductListParams,\n ShopFacets,\n // Write inputs (REB-438)\n ShopCartItemInput,\n ShopAddressInput,\n ShopBillingInput,\n ShopCheckoutInput,\n ShopValidateCartInput,\n ShopApplyDiscountInput,\n // Write responses (REB-438)\n ShopCheckoutSession,\n ShopCartValidationError,\n ShopCartValidationItem,\n ShopCartValidation,\n ShopDiscountApplication,\n // Automatic staff discount, additive on the write responses (REB-1131)\n ShopStaffAutoDiscount,\n // Order lookup (REB-829)\n ShopOrderItem,\n ShopOrder,\n // The order's invoice reference (REB-73)\n ShopOrderInvoice,\n // Stable, machine-readable write-endpoint error codes (REB-836)\n ShopErrorCode,\n // Single-step checkout (REB-1197 / REB-1198): delivery rules, pickup\n // points, resolved checkout copy, the terms version to accept, the\n // delivery choice and the pre-payment quote.\n ShopPickupLocation,\n ShopCheckoutDeliveryConfig,\n ShopCheckoutCopy,\n ShopTermsVersionRef,\n ShopFulfillmentInput,\n ShopQuoteInput,\n ShopQuoteLine,\n ShopQuote,\n} from '@reblu/base-api-contracts'\n\n// REB-834 — `POST /api/site/shop/check-email` is deprecated: it was an\n// account-enumeration oracle and now always answers `{ exists: false }`.\n// Kept (a minor may only deprecate); removed in the next major.\nexport type {\n /**\n * @deprecated REB-834 — `POST /api/site/shop/check-email` no longer reveals\n * whether an account exists. Do not call it; removed in the next major.\n */\n ShopCheckEmailInput,\n /**\n * @deprecated REB-834 — `exists` is always `false`. Never branch UI on it:\n * the checkout always offers «Iniciar sesión o continuar como invitado» and\n * the server links the order to an existing account after payment. Removed\n * in the next major.\n */\n ShopEmailCheck,\n} from '@reblu/base-api-contracts'\n\n// Academy (REB-507) — public course catalogue. `AcademyCourseSort` is the query\n// contract for the `sort` param, so the SDK can type it as a union instead of a\n// bare string (an unknown key is silently ignored server-side).\nexport type {\n AcademyCourseSort,\n // REB-547 — the documented catalogue query: q, sort, category, instructor\n // (a user id from `GET /api/site/academy/instructors`), free and the price\n // range in integer cents.\n AcademyCourseListQuery,\n AcademyCategoryPublic,\n AcademyLessonPublic,\n AcademyModulePublic,\n AcademyInstructorPublic,\n AcademyCourseSummary,\n AcademyCourseDetail,\n // REB-83 — tenant-configurable validation fields (drives the enrollment CTA form).\n AcademyValidationFieldPublic,\n // REB-1135 — a free-preview lesson, viewable by the public\n // (`GET /api/site/academy/courses/{slug}/lessons/{lessonSlug}`).\n AcademyLessonPreview,\n AcademyLessonPreviewVideo,\n // REB-1234 — tenant academy settings for the SITE\n // (`GET /api/site/academy/config`): which catalogue filters are switched on.\n AcademyConfigPublic,\n AcademyCatalogFiltersPublic,\n} from '@reblu/base-api-contracts'\n\n// Legal\nexport type { Legal, LegalTermsVersion } from '@reblu/base-api-contracts'\n// REB-1201 — the withdrawal form (`POST /api/site/withdrawal-requests`).\nexport type {\n WithdrawalRequestInput,\n WithdrawalRequestSubmission,\n} from '@reblu/base-api-contracts'\n\n// CTAs\nexport type { Cta } from '@reblu/base-api-contracts'\n\n// Trust badges\nexport type { TrustBadge, TrustBadgeType } from '@reblu/base-api-contracts'\n\n// SITE capability manifest (`/.well-known/reblu-site.json`) — REB-777.\n// Direction note (see `site-manifest.contract.ts` in base-api): this is the\n// one contract group a SITE produces and base-api consumes, the opposite of\n// every group above. The TYPE still flows through this same alias so the\n// SDK and nexus never describe two different shapes for it; the real Zod\n// validation stays in base-api only — this package never gains a Zod\n// runtime dependency.\nexport type {\n SiteManifest,\n SiteManifestSurfaceValue,\n SiteCapabilitySurfaceKey,\n} from '@reblu/base-api-contracts'\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";AAkFO,IAAM,kBAAA,GAAqB,OAAO,MAAA,CAAO;AAAA,EAC9C,QAAA;AAAA,EACA,eAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA,oBAAA;AAAA,EACA;AACF,CAAU","file":"index.js","sourcesContent":["/**\n * `@reblu/site-contracts` — public, dependency-free TypeScript types for the\n * Reblu SITE API (REB-414 / design doc §2).\n *\n * These types are the SDK-facing view of every `/api/site/*` response. They are\n * re-derived (`z.infer`) from the hand-authored response schemas that live in\n * base-api (`apps/base-api/src/lib/contracts/*.contract.ts`) and imported here\n * through the build-time-only `@reblu/base-api-contracts` type alias.\n *\n * Guarantees (enforced by the leakage guard tests):\n * - Everything below is `export type` — the import is erased at build time, so\n * NO Zod and NO Prisma reaches a consumer's runtime or `node_modules` graph.\n * The one exception is `DATA_REQUEST_TYPES` (REB-1005): a plain, import-free\n * array literal, the package's only runtime value.\n * - The published `.d.ts` is flattened and self-contained: the alias and\n * `z.infer` do not survive into the emitted declarations.\n * - Never re-exports an internal / Prisma-generated type — only the public\n * output DTOs base-api explicitly publishes.\n *\n * When base-api adds a new public contract type, add it to the matching group\n * below. The explicit list (over `export type *`) keeps the public surface a\n * reviewed, intentional decision and avoids leaking internal `*Schema` names.\n */\n\n// Envelope / pagination\nexport type { PaginationMeta } from '@reblu/base-api-contracts'\n\n// Analytics + shared contact-form mode\nexport type { Analytics, ContactFormMode } from '@reblu/base-api-contracts'\n\n// REB-845 — the tenant-editable cookie banner copy shape, standalone (not just\n// nested in `Analytics`), so `@reblu/site-next`'s `cookieBannerToConsentTexts`\n// can type its input against the real contract instead of a hand-rolled copy.\nexport type { CookieBanner } from '@reblu/base-api-contracts'\n\n// Site config\nexport type {\n Config,\n ConfigAddress,\n ConfigFiscal,\n ConfigFiscalRegistry,\n ConfigSocial,\n ConfigTaxIdKind,\n // REB-826 — typed opening hours.\n ConfigOpeningHours,\n ConfigOpeningHoursRange,\n ConfigOpeningHoursDay,\n} from '@reblu/base-api-contracts'\n\n// REB-871 — the resolved `seo` block on every detail response (pages, blog\n// posts, shop products, academy courses). `seo.title` is the FINAL page title.\nexport type { Seo } from '@reblu/base-api-contracts'\n\n// Contact form\nexport type { ContactFormSubmission, ContactFormInput } from '@reblu/base-api-contracts'\n// REB-1078 — the raw lead-origin touches a SITE sends in `metadata.attribution`\n// (contact form and `/api/site/leads`); base-api classifies the channel.\nexport type { LeadAttribution, LeadTouch } from '@reblu/base-api-contracts'\n\n// Leads\nexport type { LeadInput, LeadSubmission } from '@reblu/base-api-contracts'\n\n// GDPR data-subject requests (REB-77 endpoint, REB-980 SDK) — the public\n// `/derechos-rgpd` form body and its 72h acknowledgement.\nexport type {\n DataRequestInput,\n DataRequestSubmission,\n DataRequestType,\n} from '@reblu/base-api-contracts'\nimport type { DataRequestType } from '@reblu/base-api-contracts'\n\n/**\n * REB-1005 — every GDPR right a data subject can exercise, in base-api's order.\n * The ONE runtime value this package ships: server code (a SITE's Route\n * Handler, `@reblu/site-next`'s `createDataRequestRoute`) needs the list too,\n * and `@reblu/site-blocks` re-exports it as before.\n *\n * Single source: base-api's `dataRequestTypeSchema`. `satisfies` rejects a\n * member base-api does not know, `MissingDataRequestType` below rejects one it\n * knows and this list lacks, and `tests/unit/data-request-types.test.ts` pins\n * the order. Plain array literal, no import — the runtime stays dependency-free.\n */\nexport const DATA_REQUEST_TYPES = Object.freeze([\n 'ACCESS',\n 'RECTIFICATION',\n 'ERASURE',\n 'OBJECTION',\n 'PORTABILITY',\n 'RESTRICTION',\n 'AUTOMATED_DECISION',\n 'INFORMATION',\n] as const) satisfies readonly DataRequestType[]\n\n/** Compile error when base-api adds a right this list does not carry. */\ntype AssertNoneMissing<T extends never> = T\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ntype MissingDataRequestType = AssertNoneMissing<\n Exclude<DataRequestType, (typeof DATA_REQUEST_TYPES)[number]>\n>\n\n// Blog\nexport type {\n BlogAuthor,\n BlogAuthorDetail,\n BlogCategory,\n BlogCategoryWithCount,\n BlogTag,\n BlogPostListItem,\n BlogPostDetail,\n BlogPostPreview,\n BlogSlug,\n} from '@reblu/base-api-contracts'\n\n// Pages\nexport type {\n // The flexible pageType (service|custom|treatments|specialties|team|generic)\n // — REB-63: this is what `pages.list`'s `type` filter actually validates\n // against server-side (`pagesListParamsSchema`), not `LegacyPageType`.\n PageType,\n // Legacy DB page type (SERVICE|CUSTOM) — the `type`/`category` fields still\n // carried on each `PageListItem`/`PageDetail` for backward compat during the\n // REB-75 dual-read window. NOT the `pages.list` filter's value space anymore.\n LegacyPageType,\n PageContentMode,\n SectionLayout,\n PageCategoryRef,\n PageListItem,\n PageSectionImage,\n PageSection,\n PageDetail,\n PageSlug,\n // REB-63: `pages.list`'s sort param — same reasoning as AcademyCourseSort\n // below (a typo is a compile error instead of a silent no-op fallback).\n PagesListSort,\n // REB-869 — `pages.list`'s query, incl. `featured` (with `category`: that\n // category's featured pages, max 3, in their stored order).\n PagesListQuery,\n // REB-75 D-D — the typed block registry on `PageDetail.blocks[]`.\n BlockType,\n Block,\n // REB-849 — each block mirrors its parent section's heading/backgroundColor/\n // cta; REB-851 phase 1 — doctor_embed/specialty_embed blocks additionally\n // carry `resolved` (present only on those two block types).\n PageBlock,\n BlockCta,\n ResolvedEmbed,\n // REB-867 — slugs are unique per category: the embed reference shape\n // (`pageId`/`categorySlug`) and the 409 body of an ambiguous `GET /pages/[slug]`.\n EmbedReferenceData,\n PageAmbiguousSlugError,\n // REB-1265..1268 — `data` of the additive content blocks, for the\n // `@reblu/site-blocks` drop-in components that render them.\n BeforeAfterData,\n ChipsData,\n IconCardsData,\n // REB-1267 — the curated icon names of `icon_cards` (no uploads).\n CardIcon,\n ImageTextData,\n} from '@reblu/base-api-contracts'\n\n// Professional profile (REB-63) — pageType='team' only. Sector-agnostic\n// structured CV, same platform-shape/tenant-content split as CustomFieldDefinition.\n// REB-1099: `ProfessionalField` — a tenant-defined field (e.g. a registration\n// number) on the card (`ProfessionalSummary.fields`) and profile.\nexport type {\n ProfessionalField,\n ProfessionalSummary,\n ProfessionalProfile,\n ProfessionalCv,\n ProfessionalCvEntry,\n ProfessionalLanguage,\n ProfessionalLanguageLevel,\n ProfessionalSocialLink,\n ProfessionalSocialPlatform,\n} from '@reblu/base-api-contracts'\n\n// Custom-field registry (REB-475 / REB-75) — entity-agnostic, shared with pages/team\nexport type {\n CustomFieldValueType,\n CustomFieldEntityType,\n CustomFieldOption,\n CustomFieldDefinition,\n} from '@reblu/base-api-contracts'\n\n// Shop\nexport type {\n TaxType,\n ProductType,\n ShopConfig,\n // Store-wide product trust items (REB-858)\n ShopProductTrustIcon,\n ShopProductTrustItem,\n ShopTaxRateRef,\n ShopProductImage,\n ShopProductVideo,\n ShopProductCategoryRef,\n ShopInventoryRef,\n ShopCategory,\n ShopProductListItem,\n ShopProductVariant,\n ShopBundleComponent,\n ShopRelatedProduct,\n ShopProductDetail,\n // Taxonomy + attributes + facets (REB-474/475)\n ShopTaxonomyTermRef,\n ShopProductAttributes,\n // Per-axis selection mode (REB-809/REB-801)\n ShopTaxonomySelectionMode,\n ShopSort,\n ShopProductListParams,\n ShopFacets,\n // Write inputs (REB-438)\n ShopCartItemInput,\n ShopAddressInput,\n ShopBillingInput,\n ShopCheckoutInput,\n ShopValidateCartInput,\n ShopApplyDiscountInput,\n // Write responses (REB-438)\n ShopCheckoutSession,\n ShopCartValidationError,\n ShopCartValidationItem,\n ShopCartValidation,\n ShopDiscountApplication,\n // Automatic staff discount, additive on the write responses (REB-1131)\n ShopStaffAutoDiscount,\n // Order lookup (REB-829)\n ShopOrderItem,\n ShopOrder,\n // The order's invoice reference (REB-73)\n ShopOrderInvoice,\n // Stable, machine-readable write-endpoint error codes (REB-836)\n ShopErrorCode,\n // Single-step checkout (REB-1197 / REB-1198): delivery rules, pickup\n // points, resolved checkout copy, the terms version to accept, the\n // delivery choice and the pre-payment quote.\n ShopPickupLocation,\n ShopCheckoutDeliveryConfig,\n ShopCheckoutCopy,\n ShopTermsVersionRef,\n ShopFulfillmentInput,\n ShopQuoteInput,\n ShopQuoteLine,\n ShopQuote,\n} from '@reblu/base-api-contracts'\n\n// REB-834 — `POST /api/site/shop/check-email` is deprecated: it was an\n// account-enumeration oracle and now always answers `{ exists: false }`.\n// Kept (a minor may only deprecate); removed in the next major.\nexport type {\n /**\n * @deprecated REB-834 — `POST /api/site/shop/check-email` no longer reveals\n * whether an account exists. Do not call it; removed in the next major.\n */\n ShopCheckEmailInput,\n /**\n * @deprecated REB-834 — `exists` is always `false`. Never branch UI on it:\n * the checkout always offers «Iniciar sesión o continuar como invitado» and\n * the server links the order to an existing account after payment. Removed\n * in the next major.\n */\n ShopEmailCheck,\n} from '@reblu/base-api-contracts'\n\n// Academy (REB-507) — public course catalogue. `AcademyCourseSort` is the query\n// contract for the `sort` param, so the SDK can type it as a union instead of a\n// bare string (an unknown key is silently ignored server-side).\nexport type {\n AcademyCourseSort,\n // REB-547 — the documented catalogue query: q, sort, category, instructor\n // (a user id from `GET /api/site/academy/instructors`), free and the price\n // range in integer cents.\n AcademyCourseListQuery,\n AcademyCategoryPublic,\n AcademyLessonPublic,\n AcademyModulePublic,\n AcademyInstructorPublic,\n AcademyCourseSummary,\n AcademyCourseDetail,\n // REB-83 — tenant-configurable validation fields (drives the enrollment CTA form).\n AcademyValidationFieldPublic,\n // REB-1135 — a free-preview lesson, viewable by the public\n // (`GET /api/site/academy/courses/{slug}/lessons/{lessonSlug}`).\n AcademyLessonPreview,\n AcademyLessonPreviewVideo,\n // REB-1234 — tenant academy settings for the SITE\n // (`GET /api/site/academy/config`): which catalogue filters are switched on.\n AcademyConfigPublic,\n AcademyCatalogFiltersPublic,\n // REB-1264 — guest course checkout (`POST /api/site/academy/checkout`): a\n // course that needs no validation is bought in one step and the account is\n // created after payment. The body, its full-invoice block, the Stripe\n // session answer and the stable error codes.\n AcademyCheckoutRequest,\n AcademyCheckoutBilling,\n AcademyCheckoutSession,\n AcademyCheckoutErrorCode,\n} from '@reblu/base-api-contracts'\n\n// Legal\nexport type { Legal, LegalTermsVersion } from '@reblu/base-api-contracts'\n// REB-1201 — the withdrawal form (`POST /api/site/withdrawal-requests`).\nexport type {\n WithdrawalRequestInput,\n WithdrawalRequestSubmission,\n} from '@reblu/base-api-contracts'\n\n// CTAs\nexport type { Cta } from '@reblu/base-api-contracts'\n\n// Trust badges\nexport type { TrustBadge, TrustBadgeType } from '@reblu/base-api-contracts'\n\n// SITE capability manifest (`/.well-known/reblu-site.json`) — REB-777.\n// Direction note (see `site-manifest.contract.ts` in base-api): this is the\n// one contract group a SITE produces and base-api consumes, the opposite of\n// every group above. The TYPE still flows through this same alias so the\n// SDK and nexus never describe two different shapes for it; the real Zod\n// validation stays in base-api only — this package never gains a Zod\n// runtime dependency.\nexport type {\n SiteManifest,\n SiteManifestSurfaceValue,\n SiteCapabilitySurfaceKey,\n} from '@reblu/base-api-contracts'\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reblu/site-contracts",
3
- "version": "1.27.0",
3
+ "version": "1.29.0",
4
4
  "private": false,
5
5
  "description": "Public, dependency-free TypeScript types for the Reblu SITE API (no Zod, no Prisma at runtime; one runtime value: DATA_REQUEST_TYPES).",
6
6
  "license": "Apache-2.0",