@bettercms-ai/sdk 1.19.0 → 1.21.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.cjs +85 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +205 -15
- package/dist/index.d.ts +205 -15
- package/dist/index.js +84 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
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, 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
|
|
|
@@ -223,6 +223,8 @@ interface ManagedContentModel {
|
|
|
223
223
|
name: string;
|
|
224
224
|
slug: string;
|
|
225
225
|
description: string | null;
|
|
226
|
+
/** Public URL of one entry, e.g. `/blog/:slug` (`:slug` is the entry's slug). Null = none. */
|
|
227
|
+
urlPattern?: string | null;
|
|
226
228
|
fields: ContentModelField[];
|
|
227
229
|
createdAt: string;
|
|
228
230
|
updatedAt: string;
|
|
@@ -274,6 +276,11 @@ interface CreateManagedPageInput {
|
|
|
274
276
|
/** Append fields to an existing page's schema (additive — see addPageFields). */
|
|
275
277
|
interface AddPageFieldsInput {
|
|
276
278
|
addFields: ContentModelField[];
|
|
279
|
+
/**
|
|
280
|
+
* Optional insertion point: the key of an existing TOP-LEVEL field to insert after. Omit to
|
|
281
|
+
* append (the default). An unknown key is refused by the API, never silently appended.
|
|
282
|
+
*/
|
|
283
|
+
after?: string;
|
|
277
284
|
}
|
|
278
285
|
interface CreateModelInput {
|
|
279
286
|
name: string;
|
|
@@ -289,12 +296,27 @@ interface CreateModelInput {
|
|
|
289
296
|
* a block would orphan every entry it already has.
|
|
290
297
|
*/
|
|
291
298
|
kind?: "model" | "block";
|
|
299
|
+
/** Editor-only field grouping. Fields join one with `fieldsetId`. Order is the array index. */
|
|
300
|
+
fieldsets?: ModelFieldset[];
|
|
301
|
+
/** Public URL of one entry, e.g. `/blog/:slug`: starts with `/`, contains `:slug` exactly once. */
|
|
302
|
+
urlPattern?: string | null;
|
|
303
|
+
}
|
|
304
|
+
/** A named, editor-only group of a model's fields. Same shape as the dashboard's `Fieldset`. */
|
|
305
|
+
interface ModelFieldset {
|
|
306
|
+
id: string;
|
|
307
|
+
name: string;
|
|
308
|
+
/** One line shown under the card title in the editor, at most 500 characters. */
|
|
309
|
+
description?: string;
|
|
292
310
|
}
|
|
293
311
|
interface UpdateModelInput {
|
|
294
312
|
name?: string;
|
|
295
313
|
slug?: string;
|
|
296
314
|
description?: string;
|
|
297
315
|
fields?: ContentModelField[];
|
|
316
|
+
/** Replaces the fieldset list. `null` drops every fieldset. Sent alone, it leaves `fields` untouched. */
|
|
317
|
+
fieldsets?: ModelFieldset[] | null;
|
|
318
|
+
/** Public URL of one entry, e.g. `/blog/:slug`. `null` (or "") clears it. */
|
|
319
|
+
urlPattern?: string | null;
|
|
298
320
|
}
|
|
299
321
|
interface CreateEntryInput {
|
|
300
322
|
contentModelId: string;
|
|
@@ -308,6 +330,27 @@ interface UpdateEntryInput {
|
|
|
308
330
|
status?: "draft" | "published";
|
|
309
331
|
data?: Record<string, unknown>;
|
|
310
332
|
pageId?: string | null;
|
|
333
|
+
/** The entry's native SEO. Merges into what is stored: an omitted key is kept, null or "" clears it. */
|
|
334
|
+
meta?: {
|
|
335
|
+
metaTitle?: string | null;
|
|
336
|
+
metaDescription?: string | null;
|
|
337
|
+
noindex?: boolean;
|
|
338
|
+
canonical?: string | null;
|
|
339
|
+
og?: {
|
|
340
|
+
title?: string | null;
|
|
341
|
+
description?: string | null;
|
|
342
|
+
image?: string | null;
|
|
343
|
+
type?: string | null;
|
|
344
|
+
} | null;
|
|
345
|
+
twitter?: {
|
|
346
|
+
card?: string | null;
|
|
347
|
+
title?: string | null;
|
|
348
|
+
description?: string | null;
|
|
349
|
+
image?: string | null;
|
|
350
|
+
} | null;
|
|
351
|
+
schemaType?: string | null;
|
|
352
|
+
schema?: Record<string, unknown> | Array<Record<string, unknown>> | null;
|
|
353
|
+
};
|
|
311
354
|
}
|
|
312
355
|
/** Set a page's field VALUES (the actual content). For a singleton, upserts its one entry. */
|
|
313
356
|
interface SetPageContentInput {
|
|
@@ -354,14 +397,21 @@ declare function createModel(client: ManagementClient, input: CreateModelInput):
|
|
|
354
397
|
/** Update a content model (additive — fields/name/slug/description). */
|
|
355
398
|
declare function updateModel(client: ManagementClient, id: string, input: UpdateModelInput): Promise<ManagedContentModel>;
|
|
356
399
|
/** Create a content entry under a model. */
|
|
357
|
-
|
|
400
|
+
/**
|
|
401
|
+
* Advisory notes the server attached to a write — e.g. `REFERENCE_NOT_FOUND: …` for a reference
|
|
402
|
+
* whose target was deleted. The write succeeded; present only when there is something to say.
|
|
403
|
+
*/
|
|
404
|
+
type EntryWriteWarnings = {
|
|
405
|
+
warnings?: string[];
|
|
406
|
+
};
|
|
407
|
+
declare function createEntry(client: ManagementClient, input: CreateEntryInput): Promise<ManagedContentEntry & EntryWriteWarnings>;
|
|
358
408
|
/**
|
|
359
409
|
* Update a content entry. If `opts.ifMatch` (current optimisticVersion) is supplied,
|
|
360
410
|
* the update is optimistic-locked; omit it for programmatic last-write-wins.
|
|
361
411
|
*/
|
|
362
412
|
declare function updateEntry(client: ManagementClient, id: string, input: UpdateEntryInput, opts?: {
|
|
363
413
|
ifMatch?: number;
|
|
364
|
-
}): Promise<ManagedContentEntry>;
|
|
414
|
+
}): Promise<ManagedContentEntry & EntryWriteWarnings>;
|
|
365
415
|
|
|
366
416
|
/**
|
|
367
417
|
* Management API SDK method — media upload (P2).
|
|
@@ -385,6 +435,12 @@ interface UploadAssetInput {
|
|
|
385
435
|
filename?: string;
|
|
386
436
|
altText?: string;
|
|
387
437
|
caption?: string;
|
|
438
|
+
/**
|
|
439
|
+
* Video/audio only: the spoken words (≤ 100,000 characters). Stored on the asset and published
|
|
440
|
+
* wherever the file is used. Sent as a second JSON call after the upload, because it is too
|
|
441
|
+
* long for the upload's query string.
|
|
442
|
+
*/
|
|
443
|
+
transcript?: string;
|
|
388
444
|
/** Target Media Library folder id (defaults to project root). */
|
|
389
445
|
folderId?: string;
|
|
390
446
|
}
|
|
@@ -393,6 +449,27 @@ interface UploadedAsset {
|
|
|
393
449
|
url: string;
|
|
394
450
|
key: string;
|
|
395
451
|
filename: string;
|
|
452
|
+
/** Present when a transcript was written with the upload. */
|
|
453
|
+
transcript?: string;
|
|
454
|
+
}
|
|
455
|
+
/** Describe an existing asset. `null` clears a field; an omitted key is left alone. */
|
|
456
|
+
interface UpdateAssetInput {
|
|
457
|
+
altText?: string | null;
|
|
458
|
+
caption?: string | null;
|
|
459
|
+
/** Video/audio only, ≤ 100,000 characters. */
|
|
460
|
+
transcript?: string | null;
|
|
461
|
+
}
|
|
462
|
+
interface ManagedMediaAsset {
|
|
463
|
+
id: string;
|
|
464
|
+
url: string;
|
|
465
|
+
filename: string;
|
|
466
|
+
mimeType: string;
|
|
467
|
+
sizeBytes: number;
|
|
468
|
+
altText: string | null;
|
|
469
|
+
caption: string | null;
|
|
470
|
+
transcript: string | null;
|
|
471
|
+
folderId: string | null;
|
|
472
|
+
createdAt: string;
|
|
396
473
|
}
|
|
397
474
|
|
|
398
475
|
/** Semantic error codes used by the SDK. */
|
|
@@ -498,6 +575,75 @@ interface DeliveryFormField {
|
|
|
498
575
|
* trip — the server check is the one that counts.
|
|
499
576
|
*/
|
|
500
577
|
validation?: DeliveryFormFieldValidation;
|
|
578
|
+
/**
|
|
579
|
+
* Presentation options the renderer honours. Unlike `validation`, the API does NOT enforce
|
|
580
|
+
* these on submit — they change what the visitor is shown, not what is accepted.
|
|
581
|
+
*/
|
|
582
|
+
ui?: DeliveryFormFieldUi;
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* @see FormFieldUi in @bettercms-ai/types — same shape, delivered to the site.
|
|
586
|
+
*
|
|
587
|
+
* ── The phone composition contract every renderer implements ──
|
|
588
|
+
*
|
|
589
|
+
* A picker-enabled phone field is rendered as a country control PLUS a `tel` input, but it
|
|
590
|
+
* submits ONE value under the field's own key, in E.164. Whatever a renderer uses to hold the
|
|
591
|
+
* country (a React state, a `{key}__country` select) is scaffolding: it must never reach the
|
|
592
|
+
* POST body.
|
|
593
|
+
*
|
|
594
|
+
* Composition, from the visible input's raw text:
|
|
595
|
+
* - empty → `""`. NEVER `"+CC"`, and the reason is worse than "the server rejects it". The
|
|
596
|
+
* server's loose phone shape is `{3,32}` chars, so the outcome depends on the calling
|
|
597
|
+
* code's length: `"+1"` is REFUSED (an optional untouched field starts 400ing), while
|
|
598
|
+
* `"+91"` is ACCEPTED and stored as a real-looking submission that is only a country code.
|
|
599
|
+
* The silent case is the dangerous one. Pinned in `__tests__/lib/forms-validate.test.ts`.
|
|
600
|
+
* - starts with `"+"` → `"+" + digits(raw)`. The visitor typed an international number; the
|
|
601
|
+
* country control is ignored rather than fighting them.
|
|
602
|
+
* - otherwise → `"+" + callingCode + digits(raw).replace(/^0/, "")`, dropping ONE trunk zero.
|
|
603
|
+
* Known exception: Italian landlines keep their trunk zero, so this loses it. The value is
|
|
604
|
+
* still accepted (shape-only check) — it is a formatting loss, not a refusal.
|
|
605
|
+
*
|
|
606
|
+
* `ui` changes what the visitor SEES. It never changes what the API accepts: enforcing a format
|
|
607
|
+
* is `validation.phoneFormat`'s job and the two are independent.
|
|
608
|
+
*
|
|
609
|
+
* Renderer parity is behavioural, not implementational. FIVE lanes render this field, and they
|
|
610
|
+
* agree on the VALUE, not on the implementation:
|
|
611
|
+
*
|
|
612
|
+
* | Lane | Control | As-you-type formatting |
|
|
613
|
+
* |-------------------------------|---------------------------------|------------------------|
|
|
614
|
+
* | dashboard form preview | searchable picker + formatter | yes |
|
|
615
|
+
* | @bettercms-ai/next <BcmsForm> | native select + formatter | yes (lazy chunk) |
|
|
616
|
+
* | hosted sites (render-page) | native select + tel input | NO |
|
|
617
|
+
* | embed snippet | native select + tel input | NO |
|
|
618
|
+
* | @bettercms-ai/astro BcmsForm | native select + tel input | NO |
|
|
619
|
+
*
|
|
620
|
+
* The missing as-you-type formatting on the three vanilla lanes is a NAMED degradation, not an
|
|
621
|
+
* oversight: it is what keeps libphonenumber off a visitor's page entirely. `packages/next`
|
|
622
|
+
* pays for it only on pages that actually render a picker, via a separate chunk.
|
|
623
|
+
*
|
|
624
|
+
* When a lane builds that option list, never pass a libphonenumber helper as a bare callback:
|
|
625
|
+
* `getCountries().filter(isSupportedCountry)` hands it the array INDEX as its `metadata`
|
|
626
|
+
* argument and throws. Always wrap — `.filter((iso) => isSupportedCountry(iso))`.
|
|
627
|
+
*
|
|
628
|
+
* And when a lane ships the composition rule inside a JS TEMPLATE LITERAL (the embed snippet
|
|
629
|
+
* does), `\D` collapses to `D` and the regex silently becomes `/D/g` — stripping the letter D
|
|
630
|
+
* and leaving every other separator in place. Write `\\D` there. Raw HTML `<script>` text (the
|
|
631
|
+
* hosted renderer, the Astro inline script) takes a single backslash. Nothing throws either
|
|
632
|
+
* way; numbers just arrive malformed, so each lane pins it with an executed-script test.
|
|
633
|
+
*/
|
|
634
|
+
interface DeliveryFormFieldUi {
|
|
635
|
+
/** `phone` — render a country picker beside the number. The submitted value is E.164. */
|
|
636
|
+
countryPicker?: boolean;
|
|
637
|
+
/** `phone` — uppercase ISO 3166-1 alpha-2 the picker starts on. */
|
|
638
|
+
defaultCountry?: string;
|
|
639
|
+
/**
|
|
640
|
+
* `phone` — show the country's flag beside the dialling code.
|
|
641
|
+
*
|
|
642
|
+
* Honoured only by a renderer with a custom picker. The native `<select>` the site lanes use
|
|
643
|
+
* cannot hold an SVG, and an emoji flag renders as two grey letters on Windows, so those
|
|
644
|
+
* lanes show the country NAME instead — the same information, legibly, everywhere.
|
|
645
|
+
*/
|
|
646
|
+
showFlags?: boolean;
|
|
501
647
|
}
|
|
502
648
|
/** @see FormFieldValidation in @bettercms-ai/types — same shape, delivered to the site. */
|
|
503
649
|
interface DeliveryFormFieldValidation {
|
|
@@ -593,6 +739,14 @@ interface ManagedFormInput {
|
|
|
593
739
|
submitLabel?: string;
|
|
594
740
|
successMessage?: string;
|
|
595
741
|
redirectUrl?: string;
|
|
742
|
+
/** Require a Cloudflare Turnstile check on submit. Its secret key is set in the dashboard only. */
|
|
743
|
+
turnstileEnabled?: boolean;
|
|
744
|
+
/** Name of a hidden field that must stay empty; a filled one marks the submission as spam. */
|
|
745
|
+
honeypotField?: string | null;
|
|
746
|
+
/** Addresses notified of each submission. */
|
|
747
|
+
notifyEmails?: string[];
|
|
748
|
+
/** URL that receives each submission as a POST. */
|
|
749
|
+
webhookUrl?: string | null;
|
|
596
750
|
}
|
|
597
751
|
|
|
598
752
|
/**
|
|
@@ -819,10 +973,10 @@ declare class BetterCMSManagementClient extends BetterCMSDeliveryClient {
|
|
|
819
973
|
setPageContent(id: string, input: SetPageContentInput): Promise<ManagedContentEntry>;
|
|
820
974
|
/** Append fields to a content model (additive — rejects existing keys). */
|
|
821
975
|
addModelFields(id: string, input: AddPageFieldsInput): Promise<ManagedContentModel>;
|
|
822
|
-
createEntry(input: CreateEntryInput): Promise<ManagedContentEntry>;
|
|
976
|
+
createEntry(input: CreateEntryInput): Promise<ManagedContentEntry & EntryWriteWarnings>;
|
|
823
977
|
updateEntry(id: string, input: UpdateEntryInput, opts?: {
|
|
824
978
|
ifMatch?: number;
|
|
825
|
-
}): Promise<ManagedContentEntry>;
|
|
979
|
+
}): Promise<ManagedContentEntry & EntryWriteWarnings>;
|
|
826
980
|
/** Soft-delete a page and its content entries. */
|
|
827
981
|
deletePage(id: string): Promise<{
|
|
828
982
|
id: string;
|
|
@@ -840,6 +994,8 @@ declare class BetterCMSManagementClient extends BetterCMSDeliveryClient {
|
|
|
840
994
|
/** Get one content entry by id INCLUDING its data (incl. drafts). */
|
|
841
995
|
getEntry(id: string): Promise<ManagedContentEntry>;
|
|
842
996
|
uploadAsset(input: UploadAssetInput): Promise<UploadedAsset>;
|
|
997
|
+
/** Set an asset's alt text, caption or transcript (video/audio only). `null` clears. */
|
|
998
|
+
updateAsset(id: string, input: UpdateAssetInput): Promise<ManagedMediaAsset>;
|
|
843
999
|
/** List forms in the key's project (or workspace-level). */
|
|
844
1000
|
listForms(): Promise<ManagedForm[]>;
|
|
845
1001
|
/** Get one form by id INCLUDING its field schema + settings. */
|
|
@@ -1213,6 +1369,10 @@ interface SeoInput {
|
|
|
1213
1369
|
metaTitle?: string | null;
|
|
1214
1370
|
metaDescription?: string | null;
|
|
1215
1371
|
metaJson?: PageMetaJson | null;
|
|
1372
|
+
/** `"home"` makes the Automatic JSON-LD a WebSite, as the hosted renderer does. */
|
|
1373
|
+
slug?: string | null;
|
|
1374
|
+
/** Exclude from search engines. Surfaces as `ResolvedSeo.noindex` / `robots`. */
|
|
1375
|
+
noindex?: boolean | null;
|
|
1216
1376
|
}
|
|
1217
1377
|
/** Fully-resolved SEO values, page-over-site. Empty string ⇒ omit that tag. */
|
|
1218
1378
|
interface ResolvedSeo {
|
|
@@ -1238,9 +1398,33 @@ interface ResolvedSeo {
|
|
|
1238
1398
|
image: string;
|
|
1239
1399
|
site: string;
|
|
1240
1400
|
};
|
|
1241
|
-
/**
|
|
1401
|
+
/**
|
|
1402
|
+
* JSON-LD nodes (site schema first, then the page's), already flattened + de-empted. The page's
|
|
1403
|
+
* part follows the renderer's precedence: Custom (`metaJson.schema`) > `metaJson.schemaType` >
|
|
1404
|
+
* Automatic (WebPage; WebSite on the home page).
|
|
1405
|
+
*/
|
|
1242
1406
|
jsonLd: Array<Record<string, unknown>>;
|
|
1407
|
+
/** True when the page is excluded from search engines (the renderer's `<meta name="robots" content="noindex">`). */
|
|
1408
|
+
noindex: boolean;
|
|
1409
|
+
/** `noindex` in the `{ index, follow }` shape Next's `Metadata.robots` takes. */
|
|
1410
|
+
robots: {
|
|
1411
|
+
index: boolean;
|
|
1412
|
+
follow: boolean;
|
|
1413
|
+
};
|
|
1243
1414
|
}
|
|
1415
|
+
/**
|
|
1416
|
+
* A Delivery API entry as a `resolveSeo` input. The server already resolved the collection
|
|
1417
|
+
* template's `{{field}}` tokens for this entry and merged the entry's own SEO over it, so this is
|
|
1418
|
+
* a reshape, not a resolver:
|
|
1419
|
+
*
|
|
1420
|
+
* const entry = await bcms.getEntry("astro");
|
|
1421
|
+
* const seo = resolveSeo(entrySeoInput(entry), siteDefaults, { siteUrl, path: `/tags/${entry.slug}` });
|
|
1422
|
+
* // seo.jsonLd holds the template's schema, resolved for this entry
|
|
1423
|
+
*/
|
|
1424
|
+
declare function entrySeoInput(entry: {
|
|
1425
|
+
slug: string;
|
|
1426
|
+
seo?: DeliveryEntrySeo | null;
|
|
1427
|
+
}): SeoInput;
|
|
1244
1428
|
/** Where this page lives, so a canonical can be derived when the page sets none. */
|
|
1245
1429
|
interface SeoLocation {
|
|
1246
1430
|
/** Absolute site origin, e.g. `https://acme.com`. Trailing slash optional. */
|
|
@@ -1357,14 +1541,20 @@ interface CreateFormInput {
|
|
|
1357
1541
|
redirectUrl?: string;
|
|
1358
1542
|
webhookUrl?: string;
|
|
1359
1543
|
}
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1544
|
+
/**
|
|
1545
|
+
* A field in an admin create/update payload.
|
|
1546
|
+
*
|
|
1547
|
+
* An ALIAS of `FormField`, not a copy. It used to be a hand-written interface and it had gone
|
|
1548
|
+
* stale: it listed six of the thirteen field types the builder can author — `phone`, `date`,
|
|
1549
|
+
* `url`, `radio`, `checkboxes`, `consent` and `hidden` were all missing — and omitted
|
|
1550
|
+
* `helpText`, `hidden`, `defaultValue`, `showIf`, `validation` and `ui` entirely. A typed
|
|
1551
|
+
* consumer of this client therefore could not express a phone field at all, let alone one with
|
|
1552
|
+
* a country picker, even though the route accepts every one of them.
|
|
1553
|
+
*
|
|
1554
|
+
* The admin routes validate against `formFieldSchema`, which mirrors `FormField`, so aliasing
|
|
1555
|
+
* is what keeps this honest: there is no second declaration left to drift.
|
|
1556
|
+
*/
|
|
1557
|
+
type FormFieldInput = FormField;
|
|
1368
1558
|
interface UpdateFormInput extends Partial<Omit<CreateFormInput, "fields">> {
|
|
1369
1559
|
fields?: FormFieldInput[];
|
|
1370
1560
|
}
|
|
@@ -1480,4 +1670,4 @@ declare function inviteMember(client: BetterCMSAdminClient, workspaceId: string,
|
|
|
1480
1670
|
declare function updateMemberRole(client: BetterCMSAdminClient, workspaceId: string, memberId: string, role: MemberRole): Promise<Member>;
|
|
1481
1671
|
declare function removeMember(client: BetterCMSAdminClient, workspaceId: string, memberId: string): Promise<void>;
|
|
1482
1672
|
|
|
1483
|
-
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 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 };
|
|
1673
|
+
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 };
|
package/dist/index.js
CHANGED
|
@@ -519,12 +519,13 @@ async function updateModel(client, id, input) {
|
|
|
519
519
|
);
|
|
520
520
|
return res.data;
|
|
521
521
|
}
|
|
522
|
+
var withWarnings = (res) => res.warnings?.length ? { ...res.data, warnings: res.warnings } : res.data;
|
|
522
523
|
async function createEntry(client, input) {
|
|
523
524
|
const res = await client.fetchJSON(
|
|
524
525
|
client.url("/management/content/entries"),
|
|
525
526
|
{ method: "POST", body: JSON.stringify(input) }
|
|
526
527
|
);
|
|
527
|
-
return res
|
|
528
|
+
return withWarnings(res);
|
|
528
529
|
}
|
|
529
530
|
async function updateEntry(client, id, input, opts) {
|
|
530
531
|
const headers = {};
|
|
@@ -533,7 +534,7 @@ async function updateEntry(client, id, input, opts) {
|
|
|
533
534
|
client.url(`/management/content/entries/${id}`),
|
|
534
535
|
{ method: "PATCH", body: JSON.stringify(input), headers }
|
|
535
536
|
);
|
|
536
|
-
return res
|
|
537
|
+
return withWarnings(res);
|
|
537
538
|
}
|
|
538
539
|
async function deleteManagedPage(client, id) {
|
|
539
540
|
const res = await client.fetchJSON(
|
|
@@ -558,6 +559,13 @@ async function deleteModel(client, id) {
|
|
|
558
559
|
}
|
|
559
560
|
|
|
560
561
|
// src/methods/management/media.ts
|
|
562
|
+
async function updateAsset(client, id, input) {
|
|
563
|
+
const { data } = await client.fetchJSON(
|
|
564
|
+
client.url(`/management/media/${encodeURIComponent(id)}`),
|
|
565
|
+
{ method: "PATCH", body: JSON.stringify(input) }
|
|
566
|
+
);
|
|
567
|
+
return data;
|
|
568
|
+
}
|
|
561
569
|
var MIME_BY_EXT = {
|
|
562
570
|
png: "image/png",
|
|
563
571
|
jpg: "image/jpeg",
|
|
@@ -685,6 +693,10 @@ async function uploadAsset(client, input) {
|
|
|
685
693
|
body: bytes
|
|
686
694
|
}
|
|
687
695
|
);
|
|
696
|
+
if (input.transcript && input.transcript.trim()) {
|
|
697
|
+
await updateAsset(client, data.id, { transcript: input.transcript });
|
|
698
|
+
return { ...data, transcript: input.transcript };
|
|
699
|
+
}
|
|
688
700
|
return data;
|
|
689
701
|
}
|
|
690
702
|
|
|
@@ -946,6 +958,10 @@ var BetterCMSManagementClient = class extends BetterCMSDeliveryClient {
|
|
|
946
958
|
uploadAsset(input) {
|
|
947
959
|
return uploadAsset(this, input);
|
|
948
960
|
}
|
|
961
|
+
/** Set an asset's alt text, caption or transcript (video/audio only). `null` clears. */
|
|
962
|
+
updateAsset(id, input) {
|
|
963
|
+
return updateAsset(this, id, input);
|
|
964
|
+
}
|
|
949
965
|
// ── Forms (read-only): discover dashboard-built forms to embed into site code ──
|
|
950
966
|
/** List forms in the key's project (or workspace-level). */
|
|
951
967
|
listForms() {
|
|
@@ -1414,6 +1430,68 @@ function jsonLdNodes(schema) {
|
|
|
1414
1430
|
}
|
|
1415
1431
|
return out;
|
|
1416
1432
|
}
|
|
1433
|
+
var SCHEMA_TYPE_CHOICES = [
|
|
1434
|
+
"WebPage",
|
|
1435
|
+
"AboutPage",
|
|
1436
|
+
"ContactPage",
|
|
1437
|
+
"CollectionPage",
|
|
1438
|
+
"Blog",
|
|
1439
|
+
"BlogPosting",
|
|
1440
|
+
"Article",
|
|
1441
|
+
"Product",
|
|
1442
|
+
"FAQPage",
|
|
1443
|
+
"Event",
|
|
1444
|
+
"Organization",
|
|
1445
|
+
"LocalBusiness"
|
|
1446
|
+
];
|
|
1447
|
+
function compact(node) {
|
|
1448
|
+
return Object.fromEntries(Object.entries(node).filter(([, value]) => value != null && value !== ""));
|
|
1449
|
+
}
|
|
1450
|
+
function schemaNode(type, { name, description, image, url }) {
|
|
1451
|
+
switch (type) {
|
|
1452
|
+
case "BlogPosting":
|
|
1453
|
+
case "Article":
|
|
1454
|
+
return compact({ "@type": type, headline: name, description, image, url, mainEntityOfPage: url });
|
|
1455
|
+
case "Product":
|
|
1456
|
+
case "Event":
|
|
1457
|
+
return compact({ "@type": type, name, description, image, url });
|
|
1458
|
+
case "FAQPage":
|
|
1459
|
+
case "WebSite":
|
|
1460
|
+
return compact({ "@type": type, name, description, url });
|
|
1461
|
+
case "Organization":
|
|
1462
|
+
return compact({ "@type": type, name, description, url, logo: image });
|
|
1463
|
+
default:
|
|
1464
|
+
return compact({ "@type": type, name, description, url, image });
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
function pageJsonLd(page, meta, canonical, siteSchema) {
|
|
1468
|
+
const custom = jsonLdNodes(meta.schema);
|
|
1469
|
+
if (custom.length > 0) return custom;
|
|
1470
|
+
const props = {
|
|
1471
|
+
name: (page.metaTitle || page.title || "").trim(),
|
|
1472
|
+
description: (page.metaDescription || "").trim(),
|
|
1473
|
+
image: (meta.og?.image || "").trim(),
|
|
1474
|
+
url: canonical.trim()
|
|
1475
|
+
};
|
|
1476
|
+
const schemaType = meta.schemaType;
|
|
1477
|
+
if (typeof schemaType === "string" && SCHEMA_TYPE_CHOICES.includes(schemaType)) {
|
|
1478
|
+
return [schemaNode(schemaType, props)];
|
|
1479
|
+
}
|
|
1480
|
+
if (page.slug === "home") {
|
|
1481
|
+
return jsonLdNodes(siteSchema).length > 0 ? [] : [schemaNode("WebSite", props)];
|
|
1482
|
+
}
|
|
1483
|
+
return [schemaNode("WebPage", props)];
|
|
1484
|
+
}
|
|
1485
|
+
function entrySeoInput(entry) {
|
|
1486
|
+
const { metaTitle, metaDescription, noindex, ...metaJson } = entry.seo ?? {};
|
|
1487
|
+
return {
|
|
1488
|
+
title: metaTitle || entry.slug,
|
|
1489
|
+
metaTitle: metaTitle ?? null,
|
|
1490
|
+
metaDescription: metaDescription ?? null,
|
|
1491
|
+
metaJson,
|
|
1492
|
+
noindex: noindex === true
|
|
1493
|
+
};
|
|
1494
|
+
}
|
|
1417
1495
|
function resolveSeo(page, defaults = {}, location = {}) {
|
|
1418
1496
|
const meta = page.metaJson ?? {};
|
|
1419
1497
|
const title = page.metaTitle || page.title || "";
|
|
@@ -1441,7 +1519,9 @@ function resolveSeo(page, defaults = {}, location = {}) {
|
|
|
1441
1519
|
image: twImage,
|
|
1442
1520
|
site: defaults.twitterHandle || ""
|
|
1443
1521
|
},
|
|
1444
|
-
jsonLd: [...jsonLdNodes(defaults.siteSchema), ...
|
|
1522
|
+
jsonLd: [...jsonLdNodes(defaults.siteSchema), ...pageJsonLd(page, meta, canonical, defaults.siteSchema)],
|
|
1523
|
+
noindex: page.noindex === true,
|
|
1524
|
+
robots: { index: page.noindex !== true, follow: true }
|
|
1445
1525
|
};
|
|
1446
1526
|
}
|
|
1447
1527
|
|
|
@@ -1784,6 +1864,7 @@ export {
|
|
|
1784
1864
|
deleteSubmission,
|
|
1785
1865
|
deleteWorkspace,
|
|
1786
1866
|
encodeStega,
|
|
1867
|
+
entrySeoInput,
|
|
1787
1868
|
formInitialValues,
|
|
1788
1869
|
getApiKeyUsage,
|
|
1789
1870
|
getBlockType,
|