@bettercms-ai/types 1.6.0 → 1.8.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 +437 -5
- package/dist/index.js +1972 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -340,6 +340,326 @@ declare function getBlockType(value: unknown): BlockType | null;
|
|
|
340
340
|
/** A CSS declaration object (key → value) usable as a React `style` prop, or undefined when empty. */
|
|
341
341
|
declare function blockStyleToCss(style: BlockStyle | undefined): Record<string, string | number> | undefined;
|
|
342
342
|
|
|
343
|
+
/**
|
|
344
|
+
* Generated from lucide-react@1.8.0 dynamic icon names.
|
|
345
|
+
* Legacy CamelCase identifiers remain valid for existing Layout documents.
|
|
346
|
+
*/
|
|
347
|
+
declare const LAYOUT_SECTION_ICONS: readonly string[];
|
|
348
|
+
declare const LAYOUT_SECTION_ICON_SET: ReadonlySet<string>;
|
|
349
|
+
type LayoutSectionIcon = string;
|
|
350
|
+
|
|
351
|
+
/** Stable identifiers used by every project and page layout document. */
|
|
352
|
+
declare const PAGE_CONTENT_ANCHOR_ID: "page-content";
|
|
353
|
+
declare const NAVIGATION_SECTION_ID: "navigation";
|
|
354
|
+
declare const FOOTER_SECTION_ID: "footer";
|
|
355
|
+
|
|
356
|
+
type LayoutZone = "above-page-content" | "below-page-content";
|
|
357
|
+
type ReservedLayoutSection = "navigation" | "footer";
|
|
358
|
+
type LayoutScalarFieldType = "text" | "longtext" | "richtext" | "number" | "toggle" | "date" | "image" | "file" | "link" | "email" | "phone" | "select" | "color" | "json" | "reference" | "multi-reference";
|
|
359
|
+
type LayoutFieldType = LayoutScalarFieldType | "group" | "repeater";
|
|
360
|
+
/** A recursive, stable-ID field contract shared by Sections and variant inputs. */
|
|
361
|
+
interface LayoutFieldDefinition {
|
|
362
|
+
id: string;
|
|
363
|
+
slug: string;
|
|
364
|
+
label: string;
|
|
365
|
+
type: LayoutFieldType;
|
|
366
|
+
required?: boolean;
|
|
367
|
+
defaultValue?: unknown;
|
|
368
|
+
config?: {
|
|
369
|
+
options?: Array<{
|
|
370
|
+
label: string;
|
|
371
|
+
value: string;
|
|
372
|
+
}>;
|
|
373
|
+
referenceModelId?: string;
|
|
374
|
+
minItems?: number;
|
|
375
|
+
maxItems?: number;
|
|
376
|
+
} & Record<string, unknown>;
|
|
377
|
+
/** Required for group/repeater; forbidden for scalar fields. */
|
|
378
|
+
fields?: LayoutFieldDefinition[];
|
|
379
|
+
}
|
|
380
|
+
/** The canonical public input contract all variants in a group implement. */
|
|
381
|
+
type CanonicalInputDefinition = LayoutFieldDefinition;
|
|
382
|
+
/** Maps one canonical input onto one or more internal component prop paths. */
|
|
383
|
+
interface VariantInputMapping {
|
|
384
|
+
inputId: string;
|
|
385
|
+
targets: Array<{
|
|
386
|
+
blockId: string;
|
|
387
|
+
path: string;
|
|
388
|
+
}>;
|
|
389
|
+
}
|
|
390
|
+
interface ComponentVariantGroup {
|
|
391
|
+
id: string;
|
|
392
|
+
workspaceId: string;
|
|
393
|
+
projectId?: string | null;
|
|
394
|
+
name: string;
|
|
395
|
+
slug: string;
|
|
396
|
+
canonicalInputs: CanonicalInputDefinition[];
|
|
397
|
+
status: "draft" | "published";
|
|
398
|
+
}
|
|
399
|
+
interface LayoutFieldItem {
|
|
400
|
+
id: string;
|
|
401
|
+
kind: "field";
|
|
402
|
+
fieldId: string;
|
|
403
|
+
}
|
|
404
|
+
interface LayoutComponentItem {
|
|
405
|
+
id: string;
|
|
406
|
+
kind: "component";
|
|
407
|
+
componentId: string;
|
|
408
|
+
variantGroupId?: string;
|
|
409
|
+
bindings: Array<{
|
|
410
|
+
inputId: string;
|
|
411
|
+
fieldId: string;
|
|
412
|
+
}>;
|
|
413
|
+
literalValues?: Record<string, unknown>;
|
|
414
|
+
}
|
|
415
|
+
type LayoutSectionItem = LayoutFieldItem | LayoutComponentItem;
|
|
416
|
+
interface LayoutSection {
|
|
417
|
+
id: string;
|
|
418
|
+
name: string;
|
|
419
|
+
slug: string;
|
|
420
|
+
icon: string;
|
|
421
|
+
zone: LayoutZone;
|
|
422
|
+
orderKey: string;
|
|
423
|
+
reserved?: ReservedLayoutSection;
|
|
424
|
+
fields: LayoutFieldDefinition[];
|
|
425
|
+
items: LayoutSectionItem[];
|
|
426
|
+
}
|
|
427
|
+
interface LayoutStructureDocument {
|
|
428
|
+
version: 1;
|
|
429
|
+
pageContentAnchor: {
|
|
430
|
+
id: typeof PAGE_CONTENT_ANCHOR_ID;
|
|
431
|
+
};
|
|
432
|
+
sections: LayoutSection[];
|
|
433
|
+
}
|
|
434
|
+
interface LayoutDataDocument {
|
|
435
|
+
version: 1;
|
|
436
|
+
sections: Record<string, {
|
|
437
|
+
fields: Record<string, unknown>;
|
|
438
|
+
}>;
|
|
439
|
+
}
|
|
440
|
+
type PageLayoutOverrideState = "inherit" | "override-content" | "customize-structure" | "disable";
|
|
441
|
+
interface PageSectionPlacement {
|
|
442
|
+
zone: LayoutZone;
|
|
443
|
+
afterSectionId?: string;
|
|
444
|
+
beforeSectionId?: string;
|
|
445
|
+
localOrderKey: string;
|
|
446
|
+
}
|
|
447
|
+
type PageLayoutSectionOverride = {
|
|
448
|
+
sectionId: string;
|
|
449
|
+
state: "inherit";
|
|
450
|
+
} | {
|
|
451
|
+
sectionId: string;
|
|
452
|
+
state: "override-content";
|
|
453
|
+
values: Record<string, unknown>;
|
|
454
|
+
} | {
|
|
455
|
+
sectionId: string;
|
|
456
|
+
state: "customize-structure";
|
|
457
|
+
section: LayoutSection;
|
|
458
|
+
data: {
|
|
459
|
+
fields: Record<string, unknown>;
|
|
460
|
+
};
|
|
461
|
+
/** Retained when the inherited Section is later deleted. */
|
|
462
|
+
placement: PageSectionPlacement;
|
|
463
|
+
} | {
|
|
464
|
+
sectionId: string;
|
|
465
|
+
state: "disable";
|
|
466
|
+
};
|
|
467
|
+
interface PageOnlyLayoutSection {
|
|
468
|
+
section: LayoutSection;
|
|
469
|
+
data: {
|
|
470
|
+
fields: Record<string, unknown>;
|
|
471
|
+
};
|
|
472
|
+
placement: PageSectionPlacement;
|
|
473
|
+
}
|
|
474
|
+
type PageLayoutSectionStructureOverride = {
|
|
475
|
+
sectionId: string;
|
|
476
|
+
state: "inherit";
|
|
477
|
+
} | {
|
|
478
|
+
sectionId: string;
|
|
479
|
+
state: "override-content";
|
|
480
|
+
} | {
|
|
481
|
+
sectionId: string;
|
|
482
|
+
state: "customize-structure";
|
|
483
|
+
section: LayoutSection;
|
|
484
|
+
placement: PageSectionPlacement;
|
|
485
|
+
} | {
|
|
486
|
+
sectionId: string;
|
|
487
|
+
state: "disable";
|
|
488
|
+
};
|
|
489
|
+
/** Persisted in pages.layout_override_structure_json. */
|
|
490
|
+
interface PageLayoutOverrideStructureDocument {
|
|
491
|
+
version: 1;
|
|
492
|
+
sections: PageLayoutSectionStructureOverride[];
|
|
493
|
+
pageOnlySections: Array<{
|
|
494
|
+
section: LayoutSection;
|
|
495
|
+
placement: PageSectionPlacement;
|
|
496
|
+
}>;
|
|
497
|
+
}
|
|
498
|
+
/** Persisted independently so values can be patched without rewriting structure. */
|
|
499
|
+
interface PageLayoutOverrideDataDocument {
|
|
500
|
+
version: 1;
|
|
501
|
+
sections: Record<string, {
|
|
502
|
+
fields: Record<string, unknown>;
|
|
503
|
+
}>;
|
|
504
|
+
pageOnlySections: Record<string, {
|
|
505
|
+
fields: Record<string, unknown>;
|
|
506
|
+
}>;
|
|
507
|
+
}
|
|
508
|
+
/** Canonical in-memory form consumed by the pure resolver. */
|
|
509
|
+
interface PageLayoutOverrideDocument {
|
|
510
|
+
version: 1;
|
|
511
|
+
sections: PageLayoutSectionOverride[];
|
|
512
|
+
pageOnlySections: PageOnlyLayoutSection[];
|
|
513
|
+
}
|
|
514
|
+
/** Canonical, discriminated Management/MCP authoring transport. Authority is derived from type. */
|
|
515
|
+
type ManagementLayoutCommand = {
|
|
516
|
+
type: "set-section-values";
|
|
517
|
+
sectionId: string;
|
|
518
|
+
values: Record<string, unknown>;
|
|
519
|
+
} | {
|
|
520
|
+
type: "set-field-value";
|
|
521
|
+
sectionId: string;
|
|
522
|
+
fieldId: string;
|
|
523
|
+
value: unknown;
|
|
524
|
+
} | {
|
|
525
|
+
type: "add-component";
|
|
526
|
+
sectionId: string;
|
|
527
|
+
componentId: string;
|
|
528
|
+
variantGroupId?: string;
|
|
529
|
+
bindings?: LayoutComponentItem["bindings"];
|
|
530
|
+
literalValues?: Record<string, unknown>;
|
|
531
|
+
} | {
|
|
532
|
+
type: "remove-item";
|
|
533
|
+
sectionId: string;
|
|
534
|
+
itemId: string;
|
|
535
|
+
} | {
|
|
536
|
+
type: "move-component";
|
|
537
|
+
sectionId: string;
|
|
538
|
+
itemId: string;
|
|
539
|
+
index: number;
|
|
540
|
+
} | {
|
|
541
|
+
type: "move-item";
|
|
542
|
+
sectionId: string;
|
|
543
|
+
itemId: string;
|
|
544
|
+
index: number;
|
|
545
|
+
} | {
|
|
546
|
+
type: "swap-component-variant";
|
|
547
|
+
sectionId: string;
|
|
548
|
+
itemId: string;
|
|
549
|
+
componentId: string;
|
|
550
|
+
} | {
|
|
551
|
+
type: "set-page-state";
|
|
552
|
+
sectionId: string;
|
|
553
|
+
state: PageLayoutOverrideState | "reset";
|
|
554
|
+
} | {
|
|
555
|
+
type: "set-section-state";
|
|
556
|
+
sectionId: string;
|
|
557
|
+
state: PageLayoutOverrideState | "reset";
|
|
558
|
+
} | {
|
|
559
|
+
type: "add-section";
|
|
560
|
+
name: string;
|
|
561
|
+
icon: LayoutSectionIcon;
|
|
562
|
+
zone: "before_page" | "after_page";
|
|
563
|
+
} | {
|
|
564
|
+
type: "restore-section";
|
|
565
|
+
section: LayoutSection;
|
|
566
|
+
data: {
|
|
567
|
+
fields: Record<string, unknown>;
|
|
568
|
+
};
|
|
569
|
+
placement?: PageSectionPlacement;
|
|
570
|
+
} | {
|
|
571
|
+
type: "update-section";
|
|
572
|
+
sectionId: string;
|
|
573
|
+
name?: string;
|
|
574
|
+
icon?: LayoutSectionIcon;
|
|
575
|
+
slug?: string;
|
|
576
|
+
zone?: LayoutZone;
|
|
577
|
+
orderKey?: string;
|
|
578
|
+
} | {
|
|
579
|
+
type: "remove-section";
|
|
580
|
+
sectionId: string;
|
|
581
|
+
} | {
|
|
582
|
+
type: "move-section";
|
|
583
|
+
sectionId: string;
|
|
584
|
+
afterId?: string | null;
|
|
585
|
+
beforeId?: string | null;
|
|
586
|
+
} | {
|
|
587
|
+
type: "add-field";
|
|
588
|
+
sectionId: string;
|
|
589
|
+
parentFieldId?: string;
|
|
590
|
+
field?: LayoutFieldDefinition;
|
|
591
|
+
fieldType?: LayoutFieldType;
|
|
592
|
+
} | {
|
|
593
|
+
type: "update-field";
|
|
594
|
+
sectionId: string;
|
|
595
|
+
fieldId: string;
|
|
596
|
+
patch: Partial<Omit<LayoutFieldDefinition, "id">>;
|
|
597
|
+
} | {
|
|
598
|
+
type: "remove-field";
|
|
599
|
+
sectionId: string;
|
|
600
|
+
fieldId: string;
|
|
601
|
+
} | {
|
|
602
|
+
type: "move-field";
|
|
603
|
+
sectionId: string;
|
|
604
|
+
itemId: string;
|
|
605
|
+
index: number;
|
|
606
|
+
} | {
|
|
607
|
+
type: "set-bindings";
|
|
608
|
+
sectionId: string;
|
|
609
|
+
itemId: string;
|
|
610
|
+
bindings: LayoutComponentItem["bindings"];
|
|
611
|
+
literalValues?: Record<string, unknown>;
|
|
612
|
+
};
|
|
613
|
+
type ResolvedLayoutNode = {
|
|
614
|
+
kind: "page-content";
|
|
615
|
+
id: typeof PAGE_CONTENT_ANCHOR_ID;
|
|
616
|
+
} | {
|
|
617
|
+
kind: "section";
|
|
618
|
+
id: string;
|
|
619
|
+
section: LayoutSection;
|
|
620
|
+
data: {
|
|
621
|
+
fields: Record<string, unknown>;
|
|
622
|
+
};
|
|
623
|
+
source: "inherit" | "override-content" | "customize-structure" | "page-only" | "detached";
|
|
624
|
+
};
|
|
625
|
+
interface DeliveredLayout {
|
|
626
|
+
version: 1;
|
|
627
|
+
nodes: Array<{
|
|
628
|
+
kind: "page-content";
|
|
629
|
+
id: typeof PAGE_CONTENT_ANCHOR_ID;
|
|
630
|
+
} | {
|
|
631
|
+
kind: "section";
|
|
632
|
+
id: string;
|
|
633
|
+
slug: string;
|
|
634
|
+
name: string;
|
|
635
|
+
source: Extract<ResolvedLayoutNode, {
|
|
636
|
+
kind: "section";
|
|
637
|
+
}>["source"];
|
|
638
|
+
}>;
|
|
639
|
+
sections: Record<string, {
|
|
640
|
+
id: string;
|
|
641
|
+
slug: string;
|
|
642
|
+
name: string;
|
|
643
|
+
fields: Record<string, unknown>;
|
|
644
|
+
items: Array<{
|
|
645
|
+
id: string;
|
|
646
|
+
kind: "field";
|
|
647
|
+
fieldId: string;
|
|
648
|
+
value: unknown;
|
|
649
|
+
} | {
|
|
650
|
+
id: string;
|
|
651
|
+
kind: "component";
|
|
652
|
+
componentId: string;
|
|
653
|
+
variantGroupId?: string;
|
|
654
|
+
canonicalInputs: CanonicalInputDefinition[];
|
|
655
|
+
bindings: LayoutComponentItem["bindings"];
|
|
656
|
+
canonicalValues: Record<string, unknown>;
|
|
657
|
+
resolvedProps: Record<string, unknown>;
|
|
658
|
+
blocks: unknown[];
|
|
659
|
+
}>;
|
|
660
|
+
}>;
|
|
661
|
+
}
|
|
662
|
+
|
|
343
663
|
/**
|
|
344
664
|
* Component — a reusable, Webflow-style block tree (a "symbol").
|
|
345
665
|
*
|
|
@@ -367,9 +687,27 @@ interface ComponentPropDef {
|
|
|
367
687
|
blockId: string;
|
|
368
688
|
path: string;
|
|
369
689
|
};
|
|
370
|
-
|
|
690
|
+
/**
|
|
691
|
+
* `slot` holds ONE nested component instance — the component-level twin of the
|
|
692
|
+
* content-model field type `component-ref` (see content-model.ts), named differently for
|
|
693
|
+
* the same reason that one is: `component` already means a BLOCK type. Its value is
|
|
694
|
+
* `{ componentId, overrides }` and its `target.path` is `props`, so filling a slot writes
|
|
695
|
+
* that object over an empty `component` block's props.
|
|
696
|
+
*
|
|
697
|
+
* On a PAGE a slot fill is a LIVE reference; a published ENTRY freezes it (resolveDeep).
|
|
698
|
+
*/
|
|
699
|
+
type: "text" | "richtext" | "image" | "url" | "boolean" | "slot";
|
|
371
700
|
defaultValue?: unknown;
|
|
701
|
+
/** Per-type settings. `slot` uses `componentIds` as a pick allowlist. */
|
|
702
|
+
config?: {
|
|
703
|
+
componentIds?: string[];
|
|
704
|
+
} & Record<string, unknown>;
|
|
372
705
|
}
|
|
706
|
+
/**
|
|
707
|
+
* A component is a DRAFT until published; only the published copy reaches a visitor.
|
|
708
|
+
* Mirrors pages and entries. See migration 0186_component_draft_live_split.sql.
|
|
709
|
+
*/
|
|
710
|
+
type ComponentStatus = "draft" | "published";
|
|
373
711
|
interface Component {
|
|
374
712
|
id: string;
|
|
375
713
|
workspaceId: string;
|
|
@@ -383,14 +721,41 @@ interface Component {
|
|
|
383
721
|
* of one section. Null/absent = an ordinary component, not shown in the section library.
|
|
384
722
|
*/
|
|
385
723
|
sectionType?: string | null;
|
|
724
|
+
/** First-class variant family membership; exact workspace/project scope is enforced in DB. */
|
|
725
|
+
variantGroupId?: string | null;
|
|
726
|
+
variantInputMappings?: VariantInputMapping[];
|
|
727
|
+
/** Placement governance: `*`, `slug:<page-slug>`, and/or `type:<page-type>`. */
|
|
728
|
+
allowedOn: string[];
|
|
386
729
|
description?: string | null;
|
|
730
|
+
/** The DRAFT definition. Every builder/autosave/import write path targets these two. */
|
|
387
731
|
blockJson: ContentBlock[];
|
|
388
732
|
props: ComponentPropDef[];
|
|
733
|
+
status: ComponentStatus;
|
|
734
|
+
/**
|
|
735
|
+
* The LIVE snapshot get_components_by_handle() serves. Null until the first publish.
|
|
736
|
+
* Returned by GET-one (the Compare view needs it), omitted from list rows for payload.
|
|
737
|
+
*/
|
|
738
|
+
publishedBlockJson?: ContentBlock[] | null;
|
|
739
|
+
publishedProps?: ComponentPropDef[] | null;
|
|
740
|
+
publishedAt?: string | null;
|
|
741
|
+
/**
|
|
742
|
+
* Computed in SQL on list/get, never stored:
|
|
743
|
+
* status='published' AND (blockJson or props has diverged from its published copy).
|
|
744
|
+
* An exact jsonb compare, so it self-clears when an edit is reverted.
|
|
745
|
+
*/
|
|
746
|
+
pendingChanges?: boolean;
|
|
389
747
|
thumbnail?: string | null;
|
|
390
748
|
createdAt: string;
|
|
391
749
|
updatedAt: string;
|
|
392
750
|
}
|
|
393
|
-
/**
|
|
751
|
+
/**
|
|
752
|
+
* Public/delivery projection — the fields a renderer needs to resolve instances.
|
|
753
|
+
*
|
|
754
|
+
* DELIBERATELY UNCHANGED by the 0186 draft/live split: delivery aliases
|
|
755
|
+
* publishedBlockJson -> blockJson, so every already-deployed site and every
|
|
756
|
+
* bcms-content.json on disk keeps a byte-identical wire shape. Do not add `status` here —
|
|
757
|
+
* delivery only ever returns published rows, so it would always be the same constant.
|
|
758
|
+
*/
|
|
394
759
|
interface DeliveryComponent {
|
|
395
760
|
id: string;
|
|
396
761
|
name: string;
|
|
@@ -411,6 +776,7 @@ interface ContentEntry {
|
|
|
411
776
|
slug: string;
|
|
412
777
|
title: string;
|
|
413
778
|
blocks: ContentBlock[];
|
|
779
|
+
layout?: DeliveredLayout | null;
|
|
414
780
|
updatedAt: string;
|
|
415
781
|
}
|
|
416
782
|
|
|
@@ -423,7 +789,11 @@ interface ContentModel {
|
|
|
423
789
|
workspaceId: string;
|
|
424
790
|
name: string;
|
|
425
791
|
description?: string;
|
|
792
|
+
/** 'block' models hold no entries — they are instantiable only inside a `modular` field. */
|
|
793
|
+
kind?: ContentModelKind;
|
|
426
794
|
fields: ContentModelField[];
|
|
795
|
+
/** Authoring-only field grouping for the schema builder. Never affects the API shape. */
|
|
796
|
+
fieldsets?: Fieldset[];
|
|
427
797
|
createdAt: string;
|
|
428
798
|
updatedAt: string;
|
|
429
799
|
}
|
|
@@ -433,7 +803,13 @@ interface ContentModel {
|
|
|
433
803
|
* by the API but normalized to `array` + zones on write, so stored/delivered
|
|
434
804
|
* content never contains them.
|
|
435
805
|
*/
|
|
436
|
-
type ContentModelFieldType = "text" | "richtext" | "image" | "boolean" | "number" | "select" | "reference" | "multi-reference" | "multiReference" | "array" | "date" | "datetime" | "longtext" | "slug" | "email" | "phone" | "link" | "color" | "json" | "file" | "component-ref";
|
|
806
|
+
type ContentModelFieldType = "text" | "richtext" | "document" | "image" | "boolean" | "number" | "select" | "reference" | "multi-reference" | "multiReference" | "array" | "date" | "datetime" | "longtext" | "slug" | "email" | "phone" | "link" | "color" | "json" | "file" | "component-ref" | "modular" | "sections" | "location";
|
|
807
|
+
type ContentModelKind = "model" | "block";
|
|
808
|
+
/** A named, UI-only grouping of a model's fields. Order is the array index. */
|
|
809
|
+
interface Fieldset {
|
|
810
|
+
id: string;
|
|
811
|
+
name: string;
|
|
812
|
+
}
|
|
437
813
|
/**
|
|
438
814
|
* Nested-content config for an `array` field. A zone holds ordinary fields, and a
|
|
439
815
|
* zone field may itself be an `array` with its own zones, so nesting is recursive
|
|
@@ -462,6 +838,38 @@ interface FieldConfig {
|
|
|
462
838
|
max?: number;
|
|
463
839
|
/** date / datetime */
|
|
464
840
|
includeTime?: boolean;
|
|
841
|
+
/** modular: SLUGS of the kind='block' models this field accepts. Non-empty. */
|
|
842
|
+
blockSlugs?: string[];
|
|
843
|
+
/** modular: bounds on how many block instances the field may hold. */
|
|
844
|
+
minItems?: number;
|
|
845
|
+
maxItems?: number;
|
|
846
|
+
/**
|
|
847
|
+
* sections: SLUGS of the sections an author may insert into this zone.
|
|
848
|
+
*
|
|
849
|
+
* Deliberately NOT named `blockSlugs`. That key means "kind='block' content models" and is
|
|
850
|
+
* read by ModularField; these are section-registry slugs resolved from a different place.
|
|
851
|
+
* One key meaning two things is how `blockModels`/`blockSlugs` already drifted apart in the
|
|
852
|
+
* dashboard — a distinct name costs nothing and cannot be confused at a call site.
|
|
853
|
+
*
|
|
854
|
+
* ⚠ ABSENT ≠ EMPTY:
|
|
855
|
+
* absent → UNRESTRICTED, every registry section may be inserted
|
|
856
|
+
* [] → DENY ALL, a deliberate empty restriction
|
|
857
|
+
* [a, b] → only those
|
|
858
|
+
* `[]` means DENY here to match `components.allowed_on` (migration 0190), so two adjacent
|
|
859
|
+
* allow-lists never disagree about what empty means.
|
|
860
|
+
*
|
|
861
|
+
* Absent rather than "all current slugs" because the registry GROWS — it is fed by repo
|
|
862
|
+
* pushes and project components, so materializing today's slugs at field-creation time would
|
|
863
|
+
* silently exclude every section shipped afterwards.
|
|
864
|
+
*
|
|
865
|
+
* NOT READ DIRECTLY. Insertability is this list INTERSECTED with the component's `allowedOn`
|
|
866
|
+
* (where that section may be placed), computed by one resolver so the two cannot drift.
|
|
867
|
+
*
|
|
868
|
+
* Enforced on NEW picks only. Narrowing the list later must never invalidate sections an
|
|
869
|
+
* author already placed, the same rule modular's blockSlugs and component-ref's allowlist
|
|
870
|
+
* follow.
|
|
871
|
+
*/
|
|
872
|
+
allowedSections?: string[];
|
|
465
873
|
[key: string]: unknown;
|
|
466
874
|
}
|
|
467
875
|
/**
|
|
@@ -498,6 +906,11 @@ interface ContentModelField {
|
|
|
498
906
|
options?: string[];
|
|
499
907
|
/** Per-type config. For `array`: either `itemType` (primitive) or `zones` (nested). */
|
|
500
908
|
config?: FieldConfig | null;
|
|
909
|
+
/**
|
|
910
|
+
* Which fieldset this field renders under in the schema builder. Authoring-only: it is
|
|
911
|
+
* never delivered and cannot move a value — see {@link Fieldset}.
|
|
912
|
+
*/
|
|
913
|
+
fieldsetId?: string;
|
|
501
914
|
/**
|
|
502
915
|
* Authoring-only editor placement. See {@link ContentModelFieldPlacement}.
|
|
503
916
|
* Field ORDER is the array index — there is deliberately no `order` property.
|
|
@@ -618,6 +1031,7 @@ interface SiteSeoDefaults {
|
|
|
618
1031
|
}
|
|
619
1032
|
/** A published page with its rendered block tree. */
|
|
620
1033
|
interface DeliveryPage {
|
|
1034
|
+
projectId?: string | null;
|
|
621
1035
|
slug: string;
|
|
622
1036
|
title: string;
|
|
623
1037
|
metaTitle: string | null;
|
|
@@ -625,6 +1039,7 @@ interface DeliveryPage {
|
|
|
625
1039
|
/** Rich SEO (OG / Twitter / canonical / JSON-LD). Always present; `null` when unset. */
|
|
626
1040
|
metaJson: PageMetaJson | null;
|
|
627
1041
|
blocks: ContentBlock[];
|
|
1042
|
+
layout?: DeliveredLayout | null;
|
|
628
1043
|
updatedAt: string | null;
|
|
629
1044
|
publishedAt: string | null;
|
|
630
1045
|
}
|
|
@@ -641,25 +1056,42 @@ interface DeliveryList<T> {
|
|
|
641
1056
|
|
|
642
1057
|
/**
|
|
643
1058
|
* Form — a CMS form that renders on a page and accepts submissions.
|
|
1059
|
+
*
|
|
1060
|
+
* Mirrors the authoring row in `packages/db/src/schema/forms.ts`. That file is the source
|
|
1061
|
+
* of truth; this is the public, Drizzle-free restatement of it. The two MUST stay in step —
|
|
1062
|
+
* a consumer that types a form off this file and writes it back through the API silently
|
|
1063
|
+
* drops whatever this file forgot to declare.
|
|
644
1064
|
*/
|
|
645
1065
|
interface Form {
|
|
646
1066
|
id: string;
|
|
647
1067
|
workspaceId: string;
|
|
1068
|
+
/** Scopes the form to a project. Null for workspace-level forms. */
|
|
1069
|
+
projectId: string | null;
|
|
648
1070
|
name: string;
|
|
649
1071
|
fields: FormField[];
|
|
1072
|
+
/** Draft forms reject submissions at every ingress (403). New forms start as drafts. */
|
|
1073
|
+
status: FormStatus;
|
|
650
1074
|
submitLabel?: string;
|
|
651
1075
|
successMessage?: string;
|
|
652
1076
|
redirectUrl?: string;
|
|
653
1077
|
createdAt: string;
|
|
654
1078
|
updatedAt: string;
|
|
655
1079
|
}
|
|
1080
|
+
type FormStatus = "draft" | "published";
|
|
656
1081
|
interface FormField {
|
|
657
1082
|
key: string;
|
|
658
1083
|
label: string;
|
|
659
|
-
type: "text" | "email" | "textarea" | "select" | "checkbox";
|
|
1084
|
+
type: "text" | "email" | "textarea" | "select" | "checkbox" | "checkboxes" | "radio" | "number" | "phone" | "date" | "url" | "consent" | "hidden";
|
|
660
1085
|
placeholder?: string;
|
|
1086
|
+
helpText?: string;
|
|
661
1087
|
required?: boolean;
|
|
662
1088
|
options?: string[];
|
|
1089
|
+
hidden?: boolean;
|
|
1090
|
+
defaultValue?: string;
|
|
1091
|
+
showIf?: {
|
|
1092
|
+
field: string;
|
|
1093
|
+
equals: string;
|
|
1094
|
+
};
|
|
663
1095
|
}
|
|
664
1096
|
/**
|
|
665
1097
|
* FormSubmission — a single form submission submitted by a visitor.
|
|
@@ -794,4 +1226,4 @@ type DeepReadonly<T> = T extends Function ? T : T extends object ? {
|
|
|
794
1226
|
*/
|
|
795
1227
|
type AssertEqual<L, R> = [L] extends [R] ? ([R] extends [L] ? true : false) : false;
|
|
796
1228
|
|
|
797
|
-
export { type AlignToken, type ApiError, type ApiKey, type ApiKeyPermission, type ApiKeyTokenType, type ArrayZoneConfig, type AssertEqual, type AuthResponse, type AuthSession, type AuthUser, type BetterCMSErrorCode, type BlockStyle, type BlockType, type ButtonBlock, type ButtonProps, type ColorToken, type ColumnsBlock, type ColumnsProps, type Component, type ComponentBlock, type ComponentCategory, type ComponentPropDef, type ComponentProps, type Content, type ContentBlock, type ContentEntry, type ContentModel, type ContentModelField, type ContentModelFieldType, type ContentPageResult, type ContentResponse, type DeepReadonly, type DeliveryComponent, type DeliveryEntry, type DeliveryList, type DeliveryPage, type FieldConfig, 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, type MediaAsset, type NavLink, type NavbarBlock, type NavbarProps, type Page, type PageMetaJson, type PaginatedResult, type Perspective, type PortableTextDocument, type PortableTextNode, type RadiusToken, type Redirect, type RichTextBlock, type RichTextProps, type SectionBlock, type SectionProps, type SignInInput, type SignUpInput, type SiteSeoDefaults, type SlideItem, type SliderBlock, type SliderProps, type SpaceToken, type SpacerBlock, type SpacerProps, type TabItem, type TabsBlock, type TabsProps, type TextBlock, type TextProps, type VideoBlock, type VideoProps, type WeightToken, type Workspace, type ZoneField, blockStyleToCss, getBlockType, isBlock };
|
|
1229
|
+
export { type AlignToken, type ApiError, type ApiKey, type ApiKeyPermission, type ApiKeyTokenType, type ArrayZoneConfig, type AssertEqual, type AuthResponse, type AuthSession, type AuthUser, type BetterCMSErrorCode, type BlockStyle, type BlockType, type ButtonBlock, type ButtonProps, type CanonicalInputDefinition, type ColorToken, type ColumnsBlock, type ColumnsProps, type Component, type ComponentBlock, type ComponentCategory, type ComponentPropDef, type ComponentProps, type ComponentVariantGroup, type Content, type ContentBlock, type ContentEntry, type ContentModel, type ContentModelField, type ContentModelFieldType, type ContentPageResult, type ContentResponse, type DeepReadonly, type DeliveredLayout, type DeliveryComponent, type DeliveryEntry, type DeliveryList, type DeliveryPage, FOOTER_SECTION_ID, type FieldConfig, 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, LAYOUT_SECTION_ICONS, LAYOUT_SECTION_ICON_SET, type LayoutComponentItem, type LayoutDataDocument, type LayoutFieldDefinition, type LayoutFieldItem, type LayoutFieldType, type LayoutScalarFieldType, type LayoutSection, type LayoutSectionIcon, type LayoutSectionItem, type LayoutStructureDocument, type LayoutZone, type ManagementLayoutCommand, type MediaAsset, 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 RadiusToken, type Redirect, type ReservedLayoutSection, type ResolvedLayoutNode, type RichTextBlock, type RichTextProps, type SectionBlock, type SectionProps, type SignInInput, type SignUpInput, type SiteSeoDefaults, type SlideItem, type SliderBlock, type SliderProps, type SpaceToken, type SpacerBlock, type SpacerProps, type TabItem, type TabsBlock, type TabsProps, type TextBlock, type TextProps, type VariantInputMapping, type VideoBlock, type VideoProps, type WeightToken, type Workspace, type ZoneField, blockStyleToCss, getBlockType, isBlock };
|