@bettercms-ai/types 1.50.1 → 1.50.2

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/dist/index.d.ts CHANGED
@@ -436,6 +436,11 @@ interface ContentModelField {
436
436
  * translation write that changes one is 409 `FIELD_NOT_LOCALIZED`. None marked: rows copy as before.
437
437
  */
438
438
  localized?: boolean;
439
+ /**
440
+ * Schema V2 archive: the field is out of the entry form and the delivery API. Its key and
441
+ * stored values stay, so `false` restores it with nothing lost.
442
+ */
443
+ archived?: boolean;
439
444
  /**
440
445
  * Authoring chrome — how the field PRESENTS in the editor. Never delivered, never read by a
441
446
  * renderer, and never able to move a value; the same contract as {@link placement}.
@@ -597,6 +602,61 @@ interface Page {
597
602
  } | null;
598
603
  }
599
604
 
605
+ /**
606
+ * A page BODY's own allow-list: which components a page accepts as sections (`pages.body_schema`,
607
+ * migration 0494). "A page accepts only the components built for that page."
608
+ *
609
+ * A third axis beside a zone's `allowedSections` and a component's `allowedOn`, judged by the same
610
+ * resolver (`resolveInsertableSections`, deny reason `not-in-body-allowlist`).
611
+ *
612
+ * 🔴 THE EMPTY-ARRAY TRAP, the same as on both other lists:
613
+ * body_schema NULL = UNRESTRICTED (every page that predates 0494; today's behaviour)
614
+ * `allowed: []` = DENY-ALL — no component is accepted. Never write `[]` to mean "unset":
615
+ * unset is the column being NULL.
616
+ */
617
+ /**
618
+ * One rule. A component is accepted when ANY rule matches it.
619
+ *
620
+ * source built for this page: `splitSourceKey(component.sourceKey).page === pageId`, read off the
621
+ * component's CURRENT source key at judge time (never a string prefix). A component with
622
+ * no source key, or one whose key names no page (a shared band, a pre-per-page key), is
623
+ * not built for any page.
624
+ * component exactly this component id.
625
+ * family any component of this section family (`sectionType`, trimmed, case-insensitive) — so a
626
+ * variant swap passes iff its TARGET passes.
627
+ * builtins the platform's built-in sections (`builtin:*`), and a project's copy of one.
628
+ * workspace the workspace's shared components (`project_id IS NULL`).
629
+ */
630
+ type AllowRule = {
631
+ kind: "source";
632
+ pageId: string;
633
+ } | {
634
+ kind: "component";
635
+ id: string;
636
+ } | {
637
+ kind: "family";
638
+ sectionType: string;
639
+ } | {
640
+ kind: "builtins";
641
+ } | {
642
+ kind: "workspace";
643
+ };
644
+ /** Who wrote the list: a lane's guess (componentize), a person's confirmation of it, or a person's own. */
645
+ type BodySchemaOrigin = "inferred" | "confirmed" | "authored";
646
+ interface BodySchema {
647
+ /** `[]` = deny-all. See the file header: unset is a NULL column, never an empty list. */
648
+ allowed: AllowRule[];
649
+ origin: BodySchemaOrigin;
650
+ }
651
+ declare const BODY_SCHEMA_ORIGINS: readonly BodySchemaOrigin[];
652
+ /** Pure. One stored rule as an `AllowRule`, or null for one this reader does not know (it matches nothing). */
653
+ declare function allowRuleOf(value: unknown): AllowRule | null;
654
+ /**
655
+ * Pure. A stored `body_schema` as a `BodySchema`, or null (unrestricted) when it is not one.
656
+ * An unknown rule is dropped, which narrows the list — never widens it.
657
+ */
658
+ declare function bodySchemaOf(value: unknown): BodySchema | null;
659
+
600
660
  /**
601
661
  * Section spacing as TOKEN STEPS — the ONE list of names and default sizes, shared by the save
602
662
  * schema and every renderer. A stored value is always a token (`section-space-large`), never a
@@ -1337,6 +1397,12 @@ interface ComponentProps {
1337
1397
  * while `bind` is; dropped with it when the instance takes its copy.
1338
1398
  */
1339
1399
  bindPaths?: Record<string, string>;
1400
+ /**
1401
+ * Phase B: the props this INSTANCE does not own — their copy stays in the page's own field, which
1402
+ * the page lane keeps binding — and why: `{ <propKey>: "RICHTEXT_HEADING" | "BUTTON_LOOK_UNMAPPED" }`.
1403
+ * The dock hides these props: an override written there renders nowhere.
1404
+ */
1405
+ kept?: Record<string, "RICHTEXT_HEADING" | "BUTTON_LOOK_UNMAPPED">;
1340
1406
  }
