@reblu/site-contracts 1.30.0 → 1.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # @reblu/site-contracts
2
2
 
3
+ ## 1.32.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 49d31ea: Page links (REB-1100). Additive only: every existing field keeps its type and meaning, and every new field is optional (absent from older servers, and when the links cannot be read).
8
+ - `PageListItem.links` (optional, `PageLinkRef[]`): the published pages this page picked in nexus, in the tenant's order (a team profile's areas, the areas a page belongs to). `[]` when it links to nothing public. New type `PageLinkRef` (`{ slug, title, pageType?, category }`).
9
+ - `PageDetail.links` (optional, `ResolvedEmbed[]`): the same, with excerpt, cover and role.
10
+ - `PageDetail.team` (optional, `ResolvedEmbed[]`, derived): the published team profiles linked to this page or to any page in `links`. `[]` on a team profile.
11
+ - `PageDetail.relatedPages` (optional, `ResolvedEmbed[]`, derived): the other published pages, not team profiles, linked to this page or to any page in `links` (a profile's area pages, an area's pages, a page's siblings).
12
+
13
+ `@reblu/site-blocks` ships the drop-ins (`TeamDirectory`, `LinkedPagesGrid`, `TeamGrid`).
14
+
15
+ - c8bf6c1: Featured reviews (REB-1272). `@reblu/site-contracts` exports `FeaturedReviews` (`{ layout: 'grid' | 'carousel', reviews: Review[] }`) and `FeaturedReviewsLayout` for `GET /api/site/reviews/featured`. `@reblu/site-client` adds `client.reviews.featured({ limit? }, cache?)`: the reviews the tenant featured for its home in nexus, published only and in the featured order, plus the layout it chose (404 without the tenant's `reviews` module). `reviews.list()` and every other namespace are unchanged.
16
+ - 83084d0: «Reseñas» page block (REB-1272). `@reblu/site-contracts` adds the `reviews` block type: `ReviewsBlockData` (`{ scope: 'all' | 'page', limit?, layout?: 'grid' | 'carousel', notice? }`) and an optional `reviews: Review[]` on `PageBlock`, which the site API fills with the published reviews the block selects. `@reblu/site-blocks` renders it in `PageBlocks` with the `Reviews` drop-in (the tenant's notice included) and skips the whole section when there is no review to show. Every existing block type renders exactly as before. The carousel layout renders as the grid in the server-safe `PageBlocks`; `ReviewsBlockRenderer` from `@reblu/site-blocks/client` renders the real carousel through `components.reviews`. `PageDetail` gains an `id` (optional on the wire, always emitted), so a SITE can call `client.reviews.list({ pageId: page.id })`.
17
+
18
+ ## 1.31.0
19
+
20
+ ### Minor Changes
21
+
22
+ - 8c2e641: REB-1236: the order confirmation screen says what happens next for each purchase type.
23
+ - `@reblu/site-contracts`: `ShopOrder.purchaseTexts?: ShopOrderPurchaseText[]` (`{ kind: 'shipping' | 'pickup' | 'digital' | 'service', label, text }`), one entry per purchase type in the order, with the shop's texts from nexus or their Spanish defaults. Optional: older servers do not send it.
24
+ - `@reblu/site-blocks`: `OrderConfirmation` renders `order.purchaseTexts` under a confirmed order, with no extra wiring. New optional prop `showPurchaseTexts` (default `true`). An order without the field renders as before.
25
+
26
+ - fb9bfcc: REB-1236 follow-up: the pickup block of the order confirmation names the pickup point.
27
+ - `@reblu/site-contracts`: `ShopOrderPurchaseText.place?: { name, address: string[] }`, sent on the `pickup` entry with the pickup point frozen on the order (the same name and address lines as the confirmation email). Optional: absent on other kinds and on older servers.
28
+ - `@reblu/site-blocks`: `OrderConfirmation` shows that name and address in the pickup block, with no extra wiring.
29
+
3
30
  ## 1.30.0
4
31
 
5
32
  ### Minor Changes
@@ -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 // 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 { WithdrawalRequestInput, WithdrawalRequestSubmission } 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// Reviews (REB-1272) — published, verifiable reviews (`/api/site/reviews`).\nexport type { Review, ReviewSource } 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-1100 — a page another page links to, as carried on a list item's\n // optional `links`. The detail's `links`/`team`/`relatedPages` are `ResolvedEmbed[]`.\n PageLinkRef,\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 // The confirmation screen text per purchase type (REB-1236)\n ShopOrderPurchaseText,\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 { WithdrawalRequestInput, WithdrawalRequestSubmission } 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// Reviews (REB-1272) — published, verifiable reviews (`/api/site/reviews`), and\n// the `data` of the «Reseñas» page block (its reviews arrive on `PageBlock.reviews`).\nexport type { Review, ReviewSource, ReviewsBlockData } from '@reblu/base-api-contracts'\n// REB-1272 (owner, 8-Nov) — `GET /api/site/reviews/featured`: the home's featured\n// reviews and the layout the tenant chose (`grid` | `carousel`).\nexport type { FeaturedReviews, FeaturedReviewsLayout } 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
@@ -42,11 +42,11 @@ export type Analytics = { gaId: string | null; clarityId: string | null;
42
42
 
43
43
  export type BeforeAfterData = { pairs: { beforeUrl: string; afterUrl: string; alt?: string | undefined; }[]; kicker?: string | undefined; showCaption?: boolean | undefined; caption?: string | undefined;}
44
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; };}
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; };} | { blockType: "reviews"; data: { scope: "page" | "all"; limit?: number | undefined; layout?: "grid" | "carousel" | undefined; notice?: string | undefined; };}
46
46
 
