@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.
@@ -73,7 +73,7 @@ class PortalsApi {
73
73
  }
74
74
  /**
75
75
  * Add a block of any palette type to a portal page
76
- * Stages a single block of any supported type onto an existing portal page — the universal building block behind the customizer's 'Add new block' palette (no new page or sidebar item is created). Pass pageId (the target page node id from listPortalContent) and type. Supported types: note, content, info, docs, help, request, meetings, links, task-list, projection, files-dashboard, tasks-dashboard, chats-dashboard, files-recent, files-bucket, flexible. Type-specific fields: note/content require noteId; flexible requires template (e.g. {type:'text'|'image'|'title'|'code'|'form'|'dashboard'|'app-feature'|...}) and may carry bricks; info/projection/task-list and others take their fields via the free-form `properties` object (e.g. image/link, sourcePortalId/sourcePageId/sourceBlockId, taskListIds). This op does NOT accept type='embed', a flexible block with template.type='dashboard' or a dashboard brick (use addPortalDatabaseBlock) or type='chat' — use addPortalEmbedBlock for Embed blocks and addPortalChatBlock for Chat blocks — and it does NOT accept a flexible ai-agent template or an ai-agent brick: use addPortalAiAgentBlock, which binds the agent to the caller. Use addPortalNoteBlock for the common note case or addPortalAppPage for an app on its own page. Note: a `content` block renames the page to its title, so leave title empty for content blocks. The block is staged in the portal's customizer draft (not published immediately); the owner reviews and publishes it. Returns the block id and the draft branch/seqs. Requires portals.write access.
76
+ * Stages a single block of any supported type onto an existing portal page — the universal building block behind the customizer's 'Add new block' palette (no new page or sidebar item is created). Pass pageId (the target page node id from listPortalContent) and type. Supported types: note, content, docs, help, request, meetings, links, files-dashboard, tasks-dashboard, chats-dashboard, files-recent, flexible. Type-specific fields: note/content require noteId; flexible requires template (e.g. {type:'text'|'image'|'title'|'dashboard'|'app-feature'|...}) and may carry bricks; the link cards (docs/help/request/meetings/links) and others take their fields via the free-form `properties` object (e.g. image/link). It does NOT accept type='projection' — use addPortalLinkedBlock for a Linked block. This op does NOT accept type='embed', a flexible block with template.type='timeline' or a timeline brick (use addPortalTimelineBlock), a flexible block with template.type='dashboard' or a dashboard brick (use addPortalDatabaseBlock) or type='chat' — use addPortalEmbedBlock for Embed blocks and addPortalChatBlock for Chat blocks. It also does NOT accept type='files-bucket': use addPortalFileUploaderBlock for File uploader blocks. It does NOT accept a flexible ai-agent template or an ai-agent brick: use addPortalAiAgentBlock, which binds the agent to the caller. It does NOT accept a flexible `form` template or a `form` brick either: use addPortalFormBlock, which owns the canonical Form block and its fields. It does NOT accept type='info': use addPortalInfoBlock, which owns the canonical Info block, its icon catalog and its destination resolution. It does NOT accept type='task-list' or a note/content block with properties.templateKey='task-list': use addPortalTaskListBlock, which creates the note and its task list. Use addPortalNoteBlock for the common note case or addPortalAppPage for an app on its own page. Note: a `content` block renames the page to its title, so leave title empty for content blocks. The block is staged in the portal's customizer draft (not published immediately); the owner reviews and publishes it. Returns the block id and the draft branch/seqs. Requires portals.write access.
77
77
  */
