Utility Functions

Utility Functions

Helper functions exported by @capyseo/core.

HTML Utilities

extractMetadata

Extract metadata from HTML:

import { extractMetadata } from '@capyseo/core'; const html = '<html><head><title>My Page</title></head></html>'; const metadata = extractMetadata(html); console.log(metadata); // { // title: 'My Page', // description: undefined, // canonical: undefined, // ... // }

Signature:

function extractMetadata(html: string): PageMetadata;

loadHTML

Load and parse HTML with Cheerio:

import { loadHTML } from '@capyseo/core'; const html = '<html><body><h1>Hello</h1></body></html>'; const $ = loadHTML(html); console.log($('h1').text()); // 'Hello'

Signature:

function loadHTML(html: string): CheerioAPI;

getTextContent

Get text content excluding scripts and styles:

import { getTextContent } from '@capyseo/core'; const html = ` <body> <p>Hello world</p> <script>console.log('ignored');</script> </body> `; const text = getTextContent(html); console.log(text); // 'Hello world'

Signature:

function getTextContent(html: string): string;

URL Utilities

normalizeURL

Normalize URL for comparison:

import { normalizeURL } from '@capyseo/core'; console.log(normalizeURL('HTTPS://Example.Com/Path/')); // 'https://example.com/path' console.log(normalizeURL('/path', 'https://example.com')); // 'https://example.com/path'

Signature:

function normalizeURL(url: string, base?: string): string;

isExternalURL

Check if URL is external:

import { isExternalURL } from '@capyseo/core'; const baseURL = 'https://mysite.com'; console.log(isExternalURL('https://other.com', baseURL)); // true console.log(isExternalURL('/page', baseURL)); // false console.log(isExternalURL('https://mysite.com/page', baseURL)); // false

Signature:

function isExternalURL(url: string, base: string): boolean;

resolveURL

Resolve relative URL:

import { resolveURL } from '@capyseo/core'; console.log(resolveURL('../page', 'https://example.com/dir/file')); // 'https://example.com/page'

Signature:

function resolveURL(relative: string, base: string): string;

Text Utilities

countWords

Count words in text:

import { countWords } from '@capyseo/core'; console.log(countWords('Hello world, this is a test.')); // 6

Signature:

function countWords(text: string): number;

calculateReadability

Calculate readability score:

import { calculateReadability } from '@capyseo/core'; const text = 'This is a simple sentence. It is easy to read.'; const score = calculateReadability(text); console.log(score); // { // fleschKincaid: 95.2, // gradeLevel: 2.1, // difficulty: 'easy' // }

Signature:

function calculateReadability(text: string): ReadabilityScore; interface ReadabilityScore { fleschKincaid: number; gradeLevel: number; difficulty: 'easy' | 'moderate' | 'difficult'; }

truncate

Truncate text to length:

import { truncate } from '@capyseo/core'; console.log(truncate('Hello world', 8)); // 'Hello...' console.log(truncate('Hello world', 8, ' [more]')); // 'He [more]'

Signature:

function truncate(text: string, maxLength: number, suffix?: string): string;

Scoring Utilities

calculateScore

Calculate SEO score from issues:

import { calculateScore } from '@capyseo/core'; const issues = [ { ruleId: 'meta-title', severity: 'error', message: '...' }, { ruleId: 'image-alt', severity: 'warning', message: '...' }, ]; const score = calculateScore(issues); console.log(score); // 85

Signature:

function calculateScore(issues: SEOIssue[]): number;

getSeverityWeight

Get weight for severity level:

import { getSeverityWeight } from '@capyseo/core'; console.log(getSeverityWeight('error')); // 10 console.log(getSeverityWeight('warning')); // 5 console.log(getSeverityWeight('info')); // 1

Signature:

function getSeverityWeight(severity: Severity): number;

gradeScore

Convert score to letter grade:

import { gradeScore } from '@capyseo/core'; console.log(gradeScore(95)); // 'A' console.log(gradeScore(85)); // 'B' console.log(gradeScore(75)); // 'C' console.log(gradeScore(65)); // 'D' console.log(gradeScore(50)); // 'F'

Signature:

function gradeScore(score: number): 'A' | 'B' | 'C' | 'D' | 'F';

File Utilities

findHTMLFiles

Find HTML files in directory:

import { findHTMLFiles } from '@capyseo/core'; const files = await findHTMLFiles('./dist'); console.log(files); // ['./dist/index.html', './dist/about.html', ...]

Signature:

function findHTMLFiles( dir: string, options?: { include?: string[]; exclude?: string[]; recursive?: boolean; } ): Promise<string[]>;

readHTMLFile

Read HTML file content:

import { readHTMLFile } from '@capyseo/core'; const html = await readHTMLFile('./dist/index.html'); console.log(html); // '<html>...'

Signature:

