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.
Files changed (3) hide show
  1. package/README.md +4 -3
  2. package/dist/index.js +223 -138
  3. 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. Loads the [Ghostery adblocker](https://github.com/ghostery/adblocker) engine programmatically on each page
76
- 4. Navigates to Google, submits the query through DOM manipulation, and extracts results from the rendered page
77
- 5. Returns results as plain text or JSON, then closes Chrome
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 process5 from "process";
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.exitCode !== null) {
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(250);
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
- stdio: ["ignore", "ignore", "pipe"]
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 puppeteer_core_default.connect({ browserURL: `http://127.0.0.1:${port}` });
76301
- return { browser, chromeProcess, port };
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.exitCode === null) {
76416
+ if (activeBrowser.chromeProcess?.exitCode === null) {
76308
76417
  activeBrowser.chromeProcess.kill("SIGTERM");
76309
76418
  }
76310
76419
  }
76311
76420
  function defaultXdgDataHome() {
76312
- const configured = process.env.XDG_DATA_HOME;
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 = process.env.GOOGLE_SEARCH_USER_DATA_DIR;
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 gotoGoogleHome(page, lang, gl) {
76463
- await page.goto(createGoogleHomeUrl(lang, gl), { waitUntil: "networkidle2" });
76464
- await page.waitForSelector('textarea[name="q"], input[name="q"]');
76465
- }
76466
- async function submitSearch(page, query, lang, gl) {
76467
- await Promise.all([
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 gotoGoogleHome(page, options.lang, options.gl);
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
- await page.close().catch(() => {
76552
- return;
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
- await Promise.all(Array.from({ length: concurrency }, () => runBatchWorker(browser, {
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
- results
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 fs7 from "fs/promises";
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 fs7.mkdir(dirPath, { recursive: true });
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 fs7.access(readyMarkerPath(userDataDir));
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 fs7.writeFile(readyMarkerPath(userDataDir), `${new Date().toISOString()}
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: () => process3,
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 process3(schema, ctx, _params = { path: [], schemaPath: [] }) {
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
- process3(parent, ctx, params);
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
- process3(schema, ctx);
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
- process3(schema, ctx);
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 = process3(def.element, ctx, { ...params, path: [...params.path, "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] = process3(shape[key], ctx, {
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 = process3(def.catchall, ctx, {
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) => process3(x, ctx, {
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 = process3(def.left, ctx, {
88114
+ const a = process4(def.left, ctx, {
88030
88115
  ...params,
88031
88116
  path: [...params.path, "allOf", 0]
88032
88117
  });
88033
- const b = process3(def.right, ctx, {
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) => process3(x, ctx, {
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 ? process3(def.rest, ctx, {
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 = process3(def.valueType, ctx, {
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 = process3(def.keyType, ctx, {
88189
+ json.propertyNames = process4(def.keyType, ctx, {
88105
88190
  ...params,
88106
88191
  path: [...params.path, "propertyNames"]
88107
88192
  });
88108
88193
  }
88109
- json.additionalProperties = process3(def.valueType, ctx, {
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 = process3(def.innerType, ctx, params);
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
- process3(def.innerType, ctx, params);
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
- process3(def.innerType, ctx, params);
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
- process3(def.innerType, ctx, params);
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
- process3(def.innerType, ctx, params);
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
- process3(innerType, ctx, params);
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
- process3(def.innerType, ctx, params);
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
- process3(def.innerType, ctx, params);
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
- process3(def.innerType, ctx, params);
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
- process3(innerType, ctx, params);
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
- process3(schema, ctx2);
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
- process3(input2, ctx);
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 process3(schema, this.ctx, _params);
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 process4 from "process";
90406
+ import process5 from "process";
90322
90407
 
90323
90408
  // src/search/blocker.ts
90324
- import fs8 from "fs/promises";
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 fs8.readFile(filePath);
101471
+ return fs9.readFile(filePath);
101387
101472
  }
101388
101473
  async function writeCache(filePath, buffer) {
101389
- await fs8.mkdir(path15.dirname(filePath), { recursive: true });
101390
- await fs8.writeFile(filePath, buffer);
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 fs8.mkdir(cacheDir, { recursive: true });
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
- process4.exitCode = exitCodeForOutcomes(outcomes);
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
- process4.exitCode = 1;
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 = process5.argv.slice(2);
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
- process5.exitCode = 1;
101728
+ process6.exitCode = 1;
101644
101729
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "findweb",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Google search CLI powered by system Chrome",
5
5
  "type": "module",
6
6
  "packageManager": "bun@1.3.11",