@publish.os/nextjs 0.0.1-alpha.91 → 0.0.1-alpha.92

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 (153) hide show
  1. package/compiler-assets/nextjs/defaults/group/index.tsx +16 -11
  2. package/compiler-assets/nextjs/defaults/group/layout.tsx +6 -2
  3. package/compiler-assets/nextjs/defaults/group/page.tsx +7 -6
  4. package/compiler-assets/nextjs/defaults/project/next.config.mjs +2 -1
  5. package/compiler-assets/nextjs/defaults/root/index.tsx +16 -11
  6. package/compiler-assets/nextjs/defaults/root/layout.tsx +7 -3
  7. package/compiler-assets/nextjs/shims/agent-user-agents.ts +65 -0
  8. package/compiler-assets/nextjs/shims/document.tsx +9 -1
  9. package/compiler-assets/nextjs/shims/generated-leaf-page.tsx +3 -0
  10. package/compiler-assets/nextjs/shims/proxy.ts +156 -54
  11. package/dist/{build-operation-5QMLXF7N.js → build-operation-CJDUL4OW.js} +5 -5
  12. package/dist/{chunk-GBPLER5H.js → chunk-3T4HVDSC.js} +2 -2
  13. package/dist/{chunk-UYGCOWRF.js → chunk-DX7PXFCM.js} +860 -50
  14. package/dist/{chunk-F3AGNDF4.js → chunk-DZ3VWEV5.js} +860 -575
  15. package/dist/{chunk-OXOFRXEI.js → chunk-NHSLTARU.js} +1284 -1164
  16. package/dist/{chunk-ORIUWJBQ.js → chunk-SBMDONTV.js} +3 -2
  17. package/dist/compiler.js +42 -23
  18. package/dist/components/blocks/agent-actions.d.ts +7 -7
  19. package/dist/components/blocks/agent-actions.js +1 -32
  20. package/dist/components/blocks/toc.d.ts +7 -7
  21. package/dist/components/ui/button.d.ts +1 -2
  22. package/dist/{compose-CVBJRAF6.js → compose-44GJSMXD.js} +2 -2
  23. package/dist/config/createNextConfig.js +2 -0
  24. package/dist/{dev-operation-OSHHWRWK.js → dev-operation-WNECBHZ5.js} +17 -7
  25. package/dist/{ide-support-CU6Z5PVR.js → ide-support-TG74L4FF.js} +3 -3
  26. package/dist/index.d.ts +143 -126
  27. package/dist/index.js +25 -0
  28. package/dist/kernel/components/blocks/AgentActions.d.ts +7 -7
  29. package/dist/kernel/components/blocks/AgentActions.js +1 -32
  30. package/dist/kernel/components/blocks/agent-actions.d.ts +1 -2
  31. package/dist/kernel/components/blocks/agent-actions.js +1 -32
  32. package/dist/kernel/components/blocks/animated-icon-swap.d.ts +2 -2
  33. package/dist/kernel/components/blocks/color-palette.d.ts +2 -2
  34. package/dist/kernel/components/blocks/logo-block.d.ts +2 -2
  35. package/dist/kernel/components/blocks/nav-breadcrumb.d.ts +6 -5
  36. package/dist/kernel/components/blocks/nav-breadcrumb.js +19 -13
  37. package/dist/kernel/components/blocks/navbar.d.ts +5 -4
  38. package/dist/kernel/components/blocks/navbar.js +62 -42
  39. package/dist/kernel/components/blocks/navigation-progress.d.ts +2 -2
  40. package/dist/kernel/components/blocks/next-prev.d.ts +4 -4
  41. package/dist/kernel/components/blocks/next-prev.js +29 -6
  42. package/dist/kernel/components/blocks/page-list.d.ts +4 -4
  43. package/dist/kernel/components/blocks/page-list.js +30 -7
  44. package/dist/kernel/components/blocks/search.d.ts +9 -15
  45. package/dist/kernel/components/blocks/sidebar-node.d.ts +3 -5
  46. package/dist/kernel/components/blocks/sidebar-node.js +12 -2
  47. package/dist/kernel/components/blocks/sidebar.d.ts +6 -7
  48. package/dist/kernel/components/blocks/sidebar.js +132 -26
  49. package/dist/kernel/components/blocks/theme-toggle.d.ts +3 -4
  50. package/dist/kernel/components/blocks/toc-client.d.ts +7 -7
  51. package/dist/kernel/components/blocks/toc.d.ts +3 -3
  52. package/dist/kernel/components/mdx/components/blockquote.d.ts +2 -2
  53. package/dist/kernel/components/mdx/components/callout.d.ts +3 -3
  54. package/dist/kernel/components/mdx/components/code-block.d.ts +2 -2
  55. package/dist/kernel/components/mdx/components/copy-code-button.d.ts +2 -2
  56. package/dist/kernel/components/mdx/components/figure-caption.d.ts +2 -2
  57. package/dist/kernel/components/mdx/components/figure.d.ts +3 -3
  58. package/dist/kernel/components/mdx/components/footnotes.d.ts +2 -2
  59. package/dist/kernel/components/mdx/components/heading-copy-link.d.ts +2 -2
  60. package/dist/kernel/components/mdx/components/heading.d.ts +2 -2
  61. package/dist/kernel/components/mdx/components/hr.d.ts +4 -4
  62. package/dist/kernel/components/mdx/components/image-zoom.d.ts +3 -3
  63. package/dist/kernel/components/mdx/components/image-zoom.js +3 -2
  64. package/dist/kernel/components/mdx/components/image.d.ts +2 -2
  65. package/dist/kernel/components/mdx/components/image.js +1 -1
  66. package/dist/kernel/components/mdx/components/inline-code.d.ts +2 -2
  67. package/dist/kernel/components/mdx/components/kbd.d.ts +3 -3
  68. package/dist/kernel/components/mdx/components/link.d.ts +3 -3
  69. package/dist/kernel/components/mdx/components/paragraph.d.ts +2 -2
  70. package/dist/kernel/components/mdx/components/strikethrough.d.ts +2 -2
  71. package/dist/kernel/components/mdx/components/table.d.ts +7 -7
  72. package/dist/kernel/components/mdx/components/task-list.d.ts +3 -3
  73. package/dist/kernel/components/mdx/components/video-player.d.ts +2 -2
  74. package/dist/kernel/components/mdx/components/video.d.ts +2 -3
  75. package/dist/kernel/components/mdx/error-boundary.d.ts +2 -3
  76. package/dist/kernel/components/mdx/error-fallback.d.ts +2 -2
  77. package/dist/kernel/components/mdx/mdx.d.ts +42 -11
  78. package/dist/kernel/components/mdx/mdx.js +1 -1
  79. package/dist/kernel/components/next-image.d.ts +3 -3
  80. package/dist/kernel/components/ui/accordion.d.ts +7 -7
  81. package/dist/kernel/components/ui/breadcrumb-trail.d.ts +2 -3
  82. package/dist/kernel/components/ui/breadcrumb.d.ts +13 -13
  83. package/dist/kernel/components/ui/button-group.d.ts +5 -5
  84. package/dist/kernel/components/ui/button.d.ts +3 -3
  85. package/dist/kernel/components/ui/card.d.ts +7 -7
  86. package/dist/kernel/components/ui/dialog.d.ts +10 -10
  87. package/dist/kernel/components/ui/drawer.d.ts +12 -12
  88. package/dist/kernel/components/ui/kbd.d.ts +3 -3
  89. package/dist/kernel/components/ui/link.d.ts +3 -3
  90. package/dist/kernel/components/ui/menu.d.ts +22 -22
  91. package/dist/kernel/components/ui/mod-key.d.ts +2 -3
  92. package/dist/kernel/components/ui/navigation-menu.d.ts +15 -15
  93. package/dist/kernel/components/ui/popover.d.ts +11 -11
  94. package/dist/kernel/components/ui/progress.d.ts +7 -7
  95. package/dist/kernel/components/ui/scroll-area.d.ts +1 -2
  96. package/dist/kernel/components/ui/select.d.ts +16 -16
  97. package/dist/kernel/components/ui/separator.d.ts +3 -3
  98. package/dist/kernel/components/ui/table.d.ts +7 -7
  99. package/dist/kernel/components/ui/tabs.d.ts +12 -12
  100. package/dist/kernel/components/ui/tag.d.ts +3 -3
  101. package/dist/kernel/components/ui/text.d.ts +4 -4
  102. package/dist/kernel/components/ui/toast.d.ts +11 -11
  103. package/dist/kernel/components/ui/tooltip.d.ts +9 -9
  104. package/dist/kernel/defaults.registry.d.ts +2 -2
  105. package/dist/kernel/defaults.registry.js +2 -2
  106. package/dist/kernel/routes/agent/markdown.d.ts +4 -0
  107. package/dist/kernel/routes/agent/markdown.js +11 -7
  108. package/dist/kernel/routes/layouts/group.d.ts +1 -1
  109. package/dist/kernel/routes/metadata/feed.d.ts +1 -2
  110. package/dist/kernel/routes/metadata/feed.js +34 -29
  111. package/dist/kernel/routes/metadata/llms.d.ts +3 -31
  112. package/dist/kernel/routes/metadata/llms.js +2 -200
  113. package/dist/kernel/routes/metadata/robots.d.ts +5 -3
  114. package/dist/kernel/routes/metadata/robots.js +4 -25
  115. package/dist/kernel/routes/metadata/sitemap.d.ts +15 -1
  116. package/dist/kernel/routes/metadata/sitemap.js +200 -112
  117. package/dist/kernel/routes/not-found.js +1 -1
  118. package/dist/kernel/routes/pages/group.d.ts +3 -3
  119. package/dist/kernel/routes/pages/group.js +10 -4
  120. package/dist/kernel/routes/pages/leaf.d.ts +9 -4
  121. package/dist/kernel/routes/pages/leaf.js +16 -8
  122. package/dist/kernel/routes/pages/root.d.ts +3 -3
  123. package/dist/kernel/routes/pages/root.js +20 -5
  124. package/dist/keyboard-shortcuts.d.ts +2 -2
  125. package/dist/manifest-types-CcVPH_jh.d.ts +83 -0
  126. package/dist/resolvers/manifest-resolver.d.ts +2 -2
  127. package/dist/resolvers/manifest-resolver.js +65 -35
  128. package/dist/search.d.ts +2 -9
  129. package/dist/search.js +2 -7
  130. package/dist/sidebar-types-CMrMM0Nj.d.ts +105 -0
  131. package/dist/theme-scope.d.ts +2 -2
  132. package/dist/types-BbqmOzLC.d.ts +168 -0
  133. package/dist/types-TjH1ek0X.d.ts +22 -0
  134. package/dist/types.d.ts +116 -91
  135. package/dist/{validate-local-source-SV44DBQT.js → validate-local-source-EN2GW4FR.js} +3 -3
  136. package/dist/{validate-publish-os-source-NZJF3TB2.js → validate-publish-os-source-OEWQDB7B.js} +2 -2
  137. package/init/seed/minimal/publish.os/blog/index.tsx +25 -22
  138. package/init/seed/minimal/publish.os/blog/page.tsx +31 -16
  139. package/init/seed/minimal/publish.os/components/blog/copy-link.tsx +1 -1
  140. package/init/seed/minimal/publish.os/components/blog/frontmatter.ts +41 -0
  141. package/init/seed/minimal/publish.os/publish.os.config.json +13 -2
  142. package/init/seed/minimal/seed.json +1 -0
  143. package/init/seed/scratch/publish.os/publish.os.config.json +1 -1
  144. package/package.json +4 -4
  145. package/release/app/phosphor/package.json +1 -1
  146. package/release/app/phosphor/pnpm-lock.yaml.template +53 -127
  147. package/release/compiler/pnpm-lock.yaml.template +49 -123
  148. package/release/release.json +4 -4
  149. package/dist/sidebar-types-DKpR27II.d.ts +0 -25
  150. package/dist/types-CJWRG05y.d.ts +0 -76
  151. package/dist/types-CUtrppxt.d.ts +0 -69
  152. package/dist/types-J2w_puPF.d.ts +0 -128
  153. package/dist/{button-BdCScEKi.d.ts → button-D6Xp2HBm.d.ts} +1 -1
