@bettercms-ai/sdk 1.20.0 → 1.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _bettercms_ai_types from '@bettercms-ai/types';
2
- import { ContentPageResult, Content, DeliveredLayout, ContentModelField, BetterCMSErrorCode, LayoutStructureDocument, LayoutDataDocument, PageLayoutOverrideDocument, ManagementLayoutCommand, AuthUser, AuthSession, SignInInput, SignUpInput, Perspective, DeliveryEntry, DeliveryList, DeliveryPage, DeliveryComponent, PageMetaJson, DeliveryEntrySeo, SiteSeoDefaults, Page, MediaAsset, Form, FormSubmission, Workspace, ApiKey, ApiKeyPermission, ApiKeyTokenType } from '@bettercms-ai/types';
2
+ import { ContentPageResult, Content, DeliveredLayout, ContentModelField, BetterCMSErrorCode, LayoutStructureDocument, LayoutDataDocument, PageLayoutOverrideDocument, ManagementLayoutCommand, AuthUser, AuthSession, SignInInput, SignUpInput, Perspective, DeliveryEntry, DeliveryList, DeliveryPage, DeliveryComponent, PageMetaJson, DeliveryEntrySeo, SiteSeoDefaults, Page, MediaAsset, FormField, Form, FormSubmission, Workspace, ApiKey, ApiKeyPermission, ApiKeyTokenType } from '@bettercms-ai/types';
3
3
  export { ApiError, ApiKey, ApiKeyPermission, ApiKeyTokenType, AssertEqual, AuthSession, AuthUser, BetterCMSErrorCode, BlockType, ButtonBlock, ButtonProps, ColumnsBlock, ColumnsProps, Content, ContentBlock, ContentEntry, ContentModel, ContentModelField, ContentPageResult, ContentResponse, DeepReadonly, DeliveryComponent, DeliveryEntry, DeliveryList, DeliveryPage, Form, FormBlock, FormField, FormProps, FormSubmission, HeadingBlock, HeadingProps, ImageBlock, ImageProps, MediaAsset, Page, PageMetaJson, PaginatedResult, Perspective, Redirect, SignInInput, SignUpInput, SiteSeoDefaults, SpacerBlock, SpacerProps, TextBlock, TextProps, VideoBlock, VideoProps, Workspace, getBlockType, isBlock } from '@bettercms-ai/types';
4
4
  export { ImageFit, ImageFormat, ImageSource, ImageUrlBuilder, ImageUrlOptions, imageUrl, default as imageUrlBuilder } from '@bettercms-ai/image-url';
5
5
 
@@ -84,73 +84,6 @@ declare class BetterCMSDeliveryClient {
84
84
  fetchJSON<T>(url: string): Promise<T>;
85
85
  }
86
86
 
