@sandboxsonny/ace-kit 0.8.0 → 0.9.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @sandboxsonny/ace-kit
2
2
 
3
+ ## 0.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 6e6885f: Show the site's social image in `<AceSeo>`. The image is chosen in the site's settings in the CMS; `<AceSeo>` uses it for `og:image` and the Twitter card when you don't pass an `image` yourself. Also adds `getSite()` (Astro and React Router) for the site's name and social image.
8
+
3
9
  ## 0.8.0
4
10
 
5
11
  ### Minor Changes
@@ -3,10 +3,14 @@ import { SEO } from "astro-seo";
3
3
 
4
4
  import { seoProperties } from "../dist/index.js";
5
5
  import type { AceSeoOptions } from "../dist/index.js";
6
+ import { getSite } from "../dist/astro.js";
6
7
 
7
8
  type Props = AceSeoOptions;
8
9
 
9
- const properties = seoProperties(Astro.props);
10
+ // With no picture of its own, a page shows the social image chosen in the site's settings. The tags are never worth
11
+ // failing the page for, so a CMS that can't be reached just means no picture.
12
+ const site = Astro.props.image === undefined ? await getSite().catch(() => null) : null;
13
+ const properties = seoProperties({ ...Astro.props, image: Astro.props.image ?? site?.social_image?.src });
10
14
  ---
11
15
 
12
16
  <SEO {...properties} />
package/dist/astro.d.ts CHANGED
@@ -14,6 +14,31 @@ type AceContentTypeSchema = {
14
14
  fields: AceFieldSchema[];
15
15
  };
16
16
 
17
+ /** An image as the CMS Ace public API returns it. Use `src` and `srcset` in an `<img>`. */
18
+ type AceImageData = {
19
+ id: number;
20
+ /** The untouched original. */
21
+ url: string;
22
+ /** A web-sized copy, for browsers that ignore `srcset`. */
23
+ src: string;
24
+ /** Copies at several widths; empty when the image is too small to need them. */
25
+ srcset: string;
26
+ width: number | null;
27
+ height: number | null;
28
+ alt_text: string;
29
+ content_type: string;
30
+ };
31
+
32
+ /** The site the request is for, as the CMS Ace public API returns it. */
33
+ type AceSite = {
34
+ id: number;
35
+ name: string;
36
+ domain: string;
37
+ handle: string;
38
+ /** The picture the site's owners chose to show in search results and social posts; null if none. */
39
+ social_image: AceImageData | null;
40
+ };
41
+
17
42
  /** One link of a menu as the public API returns it, with its address already worked out. */
18
43
  type AceMenuItem = {
19
44
  label: string;
@@ -90,6 +115,7 @@ declare const ace: {
90
115
  limit?: number;
91
116
  }): Promise<AceEntry<AceValuesOf<Handle>>[]>;
92
117
  getMenu(handle: string): Promise<AceMenu | null>;
118
+ getSite(): Promise<AceSite | null>;
93
119
  getContentTypes(): Promise<AceContentTypeSchema[]>;
94
120
  };
95
121
  /** One live entry of a content type by its handle, or `null`. See `createAceClient`. */
@@ -102,6 +128,8 @@ declare const getEntries: <Handle extends AceContentTypeHandle>(contentTypeHandl
102
128
  }) => Promise<AceEntry<AceValuesOf<Handle>>[]>;
103
129
  /** A navigation menu with every link worked out, or `null`. */
104
130
  declare const getMenu: (handle: string) => Promise<AceMenu | null>;
