@obelism/content 0.3.0 → 0.5.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 CHANGED
@@ -26,6 +26,15 @@ await content.getEntry('entry_…') // Entry | null
26
26
  await content.getEntries({ contentType: 'post', limit: 20, skip: 0 }) // { items, total, limit, skip }
27
27
  for await (const post of content.getAllEntries({ contentType: 'post' })) {
28
28
  }
29
+ await content.getFirstEntry({
30
+ contentType: 'navigation',
31
+ fields: { key: 'main' },
32
+ }) // Entry | null
33
+ await content.getEntries({
34
+ contentType: 'post',
35
+ fields: { category: 'news', 'date[gte]': '2026-01-01', tags: ['a', 'b'] }, // a list: one of them
36
+ order: '-fields.date',
37
+ })
29
38
  await content.getContentModel() // the model file
30
39
  ```
31
40
 
@@ -36,12 +45,31 @@ with generics: `content.getPage<Entry<{ title: string }>>('home')`.
36
45
 
37
46
  ## Preview
38
47
 
39
- The visual editor loads your site with `?cms_preview=1&cms_entry=…&cms_environment=…`.
48
+ The visual editor loads your site with
49
+ `?cms_preview=1&cms_entry=…&cms_environment=…&cms_token=…`. `cms_token` is
50
+ made for the person editing and reads drafts for 8 hours; read the page with
51
+ it, server-side. Never show drafts because `cms_preview` is there: anyone can
52
+ add it to a URL.
40
53
 
41
54
  ```ts
