@actuate-media/cms-core 0.67.0 → 0.69.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 +27 -0
- package/dist/__tests__/api/llms-txt.test.js +287 -0
- package/dist/__tests__/api/llms-txt.test.js.map +1 -1
- package/dist/__tests__/api/route-contracts.test.js +1 -0
- package/dist/__tests__/api/route-contracts.test.js.map +1 -1
- package/dist/__tests__/seo/content-markdown.test.d.ts +2 -0
- package/dist/__tests__/seo/content-markdown.test.d.ts.map +1 -0
- package/dist/__tests__/seo/content-markdown.test.js +124 -0
- package/dist/__tests__/seo/content-markdown.test.js.map +1 -0
- package/dist/__tests__/seo/llms-sanitize.test.d.ts +2 -0
- package/dist/__tests__/seo/llms-sanitize.test.d.ts.map +1 -0
- package/dist/__tests__/seo/llms-sanitize.test.js +74 -0
- package/dist/__tests__/seo/llms-sanitize.test.js.map +1 -0
- package/dist/api/routes/seo.d.ts.map +1 -1
- package/dist/api/routes/seo.js +156 -24
- package/dist/api/routes/seo.js.map +1 -1
- package/dist/config/types.d.ts +34 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/seo/content-markdown.d.ts +15 -0
- package/dist/seo/content-markdown.d.ts.map +1 -0
- package/dist/seo/content-markdown.js +193 -0
- package/dist/seo/content-markdown.js.map +1 -0
- package/dist/seo/index.d.ts +4 -1
- package/dist/seo/index.d.ts.map +1 -1
- package/dist/seo/index.js +3 -1
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/llms-select.d.ts +34 -0
- package/dist/seo/llms-select.d.ts.map +1 -0
- package/dist/seo/llms-select.js +67 -0
- package/dist/seo/llms-select.js.map +1 -0
- package/dist/seo/llms-txt.d.ts +24 -0
- package/dist/seo/llms-txt.d.ts.map +1 -1
- package/dist/seo/llms-txt.js +104 -53
- package/dist/seo/llms-txt.js.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Convert an HTML/rich-text fragment to Markdown. Plain text passes through. */
|
|
2
|
+
export declare function htmlToMarkdown(html: string | null | undefined): string;
|
|
3
|
+
export interface DocumentMarkdownInput {
|
|
4
|
+
title?: string | null;
|
|
5
|
+
/** The document's `data` JSON column. */
|
|
6
|
+
data?: Record<string, unknown> | null;
|
|
7
|
+
/** Pre-extracted plain text fallback (the `plainText` column). */
|
|
8
|
+
plainText?: string | null;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Render a published document to clean Markdown:
|
|
12
|
+
* `# Title`, an optional one-line takeaway, then the body.
|
|
13
|
+
*/
|
|
14
|
+
export declare function documentToMarkdown(doc: DocumentMarkdownInput): string;
|
|
15
|
+
//# sourceMappingURL=content-markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-markdown.d.ts","sourceRoot":"","sources":["../../src/seo/content-markdown.ts"],"names":[],"mappings":"AAiCA,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAatE;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACrC,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1B;AA2BD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,qBAAqB,GAAG,MAAM,CAoBrE"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Document → clean Markdown serialization for the AI/agent layer.
|
|
3
|
+
*
|
|
4
|
+
* Powers per-page `.md` output and `/llms-full.txt`. The goal is a faithful,
|
|
5
|
+
* readable rendering of the *content* (so an agent can fetch the page body, not
|
|
6
|
+
* just the link) — never the chrome, settings, ids, or URLs that live alongside
|
|
7
|
+
* it in the document model.
|
|
8
|
+
*
|
|
9
|
+
* HTML/rich-text slots are converted with Turndown; structured section content
|
|
10
|
+
* is walked generically (allow-listed prose/heading keys only) so new section
|
|
11
|
+
* types render acceptably without per-type code. Output is always `noindex`-only
|
|
12
|
+
* — callers must serve it with `X-Robots-Tag: noindex` and keep it out of the
|
|
13
|
+
* sitemap (the HTML page stays canonical).
|
|
14
|
+
*/
|
|
15
|
+
import TurndownService from 'turndown';
|
|
16
|
+
import { getSectionType } from '../sections/registry.js';
|
|
17
|
+
let _td = null;
|
|
18
|
+
function turndown() {
|
|
19
|
+
if (!_td) {
|
|
20
|
+
_td = new TurndownService({
|
|
21
|
+
headingStyle: 'atx',
|
|
22
|
+
codeBlockStyle: 'fenced',
|
|
23
|
+
bulletListMarker: '-',
|
|
24
|
+
emDelimiter: '_',
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return _td;
|
|
28
|
+
}
|
|
29
|
+
const HTML_LIKE = /<[a-z!/][\s\S]*>/i;
|
|
30
|
+
/** Convert an HTML/rich-text fragment to Markdown. Plain text passes through. */
|
|
31
|
+
export function htmlToMarkdown(html) {
|
|
32
|
+
if (!html)
|
|
33
|
+
return '';
|
|
34
|
+
const s = String(html);
|
|
35
|
+
if (!HTML_LIKE.test(s))
|
|
36
|
+
return s.replace(/\s+/g, ' ').trim();
|
|
37
|
+
try {
|
|
38
|
+
return turndown().turndown(s).trim();
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Defensive: never throw from a public serializer — degrade to stripped text.
|
|
42
|
+
return s
|
|
43
|
+
.replace(/<[^>]+>/g, ' ')
|
|
44
|
+
.replace(/\s+/g, ' ')
|
|
45
|
+
.trim();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Keys whose string values are prose paragraphs.
|
|
49
|
+
const PROSE_KEYS = new Set([
|
|
50
|
+
'body',
|
|
51
|
+
'content',
|
|
52
|
+
'html',
|
|
53
|
+
'text',
|
|
54
|
+
'copy',
|
|
55
|
+
'description',
|
|
56
|
+
'answer',
|
|
57
|
+
'quote',
|
|
58
|
+
'excerpt',
|
|
59
|
+
]);
|
|
60
|
+
// Keys whose string values are headings/sub-headings within a section.
|
|
61
|
+
const HEADING_KEYS = new Set([
|
|
62
|
+
'heading',
|
|
63
|
+
'title',
|
|
64
|
+
'subtitle',
|
|
65
|
+
'subheading',
|
|
66
|
+
'eyebrow',
|
|
67
|
+
'question',
|
|
68
|
+
'label',
|
|
69
|
+
]);
|
|
70
|
+
const MAX_DEPTH = 8;
|
|
71
|
+
/**
|
|
72
|
+
* Render a published document to clean Markdown:
|
|
73
|
+
* `# Title`, an optional one-line takeaway, then the body.
|
|
74
|
+
*/
|
|
75
|
+
export function documentToMarkdown(doc) {
|
|
76
|
+
const data = (doc.data ?? {});
|
|
77
|
+
const out = [];
|
|
78
|
+
const title = firstString(data.metaTitle, doc.title, data.title) ?? 'Untitled';
|
|
79
|
+
out.push(`# ${oneLine(title)}`, '');
|
|
80
|
+
const intro = firstString(data.keyTakeaway, data.metaDescription, data.seoDescription);
|
|
81
|
+
if (intro) {
|
|
82
|
+
out.push(oneLine(intro), '');
|
|
83
|
+
}
|
|
84
|
+
const body = buildBody(data);
|
|
85
|
+
if (body) {
|
|
86
|
+
out.push(body);
|
|
87
|
+
}
|
|
88
|
+
else if (doc.plainText) {
|
|
89
|
+
out.push(String(doc.plainText).trim());
|
|
90
|
+
}
|
|
91
|
+
return collapseBlankLines(out.join('\n')).trim() + '\n';
|
|
92
|
+
}
|
|
93
|
+
function buildBody(data) {
|
|
94
|
+
const parts = [];
|
|
95
|
+
const sections = Array.isArray(data.sections) ? data.sections : null;
|
|
96
|
+
if (sections) {
|
|
97
|
+
for (const s of sections) {
|
|
98
|
+
collectFromSection(s, parts);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (parts.length === 0 && data._layout && typeof data._layout === 'object') {
|
|
102
|
+
collectFromTree(data._layout, parts, 0);
|
|
103
|
+
}
|
|
104
|
+
if (parts.length === 0) {
|
|
105
|
+
const html = firstString(data.body, data.content, data.html);
|
|
106
|
+
if (html)
|
|
107
|
+
parts.push(htmlToMarkdown(html));
|
|
108
|
+
}
|
|
109
|
+
return parts
|
|
110
|
+
.map((p) => p.trim())
|
|
111
|
+
.filter(Boolean)
|
|
112
|
+
.join('\n\n')
|
|
113
|
+
.trim();
|
|
114
|
+
}
|
|
115
|
+
function collectFromSection(section, parts) {
|
|
116
|
+
if (!isRecord(section))
|
|
117
|
+
return;
|
|
118
|
+
if (section.visible === false)
|
|
119
|
+
return;
|
|
120
|
+
const content = section.content;
|
|
121
|
+
if (!isRecord(content))
|
|
122
|
+
return;
|
|
123
|
+
// Resolve which slots hold rich text (HTML) from the section-type registry,
|
|
124
|
+
// so we convert those with Turndown rather than treating them as plain text.
|
|
125
|
+
const richKeys = new Set();
|
|
126
|
+
const typeId = typeof section.sectionType === 'string' ? section.sectionType : '';
|
|
127
|
+
const def = typeId ? getSectionType(typeId) : undefined;
|
|
128
|
+
for (const field of def?.fields ?? []) {
|
|
129
|
+
if (field?.type === 'richText' && typeof field.key === 'string')
|
|
130
|
+
richKeys.add(field.key);
|
|
131
|
+
}
|
|
132
|
+
walkContent(content, richKeys, parts, 0);
|
|
133
|
+
}
|
|
134
|
+
function collectFromTree(node, parts, depth) {
|
|
135
|
+
if (depth > MAX_DEPTH || !isRecord(node))
|
|
136
|
+
return;
|
|
137
|
+
if (isRecord(node.data)) {
|
|
138
|
+
// Block data carries author content (richText body, headings, etc.).
|
|
139
|
+
walkContent(node.data, new Set(), parts, 0);
|
|
140
|
+
}
|
|
141
|
+
if (Array.isArray(node.children)) {
|
|
142
|
+
for (const child of node.children)
|
|
143
|
+
collectFromTree(child, parts, depth + 1);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function walkContent(obj, richKeys, parts, depth) {
|
|
147
|
+
if (depth > MAX_DEPTH)
|
|
148
|
+
return;
|
|
149
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
150
|
+
if (typeof value === 'string') {
|
|
151
|
+
const trimmed = value.trim();
|
|
152
|
+
if (!trimmed)
|
|
153
|
+
continue;
|
|
154
|
+
if (richKeys.has(key) || HTML_LIKE.test(trimmed)) {
|
|
155
|
+
const md = htmlToMarkdown(trimmed);
|
|
156
|
+
if (md)
|
|
157
|
+
parts.push(md);
|
|
158
|
+
}
|
|
159
|
+
else if (HEADING_KEYS.has(key)) {
|
|
160
|
+
parts.push(`## ${oneLine(trimmed)}`);
|
|
161
|
+
}
|
|
162
|
+
else if (PROSE_KEYS.has(key)) {
|
|
163
|
+
parts.push(oneLine(trimmed));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
else if (Array.isArray(value)) {
|
|
167
|
+
for (const item of value) {
|
|
168
|
+
if (isRecord(item))
|
|
169
|
+
walkContent(item, richKeys, parts, depth + 1);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
else if (isRecord(value)) {
|
|
173
|
+
walkContent(value, richKeys, parts, depth + 1);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function isRecord(v) {
|
|
178
|
+
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
179
|
+
}
|
|
180
|
+
function firstString(...candidates) {
|
|
181
|
+
for (const c of candidates) {
|
|
182
|
+
if (typeof c === 'string' && c.trim())
|
|
183
|
+
return c;
|
|
184
|
+
}
|
|
185
|
+
return undefined;
|
|
186
|
+
}
|
|
187
|
+
function oneLine(s) {
|
|
188
|
+
return s.replace(/\s+/g, ' ').trim();
|
|
189
|
+
}
|
|
190
|
+
function collapseBlankLines(s) {
|
|
191
|
+
return s.replace(/\n{3,}/g, '\n\n');
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=content-markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-markdown.js","sourceRoot":"","sources":["../../src/seo/content-markdown.ts"],"names":[],"mappings":"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"}
|
package/dist/seo/index.d.ts
CHANGED
|
@@ -6,7 +6,10 @@ export { resolveRobotsDirectives, resolveSeoEnvironment } from './robots.js';
|
|
|
6
6
|
export type { RobotsDirectives, RobotsResolutionInput, RobotsSettings } from './robots.js';
|
|
7
7
|
export { resolveTitle, getDocumentTitle, validateTitleTemplate, applySiteTitleTemplate, SITE_TITLE_TOKENS, DEFAULT_SITE_TITLE_TEMPLATE, } from './title-templates.js';
|
|
8
8
|
export type { TitleTemplateConfig, TitleVariable, SiteTitleToken, TitleTemplateValidation, } from './title-templates.js';
|
|
9
|
-
export { generateLlmsTxt } from './llms-txt.js';
|
|
9
|
+
export { generateLlmsTxt, sanitizeLlmsText } from './llms-txt.js';
|
|
10
|
+
export { documentToMarkdown, htmlToMarkdown } from './content-markdown.js';
|
|
11
|
+
export type { DocumentMarkdownInput } from './content-markdown.js';
|
|
12
|
+
export { selectLlmsDocs, toLlmsPage, readLlmsInclude, isLlmsNoindex } from './llms-select.js';
|
|
10
13
|
export type { LlmsTxtConfig, LlmsTxtPage } from './llms-txt.js';
|
|
11
14
|
export { composePageMeta, detectSchemaType, resolveContentDates } from './page-meta.js';
|
|
12
15
|
export type { ComposePageMetaInput, ComposedPageMeta, ComposeDocumentInput } from './page-meta.js';
|
package/dist/seo/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/seo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAA;AAEtB,YAAY,EAAE,iBAAiB,EAAE,QAAQ,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAElG,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,4BAA4B,EAC5B,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,gBAAgB,CAAA;AAEvB,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAEhG,OAAO,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAE5E,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAE1F,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,2BAA2B,GAC5B,MAAM,sBAAsB,CAAA;AAE7B,YAAY,EACV,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,uBAAuB,GACxB,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/seo/index.ts"],"names":[],"mappings":"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"}
|
package/dist/seo/index.js
CHANGED
|
@@ -2,7 +2,9 @@ export { analyzeContent, calculateReadability, stripHtmlTags, countSyllables, de
|
|
|
2
2
|
export { generateMetaTags, renderMetaTagsHtml, generateNextMetadata, buildVerificationMetaEntries, renderVerificationMetaHtml, buildNextVerification, } from './meta-tags.js';
|
|
3
3
|
export { resolveRobotsDirectives, resolveSeoEnvironment } from './robots.js';
|
|
4
4
|
export { resolveTitle, getDocumentTitle, validateTitleTemplate, applySiteTitleTemplate, SITE_TITLE_TOKENS, DEFAULT_SITE_TITLE_TEMPLATE, } from './title-templates.js';
|
|
5
|
-
export { generateLlmsTxt } from './llms-txt.js';
|
|
5
|
+
export { generateLlmsTxt, sanitizeLlmsText } from './llms-txt.js';
|
|
6
|
+
export { documentToMarkdown, htmlToMarkdown } from './content-markdown.js';
|
|
7
|
+
export { selectLlmsDocs, toLlmsPage, readLlmsInclude, isLlmsNoindex } from './llms-select.js';
|
|
6
8
|
export { composePageMeta, detectSchemaType, resolveContentDates } from './page-meta.js';
|
|
7
9
|
export { analyzeImageAlts, countMissingAltImages, isDecorativeImgTag } from './alt-text.js';
|
|
8
10
|
export { buildRssFeed, buildJsonFeed } from './feeds.js';
|
package/dist/seo/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/seo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAA;AAItB,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,4BAA4B,EAC5B,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,gBAAgB,CAAA;AAIvB,OAAO,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAI5E,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,2BAA2B,GAC5B,MAAM,sBAAsB,CAAA;AAS7B,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/seo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAA;AAItB,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,4BAA4B,EAC5B,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,gBAAgB,CAAA;AAIvB,OAAO,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAI5E,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,2BAA2B,GAC5B,MAAM,sBAAsB,CAAA;AAS7B,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACjE,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE1E,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAI7F,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAIvF,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAI3F,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAIxD,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAIzF,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,mBAAmB,CAAA;AAI1B,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,EACjB,2BAA2B,GAC5B,MAAM,qBAAqB,CAAA;AAS5B,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,OAAO,EACP,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,YAAY,CAAA;AAanB,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAWpF,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,8BAA8B,EAC9B,oBAAoB,GACrB,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,mBAAmB,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { LlmsTxtPage } from './llms-txt.js';
|
|
2
|
+
export type LlmsInclude = 'AUTO' | 'ALWAYS' | 'NEVER';
|
|
3
|
+
/** Tri-state per-doc include flag; defaults to AUTO for unrecognized values. */
|
|
4
|
+
export declare function readLlmsInclude(data: unknown): LlmsInclude;
|
|
5
|
+
/** A doc is excluded from every llms surface when it is noindexed. */
|
|
6
|
+
export declare function isLlmsNoindex(data: unknown): boolean;
|
|
7
|
+
export interface LlmsSelectableDoc {
|
|
8
|
+
collection: string;
|
|
9
|
+
data: unknown;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Apply the curation + privacy rules:
|
|
13
|
+
* - internal/system collections excluded
|
|
14
|
+
* - noindexed docs excluded (privacy boundary)
|
|
15
|
+
* - `llmsInclude` NEVER excluded, ALWAYS included (overrides eligibility),
|
|
16
|
+
* AUTO included only when the collection is eligible
|
|
17
|
+
*/
|
|
18
|
+
export declare function selectLlmsDocs<T extends LlmsSelectableDoc>(docs: T[], opts: {
|
|
19
|
+
isInternalCollection: (c: string) => boolean;
|
|
20
|
+
eligible: Set<string> | null;
|
|
21
|
+
}): T[];
|
|
22
|
+
export interface LlmsDocForPage {
|
|
23
|
+
title?: string | null;
|
|
24
|
+
slug?: string | null;
|
|
25
|
+
collection: string;
|
|
26
|
+
updatedAt?: Date | null;
|
|
27
|
+
data: unknown;
|
|
28
|
+
}
|
|
29
|
+
/** Map a selected document to the generator's page shape (curation-aware). */
|
|
30
|
+
export declare function toLlmsPage(d: LlmsDocForPage, opts: {
|
|
31
|
+
base: string;
|
|
32
|
+
urlPrefix?: string;
|
|
33
|
+
}): LlmsTxtPage;
|
|
34
|
+
//# sourceMappingURL=llms-select.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llms-select.d.ts","sourceRoot":"","sources":["../../src/seo/llms-select.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAEhD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAA;AAErD,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,CAG1D;AAED,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAGpD;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,OAAO,CAAA;CACd;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,iBAAiB,EACxD,IAAI,EAAE,CAAC,EAAE,EACT,IAAI,EAAE;IAAE,oBAAoB,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAA;CAAE,GACnF,CAAC,EAAE,CAWL;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;IACvB,IAAI,EAAE,OAAO,CAAA;CACd;AAED,8EAA8E;AAC9E,wBAAgB,UAAU,CACxB,CAAC,EAAE,cAAc,EACjB,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACzC,WAAW,CA6Bb"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared selection + mapping for the llms.txt family of routes (`/llms.txt`,
|
|
3
|
+
* `/llms-full.txt`). Keeping this in one place means the curation rules and the
|
|
4
|
+
* privacy boundary (noindex exclusion) can never drift between the two surfaces.
|
|
5
|
+
*/
|
|
6
|
+
import { resolveDocumentUrl } from './page-meta.js';
|
|
7
|
+
/** Tri-state per-doc include flag; defaults to AUTO for unrecognized values. */
|
|
8
|
+
export function readLlmsInclude(data) {
|
|
9
|
+
const v = String(data?.llmsInclude ?? '').toUpperCase();
|
|
10
|
+
return v === 'ALWAYS' || v === 'NEVER' ? v : 'AUTO';
|
|
11
|
+
}
|
|
12
|
+
/** A doc is excluded from every llms surface when it is noindexed. */
|
|
13
|
+
export function isLlmsNoindex(data) {
|
|
14
|
+
const d = data;
|
|
15
|
+
return d?.noindex === true || d?.robotsNoindex === true || d?.noindex === 'true';
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Apply the curation + privacy rules:
|
|
19
|
+
* - internal/system collections excluded
|
|
20
|
+
* - noindexed docs excluded (privacy boundary)
|
|
21
|
+
* - `llmsInclude` NEVER excluded, ALWAYS included (overrides eligibility),
|
|
22
|
+
* AUTO included only when the collection is eligible
|
|
23
|
+
*/
|
|
24
|
+
export function selectLlmsDocs(docs, opts) {
|
|
25
|
+
return docs
|
|
26
|
+
.filter((d) => !opts.isInternalCollection(d.collection))
|
|
27
|
+
.filter((d) => {
|
|
28
|
+
const data = d.data || {};
|
|
29
|
+
if (isLlmsNoindex(data))
|
|
30
|
+
return false;
|
|
31
|
+
const include = readLlmsInclude(data);
|
|
32
|
+
if (include === 'NEVER')
|
|
33
|
+
return false;
|
|
34
|
+
if (include === 'ALWAYS')
|
|
35
|
+
return true;
|
|
36
|
+
return opts.eligible ? opts.eligible.has(d.collection) : true;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/** Map a selected document to the generator's page shape (curation-aware). */
|
|
40
|
+
export function toLlmsPage(d, opts) {
|
|
41
|
+
const data = d.data || {};
|
|
42
|
+
const section = typeof data.llmsSection === 'string' && data.llmsSection.trim()
|
|
43
|
+
? data.llmsSection.trim()
|
|
44
|
+
: undefined;
|
|
45
|
+
const str = (v) => typeof v === 'string' && v.trim() ? v : undefined;
|
|
46
|
+
return {
|
|
47
|
+
title: str(data.metaTitle) ?? d.title ?? str(data.title) ?? 'Untitled',
|
|
48
|
+
url: resolveDocumentUrl({
|
|
49
|
+
siteUrl: opts.base,
|
|
50
|
+
urlPrefix: opts.urlPrefix,
|
|
51
|
+
slug: d.slug ?? undefined,
|
|
52
|
+
data,
|
|
53
|
+
}),
|
|
54
|
+
description: str(data.llmsDescription) ??
|
|
55
|
+
str(data.keyTakeaway) ??
|
|
56
|
+
str(data.metaDescription) ??
|
|
57
|
+
str(data.seoDescription) ??
|
|
58
|
+
'',
|
|
59
|
+
collection: d.collection,
|
|
60
|
+
section,
|
|
61
|
+
optional: data.llmsOptional === true,
|
|
62
|
+
priority: typeof data.llmsPriority === 'number' ? data.llmsPriority : undefined,
|
|
63
|
+
updatedAt: d.updatedAt?.toISOString(),
|
|
64
|
+
isCornerstone: data.isCornerstone === true,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=llms-select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llms-select.js","sourceRoot":"","sources":["../../src/seo/llms-select.ts"],"names":[],"mappings":"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"}
|
package/dist/seo/llms-txt.d.ts
CHANGED
|
@@ -1,14 +1,38 @@
|
|
|
1
1
|
export interface LlmsTxtConfig {
|
|
2
2
|
siteName: string;
|
|
3
3
|
siteUrl: string;
|
|
4
|
+
/** The reviewed one-to-three sentence blockquote summary. */
|
|
4
5
|
siteDescription?: string;
|
|
6
|
+
/** Optional free-text context block (no headings) emitted after the summary. */
|
|
7
|
+
intro?: string;
|
|
8
|
+
/** Overall cap across all sections (default 50). */
|
|
5
9
|
maxPages?: number;
|
|
10
|
+
/** Cap per section/collection (default 25) so one large group can't flood. */
|
|
11
|
+
maxPerSection?: number;
|
|
6
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Coerce CMS-authored text into a safe single-line list-item fragment.
|
|
15
|
+
*
|
|
16
|
+
* These strings flow from editor fields into a file that AI agents read, so we
|
|
17
|
+
* defend against two things: (1) markdown-breaking characters that would corrupt
|
|
18
|
+
* the `- [title](url): desc` syntax, and (2) multi-line / control-character
|
|
19
|
+
* content that a careless or hostile editor could use to smuggle instruction-like
|
|
20
|
+
* text. This is not a complete prompt-injection defense (no text filter is) — it
|
|
21
|
+
* forces single-line, length-capped, link-safe plain text, which removes the
|
|
22
|
+
* most common corruption and obfuscation vectors.
|
|
23
|
+
*/
|
|
24
|
+
export declare function sanitizeLlmsText(raw: string | null | undefined, maxLen: number): string;
|
|
7
25
|
export interface LlmsTxtPage {
|
|
8
26
|
title: string;
|
|
9
27
|
url: string;
|
|
10
28
|
description?: string;
|
|
11
29
|
collection?: string;
|
|
30
|
+
/** Explicit section/grouping override; falls back to `collection`. */
|
|
31
|
+
section?: string;
|
|
32
|
+
/** Routes the entry into the reserved `## Optional` section. */
|
|
33
|
+
optional?: boolean;
|
|
34
|
+
/** Sort order within a section — higher first. Defaults to 0. */
|
|
35
|
+
priority?: number;
|
|
12
36
|
updatedAt?: string;
|
|
13
37
|
isCornerstone?: boolean;
|
|
14
38
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llms-txt.d.ts","sourceRoot":"","sources":["../../src/seo/llms-txt.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"llms-txt.d.ts","sourceRoot":"","sources":["../../src/seo/llms-txt.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAiBvF;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,CAgDnF"}
|
package/dist/seo/llms-txt.js
CHANGED
|
@@ -1,27 +1,97 @@
|
|
|
1
|
+
const DESCRIPTION_MAX = 200;
|
|
2
|
+
const TITLE_MAX = 160;
|
|
3
|
+
/**
|
|
4
|
+
* Coerce CMS-authored text into a safe single-line list-item fragment.
|
|
5
|
+
*
|
|
6
|
+
* These strings flow from editor fields into a file that AI agents read, so we
|
|
7
|
+
* defend against two things: (1) markdown-breaking characters that would corrupt
|
|
8
|
+
* the `- [title](url): desc` syntax, and (2) multi-line / control-character
|
|
9
|
+
* content that a careless or hostile editor could use to smuggle instruction-like
|
|
10
|
+
* text. This is not a complete prompt-injection defense (no text filter is) — it
|
|
11
|
+
* forces single-line, length-capped, link-safe plain text, which removes the
|
|
12
|
+
* most common corruption and obfuscation vectors.
|
|
13
|
+
*/
|
|
14
|
+
export function sanitizeLlmsText(raw, maxLen) {
|
|
15
|
+
if (!raw)
|
|
16
|
+
return '';
|
|
17
|
+
let s = raw
|
|
18
|
+
// Strip control characters (incl. newlines, tabs, zero-width) → space.
|
|
19
|
+
.replace(/[\u0000-\u001F\u007F\u200B-\u200D\uFEFF]/g, ' ')
|
|
20
|
+
// Remove characters that break markdown link syntax in the list item.
|
|
21
|
+
.replace(/[[\]()]/g, '')
|
|
22
|
+
// Collapse any remaining whitespace runs.
|
|
23
|
+
.replace(/\s+/g, ' ')
|
|
24
|
+
.trim();
|
|
25
|
+
if (s.length > maxLen)
|
|
26
|
+
s =
|
|
27
|
+
s
|
|
28
|
+
.slice(0, maxLen)
|
|
29
|
+
.replace(/\s+\S*$/, '')
|
|
30
|
+
.trim() || s.slice(0, maxLen);
|
|
31
|
+
return s;
|
|
32
|
+
}
|
|
1
33
|
export function generateLlmsTxt(config, pages) {
|
|
2
34
|
const maxPages = config.maxPages ?? 50;
|
|
35
|
+
const maxPerSection = config.maxPerSection ?? 25;
|
|
3
36
|
const lines = [];
|
|
4
|
-
lines.push(`# ${config.siteName}`);
|
|
37
|
+
lines.push(`# ${sanitizeLlmsText(config.siteName, TITLE_MAX) || 'Site'}`);
|
|
5
38
|
lines.push('');
|
|
6
|
-
|
|
7
|
-
|
|
39
|
+
const summary = sanitizeLlmsText(config.siteDescription, DESCRIPTION_MAX);
|
|
40
|
+
if (summary) {
|
|
41
|
+
lines.push(`> ${summary}`);
|
|
42
|
+
lines.push('');
|
|
43
|
+
}
|
|
44
|
+
// Free-text context block. It is a reviewed config field (not editor-freeform),
|
|
45
|
+
// so multi-line markdown is allowed; we only trim and drop accidental headings
|
|
46
|
+
// (which would corrupt the section structure the spec relies on).
|
|
47
|
+
const intro = (config.intro ?? '')
|
|
48
|
+
.split(/\r?\n/)
|
|
49
|
+
.filter((l) => !/^\s{0,3}#/.test(l))
|
|
50
|
+
.join('\n')
|
|
51
|
+
.trim();
|
|
52
|
+
if (intro) {
|
|
53
|
+
lines.push(intro);
|
|
8
54
|
lines.push('');
|
|
9
55
|
}
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
56
|
+
const limited = [...pages].sort(comparePages).slice(0, maxPages);
|
|
57
|
+
const main = limited.filter((p) => !p.optional);
|
|
58
|
+
const optional = limited.filter((p) => p.optional);
|
|
59
|
+
for (const [section, group] of groupBySection(main)) {
|
|
60
|
+
emitSection(lines, formatHeading(section), group, maxPerSection);
|
|
61
|
+
}
|
|
62
|
+
// The reserved `## Optional` section tells context-limited agents what to skip
|
|
63
|
+
// first. Optional entries are flat (not sub-grouped) per common convention.
|
|
64
|
+
if (optional.length > 0) {
|
|
65
|
+
emitSection(lines, 'Optional', optional, maxPerSection);
|
|
66
|
+
}
|
|
67
|
+
lines.push('## Resources');
|
|
68
|
+
lines.push('');
|
|
69
|
+
lines.push(`- [Sitemap](${config.siteUrl}/sitemap.xml)`);
|
|
70
|
+
lines.push(`- [API Documentation](${config.siteUrl}/api/cms/docs)`);
|
|
71
|
+
lines.push('');
|
|
72
|
+
return lines.join('\n');
|
|
73
|
+
}
|
|
74
|
+
/** Cornerstone first, then higher `priority`, then most-recently updated. */
|
|
75
|
+
function comparePages(a, b) {
|
|
76
|
+
if (a.isCornerstone !== b.isCornerstone)
|
|
77
|
+
return a.isCornerstone ? -1 : 1;
|
|
78
|
+
const pa = a.priority ?? 0;
|
|
79
|
+
const pb = b.priority ?? 0;
|
|
80
|
+
if (pa !== pb)
|
|
81
|
+
return pb - pa;
|
|
82
|
+
if (a.updatedAt && b.updatedAt)
|
|
83
|
+
return b.updatedAt.localeCompare(a.updatedAt);
|
|
84
|
+
if (a.updatedAt)
|
|
85
|
+
return -1;
|
|
86
|
+
if (b.updatedAt)
|
|
87
|
+
return 1;
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
90
|
+
/** Group entries by their resolved section, preserving first-seen order. */
|
|
91
|
+
function groupBySection(pages) {
|
|
22
92
|
const groups = new Map();
|
|
23
|
-
for (const page of
|
|
24
|
-
const key = page.collection ?? 'Important Pages';
|
|
93
|
+
for (const page of pages) {
|
|
94
|
+
const key = page.section ?? page.collection ?? 'Important Pages';
|
|
25
95
|
let group = groups.get(key);
|
|
26
96
|
if (!group) {
|
|
27
97
|
group = [];
|
|
@@ -29,44 +99,25 @@ export function generateLlmsTxt(config, pages) {
|
|
|
29
99
|
}
|
|
30
100
|
group.push(page);
|
|
31
101
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return a.isCornerstone ? -1 : 1;
|
|
37
|
-
if (a.updatedAt && b.updatedAt)
|
|
38
|
-
return b.updatedAt.localeCompare(a.updatedAt);
|
|
39
|
-
if (a.updatedAt)
|
|
40
|
-
return -1;
|
|
41
|
-
if (b.updatedAt)
|
|
42
|
-
return 1;
|
|
43
|
-
return 0;
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
for (const [collection, group] of groups) {
|
|
47
|
-
const heading = formatHeading(collection);
|
|
48
|
-
lines.push(`## ${heading}`);
|
|
49
|
-
lines.push('');
|
|
50
|
-
for (const page of group) {
|
|
51
|
-
// Append a freshness marker so AI answer engines can prefer recent
|
|
52
|
-
// content. `updatedAt` is an ISO string; emit the date portion only.
|
|
53
|
-
const updated = page.updatedAt ? formatLlmsDate(page.updatedAt) : undefined;
|
|
54
|
-
const suffix = [page.description, updated ? `Updated: ${updated}` : undefined]
|
|
55
|
-
.filter(Boolean)
|
|
56
|
-
.join(' — ');
|
|
57
|
-
const entry = suffix
|
|
58
|
-
? `- [${page.title}](${page.url}): ${suffix}`
|
|
59
|
-
: `- [${page.title}](${page.url})`;
|
|
60
|
-
lines.push(entry);
|
|
61
|
-
}
|
|
62
|
-
lines.push('');
|
|
63
|
-
}
|
|
64
|
-
lines.push('## Resources');
|
|
102
|
+
return groups;
|
|
103
|
+
}
|
|
104
|
+
function emitSection(lines, heading, group, maxPerSection) {
|
|
105
|
+
lines.push(`## ${heading}`);
|
|
65
106
|
lines.push('');
|
|
66
|
-
|
|
67
|
-
|
|
107
|
+
// Cap per section so a single large collection can't crowd out the rest.
|
|
108
|
+
for (const page of group.slice(0, maxPerSection)) {
|
|
109
|
+
const title = sanitizeLlmsText(page.title, TITLE_MAX) || 'Untitled';
|
|
110
|
+
const description = sanitizeLlmsText(page.description, DESCRIPTION_MAX);
|
|
111
|
+
// Append a freshness marker so AI answer engines can prefer recent content.
|
|
112
|
+
// `updatedAt` is an ISO string; emit the date portion only.
|
|
113
|
+
const updated = page.updatedAt ? formatLlmsDate(page.updatedAt) : undefined;
|
|
114
|
+
const suffix = [description, updated ? `Updated: ${updated}` : undefined]
|
|
115
|
+
.filter(Boolean)
|
|
116
|
+
.join(' — ');
|
|
117
|
+
const entry = suffix ? `- [${title}](${page.url}): ${suffix}` : `- [${title}](${page.url})`;
|
|
118
|
+
lines.push(entry);
|
|
119
|
+
}
|
|
68
120
|
lines.push('');
|
|
69
|
-
return lines.join('\n');
|
|
70
121
|
}
|
|
71
122
|
function formatHeading(collection) {
|
|
72
123
|
return collection.replace(/[-_]/g, ' ').replace(/\b\w/g, (ch) => ch.toUpperCase());
|
package/dist/seo/llms-txt.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llms-txt.js","sourceRoot":"","sources":["../../src/seo/llms-txt.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"llms-txt.js","sourceRoot":"","sources":["../../src/seo/llms-txt.ts"],"names":[],"mappings":"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"}
|