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 })}`);
}
}