recker 1.0.27 → 1.0.28-next.c61382b
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 +142 -3
- package/dist/cli/tui/shell.d.ts +1 -0
- package/dist/cli/tui/shell.js +157 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/scrape/extractors.js +2 -1
- package/dist/scrape/types.d.ts +2 -1
- package/dist/seo/analyzer.d.ts +42 -0
- package/dist/seo/analyzer.js +727 -0
- package/dist/seo/index.d.ts +5 -0
- package/dist/seo/index.js +2 -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/crawl.d.ts +2 -0
- package/dist/seo/rules/crawl.js +307 -0
- package/dist/seo/rules/cwv.d.ts +2 -0
- package/dist/seo/rules/cwv.js +337 -0
- package/dist/seo/rules/ecommerce.d.ts +2 -0
- package/dist/seo/rules/ecommerce.js +252 -0
- package/dist/seo/rules/i18n.d.ts +2 -0
- package/dist/seo/rules/i18n.js +222 -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 +52 -0
- package/dist/seo/rules/index.js +135 -0
- package/dist/seo/rules/links.d.ts +2 -0
- package/dist/seo/rules/links.js +150 -0
- package/dist/seo/rules/local.d.ts +2 -0
- package/dist/seo/rules/local.js +265 -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/readability.d.ts +2 -0
- package/dist/seo/rules/readability.js +255 -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 +286 -0
- package/dist/seo/rules/types.js +11 -0
- package/dist/seo/types.d.ts +160 -0
- package/dist/seo/types.js +1 -0
- package/dist/utils/columns.d.ts +14 -0
- package/dist/utils/columns.js +69 -0
- package/package.json +1 -1
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
export declare const SEO_THRESHOLDS: {
|
|
2
|
+
readonly title: {
|
|
3
|
+
readonly min: 30;
|
|
4
|
+
readonly ideal: {
|
|
5
|
+
readonly min: 50;
|
|
6
|
+
readonly max: 60;
|
|
7
|
+
};
|
|
8
|
+
readonly max: 70;
|
|
9
|
+
};
|
|
10
|
+
readonly metaDescription: {
|
|
11
|
+
readonly min: 70;
|
|
12
|
+
readonly ideal: {
|
|
13
|
+
readonly min: 120;
|
|
14
|
+
readonly max: 155;
|
|
15
|
+
};
|
|
16
|
+
readonly max: 160;
|
|
17
|
+
};
|
|
18
|
+
readonly og: {
|
|
19
|
+
readonly title: {
|
|
20
|
+
readonly min: 30;
|
|
21
|
+
readonly ideal: {
|
|
22
|
+
readonly min: 40;
|
|
23
|
+
readonly max: 60;
|
|
24
|
+
};
|
|
25
|
+
readonly max: 90;
|
|
26
|
+
};
|
|
27
|
+
readonly description: {
|
|
28
|
+
readonly min: 55;
|
|
29
|
+
readonly ideal: {
|
|
30
|
+
readonly min: 110;
|
|
31
|
+
readonly max: 155;
|
|
32
|
+
};
|
|
33
|
+
readonly max: 200;
|
|
34
|
+
};
|
|
35
|
+
readonly image: {
|
|
36
|
+
readonly dimensions: {
|
|
37
|
+
readonly width: 1200;
|
|
38
|
+
readonly height: 630;
|
|
39
|
+
};
|
|
40
|
+
readonly minDimensions: {
|
|
41
|
+
readonly width: 600;
|
|
42
|
+
readonly height: 315;
|
|
43
|
+
};
|
|
44
|
+
readonly ratio: 1.91;
|
|
45
|
+
readonly maxSizeKb: 300;
|
|
46
|
+
readonly maxSizeKbAbsolute: 1000;
|
|
47
|
+
readonly formats: readonly ["jpg", "jpeg", "png", "webp"];
|
|
48
|
+
};
|
|
49
|
+
readonly meta: {
|
|
50
|
+
readonly maxUrlLength: 2000;
|
|
51
|
+
readonly maxDescriptionEmojis: 2;
|
|
52
|
+
readonly maxCapsPercentage: 30;
|
|
53
|
+
};
|
|
54
|
+
readonly fallbacks: {
|
|
55
|
+
readonly requireMetaTitle: true;
|
|
56
|
+
readonly requireMetaDescription: true;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
readonly twitter: {
|
|
60
|
+
readonly title: {
|
|
61
|
+
readonly min: 30;
|
|
62
|
+
readonly ideal: {
|
|
63
|
+
readonly min: 40;
|
|
64
|
+
readonly max: 55;
|
|
65
|
+
};
|
|
66
|
+
readonly max: 70;
|
|
67
|
+
};
|
|
68
|
+
readonly description: {
|
|
69
|
+
readonly min: 70;
|
|
70
|
+
readonly ideal: {
|
|
71
|
+
readonly min: 125;
|
|
72
|
+
readonly max: 200;
|
|
73
|
+
};
|
|
74
|
+
readonly max: 200;
|
|
75
|
+
};
|
|
76
|
+
readonly image: {
|
|
77
|
+
readonly summary: {
|
|
78
|
+
readonly min: {
|
|
79
|
+
readonly width: 144;
|
|
80
|
+
readonly height: 144;
|
|
81
|
+
};
|
|
82
|
+
readonly max: {
|
|
83
|
+
readonly width: 4096;
|
|
84
|
+
readonly height: 4096;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
readonly summaryLarge: {
|
|
88
|
+
readonly min: {
|
|
89
|
+
readonly width: 300;
|
|
90
|
+
readonly height: 157;
|
|
91
|
+
};
|
|
92
|
+
readonly max: {
|
|
93
|
+
readonly width: 4096;
|
|
94
|
+
readonly height: 4096;
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
readonly maxSizeMb: 5;
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
readonly headings: {
|
|
101
|
+
readonly h1: {
|
|
102
|
+
readonly count: 1;
|
|
103
|
+
readonly minLength: 20;
|
|
104
|
+
readonly maxLength: 70;
|
|
105
|
+
};
|
|
106
|
+
readonly h2: {
|
|
107
|
+
readonly min: 2;
|
|
108
|
+
readonly max: 8;
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
readonly images: {
|
|
112
|
+
readonly alt: {
|
|
113
|
+
readonly minLength: 10;
|
|
114
|
+
readonly idealLength: {
|
|
115
|
+
readonly min: 80;
|
|
116
|
+
readonly max: 120;
|
|
117
|
+
};
|
|
118
|
+
readonly maxLength: 150;
|
|
119
|
+
};
|
|
120
|
+
readonly maxSizeKb: 100;
|
|
121
|
+
readonly maxSizeKbAcceptable: 500;
|
|
122
|
+
};
|
|
123
|
+
readonly links: {
|
|
124
|
+
readonly minInternal: 3;
|
|
125
|
+
readonly maxExternal: 100;
|
|
126
|
+
readonly genericTexts: readonly ["clique aqui", "click here", "saiba mais", "learn more", "read more", "leia mais", "here", "aqui"];
|
|
127
|
+
};
|
|
128
|
+
readonly content: {
|
|
129
|
+
readonly minWordsSimple: 150;
|
|
130
|
+
readonly minWordsRanking: 300;
|
|
131
|
+
readonly minWordsAuthority: 800;
|
|
132
|
+
readonly idealWordsAuthority: 2500;
|
|
133
|
+
readonly maxWordsPerSentence: 25;
|
|
134
|
+
readonly maxWordsPerParagraph: 90;
|
|
135
|
+
readonly minWordsPerParagraph: 40;
|
|
136
|
+
readonly minWordsPerH2Section: 150;
|
|
137
|
+
readonly minWordsPerH3Section: 50;
|
|
138
|
+
readonly imageWordRatio: {
|
|
139
|
+
readonly min: 200;
|
|
140
|
+
readonly max: 300;
|
|
141
|
+
};
|
|
142
|
+
readonly keywordDensity: {
|
|
143
|
+
readonly min: 0.8;
|
|
144
|
+
readonly max: 2;
|
|
145
|
+
};
|
|
146
|
+
readonly redundancyTolerance: 3;
|
|
147
|
+
};
|
|
148
|
+
readonly url: {
|
|
149
|
+
readonly maxLength: 75;
|
|
150
|
+
readonly maxLengthAbsolute: 2048;
|
|
151
|
+
};
|
|
152
|
+
readonly mobile: {
|
|
153
|
+
readonly minFontSize: 16;
|
|
154
|
+
readonly minTouchTarget: 48;
|
|
155
|
+
};
|
|
156
|
+
readonly thinContent: {
|
|
157
|
+
readonly minWords: 150;
|
|
158
|
+
readonly veryThinWords: 100;
|
|
159
|
+
};
|
|
160
|
+
readonly timing: {
|
|
161
|
+
readonly ttfb: {
|
|
162
|
+
readonly good: 200;
|
|
163
|
+
readonly needsImprovement: 500;
|
|
164
|
+
readonly poor: 600;
|
|
165
|
+
};
|
|
166
|
+
readonly total: {
|
|
167
|
+
readonly good: 1000;
|
|
168
|
+
readonly needsImprovement: 2500;
|
|
169
|
+
readonly poor: 4000;
|
|
170
|
+
};
|
|
171
|
+
readonly dnsLookup: {
|
|
172
|
+
readonly good: 50;
|
|
173
|
+
readonly poor: 200;
|
|
174
|
+
};
|
|
175
|
+
readonly tcpConnect: {
|
|
176
|
+
readonly good: 100;
|
|
177
|
+
readonly poor: 300;
|
|
178
|
+
};
|
|
179
|
+
readonly tlsHandshake: {
|
|
180
|
+
readonly good: 100;
|
|
181
|
+
readonly poor: 300;
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
readonly responseSize: {
|
|
185
|
+
readonly html: {
|
|
186
|
+
readonly good: number;
|
|
187
|
+
readonly warning: number;
|
|
188
|
+
readonly poor: number;
|
|
189
|
+
};
|
|
190
|
+
readonly total: {
|
|
191
|
+
readonly good: number;
|
|
192
|
+
readonly warning: number;
|
|
193
|
+
readonly poor: number;
|
|
194
|
+
};
|
|
195
|
+
};
|
|
196
|
+
};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
export const SEO_THRESHOLDS = {
|
|
2
|
+
title: {
|
|
3
|
+
min: 30,
|
|
4
|
+
ideal: { min: 50, max: 60 },
|
|
5
|
+
max: 70,
|
|
6
|
+
},
|
|
7
|
+
metaDescription: {
|
|
8
|
+
min: 70,
|
|
9
|
+
ideal: { min: 120, max: 155 },
|
|
10
|
+
max: 160,
|
|
11
|
+
},
|
|
12
|
+
og: {
|
|
13
|
+
title: { min: 30, ideal: { min: 40, max: 60 }, max: 90 },
|
|
14
|
+
description: { min: 55, ideal: { min: 110, max: 155 }, max: 200 },
|
|
15
|
+
image: {
|
|
16
|
+
dimensions: { width: 1200, height: 630 },
|
|
17
|
+
minDimensions: { width: 600, height: 315 },
|
|
18
|
+
ratio: 1.91,
|
|
19
|
+
maxSizeKb: 300,
|
|
20
|
+
maxSizeKbAbsolute: 1000,
|
|
21
|
+
formats: ['jpg', 'jpeg', 'png', 'webp'],
|
|
22
|
+
},
|
|
23
|
+
meta: {
|
|
24
|
+
maxUrlLength: 2000,
|
|
25
|
+
maxDescriptionEmojis: 2,
|
|
26
|
+
maxCapsPercentage: 30,
|
|
27
|
+
},
|
|
28
|
+
fallbacks: {
|
|
29
|
+
requireMetaTitle: true,
|
|
30
|
+
requireMetaDescription: true,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
twitter: {
|
|
34
|
+
title: { min: 30, ideal: { min: 40, max: 55 }, max: 70 },
|
|
35
|
+
description: { min: 70, ideal: { min: 125, max: 200 }, max: 200 },
|
|
36
|
+
image: {
|
|
37
|
+
summary: { min: { width: 144, height: 144 }, max: { width: 4096, height: 4096 } },
|
|
38
|
+
summaryLarge: { min: { width: 300, height: 157 }, max: { width: 4096, height: 4096 } },
|
|
39
|
+
maxSizeMb: 5,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
headings: {
|
|
43
|
+
h1: { count: 1, minLength: 20, maxLength: 70 },
|
|
44
|
+
h2: { min: 2, max: 8 },
|
|
45
|
+
},
|
|
46
|
+
images: {
|
|
47
|
+
alt: { minLength: 10, idealLength: { min: 80, max: 120 }, maxLength: 150 },
|
|
48
|
+
maxSizeKb: 100,
|
|
49
|
+
maxSizeKbAcceptable: 500,
|
|
50
|
+
},
|
|
51
|
+
links: {
|
|
52
|
+
minInternal: 3,
|
|
53
|
+
maxExternal: 100,
|
|
54
|
+
genericTexts: ['clique aqui', 'click here', 'saiba mais', 'learn more', 'read more', 'leia mais', 'here', 'aqui'],
|
|
55
|
+
},
|
|
56
|
+
content: {
|
|
57
|
+
minWordsSimple: 150,
|
|
58
|
+
minWordsRanking: 300,
|
|
59
|
+
minWordsAuthority: 800,
|
|
60
|
+
idealWordsAuthority: 2500,
|
|
61
|
+
maxWordsPerSentence: 25,
|
|
62
|
+
maxWordsPerParagraph: 90,
|
|
63
|
+
minWordsPerParagraph: 40,
|
|
64
|
+
minWordsPerH2Section: 150,
|
|
65
|
+
minWordsPerH3Section: 50,
|
|
66
|
+
imageWordRatio: { min: 200, max: 300 },
|
|
67
|
+
keywordDensity: { min: 0.8, max: 2.0 },
|
|
68
|
+
redundancyTolerance: 3,
|
|
69
|
+
},
|
|
70
|
+
url: {
|
|
71
|
+
maxLength: 75,
|
|
72
|
+
maxLengthAbsolute: 2048,
|
|
73
|
+
},
|
|
74
|
+
mobile: {
|
|
75
|
+
minFontSize: 16,
|
|
76
|
+
minTouchTarget: 48,
|
|
77
|
+
},
|
|
78
|
+
thinContent: {
|
|
79
|
+
minWords: 150,
|
|
80
|
+
veryThinWords: 100,
|
|
81
|
+
},
|
|
82
|
+
timing: {
|
|
83
|
+
ttfb: {
|
|
84
|
+
good: 200,
|
|
85
|
+
needsImprovement: 500,
|
|
86
|
+
poor: 600,
|
|
87
|
+
},
|
|
88
|
+
total: {
|
|
89
|
+
good: 1000,
|
|
90
|
+
needsImprovement: 2500,
|
|
91
|
+
poor: 4000,
|
|
92
|
+
},
|
|
93
|
+
dnsLookup: {
|
|
94
|
+
good: 50,
|
|
95
|
+
poor: 200,
|
|
96
|
+
},
|
|
97
|
+
tcpConnect: {
|
|
98
|
+
good: 100,
|
|
99
|
+
poor: 300,
|
|
100
|
+
},
|
|
101
|
+
tlsHandshake: {
|
|
102
|
+
good: 100,
|
|
103
|
+
poor: 300,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
responseSize: {
|
|
107
|
+
html: {
|
|
108
|
+
good: 100 * 1024,
|
|
109
|
+
warning: 500 * 1024,
|
|
110
|
+
poor: 1024 * 1024,
|
|
111
|
+
},
|
|
112
|
+
total: {
|
|
113
|
+
good: 1024 * 1024,
|
|
114
|
+
warning: 3 * 1024 * 1024,
|
|
115
|
+
poor: 5 * 1024 * 1024,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
};
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import type { SeoStatus } from '../types.js';
|
|
2
|
+
import type { ExtractedLink } from '../../scrape/types.js';
|
|
3
|
+
export type RuleSeverity = 'error' | 'warning' | 'info';
|
|
4
|
+
export type RuleCategory = 'title' | 'meta' | 'og' | 'twitter' | 'headings' | 'images' | 'links' | 'content' | 'technical' | 'security' | 'mobile' | 'structured-data' | 'performance' | 'accessibility';
|
|
5
|
+
export interface RuleContext {
|
|
6
|
+
title?: string;
|
|
7
|
+
titleLength?: number;
|
|
8
|
+
metaDescription?: string;
|
|
9
|
+
metaDescriptionLength?: number;
|
|
10
|
+
metaKeywords?: string[];
|
|
11
|
+
metaRobots?: string[];
|
|
12
|
+
ogTitle?: string;
|
|
13
|
+
ogDescription?: string;
|
|
14
|
+
ogImage?: string;
|
|
15
|
+
ogUrl?: string;
|
|
16
|
+
ogType?: string;
|
|
17
|
+
ogSiteName?: string;
|
|
18
|
+
twitterCard?: string;
|
|
19
|
+
twitterTitle?: string;
|
|
20
|
+
twitterDescription?: string;
|
|
21
|
+
twitterImage?: string;
|
|
22
|
+
twitterSite?: string;
|
|
23
|
+
h1Count?: number;
|
|
24
|
+
h1Text?: string;
|
|
25
|
+
h1Length?: number;
|
|
26
|
+
h2Count?: number;
|
|
27
|
+
headingHierarchyValid?: boolean;
|
|
28
|
+
headingSkippedLevels?: string[];
|
|
29
|
+
sectionWordCounts?: number[];
|
|
30
|
+
totalImages?: number;
|
|
31
|
+
imagesWithAlt?: number;
|
|
32
|
+
imagesWithoutAlt?: number;
|
|
33
|
+
imagesWithLazyLoad?: number;
|
|
34
|
+
imagesWithDimensions?: number;
|
|
35
|
+
imagesMissingDimensions?: number;
|
|
36
|
+
imagesWithEmptyAlt?: number;
|
|
37
|
+
imagesDecorativeCount?: number;
|
|
38
|
+
imagesUsingModernFormats?: number;
|
|
39
|
+
altTextLengths?: number[];
|
|
40
|
+
imageFilenames?: string[];
|
|
41
|
+
imagesWithAsyncDecoding?: number;
|
|
42
|
+
buttonsWithoutAriaLabel?: number;
|
|
43
|
+
linksWithoutAriaLabel?: number;
|
|
44
|
+
inputsWithoutLabel?: number;
|
|
45
|
+
formsWithoutAction?: number;
|
|
46
|
+
tablesWithoutCaption?: number;
|
|
47
|
+
iframesWithoutTitle?: number;
|
|
48
|
+
svgsWithoutTitle?: number;
|
|
49
|
+
interactiveElementsCount?: number;
|
|
50
|
+
ariaLabelledByMissing?: number;
|
|
51
|
+
allLinks?: ExtractedLink[];
|
|
52
|
+
totalLinks?: number;
|
|
53
|
+
internalLinks?: number;
|
|
54
|
+
externalLinks?: number;
|
|
55
|
+
linksWithoutText?: number;
|
|
56
|
+
nofollowLinks?: number;
|
|
57
|
+
sponsoredLinks?: number;
|
|
58
|
+
ugcLinks?: number;
|
|
59
|
+
brokenLinks?: number;
|
|
60
|
+
linksWithGenericText?: number;
|
|
61
|
+
externalLinksWithoutNoopener?: number;
|
|
62
|
+
externalLinksWithoutNoreferrer?: number;
|
|
63
|
+
problematicLinks?: {
|
|
64
|
+
withoutText?: ExtractedLink[];
|
|
65
|
+
genericText?: ExtractedLink[];
|
|
66
|
+
missingNoopener?: ExtractedLink[];
|
|
67
|
+
missingNoreferrer?: ExtractedLink[];
|
|
68
|
+
};
|
|
69
|
+
wordCount?: number;
|
|
70
|
+
characterCount?: number;
|
|
71
|
+
sentenceCount?: number;
|
|
72
|
+
paragraphCount?: number;
|
|
73
|
+
avgWordsPerSentence?: number;
|
|
74
|
+
avgParagraphLength?: number;
|
|
75
|
+
listCount?: number;
|
|
76
|
+
strongTagCount?: number;
|
|
77
|
+
emTagCount?: number;
|
|
78
|
+
subheadingFrequency?: number;
|
|
79
|
+
paragraphWordCounts?: number[];
|
|
80
|
+
avgSentenceLength?: number;
|
|
81
|
+
faqCount?: number;
|
|
82
|
+
imagePerWordRatio?: number;
|
|
83
|
+
mainKeyword?: string;
|
|
84
|
+
keywordDensity?: number;
|
|
85
|
+
fleschReadingEase?: number;
|
|
86
|
+
hasQuestionHeadings?: boolean;
|
|
87
|
+
hasHeader?: boolean;
|
|
88
|
+
hasNav?: boolean;
|
|
89
|
+
hasMain?: boolean;
|
|
90
|
+
hasArticle?: boolean;
|
|
91
|
+
hasSection?: boolean;
|
|
92
|
+
hasFooter?: boolean;
|
|
93
|
+
hasAboutPageLink?: boolean;
|
|
94
|
+
hasContactPageLink?: boolean;
|
|
95
|
+
hasPrivacyPolicyLink?: boolean;
|
|
96
|
+
hasTermsOfServiceLink?: boolean;
|
|
97
|
+
hasBreadcrumbsHtml?: boolean;
|
|
98
|
+
hasBreadcrumbsSchema?: boolean;
|
|
99
|
+
videoCount?: number;
|
|
100
|
+
audioCount?: number;
|
|
101
|
+
hasCanonical?: boolean;
|
|
102
|
+
canonicalUrl?: string;
|
|
103
|
+
hasViewport?: boolean;
|
|
104
|
+
viewportContent?: string;
|
|
105
|
+
hasCharset?: boolean;
|
|
106
|
+
charset?: string;
|
|
107
|
+
hasLang?: boolean;
|
|
108
|
+
langValue?: string;
|
|
109
|
+
isHttps?: boolean;
|
|
110
|
+
hasMixedContent?: boolean;
|
|
111
|
+
responseHeaders?: Record<string, string | string[]>;
|
|
112
|
+
textHtmlRatio?: number;
|
|
113
|
+
hasFavicon?: boolean;
|
|
114
|
+
faviconUrl?: string;
|
|
115
|
+
hasPreconnect?: boolean;
|
|
116
|
+
preconnectCount?: number;
|
|
117
|
+
hasDnsPrefetch?: boolean;
|
|
118
|
+
dnsPrefetchCount?: number;
|
|
119
|
+
hasPreload?: boolean;
|
|
120
|
+
preloadCount?: number;
|
|
121
|
+
renderBlockingResources?: number;
|
|
122
|
+
inlineScriptsCount?: number;
|
|
123
|
+
inlineStylesCount?: number;
|
|
124
|
+
lcpHints?: {
|
|
125
|
+
hasLargeImages?: boolean;
|
|
126
|
+
hasLazyLcp?: boolean;
|
|
127
|
+
hasPriorityHints?: boolean;
|
|
128
|
+
};
|
|
129
|
+
clsHints?: {
|
|
130
|
+
imagesWithoutDimensions?: number;
|
|
131
|
+
dynamicContent?: number;
|
|
132
|
+
};
|
|
133
|
+
jsonLdCount?: number;
|
|
134
|
+
jsonLdTypes?: string[];
|
|
135
|
+
url?: string;
|
|
136
|
+
urlLength?: number;
|
|
137
|
+
hreflangTags?: Array<{
|
|
138
|
+
lang: string;
|
|
139
|
+
href: string;
|
|
140
|
+
}>;
|
|
141
|
+
ogLocale?: string;
|
|
142
|
+
alternateLanguages?: string[];
|
|
143
|
+
titleMatchesH1?: boolean;
|
|
144
|
+
urlHasUppercase?: boolean;
|
|
145
|
+
urlHasSpecialChars?: boolean;
|
|
146
|
+
urlHasAccents?: boolean;
|
|
147
|
+
bodyTextLength?: number;
|
|
148
|
+
scriptCount?: number;
|
|
149
|
+
hasNoscriptContent?: boolean;
|
|
150
|
+
timings?: {
|
|
151
|
+
ttfb?: number;
|
|
152
|
+
dnsLookup?: number;
|
|
153
|
+
tcpConnect?: number;
|
|
154
|
+
tlsHandshake?: number;
|
|
155
|
+
download?: number;
|
|
156
|
+
total?: number;
|
|
157
|
+
};
|
|
158
|
+
responseSize?: number;
|
|
159
|
+
htmlSize?: number;
|
|
160
|
+
compressedSize?: number;
|
|
161
|
+
isCompressed?: boolean;
|
|
162
|
+
isProductPage?: boolean;
|
|
163
|
+
productSchema?: {
|
|
164
|
+
name?: string;
|
|
165
|
+
image?: string | string[];
|
|
166
|
+
offers?: {
|
|
167
|
+
price?: number | string;
|
|
168
|
+
lowPrice?: number | string;
|
|
169
|
+
priceCurrency?: string;
|
|
170
|
+
availability?: string;
|
|
171
|
+
priceValidUntil?: string;
|
|
172
|
+
validFrom?: string;
|
|
173
|
+
validThrough?: string;
|
|
174
|
+
};
|
|
175
|
+
aggregateRating?: {
|
|
176
|
+
ratingValue?: number | string;
|
|
177
|
+
reviewCount?: number;
|
|
178
|
+
ratingCount?: number;
|
|
179
|
+
};
|
|
180
|
+
review?: unknown;
|
|
181
|
+
brand?: string | {
|
|
182
|
+
name?: string;
|
|
183
|
+
};
|
|
184
|
+
sku?: string;
|
|
185
|
+
gtin?: string;
|
|
186
|
+
gtin13?: string;
|
|
187
|
+
gtin14?: string;
|
|
188
|
+
gtin8?: string;
|
|
189
|
+
mpn?: string;
|
|
190
|
+
};
|
|
191
|
+
hasLocalBusinessSignals?: boolean;
|
|
192
|
+
localBusinessSchema?: {
|
|
193
|
+
'@type'?: string;
|
|
194
|
+
name?: string;
|
|
195
|
+
address?: {
|
|
196
|
+
streetAddress?: string;
|
|
197
|
+
addressLocality?: string;
|
|
198
|
+
addressRegion?: string;
|
|
199
|
+
postalCode?: string;
|
|
200
|
+
addressCountry?: string;
|
|
201
|
+
};
|
|
202
|
+
telephone?: string;
|
|
203
|
+
openingHoursSpecification?: unknown;
|
|
204
|
+
openingHours?: string | string[];
|
|
205
|
+
geo?: {
|
|
206
|
+
latitude?: number | string;
|
|
207
|
+
longitude?: number | string;
|
|
208
|
+
};
|
|
209
|
+
areaServed?: unknown;
|
|
210
|
+
priceRange?: string;
|
|
211
|
+
};
|
|
212
|
+
hasPhoneOnPage?: boolean;
|
|
213
|
+
hasAddressOnPage?: boolean;
|
|
214
|
+
lcpCandidate?: {
|
|
215
|
+
element?: string;
|
|
216
|
+
src?: string;
|
|
217
|
+
loading?: string;
|
|
218
|
+
fetchpriority?: string;
|
|
219
|
+
};
|
|
220
|
+
hasLcpPreload?: boolean;
|
|
221
|
+
webFonts?: Array<{
|
|
222
|
+
family?: string;
|
|
223
|
+
hasSwap?: boolean;
|
|
224
|
+
hasOptional?: boolean;
|
|
225
|
+
hasSizeAdjust?: boolean;
|
|
226
|
+
hasAscentOverride?: boolean;
|
|
227
|
+
}>;
|
|
228
|
+
renderBlockingStylesheets?: number;
|
|
229
|
+
renderBlockingScripts?: number;
|
|
230
|
+
hasAspectRatioCss?: boolean;
|
|
231
|
+
hasResponsiveImages?: boolean;
|
|
232
|
+
hasAdsWithoutReservedSpace?: boolean;
|
|
233
|
+
hasBannersWithoutMinHeight?: boolean;
|
|
234
|
+
hasInfiniteScroll?: boolean;
|
|
235
|
+
largeInlineScripts?: number;
|
|
236
|
+
inlineEventHandlers?: number;
|
|
237
|
+
hasHeavyAnimations?: boolean;
|
|
238
|
+
externalOrigins?: number;
|
|
239
|
+
hasCriticalResources?: boolean;
|
|
240
|
+
hasInlineCriticalCss?: boolean;
|
|
241
|
+
hasSitemapLink?: boolean;
|
|
242
|
+
sitemapUrl?: string;
|
|
243
|
+
robotsHasSitemap?: boolean;
|
|
244
|
+
isPaginatedPage?: boolean;
|
|
245
|
+
hasRelPrev?: boolean;
|
|
246
|
+
hasRelNext?: boolean;
|
|
247
|
+
passiveVoicePercentage?: number;
|
|
248
|
+
transitionWordPercentage?: number;
|
|
249
|
+
consecutiveSentenceStarts?: number;
|
|
250
|
+
complexWordPercentage?: number;
|
|
251
|
+
}
|
|
252
|
+
export interface RuleEvidence {
|
|
253
|
+
found?: string | number | string[];
|
|
254
|
+
expected?: string | number | string[];
|
|
255
|
+
location?: string;
|
|
256
|
+
issue?: string;
|
|
257
|
+
impact?: string;
|
|
258
|
+
example?: string;
|
|
259
|
+
learnMore?: string;
|
|
260
|
+
}
|
|
261
|
+
export interface RuleResult {
|
|
262
|
+
id: string;
|
|
263
|
+
name: string;
|
|
264
|
+
category: RuleCategory;
|
|
265
|
+
severity: RuleSeverity;
|
|
266
|
+
status: SeoStatus;
|
|
267
|
+
message: string;
|
|
268
|
+
value?: string | number;
|
|
269
|
+
recommendation?: string;
|
|
270
|
+
evidence?: RuleEvidence;
|
|
271
|
+
details?: Record<string, unknown>;
|
|
272
|
+
}
|
|
273
|
+
export interface SeoRule {
|
|
274
|
+
id: string;
|
|
275
|
+
name: string;
|
|
276
|
+
category: RuleCategory;
|
|
277
|
+
severity: RuleSeverity;
|
|
278
|
+
description: string;
|
|
279
|
+
check: (ctx: RuleContext) => RuleResult | null;
|
|
280
|
+
}
|
|
281
|
+
export declare function createResult(rule: Pick<SeoRule, 'id' | 'name' | 'category' | 'severity'>, status: SeoStatus, message: string, options?: {
|
|
282
|
+
value?: string | number;
|
|
283
|
+
recommendation?: string;
|
|
284
|
+
evidence?: RuleEvidence;
|
|
285
|
+
details?: Record<string, unknown>;
|
|
286
|
+
}): RuleResult;
|