47
47
  export type BlockCta = null | { label: string; url: string; isExternal: boolean; variant: string | null;}
48
48
 
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"
49
+ export type BlockType = "hero" | "reviews" | "page_embed" | "profile_embed" | "doctor_embed" | "specialty_embed" | "richtext" | "faq" | "stats" | "testimonial" | "cta" | "feature_list" | "gallery" | "before_after" | "chips" | "icon_cards" | "image_text"
50
50
 
51
51
  export type BlogAuthor = { firstName: string | null; lastName: string | null; avatarUrl: string | null;}
52
52
 
@@ -114,6 +114,10 @@ export type DataRequestType = "ACCESS" | "RECTIFICATION" | "ERASURE" | "OBJECTIO
114
114
 
115
115
  export type EmbedReferenceData = { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined;}
116
116
 
117
+ export type FeaturedReviews = { layout: "grid" | "carousel"; reviews: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[];}
118
+
119
+ export type FeaturedReviewsLayout = "grid" | "carousel"
120
+
117
121
  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
122
 
119
123
  export type ImageTextData = { imageUrl: string; imageSide: "left" | "right"; kicker?: string | undefined; alt?: string | undefined; mobileOrder?: "image_first" | "text_first" | undefined; html?: string | undefined;}
@@ -134,15 +138,17 @@ export type LegalTermsVersion = { id: string; version: number; publishe
134
138
 
135
139
  export type PageAmbiguousSlugError = { error: string; code: "ambiguous_slug"; candidates: { categorySlug: string | null; }[];}
136
140
 
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; };}
141
+ 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: 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; };} | { 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: 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; };} | { 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | undefined; blockType: "reviews"; data: { scope: "page" | "all"; limit?: number | undefined; layout?: "grid" | "carousel" | undefined; notice?: string | undefined; };}
138
142
 
139
143
  export type PageCategoryRef = { name: string; slug: string;}
140
144
 
141
145
  export type PageContentMode = "BLOCKS" | "HTML"
142
146
 
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;}
147
+ 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; }; } | { blockType: "reviews"; data: { scope: "page" | "all"; limit?: number | undefined; layout?: "grid" | "carousel" | undefined; notice?: 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; id?: string | undefined; seo?: { title: string; } | undefined; links?: { 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; }[] | undefined; team?: { 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; }[] | undefined; relatedPages?: { 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; }[] | undefined;}
148
+
149
+ export type PageLinkRef = { slug: string; title: string; category: { name: string; slug: string; } | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined;}
144
150
 
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;}
151
+ 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; links?: { slug: string; title: string; category: { name: string; slug: string; } | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; }[] | undefined;}
146
152
 
147
153
  export type PageSection = { 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; }[];}
148
154
 