131
+ /** The site: its name and the social image its owners chose (`social_image`, or `null`). */
132
+ declare const getSite: () => Promise<AceSite | null>;
105
133
  /**
106
134
  * A menu's links, ready to draw: `[{ label, to, children? }]`. If the site has no such menu, or the CMS can't be
107
135
  * reached, you get `fallback` instead, so a missing menu never takes a page down.
@@ -136,4 +164,4 @@ declare function getPage<Values = Record<string, unknown>>(astro: {
136
164
  };
137
165
  }): Promise<AcePage<Values>>;
138
166
 
139
- export { ace, applyPage, getEntries, getEntry, getMenu, getMenuLinks, getPage };
167
+ export { ace, applyPage, getEntries, getEntry, getMenu, getMenuLinks, getPage, getSite };
package/dist/astro.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createAceClient, loadMenuLinks, loadPage } from './chunk-XYOW63V6.js';
1
+ import { createAceClient, loadMenuLinks, loadPage } from './chunk-EKZRLWNO.js';
2
2
  import './chunk-M5WR5TCR.js';
3
3
  import './chunk-YLO6IAXF.js';
4
4
  import { ACE_SITE_DOMAIN, ACE_API_URL } from 'astro:env/server';
@@ -7,6 +7,7 @@ var ace = createAceClient({ apiUrl: ACE_API_URL, siteDomain: ACE_SITE_DOMAIN });
7
7
  var getEntry = ace.getEntry;
8
8
  var getEntries = ace.getEntries;
9
9
  var getMenu = ace.getMenu;
10
+ var getSite = ace.getSite;
10
11
  function getMenuLinks(handle, options = {}) {
11
12
  return loadMenuLinks(ace, handle, options.fallback ?? []);
12
13
  }
@@ -21,4 +22,4 @@ async function getPage(astro) {
21
22
  return page;
22
23
  }
23
24
 
24
- export { ace, applyPage, getEntries, getEntry, getMenu, getMenuLinks, getPage };
25
+ export { ace, applyPage, getEntries, getEntry, getMenu, getMenuLinks, getPage, getSite };
@@ -89,6 +89,10 @@ function createAceClient({
89
89
  getMenu(handle) {
90
90
  return get(`/public/menus/${encodeURIComponent(handle)}`);
91
91
  },
92
+ /** The site itself: its name, and the social image its owners chose (null if none). */
93
+ getSite() {
94
+ return get("/public/site");
95
+ },
92
96
  /** What the site's content types and fields are, which is what type generation reads. */
