@detiq/crawler 1.1.20 → 1.1.21

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/crawler.js CHANGED
@@ -374,6 +374,7 @@ const TwoFASchema = z.object({
374
374
  has2FA: z.boolean(),
375
375
  fieldLabel: z.string().optional()
376
376
  });
377
+ const INLINE_AUTH_WALL_RE = /your login session (was|has been) expired|session (has )?expired[^.]*click|please (log ?in|sign ?in) to continue|you (are|were) logged out|your session has timed out/i;
377
378
  async function crawlProject(opts, onProgress) {
378
379
  const tuning = await getCrawlTuning();
379
380
  if (opts.screenshotDir) await fs.mkdir(opts.screenshotDir, { recursive: true });
@@ -1681,7 +1682,6 @@ async function crawlProject(opts, onProgress) {
1681
1682
  const name = pathParts.map((p) => p.charAt(0).toUpperCase() + p.slice(1).replace(/[-_]/g, " ")).join(" \u2014 ") || "Home";
1682
1683
  const screen = await AppBrain.saveScreen(opts.tenantId, opts.projectId, name, url, opts.jobId, discoveryMethodFor(url));
1683
1684
  visited.set(canonUrl, screen.id);
1684
- const INLINE_AUTH_WALL_RE = /your login session (was|has been) expired|session (has )?expired[^.]*click|please (log ?in|sign ?in) to continue|you (are|were) logged out|your session has timed out/i;
1685
1685
  const lwBodyText = await workerPage.evaluate(() => document.body?.innerText ?? "").catch(() => "");
1686
1686
  if (INLINE_AUTH_WALL_RE.test(lwBodyText)) {
1687
1687
  logger.warn({ url, screenId: screen.id }, "[lite-worker] Inline session-expired content detected \u2014 marking requiresAuth");
@@ -2875,9 +2875,9 @@ async function crawlProject(opts, onProgress) {
2875
2875
  })();
2876
2876
  }
2877
2877
  }
2878
- const INLINE_AUTH_WALL_RE = /your login session (was|has been) expired|session (has )?expired[^.]*click|please (log ?in|sign ?in) to continue|you (are|were) logged out|your session has timed out/i;
2878
+ const INLINE_AUTH_WALL_RE2 = /your login session (was|has been) expired|session (has )?expired[^.]*click|please (log ?in|sign ?in) to continue|you (are|were) logged out|your session has timed out/i;
2879
2879
  const pageBodyText = await page.evaluate(() => document.body?.innerText ?? "").catch(() => "");
2880
- if (INLINE_AUTH_WALL_RE.test(pageBodyText)) {
2880
+ if (INLINE_AUTH_WALL_RE2.test(pageBodyText)) {
2881
2881
  logger.warn({ url, screenId: screen.id }, "[crawler] Inline session-expired content detected \u2014 skipping DOM snapshot, marking requiresAuth");
2882
2882
  AppBrain.updateScreenRequiresAuth(opts.tenantId, screen.id, true).catch(() => {
2883
2883
  });
@@ -3614,6 +3614,13 @@ ${snippet}`,
3614
3614
  await AppBrain.saveElement(opts.tenantId, opts.projectId, existingScreenId, el.meaning, el.role, el.expectedData, el.notes, void 0, true, el.boundingRect, el.ariaState, el.parentLandmark).catch(() => {
3615
3615
  });
3616
3616
  }
3617
+ } else {
3618
+ const p3aBodyText = await page.evaluate(() => document.body?.innerText ?? "").catch(() => "");
3619
+ if (INLINE_AUTH_WALL_RE.test(p3aBodyText)) {
3620
+ logger.warn({ url: revisitUrl, screenId: existingScreenId }, "[P3a] Re-visit got 0 elements \u2014 inline session-expired content, marking requiresAuth");
3621
+ AppBrain.updateScreenRequiresAuth(opts.tenantId, existingScreenId, true).catch(() => {
3622
+ });
3623
+ }
3617
3624
  }
3618
3625
  const revisitLinks = await discoverLinks(stagehand, origin, page, linkLLM ?? void 0, false, rawPage ?? void 0).catch(() => []);
3619
3626
  for (const href of revisitLinks) {
@@ -3753,6 +3760,14 @@ ${snippet}`,
3753
3760
  await AppBrain.saveElement(opts.tenantId, opts.projectId, gapScreen.id, el.meaning, el.role, el.expectedData, el.notes, void 0, true, el.boundingRect, el.ariaState, el.parentLandmark).catch(() => {
3754
3761
  });
3755
3762
  }
3763
+ if (gapElems.length === 0) {
3764
+ const gapBodyText = await page.evaluate(() => document.body?.innerText ?? "").catch(() => "");
3765
+ if (INLINE_AUTH_WALL_RE.test(gapBodyText)) {
3766
+ logger.warn({ url: gapUrl, screenId: gapScreen.id }, "[P6] Gap URL got 0 elements \u2014 inline session-expired content, marking requiresAuth");
3767
+ AppBrain.updateScreenRequiresAuth(opts.tenantId, gapScreen.id, true).catch(() => {
3768
+ });
3769
+ }
3770
+ }
3756
3771
  visited.set(canonicalize(gapUrl), gapScreen.id);
3757
3772
  discovered.push({ url: gapUrl, screenId: gapScreen.id, elements: gapElems.length, version: gapScreen.version });
3758
3773
  for (const lm of gapLinkMaps) {
@@ -5867,6 +5882,16 @@ async function captureAuthDiscoveryScreen(page, opts, requestedUrl, source, ordi
5867
5882
  await AppBrain.updateScreenDomSnapshot(opts.tenantId, screen.id, authDomPath, authDomCloudUrl).catch(() => {
5868
5883
  });
5869
5884
  }
5885
+ const authDiscoveryElements = await readScreen(page).catch(() => []);
5886
+ if (authDiscoveryElements.length > 0) {
5887
+ await AppBrain.clearScreenElements(opts.tenantId, opts.projectId, screen.id).catch(() => {
5888
+ });
5889
+ for (const el of authDiscoveryElements) {
5890
+ await AppBrain.saveElement(opts.tenantId, opts.projectId, screen.id, el.label, el.role, el.expectedData, void 0, void 0, true, void 0, void 0, void 0).catch(() => {
5891
+ });
5892
+ }
5893
+ logger.info({ screenId: screen.id, elements: authDiscoveryElements.length }, "[crawler] auth-discovery: saved elements");
5894
+ }
5870
5895
  await AppBrain.saveCrawlEvidence(opts.tenantId, opts.projectId, {
5871
5896
  screenId: screen.id,
5872
5897
  jobId: opts.jobId,