@rimelight/seo 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +40 -0
- package/dist/index.mjs +178 -0
- package/dist/robots.d.mts +8 -0
- package/dist/robots.mjs +29 -0
- package/dist/sitemap.d.mts +20 -0
- package/dist/sitemap.mjs +89 -0
- package/dist/types-Ck_Zs5Ws.d.mts +301 -0
- package/dist/types.d.mts +2 -0
- package/dist/types.mjs +1 -0
- package/package.json +22 -8
- package/src/env.d.ts +0 -3
- package/src/index.ts +0 -41
- package/src/llms.test.ts +0 -61
- package/src/llms.ts +0 -124
- package/src/meta.test.ts +0 -110
- package/src/meta.ts +0 -70
- package/src/robots.test.ts +0 -75
- package/src/robots.ts +0 -59
- package/src/schema.test.ts +0 -45
- package/src/schema.ts +0 -95
- package/src/sitemap.test.ts +0 -191
- package/src/sitemap.ts +0 -166
- package/src/types.ts +0 -238
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { _ as ArticleSchemaOptions, a as RSSFeed, b as buildBreadcrumbSchema, c as SiteConfig, d as UserAgentRule, f as LlmsFullTxtOptions, g as buildLlmsTxt, h as buildLlmsFullTxt, i as OGImage, l as SitemapAlternate, m as LlmsTxtOptions, n as HeadProps, o as RobotsOptions, p as LlmsPage, r as LocaleConfig, s as SeoEntry, t as ChangeFreq, u as SitemapUrl, v as BreadcrumbItem, y as buildArticleSchema } from "./types-Ck_Zs5Ws.mjs";
|
|
2
|
+
import { buildSitemapIndexXml, buildSitemapUrls, buildSitemapXml, chunkSitemapUrls } from "./sitemap.mjs";
|
|
3
|
+
import { buildRobotsTxt } from "./robots.mjs";
|
|
4
|
+
//#region src/meta.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Build a canonical URL from a page URL and site base. - Strips trailing slash unless the path has
|
|
7
|
+
* query params (where trailing slash is removed too). - Returns undefined-safe: pass Astro.url and
|
|
8
|
+
* Astro.site directly.
|
|
9
|
+
*/
|
|
10
|
+
declare function buildCanonicalUrl(url: string | URL, base: string | URL): string;
|
|
11
|
+
/**
|
|
12
|
+
* Build a page title using a site's title template. Falls back to siteName for untitled pages; uses
|
|
13
|
+
* a 404 label for error pages.
|
|
14
|
+
*/
|
|
15
|
+
declare function buildPageTitle(opts: {
|
|
16
|
+
title?: string;
|
|
17
|
+
siteName: string;
|
|
18
|
+
titleTemplate: string;
|
|
19
|
+
is404?: boolean;
|
|
20
|
+
}): string;
|
|
21
|
+
/**
|
|
22
|
+
* Truncate a description to a maximum character length, appending "…" if trimmed.
|
|
23
|
+
*/
|
|
24
|
+
declare function buildSafeDescription(description: string, maxLength: number): string;
|
|
25
|
+
/**
|
|
26
|
+
* Build the value for the <meta name="robots"> tag. Returns the full directive string including
|
|
27
|
+
* max-image-preview for indexable pages.
|
|
28
|
+
*/
|
|
29
|
+
declare function buildRobotsMetaContent(opts: {
|
|
30
|
+
noindex?: boolean;
|
|
31
|
+
is404?: boolean;
|
|
32
|
+
override?: string;
|
|
33
|
+
}): string;
|
|
34
|
+
/**
|
|
35
|
+
* \n * Build a Schema.org WebSite JSON-LD object.\n * Pass the result to JSON.stringify and emit
|
|
36
|
+
* via <script type="application/ld+json">.\n
|
|
37
|
+
*/
|
|
38
|
+
declare function buildWebSiteSchema(config: Pick<SiteConfig, "name" | "url" | "description">, site?: string): Record<string, unknown>;
|
|
39
|
+
//#endregion
|
|
40
|
+
export { type ArticleSchemaOptions, type BreadcrumbItem, type ChangeFreq, type HeadProps, type LlmsFullTxtOptions, type LlmsPage, type LlmsTxtOptions, type LocaleConfig, type OGImage, type RSSFeed, type RobotsOptions, type SeoEntry, type SiteConfig, type SitemapAlternate, type SitemapUrl, type UserAgentRule, buildArticleSchema, buildBreadcrumbSchema, buildCanonicalUrl, buildLlmsFullTxt, buildLlmsTxt, buildPageTitle, buildRobotsMetaContent, buildRobotsTxt, buildSafeDescription, buildSitemapIndexXml, buildSitemapUrls, buildSitemapXml, buildWebSiteSchema, chunkSitemapUrls };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { buildSitemapIndexXml, buildSitemapUrls, buildSitemapXml, chunkSitemapUrls } from "./sitemap.mjs";
|
|
2
|
+
import { buildRobotsTxt } from "./robots.mjs";
|
|
3
|
+
//#region src/meta.ts
|
|
4
|
+
/**
|
|
5
|
+
* Build a canonical URL from a page URL and site base. - Strips trailing slash unless the path has
|
|
6
|
+
* query params (where trailing slash is removed too). - Returns undefined-safe: pass Astro.url and
|
|
7
|
+
* Astro.site directly.
|
|
8
|
+
*/
|
|
9
|
+
function buildCanonicalUrl(url, base) {
|
|
10
|
+
const path = new URL(url, base).toString();
|
|
11
|
+
return path.includes("?") ? path.replace(/\/?$/, "") : path.replace(/\/?$/, "/");
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Build a page title using a site's title template. Falls back to siteName for untitled pages; uses
|
|
15
|
+
* a 404 label for error pages.
|
|
16
|
+
*/
|
|
17
|
+
function buildPageTitle(opts) {
|
|
18
|
+
const { title, siteName, titleTemplate, is404 } = opts;
|
|
19
|
+
if (is404) return `404 - Not Found | ${siteName}`;
|
|
20
|
+
if (!title) return siteName;
|
|
21
|
+
return titleTemplate.replace("%s", title);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Truncate a description to a maximum character length, appending "…" if trimmed.
|
|
25
|
+
*/
|
|
26
|
+
function buildSafeDescription(description, maxLength) {
|
|
27
|
+
if (!description) return description;
|
|
28
|
+
if (description.length <= maxLength) return description;
|
|
29
|
+
return description.slice(0, maxLength - 3) + "...";
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Build the value for the <meta name="robots"> tag. Returns the full directive string including
|
|
33
|
+
* max-image-preview for indexable pages.
|
|
34
|
+
*/
|
|
35
|
+
function buildRobotsMetaContent(opts) {
|
|
36
|
+
if (opts.override) return opts.override;
|
|
37
|
+
return !opts.noindex && !opts.is404 ? "index, follow, max-image-preview:large" : "noindex, nofollow";
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* \n * Build a Schema.org WebSite JSON-LD object.\n * Pass the result to JSON.stringify and emit
|
|
41
|
+
* via <script type="application/ld+json">.\n
|
|
42
|
+
*/
|
|
43
|
+
function buildWebSiteSchema(config, site) {
|
|
44
|
+
return {
|
|
45
|
+
"@context": "https://schema.org",
|
|
46
|
+
"@type": "WebSite",
|
|
47
|
+
"name": config.name,
|
|
48
|
+
"url": site ?? config.url,
|
|
49
|
+
"description": config.description
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region src/llms.ts
|
|
54
|
+
/**
|
|
55
|
+
* Builds standard /llms.txt document format for AI discovery.
|
|
56
|
+
*/
|
|
57
|
+
function buildLlmsTxt(options) {
|
|
58
|
+
const { site, title, description, fullCorpusUrl = `${site.replace(/\/$/, "")}/llms-full.txt`, pages, sections = [] } = options;
|
|
59
|
+
const lines = [
|
|
60
|
+
`# ${title}`,
|
|
61
|
+
"",
|
|
62
|
+
description || "Documentation index for AI agents.",
|
|
63
|
+
"",
|
|
64
|
+
`Full corpus (all pages, one document): ${fullCorpusUrl}`,
|
|
65
|
+
""
|
|
66
|
+
];
|
|
67
|
+
if (sections.length > 0) {
|
|
68
|
+
lines.push("## Sections", "");
|
|
69
|
+
for (const sec of sections) lines.push(`- [${sec.label}](${sec.url})`);
|
|
70
|
+
lines.push("");
|
|
71
|
+
}
|
|
72
|
+
lines.push("## Pages", "");
|
|
73
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
74
|
+
for (const page of pages) {
|
|
75
|
+
const sec = page.section || "General";
|
|
76
|
+
if (!grouped.has(sec)) grouped.set(sec, []);
|
|
77
|
+
grouped.get(sec).push(page);
|
|
78
|
+
}
|
|
79
|
+
if (grouped.size === 1 && grouped.has("General")) for (const page of pages) {
|
|
80
|
+
const pageUrl = page.markdownUrl || page.url;
|
|
81
|
+
const desc = page.description ? ` — ${page.description}` : "";
|
|
82
|
+
lines.push(`- [${page.title}](${pageUrl})${desc}`);
|
|
83
|
+
}
|
|
84
|
+
else for (const [secName, secPages] of grouped.entries()) {
|
|
85
|
+
lines.push(`### ${secName}`, "");
|
|
86
|
+
for (const page of secPages) {
|
|
87
|
+
const pageUrl = page.markdownUrl || page.url;
|
|
88
|
+
const desc = page.description ? ` — ${page.description}` : "";
|
|
89
|
+
lines.push(`- [${page.title}](${pageUrl})${desc}`);
|
|
90
|
+
}
|
|
91
|
+
lines.push("");
|
|
92
|
+
}
|
|
93
|
+
lines.push("");
|
|
94
|
+
return lines.join("\n");
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Builds concatenated /llms-full.txt single corpus document for AI agents.
|
|
98
|
+
*/
|
|
99
|
+
function buildLlmsFullTxt(options) {
|
|
100
|
+
const { title, description, pages } = options;
|
|
101
|
+
const parts = [
|
|
102
|
+
`# ${title} — Full Documentation Corpus`,
|
|
103
|
+
"",
|
|
104
|
+
description || "Complete documentation corpus for AI agents.",
|
|
105
|
+
"",
|
|
106
|
+
"---",
|
|
107
|
+
""
|
|
108
|
+
];
|
|
109
|
+
for (const page of pages) {
|
|
110
|
+
const metaHeader = [
|
|
111
|
+
`## ${page.title}`,
|
|
112
|
+
"",
|
|
113
|
+
`URL: ${page.url}`,
|
|
114
|
+
...page.description ? [`Description: ${page.description}`] : [],
|
|
115
|
+
...page.version ? [`Version: ${page.version}`] : [],
|
|
116
|
+
"",
|
|
117
|
+
page.markdown.trim(),
|
|
118
|
+
"",
|
|
119
|
+
"---",
|
|
120
|
+
""
|
|
121
|
+
];
|
|
122
|
+
parts.push(...metaHeader);
|
|
123
|
+
}
|
|
124
|
+
return parts.join("\n");
|
|
125
|
+
}
|
|
126
|
+
//#endregion
|
|
127
|
+
//#region src/schema.ts
|
|
128
|
+
/**
|
|
129
|
+
* Builds Schema.org Article / TechArticle / BlogPosting JSON-LD.
|
|
130
|
+
*/
|
|
131
|
+
function buildArticleSchema(options) {
|
|
132
|
+
const { type = "TechArticle", title, description, url, datePublished, dateModified, authorName, authorUrl, image, publisherName = "Rimelight Entertainment", publisherLogo } = options;
|
|
133
|
+
const schema = {
|
|
134
|
+
"@context": "https://schema.org",
|
|
135
|
+
"@type": type,
|
|
136
|
+
"headline": title,
|
|
137
|
+
"mainEntityOfPage": {
|
|
138
|
+
"@type": "WebPage",
|
|
139
|
+
"@id": url
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
if (description) schema.description = description;
|
|
143
|
+
if (image) schema.image = image;
|
|
144
|
+
if (datePublished) schema.datePublished = datePublished instanceof Date ? datePublished.toISOString() : datePublished;
|
|
145
|
+
if (dateModified) schema.dateModified = dateModified instanceof Date ? dateModified.toISOString() : dateModified;
|
|
146
|
+
else if (datePublished) schema.dateModified = schema.datePublished;
|
|
147
|
+
if (authorName) schema.author = {
|
|
148
|
+
"@type": "Person",
|
|
149
|
+
"name": authorName,
|
|
150
|
+
...authorUrl ? { url: authorUrl } : {}
|
|
151
|
+
};
|
|
152
|
+
if (publisherName) schema.publisher = {
|
|
153
|
+
"@type": "Organization",
|
|
154
|
+
"name": publisherName,
|
|
155
|
+
...publisherLogo ? { logo: {
|
|
156
|
+
"@type": "ImageObject",
|
|
157
|
+
"url": publisherLogo
|
|
158
|
+
} } : {}
|
|
159
|
+
};
|
|
160
|
+
return schema;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Builds Schema.org BreadcrumbList JSON-LD.
|
|
164
|
+
*/
|
|
165
|
+
function buildBreadcrumbSchema(items) {
|
|
166
|
+
return {
|
|
167
|
+
"@context": "https://schema.org",
|
|
168
|
+
"@type": "BreadcrumbList",
|
|
169
|
+
"itemListElement": items.map((item, index) => ({
|
|
170
|
+
"@type": "ListItem",
|
|
171
|
+
"position": index + 1,
|
|
172
|
+
"name": item.name,
|
|
173
|
+
"item": item.url
|
|
174
|
+
}))
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
//#endregion
|
|
178
|
+
export { buildArticleSchema, buildBreadcrumbSchema, buildCanonicalUrl, buildLlmsFullTxt, buildLlmsTxt, buildPageTitle, buildRobotsMetaContent, buildRobotsTxt, buildSafeDescription, buildSitemapIndexXml, buildSitemapUrls, buildSitemapXml, buildWebSiteSchema, chunkSitemapUrls };
|
package/dist/robots.mjs
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region src/robots.ts
|
|
2
|
+
/**
|
|
3
|
+
* Build robots.txt content from options
|
|
4
|
+
*/
|
|
5
|
+
function buildRobotsTxt(options) {
|
|
6
|
+
const lines = [];
|
|
7
|
+
if (options.userAgentRules && options.userAgentRules.length > 0) for (const rule of options.userAgentRules) {
|
|
8
|
+
lines.push(buildUserAgentSection(rule));
|
|
9
|
+
lines.push("");
|
|
10
|
+
}
|
|
11
|
+
lines.push("User-agent: *");
|
|
12
|
+
if (options.disallow && options.disallow.length > 0) for (const path of options.disallow) lines.push(`Disallow: ${path}`);
|
|
13
|
+
if (options.allow && options.allow.length > 0) for (const path of options.allow) lines.push(`Allow: ${path}`);
|
|
14
|
+
lines.push("");
|
|
15
|
+
lines.push(`Sitemap: ${options.sitemapUrl}`);
|
|
16
|
+
return lines.join("\n");
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Build a user-agent specific section
|
|
20
|
+
*/
|
|
21
|
+
function buildUserAgentSection(rule) {
|
|
22
|
+
const lines = [];
|
|
23
|
+
lines.push(`User-agent: ${rule.userAgent}`);
|
|
24
|
+
if (rule.disallow && rule.disallow.length > 0) for (const path of rule.disallow) lines.push(`Disallow: ${path}`);
|
|
25
|
+
if (rule.allow && rule.allow.length > 0) for (const path of rule.allow) lines.push(`Allow: ${path}`);
|
|
26
|
+
return lines.join("\n");
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { buildRobotsTxt };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { r as LocaleConfig, s as SeoEntry, u as SitemapUrl } from "./types-Ck_Zs5Ws.mjs";
|
|
2
|
+
//#region src/sitemap.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Build fully-resolved sitemap URLs from entries and locale config
|
|
5
|
+
*/
|
|
6
|
+
declare function buildSitemapUrls(entries: SeoEntry[], config: LocaleConfig): SitemapUrl[];
|
|
7
|
+
/**
|
|
8
|
+
* Build sitemap XML from resolved URLs
|
|
9
|
+
*/
|
|
10
|
+
declare function buildSitemapXml(urls: SitemapUrl[]): string;
|
|
11
|
+
/**
|
|
12
|
+
* Build sitemap index XML from sitemap URLs
|
|
13
|
+
*/
|
|
14
|
+
declare function buildSitemapIndexXml(sitemapUrls: string[]): string;
|
|
15
|
+
/**
|
|
16
|
+
* Chunk sitemap URLs into multiple sitemaps (max 50k URLs per sitemap)
|
|
17
|
+
*/
|
|
18
|
+
declare function chunkSitemapUrls(urls: SitemapUrl[], limit?: number): SitemapUrl[][];
|
|
19
|
+
//#endregion
|
|
20
|
+
export { buildSitemapIndexXml, buildSitemapUrls, buildSitemapXml, chunkSitemapUrls };
|
package/dist/sitemap.mjs
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
//#region src/sitemap.ts
|
|
2
|
+
/**
|
|
3
|
+
* Build fully-resolved sitemap URLs from entries and locale config
|
|
4
|
+
*/
|
|
5
|
+
function buildSitemapUrls(entries, config) {
|
|
6
|
+
const urls = [];
|
|
7
|
+
const { site, locales, defaultLocale, prefixDefaultLocale, trailingSlash } = config;
|
|
8
|
+
for (const entry of entries) {
|
|
9
|
+
const entryLocales = entry.locales && entry.locales.length > 0 ? entry.locales : Object.keys(locales);
|
|
10
|
+
const entryUrls = [];
|
|
11
|
+
for (const locale of entryLocales) {
|
|
12
|
+
const localePrefix = !(locale === defaultLocale) || prefixDefaultLocale ? `/${locale}` : "";
|
|
13
|
+
let path = entry.path;
|
|
14
|
+
if (trailingSlash === "always" && !path.endsWith("/")) path += "/";
|
|
15
|
+
else if (trailingSlash === "never" && path.endsWith("/")) path = path.replace(/\/$/, "");
|
|
16
|
+
const item = { loc: `${site}${localePrefix}${path}` };
|
|
17
|
+
if (entry.lastmod) item.lastmod = entry.lastmod.toISOString();
|
|
18
|
+
if (entry.changefreq) item.changefreq = entry.changefreq;
|
|
19
|
+
if (entry.priority !== void 0) item.priority = entry.priority;
|
|
20
|
+
entryUrls.push(item);
|
|
21
|
+
}
|
|
22
|
+
if (entryUrls.length > 1) {
|
|
23
|
+
const defaultUrl = entryUrls.find((u) => u.loc === `${site}${prefixDefaultLocale ? `/${defaultLocale}` : ""}${entry.path}`);
|
|
24
|
+
for (const url of entryUrls) {
|
|
25
|
+
url.alternates = entryUrls.filter((u) => u.loc !== url.loc).map((u) => ({
|
|
26
|
+
hreflang: extractHreflang(u.loc, locales, defaultLocale),
|
|
27
|
+
href: u.loc
|
|
28
|
+
}));
|
|
29
|
+
if (defaultUrl && url.loc === defaultUrl.loc) url.alternates.push({
|
|
30
|
+
hreflang: "x-default",
|
|
31
|
+
href: defaultUrl.loc
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
urls.push(...entryUrls);
|
|
36
|
+
}
|
|
37
|
+
return urls;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Build sitemap XML from resolved URLs
|
|
41
|
+
*/
|
|
42
|
+
function buildSitemapXml(urls) {
|
|
43
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
44
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
|
45
|
+
${urls.map((url) => {
|
|
46
|
+
let xml = ` <url>\n <loc>${escapeXml(url.loc)}</loc>`;
|
|
47
|
+
if (url.lastmod) xml += `\n <lastmod>${url.lastmod}</lastmod>`;
|
|
48
|
+
if (url.changefreq) xml += `\n <changefreq>${url.changefreq}</changefreq>`;
|
|
49
|
+
if (url.priority !== void 0) xml += `\n <priority>${url.priority.toFixed(1)}</priority>`;
|
|
50
|
+
if (url.alternates && url.alternates.length > 0) for (const alt of url.alternates) xml += `\n <xhtml:link rel="alternate" hreflang="${alt.hreflang}" href="${escapeXml(alt.href)}" />`;
|
|
51
|
+
xml += "\n </url>";
|
|
52
|
+
return xml;
|
|
53
|
+
}).join("\n")}
|
|
54
|
+
</urlset>`;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Build sitemap index XML from sitemap URLs
|
|
58
|
+
*/
|
|
59
|
+
function buildSitemapIndexXml(sitemapUrls) {
|
|
60
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
61
|
+
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
62
|
+
${sitemapUrls.map((url) => ` <sitemap>
|
|
63
|
+
<loc>${escapeXml(url)}</loc>
|
|
64
|
+
</sitemap>`).join("\n")}
|
|
65
|
+
</sitemapindex>`;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Chunk sitemap URLs into multiple sitemaps (max 50k URLs per sitemap)
|
|
69
|
+
*/
|
|
70
|
+
function chunkSitemapUrls(urls, limit = 45e3) {
|
|
71
|
+
const chunks = [];
|
|
72
|
+
for (let i = 0; i < urls.length; i += limit) chunks.push(urls.slice(i, i + limit));
|
|
73
|
+
return chunks;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Extract hreflang from a URL based on locale config
|
|
77
|
+
*/
|
|
78
|
+
function extractHreflang(url, locales, defaultLocale) {
|
|
79
|
+
for (const [segment, hreflang] of Object.entries(locales)) if (url.includes(`/${segment}/`) || url.endsWith(`/${segment}`)) return hreflang;
|
|
80
|
+
return locales[defaultLocale] || "en";
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Escape XML special characters
|
|
84
|
+
*/
|
|
85
|
+
function escapeXml(str) {
|
|
86
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
export { buildSitemapIndexXml, buildSitemapUrls, buildSitemapXml, chunkSitemapUrls };
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
//#region src/schema.d.ts
|
|
2
|
+
interface ArticleSchemaOptions {
|
|
3
|
+
type?: "TechArticle" | "Article" | "BlogPosting";
|
|
4
|
+
title: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
url: string;
|
|
7
|
+
datePublished?: string | Date;
|
|
8
|
+
dateModified?: string | Date;
|
|
9
|
+
authorName?: string;
|
|
10
|
+
authorUrl?: string;
|
|
11
|
+
image?: string;
|
|
12
|
+
publisherName?: string;
|
|
13
|
+
publisherLogo?: string;
|
|
14
|
+
}
|
|
15
|
+
interface BreadcrumbItem {
|
|
16
|
+
name: string;
|
|
17
|
+
url: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Builds Schema.org Article / TechArticle / BlogPosting JSON-LD.
|
|
21
|
+
*/
|
|
22
|
+
declare function buildArticleSchema(options: ArticleSchemaOptions): Record<string, any>;
|
|
23
|
+
/**
|
|
24
|
+
* Builds Schema.org BreadcrumbList JSON-LD.
|
|
25
|
+
*/
|
|
26
|
+
declare function buildBreadcrumbSchema(items: BreadcrumbItem[]): Record<string, any>;
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region src/llms.d.ts
|
|
29
|
+
interface LlmsPage {
|
|
30
|
+
title: string;
|
|
31
|
+
url: string;
|
|
32
|
+
description?: string;
|
|
33
|
+
markdownUrl?: string;
|
|
34
|
+
section?: string;
|
|
35
|
+
}
|
|
36
|
+
interface LlmsTxtOptions {
|
|
37
|
+
site: string;
|
|
38
|
+
title: string;
|
|
39
|
+
description?: string;
|
|
40
|
+
fullCorpusUrl?: string;
|
|
41
|
+
pages: LlmsPage[];
|
|
42
|
+
sections?: Array<{
|
|
43
|
+
label: string;
|
|
44
|
+
url: string;
|
|
45
|
+
}>;
|
|
46
|
+
}
|
|
47
|
+
interface LlmsFullTxtOptions {
|
|
48
|
+
site: string;
|
|
49
|
+
title: string;
|
|
50
|
+
description?: string;
|
|
51
|
+
pages: Array<{
|
|
52
|
+
title: string;
|
|
53
|
+
url: string;
|
|
54
|
+
description?: string;
|
|
55
|
+
markdown: string;
|
|
56
|
+
version?: string;
|
|
57
|
+
}>;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Builds standard /llms.txt document format for AI discovery.
|
|
61
|
+
*/
|
|
62
|
+
declare function buildLlmsTxt(options: LlmsTxtOptions): string;
|
|
63
|
+
/**
|
|
64
|
+
* Builds concatenated /llms-full.txt single corpus document for AI agents.
|
|
65
|
+
*/
|
|
66
|
+
declare function buildLlmsFullTxt(options: LlmsFullTxtOptions): string;
|
|
67
|
+
//#endregion
|
|
68
|
+
//#region src/types.d.ts
|
|
69
|
+
/**
|
|
70
|
+
* Change frequency for sitemap entries
|
|
71
|
+
*/
|
|
72
|
+
type ChangeFreq = "always" | "hourly" | "daily" | "weekly" | "monthly" | "yearly" | "never";
|
|
73
|
+
/**
|
|
74
|
+
* SEO entry — a single page to include in sitemaps
|
|
75
|
+
*/
|
|
76
|
+
interface SeoEntry {
|
|
77
|
+
/**
|
|
78
|
+
* Locale-less path, e.g. "/company/blog/hello". Leading slash required.
|
|
79
|
+
*/
|
|
80
|
+
path: string;
|
|
81
|
+
lastmod?: Date;
|
|
82
|
+
changefreq?: ChangeFreq;
|
|
83
|
+
priority?: number;
|
|
84
|
+
/**
|
|
85
|
+
* Restrict to a subset of locales; defaults to all configured locales.
|
|
86
|
+
*/
|
|
87
|
+
locales?: readonly string[];
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Locale configuration for SEO builders
|
|
91
|
+
*/
|
|
92
|
+
interface LocaleConfig {
|
|
93
|
+
/**
|
|
94
|
+
* Absolute origin, e.g. "https://rimelight.com"
|
|
95
|
+
*/
|
|
96
|
+
site: string;
|
|
97
|
+
/**
|
|
98
|
+
* Map of locale segment -> hreflang, e.g. { en: "en-US", pt: "pt-BR" }
|
|
99
|
+
*/
|
|
100
|
+
locales: Record<string, string>;
|
|
101
|
+
defaultLocale: string;
|
|
102
|
+
/**
|
|
103
|
+
* Emit the default locale without a prefix. Default: false.
|
|
104
|
+
*/
|
|
105
|
+
prefixDefaultLocale?: boolean;
|
|
106
|
+
trailingSlash?: "always" | "never";
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Fully resolved sitemap URL with alternates
|
|
110
|
+
*/
|
|
111
|
+
interface SitemapUrl {
|
|
112
|
+
loc: string;
|
|
113
|
+
lastmod?: string;
|
|
114
|
+
changefreq?: ChangeFreq;
|
|
115
|
+
priority?: number;
|
|
116
|
+
alternates?: SitemapAlternate[];
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Language alternate for a sitemap URL
|
|
120
|
+
*/
|
|
121
|
+
interface SitemapAlternate {
|
|
122
|
+
hreflang: string;
|
|
123
|
+
href: string;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Options for robots.txt generation
|
|
127
|
+
*/
|
|
128
|
+
interface RobotsOptions {
|
|
129
|
+
/**
|
|
130
|
+
* The sitemap URL to reference
|
|
131
|
+
*/
|
|
132
|
+
sitemapUrl: string;
|
|
133
|
+
/**
|
|
134
|
+
* Paths to disallow for all user agents
|
|
135
|
+
*/
|
|
136
|
+
disallow?: string[];
|
|
137
|
+
/**
|
|
138
|
+
* Paths to allow for all user agents
|
|
139
|
+
*/
|
|
140
|
+
allow?: string[];
|
|
141
|
+
/**
|
|
142
|
+
* User-agent specific rules
|
|
143
|
+
*/
|
|
144
|
+
userAgentRules?: UserAgentRule[];
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* User-agent specific robots.txt rule
|
|
148
|
+
*/
|
|
149
|
+
interface UserAgentRule {
|
|
150
|
+
userAgent: string;
|
|
151
|
+
disallow?: string[];
|
|
152
|
+
allow?: string[];
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Site identity and SEO defaults shared across all Rimelight Astro sites. The UI-specific overrides
|
|
156
|
+
* (component themes, shortcuts, etc.) live in UIConfig (packages/ui) and are passed directly to the
|
|
157
|
+
* ui() integration.
|
|
158
|
+
*/
|
|
159
|
+
interface SiteConfig {
|
|
160
|
+
id: string;
|
|
161
|
+
name: string;
|
|
162
|
+
description: string;
|
|
163
|
+
url: string;
|
|
164
|
+
ogImage: string;
|
|
165
|
+
author: string;
|
|
166
|
+
email: string;
|
|
167
|
+
branding: {
|
|
168
|
+
logo: {
|
|
169
|
+
alt: string;
|
|
170
|
+
};
|
|
171
|
+
favicon: {
|
|
172
|
+
svg: string;
|
|
173
|
+
};
|
|
174
|
+
colors: {
|
|
175
|
+
themeColor: string;
|
|
176
|
+
backgroundColor: string;
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
seo: {
|
|
180
|
+
titleTemplate: string;
|
|
181
|
+
ogImageFallback: string;
|
|
182
|
+
maxDescriptionLength: number;
|
|
183
|
+
authorHandle?: string;
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Open Graph image with alt text
|
|
188
|
+
*/
|
|
189
|
+
interface OGImage {
|
|
190
|
+
/**
|
|
191
|
+
* Image URL (relative or absolute)
|
|
192
|
+
*/
|
|
193
|
+
src: string;
|
|
194
|
+
/**
|
|
195
|
+
* Alt text for the image
|
|
196
|
+
*/
|
|
197
|
+
alt: string;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* RSS feed link configuration
|
|
201
|
+
*/
|
|
202
|
+
interface RSSFeed {
|
|
203
|
+
/**
|
|
204
|
+
* RSS feed URL
|
|
205
|
+
*/
|
|
206
|
+
href: string;
|
|
207
|
+
/**
|
|
208
|
+
* Feed title (defaults to "RSS")
|
|
209
|
+
*/
|
|
210
|
+
title?: string;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Props for the RLAHead Astro component. Defined here so consumers can construct head props without
|
|
214
|
+
* importing @rimelight/ui.
|
|
215
|
+
*/
|
|
216
|
+
interface HeadProps {
|
|
217
|
+
/**
|
|
218
|
+
* Page title
|
|
219
|
+
*/
|
|
220
|
+
title?: string;
|
|
221
|
+
/**
|
|
222
|
+
* Page description
|
|
223
|
+
*/
|
|
224
|
+
description?: string;
|
|
225
|
+
/**
|
|
226
|
+
* Open Graph image with alt text
|
|
227
|
+
*/
|
|
228
|
+
ogImage?: OGImage;
|
|
229
|
+
/**
|
|
230
|
+
* Open Graph type (e.g., "website", "article")
|
|
231
|
+
*/
|
|
232
|
+
ogType?: string;
|
|
233
|
+
/**
|
|
234
|
+
* Open Graph locale (defaults to "en_US")
|
|
235
|
+
*/
|
|
236
|
+
ogLocale?: string;
|
|
237
|
+
/**
|
|
238
|
+
* Whether to prevent indexing
|
|
239
|
+
*/
|
|
240
|
+
noindex?: boolean;
|
|
241
|
+
/**
|
|
242
|
+
* Whether this is a 404 page
|
|
243
|
+
*/
|
|
244
|
+
is404?: boolean;
|
|
245
|
+
/**
|
|
246
|
+
* Robots metadata (overrides noindex/is404 logic if provided)
|
|
247
|
+
*/
|
|
248
|
+
robots?: string;
|
|
249
|
+
/**
|
|
250
|
+
* Canonical URL
|
|
251
|
+
*/
|
|
252
|
+
canonical?: string;
|
|
253
|
+
/**
|
|
254
|
+
* Language alternates for i18n
|
|
255
|
+
*/
|
|
256
|
+
languageAlternates?: Array<{
|
|
257
|
+
hreflang: string;
|
|
258
|
+
href: string;
|
|
259
|
+
}>;
|
|
260
|
+
/**
|
|
261
|
+
* Site configuration for defaults
|
|
262
|
+
*/
|
|
263
|
+
config?: SiteConfig;
|
|
264
|
+
/**
|
|
265
|
+
* Whether to enable View Transitions (ClientRouter)
|
|
266
|
+
*/
|
|
267
|
+
transitions?: boolean;
|
|
268
|
+
/**
|
|
269
|
+
* Meta charset
|
|
270
|
+
*/
|
|
271
|
+
charset?: string;
|
|
272
|
+
/**
|
|
273
|
+
* Meta viewport
|
|
274
|
+
*/
|
|
275
|
+
viewport?: string;
|
|
276
|
+
/**
|
|
277
|
+
* RSS feed configuration
|
|
278
|
+
*/
|
|
279
|
+
rssFeed?: RSSFeed;
|
|
280
|
+
/**
|
|
281
|
+
* Article or BlogPosting JSON-LD configuration
|
|
282
|
+
*/
|
|
283
|
+
articleSchema?: ArticleSchemaOptions;
|
|
284
|
+
/**
|
|
285
|
+
* Breadcrumb list for JSON-LD structured data
|
|
286
|
+
*/
|
|
287
|
+
breadcrumbs?: BreadcrumbItem[];
|
|
288
|
+
/**
|
|
289
|
+
* URL for this page's raw Markdown alternate twin
|
|
290
|
+
*/
|
|
291
|
+
markdownUrl?: string;
|
|
292
|
+
/**
|
|
293
|
+
* Version alternates for multi-version documentation
|
|
294
|
+
*/
|
|
295
|
+
versionAlternates?: Array<{
|
|
296
|
+
version: string;
|
|
297
|
+
href: string;
|
|
298
|
+
}>;
|
|
299
|
+
}
|
|
300
|
+
//#endregion
|
|
301
|
+
export { ArticleSchemaOptions as _, RSSFeed as a, buildBreadcrumbSchema as b, SiteConfig as c, UserAgentRule as d, LlmsFullTxtOptions as f, buildLlmsTxt as g, buildLlmsFullTxt as h, OGImage as i, SitemapAlternate as l, LlmsTxtOptions as m, HeadProps as n, RobotsOptions as o, LlmsPage as p, LocaleConfig as r, SeoEntry as s, ChangeFreq as t, SitemapUrl as u, BreadcrumbItem as v, buildArticleSchema as y };
|
package/dist/types.d.mts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { _ as ArticleSchemaOptions, a as RSSFeed, c as SiteConfig, d as UserAgentRule, f as LlmsFullTxtOptions, i as OGImage, l as SitemapAlternate, m as LlmsTxtOptions, n as HeadProps, o as RobotsOptions, p as LlmsPage, r as LocaleConfig, s as SeoEntry, t as ChangeFreq, u as SitemapUrl, v as BreadcrumbItem } from "./types-Ck_Zs5Ws.mjs";
|
|
2
|
+
export { type ArticleSchemaOptions, type BreadcrumbItem, ChangeFreq, HeadProps, type LlmsFullTxtOptions, type LlmsPage, type LlmsTxtOptions, LocaleConfig, OGImage, RSSFeed, RobotsOptions, SeoEntry, SiteConfig, SitemapAlternate, SitemapUrl, UserAgentRule };
|
package/dist/types.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|