@dogsbay/format-astro 0.2.0-beta.149 → 0.2.0-beta.150

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/blog.js CHANGED
@@ -300,6 +300,8 @@ const title = pageNo === 1 ? siteConfig.siteName : \`\${siteConfig.siteName} —
300
300
  themeColor={siteConfig.themeColor || undefined}
301
301
  repoUrl={siteConfig.repoUrl || undefined}
302
302
  poweredBy={siteConfig.poweredBy !== false}
303
+ siteChrome={(siteConfig as { chrome?: never }).chrome}
304
+ copyright={(siteConfig as { chrome?: unknown }).chrome ? siteConfig.copyright || undefined : undefined}
303
305
  plausibleDomain={siteConfig.plausible?.domain}
304
306
  plausibleScriptUrl={siteConfig.plausible?.scriptUrl}
305
307
  tagPrefixes={siteConfig.tagPrefixes}
package/dist/project.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { ExportPage, NavItem } from "@dogsbay/types";
2
+ import { type SiteChrome } from "@dogsbay/site-files";
2
3
  import { type VersionMenu, type ProductModel } from "@dogsbay/site-files";
3
4
  import { type BlogEmitConfig } from "./blog.js";
4
5
  import { type RedirectsConfig } from "./redirects.js";
@@ -44,6 +45,17 @@ export interface AstroProjectOptions {
44
45
  repoUrl?: string;
45
46
  editUri?: string;
46
47
  copyright?: string;
48
+ /**
49
+ * The site's chrome (@dogsbay/site-files `siteChrome`: logo, colour mode, announcement, header
50
+ * links, footer columns), written into site.json as `chrome`. With it, `copyright` is inline
51
+ * Markdown (the agreed rule); without it (legacy callers), copyright stays HTML as given.
52
+ */
53
+ chrome?: SiteChrome;
54
+ /** The chrome's logo files, absolute, checked inside the project by the caller. */
55
+ chromeLogoFiles?: {
56
+ light: string;
57
+ dark?: string;
58
+ };
47
59
  /** The line under the site name in the sidebar header (`site.tagline`). Default "Documentation". */
48
60
  tagline?: string;
49
61
  /** `content.imageCaptions`: a titled block image is a captioned figure. */
package/dist/project.js CHANGED
@@ -60,6 +60,7 @@ function combinedPrefix(options) {
60
60
  return combinePrefix(urlBase, normalizeBasePath(options.basePath));
61
61
  }
62
62
  import { detectLeadingNodes, deriveDescription } from "./lead.js";
63
+ import { chromeData, copyrightHtml } from "./site-chrome.js";
63
64
  import { collectRedirects, renderMetaRefreshPage, renderRedirectsFile, stubPathForRule, } from "./redirects.js";
64
65
  /**
65
66
  * Recursively prefix all hrefs in a nav tree.
@@ -589,7 +590,14 @@ function buildSiteConfig(siteName, options, outputDir) {
589
590
  if (options.editUri)
590
591
  cfg.editUri = options.editUri;
591
592
  if (options.copyright)
592
- cfg.copyright = options.copyright;
593
+ cfg.copyright = options.chrome ? copyrightHtml(options.copyright, combinedPrefix(options)) : options.copyright;
594
+ if (options.chrome && outputDir) {
595
+ cfg.chrome = chromeData(options.chrome, outputDir, {
596
+ combined: combinedPrefix(options),
597
+ urlBase: parseSiteUrl(options.siteUrl).urlBase,
598
+ logoFiles: options.chromeLogoFiles,
599
+ });
600
+ }
593
601
  if (options.tagline)
594
602
  cfg.tagline = options.tagline;
595
603
  // Written explicitly, both ways: the default is ON, so an ABSENT key in
@@ -1505,6 +1513,8 @@ const favicon = (siteConfigData as { favicon?: string }).favicon;
1505
1513
  favicon={favicon}
1506
1514
  noindex={true}
1507
1515
  excludeFromSearch={true}
1516
+ siteChrome={(siteConfigData as { chrome?: never }).chrome}
1517
+ copyright={(siteConfig as { chrome?: unknown }).chrome ? siteConfig.copyright || undefined : undefined}
1508
1518
  ogType="website"${productMenu ? `
