@omnicross/core 0.2.0 → 0.3.0
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/{BuiltinToolExecutor-CS2WpXhM.d.cts → BuiltinToolExecutor-BHgH-EaZ.d.cts} +25 -2
- package/dist/{BuiltinToolExecutor-BluWyeob.d.ts → BuiltinToolExecutor-Bi1LmiTP.d.ts} +25 -2
- package/dist/{CompletionService-BiJqftc-.d.cts → CompletionService-BniP7j88.d.cts} +2 -2
- package/dist/{CompletionService-NXN_Av5W.d.ts → CompletionService-BqrKPwfA.d.ts} +2 -2
- package/dist/{ProviderProxy-CgIcCVwk.d.cts → ProviderProxy-Bz_nkOwq.d.cts} +1 -1
- package/dist/{ProviderProxy-DYoY5XoT.d.ts → ProviderProxy-Ckr6oTrE.d.ts} +1 -1
- package/dist/auth/GeminiCodeAssistProjectResolver.cjs +2 -2
- package/dist/auth/GeminiCodeAssistProjectResolver.js +1 -1
- package/dist/{chunk-FJNKXOWE.js → chunk-2C3TTBS7.js} +4 -4
- package/dist/{chunk-NZYN7C3P.cjs → chunk-2RCCLQYV.cjs} +53 -53
- package/dist/{chunk-CDHS2QDC.js → chunk-4PFWFODB.js} +53 -53
- package/dist/{chunk-OST5RJOJ.cjs → chunk-4Z3ZLLC2.cjs} +13 -7
- package/dist/chunk-7RJI3NDI.cjs +236 -0
- package/dist/chunk-BTBEJRGL.cjs +781 -0
- package/dist/chunk-DBBR6RHF.js +236 -0
- package/dist/chunk-DXWFBBSK.js +781 -0
- package/dist/chunk-E4QHVXV5.cjs +118 -0
- package/dist/chunk-L7O2YQ5O.js +386 -0
- package/dist/{chunk-WSJE42SG.js → chunk-LKDAN4D7.js} +3684 -2462
- package/dist/{chunk-DEIUR2TH.js → chunk-LQYS2N47.js} +12 -8
- package/dist/chunk-MZEGQSKQ.js +118 -0
- package/dist/chunk-PTU7SXM3.cjs +386 -0
- package/dist/{chunk-CTKM773J.cjs → chunk-UPQIWJIE.cjs} +12 -8
- package/dist/{chunk-CFSGYFOZ.js → chunk-VL5TUDTM.js} +7 -1
- package/dist/{chunk-7B56AJBB.cjs → chunk-VSYQ6XYN.cjs} +2233 -1011
- package/dist/{chunk-TVYA5JSQ.cjs → chunk-ZAPN7XA6.cjs} +5 -5
- package/dist/completion/BuiltinToolExecutor.cjs +2 -2
- package/dist/completion/BuiltinToolExecutor.d.cts +3 -1
- package/dist/completion/BuiltinToolExecutor.d.ts +3 -1
- package/dist/completion/BuiltinToolExecutor.js +1 -1
- package/dist/completion/CompletionService.cjs +11 -10
- package/dist/completion/CompletionService.d.cts +6 -3
- package/dist/completion/CompletionService.d.ts +6 -3
- package/dist/completion/CompletionService.js +10 -9
- package/dist/completion.cjs +11 -10
- package/dist/completion.d.cts +6 -3
- package/dist/completion.d.ts +6 -3
- package/dist/completion.js +10 -9
- package/dist/egress-I46O_p5L.d.cts +126 -0
- package/dist/egress-I46O_p5L.d.ts +126 -0
- package/dist/frontends-Doz0RaWu.d.cts +97 -0
- package/dist/frontends-Doz0RaWu.d.ts +97 -0
- package/dist/image-generation.cjs +2 -2
- package/dist/image-generation.d.cts +7 -4
- package/dist/image-generation.d.ts +7 -4
- package/dist/image-generation.js +1 -1
- package/dist/index.cjs +25 -10
- package/dist/index.d.cts +12 -8
- package/dist/index.d.ts +12 -8
- package/dist/index.js +24 -9
- package/dist/openai-operation.d.cts +4 -1
- package/dist/openai-operation.d.ts +4 -1
- package/dist/outbound-api/routeResolver.d.cts +9 -5
- package/dist/outbound-api/routeResolver.d.ts +9 -5
- package/dist/outbound-api/subscriptionRegistryPort.d.cts +4 -1
- package/dist/outbound-api/subscriptionRegistryPort.d.ts +4 -1
- package/dist/outbound-api/types.d.cts +8 -4
- package/dist/outbound-api/types.d.ts +8 -4
- package/dist/outbound-api.cjs +25 -10
- package/dist/outbound-api.d.cts +117 -8
- package/dist/outbound-api.d.ts +117 -8
- package/dist/outbound-api.js +24 -9
- package/dist/pipeline/AccountAllowanceScheduling.d.cts +8 -4
- package/dist/pipeline/AccountAllowanceScheduling.d.ts +8 -4
- package/dist/pipeline/upstreamFetch.cjs +2 -2
- package/dist/pipeline/upstreamFetch.js +1 -1
- package/dist/ports.d.cts +8 -4
- package/dist/ports.d.ts +8 -4
- package/dist/provider-proxy/ProviderProxy.cjs +11 -10
- package/dist/provider-proxy/ProviderProxy.d.cts +5 -2
- package/dist/provider-proxy/ProviderProxy.d.ts +5 -2
- package/dist/provider-proxy/ProviderProxy.js +10 -9
- package/dist/provider-proxy/ingress/providerProxyShared.cjs +13 -10
- package/dist/provider-proxy/ingress/providerProxyShared.d.cts +22 -3
- package/dist/provider-proxy/ingress/providerProxyShared.d.ts +22 -3
- package/dist/provider-proxy/ingress/providerProxyShared.js +12 -9
- package/dist/provider-proxy/types.d.cts +4 -1
- package/dist/provider-proxy/types.d.ts +4 -1
- package/dist/provider-proxy.cjs +11 -10
- package/dist/provider-proxy.d.cts +10 -6
- package/dist/provider-proxy.d.ts +10 -6
- package/dist/provider-proxy.js +10 -9
- package/dist/proxy-UZTtjPZx.d.cts +18 -0
- package/dist/proxy-UZTtjPZx.d.ts +18 -0
- package/dist/{routeResolver-rpKQLyDO.d.cts → routeResolver-Da0yvkL1.d.cts} +2 -2
- package/dist/{routeResolver-CTCcSHWu.d.ts → routeResolver-STwMz_G4.d.ts} +2 -2
- package/dist/runtime-5NCT3J3T.cjs +8 -0
- package/dist/runtime-JTHUWCBM.js +8 -0
- package/dist/runtime-t8AZacFF.d.cts +233 -0
- package/dist/runtime-t8AZacFF.d.ts +233 -0
- package/dist/search/api.cjs +766 -0
- package/dist/search/api.d.cts +385 -0
- package/dist/search/api.d.ts +385 -0
- package/dist/search/api.js +766 -0
- package/dist/search/http.cjs +37 -0
- package/dist/search/http.d.cts +323 -0
- package/dist/search/http.d.ts +323 -0
- package/dist/search/http.js +37 -0
- package/dist/search.cjs +57 -0
- package/dist/search.d.cts +113 -0
- package/dist/search.d.ts +113 -0
- package/dist/search.js +57 -0
- package/dist/transformer/transformers/AnthropicTransformer.cjs +3 -3
- package/dist/transformer/transformers/AnthropicTransformer.js +2 -2
- package/dist/transformer/transformers.cjs +7 -7
- package/dist/transformer/transformers.js +6 -6
- package/dist/transformer.cjs +6 -6
- package/dist/transformer.js +5 -5
- package/dist/{types-DsHBBk3h.d.cts → types-BSIJdsyl.d.cts} +15 -0
- package/dist/{types-CbglB73l.d.cts → types-Be-yt_6T.d.cts} +1 -1
- package/dist/{types-CVRge76p.d.ts → types-By9Tg6-I.d.ts} +15 -0
- package/dist/types-CbCZqLGg.d.cts +127 -0
- package/dist/types-CbCZqLGg.d.ts +127 -0
- package/dist/{types-jjU24eYG.d.cts → types-D-oHYusb.d.cts} +73 -4
- package/dist/{types-Bd72H4SB.d.ts → types-Dm4_36V4.d.ts} +1 -1
- package/dist/{types-5T223WYQ.d.ts → types-Dvlpjn0d.d.ts} +73 -4
- package/package.json +6 -3
- package/dist/{chunk-6OC3ORW6.js → chunk-EUZRH544.js} +3 -3
- package/dist/{chunk-SQMAEDNE.cjs → chunk-POUTD5AM.cjs} +2 -2
|
@@ -0,0 +1,781 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2;
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
var _chunk7RJI3NDIcjs = require('./chunk-7RJI3NDI.cjs');
|
|
6
|
+
|
|
7
|
+
// src/search/http/errors.ts
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
var _searchtypes = require('@omnicross/contracts/search-types');
|
|
12
|
+
|
|
13
|
+
// src/search/http/types.ts
|
|
14
|
+
var SEARCH_HTTP_TRANSPORT_ID = "undici";
|
|
15
|
+
|
|
16
|
+
// src/search/http/errors.ts
|
|
17
|
+
function searchHttpError(code, message, init) {
|
|
18
|
+
return new (0, _searchtypes.SearchProviderError)(code, message, {
|
|
19
|
+
providerId: init.providerId,
|
|
20
|
+
retryable: init.retryable,
|
|
21
|
+
cause: init.cause,
|
|
22
|
+
// transport/stage last so a caller-supplied `details` can never shadow them.
|
|
23
|
+
details: {
|
|
24
|
+
...init.details,
|
|
25
|
+
transport: _nullishCoalesce(init.transport, () => ( SEARCH_HTTP_TRANSPORT_ID)),
|
|
26
|
+
stage: init.stage
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function asSearchProviderError(value, providerId, fallbackStage) {
|
|
31
|
+
if (_searchtypes.isSearchProviderError.call(void 0, value)) {
|
|
32
|
+
const complete = value.providerId !== void 0 && _optionalChain([value, 'access', _ => _.details, 'optionalAccess', _2 => _2.transport]) !== void 0 && _optionalChain([value, 'access', _3 => _3.details, 'optionalAccess', _4 => _4.stage]) !== void 0;
|
|
33
|
+
if (complete) return value;
|
|
34
|
+
return searchHttpError(value.code, value.message, {
|
|
35
|
+
stage: _nullishCoalesce(_optionalChain([value, 'access', _5 => _5.details, 'optionalAccess', _6 => _6.stage]), () => ( fallbackStage)),
|
|
36
|
+
providerId: _nullishCoalesce(value.providerId, () => ( providerId)),
|
|
37
|
+
retryable: value.retryable,
|
|
38
|
+
cause: value,
|
|
39
|
+
details: value.details
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return searchHttpError("upstream_unavailable", describeError(value), {
|
|
43
|
+
stage: fallbackStage,
|
|
44
|
+
providerId,
|
|
45
|
+
retryable: true,
|
|
46
|
+
cause: value
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function describeError(value) {
|
|
50
|
+
if (value instanceof Error && value.message) return value.message;
|
|
51
|
+
if (typeof value === "string" && value) return value;
|
|
52
|
+
return "search request failed";
|
|
53
|
+
}
|
|
54
|
+
function hostOf(url) {
|
|
55
|
+
try {
|
|
56
|
+
return new URL(url).hostname;
|
|
57
|
+
} catch (e) {
|
|
58
|
+
return "unknown-host";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// src/search/http/engine.ts
|
|
63
|
+
var SEARCH_RESPONSE_BYTES = 2 * 1024 * 1024;
|
|
64
|
+
var DEFAULT_SEARCH_TIMEOUT_MS = 15e3;
|
|
65
|
+
var DEFAULT_MAX_RESULTS = 5;
|
|
66
|
+
var MAX_RESULTS = 10;
|
|
67
|
+
function clampMaxResults(maxResults) {
|
|
68
|
+
return Math.min(Math.max(_nullishCoalesce(maxResults, () => ( DEFAULT_MAX_RESULTS)), 1), MAX_RESULTS);
|
|
69
|
+
}
|
|
70
|
+
async function runHttpSearch(engine, transport, query, options = {}) {
|
|
71
|
+
const providerId = engine.providerId;
|
|
72
|
+
if (_optionalChain([options, 'access', _7 => _7.signal, 'optionalAccess', _8 => _8.aborted])) {
|
|
73
|
+
throw searchHttpError("cancelled", "search was cancelled before it started", {
|
|
74
|
+
stage: "fetch",
|
|
75
|
+
providerId,
|
|
76
|
+
retryable: false
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
const maxResults = clampMaxResults(options.maxResults);
|
|
80
|
+
const timeoutMs = _nullishCoalesce(options.timeout, () => ( DEFAULT_SEARCH_TIMEOUT_MS));
|
|
81
|
+
const deadline = Date.now() + timeoutMs;
|
|
82
|
+
const urls = engine.buildUrls(query);
|
|
83
|
+
let sawRecognizedEmpty = false;
|
|
84
|
+
let lastError = searchHttpError(
|
|
85
|
+
"timeout",
|
|
86
|
+
"search deadline expired before any request was attempted",
|
|
87
|
+
{ stage: "fetch", providerId, retryable: true }
|
|
88
|
+
);
|
|
89
|
+
for (const [index, url] of urls.entries()) {
|
|
90
|
+
const remainingMs = deadline - Date.now();
|
|
91
|
+
if (remainingMs <= 0) break;
|
|
92
|
+
const attemptTimeoutMs = Math.max(1, Math.floor(remainingMs / (urls.length - index)));
|
|
93
|
+
try {
|
|
94
|
+
const resource = await transport(url, {
|
|
95
|
+
timeoutMs: attemptTimeoutMs,
|
|
96
|
+
maxResponseBytes: SEARCH_RESPONSE_BYTES,
|
|
97
|
+
signal: options.signal,
|
|
98
|
+
providerId
|
|
99
|
+
});
|
|
100
|
+
if (engine.isChallengeStatus(resource.status)) {
|
|
101
|
+
throw searchHttpError(
|
|
102
|
+
"upstream_unavailable",
|
|
103
|
+
`server returned a bot-challenge response (HTTP ${resource.status})`,
|
|
104
|
+
{ stage: "challenge", providerId, retryable: false, details: { status: String(resource.status) } }
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
const trustError = _optionalChain([engine, 'access', _9 => _9.trustError, 'optionalCall', _10 => _10(resource.finalUrl, resource.rawText)]);
|
|
108
|
+
if (trustError) {
|
|
109
|
+
throw searchHttpError("upstream_unavailable", trustError, {
|
|
110
|
+
stage: "trust",
|
|
111
|
+
providerId,
|
|
112
|
+
retryable: false
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
const parsed = engine.parse(resource.rawText, maxResults);
|
|
116
|
+
if (parsed.results.length > 0) return parsed.results;
|
|
117
|
+
if (parsed.recognized) {
|
|
118
|
+
sawRecognizedEmpty = true;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
throw searchHttpError(
|
|
122
|
+
"parse_failed",
|
|
123
|
+
`response is not recognizable as a ${engine.label} search result page`,
|
|
124
|
+
{ stage: "parse", providerId, retryable: false }
|
|
125
|
+
);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
const normalized = asSearchProviderError(error, providerId, "fetch");
|
|
128
|
+
if (normalized.code === "cancelled") throw normalized;
|
|
129
|
+
lastError = normalized;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (sawRecognizedEmpty) return [];
|
|
133
|
+
throw lastError;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// src/search/http/parsers/bing.ts
|
|
137
|
+
var _jsdom = require('jsdom');
|
|
138
|
+
|
|
139
|
+
// src/search/http/text.ts
|
|
140
|
+
var _entities = require('entities');
|
|
141
|
+
var MAX_TEXT_LENGTH = 500;
|
|
142
|
+
function cleanText(value) {
|
|
143
|
+
return _entities.decodeHTML.call(void 0, _nullishCoalesce(value, () => ( ""))).replace(/\s+/g, " ").trim().slice(0, MAX_TEXT_LENGTH);
|
|
144
|
+
}
|
|
145
|
+
function isUsableResult(result) {
|
|
146
|
+
return Boolean(result.title && /^https?:\/\//i.test(result.url));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// src/search/http/parsers/bing.ts
|
|
150
|
+
var BING_SERP_URL = "https://www.bing.com/search";
|
|
151
|
+
var BING_SERP_MARKERS = "#b_results, .b_algo";
|
|
152
|
+
function bingResultLinks(document) {
|
|
153
|
+
const scoped = [
|
|
154
|
+
...document.querySelectorAll("li.b_algo h2 a, #b_results .b_algo h2 a")
|
|
155
|
+
];
|
|
156
|
+
return scoped.length > 0 ? scoped : [...document.querySelectorAll("h2 a[href]")];
|
|
157
|
+
}
|
|
158
|
+
function isBingSerp(document) {
|
|
159
|
+
return document.querySelector(BING_SERP_MARKERS) !== null;
|
|
160
|
+
}
|
|
161
|
+
function parseBingSerp(html, maxResults) {
|
|
162
|
+
const document = new (0, _jsdom.JSDOM)(html, { url: BING_SERP_URL }).window.document;
|
|
163
|
+
const results = bingResultLinks(document).map((link) => {
|
|
164
|
+
const container = link.closest("li.b_algo, .b_algo");
|
|
165
|
+
return {
|
|
166
|
+
title: cleanText(link.textContent),
|
|
167
|
+
url: cleanBingUrl(link.href),
|
|
168
|
+
content: cleanText(_optionalChain([container, 'optionalAccess', _11 => _11.querySelector, 'call', _12 => _12(".b_caption p, .b_algoSlug, p"), 'optionalAccess', _13 => _13.textContent]))
|
|
169
|
+
};
|
|
170
|
+
}).filter(isUsableResult).slice(0, maxResults);
|
|
171
|
+
return { recognized: isBingSerp(document), results };
|
|
172
|
+
}
|
|
173
|
+
function cleanBingUrl(rawUrl) {
|
|
174
|
+
try {
|
|
175
|
+
const url = new URL(rawUrl, "https://www.bing.com");
|
|
176
|
+
const hostname = url.hostname.toLowerCase();
|
|
177
|
+
if ((hostname === "bing.com" || hostname.endsWith(".bing.com")) && url.pathname === "/ck/a") {
|
|
178
|
+
const encodedTarget = url.searchParams.get("u");
|
|
179
|
+
if (_optionalChain([encodedTarget, 'optionalAccess', _14 => _14.startsWith, 'call', _15 => _15("a1")])) {
|
|
180
|
+
const decoded = Buffer.from(encodedTarget.slice(2), "base64url").toString("utf8");
|
|
181
|
+
if (/^https?:\/\//i.test(decoded)) return decoded;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return url.href;
|
|
185
|
+
} catch (e2) {
|
|
186
|
+
return rawUrl;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// src/search/http/trust.ts
|
|
191
|
+
|
|
192
|
+
var QUERY_STOP_WORDS = /* @__PURE__ */ new Set([
|
|
193
|
+
"a",
|
|
194
|
+
"an",
|
|
195
|
+
"and",
|
|
196
|
+
"at",
|
|
197
|
+
"by",
|
|
198
|
+
"for",
|
|
199
|
+
"from",
|
|
200
|
+
"in",
|
|
201
|
+
"of",
|
|
202
|
+
"on",
|
|
203
|
+
"or",
|
|
204
|
+
"the",
|
|
205
|
+
"to",
|
|
206
|
+
"with",
|
|
207
|
+
"site",
|
|
208
|
+
"filetype",
|
|
209
|
+
"inurl",
|
|
210
|
+
"intitle"
|
|
211
|
+
]);
|
|
212
|
+
function bingSearchPageTrustError(finalUrl, html) {
|
|
213
|
+
let parsed;
|
|
214
|
+
try {
|
|
215
|
+
parsed = new URL(finalUrl);
|
|
216
|
+
} catch (e3) {
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
if (parsed.pathname !== "/search") return null;
|
|
220
|
+
const hostname = parsed.hostname.toLowerCase();
|
|
221
|
+
if (hostname !== "bing.com" && !hostname.endsWith(".bing.com")) return null;
|
|
222
|
+
return bingTrustError(_nullishCoalesce(parsed.searchParams.get("q"), () => ( "")), html);
|
|
223
|
+
}
|
|
224
|
+
function bingTrustError(query, html) {
|
|
225
|
+
const document = new (0, _jsdom.JSDOM)(html).window.document;
|
|
226
|
+
const links = bingResultLinks(document);
|
|
227
|
+
if (links.length === 0) return null;
|
|
228
|
+
const terms = meaningfulQueryTerms(query);
|
|
229
|
+
if (terms.length === 0) return null;
|
|
230
|
+
const titleSearchable = separatorFree(
|
|
231
|
+
links.map((link) => _nullishCoalesce(link.textContent, () => ( ""))).join(" ").normalize("NFKC").toLocaleLowerCase()
|
|
232
|
+
);
|
|
233
|
+
if (!terms.some((term) => titleSearchable.includes(term))) {
|
|
234
|
+
return "Bing returned an untrusted search result page with zero query-term hits in result titles; refusing to return possible bot-decoy content.";
|
|
235
|
+
}
|
|
236
|
+
const searchable = separatorFree(
|
|
237
|
+
links.map((link) => {
|
|
238
|
+
const container = link.closest("li.b_algo, .b_algo");
|
|
239
|
+
return `${_nullishCoalesce(link.textContent, () => ( ""))} ${_nullishCoalesce(link.getAttribute("href"), () => ( ""))} ${_nullishCoalesce(_optionalChain([container, 'optionalAccess', _16 => _16.querySelector, 'call', _17 => _17(".b_caption p, .b_algoSlug, p"), 'optionalAccess', _18 => _18.textContent]), () => ( ""))}`;
|
|
240
|
+
}).join(" ").normalize("NFKC").toLocaleLowerCase()
|
|
241
|
+
);
|
|
242
|
+
const coveredTerms = terms.filter((term) => searchable.includes(term));
|
|
243
|
+
const requiredCoverage = terms.length === 1 ? 1 : 2;
|
|
244
|
+
return new Set(coveredTerms).size >= requiredCoverage ? null : "Bing returned an untrusted search result page; refusing to return possible bot-decoy content.";
|
|
245
|
+
}
|
|
246
|
+
function separatorFree(text) {
|
|
247
|
+
return text.replace(/[^\p{L}\p{N}\s]/gu, "");
|
|
248
|
+
}
|
|
249
|
+
function meaningfulQueryTerms(query) {
|
|
250
|
+
const terms = _nullishCoalesce(query.normalize("NFKC").toLocaleLowerCase().match(/[\p{L}\p{N}]{2,}/gu), () => ( []));
|
|
251
|
+
const expanded = terms.flatMap((term) => {
|
|
252
|
+
if (QUERY_STOP_WORDS.has(term) || !/\p{Script=Han}/u.test(term)) return [term];
|
|
253
|
+
const characters = [...term];
|
|
254
|
+
const bigrams = characters.slice(0, -1).map((character, index) => {
|
|
255
|
+
return character + characters[index + 1];
|
|
256
|
+
});
|
|
257
|
+
return [term, ...bigrams];
|
|
258
|
+
});
|
|
259
|
+
return [...new Set(expanded.filter((term) => !QUERY_STOP_WORDS.has(term)))];
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// src/search/http/transport.ts
|
|
263
|
+
|
|
264
|
+
var _undici = require('undici');
|
|
265
|
+
|
|
266
|
+
// src/search/http/body-decode.ts
|
|
267
|
+
var META_SNIFF_BYTES = 4096;
|
|
268
|
+
var UTF8_LABELS = /* @__PURE__ */ new Set(["utf-8", "utf8", "unicode-1-1-utf-8", "x-unicode20utf8"]);
|
|
269
|
+
function charsetFromContentType(contentType) {
|
|
270
|
+
const match = /charset\s*=\s*["']?([\w:.-]+)/i.exec(contentType);
|
|
271
|
+
return match ? match[1].toLowerCase() : null;
|
|
272
|
+
}
|
|
273
|
+
function charsetFromMeta(bytes) {
|
|
274
|
+
const head = Buffer.from(bytes.subarray(0, META_SNIFF_BYTES)).toString("latin1");
|
|
275
|
+
const metaCharset = /<meta[^>]+charset\s*=\s*["']?\s*([\w:.-]+)/i.exec(head);
|
|
276
|
+
return metaCharset ? metaCharset[1].toLowerCase() : null;
|
|
277
|
+
}
|
|
278
|
+
function decodeSearchBody(bytes, contentType = "") {
|
|
279
|
+
const declared = _nullishCoalesce(charsetFromContentType(contentType), () => ( charsetFromMeta(bytes)));
|
|
280
|
+
if (declared && !UTF8_LABELS.has(declared)) {
|
|
281
|
+
const decoder = decoderFor(declared);
|
|
282
|
+
if (decoder) return decoder.decode(bytes);
|
|
283
|
+
}
|
|
284
|
+
try {
|
|
285
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
286
|
+
} catch (e4) {
|
|
287
|
+
return new TextDecoder("windows-1252").decode(bytes);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
function decoderFor(label) {
|
|
291
|
+
try {
|
|
292
|
+
return new TextDecoder(label);
|
|
293
|
+
} catch (e5) {
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// src/search/http/headers.ts
|
|
299
|
+
var CHROME_VERSION = _nullishCoalesce(process.versions.chrome, () => ( "152.0.7977.65"));
|
|
300
|
+
var CHROME_MAJOR = CHROME_VERSION.split(".")[0] || "152";
|
|
301
|
+
var SEARCH_BROWSER_HEADERS = Object.freeze({
|
|
302
|
+
"User-Agent": `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${CHROME_VERSION} Safari/537.36`,
|
|
303
|
+
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
|
|
304
|
+
"Accept-Language": "en-US,en;q=0.9",
|
|
305
|
+
"Cache-Control": "no-cache",
|
|
306
|
+
Pragma: "no-cache",
|
|
307
|
+
"Sec-CH-UA": `"Chromium";v="${CHROME_MAJOR}", "Not=A?Brand";v="24"`,
|
|
308
|
+
"Sec-CH-UA-Mobile": "?0",
|
|
309
|
+
"Sec-CH-UA-Platform": '"Windows"',
|
|
310
|
+
"Sec-Fetch-Dest": "document",
|
|
311
|
+
"Sec-Fetch-Mode": "navigate",
|
|
312
|
+
"Sec-Fetch-Site": "none",
|
|
313
|
+
"Sec-Fetch-User": "?1",
|
|
314
|
+
"Upgrade-Insecure-Requests": "1"
|
|
315
|
+
});
|
|
316
|
+
function searchBrowserHeaders() {
|
|
317
|
+
return { ...SEARCH_BROWSER_HEADERS };
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// src/search/http/impit.ts
|
|
321
|
+
var IMPIT_BROWSER = "chrome151";
|
|
322
|
+
var IMPERSONATED_HEADERS = [
|
|
323
|
+
"sec-ch-ua",
|
|
324
|
+
"sec-ch-ua-mobile",
|
|
325
|
+
"sec-ch-ua-platform",
|
|
326
|
+
"user-agent"
|
|
327
|
+
];
|
|
328
|
+
var TRANSPORT_KIND = /* @__PURE__ */ Symbol("searchFetchKind");
|
|
329
|
+
function tagFetchKind(error, kind) {
|
|
330
|
+
if (error instanceof Error) {
|
|
331
|
+
error[TRANSPORT_KIND] = kind;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
function fetchKindOf(error) {
|
|
335
|
+
return _optionalChain([error, 'optionalAccess', _19 => _19[TRANSPORT_KIND]]);
|
|
336
|
+
}
|
|
337
|
+
var impitConstructorPromise;
|
|
338
|
+
var impitClients = /* @__PURE__ */ new Map();
|
|
339
|
+
function loadImpitConstructor() {
|
|
340
|
+
impitConstructorPromise ??= Promise.resolve().then(() => _interopRequireWildcard(require("impit"))).then((module) => module.Impit).catch(() => void 0);
|
|
341
|
+
return impitConstructorPromise;
|
|
342
|
+
}
|
|
343
|
+
async function getImpitClient(proxyUrl, load = loadImpitConstructor) {
|
|
344
|
+
const ImpitClient = await load();
|
|
345
|
+
if (!ImpitClient) return void 0;
|
|
346
|
+
const key = _nullishCoalesce(proxyUrl, () => ( "<direct>"));
|
|
347
|
+
const cached = impitClients.get(key);
|
|
348
|
+
if (cached) return cached;
|
|
349
|
+
const client = new ImpitClient({
|
|
350
|
+
browser: IMPIT_BROWSER,
|
|
351
|
+
followRedirects: false,
|
|
352
|
+
vanillaFallback: false,
|
|
353
|
+
...proxyUrl ? { proxyUrl } : {}
|
|
354
|
+
});
|
|
355
|
+
impitClients.set(key, client);
|
|
356
|
+
return client;
|
|
357
|
+
}
|
|
358
|
+
function withImpersonatedHeaders(init) {
|
|
359
|
+
const headers = new Headers(init.headers);
|
|
360
|
+
for (const name of IMPERSONATED_HEADERS) headers.delete(name);
|
|
361
|
+
return { ...init, headers };
|
|
362
|
+
}
|
|
363
|
+
function proxyConfigToUrl(config) {
|
|
364
|
+
if ("url" in config) {
|
|
365
|
+
try {
|
|
366
|
+
const protocol = new URL(config.url).protocol;
|
|
367
|
+
if (protocol === "http:" || protocol === "https:") return config.url;
|
|
368
|
+
if (protocol === "socks5:" || protocol === "socks5h:") {
|
|
369
|
+
return `socks5h://${config.url.slice(protocol.length + 2)}`;
|
|
370
|
+
}
|
|
371
|
+
return void 0;
|
|
372
|
+
} catch (e6) {
|
|
373
|
+
return void 0;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
if (!config.host || !Number.isFinite(config.port)) return void 0;
|
|
377
|
+
const auth = config.username ? `${encodeURIComponent(config.username)}:${encodeURIComponent(_nullishCoalesce(config.password, () => ( "")))}@` : "";
|
|
378
|
+
if (config.type !== "http" && config.type !== "https" && config.type !== "socks5") {
|
|
379
|
+
return void 0;
|
|
380
|
+
}
|
|
381
|
+
const scheme = config.type === "socks5" ? "socks5h" : config.type;
|
|
382
|
+
return `${scheme}://${auth}${config.host}:${config.port}`;
|
|
383
|
+
}
|
|
384
|
+
function impitProxyUrlFrom(resolve, url) {
|
|
385
|
+
const config = _optionalChain([resolve, 'optionalCall', _20 => _20(url)]);
|
|
386
|
+
return config ? proxyConfigToUrl(config) : void 0;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// src/search/http/transport.ts
|
|
390
|
+
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
391
|
+
var DEFAULT_MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
|
|
392
|
+
var MAX_REDIRECTS = 5;
|
|
393
|
+
var REFUSED_STATUSES = /* @__PURE__ */ new Set([401, 403, 407, 429]);
|
|
394
|
+
function createSearchHttpTransport(options = {}) {
|
|
395
|
+
const fetchImpl = _nullishCoalesce(options.fetch, () => ( createProductionSearchFetch(options)));
|
|
396
|
+
const maxRedirects = _nullishCoalesce(options.maxRedirects, () => ( MAX_REDIRECTS));
|
|
397
|
+
const egressPolicy = options.egressPolicy;
|
|
398
|
+
return async (url, request) => {
|
|
399
|
+
const context = {
|
|
400
|
+
providerId: request.providerId,
|
|
401
|
+
host: hostOf(url)
|
|
402
|
+
};
|
|
403
|
+
const controller = new AbortController();
|
|
404
|
+
const onAbort = () => controller.abort(_optionalChain([request, 'access', _21 => _21.signal, 'optionalAccess', _22 => _22.reason]));
|
|
405
|
+
_optionalChain([request, 'access', _23 => _23.signal, 'optionalAccess', _24 => _24.addEventListener, 'call', _25 => _25("abort", onAbort, { once: true })]);
|
|
406
|
+
if (_optionalChain([request, 'access', _26 => _26.signal, 'optionalAccess', _27 => _27.aborted])) onAbort();
|
|
407
|
+
const timeoutMs = _nullishCoalesce(request.timeoutMs, () => ( DEFAULT_TIMEOUT_MS));
|
|
408
|
+
let deadlineExpired = false;
|
|
409
|
+
const timer = setTimeout(() => {
|
|
410
|
+
deadlineExpired = true;
|
|
411
|
+
controller.abort();
|
|
412
|
+
}, timeoutMs);
|
|
413
|
+
try {
|
|
414
|
+
const { response, finalUrl } = await fetchWithRedirectLimit(
|
|
415
|
+
fetchImpl,
|
|
416
|
+
url,
|
|
417
|
+
controller.signal,
|
|
418
|
+
maxRedirects,
|
|
419
|
+
context,
|
|
420
|
+
egressPolicy
|
|
421
|
+
);
|
|
422
|
+
context.host = hostOf(finalUrl);
|
|
423
|
+
const contentType = _nullishCoalesce(response.headers.get("content-type"), () => ( ""));
|
|
424
|
+
const rawText = await readBodyWithLimit(
|
|
425
|
+
response,
|
|
426
|
+
_nullishCoalesce(request.maxResponseBytes, () => ( DEFAULT_MAX_RESPONSE_BYTES)),
|
|
427
|
+
context
|
|
428
|
+
);
|
|
429
|
+
assertStatusUsable(response.status, context);
|
|
430
|
+
assertNoBotChallenge(rawText, context);
|
|
431
|
+
return { finalUrl, status: response.status, contentType, rawText };
|
|
432
|
+
} catch (error) {
|
|
433
|
+
if (_optionalChain([request, 'access', _28 => _28.signal, 'optionalAccess', _29 => _29.aborted])) {
|
|
434
|
+
throw searchHttpError("cancelled", "search request was cancelled by the caller", {
|
|
435
|
+
stage: "fetch",
|
|
436
|
+
providerId: context.providerId,
|
|
437
|
+
retryable: false,
|
|
438
|
+
cause: error,
|
|
439
|
+
details: { host: context.host }
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
if (deadlineExpired) {
|
|
443
|
+
throw searchHttpError("timeout", `search request exceeded its ${timeoutMs}ms budget`, {
|
|
444
|
+
stage: "fetch",
|
|
445
|
+
providerId: context.providerId,
|
|
446
|
+
retryable: true,
|
|
447
|
+
cause: error,
|
|
448
|
+
transport: fetchKindOf(error),
|
|
449
|
+
details: { host: context.host }
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
throw asSearchProviderError(error, context.providerId, "fetch");
|
|
453
|
+
} finally {
|
|
454
|
+
clearTimeout(timer);
|
|
455
|
+
_optionalChain([request, 'access', _30 => _30.signal, 'optionalAccess', _31 => _31.removeEventListener, 'call', _32 => _32("abort", onAbort)]);
|
|
456
|
+
}
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
var defaultSearchHttpTransport = createSearchHttpTransport();
|
|
460
|
+
function createProductionSearchFetch(options) {
|
|
461
|
+
return async (url, init) => {
|
|
462
|
+
const client = await getImpitClient(
|
|
463
|
+
impitProxyUrlFrom(options.resolveProxyConfig, url),
|
|
464
|
+
options.loadImpit
|
|
465
|
+
).catch(() => void 0);
|
|
466
|
+
if (client) {
|
|
467
|
+
try {
|
|
468
|
+
return await client.fetch(
|
|
469
|
+
url,
|
|
470
|
+
withImpersonatedHeaders(init)
|
|
471
|
+
);
|
|
472
|
+
} catch (error) {
|
|
473
|
+
tagFetchKind(error, "impit");
|
|
474
|
+
throw error;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
try {
|
|
478
|
+
const dispatcher = selectHttpDispatcher(options.env, url, options.resolveProxyDispatcher);
|
|
479
|
+
const requestInit = dispatcher ? { ...init, dispatcher } : init;
|
|
480
|
+
return await _undici.fetch.call(void 0,
|
|
481
|
+
url,
|
|
482
|
+
requestInit
|
|
483
|
+
);
|
|
484
|
+
} catch (error) {
|
|
485
|
+
tagFetchKind(error, "undici");
|
|
486
|
+
throw error;
|
|
487
|
+
}
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
function selectHttpDispatcher(env, url, resolveProxyDispatcher) {
|
|
491
|
+
return _nullishCoalesce(_optionalChain([resolveProxyDispatcher, 'optionalCall', _33 => _33(url)]), () => ( envProxyDispatcher(env)));
|
|
492
|
+
}
|
|
493
|
+
function envProxyDispatcher(env) {
|
|
494
|
+
const proxy = _chunk7RJI3NDIcjs.resolveSearchProxySettings.call(void 0, env);
|
|
495
|
+
return proxy ? _chunk7RJI3NDIcjs.getSearchProxyDispatcher.call(void 0, proxy) : void 0;
|
|
496
|
+
}
|
|
497
|
+
async function fetchWithRedirectLimit(fetchImpl, url, signal, maxRedirects, context, egressPolicy) {
|
|
498
|
+
let currentUrl = url;
|
|
499
|
+
assertEgressAllowed(currentUrl, egressPolicy, "connect", context);
|
|
500
|
+
for (let redirects = 0; redirects <= maxRedirects; redirects += 1) {
|
|
501
|
+
let response;
|
|
502
|
+
context.host = hostOf(currentUrl);
|
|
503
|
+
try {
|
|
504
|
+
response = await fetchImpl(currentUrl, {
|
|
505
|
+
signal,
|
|
506
|
+
redirect: "manual",
|
|
507
|
+
headers: searchBrowserHeaders()
|
|
508
|
+
});
|
|
509
|
+
} catch (error) {
|
|
510
|
+
if (isAbortError(error)) throw error;
|
|
511
|
+
throw searchHttpError("upstream_unavailable", networkFailureMessage(error), {
|
|
512
|
+
stage: "connect",
|
|
513
|
+
providerId: context.providerId,
|
|
514
|
+
retryable: true,
|
|
515
|
+
cause: error,
|
|
516
|
+
transport: fetchKindOf(error),
|
|
517
|
+
details: { host: context.host }
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
if (response.status < 300 || response.status >= 400) {
|
|
521
|
+
return { response, finalUrl: response.url || currentUrl };
|
|
522
|
+
}
|
|
523
|
+
const location = response.headers.get("location");
|
|
524
|
+
if (!location) return { response, finalUrl: currentUrl };
|
|
525
|
+
void _optionalChain([response, 'access', _34 => _34.body, 'optionalAccess', _35 => _35.cancel, 'call', _36 => _36(), 'access', _37 => _37.catch, 'call', _38 => _38(() => void 0)]);
|
|
526
|
+
if (redirects === maxRedirects) throw tooManyRedirects(maxRedirects, context);
|
|
527
|
+
const nextUrl = new URL(location, currentUrl).href;
|
|
528
|
+
assertEgressAllowed(nextUrl, egressPolicy, "redirect", context);
|
|
529
|
+
currentUrl = nextUrl;
|
|
530
|
+
}
|
|
531
|
+
throw tooManyRedirects(maxRedirects, context);
|
|
532
|
+
}
|
|
533
|
+
function assertEgressAllowed(url, policy, stage, context) {
|
|
534
|
+
try {
|
|
535
|
+
_chunk7RJI3NDIcjs.validateEgressUrl.call(void 0, url, policy, context.providerId);
|
|
536
|
+
} catch (error) {
|
|
537
|
+
if (!_searchtypes.isSearchProviderError.call(void 0, error)) throw error;
|
|
538
|
+
throw searchHttpError(error.code, error.message, {
|
|
539
|
+
stage,
|
|
540
|
+
providerId: context.providerId,
|
|
541
|
+
retryable: false,
|
|
542
|
+
cause: error,
|
|
543
|
+
details: error.details
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
function tooManyRedirects(maxRedirects, context) {
|
|
548
|
+
return searchHttpError("upstream_unavailable", `too many redirects (>${maxRedirects})`, {
|
|
549
|
+
stage: "redirect",
|
|
550
|
+
providerId: context.providerId,
|
|
551
|
+
retryable: false,
|
|
552
|
+
details: { host: context.host, maxRedirects: String(maxRedirects) }
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
async function readBodyWithLimit(response, maxResponseBytes, context) {
|
|
556
|
+
const reader = _optionalChain([response, 'access', _39 => _39.body, 'optionalAccess', _40 => _40.getReader, 'call', _41 => _41()]);
|
|
557
|
+
if (!reader) return "";
|
|
558
|
+
const chunks = [];
|
|
559
|
+
let totalBytes = 0;
|
|
560
|
+
while (true) {
|
|
561
|
+
const { done, value } = await reader.read();
|
|
562
|
+
if (done) break;
|
|
563
|
+
totalBytes += value.byteLength;
|
|
564
|
+
if (totalBytes > maxResponseBytes) {
|
|
565
|
+
await reader.cancel().catch(() => void 0);
|
|
566
|
+
throw searchHttpError(
|
|
567
|
+
"upstream_unavailable",
|
|
568
|
+
`search response exceeded the ${maxResponseBytes} byte cap`,
|
|
569
|
+
{
|
|
570
|
+
stage: "body-cap",
|
|
571
|
+
providerId: context.providerId,
|
|
572
|
+
retryable: false,
|
|
573
|
+
details: { host: context.host, maxResponseBytes: String(maxResponseBytes) }
|
|
574
|
+
}
|
|
575
|
+
);
|
|
576
|
+
}
|
|
577
|
+
chunks.push(value);
|
|
578
|
+
}
|
|
579
|
+
const rawBytes = new Uint8Array(chunks.reduce((sum, chunk) => sum + chunk.byteLength, 0));
|
|
580
|
+
let offset = 0;
|
|
581
|
+
for (const chunk of chunks) {
|
|
582
|
+
rawBytes.set(chunk, offset);
|
|
583
|
+
offset += chunk.byteLength;
|
|
584
|
+
}
|
|
585
|
+
return decodeSearchBody(rawBytes, _nullishCoalesce(response.headers.get("content-type"), () => ( "")));
|
|
586
|
+
}
|
|
587
|
+
function assertStatusUsable(status, context) {
|
|
588
|
+
if (!REFUSED_STATUSES.has(status)) return;
|
|
589
|
+
throw searchHttpError(
|
|
590
|
+
"upstream_unavailable",
|
|
591
|
+
`server refused the browser-shaped request (HTTP ${status})`,
|
|
592
|
+
{
|
|
593
|
+
stage: "fetch",
|
|
594
|
+
providerId: context.providerId,
|
|
595
|
+
retryable: false,
|
|
596
|
+
details: { host: context.host, status: String(status) }
|
|
597
|
+
}
|
|
598
|
+
);
|
|
599
|
+
}
|
|
600
|
+
function assertNoBotChallenge(html, context) {
|
|
601
|
+
if (!/<(?:html|body|title|script)\b/i.test(html)) return;
|
|
602
|
+
const title = _optionalChain([html, 'access', _42 => _42.match, 'call', _43 => _43(/<title[^>]*>(.*?)<\/title>/is), 'optionalAccess', _44 => _44[1], 'access', _45 => _45.replace, 'call', _46 => _46(/<[^>]+>/g, " "), 'access', _47 => _47.replace, 'call', _48 => _48(/\s+/g, " "), 'access', _49 => _49.trim, 'call', _50 => _50()]);
|
|
603
|
+
const challengeTitle = /^(?:just a moment|attention required|access denied|robot check|security check)/i.test(
|
|
604
|
+
_nullishCoalesce(title, () => ( ""))
|
|
605
|
+
);
|
|
606
|
+
const challengeInfrastructure = /cdn-cgi\/challenge-platform|cf-chl-|cf-turnstile|px-captcha|hcaptcha-container/i.test(html);
|
|
607
|
+
const challengeCopy = /verify (?:you are|that you are) human|unusual traffic from your computer|enable javascript and cookies to continue/i.test(
|
|
608
|
+
html
|
|
609
|
+
);
|
|
610
|
+
const duckDuckGoChallenge = /unfortunately, bots use duckduckgo too|complete the following challenge to confirm this search was made by a human/i.test(
|
|
611
|
+
html
|
|
612
|
+
);
|
|
613
|
+
if (challengeTitle || duckDuckGoChallenge || challengeInfrastructure && challengeCopy) {
|
|
614
|
+
throw searchHttpError(
|
|
615
|
+
"upstream_unavailable",
|
|
616
|
+
"server returned a bot-challenge page instead of the requested content",
|
|
617
|
+
{
|
|
618
|
+
stage: "challenge",
|
|
619
|
+
providerId: context.providerId,
|
|
620
|
+
retryable: false,
|
|
621
|
+
details: { host: context.host }
|
|
622
|
+
}
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
function isAbortError(error) {
|
|
627
|
+
return error instanceof Error && (error.name === "AbortError" || error.name === "TimeoutError");
|
|
628
|
+
}
|
|
629
|
+
function networkFailureMessage(error) {
|
|
630
|
+
const code = nestedErrorCode(error);
|
|
631
|
+
return code ? `network request failed (${code})` : "network request failed";
|
|
632
|
+
}
|
|
633
|
+
function nestedErrorCode(error) {
|
|
634
|
+
let current = error;
|
|
635
|
+
for (let depth = 0; depth < 4 && current instanceof Error; depth += 1) {
|
|
636
|
+
const code = current.code;
|
|
637
|
+
if (typeof code === "string" && /^[A-Z][A-Z0-9_]+$/.test(code)) return code;
|
|
638
|
+
current = current.cause;
|
|
639
|
+
}
|
|
640
|
+
return void 0;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
// src/search/http/HttpBingProvider.ts
|
|
644
|
+
var HTTP_BING_PROVIDER_ID = "http-bing";
|
|
645
|
+
var BING_ENGINE = {
|
|
646
|
+
providerId: HTTP_BING_PROVIDER_ID,
|
|
647
|
+
label: "Bing",
|
|
648
|
+
buildUrls: (query) => [`https://www.bing.com/search?q=${encodeURIComponent(query)}`],
|
|
649
|
+
// Bing has no challenge status of its own; it serves decoy CONTENT instead,
|
|
650
|
+
// which the trust check catches.
|
|
651
|
+
isChallengeStatus: () => false,
|
|
652
|
+
trustError: bingSearchPageTrustError,
|
|
653
|
+
parse: parseBingSerp
|
|
654
|
+
};
|
|
655
|
+
var HttpBingProvider = (_class = class {
|
|
656
|
+
__init() {this.id = HTTP_BING_PROVIDER_ID}
|
|
657
|
+
|
|
658
|
+
constructor(transport = defaultSearchHttpTransport) {;_class.prototype.__init.call(this);
|
|
659
|
+
this.transport = transport;
|
|
660
|
+
}
|
|
661
|
+
search(query, options) {
|
|
662
|
+
return runHttpSearch(BING_ENGINE, this.transport, query, options);
|
|
663
|
+
}
|
|
664
|
+
}, _class);
|
|
665
|
+
|
|
666
|
+
// src/search/http/parsers/duckduckgo.ts
|
|
667
|
+
|
|
668
|
+
var DUCKDUCKGO_SERP_URL = "https://html.duckduckgo.com/html/";
|
|
669
|
+
var DUCKDUCKGO_SERP_MARKERS = "#links, .results, a.result-link";
|
|
670
|
+
function isDuckDuckGoSerp(document) {
|
|
671
|
+
return document.querySelector(DUCKDUCKGO_SERP_MARKERS) !== null;
|
|
672
|
+
}
|
|
673
|
+
function parseDuckDuckGoSerp(html, maxResults) {
|
|
674
|
+
const document = new (0, _jsdom.JSDOM)(html, { url: DUCKDUCKGO_SERP_URL }).window.document;
|
|
675
|
+
const htmlResults = [
|
|
676
|
+
...document.querySelectorAll(".result, .result--web, .web-result")
|
|
677
|
+
].map((container) => {
|
|
678
|
+
const link = container.querySelector("a.result__a, .result__a");
|
|
679
|
+
return {
|
|
680
|
+
title: cleanText(_optionalChain([link, 'optionalAccess', _51 => _51.textContent])),
|
|
681
|
+
url: cleanDuckDuckGoUrl(_nullishCoalesce(_optionalChain([link, 'optionalAccess', _52 => _52.href]), () => ( ""))),
|
|
682
|
+
content: cleanText(_optionalChain([container, 'access', _53 => _53.querySelector, 'call', _54 => _54(".result__snippet, .result__body"), 'optionalAccess', _55 => _55.textContent]))
|
|
683
|
+
};
|
|
684
|
+
}).filter(isUsableResult);
|
|
685
|
+
if (htmlResults.length > 0) {
|
|
686
|
+
return { recognized: true, results: htmlResults.slice(0, maxResults) };
|
|
687
|
+
}
|
|
688
|
+
const liteResults = [
|
|
689
|
+
...document.querySelectorAll("a.result-link")
|
|
690
|
+
].map((link) => {
|
|
691
|
+
const row = link.closest("tr");
|
|
692
|
+
const snippet = _optionalChain([row, 'optionalAccess', _56 => _56.nextElementSibling, 'optionalAccess', _57 => _57.querySelector, 'call', _58 => _58(".result-snippet")]);
|
|
693
|
+
return {
|
|
694
|
+
title: cleanText(link.textContent),
|
|
695
|
+
url: cleanDuckDuckGoUrl(link.href),
|
|
696
|
+
content: cleanText(_optionalChain([snippet, 'optionalAccess', _59 => _59.textContent]))
|
|
697
|
+
};
|
|
698
|
+
}).filter(isUsableResult).slice(0, maxResults);
|
|
699
|
+
return { recognized: isDuckDuckGoSerp(document), results: liteResults };
|
|
700
|
+
}
|
|
701
|
+
function cleanDuckDuckGoUrl(rawUrl) {
|
|
702
|
+
try {
|
|
703
|
+
const absoluteUrl = rawUrl.startsWith("//") ? `https:${rawUrl}` : rawUrl;
|
|
704
|
+
const url = new URL(absoluteUrl, "https://html.duckduckgo.com");
|
|
705
|
+
return _nullishCoalesce(url.searchParams.get("uddg"), () => ( url.href));
|
|
706
|
+
} catch (e7) {
|
|
707
|
+
return rawUrl;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
// src/search/http/HttpDuckDuckGoProvider.ts
|
|
712
|
+
var HTTP_DUCKDUCKGO_PROVIDER_ID = "http-duckduckgo";
|
|
713
|
+
var DUCKDUCKGO_CHALLENGE_STATUS = 202;
|
|
714
|
+
var DUCKDUCKGO_ENGINE = {
|
|
715
|
+
providerId: HTTP_DUCKDUCKGO_PROVIDER_ID,
|
|
716
|
+
label: "DuckDuckGo",
|
|
717
|
+
buildUrls: (query) => [
|
|
718
|
+
`https://html.duckduckgo.com/html/?q=${encodeURIComponent(query)}`,
|
|
719
|
+
`https://lite.duckduckgo.com/lite/?q=${encodeURIComponent(query)}`
|
|
720
|
+
],
|
|
721
|
+
isChallengeStatus: (status) => status === DUCKDUCKGO_CHALLENGE_STATUS,
|
|
722
|
+
parse: parseDuckDuckGoSerp
|
|
723
|
+
};
|
|
724
|
+
var HttpDuckDuckGoProvider = (_class2 = class {
|
|
725
|
+
__init2() {this.id = HTTP_DUCKDUCKGO_PROVIDER_ID}
|
|
726
|
+
|
|
727
|
+
constructor(transport = defaultSearchHttpTransport) {;_class2.prototype.__init2.call(this);
|
|
728
|
+
this.transport = transport;
|
|
729
|
+
}
|
|
730
|
+
search(query, options) {
|
|
731
|
+
return runHttpSearch(DUCKDUCKGO_ENGINE, this.transport, query, options);
|
|
732
|
+
}
|
|
733
|
+
}, _class2);
|
|
734
|
+
|
|
735
|
+
// src/search/http/contributions.ts
|
|
736
|
+
var HTTP_SEARCH_CAPABILITIES = Object.freeze({
|
|
737
|
+
requiresApiKey: false,
|
|
738
|
+
supportsRegion: false,
|
|
739
|
+
supportsLanguage: false,
|
|
740
|
+
supportsTimeRange: false,
|
|
741
|
+
supportsUrlRead: false,
|
|
742
|
+
supportsCancellation: true,
|
|
743
|
+
maxResults: MAX_RESULTS
|
|
744
|
+
});
|
|
745
|
+
function builtinHttpSearchContributions(transport) {
|
|
746
|
+
return [
|
|
747
|
+
{
|
|
748
|
+
id: HTTP_BING_PROVIDER_ID,
|
|
749
|
+
source: "builtin",
|
|
750
|
+
kind: "http",
|
|
751
|
+
provider: new HttpBingProvider(transport),
|
|
752
|
+
capabilities: { ...HTTP_SEARCH_CAPABILITIES }
|
|
753
|
+
},
|
|
754
|
+
{
|
|
755
|
+
id: HTTP_DUCKDUCKGO_PROVIDER_ID,
|
|
756
|
+
source: "builtin",
|
|
757
|
+
kind: "http",
|
|
758
|
+
provider: new HttpDuckDuckGoProvider(transport),
|
|
759
|
+
capabilities: { ...HTTP_SEARCH_CAPABILITIES }
|
|
760
|
+
}
|
|
761
|
+
];
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
|
|
765
|
+
|
|
766
|
+
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
|
|
776
|
+
|
|
777
|
+
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
exports.SEARCH_HTTP_TRANSPORT_ID = SEARCH_HTTP_TRANSPORT_ID; exports.SEARCH_RESPONSE_BYTES = SEARCH_RESPONSE_BYTES; exports.DEFAULT_SEARCH_TIMEOUT_MS = DEFAULT_SEARCH_TIMEOUT_MS; exports.DEFAULT_MAX_RESULTS = DEFAULT_MAX_RESULTS; exports.MAX_RESULTS = MAX_RESULTS; exports.clampMaxResults = clampMaxResults; exports.SEARCH_BROWSER_HEADERS = SEARCH_BROWSER_HEADERS; exports.MAX_REDIRECTS = MAX_REDIRECTS; exports.createSearchHttpTransport = createSearchHttpTransport; exports.defaultSearchHttpTransport = defaultSearchHttpTransport; exports.HTTP_BING_PROVIDER_ID = HTTP_BING_PROVIDER_ID; exports.HttpBingProvider = HttpBingProvider; exports.HTTP_DUCKDUCKGO_PROVIDER_ID = HTTP_DUCKDUCKGO_PROVIDER_ID; exports.HttpDuckDuckGoProvider = HttpDuckDuckGoProvider; exports.HTTP_SEARCH_CAPABILITIES = HTTP_SEARCH_CAPABILITIES; exports.builtinHttpSearchContributions = builtinHttpSearchContributions;
|