1341
1407
  interface ComponentBlock {
1342
1408
  type: "component";
@@ -1637,7 +1703,14 @@ declare function usesHideOn(blocks: unknown): boolean;
1637
1703
  * Returns "" for anything it does not fully trust. Twin of `safeCssUrl` in render-page.ts.
1638
1704
  */
1639
1705
  declare function safeCssUrl(raw: unknown): string;
1640
- /** A CSS declaration object (key → value) usable as a React `style` prop, or undefined when empty. */
1706
+ /**
1707
+ * A CSS declaration object (key → value) usable as a React `style` prop, or undefined when empty.
1708
+ *
1709
+ * Surfaces (twin: `platformSectionCss` in src/lib/sites/render-page.ts): no theme and no fill set no
1710
+ * background, so the root is transparent; a `surface`/`muted` fill reads the kit's custom properties
1711
+ * (`--bcms-bg-surface`/`--bcms-bg-muted`), which a code-built page with no kit sets transparent;
1712
+ * an explicit theme Light/Dark is opaque by the author's choice; text colour inherits unless set.
1713
+ */
1641
1714
  declare function blockStyleToCss(style: BlockStyle | undefined): Record<string, string | number> | undefined;
1642
1715
  /**
1643
1716
  * The content column: the declarations for the INNER box a renderer nests between a block's
@@ -3655,6 +3728,15 @@ interface DerivedLocator {
3655
3728
  groupKey: string;
3656
3729
  index: number;
3657
3730
  };
3731
+ /**
3732
+ * Each ancestor's index among ITS parent's element children, in `ancestors` order.
3733
+ *
3734
+ * The chain and the sibling index stop at one level: two price cards in one grid each hold
3735
+ * `<span>.00</span>` at `div>div>span`, index 1, and those two locators are one address. With
3736
+ * the path they are two. Minted only under the field-identity grammar (@see locatorPath), and
3737
+ * compared only where the stored side has one: a locator without it matches as it always did.
3738
+ */
3739
+ path?: number[];
3658
3740
  }
3659
3741
  /** The DOM surface `locatorFor` reads. `Element` satisfies it; so does a plain object. */
