@bettercms-ai/sdk 1.14.0 → 1.16.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
@@ -723,6 +723,18 @@ interface CommandManagedLayoutInput extends GetManagedLayoutOptions {
723
723
  }
724
724
  declare function getManagedLayout(client: ManagedLayoutClient, opts?: GetManagedLayoutOptions): Promise<ManagedLayoutDocument>;
725
725
  declare function commandManagedLayout(client: ManagedLayoutClient, input: CommandManagedLayoutInput): Promise<ManagedLayoutDocument>;
726
+ interface PublishManagedLayoutInput {
727
+ /** The revision from getManagedLayout (scope global). A stale one is a 409. */
728
+ ifMatch: number;
729
+ /** Required when the management credential is workspace-scoped. */
730
+ projectId?: string;
731
+ }
732
+ /**
733
+ * Publish the Global Layout draft. Page overrides are not published here — they go live
734
+ * with their page. The response echoes `copy: "published"`, but that is the write's echo:
735
+ * a publish claim still verifies only via getManagedLayout({ copy: "published" }).
736
+ */
737
+ declare function publishManagedLayout(client: ManagedLayoutClient, input: PublishManagedLayoutInput): Promise<ManagedLayoutDocument>;
726
738
 
727
739
  interface BetterCMSManagementOptions {
728
740
  /** Base URL of the Management API. Defaults to https://api.bettercms.ai/v1 */
@@ -814,6 +826,7 @@ declare class BetterCMSManagementClient extends BetterCMSDeliveryClient {
814
826
  }>;
815
827
  getManagedLayout(opts?: GetManagedLayoutOptions): Promise<ManagedLayoutDocument>;
816
828
  commandManagedLayout(input: CommandManagedLayoutInput): Promise<ManagedLayoutDocument>;
829
+ publishManagedLayout(input: PublishManagedLayoutInput): Promise<ManagedLayoutDocument>;
817
830
  /** Write, rewrite, or translate a piece of copy. Returns the suggested text. */
818
831
  writeContent(input: WriteContentInput): Promise<string>;
819
832
  /** Generate SEO metadata for a piece of content (title, description, keywords, JSON-LD). */
@@ -943,6 +956,13 @@ interface CreateClientOptions {
943
956
  * deep-link each rendered value back to its editor. Requires `perspective: "drafts"`,
944
957
  * and then either a `previewToken` or a `content:read:draft` key. Ignored on published
945
958
  * reads — the payload must never reach a production build.
959
+ *
960
+ * **Defaults to `true` on `perspective: "drafts"`** (since 1.15.0). Provenance is the whole
961
+ * reason the drafts perspective exists in a preview build, and an option nobody knew to pass
962
+ * meant every such build rendered anonymous strings: the editor could bind them only by
963
+ * guessing at their text. It stays OFF on every other perspective, unconditionally, so a
964
+ * published build cannot acquire a payload by accident — pass `stega: false` to opt a draft
965
+ * read out (a diff or a checksum over draft content is the case that wants it).
946
966
  */
947
967
  stega?: boolean;
948
968
  /** Per-attempt timeout in ms. Defaults to 10000. */
@@ -1411,4 +1431,4 @@ declare function inviteMember(client: BetterCMSAdminClient, workspaceId: string,
1411
1431
  declare function updateMemberRole(client: BetterCMSAdminClient, workspaceId: string, memberId: string, role: MemberRole): Promise<Member>;
1412
1432
  declare function removeMember(client: BetterCMSAdminClient, workspaceId: string, memberId: string): Promise<void>;
1413
1433
 
1414
- 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 ManagedContentEntry, type ManagedContentModel, type ManagedForm, type ManagedFormInput, type ManagedLayoutClient, type ManagedLayoutDocument, type ManagedPage, type ManagementClient, type MediaListOptions, type MediaMetadata, type Member, type MemberRole, PORTABLE_TEXT_FORMAT, type PageListOptions, type PendingInvite, 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 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, 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, publishPage, regenerateApiKey, removeMember, resolveSeo, revokeApiKey, rich, search, setPageContent, shouldShowField, signIn, signInWithGithub, signInWithGoogle, signUp, stripStega, submitForm, toggleOption, updateApiKey, updateEntry, updateForm, updateMemberRole, updateModel, updatePage, updateWorkspace, uploadMedia };
1434
+ 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 ManagedContentEntry, type ManagedContentModel, type ManagedForm, type ManagedFormInput, type ManagedLayoutClient, type ManagedLayoutDocument, 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 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, 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 };
package/dist/index.d.ts CHANGED
@@ -723,6 +723,18 @@ interface CommandManagedLayoutInput extends GetManagedLayoutOptions {
723
723
  }
724
724
  declare function getManagedLayout(client: ManagedLayoutClient, opts?: GetManagedLayoutOptions): Promise<ManagedLayoutDocument>;
725
725
  declare function commandManagedLayout(client: ManagedLayoutClient, input: CommandManagedLayoutInput): Promise<ManagedLayoutDocument>;
726
+ interface PublishManagedLayoutInput {
727
+ /** The revision from getManagedLayout (scope global). A stale one is a 409. */
728
+ ifMatch: number;
729
+ /** Required when the management credential is workspace-scoped. */
730
+ projectId?: string;
731
+ }
732
+ /**
733
+ * Publish the Global Layout draft. Page overrides are not published here — they go live
734
+ * with their page. The response echoes `copy: "published"`, but that is the write's echo:
735
+ * a publish claim still verifies only via getManagedLayout({ copy: "published" }).
736
+ */
737
+ declare function publishManagedLayout(client: ManagedLayoutClient, input: PublishManagedLayoutInput): Promise<ManagedLayoutDocument>;
726
738
 
727
739
  interface BetterCMSManagementOptions {
728
740
  /** Base URL of the Management API. Defaults to https://api.bettercms.ai/v1 */
@@ -814,6 +826,7 @@ declare class BetterCMSManagementClient extends BetterCMSDeliveryClient {
814
826
  }>;
815
827
  getManagedLayout(opts?: GetManagedLayoutOptions): Promise<ManagedLayoutDocument>;
816
828
  commandManagedLayout(input: CommandManagedLayoutInput): Promise<ManagedLayoutDocument>;
829
+ publishManagedLayout(input: PublishManagedLayoutInput): Promise<ManagedLayoutDocument>;
817
830
  /** Write, rewrite, or translate a piece of copy. Returns the suggested text. */
818
831
  writeContent(input: WriteContentInput): Promise<string>;
819
832
  /** Generate SEO metadata for a piece of content (title, description, keywords, JSON-LD). */
@@ -943,6 +956,13 @@ interface CreateClientOptions {
943
956
  * deep-link each rendered value back to its editor. Requires `perspective: "drafts"`,
944
957
  * and then either a `previewToken` or a `content:read:draft` key. Ignored on published
945
958
  * reads — the payload must never reach a production build.
959
+ *
960
+ * **Defaults to `true` on `perspective: "drafts"`** (since 1.15.0). Provenance is the whole
961
+ * reason the drafts perspective exists in a preview build, and an option nobody knew to pass
962
+ * meant every such build rendered anonymous strings: the editor could bind them only by
963
+ * guessing at their text. It stays OFF on every other perspective, unconditionally, so a
964
+ * published build cannot acquire a payload by accident — pass `stega: false` to opt a draft
965
+ * read out (a diff or a checksum over draft content is the case that wants it).
946
966
  */
947
967
  stega?: boolean;
948
968
  /** Per-attempt timeout in ms. Defaults to 10000. */
@@ -1411,4 +1431,4 @@ declare function inviteMember(client: BetterCMSAdminClient, workspaceId: string,
1411
1431
  declare function updateMemberRole(client: BetterCMSAdminClient, workspaceId: string, memberId: string, role: MemberRole): Promise<Member>;
1412
1432
  declare function removeMember(client: BetterCMSAdminClient, workspaceId: string, memberId: string): Promise<void>;
1413
1433
 
1414
- 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 ManagedContentEntry, type ManagedContentModel, type ManagedForm, type ManagedFormInput, type ManagedLayoutClient, type ManagedLayoutDocument, type ManagedPage, type ManagementClient, type MediaListOptions, type MediaMetadata, type Member, type MemberRole, PORTABLE_TEXT_FORMAT, type PageListOptions, type PendingInvite, 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 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, 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, publishPage, regenerateApiKey, removeMember, resolveSeo, revokeApiKey, rich, search, setPageContent, shouldShowField, signIn, signInWithGithub, signInWithGoogle, signUp, stripStega, submitForm, toggleOption, updateApiKey, updateEntry, updateForm, updateMemberRole, updateModel, updatePage, updateWorkspace, uploadMedia };
1434
+ 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 ManagedContentEntry, type ManagedContentModel, type ManagedForm, type ManagedFormInput, type ManagedLayoutClient, type ManagedLayoutDocument, 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 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, 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 };
package/dist/index.js CHANGED
@@ -787,6 +787,14 @@ async function commandManagedLayout(client, input) {
787
787
  });
788
788
  return result.data;
789
789
  }
