@bettercms-ai/types 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/dist/index.d.ts CHANGED
@@ -168,6 +168,12 @@ interface FieldConfig {
168
168
  /** Explicit migration acknowledgement while the legacy allowlist remains readable. */
169
169
  legacyResolved?: boolean;
170
170
  legacyMappings?: Record<string, string>;
171
+ /**
172
+ * image: `"icon"` marks an inline SVG icon the import derived (its value a `data:image/svg+xml`
173
+ * url or an `image/svg+xml` asset). The editor offers an icon picker for it, and the dock budget
174
+ * and the field-pruning guards leave it alone: an icon is editable content, never markup to tidy.
175
+ */
176
+ media?: "icon";
171
177
  [key: string]: unknown;
172
178
  }
173
179
  /**
@@ -1829,6 +1835,9 @@ declare function dockBudget(screen: DockScreen): DockBudget;
1829
1835
  * 5. Two fields pair when their stem holds EXACTLY one text and one link candidate. Three or more
1830
1836
  * candidates on a stem: none pair. A field that would pair two ways pairs neither way.
1831
1837
  *
1838
+ * 0. Before all of that, an importer's spelling pairs outright (@see derivedPairs):
1839
+ * `<stem>-href` (link-typed) with the one text keyed `<stem>`, or `<stem>` with its tag swapped.
1840
+ *
1832
1841
  * When the key's words say nothing, the visible LABEL is read the same way, its stems namespaced
1833
1842
  * (`label:`) so a label reading only ever meets another label reading.
1834
1843
  */
@@ -1848,6 +1857,19 @@ type Role = {
1848
1857
  };
1849
1858
  /** The role one field plays, with every stem it offers, or null. */
1850
1859
  declare function candidateRole(candidate: ButtonLinkCandidate): Role | null;
1860
+ /**
1861
+ * The pairs an IMPORTER's spelling names outright, before any role is read.
1862
+ *
1863
+ * Derive keys a call to action by the element it found it in: `equip-a-start-exploring-href` (link)
1864
+ * beside `equip-span-start-exploring` (text). Neither key ends in a role word, so the role pass
1865
+ * cannot pair them. Here a link-typed `<stem>-href` / `<stem>_href` pairs with the ONE text field
1866
+ * keyed `<stem>`, or `<stem>` with exactly one tag segment (a/span/button/div/strong) swapped for
1867
+ * another. Two candidate texts: none pairs.
1868
+ */
1869
+ declare function derivedPairs(candidates: readonly ButtonLinkCandidate[]): Map<number, {
1870
+ pair: string;
1871
+ role: "text" | "link";
1872
+ }>;
1851
1873
  /** Every unambiguous pair in one sibling list, as `[textIndex, linkIndex]`, in list order. */
1852
1874
  declare function buttonLinkPairs(candidates: readonly ButtonLinkCandidate[]): Array<[number, number]>;
1853
1875
 
@@ -2451,4 +2473,4 @@ declare function regionOf<E extends {
2451
2473
  el: E;
2452
2474
  }[], el: unknown): string | null;
2453
2475
 
