@j0hanz/fetch-url-mcp 1.10.21 → 1.10.22
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/http/auth.d.ts +2 -0
- package/dist/http/auth.d.ts.map +1 -1
- package/dist/http/auth.js +30 -0
- package/dist/lib/core.d.ts +1 -1
- package/dist/lib/core.d.ts.map +1 -1
- package/dist/lib/core.js +44 -28
- package/dist/lib/dom-prep.d.ts +2 -0
- package/dist/lib/dom-prep.d.ts.map +1 -1
- package/dist/lib/dom-prep.js +68 -23
- package/dist/lib/http.d.ts.map +1 -1
- package/dist/lib/http.js +84 -55
- package/dist/lib/sdk-interop.d.ts +12 -0
- package/dist/lib/sdk-interop.d.ts.map +1 -1
- package/dist/lib/sdk-interop.js +12 -0
- package/dist/lib/session.d.ts +4 -1
- package/dist/lib/session.d.ts.map +1 -1
- package/dist/lib/session.js +1 -1
- package/dist/lib/utils.d.ts +5 -0
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +5 -0
- package/dist/resources/index.js +2 -2
- package/dist/schemas.js +1 -1
- package/dist/transform/html-translators.d.ts.map +1 -1
- package/dist/transform/html-translators.js +50 -8
- package/dist/transform/markdown-cleanup.d.ts.map +1 -1
- package/dist/transform/markdown-cleanup.js +71 -63
- package/dist/transform/transform.d.ts.map +1 -1
- package/dist/transform/transform.js +118 -60
- package/dist/transform/worker-pool.d.ts +2 -0
- package/dist/transform/worker-pool.d.ts.map +1 -1
- package/dist/transform/worker-pool.js +38 -17
- package/package.json +1 -1
package/dist/http/auth.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export declare function isOAuthMetadataEnabled(): boolean;
|
|
|
31
31
|
export declare function buildAuthFingerprint(auth: AuthInfo | undefined): string | null;
|
|
32
32
|
declare class AuthService {
|
|
33
33
|
private readonly staticTokenDigests;
|
|
34
|
+
private readonly introspectionCache;
|
|
34
35
|
authenticate(req: IncomingMessage, signal?: AbortSignal): Promise<AuthInfo>;
|
|
35
36
|
private authenticateWithToken;
|
|
36
37
|
private authenticateWithApiKey;
|
|
@@ -47,6 +48,7 @@ declare class AuthService {
|
|
|
47
48
|
private buildIntrospectionAuthInfo;
|
|
48
49
|
private assertRequiredScopes;
|
|
49
50
|
private verifyWithIntrospection;
|
|
51
|
+
private evictStaleEntries;
|
|
50
52
|
}
|
|
51
53
|
export declare function applyUnauthorizedAuthHeaders(req: IncomingMessage, res: ServerResponse): void;
|
|
52
54
|
export declare function applyInsufficientScopeAuthHeaders(req: IncomingMessage, res: ServerResponse, requiredScopes: readonly string[], message?: string): void;
|
package/dist/http/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/http/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,OAAO,EACL,iBAAiB,EAElB,MAAM,iDAAiD,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gDAAgD,CAAC;AAY/E,OAAO,EAEL,KAAK,cAAc,EAIpB,MAAM,cAAc,CAAC;AAMtB,cAAM,UAAU;IAId,MAAM,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO;CAuBrC;AAED,eAAO,MAAM,UAAU,YAAmB,CAAC;AAS3C,cAAM,sBAAuB,SAAQ,iBAAiB;IAElD,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE;gBAAjC,cAAc,EAAE,SAAS,MAAM,EAAE,EAC1C,OAAO,SAAuB;CAKjC;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,sBAAsB,CAEjC;AAwCD,cAAM,gBAAgB;IACpB,QAAQ,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO;IA2BtC,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,oBAAoB;IAsB5B,OAAO,CAAC,aAAa;IAsBrB,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,MAAM;CAQf;AAED,eAAO,MAAM,gBAAgB,kBAAyB,CAAC;AAMvD,wBAAgB,2BAA2B,IAAI,IAAI,CA2BlD;AAMD,eAAO,MAAM,4BAA4B,eAAe,CAAC;AACzD,eAAO,MAAM,+BAA+B,aAE1C,CAAC;AAEH,UAAU,8BAA8B;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAUD,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,OAAO,CAAC,EAAE,8BAA8B,GACvC,OAAO,CAwBT;AAED,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAQD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,GAAG,SAAS,GACzB,MAAM,GAAG,IAAI,CAWf;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/http/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/http/auth.js
CHANGED
|
@@ -220,8 +220,11 @@ export function buildAuthFingerprint(auth) {
|
|
|
220
220
|
// ---------------------------------------------------------------------------
|
|
221
221
|
const STATIC_TOKEN_TTL_SECONDS = 60 * 60 * 24;
|
|
222
222
|
const STATIC_TOKEN_HMAC_KEY = randomBytes(32);
|
|
223
|
+
const INTROSPECTION_CACHE_TTL_MS = 30_000;
|
|
224
|
+
const INTROSPECTION_CACHE_MAX_ENTRIES = 1_000;
|
|
223
225
|
class AuthService {
|
|
224
226
|
staticTokenDigests = config.auth.staticTokens.map((token) => hmacSha256Hex(STATIC_TOKEN_HMAC_KEY, token));
|
|
227
|
+
introspectionCache = new Map();
|
|
225
228
|
async authenticate(req, signal) {
|
|
226
229
|
const authHeader = getHeaderValue(req, 'authorization');
|
|
227
230
|
if (!authHeader) {
|
|
@@ -386,16 +389,43 @@ class AuthService {
|
|
|
386
389
|
if (!config.auth.introspectionUrl) {
|
|
387
390
|
throw new ServerError('Introspection not configured');
|
|
388
391
|
}
|
|
392
|
+
const cacheKey = hmacSha256Hex(STATIC_TOKEN_HMAC_KEY, token);
|
|
393
|
+
const cached = this.introspectionCache.get(cacheKey);
|
|
394
|
+
if (cached && cached.expiresAt > Date.now()) {
|
|
395
|
+
this.introspectionCache.delete(cacheKey);
|
|
396
|
+
this.introspectionCache.set(cacheKey, cached);
|
|
397
|
+
return cached.info;
|
|
398
|
+
}
|
|
389
399
|
const req = this.buildIntrospectionRequest(token, config.auth.resourceUrl, config.auth.clientId, config.auth.clientSecret);
|
|
390
400
|
const payload = await this.requestIntrospection(config.auth.introspectionUrl, req, config.auth.introspectionTimeoutMs, signal);
|
|
391
401
|
if (!isObject(payload) || payload['active'] !== true) {
|
|
402
|
+
this.introspectionCache.delete(cacheKey);
|
|
392
403
|
throw new InvalidTokenError('Token is inactive');
|
|
393
404
|
}
|
|
394
405
|
this.assertTokenAudience(payload);
|
|
395
406
|
const info = this.buildIntrospectionAuthInfo(token, payload);
|
|
396
407
|
this.assertRequiredScopes(info.scopes);
|
|
408
|
+
this.evictStaleEntries();
|
|
409
|
+
this.introspectionCache.set(cacheKey, {
|
|
410
|
+
info,
|
|
411
|
+
expiresAt: Date.now() + INTROSPECTION_CACHE_TTL_MS,
|
|
412
|
+
});
|
|
397
413
|
return info;
|
|
398
414
|
}
|
|
415
|
+
evictStaleEntries() {
|
|
416
|
+
if (this.introspectionCache.size < INTROSPECTION_CACHE_MAX_ENTRIES)
|
|
417
|
+
return;
|
|
418
|
+
const now = Date.now();
|
|
419
|
+
for (const [key, entry] of this.introspectionCache) {
|
|
420
|
+
if (entry.expiresAt <= now)
|
|
421
|
+
this.introspectionCache.delete(key);
|
|
422
|
+
}
|
|
423
|
+
if (this.introspectionCache.size >= INTROSPECTION_CACHE_MAX_ENTRIES) {
|
|
424
|
+
const oldest = this.introspectionCache.keys().next();
|
|
425
|
+
if (!oldest.done)
|
|
426
|
+
this.introspectionCache.delete(oldest.value);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
399
429
|
}
|
|
400
430
|
function resolvePublicOrigin(req) {
|
|
401
431
|
const host = getHeaderValue(req, 'host');
|
package/dist/lib/core.d.ts
CHANGED
package/dist/lib/core.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/lib/core.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAejD,eAAO,MAAM,aAAa,EAAE,MAA2C,CAAC;AACxE,KAAK,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AACpD,KAAK,WAAW,GACZ,OAAO,GACP,MAAM,GACN,QAAQ,GACR,SAAS,GACT,OAAO,GACP,UAAU,GACV,OAAO,GACP,WAAW,CAAC;AAwBhB,KAAK,mBAAmB,GAAG,SAAS,GAAG,SAAS,CAAC;AACjD,KAAK,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/lib/core.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/core.js
CHANGED
|
@@ -59,6 +59,32 @@ const ENV_BOOLEAN_SCHEMA = z.stringbool({
|
|
|
59
59
|
truthy: ['true', '1', 'yes', 'on'],
|
|
60
60
|
falsy: ['false', '0', 'no', 'off'],
|
|
61
61
|
});
|
|
62
|
+
function tryParseUrlHost(raw) {
|
|
63
|
+
if (raw.includes('://')) {
|
|
64
|
+
const hostname = URL.parse(raw)?.hostname;
|
|
65
|
+
if (hostname)
|
|
66
|
+
return normalizeHostname(hostname);
|
|
67
|
+
}
|
|
68
|
+
const candidateHostname = URL.parse(`http://${raw}`)?.hostname;
|
|
69
|
+
if (candidateHostname)
|
|
70
|
+
return normalizeHostname(candidateHostname);
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
function tryParseIpv6Bracket(lowered) {
|
|
74
|
+
if (!lowered.startsWith('['))
|
|
75
|
+
return undefined;
|
|
76
|
+
const end = lowered.indexOf(']');
|
|
77
|
+
return end === -1 ? null : normalizeHostname(lowered.slice(1, end));
|
|
78
|
+
}
|
|
79
|
+
function tryParseHostPort(lowered) {
|
|
80
|
+
const firstColon = lowered.indexOf(':');
|
|
81
|
+
if (firstColon === -1)
|
|
82
|
+
return normalizeHostname(lowered);
|
|
83
|
+
if (lowered.includes(':', firstColon + 1))
|
|
84
|
+
return null;
|
|
85
|
+
const host = lowered.slice(0, firstColon);
|
|
86
|
+
return host ? normalizeHostname(host) : null;
|
|
87
|
+
}
|
|
62
88
|
const EnvParser = {
|
|
63
89
|
integerValue(envValue, opts) {
|
|
64
90
|
if (!envValue)
|
|
@@ -146,30 +172,16 @@ const EnvParser = {
|
|
|
146
172
|
const raw = value.trim();
|
|
147
173
|
if (!raw)
|
|
148
174
|
return null;
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
return normalizeHostname(hostname);
|
|
153
|
-
}
|
|
154
|
-
const candidateHostname = URL.parse(`http://${raw}`)?.hostname;
|
|
155
|
-
if (candidateHostname)
|
|
156
|
-
return normalizeHostname(candidateHostname);
|
|
175
|
+
const fromUrl = tryParseUrlHost(raw);
|
|
176
|
+
if (fromUrl !== undefined)
|
|
177
|
+
return fromUrl;
|
|
157
178
|
const lowered = raw.toLowerCase();
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
return null;
|
|
162
|
-
return normalizeHostname(lowered.slice(1, end));
|
|
163
|
-
}
|
|
179
|
+
const fromBracket = tryParseIpv6Bracket(lowered);
|
|
180
|
+
if (fromBracket !== undefined)
|
|
181
|
+
return fromBracket;
|
|
164
182
|
if (isIP(lowered) === 6)
|
|
165
183
|
return stripTrailingDots(lowered);
|
|
166
|
-
|
|
167
|
-
if (firstColon === -1)
|
|
168
|
-
return normalizeHostname(lowered);
|
|
169
|
-
if (lowered.includes(':', firstColon + 1))
|
|
170
|
-
return null;
|
|
171
|
-
const host = lowered.slice(0, firstColon);
|
|
172
|
-
return host ? normalizeHostname(host) : null;
|
|
184
|
+
return tryParseHostPort(lowered);
|
|
173
185
|
},
|
|
174
186
|
formatHostForUrl(hostname) {
|
|
175
187
|
if (hostname.includes(':') && !hostname.startsWith('['))
|
|
@@ -409,7 +421,7 @@ export const config = {
|
|
|
409
421
|
format: env['LOG_FORMAT']?.toLowerCase() === 'json' ? 'json' : 'text',
|
|
410
422
|
},
|
|
411
423
|
constants: {
|
|
412
|
-
|
|
424
|
+
maxHtmlBytes: MAX_HTML_BYTES,
|
|
413
425
|
maxUrlLength: 2048,
|
|
414
426
|
maxInlineContentChars: MAX_INLINE_CONTENT_CHARS,
|
|
415
427
|
},
|
|
@@ -913,11 +925,15 @@ function writeLog(level, message, meta) {
|
|
|
913
925
|
}
|
|
914
926
|
forwardMcpLog(level, message, meta, sessionId);
|
|
915
927
|
}
|
|
916
|
-
function
|
|
928
|
+
function resolveLogServer(sessionId) {
|
|
917
929
|
const server = sessionId ? sessionServers.get(sessionId) : mcpServer;
|
|
918
930
|
if (!server)
|
|
919
|
-
return;
|
|
920
|
-
|
|
931
|
+
return undefined;
|
|
932
|
+
return server.isConnected() ? server : undefined;
|
|
933
|
+
}
|
|
934
|
+
function forwardMcpLog(level, message, meta, sessionId) {
|
|
935
|
+
const server = resolveLogServer(sessionId);
|
|
936
|
+
if (!server)
|
|
921
937
|
return;
|
|
922
938
|
if (!shouldForwardMcpLog(level, sessionId))
|
|
923
939
|
return;
|
|
@@ -1041,7 +1057,7 @@ class SessionCleanupLoop {
|
|
|
1041
1057
|
const evicted = this.store.evictExpired();
|
|
1042
1058
|
for (let i = 0; i < evicted.length; i += SESSION_CLOSE_BATCH_SIZE) {
|
|
1043
1059
|
const batch = evicted.slice(i, i + SESSION_CLOSE_BATCH_SIZE);
|
|
1044
|
-
const results = await Promise.allSettled(batch.map((
|
|
1060
|
+
const results = await Promise.allSettled(batch.map(({ id, entry }) => this.closeExpiredSession(id, entry)));
|
|
1045
1061
|
logRejectedSettledResults(results, 'Failed to process expired session cleanup task');
|
|
1046
1062
|
if (signal.aborted)
|
|
1047
1063
|
return;
|
|
@@ -1053,7 +1069,7 @@ class SessionCleanupLoop {
|
|
|
1053
1069
|
});
|
|
1054
1070
|
}
|
|
1055
1071
|
}
|
|
1056
|
-
async closeExpiredSession(session) {
|
|
1072
|
+
async closeExpiredSession(sessionId, session) {
|
|
1057
1073
|
if (this.onEvictSession) {
|
|
1058
1074
|
try {
|
|
1059
1075
|
await this.onEvictSession(session);
|
|
@@ -1065,7 +1081,7 @@ class SessionCleanupLoop {
|
|
|
1065
1081
|
}
|
|
1066
1082
|
}
|
|
1067
1083
|
try {
|
|
1068
|
-
|
|
1084
|
+
unregisterMcpSessionServer(sessionId);
|
|
1069
1085
|
}
|
|
1070
1086
|
catch (error) {
|
|
1071
1087
|
logWarn('Failed to unregister session server', {
|
package/dist/lib/dom-prep.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export declare function serializeDocumentForMarkdown(document: Document, fallbac
|
|
|
6
6
|
/** Surface hidden tab panels, then strip unselected tab triggers. */
|
|
7
7
|
export declare function normalizeTabContent(document: Document): void;
|
|
8
8
|
export declare function surfaceCodeEditorContent(document: Document): void;
|
|
9
|
+
export declare function stripDocsControls(document: Document): void;
|
|
10
|
+
export declare function runDocsControlPass(document: Document): void;
|
|
9
11
|
export declare function prepareDocumentForMarkdown(document: Document, baseUrl?: string, signal?: AbortSignal): void;
|
|
10
12
|
export declare function removeNoiseFromHtml(html: string, document?: Document, baseUrl?: string, signal?: AbortSignal): string;
|
|
11
13
|
export declare function getVisibleTextLength(htmlOrDocument: string | Document): number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dom-prep.d.ts","sourceRoot":"","sources":["../../src/lib/dom-prep.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"dom-prep.d.ts","sourceRoot":"","sources":["../../src/lib/dom-prep.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AA6oB9D,eAAO,MAAM,sBAAsB,QAAmB,CAAC;AAyCvD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CA6B9D;AAuBD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAY/D;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,GACf,MAAM,CASR;AA0CD,qEAAqE;AACrE,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAG5D;AA0RD,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CA2BjE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAE1D;AAWD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAQ3D;AAkCD,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,GACnB,IAAI,CAON;AA4BD,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,QAAQ,EACnB,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,GACnB,MAAM,CAcR;AA0ED,wBAAgB,oBAAoB,CAClC,cAAc,EAAE,MAAM,GAAG,QAAQ,GAChC,MAAM,CAaR;AA+KD,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,QAAQ,GACjB,QAAQ,GAAG,IAAI,CAsBjB"}
|
package/dist/lib/dom-prep.js
CHANGED
|
@@ -13,6 +13,9 @@ const ASIDE_NAV_MIN_LINKS = 10;
|
|
|
13
13
|
const INLINE_DEMO_INSTRUCTION_MAX_CHARS = 160;
|
|
14
14
|
const REDUNDANT_PREVIEW_SEGMENT_MAX_CHARS = 60;
|
|
15
15
|
const REDUNDANT_PREVIEW_MAX_SEGMENTS = 12;
|
|
16
|
+
const DENSITY_BASE_CHARS = 100;
|
|
17
|
+
const MAX_PERMALINK_TEXT_LENGTH = 2;
|
|
18
|
+
const MIN_LINES_FOR_TRUNCATION_CHECK = 3;
|
|
16
19
|
// ── Regex patterns ──────────────────────────────────────────────────
|
|
17
20
|
const HTML_DOCUMENT_MARKERS = /<\s*(?:!doctype|html|head|body)\b/i;
|
|
18
21
|
const HTML_FRAGMENT_MARKERS = /<\s*(?:article|main|section|div|nav|footer|header|aside|table|ul|ol)\b/i;
|
|
@@ -134,10 +137,16 @@ const DOCS_CONTROL_SELECTORS = [
|
|
|
134
137
|
'.mobile-header',
|
|
135
138
|
'.overlay.sidebar-overlay',
|
|
136
139
|
'.overlay.toc-overlay',
|
|
140
|
+
'.baseline-indicator',
|
|
137
141
|
'.back-to-top',
|
|
138
142
|
'.backtotop',
|
|
139
143
|
'.headerlink',
|
|
140
144
|
'[title="Edit this page"]',
|
|
145
|
+
'.article-footer',
|
|
146
|
+
'.baseline-indicator',
|
|
147
|
+
'baseline-indicator',
|
|
148
|
+
'mdn-content-feedback',
|
|
149
|
+
'interactive-example',
|
|
141
150
|
];
|
|
142
151
|
let cachedContext;
|
|
143
152
|
let lastContextKey;
|
|
@@ -260,8 +269,8 @@ function isWithinPrimaryContent(element) {
|
|
|
260
269
|
}
|
|
261
270
|
return false;
|
|
262
271
|
}
|
|
263
|
-
function
|
|
264
|
-
if (element.querySelector('nav'))
|
|
272
|
+
function isLinkDenseNavigation(element, checkContainedNav = false) {
|
|
273
|
+
if (checkContainedNav && element.querySelector('nav'))
|
|
265
274
|
return true;
|
|
266
275
|
const links = element.querySelectorAll('a[href]');
|
|
267
276
|
if (links.length < ASIDE_NAV_MIN_LINKS)
|
|
@@ -269,16 +278,8 @@ function isNavigationAside(element) {
|
|
|
269
278
|
const textLen = (element.textContent || '').trim().length;
|
|
270
279
|
if (textLen === 0)
|
|
271
280
|
return true;
|
|
272
|
-
return links.length / (textLen /
|
|
273
|
-
|
|
274
|
-
function isNavigationSidebar(element) {
|
|
275
|
-
const links = element.querySelectorAll('a[href]');
|
|
276
|
-
if (links.length < ASIDE_NAV_MIN_LINKS)
|
|
277
|
-
return false;
|
|
278
|
-
const textLen = (element.textContent || '').trim().length;
|
|
279
|
-
if (textLen === 0)
|
|
280
|
-
return true;
|
|
281
|
-
return links.length / (textLen / 100) >= ASIDE_NAV_LINK_DENSITY_THRESHOLD;
|
|
281
|
+
return (links.length / (textLen / DENSITY_BASE_CHARS) >=
|
|
282
|
+
ASIDE_NAV_LINK_DENSITY_THRESHOLD);
|
|
282
283
|
}
|
|
283
284
|
function shouldPreserve(element, tagName) {
|
|
284
285
|
// Check Dialog
|
|
@@ -297,7 +298,7 @@ function shouldPreserve(element, tagName) {
|
|
|
297
298
|
const textLen = (element.textContent || '').trim().length;
|
|
298
299
|
if (textLen < NAV_FOOTER_MIN_CHARS_FOR_PRESERVATION)
|
|
299
300
|
return false;
|
|
300
|
-
if (
|
|
301
|
+
if (isLinkDenseNavigation(element))
|
|
301
302
|
return false;
|
|
302
303
|
return true;
|
|
303
304
|
}
|
|
@@ -305,7 +306,7 @@ function shouldPreserve(element, tagName) {
|
|
|
305
306
|
if (tagName === 'aside') {
|
|
306
307
|
if (!isWithinPrimaryContent(element))
|
|
307
308
|
return false;
|
|
308
|
-
return !
|
|
309
|
+
return !isLinkDenseNavigation(element, true);
|
|
309
310
|
}
|
|
310
311
|
return false;
|
|
311
312
|
}
|
|
@@ -317,6 +318,15 @@ function removeNodes(nodes) {
|
|
|
317
318
|
}
|
|
318
319
|
}
|
|
319
320
|
}
|
|
321
|
+
// Checks if the element itself or any of its ancestors contain primary content indicators (article, main, role=main).
|
|
322
|
+
function containsPrimaryContent(element) {
|
|
323
|
+
const tag = element.tagName.toLowerCase();
|
|
324
|
+
if (tag === 'article' || tag === 'main')
|
|
325
|
+
return true;
|
|
326
|
+
if (element.getAttribute('role') === 'main')
|
|
327
|
+
return true;
|
|
328
|
+
return element.querySelector('article,main,[role="main"]') !== null;
|
|
329
|
+
}
|
|
320
330
|
function isPromoMatch(className, id, element, context) {
|
|
321
331
|
if (!context.promoEnabled)
|
|
322
332
|
return false;
|
|
@@ -324,8 +334,11 @@ function isPromoMatch(className, id, element, context) {
|
|
|
324
334
|
context.promoMatchers.aggressive.test(id);
|
|
325
335
|
if (aggTest)
|
|
326
336
|
return !isWithinPrimaryContent(element);
|
|
327
|
-
|
|
328
|
-
|
|
337
|
+
// Base test must match and be outside primary content to be considered noise
|
|
338
|
+
if (!context.promoMatchers.base.test(className) &&
|
|
339
|
+
!context.promoMatchers.base.test(id))
|
|
340
|
+
return false;
|
|
341
|
+
return !containsPrimaryContent(element);
|
|
329
342
|
}
|
|
330
343
|
function isStructuralNoise(tagName, interactive, context) {
|
|
331
344
|
return context.structuralTags.has(tagName) && !interactive;
|
|
@@ -437,12 +450,14 @@ function isHeadingPermalinkAnchor(anchor) {
|
|
|
437
450
|
return true;
|
|
438
451
|
}
|
|
439
452
|
const className = anchor.getAttribute('class') ?? '';
|
|
440
|
-
if (HEADING_PERMALINK_CLASS_PATTERN.test(className) &&
|
|
453
|
+
if (HEADING_PERMALINK_CLASS_PATTERN.test(className) &&
|
|
454
|
+
text.length <= MAX_PERMALINK_TEXT_LENGTH) {
|
|
441
455
|
return true;
|
|
442
456
|
}
|
|
443
457
|
const ariaHidden = anchor.getAttribute('aria-hidden');
|
|
444
458
|
const tabindex = anchor.getAttribute('tabindex');
|
|
445
|
-
return (ariaHidden === 'true' || tabindex === '-1') &&
|
|
459
|
+
return ((ariaHidden === 'true' || tabindex === '-1') &&
|
|
460
|
+
text.length <= MAX_PERMALINK_TEXT_LENGTH);
|
|
446
461
|
}
|
|
447
462
|
function getDirectRows(section) {
|
|
448
463
|
return Array.from(section.children).filter((child) => child.tagName === 'TR');
|
|
@@ -926,7 +941,7 @@ export function surfaceCodeEditorContent(document) {
|
|
|
926
941
|
textarea.remove();
|
|
927
942
|
}
|
|
928
943
|
}
|
|
929
|
-
function stripDocsControls(document) {
|
|
944
|
+
export function stripDocsControls(document) {
|
|
930
945
|
removeNodes(document.querySelectorAll(DOCS_CONTROL_SELECTORS.join(',')));
|
|
931
946
|
}
|
|
932
947
|
function stripAriaLiveInstructions(document) {
|
|
@@ -937,7 +952,7 @@ function stripAriaLiveInstructions(document) {
|
|
|
937
952
|
}
|
|
938
953
|
}
|
|
939
954
|
}
|
|
940
|
-
function runDocsControlPass(document) {
|
|
955
|
+
export function runDocsControlPass(document) {
|
|
941
956
|
normalizeTabContent(document);
|
|
942
957
|
surfaceCodeEditorContent(document);
|
|
943
958
|
cleanHeadings(document);
|
|
@@ -1131,6 +1146,11 @@ const SENTENCE_ENDING_CODES = new Set([
|
|
|
1131
1146
|
CharCode.QUESTION,
|
|
1132
1147
|
CharCode.COLON,
|
|
1133
1148
|
CharCode.SEMICOLON,
|
|
1149
|
+
CharCode.DOUBLE_QUOTE,
|
|
1150
|
+
CharCode.SINGLE_QUOTE,
|
|
1151
|
+
CharCode.RIGHT_PAREN,
|
|
1152
|
+
CharCode.RIGHT_BRACKET,
|
|
1153
|
+
CharCode.BACKTICK,
|
|
1134
1154
|
]);
|
|
1135
1155
|
function trimLineOffsets(text, lineStart, lineEnd) {
|
|
1136
1156
|
let start = lineStart;
|
|
@@ -1174,7 +1194,7 @@ function hasTruncatedSentences(text) {
|
|
|
1174
1194
|
lineStart = i + 1;
|
|
1175
1195
|
}
|
|
1176
1196
|
}
|
|
1177
|
-
if (linesFound <
|
|
1197
|
+
if (linesFound < MIN_LINES_FOR_TRUNCATION_CHECK)
|
|
1178
1198
|
return false;
|
|
1179
1199
|
return incompleteFound / linesFound > MAX_TRUNCATED_LINE_RATIO;
|
|
1180
1200
|
}
|
|
@@ -1183,12 +1203,37 @@ function passesContentRatioGate(articleTextLength, document) {
|
|
|
1183
1203
|
return (originalLength < MIN_HTML_LENGTH_FOR_GATE ||
|
|
1184
1204
|
articleTextLength / originalLength >= MIN_CONTENT_RATIO);
|
|
1185
1205
|
}
|
|
1206
|
+
function countRealImages(doc) {
|
|
1207
|
+
let count = 0;
|
|
1208
|
+
for (const img of doc.querySelectorAll('img')) {
|
|
1209
|
+
const src = img.getAttribute('src') ?? '';
|
|
1210
|
+
if (!src.startsWith('data:'))
|
|
1211
|
+
count++;
|
|
1212
|
+
}
|
|
1213
|
+
return count;
|
|
1214
|
+
}
|
|
1215
|
+
const DATA_IMG_PATTERN = /<img\b[^>]*\bsrc\s*=\s*["']?data:/gi;
|
|
1216
|
+
function countRealImagesFromHtml(html) {
|
|
1217
|
+
const total = html.match(/<img\b/gi)?.length ?? 0;
|
|
1218
|
+
const dataImages = html.match(DATA_IMG_PATTERN)?.length ?? 0;
|
|
1219
|
+
return total - dataImages;
|
|
1220
|
+
}
|
|
1186
1221
|
function passesRetentionRulesFromHtml(originalDoc, articleHtml) {
|
|
1187
1222
|
return RETENTION_RULES.every(({ selector, pattern, minThreshold, ratio }) => {
|
|
1188
|
-
|
|
1223
|
+
// Exclude lazy-loaded placeholder images (data: URI src) from the
|
|
1224
|
+
// original count so they don't inflate the denominator and cause
|
|
1225
|
+
// false retention failures.
|
|
1226
|
+
const original = selector === 'img'
|
|
1227
|
+
? countRealImages(originalDoc)
|
|
1228
|
+
: countMatchingElements(originalDoc, selector);
|
|
1189
1229
|
if (original < minThreshold)
|
|
1190
1230
|
return true;
|
|
1191
|
-
|
|
1231
|
+
// For images, also exclude data: URIs from the article count to
|
|
1232
|
+
// align with the denominator's real-image filtering.
|
|
1233
|
+
const articleCount = selector === 'img'
|
|
1234
|
+
? countRealImagesFromHtml(articleHtml)
|
|
1235
|
+
: (articleHtml.match(pattern)?.length ?? 0);
|
|
1236
|
+
return articleCount / original >= ratio;
|
|
1192
1237
|
});
|
|
1193
1238
|
}
|
|
1194
1239
|
function passesEmptySectionRatio(articleDoc) {
|
package/dist/lib/http.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/lib/http.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAShD,OAAO,EAAE,KAAK,EAAmB,MAAM,QAAQ,CAAC;AAehD,OAAO,EAOL,KAAK,eAAe,EAGrB,MAAM,UAAU,CAAC;AAsElB,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,MAAM,EACrB,SAAS,SAAQ,GAChB,MAAM,CAIR;AAkBD,wBAAgB,cAAc,CAC5B,GAAG,EAAE,cAAc,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,IAAI,CA6CN;
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/lib/http.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAShD,OAAO,EAAE,KAAK,EAAmB,MAAM,QAAQ,CAAC;AAehD,OAAO,EAOL,KAAK,eAAe,EAGrB,MAAM,UAAU,CAAC;AAsElB,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,MAAM,EACrB,SAAS,SAAQ,GAChB,MAAM,CAIR;AAkBD,wBAAgB,cAAc,CAC5B,GAAG,EAAE,cAAc,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,IAAI,CA6CN;AAmxCD,UAAU,qBAAqB;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA4JD,UAAU,YAAY;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AA6ND,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE/C;AACD,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG;IAC/C,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAEA;AACD,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEjE;AACD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAE9D;AACD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAExD;AACD,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,GACb,qBAAqB,CAEvB;AACD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,qBAAqB,EAC9B,QAAQ,EAAE,QAAQ,EAClB,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI,CAEN;AACD,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,qBAAqB,EAC9B,KAAK,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,MAAM,GACd,IAAI,CAEN;AACD,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,WAAW,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC,CAE7D;AACD,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CASzC;AACD,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,MAAM,CAAC,CAEjB;AACD,wBAAsB,wBAAwB,CAC5C,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC;IACT,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAED"}
|