87
- /**
88
- * SDK webhook methods — create, list, delete, test webhooks.
89
- */
90
- /**
91
- * Webhook event types supported by BetterCMS.
92
- */
93
- type WebhookEvent = "content.publish" | "content.unpublish" | "content.created" | "content.updated" | "content.deleted" | "page.published" | "page.unpublished" | "page.created" | "page.updated" | "page.deleted" | "form.submitted" | "api_key.created" | "api_key.deleted";
94
- /**
95
- * Webhook record returned from the API (without secret).
96
- */
97
- interface Webhook {
98
- id: string;
99
- projectId: string;
100
- workspaceId: string;
101
- name: string;
102
- url: string;
103
- events: WebhookEvent[];
104
- isActive: boolean;
105
- createdAt: string;
106
- updatedAt: string;
107
- }
108
- /**
109
- * Webhook with secret — returned only on create.
110
- */
111
- interface WebhookWithSecret extends Webhook {
112
- secret: string;
113
- }
114
- /**
115
- * Input for creating a webhook.
116
- */
117
- interface CreateWebhookInput {
118
- name: string;
119
- url: string;
120
- events?: WebhookEvent[];
121
- }
122
- /**
123
- * Input for updating a webhook.
124
- */
125
- interface UpdateWebhookInput {
126
- name?: string;
127
- url?: string;
128
- events?: WebhookEvent[];
129
- isActive?: boolean;
130
- }
131
- /**
132
- * Paginated list response.
133
- */
134
- interface WebhookListResponse {
135
- data: Webhook[];
136
- pagination: {
137
- page: number;
138
- limit: number;
139
- total: number;
140
- totalPages: number;
141
- };
142
- }
143
-
144
- /**
145
- * BetterCMSAdminClient — typed SDK client for admin CRUD operations.
146
- *
147
- * Extends BetterCMSDeliveryClient but overrides:
148
- * - `headers()` — uses Bearer token auth instead of API key
149
- * - `fetchJSON()` — adds Retry-After-aware retry on 429/503 (see ./retry.ts)
150
- *
151
- * @see openspec/changes/flo-6-backend-sdk-admin/specs/sdk-admin-client/spec.md
152
- */
153
-
154
87
  interface BetterCMSAdminOptions {
155
88
  /** Base URL of the Admin API. Defaults to https://api.bettercms.ai/v1 */
156
89
  baseUrl?: string;
@@ -175,19 +108,15 @@ declare class BetterCMSAdminClient extends BetterCMSDeliveryClient {
175
108
  fetchJSON<T>(url: string, init?: RequestInit): Promise<T>;
176
109
  /** Build the admin API URL. */
177
110
  url(path: string): string;
178
- /** Webhook management methods. */
179
- webhooks(): {
111
+ /** Project-scoped webhook management methods. */
112
+ webhooks(projectId: string): {
180
113
  list: (options?: {
181
114
  page?: number;
182
115
  limit?: number;
183
116
  }) => Promise<WebhookListResponse>;
184
117
  create: (input: CreateWebhookInput) => Promise<WebhookWithSecret>;
185
- get: (webhookId: string) => Promise<{
186
- data: Webhook;
187
- }>;
188
- update: (webhookId: string, input: UpdateWebhookInput) => Promise<{
189
- data: Webhook;
190
- }>;
118
+ get: (webhookId: string) => Promise<Webhook>;
119
+ update: (webhookId: string, input: UpdateWebhookInput) => Promise<Webhook>;
191
120
  delete: (webhookId: string) => Promise<{
192
121
  data: {
193
122
  id: string;
@@ -269,10 +198,21 @@ interface CreateManagedPageInput {
269
198
  slug: string;
270
199
  pageType?: "singleton" | "dynamic";
271
200
  fields?: ContentModelField[];
201
+ /**
202
+ * A singleton's field VALUES, keyed by field key — seeds its entry in the same call. When the
203
+ * server cannot store them the page is still created and the result carries `warnings`
204
+ * (`ENTRY_SEED_FAILED`) and `seedErrors`: check them, because none of `data` was saved.
205
+ */
206
+ data?: Record<string, unknown>;
272
207
  metaTitle?: string;
273
208
  metaDescription?: string;
274
209
  status?: "draft" | "published";
275
210
  }
211
+ /** What a page create reports beyond the page: the seed of `data` that did not happen. */
212
+ type PageCreateReport = {
213
+ warnings?: string[];
214
+ seedErrors?: Record<string, string>;
215
+ };
276
216
  /** Append fields to an existing page's schema (additive — see addPageFields). */
277
217
  interface AddPageFieldsInput {
278
218
  addFields: ContentModelField[];
@@ -371,7 +311,7 @@ declare function getModel(client: ManagementClient, id: string): Promise<Managed
371
311
  declare function listManagedPages(client: ManagementClient): Promise<ManagedPage[]>;
372
312
  /** Create a page (the page-first schema: title/slug/pageType/fields). Project-scoped from the key.
373
313
  * Supports both `singleton` and `dynamic` pageType. */
374
- declare function createManagedPage(client: ManagementClient, input: CreateManagedPageInput): Promise<ManagedPage>;
314
+ declare function createManagedPage(client: ManagementClient, input: CreateManagedPageInput): Promise<ManagedPage & PageCreateReport>;
375
315
  /**
376
316
  * Append fields to an existing page's schema (additive read-append). The API
377
317
  * rejects keys that already exist, so this never overwrites or retypes a field.
@@ -397,14 +337,21 @@ declare function createModel(client: ManagementClient, input: CreateModelInput):
397
337
  /** Update a content model (additive — fields/name/slug/description). */
398
338
  declare function updateModel(client: ManagementClient, id: string, input: UpdateModelInput): Promise<ManagedContentModel>;
399
339
  /** Create a content entry under a model. */
400
- declare function createEntry(client: ManagementClient, input: CreateEntryInput): Promise<ManagedContentEntry>;
340
+ /**
341
+ * Advisory notes the server attached to a write — e.g. `REFERENCE_NOT_FOUND: …` for a reference
342
+ * whose target was deleted. The write succeeded; present only when there is something to say.
343
+ */
344
+ type EntryWriteWarnings = {
345
+ warnings?: string[];
346
+ };
347
+ declare function createEntry(client: ManagementClient, input: CreateEntryInput): Promise<ManagedContentEntry & EntryWriteWarnings>;
401
348
  /**
402
349
  * Update a content entry. If `opts.ifMatch` (current optimisticVersion) is supplied,
403
350
  * the update is optimistic-locked; omit it for programmatic last-write-wins.
404
351
  */
405
352
  declare function updateEntry(client: ManagementClient, id: string, input: UpdateEntryInput, opts?: {
406
353
  ifMatch?: number;
407
- }): Promise<ManagedContentEntry>;
354
+ }): Promise<ManagedContentEntry & EntryWriteWarnings>;
408
355
 
409
356
  /**
410
357
  * Management API SDK method — media upload (P2).
@@ -568,6 +515,75 @@ interface DeliveryFormField {
568
515
  * trip — the server check is the one that counts.
569
516
  */
570
517
  validation?: DeliveryFormFieldValidation;
518
+ /**
519
+ * Presentation options the renderer honours. Unlike `validation`, the API does NOT enforce
520
+ * these on submit — they change what the visitor is shown, not what is accepted.
521
+ */
522
+ ui?: DeliveryFormFieldUi;
523
+ }
524
+ /**
525
+ * @see FormFieldUi in @bettercms-ai/types — same shape, delivered to the site.
526
+ *
527
+ * ── The phone composition contract every renderer implements ──
528
+ *
529
+ * A picker-enabled phone field is rendered as a country control PLUS a `tel` input, but it
530
+ * submits ONE value under the field's own key, in E.164. Whatever a renderer uses to hold the
531
+ * country (a React state, a `{key}__country` select) is scaffolding: it must never reach the
532
+ * POST body.
533
+ *
534
+ * Composition, from the visible input's raw text:
535
+ * - empty → `""`. NEVER `"+CC"`, and the reason is worse than "the server rejects it". The
536
+ * server's loose phone shape is `{3,32}` chars, so the outcome depends on the calling
537
+ * code's length: `"+1"` is REFUSED (an optional untouched field starts 400ing), while
538
+ * `"+91"` is ACCEPTED and stored as a real-looking submission that is only a country code.
539
+ * The silent case is the dangerous one. Pinned in `__tests__/lib/forms-validate.test.ts`.
540
+ * - starts with `"+"` → `"+" + digits(raw)`. The visitor typed an international number; the
541
+ * country control is ignored rather than fighting them.
542
+ * - otherwise → `"+" + callingCode + digits(raw).replace(/^0/, "")`, dropping ONE trunk zero.
543
+ * Known exception: Italian landlines keep their trunk zero, so this loses it. The value is
544
+ * still accepted (shape-only check) — it is a formatting loss, not a refusal.
545
+ *
546
+ * `ui` changes what the visitor SEES. It never changes what the API accepts: enforcing a format
547
+ * is `validation.phoneFormat`'s job and the two are independent.
548
+ *
549
+ * Renderer parity is behavioural, not implementational. FIVE lanes render this field, and they
550
+ * agree on the VALUE, not on the implementation:
551
+ *
552
+ * | Lane | Control | As-you-type formatting |
553
+ * |-------------------------------|---------------------------------|------------------------|
554
+ * | dashboard form preview | searchable picker + formatter | yes |
555
+ * | @bettercms-ai/next <BcmsForm> | native select + formatter | yes (lazy chunk) |
556
+ * | hosted sites (render-page) | native select + tel input | NO |
557
+ * | embed snippet | native select + tel input | NO |
558
+ * | @bettercms-ai/astro BcmsForm | native select + tel input | NO |
559
+ *
560
+ * The missing as-you-type formatting on the three vanilla lanes is a NAMED degradation, not an
561
+ * oversight: it is what keeps libphonenumber off a visitor's page entirely. `packages/next`
562
+ * pays for it only on pages that actually render a picker, via a separate chunk.
563
+ *
564
+ * When a lane builds that option list, never pass a libphonenumber helper as a bare callback:
565
+ * `getCountries().filter(isSupportedCountry)` hands it the array INDEX as its `metadata`
566
+ * argument and throws. Always wrap — `.filter((iso) => isSupportedCountry(iso))`.
567
+ *
568
+ * And when a lane ships the composition rule inside a JS TEMPLATE LITERAL (the embed snippet
569
+ * does), `\D` collapses to `D` and the regex silently becomes `/D/g` — stripping the letter D
570
+ * and leaving every other separator in place. Write `\\D` there. Raw HTML `<script>` text (the
571
+ * hosted renderer, the Astro inline script) takes a single backslash. Nothing throws either
572
+ * way; numbers just arrive malformed, so each lane pins it with an executed-script test.
573
+ */
574
+ interface DeliveryFormFieldUi {
575
+ /** `phone` — render a country picker beside the number. The submitted value is E.164. */
576
+ countryPicker?: boolean;
577
+ /** `phone` — uppercase ISO 3166-1 alpha-2 the picker starts on. */
578
+ defaultCountry?: string;
579
+ /**
580
+ * `phone` — show the country's flag beside the dialling code.
581
+ *
582
+ * Honoured only by a renderer with a custom picker. The native `<select>` the site lanes use
583
+ * cannot hold an SVG, and an emoji flag renders as two grey letters on Windows, so those
584
+ * lanes show the country NAME instead — the same information, legibly, everywhere.
585
+ */
586
+ showFlags?: boolean;
571
587
  }
572
588
  /** @see FormFieldValidation in @bettercms-ai/types — same shape, delivered to the site. */
573
589
  interface DeliveryFormFieldValidation {
@@ -663,6 +679,14 @@ interface ManagedFormInput {
663
679
  submitLabel?: string;
664
680
  successMessage?: string;
665
681
  redirectUrl?: string;
682
+ /** Require a Cloudflare Turnstile check on submit. Its secret key is set in the dashboard only. */
683
+ turnstileEnabled?: boolean;
684
+ /** Name of a hidden field that must stay empty; a filled one marks the submission as spam. */
685
+ honeypotField?: string | null;
686
+ /** Addresses notified of each submission. */
687
+ notifyEmails?: string[];
688
+ /** URL that receives each submission as a POST. */
689
+ webhookUrl?: string | null;
666
690
  }
667
691
 
668
692
  /**
@@ -882,17 +906,17 @@ declare class BetterCMSManagementClient extends BetterCMSDeliveryClient {
882
906
  listPages(): Promise<ManagedPage[]>;
883
907
  /** Get one page by id INCLUDING its field schema + pageType. */
884
908
  getPage(id: string): Promise<ManagedPage>;
885
- createPage(input: CreateManagedPageInput): Promise<ManagedPage>;
909
+ createPage(input: CreateManagedPageInput): Promise<ManagedPage & PageCreateReport>;
886
910
  /** Append fields to an existing page (additive — the API rejects existing keys). */
887
911
  addPageFields(id: string, input: AddPageFieldsInput): Promise<ManagedPage>;
888
912
  /** Set a page's field VALUES — singleton pages get/update their one entry. */
889
913
  setPageContent(id: string, input: SetPageContentInput): Promise<ManagedContentEntry>;
890
914
  /** Append fields to a content model (additive — rejects existing keys). */
891
915
  addModelFields(id: string, input: AddPageFieldsInput): Promise<ManagedContentModel>;
892
- createEntry(input: CreateEntryInput): Promise<ManagedContentEntry>;
916
+ createEntry(input: CreateEntryInput): Promise<ManagedContentEntry & EntryWriteWarnings>;
893
917
  updateEntry(id: string, input: UpdateEntryInput, opts?: {
894
918
  ifMatch?: number;
895
- }): Promise<ManagedContentEntry>;
919
+ }): Promise<ManagedContentEntry & EntryWriteWarnings>;
896
920
  /** Soft-delete a page and its content entries. */
897
921
  deletePage(id: string): Promise<{
898
922
  id: string;
@@ -1457,14 +1481,20 @@ interface CreateFormInput {
1457
1481
  redirectUrl?: string;
1458
1482
  webhookUrl?: string;
1459
1483
  }
1460
- interface FormFieldInput {
1461
- key: string;
1462
- label: string;
1463
- type: "text" | "email" | "textarea" | "select" | "checkbox" | "number";
1464
- placeholder?: string;
1465
- required?: boolean;
1466
- options?: string[];
1467
- }
1484
+ /**
1485
+ * A field in an admin create/update payload.
1486
+ *
1487
+ * An ALIAS of `FormField`, not a copy. It used to be a hand-written interface and it had gone
1488
+ * stale: it listed six of the thirteen field types the builder can author — `phone`, `date`,
1489
+ * `url`, `radio`, `checkboxes`, `consent` and `hidden` were all missing — and omitted
1490
+ * `helpText`, `hidden`, `defaultValue`, `showIf`, `validation` and `ui` entirely. A typed
1491
+ * consumer of this client therefore could not express a phone field at all, let alone one with
1492
+ * a country picker, even though the route accepts every one of them.
1493
+ *
1494
+ * The admin routes validate against `formFieldSchema`, which mirrors `FormField`, so aliasing
1495
+ * is what keeps this honest: there is no second declaration left to drift.
1496
+ */
1497
+ type FormFieldInput = FormField;
1468
1498
  interface UpdateFormInput extends Partial<Omit<CreateFormInput, "fields">> {
1469
1499
  fields?: FormFieldInput[];
1470
1500
  }
@@ -1580,4 +1610,90 @@ declare function inviteMember(client: BetterCMSAdminClient, workspaceId: string,
1580
1610
  declare function updateMemberRole(client: BetterCMSAdminClient, workspaceId: string, memberId: string, role: MemberRole): Promise<Member>;
1581
1611
  declare function removeMember(client: BetterCMSAdminClient, workspaceId: string, memberId: string): Promise<void>;
1582
1612
 
1583
- export { type AddPageFieldsInput, type ApiKeyUsage, type ApiKeyWithRaw, type AuthResult, BetterCMSError as BCMSClientError, ErrorCodes as BCMSErrorCodes, BetterCMS, BetterCMSAdminClient, type BetterCMSAdminOptions, BetterCMSDeliveryClient, BetterCMSError, BetterCMSManagementClient, type BetterCMSManagementOptions, type BetterCMSReadClient, type BetterCMSSiteOptions, type CommandManagedLayoutInput, type CreateApiKeyInput, type CreateClientOptions, type CreateEntryInput, type CreateFormInput, type CreateManagedPageInput, type CreateModelInput, type CreatePageInput, type CreateWorkspaceInput, type DeliveryForm, type DeliveryFormField, type DeliveryFormFieldType, ErrorCodes, type ExtractionCandidate, type FormFieldInput, type FormListOptions, type FormSubmitError, type FormValue, type FormValues, type GetEntryOptions, type GetManagedLayoutOptions, type ListContentAllOptions, type ListContentOptions, type ListEntriesFilter, type ListEntriesOptions, type ListPagesOptions, type ManagedComponent, type ManagedComponentInput, type ManagedComponentSummary, type ManagedContentEntry, type ManagedContentModel, type ManagedForm, type ManagedFormInput, type ManagedLayoutClient, type ManagedLayoutDocument, type ManagedMediaAsset, type ManagedPage, type ManagementClient, type MediaListOptions, type MediaMetadata, type Member, type MemberRole, PORTABLE_TEXT_FORMAT, type PageListOptions, type PendingInvite, type PublishManagedLayoutInput, type ResolvedSeo, type RichTextValue, type SearchHit, type SearchOptions, type SeoInput, type SeoLocation, type SeoMeta, type SeoMetaInput, type SetPageContentInput, type StegaPayload, type SubmissionListOptions, type SubmitFormOptions, type SubmitFormResult, type TextOrRich, type UpdateApiKeyInput, type UpdateAssetInput, type UpdateEntryInput, type UpdateFormInput, type UpdateModelInput, type UpdatePageInput, type UpdateWorkspaceInput, type UploadAssetInput, type UploadedAsset, type WriteContentInput, addModelFields, addPageFields, asStringArray, commandManagedLayout, createApiKey, createClient, createEntry, createForm, createManagedPage, createModel, createPage, createWorkspace, decodeStega, deleteForm, deleteMedia, deletePage, deleteSubmission, deleteWorkspace, encodeStega, entrySeoInput, formInitialValues, getApiKeyUsage, getEntry, getForm, getManagedLayout, getManagedPage, getMedia, getMember, getModel, getPage, getSubmission, getWorkspace, inviteMember, isMultiValueField, isRichText, listApiKeys, listEntries, listForms, listManagedPages, listMedia, listMembers, listModels, listPages, listSubmissions, listWorkspaces, plain, portableText, publishManagedLayout, publishPage, regenerateApiKey, removeMember, resolveSeo, revokeApiKey, rich, search, setPageContent, shouldShowField, signIn, signInWithGithub, signInWithGoogle, signUp, stripStega, submitForm, toggleOption, updateApiKey, updateEntry, updateForm, updateMemberRole, updateModel, updatePage, updateWorkspace, uploadMedia };
1613
+ /**
1614
+ * SDK webhook methods — create, list, delete, test webhooks.
1615
+ */
1616
+ /**
1617
+ * Webhook event types supported by BetterCMS.
1618
+ */
1619
+ type WebhookEvent = "content.publish" | "content.unpublish" | "content.stage_changed" | "deployment.triggered";
1620
+ interface WebhookAdvancedConfig {
1621
+ version: 1;
1622
+ envelopeVersion: "legacy" | "v2";
1623
+ subscriptions: Array<{
1624
+ event: WebhookEvent;
1625
+ payload: {
1626
+ mode: "complete";
1627
+ } | {
1628
+ mode: "selected";
1629
+ fields: Array<{
1630
+ path: string;
1631
+ alias?: string;
1632
+ }>;
1633
+ };
1634
+ filters: Array<{
1635
+ path: string;
1636
+ operator: "equals" | "not_equals" | "contains" | "exists";
1637
+ value?: string | number | boolean | null;
1638
+ }>;
1639
+ }>;
1640
+ headers: Array<{
1641
+ name: string;
1642
+ secretId: string;
1643
+ }>;
1644
+ }
1645
+ /**
1646
+ * Webhook record returned from the API (without secret).
1647
+ */
1648
+ interface Webhook {
1649
+ id: string;
1650
+ projectId: string;
1651
+ workspaceId: string;
1652
+ name: string;
1653
+ url: string;
1654
+ events: WebhookEvent[];
1655
+ advancedConfig: WebhookAdvancedConfig | null;
1656
+ isActive: boolean;
1657
+ createdAt: string;
1658
+ updatedAt: string;
1659
+ }
1660
+ /**
1661
+ * Webhook with secret — returned only on create.
1662
+ */
1663
+ interface WebhookWithSecret extends Webhook {
1664
+ secret: string;
1665
+ }
1666
+ /**
1667
+ * Input for creating a webhook.
1668
+ */
1669
+ interface CreateWebhookInput {
1670
+ name: string;
1671
+ url: string;
1672
+ events?: WebhookEvent[];
1673
+ isActive?: boolean;
1674
+ advancedConfig?: WebhookAdvancedConfig;
1675
+ }
1676
+ /**
1677
+ * Input for updating a webhook.
1678
+ */
1679
+ interface UpdateWebhookInput {
1680
+ name?: string;
1681
+ url?: string;
1682
+ events?: WebhookEvent[];
1683
+ isActive?: boolean;
1684
+ advancedConfig?: WebhookAdvancedConfig | null;
1685
+ }
1686
+ /**
1687
+ * Paginated list response.
1688
+ */
1689
+ interface WebhookListResponse {
1690
+ data: Webhook[];
1691
+ pagination: {
1692
+ page: number;
1693
+ limit: number;
1694
+ total: number;
1695
+ totalPages: number;
1696
+ };
1697
+ }
1698
+
1699
+ export { type AddPageFieldsInput, type ApiKeyUsage, type ApiKeyWithRaw, type AuthResult, BetterCMSError as BCMSClientError, ErrorCodes as BCMSErrorCodes, BetterCMS, BetterCMSAdminClient, type BetterCMSAdminOptions, BetterCMSDeliveryClient, BetterCMSError, BetterCMSManagementClient, type BetterCMSManagementOptions, type BetterCMSReadClient, type BetterCMSSiteOptions, type CommandManagedLayoutInput, type CreateApiKeyInput, type CreateClientOptions, type CreateEntryInput, type CreateFormInput, type CreateManagedPageInput, type CreateModelInput, type CreatePageInput, type CreateWebhookInput, type CreateWorkspaceInput, type DeliveryForm, type DeliveryFormField, type DeliveryFormFieldType, ErrorCodes, type ExtractionCandidate, type FormFieldInput, type FormListOptions, type FormSubmitError, type FormValue, type FormValues, type GetEntryOptions, type GetManagedLayoutOptions, type ListContentAllOptions, type ListContentOptions, type ListEntriesFilter, type ListEntriesOptions, type ListPagesOptions, type ManagedComponent, type ManagedComponentInput, type ManagedComponentSummary, type ManagedContentEntry, type ManagedContentModel, type ManagedForm, type ManagedFormInput, type ManagedLayoutClient, type ManagedLayoutDocument, type ManagedMediaAsset, type ManagedPage, type ManagementClient, type MediaListOptions, type MediaMetadata, type Member, type MemberRole, PORTABLE_TEXT_FORMAT, type PageCreateReport, type PageListOptions, type PendingInvite, type PublishManagedLayoutInput, type ResolvedSeo, type RichTextValue, type SearchHit, type SearchOptions, type SeoInput, type SeoLocation, type SeoMeta, type SeoMetaInput, type SetPageContentInput, type StegaPayload, type SubmissionListOptions, type SubmitFormOptions, type SubmitFormResult, type TextOrRich, type UpdateApiKeyInput, type UpdateAssetInput, type UpdateEntryInput, type UpdateFormInput, type UpdateModelInput, type UpdatePageInput, type UpdateWebhookInput, type UpdateWorkspaceInput, type UploadAssetInput, type UploadedAsset, type Webhook, type WebhookAdvancedConfig, type WebhookEvent, type WebhookListResponse, type WebhookWithSecret, type WriteContentInput, addModelFields, addPageFields, asStringArray, commandManagedLayout, createApiKey, createClient, createEntry, createForm, createManagedPage, createModel, createPage, createWorkspace, decodeStega, deleteForm, deleteMedia, deletePage, deleteSubmission, deleteWorkspace, encodeStega, entrySeoInput, formInitialValues, getApiKeyUsage, getEntry, getForm, getManagedLayout, getManagedPage, getMedia, getMember, getModel, getPage, getSubmission, getWorkspace, inviteMember, isMultiValueField, isRichText, listApiKeys, listEntries, listForms, listManagedPages, listMedia, listMembers, listModels, listPages, listSubmissions, listWorkspaces, plain, portableText, publishManagedLayout, publishPage, regenerateApiKey, removeMember, resolveSeo, revokeApiKey, rich, search, setPageContent, shouldShowField, signIn, signInWithGithub, signInWithGoogle, signUp, stripStega, submitForm, toggleOption, updateApiKey, updateEntry, updateForm, updateMemberRole, updateModel, updatePage, updateWorkspace, uploadMedia };