@@ -180,9 +186,11 @@ export type ProfessionalSummary = { role: string | null; fields?: {
180
186
 
181
187
  export type ResolvedEmbed = { 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;}
182
188
 
183
- export type Review = { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "OTHER" | "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP"; sourceName: string; sourceUrl: string;}
189
+ export type Review = { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string;}
184
190
 
185
- export type ReviewSource = "OTHER" | "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP"
191
+ export type ReviewSource = "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"
192
+
193
+ export type ReviewsBlockData = { scope: "page" | "all"; limit?: number | undefined; layout?: "grid" | "carousel" | undefined; notice?: string | undefined;}
186
194
 
187
195
  export type SectionLayout = "TEXT" | "TEXT_IMAGE" | "IMAGE_TEXT" | "IMAGE_FULL" | "FEATURE_LIST" | "GALLERY" | "CTA_BLOCK"
188
196
 
@@ -240,23 +248,25 @@ export type ShopFulfillmentInput = { type: "SHIPPING" | "PICKUP"; pickupLo
240
248
 
241
249
  export type ShopInventoryRef = { stockQuantity: number; reservedQuantity: number; lowStockThreshold: number | null;}
242
250
 
243
- export type ShopOrder = { id: string; orderNumber: string; status: "PENDING" | "CONFIRMED" | "PROCESSING" | "SHIPPED" | "DELIVERED" | "CANCELLED" | "REFUNDED"; paymentStatus: "PENDING" | "REFUNDED" | "PAID" | "FAILED" | "PARTIALLY_REFUNDED"; customerEmail: string; total: number; items: { product: { id: string; name: string; slug: string; }; quantity: number; unitPrice: number; total: number; variant?: { id: string; name: string; } | null | undefined; }[]; invoice?: { number: string; url: string; } | null | undefined;}
251
+ export type ShopOrder = { id: string; orderNumber: string; status: "PENDING" | "CONFIRMED" | "PROCESSING" | "SHIPPED" | "DELIVERED" | "CANCELLED" | "REFUNDED"; paymentStatus: "PENDING" | "REFUNDED" | "PAID" | "FAILED" | "PARTIALLY_REFUNDED"; customerEmail: string; total: number; items: { product: { id: string; name: string; slug: string; }; quantity: number; unitPrice: number; total: number; variant?: { id: string; name: string; } | null | undefined; }[]; invoice?: { number: string; url: string; } | null | undefined; purchaseTexts?: { kind: "service" | "shipping" | "pickup" | "digital"; label: string; text: string; place?: { name: string; address: string[]; } | undefined; }[] | undefined;}
244
252
 
245
253
  export type ShopOrderInvoice = { number: string; url: string;}
246
254
 
247
255
  export type ShopOrderItem = { product: { id: string; name: string; slug: string; }; quantity: number; unitPrice: number; total: number; variant?: { id: string; name: string; } | null | undefined;}
248
256
 
257
+ export type ShopOrderPurchaseText = { kind: "service" | "shipping" | "pickup" | "digital"; label: string; text: string; place?: { name: string; address: string[]; } | undefined;}
258
+
249
259
  export type ShopPickupLocation = { id: string; name: string; address: string; city: string; postalCode: string; region: string | null; country: string; phone: string | null; email: string | null; openingHoursText: string | null; pickupReadyText: string | null;}
250
260
 
251
261
  export type ShopProductAttributes = unknown
252
262
 
253
263
  export type ShopProductCategoryRef = { id: string; name: string; slug: string;}
254
264
 
255
- export type ShopProductDetail = { id: string; slug: string; name: string; description: string | null; shortDescription: string | null; price: number; comparePrice: number | null; type: "SERVICE" | "PHYSICAL" | "DIGITAL" | "SERVICE_B2B" | "BUNDLE"; isActive: boolean; sku: string | null; trackStock: boolean; weightGrams: number | null; freeShipping: boolean; metaTitle: string | null; metaDescription: string | null; category: { id: string; name: string; slug: string; } | null; taxRate: { rate: number; type: "IVA" | "IGIC" | "RETENTION" | "OTHER"; isExempt: boolean; } | null; retentionRate: { rate: number; type: "IVA" | "IGIC" | "RETENTION" | "OTHER"; isExempt: boolean; } | null; variants: { id: string; name: string; sku: string | null; price: number | null; attributes: unknown; isActive: boolean; sortOrder: number; }[]; images: { url: string; alt: string | null; isPrimary: boolean; sortOrder: number; }[]; videos: { url: string; title: string | null; isExternal: boolean; thumbnailUrl: string | null; sortOrder: number; }[]; bundleComponents: { quantity: number; component: { id: string; name: string; slug: string; price: number; }; }[]; related: { id: string; slug: string; name: string; price: number; comparePrice: number | null; images: { url: string; alt: string | null; isPrimary: boolean; sortOrder: number; }[]; }[]; taxonomyTerms: { taxonomyKey: string; taxonomyLabel: string; showAsBadge: boolean; slug: string; name: string; imageUrl: string | null; }[]; attributes: unknown; attributeDefinitions: { id: string; entityType: "page" | "product"; key: string; label: string; valueType: "boolean" | "text" | "select" | "multiselect"; options: { value: string; label: string; }[]; isFilterable: boolean; showInDetail: boolean; unit: string | null; sortOrder: number; }[]; seo?: { title: string; } | undefined;}
265
+ export type ShopProductDetail = { id: string; slug: string; name: string; description: string | null; shortDescription: string | null; price: number; comparePrice: number | null; type: "SERVICE" | "PHYSICAL" | "DIGITAL" | "SERVICE_B2B" | "BUNDLE"; isActive: boolean; sku: string | null; trackStock: boolean; weightGrams: number | null; freeShipping: boolean; metaTitle: string | null; metaDescription: string | null; category: { id: string; name: string; slug: string; } | null; taxRate: { rate: number; type: "OTHER" | "IVA" | "IGIC" | "RETENTION"; isExempt: boolean; } | null; retentionRate: { rate: number; type: "OTHER" | "IVA" | "IGIC" | "RETENTION"; isExempt: boolean; } | null; variants: { id: string; name: string; sku: string | null; price: number | null; attributes: unknown; isActive: boolean; sortOrder: number; }[]; images: { url: string; alt: string | null; isPrimary: boolean; sortOrder: number; }[]; videos: { url: string; title: string | null; isExternal: boolean; thumbnailUrl: string | null; sortOrder: number; }[]; bundleComponents: { quantity: number; component: { id: string; name: string; slug: string; price: number; }; }[]; related: { id: string; slug: string; name: string; price: number; comparePrice: number | null; images: { url: string; alt: string | null; isPrimary: boolean; sortOrder: number; }[]; }[]; taxonomyTerms: { taxonomyKey: string; taxonomyLabel: string; showAsBadge: boolean; slug: string; name: string; imageUrl: string | null; }[]; attributes: unknown; attributeDefinitions: { id: string; entityType: "page" | "product"; key: string; label: string; valueType: "boolean" | "text" | "select" | "multiselect"; options: { value: string; label: string; }[]; isFilterable: boolean; showInDetail: boolean; unit: string | null; sortOrder: number; }[]; seo?: { title: string; } | undefined;}
256
266
 
257
267
  export type ShopProductImage = { url: string; alt: string | null; isPrimary: boolean; sortOrder: number;}
258
268
 
259
- export type ShopProductListItem = { id: string; slug: string; name: string; shortDescription: string | null; price: number; comparePrice: number | null; isActive: boolean; type: "SERVICE" | "PHYSICAL" | "DIGITAL" | "SERVICE_B2B" | "BUNDLE"; category: { id: string; name: string; slug: string; } | null; taxRate: { rate: number; type: "IVA" | "IGIC" | "RETENTION" | "OTHER"; isExempt: boolean; } | null; inventory: { stockQuantity: number; reservedQuantity: number; lowStockThreshold: number | null; } | null; images: { url: string; alt: string | null; isPrimary: boolean; sortOrder: number; }[]; taxonomyTerms: { taxonomyKey: string; taxonomyLabel: string; showAsBadge: boolean; slug: string; name: string; imageUrl: string | null; }[]; attributes: unknown;}
269
+ export type ShopProductListItem = { id: string; slug: string; name: string; shortDescription: string | null; price: number; comparePrice: number | null; isActive: boolean; type: "SERVICE" | "PHYSICAL" | "DIGITAL" | "SERVICE_B2B" | "BUNDLE"; category: { id: string; name: string; slug: string; } | null; taxRate: { rate: number; type: "OTHER" | "IVA" | "IGIC" | "RETENTION"; isExempt: boolean; } | null; inventory: { stockQuantity: number; reservedQuantity: number; lowStockThreshold: number | null; } | null; images: { url: string; alt: string | null; isPrimary: boolean; sortOrder: number; }[]; taxonomyTerms: { taxonomyKey: string; taxonomyLabel: string; showAsBadge: boolean; slug: string; name: string; imageUrl: string | null; }[]; attributes: unknown;}
260
270
 
261
271
  export type ShopProductListParams = { page?: number | undefined; limit?: number | undefined; q?: string | undefined; sort?: "price_asc" | "price_desc" | "newest" | "on_sale" | undefined; category?: string | undefined; priceMin?: number | undefined; priceMax?: number | undefined; onSale?: boolean | undefined; taxonomy?: Record<string, string> | undefined; attr?: Record<string, string | string[]> | undefined;}
262
272
 
@@ -280,7 +290,7 @@ export type ShopSort = "price_asc" | "price_desc" | "newest" | "on_sale"
280
290
 
281
291
  export type ShopStaffAutoDiscount = { code: string; label: string; amount: number;}
282
292
 
283
- export type ShopTaxRateRef = { rate: number; type: "IVA" | "IGIC" | "RETENTION" | "OTHER"; isExempt: boolean;}
293
+ export type ShopTaxRateRef = { rate: number; type: "OTHER" | "IVA" | "IGIC" | "RETENTION"; isExempt: boolean;}
284
294
 
285
295
  export type ShopTaxonomySelectionMode = "single" | "multiple"
286
296
 
@@ -296,7 +306,7 @@ export type SiteManifest = { manifestVersion: 1; surfaces: Record<string,
296
306
 
297
307
  export type SiteManifestSurfaceValue = true | { path?: string | undefined;}
298
308
 
299
- export type TaxType = "IVA" | "IGIC" | "RETENTION" | "OTHER"
309
+ export type TaxType = "OTHER" | "IVA" | "IGIC" | "RETENTION"
300
310
 
301
311
  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;}
302
312
 
package/dist/index.d.ts CHANGED
@@ -42,11 +42,11 @@ export type Analytics = { gaId: string | null; clarityId: string | null;
42
42
 
43
43
  export type BeforeAfterData = { pairs: { beforeUrl: string; afterUrl: string; alt?: string | undefined; }[]; kicker?: string | undefined; showCaption?: boolean | undefined; caption?: string | undefined;}
44
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; };}
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; };} | { blockType: "reviews"; data: { scope: "page" | "all"; limit?: number | undefined; layout?: "grid" | "carousel" | undefined; notice?: string | undefined; };}
46
46
 