2454
- export { type AlignToken, type ApiError, type ApiKey, type ApiKeyPermission, type ApiKeyTokenType, type ArrayZoneConfig, type AssertEqual, type AuthResponse, type AuthSession, type AuthUser, BLOCK_BINDINGS, 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 ButtonBlock, type ButtonIcon, type ButtonLinkCandidate, type ButtonLookKey, type ButtonProps, type ButtonSizeName, type ButtonValue, type ButtonVariant, COMPONENT_PROP_TYPES, type CanonicalInputDefinition, type CollectionBlock, type CollectionProps, type ColorToken, type ColumnsBlock, type ColumnsProps, type Component, type ComponentBlock, type ComponentCategory, type ComponentFormPropRef, type ComponentPropDef, type ComponentPropType, type ComponentPropUi, type ComponentProps, type ComponentSubField, 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 DockLane, type DockNode, type DockPropGroupLike, type DockScreen, type ElementLike, type ExpandedBinding, FOOTER_SECTION_ID, type FieldConfig, 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, type ImageBlock, type ImageProps, LANDMARK_SELECTOR, LAYOUT_SECTION_ICONS, LAYOUT_SECTION_ICON_SET, 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 LocatorGrammar, MAIN_SELECTOR, type ManagementLayoutCommand, type MediaAsset, type MediaCaptionTrack, type MediaFieldValue, NAVIGATION_SECTION_ID, type NavLink, type NavbarBlock, type NavbarProps, 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 RadiusToken, type Redirect, type ReservedLayoutSection, type ResolvedLayoutNode, type RichTextBlock, type RichTextProps, SECTION_DOCTRINE, SECTION_SPACE_TOKENS, SPACE_BOTTOM_TOKENS, SPACE_STEP_TOKENS, type SectionBlock, type SectionProps, type SectionSpaceToken, type ShadowToken, type SignInInput, type SignUpInput, type SiteSeoDefaults, type SlideItem, type SliderBlock, type SliderProps, type SpaceStepToken, type SpaceToken, type SpacerBlock, type SpacerProps, type TabItem, type TabsBlock, type TabsProps, type TextBlock, type TextProps, type ThemeToken, type UiBefore, type UiOrigin, type VariantInputMapping, type VideoBlock, type VideoProps, type WeightToken, type Workspace, type ZoneField, blockStyleToCss, blockStyleToInnerCss, buttonIconOf, buttonIconSvg, buttonLinkPairs, buttonValueOfInstance, buttonValueProblem, buttonVariantOf, candidateRole, componentInstanceAddresses, componentPropTargetKey, dockBudget, dockScreens, expandBlockBindings, formatPropsAttribute, getBlockType, headingPaintCss, isBlock, isChromeLandmark, keyWords, landmarkRegions, locatorFor, parsePropsAttribute, readButtonValue, readPath, regionOf, safeCssUrl, spaceTokenCss, splitButtonStyle, withButtonLookProps };
2476
+ export { type AlignToken, type ApiError, type ApiKey, type ApiKeyPermission, type ApiKeyTokenType, type ArrayZoneConfig, type AssertEqual, type AuthResponse, type AuthSession, type AuthUser, BLOCK_BINDINGS, 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 ButtonBlock, type ButtonIcon, type ButtonLinkCandidate, type ButtonLookKey, type ButtonProps, type ButtonSizeName, type ButtonValue, type ButtonVariant, COMPONENT_PROP_TYPES, type CanonicalInputDefinition, type CollectionBlock, type CollectionProps, type ColorToken, type ColumnsBlock, type ColumnsProps, type Component, type ComponentBlock, type ComponentCategory, type ComponentFormPropRef, type ComponentPropDef, type ComponentPropType, type ComponentPropUi, type ComponentProps, type ComponentSubField, 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 DockLane, type DockNode, type DockPropGroupLike, type DockScreen, type ElementLike, type ExpandedBinding, FOOTER_SECTION_ID, type FieldConfig, 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, type ImageBlock, type ImageProps, LANDMARK_SELECTOR, LAYOUT_SECTION_ICONS, LAYOUT_SECTION_ICON_SET, 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 LocatorGrammar, MAIN_SELECTOR, type ManagementLayoutCommand, type MediaAsset, type MediaCaptionTrack, type MediaFieldValue, NAVIGATION_SECTION_ID, type NavLink, type NavbarBlock, type NavbarProps, 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 RadiusToken, type Redirect, type ReservedLayoutSection, type ResolvedLayoutNode, type RichTextBlock, type RichTextProps, SECTION_DOCTRINE, SECTION_SPACE_TOKENS, SPACE_BOTTOM_TOKENS, SPACE_STEP_TOKENS, type SectionBlock, type SectionProps, type SectionSpaceToken, type ShadowToken, type SignInInput, type SignUpInput, type SiteSeoDefaults, type SlideItem, type SliderBlock, type SliderProps, type SpaceStepToken, type SpaceToken, type SpacerBlock, type SpacerProps, type TabItem, type TabsBlock, type TabsProps, type TextBlock, type TextProps, type ThemeToken, type UiBefore, type UiOrigin, type VariantInputMapping, type VideoBlock, type VideoProps, type WeightToken, type Workspace, type ZoneField, blockStyleToCss, blockStyleToInnerCss, buttonIconOf, buttonIconSvg, buttonLinkPairs, buttonValueOfInstance, buttonValueProblem, buttonVariantOf, candidateRole, componentInstanceAddresses, componentPropTargetKey, derivedPairs, dockBudget, dockScreens, expandBlockBindings, formatPropsAttribute, getBlockType, headingPaintCss, isBlock, isChromeLandmark, keyWords, landmarkRegions, locatorFor, parsePropsAttribute, readButtonValue, readPath, regionOf, safeCssUrl, spaceTokenCss, splitButtonStyle, withButtonLookProps };
package/dist/index.js CHANGED
@@ -2700,8 +2700,48 @@ function candidateRole(candidate) {
2700
2700
  const fromLabel = roleFromWords(candidate, keyWords(label.replace(/\s+/g, "_")));
2701
2701
  return fromLabel ? { role: fromLabel.role, stems: fromLabel.stems.map((stem) => `label:${stem}`) } : null;
2702
2702
  }