42
- import { readPreviewParams } from '@obelism/content'
43
-
44
- const client = readPreviewParams(request.url) ? previewClient : deliveryClient
55
+ import {
56
+ ContentApiError,
57
+ ContentClient,
58
+ readPreviewParams,
59
+ } from '@obelism/content'
60
+
61
+ const preview = readPreviewParams(request.url)
62
+ const content = preview?.token
63
+ ? new ContentClient({ token: preview.token, init: { cache: 'no-store' } })
64
+ : deliveryClient
65
+
66
+ const page = await content.getPage(path).catch((error) => {
67
+ // A made-up or expired token: show what's published.
68
+ if (error instanceof ContentApiError && error.status === 401) {
69
+ return deliveryClient.getPage(path)
70
+ }
71
+ throw error
72
+ })
45
73
  ```
46
74
 
47
75
  ## Visual editor bridge
@@ -501,7 +501,7 @@ const runInitCommand = async ({ url, token, dir, install: shouldInstall, cwd = p
501
501
  log([
502
502
  '',
503
503
  'Next:',
504
- '- Create a delivery token (and a preview token for drafts) in Space settings, and set CONTENT_DELIVERY_TOKEN and CONTENT_PREVIEW_TOKEN.',
504
+ '- Create a delivery token in Space settings and set CONTENT_DELIVERY_TOKEN (a preview token only if the site builds from drafts; the visual editor brings its own, as cms_token).',
505
505
  '- Fetch content with ContentClient from @obelism/content; the examples show what each type looks like.',
506
506
  ...improve.enabled ? [
507
507
  "- Render _improve blocks: ask improve's SDK for the visitor's option (getTestValue / getFlagValue with the block's slug) and render pickImproveVariant(block, option)."
@@ -1,4 +1,4 @@
1
- !/*! Obelism Content bridge (@obelism/content), MIT. https://content.obelism.studio/docs/visual-editor */function(){"use strict";var e;let t="data-cms-uid",r="data-cms-entry",n="cms_environment",o="#d58a1f",a=(e="")=>`${e}[${t}]{cursor:pointer;transition:outline-color .15s}${e}[${t}]:hover{outline:2px dashed ${o};outline-offset:2px}${e}[${t}][data-cms-selected]{outline:2px solid ${o};outline-offset:2px}`,i={features:[],selectedUid:null,prompting:!1,canUndo:!1,unsaved:!1,saving:!1,publishing:!1,selecting:!1},s=()=>{let e={update:new Set,saved:new Set,published:new Set,change:new Set};return{listeners:e,on:(t,r)=>(e[t].add(r),()=>{e[t].delete(r)}),emit(t,r){for(let n of e[t])try{n(r)}catch(e){console.error("[@obelism/content bridge]",e)}}}},l=()=>Promise.reject(Error("Save and publish in the visual editor itself")),d={prompt:()=>Promise.reject(Error("Prompts only work inside the visual editor")),createPage:()=>Promise.reject(Error("New pages are made on the site itself")),undo:()=>{},save:l,publish:l,signOut:()=>{},select:()=>{},setSelecting:()=>{}},c=e=>`[${t}="${e.replace(/["\\]/g,"\\$&")}"]`,p=(e,t)=>{let r=s();e.on("saved",()=>r.emit("saved",{})),e.on("published",()=>r.emit("published",{}));let o=!1;return{isEditing:e.isEditing,mode:e.isEditing?"editor":null,entryId:e.entryId,environment:t.get(n),on:(t,n)=>("update"!==t||o||(o=!0,e.on("update",e=>{let t=e?.entry;t&&r.emit("update",{entry:t,selectedUid:null})})),r.on(t,n)),getState:()=>i,...d,destroy:()=>{}}},g={open:"Edit with a prompt",placeholder:"Describe a change, e.g. “make the heading shorter”",send:"Apply",undo:"Undo",close:"Close",scopeEntry:"Whole page",scopeBlock:"Selected block",clearBlock:"Edit the whole page instead",working:"Working on it…",save:"Save",publish:"Publish",saving:"Saving…",publishing:"Publishing…",saved:"Saved as a draft",published:"Published",unsaved:"Unsaved changes",signOut:"Exit editing",viewingDrafts:"Viewing drafts",selectHint:"Click a block to change only that block",newPage:"New page",newPageCancel:"Edit this page instead",newPagePlaceholder:"Describe the new page, e.g. “a pricing page for agencies”",path:"Path",pathPlaceholder:"/pricing",creating:"Writing the page…",created:"Opening the new page…"},u={page:'<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/>',newPage:'<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M9 15h6"/><path d="M12 18v-6"/>',block:'<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M7 8h10"/><path d="M7 12h6"/>',undo:'<path d="M9 14 4 9l5-5"/><path d="M4 9h10.5a5.5 5.5 0 0 1 0 11H11"/>',close:'<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',send:'<path d="M3.714 3.048a.498.498 0 0 0-.683.627l2.843 7.627a2 2 0 0 1 0 1.396l-2.842 7.627a.498.498 0 0 0 .682.627l18-8.5a.5.5 0 0 0 0-.904z"/><path d="M6 12h16"/>'},h=`
1
+ !/*! Obelism Content bridge (@obelism/content), MIT. https://content.obelism.studio/docs/guides/visual-editor */function(){"use strict";var e;let t="data-cms-uid",r="data-cms-entry",n="cms_environment",o="#d58a1f",a=(e="")=>`${e}[${t}]{cursor:pointer;transition:outline-color .15s}${e}[${t}]:hover{outline:2px dashed ${o};outline-offset:2px}${e}[${t}][data-cms-selected]{outline:2px solid ${o};outline-offset:2px}`,i={features:[],selectedUid:null,prompting:!1,canUndo:!1,unsaved:!1,saving:!1,publishing:!1,selecting:!1},s=()=>{let e={update:new Set,saved:new Set,published:new Set,change:new Set};return{listeners:e,on:(t,r)=>(e[t].add(r),()=>{e[t].delete(r)}),emit(t,r){for(let n of e[t])try{n(r)}catch(e){console.error("[@obelism/content bridge]",e)}}}},l=()=>Promise.reject(Error("Save and publish in the visual editor itself")),d={prompt:()=>Promise.reject(Error("Prompts only work inside the visual editor")),createPage:()=>Promise.reject(Error("New pages are made on the site itself")),undo:()=>{},save:l,publish:l,signOut:()=>{},select:()=>{},setSelecting:()=>{}},c=e=>`[${t}="${e.replace(/["\\]/g,"\\$&")}"]`,p=(e,t)=>{let r=s();e.on("saved",()=>r.emit("saved",{})),e.on("published",()=>r.emit("published",{}));let o=!1;return{isEditing:e.isEditing,mode:e.isEditing?"editor":null,entryId:e.entryId,environment:t.get(n),on:(t,n)=>("update"!==t||o||(o=!0,e.on("update",e=>{let t=e?.entry;t&&r.emit("update",{entry:t,selectedUid:null})})),r.on(t,n)),getState:()=>i,...d,destroy:()=>{}}},g={open:"Edit with a prompt",placeholder:"Describe a change, e.g. “make the heading shorter”",send:"Apply",undo:"Undo",close:"Close",scopeEntry:"Whole page",scopeBlock:"Selected block",clearBlock:"Edit the whole page instead",working:"Working on it…",save:"Save",publish:"Publish",saving:"Saving…",publishing:"Publishing…",saved:"Saved as a draft",published:"Published",unsaved:"Unsaved changes",signOut:"Exit editing",viewingDrafts:"Viewing drafts",selectHint:"Click a block to change only that block",newPage:"New page",newPageCancel:"Edit this page instead",newPagePlaceholder:"Describe the new page, e.g. “a pricing page for agencies”",path:"Path",pathPlaceholder:"/pricing",creating:"Writing the page…",created:"Opening the new page…"},u={page:'<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/>',newPage:'<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M9 15h6"/><path d="M12 18v-6"/>',block:'<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M7 8h10"/><path d="M7 12h6"/>',undo:'<path d="M9 14 4 9l5-5"/><path d="M4 9h10.5a5.5 5.5 0 0 1 0 11H11"/>',close:'<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',send:'<path d="M3.714 3.048a.498.498 0 0 0-.683.627l2.843 7.627a2 2 0 0 1 0 1.396l-2.842 7.627a.498.498 0 0 0 .682.627l18-8.5a.5.5 0 0 0 0-.904z"/><path d="M6 12h16"/>'},h=`
2
2
  :host { all: initial; }
3
3
  * { box-sizing: border-box; font: inherit; color: inherit; margin: 0; }
4
4
  .root {
package/dist/bridge.js CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, '__esModule', { value: true });
2
2
 
3
- var preview = require('./preview-by8d54dt.js');
3
+ var preview = require('./preview-mpwfmnla.js');
4
4
  var site = require('./site.js');
5
5
  var config = require('./config-ci2hxmas.js');
6
6
 
package/dist/bridge.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { P as PREVIEW_PARAMS, U as UID_ATTRIBUTE, E as ENTRY_ATTRIBUTE } from './preview-kvotryzw.mjs';
1
+ import { P as PREVIEW_PARAMS, U as UID_ATTRIBUTE, E as ENTRY_ATTRIBUTE } from './preview-h7rwp06v.mjs';
2
2
  import { SITE_EDITING_COOKIE, SITE_REQUEST_HEADER } from './site.mjs';
3
3
  import { n as normalizeUrl, D as DEFAULT_URL } from './config-c6qktlz6.mjs';
4
4
 
package/dist/index.d.mts CHANGED
@@ -17,9 +17,12 @@ type RequestOptions = {
17
17
  richText?: RichTextFormat | undefined;
18
18
  init?: RequestInit | undefined;
19
19
  };
20
+ type FieldFilterValue = string | number | boolean;
20
21
  type EntriesQuery = RequestOptions & {
21
22
  contentType?: string | undefined;
22
23
  parentPath?: string | undefined;
24
+ fields?: Record<string, FieldFilterValue | readonly FieldFilterValue[]> | undefined;
25
+ order?: string | undefined;
23
26
  limit?: number | undefined;
24
27
  skip?: number | undefined;
25
28
  };
@@ -29,7 +32,8 @@ declare class ContentClient {
29
32
  constructor({ token, url, locale, depth, richText, timeout, init, fetch: fetchImpl, }: ContentClientOptions);
30
33
  getPage: <TEntry extends Entry = Entry>(path: string, options?: RequestOptions) => Promise<TEntry | null>;
31
34
  getEntry: <TEntry extends Entry = Entry>(id: string, options?: RequestOptions) => Promise<TEntry | null>;
32
- getEntries: <TEntry extends Entry = Entry>({ contentType, parentPath, limit, skip, ...options }?: EntriesQuery) => Promise<EntryList<TEntry>>;
35
+ getEntries: <TEntry extends Entry = Entry>({ contentType, parentPath, fields, order, limit, skip, ...options }?: EntriesQuery) => Promise<EntryList<TEntry>>;
36
+ getFirstEntry: <TEntry extends Entry = Entry>(query?: Omit<EntriesQuery, "limit" | "skip">) => Promise<TEntry | null>;
33
37
  getAllEntries<TEntry extends Entry = Entry>(query?: Omit<EntriesQuery, 'skip'>): AsyncGenerator<TEntry, void, undefined>;
34
38
  getContentModel: (options?: Pick<RequestOptions, "init">) => Promise<ModelFile>;
35
39
  }
@@ -74,10 +78,12 @@ declare const PREVIEW_PARAMS: {
74
78
  readonly preview: "cms_preview";
75
79
  readonly entry: "cms_entry";
76
80
  readonly environment: "cms_environment";
81
+ readonly token: "cms_token";
77
82
  };
78
83
  type PreviewParams = {
79
84
  entryId: string | null;
80
85
  environment: string | null;
86
+ token: string | null;
81
87
  };
82
88
  type SearchParamsInput = URL | URLSearchParams | string | Record<string, string | string[] | undefined>;
83
89
  declare const readPreviewParams: (input: SearchParamsInput) => PreviewParams | null;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","sources":["../src/client.ts","../src/config.ts","../src/editable.ts","../src/errors.ts","../src/images.ts","../src/improve.ts","../src/preview.ts","../src/richText.ts"],"mappings":";;;AACA,KAAK,oBAAoB;AACzB;AACA;AACA;AACA;AACA,eAAe,cAAc;AAC7B;AACA,WAAW,WAAW;AACtB,mBAAmB,KAAK;AACxB;AACA,KAAK,cAAc;AACnB;AACA;AACA,eAAe,cAAc;AAC7B,WAAW,WAAW;AACtB;AACA,KAAK,YAAY,GAAG,cAAc;AAClC;AACA;AACA;AACA;AACA;AACA,cAAc,aAAa;AAC3B;AACA;AACA,2FAA2F,oBAAoB;AAC/G,6BAA6B,KAAK,GAAG,KAAK,0BAA0B,cAAc,KAAK,OAAO;AAC9F,8BAA8B,KAAK,GAAG,KAAK,wBAAwB,cAAc,KAAK,OAAO;AAC7F,gCAAgC,KAAK,GAAG,KAAK,yDAAyD,YAAY,KAAK,OAAO,CAAC,SAAS;AACxI,iCAAiC,KAAK,GAAG,KAAK,UAAU,IAAI,CAAC,YAAY,YAAY,cAAc;AACnG,gCAAgC,IAAI,CAAC,cAAc,cAAc,OAAO,CAAC,SAAS;AAClF;;AChCA,cAAc,WAAW;;ACAzB,cAAc,aAAa;AAC3B,cAAc,eAAe;AAC7B,KAAK,QAAQ;AACb;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA,yBAAyB,QAAQ;;ACXjC,cAAc,eAAe,SAAS,KAAK;AAC3C;AACA;AACA;AACA;AACA;;ACJA,KAAK,cAAc;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ,UAAU,IAAI,CAAC,KAAK,+BAA+B,cAAc;AACvF,cAAc,WAAW,UAAU,IAAI,CAAC,KAAK,iDAAiD,IAAI,CAAC,cAAc;;ACRjH,cAAc,aAAa;AAC3B,cAAc,cAAc,UAAU,KAAK,cAAc,YAAY;AACrE,cAAc,kBAAkB,kBAAkB,KAAK,SAAS,YAAY;;ACH5E,cAAc,cAAc;AAC5B;AACA;AACA;AACA;AACA,KAAK,aAAa;AAClB;AACA;AACA;AACA,KAAK,iBAAiB,GAAG,GAAG,GAAG,eAAe,YAAY,MAAM;AAChE,cAAc,iBAAiB,UAAU,iBAAiB,KAAK,aAAa;;ACT5E,cAAc,SAAS,EAAE,MAAM;AAC/B,cAAc,UAAU;AACxB,KAAK,mBAAmB;AACxB,0BAA0B,KAAK,GAAG,SAAS,QAAQ,YAAY;AAC/D,0BAA0B,KAAK,QAAQ,YAAY;AACnD;AACA,cAAc,cAAc,QAAQ,YAAY,oDAAoD,mBAAmB;AACvH,cAAc,YAAY,SAAS,YAAY;AAC/C,cAAc,mBAAmB,QAAQ,YAAY;;","names":[]}
1
+ {"version":3,"file":"index.d.mts","sources":["../src/client.ts","../src/config.ts","../src/editable.ts","../src/errors.ts","../src/images.ts","../src/improve.ts","../src/preview.ts","../src/richText.ts"],"mappings":";;;AACA,KAAK,oBAAoB;AACzB;AACA;AACA;AACA;AACA,eAAe,cAAc;AAC7B;AACA,WAAW,WAAW;AACtB,mBAAmB,KAAK;AACxB;AACA,KAAK,cAAc;AACnB;AACA;AACA,eAAe,cAAc;AAC7B,WAAW,WAAW;AACtB;AACA,KAAK,gBAAgB;AACrB,KAAK,YAAY,GAAG,cAAc;AAClC;AACA;AACA,aAAa,MAAM,SAAS,gBAAgB,YAAY,gBAAgB;AACxE;AACA;AACA;AACA;AACA,cAAc,aAAa;AAC3B;AACA;AACA,2FAA2F,oBAAoB;AAC/G,6BAA6B,KAAK,GAAG,KAAK,0BAA0B,cAAc,KAAK,OAAO;AAC9F,8BAA8B,KAAK,GAAG,KAAK,wBAAwB,cAAc,KAAK,OAAO;AAC7F,gCAAgC,KAAK,GAAG,KAAK,wEAAwE,YAAY,KAAK,OAAO,CAAC,SAAS;AACvJ,mCAAmC,KAAK,GAAG,KAAK,UAAU,IAAI,CAAC,YAAY,wBAAwB,OAAO;AAC1G,iCAAiC,KAAK,GAAG,KAAK,UAAU,IAAI,CAAC,YAAY,YAAY,cAAc;AACnG,gCAAgC,IAAI,CAAC,cAAc,cAAc,OAAO,CAAC,SAAS;AAClF;;ACpCA,cAAc,WAAW;;ACAzB,cAAc,aAAa;AAC3B,cAAc,eAAe;AAC7B,KAAK,QAAQ;AACb;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA,yBAAyB,QAAQ;;ACXjC,cAAc,eAAe,SAAS,KAAK;AAC3C;AACA;AACA;AACA;AACA;;ACJA,KAAK,cAAc;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ,UAAU,IAAI,CAAC,KAAK,+BAA+B,cAAc;AACvF,cAAc,WAAW,UAAU,IAAI,CAAC,KAAK,iDAAiD,IAAI,CAAC,cAAc;;ACRjH,cAAc,aAAa;AAC3B,cAAc,cAAc,UAAU,KAAK,cAAc,YAAY;AACrE,cAAc,kBAAkB,kBAAkB,KAAK,SAAS,YAAY;;ACH5E,cAAc,cAAc;AAC5B;AACA;AACA;AACA;AACA;AACA,KAAK,aAAa;AAClB;AACA;AACA;AACA;AACA,KAAK,iBAAiB,GAAG,GAAG,GAAG,eAAe,YAAY,MAAM;AAChE,cAAc,iBAAiB,UAAU,iBAAiB,KAAK,aAAa;;ACX5E,cAAc,SAAS,EAAE,MAAM;AAC/B,cAAc,UAAU;AACxB,KAAK,mBAAmB;AACxB,0BAA0B,KAAK,GAAG,SAAS,QAAQ,YAAY;AAC/D,0BAA0B,KAAK,QAAQ,YAAY;AACnD;AACA,cAAc,cAAc,QAAQ,YAAY,oDAAoD,mBAAmB;AACvH,cAAc,YAAY,SAAS,YAAY;AAC/C,cAAc,mBAAmB,QAAQ,YAAY;;","names":[]}
package/dist/index.d.ts CHANGED
@@ -17,9 +17,12 @@ type RequestOptions = {
17
17
  richText?: RichTextFormat | undefined;
18
18
  init?: RequestInit | undefined;
19
19
  };
20
+ type FieldFilterValue = string | number | boolean;
20
21
  type EntriesQuery = RequestOptions & {
21
22
  contentType?: string | undefined;
22
23
  parentPath?: string | undefined;
24
+ fields?: Record<string, FieldFilterValue | readonly FieldFilterValue[]> | undefined;
25
+ order?: string | undefined;
23
26
  limit?: number | undefined;
24
27
  skip?: number | undefined;
25
28
  };
@@ -29,7 +32,8 @@ declare class ContentClient {
29
32
  constructor({ token, url, locale, depth, richText, timeout, init, fetch: fetchImpl, }: ContentClientOptions);
30
33
  getPage: <TEntry extends Entry = Entry>(path: string, options?: RequestOptions) => Promise<TEntry | null>;
31
34
  getEntry: <TEntry extends Entry = Entry>(id: string, options?: RequestOptions) => Promise<TEntry | null>;
32
- getEntries: <TEntry extends Entry = Entry>({ contentType, parentPath, limit, skip, ...options }?: EntriesQuery) => Promise<EntryList<TEntry>>;
35
+ getEntries: <TEntry extends Entry = Entry>({ contentType, parentPath, fields, order, limit, skip, ...options }?: EntriesQuery) => Promise<EntryList<TEntry>>;
36
+ getFirstEntry: <TEntry extends Entry = Entry>(query?: Omit<EntriesQuery, "limit" | "skip">) => Promise<TEntry | null>;
33
37
  getAllEntries<TEntry extends Entry = Entry>(query?: Omit<EntriesQuery, 'skip'>): AsyncGenerator<TEntry, void, undefined>;
34
38
  getContentModel: (options?: Pick<RequestOptions, "init">) => Promise<ModelFile>;
35
39
  }
@@ -74,10 +78,12 @@ declare const PREVIEW_PARAMS: {
74
78
  readonly preview: "cms_preview";
75
79
  readonly entry: "cms_entry";
76
80
  readonly environment: "cms_environment";
81
+ readonly token: "cms_token";
77
82
  };
78
83
  type PreviewParams = {
79
84
  entryId: string | null;
80
85
  environment: string | null;
86
+ token: string | null;
81
87
  };
82
88
  type SearchParamsInput = URL | URLSearchParams | string | Record<string, string | string[] | undefined>;
83
89
  declare const readPreviewParams: (input: SearchParamsInput) => PreviewParams | null;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sources":["../src/client.ts","../src/config.ts","../src/editable.ts","../src/errors.ts","../src/images.ts","../src/improve.ts","../src/preview.ts","../src/richText.ts"],"mappings":";;;AACA,KAAK,oBAAoB;AACzB;AACA;AACA;AACA;AACA,eAAe,cAAc;AAC7B;AACA,WAAW,WAAW;AACtB,mBAAmB,KAAK;AACxB;AACA,KAAK,cAAc;AACnB;AACA;AACA,eAAe,cAAc;AAC7B,WAAW,WAAW;AACtB;AACA,KAAK,YAAY,GAAG,cAAc;AAClC;AACA;AACA;AACA;AACA;AACA,cAAc,aAAa;AAC3B;AACA;AACA,2FAA2F,oBAAoB;AAC/G,6BAA6B,KAAK,GAAG,KAAK,0BAA0B,cAAc,KAAK,OAAO;AAC9F,8BAA8B,KAAK,GAAG,KAAK,wBAAwB,cAAc,KAAK,OAAO;AAC7F,gCAAgC,KAAK,GAAG,KAAK,yDAAyD,YAAY,KAAK,OAAO,CAAC,SAAS;AACxI,iCAAiC,KAAK,GAAG,KAAK,UAAU,IAAI,CAAC,YAAY,YAAY,cAAc;AACnG,gCAAgC,IAAI,CAAC,cAAc,cAAc,OAAO,CAAC,SAAS;AAClF;;AChCA,cAAc,WAAW;;ACAzB,cAAc,aAAa;AAC3B,cAAc,eAAe;AAC7B,KAAK,QAAQ;AACb;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA,yBAAyB,QAAQ;;ACXjC,cAAc,eAAe,SAAS,KAAK;AAC3C;AACA;AACA;AACA;AACA;;ACJA,KAAK,cAAc;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ,UAAU,IAAI,CAAC,KAAK,+BAA+B,cAAc;AACvF,cAAc,WAAW,UAAU,IAAI,CAAC,KAAK,iDAAiD,IAAI,CAAC,cAAc;;ACRjH,cAAc,aAAa;AAC3B,cAAc,cAAc,UAAU,KAAK,cAAc,YAAY;AACrE,cAAc,kBAAkB,kBAAkB,KAAK,SAAS,YAAY;;ACH5E,cAAc,cAAc;AAC5B;AACA;AACA;AACA;AACA,KAAK,aAAa;AAClB;AACA;AACA;AACA,KAAK,iBAAiB,GAAG,GAAG,GAAG,eAAe,YAAY,MAAM;AAChE,cAAc,iBAAiB,UAAU,iBAAiB,KAAK,aAAa;;ACT5E,cAAc,SAAS,EAAE,MAAM;AAC/B,cAAc,UAAU;AACxB,KAAK,mBAAmB;AACxB,0BAA0B,KAAK,GAAG,SAAS,QAAQ,YAAY;AAC/D,0BAA0B,KAAK,QAAQ,YAAY;AACnD;AACA,cAAc,cAAc,QAAQ,YAAY,oDAAoD,mBAAmB;AACvH,cAAc,YAAY,SAAS,YAAY;AAC/C,cAAc,mBAAmB,QAAQ,YAAY;;","names":[]}
1
+ {"version":3,"file":"index.d.ts","sources":["../src/client.ts","../src/config.ts","../src/editable.ts","../src/errors.ts","../src/images.ts","../src/improve.ts","../src/preview.ts","../src/richText.ts"],"mappings":";;;AACA,KAAK,oBAAoB;AACzB;AACA;AACA;AACA;AACA,eAAe,cAAc;AAC7B;AACA,WAAW,WAAW;AACtB,mBAAmB,KAAK;AACxB;AACA,KAAK,cAAc;AACnB;AACA;AACA,eAAe,cAAc;AAC7B,WAAW,WAAW;AACtB;AACA,KAAK,gBAAgB;AACrB,KAAK,YAAY,GAAG,cAAc;AAClC;AACA;AACA,aAAa,MAAM,SAAS,gBAAgB,YAAY,gBAAgB;AACxE;AACA;AACA;AACA;AACA,cAAc,aAAa;AAC3B;AACA;AACA,2FAA2F,oBAAoB;AAC/G,6BAA6B,KAAK,GAAG,KAAK,0BAA0B,cAAc,KAAK,OAAO;AAC9F,8BAA8B,KAAK,GAAG,KAAK,wBAAwB,cAAc,KAAK,OAAO;AAC7F,gCAAgC,KAAK,GAAG,KAAK,wEAAwE,YAAY,KAAK,OAAO,CAAC,SAAS;AACvJ,mCAAmC,KAAK,GAAG,KAAK,UAAU,IAAI,CAAC,YAAY,wBAAwB,OAAO;AAC1G,iCAAiC,KAAK,GAAG,KAAK,UAAU,IAAI,CAAC,YAAY,YAAY,cAAc;AACnG,gCAAgC,IAAI,CAAC,cAAc,cAAc,OAAO,CAAC,SAAS;AAClF;;ACpCA,cAAc,WAAW;;ACAzB,cAAc,aAAa;AAC3B,cAAc,eAAe;AAC7B,KAAK,QAAQ;AACb;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA,yBAAyB,QAAQ;;ACXjC,cAAc,eAAe,SAAS,KAAK;AAC3C;AACA;AACA;AACA;AACA;;ACJA,KAAK,cAAc;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ,UAAU,IAAI,CAAC,KAAK,+BAA+B,cAAc;AACvF,cAAc,WAAW,UAAU,IAAI,CAAC,KAAK,iDAAiD,IAAI,CAAC,cAAc;;ACRjH,cAAc,aAAa;AAC3B,cAAc,cAAc,UAAU,KAAK,cAAc,YAAY;AACrE,cAAc,kBAAkB,kBAAkB,KAAK,SAAS,YAAY;;ACH5E,cAAc,cAAc;AAC5B;AACA;AACA;AACA;AACA;AACA,KAAK,aAAa;AAClB;AACA;AACA;AACA;AACA,KAAK,iBAAiB,GAAG,GAAG,GAAG,eAAe,YAAY,MAAM;AAChE,cAAc,iBAAiB,UAAU,iBAAiB,KAAK,aAAa;;ACX5E,cAAc,SAAS,EAAE,MAAM;AAC/B,cAAc,UAAU;AACxB,KAAK,mBAAmB;AACxB,0BAA0B,KAAK,GAAG,SAAS,QAAQ,YAAY;AAC/D,0BAA0B,KAAK,QAAQ,YAAY;AACnD;AACA,cAAc,cAAc,QAAQ,YAAY,oDAAoD,mBAAmB;AACvH,cAAc,YAAY,SAAS,YAAY;AAC/C,cAAc,mBAAmB,QAAQ,YAAY;;","names":[]}
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, '__esModule', { value: true });
2
2
 
3
3
  var config = require('./config-ci2hxmas.js');
4
- var preview = require('./preview-by8d54dt.js');
4
+ var preview = require('./preview-mpwfmnla.js');
5
5
 
6
6
  // A response from the API that wasn't a success. `message` is the API's own
7
7
  // `error` text when it sent one.
@@ -16,6 +16,18 @@ class ContentApiError extends Error {
16
16
  }
17
17
  }
18
18
 
19
+ // `fields` as the API's `fields.<apiId>[op]` parameters.
20
+ const fieldParams = (fields)=>Object.fromEntries(Object.entries(fields ?? {}).map(([key, value])=>{
21
+ if (!Array.isArray(value)) return [
22
+ `fields.${key}`,
23
+ String(value)
24
+ ];
25
+ const name = key.includes('[') ? key : `${key}[in]`;
26
+ return [
27
+ `fields.${name}`,
28
+ value.join(',')
29
+ ];
30
+ }));
19
31
  const trimSlashes = (path)=>path.replace(/^\/+|\/+$/g, '');
20
32
  // Reads one space environment's content through the delivery API. The token
21
33
  // decides the space, the environment and whether drafts are visible.
@@ -50,12 +62,22 @@ class ContentClient {
50
62
  return result?.entry ?? null;
51
63
  };
52
64
  // One page of entries, ordered as in the space's tree.
53
- this.getEntries = ({ contentType, parentPath, limit, skip, ...options } = {})=>this.#request('/entries', {
65
+ this.getEntries = ({ contentType, parentPath, fields, order, limit, skip, ...options } = {})=>this.#request('/entries', {
54
66
  contentType,
55
67
  parentPath: parentPath === undefined ? undefined : trimSlashes(parentPath),
68
+ ...fieldParams(fields),
69
+ order,
56
70
  limit,
57
71
  skip
58
72
  }, options);
73
+ // The first entry matching the query, or null: a settings entry, or a
74
+ // navigation by its key, without its id.
75
+ //
76
+ // await content.getFirstEntry({ contentType: 'navigation', fields: { key: 'main' } })
77
+ this.getFirstEntry = async (query = {})=>(await this.getEntries({
78
+ ...query,
79
+ limit: 1
80
+ })).items[0] ?? null;
59
81
  // The environment's content model, e.g. to generate types in a build.
60
82
  this.getContentModel = (options = {})=>this.#request('/content-model', {}, options, {
61
83
  defaults: false
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { n as normalizeUrl, a as DEFAULT_TIMEOUT, b as DELIVERY_PATH, D as DEFAULT_URL } from './config-c6qktlz6.mjs';
2
- export { E as ENTRY_ATTRIBUTE, P as PREVIEW_PARAMS, U as UID_ATTRIBUTE, e as editable, r as readPreviewParams } from './preview-kvotryzw.mjs';
2
+ export { E as ENTRY_ATTRIBUTE, P as PREVIEW_PARAMS, U as UID_ATTRIBUTE, e as editable, r as readPreviewParams } from './preview-h7rwp06v.mjs';
3
3
 
4
4
  // A response from the API that wasn't a success. `message` is the API's own
5
5
  // `error` text when it sent one.
@@ -14,6 +14,18 @@ class ContentApiError extends Error {
14
14
  }
15
15
  }
16
16
 
17
+ // `fields` as the API's `fields.<apiId>[op]` parameters.
18
+ const fieldParams = (fields)=>Object.fromEntries(Object.entries(fields ?? {}).map(([key, value])=>{
19
+ if (!Array.isArray(value)) return [
20
+ `fields.${key}`,
21
+ String(value)
22
+ ];
23
+ const name = key.includes('[') ? key : `${key}[in]`;
24
+ return [
25
+ `fields.${name}`,
26
+ value.join(',')
27
+ ];
28
+ }));
17
29
  const trimSlashes = (path)=>path.replace(/^\/+|\/+$/g, '');
18
30
  // Reads one space environment's content through the delivery API. The token
19
31
  // decides the space, the environment and whether drafts are visible.
@@ -48,12 +60,22 @@ class ContentClient {
48
60
  return result?.entry ?? null;
49
61
  };
50
62
  // One page of entries, ordered as in the space's tree.
51
- this.getEntries = ({ contentType, parentPath, limit, skip, ...options } = {})=>this.#request('/entries', {
63
+ this.getEntries = ({ contentType, parentPath, fields, order, limit, skip, ...options } = {})=>this.#request('/entries', {
52
64
  contentType,
53
65
  parentPath: parentPath === undefined ? undefined : trimSlashes(parentPath),
66
+ ...fieldParams(fields),
67
+ order,
54
68
  limit,
55
69
  skip
56
70
  }, options);
71
+ // The first entry matching the query, or null: a settings entry, or a
72
+ // navigation by its key, without its id.
73
+ //
74
+ // await content.getFirstEntry({ contentType: 'navigation', fields: { key: 'main' } })
75
+ this.getFirstEntry = async (query = {})=>(await this.getEntries({
76
+ ...query,
77
+ limit: 1
78
+ })).items[0] ?? null;
57
79
  // The environment's content model, e.g. to generate types in a build.
58
80
  this.getContentModel = (options = {})=>this.#request('/content-model', {}, options, {
59
81
  defaults: false
@@ -24,12 +24,15 @@ const editable = (target)=>{
24
24
  };
25
25
 
26
26
  // The visual editor loads the site in an iframe at the environment's preview
27
- // URL plus the entry's path, with these parameters added. A request carrying
28
- // `cms_preview` should be answered with drafts: fetch with a preview token.
27
+ // URL plus the entry's path, with these parameters added. `cms_token` is a
28
+ // token the CMS made for the person editing (`cms_v_…`): it reads drafts
29
+ // through the delivery API for 8 hours. Read drafts with it, never because
30
+ // `cms_preview` is there: anyone can add that to a URL.
29
31
  const PREVIEW_PARAMS = {
30
32
  preview: 'cms_preview',
31
33
  entry: 'cms_entry',
32
- environment: 'cms_environment'
34
+ environment: 'cms_environment',
35
+ token: 'cms_token'
33
36
  };
34
37
  const toSearchParams = (input)=>{
35
38
  if (input instanceof URL) return input.searchParams;
@@ -51,13 +54,19 @@ const toSearchParams = (input)=>{
51
54
  // The editor's parameters when this is a preview request, else null.
52
55
  //
53
56
  // const preview = readPreviewParams(request.url)
54
- // const content = preview ? previewClient : deliveryClient
57
+ // const content = preview?.token
58
+ // ? new ContentClient({ token: preview.token, init: { cache: 'no-store' } })
59
+ // : deliveryClient
60
+ //
61
+ // A made-up or expired token makes the client throw a ContentApiError with
62
+ // status 401: answer with `deliveryClient` then.
55
63
  const readPreviewParams = (input)=>{
56
64
  const params = toSearchParams(input);
57
65
  if (!params.has(PREVIEW_PARAMS.preview)) return null;
58
66
  return {
59
67
  entryId: params.get(PREVIEW_PARAMS.entry),
60
- environment: params.get(PREVIEW_PARAMS.environment)
68
+ environment: params.get(PREVIEW_PARAMS.environment),
69
+ token: params.get(PREVIEW_PARAMS.token)
61
70
  };
62
71
  };
63
72
 
@@ -24,12 +24,15 @@ const editable = (target)=>{
24
24
  };
25
25
 
26
26
  // The visual editor loads the site in an iframe at the environment's preview
27
- // URL plus the entry's path, with these parameters added. A request carrying
28
- // `cms_preview` should be answered with drafts: fetch with a preview token.
27
+ // URL plus the entry's path, with these parameters added. `cms_token` is a
28
+ // token the CMS made for the person editing (`cms_v_…`): it reads drafts
29
+ // through the delivery API for 8 hours. Read drafts with it, never because
30
+ // `cms_preview` is there: anyone can add that to a URL.
29
31
  const PREVIEW_PARAMS = {
30
32
  preview: 'cms_preview',
31
33
  entry: 'cms_entry',
32
- environment: 'cms_environment'
34
+ environment: 'cms_environment',
35
+ token: 'cms_token'
33
36
  };
34
37
  const toSearchParams = (input)=>{
35
38
  if (input instanceof URL) return input.searchParams;
@@ -51,13 +54,19 @@ const toSearchParams = (input)=>{
51
54
  // The editor's parameters when this is a preview request, else null.
52
55
  //
53
56
  // const preview = readPreviewParams(request.url)
54
- // const content = preview ? previewClient : deliveryClient
57
+ // const content = preview?.token
58
+ // ? new ContentClient({ token: preview.token, init: { cache: 'no-store' } })
59
+ // : deliveryClient
60
+ //
61
+ // A made-up or expired token makes the client throw a ContentApiError with
62
+ // status 401: answer with `deliveryClient` then.
55
63
  const readPreviewParams = (input)=>{
56
64
  const params = toSearchParams(input);
57
65
  if (!params.has(PREVIEW_PARAMS.preview)) return null;
58
66
  return {
59
67
  entryId: params.get(PREVIEW_PARAMS.entry),
60
- environment: params.get(PREVIEW_PARAMS.environment)
68
+ environment: params.get(PREVIEW_PARAMS.environment),
69
+ token: params.get(PREVIEW_PARAMS.token)
61
70
  };
62
71
  };
63
72
 
package/dist/site.js CHANGED
@@ -2,9 +2,9 @@ Object.defineProperty(exports, '__esModule', { value: true });
2
2
 
3
3
  var config = require('./config-ci2hxmas.js');
4
4
 
5
- // Editing on your own site, outside the visual editor (the CMS's
6
- // docs/site-editing.md). One handler serves everything under `/cms` (the
7
- // `basePath`) on your site:
5
+ // Editing on your own site, outside the visual editor
6
+ // (https://content.obelism.studio/docs/guides/site-editing). One handler
7
+ // serves everything under `/cms` (the `basePath`) on your site:
8
8
  //
9
9
  // - `/cms/login?return_to=/pricing` — sends the browser to Obelism Content
10
10
  // to sign in, with a PKCE challenge, and…
package/dist/site.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  import { n as normalizeUrl, a as DEFAULT_TIMEOUT, D as DEFAULT_URL } from './config-c6qktlz6.mjs';
2
2
 
3
- // Editing on your own site, outside the visual editor (the CMS's
4
- // docs/site-editing.md). One handler serves everything under `/cms` (the
5
- // `basePath`) on your site:
3
+ // Editing on your own site, outside the visual editor
4
+ // (https://content.obelism.studio/docs/guides/site-editing). One handler
5
+ // serves everything under `/cms` (the `basePath`) on your site:
6
6
  //
7
7
  // - `/cms/login?return_to=/pricing` — sends the browser to Obelism Content
8
8
  // to sign in, with a PKCE challenge, and…
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@obelism/content",
3
3
  "description": "Obelism Content SDK: the delivery API client, the visual editor bridge with prompt editing, editing on your own site, and the content model CLI",
4
- "version": "0.3.0",
4
+ "version": "0.5.0",
5
5
  "keywords": [
6
6
  "cms",
7
7
  "headless-cms",