Skip to main content
Glama
lighthouse-adapter.ts3.24 kB
import lighthouse from 'lighthouse'; import type { Result as LighthouseResult } from 'lighthouse'; import type { LighthouseResult as AuditLighthouseResult } from '../types/audit.js'; import { resolveUrl, type ResolvedUrl } from '../utils/url-resolver.js'; export interface LighthouseAdapterOptions { timeout?: number; categories?: string[]; onlyCategories?: string[]; skipAudits?: string[]; } export class LighthouseAdapter { private readonly timeout: number; constructor(options: LighthouseAdapterOptions = {}) { this.timeout = options.timeout ?? 60000; } async audit(urlOrPath: string, options?: LighthouseAdapterOptions): Promise<AuditLighthouseResult> { const resolved: ResolvedUrl = await resolveUrl(urlOrPath); const chromeFlags = ['--headless', '--no-sandbox']; const config: { extends?: string; categories?: Record<string, { title: string }>; onlyCategories?: string[]; skipAudits?: string[]; } = { extends: 'lighthouse:default', }; if (options?.onlyCategories) { config.onlyCategories = options.onlyCategories; } else if (options?.categories) { config.onlyCategories = options.categories; } if (options?.skipAudits) { config.skipAudits = options.skipAudits; } let result: LighthouseResult | null = null; try { result = await lighthouse(resolved.url, { port: 9222, chromeFlags, logLevel: 'error', output: 'json', onlyCategories: config.onlyCategories, skipAudits: config.skipAudits, }); } finally { if (resolved.cleanup) { await resolved.cleanup(); } } if (!result) { throw new Error('Lighthouse audit returned no result'); } return this.transformResult(result); } private transformResult(result: LighthouseResult): AuditLighthouseResult { return { url: result.lhr.finalUrl, fetchTime: result.lhr.fetchTime, audits: Object.entries(result.lhr.audits).reduce((acc, [key, audit]) => { acc[key] = { id: audit.id, title: audit.title, description: audit.description, score: audit.score, scoreDisplayMode: audit.scoreDisplayMode, displayValue: audit.displayValue, details: audit.details ? { type: audit.details.type, headings: audit.details.headings, items: audit.details.items, nodes: audit.details.nodes, } : undefined, }; return acc; }, {} as Record<string, AuditLighthouseResult['audits'][string]>), categories: Object.entries(result.lhr.categories).reduce((acc, [key, category]) => { acc[key] = { id: category.id, title: category.title, score: category.score, description: category.description, manualDescription: category.manualDescription, auditRefs: category.auditRefs.map((ref) => ({ id: ref.id, weight: ref.weight, group: ref.group, })), }; return acc; }, {} as Record<string, AuditLighthouseResult['categories'][string]>), }; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Duds/accessibility-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server