2703
+ var TAG_SEGMENTS = /* @__PURE__ */ new Set(["a", "span", "button", "div", "strong"]);
2704
+ var isScalarText = (value) => value === void 0 || value === null || typeof value === "string";
2705
+ function derivedPairs(candidates) {
2706
+ const out = /* @__PURE__ */ new Map();
2707
+ const leaf = (key) => key.split(".").pop() ?? "";
2708
+ const isText = (c) => TEXT_TYPES.has((c.type ?? "").toLowerCase()) && isScalarText(c.value) && !/[-_]href$/i.test(leaf(c.key));
2709
+ const sameButTag = (a, b) => {
2710
+ if (a === b) return true;
2711
+ const x = a.split(/[-_]/);
2712
+ const y = b.split(/[-_]/);
2713
+ if (x.length !== y.length) return false;
2714
+ let swapped = 0;
2715
+ for (let i = 0; i < x.length; i++) {
2716
+ if (x[i] === y[i]) continue;
2717
+ if (!TAG_SEGMENTS.has(x[i]) || !TAG_SEGMENTS.has(y[i])) return false;
2718
+ swapped++;
2719
+ }
2720
+ return swapped === 1;
2721
+ };
2722
+ candidates.forEach((link, linkIndex) => {
2723
+ if (out.has(linkIndex) || !LINK_TYPES.has((link.type ?? "").toLowerCase()) || !isScalarText(link.value)) return;
2724
+ const key = leaf(link.key);
2725
+ const suffix = /[-_]href$/i.exec(key);
2726
+ if (!suffix) return;
2727
+ const stem = key.slice(0, suffix.index);
2728
+ const parent = link.key.slice(0, link.key.length - key.length);
2729
+ const texts = candidates.map((text, textIndex) => ({ text, textIndex })).filter(
2730
+ ({ text, textIndex }) => textIndex !== linkIndex && !out.has(textIndex) && isText(text) && text.key.startsWith(parent) && sameButTag(leaf(text.key), stem)
2731
+ );
2732
+ if (texts.length !== 1) return;
2733
+ const pair = `${texts[0].textIndex}:${linkIndex}`;
2734
+ out.set(texts[0].textIndex, { pair, role: "text" });
2735
+ out.set(linkIndex, { pair, role: "link" });
2736
+ });
2737
+ return out;
2738
+ }
2703
2739
  function buttonLinkPairs(candidates) {
2704
- const roles = candidates.map(candidateRole);
2740
+ const derived = derivedPairs(candidates);
2741
+ const roles = candidates.map((candidate, index) => {
2742
+ const half = derived.get(index);
2743
+ return half ? { role: half.role, stems: [`derived:${half.pair}`] } : candidateRole(candidate);
2744
+ });
2705
2745
  const byStem = /* @__PURE__ */ new Map();
2706
2746
  roles.forEach((role, index) => {
2707
2747
  if (!role) return;
@@ -2915,6 +2955,7 @@ export {
2915
2955
  candidateRole,
2916
2956
  componentInstanceAddresses,
2917
2957
  componentPropTargetKey,
2958
+ derivedPairs,
2918
2959
  dockBudget,
2919
2960
  dockScreens,
2920
2961
  expandBlockBindings,