78
78
  async addPortalBlock(params) {
79
79
  return this.client.request({
@@ -101,6 +101,21 @@ class PortalsApi {
101
101
  expectedContentType: "application/json",
102
102
  });
103
103
  }
104
+ /**
105
+ * Add a Card group block to a portal page
106
+ * Stages one Customizer-compatible Card group on an EXISTING portal page — the programmatic equivalent of the customizer's Content display "Card group" tile, a row of small linked cards. It creates exactly one flexible block with a Description brick and the cards; no page, sidebar item or media asset is created. `content.items` holds 1 to 6 cards, each with a `title` (the caption, plain text without dynamic variables), an optional `image` naming one of the four built-in tile images (`calendar`, `book`, `pen`, `briefcase` — an url, upload, asset id or local path is rejected) and an optional `destination`: an exact `pageId` of a page in THIS portal, an absolute https URL or an email address; omitting it keeps the template link of that card position and an explicit `null` leaves the card without a link. Omitting `content.items` reproduces the Customizer's four template cards. `content.description` is the text above the cards (`visible: false` hides it, otherwise plain text plus one palette colour token such as `cyan-700`, size `s`/`m`/`l`/`xl`, a unique set of `bold`/`italic`/`underline`/`lineThrough` styles and alignment); `visible` defaults to `true`, so a visible Description does NOT need `visible: true`. `title` is the wrapper title shown above the cards (default "Card group"). `appearance` is optional; omitting it keeps the Card group's canonical blank wrapper, and a `custom` backdrop takes a colour, gradient or one of the five preset background images (`azure`, `mira`, `solis`, `serenity`, `glow`). `layout` sets Customizer Width (2-6, default 4) and Height (Auto by default, a manual value is at least 50px). Per-card colours, the card gap and justification are customizer-only settings and are not accepted here, and neither are HTML, Markdown, CSS, Tailwind classes or raw bricks. The block is staged in the portal's customizer draft (not published immediately). Requires portals.write access.
107
+ */
108
+ async addPortalCardGroupBlock(params) {
109
+ return this.client.request({
110
+ method: "POST",
111
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/card-group",
112
+ pathParams: params.path,
113
+ headers: params.headers,
114
+ body: params.body,
115
+ opId: "addPortalCardGroupBlock",
116
+ expectedContentType: "application/json",
117
+ });
118
+ }
104
119
  /**
105
120
  * Add a Carousel block to a portal page
106
121
  * Stages one Customizer-compatible Carousel on an EXISTING portal page — the programmatic equivalent of the customizer's Content display "Carousel" tile. It creates exactly one flexible block with a single Carousel brick; no page, sidebar item or media asset is created. Omit `content` to get the Customizer default of three slides (Deliberation, Elaboration, Presentation) with their built-in images, descriptions, More buttons and links. `content.items` replaces that list entirely and must hold 1 to 6 slides in visual order; the slide index is taken from the array position and is not accepted from the caller. Each slide takes `caption` and `description` (plain text; only `description` supports the `{{ClientName}}` and `{{ClientLastName}}` variables), `button: {text}` or `null` for no Button, and `destination` or `null` for no link — an exact `pageId` of a page in THIS portal, an absolute https URL or an email address. The slide surface and its Button share that one destination. Every slide image is a built-in one: an image/video URL, asset id, file name, base64, local path or upload is rejected, as are a raw DynamicLink, raw item index, brick, CSS class, autoplay, duration, controls and indicators. Carousel has no public Appearance settings. `layout` sets Customizer Width (2-6, default 6) and Height (Auto by default, a manual value is at least 50px). The block is staged in the portal's customizer draft (not published immediately). Requires portals.write access.
@@ -146,6 +161,21 @@ class PortalsApi {
146
161
  expectedContentType: "application/json",
147
162
  });
148
163
  }
164
+ /**
165
+ * Add a Custom widget block to a portal page
166
+ * Stages one Customizer-compatible Custom widget on an EXISTING portal page — the programmatic equivalent of the customizer's Custom "Custom widget" tile. It creates exactly one flexible block of the `custom` template; no page, sidebar item or media asset is created. Omit `content` to get the Customizer default of the nine "Your Consultant" bricks. `content.bricks` replaces that list entirely and holds the bricks in visual order, each one of the seven kinds the Customizer's "Add block" palette offers: `heading`, `text`, `image`, `avatar`, `rating`, `link` and `button`. A field belonging to another brick kind is rejected rather than dropped. Every image is a built-in one: an image URL, asset id, file name, base64, local path or upload is rejected, as are a raw DynamicLink, a raw brick index, a CSS class and a theme override. A `link` brick needs a `destination`; a `button` brick without one is created unlinked and stays linkable in the Customizer. A destination is an exact `pageId` of a page in THIS portal, an absolute https URL or an email address. `title` and `appearance` set the Customizer Appearance section: omitting `appearance` keeps the widget's canonical `blank` backdrop with the title shown, and `background`, `padding` and `showTitle` apply only to `custom`. `layout` sets Customizer Width (2-6, default 2) and Height (Auto by default, a manual value is at least 50px). The block is staged in the portal's customizer draft (not published immediately). Requires portals.write access.
167
+ */
168
+ async addPortalCustomWidgetBlock(params) {
169
+ return this.client.request({
170
+ method: "POST",
171
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/custom-widget",
172
+ pathParams: params.path,
173
+ headers: params.headers,
174
+ body: params.body,
175
+ opId: "addPortalCustomWidgetBlock",
176
+ expectedContentType: "application/json",
177
+ });
178
+ }
149
179
  /**
150
180
  * Add a Database block to a portal page
151
181
  * Stages one Customizer-compatible Database block on an EXISTING portal page — the programmatic equivalent of the customizer's "Database" tile. It creates exactly one flexible block with a single dashboard brick; no page, sidebar item, database, dashboard or view is created and the selected view's own settings are untouched. Both Customizer types are supported: `database` (Database -> Table -> View) and `dashboard` (a shared source such as All forms -> View). Pass exact ids from listPortalDatabaseBlockSources; names, aliases and URLs are rejected, and the dashboard must belong to `databaseId` in database mode. Optional `title` (default "Database"), `itemsPerPage` (10/20/50/100/200/500, default 100), `appearance` and `layout`. To change whether the view is editable call setDashboardViewReadonly separately — that is a global view setting. The block is staged in the portal's customizer draft (not published immediately). Requires portals.write access.
@@ -176,6 +206,36 @@ class PortalsApi {
176
206
  expectedContentType: "application/json",
177
207
  });
178
208
  }
209
+ /**
210
+ * Add a File uploader block to a portal page
211
+ * Stages one Customizer-compatible File uploader on an EXISTING portal page — the programmatic equivalent of the customizer's File management "File uploader" tile. It creates an EMPTY upload area (internally a `files-bucket` block) that non-visitor portal users can upload files to and manage; no page, sidebar item, bucket or file is created and nothing is uploaded. The body may be empty, which reproduces the Customizer default: the title "File uploader", no description and both file columns hidden. `title` is plain text and `description` is a plain-text hint of at most 50 characters. `showAuthor` and `showUploadDate` add the matching file-list columns; neither changes who may upload — that stays a function of the viewer's portal role. `layout` sets Width (3, 4 or 6, default 3) and Height (Auto by default, a manual value is at least 50px). The screen has no Appearance section, so `appearance`, `rowspan`, upload permissions, bucket/file ids and query/sort/limit are not accepted. The block is staged in the portal's customizer draft (not published immediately). Requires portals.write access.
212
+ */
213
+ async addPortalFileUploaderBlock(params) {
214
+ return this.client.request({
215
+ method: "POST",
216
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/file-uploader",
217
+ pathParams: params.path,
218
+ headers: params.headers,
219
+ body: params.body,
220
+ opId: "addPortalFileUploaderBlock",
221
+ expectedContentType: "application/json",
222
+ });
223
+ }
224
+ /**
225
+ * Add a Form block to a portal page
226
+ * Stages one Customizer-compatible Form on an EXISTING portal page — the programmatic equivalent of the customizer's Content display "Form" tile. It creates exactly one flexible block with a Description brick and a Form content brick; no page, sidebar item, form response or file is created. The body may be empty, which reproduces the Customizer default: the title "Form", the contact-and-company description copy and five fields — required half-width First name, Last name and Contact email, optional half-width Project name and an optional full-width Project overview — plus a visible "Submit" button and reusable true. `content.form.fields` is the COMPLETE visual-order list: omit it to keep those five, or send [] for a Form without fields. Each field takes a `type` (text, textarea, number, phone, email, checkbox, select, file or date) and the optional `label`, `required` and `width` (`half`/`full`); `placeholder` is accepted only for text, textarea, number, phone, email and select, and `options` is a string array for select only — never the persisted newline-separated string. Field ids, indexes, column counts, raw bricks and renderer schema are rejected. Field labels, placeholders, options and the submit text are plain text without dynamic variables; the block `title` and the Description text accept `{{ClientName}}` and `{{ClientLastName}}`. `content.description` and `content.form` are hidden independently with `visible: false`. `appearance` sets Customizer Backdrop `none`, `blank` or `custom`; omitting it keeps the canonical blank backdrop with the title shown, and a custom backdrop takes a background, padding (default `s`) and `showTitle` (default true). `layout` sets Width (2-6, default 6) and Height (Auto by default, a manual value is at least 50px). The block is staged in the portal's customizer draft (not published immediately). Requires portals.write access.
227
+ */
228
+ async addPortalFormBlock(params) {
229
+ return this.client.request({
230
+ method: "POST",
231
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/form",
232
+ pathParams: params.path,
233
+ headers: params.headers,
234
+ body: params.body,
235
+ opId: "addPortalFormBlock",
236
+ expectedContentType: "application/json",
237
+ });
238
+ }
179
239
  /**
180
240
  * Add a Text & Media Heading block to a portal page
181
241
  * Stages one Customizer-compatible Heading block on an existing portal page — the programmatic equivalent of the customizer's Text & Media "Heading" tile. `content` carries the text settings (plain text, one palette colour token such as `cyan-700` — never HEX or CSS —, size `s`/`m`/`l`/`xl`, a unique set of `bold`, `italic`, `underline`, `lineThrough` styles and alignment). `appearance` is the Customizer Appearance section; a `custom` backdrop takes a colour, gradient or one of the five preset background images (`azure`, `mira`, `solis`, `serenity`, `glow`) — an image URL, asset id or upload is rejected. HTML, Markdown, CSS, Tailwind classes, a wrapper title and raw bricks are not accepted. Defaults: text "Your Title Goes Here", size `l`, no styles, left alignment and a blank backdrop. It creates exactly one flexible block on an EXISTING page; no page, sidebar item or media asset is created. `layout` sets Customizer Width (2-6, default 6) and Height (Auto by default, a manual value is at least 50px); `rowspan`, row placement and responsive values are not part of this contract. The block is staged in the portal's customizer draft (not published immediately). Requires portals.write access.
@@ -191,6 +251,21 @@ class PortalsApi {
191
251
  expectedContentType: "application/json",
192
252
  });
193
253
  }
254
+ /**
255
+ * Add an HTML/CSS block to a portal page
256
+ * Stages one Customizer-compatible HTML/CSS block on an EXISTING portal page — the programmatic equivalent of the customizer's Custom "HTML/CSS block" tile. It creates exactly one flexible block of the `code` template carrying a single code brick; no page, sidebar item or media asset is created. ONLY a portal served from a verified custom CNAME domain may carry one — on a Fusebase-owned portal subdomain the request is rejected with 400. (The Customizer's own HTML/CSS editors gate on the domain only and have a beta-programme escape hatch this operation does not honour, so a rejection here does not always mean the owner cannot do it in the UI.) Omit `content` to get the Customizer default demo (a "Sales Distribution" pie chart). `content` replaces that demo entirely and takes `html` (markup inserted as-is), `style` (raw CSS with no `<style>` tag, injected globally, so scope every rule with your own class names) and `script` (raw JavaScript with no `<script>` tag, run on every visit of the published page); an omitted field is empty rather than the demo value, and each is limited to 50000 characters. The code is stored verbatim and is NOT sanitized, so send only markup and scripts the portal owner asked for. The block's wrapper is pinned to the Customizer's own edge-to-edge one, which hides `title` BY DEFAULT; the owner can change the backdrop, padding and Show title in the Customizer's Appearance section afterwards, so this operation exposes no `appearance` field rather than a partial one. `layout` sets Customizer Width (2-6, default 3) and Height (Auto by default, a manual value is at least 50px). The block is staged in the portal's customizer draft (not published immediately), so the portal owner reviews the code before it goes live. Requires portals.write access.
257
+ */
258
+ async addPortalHtmlCssBlock(params) {
259
+ return this.client.request({
260
+ method: "POST",
261
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/html-css",
262
+ pathParams: params.path,
263
+ headers: params.headers,
264
+ body: params.body,
265
+ opId: "addPortalHtmlCssBlock",
266
+ expectedContentType: "application/json",
267
+ });
268
+ }
194
269
  /**
195
270
  * Add a Text & Media Image block to a portal page
196
271
  * Stages one Customizer-compatible Image block on an existing portal page — the programmatic equivalent of the customizer's Text & Media "Image" tile. It always creates the customizer's default stock image: `assetId`, `src`, a URL, base64, a file path or name, HTML and any other image input are rejected, and so are Appearance and text settings. Only `layout` applies. It creates exactly one flexible block on an EXISTING page; no page, sidebar item or media asset is created. `layout` sets Customizer Width (2-6, default 6) and Height (Auto by default, a manual value is at least 50px); `rowspan`, row placement and responsive values are not part of this contract. The block is staged in the portal's customizer draft (not published immediately). Requires portals.write access.
@@ -206,6 +281,51 @@ class PortalsApi {
206
281
  expectedContentType: "application/json",
207
282
  });
208
283
  }
284
+ /**
285
+ * Add an Info block to a portal page
286
+ * Stages one Customizer-compatible Info block on an EXISTING portal page — the programmatic equivalent of the customizer's Content display "Info block" tile: a compact clickable tile with one image, one title and one destination. No page, sidebar item or media asset is created, and it is NOT the Card tile (use addPortalCardBlock for that). Required `title` is the text shown inside the tile. Required `image` is exactly one semantic variant: `{type:"emoji", emoji}` with one visible Unicode emoji, `{type:"icon", iconId}` with an exact id from searchPortalInfoBlockIcons, or `{type:"custom", url}` with an existing absolute https image URL the user supplied — this operation uploads nothing and the internal `emoji#`/`icon#`/`url#` format is rejected. Required `destination` is an exact `pageId` of a page in THIS portal or an absolute https URL. Optional `openInNewTab` (default true) and `layout` set Customizer Width (1-3, default 1) and Height (Auto by default, a manual value is at least 50px); there is no row count. The Info block has no Appearance section: a backdrop, colour, padding, CSS or a raw wrapper is rejected. The block is staged in the portal's customizer draft (not published immediately). Requires portals.write access.
287
+ */
288
+ async addPortalInfoBlock(params) {
289
+ return this.client.request({
290
+ method: "POST",
291
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/info",
292
+ pathParams: params.path,
293
+ headers: params.headers,
294
+ body: params.body,
295
+ opId: "addPortalInfoBlock",
296
+ expectedContentType: "application/json",
297
+ });
298
+ }
299
+ /**
300
+ * Add a Kanban board as a block to a portal page
301
+ * Creates a new Fusebase note, shares it into the portal, initialises a Kanban board inside it and adds the note as a block to an existing portal page — the programmatic equivalent of the customizer's Project management "Kanban" tile. No new page and no sidebar menu item is created. For a published page resolve pageId from listPortalContent; for a page created earlier in the active draft use the pageId that operation returned. Optional body: title (block, note and board title, non-empty and at most 100 characters, default "Kanban") and columns (1-10 column titles in order, each at most 100 characters, default "To do", "In progress", "Done"). The board starts empty — tasks are added by portal users, not by this operation. Use addPortalBlankNoteBlock when an empty note is wanted instead. The block is appended after the last block of the page body and is staged in the portal's customizer draft (not published immediately). Returns the note/board/block ids and the draft branch/seqs. Requires portals.write access.
302
+ */
303
+ async addPortalKanbanBlock(params) {
304
+ return this.client.request({
305
+ method: "POST",
306
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/kanban",
307
+ pathParams: params.path,
308
+ headers: params.headers,
309
+ body: params.body,
310
+ opId: "addPortalKanbanBlock",
311
+ expectedContentType: "application/json",
312
+ });
313
+ }
314
+ /**
315
+ * Add a Linked block to a portal page
316
+ * Stages one Customizer-compatible Linked block on an EXISTING portal page — the programmatic equivalent of the customizer's Custom "Linked block" tile. The block MIRRORS an existing block of another page: its title, width, height, wrapper and actions are taken from the source and it keeps following the source, so no title, layout, appearance or content is accepted here. `source` is the exact `portalId`/`pageId`/`blockId` triple from listPortalLinkableBlocks; never invent ids. Both portals must belong to this organization and the caller must be allowed to edit both. A block staged only in a draft can be linked ONLY within the same portal — a cross-portal source must already be published. A Linked block cannot point at another Linked block, nor at a block on the target page itself. The block is staged in the target portal's customizer draft (not published immediately). Requires portals.write access.
317
+ */
318
+ async addPortalLinkedBlock(params) {
319
+ return this.client.request({
320
+ method: "POST",
321
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/linked",
322
+ pathParams: params.path,
323
+ headers: params.headers,
324
+ body: params.body,
325
+ opId: "addPortalLinkedBlock",
326
+ expectedContentType: "application/json",
327
+ });
328
+ }
209
329
  /**
210
330
  * Add an existing Fusebase note as a block to a portal page
211
331
  * Embeds an existing Fusebase note as a content block on an existing portal page (no new page or sidebar item is created). The note must already exist in the portal's workspace and be shared into the portal (e.g. created via createPortalPageWithNote). Pass pageId (the target page node id, obtained from listPortalContent) and noteId. The block is staged in the portal's customizer draft (not published immediately): the portal owner opens the customizer, reviews the pending block, and publishes it. Returns the created block id and the draft branch/seqs. Requires portals.write access.
@@ -221,6 +341,21 @@ class PortalsApi {
221
341
  expectedContentType: "application/json",
222
342
  });
223
343
  }
344
+ /**
345
+ * Add a task list as a block to a portal page
346
+ * Creates a new Fusebase note, shares it into the portal, initialises a task list inside it and adds the note as a block to an existing portal page — the programmatic equivalent of the customizer's Project management "Task list" tile. No new page and no sidebar menu item is created. For a published page resolve pageId from listPortalContent; for a page created earlier in the active draft use the pageId that operation returned. Optional body: title (block and task list title, at most 100 characters, default "Task list") and layout (colspan 3-6, default 6; height in pixels or null for Auto, default null). The list starts empty — tasks are added by portal users, not by this operation, and an existing task list cannot be attached. Use addPortalBlankNoteBlock when an empty note is wanted instead. The block is appended after the last block of the page body and is staged in the portal's customizer draft (not published immediately). Returns the note/task list/block ids and the draft branch/seqs. Requires portals.write access.
347
+ */
348
+ async addPortalTaskListBlock(params) {
349
+ return this.client.request({
350
+ method: "POST",
351
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/task-list",
352
+ pathParams: params.path,
353
+ headers: params.headers,
354
+ body: params.body,
355
+ opId: "addPortalTaskListBlock",
356
+ expectedContentType: "application/json",
357
+ });
358
+ }
224
359
  /**
225
360
  * Add a Text & Media Simple text block to a portal page
226
361
  * Stages one Customizer-compatible Simple text block on an existing portal page — the programmatic equivalent of the customizer's Text & Media "Simple text" tile. `content` carries the text settings (plain text, one palette colour token such as `cyan-700` — never HEX or CSS —, size `s`/`m`/`l`/`xl`, a unique set of `bold`, `italic`, `underline`, `lineThrough` styles and alignment). `appearance` is the Customizer Appearance section; a `custom` backdrop takes a colour, gradient or one of the five preset background images (`azure`, `mira`, `solis`, `serenity`, `glow`) — an image URL, asset id or upload is rejected. HTML, Markdown, CSS, Tailwind classes, a wrapper title and raw bricks are not accepted. Defaults: text "Your journey starts here! Add your unique message to engage your audience.", size `m`, no styles, left alignment and a blank backdrop. It creates exactly one flexible block on an EXISTING page; no page, sidebar item or media asset is created. `layout` sets Customizer Width (2-6, default 6) and Height (Auto by default, a manual value is at least 50px); `rowspan`, row placement and responsive values are not part of this contract. The block is staged in the portal's customizer draft (not published immediately). Requires portals.write access.
@@ -236,6 +371,21 @@ class PortalsApi {
236
371
  expectedContentType: "application/json",
237
372
  });
238
373
  }
374
+ /**
375
+ * Add a Timeline block to a portal page
376
+ * Stages one Customizer-compatible Timeline block on an EXISTING portal page — the programmatic equivalent of the customizer's "Timeline" tile from Project management. Use it for a visual ordered sequence of project phases, milestones or steps with completion progress; it is NOT a Task list, Kanban, Carousel or Card group. It creates exactly one flexible block with four bricks (Image, Description, Step group, Button); no page, sidebar item or media asset is created. The body may be empty, which reproduces the Customizer default: the title "Timeline", the horizontal view, the built-in image, the project description, the completed Vision and Arrangements steps, the incomplete Launch step and a "View project" button. `view` is `horizontal` (default) or `vertical`. `title` is the wrapper title (plain text, only the `{{ClientName}}` and `{{ClientLastName}}` variables). `content.image.visible` shows or hides the BUILT-IN image; no image url, asset id, filename, base64 or local path is accepted. `content.description` takes `visible`, `text`, `color`, `size`, `styles` and `align`. `content.steps` REPLACES the whole step list with 1 to 6 steps in visual order; every step takes a `title` of at most 25 characters and may take `completed` and a `destination`, and completed steps must be consecutive from the first one. `content.button` takes `visible`, a plain `text` and a `destination`. A step or Button destination is an exact pageId in this SAME portal, an absolute https:// URL or an email address; raw DynamicLink fields are rejected. `appearance` sets Customizer Backdrop `none`, `blank` or `custom`; a custom backdrop takes a background, padding (default `s`) and `showTitle` (default true). `layout` sets Width (2-6, default 6) and Height (Auto by default, a manual value is at least 50px). The block is staged in the portal's customizer draft (not published immediately). Requires portals.write access.
377
+ */
378
+ async addPortalTimelineBlock(params) {
379
+ return this.client.request({
380
+ method: "POST",
381
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/timeline",
382
+ pathParams: params.path,
383
+ headers: params.headers,
384
+ body: params.body,
385
+ opId: "addPortalTimelineBlock",
386
+ expectedContentType: "application/json",
387
+ });
388
+ }
239
389
  /**
240
390
  * Invite multiple users to a portal in one call
241
391
  * Invites a batch of users to a single portal in one request, replacing N sequential inviteToPortal calls. Portal discovery (listPortals/getPortal) runs once for the whole batch. Invites are processed with bounded concurrency (default 5, max 5); the rest are queued. With background=false (default) the response waits for all invites and returns aggregated per-invitation results (status='completed'). With background=true the response returns immediately (status='processing') and invites run in the background without blocking the caller. Per-invitation orgRole/isFullAccess semantics match inviteToPortal. Invarian — before calling for client invites (orgRole='client' or unspecified): ALWAYS ask the user 'Full access (all pages) or Shared only (public pages)?' and wait for their answer.
@@ -473,6 +623,20 @@ class PortalsApi {
473
623
  expectedContentType: "application/json",
474
624
  });
475
625
  }
626
+ /**
627
+ * Discover the blocks a Linked block can point at
628
+ * Read-only discovery of the exact source block ids addPortalLinkedBlock requires. Lists the blocks of ONE page over the published portal AND its active customizer draft, in display order, as `blocks` of `blockId`, `type`, `templateType`, `title` and `draftOnly`. A `draftOnly` block is staged but not published and may only be linked from a page in the SAME portal. Linked blocks are excluded — a Linked block cannot point at another one. The response carries identity only: never bricks, wrappers, content, data or draft events. Requires portals.write access.
629
+ */
630
+ async listPortalLinkableBlocks(params) {
631
+ return this.client.request({
632
+ method: "GET",
633
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/linkable",
634
+ pathParams: params.path,
635
+ headers: params.headers,
636
+ opId: "listPortalLinkableBlocks",
637
+ expectedContentType: "application/json",
638
+ });
639
+ }
476
640
  /**
477
641
  * List organization portals
478
642
  * Returns portals visible for the caller in the organization. Requires portals.read and org access.
@@ -488,8 +652,8 @@ class PortalsApi {
488
652
  });
489
653
  }
490
654
  /**
491
- * Publish a portal's staged draft
492
- * Publishes all staged changes in the portal's customizer draft to the live portal, applying them through the same content pipeline the customizer's Publish button uses. Use this to make an agent's previously staged content/settings ops (folders, pages, blocks, access mode, custom code) visible to clients without opening the customizer. Returns 400 if the draft is empty and 409 if the portal was published elsewhere since the draft was based (refresh the draft first). Requires portals.write access.
655
+ * Publish an entire portal draft after user confirmation
656
+ * Publishes every staged change in the portal's customizer draft to the live portal, including changes the owner or another user staged manually. Never call this operation automatically after staging content or settings. Before every call, tell the user that the entire pending draft will go live, ask one clear yes/no question, and wait for explicit confirmation. Do not infer publish permission from a content-edit request or successful staging. Confirmation is single-use and applies only to the current draft and one attempt. Returns 400 if the draft is empty and 409 if the portal was published elsewhere since the draft was based; obtain new confirmation before retrying. Requires portals.write access.
493
657
  */
494
658
  async publishPortalDraft(params) {
495
659
  return this.client.request({
@@ -501,6 +665,20 @@ class PortalsApi {
501
665
  expectedContentType: "application/json",
502
666
  });
503
667
  }
668
+ /**
669
+ * Search the Portal Info block icon catalog
670
+ * Searches the icon catalog addPortalInfoBlock accepts — a versioned snapshot of the Customizer's own icon set. Call it before addPortalInfoBlock whenever the user asks for an Icon rather than an Emoji or a Custom image, and pass the returned exact `items[].id` as `image.iconId`; never derive an id from a label. `query` is optional (omit it to browse) and is matched against the icon id. Returns one bounded page of { id, label }, the matching `total`, and a nextCursor when more pages exist. The catalog is global and read-only: it is not scoped to an organization or portal, returns no SVG content, and changes nothing.
671
+ */
672
+ async searchPortalInfoBlockIcons(params) {
673
+ return this.client.request({
674
+ method: "GET",
675
+ path: "/portals/block-options/info-icons",
676
+ query: params.query,
677
+ headers: params.headers,
678
+ opId: "searchPortalInfoBlockIcons",
679
+ expectedContentType: "application/json",
680
+ });
681
+ }
504
682
  /**
505
683
  * Restrict or allow editing of a dashboard view
506
684
  * The customizer's "Restrict editing" switch. This is a GLOBAL view setting, not a portal-block setting: it applies everywhere the view is used, including other portal blocks and the dashboard itself. Call it only when the user explicitly asks to restrict or allow editing; it is never part of addPortalDatabaseBlock. Requires dashboard.write access.
@@ -533,7 +711,7 @@ class PortalsApi {
533
711
  }
534
712
  /**
535
713
  * Update portal custom CSS/JS code
536
- * Sets custom code for the portal: css (custom styles), headCode (HTML/JS at the start of <head>), and bodyCode (HTML/JS at the end of <body>). Only the provided fields change; omitted fields keep their current value, and an empty string clears a field. At least one field is required. Custom code only renders on portals served from a custom CNAME domain. The change is staged in the portal's customizer draft (not published immediately): the portal owner opens the customizer, reviews the pending change, and publishes it. Returns the draft branch/seq. Requires portals.write access.
714
+ * Sets custom code for the portal: css (custom styles), headCode (HTML/JS at the start of <head>), and bodyCode (HTML/JS at the end of <body>). css is auto-scoped under the portal root container #main-scrolling-container so it cannot leak into the customizer UI; scope selectors accordingly and avoid body/html/:root. Only the provided fields change; omitted fields keep their current value, and an empty string clears a field. At least one field is required. Custom code only renders on portals served from a custom CNAME domain. The change is staged in the portal's customizer draft (not published immediately): the portal owner opens the customizer, reviews the pending change, and publishes it. Returns the draft branch/seq. Requires portals.write access.
537
715
  */
538
716
  async updatePortalCustomCode(params) {
539
717
  return this.client.request({
@@ -476,6 +476,65 @@ export interface IsolatedStoreSqlDeleteRequestContract {
476
476
  export interface IsolatedStoreSqlDeleteResponseContract {
477
477
  rowCount: number;
478
478
  }
479
+ export type IsolatedStoreSqlBatchOperationKindContract = "query" | "execute" | "count" | "select" | "insert" | "batchInsert" | "update" | "delete";
480
+ /**
481
+ * One step of a batch. Fields mirror the single-operation request of the same
482
+ * kind; only the ones that kind uses are read. `rlsContext` /
483
+ * `trustedRuntimeContext` are batch-level and cannot be set per operation.
484
+ */
485
+ export interface IsolatedStoreSqlBatchOperationContract {
486
+ op: IsolatedStoreSqlBatchOperationKindContract;
487
+ /** `query` / `execute` only. */
488
+ sql?: string | null;
489
+ /** `query` / `execute` only. */
490
+ params?: unknown[] | null;
491
+ schemaName?: IsolatedStoreSqlSchemaNameInQueryOptional;
492
+ tableName?: string | null;
493
+ /** `select` only. */
494
+ columns?: string[] | null;
495
+ filters?: IsolatedStoreSqlFilterContract[] | null;
496
+ /** `select` only. */
497
+ sort?: IsolatedStoreSqlSortContract[] | null;
498
+ /** `select` only. */
499
+ limit?: number | null;
500
+ /** `select` only. */
501
+ offset?: number | null;
502
+ /** `insert` / `update` only. */
503
+ values?: Record<string, unknown> | null;
504
+ /** `batchInsert` only. */
505
+ rows?: Record<string, unknown>[] | null;
506
+ returning?: string[] | null;
507
+ /** `update` / `delete` only — required to mutate without filters. */
508
+ allowAll?: boolean | null;
509
+ }
510
+ export interface IsolatedStoreSqlBatchRequestContract {
511
+ operations: IsolatedStoreSqlBatchOperationContract[];
512
+ rlsContext?: IsolatedStoreSqlRlsContextContract | null;
513
+ trustedRuntimeContext?: IsolatedStoreSqlTrustedRuntimeContextContract | null;
514
+ }
515
+ /** Flat superset of the single-operation responses; populated per `op`. */
516
+ export interface IsolatedStoreSqlBatchOperationResultContract {
517
+ op: IsolatedStoreSqlBatchOperationKindContract;
518
+ /** `query` / `execute`. */
519
+ result?: IsolatedStoreSqlQueryResultContract | null;
520
+ /** `count`. */
521
+ count?: number | null;
522
+ /** `select`. */
523
+ columns?: string[] | null;
524
+ /** `select` / `insert` / `batchInsert` / `update`. */
525
+ rows?: Record<string, unknown>[] | null;
526
+ /** `insert` / `batchInsert` / `update` / `delete`. */
527
+ rowCount?: number | null;
528
+ /** `select`. */
529
+ page?: {
530
+ limit: number;
531
+ offset: number;
532
+ rowCount: number;
533
+ } | null;
534
+ }
535
+ export interface IsolatedStoreSqlBatchResponseContract {
536
+ results: IsolatedStoreSqlBatchOperationResultContract[];
537
+ }
479
538
  export interface CreateIsolatedStoreRequestContract {
480
539
  alias: string;
481
540
  storeType: IsolatedStoreTypeContract;
@@ -657,3 +716,13 @@ export declare const IsolatedStoreSqlImportFormatContract: {
657
716
  readonly Csv: "csv";
658
717
  readonly Tsv: "tsv";
659
718
  };
719
+ export declare const IsolatedStoreSqlBatchOperationKindContract: {
720
+ readonly Query: "query";
721
+ readonly Execute: "execute";
722
+ readonly Count: "count";
723
+ readonly Select: "select";
724
+ readonly Insert: "insert";
725
+ readonly Batchinsert: "batchInsert";
726
+ readonly Update: "update";
727
+ readonly Delete: "delete";
728
+ };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.IsolatedStoreSqlImportFormatContract = exports.IsolatedStoreSqlSortDirectionContract = exports.IsolatedStoreSqlFilterOperatorContract = exports.IsolatedStoreSqlMigrationIssueFieldContract = exports.IsolatedStoreSqlMigrationIssueCodeContract = exports.IsolatedStoreSqlRlsValidationWarningCodeContract = exports.IsolatedStoreSqlRlsTableClassificationContract = exports.IsolatedStoreSqlRlsWarningCodeContract = exports.IsolatedStoreScopeTypeContract = exports.IsolatedStoreRevisionKindContract = exports.IsolatedStoreStageStatusContract = exports.IsolatedStoreStatusContract = exports.IsolatedStoreEngineContract = exports.IsolatedStoreTypeContract = void 0;
3
+ exports.IsolatedStoreSqlBatchOperationKindContract = exports.IsolatedStoreSqlImportFormatContract = exports.IsolatedStoreSqlSortDirectionContract = exports.IsolatedStoreSqlFilterOperatorContract = exports.IsolatedStoreSqlMigrationIssueFieldContract = exports.IsolatedStoreSqlMigrationIssueCodeContract = exports.IsolatedStoreSqlRlsValidationWarningCodeContract = exports.IsolatedStoreSqlRlsTableClassificationContract = exports.IsolatedStoreSqlRlsWarningCodeContract = exports.IsolatedStoreScopeTypeContract = exports.IsolatedStoreRevisionKindContract = exports.IsolatedStoreStageStatusContract = exports.IsolatedStoreStatusContract = exports.IsolatedStoreEngineContract = exports.IsolatedStoreTypeContract = void 0;
4
4
  exports.IsolatedStoreTypeContract = {
5
5
  Sql: "sql"
6
6
  };
@@ -92,3 +92,13 @@ exports.IsolatedStoreSqlImportFormatContract = {
92
92
  Csv: "csv",
93
93
  Tsv: "tsv"
94
94
  };
95
+ exports.IsolatedStoreSqlBatchOperationKindContract = {
96
+ Query: "query",
97
+ Execute: "execute",
98
+ Count: "count",
99
+ Select: "select",
100
+ Insert: "insert",
101
+ Batchinsert: "batchInsert",
102
+ Update: "update",
103
+ Delete: "delete"
104
+ };