recker 1.0.27-next.8396df6 → 1.0.28-next.32fe8ef
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/dist/browser/scrape/extractors.js +2 -1
- package/dist/browser/scrape/types.d.ts +2 -1
- package/dist/cli/index.js +47 -3
- package/dist/cli/tui/shell.d.ts +1 -0
- package/dist/cli/tui/shell.js +157 -0
- package/dist/scrape/extractors.js +2 -1
- package/dist/scrape/types.d.ts +2 -1
- package/dist/seo/analyzer.d.ts +32 -10
- package/dist/seo/analyzer.js +557 -386
- package/dist/seo/index.d.ts +4 -1
- package/dist/seo/index.js +1 -0
- package/dist/seo/rules/accessibility.d.ts +2 -0
- package/dist/seo/rules/accessibility.js +128 -0
- package/dist/seo/rules/content.d.ts +2 -0
- package/dist/seo/rules/content.js +236 -0
- package/dist/seo/rules/images.d.ts +2 -0
- package/dist/seo/rules/images.js +180 -0
- package/dist/seo/rules/index.d.ts +20 -0
- package/dist/seo/rules/index.js +72 -0
- package/dist/seo/rules/links.d.ts +2 -0
- package/dist/seo/rules/links.js +150 -0
- package/dist/seo/rules/meta.d.ts +2 -0
- package/dist/seo/rules/meta.js +523 -0
- package/dist/seo/rules/mobile.d.ts +2 -0
- package/dist/seo/rules/mobile.js +71 -0
- package/dist/seo/rules/performance.d.ts +2 -0
- package/dist/seo/rules/performance.js +246 -0
- package/dist/seo/rules/schema.d.ts +2 -0
- package/dist/seo/rules/schema.js +54 -0
- package/dist/seo/rules/security.d.ts +2 -0
- package/dist/seo/rules/security.js +147 -0
- package/dist/seo/rules/structural.d.ts +2 -0
- package/dist/seo/rules/structural.js +155 -0
- package/dist/seo/rules/technical.d.ts +2 -0
- package/dist/seo/rules/technical.js +223 -0
- package/dist/seo/rules/thresholds.d.ts +196 -0
- package/dist/seo/rules/thresholds.js +118 -0
- package/dist/seo/rules/types.d.ts +191 -0
- package/dist/seo/rules/types.js +11 -0
- package/dist/seo/types.d.ts +61 -1
- package/package.json +1 -1
|
@@ -76,6 +76,7 @@ export function extractImages($, options) {
|
|
|
76
76
|
height: height ? parseInt(height, 10) : undefined,
|
|
77
77
|
srcset: $el.attr('srcset'),
|
|
78
78
|
loading: $el.attr('loading'),
|
|
79
|
+
decoding: $el.attr('decoding'),
|
|
79
80
|
});
|
|
80
81
|
});
|
|
81
82
|
return images;
|
|
@@ -117,7 +118,7 @@ export function extractMeta($) {
|
|
|
117
118
|
meta.author = content;
|
|
118
119
|
break;
|
|
119
120
|
case 'robots':
|
|
120
|
-
meta.robots = content;
|
|
121
|
+
meta.robots = content.split(',').map((r) => r.trim().toLowerCase());
|
|
121
122
|
break;
|
|
122
123
|
case 'viewport':
|
|
123
124
|
meta.viewport = content;
|
|
@@ -14,13 +14,14 @@ export interface ExtractedImage {
|
|
|
14
14
|
height?: number;
|
|
15
15
|
srcset?: string;
|
|
16
16
|
loading?: 'lazy' | 'eager';
|
|
17
|
+
decoding?: 'async' | 'auto' | 'sync';
|
|
17
18
|
}
|
|
18
19
|
export interface ExtractedMeta {
|
|
19
20
|
title?: string;
|
|
20
21
|
description?: string;
|
|
21
22
|
keywords?: string[];
|
|
22
23
|
author?: string;
|
|
23
|
-
robots?: string;
|
|
24
|
+
robots?: string[];
|
|
24
25
|
canonical?: string;
|
|
25
26
|
viewport?: string;
|
|
26
27
|
charset?: string;
|
package/dist/cli/index.js
CHANGED
|
@@ -393,10 +393,13 @@ ${colors.bold('Details:')}`);
|
|
|
393
393
|
.description('Analyze page SEO (title, meta, headings, links, images, structured data)')
|
|
394
394
|
.argument('<url>', 'URL to analyze')
|
|
395
395
|
.option('-a, --all', 'Show all checks including passed ones')
|
|
396
|
+
.option('--format <format>', 'Output format: text (default) or json', 'text')
|
|
396
397
|
.addHelpText('after', `
|
|
397
398
|
${colors.bold(colors.yellow('Examples:'))}
|
|
398
|
-
${colors.green('$ rek seo example.com')}
|
|
399
|
-
${colors.green('$ rek seo example.com -a')}
|
|
399
|
+
${colors.green('$ rek seo example.com')} ${colors.gray('Basic SEO analysis')}
|
|
400
|
+
${colors.green('$ rek seo example.com -a')} ${colors.gray('Show all checks')}
|
|
401
|
+
${colors.green('$ rek seo example.com --format json')} ${colors.gray('Output as JSON')}
|
|
402
|
+
${colors.green('$ rek seo example.com --format json | jq')} ${colors.gray('Pipe to jq for processing')}
|
|
400
403
|
|
|
401
404
|
${colors.bold(colors.yellow('Checks:'))}
|
|
402
405
|
${colors.cyan('Title Tag')} Length and presence
|
|
@@ -412,14 +415,45 @@ ${colors.bold(colors.yellow('Checks:'))}
|
|
|
412
415
|
.action(async (url, options) => {
|
|
413
416
|
if (!url.startsWith('http'))
|
|
414
417
|
url = `https://${url}`;
|
|
418
|
+
const isJson = options.format === 'json';
|
|
415
419
|
const { createClient } = await import('../core/client.js');
|
|
416
420
|
const { analyzeSeo } = await import('../seo/analyzer.js');
|
|
417
|
-
|
|
421
|
+
if (!isJson) {
|
|
422
|
+
console.log(colors.gray(`Analyzing SEO for ${url}...`));
|
|
423
|
+
}
|
|
418
424
|
try {
|
|
419
425
|
const client = createClient({ timeout: 30000 });
|
|
420
426
|
const res = await client.get(url);
|
|
421
427
|
const html = await res.text();
|
|
422
428
|
const report = await analyzeSeo(html, { baseUrl: url });
|
|
429
|
+
if (isJson) {
|
|
430
|
+
const jsonOutput = {
|
|
431
|
+
url,
|
|
432
|
+
analyzedAt: new Date().toISOString(),
|
|
433
|
+
score: report.score,
|
|
434
|
+
grade: report.grade,
|
|
435
|
+
title: report.title,
|
|
436
|
+
metaDescription: report.metaDescription,
|
|
437
|
+
content: report.content,
|
|
438
|
+
headings: report.headings,
|
|
439
|
+
links: report.links,
|
|
440
|
+
images: report.images,
|
|
441
|
+
openGraph: report.social.openGraph,
|
|
442
|
+
twitterCard: report.social.twitterCard,
|
|
443
|
+
jsonLd: report.jsonLd,
|
|
444
|
+
technical: report.technical,
|
|
445
|
+
checks: report.checks,
|
|
446
|
+
summary: {
|
|
447
|
+
total: report.checks.length,
|
|
448
|
+
passed: report.checks.filter(c => c.status === 'pass').length,
|
|
449
|
+
warnings: report.checks.filter(c => c.status === 'warn').length,
|
|
450
|
+
errors: report.checks.filter(c => c.status === 'fail').length,
|
|
451
|
+
info: report.checks.filter(c => c.status === 'info').length,
|
|
452
|
+
},
|
|
453
|
+
};
|
|
454
|
+
console.log(JSON.stringify(jsonOutput, null, 2));
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
423
457
|
let gradeColor = colors.red;
|
|
424
458
|
if (report.grade === 'A')
|
|
425
459
|
gradeColor = colors.green;
|
|
@@ -463,6 +497,16 @@ ${colors.gray('Grade:')} ${gradeColor(colors.bold(report.grade))} ${colors.gray
|
|
|
463
497
|
if (check.recommendation && check.status !== 'pass') {
|
|
464
498
|
console.log(` ${colors.gray('→')} ${colors.gray(check.recommendation)}`);
|
|
465
499
|
}
|
|
500
|
+
const evidence = check.evidence;
|
|
501
|
+
if (evidence && check.status !== 'pass') {
|
|
502
|
+
if (evidence.found && Array.isArray(evidence.found) && evidence.found.length > 0) {
|
|
503
|
+
const items = evidence.found.slice(0, 3);
|
|
504
|
+
console.log(` ${colors.gray('Found:')} ${colors.red(items.join(', '))}${evidence.found.length > 3 ? ` (+${evidence.found.length - 3} more)` : ''}`);
|
|
505
|
+
}
|
|
506
|
+
if (evidence.example) {
|
|
507
|
+
console.log(` ${colors.gray('Example:')} ${colors.cyan(evidence.example.split('\n')[0])}`);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
466
510
|
}
|
|
467
511
|
}
|
|
468
512
|
console.log('');
|
package/dist/cli/tui/shell.d.ts
CHANGED
package/dist/cli/tui/shell.js
CHANGED
|
@@ -14,6 +14,7 @@ import colors from '../../utils/colors.js';
|
|
|
14
14
|
import { getShellSearch } from './shell-search.js';
|
|
15
15
|
import { openSearchPanel } from './search-panel.js';
|
|
16
16
|
import { ScrollBuffer, parseScrollKey, parseMouseScroll, disableMouseReporting } from './scroll-buffer.js';
|
|
17
|
+
import { analyzeSeo } from '../../seo/index.js';
|
|
17
18
|
let highlight;
|
|
18
19
|
async function initDependencies() {
|
|
19
20
|
if (!highlight) {
|
|
@@ -343,6 +344,9 @@ export class RekShell {
|
|
|
343
344
|
case 'security':
|
|
344
345
|
await this.runSecurityGrader(parts[1]);
|
|
345
346
|
return;
|
|
347
|
+
case 'seo':
|
|
348
|
+
await this.runSeo(parts[1], parts.includes('-a') || parts.includes('--all'), parts.includes('--format') && parts[parts.indexOf('--format') + 1] === 'json');
|
|
349
|
+
return;
|
|
346
350
|
case 'ip':
|
|
347
351
|
await this.runIpIntelligence(parts[1]);
|
|
348
352
|
return;
|
|
@@ -944,6 +948,156 @@ ${colors.bold('Details:')}`);
|
|
|
944
948
|
}
|
|
945
949
|
console.log('');
|
|
946
950
|
}
|
|
951
|
+
async runSeo(url, showAll = false, jsonOutput = false) {
|
|
952
|
+
if (!url) {
|
|
953
|
+
url = this.currentDocUrl || this.baseUrl || '';
|
|
954
|
+
if (!url) {
|
|
955
|
+
console.log(colors.yellow('Usage: seo <url> [-a] [--format json]'));
|
|
956
|
+
console.log(colors.gray(' Examples: seo google.com | seo https://example.com -a'));
|
|
957
|
+
console.log(colors.gray(' -a, --all Show all checks (including passed)'));
|
|
958
|
+
console.log(colors.gray(' --format json Output raw JSON for programmatic use'));
|
|
959
|
+
console.log(colors.gray(' Or set a base URL first: url https://example.com'));
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
else if (!url.startsWith('http') && !url.startsWith('-')) {
|
|
964
|
+
url = `https://${url}`;
|
|
965
|
+
}
|
|
966
|
+
if (!jsonOutput) {
|
|
967
|
+
console.log(colors.gray(`Analyzing SEO for ${url}...`));
|
|
968
|
+
}
|
|
969
|
+
const startTime = performance.now();
|
|
970
|
+
try {
|
|
971
|
+
const res = await this.client.get(url);
|
|
972
|
+
const html = await res.text();
|
|
973
|
+
const duration = Math.round(performance.now() - startTime);
|
|
974
|
+
const report = await analyzeSeo(html, { baseUrl: url });
|
|
975
|
+
if (jsonOutput) {
|
|
976
|
+
const jsonResult = {
|
|
977
|
+
url,
|
|
978
|
+
analyzedAt: new Date().toISOString(),
|
|
979
|
+
durationMs: duration,
|
|
980
|
+
score: report.score,
|
|
981
|
+
grade: report.grade,
|
|
982
|
+
title: report.title,
|
|
983
|
+
metaDescription: report.metaDescription,
|
|
984
|
+
content: report.content,
|
|
985
|
+
headings: report.headings,
|
|
986
|
+
links: report.links,
|
|
987
|
+
images: report.images,
|
|
988
|
+
openGraph: report.social.openGraph,
|
|
989
|
+
twitterCard: report.social.twitterCard,
|
|
990
|
+
jsonLd: report.jsonLd,
|
|
991
|
+
technical: report.technical,
|
|
992
|
+
checks: report.checks,
|
|
993
|
+
summary: {
|
|
994
|
+
total: report.checks.length,
|
|
995
|
+
passed: report.checks.filter(c => c.status === 'pass').length,
|
|
996
|
+
warnings: report.checks.filter(c => c.status === 'warn').length,
|
|
997
|
+
errors: report.checks.filter(c => c.status === 'fail').length,
|
|
998
|
+
info: report.checks.filter(c => c.status === 'info').length,
|
|
999
|
+
},
|
|
1000
|
+
};
|
|
1001
|
+
console.log(JSON.stringify(jsonResult, null, 2));
|
|
1002
|
+
this.lastResponse = jsonResult;
|
|
1003
|
+
return;
|
|
1004
|
+
}
|
|
1005
|
+
let gradeColor = colors.red;
|
|
1006
|
+
if (report.grade === 'A')
|
|
1007
|
+
gradeColor = colors.green;
|
|
1008
|
+
else if (report.grade === 'B')
|
|
1009
|
+
gradeColor = colors.blue;
|
|
1010
|
+
else if (report.grade === 'C')
|
|
1011
|
+
gradeColor = colors.yellow;
|
|
1012
|
+
else if (report.grade === 'D')
|
|
1013
|
+
gradeColor = colors.magenta;
|
|
1014
|
+
console.log(`
|
|
1015
|
+
${colors.bold(colors.cyan('🔍 SEO Analysis Report'))} ${colors.gray(`(${duration}ms)`)}
|
|
1016
|
+
Grade: ${gradeColor(colors.bold(report.grade))} (${report.score}/100)
|
|
1017
|
+
`);
|
|
1018
|
+
if (report.title) {
|
|
1019
|
+
console.log(colors.bold('Title:') + ` ${report.title.text} ` + colors.gray(`(${report.title.length} chars)`));
|
|
1020
|
+
}
|
|
1021
|
+
if (report.metaDescription) {
|
|
1022
|
+
const desc = report.metaDescription.text.length > 80
|
|
1023
|
+
? report.metaDescription.text.slice(0, 77) + '...'
|
|
1024
|
+
: report.metaDescription.text;
|
|
1025
|
+
console.log(colors.bold('Description:') + ` ${desc} ` + colors.gray(`(${report.metaDescription.length} chars)`));
|
|
1026
|
+
}
|
|
1027
|
+
if (report.content) {
|
|
1028
|
+
console.log(colors.bold('Content:') + ` ${report.content.wordCount} words, ${report.content.paragraphCount} paragraphs, ~${report.content.readingTimeMinutes} min read`);
|
|
1029
|
+
}
|
|
1030
|
+
console.log('');
|
|
1031
|
+
console.log(colors.bold('Checks:'));
|
|
1032
|
+
const checksToShow = showAll
|
|
1033
|
+
? report.checks
|
|
1034
|
+
: report.checks.filter(c => c.status !== 'pass');
|
|
1035
|
+
const failed = checksToShow.filter(c => c.status === 'fail');
|
|
1036
|
+
const warnings = checksToShow.filter(c => c.status === 'warn');
|
|
1037
|
+
const info = checksToShow.filter(c => c.status === 'info');
|
|
1038
|
+
const passed = showAll ? checksToShow.filter(c => c.status === 'pass') : [];
|
|
1039
|
+
const displayCheck = (check) => {
|
|
1040
|
+
let icon;
|
|
1041
|
+
let nameColor;
|
|
1042
|
+
switch (check.status) {
|
|
1043
|
+
case 'pass':
|
|
1044
|
+
icon = colors.green('✔');
|
|
1045
|
+
nameColor = colors.green;
|
|
1046
|
+
break;
|
|
1047
|
+
case 'warn':
|
|
1048
|
+
icon = colors.yellow('⚠');
|
|
1049
|
+
nameColor = colors.yellow;
|
|
1050
|
+
break;
|
|
1051
|
+
case 'fail':
|
|
1052
|
+
icon = colors.red('✖');
|
|
1053
|
+
nameColor = colors.red;
|
|
1054
|
+
break;
|
|
1055
|
+
default:
|
|
1056
|
+
icon = colors.blue('ℹ');
|
|
1057
|
+
nameColor = colors.blue;
|
|
1058
|
+
}
|
|
1059
|
+
console.log(` ${icon} ${nameColor(check.name.padEnd(22))} ${check.message}`);
|
|
1060
|
+
if (check.recommendation && check.status !== 'pass') {
|
|
1061
|
+
console.log(` ${colors.gray('→')} ${colors.gray(check.recommendation)}`);
|
|
1062
|
+
}
|
|
1063
|
+
const evidence = check.evidence;
|
|
1064
|
+
if (evidence && check.status !== 'pass') {
|
|
1065
|
+
if (evidence.found && Array.isArray(evidence.found) && evidence.found.length > 0) {
|
|
1066
|
+
const items = evidence.found.slice(0, 3);
|
|
1067
|
+
console.log(` ${colors.gray('Found:')} ${colors.red(items.join(', '))}${evidence.found.length > 3 ? ` (+${evidence.found.length - 3} more)` : ''}`);
|
|
1068
|
+
}
|
|
1069
|
+
if (evidence.example) {
|
|
1070
|
+
console.log(` ${colors.gray('Example:')} ${colors.cyan(evidence.example.split('\n')[0])}`);
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
};
|
|
1074
|
+
if (failed.length > 0) {
|
|
1075
|
+
console.log(colors.red(`\n Errors (${failed.length}):`));
|
|
1076
|
+
failed.forEach(displayCheck);
|
|
1077
|
+
}
|
|
1078
|
+
if (warnings.length > 0) {
|
|
1079
|
+
console.log(colors.yellow(`\n Warnings (${warnings.length}):`));
|
|
1080
|
+
warnings.forEach(displayCheck);
|
|
1081
|
+
}
|
|
1082
|
+
if (info.length > 0) {
|
|
1083
|
+
console.log(colors.blue(`\n Info (${info.length}):`));
|
|
1084
|
+
info.forEach(displayCheck);
|
|
1085
|
+
}
|
|
1086
|
+
if (passed.length > 0) {
|
|
1087
|
+
console.log(colors.green(`\n Passed (${passed.length}):`));
|
|
1088
|
+
passed.forEach(displayCheck);
|
|
1089
|
+
}
|
|
1090
|
+
if (!showAll && report.checks.filter(c => c.status === 'pass').length > 0) {
|
|
1091
|
+
console.log(colors.gray(`\n ${report.checks.filter(c => c.status === 'pass').length} checks passed. Use -a to show all.`));
|
|
1092
|
+
}
|
|
1093
|
+
console.log('');
|
|
1094
|
+
this.lastResponse = report;
|
|
1095
|
+
}
|
|
1096
|
+
catch (error) {
|
|
1097
|
+
console.error(colors.red(`SEO analysis failed: ${error.message}`));
|
|
1098
|
+
}
|
|
1099
|
+
console.log('');
|
|
1100
|
+
}
|
|
947
1101
|
async runIpIntelligence(address) {
|
|
948
1102
|
if (!address) {
|
|
949
1103
|
console.log(colors.yellow('Usage: ip <address>'));
|
|
@@ -2182,6 +2336,9 @@ ${colors.bold('Network:')}
|
|
|
2182
2336
|
${colors.green('dns <domain>')} Full DNS lookup (A, AAAA, MX, NS, SPF, DMARC).
|
|
2183
2337
|
${colors.green('rdap <domain>')} RDAP lookup (modern WHOIS).
|
|
2184
2338
|
${colors.green('ping <host>')} Quick TCP connectivity check.
|
|
2339
|
+
${colors.green('seo <url> [-a] [--format json]')} SEO analysis (70+ rules).
|
|
2340
|
+
${colors.gray('-a, --all Show all checks including passed')}
|
|
2341
|
+
${colors.gray('--format json Output raw JSON for programmatic use')}
|
|
2185
2342
|
|
|
2186
2343
|
${colors.bold('Web Scraping:')}
|
|
2187
2344
|
${colors.green('scrap <url>')} Fetch and parse HTML document.
|
|
@@ -76,6 +76,7 @@ export function extractImages($, options) {
|
|
|
76
76
|
height: height ? parseInt(height, 10) : undefined,
|
|
77
77
|
srcset: $el.attr('srcset'),
|
|
78
78
|
loading: $el.attr('loading'),
|
|
79
|
+
decoding: $el.attr('decoding'),
|
|
79
80
|
});
|
|
80
81
|
});
|
|
81
82
|
return images;
|
|
@@ -117,7 +118,7 @@ export function extractMeta($) {
|
|
|
117
118
|
meta.author = content;
|
|
118
119
|
break;
|
|
119
120
|
case 'robots':
|
|
120
|
-
meta.robots = content;
|
|
121
|
+
meta.robots = content.split(',').map((r) => r.trim().toLowerCase());
|
|
121
122
|
break;
|
|
122
123
|
case 'viewport':
|
|
123
124
|
meta.viewport = content;
|
package/dist/scrape/types.d.ts
CHANGED
|
@@ -14,13 +14,14 @@ export interface ExtractedImage {
|
|
|
14
14
|
height?: number;
|
|
15
15
|
srcset?: string;
|
|
16
16
|
loading?: 'lazy' | 'eager';
|
|
17
|
+
decoding?: 'async' | 'auto' | 'sync';
|
|
17
18
|
}
|
|
18
19
|
export interface ExtractedMeta {
|
|
19
20
|
title?: string;
|
|
20
21
|
description?: string;
|
|
21
22
|
keywords?: string[];
|
|
22
23
|
author?: string;
|
|
23
|
-
robots?: string;
|
|
24
|
+
robots?: string[];
|
|
24
25
|
canonical?: string;
|
|
25
26
|
viewport?: string;
|
|
26
27
|
charset?: string;
|
package/dist/seo/analyzer.d.ts
CHANGED
|
@@ -1,20 +1,42 @@
|
|
|
1
1
|
import type { CheerioAPI } from 'cheerio';
|
|
2
2
|
import type { SeoReport, SeoAnalyzerOptions } from './types.js';
|
|
3
|
+
import { type RulesEngineOptions } from './rules/index.js';
|
|
4
|
+
export interface SeoAnalyzerFullOptions extends SeoAnalyzerOptions {
|
|
5
|
+
rules?: RulesEngineOptions;
|
|
6
|
+
}
|
|
3
7
|
export declare class SeoAnalyzer {
|
|
4
8
|
private $;
|
|
5
9
|
private options;
|
|
6
|
-
|
|
7
|
-
|
|
10
|
+
private rulesEngine;
|
|
11
|
+
constructor($: CheerioAPI, options?: SeoAnalyzerFullOptions);
|
|
12
|
+
static fromHtml(html: string, options?: SeoAnalyzerFullOptions): Promise<SeoAnalyzer>;
|
|
8
13
|
analyze(): SeoReport;
|
|
9
|
-
private
|
|
10
|
-
private
|
|
14
|
+
private buildRuleContext;
|
|
15
|
+
private analyzeUrlQuality;
|
|
16
|
+
private analyzeJsRendering;
|
|
17
|
+
private checkMixedContent;
|
|
18
|
+
private analyzeLinkSecurity;
|
|
19
|
+
private detectFavicon;
|
|
20
|
+
private analyzePerformanceHints;
|
|
21
|
+
private analyzeCWVHints;
|
|
22
|
+
private analyzeAccessibility;
|
|
23
|
+
private analyzeStructuralHtml;
|
|
24
|
+
private analyzeBreadcrumbs;
|
|
25
|
+
private analyzeMultimedia;
|
|
26
|
+
private analyzeTrustSignals;
|
|
27
|
+
private calculateTextHtmlRatio;
|
|
28
|
+
private convertToCheckResults;
|
|
11
29
|
private analyzeHeadings;
|
|
12
30
|
private analyzeContent;
|
|
13
|
-
private
|
|
14
|
-
private
|
|
15
|
-
private
|
|
16
|
-
private
|
|
17
|
-
private analyzeJsonLd;
|
|
31
|
+
private buildLinkAnalysis;
|
|
32
|
+
private buildImageAnalysis;
|
|
33
|
+
private buildSocialAnalysis;
|
|
34
|
+
private buildTechnicalAnalysis;
|
|
18
35
|
private calculateScore;
|
|
36
|
+
getRules(): import("./rules/types.js").SeoRule[];
|
|
37
|
+
getRulesByCategory(category: string): import("./rules/types.js").SeoRule[];
|
|
38
|
+
getCategories(): import("./rules/types.js").RuleCategory[];
|
|
19
39
|
}
|
|
20
|
-
export declare function analyzeSeo(html: string, options?:
|
|
40
|
+
export declare function analyzeSeo(html: string, options?: SeoAnalyzerFullOptions): Promise<SeoReport>;
|
|
41
|
+
export { SEO_THRESHOLDS, createRulesEngine, SeoRulesEngine } from './rules/index.js';
|
|
42
|
+
export type { RuleContext, RuleResult, RulesEngineOptions, RuleCategory, RuleSeverity, SeoRule } from './rules/index.js';
|