@aexol/spectral 0.9.42 → 0.9.43
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/extensions/aexol-mcp.d.ts.map +1 -1
- package/dist/extensions/aexol-mcp.js +44 -9
- package/dist/extensions/browser/browser-service.d.ts +4 -1
- package/dist/extensions/browser/browser-service.d.ts.map +1 -1
- package/dist/extensions/browser/browser-service.js +34 -7
- package/dist/extensions/browser/config.d.ts +3 -0
- package/dist/extensions/browser/config.d.ts.map +1 -1
- package/dist/extensions/browser/config.js +1 -0
- package/dist/extensions/browser/index.d.ts.map +1 -1
- package/dist/extensions/browser/index.js +3 -0
- package/dist/extensions/browser/record/record-tool.d.ts.map +1 -1
- package/dist/extensions/browser/record/record-tool.js +27 -4
- package/dist/extensions/browser/scenario/markdown-parser.d.ts +44 -0
- package/dist/extensions/browser/scenario/markdown-parser.d.ts.map +1 -0
- package/dist/extensions/browser/scenario/markdown-parser.js +159 -0
- package/dist/extensions/browser/scenario/scenario-tool.d.ts +4 -0
- package/dist/extensions/browser/scenario/scenario-tool.d.ts.map +1 -0
- package/dist/extensions/browser/scenario/scenario-tool.js +381 -0
- package/dist/extensions/browser/tools/core.js +1 -1
- package/dist/extensions/browser/tools/screenshot.d.ts.map +1 -1
- package/dist/extensions/browser/tools/screenshot.js +2 -1
- package/dist/extensions/seo/analyzers/agent-ux.d.ts +5 -0
- package/dist/extensions/seo/analyzers/agent-ux.d.ts.map +1 -0
- package/dist/extensions/seo/analyzers/agent-ux.js +95 -0
- package/dist/extensions/seo/analyzers/content.d.ts +16 -0
- package/dist/extensions/seo/analyzers/content.d.ts.map +1 -0
- package/dist/extensions/seo/analyzers/content.js +174 -0
- package/dist/extensions/seo/analyzers/drift.d.ts +13 -0
- package/dist/extensions/seo/analyzers/drift.d.ts.map +1 -0
- package/dist/extensions/seo/analyzers/drift.js +204 -0
- package/dist/extensions/seo/analyzers/images.d.ts +10 -0
- package/dist/extensions/seo/analyzers/images.d.ts.map +1 -0
- package/dist/extensions/seo/analyzers/images.js +49 -0
- package/dist/extensions/seo/analyzers/parasite.d.ts +18 -0
- package/dist/extensions/seo/analyzers/parasite.d.ts.map +1 -0
- package/dist/extensions/seo/analyzers/parasite.js +142 -0
- package/dist/extensions/seo/analyzers/preload.d.ts +12 -0
- package/dist/extensions/seo/analyzers/preload.d.ts.map +1 -0
- package/dist/extensions/seo/analyzers/preload.js +108 -0
- package/dist/extensions/seo/analyzers/schema.d.ts +21 -0
- package/dist/extensions/seo/analyzers/schema.d.ts.map +1 -0
- package/dist/extensions/seo/analyzers/schema.js +324 -0
- package/dist/extensions/seo/analyzers/sitemap.d.ts +20 -0
- package/dist/extensions/seo/analyzers/sitemap.d.ts.map +1 -0
- package/dist/extensions/seo/analyzers/sitemap.js +121 -0
- package/dist/extensions/seo/analyzers/technical.d.ts +11 -0
- package/dist/extensions/seo/analyzers/technical.d.ts.map +1 -0
- package/dist/extensions/seo/analyzers/technical.js +268 -0
- package/dist/extensions/seo/config.d.ts +24 -0
- package/dist/extensions/seo/config.d.ts.map +1 -0
- package/dist/extensions/seo/config.js +48 -0
- package/dist/extensions/seo/index.d.ts +16 -0
- package/dist/extensions/seo/index.d.ts.map +1 -0
- package/dist/extensions/seo/index.js +88 -0
- package/dist/extensions/seo/tools/agent-ux.d.ts +7 -0
- package/dist/extensions/seo/tools/agent-ux.d.ts.map +1 -0
- package/dist/extensions/seo/tools/agent-ux.js +63 -0
- package/dist/extensions/seo/tools/content.d.ts +7 -0
- package/dist/extensions/seo/tools/content.d.ts.map +1 -0
- package/dist/extensions/seo/tools/content.js +55 -0
- package/dist/extensions/seo/tools/drift.d.ts +7 -0
- package/dist/extensions/seo/tools/drift.d.ts.map +1 -0
- package/dist/extensions/seo/tools/drift.js +104 -0
- package/dist/extensions/seo/tools/fetch.d.ts +7 -0
- package/dist/extensions/seo/tools/fetch.d.ts.map +1 -0
- package/dist/extensions/seo/tools/fetch.js +123 -0
- package/dist/extensions/seo/tools/full-audit.d.ts +10 -0
- package/dist/extensions/seo/tools/full-audit.d.ts.map +1 -0
- package/dist/extensions/seo/tools/full-audit.js +191 -0
- package/dist/extensions/seo/tools/helpers.d.ts +13 -0
- package/dist/extensions/seo/tools/helpers.d.ts.map +1 -0
- package/dist/extensions/seo/tools/helpers.js +24 -0
- package/dist/extensions/seo/tools/images.d.ts +7 -0
- package/dist/extensions/seo/tools/images.d.ts.map +1 -0
- package/dist/extensions/seo/tools/images.js +46 -0
- package/dist/extensions/seo/tools/parasite.d.ts +7 -0
- package/dist/extensions/seo/tools/parasite.d.ts.map +1 -0
- package/dist/extensions/seo/tools/parasite.js +53 -0
- package/dist/extensions/seo/tools/parse.d.ts +7 -0
- package/dist/extensions/seo/tools/parse.d.ts.map +1 -0
- package/dist/extensions/seo/tools/parse.js +66 -0
- package/dist/extensions/seo/tools/preload.d.ts +7 -0
- package/dist/extensions/seo/tools/preload.d.ts.map +1 -0
- package/dist/extensions/seo/tools/preload.js +52 -0
- package/dist/extensions/seo/tools/report.d.ts +4 -0
- package/dist/extensions/seo/tools/report.d.ts.map +1 -0
- package/dist/extensions/seo/tools/report.js +167 -0
- package/dist/extensions/seo/tools/schema.d.ts +7 -0
- package/dist/extensions/seo/tools/schema.d.ts.map +1 -0
- package/dist/extensions/seo/tools/schema.js +105 -0
- package/dist/extensions/seo/tools/sitemap.d.ts +7 -0
- package/dist/extensions/seo/tools/sitemap.d.ts.map +1 -0
- package/dist/extensions/seo/tools/sitemap.js +85 -0
- package/dist/extensions/seo/tools/technical.d.ts +7 -0
- package/dist/extensions/seo/tools/technical.d.ts.map +1 -0
- package/dist/extensions/seo/tools/technical.js +62 -0
- package/dist/extensions/seo/types.d.ts +289 -0
- package/dist/extensions/seo/types.d.ts.map +1 -0
- package/dist/extensions/seo/types.js +7 -0
- package/dist/extensions/seo/utils/fetcher.d.ts +28 -0
- package/dist/extensions/seo/utils/fetcher.d.ts.map +1 -0
- package/dist/extensions/seo/utils/fetcher.js +118 -0
- package/dist/extensions/seo/utils/parser.d.ts +8 -0
- package/dist/extensions/seo/utils/parser.d.ts.map +1 -0
- package/dist/extensions/seo/utils/parser.js +265 -0
- package/dist/extensions/seo/utils/renderer.d.ts +39 -0
- package/dist/extensions/seo/utils/renderer.d.ts.map +1 -0
- package/dist/extensions/seo/utils/renderer.js +190 -0
- package/dist/extensions/seo/utils/url-safety.d.ts +31 -0
- package/dist/extensions/seo/utils/url-safety.d.ts.map +1 -0
- package/dist/extensions/seo/utils/url-safety.js +200 -0
- package/dist/sdk/coding-agent/core/extensions/native-extensions.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/extensions/native-extensions.js +11 -0
- package/package.json +1 -1
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the SEO extension.
|
|
3
|
+
*
|
|
4
|
+
* All types are plain data structures (no class hierarchies) so they can be
|
|
5
|
+
* serialised to JSON and returned as tool `details` without transformation.
|
|
6
|
+
*/
|
|
7
|
+
/** A single HTTP redirect hop in a fetch redirect chain. */
|
|
8
|
+
export interface RedirectHop {
|
|
9
|
+
url: string;
|
|
10
|
+
status: number;
|
|
11
|
+
}
|
|
12
|
+
/** Result of fetching a URL. */
|
|
13
|
+
export interface FetchResult {
|
|
14
|
+
url: string;
|
|
15
|
+
finalUrl: string;
|
|
16
|
+
statusCode: number;
|
|
17
|
+
statusText: string;
|
|
18
|
+
headers: Record<string, string>;
|
|
19
|
+
content: string;
|
|
20
|
+
redirectChain: RedirectHop[];
|
|
21
|
+
contentLengthBytes: number;
|
|
22
|
+
fetchedAt: string;
|
|
23
|
+
error?: string;
|
|
24
|
+
}
|
|
25
|
+
/** A parsed heading element. */
|
|
26
|
+
export interface HeadingInfo {
|
|
27
|
+
level: 1 | 2 | 3 | 4 | 5 | 6;
|
|
28
|
+
text: string;
|
|
29
|
+
/** True if the heading looks auto-generated or suspicious (e.g. empty, "Click here"). */
|
|
30
|
+
suspicious?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/** A parsed image element. */
|
|
33
|
+
export interface ImageInfo {
|
|
34
|
+
src: string;
|
|
35
|
+
alt: string;
|
|
36
|
+
width?: string;
|
|
37
|
+
height?: string;
|
|
38
|
+
loading?: string;
|
|
39
|
+
/** Detected lazy-loading method: "native", "dataSrc", "dataLazy", "none". */
|
|
40
|
+
lazyMethod: "native" | "dataSrc" | "dataLazy" | "none";
|
|
41
|
+
fetchpriority?: string;
|
|
42
|
+
}
|
|
43
|
+
/** A parsed link element. */
|
|
44
|
+
export interface LinkInfo {
|
|
45
|
+
href: string;
|
|
46
|
+
text: string;
|
|
47
|
+
rel: string;
|
|
48
|
+
/** "internal" or "external" relative to baseUrl. */
|
|
49
|
+
type: "internal" | "external";
|
|
50
|
+
nofollow: boolean;
|
|
51
|
+
}
|
|
52
|
+
/** A detected JSON-LD schema block. */
|
|
53
|
+
export interface SchemaBlock {
|
|
54
|
+
type: string;
|
|
55
|
+
format: "json-ld" | "microdata" | "rdfa";
|
|
56
|
+
raw: string;
|
|
57
|
+
parsed?: unknown;
|
|
58
|
+
issues: string[];
|
|
59
|
+
}
|
|
60
|
+
/** Open Graph tag. */
|
|
61
|
+
export interface OpenGraphTag {
|
|
62
|
+
property: string;
|
|
63
|
+
content: string;
|
|
64
|
+
}
|
|
65
|
+
/** Twitter Card tag. */
|
|
66
|
+
export interface TwitterTag {
|
|
67
|
+
name: string;
|
|
68
|
+
content: string;
|
|
69
|
+
}
|
|
70
|
+
/** Hreflang entry. */
|
|
71
|
+
export interface HreflangEntry {
|
|
72
|
+
href: string;
|
|
73
|
+
hreflang: string;
|
|
74
|
+
}
|
|
75
|
+
/** Parsed on-page SEO data extracted from HTML. */
|
|
76
|
+
export interface PageData {
|
|
77
|
+
url: string;
|
|
78
|
+
baseUrl: string;
|
|
79
|
+
title: string | null;
|
|
80
|
+
titleLength: number;
|
|
81
|
+
metaDescription: string | null;
|
|
82
|
+
metaDescriptionLength: number;
|
|
83
|
+
metaRobots: string | null;
|
|
84
|
+
canonical: string | null;
|
|
85
|
+
ogTags: OpenGraphTag[];
|
|
86
|
+
twitterTags: TwitterTag[];
|
|
87
|
+
headings: HeadingInfo[];
|
|
88
|
+
h1Count: number;
|
|
89
|
+
h2Count: number;
|
|
90
|
+
h3Count: number;
|
|
91
|
+
images: ImageInfo[];
|
|
92
|
+
links: LinkInfo[];
|
|
93
|
+
internalLinkCount: number;
|
|
94
|
+
externalLinkCount: number;
|
|
95
|
+
schemaBlocks: SchemaBlock[];
|
|
96
|
+
hreflang: HreflangEntry[];
|
|
97
|
+
wordCount: number;
|
|
98
|
+
language: string | null;
|
|
99
|
+
viewport: string | null;
|
|
100
|
+
charset: string | null;
|
|
101
|
+
}
|
|
102
|
+
/** A single audit issue with severity. */
|
|
103
|
+
export interface AuditIssue {
|
|
104
|
+
category: string;
|
|
105
|
+
severity: "critical" | "high" | "medium" | "low";
|
|
106
|
+
title: string;
|
|
107
|
+
description: string;
|
|
108
|
+
recommendation: string;
|
|
109
|
+
}
|
|
110
|
+
/** Result of a technical SEO audit. */
|
|
111
|
+
export interface TechnicalAuditResult {
|
|
112
|
+
url: string;
|
|
113
|
+
score: number;
|
|
114
|
+
issues: AuditIssue[];
|
|
115
|
+
categoryScores: Record<string, number>;
|
|
116
|
+
robotsTxt: {
|
|
117
|
+
exists: boolean;
|
|
118
|
+
sitemapDeclared: boolean;
|
|
119
|
+
aiCrawlerRules: string[];
|
|
120
|
+
content?: string;
|
|
121
|
+
};
|
|
122
|
+
securityHeaders: Record<string, string | null>;
|
|
123
|
+
isHttps: boolean;
|
|
124
|
+
mobileOptimized: boolean;
|
|
125
|
+
}
|
|
126
|
+
/** Result of content quality analysis. */
|
|
127
|
+
export interface ContentQualityResult {
|
|
128
|
+
url?: string;
|
|
129
|
+
wordCount: number;
|
|
130
|
+
tokens: number;
|
|
131
|
+
uniqueTokens: number;
|
|
132
|
+
fillerScore: number;
|
|
133
|
+
aiPatternScore: number;
|
|
134
|
+
informationDensity: number;
|
|
135
|
+
repetitionScore: number;
|
|
136
|
+
overallQuality: number;
|
|
137
|
+
flags: string[];
|
|
138
|
+
fillerMatches: string[];
|
|
139
|
+
aiPatternMatches: string[];
|
|
140
|
+
}
|
|
141
|
+
/** Result of schema audit. */
|
|
142
|
+
export interface SchemaAuditResult {
|
|
143
|
+
url?: string;
|
|
144
|
+
detectedSchemas: SchemaBlock[];
|
|
145
|
+
deprecatedTypes: string[];
|
|
146
|
+
missingContext: boolean;
|
|
147
|
+
relativeUrls: string[];
|
|
148
|
+
invalidDates: string[];
|
|
149
|
+
recommendations: string[];
|
|
150
|
+
}
|
|
151
|
+
/** Result of sitemap analysis. */
|
|
152
|
+
export interface SitemapAnalysisResult {
|
|
153
|
+
url: string;
|
|
154
|
+
urlCount: number;
|
|
155
|
+
urls: string[];
|
|
156
|
+
lastmodCoverage: number;
|
|
157
|
+
invalidEntries: number;
|
|
158
|
+
sizeBytes: number;
|
|
159
|
+
isSitemapIndex: boolean;
|
|
160
|
+
childSitemaps: string[];
|
|
161
|
+
warnings: string[];
|
|
162
|
+
}
|
|
163
|
+
/** Result of image audit. */
|
|
164
|
+
export interface ImageAuditResult {
|
|
165
|
+
url: string;
|
|
166
|
+
totalImages: number;
|
|
167
|
+
missingAlt: number;
|
|
168
|
+
missingDimensions: number;
|
|
169
|
+
lazyLoading: {
|
|
170
|
+
native: number;
|
|
171
|
+
dataSrc: number;
|
|
172
|
+
dataLazy: number;
|
|
173
|
+
none: number;
|
|
174
|
+
};
|
|
175
|
+
modernFormats: number;
|
|
176
|
+
oversized: string[];
|
|
177
|
+
images: ImageInfo[];
|
|
178
|
+
}
|
|
179
|
+
/** Result of preload / speculation rules audit. */
|
|
180
|
+
export interface PreloadAuditResult {
|
|
181
|
+
url: string;
|
|
182
|
+
speculationRules: {
|
|
183
|
+
inlineBlocks: number;
|
|
184
|
+
headerPresent: boolean;
|
|
185
|
+
actions: string[];
|
|
186
|
+
};
|
|
187
|
+
preloadHints: number;
|
|
188
|
+
prerenderLinks: number;
|
|
189
|
+
bfcacheSignals: {
|
|
190
|
+
cacheControlNoStore: boolean;
|
|
191
|
+
unloadListener: boolean;
|
|
192
|
+
beforeunloadListener: boolean;
|
|
193
|
+
};
|
|
194
|
+
lcpResourceHints: {
|
|
195
|
+
preloadLcpCandidate: boolean;
|
|
196
|
+
fetchpriorityHigh: number;
|
|
197
|
+
};
|
|
198
|
+
score: number;
|
|
199
|
+
recommendations: string[];
|
|
200
|
+
}
|
|
201
|
+
/** Result of agent UX audit. */
|
|
202
|
+
export interface AgentUxAuditResult {
|
|
203
|
+
url: string;
|
|
204
|
+
agentUxScore: number;
|
|
205
|
+
html: {
|
|
206
|
+
realButtons: number;
|
|
207
|
+
realAnchors: number;
|
|
208
|
+
divOnclickWidgets: number;
|
|
209
|
+
semanticLandmarks: number;
|
|
210
|
+
inputsTotal: number;
|
|
211
|
+
inputsMissingLabel: number;
|
|
212
|
+
};
|
|
213
|
+
accessibilityTree: {
|
|
214
|
+
totalNodes: number;
|
|
215
|
+
interactiveNodes: number;
|
|
216
|
+
unnamedInteractive: number;
|
|
217
|
+
roleGenericRatio: number;
|
|
218
|
+
};
|
|
219
|
+
opportunities: string[];
|
|
220
|
+
}
|
|
221
|
+
/** A single page's parasite-SEO audit data. */
|
|
222
|
+
export interface ParasitePageAudit {
|
|
223
|
+
url: string;
|
|
224
|
+
thirdPartyHits: number;
|
|
225
|
+
commerceHits: number;
|
|
226
|
+
affiliateLinkHits: number;
|
|
227
|
+
}
|
|
228
|
+
/** Result of parasite risk scan. */
|
|
229
|
+
export interface ParasiteRiskResult {
|
|
230
|
+
host: string;
|
|
231
|
+
totalPages: number;
|
|
232
|
+
sections: Array<{
|
|
233
|
+
section: string;
|
|
234
|
+
pageCount: number;
|
|
235
|
+
thirdPartyHitsPerPage: number;
|
|
236
|
+
commerceHitsPerPage: number;
|
|
237
|
+
affiliateLinkHitsPerPage: number;
|
|
238
|
+
flags: string[];
|
|
239
|
+
risk: "high" | "medium" | "low";
|
|
240
|
+
}>;
|
|
241
|
+
}
|
|
242
|
+
/** A drift baseline snapshot. */
|
|
243
|
+
export interface DriftBaseline {
|
|
244
|
+
id: number;
|
|
245
|
+
url: string;
|
|
246
|
+
urlHash: string;
|
|
247
|
+
timestamp: string;
|
|
248
|
+
title: string | null;
|
|
249
|
+
metaDescription: string | null;
|
|
250
|
+
canonical: string | null;
|
|
251
|
+
robots: string | null;
|
|
252
|
+
h1: string | null;
|
|
253
|
+
h2Json: string;
|
|
254
|
+
h3Json: string;
|
|
255
|
+
schemaJson: string;
|
|
256
|
+
ogJson: string;
|
|
257
|
+
htmlHash: string;
|
|
258
|
+
schemaHash: string;
|
|
259
|
+
statusCode: number;
|
|
260
|
+
}
|
|
261
|
+
/** Result of comparing current state against a baseline. */
|
|
262
|
+
export interface DriftCompareResult {
|
|
263
|
+
url: string;
|
|
264
|
+
baselineId: number;
|
|
265
|
+
baselineTimestamp: string;
|
|
266
|
+
comparedAt: string;
|
|
267
|
+
changedFields: string[];
|
|
268
|
+
details: Record<string, {
|
|
269
|
+
before: unknown;
|
|
270
|
+
after: unknown;
|
|
271
|
+
}>;
|
|
272
|
+
severity: "none" | "low" | "medium" | "high";
|
|
273
|
+
}
|
|
274
|
+
/** Full audit result combining all sub-audits. */
|
|
275
|
+
export interface FullAuditResult {
|
|
276
|
+
url: string;
|
|
277
|
+
auditedAt: string;
|
|
278
|
+
overallScore: number;
|
|
279
|
+
technical?: TechnicalAuditResult;
|
|
280
|
+
content?: ContentQualityResult;
|
|
281
|
+
schema?: SchemaAuditResult;
|
|
282
|
+
images?: ImageAuditResult;
|
|
283
|
+
preload?: PreloadAuditResult;
|
|
284
|
+
agentUx?: AgentUxAuditResult;
|
|
285
|
+
sitemap?: SitemapAnalysisResult;
|
|
286
|
+
allIssues: AuditIssue[];
|
|
287
|
+
summary: string;
|
|
288
|
+
}
|
|
289
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/extensions/seo/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP fetcher with redirect tracking, timeout, and charset detection.
|
|
3
|
+
*
|
|
4
|
+
* Ported from the Python `fetch_page.py` in claude-seo. Uses Node's native
|
|
5
|
+
* fetch (Node 20+) with manual redirect handling to capture the full chain.
|
|
6
|
+
*/
|
|
7
|
+
import type { SeoConfig } from "../config.js";
|
|
8
|
+
import type { FetchResult } from "../types.js";
|
|
9
|
+
export interface FetchOptions {
|
|
10
|
+
userAgent?: "default" | "googlebot" | string;
|
|
11
|
+
timeout?: number;
|
|
12
|
+
followRedirects?: boolean;
|
|
13
|
+
maxRedirects?: number;
|
|
14
|
+
/** Extra headers to send. */
|
|
15
|
+
headers?: Record<string, string>;
|
|
16
|
+
/** Whether to run SSRF protection (DNS-based private IP blocking). */
|
|
17
|
+
ssrfProtection?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Fetch a URL with full redirect-chain tracking.
|
|
21
|
+
*
|
|
22
|
+
* Returns a FetchResult containing the final URL, status, headers, content,
|
|
23
|
+
* and the complete redirect chain.
|
|
24
|
+
*/
|
|
25
|
+
export declare function fetchPage(url: string, config: SeoConfig, opts?: FetchOptions): Promise<FetchResult>;
|
|
26
|
+
/** Fetch a robots.txt file for a given URL's origin. */
|
|
27
|
+
export declare function fetchRobotsTxt(pageUrl: string, config: SeoConfig, opts?: FetchOptions): Promise<FetchResult>;
|
|
28
|
+
//# sourceMappingURL=fetcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../../../../src/extensions/seo/utils/fetcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAe,MAAM,aAAa,CAAC;AAG5D,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,MAAM,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,sEAAsE;IACtE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAwBD;;;;;GAKG;AACH,wBAAsB,SAAS,CAC7B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,SAAS,EACjB,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,WAAW,CAAC,CA4FtB;AAED,wDAAwD;AACxD,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,SAAS,EACjB,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,WAAW,CAAC,CAItB"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { UrlSafetyError, validateUrl } from "./url-safety.js";
|
|
2
|
+
/** Decode a fetch response body respecting charset from Content-Type header. */
|
|
3
|
+
async function decodeBody(res) {
|
|
4
|
+
const contentType = res.headers.get("content-type") ?? "";
|
|
5
|
+
const buffer = await res.arrayBuffer();
|
|
6
|
+
const decoder = new TextDecoder(detectCharset(contentType) ?? "utf-8");
|
|
7
|
+
return decoder.decode(buffer);
|
|
8
|
+
}
|
|
9
|
+
function detectCharset(contentType) {
|
|
10
|
+
const match = /charset=([^\s;]+)/i.exec(contentType);
|
|
11
|
+
if (match)
|
|
12
|
+
return match[1].toLowerCase().trim();
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
function headersToRecord(headers) {
|
|
16
|
+
const rec = {};
|
|
17
|
+
headers.forEach((value, key) => {
|
|
18
|
+
rec[key] = value;
|
|
19
|
+
});
|
|
20
|
+
return rec;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Fetch a URL with full redirect-chain tracking.
|
|
24
|
+
*
|
|
25
|
+
* Returns a FetchResult containing the final URL, status, headers, content,
|
|
26
|
+
* and the complete redirect chain.
|
|
27
|
+
*/
|
|
28
|
+
export async function fetchPage(url, config, opts = {}) {
|
|
29
|
+
const timeout = opts.timeout ?? config.timeout;
|
|
30
|
+
const followRedirects = opts.followRedirects ?? config.followRedirects;
|
|
31
|
+
const maxRedirects = opts.maxRedirects ?? config.maxRedirects;
|
|
32
|
+
const ssrfProtection = opts.ssrfProtection ?? config.ssrfProtection;
|
|
33
|
+
const validated = await validateUrl(url, { ssrfProtection });
|
|
34
|
+
const ua = opts.userAgent === "googlebot"
|
|
35
|
+
? config.googlebotUserAgent
|
|
36
|
+
: opts.userAgent === "default" || !opts.userAgent
|
|
37
|
+
? config.userAgent
|
|
38
|
+
: opts.userAgent;
|
|
39
|
+
const redirectChain = [];
|
|
40
|
+
let currentUrl = validated.href;
|
|
41
|
+
let lastResponse = null;
|
|
42
|
+
let lastError;
|
|
43
|
+
for (let i = 0; i <= maxRedirects; i++) {
|
|
44
|
+
const controller = new AbortController();
|
|
45
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
46
|
+
try {
|
|
47
|
+
const res = await fetch(currentUrl, {
|
|
48
|
+
redirect: "manual",
|
|
49
|
+
signal: controller.signal,
|
|
50
|
+
headers: {
|
|
51
|
+
"User-Agent": ua,
|
|
52
|
+
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
53
|
+
"Accept-Language": "en-US,en;q=0.9",
|
|
54
|
+
...opts.headers,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
clearTimeout(timeoutId);
|
|
58
|
+
// Handle redirects manually to capture the full chain.
|
|
59
|
+
if (res.status >= 300 && res.status < 400 && followRedirects) {
|
|
60
|
+
const location = res.headers.get("location");
|
|
61
|
+
if (location) {
|
|
62
|
+
redirectChain.push({ url: currentUrl, status: res.status });
|
|
63
|
+
currentUrl = new URL(location, currentUrl).href;
|
|
64
|
+
// Validate redirect target for SSRF.
|
|
65
|
+
await validateUrl(currentUrl, { ssrfProtection, resolveDns: false });
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
lastResponse = res;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
clearTimeout(timeoutId);
|
|
74
|
+
if (err instanceof UrlSafetyError)
|
|
75
|
+
throw err;
|
|
76
|
+
lastError = err instanceof Error ? err.message : String(err);
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (!lastResponse) {
|
|
81
|
+
return {
|
|
82
|
+
url: validated.href,
|
|
83
|
+
finalUrl: currentUrl,
|
|
84
|
+
statusCode: 0,
|
|
85
|
+
statusText: "Error",
|
|
86
|
+
headers: {},
|
|
87
|
+
content: "",
|
|
88
|
+
redirectChain,
|
|
89
|
+
contentLengthBytes: 0,
|
|
90
|
+
fetchedAt: new Date().toISOString(),
|
|
91
|
+
error: lastError ?? "Unknown fetch error",
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
let content = "";
|
|
95
|
+
try {
|
|
96
|
+
content = await decodeBody(lastResponse);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
content = "";
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
url: validated.href,
|
|
103
|
+
finalUrl: currentUrl,
|
|
104
|
+
statusCode: lastResponse.status,
|
|
105
|
+
statusText: lastResponse.statusText,
|
|
106
|
+
headers: headersToRecord(lastResponse.headers),
|
|
107
|
+
content,
|
|
108
|
+
redirectChain,
|
|
109
|
+
contentLengthBytes: Buffer.byteLength(content, "utf-8"),
|
|
110
|
+
fetchedAt: new Date().toISOString(),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/** Fetch a robots.txt file for a given URL's origin. */
|
|
114
|
+
export async function fetchRobotsTxt(pageUrl, config, opts = {}) {
|
|
115
|
+
const validated = await validateUrl(pageUrl, { ssrfProtection: opts.ssrfProtection ?? config.ssrfProtection });
|
|
116
|
+
const robotsUrl = `${validated.protocol}//${validated.hostname}/robots.txt`;
|
|
117
|
+
return fetchPage(robotsUrl, config, opts);
|
|
118
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PageData } from "../types.js";
|
|
2
|
+
/** Parse a full PageData object from HTML. */
|
|
3
|
+
export declare function parsePage(html: string, url?: string, baseUrl?: string): PageData;
|
|
4
|
+
/** Extract the visible text content from HTML body. */
|
|
5
|
+
export declare function extractText(html: string): string;
|
|
6
|
+
/** Extract raw JSON-LD blocks as parsed objects. */
|
|
7
|
+
export declare function extractJsonLd(html: string): unknown[];
|
|
8
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../../src/extensions/seo/utils/parser.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAMV,QAAQ,EAGT,MAAM,aAAa,CAAC;AAgGrB,8CAA8C;AAC9C,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,QAAQ,CA4IhF;AAED,uDAAuD;AACvD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKhD;AAED,oDAAoD;AACpD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CAerD"}
|