function readHTMLFile(path: string): Promise<string>;

Configuration Utilities

loadConfig

Load configuration from file:

import { loadConfig } from '@capyseo/core'; const config = await loadConfig('./capyseo.config.js'); console.log(config);

Signature:

function loadConfig(path?: string): Promise<CapyseoConfig>;

mergeConfig

Merge configuration objects:

import { mergeConfig } from '@capyseo/core'; const base = { rules: { 'meta-title': { severity: 'error' } } }; const override = { ai: { enabled: true } }; const merged = mergeConfig(base, override); // { // rules: { 'meta-title': { severity: 'error' } }, // ai: { enabled: true } // }

Signature:

function mergeConfig( base: CapyseoConfig, ...overrides: Partial<CapyseoConfig>[] ): CapyseoConfig;

validateConfig

Validate configuration:

import { validateConfig } from '@capyseo/core'; const config = { rules: { 'invalid-rule': {} } }; const result = validateConfig(config); if (!result.valid) { console.log(result.errors); // ['Unknown rule: invalid-rule'] }

Signature:

function validateConfig(config: unknown): { valid: boolean; errors: string[]; config?: CapyseoConfig; };

Rule Utilities

getRuleById

Get rule by ID:

import { getRuleById } from '@capyseo/core'; const rule = getRuleById('meta-title'); console.log(rule?.name); // 'Meta Title'

Signature:

function getRuleById(id: string): SEORule | undefined;

getRulesByCategory

Get rules by category:

import { getRulesByCategory } from '@capyseo/core'; const rules = getRulesByCategory('meta-tags'); console.log(rules.map(r => r.id)); // ['meta-title', 'meta-description', 'viewport', ...]

Signature:

function getRulesByCategory(category: RuleCategory): SEORule[];

getAllRules

Get all available rules:

import { getAllRules } from '@capyseo/core'; const rules = getAllRules(); console.log(`Total rules: ${rules.length}`); // 46

Signature:

function getAllRules(): SEORule[];

Reporter Utilities

formatIssue

Format issue for display:

import { formatIssue } from '@capyseo/core'; const issue = { ruleId: 'meta-description', message: 'Missing meta description', severity: 'error', }; console.log(formatIssue(issue)); // '[x] [meta-description] Missing meta description'

Signature:

function formatIssue(issue: SEOIssue): string;

formatScore

Format score for display:

import { formatScore } from '@capyseo/core'; console.log(formatScore(85)); // '85/100' console.log(formatScore(85, { showGrade: true })); // '85/100 (B)'

Signature:

function formatScore( score: number, options?: { showGrade?: boolean } ): string;

Cache Utilities

createCache

Create a cache instance:

import { createCache } from '@capyseo/core'; const cache = createCache({ dir: '.capyseo-cache', ttl: 86400000, // 24 hours }); await cache.set('key', 'value'); const value = await cache.get('key');

Signature:

function createCache(options: CacheOptions): Cache; interface CacheOptions { dir: string; ttl: number; } interface Cache { get<T>(key: string): Promise<T | undefined>; set<T>(key: string, value: T): Promise<void>; has(key: string): Promise<boolean>; delete(key: string): Promise<void>; clear(): Promise<void>; }

Async Utilities

parallel

Run functions in parallel with concurrency limit:

import { parallel } from '@capyseo/core'; const urls = ['page1.html', 'page2.html', 'page3.html']; const results = await parallel( urls, async (url) => analyzeFile(url), { concurrency: 2 } );

Signature:

function parallel<T, R>( items: T[], fn: (item: T) => Promise<R>, options?: { concurrency?: number } ): Promise<R[]>;

retry

Retry function with exponential backoff:

import { retry } from '@capyseo/core'; const result = await retry( () => fetchAPI(), { maxAttempts: 3, delay: 1000 } );

Signature:

function retry<T>( fn: () => Promise<T>, options?: { maxAttempts?: number; delay?: number; backoff?: number; } ): Promise<T>;

Complete Example

import { loadConfig, findHTMLFiles, readHTMLFile, loadHTML, extractMetadata, countWords, calculateScore, formatScore, } from '@capyseo/core'; async function customAnalysis(dir: string) { // Load config const config = await loadConfig(); // Find files const files = await findHTMLFiles(dir); for (const file of files) { // Read and parse const html = await readHTMLFile(file); const $ = loadHTML(html); const metadata = extractMetadata(html); // Analyze const words = countWords($('body').text()); const issues = []; if (!metadata.title) { issues.push({ ruleId: 'meta-title', message: 'Missing title', severity: 'error' as const, }); } if (words < 300) { issues.push({ ruleId: 'word-count', message: `Only ${words} words`, severity: 'warning' as const, }); } // Score const score = calculateScore(issues); console.log(`${file}: ${formatScore(score, { showGrade: true })}`); } }