@seoengine.ai/next-llm-ready 1.0.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/LICENSE +21 -0
- package/README.md +858 -0
- package/dist/api/index.cjs +624 -0
- package/dist/api/index.cjs.map +1 -0
- package/dist/api/index.d.cts +295 -0
- package/dist/api/index.d.ts +295 -0
- package/dist/api/index.js +613 -0
- package/dist/api/index.js.map +1 -0
- package/dist/hooks/index.cjs +619 -0
- package/dist/hooks/index.cjs.map +1 -0
- package/dist/hooks/index.d.cts +257 -0
- package/dist/hooks/index.d.ts +257 -0
- package/dist/hooks/index.js +611 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.cjs +1609 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +850 -0
- package/dist/index.d.ts +850 -0
- package/dist/index.js +1576 -0
- package/dist/index.js.map +1 -0
- package/dist/server/index.cjs +398 -0
- package/dist/server/index.cjs.map +1 -0
- package/dist/server/index.d.cts +134 -0
- package/dist/server/index.d.ts +134 -0
- package/dist/server/index.js +390 -0
- package/dist/server/index.js.map +1 -0
- package/dist/styles.css +855 -0
- package/package.json +118 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/server/generate-llms-txt.ts","../../src/api/llms-txt-handler.ts","../../src/utils/html-to-markdown.ts","../../src/server/generate-markdown.ts","../../src/api/markdown-handler.ts","../../src/api/analytics-handler.ts"],"names":["NextResponse"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * LLMs.txt Generator\n * Generate sitemap-style content listing for AI crawlers\n * Follows the llms.txt specification\n */\n\nimport type { LLMsTxtConfig, LLMsTxtItem } from '../types';\n\n/**\n * Generate llms.txt content\n */\nexport function generateLLMsTxt(config: LLMsTxtConfig): string {\n const parts: string[] = [];\n\n // Header\n parts.push(`# ${config.siteName}`);\n parts.push('');\n\n if (config.siteDescription) {\n parts.push(`> ${config.siteDescription}`);\n parts.push('');\n }\n\n // Custom header text or default\n if (config.headerText) {\n parts.push(config.headerText);\n } else {\n parts.push('This file provides LLM-friendly access to the content on this website.');\n }\n parts.push('');\n\n // Site info\n parts.push('---');\n parts.push(`- **Site URL**: ${config.siteUrl}`);\n parts.push('- **Format**: Append `?llm=1` to any page URL to get markdown');\n parts.push('---');\n parts.push('');\n\n // Content listing\n if (config.content.length > 0) {\n parts.push('## Available Content');\n parts.push('');\n\n for (const item of config.content) {\n const llmUrl = appendQueryParam(item.url, 'llm', '1');\n\n parts.push(`### [${item.title}](${llmUrl})`);\n\n if (item.type) {\n parts.push(`- **Type**: ${item.type}`);\n }\n\n if (item.date) {\n parts.push(`- **Date**: ${item.date}`);\n }\n\n if (item.description) {\n parts.push(`- **Description**: ${item.description}`);\n }\n\n parts.push(`- **Markdown URL**: ${llmUrl}`);\n parts.push('');\n }\n }\n\n // Footer\n parts.push('---');\n parts.push('');\n\n if (config.footerText) {\n parts.push(config.footerText);\n } else {\n parts.push('*Generated by [next-llm-ready](https://seoengine.ai) - Make your content AI-ready*');\n }\n\n return parts.join('\\n');\n}\n\n/**\n * Append query parameter to URL\n */\nfunction appendQueryParam(url: string, key: string, value: string): string {\n const separator = url.includes('?') ? '&' : '?';\n return `${url}${separator}${key}=${value}`;\n}\n\n/**\n * Sort content items by date (newest first)\n */\nexport function sortByDate(items: LLMsTxtItem[]): LLMsTxtItem[] {\n return [...items].sort((a, b) => {\n if (!a.date) return 1;\n if (!b.date) return -1;\n return new Date(b.date).getTime() - new Date(a.date).getTime();\n });\n}\n\n/**\n * Filter content by type\n */\nexport function filterByType(items: LLMsTxtItem[], types: string[]): LLMsTxtItem[] {\n const typeSet = new Set(types.map((t) => t.toLowerCase()));\n return items.filter((item) => !item.type || typeSet.has(item.type.toLowerCase()));\n}\n\n/**\n * Create LLMsTxtItem from minimal data\n */\nexport function createLLMsTxtItem(\n title: string,\n url: string,\n options?: Partial<Omit<LLMsTxtItem, 'title' | 'url'>>\n): LLMsTxtItem {\n return {\n title,\n url,\n ...options,\n };\n}\n","/**\n * LLMs.txt API Route Handler\n * Creates an API route handler for serving /llms.txt\n */\n\nimport { NextRequest, NextResponse } from 'next/server';\nimport type { LLMsTxtConfig, LLMsTxtItem } from '../types';\nimport { generateLLMsTxt } from '../server/generate-llms-txt';\n\nexport interface LLMsTxtHandlerOptions {\n /** Function to get site configuration */\n getSiteConfig: () => Promise<{\n siteName: string;\n siteDescription?: string;\n siteUrl: string;\n }>;\n /** Function to get all content items */\n getContent: () => Promise<LLMsTxtItem[]>;\n /** Cache control header (default: 1 hour) */\n cacheControl?: string;\n /** Custom header text */\n headerText?: string;\n /** Custom footer text */\n footerText?: string;\n}\n\n/**\n * Create an API route handler for /llms.txt\n *\n * @example\n * ```ts\n * // app/llms.txt/route.ts\n * import { createLLMsTxtHandler } from 'next-llm-ready/api';\n *\n * export const GET = createLLMsTxtHandler({\n * getSiteConfig: async () => ({\n * siteName: 'My Site',\n * siteDescription: 'A great website',\n * siteUrl: 'https://example.com',\n * }),\n * getContent: async () => {\n * const posts = await getAllPosts();\n * return posts.map(post => ({\n * title: post.title,\n * url: `https://example.com/blog/${post.slug}`,\n * type: 'post',\n * date: post.date,\n * }));\n * },\n * });\n * ```\n */\nexport function createLLMsTxtHandler(options: LLMsTxtHandlerOptions) {\n return async function handler(request: NextRequest): Promise<NextResponse> {\n try {\n const siteConfig = await options.getSiteConfig();\n const content = await options.getContent();\n\n const config: LLMsTxtConfig = {\n siteName: siteConfig.siteName,\n siteDescription: siteConfig.siteDescription,\n siteUrl: siteConfig.siteUrl,\n content,\n headerText: options.headerText,\n footerText: options.footerText,\n };\n\n const llmsTxt = generateLLMsTxt(config);\n\n return new NextResponse(llmsTxt, {\n status: 200,\n headers: {\n 'Content-Type': 'text/plain; charset=utf-8',\n 'Cache-Control': options.cacheControl || 'public, max-age=3600',\n 'X-Robots-Tag': 'noindex',\n },\n });\n } catch (error) {\n console.error('Error generating llms.txt:', error);\n return new NextResponse('Error generating llms.txt', { status: 500 });\n }\n };\n}\n\n/**\n * Create a Pages Router API handler for /api/llms.txt\n *\n * @example\n * ```ts\n * // pages/api/llms.txt.ts\n * import { createLLMsTxtPageHandler } from 'next-llm-ready/api';\n *\n * export default createLLMsTxtPageHandler({\n * getSiteConfig: async () => ({ ... }),\n * getContent: async () => { ... },\n * });\n * ```\n */\nexport function createLLMsTxtPageHandler(options: LLMsTxtHandlerOptions) {\n return async function handler(\n req: { method?: string },\n res: {\n status: (code: number) => { end: (body?: string) => void; json: (body: unknown) => void };\n setHeader: (name: string, value: string) => void;\n }\n ): Promise<void> {\n if (req.method !== 'GET') {\n res.status(405).end('Method Not Allowed');\n return;\n }\n\n try {\n const siteConfig = await options.getSiteConfig();\n const content = await options.getContent();\n\n const config: LLMsTxtConfig = {\n siteName: siteConfig.siteName,\n siteDescription: siteConfig.siteDescription,\n siteUrl: siteConfig.siteUrl,\n content,\n headerText: options.headerText,\n footerText: options.footerText,\n };\n\n const llmsTxt = generateLLMsTxt(config);\n\n res.setHeader('Content-Type', 'text/plain; charset=utf-8');\n res.setHeader('Cache-Control', options.cacheControl || 'public, max-age=3600');\n res.setHeader('X-Robots-Tag', 'noindex');\n res.status(200).end(llmsTxt);\n } catch (error) {\n console.error('Error generating llms.txt:', error);\n res.status(500).end('Error generating llms.txt');\n }\n };\n}\n","/**\n * HTML to Markdown Converter\n * Converts HTML content to clean markdown format\n */\n\nimport type { HTMLToMarkdownOptions } from '../types';\n\nconst defaultOptions: HTMLToMarkdownOptions = {\n preserveLineBreaks: true,\n convertImages: true,\n convertLinks: true,\n stripScripts: true,\n customHandlers: {},\n};\n\n/**\n * Convert HTML string to Markdown\n */\nexport function htmlToMarkdown(\n html: string,\n options: HTMLToMarkdownOptions = {}\n): string {\n const opts = { ...defaultOptions, ...options };\n\n // Create a temporary DOM element to parse HTML\n if (typeof window === 'undefined') {\n // Server-side: use basic regex conversion\n return serverSideConvert(html, opts);\n }\n\n // Client-side: use DOM parsing\n const doc = new DOMParser().parseFromString(html, 'text/html');\n return convertNode(doc.body, opts);\n}\n\n/**\n * Server-side HTML to Markdown conversion (regex-based)\n */\nfunction serverSideConvert(html: string, opts: HTMLToMarkdownOptions): string {\n let markdown = html;\n\n // Strip scripts and styles\n if (opts.stripScripts) {\n markdown = markdown.replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '');\n markdown = markdown.replace(/<style\\b[^<]*(?:(?!<\\/style>)<[^<]*)*<\\/style>/gi, '');\n }\n\n // Headings\n markdown = markdown.replace(/<h1[^>]*>(.*?)<\\/h1>/gi, '\\n# $1\\n');\n markdown = markdown.replace(/<h2[^>]*>(.*?)<\\/h2>/gi, '\\n## $1\\n');\n markdown = markdown.replace(/<h3[^>]*>(.*?)<\\/h3>/gi, '\\n### $1\\n');\n markdown = markdown.replace(/<h4[^>]*>(.*?)<\\/h4>/gi, '\\n#### $1\\n');\n markdown = markdown.replace(/<h5[^>]*>(.*?)<\\/h5>/gi, '\\n##### $1\\n');\n markdown = markdown.replace(/<h6[^>]*>(.*?)<\\/h6>/gi, '\\n###### $1\\n');\n\n // Bold and italic\n markdown = markdown.replace(/<(strong|b)[^>]*>(.*?)<\\/\\1>/gi, '**$2**');\n markdown = markdown.replace(/<(em|i)[^>]*>(.*?)<\\/\\1>/gi, '*$2*');\n\n // Links\n if (opts.convertLinks) {\n markdown = markdown.replace(/<a[^>]*href=[\"']([^\"']*)[\"'][^>]*>(.*?)<\\/a>/gi, '[$2]($1)');\n }\n\n // Images\n if (opts.convertImages) {\n markdown = markdown.replace(\n /<img[^>]*src=[\"']([^\"']*)[\"'][^>]*alt=[\"']([^\"']*)[\"'][^>]*\\/?>/gi,\n ''\n );\n markdown = markdown.replace(\n /<img[^>]*alt=[\"']([^\"']*)[\"'][^>]*src=[\"']([^\"']*)[\"'][^>]*\\/?>/gi,\n ''\n );\n markdown = markdown.replace(/<img[^>]*src=[\"']([^\"']*)[\"'][^>]*\\/?>/gi, '');\n }\n\n // Lists\n markdown = markdown.replace(/<ul[^>]*>/gi, '\\n');\n markdown = markdown.replace(/<\\/ul>/gi, '\\n');\n markdown = markdown.replace(/<ol[^>]*>/gi, '\\n');\n markdown = markdown.replace(/<\\/ol>/gi, '\\n');\n markdown = markdown.replace(/<li[^>]*>(.*?)<\\/li>/gi, '- $1\\n');\n\n // Blockquotes\n markdown = markdown.replace(/<blockquote[^>]*>(.*?)<\\/blockquote>/gis, (_, content) => {\n return '\\n> ' + content.trim().replace(/\\n/g, '\\n> ') + '\\n';\n });\n\n // Code blocks\n markdown = markdown.replace(/<pre[^>]*><code[^>]*>(.*?)<\\/code><\\/pre>/gis, '\\n```\\n$1\\n```\\n');\n markdown = markdown.replace(/<code[^>]*>(.*?)<\\/code>/gi, '`$1`');\n\n // Paragraphs and line breaks\n markdown = markdown.replace(/<p[^>]*>(.*?)<\\/p>/gis, '\\n$1\\n');\n markdown = markdown.replace(/<br\\s*\\/?>/gi, '\\n');\n\n // Horizontal rules\n markdown = markdown.replace(/<hr[^>]*\\/?>/gi, '\\n---\\n');\n\n // Strip remaining HTML tags\n markdown = markdown.replace(/<[^>]+>/g, '');\n\n // Decode HTML entities\n markdown = decodeHTMLEntities(markdown);\n\n // Clean up whitespace\n markdown = markdown.replace(/\\n{3,}/g, '\\n\\n');\n markdown = markdown.trim();\n\n return markdown;\n}\n\n/**\n * Client-side DOM-based conversion\n */\nfunction convertNode(node: Node, opts: HTMLToMarkdownOptions): string {\n if (node.nodeType === Node.TEXT_NODE) {\n return node.textContent || '';\n }\n\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return '';\n }\n\n const element = node as Element;\n const tagName = element.tagName.toLowerCase();\n\n // Check for custom handler\n if (opts.customHandlers?.[tagName]) {\n return opts.customHandlers[tagName](element);\n }\n\n // Skip scripts and styles\n if (opts.stripScripts && (tagName === 'script' || tagName === 'style')) {\n return '';\n }\n\n const childContent = Array.from(element.childNodes)\n .map((child) => convertNode(child, opts))\n .join('');\n\n switch (tagName) {\n case 'h1':\n return `\\n# ${childContent.trim()}\\n`;\n case 'h2':\n return `\\n## ${childContent.trim()}\\n`;\n case 'h3':\n return `\\n### ${childContent.trim()}\\n`;\n case 'h4':\n return `\\n#### ${childContent.trim()}\\n`;\n case 'h5':\n return `\\n##### ${childContent.trim()}\\n`;\n case 'h6':\n return `\\n###### ${childContent.trim()}\\n`;\n case 'p':\n return `\\n${childContent.trim()}\\n`;\n case 'br':\n return opts.preserveLineBreaks ? '\\n' : ' ';\n case 'strong':\n case 'b':\n return `**${childContent}**`;\n case 'em':\n case 'i':\n return `*${childContent}*`;\n case 'u':\n return `_${childContent}_`;\n case 's':\n case 'strike':\n case 'del':\n return `~~${childContent}~~`;\n case 'a':\n if (opts.convertLinks) {\n const href = element.getAttribute('href') || '';\n return `[${childContent}](${href})`;\n }\n return childContent;\n case 'img':\n if (opts.convertImages) {\n const src = element.getAttribute('src') || '';\n const alt = element.getAttribute('alt') || '';\n return ``;\n }\n return '';\n case 'ul':\n return `\\n${childContent}\\n`;\n case 'ol':\n return `\\n${childContent}\\n`;\n case 'li':\n return `- ${childContent.trim()}\\n`;\n case 'blockquote':\n return `\\n> ${childContent.trim().replace(/\\n/g, '\\n> ')}\\n`;\n case 'pre':\n const codeElement = element.querySelector('code');\n const lang = codeElement?.className.match(/language-(\\w+)/)?.[1] || '';\n const code = codeElement?.textContent || childContent;\n return `\\n\\`\\`\\`${lang}\\n${code.trim()}\\n\\`\\`\\`\\n`;\n case 'code':\n // Check if inside pre\n if (element.parentElement?.tagName.toLowerCase() === 'pre') {\n return childContent;\n }\n return `\\`${childContent}\\``;\n case 'hr':\n return '\\n---\\n';\n case 'table':\n return convertTable(element);\n case 'div':\n case 'section':\n case 'article':\n case 'main':\n case 'aside':\n case 'header':\n case 'footer':\n case 'nav':\n return childContent;\n default:\n return childContent;\n }\n}\n\n/**\n * Convert HTML table to Markdown table\n */\nfunction convertTable(table: Element): string {\n const rows = table.querySelectorAll('tr');\n if (rows.length === 0) return '';\n\n let markdown = '\\n';\n let headerProcessed = false;\n\n rows.forEach((row, index) => {\n const cells = row.querySelectorAll('th, td');\n const rowContent = Array.from(cells)\n .map((cell) => cell.textContent?.trim() || '')\n .join(' | ');\n\n markdown += `| ${rowContent} |\\n`;\n\n // Add separator after header row\n if (!headerProcessed && (row.querySelector('th') || index === 0)) {\n const separator = Array.from(cells)\n .map(() => '---')\n .join(' | ');\n markdown += `| ${separator} |\\n`;\n headerProcessed = true;\n }\n });\n\n return markdown + '\\n';\n}\n\n/**\n * Decode HTML entities\n */\nfunction decodeHTMLEntities(text: string): string {\n const entities: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '"': '\"',\n ''': \"'\",\n ''': \"'\",\n ' ': ' ',\n '—': '—',\n '–': '–',\n '…': '…',\n '©': '©',\n '®': '®',\n '™': '™',\n };\n\n let result = text;\n for (const [entity, char] of Object.entries(entities)) {\n result = result.replace(new RegExp(entity, 'g'), char);\n }\n\n // Decode numeric entities\n result = result.replace(/&#(\\d+);/g, (_, num) => String.fromCharCode(parseInt(num, 10)));\n result = result.replace(/&#x([0-9a-f]+);/gi, (_, hex) =>\n String.fromCharCode(parseInt(hex, 16))\n );\n\n return result;\n}\n\n/**\n * Calculate word count from text\n */\nexport function countWords(text: string): number {\n return text\n .replace(/[^\\w\\s]/g, '')\n .split(/\\s+/)\n .filter((word) => word.length > 0).length;\n}\n\n/**\n * Calculate reading time in minutes\n */\nexport function calculateReadingTime(text: string, wordsPerMinute = 200): number {\n const words = countWords(text);\n return Math.ceil(words / wordsPerMinute);\n}\n\n/**\n * Extract headings from HTML for TOC\n */\nexport function extractHeadings(\n html: string,\n levels: string[] = ['h2', 'h3', 'h4']\n): Array<{ id: string; text: string; level: number }> {\n const headings: Array<{ id: string; text: string; level: number }> = [];\n const levelPattern = levels.join('|');\n const regex = new RegExp(\n `<(${levelPattern})[^>]*(?:id=[\"']([^\"']*)[\"'])?[^>]*>(.*?)<\\\\/\\\\1>`,\n 'gi'\n );\n\n let match;\n let index = 0;\n while ((match = regex.exec(html)) !== null) {\n const level = parseInt(match[1].charAt(1), 10);\n const id = match[2] || `heading-${index}`;\n const text = match[3].replace(/<[^>]+>/g, '').trim();\n\n headings.push({ id, text, level });\n index++;\n }\n\n return headings;\n}\n","/**\n * Server-side Markdown Generation\n * Generate LLM-ready markdown from content\n */\n\nimport type { LLMContent, MarkdownOutput, TOCHeading } from '../types';\nimport { htmlToMarkdown, countWords, calculateReadingTime } from '../utils/html-to-markdown';\n\n/**\n * Generate complete markdown output from LLM content\n */\nexport function generateMarkdown(content: LLMContent): MarkdownOutput {\n const parts: string[] = [];\n\n // Add custom prompt prefix if set\n if (content.promptPrefix?.trim()) {\n parts.push(content.promptPrefix.trim());\n parts.push('');\n }\n\n // Title\n parts.push(`# ${content.title}`);\n parts.push('');\n\n // Excerpt as blockquote\n if (content.excerpt) {\n parts.push(`> ${content.excerpt}`);\n parts.push('');\n }\n\n // Metadata section\n parts.push('---');\n parts.push(`- **Source**: ${content.url}`);\n\n if (content.date) {\n parts.push(`- **Date**: ${content.date}`);\n }\n\n if (content.modifiedDate) {\n parts.push(`- **Modified**: ${content.modifiedDate}`);\n }\n\n if (content.author) {\n parts.push(`- **Author**: ${content.author}`);\n }\n\n if (content.categories?.length) {\n parts.push(`- **Categories**: ${content.categories.join(', ')}`);\n }\n\n if (content.tags?.length) {\n parts.push(`- **Tags**: ${content.tags.join(', ')}`);\n }\n\n if (content.readingTime) {\n parts.push(`- **Reading Time**: ${content.readingTime} min`);\n }\n\n parts.push('---');\n parts.push('');\n\n // Main content (convert HTML to markdown if needed)\n if (content.content) {\n const contentMarkdown = isHTML(content.content)\n ? htmlToMarkdown(content.content)\n : content.content;\n parts.push(contentMarkdown);\n }\n\n const markdown = parts.join('\\n').trim();\n const wordCount = countWords(markdown);\n const readingTime = calculateReadingTime(markdown);\n const headings = extractMarkdownHeadings(markdown);\n\n return {\n markdown,\n wordCount,\n readingTime,\n headings,\n };\n}\n\n/**\n * Generate markdown string only (without metadata)\n */\nexport function generateMarkdownString(content: LLMContent): string {\n return generateMarkdown(content).markdown;\n}\n\n/**\n * Check if string contains HTML\n */\nfunction isHTML(str: string): boolean {\n return /<[a-z][\\s\\S]*>/i.test(str);\n}\n\n/**\n * Extract headings from markdown for TOC\n */\nfunction extractMarkdownHeadings(markdown: string): TOCHeading[] {\n const headings: TOCHeading[] = [];\n const lines = markdown.split('\\n');\n let index = 0;\n\n for (const line of lines) {\n const match = line.match(/^(#{1,6})\\s+(.+)$/);\n if (match) {\n const level = match[1].length;\n const text = match[2].trim();\n const id = generateSlug(text, index);\n\n headings.push({ id, text, level });\n index++;\n }\n }\n\n return headings;\n}\n\n/**\n * Generate URL-friendly slug from text\n */\nfunction generateSlug(text: string, index: number): string {\n const slug = text\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '')\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-+|-+$/g, '');\n\n return slug || `heading-${index}`;\n}\n\n/**\n * Convert LLMContent to plain text (for previews, etc.)\n */\nexport function contentToPlainText(content: LLMContent): string {\n const markdown = generateMarkdownString(content);\n return markdown\n .replace(/^#+\\s+/gm, '') // Remove headings\n .replace(/\\*\\*([^*]+)\\*\\*/g, '$1') // Remove bold\n .replace(/\\*([^*]+)\\*/g, '$1') // Remove italic\n .replace(/`([^`]+)`/g, '$1') // Remove inline code\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1') // Remove links\n .replace(/!\\[([^\\]]*)\\]\\([^)]+\\)/g, '') // Remove images\n .replace(/^[-*+]\\s+/gm, '') // Remove list markers\n .replace(/^>\\s+/gm, '') // Remove blockquotes\n .replace(/^---$/gm, '') // Remove horizontal rules\n .replace(/\\n{2,}/g, '\\n\\n') // Normalize line breaks\n .trim();\n}\n","/**\n * Markdown API Route Handler\n * Serves markdown content for ?llm=1 requests\n */\n\nimport { NextRequest, NextResponse } from 'next/server';\nimport type { LLMContent, MarkdownHandlerOptions } from '../types';\nimport { generateMarkdownString } from '../server/generate-markdown';\n\n/**\n * Create middleware to handle ?llm=1 query parameter\n *\n * @example\n * ```ts\n * // middleware.ts\n * import { withLLMParam } from 'next-llm-ready/api';\n *\n * export default withLLMParam({\n * getContent: async (pathname) => {\n * // Extract slug and fetch content\n * const slug = pathname.split('/').pop();\n * const post = await getPostBySlug(slug);\n * if (!post) return null;\n * return {\n * title: post.title,\n * content: post.content,\n * url: `https://example.com${pathname}`,\n * date: post.date,\n * };\n * },\n * });\n * ```\n */\nexport function withLLMParam(options: MarkdownHandlerOptions) {\n return async function middleware(request: NextRequest): Promise<NextResponse | undefined> {\n const url = new URL(request.url);\n const llmParam = url.searchParams.get('llm');\n\n // Only handle if ?llm=1 is present\n if (llmParam !== '1') {\n return undefined; // Continue to next middleware/page\n }\n\n try {\n const pathname = url.pathname;\n const content = await options.getContent(pathname);\n\n if (!content) {\n return new NextResponse('Content not found', { status: 404 });\n }\n\n const markdown = generateMarkdownString(content);\n\n return new NextResponse(markdown, {\n status: 200,\n headers: {\n 'Content-Type': 'text/markdown; charset=utf-8',\n 'Cache-Control': options.cacheControl || 'public, max-age=3600',\n 'X-Robots-Tag': 'noindex',\n ...(options.cors && {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET',\n }),\n },\n });\n } catch (error) {\n console.error('Error generating markdown:', error);\n return new NextResponse('Error generating markdown', { status: 500 });\n }\n };\n}\n\n/**\n * Create an API route handler for markdown endpoints\n *\n * @example\n * ```ts\n * // app/api/content/[slug]/route.ts\n * import { createMarkdownHandler } from 'next-llm-ready/api';\n *\n * export const GET = createMarkdownHandler({\n * getContent: async (slug) => {\n * const post = await getPostBySlug(slug);\n * if (!post) return null;\n * return {\n * title: post.title,\n * content: post.content,\n * url: `https://example.com/blog/${slug}`,\n * };\n * },\n * });\n * ```\n */\nexport function createMarkdownHandler(\n options: Omit<MarkdownHandlerOptions, 'getContent'> & {\n getContent: (slug: string) => Promise<LLMContent | null>;\n }\n) {\n return async function handler(\n request: NextRequest,\n { params }: { params: { slug?: string } }\n ): Promise<NextResponse> {\n try {\n const slug = params?.slug || '';\n const content = await options.getContent(slug);\n\n if (!content) {\n return new NextResponse('Content not found', {\n status: 404,\n headers: { 'Content-Type': 'text/plain' },\n });\n }\n\n const markdown = generateMarkdownString(content);\n\n return new NextResponse(markdown, {\n status: 200,\n headers: {\n 'Content-Type': 'text/markdown; charset=utf-8',\n 'Cache-Control': options.cacheControl || 'public, max-age=3600',\n 'X-Robots-Tag': 'noindex',\n ...(options.cors && {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET',\n }),\n },\n });\n } catch (error) {\n console.error('Error generating markdown:', error);\n return new NextResponse('Error generating markdown', { status: 500 });\n }\n };\n}\n\n/**\n * Helper to check if request has ?llm=1 parameter\n */\nexport function hasLLMParam(request: NextRequest): boolean {\n const url = new URL(request.url);\n return url.searchParams.get('llm') === '1';\n}\n","/**\n * Analytics API Route Handler\n * Tracks copy/view/download events\n */\n\nimport { NextRequest, NextResponse } from 'next/server';\nimport type { AnalyticsEvent, AnalyticsHandlerOptions, AnalyticsStorageAdapter } from '../types';\n\n/**\n * In-memory analytics storage (for development/testing)\n */\nexport function createInMemoryStorage(): AnalyticsStorageAdapter {\n const events: AnalyticsEvent[] = [];\n\n return {\n save: async (event: AnalyticsEvent) => {\n events.push(event);\n },\n getAll: async () => [...events],\n clear: async () => {\n events.length = 0;\n },\n };\n}\n\n/**\n * Create an API route handler for analytics tracking\n *\n * @example\n * ```ts\n * // app/api/analytics/route.ts\n * import { createAnalyticsHandler, createInMemoryStorage } from 'next-llm-ready/api';\n *\n * const storage = createInMemoryStorage();\n *\n * export const POST = createAnalyticsHandler({\n * storage,\n * rateLimit: 100,\n * });\n *\n * export const GET = async () => {\n * const events = await storage.getAll();\n * return NextResponse.json({ events });\n * };\n * ```\n */\nexport function createAnalyticsHandler(options: AnalyticsHandlerOptions) {\n // Simple rate limiting state\n const requestCounts = new Map<string, { count: number; resetAt: number }>();\n\n return async function handler(request: NextRequest): Promise<NextResponse> {\n // CORS preflight\n if (request.method === 'OPTIONS') {\n return new NextResponse(null, {\n status: 204,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type',\n },\n });\n }\n\n if (request.method !== 'POST') {\n return new NextResponse('Method Not Allowed', { status: 405 });\n }\n\n // Rate limiting\n if (options.rateLimit) {\n const clientIp = request.headers.get('x-forwarded-for') || 'unknown';\n const now = Date.now();\n const windowMs = 60000; // 1 minute window\n\n const clientData = requestCounts.get(clientIp) || { count: 0, resetAt: now + windowMs };\n\n if (now > clientData.resetAt) {\n clientData.count = 0;\n clientData.resetAt = now + windowMs;\n }\n\n clientData.count++;\n requestCounts.set(clientIp, clientData);\n\n if (clientData.count > options.rateLimit) {\n return new NextResponse('Rate limit exceeded', {\n status: 429,\n headers: {\n 'Retry-After': Math.ceil((clientData.resetAt - now) / 1000).toString(),\n },\n });\n }\n }\n\n try {\n const body = await request.json();\n const event: AnalyticsEvent = {\n action: body.action || 'copy',\n contentId: body.contentId,\n url: body.url || request.headers.get('referer'),\n timestamp: new Date().toISOString(),\n metadata: body.metadata,\n };\n\n await options.storage.save(event);\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (options.cors) {\n headers['Access-Control-Allow-Origin'] = '*';\n }\n\n return NextResponse.json({ success: true, event }, { headers });\n } catch (error) {\n console.error('Analytics tracking error:', error);\n return NextResponse.json({ success: false, error: 'Failed to track event' }, { status: 500 });\n }\n };\n}\n\n/**\n * Create a Pages Router API handler for analytics\n */\nexport function createAnalyticsPageHandler(options: AnalyticsHandlerOptions) {\n return async function handler(\n req: {\n method?: string;\n body?: unknown;\n headers?: { [key: string]: string | string[] | undefined };\n },\n res: {\n status: (code: number) => {\n end: (body?: string) => void;\n json: (body: unknown) => void;\n };\n setHeader: (name: string, value: string) => void;\n }\n ): Promise<void> {\n if (req.method !== 'POST') {\n res.status(405).end('Method Not Allowed');\n return;\n }\n\n try {\n const body = req.body as Record<string, unknown>;\n const event: AnalyticsEvent = {\n action: (body?.action as AnalyticsEvent['action']) || 'copy',\n contentId: body?.contentId as string,\n url: (body?.url as string) || (req.headers?.referer as string),\n timestamp: new Date().toISOString(),\n metadata: body?.metadata as Record<string, unknown>,\n };\n\n await options.storage.save(event);\n\n if (options.cors) {\n res.setHeader('Access-Control-Allow-Origin', '*');\n }\n\n res.status(200).json({ success: true, event });\n } catch (error) {\n console.error('Analytics tracking error:', error);\n res.status(500).json({ success: false, error: 'Failed to track event' });\n }\n };\n}\n\n/**\n * Aggregate analytics events by action type\n */\nexport async function aggregateEvents(\n storage: AnalyticsStorageAdapter\n): Promise<Record<string, number>> {\n const events = await storage.getAll();\n const counts: Record<string, number> = {\n copy: 0,\n view: 0,\n download: 0,\n };\n\n for (const event of events) {\n if (event.action in counts) {\n counts[event.action]++;\n }\n }\n\n return counts;\n}\n\n/**\n * Get events for a specific content ID\n */\nexport async function getEventsForContent(\n storage: AnalyticsStorageAdapter,\n contentId: string\n): Promise<AnalyticsEvent[]> {\n const events = await storage.getAll();\n return events.filter((event) => event.contentId === contentId);\n}\n"]}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* next-llm-ready - TypeScript Type Definitions
|
|
5
|
+
* Make your Next.js content AI-ready
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Content metadata for LLM-ready output
|
|
9
|
+
*/
|
|
10
|
+
interface LLMContent {
|
|
11
|
+
/** Page/post title */
|
|
12
|
+
title: string;
|
|
13
|
+
/** Main content (HTML or Markdown) */
|
|
14
|
+
content: string;
|
|
15
|
+
/** Short description/excerpt */
|
|
16
|
+
excerpt?: string;
|
|
17
|
+
/** Canonical URL */
|
|
18
|
+
url: string;
|
|
19
|
+
/** Publication date (ISO 8601) */
|
|
20
|
+
date?: string;
|
|
21
|
+
/** Last modified date (ISO 8601) */
|
|
22
|
+
modifiedDate?: string;
|
|
23
|
+
/** Author name */
|
|
24
|
+
author?: string;
|
|
25
|
+
/** Categories/sections */
|
|
26
|
+
categories?: string[];
|
|
27
|
+
/** Tags/keywords */
|
|
28
|
+
tags?: string[];
|
|
29
|
+
/** Custom prompt prefix for AI context */
|
|
30
|
+
promptPrefix?: string;
|
|
31
|
+
/** Featured image URL */
|
|
32
|
+
image?: string;
|
|
33
|
+
/** Reading time in minutes */
|
|
34
|
+
readingTime?: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Copy action types for analytics
|
|
38
|
+
*/
|
|
39
|
+
type CopyAction = 'copy' | 'view' | 'download';
|
|
40
|
+
/**
|
|
41
|
+
* Analytics event
|
|
42
|
+
*/
|
|
43
|
+
interface AnalyticsEvent {
|
|
44
|
+
/** Event type */
|
|
45
|
+
action: CopyAction;
|
|
46
|
+
/** Page/content identifier */
|
|
47
|
+
contentId?: string;
|
|
48
|
+
/** Page URL */
|
|
49
|
+
url?: string;
|
|
50
|
+
/** Timestamp */
|
|
51
|
+
timestamp?: string;
|
|
52
|
+
/** Additional metadata */
|
|
53
|
+
metadata?: Record<string, unknown>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Custom analytics storage adapter
|
|
57
|
+
*/
|
|
58
|
+
interface AnalyticsStorageAdapter {
|
|
59
|
+
/** Save event */
|
|
60
|
+
save: (event: AnalyticsEvent) => Promise<void>;
|
|
61
|
+
/** Get all events */
|
|
62
|
+
getAll: () => Promise<AnalyticsEvent[]>;
|
|
63
|
+
/** Clear events */
|
|
64
|
+
clear: () => Promise<void>;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Single item in LLMs.txt listing
|
|
68
|
+
*/
|
|
69
|
+
interface LLMsTxtItem {
|
|
70
|
+
/** Content title */
|
|
71
|
+
title: string;
|
|
72
|
+
/** Page URL */
|
|
73
|
+
url: string;
|
|
74
|
+
/** Content type (post, page, etc.) */
|
|
75
|
+
type?: string;
|
|
76
|
+
/** Publication date */
|
|
77
|
+
date?: string;
|
|
78
|
+
/** Short description */
|
|
79
|
+
description?: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Markdown API handler options
|
|
83
|
+
*/
|
|
84
|
+
interface MarkdownHandlerOptions {
|
|
85
|
+
/** Function to fetch content by slug/id */
|
|
86
|
+
getContent: (slug: string) => Promise<LLMContent | null>;
|
|
87
|
+
/** Cache control header value */
|
|
88
|
+
cacheControl?: string;
|
|
89
|
+
/** Enable CORS */
|
|
90
|
+
cors?: boolean;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Analytics API handler options
|
|
94
|
+
*/
|
|
95
|
+
interface AnalyticsHandlerOptions {
|
|
96
|
+
/** Storage adapter */
|
|
97
|
+
storage: AnalyticsStorageAdapter;
|
|
98
|
+
/** Rate limiting (requests per minute) */
|
|
99
|
+
rateLimit?: number;
|
|
100
|
+
/** Enable CORS */
|
|
101
|
+
cors?: boolean;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* LLMs.txt API Route Handler
|
|
106
|
+
* Creates an API route handler for serving /llms.txt
|
|
107
|
+
*/
|
|
108
|
+
|
|
109
|
+
interface LLMsTxtHandlerOptions {
|
|
110
|
+
/** Function to get site configuration */
|
|
111
|
+
getSiteConfig: () => Promise<{
|
|
112
|
+
siteName: string;
|
|
113
|
+
siteDescription?: string;
|
|
114
|
+
siteUrl: string;
|
|
115
|
+
}>;
|
|
116
|
+
/** Function to get all content items */
|
|
117
|
+
getContent: () => Promise<LLMsTxtItem[]>;
|
|
118
|
+
/** Cache control header (default: 1 hour) */
|
|
119
|
+
cacheControl?: string;
|
|
120
|
+
/** Custom header text */
|
|
121
|
+
headerText?: string;
|
|
122
|
+
/** Custom footer text */
|
|
123
|
+
footerText?: string;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Create an API route handler for /llms.txt
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```ts
|
|
130
|
+
* // app/llms.txt/route.ts
|
|
131
|
+
* import { createLLMsTxtHandler } from 'next-llm-ready/api';
|
|
132
|
+
*
|
|
133
|
+
* export const GET = createLLMsTxtHandler({
|
|
134
|
+
* getSiteConfig: async () => ({
|
|
135
|
+
* siteName: 'My Site',
|
|
136
|
+
* siteDescription: 'A great website',
|
|
137
|
+
* siteUrl: 'https://example.com',
|
|
138
|
+
* }),
|
|
139
|
+
* getContent: async () => {
|
|
140
|
+
* const posts = await getAllPosts();
|
|
141
|
+
* return posts.map(post => ({
|
|
142
|
+
* title: post.title,
|
|
143
|
+
* url: `https://example.com/blog/${post.slug}`,
|
|
144
|
+
* type: 'post',
|
|
145
|
+
* date: post.date,
|
|
146
|
+
* }));
|
|
147
|
+
* },
|
|
148
|
+
* });
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
declare function createLLMsTxtHandler(options: LLMsTxtHandlerOptions): (request: NextRequest) => Promise<NextResponse>;
|
|
152
|
+
/**
|
|
153
|
+
* Create a Pages Router API handler for /api/llms.txt
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```ts
|
|
157
|
+
* // pages/api/llms.txt.ts
|
|
158
|
+
* import { createLLMsTxtPageHandler } from 'next-llm-ready/api';
|
|
159
|
+
*
|
|
160
|
+
* export default createLLMsTxtPageHandler({
|
|
161
|
+
* getSiteConfig: async () => ({ ... }),
|
|
162
|
+
* getContent: async () => { ... },
|
|
163
|
+
* });
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
declare function createLLMsTxtPageHandler(options: LLMsTxtHandlerOptions): (req: {
|
|
167
|
+
method?: string;
|
|
168
|
+
}, res: {
|
|
169
|
+
status: (code: number) => {
|
|
170
|
+
end: (body?: string) => void;
|
|
171
|
+
json: (body: unknown) => void;
|
|
172
|
+
};
|
|
173
|
+
setHeader: (name: string, value: string) => void;
|
|
174
|
+
}) => Promise<void>;
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Markdown API Route Handler
|
|
178
|
+
* Serves markdown content for ?llm=1 requests
|
|
179
|
+
*/
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Create middleware to handle ?llm=1 query parameter
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```ts
|
|
186
|
+
* // middleware.ts
|
|
187
|
+
* import { withLLMParam } from 'next-llm-ready/api';
|
|
188
|
+
*
|
|
189
|
+
* export default withLLMParam({
|
|
190
|
+
* getContent: async (pathname) => {
|
|
191
|
+
* // Extract slug and fetch content
|
|
192
|
+
* const slug = pathname.split('/').pop();
|
|
193
|
+
* const post = await getPostBySlug(slug);
|
|
194
|
+
* if (!post) return null;
|
|
195
|
+
* return {
|
|
196
|
+
* title: post.title,
|
|
197
|
+
* content: post.content,
|
|
198
|
+
* url: `https://example.com${pathname}`,
|
|
199
|
+
* date: post.date,
|
|
200
|
+
* };
|
|
201
|
+
* },
|
|
202
|
+
* });
|
|
203
|
+
* ```
|
|
204
|
+
*/
|
|
205
|
+
declare function withLLMParam(options: MarkdownHandlerOptions): (request: NextRequest) => Promise<NextResponse | undefined>;
|
|
206
|
+
/**
|
|
207
|
+
* Create an API route handler for markdown endpoints
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* ```ts
|
|
211
|
+
* // app/api/content/[slug]/route.ts
|
|
212
|
+
* import { createMarkdownHandler } from 'next-llm-ready/api';
|
|
213
|
+
*
|
|
214
|
+
* export const GET = createMarkdownHandler({
|
|
215
|
+
* getContent: async (slug) => {
|
|
216
|
+
* const post = await getPostBySlug(slug);
|
|
217
|
+
* if (!post) return null;
|
|
218
|
+
* return {
|
|
219
|
+
* title: post.title,
|
|
220
|
+
* content: post.content,
|
|
221
|
+
* url: `https://example.com/blog/${slug}`,
|
|
222
|
+
* };
|
|
223
|
+
* },
|
|
224
|
+
* });
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
227
|
+
declare function createMarkdownHandler(options: Omit<MarkdownHandlerOptions, 'getContent'> & {
|
|
228
|
+
getContent: (slug: string) => Promise<LLMContent | null>;
|
|
229
|
+
}): (request: NextRequest, { params }: {
|
|
230
|
+
params: {
|
|
231
|
+
slug?: string;
|
|
232
|
+
};
|
|
233
|
+
}) => Promise<NextResponse>;
|
|
234
|
+
/**
|
|
235
|
+
* Helper to check if request has ?llm=1 parameter
|
|
236
|
+
*/
|
|
237
|
+
declare function hasLLMParam(request: NextRequest): boolean;
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Analytics API Route Handler
|
|
241
|
+
* Tracks copy/view/download events
|
|
242
|
+
*/
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* In-memory analytics storage (for development/testing)
|
|
246
|
+
*/
|
|
247
|
+
declare function createInMemoryStorage(): AnalyticsStorageAdapter;
|
|
248
|
+
/**
|
|
249
|
+
* Create an API route handler for analytics tracking
|
|
250
|
+
*
|
|
251
|
+
* @example
|
|
252
|
+
* ```ts
|
|
253
|
+
* // app/api/analytics/route.ts
|
|
254
|
+
* import { createAnalyticsHandler, createInMemoryStorage } from 'next-llm-ready/api';
|
|
255
|
+
*
|
|
256
|
+
* const storage = createInMemoryStorage();
|
|
257
|
+
*
|
|
258
|
+
* export const POST = createAnalyticsHandler({
|
|
259
|
+
* storage,
|
|
260
|
+
* rateLimit: 100,
|
|
261
|
+
* });
|
|
262
|
+
*
|
|
263
|
+
* export const GET = async () => {
|
|
264
|
+
* const events = await storage.getAll();
|
|
265
|
+
* return NextResponse.json({ events });
|
|
266
|
+
* };
|
|
267
|
+
* ```
|
|
268
|
+
*/
|
|
269
|
+
declare function createAnalyticsHandler(options: AnalyticsHandlerOptions): (request: NextRequest) => Promise<NextResponse>;
|
|
270
|
+
/**
|
|
271
|
+
* Create a Pages Router API handler for analytics
|
|
272
|
+
*/
|
|
273
|
+
declare function createAnalyticsPageHandler(options: AnalyticsHandlerOptions): (req: {
|
|
274
|
+
method?: string;
|
|
275
|
+
body?: unknown;
|
|
276
|
+
headers?: {
|
|
277
|
+
[key: string]: string | string[] | undefined;
|
|
278
|
+
};
|
|
279
|
+
}, res: {
|
|
280
|
+
status: (code: number) => {
|
|
281
|
+
end: (body?: string) => void;
|
|
282
|
+
json: (body: unknown) => void;
|
|
283
|
+
};
|
|
284
|
+
setHeader: (name: string, value: string) => void;
|
|
285
|
+
}) => Promise<void>;
|
|
286
|
+
/**
|
|
287
|
+
* Aggregate analytics events by action type
|
|
288
|
+
*/
|
|
289
|
+
declare function aggregateEvents(storage: AnalyticsStorageAdapter): Promise<Record<string, number>>;
|
|
290
|
+
/**
|
|
291
|
+
* Get events for a specific content ID
|
|
292
|
+
*/
|
|
293
|
+
declare function getEventsForContent(storage: AnalyticsStorageAdapter, contentId: string): Promise<AnalyticsEvent[]>;
|
|
294
|
+
|
|
295
|
+
export { type AnalyticsEvent, type AnalyticsHandlerOptions, type AnalyticsStorageAdapter, type LLMsTxtHandlerOptions, type MarkdownHandlerOptions, aggregateEvents, createAnalyticsHandler, createAnalyticsPageHandler, createInMemoryStorage, createLLMsTxtHandler, createLLMsTxtPageHandler, createMarkdownHandler, getEventsForContent, hasLLMParam, withLLMParam };
|