payload-plugin-llms 0.9.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/README.md ADDED
@@ -0,0 +1,107 @@
1
+ # payload-plugin-llms
2
+
3
+ Payload CMS plugin and Next.js helpers for `llms.txt`, markdown page responses, markdown rewrites, and Lexical-to-Markdown conversion.
4
+
5
+ ## Usage
6
+
7
+ ```ts
8
+ import { buildConfig } from "payload"
9
+ import { payloadPluginLlms } from "payload-plugin-llms"
10
+
11
+ export default buildConfig({
12
+ plugins: [
13
+ payloadPluginLlms({
14
+ routes: {
15
+ llmsTxt: "/llms.txt",
16
+ markdownSegment: "md",
17
+ },
18
+ }),
19
+ ],
20
+ })
21
+ ```
22
+
23
+ The Payload plugin entrypoint keeps this package visible in Payload config and normalizes shared options. Next.js routes still live in your app route files.
24
+
25
+ ## llms.txt Route
26
+
27
+ ```ts
28
+ import { createLlmsTxtRoute } from "payload-plugin-llms/next"
29
+
30
+ export const GET = createLlmsTxtRoute({
31
+ loadContent: async () => ({
32
+ title: "Acme",
33
+ description: "Useful website content.",
34
+ intro: "This website is built with Next.js and Payload CMS.",
35
+ sections: [
36
+ {
37
+ title: "Pages",
38
+ links: [
39
+ {
40
+ title: "Home",
41
+ url: "https://example.com",
42
+ description: "Start here.",
43
+ },
44
+ ],
45
+ },
46
+ ],
47
+ }),
48
+ })
49
+ ```
50
+
51
+ Place this in a route such as `src/app/(meta)/llms.txt/route.ts`.
52
+
53
+ ## Markdown Page Route
54
+
55
+ ```ts
56
+ import { draftMode } from "next/headers"
57
+ import { createMarkdownRoute } from "payload-plugin-llms/next"
58
+
59
+ import { LOCALES } from "@/payload.i18n"
60
+ import { getCachedPageMarkdown } from "@/server/queries/get-cached-page-markdown"
61
+
62
+ export const GET = createMarkdownRoute({
63
+ locales: LOCALES,
64
+ draftMode,
65
+ searchParams: ["q", "collection"],
66
+ getMarkdown: getCachedPageMarkdown,
67
+ })
68
+ ```
69
+
70
+ Place this in a route such as `src/app/(frontend)/[locale]/md/[[...slug]]/route.ts`.
71
+
72
+ ## Markdown Rewrites
73
+
74
+ ```ts
75
+ import { createMarkdownRewrites } from "payload-plugin-llms/next"
76
+
77
+ import { LOCALES } from "@/payload.i18n"
78
+
79
+ export async function rewrites() {
80
+ return createMarkdownRewrites({
81
+ locales: LOCALES,
82
+ markdownSegment: "md",
83
+ })
84
+ }
85
+ ```
86
+
87
+ Requests with an `Accept` header containing `text/markdown` are rewritten to the localized markdown route.
88
+
89
+ ## Lexical Utility
90
+
91
+ ```ts
92
+ import { lexicalToMarkdown } from "payload-plugin-llms"
93
+
94
+ const markdown = lexicalToMarkdown(doc.content, {
95
+ resolveInternalLink: ({ relationTo, value }) => {
96
+ if (relationTo === "pages" && typeof value === "object" && value !== null && "slug" in value) {
97
+ return `/${String(value.slug)}`
98
+ }
99
+
100
+ return null
101
+ },
102
+ })
103
+ ```
104
+
105
+ ## App-Owned Rendering
106
+
107
+ The plugin does not ship project-specific document lookup, block rendering, cache tags, or URL building. Keep functions such as `getCachedPageMarkdown`, `docResultToMarkdown`, and `blocksToMarkdown` in your app and pass them to the route factories.
@@ -0,0 +1,3 @@
1
+ function o(i){let t=`- [${i.title}](${i.url})`;return i.description?`${t}: ${i.description}`:t}function g(i){let t=[];i.title&&t.push(`# ${i.title}`,""),i.description&&t.push(`> ${i.description}`,""),e(t,i.intro);for(let n of i.sections??[]){t.push(`## ${n.title}`,""),e(t,n.content,{trailingBlank:!1});for(let s of n.links??[])t.push(o(s));t.push("")}return e(t,i.footer,{trailingBlank:!1}),l(t).join(`
2
+ `)}function e(i,t,n={}){let s=Array.isArray(t)?t:t?[t]:[];if(s.length!==0){if(n.trailingBlank??!0){for(let r of s)i.push(r,"");return}for(let r of s)i.push(r)}}function l(i){let t=[...i];for(;t[0]==="";)t.shift();for(;t.at(-1)==="";)t.pop();return t}export{o as a,g as b};
3
+ //# sourceMappingURL=chunk-B5YH4Y5S.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/llms-txt.ts"],"sourcesContent":["export type LlmsTxtLink = {\n title: string\n url: string\n description?: string | null\n}\n\nexport type LlmsTxtSection = {\n title: string\n content?: string | string[]\n links?: LlmsTxtLink[]\n}\n\nexport type LlmsTxtContent = {\n title?: string\n description?: string\n intro?: string | string[]\n sections?: LlmsTxtSection[]\n footer?: string | string[]\n}\n\nexport function formatLlmsTxtLink(link: LlmsTxtLink): string {\n const line = `- [${link.title}](${link.url})`\n return link.description ? `${line}: ${link.description}` : line\n}\n\nexport function buildLlmsTxt(content: LlmsTxtContent): string {\n const lines: string[] = []\n\n if (content.title) {\n lines.push(`# ${content.title}`, \"\")\n }\n if (content.description) {\n lines.push(`> ${content.description}`, \"\")\n }\n\n appendLines(lines, content.intro)\n\n for (const section of content.sections ?? []) {\n lines.push(`## ${section.title}`, \"\")\n appendLines(lines, section.content, { trailingBlank: false })\n for (const link of section.links ?? []) {\n lines.push(formatLlmsTxtLink(link))\n }\n lines.push(\"\")\n }\n\n appendLines(lines, content.footer, { trailingBlank: false })\n\n return trimBlankEdges(lines).join(\"\\n\")\n}\n\nfunction appendLines(\n lines: string[],\n value: string | string[] | undefined,\n options: { trailingBlank?: boolean } = {},\n) {\n const values = Array.isArray(value) ? value : value ? [value] : []\n if (values.length === 0) return\n\n if (options.trailingBlank ?? true) {\n for (const item of values) {\n lines.push(item, \"\")\n }\n return\n }\n\n for (const item of values) {\n lines.push(item)\n }\n}\n\nfunction trimBlankEdges(lines: string[]) {\n const trimmed = [...lines]\n while (trimmed[0] === \"\") trimmed.shift()\n while (trimmed.at(-1) === \"\") trimmed.pop()\n return trimmed\n}\n"],"mappings":"AAoBO,SAASA,EAAkBC,EAA2B,CAC3D,IAAMC,EAAO,MAAMD,EAAK,KAAK,KAAKA,EAAK,GAAG,IAC1C,OAAOA,EAAK,YAAc,GAAGC,CAAI,KAAKD,EAAK,WAAW,GAAKC,CAC7D,CAEO,SAASC,EAAaC,EAAiC,CAC5D,IAAMC,EAAkB,CAAC,EAErBD,EAAQ,OACVC,EAAM,KAAK,KAAKD,EAAQ,KAAK,GAAI,EAAE,EAEjCA,EAAQ,aACVC,EAAM,KAAK,KAAKD,EAAQ,WAAW,GAAI,EAAE,EAG3CE,EAAYD,EAAOD,EAAQ,KAAK,EAEhC,QAAWG,KAAWH,EAAQ,UAAY,CAAC,EAAG,CAC5CC,EAAM,KAAK,MAAME,EAAQ,KAAK,GAAI,EAAE,EACpCD,EAAYD,EAAOE,EAAQ,QAAS,CAAE,cAAe,EAAM,CAAC,EAC5D,QAAWN,KAAQM,EAAQ,OAAS,CAAC,EACnCF,EAAM,KAAKL,EAAkBC,CAAI,CAAC,EAEpCI,EAAM,KAAK,EAAE,CACf,CAEA,OAAAC,EAAYD,EAAOD,EAAQ,OAAQ,CAAE,cAAe,EAAM,CAAC,EAEpDI,EAAeH,CAAK,EAAE,KAAK;AAAA,CAAI,CACxC,CAEA,SAASC,EACPD,EACAI,EACAC,EAAuC,CAAC,EACxC,CACA,IAAMC,EAAS,MAAM,QAAQF,CAAK,EAAIA,EAAQA,EAAQ,CAACA,CAAK,EAAI,CAAC,EACjE,GAAIE,EAAO,SAAW,EAEtB,IAAID,EAAQ,eAAiB,GAAM,CACjC,QAAWE,KAAQD,EACjBN,EAAM,KAAKO,EAAM,EAAE,EAErB,MACF,CAEA,QAAWA,KAAQD,EACjBN,EAAM,KAAKO,CAAI,EAEnB,CAEA,SAASJ,EAAeH,EAAiB,CACvC,IAAMQ,EAAU,CAAC,GAAGR,CAAK,EACzB,KAAOQ,EAAQ,CAAC,IAAM,IAAIA,EAAQ,MAAM,EACxC,KAAOA,EAAQ,GAAG,EAAE,IAAM,IAAIA,EAAQ,IAAI,EAC1C,OAAOA,CACT","names":["formatLlmsTxtLink","link","line","buildLlmsTxt","content","lines","appendLines","section","trimBlankEdges","value","options","values","item","trimmed"]}
package/dist/index.cjs ADDED
@@ -0,0 +1,17 @@
1
+ "use strict";var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var L=Object.prototype.hasOwnProperty;var T=(e,t)=>{for(var n in t)s(e,n,{get:t[n],enumerable:!0})},k=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of f(t))!L.call(e,r)&&r!==n&&s(e,r,{get:()=>t[r],enumerable:!(i=x(t,r))||i.enumerable});return e};var S=e=>k(s({},"__esModule",{value:!0}),e);var P={};T(P,{buildLlmsTxt:()=>m,default:()=>u,formatLlmsTxtLink:()=>d,lexicalToMarkdown:()=>p,normalizeOptions:()=>l,payloadPluginLlms:()=>u});module.exports=S(P);function d(e){let t=`- [${e.title}](${e.url})`;return e.description?`${t}: ${e.description}`:t}function m(e){let t=[];e.title&&t.push(`# ${e.title}`,""),e.description&&t.push(`> ${e.description}`,""),a(t,e.intro);for(let n of e.sections??[]){t.push(`## ${n.title}`,""),a(t,n.content,{trailingBlank:!1});for(let i of n.links??[])t.push(d(i));t.push("")}return a(t,e.footer,{trailingBlank:!1}),y(t).join(`
2
+ `)}function a(e,t,n={}){let i=Array.isArray(t)?t:t?[t]:[];if(i.length!==0){if(n.trailingBlank??!0){for(let r of i)e.push(r,"");return}for(let r of i)e.push(r)}}function y(e){let t=[...e];for(;t[0]==="";)t.shift();for(;t.at(-1)==="";)t.pop();return t}function p(e,t={}){return(e.root?.children??[]).map(i=>c(i,t)).join("").trim()}function c(e,t){switch(e.type){case"text":return N(e.text??"",e.format);case"linebreak":return`
3
+ `;case"tab":return" ";case"heading":return z(e,t);case"paragraph":return O(e,t);case"link":case"autolink":return w(e,t);case"list":return h(e,t);case"listitem":return o(e,t).trim();case"quote":case"blockquote":return E(e,t);case"horizontalrule":return`---
4
+
5
+ `;case"root":return o(e,t).trim();default:return o(e,t)}}function o(e,t){return(e.children??[]).map(n=>c(n,t)).join("")}function N(e,t=0){if((t&16)===16)return`\`${e}\``;let n=e,i=(t&1)===1,r=(t&2)===2;return i&&r?n=`***${n}***`:i?n=`**${n}**`:r&&(n=`_${n}_`),(t&4)===4&&(n=`~~${n}~~`),(t&8)===8&&(n=`<u>${n}</u>`),n}function z(e,t){let i=(typeof e.tag=="string"?/^h([1-6])$/.exec(e.tag):null)?.[1]??"2",r=o(e,t).trim();return`${"#".repeat(Number(i))} ${r}
6
+
7
+ `}function O(e,t){return`${o(e,t).trim()}
8
+
9
+ `}function w(e,t){let n=o(e,t).trim(),i=I(e,t);return`[${n}](${i})`}function I(e,t){let n=e.fields,i=n?.url??e.url;return n?.linkType==="internal"?t.resolveInternalLink?.({relationTo:n.doc?.relationTo,value:n.doc?.value,url:i})??i??"#":i??"#"}function h(e,t){let n=e.listType==="number"||e.listType==="ordered";return`${(e.children??[]).map((r,g)=>`${n?`${g+1}. `:"- "}${c(r,t).trim()}`).join(`
10
+ `)}
11
+
12
+ `}function E(e,t){return`${o(e,t).trim().split(`
13
+ `).map(i=>`> ${i}`).join(`
14
+ `)}
15
+
16
+ `}function l(e={}){return{enabled:e.enabled??!0,routes:{llmsTxt:e.routes?.llmsTxt??"/llms.txt",markdownSegment:e.routes?.markdownSegment??"md"}}}var u=e=>(l(e),t=>t);0&&(module.exports={buildLlmsTxt,formatLlmsTxtLink,lexicalToMarkdown,normalizeOptions,payloadPluginLlms});
17
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/llms-txt.ts","../src/lexical.ts","../src/options.ts","../src/plugin.ts"],"sourcesContent":["export { buildLlmsTxt, formatLlmsTxtLink } from \"./llms-txt\"\nexport { lexicalToMarkdown } from \"./lexical\"\nexport { normalizeOptions } from \"./options\"\nexport { payloadPluginLlms } from \"./plugin\"\n\nexport type { LexicalToMarkdownOptions, SerializedLexicalNode } from \"./lexical\"\nexport type { LlmsTxtContent, LlmsTxtLink, LlmsTxtSection } from \"./llms-txt\"\nexport type {\n NormalizedPayloadPluginLlmsOptions,\n PayloadPlugin,\n PayloadPluginConfig,\n PayloadPluginLlmsOptions,\n} from \"./types\"\n\nexport { payloadPluginLlms as default } from \"./plugin\"\n","export type LlmsTxtLink = {\n title: string\n url: string\n description?: string | null\n}\n\nexport type LlmsTxtSection = {\n title: string\n content?: string | string[]\n links?: LlmsTxtLink[]\n}\n\nexport type LlmsTxtContent = {\n title?: string\n description?: string\n intro?: string | string[]\n sections?: LlmsTxtSection[]\n footer?: string | string[]\n}\n\nexport function formatLlmsTxtLink(link: LlmsTxtLink): string {\n const line = `- [${link.title}](${link.url})`\n return link.description ? `${line}: ${link.description}` : line\n}\n\nexport function buildLlmsTxt(content: LlmsTxtContent): string {\n const lines: string[] = []\n\n if (content.title) {\n lines.push(`# ${content.title}`, \"\")\n }\n if (content.description) {\n lines.push(`> ${content.description}`, \"\")\n }\n\n appendLines(lines, content.intro)\n\n for (const section of content.sections ?? []) {\n lines.push(`## ${section.title}`, \"\")\n appendLines(lines, section.content, { trailingBlank: false })\n for (const link of section.links ?? []) {\n lines.push(formatLlmsTxtLink(link))\n }\n lines.push(\"\")\n }\n\n appendLines(lines, content.footer, { trailingBlank: false })\n\n return trimBlankEdges(lines).join(\"\\n\")\n}\n\nfunction appendLines(\n lines: string[],\n value: string | string[] | undefined,\n options: { trailingBlank?: boolean } = {},\n) {\n const values = Array.isArray(value) ? value : value ? [value] : []\n if (values.length === 0) return\n\n if (options.trailingBlank ?? true) {\n for (const item of values) {\n lines.push(item, \"\")\n }\n return\n }\n\n for (const item of values) {\n lines.push(item)\n }\n}\n\nfunction trimBlankEdges(lines: string[]) {\n const trimmed = [...lines]\n while (trimmed[0] === \"\") trimmed.shift()\n while (trimmed.at(-1) === \"\") trimmed.pop()\n return trimmed\n}\n","export type SerializedLexicalNode = {\n type?: string\n [key: string]: unknown\n}\n\ntype SerializedElementNode = SerializedLexicalNode & {\n children?: SerializedLexicalNode[]\n}\n\ntype SerializedTextNode = SerializedLexicalNode & {\n type: \"text\"\n text?: string\n format?: number\n}\n\ntype SerializedLinkNode = SerializedElementNode & {\n url?: string\n fields?: {\n linkType?: string\n url?: string\n doc?: {\n relationTo?: string\n value?: unknown\n }\n }\n}\n\nexport type LexicalToMarkdownOptions = {\n resolveInternalLink?: (reference: {\n relationTo?: string\n value?: unknown\n url?: string\n }) => string | null | undefined\n}\n\nconst IS_BOLD = 1\nconst IS_ITALIC = 2\nconst IS_STRIKETHROUGH = 4\nconst IS_UNDERLINE = 8\nconst IS_CODE = 16\n\nexport function lexicalToMarkdown(\n data: { root?: { children?: SerializedLexicalNode[] } },\n options: LexicalToMarkdownOptions = {},\n): string {\n const children = data.root?.children ?? []\n return children.map((node) => nodeToMarkdown(node, options)).join(\"\").trim()\n}\n\nfunction nodeToMarkdown(node: SerializedLexicalNode, options: LexicalToMarkdownOptions): string {\n switch (node.type) {\n case \"text\":\n return formatText((node as SerializedTextNode).text ?? \"\", (node as SerializedTextNode).format)\n case \"linebreak\":\n return \"\\n\"\n case \"tab\":\n return \"\\t\"\n case \"heading\":\n return headingToMarkdown(node as SerializedElementNode, options)\n case \"paragraph\":\n return paragraphToMarkdown(node as SerializedElementNode, options)\n case \"link\":\n case \"autolink\":\n return linkToMarkdown(node as SerializedLinkNode, options)\n case \"list\":\n return listToMarkdown(node as SerializedElementNode & { listType?: string }, options)\n case \"listitem\":\n return childrenToMarkdown(node as SerializedElementNode, options).trim()\n case \"quote\":\n case \"blockquote\":\n return quoteToMarkdown(node as SerializedElementNode, options)\n case \"horizontalrule\":\n return \"---\\n\\n\"\n case \"root\":\n return childrenToMarkdown(node as SerializedElementNode, options).trim()\n default:\n return childrenToMarkdown(node as SerializedElementNode, options)\n }\n}\n\nfunction childrenToMarkdown(\n node: SerializedElementNode,\n options: LexicalToMarkdownOptions,\n): string {\n return (node.children ?? []).map((child) => nodeToMarkdown(child, options)).join(\"\")\n}\n\nfunction formatText(text: string, format = 0): string {\n if ((format & IS_CODE) === IS_CODE) {\n return `\\`${text}\\``\n }\n\n let markdown = text\n const isBold = (format & IS_BOLD) === IS_BOLD\n const isItalic = (format & IS_ITALIC) === IS_ITALIC\n\n if (isBold && isItalic) {\n markdown = `***${markdown}***`\n } else if (isBold) {\n markdown = `**${markdown}**`\n } else if (isItalic) {\n markdown = `_${markdown}_`\n }\n\n if ((format & IS_STRIKETHROUGH) === IS_STRIKETHROUGH) {\n markdown = `~~${markdown}~~`\n }\n\n if ((format & IS_UNDERLINE) === IS_UNDERLINE) {\n markdown = `<u>${markdown}</u>`\n }\n\n return markdown\n}\n\nfunction headingToMarkdown(\n node: SerializedElementNode & { tag?: unknown },\n options: LexicalToMarkdownOptions,\n): string {\n const match = typeof node.tag === \"string\" ? /^h([1-6])$/.exec(node.tag) : null\n const level = match?.[1] ?? \"2\"\n const content = childrenToMarkdown(node, options).trim()\n\n return `${\"#\".repeat(Number(level))} ${content}\\n\\n`\n}\n\nfunction paragraphToMarkdown(\n node: SerializedElementNode,\n options: LexicalToMarkdownOptions,\n): string {\n return `${childrenToMarkdown(node, options).trim()}\\n\\n`\n}\n\nfunction linkToMarkdown(node: SerializedLinkNode, options: LexicalToMarkdownOptions): string {\n const text = childrenToMarkdown(node, options).trim()\n const href = getLinkHref(node, options)\n\n return `[${text}](${href})`\n}\n\nfunction getLinkHref(node: SerializedLinkNode, options: LexicalToMarkdownOptions): string {\n const fields = node.fields\n const fallbackUrl = fields?.url ?? node.url\n\n if (fields?.linkType === \"internal\") {\n const resolved = options.resolveInternalLink?.({\n relationTo: fields.doc?.relationTo,\n value: fields.doc?.value,\n url: fallbackUrl,\n })\n\n return resolved ?? fallbackUrl ?? \"#\"\n }\n\n return fallbackUrl ?? \"#\"\n}\n\nfunction listToMarkdown(\n node: SerializedElementNode & { listType?: string },\n options: LexicalToMarkdownOptions,\n): string {\n const isNumbered = node.listType === \"number\" || node.listType === \"ordered\"\n const items = (node.children ?? []).map((child, index) => {\n const prefix = isNumbered ? `${index + 1}. ` : \"- \"\n return `${prefix}${nodeToMarkdown(child, options).trim()}`\n })\n\n return `${items.join(\"\\n\")}\\n\\n`\n}\n\nfunction quoteToMarkdown(node: SerializedElementNode, options: LexicalToMarkdownOptions): string {\n const content = childrenToMarkdown(node, options)\n .trim()\n .split(\"\\n\")\n .map((line) => `> ${line}`)\n .join(\"\\n\")\n\n return `${content}\\n\\n`\n}\n","import type { NormalizedPayloadPluginLlmsOptions, PayloadPluginLlmsOptions } from \"./types\"\n\nexport function normalizeOptions(\n options: PayloadPluginLlmsOptions = {},\n): NormalizedPayloadPluginLlmsOptions {\n return {\n enabled: options.enabled ?? true,\n routes: {\n llmsTxt: options.routes?.llmsTxt ?? \"/llms.txt\",\n markdownSegment: options.routes?.markdownSegment ?? \"md\",\n },\n }\n}\n","import { normalizeOptions } from \"./options\"\n\nimport type { PayloadPlugin, PayloadPluginLlmsOptions } from \"./types\"\n\nexport const payloadPluginLlms = (options?: PayloadPluginLlmsOptions): PayloadPlugin => {\n normalizeOptions(options)\n\n return (config) => config\n}\n"],"mappings":"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","names":["index_exports","__export","buildLlmsTxt","payloadPluginLlms","formatLlmsTxtLink","lexicalToMarkdown","normalizeOptions","__toCommonJS","formatLlmsTxtLink","link","line","buildLlmsTxt","content","lines","appendLines","section","trimBlankEdges","value","options","values","item","trimmed","lexicalToMarkdown","data","options","node","nodeToMarkdown","formatText","headingToMarkdown","paragraphToMarkdown","linkToMarkdown","listToMarkdown","childrenToMarkdown","quoteToMarkdown","child","text","format","markdown","isBold","isItalic","level","content","href","getLinkHref","fields","fallbackUrl","isNumbered","index","line","normalizeOptions","options","payloadPluginLlms","options","normalizeOptions","config"]}
@@ -0,0 +1,9 @@
1
+ export { buildLlmsTxt, formatLlmsTxtLink } from "./llms-txt";
2
+ export { lexicalToMarkdown } from "./lexical";
3
+ export { normalizeOptions } from "./options";
4
+ export { payloadPluginLlms } from "./plugin";
5
+ export type { LexicalToMarkdownOptions, SerializedLexicalNode } from "./lexical";
6
+ export type { LlmsTxtContent, LlmsTxtLink, LlmsTxtSection } from "./llms-txt";
7
+ export type { NormalizedPayloadPluginLlmsOptions, PayloadPlugin, PayloadPluginConfig, PayloadPluginLlmsOptions, } from "./types";
8
+ export { payloadPluginLlms as default } from "./plugin";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAE5C,YAAY,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAA;AAChF,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC7E,YAAY,EACV,kCAAkC,EAClC,aAAa,EACb,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,SAAS,CAAA;AAEhB,OAAO,EAAE,iBAAiB,IAAI,OAAO,EAAE,MAAM,UAAU,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ import{a as c,b as u}from"./chunk-B5YH4Y5S.js";function m(e,n={}){return(e.root?.children??[]).map(i=>o(i,n)).join("").trim()}function o(e,n){switch(e.type){case"text":return p(e.text??"",e.format);case"linebreak":return`
2
+ `;case"tab":return" ";case"heading":return x(e,n);case"paragraph":return L(e,n);case"link":case"autolink":return g(e,n);case"list":return S(e,n);case"listitem":return l(e,n).trim();case"quote":case"blockquote":return k(e,n);case"horizontalrule":return`---
3
+
4
+ `;case"root":return l(e,n).trim();default:return l(e,n)}}function l(e,n){return(e.children??[]).map(t=>o(t,n)).join("")}function p(e,n=0){if((n&16)===16)return`\`${e}\``;let t=e,i=(n&1)===1,r=(n&2)===2;return i&&r?t=`***${t}***`:i?t=`**${t}**`:r&&(t=`_${t}_`),(n&4)===4&&(t=`~~${t}~~`),(n&8)===8&&(t=`<u>${t}</u>`),t}function x(e,n){let i=(typeof e.tag=="string"?/^h([1-6])$/.exec(e.tag):null)?.[1]??"2",r=l(e,n).trim();return`${"#".repeat(Number(i))} ${r}
5
+
6
+ `}function L(e,n){return`${l(e,n).trim()}
7
+
8
+ `}function g(e,n){let t=l(e,n).trim(),i=T(e,n);return`[${t}](${i})`}function T(e,n){let t=e.fields,i=t?.url??e.url;return t?.linkType==="internal"?n.resolveInternalLink?.({relationTo:t.doc?.relationTo,value:t.doc?.value,url:i})??i??"#":i??"#"}function S(e,n){let t=e.listType==="number"||e.listType==="ordered";return`${(e.children??[]).map((r,d)=>`${t?`${d+1}. `:"- "}${o(r,n).trim()}`).join(`
9
+ `)}
10
+
11
+ `}function k(e,n){return`${l(e,n).trim().split(`
12
+ `).map(i=>`> ${i}`).join(`
13
+ `)}
14
+
15
+ `}function a(e={}){return{enabled:e.enabled??!0,routes:{llmsTxt:e.routes?.llmsTxt??"/llms.txt",markdownSegment:e.routes?.markdownSegment??"md"}}}var s=e=>(a(e),n=>n);export{u as buildLlmsTxt,s as default,c as formatLlmsTxtLink,m as lexicalToMarkdown,a as normalizeOptions,s as payloadPluginLlms};
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lexical.ts","../src/options.ts","../src/plugin.ts"],"sourcesContent":["export type SerializedLexicalNode = {\n type?: string\n [key: string]: unknown\n}\n\ntype SerializedElementNode = SerializedLexicalNode & {\n children?: SerializedLexicalNode[]\n}\n\ntype SerializedTextNode = SerializedLexicalNode & {\n type: \"text\"\n text?: string\n format?: number\n}\n\ntype SerializedLinkNode = SerializedElementNode & {\n url?: string\n fields?: {\n linkType?: string\n url?: string\n doc?: {\n relationTo?: string\n value?: unknown\n }\n }\n}\n\nexport type LexicalToMarkdownOptions = {\n resolveInternalLink?: (reference: {\n relationTo?: string\n value?: unknown\n url?: string\n }) => string | null | undefined\n}\n\nconst IS_BOLD = 1\nconst IS_ITALIC = 2\nconst IS_STRIKETHROUGH = 4\nconst IS_UNDERLINE = 8\nconst IS_CODE = 16\n\nexport function lexicalToMarkdown(\n data: { root?: { children?: SerializedLexicalNode[] } },\n options: LexicalToMarkdownOptions = {},\n): string {\n const children = data.root?.children ?? []\n return children.map((node) => nodeToMarkdown(node, options)).join(\"\").trim()\n}\n\nfunction nodeToMarkdown(node: SerializedLexicalNode, options: LexicalToMarkdownOptions): string {\n switch (node.type) {\n case \"text\":\n return formatText((node as SerializedTextNode).text ?? \"\", (node as SerializedTextNode).format)\n case \"linebreak\":\n return \"\\n\"\n case \"tab\":\n return \"\\t\"\n case \"heading\":\n return headingToMarkdown(node as SerializedElementNode, options)\n case \"paragraph\":\n return paragraphToMarkdown(node as SerializedElementNode, options)\n case \"link\":\n case \"autolink\":\n return linkToMarkdown(node as SerializedLinkNode, options)\n case \"list\":\n return listToMarkdown(node as SerializedElementNode & { listType?: string }, options)\n case \"listitem\":\n return childrenToMarkdown(node as SerializedElementNode, options).trim()\n case \"quote\":\n case \"blockquote\":\n return quoteToMarkdown(node as SerializedElementNode, options)\n case \"horizontalrule\":\n return \"---\\n\\n\"\n case \"root\":\n return childrenToMarkdown(node as SerializedElementNode, options).trim()\n default:\n return childrenToMarkdown(node as SerializedElementNode, options)\n }\n}\n\nfunction childrenToMarkdown(\n node: SerializedElementNode,\n options: LexicalToMarkdownOptions,\n): string {\n return (node.children ?? []).map((child) => nodeToMarkdown(child, options)).join(\"\")\n}\n\nfunction formatText(text: string, format = 0): string {\n if ((format & IS_CODE) === IS_CODE) {\n return `\\`${text}\\``\n }\n\n let markdown = text\n const isBold = (format & IS_BOLD) === IS_BOLD\n const isItalic = (format & IS_ITALIC) === IS_ITALIC\n\n if (isBold && isItalic) {\n markdown = `***${markdown}***`\n } else if (isBold) {\n markdown = `**${markdown}**`\n } else if (isItalic) {\n markdown = `_${markdown}_`\n }\n\n if ((format & IS_STRIKETHROUGH) === IS_STRIKETHROUGH) {\n markdown = `~~${markdown}~~`\n }\n\n if ((format & IS_UNDERLINE) === IS_UNDERLINE) {\n markdown = `<u>${markdown}</u>`\n }\n\n return markdown\n}\n\nfunction headingToMarkdown(\n node: SerializedElementNode & { tag?: unknown },\n options: LexicalToMarkdownOptions,\n): string {\n const match = typeof node.tag === \"string\" ? /^h([1-6])$/.exec(node.tag) : null\n const level = match?.[1] ?? \"2\"\n const content = childrenToMarkdown(node, options).trim()\n\n return `${\"#\".repeat(Number(level))} ${content}\\n\\n`\n}\n\nfunction paragraphToMarkdown(\n node: SerializedElementNode,\n options: LexicalToMarkdownOptions,\n): string {\n return `${childrenToMarkdown(node, options).trim()}\\n\\n`\n}\n\nfunction linkToMarkdown(node: SerializedLinkNode, options: LexicalToMarkdownOptions): string {\n const text = childrenToMarkdown(node, options).trim()\n const href = getLinkHref(node, options)\n\n return `[${text}](${href})`\n}\n\nfunction getLinkHref(node: SerializedLinkNode, options: LexicalToMarkdownOptions): string {\n const fields = node.fields\n const fallbackUrl = fields?.url ?? node.url\n\n if (fields?.linkType === \"internal\") {\n const resolved = options.resolveInternalLink?.({\n relationTo: fields.doc?.relationTo,\n value: fields.doc?.value,\n url: fallbackUrl,\n })\n\n return resolved ?? fallbackUrl ?? \"#\"\n }\n\n return fallbackUrl ?? \"#\"\n}\n\nfunction listToMarkdown(\n node: SerializedElementNode & { listType?: string },\n options: LexicalToMarkdownOptions,\n): string {\n const isNumbered = node.listType === \"number\" || node.listType === \"ordered\"\n const items = (node.children ?? []).map((child, index) => {\n const prefix = isNumbered ? `${index + 1}. ` : \"- \"\n return `${prefix}${nodeToMarkdown(child, options).trim()}`\n })\n\n return `${items.join(\"\\n\")}\\n\\n`\n}\n\nfunction quoteToMarkdown(node: SerializedElementNode, options: LexicalToMarkdownOptions): string {\n const content = childrenToMarkdown(node, options)\n .trim()\n .split(\"\\n\")\n .map((line) => `> ${line}`)\n .join(\"\\n\")\n\n return `${content}\\n\\n`\n}\n","import type { NormalizedPayloadPluginLlmsOptions, PayloadPluginLlmsOptions } from \"./types\"\n\nexport function normalizeOptions(\n options: PayloadPluginLlmsOptions = {},\n): NormalizedPayloadPluginLlmsOptions {\n return {\n enabled: options.enabled ?? true,\n routes: {\n llmsTxt: options.routes?.llmsTxt ?? \"/llms.txt\",\n markdownSegment: options.routes?.markdownSegment ?? \"md\",\n },\n }\n}\n","import { normalizeOptions } from \"./options\"\n\nimport type { PayloadPlugin, PayloadPluginLlmsOptions } from \"./types\"\n\nexport const payloadPluginLlms = (options?: PayloadPluginLlmsOptions): PayloadPlugin => {\n normalizeOptions(options)\n\n return (config) => config\n}\n"],"mappings":"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","names":["lexicalToMarkdown","data","options","node","nodeToMarkdown","formatText","headingToMarkdown","paragraphToMarkdown","linkToMarkdown","listToMarkdown","childrenToMarkdown","quoteToMarkdown","child","text","format","markdown","isBold","isItalic","level","content","href","getLinkHref","fields","fallbackUrl","isNumbered","index","line","normalizeOptions","options","payloadPluginLlms","options","normalizeOptions","config"]}
@@ -0,0 +1,17 @@
1
+ export type SerializedLexicalNode = {
2
+ type?: string;
3
+ [key: string]: unknown;
4
+ };
5
+ export type LexicalToMarkdownOptions = {
6
+ resolveInternalLink?: (reference: {
7
+ relationTo?: string;
8
+ value?: unknown;
9
+ url?: string;
10
+ }) => string | null | undefined;
11
+ };
12
+ export declare function lexicalToMarkdown(data: {
13
+ root?: {
14
+ children?: SerializedLexicalNode[];
15
+ };
16
+ }, options?: LexicalToMarkdownOptions): string;
17
+ //# sourceMappingURL=lexical.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lexical.d.ts","sourceRoot":"","sources":["../src/lexical.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB,CAAA;AAwBD,MAAM,MAAM,wBAAwB,GAAG;IACrC,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE;QAChC,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,KAAK,CAAC,EAAE,OAAO,CAAA;QACf,GAAG,CAAC,EAAE,MAAM,CAAA;KACb,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;CAChC,CAAA;AAQD,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,qBAAqB,EAAE,CAAA;KAAE,CAAA;CAAE,EACvD,OAAO,GAAE,wBAA6B,GACrC,MAAM,CAGR"}
@@ -0,0 +1,20 @@
1
+ export type LlmsTxtLink = {
2
+ title: string;
3
+ url: string;
4
+ description?: string | null;
5
+ };
6
+ export type LlmsTxtSection = {
7
+ title: string;
8
+ content?: string | string[];
9
+ links?: LlmsTxtLink[];
10
+ };
11
+ export type LlmsTxtContent = {
12
+ title?: string;
13
+ description?: string;
14
+ intro?: string | string[];
15
+ sections?: LlmsTxtSection[];
16
+ footer?: string | string[];
17
+ };
18
+ export declare function formatLlmsTxtLink(link: LlmsTxtLink): string;
19
+ export declare function buildLlmsTxt(content: LlmsTxtContent): string;
20
+ //# sourceMappingURL=llms-txt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llms-txt.d.ts","sourceRoot":"","sources":["../src/llms-txt.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC3B,KAAK,CAAC,EAAE,WAAW,EAAE,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACzB,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAA;IAC3B,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAC3B,CAAA;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAG3D;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAwB5D"}
@@ -0,0 +1,10 @@
1
+ export declare const DEFAULT_MARKDOWN_HEADERS: {
2
+ "Content-Type": string;
3
+ };
4
+ export declare const DEFAULT_LLMS_TXT_HEADERS: {
5
+ "Content-Type": string;
6
+ "Cache-Control": string;
7
+ };
8
+ export declare function isMarkdownAccepted(accept: string | null | undefined): boolean;
9
+ export declare function mergeHeaders(defaults: HeadersInit, overrides?: HeadersInit): Headers;
10
+ //# sourceMappingURL=headers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../../src/next/headers.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,wBAAwB;;CAEd,CAAA;AAEvB,eAAO,MAAM,wBAAwB;;;CAGd,CAAA;AAEvB,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAW7E;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,WAAW,GAAG,OAAO,CASpF"}
@@ -0,0 +1,3 @@
1
+ "use strict";var p=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var H=Object.prototype.hasOwnProperty;var P=(e,t)=>{for(var r in t)p(e,r,{get:t[r],enumerable:!0})},S=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of C(t))!H.call(e,o)&&o!==r&&p(e,o,{get:()=>t[o],enumerable:!(n=y(t,o))||n.enumerable});return e};var A=e=>S(p({},"__esModule",{value:!0}),e);var _={};P(_,{DEFAULT_LLMS_TXT_HEADERS:()=>l,DEFAULT_MARKDOWN_HEADERS:()=>u,createLlmsTxtRoute:()=>k,createMarkdownResponse:()=>f,createMarkdownRewrites:()=>L,createMarkdownRoute:()=>h,isMarkdownAccepted:()=>g,mergeHeaders:()=>i});module.exports=A(_);var u={"Content-Type":"text/markdown; charset=utf-8"},l={"Content-Type":"text/plain; charset=utf-8","Cache-Control":"public, max-age=3600, s-maxage=86400"};function g(e){return(e??"").split(",").some(t=>{let[r="",...n]=t.split(";").map(a=>a.trim());if(r.toLowerCase()!=="text/markdown")return!1;let o=n.find(a=>/^q\s*=/i.test(a));if(!o)return!0;let[,s=""]=o.split("=");return Number.parseFloat(s.trim())>0})}function i(e,t){let r=new Headers(e);return t&&new Headers(t).forEach((o,s)=>{r.set(s,o)}),r}function E(e){let t=`- [${e.title}](${e.url})`;return e.description?`${t}: ${e.description}`:t}function R(e){let t=[];e.title&&t.push(`# ${e.title}`,""),e.description&&t.push(`> ${e.description}`,""),w(t,e.intro);for(let r of e.sections??[]){t.push(`## ${r.title}`,""),w(t,r.content,{trailingBlank:!1});for(let n of r.links??[])t.push(E(n));t.push("")}return w(t,e.footer,{trailingBlank:!1}),b(t).join(`
2
+ `)}function w(e,t,r={}){let n=Array.isArray(t)?t:t?[t]:[];if(n.length!==0){if(r.trailingBlank??!0){for(let o of n)e.push(o,"");return}for(let o of n)e.push(o)}}function b(e){let t=[...e];for(;t[0]==="";)t.shift();for(;t.at(-1)==="";)t.pop();return t}function k(e){return async function(r){let n={request:r},o=await e.loadContent(n),s=e.beforeBuild?await e.beforeBuild(o,n):o,a=R(s),c=e.afterBuild?await e.afterBuild(a,n):a,d=typeof e.headers=="function"?await e.headers(s,n):e.headers;return new Response(c,{headers:i(l,d)})}}function f(e,t={}){return new Response(e,{headers:i(u,t.headers)})}function h(e){let t=new Set(e.locales);return async function(n,o){let s=await o.params;if(!t.has(s.locale))return M(e);let a=await D(e.draftMode),c=F(new URL(n.url).searchParams,e.searchParams),d={locale:s.locale,slug:s.slug,draft:a,searchParams:c,request:n},m=await e.getMarkdown(d);if(m===null)return M(e);let x=e.beforeResponse?await e.beforeResponse(m,d):m,T=typeof e.headers=="function"?await e.headers(x,d):e.headers;return f(x,{headers:T})}}function M(e){return new Response(e.notFoundBody??"Not Found",{status:e.notFoundStatus??404})}async function D(e){if(!e)return!1;let t=typeof e=="function"?await e():e;return typeof t=="boolean"?t:t.isEnabled}function F(e,t){if(!t)return{};if(typeof t=="function")return t(e);let r={};for(let n of t){let o=e.get(n);o&&(r[n]=o)}return r}function L(e){let t=e.markdownSegment??"md",r=e.locales.map(O).join("|"),n=e.has??[{type:"header",key:"accept",value:e.acceptHeaderPattern??"(.*)text/markdown(.*)"}],o=[{source:`/:locale(${r})/:path*`,destination:`/:locale/${t}/:path*`,has:n}];return(e.includeIndexRewrite??!0)&&o.push({source:`/:locale(${r})`,destination:`/:locale/${t}`,has:n}),o}function O(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}0&&(module.exports={DEFAULT_LLMS_TXT_HEADERS,DEFAULT_MARKDOWN_HEADERS,createLlmsTxtRoute,createMarkdownResponse,createMarkdownRewrites,createMarkdownRoute,isMarkdownAccepted,mergeHeaders});
3
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/next/index.ts","../../src/next/headers.ts","../../src/llms-txt.ts","../../src/next/llms-route.ts","../../src/next/markdown-route.ts","../../src/next/rewrites.ts"],"sourcesContent":["export {\n DEFAULT_LLMS_TXT_HEADERS,\n DEFAULT_MARKDOWN_HEADERS,\n isMarkdownAccepted,\n mergeHeaders,\n} from \"./headers\"\nexport { createLlmsTxtRoute } from \"./llms-route\"\nexport type { CreateLlmsTxtRouteOptions, LlmsTxtRouteContext } from \"./llms-route\"\nexport { createMarkdownResponse, createMarkdownRoute } from \"./markdown-route\"\nexport type {\n CreateMarkdownRouteOptions,\n MarkdownRouteContext,\n MarkdownRouteGetMarkdownArgs,\n MarkdownRouteParams,\n MarkdownSearchParamsMapper,\n} from \"./markdown-route\"\nexport { createMarkdownRewrites } from \"./rewrites\"\nexport type {\n CreateMarkdownRewritesOptions,\n MarkdownRewrite,\n MarkdownRewriteHasCondition,\n} from \"./rewrites\"\nexport type { HeaderResolver, HeadersInput } from \"./types\"\n","export const DEFAULT_MARKDOWN_HEADERS = {\n \"Content-Type\": \"text/markdown; charset=utf-8\",\n} satisfies HeadersInit\n\nexport const DEFAULT_LLMS_TXT_HEADERS = {\n \"Content-Type\": \"text/plain; charset=utf-8\",\n \"Cache-Control\": \"public, max-age=3600, s-maxage=86400\",\n} satisfies HeadersInit\n\nexport function isMarkdownAccepted(accept: string | null | undefined): boolean {\n return (accept ?? \"\").split(\",\").some((range) => {\n const [mediaType = \"\", ...parameters] = range.split(\";\").map((part) => part.trim())\n if (mediaType.toLowerCase() !== \"text/markdown\") return false\n\n const qParameter = parameters.find((parameter) => /^q\\s*=/i.test(parameter))\n if (!qParameter) return true\n\n const [, value = \"\"] = qParameter.split(\"=\")\n return Number.parseFloat(value.trim()) > 0\n })\n}\n\nexport function mergeHeaders(defaults: HeadersInit, overrides?: HeadersInit): Headers {\n const headers = new Headers(defaults)\n if (!overrides) return headers\n\n const overrideHeaders = new Headers(overrides)\n overrideHeaders.forEach((value, key) => {\n headers.set(key, value)\n })\n return headers\n}\n","export type LlmsTxtLink = {\n title: string\n url: string\n description?: string | null\n}\n\nexport type LlmsTxtSection = {\n title: string\n content?: string | string[]\n links?: LlmsTxtLink[]\n}\n\nexport type LlmsTxtContent = {\n title?: string\n description?: string\n intro?: string | string[]\n sections?: LlmsTxtSection[]\n footer?: string | string[]\n}\n\nexport function formatLlmsTxtLink(link: LlmsTxtLink): string {\n const line = `- [${link.title}](${link.url})`\n return link.description ? `${line}: ${link.description}` : line\n}\n\nexport function buildLlmsTxt(content: LlmsTxtContent): string {\n const lines: string[] = []\n\n if (content.title) {\n lines.push(`# ${content.title}`, \"\")\n }\n if (content.description) {\n lines.push(`> ${content.description}`, \"\")\n }\n\n appendLines(lines, content.intro)\n\n for (const section of content.sections ?? []) {\n lines.push(`## ${section.title}`, \"\")\n appendLines(lines, section.content, { trailingBlank: false })\n for (const link of section.links ?? []) {\n lines.push(formatLlmsTxtLink(link))\n }\n lines.push(\"\")\n }\n\n appendLines(lines, content.footer, { trailingBlank: false })\n\n return trimBlankEdges(lines).join(\"\\n\")\n}\n\nfunction appendLines(\n lines: string[],\n value: string | string[] | undefined,\n options: { trailingBlank?: boolean } = {},\n) {\n const values = Array.isArray(value) ? value : value ? [value] : []\n if (values.length === 0) return\n\n if (options.trailingBlank ?? true) {\n for (const item of values) {\n lines.push(item, \"\")\n }\n return\n }\n\n for (const item of values) {\n lines.push(item)\n }\n}\n\nfunction trimBlankEdges(lines: string[]) {\n const trimmed = [...lines]\n while (trimmed[0] === \"\") trimmed.shift()\n while (trimmed.at(-1) === \"\") trimmed.pop()\n return trimmed\n}\n","import { buildLlmsTxt } from \"../llms-txt\"\nimport { DEFAULT_LLMS_TXT_HEADERS, mergeHeaders } from \"./headers\"\n\nimport type { LlmsTxtContent } from \"../llms-txt\"\n\nexport type LlmsTxtRouteContext = {\n request: Request\n}\n\nexport type CreateLlmsTxtRouteOptions = {\n loadContent: (context: LlmsTxtRouteContext) => Promise<LlmsTxtContent> | LlmsTxtContent\n beforeBuild?: (\n content: LlmsTxtContent,\n context: LlmsTxtRouteContext,\n ) => Promise<LlmsTxtContent> | LlmsTxtContent\n afterBuild?: (text: string, context: LlmsTxtRouteContext) => Promise<string> | string\n headers?:\n | HeadersInit\n | ((content: LlmsTxtContent, context: LlmsTxtRouteContext) => HeadersInit | Promise<HeadersInit>)\n}\n\nexport function createLlmsTxtRoute(options: CreateLlmsTxtRouteOptions) {\n return async function GET(request: Request): Promise<Response> {\n const context = { request }\n const loaded = await options.loadContent(context)\n const content = options.beforeBuild ? await options.beforeBuild(loaded, context) : loaded\n const built = buildLlmsTxt(content)\n const text = options.afterBuild ? await options.afterBuild(built, context) : built\n const headerOverrides =\n typeof options.headers === \"function\"\n ? await options.headers(content, context)\n : options.headers\n\n return new Response(text, {\n headers: mergeHeaders(DEFAULT_LLMS_TXT_HEADERS, headerOverrides),\n })\n }\n}\n","import { DEFAULT_MARKDOWN_HEADERS, mergeHeaders } from \"./headers\"\n\nexport function createMarkdownResponse(\n markdown: string,\n options: { headers?: HeadersInit } = {},\n): Response {\n return new Response(markdown, {\n headers: mergeHeaders(DEFAULT_MARKDOWN_HEADERS, options.headers),\n })\n}\n\nexport type MarkdownRouteParams = {\n locale: string\n slug?: string[]\n}\n\nexport type MarkdownRouteContext = {\n params: MarkdownRouteParams | Promise<MarkdownRouteParams>\n}\n\nexport type MarkdownSearchParamsMapper =\n | string[]\n | ((searchParams: URLSearchParams) => Record<string, string>)\n\nexport type MarkdownRouteGetMarkdownArgs = {\n locale: string\n slug?: string[]\n draft: boolean\n searchParams: Record<string, string>\n request: Request\n}\n\ntype DraftModeValue = boolean | { isEnabled: boolean }\n\nexport type CreateMarkdownRouteOptions = {\n locales: readonly string[]\n getMarkdown: (args: MarkdownRouteGetMarkdownArgs) => Promise<string | null> | string | null\n draftMode?: (() => Promise<DraftModeValue> | DraftModeValue) | DraftModeValue\n searchParams?: MarkdownSearchParamsMapper\n notFoundBody?: string\n notFoundStatus?: number\n headers?:\n | HeadersInit\n | ((markdown: string, context: MarkdownRouteGetMarkdownArgs) => HeadersInit | Promise<HeadersInit>)\n beforeResponse?: (\n markdown: string,\n context: MarkdownRouteGetMarkdownArgs,\n ) => Promise<string> | string\n}\n\nexport function createMarkdownRoute(options: CreateMarkdownRouteOptions) {\n const localeSet = new Set(options.locales)\n\n return async function GET(request: Request, context: MarkdownRouteContext): Promise<Response> {\n const params = await context.params\n if (!localeSet.has(params.locale)) {\n return notFound(options)\n }\n\n const draft = await resolveDraft(options.draftMode)\n const searchParams = mapSearchParams(new URL(request.url).searchParams, options.searchParams)\n const routeContext: MarkdownRouteGetMarkdownArgs = {\n locale: params.locale,\n slug: params.slug,\n draft,\n searchParams,\n request,\n }\n\n const markdown = await options.getMarkdown(routeContext)\n if (markdown === null) {\n return notFound(options)\n }\n\n const finalMarkdown = options.beforeResponse\n ? await options.beforeResponse(markdown, routeContext)\n : markdown\n const headers =\n typeof options.headers === \"function\"\n ? await options.headers(finalMarkdown, routeContext)\n : options.headers\n\n return createMarkdownResponse(finalMarkdown, { headers })\n }\n}\n\nfunction notFound(options: Pick<CreateMarkdownRouteOptions, \"notFoundBody\" | \"notFoundStatus\">) {\n return new Response(options.notFoundBody ?? \"Not Found\", {\n status: options.notFoundStatus ?? 404,\n })\n}\n\nasync function resolveDraft(\n draftMode: CreateMarkdownRouteOptions[\"draftMode\"],\n): Promise<boolean> {\n if (!draftMode) return false\n const result = typeof draftMode === \"function\" ? await draftMode() : draftMode\n return typeof result === \"boolean\" ? result : result.isEnabled\n}\n\nfunction mapSearchParams(\n searchParams: URLSearchParams,\n mapper: MarkdownSearchParamsMapper | undefined,\n): Record<string, string> {\n if (!mapper) return {}\n if (typeof mapper === \"function\") return mapper(searchParams)\n\n const result: Record<string, string> = {}\n for (const key of mapper) {\n const value = searchParams.get(key)\n if (value) result[key] = value\n }\n return result\n}\n","export type MarkdownRewriteHasCondition = {\n type: \"header\" | \"host\" | \"cookie\" | \"query\"\n key: string\n value?: string\n}\n\nexport type MarkdownRewrite = {\n source: string\n destination: string\n has?: MarkdownRewriteHasCondition[]\n}\n\nexport type CreateMarkdownRewritesOptions = {\n locales: readonly string[]\n markdownSegment?: string\n acceptHeaderPattern?: string\n includeIndexRewrite?: boolean\n has?: MarkdownRewriteHasCondition[]\n}\n\nexport function createMarkdownRewrites(options: CreateMarkdownRewritesOptions): MarkdownRewrite[] {\n const markdownSegment = options.markdownSegment ?? \"md\"\n const localeSegment = options.locales.map(escapeRegex).join(\"|\")\n const has = options.has ?? [\n {\n type: \"header\",\n key: \"accept\",\n value: options.acceptHeaderPattern ?? \"(.*)text/markdown(.*)\",\n },\n ]\n\n const rewrites: MarkdownRewrite[] = [\n {\n source: `/:locale(${localeSegment})/:path*`,\n destination: `/:locale/${markdownSegment}/:path*`,\n has,\n },\n ]\n\n if (options.includeIndexRewrite ?? true) {\n rewrites.push({\n source: `/:locale(${localeSegment})`,\n destination: `/:locale/${markdownSegment}`,\n has,\n })\n }\n\n return rewrites\n}\n\nfunction escapeRegex(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n}\n"],"mappings":"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","names":["next_exports","__export","DEFAULT_LLMS_TXT_HEADERS","DEFAULT_MARKDOWN_HEADERS","createLlmsTxtRoute","createMarkdownResponse","createMarkdownRewrites","createMarkdownRoute","isMarkdownAccepted","mergeHeaders","__toCommonJS","DEFAULT_MARKDOWN_HEADERS","DEFAULT_LLMS_TXT_HEADERS","isMarkdownAccepted","accept","range","mediaType","parameters","part","qParameter","parameter","value","mergeHeaders","defaults","overrides","headers","key","formatLlmsTxtLink","link","line","buildLlmsTxt","content","lines","appendLines","section","trimBlankEdges","value","options","values","item","trimmed","createLlmsTxtRoute","options","request","context","loaded","content","built","buildLlmsTxt","text","headerOverrides","mergeHeaders","DEFAULT_LLMS_TXT_HEADERS","createMarkdownResponse","markdown","options","mergeHeaders","DEFAULT_MARKDOWN_HEADERS","createMarkdownRoute","localeSet","request","context","params","notFound","draft","resolveDraft","searchParams","mapSearchParams","routeContext","finalMarkdown","headers","draftMode","result","mapper","key","value","createMarkdownRewrites","options","markdownSegment","localeSegment","escapeRegex","has","rewrites","value"]}
@@ -0,0 +1,9 @@
1
+ export { DEFAULT_LLMS_TXT_HEADERS, DEFAULT_MARKDOWN_HEADERS, isMarkdownAccepted, mergeHeaders, } from "./headers";
2
+ export { createLlmsTxtRoute } from "./llms-route";
3
+ export type { CreateLlmsTxtRouteOptions, LlmsTxtRouteContext } from "./llms-route";
4
+ export { createMarkdownResponse, createMarkdownRoute } from "./markdown-route";
5
+ export type { CreateMarkdownRouteOptions, MarkdownRouteContext, MarkdownRouteGetMarkdownArgs, MarkdownRouteParams, MarkdownSearchParamsMapper, } from "./markdown-route";
6
+ export { createMarkdownRewrites } from "./rewrites";
7
+ export type { CreateMarkdownRewritesOptions, MarkdownRewrite, MarkdownRewriteHasCondition, } from "./rewrites";
8
+ export type { HeaderResolver, HeadersInput } from "./types";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,YAAY,GACb,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACjD,YAAY,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAClF,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAC9E,YAAY,EACV,0BAA0B,EAC1B,oBAAoB,EACpB,4BAA4B,EAC5B,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AACnD,YAAY,EACV,6BAA6B,EAC7B,eAAe,EACf,2BAA2B,GAC5B,MAAM,YAAY,CAAA;AACnB,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA"}
@@ -0,0 +1,2 @@
1
+ import{b as p}from"../chunk-B5YH4Y5S.js";var l={"Content-Type":"text/markdown; charset=utf-8"},m={"Content-Type":"text/plain; charset=utf-8","Cache-Control":"public, max-age=3600, s-maxage=86400"};function k(e){return(e??"").split(",").some(t=>{let[o="",...r]=t.split(";").map(s=>s.trim());if(o.toLowerCase()!=="text/markdown")return!1;let n=r.find(s=>/^q\s*=/i.test(s));if(!n)return!0;let[,a=""]=n.split("=");return Number.parseFloat(a.trim())>0})}function i(e,t){let o=new Headers(e);return t&&new Headers(t).forEach((n,a)=>{o.set(a,n)}),o}function M(e){return async function(o){let r={request:o},n=await e.loadContent(r),a=e.beforeBuild?await e.beforeBuild(n,r):n,s=p(a),u=e.afterBuild?await e.afterBuild(s,r):s,d=typeof e.headers=="function"?await e.headers(a,r):e.headers;return new Response(u,{headers:i(m,d)})}}function x(e,t={}){return new Response(e,{headers:i(l,t.headers)})}function g(e){let t=new Set(e.locales);return async function(r,n){let a=await n.params;if(!t.has(a.locale))return R(e);let s=await h(e.draftMode),u=y(new URL(r.url).searchParams,e.searchParams),d={locale:a.locale,slug:a.slug,draft:s,searchParams:u,request:r},c=await e.getMarkdown(d);if(c===null)return R(e);let w=e.beforeResponse?await e.beforeResponse(c,d):c,f=typeof e.headers=="function"?await e.headers(w,d):e.headers;return x(w,{headers:f})}}function R(e){return new Response(e.notFoundBody??"Not Found",{status:e.notFoundStatus??404})}async function h(e){if(!e)return!1;let t=typeof e=="function"?await e():e;return typeof t=="boolean"?t:t.isEnabled}function y(e,t){if(!t)return{};if(typeof t=="function")return t(e);let o={};for(let r of t){let n=e.get(r);n&&(o[r]=n)}return o}function C(e){let t=e.markdownSegment??"md",o=e.locales.map(T).join("|"),r=e.has??[{type:"header",key:"accept",value:e.acceptHeaderPattern??"(.*)text/markdown(.*)"}],n=[{source:`/:locale(${o})/:path*`,destination:`/:locale/${t}/:path*`,has:r}];return(e.includeIndexRewrite??!0)&&n.push({source:`/:locale(${o})`,destination:`/:locale/${t}`,has:r}),n}function T(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}export{m as DEFAULT_LLMS_TXT_HEADERS,l as DEFAULT_MARKDOWN_HEADERS,M as createLlmsTxtRoute,x as createMarkdownResponse,C as createMarkdownRewrites,g as createMarkdownRoute,k as isMarkdownAccepted,i as mergeHeaders};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/next/headers.ts","../../src/next/llms-route.ts","../../src/next/markdown-route.ts","../../src/next/rewrites.ts"],"sourcesContent":["export const DEFAULT_MARKDOWN_HEADERS = {\n \"Content-Type\": \"text/markdown; charset=utf-8\",\n} satisfies HeadersInit\n\nexport const DEFAULT_LLMS_TXT_HEADERS = {\n \"Content-Type\": \"text/plain; charset=utf-8\",\n \"Cache-Control\": \"public, max-age=3600, s-maxage=86400\",\n} satisfies HeadersInit\n\nexport function isMarkdownAccepted(accept: string | null | undefined): boolean {\n return (accept ?? \"\").split(\",\").some((range) => {\n const [mediaType = \"\", ...parameters] = range.split(\";\").map((part) => part.trim())\n if (mediaType.toLowerCase() !== \"text/markdown\") return false\n\n const qParameter = parameters.find((parameter) => /^q\\s*=/i.test(parameter))\n if (!qParameter) return true\n\n const [, value = \"\"] = qParameter.split(\"=\")\n return Number.parseFloat(value.trim()) > 0\n })\n}\n\nexport function mergeHeaders(defaults: HeadersInit, overrides?: HeadersInit): Headers {\n const headers = new Headers(defaults)\n if (!overrides) return headers\n\n const overrideHeaders = new Headers(overrides)\n overrideHeaders.forEach((value, key) => {\n headers.set(key, value)\n })\n return headers\n}\n","import { buildLlmsTxt } from \"../llms-txt\"\nimport { DEFAULT_LLMS_TXT_HEADERS, mergeHeaders } from \"./headers\"\n\nimport type { LlmsTxtContent } from \"../llms-txt\"\n\nexport type LlmsTxtRouteContext = {\n request: Request\n}\n\nexport type CreateLlmsTxtRouteOptions = {\n loadContent: (context: LlmsTxtRouteContext) => Promise<LlmsTxtContent> | LlmsTxtContent\n beforeBuild?: (\n content: LlmsTxtContent,\n context: LlmsTxtRouteContext,\n ) => Promise<LlmsTxtContent> | LlmsTxtContent\n afterBuild?: (text: string, context: LlmsTxtRouteContext) => Promise<string> | string\n headers?:\n | HeadersInit\n | ((content: LlmsTxtContent, context: LlmsTxtRouteContext) => HeadersInit | Promise<HeadersInit>)\n}\n\nexport function createLlmsTxtRoute(options: CreateLlmsTxtRouteOptions) {\n return async function GET(request: Request): Promise<Response> {\n const context = { request }\n const loaded = await options.loadContent(context)\n const content = options.beforeBuild ? await options.beforeBuild(loaded, context) : loaded\n const built = buildLlmsTxt(content)\n const text = options.afterBuild ? await options.afterBuild(built, context) : built\n const headerOverrides =\n typeof options.headers === \"function\"\n ? await options.headers(content, context)\n : options.headers\n\n return new Response(text, {\n headers: mergeHeaders(DEFAULT_LLMS_TXT_HEADERS, headerOverrides),\n })\n }\n}\n","import { DEFAULT_MARKDOWN_HEADERS, mergeHeaders } from \"./headers\"\n\nexport function createMarkdownResponse(\n markdown: string,\n options: { headers?: HeadersInit } = {},\n): Response {\n return new Response(markdown, {\n headers: mergeHeaders(DEFAULT_MARKDOWN_HEADERS, options.headers),\n })\n}\n\nexport type MarkdownRouteParams = {\n locale: string\n slug?: string[]\n}\n\nexport type MarkdownRouteContext = {\n params: MarkdownRouteParams | Promise<MarkdownRouteParams>\n}\n\nexport type MarkdownSearchParamsMapper =\n | string[]\n | ((searchParams: URLSearchParams) => Record<string, string>)\n\nexport type MarkdownRouteGetMarkdownArgs = {\n locale: string\n slug?: string[]\n draft: boolean\n searchParams: Record<string, string>\n request: Request\n}\n\ntype DraftModeValue = boolean | { isEnabled: boolean }\n\nexport type CreateMarkdownRouteOptions = {\n locales: readonly string[]\n getMarkdown: (args: MarkdownRouteGetMarkdownArgs) => Promise<string | null> | string | null\n draftMode?: (() => Promise<DraftModeValue> | DraftModeValue) | DraftModeValue\n searchParams?: MarkdownSearchParamsMapper\n notFoundBody?: string\n notFoundStatus?: number\n headers?:\n | HeadersInit\n | ((markdown: string, context: MarkdownRouteGetMarkdownArgs) => HeadersInit | Promise<HeadersInit>)\n beforeResponse?: (\n markdown: string,\n context: MarkdownRouteGetMarkdownArgs,\n ) => Promise<string> | string\n}\n\nexport function createMarkdownRoute(options: CreateMarkdownRouteOptions) {\n const localeSet = new Set(options.locales)\n\n return async function GET(request: Request, context: MarkdownRouteContext): Promise<Response> {\n const params = await context.params\n if (!localeSet.has(params.locale)) {\n return notFound(options)\n }\n\n const draft = await resolveDraft(options.draftMode)\n const searchParams = mapSearchParams(new URL(request.url).searchParams, options.searchParams)\n const routeContext: MarkdownRouteGetMarkdownArgs = {\n locale: params.locale,\n slug: params.slug,\n draft,\n searchParams,\n request,\n }\n\n const markdown = await options.getMarkdown(routeContext)\n if (markdown === null) {\n return notFound(options)\n }\n\n const finalMarkdown = options.beforeResponse\n ? await options.beforeResponse(markdown, routeContext)\n : markdown\n const headers =\n typeof options.headers === \"function\"\n ? await options.headers(finalMarkdown, routeContext)\n : options.headers\n\n return createMarkdownResponse(finalMarkdown, { headers })\n }\n}\n\nfunction notFound(options: Pick<CreateMarkdownRouteOptions, \"notFoundBody\" | \"notFoundStatus\">) {\n return new Response(options.notFoundBody ?? \"Not Found\", {\n status: options.notFoundStatus ?? 404,\n })\n}\n\nasync function resolveDraft(\n draftMode: CreateMarkdownRouteOptions[\"draftMode\"],\n): Promise<boolean> {\n if (!draftMode) return false\n const result = typeof draftMode === \"function\" ? await draftMode() : draftMode\n return typeof result === \"boolean\" ? result : result.isEnabled\n}\n\nfunction mapSearchParams(\n searchParams: URLSearchParams,\n mapper: MarkdownSearchParamsMapper | undefined,\n): Record<string, string> {\n if (!mapper) return {}\n if (typeof mapper === \"function\") return mapper(searchParams)\n\n const result: Record<string, string> = {}\n for (const key of mapper) {\n const value = searchParams.get(key)\n if (value) result[key] = value\n }\n return result\n}\n","export type MarkdownRewriteHasCondition = {\n type: \"header\" | \"host\" | \"cookie\" | \"query\"\n key: string\n value?: string\n}\n\nexport type MarkdownRewrite = {\n source: string\n destination: string\n has?: MarkdownRewriteHasCondition[]\n}\n\nexport type CreateMarkdownRewritesOptions = {\n locales: readonly string[]\n markdownSegment?: string\n acceptHeaderPattern?: string\n includeIndexRewrite?: boolean\n has?: MarkdownRewriteHasCondition[]\n}\n\nexport function createMarkdownRewrites(options: CreateMarkdownRewritesOptions): MarkdownRewrite[] {\n const markdownSegment = options.markdownSegment ?? \"md\"\n const localeSegment = options.locales.map(escapeRegex).join(\"|\")\n const has = options.has ?? [\n {\n type: \"header\",\n key: \"accept\",\n value: options.acceptHeaderPattern ?? \"(.*)text/markdown(.*)\",\n },\n ]\n\n const rewrites: MarkdownRewrite[] = [\n {\n source: `/:locale(${localeSegment})/:path*`,\n destination: `/:locale/${markdownSegment}/:path*`,\n has,\n },\n ]\n\n if (options.includeIndexRewrite ?? true) {\n rewrites.push({\n source: `/:locale(${localeSegment})`,\n destination: `/:locale/${markdownSegment}`,\n has,\n })\n }\n\n return rewrites\n}\n\nfunction escapeRegex(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n}\n"],"mappings":"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","names":["DEFAULT_MARKDOWN_HEADERS","DEFAULT_LLMS_TXT_HEADERS","isMarkdownAccepted","accept","range","mediaType","parameters","part","qParameter","parameter","value","mergeHeaders","defaults","overrides","headers","key","createLlmsTxtRoute","options","request","context","loaded","content","built","buildLlmsTxt","text","headerOverrides","mergeHeaders","DEFAULT_LLMS_TXT_HEADERS","createMarkdownResponse","markdown","options","mergeHeaders","DEFAULT_MARKDOWN_HEADERS","createMarkdownRoute","localeSet","request","context","params","notFound","draft","resolveDraft","searchParams","mapSearchParams","routeContext","finalMarkdown","headers","draftMode","result","mapper","key","value","createMarkdownRewrites","options","markdownSegment","localeSegment","escapeRegex","has","rewrites","value"]}
@@ -0,0 +1,12 @@
1
+ import type { LlmsTxtContent } from "../llms-txt";
2
+ export type LlmsTxtRouteContext = {
3
+ request: Request;
4
+ };
5
+ export type CreateLlmsTxtRouteOptions = {
6
+ loadContent: (context: LlmsTxtRouteContext) => Promise<LlmsTxtContent> | LlmsTxtContent;
7
+ beforeBuild?: (content: LlmsTxtContent, context: LlmsTxtRouteContext) => Promise<LlmsTxtContent> | LlmsTxtContent;
8
+ afterBuild?: (text: string, context: LlmsTxtRouteContext) => Promise<string> | string;
9
+ headers?: HeadersInit | ((content: LlmsTxtContent, context: LlmsTxtRouteContext) => HeadersInit | Promise<HeadersInit>);
10
+ };
11
+ export declare function createLlmsTxtRoute(options: CreateLlmsTxtRouteOptions): (request: Request) => Promise<Response>;
12
+ //# sourceMappingURL=llms-route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llms-route.d.ts","sourceRoot":"","sources":["../../src/next/llms-route.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,yBAAyB,GAAG;IACtC,WAAW,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,cAAc,CAAC,GAAG,cAAc,CAAA;IACvF,WAAW,CAAC,EAAE,CACZ,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,mBAAmB,KACzB,OAAO,CAAC,cAAc,CAAC,GAAG,cAAc,CAAA;IAC7C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAA;IACrF,OAAO,CAAC,EACJ,WAAW,GACX,CAAC,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,mBAAmB,KAAK,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAA;CACpG,CAAA;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,IACzC,SAAS,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC,CAe/D"}
@@ -0,0 +1,34 @@
1
+ export declare function createMarkdownResponse(markdown: string, options?: {
2
+ headers?: HeadersInit;
3
+ }): Response;
4
+ export type MarkdownRouteParams = {
5
+ locale: string;
6
+ slug?: string[];
7
+ };
8
+ export type MarkdownRouteContext = {
9
+ params: MarkdownRouteParams | Promise<MarkdownRouteParams>;
10
+ };
11
+ export type MarkdownSearchParamsMapper = string[] | ((searchParams: URLSearchParams) => Record<string, string>);
12
+ export type MarkdownRouteGetMarkdownArgs = {
13
+ locale: string;
14
+ slug?: string[];
15
+ draft: boolean;
16
+ searchParams: Record<string, string>;
17
+ request: Request;
18
+ };
19
+ type DraftModeValue = boolean | {
20
+ isEnabled: boolean;
21
+ };
22
+ export type CreateMarkdownRouteOptions = {
23
+ locales: readonly string[];
24
+ getMarkdown: (args: MarkdownRouteGetMarkdownArgs) => Promise<string | null> | string | null;
25
+ draftMode?: (() => Promise<DraftModeValue> | DraftModeValue) | DraftModeValue;
26
+ searchParams?: MarkdownSearchParamsMapper;
27
+ notFoundBody?: string;
28
+ notFoundStatus?: number;
29
+ headers?: HeadersInit | ((markdown: string, context: MarkdownRouteGetMarkdownArgs) => HeadersInit | Promise<HeadersInit>);
30
+ beforeResponse?: (markdown: string, context: MarkdownRouteGetMarkdownArgs) => Promise<string> | string;
31
+ };
32
+ export declare function createMarkdownRoute(options: CreateMarkdownRouteOptions): (request: Request, context: MarkdownRouteContext) => Promise<Response>;
33
+ export {};
34
+ //# sourceMappingURL=markdown-route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-route.d.ts","sourceRoot":"","sources":["../../src/next/markdown-route.ts"],"names":[],"mappings":"AAEA,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,WAAW,CAAA;CAAO,GACtC,QAAQ,CAIV;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;CAC3D,CAAA;AAED,MAAM,MAAM,0BAA0B,GAClC,MAAM,EAAE,GACR,CAAC,CAAC,YAAY,EAAE,eAAe,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;AAE/D,MAAM,MAAM,4BAA4B,GAAG;IACzC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,KAAK,EAAE,OAAO,CAAA;IACd,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACpC,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,KAAK,cAAc,GAAG,OAAO,GAAG;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,CAAA;AAEtD,MAAM,MAAM,0BAA0B,GAAG;IACvC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1B,WAAW,EAAE,CAAC,IAAI,EAAE,4BAA4B,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,CAAA;IAC3F,SAAS,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,cAAc,CAAC,GAAG,cAAc,CAAC,GAAG,cAAc,CAAA;IAC7E,YAAY,CAAC,EAAE,0BAA0B,CAAA;IACzC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,OAAO,CAAC,EACJ,WAAW,GACX,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,4BAA4B,KAAK,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAA;IACrG,cAAc,CAAC,EAAE,CACf,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,4BAA4B,KAClC,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAA;CAC9B,CAAA;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,IAG3C,SAAS,OAAO,EAAE,SAAS,oBAAoB,KAAG,OAAO,CAAC,QAAQ,CAAC,CA+B9F"}
@@ -0,0 +1,19 @@
1
+ export type MarkdownRewriteHasCondition = {
2
+ type: "header" | "host" | "cookie" | "query";
3
+ key: string;
4
+ value?: string;
5
+ };
6
+ export type MarkdownRewrite = {
7
+ source: string;
8
+ destination: string;
9
+ has?: MarkdownRewriteHasCondition[];
10
+ };
11
+ export type CreateMarkdownRewritesOptions = {
12
+ locales: readonly string[];
13
+ markdownSegment?: string;
14
+ acceptHeaderPattern?: string;
15
+ includeIndexRewrite?: boolean;
16
+ has?: MarkdownRewriteHasCondition[];
17
+ };
18
+ export declare function createMarkdownRewrites(options: CreateMarkdownRewritesOptions): MarkdownRewrite[];
19
+ //# sourceMappingURL=rewrites.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rewrites.d.ts","sourceRoot":"","sources":["../../src/next/rewrites.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,2BAA2B,GAAG;IACxC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAA;IAC5C,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;IACnB,GAAG,CAAC,EAAE,2BAA2B,EAAE,CAAA;CACpC,CAAA;AAED,MAAM,MAAM,6BAA6B,GAAG;IAC1C,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,GAAG,CAAC,EAAE,2BAA2B,EAAE,CAAA;CACpC,CAAA;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,6BAA6B,GAAG,eAAe,EAAE,CA4BhG"}
@@ -0,0 +1,3 @@
1
+ export type HeadersInput = HeadersInit | undefined;
2
+ export type HeaderResolver<Context> = HeadersInit | ((context: Context) => HeadersInit | Promise<HeadersInit>) | undefined;
3
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/next/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,SAAS,CAAA;AAElD,MAAM,MAAM,cAAc,CAAC,OAAO,IAC9B,WAAW,GACX,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,GAC1D,SAAS,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { NormalizedPayloadPluginLlmsOptions, PayloadPluginLlmsOptions } from "./types";
2
+ export declare function normalizeOptions(options?: PayloadPluginLlmsOptions): NormalizedPayloadPluginLlmsOptions;
3
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kCAAkC,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAA;AAE3F,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE,wBAA6B,GACrC,kCAAkC,CAQpC"}
@@ -0,0 +1,3 @@
1
+ import type { PayloadPlugin, PayloadPluginLlmsOptions } from "./types";
2
+ export declare const payloadPluginLlms: (options?: PayloadPluginLlmsOptions) => PayloadPlugin;
3
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAA;AAEtE,eAAO,MAAM,iBAAiB,GAAI,UAAU,wBAAwB,KAAG,aAItE,CAAA"}
@@ -0,0 +1,20 @@
1
+ export type PayloadPluginConfig = {
2
+ collections?: unknown[];
3
+ [key: string]: unknown;
4
+ };
5
+ export type PayloadPlugin = (config: PayloadPluginConfig) => PayloadPluginConfig;
6
+ export type PayloadPluginLlmsOptions = {
7
+ enabled?: boolean;
8
+ routes?: {
9
+ llmsTxt?: string;
10
+ markdownSegment?: string;
11
+ };
12
+ };
13
+ export type NormalizedPayloadPluginLlmsOptions = {
14
+ enabled: boolean;
15
+ routes: {
16
+ llmsTxt: string;
17
+ markdownSegment: string;
18
+ };
19
+ };
20
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,CAAC,EAAE,OAAO,EAAE,CAAA;IACvB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,mBAAmB,KAAK,mBAAmB,CAAA;AAEhF,MAAM,MAAM,wBAAwB,GAAG;IACrC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,eAAe,CAAC,EAAE,MAAM,CAAA;KACzB,CAAA;CACF,CAAA;AAED,MAAM,MAAM,kCAAkC,GAAG;IAC/C,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAA;QACf,eAAe,EAAE,MAAM,CAAA;KACxB,CAAA;CACF,CAAA"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "payload-plugin-llms",
3
+ "version": "0.9.0",
4
+ "description": "Payload CMS plugin and Next.js helpers for llms.txt and markdown routes.",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "keywords": [
8
+ "payload",
9
+ "payloadcms",
10
+ "plugin",
11
+ "llms",
12
+ "markdown"
13
+ ],
14
+ "author": "Mattia Dalzocchio <mattia@dalzocch.io>",
15
+ "homepage": "https://github.com/uxio-labs/payload-website-plugins/tree/main/packages/payload-plugin-llms#readme",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/uxio-labs/payload-website-plugins.git",
19
+ "directory": "packages/payload-plugin-llms"
20
+ },
21
+ "bugs": {
22
+ "url": "https://github.com/uxio-labs/payload-website-plugins/issues"
23
+ },
24
+ "main": "./dist/index.cjs",
25
+ "module": "./dist/index.js",
26
+ "types": "./dist/index.d.ts",
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js",
31
+ "require": "./dist/index.cjs"
32
+ },
33
+ "./next": {
34
+ "types": "./dist/next/index.d.ts",
35
+ "import": "./dist/next/index.js",
36
+ "require": "./dist/next/index.cjs"
37
+ }
38
+ },
39
+ "files": [
40
+ "dist",
41
+ "README.md"
42
+ ],
43
+ "scripts": {
44
+ "build": "tsup --config tsup.config.ts --minify && tsc -p tsconfig.build.json --emitDeclarationOnly",
45
+ "dev": "tsup --config tsup.config.ts --watch",
46
+ "test": "vitest run tests/index.test.ts",
47
+ "typecheck": "tsc --noEmit"
48
+ },
49
+ "peerDependencies": {
50
+ "next": ">=15.0.0",
51
+ "payload": ">=3.0.0"
52
+ },
53
+ "peerDependenciesMeta": {
54
+ "next": {
55
+ "optional": true
56
+ }
57
+ },
58
+ "publishConfig": {
59
+ "access": "public"
60
+ }
61
+ }