findweb 0.1.3 → 0.1.4
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/README.md +4 -3
- package/dist/index.js +223 -138
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -72,9 +72,10 @@ findweb "yc"
|
|
|
72
72
|
|
|
73
73
|
1. Launches system Chrome (`/Applications/Google Chrome.app`) with a free debugging port
|
|
74
74
|
2. Connects via CDP using puppeteer-core
|
|
75
|
-
3.
|
|
76
|
-
4.
|
|
77
|
-
5.
|
|
75
|
+
3. Reuses a background headless Chrome for the same profile when available
|
|
76
|
+
4. Loads the [Ghostery adblocker](https://github.com/ghostery/adblocker) engine programmatically on each page
|
|
77
|
+
5. Navigates directly to Google search results and extracts data from the rendered page
|
|
78
|
+
6. Returns results as plain text or JSON, then disconnects from Chrome
|
|
78
79
|
|
|
79
80
|
No Chromium download. No browser extension. No user confirmation.
|
|
80
81
|
|
package/dist/index.js
CHANGED
|
@@ -66517,7 +66517,7 @@ var init_LaunchOptions = __esm(() => {
|
|
|
66517
66517
|
});
|
|
66518
66518
|
|
|
66519
66519
|
// src/index.ts
|
|
66520
|
-
import
|
|
66520
|
+
import process6 from "process";
|
|
66521
66521
|
|
|
66522
66522
|
// node_modules/citty/dist/_chunks/libs/scule.mjs
|
|
66523
66523
|
var NUMBER_CHAR_RE = /\d/;
|
|
@@ -66932,10 +66932,12 @@ async function runMain(cmd, opts = {}) {
|
|
|
66932
66932
|
}
|
|
66933
66933
|
|
|
66934
66934
|
// src/search/browser.ts
|
|
66935
|
+
import fs7 from "fs/promises";
|
|
66935
66936
|
import { spawn as spawn3 } from "child_process";
|
|
66936
66937
|
import http2 from "http";
|
|
66937
66938
|
import os9 from "os";
|
|
66938
66939
|
import path12 from "path";
|
|
66940
|
+
import process3 from "process";
|
|
66939
66941
|
|
|
66940
66942
|
// node_modules/puppeteer-core/lib/esm/puppeteer/api/api.js
|
|
66941
66943
|
init_Browser();
|
|
@@ -76219,9 +76221,42 @@ var puppeteer_core_default = puppeteer;
|
|
|
76219
76221
|
// src/search/browser.ts
|
|
76220
76222
|
var CHROME_BIN = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
|
|
76221
76223
|
var DEFAULT_TIMEOUT_MS = 30000;
|
|
76224
|
+
var CDP_POLL_MS = 100;
|
|
76225
|
+
var REUSABLE_PAGE_URL = "about:blank";
|
|
76222
76226
|
function createDebugServer() {
|
|
76223
76227
|
return http2.createServer();
|
|
76224
76228
|
}
|
|
76229
|
+
function persistentStatePath(userDataDir) {
|
|
76230
|
+
return path12.join(userDataDir, ".findweb-browser.json");
|
|
76231
|
+
}
|
|
76232
|
+
function isProcessRunning(pid) {
|
|
76233
|
+
try {
|
|
76234
|
+
process3.kill(pid, 0);
|
|
76235
|
+
return true;
|
|
76236
|
+
} catch {
|
|
76237
|
+
return false;
|
|
76238
|
+
}
|
|
76239
|
+
}
|
|
76240
|
+
async function readPersistentState(userDataDir) {
|
|
76241
|
+
try {
|
|
76242
|
+
const file = await fs7.readFile(persistentStatePath(userDataDir), "utf8");
|
|
76243
|
+
const parsed = JSON.parse(file);
|
|
76244
|
+
if (typeof parsed.pid !== "number" || typeof parsed.port !== "number") {
|
|
76245
|
+
return null;
|
|
76246
|
+
}
|
|
76247
|
+
return { pid: parsed.pid, port: parsed.port };
|
|
76248
|
+
} catch {
|
|
76249
|
+
return null;
|
|
76250
|
+
}
|
|
76251
|
+
}
|
|
76252
|
+
async function writePersistentState(userDataDir, state) {
|
|
76253
|
+
await fs7.mkdir(userDataDir, { recursive: true });
|
|
76254
|
+
await fs7.writeFile(persistentStatePath(userDataDir), `${JSON.stringify(state)}
|
|
76255
|
+
`, "utf8");
|
|
76256
|
+
}
|
|
76257
|
+
async function clearPersistentState(userDataDir) {
|
|
76258
|
+
await fs7.rm(persistentStatePath(userDataDir), { force: true });
|
|
76259
|
+
}
|
|
76225
76260
|
function wait(delayMs) {
|
|
76226
76261
|
return new Promise((resolve6) => setTimeout(resolve6, delayMs));
|
|
76227
76262
|
}
|
|
@@ -76266,16 +76301,66 @@ async function isCdpReady(port) {
|
|
|
76266
76301
|
async function waitForCdp(port, activeBrowser) {
|
|
76267
76302
|
const deadline = Date.now() + DEFAULT_TIMEOUT_MS;
|
|
76268
76303
|
while (Date.now() < deadline) {
|
|
76269
|
-
if (activeBrowser
|
|
76304
|
+
if (activeBrowser?.exitCode !== null) {
|
|
76270
76305
|
throw new Error(`Chrome exited before opening debugging port ${port}`);
|
|
76271
76306
|
}
|
|
76272
76307
|
if (await isCdpReady(port)) {
|
|
76273
76308
|
return;
|
|
76274
76309
|
}
|
|
76275
|
-
await wait(
|
|
76310
|
+
await wait(CDP_POLL_MS);
|
|
76276
76311
|
}
|
|
76277
76312
|
throw new Error(`Chrome debugging port ${port} did not become ready in time`);
|
|
76278
76313
|
}
|
|
76314
|
+
function reusablePageScore(url) {
|
|
76315
|
+
if (url.startsWith("https://www.google.com/search?")) {
|
|
76316
|
+
return 3;
|
|
76317
|
+
}
|
|
76318
|
+
if (url === REUSABLE_PAGE_URL) {
|
|
76319
|
+
return 2;
|
|
76320
|
+
}
|
|
76321
|
+
if (url.startsWith("https://www.google.com/")) {
|
|
76322
|
+
return 1;
|
|
76323
|
+
}
|
|
76324
|
+
return 0;
|
|
76325
|
+
}
|
|
76326
|
+
async function reusablePage(browser) {
|
|
76327
|
+
const pages = await browser.pages();
|
|
76328
|
+
const existing = pages.filter((page2) => !page2.isClosed()).sort((a, b) => reusablePageScore(b.url()) - reusablePageScore(a.url()))[0] ?? null;
|
|
76329
|
+
if (existing) {
|
|
76330
|
+
return existing;
|
|
76331
|
+
}
|
|
76332
|
+
const page = await browser.newPage().catch(() => null);
|
|
76333
|
+
if (!page) {
|
|
76334
|
+
return null;
|
|
76335
|
+
}
|
|
76336
|
+
await page.goto(REUSABLE_PAGE_URL, { waitUntil: "domcontentloaded" }).catch(() => {
|
|
76337
|
+
return;
|
|
76338
|
+
});
|
|
76339
|
+
return page;
|
|
76340
|
+
}
|
|
76341
|
+
async function connectToBrowser(port) {
|
|
76342
|
+
return puppeteer_core_default.connect({ browserURL: `http://127.0.0.1:${port}` });
|
|
76343
|
+
}
|
|
76344
|
+
async function connectPersistentBrowser(options) {
|
|
76345
|
+
const state = await readPersistentState(options.userDataDir);
|
|
76346
|
+
if (!state || !isProcessRunning(state.pid) || !await isCdpReady(state.port)) {
|
|
76347
|
+
await clearPersistentState(options.userDataDir);
|
|
76348
|
+
return null;
|
|
76349
|
+
}
|
|
76350
|
+
try {
|
|
76351
|
+
const browser = await connectToBrowser(state.port);
|
|
76352
|
+
return {
|
|
76353
|
+
browser,
|
|
76354
|
+
chromeProcess: null,
|
|
76355
|
+
initialPage: await reusablePage(browser),
|
|
76356
|
+
persistent: true,
|
|
76357
|
+
port: state.port
|
|
76358
|
+
};
|
|
76359
|
+
} catch {
|
|
76360
|
+
await clearPersistentState(options.userDataDir);
|
|
76361
|
+
return null;
|
|
76362
|
+
}
|
|
76363
|
+
}
|
|
76279
76364
|
function createChromeArgs(options, port) {
|
|
76280
76365
|
const args = [
|
|
76281
76366
|
`--remote-debugging-port=${port}`,
|
|
@@ -76292,31 +76377,55 @@ function createChromeArgs(options, port) {
|
|
|
76292
76377
|
return args;
|
|
76293
76378
|
}
|
|
76294
76379
|
async function launchSearchBrowser(options) {
|
|
76380
|
+
if (!options.headed) {
|
|
76381
|
+
const activeBrowser = await connectPersistentBrowser(options);
|
|
76382
|
+
if (activeBrowser) {
|
|
76383
|
+
return activeBrowser;
|
|
76384
|
+
}
|
|
76385
|
+
}
|
|
76295
76386
|
const port = await findFreePort();
|
|
76296
76387
|
const chromeProcess = spawn3(CHROME_BIN, createChromeArgs(options, port), {
|
|
76297
|
-
|
|
76388
|
+
detached: !options.headed,
|
|
76389
|
+
stdio: options.headed ? ["ignore", "ignore", "pipe"] : "ignore"
|
|
76298
76390
|
});
|
|
76391
|
+
if (!options.headed) {
|
|
76392
|
+
chromeProcess.unref();
|
|
76393
|
+
}
|
|
76299
76394
|
await waitForCdp(port, chromeProcess);
|
|
76300
|
-
const browser = await
|
|
76301
|
-
|
|
76395
|
+
const browser = await connectToBrowser(port);
|
|
76396
|
+
const initialPage = await reusablePage(browser);
|
|
76397
|
+
if (!options.headed && typeof chromeProcess.pid === "number") {
|
|
76398
|
+
await writePersistentState(options.userDataDir, { pid: chromeProcess.pid, port });
|
|
76399
|
+
}
|
|
76400
|
+
return {
|
|
76401
|
+
browser,
|
|
76402
|
+
chromeProcess,
|
|
76403
|
+
initialPage,
|
|
76404
|
+
persistent: !options.headed,
|
|
76405
|
+
port
|
|
76406
|
+
};
|
|
76302
76407
|
}
|
|
76303
76408
|
async function closeSearchBrowser(activeBrowser) {
|
|
76409
|
+
if (activeBrowser.persistent) {
|
|
76410
|
+
activeBrowser.browser.disconnect();
|
|
76411
|
+
return;
|
|
76412
|
+
}
|
|
76304
76413
|
await activeBrowser.browser.close().catch(() => {
|
|
76305
76414
|
return;
|
|
76306
76415
|
});
|
|
76307
|
-
if (activeBrowser.chromeProcess
|
|
76416
|
+
if (activeBrowser.chromeProcess?.exitCode === null) {
|
|
76308
76417
|
activeBrowser.chromeProcess.kill("SIGTERM");
|
|
76309
76418
|
}
|
|
76310
76419
|
}
|
|
76311
76420
|
function defaultXdgDataHome() {
|
|
76312
|
-
const configured =
|
|
76421
|
+
const configured = process3.env.XDG_DATA_HOME;
|
|
76313
76422
|
if (configured && path12.isAbsolute(configured)) {
|
|
76314
76423
|
return configured;
|
|
76315
76424
|
}
|
|
76316
76425
|
return path12.join(os9.homedir(), ".local", "share");
|
|
76317
76426
|
}
|
|
76318
76427
|
function defaultUserDataDir() {
|
|
76319
|
-
const configured =
|
|
76428
|
+
const configured = process3.env.GOOGLE_SEARCH_USER_DATA_DIR;
|
|
76320
76429
|
if (configured) {
|
|
76321
76430
|
return configured;
|
|
76322
76431
|
}
|
|
@@ -76326,6 +76435,17 @@ function defaultUserDataDir() {
|
|
|
76326
76435
|
// src/search/page.ts
|
|
76327
76436
|
var DEFAULT_TIMEOUT_MS2 = 30000;
|
|
76328
76437
|
var DEFAULT_PWS = "0";
|
|
76438
|
+
var SEARCH_READY_SCRIPT = `(() => {
|
|
76439
|
+
if (window.location.pathname.includes('/sorry/')) {
|
|
76440
|
+
return true;
|
|
76441
|
+
}
|
|
76442
|
+
|
|
76443
|
+
if (document.querySelector('a h3')) {
|
|
76444
|
+
return true;
|
|
76445
|
+
}
|
|
76446
|
+
|
|
76447
|
+
return window.location.pathname === '/search' && document.readyState !== 'loading' && Boolean(document.querySelector('textarea[name="q"], input[name="q"]'));
|
|
76448
|
+
})()`;
|
|
76329
76449
|
function userAgent() {
|
|
76330
76450
|
return [
|
|
76331
76451
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
|
|
@@ -76343,9 +76463,6 @@ function acceptLanguage(lang) {
|
|
|
76343
76463
|
}
|
|
76344
76464
|
return `${lang};q=1.0,en;q=0.8`;
|
|
76345
76465
|
}
|
|
76346
|
-
function createGoogleHomeUrl(lang, gl) {
|
|
76347
|
-
return `https://www.google.com/?hl=${encodeURIComponent(lang)}&gl=${encodeURIComponent(gl)}&pws=${DEFAULT_PWS}`;
|
|
76348
|
-
}
|
|
76349
76466
|
function createGoogleSearchUrl(query, lang, gl) {
|
|
76350
76467
|
return [
|
|
76351
76468
|
"https://www.google.com/search",
|
|
@@ -76355,62 +76472,6 @@ function createGoogleSearchUrl(query, lang, gl) {
|
|
|
76355
76472
|
`&q=${encodeURIComponent(query)}`
|
|
76356
76473
|
].join("");
|
|
76357
76474
|
}
|
|
76358
|
-
function createSubmitSearchScript(query, lang, gl) {
|
|
76359
|
-
return `(() => {
|
|
76360
|
-
const value = ${JSON.stringify(query)};
|
|
76361
|
-
const lang = ${JSON.stringify(lang)};
|
|
76362
|
-
const gl = ${JSON.stringify(gl)};
|
|
76363
|
-
const pws = ${JSON.stringify(DEFAULT_PWS)};
|
|
76364
|
-
const el = document.querySelector('textarea[name="q"], input[name="q"]');
|
|
76365
|
-
if (!el) {
|
|
76366
|
-
throw new Error("Google search input not found");
|
|
76367
|
-
}
|
|
76368
|
-
|
|
76369
|
-
const setHidden = (form, name, hiddenValue) => {
|
|
76370
|
-
let input = form.querySelector('input[name="' + name + '"]');
|
|
76371
|
-
if (!input) {
|
|
76372
|
-
input = document.createElement("input");
|
|
76373
|
-
input.setAttribute("type", "hidden");
|
|
76374
|
-
input.setAttribute("name", name);
|
|
76375
|
-
form.appendChild(input);
|
|
76376
|
-
}
|
|
76377
|
-
input.setAttribute("value", hiddenValue);
|
|
76378
|
-
};
|
|
76379
|
-
|
|
76380
|
-
el.focus();
|
|
76381
|
-
const proto = Object.getPrototypeOf(el);
|
|
76382
|
-
const descriptor = proto ? Object.getOwnPropertyDescriptor(proto, "value") : undefined;
|
|
76383
|
-
if (descriptor && typeof descriptor.set === "function") {
|
|
76384
|
-
descriptor.set.call(el, value);
|
|
76385
|
-
} else {
|
|
76386
|
-
el.value = value;
|
|
76387
|
-
}
|
|
76388
|
-
|
|
76389
|
-
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
76390
|
-
el.dispatchEvent(new Event("change", { bubbles: true }));
|
|
76391
|
-
|
|
76392
|
-
const form = el.form || document.querySelector('form[action="/search"]');
|
|
76393
|
-
if (form && typeof form.requestSubmit === "function") {
|
|
76394
|
-
setHidden(form, "hl", lang);
|
|
76395
|
-
setHidden(form, "gl", gl);
|
|
76396
|
-
setHidden(form, "pws", pws);
|
|
76397
|
-
form.requestSubmit();
|
|
76398
|
-
return;
|
|
76399
|
-
}
|
|
76400
|
-
|
|
76401
|
-
if (form) {
|
|
76402
|
-
const action = new URL(form.getAttribute("action") || "/search", window.location.origin);
|
|
76403
|
-
action.searchParams.set("hl", lang);
|
|
76404
|
-
action.searchParams.set("gl", gl);
|
|
76405
|
-
action.searchParams.set("pws", pws);
|
|
76406
|
-
form.setAttribute("action", action.toString());
|
|
76407
|
-
form.submit();
|
|
76408
|
-
return;
|
|
76409
|
-
}
|
|
76410
|
-
|
|
76411
|
-
window.location.href = ${JSON.stringify(createGoogleSearchUrl(query, lang, gl))};
|
|
76412
|
-
})()`;
|
|
76413
|
-
}
|
|
76414
76475
|
function createExtractResultsScript(limit) {
|
|
76415
76476
|
return `(() => {
|
|
76416
76477
|
const max = ${JSON.stringify(limit)};
|
|
@@ -76459,24 +76520,16 @@ async function preparePage(page, lang) {
|
|
|
76459
76520
|
"accept-language": acceptLanguage(lang)
|
|
76460
76521
|
});
|
|
76461
76522
|
}
|
|
76462
|
-
async function
|
|
76463
|
-
|
|
76464
|
-
|
|
76465
|
-
}
|
|
76466
|
-
|
|
76467
|
-
await
|
|
76468
|
-
page.waitForNavigation({ waitUntil: "networkidle2" }),
|
|
76469
|
-
page.evaluate(createSubmitSearchScript(query, lang, gl))
|
|
76470
|
-
]);
|
|
76523
|
+
async function gotoGoogleSearchResults(page, query, lang, gl) {
|
|
76524
|
+
const searchUrl = createGoogleSearchUrl(query, lang, gl);
|
|
76525
|
+
if (page.url() !== searchUrl) {
|
|
76526
|
+
await page.goto(searchUrl, { waitUntil: "domcontentloaded" });
|
|
76527
|
+
}
|
|
76528
|
+
await page.waitForFunction(SEARCH_READY_SCRIPT, { timeout: DEFAULT_TIMEOUT_MS2 });
|
|
76471
76529
|
}
|
|
76472
76530
|
async function extractResults(page, limit) {
|
|
76473
76531
|
return page.evaluate(createExtractResultsScript(limit));
|
|
76474
76532
|
}
|
|
76475
|
-
async function waitForIdle(page) {
|
|
76476
|
-
await page.waitForNetworkIdle({ idleTime: 700, timeout: DEFAULT_TIMEOUT_MS2 }).catch(() => {
|
|
76477
|
-
return;
|
|
76478
|
-
});
|
|
76479
|
-
}
|
|
76480
76533
|
|
|
76481
76534
|
// src/search/search.ts
|
|
76482
76535
|
var LOGIN_POLL_MS = 250;
|
|
@@ -76533,13 +76586,11 @@ function isInterruptedLoginError(error, loginPage, browser) {
|
|
|
76533
76586
|
return message.includes("Navigating frame was detached") || message.includes("LifecycleWatcher disposed") || message.includes("Target closed") || message.includes("Session closed");
|
|
76534
76587
|
}
|
|
76535
76588
|
async function searchQuery(options) {
|
|
76536
|
-
const page = await options.browser.newPage();
|
|
76589
|
+
const page = options.page ?? await options.browser.newPage();
|
|
76537
76590
|
try {
|
|
76538
76591
|
await preparePage(page, options.lang);
|
|
76539
76592
|
await options.blocker.enableBlockingInPage(page);
|
|
76540
|
-
await
|
|
76541
|
-
await waitForIdle(page);
|
|
76542
|
-
await submitSearch(page, options.query, options.lang, options.gl);
|
|
76593
|
+
await gotoGoogleSearchResults(page, options.query, options.lang, options.gl);
|
|
76543
76594
|
if (isSorryPage(page.url())) {
|
|
76544
76595
|
throw new Error("Google returned a /sorry/ page for this profile/IP. Re-run later or use a logged-in profile.");
|
|
76545
76596
|
}
|
|
@@ -76548,9 +76599,28 @@ async function searchQuery(options) {
|
|
|
76548
76599
|
await options.blocker.disableBlockingInPage(page).catch(() => {
|
|
76549
76600
|
return;
|
|
76550
76601
|
});
|
|
76551
|
-
|
|
76552
|
-
|
|
76602
|
+
if (!options.keepOpen) {
|
|
76603
|
+
await page.close().catch(() => {
|
|
76604
|
+
return;
|
|
76605
|
+
});
|
|
76606
|
+
}
|
|
76607
|
+
}
|
|
76608
|
+
}
|
|
76609
|
+
async function runSingleQuery(browser, options) {
|
|
76610
|
+
try {
|
|
76611
|
+
const results = await searchQuery({
|
|
76612
|
+
blocker: options.blocker,
|
|
76613
|
+
browser,
|
|
76614
|
+
gl: options.gl,
|
|
76615
|
+
keepOpen: Boolean(options.page),
|
|
76616
|
+
lang: options.lang,
|
|
76617
|
+
num: options.num,
|
|
76618
|
+
page: options.page ?? undefined,
|
|
76619
|
+
query: options.query
|
|
76553
76620
|
});
|
|
76621
|
+
return { error: null, query: options.query, results };
|
|
76622
|
+
} catch (error) {
|
|
76623
|
+
return { error: toErrorMessage(error), query: options.query, results: [] };
|
|
76554
76624
|
}
|
|
76555
76625
|
}
|
|
76556
76626
|
async function runBatchWorker(browser, options) {
|
|
@@ -76576,20 +76646,35 @@ async function runBatchWorker(browser, options) {
|
|
|
76576
76646
|
}
|
|
76577
76647
|
}
|
|
76578
76648
|
}
|
|
76579
|
-
async function searchQueriesInTabs(browser, blocker, queries, options) {
|
|
76649
|
+
async function searchQueriesInTabs(browser, blocker, queries, options, initialPage = null) {
|
|
76580
76650
|
const concurrency = Math.max(1, Math.min(options.parallel, queries.length));
|
|
76581
76651
|
const results = new Array(queries.length);
|
|
76582
76652
|
const cursor = { value: 0 };
|
|
76583
|
-
|
|
76653
|
+
const initialTask = initialPage && queries[0] ? runSingleQuery(browser, {
|
|
76584
76654
|
blocker,
|
|
76585
|
-
cursor,
|
|
76586
76655
|
gl: options.gl,
|
|
76587
76656
|
lang: options.lang,
|
|
76588
76657
|
num: options.num,
|
|
76658
|
+
page: initialPage,
|
|
76589
76659
|
parallel: options.parallel,
|
|
76590
|
-
queries
|
|
76591
|
-
|
|
76592
|
-
|
|
76660
|
+
query: queries[0]
|
|
76661
|
+
}).then((outcome) => {
|
|
76662
|
+
results[0] = outcome;
|
|
76663
|
+
}) : null;
|
|
76664
|
+
cursor.value = initialTask ? 1 : 0;
|
|
76665
|
+
await Promise.all([
|
|
76666
|
+
...initialTask ? [initialTask] : [],
|
|
76667
|
+
...Array.from({ length: Math.max(0, concurrency - (initialTask ? 1 : 0)) }, () => runBatchWorker(browser, {
|
|
76668
|
+
blocker,
|
|
76669
|
+
cursor,
|
|
76670
|
+
gl: options.gl,
|
|
76671
|
+
lang: options.lang,
|
|
76672
|
+
num: options.num,
|
|
76673
|
+
parallel: options.parallel,
|
|
76674
|
+
queries,
|
|
76675
|
+
results
|
|
76676
|
+
}))
|
|
76677
|
+
]);
|
|
76593
76678
|
return results;
|
|
76594
76679
|
}
|
|
76595
76680
|
async function runLoginSession(options) {
|
|
@@ -76619,18 +76704,18 @@ async function runLoginSession(options) {
|
|
|
76619
76704
|
}
|
|
76620
76705
|
|
|
76621
76706
|
// src/cli/profile.ts
|
|
76622
|
-
import
|
|
76707
|
+
import fs8 from "fs/promises";
|
|
76623
76708
|
import path13 from "path";
|
|
76624
76709
|
var PROFILE_READY_MARKER = ".findweb-profile-ready";
|
|
76625
76710
|
async function ensureProfileDir(dirPath) {
|
|
76626
|
-
await
|
|
76711
|
+
await fs8.mkdir(dirPath, { recursive: true });
|
|
76627
76712
|
}
|
|
76628
76713
|
function readyMarkerPath(userDataDir) {
|
|
76629
76714
|
return path13.join(userDataDir, PROFILE_READY_MARKER);
|
|
76630
76715
|
}
|
|
76631
76716
|
async function hasPreparedProfile(userDataDir) {
|
|
76632
76717
|
try {
|
|
76633
|
-
await
|
|
76718
|
+
await fs8.access(readyMarkerPath(userDataDir));
|
|
76634
76719
|
return true;
|
|
76635
76720
|
} catch {
|
|
76636
76721
|
return false;
|
|
@@ -76638,7 +76723,7 @@ async function hasPreparedProfile(userDataDir) {
|
|
|
76638
76723
|
}
|
|
76639
76724
|
async function markProfilePrepared(userDataDir) {
|
|
76640
76725
|
await ensureProfileDir(userDataDir);
|
|
76641
|
-
await
|
|
76726
|
+
await fs8.writeFile(readyMarkerPath(userDataDir), `${new Date().toISOString()}
|
|
76642
76727
|
`, "utf8");
|
|
76643
76728
|
}
|
|
76644
76729
|
|
|
@@ -76938,7 +77023,7 @@ __export(exports_core2, {
|
|
|
76938
77023
|
safeDecode: () => safeDecode,
|
|
76939
77024
|
registry: () => registry,
|
|
76940
77025
|
regexes: () => exports_regexes,
|
|
76941
|
-
process: () =>
|
|
77026
|
+
process: () => process4,
|
|
76942
77027
|
prettifyError: () => prettifyError,
|
|
76943
77028
|
parseAsync: () => parseAsync,
|
|
76944
77029
|
parse: () => parse,
|
|
@@ -87402,7 +87487,7 @@ function initializeContext(params) {
|
|
|
87402
87487
|
external: params?.external ?? undefined
|
|
87403
87488
|
};
|
|
87404
87489
|
}
|
|
87405
|
-
function
|
|
87490
|
+
function process4(schema, ctx, _params = { path: [], schemaPath: [] }) {
|
|
87406
87491
|
var _a5;
|
|
87407
87492
|
const def = schema._zod.def;
|
|
87408
87493
|
const seen = ctx.seen.get(schema);
|
|
@@ -87439,7 +87524,7 @@ function process3(schema, ctx, _params = { path: [], schemaPath: [] }) {
|
|
|
87439
87524
|
if (parent) {
|
|
87440
87525
|
if (!result.ref)
|
|
87441
87526
|
result.ref = parent;
|
|
87442
|
-
|
|
87527
|
+
process4(parent, ctx, params);
|
|
87443
87528
|
ctx.seen.get(parent).isParent = true;
|
|
87444
87529
|
}
|
|
87445
87530
|
}
|
|
@@ -87715,14 +87800,14 @@ function isTransforming(_schema, _ctx) {
|
|
|
87715
87800
|
}
|
|
87716
87801
|
var createToJSONSchemaMethod = (schema, processors = {}) => (params) => {
|
|
87717
87802
|
const ctx = initializeContext({ ...params, processors });
|
|
87718
|
-
|
|
87803
|
+
process4(schema, ctx);
|
|
87719
87804
|
extractDefs(ctx, schema);
|
|
87720
87805
|
return finalize(ctx, schema);
|
|
87721
87806
|
};
|
|
87722
87807
|
var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) => {
|
|
87723
87808
|
const { libraryOptions, target } = params ?? {};
|
|
87724
87809
|
const ctx = initializeContext({ ...libraryOptions ?? {}, target, io, processors });
|
|
87725
|
-
|
|
87810
|
+
process4(schema, ctx);
|
|
87726
87811
|
extractDefs(ctx, schema);
|
|
87727
87812
|
return finalize(ctx, schema);
|
|
87728
87813
|
};
|
|
@@ -87973,7 +88058,7 @@ var arrayProcessor = (schema, ctx, _json, params) => {
|
|
|
87973
88058
|
if (typeof maximum === "number")
|
|
87974
88059
|
json.maxItems = maximum;
|
|
87975
88060
|
json.type = "array";
|
|
87976
|
-
json.items =
|
|
88061
|
+
json.items = process4(def.element, ctx, { ...params, path: [...params.path, "items"] });
|
|
87977
88062
|
};
|
|
87978
88063
|
var objectProcessor = (schema, ctx, _json, params) => {
|
|
87979
88064
|
const json = _json;
|
|
@@ -87982,7 +88067,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
87982
88067
|
json.properties = {};
|
|
87983
88068
|
const shape = def.shape;
|
|
87984
88069
|
for (const key in shape) {
|
|
87985
|
-
json.properties[key] =
|
|
88070
|
+
json.properties[key] = process4(shape[key], ctx, {
|
|
87986
88071
|
...params,
|
|
87987
88072
|
path: [...params.path, "properties", key]
|
|
87988
88073
|
});
|
|
@@ -88005,7 +88090,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
88005
88090
|
if (ctx.io === "output")
|
|
88006
88091
|
json.additionalProperties = false;
|
|
88007
88092
|
} else if (def.catchall) {
|
|
88008
|
-
json.additionalProperties =
|
|
88093
|
+
json.additionalProperties = process4(def.catchall, ctx, {
|
|
88009
88094
|
...params,
|
|
88010
88095
|
path: [...params.path, "additionalProperties"]
|
|
88011
88096
|
});
|
|
@@ -88014,7 +88099,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
88014
88099
|
var unionProcessor = (schema, ctx, json, params) => {
|
|
88015
88100
|
const def = schema._zod.def;
|
|
88016
88101
|
const isExclusive = def.inclusive === false;
|
|
88017
|
-
const options = def.options.map((x, i) =>
|
|
88102
|
+
const options = def.options.map((x, i) => process4(x, ctx, {
|
|
88018
88103
|
...params,
|
|
88019
88104
|
path: [...params.path, isExclusive ? "oneOf" : "anyOf", i]
|
|
88020
88105
|
}));
|
|
@@ -88026,11 +88111,11 @@ var unionProcessor = (schema, ctx, json, params) => {
|
|
|
88026
88111
|
};
|
|
88027
88112
|
var intersectionProcessor = (schema, ctx, json, params) => {
|
|
88028
88113
|
const def = schema._zod.def;
|
|
88029
|
-
const a =
|
|
88114
|
+
const a = process4(def.left, ctx, {
|
|
88030
88115
|
...params,
|
|
88031
88116
|
path: [...params.path, "allOf", 0]
|
|
88032
88117
|
});
|
|
88033
|
-
const b =
|
|
88118
|
+
const b = process4(def.right, ctx, {
|
|
88034
88119
|
...params,
|
|
88035
88120
|
path: [...params.path, "allOf", 1]
|
|
88036
88121
|
});
|
|
@@ -88047,11 +88132,11 @@ var tupleProcessor = (schema, ctx, _json, params) => {
|
|
|
88047
88132
|
json.type = "array";
|
|
88048
88133
|
const prefixPath = ctx.target === "draft-2020-12" ? "prefixItems" : "items";
|
|
88049
88134
|
const restPath = ctx.target === "draft-2020-12" ? "items" : ctx.target === "openapi-3.0" ? "items" : "additionalItems";
|
|
88050
|
-
const prefixItems = def.items.map((x, i) =>
|
|
88135
|
+
const prefixItems = def.items.map((x, i) => process4(x, ctx, {
|
|
88051
88136
|
...params,
|
|
88052
88137
|
path: [...params.path, prefixPath, i]
|
|
88053
88138
|
}));
|
|
88054
|
-
const rest = def.rest ?
|
|
88139
|
+
const rest = def.rest ? process4(def.rest, ctx, {
|
|
88055
88140
|
...params,
|
|
88056
88141
|
path: [...params.path, restPath, ...ctx.target === "openapi-3.0" ? [def.items.length] : []]
|
|
88057
88142
|
}) : null;
|
|
@@ -88091,7 +88176,7 @@ var recordProcessor = (schema, ctx, _json, params) => {
|
|
|
88091
88176
|
const keyBag = keyType._zod.bag;
|
|
88092
88177
|
const patterns = keyBag?.patterns;
|
|
88093
88178
|
if (def.mode === "loose" && patterns && patterns.size > 0) {
|
|
88094
|
-
const valueSchema =
|
|
88179
|
+
const valueSchema = process4(def.valueType, ctx, {
|
|
88095
88180
|
...params,
|
|
88096
88181
|
path: [...params.path, "patternProperties", "*"]
|
|
88097
88182
|
});
|
|
@@ -88101,12 +88186,12 @@ var recordProcessor = (schema, ctx, _json, params) => {
|
|
|
88101
88186
|
}
|
|
88102
88187
|
} else {
|
|
88103
88188
|
if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") {
|
|
88104
|
-
json.propertyNames =
|
|
88189
|
+
json.propertyNames = process4(def.keyType, ctx, {
|
|
88105
88190
|
...params,
|
|
88106
88191
|
path: [...params.path, "propertyNames"]
|
|
88107
88192
|
});
|
|
88108
88193
|
}
|
|
88109
|
-
json.additionalProperties =
|
|
88194
|
+
json.additionalProperties = process4(def.valueType, ctx, {
|
|
88110
88195
|
...params,
|
|
88111
88196
|
path: [...params.path, "additionalProperties"]
|
|
88112
88197
|
});
|
|
@@ -88121,7 +88206,7 @@ var recordProcessor = (schema, ctx, _json, params) => {
|
|
|
88121
88206
|
};
|
|
88122
88207
|
var nullableProcessor = (schema, ctx, json, params) => {
|
|
88123
88208
|
const def = schema._zod.def;
|
|
88124
|
-
const inner =
|
|
88209
|
+
const inner = process4(def.innerType, ctx, params);
|
|
88125
88210
|
const seen = ctx.seen.get(schema);
|
|
88126
88211
|
if (ctx.target === "openapi-3.0") {
|
|
88127
88212
|
seen.ref = def.innerType;
|
|
@@ -88132,20 +88217,20 @@ var nullableProcessor = (schema, ctx, json, params) => {
|
|
|
88132
88217
|
};
|
|
88133
88218
|
var nonoptionalProcessor = (schema, ctx, _json, params) => {
|
|
88134
88219
|
const def = schema._zod.def;
|
|
88135
|
-
|
|
88220
|
+
process4(def.innerType, ctx, params);
|
|
88136
88221
|
const seen = ctx.seen.get(schema);
|
|
88137
88222
|
seen.ref = def.innerType;
|
|
88138
88223
|
};
|
|
88139
88224
|
var defaultProcessor = (schema, ctx, json, params) => {
|
|
88140
88225
|
const def = schema._zod.def;
|
|
88141
|
-
|
|
88226
|
+
process4(def.innerType, ctx, params);
|
|
88142
88227
|
const seen = ctx.seen.get(schema);
|
|
88143
88228
|
seen.ref = def.innerType;
|
|
88144
88229
|
json.default = JSON.parse(JSON.stringify(def.defaultValue));
|
|
88145
88230
|
};
|
|
88146
88231
|
var prefaultProcessor = (schema, ctx, json, params) => {
|
|
88147
88232
|
const def = schema._zod.def;
|
|
88148
|
-
|
|
88233
|
+
process4(def.innerType, ctx, params);
|
|
88149
88234
|
const seen = ctx.seen.get(schema);
|
|
88150
88235
|
seen.ref = def.innerType;
|
|
88151
88236
|
if (ctx.io === "input")
|
|
@@ -88153,7 +88238,7 @@ var prefaultProcessor = (schema, ctx, json, params) => {
|
|
|
88153
88238
|
};
|
|
88154
88239
|
var catchProcessor = (schema, ctx, json, params) => {
|
|
88155
88240
|
const def = schema._zod.def;
|
|
88156
|
-
|
|
88241
|
+
process4(def.innerType, ctx, params);
|
|
88157
88242
|
const seen = ctx.seen.get(schema);
|
|
88158
88243
|
seen.ref = def.innerType;
|
|
88159
88244
|
let catchValue;
|
|
@@ -88167,32 +88252,32 @@ var catchProcessor = (schema, ctx, json, params) => {
|
|
|
88167
88252
|
var pipeProcessor = (schema, ctx, _json, params) => {
|
|
88168
88253
|
const def = schema._zod.def;
|
|
88169
88254
|
const innerType = ctx.io === "input" ? def.in._zod.def.type === "transform" ? def.out : def.in : def.out;
|
|
88170
|
-
|
|
88255
|
+
process4(innerType, ctx, params);
|
|
88171
88256
|
const seen = ctx.seen.get(schema);
|
|
88172
88257
|
seen.ref = innerType;
|
|
88173
88258
|
};
|
|
88174
88259
|
var readonlyProcessor = (schema, ctx, json, params) => {
|
|
88175
88260
|
const def = schema._zod.def;
|
|
88176
|
-
|
|
88261
|
+
process4(def.innerType, ctx, params);
|
|
88177
88262
|
const seen = ctx.seen.get(schema);
|
|
88178
88263
|
seen.ref = def.innerType;
|
|
88179
88264
|
json.readOnly = true;
|
|
88180
88265
|
};
|
|
88181
88266
|
var promiseProcessor = (schema, ctx, _json, params) => {
|
|
88182
88267
|
const def = schema._zod.def;
|
|
88183
|
-
|
|
88268
|
+
process4(def.innerType, ctx, params);
|
|
88184
88269
|
const seen = ctx.seen.get(schema);
|
|
88185
88270
|
seen.ref = def.innerType;
|
|
88186
88271
|
};
|
|
88187
88272
|
var optionalProcessor = (schema, ctx, _json, params) => {
|
|
88188
88273
|
const def = schema._zod.def;
|
|
88189
|
-
|
|
88274
|
+
process4(def.innerType, ctx, params);
|
|
88190
88275
|
const seen = ctx.seen.get(schema);
|
|
88191
88276
|
seen.ref = def.innerType;
|
|
88192
88277
|
};
|
|
88193
88278
|
var lazyProcessor = (schema, ctx, _json, params) => {
|
|
88194
88279
|
const innerType = schema._zod.innerType;
|
|
88195
|
-
|
|
88280
|
+
process4(innerType, ctx, params);
|
|
88196
88281
|
const seen = ctx.seen.get(schema);
|
|
88197
88282
|
seen.ref = innerType;
|
|
88198
88283
|
};
|
|
@@ -88244,7 +88329,7 @@ function toJSONSchema(input2, params) {
|
|
|
88244
88329
|
const defs = {};
|
|
88245
88330
|
for (const entry of registry2._idmap.entries()) {
|
|
88246
88331
|
const [_2, schema] = entry;
|
|
88247
|
-
|
|
88332
|
+
process4(schema, ctx2);
|
|
88248
88333
|
}
|
|
88249
88334
|
const schemas = {};
|
|
88250
88335
|
const external = {
|
|
@@ -88267,7 +88352,7 @@ function toJSONSchema(input2, params) {
|
|
|
88267
88352
|
return { schemas };
|
|
88268
88353
|
}
|
|
88269
88354
|
const ctx = initializeContext({ ...params, processors: allProcessors });
|
|
88270
|
-
|
|
88355
|
+
process4(input2, ctx);
|
|
88271
88356
|
extractDefs(ctx, input2);
|
|
88272
88357
|
return finalize(ctx, input2);
|
|
88273
88358
|
}
|
|
@@ -88313,7 +88398,7 @@ class JSONSchemaGenerator {
|
|
|
88313
88398
|
});
|
|
88314
88399
|
}
|
|
88315
88400
|
process(schema, _params = { path: [], schemaPath: [] }) {
|
|
88316
|
-
return
|
|
88401
|
+
return process4(schema, this.ctx, _params);
|
|
88317
88402
|
}
|
|
88318
88403
|
emit(schema, _params) {
|
|
88319
88404
|
if (_params) {
|
|
@@ -90318,10 +90403,10 @@ function createLoginCommand(commandName = "findweb login") {
|
|
|
90318
90403
|
}
|
|
90319
90404
|
|
|
90320
90405
|
// src/cli/commands/search.ts
|
|
90321
|
-
import
|
|
90406
|
+
import process5 from "process";
|
|
90322
90407
|
|
|
90323
90408
|
// src/search/blocker.ts
|
|
90324
|
-
import
|
|
90409
|
+
import fs9 from "fs/promises";
|
|
90325
90410
|
import os10 from "os";
|
|
90326
90411
|
import path15 from "path";
|
|
90327
90412
|
|
|
@@ -101383,17 +101468,17 @@ function defaultCacheDir() {
|
|
|
101383
101468
|
return process.env.GOOGLE_SEARCH_CACHE_DIR ?? path15.join(os10.homedir(), ".cache", "google-search");
|
|
101384
101469
|
}
|
|
101385
101470
|
async function readCache(filePath) {
|
|
101386
|
-
return
|
|
101471
|
+
return fs9.readFile(filePath);
|
|
101387
101472
|
}
|
|
101388
101473
|
async function writeCache(filePath, buffer) {
|
|
101389
|
-
await
|
|
101390
|
-
await
|
|
101474
|
+
await fs9.mkdir(path15.dirname(filePath), { recursive: true });
|
|
101475
|
+
await fs9.writeFile(filePath, buffer);
|
|
101391
101476
|
}
|
|
101392
101477
|
async function loadBlocker() {
|
|
101393
101478
|
if (!blockerPromise) {
|
|
101394
101479
|
blockerPromise = (async () => {
|
|
101395
101480
|
const cacheDir = defaultCacheDir();
|
|
101396
|
-
await
|
|
101481
|
+
await fs9.mkdir(cacheDir, { recursive: true });
|
|
101397
101482
|
return PuppeteerBlocker.fromPrebuiltAdsAndTracking(globalThis.fetch.bind(globalThis), {
|
|
101398
101483
|
path: path15.join(cacheDir, "ghostery-engine.bin"),
|
|
101399
101484
|
read: readCache,
|
|
@@ -101535,9 +101620,9 @@ async function runSearch(args) {
|
|
|
101535
101620
|
lang: options.lang,
|
|
101536
101621
|
num: options.num,
|
|
101537
101622
|
parallel: options.parallel
|
|
101538
|
-
});
|
|
101623
|
+
}, activeBrowser.initialPage);
|
|
101539
101624
|
printResults(options.json, outcomes);
|
|
101540
|
-
|
|
101625
|
+
process5.exitCode = exitCodeForOutcomes(outcomes);
|
|
101541
101626
|
} finally {
|
|
101542
101627
|
await closeSearchBrowser(activeBrowser);
|
|
101543
101628
|
}
|
|
@@ -101554,7 +101639,7 @@ function createSearchCommand(commandName = "findweb") {
|
|
|
101554
101639
|
await runSearch(args);
|
|
101555
101640
|
} catch (error49) {
|
|
101556
101641
|
printCommandError2(error49);
|
|
101557
|
-
|
|
101642
|
+
process5.exitCode = 1;
|
|
101558
101643
|
}
|
|
101559
101644
|
}
|
|
101560
101645
|
});
|
|
@@ -101623,7 +101708,7 @@ function showRootHelp() {
|
|
|
101623
101708
|
console.log(renderRootHelp());
|
|
101624
101709
|
}
|
|
101625
101710
|
async function main() {
|
|
101626
|
-
const rawArgs =
|
|
101711
|
+
const rawArgs = process6.argv.slice(2);
|
|
101627
101712
|
const action = resolveRootAction(rawArgs);
|
|
101628
101713
|
if (action.kind === "help") {
|
|
101629
101714
|
showRootHelp();
|
|
@@ -101640,5 +101725,5 @@ try {
|
|
|
101640
101725
|
} catch (error49) {
|
|
101641
101726
|
const message = error49 instanceof Error ? error49.message : String(error49);
|
|
101642
101727
|
console.error(`ERROR: ${message}`);
|
|
101643
|
-
|
|
101728
|
+
process6.exitCode = 1;
|
|
101644
101729
|
}
|