1509
1519
  switcherMap={{ versions: [], byLogicalKey: {}, products: switcherMapData.products } as never}` : ""}
1510
1520
  >
@@ -2146,6 +2156,10 @@ export async function emitAstroPages(pages, nav, outputDir, options) {
2146
2156
  ` linkIcons={siteConfig.linkIcons}`,
2147
2157
  // Default ON: an absent key means yes, `false` means no.
2148
2158
  ` poweredBy={siteConfig.poweredBy !== false}`,
2159
+ // site.copyright (inline Markdown, rendered into site.json): written there and never shown until 2026-10-30
2160
+ ` copyright={(siteConfig as { chrome?: unknown }).chrome ? siteConfig.copyright || undefined : undefined}`,
2161
+ // The site's chrome (site-chrome.ts): logo, colour mode, announcement, header links, footer
2162
+ ` siteChrome={(siteConfigData as { chrome?: never }).chrome}`,
2149
2163
  ` multiSource={${pageLiteral(page.multiSource ?? null)} ?? undefined}`,
2150
2164
  ` switcherMap={switcherMapData}`,
2151
2165
  // basePath here is the COMBINED URL prefix (urlBase from
@@ -0,0 +1,60 @@
1
+ import { type SiteChrome } from "@dogsbay/site-files";
2
+ /** What DocsLayout reads (`chrome` in site.json). */
3
+ export interface ChromeData {
4
+ colorMode: "light" | "dark" | "system";
5
+ logo?: {
6
+ light: string;
7
+ dark?: string;
8
+ alt: string;
9
+ replacesName: boolean;
10
+ };
11
+ announcement?: {
12
+ id: string;
13
+ html: string;
14
+ tone: string;
15
+ closeable: boolean;
16
+ };
17
+ header: {
18
+ links: Array<{
19
+ label: string;
20
+ href: string;
21
+ } | {
22
+ label: string;
23
+ items: Array<{
24
+ label: string;
25
+ href: string;
26
+ }>;
27
+ }>;
28
+ social: ChromeSocial[];
29
+ };
30
+ footer: {
31
+ columns: Array<{
32
+ title: string;
33
+ links: Array<{
34
+ label: string;
35
+ href: string;
36
+ }>;
37
+ }>;
38
+ social: ChromeSocial[];
39
+ };
40
+ }
41
+ export interface ChromeSocial {
42
+ label: string;
43
+ href: string;
44
+ svg: string;
45
+ }
46
+ export interface ChromeEmitOptions {
47
+ /** The URL prefix site paths take (urlBase + basePath). */
48
+ combined: string;
49
+ /** The host's base (the path of site.url): where `public/` is served. */
50
+ urlBase: string;
51
+ /** The logo files, absolute and already checked inside the project by the caller. */
52
+ logoFiles?: {
53
+ light: string;
54
+ dark?: string;
55
+ };
56
+ }
57
+ /** `chrome` for site.json; copies the logo files into `<outputDir>/public/_dogsbay/site/`. */
58
+ export declare function chromeData(chrome: SiteChrome, outputDir: string, o: ChromeEmitOptions): ChromeData;
59
+ /** `site.copyright` as HTML: inline Markdown, links with the site's prefix. */
60
+ export declare function copyrightHtml(copyright: string, combined: string): string;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * The site's chrome (@dogsbay/site-files `siteChrome`) as DocsLayout draws it, written into
3
+ * `src/data/site.json` as `chrome`: links with the site's prefix, the texts rendered once with
4
+ * site-files' inline Markdown (the same HTML as dogsbay-ssg), the brand icons as SVG, and the
5
+ * logo files copied to `public/_dogsbay/site/` (served from the host's base, as the favicon).
6
+ * See plans/site-chrome.md.
7
+ */
8
+ import { mkdirSync } from "node:fs";
9
+ import { extname, join } from "node:path";
10
+ import { inlineMarkdownHtml, isChromeMenu, versionMenuHref } from "@dogsbay/site-files";
11
+ import { socialIconSvg } from "@dogsbay/icons/social";
12
+ import { copyFileSync } from "./write-if-changed.js";
13
+ /** `chrome` for site.json; copies the logo files into `<outputDir>/public/_dogsbay/site/`. */
14
+ export function chromeData(chrome, outputDir, o) {
15
+ const href = (h) => versionMenuHref(h, o.combined);
16
+ const social = (list) => list.flatMap((s) => {
17
+ const svg = socialIconSvg(s.icon, 20);
18
+ return svg ? [{ label: s.label, href: href(s.href), svg }] : [];
19
+ });
20
+ const data = {
21
+ colorMode: chrome.colorMode,
22
+ header: {
23
+ links: chrome.header.links.map((l) => (isChromeMenu(l) ? { label: l.label, items: l.items.map((i) => ({ label: i.label, href: href(i.href) })) } : { label: l.label, href: href(l.href) })),
24
+ social: social(chrome.header.social),
25
+ },
26
+ footer: {
27
+ columns: chrome.footer.columns.map((c) => ({ title: c.title, links: c.links.map((l) => ({ label: l.label, href: href(l.href) })) })),
28
+ social: social(chrome.footer.social),
29
+ },
30
+ };
31
+ if (chrome.announcement) {
32
+ const a = chrome.announcement;
33
+ data.announcement = { id: a.id, html: inlineMarkdownHtml(a.text, { href }), tone: a.tone, closeable: a.closeable };
34
+ }
35
+ if (chrome.logo && o.logoFiles) {
36
+ const dir = join(outputDir, "public", "_dogsbay", "site");
37
+ mkdirSync(dir, { recursive: true });
38
+ // The type is the config's path's (checked by siteChrome), not a symbolic link target's
39
+ const served = (from, written, name) => {
40
+ const file = `${name}${extname(written).toLowerCase()}`;
41
+ copyFileSync(from, join(dir, file));
42
+ return `${o.urlBase}/_dogsbay/site/${file}`;
43
+ };
44
+ data.logo = {
45
+ light: served(o.logoFiles.light, chrome.logo.light, "logo-light"),
46
+ ...(o.logoFiles.dark && chrome.logo.dark ? { dark: served(o.logoFiles.dark, chrome.logo.dark, "logo-dark") } : {}),
47
+ alt: chrome.logo.alt,
48
+ replacesName: chrome.logo.replacesName,
49
+ };
50
+ }
51
+ return data;
52
+ }
53
+ /** `site.copyright` as HTML: inline Markdown, links with the site's prefix. */
54
+ export function copyrightHtml(copyright, combined) {
55
+ return inlineMarkdownHtml(copyright, { href: (h) => versionMenuHref(h, combined) });
56
+ }
package/dist/taxonomy.js CHANGED
@@ -412,6 +412,8 @@ ${displayConfig}
412
412
  themeColor={siteConfig.themeColor || undefined}
413
413
  repoUrl={siteConfig.repoUrl || undefined}
414
414
  poweredBy={siteConfig.poweredBy !== false}
415
+ siteChrome={(siteConfig as { chrome?: never }).chrome}
416
+ copyright={(siteConfig as { chrome?: unknown }).chrome ? siteConfig.copyright || undefined : undefined}
415
417
  plausibleDomain={siteConfig.plausible?.domain}
416
418
  plausibleScriptUrl={siteConfig.plausible?.scriptUrl}
417
419
  tagPrefixes={siteConfig.tagPrefixes}
@@ -470,6 +472,8 @@ const title = \`\${term.label} — ${escapeTemplate(taxonomyDisplay)}\`;
470
472
  themeColor={siteConfig.themeColor || undefined}
471
473
  repoUrl={siteConfig.repoUrl || undefined}
472
474
  poweredBy={siteConfig.poweredBy !== false}
475
+ siteChrome={(siteConfig as { chrome?: never }).chrome}
476
+ copyright={(siteConfig as { chrome?: unknown }).chrome ? siteConfig.copyright || undefined : undefined}
473
477
  plausibleDomain={siteConfig.plausible?.domain}
474
478
  plausibleScriptUrl={siteConfig.plausible?.scriptUrl}
475
479
  tagPrefixes={siteConfig.tagPrefixes}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dogsbay/format-astro",
3
- "version": "0.2.0-beta.149",
3
+ "version": "0.2.0-beta.150",
4
4
  "description": "Astro format plugin for Dogsbay — export TreeNode[] to Astro component markup",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -32,12 +32,13 @@
32
32
  "license": "MIT",
33
33
  "dependencies": {
34
34
  "markdown-it": "^14.3.0",
35
- "@dogsbay/format-dogsbay-md": "0.2.0-beta.149",
36
- "@dogsbay/render-html": "0.2.0-beta.149",
37
- "@dogsbay/serialize-core": "0.2.0-beta.149",
38
- "@dogsbay/site-files": "0.2.0-beta.149",
39
- "@dogsbay/types": "0.2.0-beta.149",
40
- "@dogsbay/ui": "0.2.0-beta.149"
35
+ "@dogsbay/format-dogsbay-md": "0.2.0-beta.150",
36
+ "@dogsbay/icons": "0.2.0-beta.150",
37
+ "@dogsbay/render-html": "0.2.0-beta.150",
38
+ "@dogsbay/site-files": "0.2.0-beta.150",
39
+ "@dogsbay/serialize-core": "0.2.0-beta.150",
40
+ "@dogsbay/types": "0.2.0-beta.150",
41
+ "@dogsbay/ui": "0.2.0-beta.150"
41
42
  },
42
43
  "repository": {
43
44
  "type": "git",