93
97
  async getContentTypes() {
94
98
  return await get("/public/content-types") ?? [];
package/dist/cli.js CHANGED
@@ -9,8 +9,8 @@ if (major < 22 || major === 22 && minor < 12) {
9
9
  process.exit(1);
10
10
  }
11
11
  try {
12
- const { createRealEnvironment } = await import("./environment-NGXBLWXM.js");
13
- const { runCli } = await import("./main-JOA27GX6.js");
12
+ const { createRealEnvironment } = await import("./environment-YCQRJ56U.js");
13
+ const { runCli } = await import("./main-6O2IIVHO.js");
14
14
  const environment = await createRealEnvironment();
15
15
  process.exit(await runCli(process.argv.slice(2), environment));
16
16
  } catch (error) {
@@ -145,7 +145,7 @@ function createLastApiUrl(path) {
145
145
  }
146
146
 
147
147
  // src/cli/version.ts
148
- var aceKitVersion = true ? "0.8.0" : "development";
148
+ var aceKitVersion = true ? "0.9.0" : "development";
149
149
 
150
150
  // src/cli/environment.ts
151
151
  var runCommand = (command, commandArguments, input) => new Promise((resolve, reject) => {
package/dist/index.d.ts CHANGED
@@ -84,6 +84,31 @@ type AceNavigationLink = {
84
84
  children?: AceNavigationLink[];
85
85
  };
86
86
 
87
+ /** An image as the CMS Ace public API returns it. Use `src` and `srcset` in an `<img>`. */
88
+ type AceImageData = {
89
+ id: number;
90
+ /** The untouched original. */
91
+ url: string;
92
+ /** A web-sized copy, for browsers that ignore `srcset`. */
93
+ src: string;
94
+ /** Copies at several widths; empty when the image is too small to need them. */
95
+ srcset: string;
96
+ width: number | null;
97
+ height: number | null;
98
+ alt_text: string;
99
+ content_type: string;
100
+ };
101
+
102
+ /** The site the request is for, as the CMS Ace public API returns it. */
103
+ type AceSite = {
104
+ id: number;
105
+ name: string;
106
+ domain: string;
107
+ handle: string;
108
+ /** The picture the site's owners chose to show in search results and social posts; null if none. */
109
+ social_image: AceImageData | null;
110
+ };
111
+
87
112
  /**
88
113
  * A client for the CMS Ace public API. It runs on the server only, so the visitor's browser never talks to the
89
114
  * API. The API finds the site from X-Ace-Site-Domain, which this client sets to the site's domain. X-Forwarded-Host
@@ -104,6 +129,8 @@ declare function createAceClient({ apiUrl, siteDomain, cacheSeconds, fetchImplem
104
129
  }): Promise<AceEntry<AceValuesOf<Handle>>[]>;
105
130
  /** One of the site's navigation menus by its handle, with every link worked out; null if the site has none. */
106
131
  getMenu(handle: string): Promise<AceMenu | null>;
132
+ /** The site itself: its name, and the social image its owners chose (null if none). */
133
+ getSite(): Promise<AceSite | null>;
107
134
  /** What the site's content types and fields are, which is what type generation reads. */
108
135
  getContentTypes(): Promise<AceContentTypeSchema[]>;
109
136
  };
@@ -142,21 +169,6 @@ declare const isHomeAddress: (address: AceAddress) => boolean;
142
169
  */
143
170
  declare function visitablePath(path: string): string;
144
171
 
145
- /** An image as the CMS Ace public API returns it. Use `src` and `srcset` in an `<img>`. */
146
- type AceImageData = {
147
- id: number;
148
- /** The untouched original. */
149
- url: string;
150
- /** A web-sized copy, for browsers that ignore `srcset`. */
151
- src: string;
152
- /** Copies at several widths; empty when the image is too small to need them. */
153
- srcset: string;
154
- width: number | null;
155
- height: number | null;
156
- alt_text: string;
157
- content_type: string;
158
- };
159
-
160
172
  type AceImageOptions = {
161
173
  /** How wide the image is shown, e.g. "(min-width: 64rem) 64rem, 100vw". The browser uses it to pick a copy from srcset. */
162
174
  sizes: string;
@@ -461,7 +473,10 @@ type AceSeoOptions = {
461
473
  siteName?: string;
462
474
  /** The page's address, if it isn't the one requested. Left out, the requested address is used. */
463
475
  canonical?: string;
464
- /** A picture to show when the page is shared: a full web address. */
476
+ /**
477
+ * A picture to show when the page is shared: a full web address. In the Astro `<AceSeo>`, leaving it out uses the
478
+ * social image chosen in the site's settings in the CMS (if any).
479
+ */
465
480
  image?: string;
466
481
  /** Tells search engines to leave the page out, as for a draft shown in preview. */
467
482
  noindex?: boolean;
@@ -536,4 +551,4 @@ type AceSection = {
536
551
  blocks: AceSectionBlock[];
537
552
  };
538
553
 
539
- export { type AceAddress, type AceClient, type AceClientOptions, type AceContentTypeHandle, type AceContentTypeSchema, type AceContentTypes, type AceDateFormat, type AceEntry, type AceFieldSchema, type AceImageAttributes, type AceImageData, type AceImageOptions, type AceLinkAttributes, type AceLinkData, type AceMenu, type AceMenuItem, type AceNavigationLink, type AcePage, AcePreviewExpiredError, type AceRichTextDocument, type AceRichTextMark, type AceRichTextNode, type AceSection, type AceSectionBlock, type AceSeoOptions, type AceSeoProperties, AceUnavailableError, type AceValuesOf, type BlockDefinition, type SectionDefinition, type SectionFieldDefinition, type SectionFieldType, type SectionOf, type SectionTypesPayload, type ValuesOfFields, addFramingPolicy, addressFromPath, checkSectionDefinition, createAceClient, defineSection, formatAceDate, framingPolicy, headingLevel, homeAddress, imageAttributes, isCurrentPage, isHomeAddress, isInternalPath, isRefreshRequest, linkAddress, linkAttributes, linksFromMenu, listStart, listenForPreviewRefresh, loadMenuLinks, loadPage, originOf, pageNotices, pathOfAddress, previewHeaders, previewParameter, previewTokenFrom, refreshMessageType, refreshPageContent, renderRichText, renderTextArea, richTextImageSizes, sectionTypesPayload, seoDescriptionHandle, seoProperties, seoTitleHandle, swapPageContent, visitablePath };
554
+ export { type AceAddress, type AceClient, type AceClientOptions, type AceContentTypeHandle, type AceContentTypeSchema, type AceContentTypes, type AceDateFormat, type AceEntry, type AceFieldSchema, type AceImageAttributes, type AceImageData, type AceImageOptions, type AceLinkAttributes, type AceLinkData, type AceMenu, type AceMenuItem, type AceNavigationLink, type AcePage, AcePreviewExpiredError, type AceRichTextDocument, type AceRichTextMark, type AceRichTextNode, type AceSection, type AceSectionBlock, type AceSeoOptions, type AceSeoProperties, type AceSite, AceUnavailableError, type AceValuesOf, type BlockDefinition, type SectionDefinition, type SectionFieldDefinition, type SectionFieldType, type SectionOf, type SectionTypesPayload, type ValuesOfFields, addFramingPolicy, addressFromPath, checkSectionDefinition, createAceClient, defineSection, formatAceDate, framingPolicy, headingLevel, homeAddress, imageAttributes, isCurrentPage, isHomeAddress, isInternalPath, isRefreshRequest, linkAddress, linkAttributes, linksFromMenu, listStart, listenForPreviewRefresh, loadMenuLinks, loadPage, originOf, pageNotices, pathOfAddress, previewHeaders, previewParameter, previewTokenFrom, refreshMessageType, refreshPageContent, renderRichText, renderTextArea, richTextImageSizes, sectionTypesPayload, seoDescriptionHandle, seoProperties, seoTitleHandle, swapPageContent, visitablePath };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  export { pageNotices } from './chunk-XPZY5R5A.js';
2
2
  export { headingLevel, imageAttributes, isInternalPath, linkAddress, linkAttributes, listStart, renderRichText, renderTextArea, richTextImageSizes } from './chunk-FVR55GIU.js';
3
3
  export { listenForPreviewRefresh, refreshPageContent } from './chunk-YN7LJWGI.js';
4
- export { AcePreviewExpiredError, AceUnavailableError, createAceClient, isCurrentPage, linksFromMenu, loadMenuLinks, loadPage } from './chunk-XYOW63V6.js';
4
+ export { AcePreviewExpiredError, AceUnavailableError, createAceClient, isCurrentPage, linksFromMenu, loadMenuLinks, loadPage } from './chunk-EKZRLWNO.js';
5
5
  export { addressFromPath, homeAddress, isHomeAddress, pathOfAddress, visitablePath } from './chunk-M5WR5TCR.js';
6
6
  export { addFramingPolicy, framingPolicy, isRefreshRequest, originOf, previewHeaders, previewParameter, previewTokenFrom, refreshMessageType, swapPageContent } from './chunk-YLO6IAXF.js';
7
7
 
@@ -1367,6 +1367,10 @@ function createAceClient({
1367
1367
  getMenu(handle) {
1368
1368
  return get(`/public/menus/${encodeURIComponent(handle)}`);
1369
1369
  },
1370
+ /** The site itself: its name, and the social image its owners chose (null if none). */
1371
+ getSite() {
1372
+ return get("/public/site");
1373
+ },
1370
1374
  /** What the site's content types and fields are, which is what type generation reads. */
1371
1375
  async getContentTypes() {
1372
1376
  return await get("/public/content-types") ?? [];
@@ -35,6 +35,31 @@ type AceValuesOf<Handle extends string> = Handle extends keyof AceContentTypes
35
35
  ? AceContentTypes[Handle]
36
36
  : Record<string, unknown>;
37
37
 
38
+ /** An image as the CMS Ace public API returns it. Use `src` and `srcset` in an `<img>`. */
39
+ type AceImageData = {
40
+ id: number;
41
+ /** The untouched original. */
42
+ url: string;
43
+ /** A web-sized copy, for browsers that ignore `srcset`. */
44
+ src: string;
45
+ /** Copies at several widths; empty when the image is too small to need them. */
46
+ srcset: string;
47
+ width: number | null;
48
+ height: number | null;
49
+ alt_text: string;
50
+ content_type: string;
51
+ };
52
+
53
+ /** The site the request is for, as the CMS Ace public API returns it. */
54
+ type AceSite = {
55
+ id: number;
56
+ name: string;
57
+ domain: string;
58
+ handle: string;
59
+ /** The picture the site's owners chose to show in search results and social posts; null if none. */
60
+ social_image: AceImageData | null;
61
+ };
62
+
38
63
  /** One link of a menu as the public API returns it, with its address already worked out. */
39
64
  type AceMenuItem = {
40
65
  label: string;
@@ -107,6 +132,8 @@ declare function createAceClient({ apiUrl, siteDomain, cacheSeconds, fetchImplem
107
132
  }): Promise<AceEntry<AceValuesOf<Handle>>[]>;
108
133
  /** One of the site's navigation menus by its handle, with every link worked out; null if the site has none. */
109
134
  getMenu(handle: string): Promise<AceMenu | null>;
135
+ /** The site itself: its name, and the social image its owners chose (null if none). */
136
+ getSite(): Promise<AceSite | null>;
110
137
  /** What the site's content types and fields are, which is what type generation reads. */
111
138
  getContentTypes(): Promise<AceContentTypeSchema[]>;
112
139
  };
@@ -134,6 +161,8 @@ declare const getEntry: AceClient["getEntry"];
134
161
  declare const getEntries: AceClient["getEntries"];
135
162
  /** A navigation menu with every link worked out, or `null`. */
136
163
  declare const getMenu: (handle: string) => Promise<AceMenu | null>;
164
+ /** The site: its name and the social image its owners chose (`social_image`, or `null`). */
165
+ declare const getSite: () => Promise<AceSite | null>;
137
166
  /**
138
167
  * A menu's links, ready to draw. If the site has no such menu, or the CMS can't be reached, you get `fallback`
139
168
  * instead, so a missing menu never takes a page down.
@@ -223,4 +252,4 @@ declare const streamTimeout = 5000;
223
252
  */
224
253
  declare function handleRequest(request: Request, responseStatusCode: number, responseHeaders: Headers, routerContext: EntryContext, _loadContext: AppLoadContext): Promise<Response>;
225
254
 
226
- export { createPageLoader, createRootLoader, getAceClient, getEntries, getEntry, getMenu, getMenuLinks, handleRequest, headers, loader, streamTimeout };
255
+ export { createPageLoader, createRootLoader, getAceClient, getEntries, getEntry, getMenu, getMenuLinks, getSite, handleRequest, headers, loader, streamTimeout };
@@ -1,4 +1,4 @@
1
- import { createAceClient, loadMenuLinks, loadPage } from './chunk-XYOW63V6.js';
1
+ import { createAceClient, loadMenuLinks, loadPage } from './chunk-EKZRLWNO.js';
2
2
  import './chunk-M5WR5TCR.js';
3
3
  import { hostedAdminOrigin, hostedApiUrl } from './chunk-N5DIMG3X.js';
4
4
  import { previewTokenFrom, addFramingPolicy } from './chunk-YLO6IAXF.js';
@@ -32,6 +32,7 @@ function getAceClient() {
32
32
  var getEntry = ((...parameters) => getAceClient().getEntry(...parameters));
33
33
  var getEntries = ((...parameters) => getAceClient().getEntries(...parameters));
34
34
  var getMenu = (handle) => getAceClient().getMenu(handle);
35
+ var getSite = () => getAceClient().getSite();
35
36
  var getMenuLinks = (handle, options = {}) => loadMenuLinks(getAceClient(), handle, options.fallback ?? []);
36
37
  function createPageLoader() {
37
38
  return async function loader2({ request }) {
@@ -87,4 +88,4 @@ function handleRequest(request, responseStatusCode, responseHeaders, routerConte
87
88
  });
88
89
  }
89
90
 
90
- export { createPageLoader, createRootLoader, getAceClient, getEntries, getEntry, getMenu, getMenuLinks, handleRequest, headers, loader, streamTimeout };
91
+ export { createPageLoader, createRootLoader, getAceClient, getEntries, getEntry, getMenu, getMenuLinks, getSite, handleRequest, headers, loader, streamTimeout };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sandboxsonny/ace-kit",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Everything a website needs to use CMS Ace: a typed client, addressing, images, menus, rich text, live preview, and Astro and React adapters.",
5
5
  "keywords": [
6
6
  "cms",