790
+ async function publishManagedLayout(client, input) {
791
+ const result = await client.fetchJSON(client.url("/management/layout/publish"), {
792
+ method: "POST",
793
+ headers: { "If-Match": `W/"${input.ifMatch}"`, ...input.projectId ? { "X-BCMS-Project": input.projectId } : {} },
794
+ body: JSON.stringify({ scope: "global" })
795
+ });
796
+ return result.data;
797
+ }
790
798
 
791
799
  // src/management-client.ts
792
800
  var DEFAULT_BASE_URL2 = "https://api.bettercms.ai/v1";
@@ -962,13 +970,16 @@ var BetterCMSManagementClient = class extends BetterCMSDeliveryClient {
962
970
  extractComponent(input) {
963
971
  return extractComponent(this, input);
964
972
  }
965
- // ── Layout: draft-only Global/page authoring; publishing remains dashboard-gated. ──
973
+ // ── Layout: Global/page draft authoring + Global Layout publish (page overrides go live with the page). ──
966
974
  getManagedLayout(opts) {
967
975
  return getManagedLayout(this, opts);
968
976
  }
969
977
  commandManagedLayout(input) {
970
978
  return commandManagedLayout(this, input);
971
979
  }
980
+ publishManagedLayout(input) {
981
+ return publishManagedLayout(this, input);
982
+ }
972
983
  // ── AI (Option B): write/rewrite/translate copy + generate SEO meta (BYOK-metered) ──
973
984
  /** Write, rewrite, or translate a piece of copy. Returns the suggested text. */
974
985
  writeContent(input) {
@@ -1189,6 +1200,7 @@ function createClient(options) {
1189
1200
  throw lastError ?? new BetterCMSError("Unreachable", 0, "NETWORK_ERROR");
1190
1201
  }
1191
1202
  const draft = perspective === "drafts";
1203
+ const stega = options.stega ?? draft;
1192
1204
  return {
1193
1205
  perspective,
1194
1206
  async getEntry(slug, opts) {
@@ -1196,12 +1208,12 @@ function createClient(options) {
1196
1208
  token: previewToken,
1197
1209
  depth: opts?.depth,
1198
1210
  select: opts?.select?.join(","),
1199
- stega: options.stega ? "1" : void 0
1211
+ stega: stega ? "1" : void 0
1200
1212
  })}` : `${base}/content-entries/${encodeURIComponent(slug)}${qs({
1201
1213
  depth: opts?.depth,
1202
1214
  select: opts?.select?.join(","),
1203
1215
  perspective: draft ? "draft" : void 0,
1204
- stega: draft && options.stega ? "1" : void 0
1216
+ stega: draft && stega ? "1" : void 0
1205
1217
  })}`;
1206
1218
  return unwrap(await fetchJSON(url));
1207
1219
  },
@@ -1213,7 +1225,7 @@ function createClient(options) {
1213
1225
  depth: opts?.depth,
1214
1226
  select: opts?.select?.join(","),
1215
1227
  perspective: draft ? "draft" : void 0,
1216
- stega: draft && options.stega ? "1" : void 0
1228
+ stega: draft && stega ? "1" : void 0
1217
1229
  })}`;
1218
1230
  return unwrap(await fetchJSON(url));
1219
1231
  },
@@ -1339,7 +1351,21 @@ function derivedCanonical({ siteUrl, path }) {
1339
1351
  function jsonLdNodes(schema) {
1340
1352
  if (!schema) return [];
1341
1353
  const arr = Array.isArray(schema) ? schema : [schema];
1342
- return arr.filter((node) => node && Object.keys(node).length > 0);
1354
+ const out = [];
1355
+ for (const node of arr) {
1356
+ if (!node || Object.keys(node).length === 0) continue;
1357
+ const graph = node["@graph"];
1358
+ if (Array.isArray(graph)) {
1359
+ for (const child of graph) {
1360
+ if (child && typeof child === "object" && !Array.isArray(child) && Object.keys(child).length > 0) {
1361
+ out.push(child);
1362
+ }
1363
+ }
1364
+ continue;
1365
+ }
1366
+ out.push(node);
1367
+ }
1368
+ return out;
1343
1369
  }
1344
1370
  function resolveSeo(page, defaults = {}, location = {}) {
1345
1371
  const meta = page.metaJson ?? {};
@@ -1742,6 +1768,7 @@ export {
1742
1768
  listWorkspaces,
1743
1769
  plain,
1744
1770
  portableText,
1771
+ publishManagedLayout,
1745
1772
  publishPage,
1746
1773
  regenerateApiKey,
1747
1774
  removeMember,