@fusebase/fusebase-gate-sdk 2.5.1-sdk.1 → 2.5.1-sdk.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.
@@ -180,6 +180,67 @@ export interface AddPortalBlankNoteBlockResponseContract {
180
180
  */
181
181
  staged: boolean;
182
182
  }
183
+ export interface AddPortalKanbanBlockRequestContract {
184
+ /**
185
+ * Title of the block, its note and its board (defaults to "Kanban").
186
+ * @minLength 1
187
+ * @maxLength 100
188
+ */
189
+ title?: string;
190
+ /**
191
+ * Column titles of the new board, in order. 1..10 non-empty titles, each at
192
+ * most 100 characters. Defaults to "To do", "In progress", "Done".
193
+ */
194
+ columns?: string[];
195
+ }
196
+ export interface AddPortalKanbanBlockResponseContract {
197
+ /** Global id of the newly created Fusebase note holding the board. */
198
+ noteId: string;
199
+ /** Global id of the created Kanban board. */
200
+ boardId: string;
201
+ /** Id of the created note block. */
202
+ blockId: string;
203
+ /** Id of the page the block was added to. */
204
+ pageId: string;
205
+ /** Draft branch the change was staged on. */
206
+ branchId: string;
207
+ /** Sequence numbers assigned to the staged change events (addBlock). */
208
+ seqs: number[];
209
+ /**
210
+ * Always true: the block is staged in the portal's customizer draft, not yet
211
+ * live. The portal owner reviews and publishes it from the customizer.
212
+ */
213
+ staged: boolean;
214
+ }
215
+ export interface AddPortalTaskListBlockRequestContract {
216
+ /**
217
+ * Title of the block and of its task list (defaults to "Task list"). The
218
+ * backing note keeps the customizer's own "New page" title.
219
+ * @maxLength 100
220
+ */
221
+ title?: string;
222
+ /** Grid placement. Default: width 6 columns and automatic height. */
223
+ layout?: PortalTaskListBlockLayoutContract;
224
+ }
225
+ export interface AddPortalTaskListBlockResponseContract {
226
+ /** Global id of the newly created Fusebase note holding the task list. */
227
+ noteId: string;
228
+ /** Global id of the created task list. */
229
+ taskListId: string;
230
+ /** Id of the created note block. */
231
+ blockId: string;
232
+ /** Id of the page the block was added to. */
233
+ pageId: string;
234
+ /** Draft branch the change was staged on. */
235
+ branchId: string;
236
+ /** Sequence numbers assigned to the staged change events (addBlock). */
237
+ seqs: number[];
238
+ /**
239
+ * Always true: the block is staged in the portal's customizer draft, not yet
240
+ * live. The portal owner reviews and publishes it from the customizer.
241
+ */
242
+ staged: boolean;
243
+ }
183
244
  export interface AddPortalNoteBlockResponseContract {
184
245
  /** Id of the created note content block. */
185
246
  blockId: string;
@@ -278,6 +339,13 @@ export type PortalDatabaseBlockAppearanceContract = {
278
339
  /** Default: true. */
279
340
  showTitle?: boolean;
280
341
  };
342
+ /** Customizer Layout section of the Task list block. */
343
+ export interface PortalTaskListBlockLayoutContract {
344
+ /** Customizer Width. Default: 6. */
345
+ colspan?: 3 | 4 | 5 | 6;
346
+ /** Customizer Height: null = Auto; a manual value is at least 50px. Default: null. */
347
+ height?: number | null;
348
+ }
281
349
  /** Customizer Layout section. */
282
350
  export interface PortalDatabaseBlockLayoutContract {
283
351
  /** Customizer Width. Default: 6. */
@@ -403,7 +471,867 @@ export interface AddPortalImageBlockRequestContract {
403
471
  /** Default: width 6 columns and automatic height. */
404
472
  layout?: PortalTextAndMediaLayoutContract;
405
473
  }
406
- export interface PortalTextAndMediaBlockResponseContract {
474
+ export interface PortalTextAndMediaBlockResponseContract {
475
+ /** Id of the created block. */
476
+ blockId: string;
477
+ /** Id of the page the block was added to. */
478
+ pageId: string;
479
+ /** Draft branch the change was staged on. */
480
+ branchId: string;
481
+ /** Sequence numbers assigned to the staged change events (addBlock). */
482
+ seqs: number[];
483
+ /** Always true: the block is staged in the customizer draft, not yet live. */
484
+ staged: boolean;
485
+ }
486
+ /**
487
+ * Customizer background picker. Colours are palette tokens; an image is one of
488
+ * the five built-in presets.
489
+ */
490
+ export type PortalCardBackgroundContract = {
491
+ type: "color";
492
+ /** @pattern ^(transparent|white|black|(slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(50|100|200|300|400|500|600|700|800|900|950))$ */
493
+ color: PortalColorToken;
494
+ } | {
495
+ type: "gradient";
496
+ /** @pattern ^(transparent|white|black|(slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(50|100|200|300|400|500|600|700|800|900|950))$ */
497
+ from: PortalColorToken;
498
+ /** @pattern ^(transparent|white|black|(slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(50|100|200|300|400|500|600|700|800|900|950))$ */
499
+ to: PortalColorToken;
500
+ /** Default: `to-t`. */
501
+ direction?: "to-t" | "to-r" | "to-b" | "to-l";
502
+ } | {
503
+ type: "image";
504
+ preset: PortalBackgroundImagePreset;
505
+ /** Default: false. */
506
+ blur?: boolean;
507
+ };
508
+ /** The four Card Types of the Customizer's Card tile. `compact` is legacy and rejected. */
509
+ export type PortalCardViewContract = "top-image" | "left-image" | "right-image" | "fill-image";
510
+ /**
511
+ * Customizer Appearance section of a Card. Omitting `appearance` keeps the
512
+ * Card's canonical `bare` wrapper, which is not a selectable backdrop.
513
+ */
514
+ export type PortalCardAppearanceContract = {
515
+ backdrop: "none" | "blank";
516
+ } | {
517
+ backdrop: "custom";
518
+ background: PortalCardBackgroundContract;
519
+ /** Default: `s`. */
520
+ padding?: "none" | "s" | "m" | "l";
521
+ /** Default: false. */
522
+ showTitle?: boolean;
523
+ };
524
+ /** Customizer Layout section of a Card. */
525
+ export interface PortalCardLayoutContract {
526
+ /** Customizer Width. Default: 3. */
527
+ colspan?: 2 | 3 | 4 | 5 | 6;
528
+ /**
529
+ * Customizer Height: null = Auto; a manual value is at least 50px. Default: null.
530
+ * @minimum 50
531
+ */
532
+ height?: number | null;
533
+ }
534
+ /**
535
+ * A hidden Card item carries ONLY `visible: false`: sending text or styles next
536
+ * to it would silently drop settings the caller believes they applied.
537
+ */
538
+ export type PortalCardHeadingContract = {
539
+ visible: false;
540
+ } | {
541
+ /** Default: true. */
542
+ visible?: true;
543
+ /**
544
+ * Plain text. Only `{{ClientName}}` and `{{ClientLastName}}` are variables.
545
+ * @minLength 1
546
+ * @maxLength 100
547
+ */
548
+ text?: string;
549
+ /** @pattern ^(transparent|white|black|(slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(50|100|200|300|400|500|600|700|800|900|950))$ */
550
+ color?: PortalColorToken;
551
+ size?: PortalTextSize;
552
+ /** Set semantics: a duplicate value is rejected with 400. */
553
+ styles?: PortalTextStyle[];
554
+ align?: PortalTextAlign;
555
+ };
556
+ export type PortalCardDescriptionContract = {
557
+ visible: false;
558
+ } | {
559
+ /** Default: true. */
560
+ visible?: true;
561
+ /**
562
+ * Plain text. Only `{{ClientName}}` and `{{ClientLastName}}` are variables.
563
+ * @minLength 1
564
+ * @maxLength 2000
565
+ */
566
+ text?: string;
567
+ /** @pattern ^(transparent|white|black|(slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(50|100|200|300|400|500|600|700|800|900|950))$ */
568
+ color?: PortalColorToken;
569
+ size?: PortalTextSize;
570
+ /** Set semantics: a duplicate value is rejected with 400. */
571
+ styles?: PortalTextStyle[];
572
+ align?: PortalTextAlign;
573
+ };
574
+ export type PortalCardButtonContract = {
575
+ visible: false;
576
+ } | {
577
+ /** Default: true. */
578
+ visible?: true;
579
+ /**
580
+ * Plain text; the Button label supports no dynamic variables.
581
+ * @minLength 1
582
+ * @maxLength 100
583
+ */
584
+ text?: string;
585
+ };
586
+ /** The Card always uses the template image: no source field is accepted. */
587
+ export interface PortalCardImageContract {
588
+ /** Default: true. */
589
+ visible?: boolean;
590
+ }
591
+ /** Semantic Destination of the whole Card (and of its Button). */
592
+ export type PortalCardDestinationContract = {
593
+ type: "portalPage";
594
+ /** Exact id of an existing page in the SAME portal. */
595
+ pageId: string;
596
+ } | {
597
+ type: "external";
598
+ /**
599
+ * Absolute https:// URL. `javascript:`, `data:`, a protocol-relative URL
600
+ * and embedded credentials are rejected.
601
+ * @maxLength 2048
602
+ */
603
+ url: string;
604
+ } | {
605
+ type: "email";
606
+ /**
607
+ * Address only; portal-service adds the `mailto:` scheme.
608
+ * @maxLength 254
609
+ */
610
+ email: string;
611
+ };
612
+ /** Customizer Content section of a Card. */
613
+ export interface PortalCardContentContract {
614
+ image?: PortalCardImageContract;
615
+ /** Default: "Helpful Resources", bold. */
616
+ heading?: PortalCardHeadingContract;
617
+ /** Default: the Customizer's Card copy. */
618
+ description?: PortalCardDescriptionContract;
619
+ /** Default: "Explore". */
620
+ button?: PortalCardButtonContract;
621
+ /**
622
+ * Omitted keeps the Customizer default link; `null` leaves the Card without
623
+ * any destination.
624
+ */
625
+ destination?: PortalCardDestinationContract | null;
626
+ }
627
+ export interface AddPortalCardBlockRequestContract {
628
+ /** Card Type. Default: `top-image`. */
629
+ view?: PortalCardViewContract;
630
+ content?: PortalCardContentContract;
631
+ /** Omitted keeps the Card's canonical bare wrapper. */
632
+ appearance?: PortalCardAppearanceContract;
633
+ /** Default: width 3 columns and automatic height. */
634
+ layout?: PortalCardLayoutContract;
635
+ }
636
+ export interface AddPortalCardBlockResponseContract {
637
+ /** Id of the created block. */
638
+ blockId: string;
639
+ /** Id of the page the block was added to. */
640
+ pageId: string;
641
+ /** Draft branch the change was staged on. */
642
+ branchId: string;
643
+ /** Sequence numbers assigned to the staged change events (addBlock). */
644
+ seqs: number[];
645
+ /** Always true: the block is staged in the customizer draft, not yet live. */
646
+ staged: boolean;
647
+ }
648
+ /** Customizer Layout section of a Carousel. */
649
+ export interface PortalCarouselLayoutContract {
650
+ /** Customizer Width. Default: 6. */
651
+ colspan?: 2 | 3 | 4 | 5 | 6;
652
+ /**
653
+ * Customizer Height: null = Auto; a manual value is at least 50px. Default: null.
654
+ * @minimum 50
655
+ */
656
+ height?: number | null;
657
+ }
658
+ /**
659
+ * One Carousel slide. The image is always a built-in one, and the index comes
660
+ * from the array order: neither is accepted from the caller.
661
+ */
662
+ export interface PortalCarouselItemContract {
663
+ /**
664
+ * Plain text; the caption supports no dynamic variables.
665
+ * @minLength 1
666
+ */
667
+ caption?: string;
668
+ /**
669
+ * Plain text. Only `{{ClientName}}` and `{{ClientLastName}}` are variables.
670
+ * @minLength 1
671
+ */
672
+ description?: string;
673
+ /** `null` or omitted leaves the slide without a Button. */
674
+ button?: {
675
+ /**
676
+ * Plain label; the Button supports no dynamic variables.
677
+ * @minLength 1
678
+ */
679
+ text: string;
680
+ } | null;
681
+ /**
682
+ * Destination of both the slide surface and its Button. `null` or omitted
683
+ * leaves the slide without a link.
684
+ */
685
+ destination?: PortalCardDestinationContract | null;
686
+ }
687
+ /** Customizer Content section of a Carousel. */
688
+ export interface PortalCarouselContentContract {
689
+ /**
690
+ * The full desired slide list in visual order, not a patch. Omitting it keeps
691
+ * the three factory slides (Deliberation, Elaboration, Presentation).
692
+ * Server-side limits: 1 to 6 slides.
693
+ */
694
+ items?: PortalCarouselItemContract[];
695
+ }
696
+ export interface AddPortalCarouselBlockRequestContract {
697
+ content?: PortalCarouselContentContract;
698
+ /** Default: width 6 columns and automatic height. */
699
+ layout?: PortalCarouselLayoutContract;
700
+ }
701
+ export interface AddPortalCarouselBlockResponseContract {
702
+ /** Id of the created block. */
703
+ blockId: string;
704
+ /** Id of the page the block was added to. */
705
+ pageId: string;
706
+ /** Draft branch the change was staged on. */
707
+ branchId: string;
708
+ /** Sequence numbers assigned to the staged change events (addBlock). */
709
+ seqs: number[];
710
+ /** Always true: the block is staged in the customizer draft, not yet live. */
711
+ staged: boolean;
712
+ }
713
+ /**
714
+ * Customizer Appearance section of a Countdown. Omitting `appearance` keeps the
715
+ * Countdown's canonical `blank` backdrop with the block title shown.
716
+ */
717
+ export type PortalCountdownAppearanceContract = {
718
+ backdrop: "none" | "blank";
719
+ } | {
720
+ backdrop: "custom";
721
+ background: PortalCardBackgroundContract;
722
+ /** Default: `s`. */
723
+ padding?: "none" | "s" | "m" | "l";
724
+ /** Default: true. */
725
+ showTitle?: boolean;
726
+ };
727
+ /** Customizer Layout section of a Countdown. */
728
+ export interface PortalCountdownLayoutContract {
729
+ /** Customizer Width. Default: 6. */
730
+ colspan?: 2 | 3 | 4 | 5 | 6;
731
+ /**
732
+ * Customizer Height: null = Auto; a manual value is at least 50px. Default: null.
733
+ * @minimum 50
734
+ */
735
+ height?: number | null;
736
+ }
737
+ /** Customizer Content section of a Countdown. */
738
+ export interface PortalCountdownContentContract {
739
+ /**
740
+ * The moment the countdown ends, as an absolute RFC 3339 date-time carrying
741
+ * `Z` or an explicit UTC offset, for example `2026-08-15T09:00:00+07:00`.
742
+ * Never epoch seconds/milliseconds and never a timezone-less local date.
743
+ * Default: 30 days after creation. Server-side limits: not in the past and at
744
+ * most 99 days after creation.
745
+ * @format date-time
746
+ */
747
+ targetAt?: string;
748
+ }
749
+ export interface AddPortalCountdownBlockRequestContract {
750
+ /**
751
+ * Block title shown above the countdown. Plain text; only `{{ClientName}}`
752
+ * and `{{ClientLastName}}` are variables. Default: `Countdown`.
753
+ * @minLength 1
754
+ * @maxLength 100
755
+ */
756
+ title?: string;
757
+ content?: PortalCountdownContentContract;
758
+ /** Omitted keeps the canonical blank backdrop with the title shown. */
759
+ appearance?: PortalCountdownAppearanceContract;
760
+ /** Default: width 6 columns and automatic height. */
761
+ layout?: PortalCountdownLayoutContract;
762
+ }
763
+ export interface AddPortalCountdownBlockResponseContract {
764
+ /** Id of the created block. */
765
+ blockId: string;
766
+ /** Id of the page the block was added to. */
767
+ pageId: string;
768
+ /** Draft branch the change was staged on. */
769
+ branchId: string;
770
+ /** Sequence numbers assigned to the staged change events (addBlock). */
771
+ seqs: number[];
772
+ /** Always true: the block is staged in the customizer draft, not yet live. */
773
+ staged: boolean;
774
+ }
775
+ /** One block a Linked block may point at. */
776
+ export interface PortalLinkableBlockContract {
777
+ /** Exact id to send as `source.blockId`. Never invent one. */
778
+ blockId: string;
779
+ /** Canonical portal block type, e.g. `flexible`. */
780
+ type: string;
781
+ /** Flexible template behind the block (e.g. `info-card`); null for other types. */
782
+ templateType: string | null;
783
+ /** Block title as shown in the customizer. */
784
+ title: string;
785
+ /**
786
+ * The block exists only in this portal's customizer draft. Such a block can
787
+ * be linked only from a page in the SAME portal.
788
+ */
789
+ draftOnly: boolean;
790
+ }
791
+ export interface ListPortalLinkableBlocksResponseContract {
792
+ /** Blocks of the page in display order; Linked blocks are excluded. */
793
+ blocks: PortalLinkableBlockContract[];
794
+ }
795
+ /** Exact identity of the block the Linked block mirrors. */
796
+ export interface PortalLinkedBlockSourceContract {
797
+ /** Portal holding the source block. Must be in the same organization. */
798
+ portalId: string;
799
+ /** Page holding the source block, from listPortalContent. */
800
+ pageId: string;
801
+ /** Exact block id from listPortalLinkableBlocks. Never invent one. */
802
+ blockId: string;
803
+ }
804
+ export interface AddPortalLinkedBlockRequestContract {
805
+ source: PortalLinkedBlockSourceContract;
806
+ }
807
+ export interface AddPortalLinkedBlockResponseContract {
808
+ /** Id of the created Linked block. */
809
+ blockId: string;
810
+ /** Id of the page the block was added to. */
811
+ pageId: string;
812
+ /** Draft branch the change was staged on. */
813
+ branchId: string;
814
+ /** Sequence numbers assigned to the staged change events (addBlock). */
815
+ seqs: number[];
816
+ /** Always true: the block is staged in the customizer draft, not yet live. */
817
+ staged: boolean;
818
+ }
819
+ /**
820
+ * Customizer Appearance section of a Form. Omitting `appearance` keeps the
821
+ * Form's canonical `blank` backdrop with the block title shown.
822
+ */
823
+ export type PortalFormAppearanceContract = {
824
+ backdrop: "none" | "blank";
825
+ } | {
826
+ backdrop: "custom";
827
+ background: PortalCardBackgroundContract;
828
+ /** Default: `s`. */
829
+ padding?: "none" | "s" | "m" | "l";
830
+ /** Default: true. */
831
+ showTitle?: boolean;
832
+ };
833
+ /** Customizer Layout section of a Form. */
834
+ export interface PortalFormLayoutContract {
835
+ /** Customizer Width. Default: 6. */
836
+ colspan?: 2 | 3 | 4 | 5 | 6;
837
+ /**
838
+ * Customizer Height: null = Auto; a manual value is at least 50px. Default: null.
839
+ * @minimum 50
840
+ */
841
+ height?: number | null;
842
+ }
843
+ export type PortalFormDescriptionContract = {
844
+ visible: false;
845
+ } | {
846
+ /** Default: true. */
847
+ visible?: true;
848
+ /**
849
+ * Plain text. Only `{{ClientName}}` and `{{ClientLastName}}` are variables.
850
+ * @minLength 1
851
+ * @maxLength 2000
852
+ */
853
+ text?: string;
854
+ /** @pattern ^(transparent|white|black|(slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(50|100|200|300|400|500|600|700|800|900|950))$ */
855
+ color?: PortalColorToken;
856
+ /** Default: `m`. */
857
+ size?: PortalTextSize;
858
+ /** Set semantics: a duplicate value is rejected with 400. */
859
+ styles?: PortalTextStyle[];
860
+ align?: PortalTextAlign;
861
+ };
862
+ /** The nine field types the Customizer's "Add field" menu offers. */
863
+ export type PortalFormFieldTypeContract = "text" | "textarea" | "number" | "phone" | "email" | "checkbox" | "select" | "file" | "date";
864
+ /** Customizer Field width. The persisted column count is internal. */
865
+ export type PortalFormFieldWidthContract = "half" | "full";
866
+ /** One Form field. Its id, index and persisted column count are server-owned. */
867
+ export interface PortalFormFieldContract {
868
+ type: PortalFormFieldTypeContract;
869
+ /**
870
+ * Customizer "Field name". Plain text, no dynamic variables. Default: the
871
+ * field type's own label, e.g. `Email Address` for `email`.
872
+ * @minLength 1
873
+ * @maxLength 200
874
+ */
875
+ label?: string;
876
+ /**
877
+ * Available only for `text`, `textarea`, `number`, `phone`, `email` and
878
+ * `select` — the Customizer shows no placeholder control for the other three.
879
+ * Plain text, no dynamic variables. Empty clears the Customizer's input.
880
+ * @maxLength 500
881
+ */
882
+ placeholder?: string;
883
+ /** Customizer "Required field". Default: false. */
884
+ required?: boolean;
885
+ /** Default: the field type's own width, e.g. `half` for `select` and `date`. */
886
+ width?: PortalFormFieldWidthContract;
887
+ /**
888
+ * `select` only, one entry per option. Never the persisted newline-separated
889
+ * string. Default: `["Option 1", "Option 2", "Option 3"]`.
890
+ */
891
+ options?: string[];
892
+ }
893
+ export type PortalFormSubmitContract = {
894
+ visible: false;
895
+ } | {
896
+ /** Default: true. */
897
+ visible?: true;
898
+ /**
899
+ * Customizer "Button text". Plain text, no dynamic variables.
900
+ * @minLength 1
901
+ * @maxLength 100
902
+ */
903
+ text?: string;
904
+ };
905
+ export type PortalFormContentBrickContract = {
906
+ visible: false;
907
+ } | {
908
+ /** Default: true. */
909
+ visible?: true;
910
+ /**
911
+ * The complete visual-order list. Omitted keeps the five default fields;
912
+ * `[]` creates a Form without fields.
913
+ */
914
+ fields?: PortalFormFieldContract[];
915
+ submit?: PortalFormSubmitContract;
916
+ /**
917
+ * Customizer "Reusable form": true lets the same portal user submit again,
918
+ * false leaves the form disabled after its first response. Default: true.
919
+ */
920
+ reusable?: boolean;
921
+ };
922
+ /** Customizer Content section of a Form. */
923
+ export interface PortalFormBlockContentContract {
924
+ /** Default: the Customizer's Form copy. */
925
+ description?: PortalFormDescriptionContract;
926
+ form?: PortalFormContentBrickContract;
927
+ }
928
+ export interface AddPortalFormBlockRequestContract {
929
+ /**
930
+ * Block title shown above the form. Plain text; only `{{ClientName}}` and
931
+ * `{{ClientLastName}}` are variables. Default: `Form`.
932
+ * @minLength 1
933
+ * @maxLength 100
934
+ */
935
+ title?: string;
936
+ content?: PortalFormBlockContentContract;
937
+ /** Omitted keeps the canonical blank backdrop with the title shown. */
938
+ appearance?: PortalFormAppearanceContract;
939
+ /** Default: width 6 columns and automatic height. */
940
+ layout?: PortalFormLayoutContract;
941
+ }
942
+ export interface AddPortalFormBlockResponseContract {
943
+ /** Id of the created block. */
944
+ blockId: string;
945
+ /** Id of the page the block was added to. */
946
+ pageId: string;
947
+ /** Draft branch the change was staged on. */
948
+ branchId: string;
949
+ /** Sequence numbers assigned to the staged change events (addBlock). */
950
+ seqs: number[];
951
+ /** Always true: the block is staged in the customizer draft, not yet live. */
952
+ staged: boolean;
953
+ }
954
+ /** The four built-in tile images of the Customizer's Card group. */
955
+ export type PortalCardGroupImageContract = "calendar" | "book" | "pen" | "briefcase";
956
+ /** One card of a Card group. */
957
+ export interface PortalCardGroupItemContract {
958
+ /**
959
+ * Caption under the image. Plain text; dynamic variables are not supported.
960
+ * @minLength 1
961
+ * @maxLength 100
962
+ */
963
+ title: string;
964
+ /** Default: the template image of this position. */
965
+ image?: PortalCardGroupImageContract;
966
+ /**
967
+ * Omitted keeps the template link of this position; `null` leaves the card
968
+ * without any link.
969
+ */
970
+ destination?: PortalCardDestinationContract | null;
971
+ }
972
+ /** Customizer Content section of a Card group. */
973
+ export interface PortalCardGroupContentContract {
974
+ /** Default: the Customizer's Card group copy. */
975
+ description?: PortalCardDescriptionContract;
976
+ /**
977
+ * The cards: between 1 and 6, the same range the Customizer allows. The count
978
+ * is enforced by portal-service — the schema generator drops `@minItems` /
979
+ * `@maxItems`, so declaring them here would read as shipped and be inert.
980
+ */
981
+ items?: PortalCardGroupItemContract[];
982
+ }
983
+ /**
984
+ * Customizer Appearance section of a Card group. Omitting `appearance` keeps the
985
+ * Card group's canonical `blank` wrapper, with the title shown. Separate from the
986
+ * Card's contract: a `$ref` would publish the Card's opposite defaults.
987
+ */
988
+ export type PortalCardGroupAppearanceContract = {
989
+ backdrop: "none" | "blank";
990
+ } | {
991
+ backdrop: "custom";
992
+ background: PortalCardBackgroundContract;
993
+ /** Default: `s`. */
994
+ padding?: "none" | "s" | "m" | "l";
995
+ /** Default: true. */
996
+ showTitle?: boolean;
997
+ };
998
+ export interface AddPortalCardGroupBlockRequestContract {
999
+ /**
1000
+ * Wrapper title, shown above the cards. Default: "Card group".
1001
+ * @minLength 1
1002
+ * @maxLength 100
1003
+ */
1004
+ title?: string;
1005
+ content?: PortalCardGroupContentContract;
1006
+ appearance?: PortalCardGroupAppearanceContract;
1007
+ /** Default: width 4 columns and automatic height. */
1008
+ layout?: PortalCardGroupLayoutContract;
1009
+ }
1010
+ /** Customizer Layout section of a Card group. */
1011
+ export interface PortalCardGroupLayoutContract {
1012
+ /** Customizer Width: the control offers 2 to 6 columns. Default: 4. */
1013
+ colspan?: 2 | 3 | 4 | 5 | 6;
1014
+ /**
1015
+ * Customizer Height: null = Auto; a manual value is at least 50px. Default: null.
1016
+ * @minimum 50
1017
+ */
1018
+ height?: number | null;
1019
+ }
1020
+ export interface AddPortalCardGroupBlockResponseContract {
1021
+ /** Id of the created block. */
1022
+ blockId: string;
1023
+ /** Id of the page the block was added to. */
1024
+ pageId: string;
1025
+ /** Draft branch the change was staged on. */
1026
+ branchId: string;
1027
+ /** Sequence numbers assigned to the staged change events (addBlock). */
1028
+ seqs: number[];
1029
+ /** Always true: the block is staged in the customizer draft, not yet live. */
1030
+ staged: boolean;
1031
+ }
1032
+ /**
1033
+ * One entry of the Info block icon catalog. `id` is the only value
1034
+ * addPortalInfoBlock accepts; the renderer's internal IconKey is never exposed.
1035
+ */
1036
+ export interface PortalInfoIconContract {
1037
+ id: string;
1038
+ /** Human-readable name, for showing the choices to the user. */
1039
+ label: string;
1040
+ }
1041
+ export interface SearchPortalInfoBlockIconsResponseContract {
1042
+ items: PortalInfoIconContract[];
1043
+ /**
1044
+ * Total number of matching icons across all pages.
1045
+ * @TJS-type integer
1046
+ */
1047
+ total: number;
1048
+ /** Opaque cursor for the next page; absent when there are no more results. */
1049
+ nextCursor?: string;
1050
+ }
1051
+ /**
1052
+ * The image of an Info block, as one semantic variant. The persisted
1053
+ * `emoji#...`/`icon#...`/`url#...` form is built by portal-service and is never
1054
+ * accepted here.
1055
+ */
1056
+ export type PortalInfoImageContract = {
1057
+ type: "emoji";
1058
+ /** Exactly one visible Unicode emoji, e.g. "🥳". Text and several emoji are rejected. */
1059
+ emoji: string;
1060
+ } | {
1061
+ type: "icon";
1062
+ /** Exact `items[].id` from searchPortalInfoBlockIcons. */
1063
+ iconId: string;
1064
+ } | {
1065
+ type: "custom";
1066
+ /**
1067
+ * Absolute https:// URL of an image the user already has. This operation
1068
+ * uploads nothing; credentials and a `#` fragment are rejected, and so is
1069
+ * a loopback or private host.
1070
+ * @maxLength 2048
1071
+ */
1072
+ url: string;
1073
+ };
1074
+ /** Semantic Destination the whole Info block links to. */
1075
+ export type PortalInfoDestinationContract = {
1076
+ type: "portalPage";
1077
+ /** Exact id of an existing page in the SAME portal. */
1078
+ pageId: string;
1079
+ } | {
1080
+ type: "external";
1081
+ /**
1082
+ * Absolute https:// URL. `javascript:`, `data:`, a protocol-relative URL
1083
+ * and embedded credentials are rejected.
1084
+ * @maxLength 2048
1085
+ */
1086
+ url: string;
1087
+ };
1088
+ /** Customizer Layout section of an Info block. */
1089
+ export interface PortalInfoLayoutContract {
1090
+ /** Customizer Width. Default: 1. */
1091
+ colspan?: 1 | 2 | 3;
1092
+ /**
1093
+ * Customizer Height: null = Auto; a manual value is at least 50px. Default: null.
1094
+ * @minimum 50
1095
+ */
1096
+ height?: number | null;
1097
+ }
1098
+ export interface AddPortalInfoBlockRequestContract {
1099
+ /**
1100
+ * Text shown inside the tile.
1101
+ * @minLength 1
1102
+ * @maxLength 255
1103
+ */
1104
+ title: string;
1105
+ image: PortalInfoImageContract;
1106
+ destination: PortalInfoDestinationContract;
1107
+ /** Whether the destination opens in a new tab. Default: true. */
1108
+ openInNewTab?: boolean;
1109
+ /** Default: width 1 column, one row and automatic height. */
1110
+ layout?: PortalInfoLayoutContract;
1111
+ }
1112
+ export interface AddPortalInfoBlockResponseContract {
1113
+ /** Id of the created block. */
1114
+ blockId: string;
1115
+ /** Id of the page the block was added to. */
1116
+ pageId: string;
1117
+ /** Draft branch the change was staged on. */
1118
+ branchId: string;
1119
+ /** Sequence numbers assigned to the staged change events (addBlock). */
1120
+ seqs: number[];
1121
+ /** Always true: the block is staged in the customizer draft, not yet live. */
1122
+ staged: boolean;
1123
+ }
1124
+ /** Semantic Destination of one Custom widget Link or Button brick. */
1125
+ export type PortalCustomWidgetDestinationContract = {
1126
+ type: "portalPage";
1127
+ /** Exact id of an existing page in the SAME portal. */
1128
+ pageId: string;
1129
+ } | {
1130
+ type: "external";
1131
+ /**
1132
+ * Absolute https:// URL. `javascript:`, `data:`, a protocol-relative URL
1133
+ * and embedded credentials are rejected.
1134
+ * @maxLength 2048
1135
+ */
1136
+ url: string;
1137
+ } | {
1138
+ type: "email";
1139
+ /**
1140
+ * Address only; portal-service adds the `mailto:` scheme.
1141
+ * @maxLength 254
1142
+ */
1143
+ email: string;
1144
+ };
1145
+ /**
1146
+ * One brick of a Custom widget, in the shape the Customizer's "Add block"
1147
+ * palette inserts. The brick image, index and CSS classes are canonical and are
1148
+ * not accepted from the caller.
1149
+ */
1150
+ export type PortalCustomWidgetBrickContract = {
1151
+ type: "heading";
1152
+ /**
1153
+ * Plain text. Only `{{ClientName}}` and `{{ClientLastName}}` are variables.
1154
+ * Default: "Heading".
1155
+ * @minLength 1
1156
+ * @maxLength 100
1157
+ */
1158
+ text?: string;
1159
+ } | {
1160
+ type: "text";
1161
+ /**
1162
+ * Plain text. Only `{{ClientName}}` and `{{ClientLastName}}` are variables.
1163
+ * Default: the Customizer's lorem ipsum paragraph.
1164
+ * @minLength 1
1165
+ * @maxLength 2000
1166
+ */
1167
+ text?: string;
1168
+ } | {
1169
+ /** Always the built-in widget image; no source field is accepted. */
1170
+ type: "image";
1171
+ } | {
1172
+ type: "avatar";
1173
+ /**
1174
+ * Default: "Amelia Wells". The avatar picture is always the built-in one.
1175
+ * No dynamic variables — the avatar is never substituted, so a variable
1176
+ * would be shown to the portal visitor verbatim.
1177
+ * @minLength 1
1178
+ * @maxLength 100
1179
+ */
1180
+ name?: string;
1181
+ /**
1182
+ * Default: "Your Personal Assistant". No dynamic variables.
1183
+ * @minLength 1
1184
+ * @maxLength 200
1185
+ */
1186
+ description?: string;
1187
+ /** Default: `ring`. */
1188
+ style?: "ring" | "square";
1189
+ } | {
1190
+ type: "rating";
1191
+ /**
1192
+ * Filled marks, a whole number 1 to 5. Default: 5. The Customizer's own
1193
+ * control clamps to this range, so 0 is not a reachable state.
1194
+ * @minimum 1
1195
+ * @maximum 5
1196
+ */
1197
+ value?: number;
1198
+ /** Default: `star`. */
1199
+ style?: "star" | "heart";
1200
+ /** Default: true. */
1201
+ colored?: boolean;
1202
+ } | {
1203
+ type: "link";
1204
+ /**
1205
+ * Visible label. An internal page contributes its own title; anything else
1206
+ * defaults to "Custom link". No dynamic variables.
1207
+ * @minLength 1
1208
+ * @maxLength 100
1209
+ */
1210
+ text?: string;
1211
+ destination: PortalCustomWidgetDestinationContract;
1212
+ } | {
1213
+ type: "button";
1214
+ /**
1215
+ * Plain label; the Button supports no dynamic variables. Default: "Explore".
1216
+ * @minLength 1
1217
+ * @maxLength 100
1218
+ */
1219
+ text?: string;
1220
+ /**
1221
+ * Omitted creates the Button unlinked; the user can still add the link in
1222
+ * the Customizer afterwards.
1223
+ */
1224
+ destination?: PortalCustomWidgetDestinationContract;
1225
+ };
1226
+ /** Customizer Content section of a Custom widget. */
1227
+ export interface PortalCustomWidgetContentContract {
1228
+ /**
1229
+ * The full desired brick list in visual order, not a patch. Omitting it keeps
1230
+ * the nine factory bricks of the "Your Consultant" widget. Server-side limit:
1231
+ * at least 1 brick.
1232
+ */
1233
+ bricks?: PortalCustomWidgetBrickContract[];
1234
+ }
1235
+ /**
1236
+ * Customizer Appearance section of a Custom widget. Omitting `appearance` keeps
1237
+ * the widget's canonical `blank` wrapper with the block title shown.
1238
+ */
1239
+ export type PortalCustomWidgetAppearanceContract = {
1240
+ backdrop: "none" | "blank";
1241
+ } | {
1242
+ backdrop: "custom";
1243
+ background: PortalCardBackgroundContract;
1244
+ /** Default: `s`. */
1245
+ padding?: "none" | "s" | "m" | "l";
1246
+ /** Default: true. */
1247
+ showTitle?: boolean;
1248
+ };
1249
+ /** Customizer Layout section of a Custom widget. */
1250
+ export interface PortalCustomWidgetLayoutContract {
1251
+ /** Customizer Width. Default: 2. */
1252
+ colspan?: 2 | 3 | 4 | 5 | 6;
1253
+ /**
1254
+ * Customizer Height: null = Auto; a manual value is at least 50px. Default: null.
1255
+ * @minimum 50
1256
+ */
1257
+ height?: number | null;
1258
+ }
1259
+ export interface AddPortalCustomWidgetBlockRequestContract {
1260
+ /**
1261
+ * Block title, shown by the `blank` and `custom` backdrops.
1262
+ * Default: "Your Consultant".
1263
+ * @minLength 1
1264
+ * @maxLength 100
1265
+ */
1266
+ title?: string;
1267
+ content?: PortalCustomWidgetContentContract;
1268
+ appearance?: PortalCustomWidgetAppearanceContract;
1269
+ /** Default: width 2 columns and automatic height. */
1270
+ layout?: PortalCustomWidgetLayoutContract;
1271
+ }
1272
+ export interface AddPortalCustomWidgetBlockResponseContract {
1273
+ /** Id of the created block. */
1274
+ blockId: string;
1275
+ /** Id of the page the block was added to. */
1276
+ pageId: string;
1277
+ /** Draft branch the change was staged on. */
1278
+ branchId: string;
1279
+ /** Sequence numbers assigned to the staged change events (addBlock). */
1280
+ seqs: number[];
1281
+ /** Always true: the block is staged in the customizer draft, not yet live. */
1282
+ staged: boolean;
1283
+ }
1284
+ /**
1285
+ * Customizer Content section of an HTML/CSS block. Omitting it on the request
1286
+ * creates the Customizer's demo "Sales Distribution" pie chart; sending it
1287
+ * replaces that demo entirely, so an omitted field below is empty rather than
1288
+ * the demo value.
1289
+ */
1290
+ export interface PortalHtmlCssContentContract {
1291
+ /**
1292
+ * Customizer "Edit HTML". Markup only — it is inserted into the block as-is.
1293
+ * Omitted or empty means no markup.
1294
+ * @maxLength 50000
1295
+ */
1296
+ html?: string;
1297
+ /**
1298
+ * Customizer "Edit Style". Raw CSS WITHOUT a `<style>` tag; the portal injects
1299
+ * it globally, so scope the rules with your own class names.
1300
+ * @maxLength 50000
1301
+ */
1302
+ style?: string;
1303
+ /**
1304
+ * Customizer "Edit Script". Raw JavaScript WITHOUT a `<script>` tag, run on
1305
+ * every visit of the published page. Omitted or empty means no script.
1306
+ * @maxLength 50000
1307
+ */
1308
+ script?: string;
1309
+ }
1310
+ /** Customizer Layout section of an HTML/CSS block. Default: width 3, Auto height. */
1311
+ export interface PortalHtmlCssLayoutContract {
1312
+ /** Customizer Width. Default: 3. */
1313
+ colspan?: 2 | 3 | 4 | 5 | 6;
1314
+ /**
1315
+ * Customizer Height: null = Auto; a manual value is at least 50px. Default: null.
1316
+ * @minimum 50
1317
+ */
1318
+ height?: number | null;
1319
+ }
1320
+ export interface AddPortalHtmlCssBlockRequestContract {
1321
+ /**
1322
+ * Block title. The block's wrapper hides it BY DEFAULT, so it normally only
1323
+ * labels the block in the Customizer — but the owner can turn on Appearance
1324
+ * "Show title", and then it is visitor-facing. May contain the dynamic
1325
+ * variables {{ClientName}} and {{ClientLastName}} and no others.
1326
+ * Default: "HTML/CSS Block".
1327
+ * @minLength 1
1328
+ * @maxLength 200
1329
+ */
1330
+ title?: string;
1331
+ content?: PortalHtmlCssContentContract;
1332
+ layout?: PortalHtmlCssLayoutContract;
1333
+ }
1334
+ export interface AddPortalHtmlCssBlockResponseContract {
407
1335
  /** Id of the created block. */
408
1336
  blockId: string;
409
1337
  /** Id of the page the block was added to. */
@@ -415,77 +1343,29 @@ export interface PortalTextAndMediaBlockResponseContract {
415
1343
  /** Always true: the block is staged in the customizer draft, not yet live. */
416
1344
  staged: boolean;
417
1345
  }
1346
+ /** The two Timeline views of the Customizer's Timeline tile. */
1347
+ export type PortalTimelineViewContract = "horizontal" | "vertical";
418
1348
  /**
419
- * Customizer background picker. Colours are palette tokens; an image is one of
420
- * the five built-in presets.
421
- */
422
- export type PortalCardBackgroundContract = {
423
- type: "color";
424
- /** @pattern ^(transparent|white|black|(slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(50|100|200|300|400|500|600|700|800|900|950))$ */
425
- color: PortalColorToken;
426
- } | {
427
- type: "gradient";
428
- /** @pattern ^(transparent|white|black|(slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(50|100|200|300|400|500|600|700|800|900|950))$ */
429
- from: PortalColorToken;
430
- /** @pattern ^(transparent|white|black|(slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(50|100|200|300|400|500|600|700|800|900|950))$ */
431
- to: PortalColorToken;
432
- /** Default: `to-t`. */
433
- direction?: "to-t" | "to-r" | "to-b" | "to-l";
434
- } | {
435
- type: "image";
436
- preset: PortalBackgroundImagePreset;
437
- /** Default: false. */
438
- blur?: boolean;
439
- };
440
- /** The four Card Types of the Customizer's Card tile. `compact` is legacy and rejected. */
441
- export type PortalCardViewContract = "top-image" | "left-image" | "right-image" | "fill-image";
442
- /**
443
- * Customizer Appearance section of a Card. Omitting `appearance` keeps the
444
- * Card's canonical `bare` wrapper, which is not a selectable backdrop.
1349
+ * One step of the Step group. The Customizer keeps completion sequential, so
1350
+ * `completed` steps must form a prefix of the list.
445
1351
  */
446
- export type PortalCardAppearanceContract = {
447
- backdrop: "none" | "blank";
448
- } | {
449
- backdrop: "custom";
450
- background: PortalCardBackgroundContract;
451
- /** Default: `s`. */
452
- padding?: "none" | "s" | "m" | "l";
453
- /** Default: false. */
454
- showTitle?: boolean;
455
- };
456
- /** Customizer Layout section of a Card. */
457
- export interface PortalCardLayoutContract {
458
- /** Customizer Width. Default: 3. */
459
- colspan?: 2 | 3 | 4 | 5 | 6;
1352
+ export interface PortalTimelineStepContract {
460
1353
  /**
461
- * Customizer Height: null = Auto; a manual value is at least 50px. Default: null.
462
- * @minimum 50
1354
+ * Plain text; the step caption supports no dynamic variables. The Customizer
1355
+ * allows an empty caption.
1356
+ * @maxLength 25
463
1357
  */
464
- height?: number | null;
1358
+ title: string;
1359
+ /** Default: false. */
1360
+ completed?: boolean;
1361
+ /** Omitted or `null` both leave the step without a link. */
1362
+ destination?: PortalCardDestinationContract | null;
465
1363
  }
466
1364
  /**
467
- * A hidden Card item carries ONLY `visible: false`: sending text or styles next
468
- * to it would silently drop settings the caller believes they applied.
1365
+ * A hidden Timeline item carries ONLY `visible: false`: sending text or styles
1366
+ * next to it would silently drop settings the caller believes they applied.
469
1367
  */
470
- export type PortalCardHeadingContract = {
471
- visible: false;
472
- } | {
473
- /** Default: true. */
474
- visible?: true;
475
- /**
476
- * Plain text. Only `{{ClientName}}` and `{{ClientLastName}}` are variables.
477
- * @minLength 1
478
- * @maxLength 100
479
- */
480
- text?: string;
481
- /** @pattern ^(transparent|white|black|(slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(50|100|200|300|400|500|600|700|800|900|950))$ */
482
- color?: PortalColorToken;
483
- size?: PortalTextSize;
484
- /** Set semantics: a duplicate value is rejected with 400. */
485
- styles?: PortalTextStyle[];
486
- align?: PortalTextAlign;
487
- };
488
- export type PortalCardDescriptionContract = {
1368
+ export type PortalTimelineDescriptionContract = {
489
1369
  visible: false;
490
1370
  } | {
491
1371
  /** Default: true. */
@@ -503,7 +1383,7 @@ export type PortalCardDescriptionContract = {
503
1383
  styles?: PortalTextStyle[];
504
1384
  align?: PortalTextAlign;
505
1385
  };
506
- export type PortalCardButtonContract = {
1386
+ export type PortalTimelineButtonContract = {
507
1387
  visible: false;
508
1388
  } | {
509
1389
  /** Default: true. */
@@ -514,71 +1394,52 @@ export type PortalCardButtonContract = {
514
1394
  * @maxLength 100
515
1395
  */
516
1396
  text?: string;
1397
+ /**
1398
+ * Omitted keeps the Customizer's own Project link; `null` leaves the
1399
+ * Button without any destination.
1400
+ */
1401
+ destination?: PortalCardDestinationContract | null;
517
1402
  };
518
- /** The Card always uses the template image: no source field is accepted. */
519
- export interface PortalCardImageContract {
1403
+ /** The Timeline always uses the built-in image: no source field is accepted. */
1404
+ export interface PortalTimelineImageContract {
520
1405
  /** Default: true. */
521
1406
  visible?: boolean;
522
1407
  }
523
- /** Semantic Destination of the whole Card (and of its Button). */
524
- export type PortalCardDestinationContract = {
525
- type: "portalPage";
526
- /** Exact id of an existing page in the SAME portal. */
527
- pageId: string;
528
- } | {
529
- type: "external";
1408
+ /** Customizer Content section of a Timeline. */
1409
+ export interface PortalTimelineContentContract {
1410
+ image?: PortalTimelineImageContract;
1411
+ /** Default: the Customizer's Timeline copy. */
1412
+ description?: PortalTimelineDescriptionContract;
530
1413
  /**
531
- * Absolute https:// URL. `javascript:`, `data:`, a protocol-relative URL
532
- * and embedded credentials are rejected.
533
- * @maxLength 2048
1414
+ * The FULL desired step list in visual order, not a patch. Omitted keeps the
1415
+ * three factory steps (Vision and Arrangements completed, Launch not).
1416
+ *
1417
+ * The generator drops both tags today (NIM-42761 tracks the same gap for
1418
+ * `@uniqueItems`), so the 1..6 bound is ENFORCED by portal-service and stated
1419
+ * in this op's description and MCP prompt.
1420
+ * @minItems 1
1421
+ * @maxItems 6
534
1422
  */
535
- url: string;
1423
+ steps?: PortalTimelineStepContract[];
1424
+ /** Default: "View project" linking to the Customizer's Project page. */
1425
+ button?: PortalTimelineButtonContract;
1426
+ }
1427
+ /**
1428
+ * Customizer Appearance section of a Timeline. Omitting `appearance` keeps the
1429
+ * factory `blank` wrapper with the block title shown.
1430
+ */
1431
+ export type PortalTimelineAppearanceContract = {
1432
+ backdrop: "none" | "blank";
536
1433
  } | {
537
- type: "email";
538
- /**
539
- * Address only; portal-service adds the `mailto:` scheme.
540
- * @maxLength 254
541
- */
542
- email: string;
1434
+ backdrop: "custom";
1435
+ background: PortalCardBackgroundContract;
1436
+ /** Default: `s`. */
1437
+ padding?: "none" | "s" | "m" | "l";
1438
+ /** Default: true. */
1439
+ showTitle?: boolean;
543
1440
  };
544
- /** Customizer Content section of a Card. */
545
- export interface PortalCardContentContract {
546
- image?: PortalCardImageContract;
547
- /** Default: "Helpful Resources", bold. */
548
- heading?: PortalCardHeadingContract;
549
- /** Default: the Customizer's Card copy. */
550
- description?: PortalCardDescriptionContract;
551
- /** Default: "Explore". */
552
- button?: PortalCardButtonContract;
553
- /**
554
- * Omitted keeps the Customizer default link; `null` leaves the Card without
555
- * any destination.
556
- */
557
- destination?: PortalCardDestinationContract | null;
558
- }
559
- export interface AddPortalCardBlockRequestContract {
560
- /** Card Type. Default: `top-image`. */
561
- view?: PortalCardViewContract;
562
- content?: PortalCardContentContract;
563
- /** Omitted keeps the Card's canonical bare wrapper. */
564
- appearance?: PortalCardAppearanceContract;
565
- /** Default: width 3 columns and automatic height. */
566
- layout?: PortalCardLayoutContract;
567
- }
568
- export interface AddPortalCardBlockResponseContract {
569
- /** Id of the created block. */
570
- blockId: string;
571
- /** Id of the page the block was added to. */
572
- pageId: string;
573
- /** Draft branch the change was staged on. */
574
- branchId: string;
575
- /** Sequence numbers assigned to the staged change events (addBlock). */
576
- seqs: number[];
577
- /** Always true: the block is staged in the customizer draft, not yet live. */
578
- staged: boolean;
579
- }
580
- /** Customizer Layout section of a Carousel. */
581
- export interface PortalCarouselLayoutContract {
1441
+ /** Customizer Layout section of a Timeline. */
1442
+ export interface PortalTimelineLayoutContract {
582
1443
  /** Customizer Width. Default: 6. */
583
1444
  colspan?: 2 | 3 | 4 | 5 | 6;
584
1445
  /**
@@ -587,50 +1448,23 @@ export interface PortalCarouselLayoutContract {
587
1448
  */
588
1449
  height?: number | null;
589
1450
  }
590
- /**
591
- * One Carousel slide. The image is always a built-in one, and the index comes
592
- * from the array order: neither is accepted from the caller.
593
- */
594
- export interface PortalCarouselItemContract {
595
- /**
596
- * Plain text; the caption supports no dynamic variables.
597
- * @minLength 1
598
- */
599
- caption?: string;
1451
+ export interface AddPortalTimelineBlockRequestContract {
1452
+ /** Timeline view. Default: `horizontal`. */
1453
+ view?: PortalTimelineViewContract;
600
1454
  /**
601
- * Plain text. Only `{{ClientName}}` and `{{ClientLastName}}` are variables.
1455
+ * Wrapper title. Plain text; only `{{ClientName}}` and `{{ClientLastName}}`
1456
+ * are variables. Default: `Timeline`.
602
1457
  * @minLength 1
1458
+ * @maxLength 100
603
1459
  */
604
- description?: string;
605
- /** `null` or omitted leaves the slide without a Button. */
606
- button?: {
607
- /**
608
- * Plain label; the Button supports no dynamic variables.
609
- * @minLength 1
610
- */
611
- text: string;
612
- } | null;
613
- /**
614
- * Destination of both the slide surface and its Button. `null` or omitted
615
- * leaves the slide without a link.
616
- */
617
- destination?: PortalCardDestinationContract | null;
618
- }
619
- /** Customizer Content section of a Carousel. */
620
- export interface PortalCarouselContentContract {
621
- /**
622
- * The full desired slide list in visual order, not a patch. Omitting it keeps
623
- * the three factory slides (Deliberation, Elaboration, Presentation).
624
- * Server-side limits: 1 to 6 slides.
625
- */
626
- items?: PortalCarouselItemContract[];
627
- }
628
- export interface AddPortalCarouselBlockRequestContract {
629
- content?: PortalCarouselContentContract;
1460
+ title?: string;
1461
+ content?: PortalTimelineContentContract;
1462
+ /** Omitted keeps the canonical blank backdrop with the title shown. */
1463
+ appearance?: PortalTimelineAppearanceContract;
630
1464
  /** Default: width 6 columns and automatic height. */
631
- layout?: PortalCarouselLayoutContract;
1465
+ layout?: PortalTimelineLayoutContract;
632
1466
  }
633
- export interface AddPortalCarouselBlockResponseContract {
1467
+ export interface AddPortalTimelineBlockResponseContract {
634
1468
  /** Id of the created block. */
635
1469
  blockId: string;
636
1470
  /** Id of the page the block was added to. */
@@ -642,57 +1476,37 @@ export interface AddPortalCarouselBlockResponseContract {
642
1476
  /** Always true: the block is staged in the customizer draft, not yet live. */
643
1477
  staged: boolean;
644
1478
  }
645
- /**
646
- * Customizer Appearance section of a Countdown. Omitting `appearance` keeps the
647
- * Countdown's canonical `blank` backdrop with the block title shown.
648
- */
649
- export type PortalCountdownAppearanceContract = {
650
- backdrop: "none" | "blank";
651
- } | {
652
- backdrop: "custom";
653
- background: PortalCardBackgroundContract;
654
- /** Default: `s`. */
655
- padding?: "none" | "s" | "m" | "l";
656
- /** Default: true. */
657
- showTitle?: boolean;
658
- };
659
- /** Customizer Layout section of a Countdown. */
660
- export interface PortalCountdownLayoutContract {
661
- /** Customizer Width. Default: 6. */
662
- colspan?: 2 | 3 | 4 | 5 | 6;
1479
+ /** Customizer Layout section of a File uploader. */
1480
+ export interface PortalFileUploaderLayoutContract {
1481
+ /** Customizer Width. Default: 3. */
1482
+ colspan?: 3 | 4 | 6;
663
1483
  /**
664
1484
  * Customizer Height: null = Auto; a manual value is at least 50px. Default: null.
665
1485
  * @minimum 50
666
1486
  */
667
1487
  height?: number | null;
668
1488
  }
669
- /** Customizer Content section of a Countdown. */
670
- export interface PortalCountdownContentContract {
671
- /**
672
- * The moment the countdown ends, as an absolute RFC 3339 date-time carrying
673
- * `Z` or an explicit UTC offset, for example `2026-08-15T09:00:00+07:00`.
674
- * Never epoch seconds/milliseconds and never a timezone-less local date.
675
- * Default: 30 days after creation. Server-side limits: not in the past and at
676
- * most 99 days after creation.
677
- * @format date-time
678
- */
679
- targetAt?: string;
680
- }
681
- export interface AddPortalCountdownBlockRequestContract {
1489
+ export interface AddPortalFileUploaderBlockRequestContract {
682
1490
  /**
683
- * Block title shown above the countdown. Plain text; only `{{ClientName}}`
684
- * and `{{ClientLastName}}` are variables. Default: `Countdown`.
1491
+ * Block title rendered above the file list. Plain text — the screen has no
1492
+ * dynamic-variable control. Default: `File uploader`.
685
1493
  * @minLength 1
686
1494
  * @maxLength 100
687
1495
  */
688
1496
  title?: string;
689
- content?: PortalCountdownContentContract;
690
- /** Omitted keeps the canonical blank backdrop with the title shown. */
691
- appearance?: PortalCountdownAppearanceContract;
692
- /** Default: width 6 columns and automatic height. */
693
- layout?: PortalCountdownLayoutContract;
1497
+ /**
1498
+ * Short plain-text hint under the title. Default: empty.
1499
+ * @maxLength 50
1500
+ */
1501
+ description?: string;
1502
+ /** Show the uploader's Author column. Default: false. */
1503
+ showAuthor?: boolean;
1504
+ /** Show the Upload date column. Default: false. */
1505
+ showUploadDate?: boolean;
1506
+ /** Default: width 3 columns and automatic height. */
1507
+ layout?: PortalFileUploaderLayoutContract;
694
1508
  }
695
- export interface AddPortalCountdownBlockResponseContract {
1509
+ export interface AddPortalFileUploaderBlockResponseContract {
696
1510
  /** Id of the created block. */
697
1511
  blockId: string;
698
1512
  /** Id of the page the block was added to. */
@@ -842,7 +1656,7 @@ export interface ListPortalChatUsersResponseContract {
842
1656
  * Any other value is rejected with 400 (the reducer throws on unknown types,
843
1657
  * which would otherwise fail the whole draft at publish time).
844
1658
  */
845
- export type PortalBlockType = "note" | "content" | "info" | "docs" | "help" | "request" | "meetings" | "links" | "task-list" | "projection" | "files-dashboard" | "tasks-dashboard" | "chats-dashboard" | "files-recent" | "files-bucket" | "flexible";
1659
+ export type PortalBlockType = "note" | "content" | "docs" | "help" | "request" | "meetings" | "links" | "files-dashboard" | "tasks-dashboard" | "chats-dashboard" | "files-recent" | "flexible";
846
1660
  export interface AddPortalBlockRequestContract {
847
1661
  /** Id of the existing portal page node to add the block to. */
848
1662
  pageId: string;
@@ -861,9 +1675,9 @@ export interface AddPortalBlockRequestContract {
861
1675
  bricks?: unknown[];
862
1676
  /**
863
1677
  * Optional type-specific fields for the staged block, e.g. flat strings
864
- * `image`/`link` for info,
865
- * `sourcePortalId`/`sourcePageId`/`sourceBlockId` for projection,
866
- * `taskListIds` for task-list. Also overrides scaffold defaults (colspan,
1678
+ * `image`/`link` for docs/help/request/meetings/links,
1679
+ * `sourcePortalId`/`sourcePageId`/`sourceBlockId` for projection.
1680
+ * Also overrides scaffold defaults (colspan,
867
1681
  * rowspan, …) when provided. Every field is validated against the block's
868
1682
  * real customizer shape — an unknown field or a wrong-typed value (e.g. an
869
1683
  * object where a flat string is expected) is rejected with 400.
@@ -983,8 +1797,10 @@ export interface AddPortalAppBlockResponseContract {
983
1797
  }
984
1798
  export interface UpdatePortalCustomCodeRequestContract {
985
1799
  /**
986
- * Custom CSS applied to every published portal page (portal-service
987
- * `customStyle`). Pass an empty string to clear it.
1800
+ * Custom CSS for the portal (portal-service `customStyle`). Gate nests it under
1801
+ * the portal's root container `#main-scrolling-container` so styles stay inside
1802
+ * the portal zone and do not leak into the customizer UI. Scope selectors
1803
+ * accordingly and avoid `body`/`html`/`:root`. Pass an empty string to clear it.
988
1804
  */
989
1805
  css?: string;
990
1806
  /**
@@ -1260,3 +2076,60 @@ export declare const PortalCountdownAppearanceContract: {
1260
2076
  readonly Blank: "blank";
1261
2077
  readonly Custom: "custom";
1262
2078
  };
2079
+ export declare const PortalFormAppearanceContract: {
2080
+ readonly None: "none";
2081
+ readonly Blank: "blank";
2082
+ readonly Custom: "custom";
2083
+ };
2084
+ export declare const PortalFormFieldTypeContract: {
2085
+ readonly Text: "text";
2086
+ readonly Textarea: "textarea";
2087
+ readonly Number: "number";
2088
+ readonly Phone: "phone";
2089
+ readonly Email: "email";
2090
+ readonly Checkbox: "checkbox";
2091
+ readonly Select: "select";
2092
+ readonly File: "file";
2093
+ readonly Date: "date";
2094
+ };
2095
+ export declare const PortalFormFieldWidthContract: {
2096
+ readonly Half: "half";
2097
+ readonly Full: "full";
2098
+ };
2099
+ export declare const PortalCardGroupImageContract: {
2100
+ readonly Calendar: "calendar";
2101
+ readonly Book: "book";
2102
+ readonly Pen: "pen";
2103
+ readonly Briefcase: "briefcase";
2104
+ };
2105
+ export declare const PortalCardGroupAppearanceContract: {
2106
+ readonly None: "none";
2107
+ readonly Blank: "blank";
2108
+ readonly Custom: "custom";
2109
+ };
2110
+ export declare const PortalInfoImageContract: {
2111
+ readonly Emoji: "emoji";
2112
+ };
2113
+ export declare const PortalInfoDestinationContract: {
2114
+ readonly Portalpage: "portalPage";
2115
+ };
2116
+ export declare const PortalCustomWidgetDestinationContract: {
2117
+ readonly Portalpage: "portalPage";
2118
+ };
2119
+ export declare const PortalCustomWidgetBrickContract: {
2120
+ readonly Heading: "heading";
2121
+ };
2122
+ export declare const PortalCustomWidgetAppearanceContract: {
2123
+ readonly None: "none";
2124
+ readonly Blank: "blank";
2125
+ readonly Custom: "custom";
2126
+ };
2127
+ export declare const PortalTimelineViewContract: {
2128
+ readonly Horizontal: "horizontal";
2129
+ readonly Vertical: "vertical";
2130
+ };
2131
+ export declare const PortalTimelineAppearanceContract: {
2132
+ readonly None: "none";
2133
+ readonly Blank: "blank";
2134
+ readonly Custom: "custom";
2135
+ };