@@ -5,7 +5,8 @@ import { cacheLife, cacheTag } from "next/cache";
5
5
  // src/lib/runtime/metadata/canonical-url.ts
6
6
  function canonicalUrl(manifest, path, group) {
7
7
  let origin = (group && manifest.groups[group]?.origin) ?? manifest.site.origin;
8
- if (!origin) return path;
8
+ if (!origin)
9
+ return /^[a-z][a-z\d+.-]*:/i.test(path) ? path : new URL(path, "https://publish.invalid").pathname;
9
10
  try {
10
11
  return new URL(path, `${origin}/`).toString();
11
12
  } catch {
@@ -17,36 +18,66 @@ function canonicalUrl(manifest, path, group) {
17
18
  function discoveryOrigin(manifest, group) {
18
19
  return (group ? manifest.groups[group]?.origin : void 0) ?? manifest.site.origin;
19
20
  }
20
- function pathWithin(path, basePath) {
21
- return basePath === "/" || path === basePath || path.startsWith(`${basePath}/`);
22
- }
23
- function discoveryPages({
21
+ function navigationDiscoverySections({
24
22
  manifest,
25
23
  group,
26
24
  scope,
27
- limit
28
- }) {
29
- let origin = discoveryOrigin(manifest, group), basePath = group ? manifest.groups[group]?.path ?? "/" : "/", pages = manifest.pages.filter((page) => page.status !== "published" || discoveryOrigin(manifest, page.group) !== origin ? !1 : !group || scope === "site" ? !0 : pathWithin(page.path, basePath) ? page.group === group || scope !== "self" && page.group.startsWith(`${group}/`) : !1);
30
- return limit ? pages.slice(0, limit) : pages;
31
- }
32
- function groupDiscoveryPages({
33
- manifest,
34
- pages
25
+ limit,
26
+ excludeGroups = [],
27
+ markdownPaths
35
28
  }) {
36
- let sections = /* @__PURE__ */ new Map();
37
- for (let page of pages) {
38
- let group = manifest.groups[page.group], key = group ? page.group : "", section = sections.get(key);
39
- section || (section = {
40
- ...group ? { group: page.group } : {},
41
- title: group ? group.key === "__root" ? manifest.site.name : group.title : "Pages",
42
- pages: []
43
- }, sections.set(key, section)), section.pages.push(page);
44
- }
45
- return [...sections.values()].sort(
46
- (a, b) => (manifest.groups[a.group ?? ""]?.path ?? "/").localeCompare(
47
- manifest.groups[b.group ?? ""]?.path ?? "/"
48
- ) || a.title.localeCompare(b.title)
49
- );
29
+ let origin = discoveryOrigin(manifest, group), targetGroup = group ? manifest.groups[group] : void 0, mountedGroup = Object.values(manifest.groups).find(
30
+ (candidate) => candidate.key !== "__root" && candidate.path === "/" && discoveryOrigin(manifest, candidate.key) === origin
31
+ ), rootGroups = targetGroup && scope !== "site" ? [manifest.groups[targetGroup.navigation.rootGroup]] : Object.values(manifest.groups).filter(
32
+ (candidate) => candidate.key === candidate.navigation.rootGroup && (candidate.key !== "__root" || !mountedGroup) && discoveryOrigin(manifest, candidate.key) === origin
33
+ ), sections = [], pageKeys = /* @__PURE__ */ new Set(), pageCount = 0, inScope = (entryGroup) => discoveryOrigin(manifest, entryGroup) !== origin || excludeGroups.some(
34
+ (excluded) => entryGroup === excluded || entryGroup.startsWith(`${excluded}/`)
35
+ ) ? !1 : !targetGroup || scope === "site" ? !0 : entryGroup === targetGroup.key || scope !== "self" && entryGroup.startsWith(`${targetGroup.key}/`), append = (title, entry) => {
36
+ let previous = sections.at(-1);
37
+ previous?.title === title ? previous.entries.push(entry) : sections.push({ title, entries: [entry] });
38
+ }, visit = (nodes, groupKey, headings) => {
39
+ for (let node of nodes)
40
+ if (node.type === "page") {
41
+ let page = node.page, key = `${page.group}/${page.fileID}`;
42
+ if (page.frontmatter.status !== "published" || !inScope(page.group) || pageKeys.has(key) || limit !== void 0 && limit > 0 && pageCount >= limit)
43
+ continue;
44
+ pageKeys.add(key), pageCount += 1, append(headings.join(" > "), {
45
+ type: "page",
46
+ title: node.label || page.frontmatter.title,
47
+ url: canonicalUrl(
48
+ manifest,
49
+ markdownPaths?.get(page.path) ?? page.path,
50
+ page.group
51
+ ),
52
+ path: page.path,
53
+ group: page.group,
54
+ ...page.frontmatter.description ? { description: page.frontmatter.description } : {}
55
+ }), node.children && visit(node.children, page.group, headings);
56
+ } else node.type === "group" ? (inScope(node.groupKey) && append(headings.join(" > "), {
57
+ type: "link",
58
+ title: node.label,
59
+ url: canonicalUrl(manifest, node.route, node.groupKey),
60
+ group: node.groupKey
61
+ }), visit(node.children, node.groupKey, [...headings, node.label])) : node.type === "link" ? inScope(groupKey) && append(headings.join(" > "), {
62
+ type: "link",
63
+ title: node.label,
64
+ url: canonicalUrl(manifest, node.href, groupKey),
65
+ group: groupKey
66
+ }) : node.type === "section" || node.type === "folder" ? visit(node.children, groupKey, [...headings, node.label]) : node.type === "view" && visit(node.items, groupKey, headings);
67
+ };
68
+ for (let root of rootGroups)
69
+ !root || discoveryOrigin(manifest, root.key) !== origin || (!targetGroup || scope === "site" ? append(root.title, {
70
+ type: "link",
71
+ title: root.title,
72
+ url: canonicalUrl(manifest, root.path, root.key),
73
+ group: root.key
74
+ }) : root.key === targetGroup.key && append(root.title, {
75
+ type: "link",
76
+ title: root.title,
77
+ url: canonicalUrl(manifest, root.path, root.key),
78
+ group: root.key
79
+ }), visit(root.navigation.items, root.key, [root.title]));
80
+ return sections;
50
81
  }
51
82
 
52
83
  // src/lib/runtime/metadata/llms-serialization.ts
@@ -61,30 +92,18 @@ function markdownLink(link) {
61
92
  return `[${inlineText(link.title)}](${url})`;
62
93
  }
63
94
  function serializeLlmsIndex(input) {
64
- let body = (input.sections ?? [
65
- { title: "Pages", pages: input.pages ?? [] }
66
- ]).map((section) => {
67
- let lines = [
68
- ...(section.links ?? []).map((link) => `- ${markdownLink(link)}`),
69
- ...section.pages.map((page) => {
70
- let description = input.includeDescriptions && page.description ? `: ${inlineText(page.description)}` : "", alternate = page.alternate ? ` (${markdownLink(page.alternate)})` : "";
71
- return `- ${markdownLink(page)}${alternate}${description}`;
72
- })
73
- ];
95
+ let body = (input.sections ?? []).map((section) => {
96
+ let lines = section.entries.map((entry) => {
97
+ let description = input.includeDescriptions && entry.description ? `: ${inlineText(entry.description)}` : "", alternate = entry.alternate ? ` (${markdownLink(entry.alternate)})` : "";
98
+ return `- ${markdownLink(entry)}${alternate}${description}`;
99
+ });
74
100
  return `## ${inlineText(section.title)}
75
101
 
76
102
  ${lines.join(`
77
103
  `)}`;
78
104
  }).join(`
79
105
 
80
- `), linkLines = (input.links ?? []).map(
81
- (link) => `- ${markdownLink(link)}`
82
- ), linkSection = linkLines.length ? `
83
-
84
- ## Group LLM indexes
85
-
86
- ${linkLines.join(`
87
- `)}` : "", otherGroupLines = (input.otherGroupLinks ?? []).map(
106
+ `), otherGroupLines = (input.otherGroupLinks ?? []).map(
88
107
  (link) => `- ${markdownLink(link)}`
89
108
  ), otherGroupSection = otherGroupLines.length ? `
90
109
 
@@ -96,7 +115,7 @@ ${otherGroupLines.join(`
96
115
 
97
116
  > ${inlineText(input.summary)}
98
117
 
99
- ${body}${linkSection}${otherGroupSection}
118
+ ${body}${otherGroupSection}
100
119
  `;
101
120
  }
102
121
 
@@ -122,12 +141,25 @@ function createCachedTextResponse(options) {
122
141
 
123
142
  // src/route-metadata-sitemap.ts
124
143
  var ROOT_CONTENT_GROUP_KEY = "__root";
144
+ function assertSitemapSize(options) {
145
+ let bytes = new TextEncoder().encode(options.body).byteLength;
146
+ if (options.entryCount > 5e4 || bytes > 52428800)
147
+ throw new RangeError(
148
+ `Generated sitemap "${options.path}" exceeds ${5e4} entries or ${52428800} UTF-8 bytes. Split or limit its content.`
149
+ );
150
+ return options.body;
151
+ }
125
152
  function xmlEscape(value) {
126
153
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/'/g, "&apos;").replace(/"/g, "&quot;");
127
154
  }
128
155
  function sitemapDirectory(path) {
129
156
  return path.slice(0, path.lastIndexOf("/") + 1) || "/";
130
157
  }
158
+ function isWithinDirectory(path, directories) {
159
+ for (let end = path.indexOf("/"); end >= 0; end = path.indexOf("/", end + 1))
160
+ if (directories.has(path.slice(0, end + 1))) return !0;
161
+ return !1;
162
+ }
131
163
  function rootMountedGroup(manifest, origin) {
132
164
  return Object.values(manifest.groups).find(
133
165
  (group) => group.key !== ROOT_CONTENT_GROUP_KEY && group.path === "/" && discoveryOrigin(manifest, group.key) === origin
@@ -138,11 +170,15 @@ async function sitemapXml(manifest, options) {
138
170
  cacheLife("page"), cacheTag(tags.site(), tags.sitemap(), tags.manifest(manifest.contentHash));
139
171
  let targetGroup = options.group ? manifest.groups[options.group] : void 0, directory = sitemapDirectory(
140
172
  options.path ?? `${targetGroup?.path === "/" ? "" : targetGroup?.path ?? ""}/sitemap.xml`
141
- ), origin = targetGroup ? discoveryOrigin(manifest, targetGroup.key) : manifest.site.origin;
142
- if (options.sitemaps)
143
- return `<?xml version="1.0" encoding="UTF-8"?>
144
- <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
145
- ${[
173
+ ), origin = targetGroup ? discoveryOrigin(manifest, targetGroup.key) : manifest.site.origin, includedUrls = options.includeUrls ? new Set(
174
+ options.includeUrls.map(
175
+ ({ path, group }) => JSON.stringify([group ?? null, path])
176
+ )
177
+ ) : void 0, excludedDirectories = new Set(
178
+ (options.exclude ?? []).filter((sitemap) => discoveryOrigin(manifest, sitemap.group) === origin).map((sitemap) => sitemapDirectory(sitemap.path))
179
+ );
180
+ if (options.sitemaps) {
181
+ let urls2 = [
146
182
  ...new Set(
147
183
  options.sitemaps.filter(
148
184
  (sitemap) => discoveryOrigin(manifest, sitemap.group) === origin
@@ -152,10 +188,18 @@ ${[
152
188
  (sitemap) => canonicalUrl(manifest, sitemap.path, sitemap.group)
153
189
  )
154
190
  )
155
- ].map((url) => ` <sitemap><loc>${xmlEscape(url)}</loc></sitemap>`).join(`
156
- `)}
191
+ ], body2 = urls2.map((url) => ` <sitemap><loc>${xmlEscape(url)}</loc></sitemap>`).join(`
192
+ `);
193
+ return assertSitemapSize({
194
+ path: options.path ?? "/sitemap.xml",
195
+ entryCount: urls2.length,
196
+ body: `<?xml version="1.0" encoding="UTF-8"?>
197
+ <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
198
+ ${body2}
157
199
  </sitemapindex>
158
- `;
200
+ `
201
+ });
202
+ }
159
203
  let homeGroup = targetGroup ?? rootMountedGroup(manifest, origin), groups = Object.values(manifest.groups).filter(
160
204
  (group) => discoveryOrigin(manifest, group.key) === origin && (directory === "/" || group.path.startsWith(directory))
161
205
  ), urls = [
@@ -164,23 +208,27 @@ ${[
164
208
  group: homeGroup?.key
165
209
  },
166
210
  ...groups.map((group) => ({ path: group.path, group: group.key })),
167
- ...manifest.pages.filter((page) => page.status === "published").filter((page) => discoveryOrigin(manifest, page.group) === origin).map((page) => ({ path: page.path, group: page.group }))
211
+ ...manifest.pages.filter(
212
+ (page) => page.frontmatter.status === "published" && page.frontmatter.metadata.robots?.index !== !1
213
+ ).filter((page) => discoveryOrigin(manifest, page.group) === origin).map((page) => ({ path: page.path, group: page.group }))
168
214
  ].filter(
169
- ({ path }) => (directory === "/" || path.startsWith(directory)) && !(options.exclude ?? []).some(
170
- (sitemap) => discoveryOrigin(manifest, sitemap.group) === origin && path.startsWith(sitemapDirectory(sitemap.path))
171
- )
172
- );
173
- return `<?xml version="1.0" encoding="UTF-8"?>
174
- <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
175
- ${[...new Map(
215
+ ({ path, group }) => (directory === "/" || path.startsWith(directory)) && (!includedUrls || includedUrls.has(JSON.stringify([group ?? null, path]))) && !isWithinDirectory(path, excludedDirectories)
216
+ ), uniqueUrls = new Map(
176
217
  urls.map(({ path, group }) => {
177
218
  let url = canonicalUrl(manifest, path, group);
178
219
  return [url, url];
179
220
  })
180
- ).values()].map((url) => ` <url><loc>${xmlEscape(url)}</loc></url>`).join(`
181
- `)}
221
+ ), body = [...uniqueUrls.values()].map((url) => ` <url><loc>${xmlEscape(url)}</loc></url>`).join(`
222
+ `);
223
+ return assertSitemapSize({
224
+ path: options.path ?? "/sitemap.xml",
225
+ entryCount: uniqueUrls.size,
226
+ body: `<?xml version="1.0" encoding="UTF-8"?>
227
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
228
+ ${body}
182
229
  </urlset>
183
- `;
230
+ `
231
+ });
184
232
  }
185
233
  function createSitemapXmlRoute(manifest, options = {}) {
186
234
  return async function() {
@@ -191,67 +239,107 @@ function createSitemapXmlRoute(manifest, options = {}) {
191
239
  };
192
240
  }
193
241
  async function sitemapMarkdown(manifest, artifactManifest, options) {
194
- let origin = discoveryOrigin(manifest, options.group), targetGroup = options.group ? manifest.groups[options.group] : void 0, rootGroup = targetGroup?.key === ROOT_CONTENT_GROUP_KEY ? void 0 : targetGroup ?? rootMountedGroup(manifest, origin), groups = Object.values(manifest.groups).filter((group) => group.key !== ROOT_CONTENT_GROUP_KEY).filter((group) => discoveryOrigin(manifest, group.key) === origin).filter(
195
- (group) => !targetGroup || options.scope === "site" || pathWithin(group.path, targetGroup.path) && (group.key === targetGroup.key || options.scope !== "self" && group.key.startsWith(`${targetGroup.key}/`))
196
- ), pages = discoveryPages({ manifest, ...options }).sort(
197
- (a, b) => a.path.localeCompare(b.path)
198
- ), sections = groupDiscoveryPages({ manifest, pages });
199
- for (let group of groups)
200
- sections.some((section) => section.group === group.key) || sections.push({ group: group.key, title: group.title, pages: [] });
201
- sections.sort(
202
- (a, b) => (manifest.groups[a.group ?? ""]?.path ?? "/").localeCompare(
203
- manifest.groups[b.group ?? ""]?.path ?? "/"
204
- )
205
- );
206
- let links = options.links ?? [
242
+ let origin = discoveryOrigin(manifest, options.group), targetGroup = options.group ? manifest.groups[options.group] : void 0, rootGroup = targetGroup?.key === ROOT_CONTENT_GROUP_KEY ? void 0 : targetGroup ?? rootMountedGroup(manifest, origin), markdownPaths = new Map(
243
+ options.markdownAlternates === !1 ? [] : Object.entries(artifactManifest.byHtmlPath)
244
+ ), linkedParts = options.parts ?? [], groupSitemaps = options.groupSitemaps ?? [], discoverySections = linkedParts.length ? [] : navigationDiscoverySections({
245
+ manifest,
246
+ ...options,
247
+ markdownPaths
248
+ }), selectors = options.includeUrls, remainingSelectors = /* @__PURE__ */ new Map(), selectorKeys = /* @__PURE__ */ new Map();
249
+ for (let [index, selector] of (selectors ?? []).entries()) {
250
+ let keys = /* @__PURE__ */ new Set();
251
+ selector.path !== void 0 && (keys.add(
252
+ `page:${JSON.stringify([selector.group ?? null, selector.path])}`
253
+ ), keys.add(
254
+ `url:${JSON.stringify([
255
+ selector.group ?? null,
256
+ canonicalUrl(manifest, selector.path, selector.group)
257
+ ])}`
258
+ )), selector.url !== void 0 && keys.add(`url:${JSON.stringify([selector.group ?? null, selector.url])}`), selectorKeys.set(index, [...keys]);
259
+ for (let key of keys) {
260
+ let candidates = remainingSelectors.get(key) ?? /* @__PURE__ */ new Set();
261
+ candidates.add(index), remainingSelectors.set(key, candidates);
262
+ }
263
+ }
264
+ let selectedSections = discoverySections.map((section) => ({
265
+ ...section,
266
+ entries: section.entries.filter((entry) => {
267
+ if (!selectors) return !0;
268
+ let key = entry.type === "page" ? `page:${JSON.stringify([entry.group ?? null, entry.path])}` : `url:${JSON.stringify([entry.group ?? null, entry.url])}`, selectorIndex = remainingSelectors.get(key)?.values().next().value;
269
+ if (selectorIndex === void 0) return !1;
270
+ for (let selectorKey of selectorKeys.get(selectorIndex) ?? []) {
271
+ let selectorCandidates = remainingSelectors.get(selectorKey);
272
+ selectorCandidates?.delete(selectorIndex), selectorCandidates?.size === 0 && remainingSelectors.delete(selectorKey);
273
+ }
274
+ return !0;
275
+ })
276
+ })).filter((section) => section.entries.length > 0), links = options.links ?? [
207
277
  { title: "LLMS index", path: "/llms.txt" },
208
278
  { title: "Full LLMS index", path: "/llms-full.txt" },
209
279
  { title: "XML sitemap", path: "/sitemap.xml" }
210
- ];
211
- return serializeLlmsIndex({
280
+ ], body = serializeLlmsIndex({
212
281
  title: `${rootGroup?.title ?? manifest.site.name} Sitemap`,
213
282
  summary: "Browse the published pages and their available Markdown versions.",
214
283
  sections: [
284
+ ...groupSitemaps.length ? [
285
+ {
286
+ title: "Content groups",
287
+ entries: groupSitemaps.map((sitemap) => ({
288
+ title: sitemap.title,
289
+ url: canonicalUrl(manifest, sitemap.path, sitemap.group)
290
+ }))
291
+ }
292
+ ] : [],
293
+ ...linkedParts.length ? [
294
+ {
295
+ title: "Parts",
296
+ entries: linkedParts.map((part) => ({
297
+ title: part.title,
298
+ url: canonicalUrl(manifest, part.path, part.group)
299
+ }))
300
+ }
301
+ ] : [],
215
302
  ...links.length ? [
216
303
  {
217
304
  title: "Agent indexes",
218
- pages: [],
219
- links: links.map((link) => ({
305
+ entries: links.map((link) => ({
220
306
  title: link.title,
221
307
  url: canonicalUrl(manifest, link.path, link.group)
222
308
  }))
223
309
  }
224
310
  ] : [],
225
- ...sections.map((section) => {
226
- let group = manifest.groups[section.group ?? ""];
227
- return {
228
- title: section.title,
229
- links: group && group.key !== ROOT_CONTENT_GROUP_KEY ? [
230
- {
231
- title: group.title,
232
- url: canonicalUrl(manifest, group.path, group.key)
233
- }
234
- ] : [],
235
- pages: section.pages.map((page) => {
236
- let markdownPath = options.markdownAlternates === !1 ? void 0 : artifactManifest.byHtmlPath[page.path];
237
- return {
238
- title: page.title,
239
- url: canonicalUrl(manifest, page.path, page.group),
240
- ...markdownPath ? {
241
- alternate: {
242
- title: "Markdown",
243
- url: canonicalUrl(manifest, markdownPath, page.group)
244
- }
245
- } : {}
246
- };
247
- })
248
- };
249
- })
250
- ],
251
- otherGroupLinks: options.otherGroupLinks?.map((link) => ({
252
- title: link.title,
253
- url: canonicalUrl(manifest, link.path, link.group)
254
- }))
311
+ ...selectedSections.map((section) => ({
312
+ title: section.title,
313
+ entries: section.entries.map((entry) => {
314
+ if (entry.type === "link") return entry;
315
+ let markdownPath = markdownPaths.get(entry.path);
316
+ return {
317
+ title: entry.title,
318
+ url: canonicalUrl(manifest, entry.path, entry.group),
319
+ ...markdownPath ? {
320
+ alternate: {
321
+ title: "Markdown",
322
+ url: canonicalUrl(manifest, markdownPath, entry.group)
323
+ }
324
+ } : {}
325
+ };
326
+ })
327
+ })),
328
+ ...options.otherGroupLinks?.length ? [
329
+ {
330
+ title: "Other content groups",
331
+ entries: options.otherGroupLinks.map((link) => ({
332
+ title: link.title,
333
+ url: canonicalUrl(manifest, link.path, link.group)
334
+ }))
335
+ }
336
+ ] : []
337
+ ]
338
+ });
339
+ return assertSitemapSize({
340
+ path: options.path ?? (options.group ? `${manifest.groups[options.group]?.path ?? ""}/sitemap.md` : "/sitemap.md"),
341
+ entryCount: (body.match(/\]\(/g) ?? []).length,
342
+ body
255
343
  });
256
344
  }
257
345
  function createSitemapMarkdownRoute(manifest, artifactManifest, options = {}) {
@@ -38,7 +38,7 @@ function normalizePublicPath(pathname) {
38
38
  }
39
39
  if (decoded === "." || decoded === ".." || /[/\\]/u.test(decoded) || /%[\da-f]{2}/iu.test(decoded) || UNSAFE_PATH_CHARACTERS.test(decoded))
40
40
  return;
41
- segments.push(decoded);
41
+ segments.push(decoded.normalize("NFC"));
42
42
  }
43
43
  return `/${segments.join("/")}`;
44
44
  }
@@ -1,6 +1,6 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { Metadata } from 'next';
1
+ import * as react from 'react';
3
2
  import { ReactElement } from 'react';
3
+ import { Metadata } from 'next';
4
4
  import { O as OgManifestLike } from '../../../route-metadata-og-image-BeKKFHg7.js';
5
5
  import { ManifestLike, IndexPageProps } from '../../../types.js';
6
6
 
@@ -11,7 +11,7 @@ type GroupRouteConfig = {
11
11
  ogManifest?: OgManifestLike;
12
12
  IndexPage: IndexPageComponent;
13
13
  };
14
- declare function createGroupPage({ group, manifest, IndexPage, }: GroupRouteConfig): () => Promise<react_jsx_runtime.JSX.Element>;
14
+ declare function createGroupPage({ group, manifest, IndexPage, }: GroupRouteConfig): () => Promise<react.JSX.Element>;
15
15
  declare function createGroupMetadata({ group, manifest, ogManifest, }: GroupRouteConfig): Metadata;
16
16
 
17
17
  export { type GroupRouteConfig, type IndexPageComponent, createGroupMetadata, createGroupPage };
@@ -23,7 +23,8 @@ var isDev = process.env.NODE_ENV !== "production", isDebugEnabled = process.env.
23
23
  // src/lib/runtime/metadata/canonical-url.ts
24
24
  function canonicalUrl(manifest, path, group) {
25
25
  let origin = (group && manifest.groups[group]?.origin) ?? manifest.site.origin;
26
- if (!origin) return path;
26
+ if (!origin)
27
+ return /^[a-z][a-z\d+.-]*:/i.test(path) ? path : new URL(path, "https://publish.invalid").pathname;
27
28
  try {
28
29
  return new URL(path, `${origin}/`).toString();
29
30
  } catch {
@@ -46,7 +47,12 @@ function agentReadableAlternates({
46
47
  return {
47
48
  ...canonical.startsWith("http") ? { canonical } : {},
48
49
  types: {
49
- ...markdownPath ? { "text/markdown": normalizePath(markdownPath) } : {},
50
+ ...markdownPath ? {
51
+ "text/markdown": new URL(
52
+ normalizePath(markdownPath),
53
+ "https://publish.invalid"
54
+ ).pathname
55
+ } : {},
50
56
  "text/plain": "/llms.txt"
51
57
  }
52
58
  };
@@ -136,11 +142,11 @@ function createGroupMetadata({
136
142
  }) : void 0,
137
143
  ...createSocialMetadata({
138
144
  canonicalPath,
139
- description,
145
+ description: groupData?.metadata?.openGraph?.description ?? description,
140
146
  group,
141
147
  manifest,
142
148
  ogManifest,
143
- title
149
+ title: groupData?.metadata?.openGraph?.title ?? title
144
150
  })
145
151
  };
146
152
  }
@@ -1,6 +1,6 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { Metadata } from 'next';
1
+ import * as react from 'react';
3
2
  import { ReactElement, ReactNode } from 'react';
3
+ import { Metadata } from 'next';
4
4
  import { O as OgManifestLike } from '../../../route-metadata-og-image-BeKKFHg7.js';
5
5
  import { PageProps, ManifestLike, ResolvedAttribution } from '../../../types.js';
6
6
 
@@ -11,6 +11,10 @@ type MarkdownRouteArtifact = {
11
11
  htmlPath: string;
12
12
  markdownPath: string;
13
13
  sourceHash?: string;
14
+ robots?: {
15
+ index?: boolean;
16
+ follow?: boolean;
17
+ };
14
18
  title: string;
15
19
  };
16
20
  type MarkdownRouteArtifactIndexEntry = Omit<MarkdownRouteArtifact, "body"> & {
@@ -39,6 +43,7 @@ type LeafRouteConfig = {
39
43
  manifest: ManifestLike;
40
44
  markdownArtifactManifest?: Pick<MarkdownRouteArtifactManifest, "byMarkdownPath">;
41
45
  ogManifest?: OgManifestLike;
46
+ markdownRoutesEnabled?: boolean;
42
47
  Leaf: LeafComponent;
43
48
  PoweredByFooter?: PoweredByFooterComponent;
44
49
  };
@@ -54,8 +59,8 @@ declare function appendPoweredByFooter({ footer, node, }: {
54
59
  node: ReactNode;
55
60
  placed: boolean;
56
61
  };
57
- declare function createLeafPage({ group, manifest, markdownArtifactManifest, Leaf, PoweredByFooter, }: LeafRouteConfig): ({ params }: PageRouteProps) => Promise<react_jsx_runtime.JSX.Element>;
58
- declare function createLeafMetadata({ group, manifest, ogManifest, }: LeafRouteConfig): ({ params, }: PageRouteProps) => Promise<Metadata>;
62
+ declare function createLeafPage({ group, manifest, markdownArtifactManifest, Leaf, PoweredByFooter, }: LeafRouteConfig): ({ params }: PageRouteProps) => Promise<react.JSX.Element>;
63
+ declare function createLeafMetadata({ group, manifest, ogManifest, markdownRoutesEnabled, }: LeafRouteConfig): ({ params, }: PageRouteProps) => Promise<Metadata>;
59
64
  declare function createLeafStaticParams({ group, manifest }: LeafRouteConfig): () => {
60
65
  slug: string[];
61
66
  }[];
@@ -32,7 +32,8 @@ var isDev = process.env.NODE_ENV !== "production", isDebugEnabled = process.env.
32
32
  // src/lib/runtime/metadata/canonical-url.ts
33
33
  function canonicalUrl(manifest, path, group) {
34
34
  let origin = (group && manifest.groups[group]?.origin) ?? manifest.site.origin;
35
- if (!origin) return path;
35
+ if (!origin)
36
+ return /^[a-z][a-z\d+.-]*:/i.test(path) ? path : new URL(path, "https://publish.invalid").pathname;
36
37
  try {
37
38
  return new URL(path, `${origin}/`).toString();
38
39
  } catch {
@@ -59,7 +60,12 @@ function agentReadableAlternates({
59
60
  return {
60
61
  ...canonical.startsWith("http") ? { canonical } : {},
61
62
  types: {
62
- ...markdownPath ? { "text/markdown": normalizePath(markdownPath) } : {},
63
+ ...markdownPath ? {
64
+ "text/markdown": new URL(
65
+ normalizePath(markdownPath),
66
+ "https://publish.invalid"
67
+ ).pathname
68
+ } : {},
63
69
  "text/plain": "/llms.txt"
64
70
  }
65
71
  };
@@ -225,7 +231,8 @@ function createLeafPage({
225
231
  function createLeafMetadata({
226
232
  group,
227
233
  manifest,
228
- ogManifest
234
+ ogManifest,
235
+ markdownRoutesEnabled
229
236
  }) {
230
237
  return async function({
231
238
  params
@@ -234,21 +241,22 @@ function createLeafMetadata({
234
241
  log.debug("[metadata]", `${group}/${slug.join("/")}`);
235
242
  let resolved = resolveLeaf(manifest, group, slug);
236
243
  return resolved ? {
237
- title: resolved.page.title,
238
- description: resolved.page.description,
244
+ title: resolved.page.frontmatter.title,
245
+ description: resolved.page.frontmatter.description,
246
+ ...resolved.page.frontmatter.metadata.robots ? { robots: resolved.page.frontmatter.metadata.robots } : {},
239
247
  alternates: agentReadableAlternates({
240
248
  canonicalPath: resolved.page.path,
241
249
  group,
242
250
  manifest,
243
- markdownPath: markdownPathForHtmlPath(resolved.page.path)
251
+ markdownPath: markdownRoutesEnabled === !1 ? void 0 : markdownPathForHtmlPath(resolved.page.path)
244
252
  }),
245
253
  ...createSocialMetadata({
246
254
  canonicalPath: resolved.page.path,
247
- description: resolved.page.description,
255
+ description: resolved.page.frontmatter.metadata.openGraph?.description ?? resolved.page.frontmatter.description,
248
256
  group,
249
257
  manifest,
250
258
  ogManifest,
251
- title: resolved.page.title,
259
+ title: resolved.page.frontmatter.metadata.openGraph?.title ?? resolved.page.frontmatter.title,
252
260
  type: "article"
253
261
  })
254
262
  } : {};
@@ -1,6 +1,6 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { Metadata } from 'next';
1
+ import * as react from 'react';
3
2
  import { ReactElement } from 'react';
3
+ import { Metadata } from 'next';
4
4
  import { O as OgManifestLike } from '../../../route-metadata-og-image-BeKKFHg7.js';
5
5
  import { RootPageProps, ManifestLike } from '../../../types.js';
6
6
 
@@ -10,7 +10,7 @@ type RootRouteConfig = {
10
10
  ogManifest?: OgManifestLike;
11
11
  RootPage: RootPageComponent;
12
12
  };
13
- declare function createRootPage({ manifest, RootPage }: RootRouteConfig): () => Promise<react_jsx_runtime.JSX.Element>;
13
+ declare function createRootPage({ manifest, RootPage }: RootRouteConfig): () => Promise<react.JSX.Element>;
14
14
  declare function createRootMetadata({ manifest, ogManifest, }: RootRouteConfig): Metadata;
15
15
 
16
16
  export { type RootPageComponent, type RootRouteConfig, createRootMetadata, createRootPage };