47
47
  export type BlockCta = null | { label: string; url: string; isExternal: boolean; variant: string | null;}
48
48
 
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"
49
+ export type BlockType = "hero" | "reviews" | "page_embed" | "profile_embed" | "doctor_embed" | "specialty_embed" | "richtext" | "faq" | "stats" | "testimonial" | "cta" | "feature_list" | "gallery" | "before_after" | "chips" | "icon_cards" | "image_text"
50
50
 
51
51
  export type BlogAuthor = { firstName: string | null; lastName: string | null; avatarUrl: string | null;}
52
52
 
@@ -114,6 +114,10 @@ export type DataRequestType = "ACCESS" | "RECTIFICATION" | "ERASURE" | "OBJECTIO
114
114
 
115
115
  export type EmbedReferenceData = { pageSlug: string; pageId?: string | undefined; categorySlug?: string | null | undefined;}
116
116
 
117
+ export type FeaturedReviews = { layout: "grid" | "carousel"; reviews: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[];}
118
+
119
+ export type FeaturedReviewsLayout = "grid" | "carousel"
120
+
117
121
  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
122
 
119
123
  export type ImageTextData = { imageUrl: string; imageSide: "left" | "right"; kicker?: string | undefined; alt?: string | undefined; mobileOrder?: "image_first" | "text_first" | undefined; html?: string | undefined;}
