@dogsbay/format-astro 0.2.0-beta.12 → 0.2.0-beta.120

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.
Files changed (83) hide show
  1. package/dist/api-markdown.d.ts +8 -0
  2. package/dist/api-markdown.d.ts.map +1 -0
  3. package/dist/api-markdown.js +50 -0
  4. package/dist/api-markdown.js.map +1 -0
  5. package/dist/base-path.d.ts +93 -7
  6. package/dist/base-path.d.ts.map +1 -1
  7. package/dist/base-path.js +122 -8
  8. package/dist/base-path.js.map +1 -1
  9. package/dist/blog.d.ts +134 -0
  10. package/dist/blog.d.ts.map +1 -0
  11. package/dist/blog.js +324 -0
  12. package/dist/blog.js.map +1 -0
  13. package/dist/browser.d.ts +14 -0
  14. package/dist/browser.d.ts.map +1 -0
  15. package/dist/browser.js +14 -0
  16. package/dist/browser.js.map +1 -0
  17. package/dist/canonical.d.ts +34 -0
  18. package/dist/canonical.d.ts.map +1 -0
  19. package/dist/canonical.js +107 -0
  20. package/dist/canonical.js.map +1 -0
  21. package/dist/cli.d.ts.map +1 -1
  22. package/dist/cli.js +1 -0
  23. package/dist/cli.js.map +1 -1
  24. package/dist/diff-decoration.d.ts +79 -0
  25. package/dist/diff-decoration.d.ts.map +1 -0
  26. package/dist/diff-decoration.js +541 -0
  27. package/dist/diff-decoration.js.map +1 -0
  28. package/dist/granularity.d.ts +83 -0
  29. package/dist/granularity.d.ts.map +1 -0
  30. package/dist/granularity.js +247 -0
  31. package/dist/granularity.js.map +1 -0
  32. package/dist/head-metadata.d.ts +26 -0
  33. package/dist/head-metadata.d.ts.map +1 -0
  34. package/dist/head-metadata.js +56 -0
  35. package/dist/head-metadata.js.map +1 -0
  36. package/dist/index.d.ts +24 -4
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +30 -3
  39. package/dist/index.js.map +1 -1
  40. package/dist/lead.d.ts +1 -38
  41. package/dist/lead.d.ts.map +1 -1
  42. package/dist/lead.js +3 -37
  43. package/dist/lead.js.map +1 -1
  44. package/dist/llms-txt.d.ts +53 -11
  45. package/dist/llms-txt.d.ts.map +1 -1
  46. package/dist/llms-txt.js +85 -222
  47. package/dist/llms-txt.js.map +1 -1
  48. package/dist/plugins.d.ts.map +1 -1
  49. package/dist/plugins.js +4 -2
  50. package/dist/plugins.js.map +1 -1
  51. package/dist/project.d.ts +377 -12
  52. package/dist/project.d.ts.map +1 -1
  53. package/dist/project.js +2263 -661
  54. package/dist/project.js.map +1 -1
  55. package/dist/redirects.d.ts +116 -0
  56. package/dist/redirects.d.ts.map +1 -0
  57. package/dist/redirects.js +224 -0
  58. package/dist/redirects.js.map +1 -0
  59. package/dist/serialize.d.ts +14 -0
  60. package/dist/serialize.d.ts.map +1 -1
  61. package/dist/serialize.js +643 -216
  62. package/dist/serialize.js.map +1 -1
  63. package/dist/sitemap.d.ts +108 -0
  64. package/dist/sitemap.d.ts.map +1 -0
  65. package/dist/sitemap.js +127 -0
  66. package/dist/sitemap.js.map +1 -0
  67. package/dist/taxonomy.d.ts +48 -1
  68. package/dist/taxonomy.d.ts.map +1 -1
  69. package/dist/taxonomy.js +46 -11
  70. package/dist/taxonomy.js.map +1 -1
  71. package/dist/theme-css.d.ts +26 -0
  72. package/dist/theme-css.d.ts.map +1 -0
  73. package/dist/theme-css.js +642 -0
  74. package/dist/theme-css.js.map +1 -0
  75. package/dist/tone-classes.d.ts +14 -0
  76. package/dist/tone-classes.d.ts.map +1 -0
  77. package/dist/tone-classes.js +30 -0
  78. package/dist/tone-classes.js.map +1 -0
  79. package/dist/write-if-changed.d.ts +21 -0
  80. package/dist/write-if-changed.d.ts.map +1 -0
  81. package/dist/write-if-changed.js +58 -0
  82. package/dist/write-if-changed.js.map +1 -0
  83. package/package.json +16 -7
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Granularity views — assemble a whole-book page from topic pages + nav.
3
+ *
4
+ * The additive-MVP core (see plans/granularity-views.md). Given the topic-grained
5
+ * `ExportPage[]` + the `NavItem[]` tree a site already produces, this reassembles
6
+ * an entire nav subtree into ONE "book" page:
7
+ * - each nav node becomes a heading (level = nav depth; book title is the
8
+ * implicit H1, so a top-level node is H2, its children H3, … clamped at H6);
9
+ * - a topic's own body headings are shifted down by `level − 1` so they nest
10
+ * under their topic's title;
11
+ * - every node gets a stable, page-unique anchor, so a topic resolves to
12
+ * `<book>/_book#<anchor>` (the "Read as single page" button target).
13
+ *
14
+ * Pure + source-agnostic: it never touches the network or the original source,
15
+ * only the already-converted `TreeNode` trees ("convert once, project many").
16
+ * The original topic trees are NOT mutated — each is deep-cloned before its
17
+ * headings are shifted.
18
+ *
19
+ * This is a platform generalization of `format-fluidtopics-rest/src/single-page.ts`
20
+ * (which is khub-coupled). The FT `--single-page` branch will fold into this.
21
+ */
22
+ import type { ExportPage, NavItem, TreeNode } from "@dogsbay/types";
23
+ /**
24
+ * Reserved route segment for the book rollup. NOT `_`-prefixed: Astro treats
25
+ * `src/pages/` files/dirs starting with `_` as private (non-routable), so a
26
+ * `_book.astro` would 404. `~book` is collision-proof instead — `slugify`
27
+ * strips `~`, so no content slug can ever produce this segment (no slugifier
28
+ * reservation needed).
29
+ */
30
+ export declare const BOOK_SEGMENT = "~book";
31
+ export interface AssembleBookOptions {
32
+ /** Route prefix the nav hrefs carry (e.g. "/docs" or ""); stripped to get slugs. */
33
+ hrefPrefix?: string;
34
+ /** Book page title; defaults to the first nav item's label. */
35
+ title?: string;
36
+ /** Reserved suffix segment for the rollup route. Default `_book`. */
37
+ bookSegment?: string;
38
+ }
39
+ export interface BookView {
40
+ /** The assembled book page (noindex; excluded from nav/sitemap/search/llms). */
41
+ page: ExportPage;
42
+ /**
43
+ * topic slug → its anchor on the book page. Powers the per-topic
44
+ * "Read as single page" button (`<bookRoute>#<anchor>`).
45
+ */
46
+ topicAnchors: Map<string, string>;
47
+ }
48
+ /**
49
+ * Rough estimate of a TreeNode[]'s textual content size in bytes — the sum of
50
+ * its prose text, pre-rendered html, and string prop values (code, etc.). Used
51
+ * as the granularity size cap's input: it tracks source size closely enough to
52
+ * catch the 10 MB+ rollups (rest_api, installing) that blow up build + DOM,
53
+ * without a full serialize. See docs-dev/granularity-book-perf.md.
54
+ */
55
+ export declare function estimateTreeBytes(tree: TreeNode[]): number;
56
+ /**
57
+ * Assemble one book page from a nav subtree + the topic pages it references.
58
+ * Returns null when the subtree references no actual pages.
59
+ */
60
+ export declare function assembleBook(nav: NavItem[], pages: ExportPage[], opts?: AssembleBookOptions): BookView | null;
61
+ /** The "Open as page ↗" affordance — a link from a book section back to its topic page. */
62
+ export declare function openAsPageNode(slug: string, hrefPrefix: string): TreeNode;
63
+ /** A heading node for a nav entry's title, carrying the explicit anchor id. */
64
+ export declare function bookHeading(level: number, title: string, anchor: string): TreeNode;
65
+ /** Shift every heading in a (topic body) tree down by `offset` ranks (max H6). */
66
+ export declare function shiftHeadings(tree: TreeNode[], offset: number): void;
67
+ /**
68
+ * Rewrite **intra-book** xrefs to in-page anchors so the reader stays in the
69
+ * book. A link is rewritten iff its target slug is in *this* book's
70
+ * `topicAnchors` (the "is it in this book?" test). Cross-book links (target not
71
+ * in the book) and external links are left untouched — they keep pointing at the
72
+ * canonical topic page, which is correct. Mutates `tree` (already a clone).
73
+ */
74
+ export declare function rewriteIntraBookLinks(tree: TreeNode[], topicAnchors: Map<string, string>, hrefPrefix: string): void;
75
+ /**
76
+ * Longest common path prefix (slash-segment-wise) of the member slugs — the
77
+ * book's base route (e.g. the FT book base `…/16.0`). Falls back to `fallback`.
78
+ */
79
+ export declare function bookSlugFrom(slugs: string[], fallback: string): string;
80
+ /** Strip the route prefix + leading slash + anchor/query from a nav href → slug. */
81
+ export declare function slugFromHref(href: string | undefined, hrefPrefix: string): string;
82
+ export declare function slugify(text: string): string;
83
+ //# sourceMappingURL=granularity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"granularity.d.ts","sourceRoot":"","sources":["../src/granularity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAW,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE7E;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,UAAU,CAAC;AAEpC,MAAM,WAAW,mBAAmB;IAClC,oFAAoF;IACpF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,gFAAgF;IAChF,IAAI,EAAE,UAAU,CAAC;IACjB;;;OAGG;IACH,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,CAoB1D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,OAAO,EAAE,EACd,KAAK,EAAE,UAAU,EAAE,EACnB,IAAI,GAAE,mBAAwB,GAC7B,QAAQ,GAAG,IAAI,CAuEjB;AAID,2FAA2F;AAC3F,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,QAAQ,CAOzE;AAED,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,CAMlF;AAED,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAUpE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,QAAQ,EAAE,EAChB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACjC,UAAU,EAAE,MAAM,GACjB,IAAI,CAmBN;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAUtE;AAED,oFAAoF;AACpF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAKjF;AAuCD,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAU5C"}
@@ -0,0 +1,247 @@
1
+ /**
2
+ * Reserved route segment for the book rollup. NOT `_`-prefixed: Astro treats
3
+ * `src/pages/` files/dirs starting with `_` as private (non-routable), so a
4
+ * `_book.astro` would 404. `~book` is collision-proof instead — `slugify`
5
+ * strips `~`, so no content slug can ever produce this segment (no slugifier
6
+ * reservation needed).
7
+ */
8
+ export const BOOK_SEGMENT = "~book";
9
+ /**
10
+ * Rough estimate of a TreeNode[]'s textual content size in bytes — the sum of
11
+ * its prose text, pre-rendered html, and string prop values (code, etc.). Used
12
+ * as the granularity size cap's input: it tracks source size closely enough to
13
+ * catch the 10 MB+ rollups (rest_api, installing) that blow up build + DOM,
14
+ * without a full serialize. See docs-dev/granularity-book-perf.md.
15
+ */
16
+ export function estimateTreeBytes(tree) {
17
+ let bytes = 0;
18
+ const walk = (nodes) => {
19
+ for (const node of nodes) {
20
+ const n = node;
21
+ if (typeof n.html === "string")
22
+ bytes += n.html.length;
23
+ if (n.props) {
24
+ for (const v of Object.values(n.props))
25
+ if (typeof v === "string")
26
+ bytes += v.length;
27
+ }
28
+ if (Array.isArray(n.inline)) {
29
+ for (const i of n.inline) {
30
+ if (typeof i.text === "string")
31
+ bytes += i.text.length;
32
+ else if (typeof i.value === "string")
33
+ bytes += i.value.length;
34
+ }
35
+ }
36
+ if (n.children?.length)
37
+ walk(n.children);
38
+ }
39
+ };
40
+ walk(tree);
41
+ return bytes;
42
+ }
43
+ /**
44
+ * Assemble one book page from a nav subtree + the topic pages it references.
45
+ * Returns null when the subtree references no actual pages.
46
+ */
47
+ export function assembleBook(nav, pages, opts = {}) {
48
+ const hrefPrefix = opts.hrefPrefix ?? "";
49
+ const bookSegment = opts.bookSegment ?? BOOK_SEGMENT;
50
+ const bySlug = new Map(pages.map((p) => [p.slug, p]));
51
+ const topicAnchors = new Map();
52
+ const memberSlugs = [];
53
+ const seenAnchor = new Map();
54
+ const uniqueAnchor = (base) => {
55
+ const b = base || "section";
56
+ const n = seenAnchor.get(b) ?? 0;
57
+ seenAnchor.set(b, n + 1);
58
+ return n === 0 ? b : `${b}-${n}`;
59
+ };
60
+ const ordered = [];
61
+ const assign = (items, depth) => {
62
+ for (const item of items) {
63
+ const level = Math.min(depth + 2, 6);
64
+ const slug = slugFromHref(item.href, hrefPrefix);
65
+ const anchor = uniqueAnchor(slugify(slug ? lastSegment(slug) : item.label));
66
+ ordered.push({ label: item.label, level, slug, anchor });
67
+ if (slug && bySlug.has(slug)) {
68
+ topicAnchors.set(slug, anchor);
69
+ memberSlugs.push(slug);
70
+ }
71
+ if (item.children?.length)
72
+ assign(item.children, depth + 1);
73
+ }
74
+ };
75
+ assign(nav, 0);
76
+ if (memberSlugs.length === 0)
77
+ return null;
78
+ // Pass 2 — assemble: a heading per node, then the topic body (cloned, headings
79
+ // shifted to nest, and intra-book xrefs rewritten to in-page anchors).
80
+ const tree = [];
81
+ for (const { label, level, slug, anchor } of ordered) {
82
+ tree.push(bookHeading(level, label, anchor));
83
+ const page = slug ? bySlug.get(slug) : undefined;
84
+ if (page) {
85
+ // "Open as page ↗" — the way back from the book to the focused topic.
86
+ // Pushed OUTSIDE the body so rewriteIntraBookLinks (which runs on the
87
+ // clone only) doesn't collapse it to an in-page anchor.
88
+ tree.push(openAsPageNode(slug, hrefPrefix));
89
+ // Clone so we never mutate the topic page that is also emitted standalone.
90
+ const body = structuredClone(page.tree);
91
+ shiftHeadings(body, level - 1);
92
+ rewriteIntraBookLinks(body, topicAnchors, hrefPrefix);
93
+ tree.push(...body);
94
+ }
95
+ }
96
+ const title = opts.title ?? nav[0]?.label ?? "Book";
97
+ const base = bookSlugFrom(memberSlugs, slugify(title));
98
+ const slug = `${base}/${bookSegment}`;
99
+ const page = {
100
+ slug,
101
+ title,
102
+ tree,
103
+ headings: extractBookHeadings(tree),
104
+ // Quarantine marker — the emitters keep the book out of search / sitemap /
105
+ // llms and tag it noindex. Kept in frontmatter so it round-trips + is visible.
106
+ frontmatter: { noindex: true, granularity: "book" },
107
+ };
108
+ return { page, topicAnchors };
109
+ }
110
+ // ── pure helpers (ported from format-fluidtopics-rest/single-page.ts) ──────
111
+ /** The "Open as page ↗" affordance — a link from a book section back to its topic page. */
112
+ export function openAsPageNode(slug, hrefPrefix) {
113
+ const route = hrefPrefix ? `${hrefPrefix}/${slug}` : `/${slug}`;
114
+ return {
115
+ type: "paragraph",
116
+ props: { class: "dsb-open-as-page" },
117
+ children: [{ type: "prose", inline: [{ type: "link", href: route, children: [{ type: "text", text: "Open as page ↗" }] }] }],
118
+ };
119
+ }
120
+ /** A heading node for a nav entry's title, carrying the explicit anchor id. */
121
+ export function bookHeading(level, title, anchor) {
122
+ return {
123
+ type: "heading",
124
+ props: { level, slug: anchor, text: title },
125
+ children: [{ type: "prose", inline: [{ type: "text", text: title }] }],
126
+ };
127
+ }
128
+ /** Shift every heading in a (topic body) tree down by `offset` ranks (max H6). */
129
+ export function shiftHeadings(tree, offset) {
130
+ if (offset <= 0)
131
+ return;
132
+ for (const n of tree) {
133
+ if (n.type === "heading") {
134
+ const lvl = n.props?.level ?? 1;
135
+ if (!n.props)
136
+ n.props = {};
137
+ n.props.level = Math.min(lvl + offset, 6);
138
+ }
139
+ if (n.children)
140
+ shiftHeadings(n.children, offset);
141
+ }
142
+ }
143
+ /**
144
+ * Rewrite **intra-book** xrefs to in-page anchors so the reader stays in the
145
+ * book. A link is rewritten iff its target slug is in *this* book's
146
+ * `topicAnchors` (the "is it in this book?" test). Cross-book links (target not
147
+ * in the book) and external links are left untouched — they keep pointing at the
148
+ * canonical topic page, which is correct. Mutates `tree` (already a clone).
149
+ */
150
+ export function rewriteIntraBookLinks(tree, topicAnchors, hrefPrefix) {
151
+ const rewriteInline = (nodes) => {
152
+ for (const n of nodes) {
153
+ if (n.type === "link" && typeof n.href === "string") {
154
+ const slug = slugFromHref(n.href, hrefPrefix);
155
+ const anchor = slug ? topicAnchors.get(slug) : undefined;
156
+ if (anchor)
157
+ n.href = `#${anchor}`;
158
+ }
159
+ if (Array.isArray(n.children))
160
+ rewriteInline(n.children);
161
+ }
162
+ };
163
+ const walk = (ns) => {
164
+ for (const n of ns) {
165
+ if (n.inline)
166
+ rewriteInline(n.inline);
167
+ if (n.children)
168
+ walk(n.children);
169
+ }
170
+ };
171
+ walk(tree);
172
+ }
173
+ /**
174
+ * Longest common path prefix (slash-segment-wise) of the member slugs — the
175
+ * book's base route (e.g. the FT book base `…/16.0`). Falls back to `fallback`.
176
+ */
177
+ export function bookSlugFrom(slugs, fallback) {
178
+ const parts = slugs.filter(Boolean).map((s) => s.split("/"));
179
+ if (!parts.length)
180
+ return fallback;
181
+ const first = parts[0];
182
+ let i = 0;
183
+ for (; i < first.length; i++) {
184
+ const seg = first[i];
185
+ if (!parts.every((p) => p[i] === seg))
186
+ break;
187
+ }
188
+ return first.slice(0, i).join("/") || fallback;
189
+ }
190
+ /** Strip the route prefix + leading slash + anchor/query from a nav href → slug. */
191
+ export function slugFromHref(href, hrefPrefix) {
192
+ if (!href)
193
+ return "";
194
+ let s = href.split("#")[0].split("?")[0].trim();
195
+ if (hrefPrefix && s.startsWith(hrefPrefix))
196
+ s = s.slice(hrefPrefix.length);
197
+ return s.replace(/^\/+/, "").replace(/\/+$/, "");
198
+ }
199
+ function lastSegment(slug) {
200
+ return slug.split("/").pop() ?? slug;
201
+ }
202
+ /** Collect Heading[] from an assembled tree (nodes already carry props.slug/level/text). */
203
+ function extractBookHeadings(tree) {
204
+ const out = [];
205
+ const walk = (ns) => {
206
+ for (const n of ns) {
207
+ if (n.type === "heading") {
208
+ out.push({
209
+ depth: n.props?.level ?? 1,
210
+ slug: n.props?.slug ?? "",
211
+ text: n.props?.text ?? inlineText(n),
212
+ });
213
+ }
214
+ if (n.children)
215
+ walk(n.children);
216
+ }
217
+ };
218
+ walk(tree);
219
+ return out;
220
+ }
221
+ function inlineText(node) {
222
+ const parts = [];
223
+ const fromInline = (ns = []) => {
224
+ for (const n of ns) {
225
+ if (typeof n.text === "string")
226
+ parts.push(n.text);
227
+ else if (Array.isArray(n.children))
228
+ fromInline(n.children);
229
+ }
230
+ };
231
+ if (node.inline)
232
+ fromInline(node.inline);
233
+ if (node.children)
234
+ for (const c of node.children)
235
+ parts.push(inlineText(c));
236
+ return parts.join("").trim();
237
+ }
238
+ export function slugify(text) {
239
+ return (text
240
+ .toLowerCase()
241
+ .replace(/[^\w\s-]/g, "")
242
+ .replace(/\s+/g, "-")
243
+ .replace(/-+/g, "-")
244
+ .replace(/^-+|-+$/g, "")
245
+ .trim() || "section");
246
+ }
247
+ //# sourceMappingURL=granularity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"granularity.js","sourceRoot":"","sources":["../src/granularity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Head metadata per page (dogsbay-ssg plans/head-metadata.md, Blume item 2):
3
+ * whether it is a home page (JSON-LD `WebSite`, og:type website), its
4
+ * `hreflang` alternates across languages, and its nav trail for JSON-LD
5
+ * `BreadcrumbList`. The builders are @dogsbay/site-files', shared with
6
+ * dogsbay-ssg; this file finds the inputs in the imported pages and the nav.
7
+ */
8
+ import type { ExportPage, NavItem } from "@dogsbay/types";
9
+ import { type HreflangLink } from "@dogsbay/site-files";
10
+ export interface HeadMetadata {
11
+ home: boolean;
12
+ alternates: HreflangLink[];
13
+ breadcrumbJsonLd?: Record<string, unknown>;
14
+ }
15
+ export interface HeadMetadataOptions {
16
+ siteUrl?: string;
17
+ /** urlBase + basePath, as the sitemap takes it. */
18
+ basePath?: string;
19
+ defaultLocale?: string;
20
+ /** Pages the build writes (not fragments or excluded routes); others are never an alternate. Drafts and redirects are left out as well. */
21
+ isEmitted?: (p: ExportPage) => boolean;
22
+ /** Pages that list alternates: their own canonical and indexable (hreflang between non-canonical URLs is ignored by search engines). */
23
+ indexable?: (p: ExportPage) => boolean;
24
+ }
25
+ export declare function headMetadata(pages: ExportPage[], nav: NavItem[], o: HeadMetadataOptions): Map<string, HeadMetadata>;
26
+ //# sourceMappingURL=head-metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"head-metadata.d.ts","sourceRoot":"","sources":["../src/head-metadata.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAA6C,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnG,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2IAA2I;IAC3I,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,OAAO,CAAC;IACvC,wIAAwI;IACxI,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,OAAO,CAAC;CACxC;AAQD,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,mBAAmB,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CA+CnH"}
@@ -0,0 +1,56 @@
1
+ import { buildBreadcrumbJsonLd, buildHreflangLinks } from "@dogsbay/site-files";
2
+ import { normalizePrefix, originOf, pageHref } from "./sitemap.js";
3
+ /** Path inside the page's source (`guide/install`), `index` for a home page. */
4
+ function inside(p) {
5
+ const orig = (p.multiSource?.originalSlug ?? p.slug).replace(/^\/+|\/+$/g, "");
6
+ return orig === "" || orig === "index" ? "index" : orig.replace(/\/index$/, "");
7
+ }
8
+ export function headMetadata(pages, nav, o) {
9
+ const plan = new Map();
10
+ const live = (p) => !p.redirect && p.frontmatter?.draft !== true && p.frontmatter?.status !== "draft" && (o.isEmitted?.(p) ?? true);
11
+ const prefix = normalizePrefix(o.basePath);
12
+ const origin = o.siteUrl && /^https?:\/\//.test(o.siteUrl) ? originOf(o.siteUrl).replace(/\/+$/, "") : undefined;
13
+ const url = (slug) => (origin ? `${origin}${pageHref(slug, prefix)}` : undefined);
14
+ // Copies of one page across languages: same namespace, version and path inside the source.
15
+ const copies = new Map();
16
+ const locales = new Set(pages.map((p) => p.multiSource?.locale).filter(Boolean));
17
+ if (origin && locales.size >= 2) {
18
+ for (const p of pages) {
19
+ const m = p.multiSource;
20
+ if (!m?.locale || !live(p))
21
+ continue;
22
+ const key = `${m.namespace ?? ""}\0${m.version ?? ""}\0${inside(p)}`;
23
+ const list = copies.get(key) ?? [];
24
+ list.push({ lang: m.locale, url: url(p.slug) });
25
+ copies.set(key, list);
26
+ }
27
+ }
28
+ // The nav trail to each page: labels and hrefs from the top level down.
29
+ const trails = new Map();
30
+ const clean = (href) => href.replace(/[?#].*$/, "").replace(/^\/+|\/+$/g, "").replace(/(^|\/)index$/, "");
31
+ const mount = prefix.replace(/^\/+/, "");
32
+ const key = (href) => {
33
+ const h = clean(href);
34
+ return mount && (h === mount || h.startsWith(`${mount}/`)) ? h.slice(mount.length).replace(/^\/+/, "") : h;
35
+ };
36
+ const walk = (items, chain) => {
37
+ for (const it of items) {
38
+ const here = [...chain, { name: it.label, href: it.href }];
39
+ if (it.href && !/^[a-z][a-z0-9+.-]*:/i.test(it.href) && !it.href.includes("#") && !trails.has(key(it.href)))
40
+ trails.set(key(it.href), here);
41
+ if (it.children?.length)
42
+ walk(it.children, here);
43
+ }
44
+ };
45
+ walk(nav, []);
46
+ for (const p of pages) {
47
+ const home = inside(p) === "index";
48
+ const m = p.multiSource;
49
+ const alternates = m?.locale && live(p) && (o.indexable?.(p) ?? true) ? buildHreflangLinks(copies.get(`${m.namespace ?? ""}\0${m.version ?? ""}\0${inside(p)}`) ?? [], o.defaultLocale) : [];
50
+ const trail = origin && !home ? trails.get(clean(p.slug)) : undefined;
51
+ const breadcrumbJsonLd = trail ? buildBreadcrumbJsonLd(trail.map((t) => ({ name: t.name, url: t.href ? url(key(t.href)) : undefined }))) : undefined;
52
+ plan.set(p.slug, { home, alternates, ...(breadcrumbJsonLd ? { breadcrumbJsonLd } : {}) });
53
+ }
54
+ return plan;
55
+ }
56
+ //# sourceMappingURL=head-metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"head-metadata.js","sourceRoot":"","sources":["../src/head-metadata.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,14 +1,34 @@
1
1
  export { treeToAstro, escapeExpr, escapeAttr, escapeTemplate } from "./serialize.js";
2
- export { detectLeadingNodes } from "./lead.js";
2
+ export { writeFileSync, copyFileSync } from "./write-if-changed.js";
3
+ export { detectLeadingNodes, deriveDescription } from "./lead.js";
3
4
  export type { LeadingNodeInfo } from "./lead.js";
4
5
  export type { AstroGenResult, AstroGenOptions, AstroRenderMode } from "./serialize.js";
5
- export { DEFAULT_BASE_PATH, normalizeBasePath, basePathSegments, joinBaseUrl, buildCurrentPath, } from "./base-path.js";
6
+ export { DEFAULT_BASE_PATH, normalizeBasePath, basePathSegments, joinBaseUrl, buildCurrentPath, parseSiteUrl, combinePrefix, resolvePrefixes, } from "./base-path.js";
6
7
  export { buildLlmsTxt, buildSectionLlmsTxt, buildLlmsFullTxt, extractFirstParagraph, } from "./llms-txt.js";
7
8
  export type { BuildLlmsTxtOptions, BuildLlmsFullTxtOptions, } from "./llms-txt.js";
8
- export { exportAstroProject, emitSiteScaffold, emitSiteConfig, emitAstroPages, emitConfigDerivedFiles, emitAgentReadinessFiles, emitSwitcherMap, emitMissingTranslationStubs, } from "./project.js";
9
- export type { AstroProjectOptions, SwitcherMap } from "./project.js";
9
+ export { assertLeafSitemap, buildSitemap, buildSitemapFiles, buildSitemapIndex } from "./sitemap.js";
10
+ export { buildBlogData, blogAdjacency, emitBlogFiles, indexPageCount, readingMinutes, countWords, BLOG_DEFAULTS, } from "./blog.js";
11
+ export type { BlogEmitConfig, BlogData, BlogPostRef, BlogAdjacency, } from "./blog.js";
12
+ export type { BuildSitemapOptions } from "./sitemap.js";
13
+ export { exportAstroProject, emitSiteScaffold, emitSiteConfig, emitAstroPages, emitConfigDerivedFiles, syncSiteDependencies, copyComponents, emitAgentReadinessFiles, emitSwitcherMap, emitMissingTranslationStubs, emitPassthroughAstroPages, emitDeployArtifacts, workersSubpathOutDir, makeSlugExcluder, dropUnsafeNavHrefs, } from "./project.js";
14
+ export type { AstroProjectOptions, SwitcherMap, PassthroughCopy, } from "./project.js";
10
15
  export { emitPluginRuntime } from "./plugins.js";
11
16
  export type { EmitPluginRuntimeOptions, PluginClientModulesGroup, PluginStylesGroup, PluginClientConfig, } from "./plugins.js";
12
17
  export { buildTaxonomyData, emitTaxonomyForName, emitTaxonomyRoutes, getPageTerms, } from "./taxonomy.js";
13
18
  export type { TaxonomyEmitConfig, TaxonomyTerm, TaxonomyPageRef, TaxonomyData, } from "./taxonomy.js";
19
+ export { DIFF_CSS, decorateDiff, diffMarksOf, hasDiffMarks, injectAttrs, inlineSegmentsToHtml, } from "./diff-decoration.js";
20
+ export type { DiffMarks } from "./diff-decoration.js";
21
+ /**
22
+ * Granularity book view — assemble a nav subtree into one page.
23
+ *
24
+ * Exported because it is the PLATFORM generalization of the same algorithm
25
+ * `format-fluidtopics-rest/src/single-page.ts` implements against khub TOCs:
26
+ * without an export, no other package could reach it, which is a large part of
27
+ * why the fold described in that module never happened.
28
+ *
29
+ * See plans/granularity-views.md and docs/single-page-view.md.
30
+ */
31
+ export { BOOK_SEGMENT, assembleBook, bookHeading, bookSlugFrom, estimateTreeBytes, openAsPageNode, rewriteIntraBookLinks, shiftHeadings, slugFromHref, } from "./granularity.js";
32
+ export type { AssembleBookOptions, BookView } from "./granularity.js";
33
+ export { pageUnitPrefix, inPageUnit, normalizeTarget } from "./redirects.js";
14
34
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAMrF,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAKvF,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,EACX,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,eAAe,CAAC;AAavB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,sBAAsB,EACtB,uBAAuB,EACvB,eAAe,EACf,2BAA2B,GAC5B,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAKrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EACV,wBAAwB,EACxB,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAKtB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,YAAY,GACb,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAMpE,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAClE,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAKvF,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,eAAe,GAChB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAKrG,OAAO,EACL,aAAa,EACb,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EACd,UAAU,EACV,aAAa,GACd,MAAM,WAAW,CAAC;AACnB,YAAY,EACV,cAAc,EACd,QAAQ,EACR,WAAW,EACX,aAAa,GACd,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAaxD,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,sBAAsB,EACtB,oBAAoB,EACpB,cAAc,EACd,uBAAuB,EACvB,eAAe,EACf,2BAA2B,EAC3B,yBAAyB,EACzB,mBAAmB,EAKnB,oBAAoB,EACpB,gBAAgB,EAEhB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,mBAAmB,EACnB,WAAW,EACX,eAAe,GAChB,MAAM,cAAc,CAAC;AAKtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EACV,wBAAwB,EACxB,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAKtB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,WAAW,EACX,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;;;;;;;;GASG;AACH,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,aAAa,EACb,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -1,16 +1,23 @@
1
1
  // Astro serializer (TreeNode[] → Astro component markup)
2
2
  export { treeToAstro, escapeExpr, escapeAttr, escapeTemplate } from "./serialize.js";
3
+ export { writeFileSync, copyFileSync } from "./write-if-changed.js";
3
4
  // Auto-lede detection — figures out whether a page tree already
4
5
  // has a leading H1 / paragraph so format-astro can decide whether
5
6
  // to inject frontmatter title + description at the top of <main>.
6
7
  // See plans/auto-lede.md.
7
- export { detectLeadingNodes } from "./lead.js";
8
+ export { detectLeadingNodes, deriveDescription } from "./lead.js";
8
9
  // Base-path helpers — single source of truth for the `basePath` URL
9
10
  // prefix shared across project / nav / llms-txt / taxonomy emitters.
10
11
  // See plans/configurable-base-path.md.
11
- export { DEFAULT_BASE_PATH, normalizeBasePath, basePathSegments, joinBaseUrl, buildCurrentPath, } from "./base-path.js";
12
+ export { DEFAULT_BASE_PATH, normalizeBasePath, basePathSegments, joinBaseUrl, buildCurrentPath, parseSiteUrl, combinePrefix, resolvePrefixes, } from "./base-path.js";
12
13
  // llms.txt + llms-full.txt builders (LLM discovery files)
13
14
  export { buildLlmsTxt, buildSectionLlmsTxt, buildLlmsFullTxt, extractFirstParagraph, } from "./llms-txt.js";
15
+ // Sitemap builders (per-mount, sitemaps.org 0.9)
16
+ export { assertLeafSitemap, buildSitemap, buildSitemapFiles, buildSitemapIndex } from "./sitemap.js";
17
+ // Blog emission — reverse-chron index + post adjacency. The sibling of
18
+ // taxonomy.ts: same data-file + generated-route + writer-override shape,
19
+ // sorted by date instead of grouped by term. See plans/blog-capability.md.
20
+ export { buildBlogData, blogAdjacency, emitBlogFiles, indexPageCount, readingMinutes, countWords, BLOG_DEFAULTS, } from "./blog.js";
14
21
  // Project export — orchestrator + per-tier emitters
15
22
  //
16
23
  // `exportAstroProject` is the high-level entry: generates a complete
@@ -22,7 +29,14 @@ export { buildLlmsTxt, buildSectionLlmsTxt, buildLlmsFullTxt, extractFirstParagr
22
29
  // alone; `dogsbay site build` calls `emitAstroPages` +
23
30
  // `emitConfigDerivedFiles` + `emitAgentReadinessFiles`. Pure
24
31
  // `dogsbay convert --to astro` (Step 7) calls only `emitAstroPages`.
25
- export { exportAstroProject, emitSiteScaffold, emitSiteConfig, emitAstroPages, emitConfigDerivedFiles, emitAgentReadinessFiles, emitSwitcherMap, emitMissingTranslationStubs, } from "./project.js";
32
+ export { exportAstroProject, emitSiteScaffold, emitSiteConfig, emitAstroPages, emitConfigDerivedFiles, syncSiteDependencies, copyComponents, emitAgentReadinessFiles, emitSwitcherMap, emitMissingTranslationStubs, emitPassthroughAstroPages, emitDeployArtifacts,
33
+ // Where a Workers subpath-mounted build actually lands. Consumers that
34
+ // read the BUILT site (e.g. `dogsbay site check --dist`) must resolve
35
+ // the same directory the emitter told Astro to write to, or they audit
36
+ // an empty dist/ root.
37
+ workersSubpathOutDir, makeSlugExcluder,
38
+ // Drops nav hrefs with a scheme other than http(s)/mailto/tel.
39
+ dropUnsafeNavHrefs, } from "./project.js";
26
40
  // Plugin runtime codegen — emits the entry, virtual config modules,
27
41
  // stylesheets, and Vite alias file each plugin needs to participate
28
42
  // in the Astro / Vite build. See plans/plugin-api.md.
@@ -31,4 +45,17 @@ export { emitPluginRuntime } from "./plugins.js";
31
45
  // Per declared taxonomy in `dogsbay.config.yml`'s `taxonomies:` block,
32
46
  // emits a JSON data file + index/term .astro route files.
33
47
  export { buildTaxonomyData, emitTaxonomyForName, emitTaxonomyRoutes, getPageTerms, } from "./taxonomy.js";
48
+ export { DIFF_CSS, decorateDiff, diffMarksOf, hasDiffMarks, injectAttrs, inlineSegmentsToHtml, } from "./diff-decoration.js";
49
+ /**
50
+ * Granularity book view — assemble a nav subtree into one page.
51
+ *
52
+ * Exported because it is the PLATFORM generalization of the same algorithm
53
+ * `format-fluidtopics-rest/src/single-page.ts` implements against khub TOCs:
54
+ * without an export, no other package could reach it, which is a large part of
55
+ * why the fold described in that module never happened.
56
+ *
57
+ * See plans/granularity-views.md and docs/single-page-view.md.
58
+ */
59
+ export { BOOK_SEGMENT, assembleBook, bookHeading, bookSlugFrom, estimateTreeBytes, openAsPageNode, rewriteIntraBookLinks, shiftHeadings, slugFromHref, } from "./granularity.js";
60
+ export { pageUnitPrefix, inPageUnit, normalizeTarget } from "./redirects.js";
34
61
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErF,gEAAgE;AAChE,kEAAkE;AAClE,kEAAkE;AAClE,0BAA0B;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAI/C,oEAAoE;AACpE,qEAAqE;AACrE,uCAAuC;AACvC,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,EACX,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AAExB,0DAA0D;AAC1D,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AAMvB,oDAAoD;AACpD,EAAE;AACF,qEAAqE;AACrE,kEAAkE;AAClE,mBAAmB;AACnB,EAAE;AACF,gEAAgE;AAChE,sEAAsE;AACtE,uDAAuD;AACvD,6DAA6D;AAC7D,qEAAqE;AACrE,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,sBAAsB,EACtB,uBAAuB,EACvB,eAAe,EACf,2BAA2B,GAC5B,MAAM,cAAc,CAAC;AAGtB,oEAAoE;AACpE,oEAAoE;AACpE,sDAAsD;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAQjD,kEAAkE;AAClE,uEAAuE;AACvE,0DAA0D;AAC1D,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,GACb,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAEpE,gEAAgE;AAChE,kEAAkE;AAClE,kEAAkE;AAClE,0BAA0B;AAC1B,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAIlE,oEAAoE;AACpE,qEAAqE;AACrE,uCAAuC;AACvC,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,eAAe,GAChB,MAAM,gBAAgB,CAAC;AAExB,0DAA0D;AAC1D,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AAMvB,iDAAiD;AACjD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAErG,uEAAuE;AACvE,yEAAyE;AACzE,2EAA2E;AAC3E,OAAO,EACL,aAAa,EACb,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EACd,UAAU,EACV,aAAa,GACd,MAAM,WAAW,CAAC;AASnB,oDAAoD;AACpD,EAAE;AACF,qEAAqE;AACrE,kEAAkE;AAClE,mBAAmB;AACnB,EAAE;AACF,gEAAgE;AAChE,sEAAsE;AACtE,uDAAuD;AACvD,6DAA6D;AAC7D,qEAAqE;AACrE,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,sBAAsB,EACtB,oBAAoB,EACpB,cAAc,EACd,uBAAuB,EACvB,eAAe,EACf,2BAA2B,EAC3B,yBAAyB,EACzB,mBAAmB;AACnB,uEAAuE;AACvE,sEAAsE;AACtE,uEAAuE;AACvE,uBAAuB;AACvB,oBAAoB,EACpB,gBAAgB;AAChB,+DAA+D;AAC/D,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAOtB,oEAAoE;AACpE,oEAAoE;AACpE,sDAAsD;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAQjD,kEAAkE;AAClE,uEAAuE;AACvE,0DAA0D;AAC1D,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,GACb,MAAM,eAAe,CAAC;AAOvB,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,WAAW,EACX,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAG9B;;;;;;;;;GASG;AACH,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,aAAa,EACb,YAAY,GACb,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/lead.d.ts CHANGED
@@ -1,39 +1,2 @@
1
- /**
2
- * Detect whether a page's body tree already provides a level-1
3
- * heading and / or a leading paragraph.
4
- *
5
- * `format-astro` uses this to decide whether to auto-inject the
6
- * frontmatter `title` and `description` at the top of `<main>` —
7
- * we never overwrite writer-authored content, only fill in what
8
- * the body doesn't already cover.
9
- *
10
- * See plans/auto-lede.md.
11
- */
12
- import type { TreeNode } from "@dogsbay/types";
13
- export interface LeadingNodeInfo {
14
- /**
15
- * `true` when `tree[0]` is a level-1 heading. Heading depth
16
- * lives at either `node.depth` (some importers) or
17
- * `node.props.level` (others); both shapes are recognized.
18
- */
19
- hasH1: boolean;
20
- /**
21
- * `true` when the body's first non-heading node is a paragraph.
22
- * Used to decide whether the description should be auto-rendered
23
- * as a lede `<p>` — if the writer already wrote a lede
24
- * paragraph, we leave it alone.
25
- *
26
- * "First non-heading node" means: `tree[1]` when `tree[0]` is a
27
- * heading; otherwise `tree[0]`. So `# Title\nLede paragraph`
28
- * yields `{ hasH1: true, hasLede: true }`.
29
- */
30
- hasLede: boolean;
31
- }
32
- /**
33
- * Inspect the leading nodes of a page tree.
34
- *
35
- * Defensive against empty trees and missing properties — returns
36
- * `false` for both flags when the tree is empty.
37
- */
38
- export declare function detectLeadingNodes(tree: TreeNode[] | undefined): LeadingNodeInfo;
1
+ export { detectLeadingNodes, deriveDescription, type LeadingNodeInfo } from "@dogsbay/serialize-core";
39
2
  //# sourceMappingURL=lead.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lead.d.ts","sourceRoot":"","sources":["../src/lead.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,KAAK,EAAE,OAAO,CAAC;IACf;;;;;;;;;OASG;IACH,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,QAAQ,EAAE,GAAG,SAAS,GAC3B,eAAe,CAcjB"}
1
+ {"version":3,"file":"lead.d.ts","sourceRoot":"","sources":["../src/lead.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC"}