@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/README.md +34 -0
- package/dist/index.cjs +33 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -1
- package/dist/index.d.ts +21 -1
- package/dist/index.js +32 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -85,6 +85,40 @@ try {
|
|
|
85
85
|
}
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
+
## Draft previews and visual editing
|
|
89
|
+
|
|
90
|
+
A client created with `perspective: "drafts"` reads unpublished content — through a
|
|
91
|
+
`content:read:draft` API key, or through a `previewToken` minted for one document.
|
|
92
|
+
|
|
93
|
+
Draft reads also carry **stega provenance**: invisible zero-width characters appended to every
|
|
94
|
+
prose value, naming the entry and field it came from. That is what lets the dashboard's canvas
|
|
95
|
+
(and the `<VisualEditing>` overlay) map a rendered string back to its editor without guessing at
|
|
96
|
+
its text. It is **on by default for `perspective: "drafts"` from 1.15.0** — before that it had to
|
|
97
|
+
be asked for, and a preview build that did not know to ask rendered anonymous strings.
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
const draft = createClient({
|
|
101
|
+
apiUrl,
|
|
102
|
+
workspace: "my-workspace",
|
|
103
|
+
apiKey: process.env.BETTERCMS_DRAFT_KEY,
|
|
104
|
+
perspective: "drafts", // stega is on
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Opt out — e.g. when diffing or checksumming draft content, where the invisible
|
|
108
|
+
// characters would show up as differences.
|
|
109
|
+
const plain = createClient({
|
|
110
|
+
apiUrl,
|
|
111
|
+
workspace: "my-workspace",
|
|
112
|
+
apiKey: process.env.BETTERCMS_DRAFT_KEY,
|
|
113
|
+
perspective: "drafts",
|
|
114
|
+
stega: false,
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Published reads never carry provenance, whatever `stega` is set to: the payload must not reach a
|
|
119
|
+
production build. Strip it yourself with `stripStega(value)` if you need the clean string, and
|
|
120
|
+
decode it with `decodeStega(value)`.
|
|
121
|
+
|
|
88
122
|
## API
|
|
89
123
|
|
|
90
124
|
### `BetterCMS.site(options)`
|
package/dist/index.cjs
CHANGED
|
@@ -89,6 +89,7 @@ __export(index_exports, {
|
|
|
89
89
|
listWorkspaces: () => listWorkspaces,
|
|
90
90
|
plain: () => plain,
|
|
91
91
|
portableText: () => portableText,
|
|
92
|
+
publishManagedLayout: () => publishManagedLayout,
|
|
92
93
|
publishPage: () => publishPage,
|
|
93
94
|
regenerateApiKey: () => regenerateApiKey,
|
|
94
95
|
removeMember: () => removeMember,
|
|
@@ -905,6 +906,14 @@ async function commandManagedLayout(client, input) {
|
|
|
905
906
|
});
|
|
906
907
|
return result.data;
|
|
907
908
|
}
|
|
909
|
+
async function publishManagedLayout(client, input) {
|
|
910
|
+
const result = await client.fetchJSON(client.url("/management/layout/publish"), {
|
|
911
|
+
method: "POST",
|
|
912
|
+
headers: { "If-Match": `W/"${input.ifMatch}"`, ...input.projectId ? { "X-BCMS-Project": input.projectId } : {} },
|
|
913
|
+
body: JSON.stringify({ scope: "global" })
|
|
914
|
+
});
|
|
915
|
+
return result.data;
|
|
916
|
+
}
|
|
908
917
|
|
|
909
918
|
// src/management-client.ts
|
|
910
919
|
var DEFAULT_BASE_URL2 = "https://api.bettercms.ai/v1";
|
|
@@ -1080,13 +1089,16 @@ var BetterCMSManagementClient = class extends BetterCMSDeliveryClient {
|
|
|
1080
1089
|
extractComponent(input) {
|
|
1081
1090
|
return extractComponent(this, input);
|
|
1082
1091
|
}
|
|
1083
|
-
// ── Layout:
|
|
1092
|
+
// ── Layout: Global/page draft authoring + Global Layout publish (page overrides go live with the page). ──
|
|
1084
1093
|
getManagedLayout(opts) {
|
|
1085
1094
|
return getManagedLayout(this, opts);
|
|
1086
1095
|
}
|
|
1087
1096
|
commandManagedLayout(input) {
|
|
1088
1097
|
return commandManagedLayout(this, input);
|
|
1089
1098
|
}
|
|
1099
|
+
publishManagedLayout(input) {
|
|
1100
|
+
return publishManagedLayout(this, input);
|
|
1101
|
+
}
|
|
1090
1102
|
// ── AI (Option B): write/rewrite/translate copy + generate SEO meta (BYOK-metered) ──
|
|
1091
1103
|
/** Write, rewrite, or translate a piece of copy. Returns the suggested text. */
|
|
1092
1104
|
writeContent(input) {
|
|
@@ -1307,6 +1319,7 @@ function createClient(options) {
|
|
|
1307
1319
|
throw lastError ?? new BetterCMSError("Unreachable", 0, "NETWORK_ERROR");
|
|
1308
1320
|
}
|
|
1309
1321
|
const draft = perspective === "drafts";
|
|
1322
|
+
const stega = options.stega ?? draft;
|
|
1310
1323
|
return {
|
|
1311
1324
|
perspective,
|
|
1312
1325
|
async getEntry(slug, opts) {
|
|
@@ -1314,12 +1327,12 @@ function createClient(options) {
|
|
|
1314
1327
|
token: previewToken,
|
|
1315
1328
|
depth: opts?.depth,
|
|
1316
1329
|
select: opts?.select?.join(","),
|
|
1317
|
-
stega:
|
|
1330
|
+
stega: stega ? "1" : void 0
|
|
1318
1331
|
})}` : `${base}/content-entries/${encodeURIComponent(slug)}${qs({
|
|
1319
1332
|
depth: opts?.depth,
|
|
1320
1333
|
select: opts?.select?.join(","),
|
|
1321
1334
|
perspective: draft ? "draft" : void 0,
|
|
1322
|
-
stega: draft &&
|
|
1335
|
+
stega: draft && stega ? "1" : void 0
|
|
1323
1336
|
})}`;
|
|
1324
1337
|
return unwrap(await fetchJSON(url));
|
|
1325
1338
|
},
|
|
@@ -1331,7 +1344,7 @@ function createClient(options) {
|
|
|
1331
1344
|
depth: opts?.depth,
|
|
1332
1345
|
select: opts?.select?.join(","),
|
|
1333
1346
|
perspective: draft ? "draft" : void 0,
|
|
1334
|
-
stega: draft &&
|
|
1347
|
+
stega: draft && stega ? "1" : void 0
|
|
1335
1348
|
})}`;
|
|
1336
1349
|
return unwrap(await fetchJSON(url));
|
|
1337
1350
|
},
|
|
@@ -1457,7 +1470,21 @@ function derivedCanonical({ siteUrl, path }) {
|
|
|
1457
1470
|
function jsonLdNodes(schema) {
|
|
1458
1471
|
if (!schema) return [];
|
|
1459
1472
|
const arr = Array.isArray(schema) ? schema : [schema];
|
|
1460
|
-
|
|
1473
|
+
const out = [];
|
|
1474
|
+
for (const node of arr) {
|
|
1475
|
+
if (!node || Object.keys(node).length === 0) continue;
|
|
1476
|
+
const graph = node["@graph"];
|
|
1477
|
+
if (Array.isArray(graph)) {
|
|
1478
|
+
for (const child of graph) {
|
|
1479
|
+
if (child && typeof child === "object" && !Array.isArray(child) && Object.keys(child).length > 0) {
|
|
1480
|
+
out.push(child);
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
continue;
|
|
1484
|
+
}
|
|
1485
|
+
out.push(node);
|
|
1486
|
+
}
|
|
1487
|
+
return out;
|
|
1461
1488
|
}
|
|
1462
1489
|
function resolveSeo(page, defaults = {}, location = {}) {
|
|
1463
1490
|
const meta = page.metaJson ?? {};
|
|
@@ -1861,6 +1888,7 @@ var import_types = require("@bettercms-ai/types");
|
|
|
1861
1888
|
listWorkspaces,
|
|
1862
1889
|
plain,
|
|
1863
1890
|
portableText,
|
|
1891
|
+
publishManagedLayout,
|
|
1864
1892
|
publishPage,
|
|
1865
1893
|
regenerateApiKey,
|
|
1866
1894
|
removeMember,
|