@@ -134,15 +138,17 @@ export type LegalTermsVersion = { id: string; version: number; publishe
134
138
 
135
139
  export type PageAmbiguousSlugError = { error: string; code: "ambiguous_slug"; candidates: { categorySlug: string | null; }[];}
136
140
 
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; };}
141
+ 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: 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; };} | { 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: 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; };} | { 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | undefined; blockType: "reviews"; data: { scope: "page" | "all"; limit?: number | undefined; layout?: "grid" | "carousel" | undefined; notice?: string | undefined; };}
138
142
 
139
143
  export type PageCategoryRef = { name: string; slug: string;}
140
144
 
141
145
  export type PageContentMode = "BLOCKS" | "HTML"
142
146
 
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;}
147
+ 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; reviews?: { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string; }[] | 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; }; } | { blockType: "reviews"; data: { scope: "page" | "all"; limit?: number | undefined; layout?: "grid" | "carousel" | undefined; notice?: 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; id?: string | undefined; seo?: { title: string; } | undefined; links?: { 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; }[] | undefined; team?: { 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; }[] | undefined; relatedPages?: { 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; }[] | undefined;}
148
+
149
+ export type PageLinkRef = { slug: string; title: string; category: { name: string; slug: string; } | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined;}
144
150
 
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;}
151
+ 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; links?: { slug: string; title: string; category: { name: string; slug: string; } | null; pageType?: "custom" | "service" | "treatments" | "specialties" | "team" | "generic" | undefined; }[] | undefined;}
146
152
 
