@f-o-t/content-analysis 1.0.3 → 1.0.6

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.
@@ -0,0 +1,17 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/markdown.ts", "../src/utils.ts", "../src/bad-patterns.ts", "../src/keywords.ts", "../src/readability.ts", "../src/seo.ts", "../src/structure.ts", "../src/index.ts"],
4
+ "sourcesContent": [
5
+ "// @ts-nocheck\nimport type { MarkdownDocument, Node } from \"@f-o-t/markdown\";\nimport { parseToAst } from \"@f-o-t/markdown\";\n\nexport type MarkdownExtract = {\n text: string;\n headings: Array<{ level: number; text: string; index: number }>;\n links: Array<{ href: string; text: string }>;\n images: Array<{ alt: string; src: string }>;\n tables: number;\n paragraphs: string[];\n};\n\nexport function extractFromMarkdown(content: string): MarkdownExtract {\n const ast = parseToAst(content) as MarkdownDocument;\n const headings: MarkdownExtract[\"headings\"] = [];\n const links: MarkdownExtract[\"links\"] = [];\n const images: MarkdownExtract[\"images\"] = [];\n const paragraphs: string[] = [];\n let tables = 0;\n\n const textParts: string[] = [];\n let index = 0;\n\n const walk = (node: Node): void => {\n switch (node.type) {\n case \"heading\": {\n const text = collectText(node);\n headings.push({ level: node.level, text, index });\n textParts.push(text);\n index += 1;\n break;\n }\n case \"paragraph\": {\n const text = collectText(node);\n if (text.trim().length > 0) {\n paragraphs.push(text);\n textParts.push(text);\n }\n break;\n }\n case \"link\": {\n const text = collectText(node);\n links.push({ href: node.url, text });\n break;\n }\n case \"image\": {\n images.push({ alt: node.alt ?? \"\", src: node.url });\n break;\n }\n case \"codeBlock\": {\n return;\n }\n case \"codeSpan\": {\n return;\n }\n case \"table\": {\n tables += 1;\n break;\n }\n default:\n break;\n }\n\n if (\"children\" in node && Array.isArray(node.children)) {\n for (const child of node.children) walk(child);\n }\n };\n\n for (const node of ast.children) {\n walk(node);\n }\n\n return {\n text: textParts.join(\"\\n\\n\"),\n headings,\n links,\n images,\n tables,\n paragraphs,\n };\n}\n\nfunction collectText(node: Node): string {\n const parts: string[] = [];\n const walk = (current: Node): void => {\n if (current.type === \"text\") {\n parts.push(current.value);\n }\n if (current.type === \"codeSpan\") {\n return;\n }\n if (\"children\" in current && Array.isArray(current.children)) {\n for (const child of current.children) walk(child);\n }\n };\n walk(node);\n return parts.join(\"\");\n}\n",
6
+ "/**\n * Shared utility functions for content analysis\n */\n\nimport { extractFromMarkdown } from \"./markdown\";\n\n/**\n * Count syllables in a word using a simplified vowel group algorithm\n */\nexport function countSyllables(word: string): number {\n const w = word.toLowerCase();\n if (w.length <= 3) return 1;\n\n const vowelGroups = w.match(/[aeiouy]+/g) || [];\n let count = vowelGroups.length;\n\n // Silent 'e' at the end\n if (w.endsWith(\"e\")) count--;\n\n return Math.max(1, count);\n}\n\n/**\n * Calculate Flesch-Kincaid readability metrics\n */\nexport function calculateFleschKincaid(text: string): {\n readingEase: number;\n gradeLevel: number;\n} {\n const cleanText = text.replace(/[^\\w\\s.!?]/g, \"\");\n const sentences = cleanText.split(/[.!?]+/).filter(Boolean);\n const words = cleanText.split(/\\s+/).filter(Boolean);\n\n if (words.length === 0 || sentences.length === 0) {\n return { readingEase: 0, gradeLevel: 0 };\n }\n\n const totalSyllables = words.reduce(\n (sum, word) => sum + countSyllables(word),\n 0,\n );\n const avgWordsPerSentence = words.length / sentences.length;\n const avgSyllablesPerWord = totalSyllables / words.length;\n\n // Flesch Reading Ease formula\n const readingEase =\n 206.835 - 1.015 * avgWordsPerSentence - 84.6 * avgSyllablesPerWord;\n\n // Flesch-Kincaid Grade Level formula\n const gradeLevel =\n 0.39 * avgWordsPerSentence + 11.8 * avgSyllablesPerWord - 15.59;\n\n return {\n readingEase: Math.max(\n 0,\n Math.min(100, Math.round(readingEase * 10) / 10),\n ),\n gradeLevel: Math.max(0, Math.round(gradeLevel * 10) / 10),\n };\n}\n\n/**\n * Convert reading ease score to human-readable level\n */\nexport function getReadabilityLevel(score: number): string {\n if (score >= 90) return \"Very Easy (5th grade)\";\n if (score >= 80) return \"Easy (6th grade)\";\n if (score >= 70) return \"Fairly Easy (7th grade)\";\n if (score >= 60) return \"Standard (8th-9th grade)\";\n if (score >= 50) return \"Fairly Difficult (10th-12th grade)\";\n if (score >= 30) return \"Difficult (College)\";\n return \"Very Difficult (College Graduate)\";\n}\n\n/**\n * Find all occurrences of a regex pattern with surrounding context\n */\nexport function findOccurrences(regex: RegExp, text: string): string[] {\n const matches: string[] = [];\n const flags = regex.flags.includes(\"g\") ? regex.flags : `${regex.flags}g`;\n const globalRegex = new RegExp(regex.source, flags);\n let match: RegExpExecArray | null = globalRegex.exec(text);\n\n while (match) {\n const start = Math.max(0, match.index - 20);\n const end = Math.min(text.length, match.index + match[0].length + 20);\n const context = text.slice(start, end);\n matches.push(`...${context}...`);\n match = globalRegex.exec(text);\n }\n\n return matches;\n}\n\n/**\n * Extract words from content\n */\nexport function extractWords(content: string): string[] {\n return content.split(/\\s+/).filter(Boolean);\n}\n\n/**\n * Extract plain text from markdown using AST parsing\n */\nexport function extractPlainTextFromMarkdown(content: string): string {\n return extractFromMarkdown(content).text;\n}\n\n/**\n * Tokenize content into normalized terms\n */\nexport function tokenize(content: string): string[] {\n const normalized = content\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n\n if (!normalized) return [];\n return normalized.split(\" \").filter(Boolean);\n}\n\n/**\n * Extract paragraphs from content\n */\nexport function extractParagraphs(content: string): string[] {\n return content.split(/\\n\\n+/).filter(Boolean);\n}\n\n/**\n * Extract headings from markdown content\n */\nexport function extractHeadings(\n content: string,\n): Array<{ level: number; text: string; index: number }> {\n const headingMatches = [...content.matchAll(/^(#{1,6})\\s+(.+)$/gm)];\n const headings: Array<{ level: number; text: string; index: number }> = [];\n\n for (const match of headingMatches) {\n const hashMarks = match[1];\n const headingText = match[2];\n if (hashMarks && headingText) {\n headings.push({\n level: hashMarks.length,\n text: headingText,\n index: match.index ?? 0,\n });\n }\n }\n\n return headings;\n}\n\n/**\n * Clamp score between 0 and 100\n */\nexport function clampScore(score: number): number {\n return Math.max(0, Math.min(100, score));\n}\n\n/**\n * Check if content has a quick answer pattern in the first portion\n */\nexport function hasQuickAnswerPattern(text: string): boolean {\n return (\n /\\*\\*quick\\s*answer\\*\\*|>.*quick.*answer|tl;?dr|em\\s+resumo|resumindo/i.test(\n text,\n ) ||\n /^.*?\\*\\*[^*]+\\*\\*\\s+(?:é|is|are|was|were|significa)\\s/im.test(text) ||\n /^\\|.*\\|.*\\|$/m.test(text)\n );\n}\n\n/**\n * Check if content has a conclusion section\n */\nexport function hasConclusionSection(content: string): boolean {\n return /##\\s*(?:conclus|conclusion|resumo|takeaway|key\\s*takeaway|final|wrapping\\s*up)/i.test(\n content,\n );\n}\n",
7
+ "/**\n * Bad Pattern Detection Module\n * Detects problematic content patterns that hurt quality and SEO\n */\n\nimport type { BadPattern, BadPatternResult } from \"./plugins/types/index\";\nimport { extractParagraphs, extractWords, findOccurrences } from \"./utils\";\n\n/**\n * Analyze content for bad patterns\n */\nexport function analyzeBadPatterns(\n content: string,\n title?: string,\n): BadPatternResult {\n const patterns: BadPattern[] = [];\n\n // 1. Word count mentions\n const wordCountPattern =\n /\\b\\d+\\+?\\s*(?:palavras?|words?)\\b|~\\s*\\d+\\s*(?:palavras?|words?)|word\\s*count|contagem\\s*de\\s*palavras/gi;\n const wordCountMatches = findOccurrences(wordCountPattern, content);\n if (wordCountMatches.length > 0) {\n patterns.push({\n pattern: \"word_count_mention\",\n severity: \"warning\",\n locations: wordCountMatches,\n suggestion:\n \"Remove word count mentions. Readers don't care about article length.\",\n });\n }\n\n // Also check title for word count\n if (title) {\n wordCountPattern.lastIndex = 0;\n const titleWordCountMatch = wordCountPattern.exec(title);\n if (titleWordCountMatch) {\n patterns.push({\n pattern: \"word_count_in_title\",\n severity: \"warning\",\n locations: [`Title: \"${title}\"`],\n suggestion:\n \"Remove word count claims from title. Focus on value, not length.\",\n });\n }\n }\n\n // 2. Meta-commentary\n const metaCommentaryPatterns = [\n /\\b(?:neste\\s+artigo|in\\s+this\\s+(?:article|post|guide))\\b/gi,\n /\\b(?:como\\s+mencionado|as\\s+(?:mentioned|discussed|noted)\\s+(?:above|earlier|before))\\b/gi,\n /\\b(?:vamos\\s+explorar|let'?s\\s+explore|we\\s+will\\s+(?:discuss|explore|cover))\\b/gi,\n /\\b(?:conforme\\s+vimos|as\\s+we\\s+(?:saw|discussed|covered))\\b/gi,\n ];\n\n for (const pattern of metaCommentaryPatterns) {\n const matches = findOccurrences(pattern, content);\n if (matches.length > 0) {\n patterns.push({\n pattern: \"meta_commentary\",\n severity: \"warning\",\n locations: matches,\n suggestion:\n \"Remove meta-commentary. Just deliver the information directly.\",\n });\n }\n }\n\n // 3. Engagement begging\n const engagementPatterns = [\n /\\b(?:não\\s+esqueça\\s+de|don'?t\\s+forget\\s+to)\\s+(?:curtir|like|subscribe|seguir|compartilhar|share)/gi,\n /\\b(?:deixe\\s+(?:um\\s+)?comentário|leave\\s+a\\s+comment|comment\\s+below)/gi,\n /\\b(?:inscreva-se|subscribe|sign\\s+up)\\s+(?:para|to|for)\\s+(?:nossa|my|our|the)\\s+(?:newsletter|canal|channel)/gi,\n /\\b(?:compartilhe\\s+com|share\\s+(?:this|with))\\s+(?:seus\\s+amigos|your\\s+friends)/gi,\n /\\bsmash\\s+(?:that\\s+)?(?:like|subscribe)\\s+button\\b/gi,\n ];\n\n for (const pattern of engagementPatterns) {\n const matches = findOccurrences(pattern, content);\n if (matches.length > 0) {\n patterns.push({\n pattern: \"engagement_begging\",\n severity: \"warning\",\n locations: matches,\n suggestion:\n \"Remove engagement begging. Let quality content earn engagement naturally.\",\n });\n }\n }\n\n // 4. Endless introduction check\n const firstH2Index = content.search(/^##\\s+/m);\n if (firstH2Index > 0) {\n const introText = content.slice(0, firstH2Index);\n const introWords = extractWords(introText).length;\n if (introWords > 150) {\n patterns.push({\n pattern: \"endless_introduction\",\n severity: \"warning\",\n locations: [`Introduction: ~${introWords} words before first H2`],\n suggestion:\n \"Shorten introduction to under 150 words. Get to the point faster.\",\n });\n }\n }\n\n // 5. Vague instructions\n const vaguePatterns = [\n /\\b(?:configure\\s+(?:appropriately|properly|correctly))\\b/gi,\n /\\b(?:set\\s+up\\s+(?:as\\s+needed|accordingly))\\b/gi,\n /\\b(?:adjust\\s+(?:as\\s+necessary|accordingly|as\\s+needed))\\b/gi,\n /\\b(?:use\\s+(?:the\\s+right|appropriate|suitable)\\s+(?:settings|options|values))\\b/gi,\n ];\n\n for (const pattern of vaguePatterns) {\n const matches = findOccurrences(pattern, content);\n if (matches.length > 0) {\n patterns.push({\n pattern: \"vague_instructions\",\n severity: \"warning\",\n locations: matches,\n suggestion:\n \"Be specific. Instead of 'configure appropriately', say exactly what to configure and how.\",\n });\n }\n }\n\n // 6. Clickbait markers\n const clickbaitPatterns = [\n /\\b(?:you\\s+won'?t\\s+believe|você\\s+não\\s+vai\\s+acreditar)\\b/gi,\n /\\b(?:this\\s+one\\s+(?:trick|tip|secret))\\b/gi,\n /\\b(?:AMAZING|INCREDIBLE|MIND-?BLOWING)\\b/g,\n /!!+|\\?!+|!{3,}/g,\n ];\n\n for (const pattern of clickbaitPatterns) {\n const matches = findOccurrences(pattern, content);\n if (matches.length > 0) {\n patterns.push({\n pattern: \"clickbait_markers\",\n severity: \"warning\",\n locations: matches,\n suggestion:\n \"Remove clickbait language. Use accurate, professional language instead.\",\n });\n }\n }\n\n // 7. Filler phrases\n const fillerPatterns = [\n /\\b(?:it\\s+goes\\s+without\\s+saying|vai\\s+sem\\s+dizer)\\b/gi,\n /\\b(?:without\\s+further\\s+ado|sem\\s+mais\\s+delongas)\\b/gi,\n /\\b(?:at\\s+the\\s+end\\s+of\\s+the\\s+day|no\\s+final\\s+das\\s+contas)\\b/gi,\n /\\b(?:in\\s+today'?s\\s+(?:digital\\s+)?(?:landscape|world|age))\\b/gi,\n /\\b(?:(?:as\\s+)?a\\s+matter\\s+of\\s+fact)\\b/gi,\n /\\b(?:needless\\s+to\\s+say|escusado\\s+será\\s+dizer)\\b/gi,\n /\\b(?:in\\s+(?:conclusion|summary)|em\\s+(?:conclusão|resumo))(?:\\s*[,:])\\b/gi,\n ];\n\n for (const pattern of fillerPatterns) {\n const matches = findOccurrences(pattern, content);\n if (matches.length > 0) {\n patterns.push({\n pattern: \"filler_phrases\",\n severity: \"warning\",\n locations: matches,\n suggestion:\n \"Remove filler phrases. They add no value and waste reader's time.\",\n });\n }\n }\n\n // 8. Over-formatting\n const overFormattingPattern =\n /(\\*{1,2}[^*]+\\*{1,2}\\s*){3,}|(_{1,2}[^_]+_{1,2}\\s*){3,}/g;\n const overFormattingMatches = findOccurrences(\n overFormattingPattern,\n content,\n );\n if (overFormattingMatches.length > 0) {\n patterns.push({\n pattern: \"over_formatting\",\n severity: \"warning\",\n locations: overFormattingMatches,\n suggestion:\n \"Reduce consecutive formatting. Use bold/italic sparingly for emphasis.\",\n });\n }\n\n // 9. Wall of text\n const paragraphs = extractParagraphs(content);\n const longParagraphs: string[] = [];\n for (const paragraph of paragraphs) {\n if (paragraph.startsWith(\"```\") || paragraph.startsWith(\"#\")) continue;\n const wordCount = extractWords(paragraph).length;\n if (wordCount > 100) {\n const preview = paragraph.slice(0, 50) + \"...\" + paragraph.slice(-30);\n longParagraphs.push(`~${wordCount} words: \"${preview}\"`);\n }\n }\n if (longParagraphs.length > 0) {\n patterns.push({\n pattern: \"wall_of_text\",\n severity: \"warning\",\n locations: longParagraphs,\n suggestion:\n \"Break up long paragraphs. Keep paragraphs under 100 words for better readability.\",\n });\n }\n\n // 10. Keyword stuffing\n const wordsLower = content.toLowerCase();\n const totalWords = extractWords(content).length;\n const phraseCount: Record<string, number> = {};\n\n const tokens = wordsLower.match(/\\b[a-záàâãéèêíïóôõöúç]{3,}\\b/g) || [];\n for (let i = 0; i < tokens.length - 1; i++) {\n const bigram = `${tokens[i]} ${tokens[i + 1]}`;\n phraseCount[bigram] = (phraseCount[bigram] || 0) + 1;\n }\n\n const stuffedPhrases: string[] = [];\n for (const [phrase, count] of Object.entries(phraseCount)) {\n const density = (count / totalWords) * 100;\n if (density > 3 && count > 5) {\n stuffedPhrases.push(\n `\"${phrase}\" appears ${count} times (${density.toFixed(1)}% density)`,\n );\n }\n }\n if (stuffedPhrases.length > 0) {\n patterns.push({\n pattern: \"keyword_stuffing\",\n severity: \"warning\",\n locations: stuffedPhrases,\n suggestion:\n \"Reduce keyword repetition. Use synonyms and natural language variation.\",\n });\n }\n\n return {\n hasIssues: patterns.length > 0,\n issueCount: patterns.length,\n patterns,\n };\n}\n",
8
+ "/**\n * Keyword Analysis Module\n * Analyzes keyword usage, density, and placement in content\n */\n\nimport { extractFromMarkdown } from \"./markdown\";\nimport type {\n KeywordAnalysisItem,\n KeywordAnalysisResult,\n KeywordInput,\n KeywordMetrics,\n TopKeyword,\n TopPhrase,\n TopTerm,\n} from \"./plugins/types/index\";\nimport { extractWords, tokenize } from \"./utils\";\n\n/**\n * Analyze keyword usage in content\n */\nexport function analyzeKeywords(input: KeywordInput): KeywordAnalysisResult {\n const { content, title, targetKeywords } = input;\n const analysis: KeywordAnalysisItem[] = [];\n const recommendations: string[] = [];\n\n const extracted = extractFromMarkdown(content);\n const words = extractWords(extracted.text);\n const totalWordCount = words.length;\n const uniqueWords = new Set(words.map((w) => w.toLowerCase()));\n const contentLower = extracted.text.toLowerCase();\n const titleLower = title?.toLowerCase() || \"\";\n\n // Extract headings\n const headingsText = extracted.headings\n .map((heading) => heading.text)\n .join(\" \")\n .toLowerCase();\n\n // First and last 100 words\n const first100Words = words.slice(0, 100).join(\" \").toLowerCase();\n const last100Words = words.slice(-100).join(\" \").toLowerCase();\n\n let totalDensity = 0;\n\n for (const keyword of targetKeywords) {\n const keywordLower = keyword.toLowerCase();\n const regex = new RegExp(keywordLower, \"gi\");\n const matches = contentLower.match(regex) || [];\n const count = matches.length;\n const density = totalWordCount > 0 ? (count / totalWordCount) * 100 : 0;\n totalDensity += density;\n\n // Determine locations\n const locations: KeywordAnalysisItem[\"locations\"] = [];\n\n if (titleLower.includes(keywordLower)) {\n locations.push({ type: \"title\" });\n }\n if (headingsText.includes(keywordLower)) {\n locations.push({ type: \"heading\" });\n }\n if (first100Words.includes(keywordLower)) {\n locations.push({ type: \"first100words\" });\n }\n if (last100Words.includes(keywordLower)) {\n locations.push({ type: \"last100words\" });\n }\n\n // Determine status\n let status: KeywordAnalysisItem[\"status\"];\n let suggestion: string | undefined;\n\n if (count === 0) {\n status = \"missing\";\n suggestion = `Add \"${keyword}\" naturally to your content`;\n } else if (density < 0.5) {\n status = \"low\";\n suggestion = `Consider using \"${keyword}\" a few more times`;\n } else if (density > 3) {\n status = \"high\";\n suggestion = `Reduce usage of \"${keyword}\" - it may appear spammy`;\n } else {\n status = \"optimal\";\n }\n\n analysis.push({\n keyword,\n count,\n density: Math.round(density * 100) / 100,\n locations,\n status,\n suggestion,\n });\n }\n\n // Calculate overall score\n let overallScore = 100;\n for (const item of analysis) {\n if (item.status === \"missing\") overallScore -= 15;\n else if (item.status === \"low\") overallScore -= 10;\n else if (item.status === \"high\") overallScore -= 5;\n }\n overallScore = Math.max(0, Math.min(100, overallScore));\n\n // Generate recommendations\n const missingKeywords = analysis.filter((a) => a.status === \"missing\");\n const lowKeywords = analysis.filter((a) => a.status === \"low\");\n const highKeywords = analysis.filter((a) => a.status === \"high\");\n\n if (missingKeywords.length > 0) {\n recommendations.push(\n `Add missing keywords: ${missingKeywords.map((k) => k.keyword).join(\", \")}`,\n );\n }\n if (lowKeywords.length > 0) {\n recommendations.push(\n `Increase usage of: ${lowKeywords.map((k) => k.keyword).join(\", \")}`,\n );\n }\n if (highKeywords.length > 0) {\n recommendations.push(\n `Reduce overused keywords: ${highKeywords.map((k) => k.keyword).join(\", \")}`,\n );\n }\n\n // Top keywords (most used phrases in content)\n const tokenList = tokenize(extracted.text);\n const phraseCount: Record<string, number> = {};\n for (const token of tokenList) {\n phraseCount[token] = (phraseCount[token] || 0) + 1;\n }\n\n const topKeywords: TopKeyword[] = Object.entries(phraseCount)\n .filter(\n ([word]) =>\n word.length > 4 &&\n ![\"that\", \"this\", \"with\", \"from\", \"have\", \"been\"].includes(word),\n )\n .sort(([, a], [, b]) => b - a)\n .slice(0, 10)\n .map(([keyword, count]) => ({\n keyword,\n count,\n density: Math.round((count / totalWordCount) * 10000) / 100,\n }));\n\n const stopwords = new Set([\n \"the\",\n \"and\",\n \"for\",\n \"with\",\n \"that\",\n \"this\",\n \"from\",\n \"have\",\n \"been\",\n \"your\",\n \"you\",\n \"are\",\n \"was\",\n \"were\",\n \"not\",\n \"can\",\n \"will\",\n \"its\",\n \"their\",\n \"about\",\n \"into\",\n \"more\",\n \"than\",\n \"when\",\n \"what\",\n \"which\",\n \"who\",\n \"how\",\n \"why\",\n ]);\n\n const topTerms: TopTerm[] = Object.entries(phraseCount)\n .filter(([term]) => term.length > 3 && !stopwords.has(term))\n .sort(([, a], [, b]) => b - a)\n .slice(0, 10)\n .map(([term, count]) => ({\n term,\n count,\n density: Math.round((count / totalWordCount) * 10000) / 100,\n }));\n\n const bigramCount: Record<string, number> = {};\n for (let index = 0; index < tokenList.length - 1; index += 1) {\n const phrase = `${tokenList[index]} ${tokenList[index + 1]}`;\n bigramCount[phrase] = (bigramCount[phrase] || 0) + 1;\n }\n\n const topPhrases: TopPhrase[] = Object.entries(bigramCount)\n .filter(([phrase]) => phrase.length > 5)\n .sort(([, a], [, b]) => b - a)\n .slice(0, 10)\n .map(([phrase, count]) => ({\n phrase,\n count,\n density: Math.round((count / totalWordCount) * 10000) / 100,\n }));\n\n const metrics: KeywordMetrics = {\n totalWordCount,\n uniqueWordCount: uniqueWords.size,\n avgKeywordDensity:\n targetKeywords.length > 0\n ? Math.round((totalDensity / targetKeywords.length) * 100) / 100\n : 0,\n };\n\n return {\n analysis,\n overallScore,\n topKeywords,\n topTerms,\n topPhrases,\n recommendations,\n metrics,\n };\n}\n",
9
+ "/**\n * Readability Analysis Module\n * Analyzes content readability using Flesch-Kincaid algorithms\n */\n\nimport type {\n ReadabilityMetrics,\n ReadabilityResult,\n TargetAudience,\n TargetScore,\n} from \"./plugins/types/index\";\nimport {\n calculateFleschKincaid,\n countSyllables,\n getReadabilityLevel,\n} from \"./utils\";\n\nconst TARGET_SCORES: Record<TargetAudience, TargetScore> = {\n general: {\n min: 60,\n max: 70,\n description: \"Easy to read for general audience\",\n },\n technical: {\n min: 40,\n max: 60,\n description: \"Technical but accessible\",\n },\n academic: {\n min: 30,\n max: 50,\n description: \"Academic/professional level\",\n },\n casual: {\n min: 70,\n max: 80,\n description: \"Very easy, conversational\",\n },\n};\n\n/**\n * Analyze content readability\n */\nexport function analyzeReadability(\n content: string,\n targetAudience: TargetAudience = \"general\",\n): ReadabilityResult {\n const { readingEase, gradeLevel } = calculateFleschKincaid(content);\n const readabilityLevel = getReadabilityLevel(readingEase);\n\n const targetScore = TARGET_SCORES[targetAudience];\n const isOnTarget =\n readingEase >= targetScore.min && readingEase <= targetScore.max;\n\n // Calculate metrics\n const cleanText = content.replace(/[^\\w\\s.!?]/g, \"\");\n const sentences = cleanText.split(/[.!?]+/).filter(Boolean);\n const words = cleanText.split(/\\s+/).filter(Boolean);\n\n const complexWords = words.filter((w: string) => countSyllables(w) >= 3);\n const totalSyllables = words.reduce(\n (sum: number, word: string) => sum + countSyllables(word),\n 0,\n );\n\n // Generate suggestions\n const suggestions: string[] = [];\n\n if (readingEase < targetScore.min) {\n suggestions.push(\n \"Simplify your language - use shorter words and sentences\",\n );\n\n const avgWordsPerSentence = words.length / sentences.length;\n if (avgWordsPerSentence > 20) {\n suggestions.push(\n `Average sentence length is ${Math.round(avgWordsPerSentence)} words. Try to keep it under 20.`,\n );\n }\n\n if (complexWords.length / words.length > 0.2) {\n suggestions.push(\n \"Too many complex words (3+ syllables). Replace with simpler alternatives.\",\n );\n }\n\n suggestions.push(\"Break long sentences into shorter ones\");\n suggestions.push(\"Use active voice instead of passive voice\");\n } else if (readingEase > targetScore.max && targetAudience !== \"casual\") {\n suggestions.push(\"Content may be too simple for your target audience\");\n suggestions.push(\"Consider adding more technical depth or detail\");\n }\n\n if (sentences.some((s) => s.split(/\\s+/).length > 40)) {\n suggestions.push(\n \"Some sentences are very long. Consider breaking them up.\",\n );\n }\n\n const metrics: ReadabilityMetrics = {\n sentenceCount: sentences.length,\n wordCount: words.length,\n avgWordsPerSentence:\n sentences.length > 0\n ? Math.round((words.length / sentences.length) * 10) / 10\n : 0,\n avgSyllablesPerWord:\n words.length > 0\n ? Math.round((totalSyllables / words.length) * 100) / 100\n : 0,\n complexWordCount: complexWords.length,\n complexWordPercentage:\n words.length > 0\n ? Math.round((complexWords.length / words.length) * 1000) / 10\n : 0,\n };\n\n return {\n fleschKincaidReadingEase: readingEase,\n fleschKincaidGradeLevel: gradeLevel,\n readabilityLevel,\n targetScore,\n isOnTarget,\n suggestions,\n metrics,\n };\n}\n",
10
+ "/**\n * SEO Analysis Module\n * Analyzes content for search engine optimization factors\n */\n\nimport { extractFromMarkdown } from \"./markdown\";\nimport type { SeoInput, SeoIssue, SeoMetrics, SeoResult } from \"./plugins/types/index\";\nimport {\n clampScore,\n extractWords,\n hasConclusionSection,\n hasQuickAnswerPattern,\n} from \"./utils\";\n\n/**\n * Analyze content for SEO optimization\n */\nexport function analyzeSeo(input: SeoInput): SeoResult {\n const { content, title, metaDescription, targetKeywords } = input;\n const issues: SeoIssue[] = [];\n const recommendations: string[] = [];\n\n // Basic content analysis\n const extracted = extractFromMarkdown(content);\n const words = extractWords(extracted.text);\n const wordCount = words.length;\n const paragraphs = extracted.paragraphs;\n const headings = extracted.headings;\n const h2Headings = headings.filter((heading) => heading.level === 2);\n const links = extracted.links;\n const images = extracted.images;\n\n // Get first paragraph or fallback to first 100 words\n const firstParagraphText =\n paragraphs.length > 0\n ? (paragraphs[0] ?? \"\")\n : words.slice(0, 100).join(\" \");\n\n let score = 100;\n\n // Title checks (15 points max)\n if (!title) {\n issues.push({\n type: \"title\",\n severity: \"error\",\n message: \"Missing title\",\n suggestion: \"Add a descriptive title (50-60 characters)\",\n });\n score -= 15;\n } else if (title.length < 30) {\n issues.push({\n type: \"title\",\n severity: \"warning\",\n message: \"Title is too short\",\n suggestion: \"Expand title to 50-60 characters for better SEO\",\n });\n score -= 8;\n } else if (title.length > 60) {\n issues.push({\n type: \"title\",\n severity: \"warning\",\n message: \"Title is too long\",\n suggestion:\n \"Shorten to under 60 characters to avoid truncation in search results\",\n });\n score -= 5;\n }\n\n // Check for keyword in title\n if (title && targetKeywords && targetKeywords.length > 0) {\n const titleLower = title.toLowerCase();\n const hasKeywordInTitle = targetKeywords.some((kw) =>\n titleLower.includes(kw.toLowerCase()),\n );\n if (!hasKeywordInTitle) {\n issues.push({\n type: \"title\",\n severity: \"warning\",\n message: \"Primary keyword not found in title\",\n suggestion: \"Include your primary keyword naturally in the title\",\n });\n score -= 5;\n }\n }\n\n // Meta description checks (10 points max)\n if (!metaDescription) {\n issues.push({\n type: \"meta_description\",\n severity: \"warning\",\n message: \"Missing meta description\",\n suggestion: \"Add a meta description (150-160 characters)\",\n });\n score -= 10;\n } else if (metaDescription.length < 120) {\n issues.push({\n type: \"meta_description\",\n severity: \"info\",\n message: \"Meta description could be longer\",\n suggestion: \"Expand to 150-160 characters\",\n });\n score -= 3;\n } else if (metaDescription.length > 160) {\n issues.push({\n type: \"meta_description\",\n severity: \"warning\",\n message: \"Meta description is too long\",\n suggestion: \"Shorten to under 160 characters\",\n });\n score -= 5;\n }\n\n // Headings checks (15 points max)\n if (headings.length === 0) {\n issues.push({\n type: \"headings\",\n severity: \"error\",\n message: \"No headings found\",\n suggestion: \"Add H2 and H3 headings to structure your content\",\n });\n score -= 15;\n } else if (h2Headings.length < 3 && wordCount > 500) {\n issues.push({\n type: \"headings\",\n severity: \"warning\",\n message: \"Too few H2 headings for content length\",\n suggestion: \"Add more H2 subheadings (one every 200-300 words)\",\n });\n score -= 5;\n }\n\n // Check heading hierarchy - no H1 in content\n const h1Headings = headings.filter((heading) => heading.level === 1);\n if (h1Headings.length > 0) {\n issues.push({\n type: \"headings\",\n severity: \"error\",\n message: \"H1 heading found in content body\",\n suggestion:\n \"Remove H1 from content. The title is in frontmatter. Start with H2.\",\n });\n score -= 10;\n }\n\n // Check for keywords in H2 headings\n if (targetKeywords && targetKeywords.length > 0 && h2Headings.length > 0) {\n const h2Text = h2Headings.map((heading) => heading.text).join(\" \");\n const hasKeywordInH2 = targetKeywords.some((kw) =>\n h2Text.toLowerCase().includes(kw.toLowerCase()),\n );\n if (!hasKeywordInH2) {\n issues.push({\n type: \"heading_keywords\",\n severity: \"info\",\n message: \"Target keywords not found in any H2 headings\",\n suggestion: \"Include keywords naturally in at least one H2 heading\",\n });\n score -= 3;\n }\n }\n\n // Content length checks (10 points max)\n if (wordCount < 300) {\n issues.push({\n type: \"content_length\",\n severity: \"error\",\n message: \"Content is too short\",\n suggestion: \"Aim for at least 600-1000 words for blog posts\",\n });\n score -= 10;\n } else if (wordCount < 600) {\n issues.push({\n type: \"content_length\",\n severity: \"warning\",\n message: \"Content could be longer\",\n suggestion: \"Consider expanding to 1000+ words for better ranking\",\n });\n score -= 5;\n }\n\n // Link checks (10 points max)\n if (links.length === 0 && wordCount > 500) {\n issues.push({\n type: \"links\",\n severity: \"warning\",\n message: \"No links found\",\n suggestion: \"Add internal and external links to improve SEO\",\n });\n score -= 10;\n } else if (links.length < 3 && wordCount > 1000) {\n issues.push({\n type: \"links\",\n severity: \"info\",\n message: \"Few links for content length\",\n suggestion:\n \"Add more internal links to related content and external links to authoritative sources\",\n });\n score -= 3;\n }\n\n // Image checks\n if (images.length === 0 && wordCount > 300) {\n issues.push({\n type: \"images\",\n severity: \"info\",\n message: \"No images found\",\n suggestion: \"Add images with descriptive alt text\",\n });\n score -= 3;\n }\n\n // Quick Answer check (10 points max)\n const hasQuickAnswer = hasQuickAnswerPattern(firstParagraphText);\n\n if (!hasQuickAnswer && wordCount > 300) {\n issues.push({\n type: \"quick_answer\",\n severity: \"warning\",\n message: \"No quick answer detected in first 100 words\",\n suggestion:\n \"Add a TL;DR, definition lead, or comparison table early to answer the reader's question immediately\",\n });\n score -= 10;\n }\n\n // First paragraph keyword check\n let keywordInFirstParagraph = false;\n if (targetKeywords && targetKeywords.length > 0) {\n const firstParaLower = firstParagraphText.toLowerCase();\n keywordInFirstParagraph = targetKeywords.some((kw) =>\n firstParaLower.includes(kw.toLowerCase()),\n );\n if (!keywordInFirstParagraph) {\n issues.push({\n type: \"first_paragraph\",\n severity: \"warning\",\n message: \"Primary keyword not found in first paragraph\",\n suggestion:\n \"Include your primary keyword in the first 100 words for better SEO\",\n });\n score -= 5;\n }\n }\n\n // Keyword density\n const keywordDensity: Record<string, number> = {};\n if (targetKeywords && targetKeywords.length > 0) {\n const contentLower = extracted.text.toLowerCase();\n for (const keyword of targetKeywords) {\n const regex = new RegExp(keyword.toLowerCase(), \"gi\");\n const matches = contentLower.match(regex) || [];\n keywordDensity[keyword] = Number(\n ((matches.length / wordCount) * 100).toFixed(2),\n );\n\n if (keywordDensity[keyword] === 0) {\n issues.push({\n type: \"keyword_density\",\n severity: \"warning\",\n message: `Target keyword \"${keyword}\" not found`,\n suggestion: `Include \"${keyword}\" naturally in your content`,\n });\n score -= 5;\n } else if (keywordDensity[keyword] > 3) {\n issues.push({\n type: \"keyword_density\",\n severity: \"warning\",\n message: `Keyword \"${keyword}\" may be overused (${keywordDensity[keyword]}%)`,\n suggestion: \"Reduce keyword density to 1-2%\",\n });\n score -= 3;\n }\n }\n }\n\n // Structure quality check\n const hasConclusion = hasConclusionSection(content);\n if (!hasConclusion && wordCount > 500) {\n issues.push({\n type: \"structure\",\n severity: \"info\",\n message: \"No conclusion section detected\",\n suggestion: \"Add a conclusion with key takeaways and a call-to-action\",\n });\n score -= 5;\n }\n\n // Generate recommendations\n if (issues.some((i) => i.type === \"content_length\")) {\n recommendations.push(\n \"Expand your content with more detailed explanations and examples\",\n );\n }\n if (issues.some((i) => i.type === \"headings\")) {\n recommendations.push(\n \"Structure your content with clear H2 and H3 headings\",\n );\n }\n if (issues.some((i) => i.type === \"links\")) {\n recommendations.push(\n \"Add relevant internal links to other blog posts and external links to authoritative sources\",\n );\n }\n if (issues.some((i) => i.type === \"quick_answer\")) {\n recommendations.push(\n \"Start with a quick answer - readers want the answer immediately, not after scrolling\",\n );\n }\n if (issues.some((i) => i.type === \"first_paragraph\")) {\n recommendations.push(\n \"Include your primary keyword in the first paragraph for better search visibility\",\n );\n }\n\n const metrics: SeoMetrics = {\n wordCount,\n headingCount: headings.length,\n paragraphCount: paragraphs.length,\n linkCount: links.length,\n imageCount: images.length,\n hasQuickAnswer,\n keywordInFirstParagraph,\n keywordDensity:\n Object.keys(keywordDensity).length > 0 ? keywordDensity : undefined,\n };\n\n return {\n score: clampScore(score),\n issues,\n recommendations,\n metrics,\n };\n}\n",
11
+ "/**\n * Content Structure Analysis Module\n * Analyzes content structure for SEO and readability best practices\n */\n\nimport type {\n ContentStructure,\n ContentType,\n StructureIssue,\n StructureResult,\n} from \"./plugins/types/index\";\nimport {\n clampScore,\n extractHeadings,\n extractParagraphs,\n extractWords,\n hasConclusionSection,\n hasQuickAnswerPattern,\n} from \"./utils\";\n\n/**\n * Analyze content structure\n */\nexport function analyzeStructure(\n content: string,\n contentType?: ContentType,\n): StructureResult {\n const issues: StructureIssue[] = [];\n let score = 100;\n\n const words = extractWords(content);\n const wordCount = words.length;\n const paragraphs = extractParagraphs(content);\n const headings = extractHeadings(content);\n\n // Check for H1 in content\n const hasH1InContent = headings.some((h) => h.level === 1);\n if (hasH1InContent) {\n issues.push({\n type: \"heading_h1\",\n severity: \"error\",\n message: \"H1 heading found in content body\",\n suggestion:\n \"Remove H1 (# heading) from content. The title is in frontmatter. Start content with H2 (##).\",\n });\n score -= 15;\n }\n\n // Check heading hierarchy\n let headingHierarchyValid = true;\n for (let i = 1; i < headings.length; i++) {\n const prevHeading = headings[i - 1];\n const currentHeading = headings[i];\n if (!prevHeading || !currentHeading) continue;\n const prevLevel = prevHeading.level;\n const currentLevel = currentHeading.level;\n if (currentLevel > prevLevel + 1) {\n headingHierarchyValid = false;\n issues.push({\n type: \"heading_hierarchy\",\n severity: \"warning\",\n message: `Heading level skipped: H${prevLevel} to H${currentLevel} (\"${currentHeading.text}\")`,\n suggestion: `Don't skip heading levels. Use H${prevLevel + 1} instead of H${currentLevel}.`,\n });\n score -= 5;\n }\n }\n\n // Check for quick answer in first 100 words\n const first100Words = words.slice(0, 100).join(\" \");\n const hasQuickAnswer = hasQuickAnswerPattern(first100Words);\n\n if (!hasQuickAnswer && wordCount > 300) {\n issues.push({\n type: \"quick_answer\",\n severity: \"warning\",\n message: \"No quick answer detected in first 100 words\",\n suggestion:\n \"Add a TL;DR box, definition lead, or comparison table early to answer the reader's question immediately.\",\n });\n score -= 10;\n }\n\n // Check paragraph lengths\n let totalSentences = 0;\n let longParagraphs = 0;\n for (const paragraph of paragraphs) {\n if (paragraph.startsWith(\"#\") || paragraph.startsWith(\"```\")) continue;\n const sentences = paragraph.split(/[.!?]+/).filter(Boolean);\n totalSentences += sentences.length;\n if (sentences.length > 4) {\n longParagraphs++;\n }\n }\n\n const avgParagraphLength =\n paragraphs.length > 0 ? totalSentences / paragraphs.length : 0;\n\n if (longParagraphs > 0) {\n issues.push({\n type: \"paragraph_length\",\n severity: \"info\",\n message: `${longParagraphs} paragraph(s) exceed 4 sentences`,\n suggestion:\n \"Break up long paragraphs. Aim for 2-4 sentences per paragraph for better readability.\",\n });\n score -= Math.min(longParagraphs * 2, 10);\n }\n\n // Check H2 frequency\n const h2Headings = headings.filter((h) => h.level === 2);\n const expectedH2Count = Math.floor(wordCount / 250);\n if (h2Headings.length < expectedH2Count && wordCount > 500) {\n issues.push({\n type: \"heading_frequency\",\n severity: \"warning\",\n message: `Only ${h2Headings.length} H2 headings for ${wordCount} words (recommended: ${expectedH2Count})`,\n suggestion:\n \"Add more H2 headings to break up content. Aim for one H2 every 200-300 words.\",\n });\n score -= 5;\n }\n\n // Check for table of contents\n const hasTableOfContents =\n /##\\s*(?:table of contents|sumário|índice|contents)/i.test(content) ||\n /\\[.*\\]\\(#.*\\)/.test(content.slice(0, 500));\n\n if (wordCount > 1500 && !hasTableOfContents) {\n issues.push({\n type: \"table_of_contents\",\n severity: \"info\",\n message: \"No table of contents detected for long-form content\",\n suggestion:\n \"Add a table of contents near the beginning for posts over 1500 words.\",\n });\n score -= 3;\n }\n\n // Check for tables\n const hasTables = /^\\|.*\\|.*\\|$/m.test(content);\n\n // Check for conclusion\n const hasConclusion = hasConclusionSection(content);\n\n if (!hasConclusion && wordCount > 500) {\n issues.push({\n type: \"conclusion\",\n severity: \"info\",\n message: \"No conclusion section detected\",\n suggestion:\n \"Add a conclusion with key takeaways and a call-to-action.\",\n });\n score -= 5;\n }\n\n // Content type specific checks\n if (contentType === \"how-to\") {\n const hasNumberedSteps =\n /^\\d+\\.\\s+/m.test(content) || /step\\s*\\d+|passo\\s*\\d+/i.test(content);\n if (!hasNumberedSteps) {\n issues.push({\n type: \"how_to_structure\",\n severity: \"warning\",\n message: \"How-to content should have numbered steps\",\n suggestion:\n \"Use numbered lists (1. 2. 3.) for step-by-step instructions.\",\n });\n score -= 5;\n }\n }\n\n if (contentType === \"comparison\") {\n if (!hasTables) {\n issues.push({\n type: \"comparison_structure\",\n severity: \"warning\",\n message: \"Comparison content should include a comparison table\",\n suggestion:\n \"Add a table comparing key metrics between the options.\",\n });\n score -= 5;\n }\n }\n\n if (contentType === \"listicle\") {\n const listItemCount = (content.match(/^[-*]\\s+/gm) || []).length;\n if (listItemCount < 3) {\n issues.push({\n type: \"listicle_structure\",\n severity: \"warning\",\n message: \"Listicle should have multiple list items\",\n suggestion:\n \"Add more items to your list for a comprehensive listicle.\",\n });\n score -= 5;\n }\n }\n\n const structure: ContentStructure = {\n hasQuickAnswer,\n headingHierarchyValid,\n avgParagraphLength: Math.round(avgParagraphLength * 10) / 10,\n hasTableOfContents,\n hasTables,\n hasConclusion,\n headingCount: headings.length,\n wordCount,\n };\n\n return {\n score: clampScore(score),\n issues,\n structure,\n };\n}\n",
12
+ "/**\n * Content Analysis Library\n *\n * A comprehensive library for analyzing content quality, SEO optimization,\n * readability, structure, and detecting problematic patterns.\n *\n * @packageDocumentation\n */\n\nexport { analyzeBadPatterns } from \"./bad-patterns\";\nexport { analyzeKeywords } from \"./keywords\";\nexport { analyzeReadability } from \"./readability\";\n// Individual analyzers\nexport { analyzeSeo } from \"./seo\";\nexport { analyzeStructure } from \"./structure\";\n\n// Types\nexport * from \"./plugins/types/index\";\n\n// Utilities (exported for advanced usage)\nexport {\n calculateFleschKincaid,\n clampScore,\n countSyllables,\n extractHeadings,\n extractParagraphs,\n extractWords,\n findOccurrences,\n getReadabilityLevel,\n hasConclusionSection,\n hasQuickAnswerPattern,\n} from \"./utils\";\n\nimport { analyzeBadPatterns } from \"./bad-patterns\";\nimport { analyzeKeywords } from \"./keywords\";\nimport { analyzeReadability } from \"./readability\";\nimport { analyzeSeo } from \"./seo\";\nimport { analyzeStructure } from \"./structure\";\n// Import for combined analysis\nimport type { AnalysisInput, ContentAnalysisResult } from \"./plugins/types/index\";\n\n/**\n * Perform a comprehensive content analysis\n *\n * This function runs all available analyzers and returns a combined result:\n * - SEO analysis (title, meta, keywords, structure)\n * - Readability analysis (Flesch-Kincaid scores)\n * - Structure analysis (headings, paragraphs, quick answers)\n * - Bad pattern detection (filler phrases, clickbait, etc.)\n * - Keyword analysis (density, placement, recommendations)\n *\n * @param input - The content and metadata to analyze\n * @returns Combined analysis results from all analyzers\n *\n * @example\n * ```typescript\n * import { analyzeContent } from '@f-o-t/content-analysis';\n *\n * const result = analyzeContent({\n * content: '## Introduction\\n\\nThis is my blog post...',\n * title: 'My Blog Post Title',\n * description: 'A short description for SEO',\n * targetKeywords: ['blog', 'tutorial'],\n * });\n *\n * console.log(result.seo.score); // 85\n * console.log(result.readability.fleschKincaidReadingEase); // 65.2\n * ```\n */\nexport function analyzeContent(input: AnalysisInput): ContentAnalysisResult {\n const { content, title, description, targetKeywords } = input;\n\n const seo = analyzeSeo({\n content,\n title,\n metaDescription: description,\n targetKeywords,\n });\n\n const readability = analyzeReadability(content, \"general\");\n const structure = analyzeStructure(content);\n const badPatterns = analyzeBadPatterns(content, title);\n\n const keywords =\n targetKeywords && targetKeywords.length > 0\n ? analyzeKeywords({ content, title, targetKeywords })\n : null;\n\n return {\n seo,\n readability,\n structure,\n badPatterns,\n keywords,\n analyzedAt: new Date().toISOString(),\n };\n}\n"
13
+ ],
14
+ "mappings": "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",
15
+ "debugId": "803CE7EA001F6D4064756E2164756E21",
16
+ "names": []
17
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Keyword Analysis Module
3
+ * Analyzes keyword usage, density, and placement in content
4
+ */
5
+ import type { KeywordAnalysisResult, KeywordInput } from "./plugins/types/index";
6
+ /**
7
+ * Analyze keyword usage in content
8
+ */
9
+ export declare function analyzeKeywords(input: KeywordInput): KeywordAnalysisResult;
10
+ //# sourceMappingURL=keywords.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keywords.d.ts","sourceRoot":"","sources":["../src/keywords.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAET,qBAAqB,EACrB,YAAY,EAKd,MAAM,uBAAuB,CAAC;AAG/B;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,qBAAqB,CA0M1E"}
@@ -0,0 +1,20 @@
1
+ export type MarkdownExtract = {
2
+ text: string;
3
+ headings: Array<{
4
+ level: number;
5
+ text: string;
6
+ index: number;
7
+ }>;
8
+ links: Array<{
9
+ href: string;
10
+ text: string;
11
+ }>;
12
+ images: Array<{
13
+ alt: string;
14
+ src: string;
15
+ }>;
16
+ tables: number;
17
+ paragraphs: string[];
18
+ };
19
+ export declare function extractFromMarkdown(content: string): MarkdownExtract;
20
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,eAAe,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChE,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7C,MAAM,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,CAoEpE"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Content Analysis Types
3
+ * All type definitions for SEO, readability, structure, and pattern analysis
4
+ */
5
+ export type SeoIssueType = "title" | "meta_description" | "headings" | "keyword_density" | "content_length" | "readability" | "links" | "images" | "quick_answer" | "first_paragraph" | "heading_keywords" | "structure";
6
+ export type Severity = "error" | "warning" | "info";
7
+ export type SeoIssue = {
8
+ type: SeoIssueType;
9
+ severity: Severity;
10
+ message: string;
11
+ suggestion: string;
12
+ };
13
+ export type SeoMetrics = {
14
+ wordCount: number;
15
+ headingCount: number;
16
+ paragraphCount: number;
17
+ linkCount: number;
18
+ imageCount: number;
19
+ hasQuickAnswer: boolean;
20
+ keywordInFirstParagraph: boolean;
21
+ keywordDensity?: Record<string, number>;
22
+ };
23
+ export type SeoResult = {
24
+ score: number;
25
+ issues: SeoIssue[];
26
+ recommendations: string[];
27
+ metrics: SeoMetrics;
28
+ };
29
+ export type SeoInput = {
30
+ content: string;
31
+ title?: string;
32
+ metaDescription?: string;
33
+ targetKeywords?: string[];
34
+ };
35
+ export type TargetAudience = "general" | "technical" | "academic" | "casual";
36
+ export type ReadabilityMetrics = {
37
+ sentenceCount: number;
38
+ wordCount: number;
39
+ avgWordsPerSentence: number;
40
+ avgSyllablesPerWord: number;
41
+ complexWordCount: number;
42
+ complexWordPercentage: number;
43
+ };
44
+ export type TargetScore = {
45
+ min: number;
46
+ max: number;
47
+ description: string;
48
+ };
49
+ export type ReadabilityResult = {
50
+ fleschKincaidReadingEase: number;
51
+ fleschKincaidGradeLevel: number;
52
+ readabilityLevel: string;
53
+ targetScore: TargetScore;
54
+ isOnTarget: boolean;
55
+ suggestions: string[];
56
+ metrics: ReadabilityMetrics;
57
+ };
58
+ export type ContentType = "how-to" | "comparison" | "explainer" | "listicle" | "general";
59
+ export type StructureIssue = {
60
+ type: string;
61
+ severity: Severity;
62
+ message: string;
63
+ suggestion: string;
64
+ };
65
+ export type ContentStructure = {
66
+ hasQuickAnswer: boolean;
67
+ headingHierarchyValid: boolean;
68
+ avgParagraphLength: number;
69
+ hasTableOfContents: boolean;
70
+ hasTables: boolean;
71
+ hasConclusion: boolean;
72
+ headingCount: number;
73
+ wordCount: number;
74
+ };
75
+ export type StructureResult = {
76
+ score: number;
77
+ issues: StructureIssue[];
78
+ structure: ContentStructure;
79
+ };
80
+ export type BadPatternType = "word_count_mention" | "word_count_in_title" | "meta_commentary" | "engagement_begging" | "endless_introduction" | "vague_instructions" | "clickbait_markers" | "filler_phrases" | "over_formatting" | "wall_of_text" | "keyword_stuffing";
81
+ export type BadPattern = {
82
+ pattern: string;
83
+ severity: "error" | "warning";
84
+ locations: string[];
85
+ suggestion: string;
86
+ };
87
+ export type BadPatternResult = {
88
+ hasIssues: boolean;
89
+ issueCount: number;
90
+ patterns: BadPattern[];
91
+ };
92
+ export type KeywordLocationType = "title" | "heading" | "paragraph" | "first100words" | "last100words";
93
+ export type KeywordStatus = "optimal" | "low" | "high" | "missing";
94
+ export type KeywordLocation = {
95
+ type: KeywordLocationType;
96
+ index?: number;
97
+ };
98
+ export type KeywordAnalysisItem = {
99
+ keyword: string;
100
+ count: number;
101
+ density: number;
102
+ locations: KeywordLocation[];
103
+ status: KeywordStatus;
104
+ suggestion?: string;
105
+ };
106
+ export type TopKeyword = {
107
+ keyword: string;
108
+ count: number;
109
+ density: number;
110
+ };
111
+ export type TopTerm = {
112
+ term: string;
113
+ count: number;
114
+ density: number;
115
+ };
116
+ export type TopPhrase = {
117
+ phrase: string;
118
+ count: number;
119
+ density: number;
120
+ };
121
+ export type KeywordMetrics = {
122
+ totalWordCount: number;
123
+ uniqueWordCount: number;
124
+ avgKeywordDensity: number;
125
+ };
126
+ export type KeywordAnalysisResult = {
127
+ analysis: KeywordAnalysisItem[];
128
+ overallScore: number;
129
+ topKeywords: TopKeyword[];
130
+ topTerms: TopTerm[];
131
+ topPhrases: TopPhrase[];
132
+ recommendations: string[];
133
+ metrics: KeywordMetrics;
134
+ };
135
+ export type KeywordInput = {
136
+ content: string;
137
+ title?: string;
138
+ targetKeywords: string[];
139
+ };
140
+ export type ContentAnalysisResult = {
141
+ seo: SeoResult;
142
+ readability: ReadabilityResult;
143
+ structure: StructureResult;
144
+ badPatterns: BadPatternResult;
145
+ keywords: KeywordAnalysisResult | null;
146
+ analyzedAt: string;
147
+ };
148
+ export type AnalysisInput = {
149
+ content: string;
150
+ title?: string;
151
+ description?: string;
152
+ targetKeywords?: string[];
153
+ };
154
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/types/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ // @bun
2
+ import"../../index-9t11m1re.js";
3
+
4
+ //# debugId=B1ED36E0B1DAAC5B64756E2164756E21
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [
5
+ ],
6
+ "mappings": "",
7
+ "debugId": "B1ED36E0B1DAAC5B64756E2164756E21",
8
+ "names": []
9
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Readability Analysis Module
3
+ * Analyzes content readability using Flesch-Kincaid algorithms
4
+ */
5
+ import type { ReadabilityResult, TargetAudience } from "./plugins/types/index";
6
+ /**
7
+ * Analyze content readability
8
+ */
9
+ export declare function analyzeReadability(content: string, targetAudience?: TargetAudience): ReadabilityResult;
10
+ //# sourceMappingURL=readability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readability.d.ts","sourceRoot":"","sources":["../src/readability.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAET,iBAAiB,EACjB,cAAc,EAEhB,MAAM,uBAAuB,CAAC;AA8B/B;;GAEG;AACH,wBAAgB,kBAAkB,CAC/B,OAAO,EAAE,MAAM,EACf,cAAc,GAAE,cAA0B,GAC1C,iBAAiB,CAgFnB"}
package/dist/seo.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * SEO Analysis Module
3
+ * Analyzes content for search engine optimization factors
4
+ */
5
+ import type { SeoInput, SeoResult } from "./plugins/types/index";
6
+ /**
7
+ * Analyze content for SEO optimization
8
+ */
9
+ export declare function analyzeSeo(input: SeoInput): SeoResult;
10
+ //# sourceMappingURL=seo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo.d.ts","sourceRoot":"","sources":["../src/seo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAwB,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAQvF;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,SAAS,CA2TrD"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Content Structure Analysis Module
3
+ * Analyzes content structure for SEO and readability best practices
4
+ */
5
+ import type { ContentType, StructureResult } from "./plugins/types/index";
6
+ /**
7
+ * Analyze content structure
8
+ */
9
+ export declare function analyzeStructure(content: string, contentType?: ContentType): StructureResult;
10
+ //# sourceMappingURL=structure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structure.d.ts","sourceRoot":"","sources":["../src/structure.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAET,WAAW,EAEX,eAAe,EACjB,MAAM,uBAAuB,CAAC;AAU/B;;GAEG;AACH,wBAAgB,gBAAgB,CAC7B,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,WAAW,GACzB,eAAe,CA6LjB"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Shared utility functions for content analysis
3
+ */
4
+ /**
5
+ * Count syllables in a word using a simplified vowel group algorithm
6
+ */
7
+ export declare function countSyllables(word: string): number;
8
+ /**
9
+ * Calculate Flesch-Kincaid readability metrics
10
+ */
11
+ export declare function calculateFleschKincaid(text: string): {
12
+ readingEase: number;
13
+ gradeLevel: number;
14
+ };
15
+ /**
16
+ * Convert reading ease score to human-readable level
17
+ */
18
+ export declare function getReadabilityLevel(score: number): string;
19
+ /**
20
+ * Find all occurrences of a regex pattern with surrounding context
21
+ */
22
+ export declare function findOccurrences(regex: RegExp, text: string): string[];
23
+ /**
24
+ * Extract words from content
25
+ */
26
+ export declare function extractWords(content: string): string[];
27
+ /**
28
+ * Extract plain text from markdown using AST parsing
29
+ */
30
+ export declare function extractPlainTextFromMarkdown(content: string): string;
31
+ /**
32
+ * Tokenize content into normalized terms
33
+ */
34
+ export declare function tokenize(content: string): string[];
35
+ /**
36
+ * Extract paragraphs from content
37
+ */
38
+ export declare function extractParagraphs(content: string): string[];
39
+ /**
40
+ * Extract headings from markdown content
41
+ */
42
+ export declare function extractHeadings(content: string): Array<{
43
+ level: number;
44
+ text: string;
45
+ index: number;
46
+ }>;
47
+ /**
48
+ * Clamp score between 0 and 100
49
+ */
50
+ export declare function clampScore(score: number): number;
51
+ /**
52
+ * Check if content has a quick answer pattern in the first portion
53
+ */
54
+ export declare function hasQuickAnswerPattern(text: string): boolean;
55
+ /**
56
+ * Check if content has a conclusion section
57
+ */
58
+ export declare function hasConclusionSection(content: string): boolean;
59
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWnD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACrB,CA+BA;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQzD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAerE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAEtD;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CASlD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAE3D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC5B,OAAO,EAAE,MAAM,GACf,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAiBvD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQ3D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAI7D"}
package/package.json CHANGED
@@ -1,39 +1,39 @@
1
1
  {
2
- "name": "@f-o-t/content-analysis",
3
- "version": "1.0.3",
4
- "type": "module",
5
- "files": [
6
- "dist"
7
- ],
8
- "main": "./dist/index.js",
9
- "types": "./dist/index.d.ts",
10
- "exports": {
11
- ".": {
12
- "types": "./dist/index.d.ts",
13
- "default": "./dist/index.js"
14
- },
15
- "./plugins/types": {
16
- "types": "./dist/plugins/types/index.d.ts",
17
- "default": "./dist/plugins/types/index.js"
18
- }
19
- },
20
- "scripts": {
21
- "build": "bun x --bun fot build",
22
- "test": "bun x --bun fot test",
23
- "lint": "bun x --bun fot lint",
24
- "format": "bun x --bun fot format",
25
- "typecheck": "bun x --bun fot typecheck"
26
- },
27
- "dependencies": {
28
- "@f-o-t/markdown": "^1.0.2"
29
- },
30
- "devDependencies": {
31
- "@f-o-t/cli": "^1.0.0",
32
- "@f-o-t/config": "^1.0.0"
33
- },
34
- "repository": {
35
- "type": "git",
36
- "url": "https://github.com/F-O-T/libraries.git",
37
- "directory": "libraries/content-analysis"
38
- }
2
+ "name": "@f-o-t/content-analysis",
3
+ "version": "1.0.6",
4
+ "type": "module",
5
+ "files": [
6
+ "dist"
7
+ ],
8
+ "main": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "./plugins/types": {
16
+ "types": "./dist/plugins/types/index.d.ts",
17
+ "default": "./dist/plugins/types/index.js"
18
+ }
19
+ },
20
+ "scripts": {
21
+ "build": "bun x --bun fot build",
22
+ "test": "bun x --bun fot test",
23
+ "lint": "bun x --bun fot lint",
24
+ "format": "bun x --bun fot format",
25
+ "typecheck": "bun x --bun fot typecheck"
26
+ },
27
+ "dependencies": {
28
+ "@f-o-t/markdown": "^1.0.2"
29
+ },
30
+ "devDependencies": {
31
+ "@f-o-t/cli": "^1.0.0",
32
+ "@f-o-t/config": "^1.0.0"
33
+ },
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "https://github.com/F-O-T/libraries.git",
37
+ "directory": "libraries/content-analysis"
38
+ }
39
39
  }