3660
3742
  interface ElementLike {
@@ -3691,6 +3773,18 @@ interface LandmarkChainElement extends ElementLike {
3691
3773
  */
3692
3774
  declare function locatorFor(el: ElementLike, region: string | null): DerivedLocator;
3693
3775
  declare function locatorFor(el: LandmarkChainElement, region: string | null, landmarks: boolean): DerivedLocator;
3776
+ /**
3777
+ * `DerivedLocator.path` for an element: its ancestors' own sibling indices, over the very chain
3778
+ * `locatorFor` walks (same stop, same order), so the two always describe one chain.
3779
+ */
3780
+ declare function locatorPath(el: ElementLike, landmarks?: false): number[];
3781
+ declare function locatorPath(el: LandmarkChainElement, landmarks: boolean): number[];
3782
+ /**
3783
+ * Where a RESOLVED locator keeps its element's `path`: a symbol, so a locator a resolver hands out
3784
+ * has no `path` of its own. Used as the stored side (a pin, a test's expectation) it compares as it
3785
+ * always did, and it serializes as it always did. `atLocator` reads it by this registry key.
3786
+ */
3787
+ declare const LOCATOR_PATH: unique symbol;
3694
3788
  /** The DOM surface `landmarkRegions` reads of each element it considers. */
3695
3789
  interface LandmarkElement {
3696
3790
  tagName: string;
@@ -3771,6 +3865,18 @@ declare function regionOf<E extends {
3771
3865
  * "Span" and "Icon".
3772
3866
  */
3773
3867
  declare const TAG_HEADS: ReadonlySet<string>;
3868
+ /**
3869
+ * The ROLES a structural key ends in (`hero-headline`, `pricing-plans[0].plan-name`): what a value
3870
+ * is FOR, never which element holds it. The same closed list as the server's `ROLE_VOCABULARY`
3871
+ * (src/lib/content/field-names.ts); this package ships alone, so the two change together.
3872
+ */
3873
+ declare const ROLE_KEYS: ReadonlySet<string>;
3874
+ /**
3875
+ * Is this WHOLE key a bare role — `headline`, `primary-button-href`, `link-2` — the key a value
3876
+ * outside any band gets? Such a key names no family. Only the whole key: `features-heading` is
3877
+ * the `features` family, and `video-h2-take-the-tour` a tag-grammar key whose family is `video`.
3878
+ */
3879
+ declare function isRoleKey(key: string): boolean;
3774
3880
  /** The top-level field key a path belongs to: `hero.title` → `hero`, `faq[0].q` → `faq`. */
3775
3881
  declare const topFieldKeyOf: (path: string) => string;
3776
3882
  /**
@@ -3823,4 +3929,4 @@ type SectionPlanItem<B> = {
3823
3929
  */
3824
3930
  declare function planSections<B>(slots: readonly string[], blocks: readonly B[] | null | undefined): SectionPlanItem<B>[];
3825
3931
 
3826
- export { type AlignToken, type ApiError, type ApiKey, type ApiKeyPermission, type ApiKeyTokenType, type ArrayZoneConfig, type AssertEqual, type AuthResponse, type AuthSession, type AuthUser, BLOCK_BINDINGS, BREAKPOINTS, BUTTON_ACTIONS, BUTTON_FULL_WIDTH_INVALID, BUTTON_ICONS, BUTTON_ICON_NAMES, BUTTON_LOOK_KEYS, BUTTON_PLACEMENT_KEYS, BUTTON_SIZES, BUTTON_VARIANTS, type BetterCMSErrorCode, type BgToken, type BindingKind, type BlockBinding, type BlockHoverStyle, type BlockStyle, type BlockType, type ButtonAction, type ButtonBlock, type ButtonIcon, type ButtonLinkCandidate, type ButtonLookKey, type ButtonProps, type ButtonSiteLook, type ButtonSizeName, type ButtonValue, type ButtonVariant, CODE_SLOT_PREFIX, COMPONENT_PROP_TYPES, type CanonicalInputDefinition, type ChoiceOption, type CollectionBlock, type CollectionFilter, type CollectionProps, type ColorToken, type ColumnsBlock, type ColumnsProps, type Component, type ComponentBlock, type ComponentCategory, type ComponentFormPropRef, type ComponentPreview, type ComponentPropDef, type ComponentPropType, type ComponentPropUi, type ComponentProps, type ComponentSubField, type ComponentTab, type ComponentVariantGroup, type Content, type ContentBlock, type ContentEntry, type ContentModel, type ContentModelField, type ContentModelFieldType, type ContentModelFieldUi, type ContentPageResult, type ContentResponse, type ContentWidthToken, type CornerToken, DIALOG_SELECTOR, DOCK_BUDGET, DOCK_ICON_NAMES, DOCK_ICON_NAME_SET, type DeepReadonly, type DeliveredLayout, type DeliveryComponent, type DeliveryEntry, type DeliveryEntrySeo, type DeliveryList, type DeliveryPage, type DerivedLocator, type DockBudget, type DockFieldLike, type DockFieldsetLike, type DockIconName, type DockInputRef, type DockLane, type DockNode, type DockPropGroupLike, type DockScreen, type ElementLike, type ExpandedBinding, FIELD_SIZE_ZOOM, FIELD_STYLE_KEYS, FOOTER_SECTION_ID, type FieldConfig, type FieldSize, type FieldStyle, type FieldStyleKey, type FieldStyles, type Fieldset, type FieldsetKind, type FieldsetUiBefore, type FontSizeToken, type FooterBlock, type FooterColumn, type FooterProps, type Form, type FormBlock, type FormField, type FormProps, type FormSubmission, type HeadingBlock, type HeadingProps, IMAGE_ASPECTS, IMAGE_FRAME_RADIUS, type ImageAspect, type ImageBlock, type ImageProps, LANDMARK_SELECTOR, LAYOUT_SECTION_ICONS, LAYOUT_SECTION_ICON_SET, LINK_RELS, LINK_VALUE_TYPES, LIST_ITEMS_CAP, type LandmarkChainElement, type LandmarkElement, type LayoutComponentItem, type LayoutDataDocument, type LayoutFieldDefinition, type LayoutFieldItem, type LayoutFieldType, type LayoutScalarFieldType, type LayoutSection, type LayoutSectionIcon, type LayoutSectionItem, type LayoutStructureDocument, type LayoutZone, type LinkRel, type LinkValue, type LinkValueType, type LocatorGrammar, MAIN_SELECTOR, type ManagementLayoutCommand, type MediaAsset, type MediaCaptionTrack, type MediaFieldValue, NAVIGATION_SECTION_ID, type NavLink, type NavbarBlock, type NavbarProps, type NumberFieldFormat, type NumberScale, OPTION_DESCRIPTION_MAX, type OpenMode, PAGE_CONTENT_ANCHOR_ID, type Page, type PageLayoutOverrideDataDocument, type PageLayoutOverrideDocument, type PageLayoutOverrideState, type PageLayoutOverrideStructureDocument, type PageLayoutSectionOverride, type PageLayoutSectionStructureOverride, type PageMetaJson, type PageOnlyLayoutSection, type PageSectionPlacement, type PaginatedResult, type Perspective, type PortableTextDocument, type PortableTextNode, type PropGroup, type PropTab, RESPONSIVE_CSS, type RadiusToken, type ReadButtonValue, type Redirect, type ReservedLayoutSection, type ResolvedLayoutNode, type RichTextBlock, type RichTextProps, SECTION_DOCTRINE, SECTION_SPACE_TOKENS, SIDE_SPACE_MIN_PX, SIDE_SPACE_TOKENS, SLOT_CHILD_KEYS, SLOT_ITEMS_CAP, SLOT_MAX_ITEMS, SPACE_BOTTOM_TOKENS, SPACE_STEP_TOKENS, type ScaleUnit, type SectionBlock, type SectionPlanItem, type SectionProps, type SectionSpaceToken, type ShadowToken, type ShowIf, type ShowIfRule, type SignInInput, type SignUpInput, type SiteSeoDefaults, type SlideItem, type SliderBlock, type SliderProps, type SlotChild, type SlotItem, type SlotShapeOptions, type SlotShapeProblem, type SlotValue, type SpaceStepToken, type SpaceToken, type SpacerBlock, type SpacerProps, TABLE_COLUMN_TYPES, TABLE_JSONLD_TYPES, TABLE_LIMITS, TABLE_RESPONSIVE, TAG_HEADS, type TabItem, type TableCell, type TableCellObject, type TableCellValue, type TableCheckOptions, type TableColumn, type TableColumnType, type TableFieldOptions, type TableFootnote, type TableGroup, type TableLink, type TableProblem, type TableRef, type TableRefResolved, type TableRow, type TableValue, type TabsBlock, type TabsProps, type TextBlock, type TextProps, type ThemeToken, type UiBefore, type UiOrigin, VIDEO_TRANSCRIPT_MAX, VIDEO_VALUE_KEYS, type VariantInputMapping, type VideoBlock, type VideoProps, type VideoValue, type VisibilityWindow, type WeightToken, type WindowState, type Workspace, type ZoneField, anchorTargetRel, blockStyleToColumnCss, blockStyleToCss, blockStyleToInnerCss, buttonBlockProps, buttonFullWidthProblem, buttonIconOf, buttonIconSvg, buttonLinkPairs, buttonLookValue, buttonSiteLookOf, buttonValueOfInstance, buttonValueProblem, buttonVariantOf, candidateRole, componentInstanceAddresses, componentPropTargetKey, derivedPairs, dockBudget, dockScreens, expandBlockBindings, fieldGroupOf, fieldStyleCssText, fieldStyleToCss, formatNumber, formatPropsAttribute, getBlockType, headingPaintCss, hiddenEverywhere, hideOnAttr, imageFrameCss, inWindow, isBlock, isButtonLookValue, isChromeLandmark, isCodeButton, isLinkObject, isScriptHref, isSlotChild, isTableValue, keyWords, landmarkRegions, linkAnchorOf, linkHref, linkRefOf, linkValueProblem, locatorFor, normalizeLinkValue, normalizeTableValue, normalizeWindow, parseNumberText, parsePropsAttribute, pickFieldStyle, placementBindOf, planSections, readButtonValue, readNumberFormat, readPath, regionOf, renderTableHtml, safeCssUrl, sideFloorApplies, sideSpaceCss, slotBindOf, slotChildValues, slotItems, slotPathString, slotShapeProblems, spaceTokenCss, splitButtonStyle, tableCellText, tablePathString, tableRefCells, tableSearchText, tableToMarkdown, tableValueProblems, topFieldKeyOf, usesHideOn, videoUrlOf, videoValueProblem, visibleBlocks, visibleDeliveredLayout, visibleLayoutStructure, windowState, withButtonLookProps };
3932
+ export { type AlignToken, type AllowRule, type ApiError, type ApiKey, type ApiKeyPermission, type ApiKeyTokenType, type ArrayZoneConfig, type AssertEqual, type AuthResponse, type AuthSession, type AuthUser, BLOCK_BINDINGS, BODY_SCHEMA_ORIGINS, BREAKPOINTS, BUTTON_ACTIONS, BUTTON_FULL_WIDTH_INVALID, BUTTON_ICONS, BUTTON_ICON_NAMES, BUTTON_LOOK_KEYS, BUTTON_PLACEMENT_KEYS, BUTTON_SIZES, BUTTON_VARIANTS, type BetterCMSErrorCode, type BgToken, type BindingKind, type BlockBinding, type BlockHoverStyle, type BlockStyle, type BlockType, type BodySchema, type BodySchemaOrigin, type ButtonAction, type ButtonBlock, type ButtonIcon, type ButtonLinkCandidate, type ButtonLookKey, type ButtonProps, type ButtonSiteLook, type ButtonSizeName, type ButtonValue, type ButtonVariant, CODE_SLOT_PREFIX, COMPONENT_PROP_TYPES, type CanonicalInputDefinition, type ChoiceOption, type CollectionBlock, type CollectionFilter, type CollectionProps, type ColorToken, type ColumnsBlock, type ColumnsProps, type Component, type ComponentBlock, type ComponentCategory, type ComponentFormPropRef, type ComponentPreview, type ComponentPropDef, type ComponentPropType, type ComponentPropUi, type ComponentProps, type ComponentSubField, type ComponentTab, type ComponentVariantGroup, type Content, type ContentBlock, type ContentEntry, type ContentModel, type ContentModelField, type ContentModelFieldType, type ContentModelFieldUi, type ContentPageResult, type ContentResponse, type ContentWidthToken, type CornerToken, DIALOG_SELECTOR, DOCK_BUDGET, DOCK_ICON_NAMES, DOCK_ICON_NAME_SET, type DeepReadonly, type DeliveredLayout, type DeliveryComponent, type DeliveryEntry, type DeliveryEntrySeo, type DeliveryList, type DeliveryPage, type DerivedLocator, type DockBudget, type DockFieldLike, type DockFieldsetLike, type DockIconName, type DockInputRef, type DockLane, type DockNode, type DockPropGroupLike, type DockScreen, type ElementLike, type ExpandedBinding, FIELD_SIZE_ZOOM, FIELD_STYLE_KEYS, FOOTER_SECTION_ID, type FieldConfig, type FieldSize, type FieldStyle, type FieldStyleKey, type FieldStyles, type Fieldset, type FieldsetKind, type FieldsetUiBefore, type FontSizeToken, type FooterBlock, type FooterColumn, type FooterProps, type Form, type FormBlock, type FormField, type FormProps, type FormSubmission, type HeadingBlock, type HeadingProps, IMAGE_ASPECTS, IMAGE_FRAME_RADIUS, type ImageAspect, type ImageBlock, type ImageProps, LANDMARK_SELECTOR, LAYOUT_SECTION_ICONS, LAYOUT_SECTION_ICON_SET, LINK_RELS, LINK_VALUE_TYPES, LIST_ITEMS_CAP, LOCATOR_PATH, type LandmarkChainElement, type LandmarkElement, type LayoutComponentItem, type LayoutDataDocument, type LayoutFieldDefinition, type LayoutFieldItem, type LayoutFieldType, type LayoutScalarFieldType, type LayoutSection, type LayoutSectionIcon, type LayoutSectionItem, type LayoutStructureDocument, type LayoutZone, type LinkRel, type LinkValue, type LinkValueType, type LocatorGrammar, MAIN_SELECTOR, type ManagementLayoutCommand, type MediaAsset, type MediaCaptionTrack, type MediaFieldValue, NAVIGATION_SECTION_ID, type NavLink, type NavbarBlock, type NavbarProps, type NumberFieldFormat, type NumberScale, OPTION_DESCRIPTION_MAX, type OpenMode, PAGE_CONTENT_ANCHOR_ID, type Page, type PageLayoutOverrideDataDocument, type PageLayoutOverrideDocument, type PageLayoutOverrideState, type PageLayoutOverrideStructureDocument, type PageLayoutSectionOverride, type PageLayoutSectionStructureOverride, type PageMetaJson, type PageOnlyLayoutSection, type PageSectionPlacement, type PaginatedResult, type Perspective, type PortableTextDocument, type PortableTextNode, type PropGroup, type PropTab, RESPONSIVE_CSS, ROLE_KEYS, type RadiusToken, type ReadButtonValue, type Redirect, type ReservedLayoutSection, type ResolvedLayoutNode, type RichTextBlock, type RichTextProps, SECTION_DOCTRINE, SECTION_SPACE_TOKENS, SIDE_SPACE_MIN_PX, SIDE_SPACE_TOKENS, SLOT_CHILD_KEYS, SLOT_ITEMS_CAP, SLOT_MAX_ITEMS, SPACE_BOTTOM_TOKENS, SPACE_STEP_TOKENS, type ScaleUnit, type SectionBlock, type SectionPlanItem, type SectionProps, type SectionSpaceToken, type ShadowToken, type ShowIf, type ShowIfRule, type SignInInput, type SignUpInput, type SiteSeoDefaults, type SlideItem, type SliderBlock, type SliderProps, type SlotChild, type SlotItem, type SlotShapeOptions, type SlotShapeProblem, type SlotValue, type SpaceStepToken, type SpaceToken, type SpacerBlock, type SpacerProps, TABLE_COLUMN_TYPES, TABLE_JSONLD_TYPES, TABLE_LIMITS, TABLE_RESPONSIVE, TAG_HEADS, type TabItem, type TableCell, type TableCellObject, type TableCellValue, type TableCheckOptions, type TableColumn, type TableColumnType, type TableFieldOptions, type TableFootnote, type TableGroup, type TableLink, type TableProblem, type TableRef, type TableRefResolved, type TableRow, type TableValue, type TabsBlock, type TabsProps, type TextBlock, type TextProps, type ThemeToken, type UiBefore, type UiOrigin, VIDEO_TRANSCRIPT_MAX, VIDEO_VALUE_KEYS, type VariantInputMapping, type VideoBlock, type VideoProps, type VideoValue, type VisibilityWindow, type WeightToken, type WindowState, type Workspace, type ZoneField, allowRuleOf, anchorTargetRel, blockStyleToColumnCss, blockStyleToCss, blockStyleToInnerCss, bodySchemaOf, buttonBlockProps, buttonFullWidthProblem, buttonIconOf, buttonIconSvg, buttonLinkPairs, buttonLookValue, buttonSiteLookOf, buttonValueOfInstance, buttonValueProblem, buttonVariantOf, candidateRole, componentInstanceAddresses, componentPropTargetKey, derivedPairs, dockBudget, dockScreens, expandBlockBindings, fieldGroupOf, fieldStyleCssText, fieldStyleToCss, formatNumber, formatPropsAttribute, getBlockType, headingPaintCss, hiddenEverywhere, hideOnAttr, imageFrameCss, inWindow, isBlock, isButtonLookValue, isChromeLandmark, isCodeButton, isLinkObject, isRoleKey, isScriptHref, isSlotChild, isTableValue, keyWords, landmarkRegions, linkAnchorOf, linkHref, linkRefOf, linkValueProblem, locatorFor, locatorPath, normalizeLinkValue, normalizeTableValue, normalizeWindow, parseNumberText, parsePropsAttribute, pickFieldStyle, placementBindOf, planSections, readButtonValue, readNumberFormat, readPath, regionOf, renderTableHtml, safeCssUrl, sideFloorApplies, sideSpaceCss, slotBindOf, slotChildValues, slotItems, slotPathString, slotShapeProblems, spaceTokenCss, splitButtonStyle, tableCellText, tablePathString, tableRefCells, tableSearchText, tableToMarkdown, tableValueProblems, topFieldKeyOf, usesHideOn, videoUrlOf, videoValueProblem, visibleBlocks, visibleDeliveredLayout, visibleLayoutStructure, windowState, withButtonLookProps };
package/dist/index.js CHANGED
@@ -1,3 +1,30 @@
1
+ // src/body-schema.ts
2
+ var BODY_SCHEMA_ORIGINS = ["inferred", "confirmed", "authored"];
3
+ var isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
4
+ var nonEmpty = (v) => typeof v === "string" && v.length > 0;
5
+ function allowRuleOf(value) {
6
+ if (!isRecord(value)) return null;
7
+ switch (value.kind) {
8
+ case "source":
9
+ return nonEmpty(value.pageId) ? { kind: "source", pageId: value.pageId } : null;
10
+ case "component":
11
+ return nonEmpty(value.id) ? { kind: "component", id: value.id } : null;
12
+ case "family":
13
+ return nonEmpty(value.sectionType) ? { kind: "family", sectionType: value.sectionType } : null;
14
+ case "builtins":
15
+ return { kind: "builtins" };
16
+ case "workspace":
17
+ return { kind: "workspace" };
18
+ default:
19
+ return null;
20
+ }
21
+ }
22
+ function bodySchemaOf(value) {
23
+ if (!isRecord(value) || !Array.isArray(value.allowed)) return null;
24
+ const origin = BODY_SCHEMA_ORIGINS.includes(value.origin) ? value.origin : "authored";
25
+ return { allowed: value.allowed.map(allowRuleOf).filter((r) => r !== null), origin };
26
+ }
27
+
1
28
  // src/block.ts
2
29
  var WINDOW_INSTANT = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:\d{2})$/;
3
30
  function normalizeWindow(value) {
@@ -197,14 +224,14 @@ var BLOCK_BINDINGS = {
197
224
  ],
198
225
  tabs: [{ path: "tabs[].label", kind: "text" }]
199
226
  };
200
- var isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
227
+ var isRecord2 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
201
228
  function readPath(root, path) {
202
229
  let cursor = root;
203
230
  for (const segment of path.split(".")) {
204
231
  if (!segment) return void 0;
205
232
  const key = segment.replace(/\[\d+\]/g, "");
206
233
  if (key) {
207
- if (!isRecord(cursor)) return void 0;
234
+ if (!isRecord2(cursor)) return void 0;
208
235
  cursor = cursor[key];
209
236
  }
210
237
  for (const index of segment.matchAll(/\[(\d+)\]/g)) {
@@ -229,7 +256,7 @@ function expandBlockBindings(block) {
229
256
  const declared = BLOCK_BINDINGS[block.type];
230
257
  if (!declared) return [];
231
258
  const props = block.props;
232
- if (!isRecord(props)) return [];
259
+ if (!isRecord2(props)) return [];
233
260
  return declared.flatMap((binding) => expandTemplate(binding, props, binding.path)).filter((binding) => readPath(props, binding.path) !== void 0);
234
261
  }
235
262
  function formatPropsAttribute(entries) {
@@ -612,8 +639,8 @@ function slotItems(value) {
612
639
  // src/slot-child.ts
613
640
  var SLOT_CHILD_KEYS = ["_key", "_type", "_variant", "_settings"];
614
641
  var RESERVED = new Set(SLOT_CHILD_KEYS);
615
- var isRecord2 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
616
- var isSlotChild = (v) => isRecord2(v) && typeof v._type === "string" && v._type !== "";
642
+ var isRecord3 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
643
+ var isSlotChild = (v) => isRecord3(v) && typeof v._type === "string" && v._type !== "";
617
644
  function slotChildValues(child) {
618
645
  const out = {};
619
646
  for (const [k, v] of Object.entries(child)) if (!RESERVED.has(k)) out[k] = v;
@@ -628,7 +655,7 @@ function slotShapeProblems(value, opts = {}) {
628
655
  if (opts.min !== void 0 && value.length < opts.min) out.push({ path: [], code: "slot_too_few", message: `slot_too_few: ${label} needs at least ${opts.min} blocks, got ${value.length}` });
629
656
  const keys = /* @__PURE__ */ new Set();
630
657
  value.forEach((child, i) => {
631
- if (!isRecord2(child)) {
658
+ if (!isRecord3(child)) {
632
659
  out.push({ path: [i], code: "slot_value_invalid", message: `slot_value_invalid: ${label}: block ${i + 1} must be an object { _key, _type, ...values }` });
633
660
  return;
634
661
  }
@@ -646,7 +673,7 @@ function slotShapeProblems(value, opts = {}) {
646
673
  }
647
674
  if (child._settings !== void 0) {
648
675
  if (!opts.settings) out.push({ path: [i, "_settings"], code: "slot_settings_undeclared", message: `slot_settings_undeclared: ${label} declares no slotSettings, so a block holds no _settings` });
649
- else if (!isRecord2(child._settings)) out.push({ path: [i, "_settings"], code: "slot_value_invalid", message: `slot_value_invalid: ${label}: _settings must be an object keyed by the slot's slotSettings` });
676
+ else if (!isRecord3(child._settings)) out.push({ path: [i, "_settings"], code: "slot_value_invalid", message: `slot_value_invalid: ${label}: _settings must be an object keyed by the slot's slotSettings` });
650
677
  }
651
678
  for (const k of Object.keys(child)) {
652
679
  if (k.startsWith("_") && !RESERVED.has(k)) {
@@ -3152,10 +3179,10 @@ function layout(fields, fieldsets, root) {
3152
3179
  const byId = new Map(fieldsets.map((s) => [s.id, s]));
3153
3180
  const tabIds = root ? fieldsets.filter((s) => s.kind === "tab").map((s) => s.id) : [];
3154
3181
  const tabOf = (s) => s?.kind === "tab" ? s.id : s?.tab !== void 0 && byId.get(s.tab)?.kind === "tab" ? s.tab : void 0;
3155
- const nonEmpty = new Set(
3182
+ const nonEmpty2 = new Set(
3156
3183
  fields.map((f) => tabOf(byId.get(f.fieldsetId ?? ""))).filter((t) => t && tabIds.includes(t))
3157
3184
  );
3158
- const strip2 = nonEmpty.size >= 2;
3185
+ const strip2 = nonEmpty2.size >= 2;
3159
3186
  const branches = /* @__PURE__ */ new Map();
3160
3187
  const nodeFor = (f, path) => {
3161
3188
  const key = `${path}${f.key}`;
@@ -3176,7 +3203,7 @@ function layout(fields, fieldsets, root) {
3176
3203
  return { kind: "leaf", key };
3177
3204
  };
3178
3205
  const pinned = [];
3179
- const panels = new Map(strip2 ? tabIds.filter((t) => nonEmpty.has(t)).map((t) => [t, []]) : []);
3206
+ const panels = new Map(strip2 ? tabIds.filter((t) => nonEmpty2.has(t)).map((t) => [t, []]) : []);
3180
3207
  const containers = /* @__PURE__ */ new Map();
3181
3208
  for (const f of fields) {
3182
3209
  const node = nodeFor(f, "");
@@ -4184,6 +4211,14 @@ function locatorFor(el, region, landmarks = false) {
4184
4211
  tag: el.tagName.toLowerCase()
4185
4212
  };
4186
4213
  }
4214
+ function locatorPath(el, landmarks = false) {
4215
+ const path = [];
4216
+ for (let parent = el.parentElement; parent && parent.tagName !== "BODY" && !isChromeLandmark(parent, landmarks); parent = parent.parentElement) {
4217
+ path.unshift(parent.parentElement ? Math.max(Array.from(parent.parentElement.children).indexOf(parent), 0) : 0);
4218
+ }
4219
+ return path;
4220
+ }
4221
+ var LOCATOR_PATH = /* @__PURE__ */ Symbol.for("bcms.locator.path");
4187
4222
  function landmarkRegions(doc, dialogs = false, landmarks = false) {
4188
4223
  const counts = /* @__PURE__ */ new Map();
4189
4224
  const out = [];
@@ -4244,9 +4279,79 @@ var TAG_HEADS = /* @__PURE__ */ new Set([
4244
4279
  "icon",
4245
4280
  "bg"
4246
4281
  ]);
4282
+ var ROLE_KEYS = /* @__PURE__ */ new Set([
4283
+ "headline",
4284
+ "heading",
4285
+ "subheading",
4286
+ "eyebrow",
4287
+ "intro",
4288
+ "paragraph",
4289
+ "text",
4290
+ "primary-button",
4291
+ "secondary-button",
4292
+ "button",
4293
+ "link",
4294
+ "home-link",
4295
+ "image",
4296
+ "icon",
4297
+ "logo",
4298
+ "background-image",
4299
+ "video-poster",
4300
+ "video",
4301
+ "embed",
4302
+ "audio",
4303
+ "body",
4304
+ "content",
4305
+ "copyright",
4306
+ "email",
4307
+ "phone",
4308
+ "price",
4309
+ "percentage",
4310
+ "number",
4311
+ "date",
4312
+ "stat-value",
4313
+ "stat-label",
4314
+ "quote",
4315
+ "attribution",
4316
+ "caption",
4317
+ "label",
4318
+ "summary",
4319
+ "address",
4320
+ "code",
4321
+ "term",
4322
+ "definition",
4323
+ "table-heading",
4324
+ "table-cell",
4325
+ "list-item",
4326
+ "title",
4327
+ "subtitle",
4328
+ "description",
4329
+ "value",
4330
+ "list",
4331
+ "plan-name",
4332
+ "cents",
4333
+ "billing-period",
4334
+ "badge",
4335
+ "features",
4336
+ "question",
4337
+ "answer",
4338
+ "author",
4339
+ "role",
4340
+ "tooltip",
4341
+ "placeholder",
4342
+ "image-description",
4343
+ "counter-target"
4344
+ ]);
4345
+ var ROLE_TAILS = /(?:-label)?(?:-[a-z])?(?:-\d+)?(?:-href)?$/;
4346
+ function isRoleKey(key) {
4347
+ if (ROLE_KEYS.has(key)) return true;
4348
+ const tail = ROLE_TAILS.exec(key);
4349
+ return !!tail && tail[0] !== "" && ROLE_KEYS.has(key.slice(0, tail.index));
4350
+ }
4247
4351
  var topFieldKeyOf = (path) => path.split(/[.[]/, 1)[0] ?? path;
4248
4352
  function fieldGroupOf(topKey, flat = false) {
4249
4353
  if (topKey.startsWith("group-")) return { groupKey: topKey, rooted: true };
4354
+ if (isRoleKey(topKey)) return { groupKey: topKey, rooted: false };
4250
4355
  const camel = flat ? /^([a-z][a-z0-9]*)[A-Z]/.exec(topKey)?.[1] : void 0;
4251
4356
  if (camel) return TAG_HEADS.has(camel) ? { groupKey: topKey, rooted: false } : { groupKey: camel, rooted: true };
4252
4357
  const head = topKey.split(/[-_]/, 1)[0] || topKey;
@@ -4300,6 +4405,7 @@ function planSections(slots, blocks) {
4300
4405
  }
4301
4406
  export {
4302
4407
  BLOCK_BINDINGS,
4408
+ BODY_SCHEMA_ORIGINS,
4303
4409
  BREAKPOINTS,
4304
4410
  BUTTON_ACTIONS,
4305
4411
  BUTTON_FULL_WIDTH_INVALID,
@@ -4326,11 +4432,13 @@ export {
4326
4432
  LINK_RELS,
4327
4433
  LINK_VALUE_TYPES,
4328
4434
  LIST_ITEMS_CAP,
4435
+ LOCATOR_PATH,
4329
4436
  MAIN_SELECTOR,
4330
4437
  NAVIGATION_SECTION_ID,
4331
4438
  OPTION_DESCRIPTION_MAX,
4332
4439
  PAGE_CONTENT_ANCHOR_ID,
4333
4440
  RESPONSIVE_CSS,
4441
+ ROLE_KEYS,
4334
4442
  SECTION_DOCTRINE,
4335
4443
  SECTION_SPACE_TOKENS,
4336
4444
  SIDE_SPACE_MIN_PX,
@@ -4347,10 +4455,12 @@ export {
4347
4455
  TAG_HEADS,
4348
4456
  VIDEO_TRANSCRIPT_MAX,
4349
4457
  VIDEO_VALUE_KEYS,
4458
+ allowRuleOf,
4350
4459
  anchorTargetRel,
4351
4460
  blockStyleToColumnCss,
4352
4461
  blockStyleToCss,
4353
4462
  blockStyleToInnerCss,
4463
+ bodySchemaOf,
4354
4464
  buttonBlockProps,
4355
4465
  buttonFullWidthProblem,
4356
4466
  buttonIconOf,
@@ -4384,6 +4494,7 @@ export {
4384
4494
  isChromeLandmark,
4385
4495
  isCodeButton,
4386
4496
  isLinkObject,
4497
+ isRoleKey,
4387
4498
  isScriptHref,
4388
4499
  isSlotChild,
4389
4500
  isTableValue,
@@ -4394,6 +4505,7 @@ export {
4394
4505
  linkRefOf,
4395
4506
  linkValueProblem,
4396
4507
  locatorFor,
4508
+ locatorPath,
4397
4509
  normalizeLinkValue,
4398
4510
  normalizeTableValue,
4399
4511
  normalizeWindow,