147
153
  export type PageSection = { 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; }[];}
148
154
 
@@ -180,9 +186,11 @@ export type ProfessionalSummary = { role: string | null; fields?: {
180
186
 
181
187
  export type ResolvedEmbed = { 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;}
182
188
 
183
- export type Review = { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "OTHER" | "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP"; sourceName: string; sourceUrl: string;}
189
+ export type Review = { id: string; authorName: string; rating: number; text: string | null; reviewDate: string; source: "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"; sourceName: string; sourceUrl: string;}
184
190
 
185
- export type ReviewSource = "OTHER" | "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP"
191
+ export type ReviewSource = "GOOGLE" | "DOCTORALIA" | "TRIPADVISOR" | "TRUSTPILOT" | "FACEBOOK" | "TOP_DOCTORS" | "YELP" | "OTHER"
192
+
193
+ export type ReviewsBlockData = { scope: "page" | "all"; limit?: number | undefined; layout?: "grid" | "carousel" | undefined; notice?: string | undefined;}
186
194
 
187
195
  export type SectionLayout = "TEXT" | "TEXT_IMAGE" | "IMAGE_TEXT" | "IMAGE_FULL" | "FEATURE_LIST" | "GALLERY" | "CTA_BLOCK"
188
196
 
@@ -240,23 +248,25 @@ export type ShopFulfillmentInput = { type: "SHIPPING" | "PICKUP"; pickupLo
240
248
 
241
249
  export type ShopInventoryRef = { stockQuantity: number; reservedQuantity: number; lowStockThreshold: number | null;}
242
250
 
243
- export type ShopOrder = { id: string; orderNumber: string; status: "PENDING" | "CONFIRMED" | "PROCESSING" | "SHIPPED" | "DELIVERED" | "CANCELLED" | "REFUNDED"; paymentStatus: "PENDING" | "REFUNDED" | "PAID" | "FAILED" | "PARTIALLY_REFUNDED"; customerEmail: string; total: number; items: { product: { id: string; name: string; slug: string; }; quantity: number; unitPrice: number; total: number; variant?: { id: string; name: string; } | null | undefined; }[]; invoice?: { number: string; url: string; } | null | undefined;}
251
+ export type ShopOrder = { id: string; orderNumber: string; status: "PENDING" | "CONFIRMED" | "PROCESSING" | "SHIPPED" | "DELIVERED" | "CANCELLED" | "REFUNDED"; paymentStatus: "PENDING" | "REFUNDED" | "PAID" | "FAILED" | "PARTIALLY_REFUNDED"; customerEmail: string; total: number; items: { product: { id: string; name: string; slug: string; }; quantity: number; unitPrice: number; total: number; variant?: { id: string; name: string; } | null | undefined; }[]; invoice?: { number: string; url: string; } | null | undefined; purchaseTexts?: { kind: "service" | "shipping" | "pickup" | "digital"; label: string; text: string; place?: { name: string; address: string[]; } | undefined; }[] | undefined;}
244
252
 
245
253
  export type ShopOrderInvoice = { number: string; url: string;}
246
254
 
247
255
  export type ShopOrderItem = { product: { id: string; name: string; slug: string; }; quantity: number; unitPrice: number; total: number; variant?: { id: string; name: string; } | null | undefined;}
248
256
 
257
+ export type ShopOrderPurchaseText = { kind: "service" | "shipping" | "pickup" | "digital"; label: string; text: string; place?: { name: string; address: string[]; } | undefined;}
258
+
249
259
  export type ShopPickupLocation = { id: string; name: string; address: string; city: string; postalCode: string; region: string | null; country: string; phone: string | null; email: string | null; openingHoursText: string | null; pickupReadyText: string | null;}
250
260
 
251
261
  export type ShopProductAttributes = unknown
252
262
 
253
263
  export type ShopProductCategoryRef = { id: string; name: string; slug: string;}
254
264
 
255
- export type ShopProductDetail = { id: string; slug: string; name: string; description: string | null; shortDescription: string | null; price: number; comparePrice: number | null; type: "SERVICE" | "PHYSICAL" | "DIGITAL" | "SERVICE_B2B" | "BUNDLE"; isActive: boolean; sku: string | null; trackStock: boolean; weightGrams: number | null; freeShipping: boolean; metaTitle: string | null; metaDescription: string | null; category: { id: string; name: string; slug: string; } | null; taxRate: { rate: number; type: "IVA" | "IGIC" | "RETENTION" | "OTHER"; isExempt: boolean; } | null; retentionRate: { rate: number; type: "IVA" | "IGIC" | "RETENTION" | "OTHER"; isExempt: boolean; } | null; variants: { id: string; name: string; sku: string | null; price: number | null; attributes: unknown; isActive: boolean; sortOrder: number; }[]; images: { url: string; alt: string | null; isPrimary: boolean; sortOrder: number; }[]; videos: { url: string; title: string | null; isExternal: boolean; thumbnailUrl: string | null; sortOrder: number; }[]; bundleComponents: { quantity: number; component: { id: string; name: string; slug: string; price: number; }; }[]; related: { id: string; slug: string; name: string; price: number; comparePrice: number | null; images: { url: string; alt: string | null; isPrimary: boolean; sortOrder: number; }[]; }[]; taxonomyTerms: { taxonomyKey: string; taxonomyLabel: string; showAsBadge: boolean; slug: string; name: string; imageUrl: string | null; }[]; attributes: unknown; attributeDefinitions: { id: string; entityType: "page" | "product"; key: string; label: string; valueType: "boolean" | "text" | "select" | "multiselect"; options: { value: string; label: string; }[]; isFilterable: boolean; showInDetail: boolean; unit: string | null; sortOrder: number; }[]; seo?: { title: string; } | undefined;}
265
+ export type ShopProductDetail = { id: string; slug: string; name: string; description: string | null; shortDescription: string | null; price: number; comparePrice: number | null; type: "SERVICE" | "PHYSICAL" | "DIGITAL" | "SERVICE_B2B" | "BUNDLE"; isActive: boolean; sku: string | null; trackStock: boolean; weightGrams: number | null; freeShipping: boolean; metaTitle: string | null; metaDescription: string | null; category: { id: string; name: string; slug: string; } | null; taxRate: { rate: number; type: "OTHER" | "IVA" | "IGIC" | "RETENTION"; isExempt: boolean; } | null; retentionRate: { rate: number; type: "OTHER" | "IVA" | "IGIC" | "RETENTION"; isExempt: boolean; } | null; variants: { id: string; name: string; sku: string | null; price: number | null; attributes: unknown; isActive: boolean; sortOrder: number; }[]; images: { url: string; alt: string | null; isPrimary: boolean; sortOrder: number; }[]; videos: { url: string; title: string | null; isExternal: boolean; thumbnailUrl: string | null; sortOrder: number; }[]; bundleComponents: { quantity: number; component: { id: string; name: string; slug: string; price: number; }; }[]; related: { id: string; slug: string; name: string; price: number; comparePrice: number | null; images: { url: string; alt: string | null; isPrimary: boolean; sortOrder: number; }[]; }[]; taxonomyTerms: { taxonomyKey: string; taxonomyLabel: string; showAsBadge: boolean; slug: string; name: string; imageUrl: string | null; }[]; attributes: unknown; attributeDefinitions: { id: string; entityType: "page" | "product"; key: string; label: string; valueType: "boolean" | "text" | "select" | "multiselect"; options: { value: string; label: string; }[]; isFilterable: boolean; showInDetail: boolean; unit: string | null; sortOrder: number; }[]; seo?: { title: string; } | undefined;}
256
266
 
257
267
  export type ShopProductImage = { url: string; alt: string | null; isPrimary: boolean; sortOrder: number;}
258
268
 
259
- export type ShopProductListItem = { id: string; slug: string; name: string; shortDescription: string | null; price: number; comparePrice: number | null; isActive: boolean; type: "SERVICE" | "PHYSICAL" | "DIGITAL" | "SERVICE_B2B" | "BUNDLE"; category: { id: string; name: string; slug: string; } | null; taxRate: { rate: number; type: "IVA" | "IGIC" | "RETENTION" | "OTHER"; isExempt: boolean; } | null; inventory: { stockQuantity: number; reservedQuantity: number; lowStockThreshold: number | null; } | null; images: { url: string; alt: string | null; isPrimary: boolean; sortOrder: number; }[]; taxonomyTerms: { taxonomyKey: string; taxonomyLabel: string; showAsBadge: boolean; slug: string; name: string; imageUrl: string | null; }[]; attributes: unknown;}
269
+ export type ShopProductListItem = { id: string; slug: string; name: string; shortDescription: string | null; price: number; comparePrice: number | null; isActive: boolean; type: "SERVICE" | "PHYSICAL" | "DIGITAL" | "SERVICE_B2B" | "BUNDLE"; category: { id: string; name: string; slug: string; } | null; taxRate: { rate: number; type: "OTHER" | "IVA" | "IGIC" | "RETENTION"; isExempt: boolean; } | null; inventory: { stockQuantity: number; reservedQuantity: number; lowStockThreshold: number | null; } | null; images: { url: string; alt: string | null; isPrimary: boolean; sortOrder: number; }[]; taxonomyTerms: { taxonomyKey: string; taxonomyLabel: string; showAsBadge: boolean; slug: string; name: string; imageUrl: string | null; }[]; attributes: unknown;}
260
270
 
261
271
  export type ShopProductListParams = { page?: number | undefined; limit?: number | undefined; q?: string | undefined; sort?: "price_asc" | "price_desc" | "newest" | "on_sale" | undefined; category?: string | undefined; priceMin?: number | undefined; priceMax?: number | undefined; onSale?: boolean | undefined; taxonomy?: Record<string, string> | undefined; attr?: Record<string, string | string[]> | undefined;}
262
272
 
@@ -280,7 +290,7 @@ export type ShopSort = "price_asc" | "price_desc" | "newest" | "on_sale"
280
290
 
281
291
  export type ShopStaffAutoDiscount = { code: string; label: string; amount: number;}
282
292
 
283
- export type ShopTaxRateRef = { rate: number; type: "IVA" | "IGIC" | "RETENTION" | "OTHER"; isExempt: boolean;}
293
+ export type ShopTaxRateRef = { rate: number; type: "OTHER" | "IVA" | "IGIC" | "RETENTION"; isExempt: boolean;}
284
294
 
285
295
  export type ShopTaxonomySelectionMode = "single" | "multiple"
286
296
 
@@ -296,7 +306,7 @@ export type SiteManifest = { manifestVersion: 1; surfaces: Record<string,
296
306
 
297
307
  export type SiteManifestSurfaceValue = true | { path?: string | undefined;}
298
308
 
299
- export type TaxType = "IVA" | "IGIC" | "RETENTION" | "OTHER"
309
+ export type TaxType = "OTHER" | "IVA" | "IGIC" | "RETENTION"
300
310
 
301
311
  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;}
302
312
 
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 // 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 { WithdrawalRequestInput, WithdrawalRequestSubmission } 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// Reviews (REB-1272) — published, verifiable reviews (`/api/site/reviews`).\nexport type { Review, ReviewSource } 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-1100 — a page another page links to, as carried on a list item's\n // optional `links`. The detail's `links`/`team`/`relatedPages` are `ResolvedEmbed[]`.\n PageLinkRef,\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 // The confirmation screen text per purchase type (REB-1236)\n ShopOrderPurchaseText,\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 { WithdrawalRequestInput, WithdrawalRequestSubmission } 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// Reviews (REB-1272) — published, verifiable reviews (`/api/site/reviews`), and\n// the `data` of the «Reseñas» page block (its reviews arrive on `PageBlock.reviews`).\nexport type { Review, ReviewSource, ReviewsBlockData } from '@reblu/base-api-contracts'\n// REB-1272 (owner, 8-Nov) — `GET /api/site/reviews/featured`: the home's featured\n// reviews and the layout the tenant chose (`grid` | `carousel`).\nexport type { FeaturedReviews, FeaturedReviewsLayout } 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.30.0",
3
+ "version": "1.32.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",